static QByteArray getFileContent(QString filePath) { QByteArray fileContent; CppTools::CppModelManager *cppMM = CppTools::CppModelManager::instance(); CppTools::WorkingCopy wc = cppMM->workingCopy(); if (wc.contains(filePath)) { fileContent = wc.source(filePath); } else { QString error; const QTextCodec *codec = Core::EditorManager::defaultTextCodec(); if (Utils::TextFileFormat::readFileUTF8(filePath, codec, &fileContent, &error) != Utils::TextFileFormat::ReadSuccess) { qDebug() << "Failed to read file" << filePath << ":" << error; } } return fileContent; }
static Document::Ptr getParsedDocument(const QString &fileName, CppTools::WorkingCopy &workingCopy, Snapshot &snapshot) { QByteArray src; if (workingCopy.contains(fileName)) { src = workingCopy.source(fileName); } else { Utils::FileReader reader; if (reader.fetch(fileName)) // ### FIXME error reporting src = QString::fromLocal8Bit(reader.data()).toUtf8(); } Document::Ptr doc = snapshot.preprocessedDocument(src, fileName); doc->check(); snapshot.insert(doc); return doc; }
bool QtCreatorIntegration::navigateToSlot(const QString &objectName, const QString &signalSignature, const QStringList ¶meterNames, QString *errorMessage) { typedef QMap<int, Document::Ptr> DocumentMap; const Utils::FileName currentUiFile = FormEditorW::activeEditor()->document()->filePath(); #if 0 return Designer::Internal::navigateToSlot(currentUiFile.toString(), objectName, signalSignature, parameterNames, errorMessage); #endif // TODO: we should pass to findDocumentsIncluding an absolute path to generated .h file from ui. // Currently we are guessing the name of ui_<>.h file and pass the file name only to the findDocumentsIncluding(). // The idea is that the .pro file knows if the .ui files is inside, and the .pro file knows it will // be generating the ui_<>.h file for it, and the .pro file knows what the generated file's name and its absolute path will be. // So we should somehow get that info from project manager (?) const QFileInfo fi = currentUiFile.toFileInfo(); const QString uiFolder = fi.absolutePath(); const QString uicedName = "ui_" + fi.completeBaseName() + ".h"; // Retrieve code model snapshot restricted to project of ui file or the working copy. Snapshot docTable = CppTools::CppModelManager::instance()->snapshot(); Snapshot newDocTable; const Project *uiProject = SessionManager::projectForFile(currentUiFile); if (uiProject) { for (Snapshot::const_iterator i = docTable.begin(), ei = docTable.end(); i != ei; ++i) { const Project *project = SessionManager::projectForFile(i.key()); if (project == uiProject) newDocTable.insert(i.value()); } } else { const CppTools::WorkingCopy workingCopy = CppTools::CppModelManager::instance()->workingCopy(); const Utils::FileName configFileName = Utils::FileName::fromString(CppTools::CppModelManager::configurationFileName()); QHashIterator<Utils::FileName, QPair<QByteArray, unsigned> > it = workingCopy.iterator(); while (it.hasNext()) { it.next(); const Utils::FileName &fileName = it.key(); if (fileName != configFileName) newDocTable.insert(docTable.document(fileName)); } } docTable = newDocTable; // take all docs, find the ones that include the ui_xx.h. // Sort into a map, putting the ones whose path closely matches the ui-folder path // first in case there are project subdirectories that contain identical file names. const QList<Document::Ptr> docList = findDocumentsIncluding(docTable, uicedName, true); // change to false when we know the absolute path to generated ui_<>.h file DocumentMap docMap; for (const Document::Ptr &d : docList) { const QFileInfo docFi(d->fileName()); docMap.insert(qAbs(docFi.absolutePath().compare(uiFolder, Qt::CaseInsensitive)), d); } if (Designer::Constants::Internal::debug) qDebug() << Q_FUNC_INFO << objectName << signalSignature << "Looking for " << uicedName << " returned " << docList.size(); if (docMap.isEmpty()) { *errorMessage = tr("No documents matching \"%1\" could be found.\nRebuilding the project might help.").arg(uicedName); return false; } QDesignerFormWindowInterface *fwi = FormEditorW::activeWidgetHost()->formWindow(); const QString uiClass = uiClassName(fwi->mainContainer()->objectName()); if (Designer::Constants::Internal::debug) qDebug() << "Checking docs for " << uiClass; // Find the class definition (ui class defined as member or base class) // in the file itself or in the directly included files (order 1). QString namespaceName; const Class *cl = 0; Document::Ptr doc; for (const Document::Ptr &d : qAsConst(docMap)) { LookupContext context(d, docTable); const ClassDocumentPtrPair cd = findClassRecursively(context, uiClass, 1u , &namespaceName); if (cd.first) { cl = cd.first; doc = cd.second; break; } } if (!cl) { *errorMessage = msgClassNotFound(uiClass, docList); return false; } Overview o; const QString className = namespaceName + o.prettyName(cl->name()); if (Designer::Constants::Internal::debug) qDebug() << "Found class " << className << doc->fileName(); const QString functionName = "on_" + objectName + '_' + signalSignature; const QString functionNameWithParameterNames = addParameterNames(functionName, parameterNames); if (Designer::Constants::Internal::debug) qDebug() << Q_FUNC_INFO << "Found " << uiClass << doc->fileName() << " checking " << functionName << functionNameWithParameterNames; int line = 0; Document::Ptr sourceDoc; if (Function *fun = findDeclaration(cl, functionName)) { sourceDoc = findDefinition(fun, &line); if (!sourceDoc) { // add function definition to cpp file sourceDoc = addDefinition(docTable, doc->fileName(), className, functionNameWithParameterNames, &line); } } else { // add function declaration to cl CppTools::WorkingCopy workingCopy = CppTools::CppModelManager::instance()->workingCopy(); const QString fileName = doc->fileName(); getParsedDocument(fileName, workingCopy, docTable); addDeclaration(docTable, fileName, cl, functionNameWithParameterNames); // add function definition to cpp file sourceDoc = addDefinition(docTable, fileName, className, functionNameWithParameterNames, &line); } if (!sourceDoc) { *errorMessage = tr("Unable to add the method definition."); return false; } // jump to function definition, position within code Core::EditorManager::openEditorAt(sourceDoc->fileName(), line + 2, indentation); return true; }