forked from qt-creator/qt-creator
Fixes: Designer/'Goto Slot' doesn't work with multiple inheritance
Task: 247782 Details: Check for inheritance as well as member when looking for UI::FormClass.
This commit is contained in:
@@ -1,9 +1,6 @@
|
||||
<ui version="4.0" stdsetdef="1" >
|
||||
<ui version="4.0">
|
||||
<class>%CLASS%Class</class>
|
||||
<widget class="%BASECLASS%" name="%CLASS%Class" >
|
||||
<property name="objectName" >
|
||||
<cstring>%CLASS%Class</cstring>
|
||||
</property>
|
||||
<property name="geometry" >
|
||||
<rect>
|
||||
<x>0</x>
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
#include "formtemplatewizardpage.h"
|
||||
#include "formeditorw.h"
|
||||
#include "designerconstants.h"
|
||||
|
||||
#include <qt_private/abstractnewformwidget_p.h>
|
||||
|
||||
@@ -278,6 +279,8 @@ namespace {
|
||||
|
||||
QString FormTemplateWizardPage::changeUiClassName(const QString &uiXml, const QString &newUiClassName)
|
||||
{
|
||||
if (Designer::Constants::Internal::debug)
|
||||
qDebug() << '>' << Q_FUNC_INFO << newUiClassName;
|
||||
QDomDocument domUi;
|
||||
if (!domUi.setContent(uiXml)) {
|
||||
qWarning("Failed to parse:\n%s", uiXml.toUtf8().constData());
|
||||
@@ -320,6 +323,8 @@ QString FormTemplateWizardPage::changeUiClassName(const QString &uiXml, const QS
|
||||
}
|
||||
}
|
||||
const QString rc = domUi.toString();
|
||||
if (Designer::Constants::Internal::debug > 1)
|
||||
qDebug() << '<' << Q_FUNC_INFO << newUiClassName << rc;
|
||||
return rc;
|
||||
}
|
||||
#endif // USE_XSLT
|
||||
|
||||
@@ -36,14 +36,14 @@ using namespace Designer::Internal;
|
||||
|
||||
void SettingsManager::beginGroup(const QString &prefix)
|
||||
{
|
||||
if (Designer::Constants::Internal::debug)
|
||||
if (Designer::Constants::Internal::debug > 1)
|
||||
qDebug() << Q_FUNC_INFO << addPrefix(prefix);
|
||||
m_settings.beginGroup(addPrefix(prefix));
|
||||
}
|
||||
|
||||
void SettingsManager::endGroup()
|
||||
{
|
||||
if (Designer::Constants::Internal::debug)
|
||||
if (Designer::Constants::Internal::debug > 1)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
m_settings.endGroup();
|
||||
}
|
||||
@@ -55,7 +55,7 @@ bool SettingsManager::contains(const QString &key) const
|
||||
|
||||
void SettingsManager::setValue(const QString &key, const QVariant &value)
|
||||
{
|
||||
if (Designer::Constants::Internal::debug)
|
||||
if (Designer::Constants::Internal::debug > 1)
|
||||
qDebug() << Q_FUNC_INFO << addPrefix(key) << ": " << value;
|
||||
m_settings.setValue(addPrefix(key), value);
|
||||
}
|
||||
@@ -63,7 +63,7 @@ void SettingsManager::setValue(const QString &key, const QVariant &value)
|
||||
QVariant SettingsManager::value(const QString &key, const QVariant &defaultValue) const
|
||||
{
|
||||
QVariant result = m_settings.value(addPrefix(key), defaultValue);
|
||||
if (Designer::Constants::Internal::debug)
|
||||
if (Designer::Constants::Internal::debug > 1)
|
||||
qDebug() << Q_FUNC_INFO << addPrefix(key) << ": " << result;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -125,6 +125,16 @@ static QList<Document::Ptr> findDocumentsIncluding(const CPlusPlus::Snapshot &do
|
||||
return docList;
|
||||
}
|
||||
|
||||
// Does klass inherit baseClass?
|
||||
static bool inherits(const Overview &o, const Class *klass, const QString &baseClass)
|
||||
{
|
||||
const int baseClassCount = klass->baseClassCount();
|
||||
for (int b = 0; b < baseClassCount; b++)
|
||||
if (o.prettyName(klass->baseClassAt(b)->name()) == baseClass)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for a class name where haystack is a member class of an object.
|
||||
// So, haystack can be shorter (can have some namespaces omitted because of a
|
||||
// "using namespace" declaration, for example, comparing
|
||||
@@ -141,7 +151,9 @@ static bool matchMemberClassName(const QString &needle, const QString &hayStack)
|
||||
return separatorPos > 1 && needle.at(separatorPos) == QLatin1Char(':');
|
||||
}
|
||||
|
||||
// Find class definition in namespace
|
||||
// Find class definition in namespace (that is, the outer class
|
||||
// containing a member of the desired class type) or inheriting the desired class
|
||||
// in case of forms using the Multiple Inheritance approach
|
||||
static const Class *findClass(const Namespace *parentNameSpace, const QString &className, QString *namespaceName)
|
||||
{
|
||||
if (Designer::Constants::Internal::debug)
|
||||
@@ -153,8 +165,9 @@ static const Class *findClass(const Namespace *parentNameSpace, const QString &c
|
||||
const Symbol *sym = parentNameSpace->memberAt(i);
|
||||
// we have found a class - we are interested in classes only
|
||||
if (const Class *cl = sym->asClass()) {
|
||||
// 1) we go through class members
|
||||
const unsigned classMemberCount = cl->memberCount();
|
||||
for (unsigned j = 0; j < classMemberCount; j++) // we go through class members
|
||||
for (unsigned j = 0; j < classMemberCount; j++)
|
||||
if (const Declaration *decl = cl->memberAt(j)->asDeclaration()) {
|
||||
// we want to know if the class contains a member (so we look into
|
||||
// a declaration) of uiClassName type
|
||||
@@ -166,6 +179,9 @@ static const Class *findClass(const Namespace *parentNameSpace, const QString &c
|
||||
if (nt && matchMemberClassName(className, o.prettyName(nt->name())))
|
||||
return cl;
|
||||
} // decl
|
||||
// 2) does it inherit the desired class
|
||||
if (inherits(o, cl, className))
|
||||
return cl;
|
||||
} else {
|
||||
// Check namespaces
|
||||
if (const Namespace *ns = sym->asNamespace()) {
|
||||
@@ -386,8 +402,15 @@ static void addDeclaration(const QString &docFileName, const Class *cl, const QS
|
||||
// fun->column() returns always 0, what can cause trouble in case in one
|
||||
// line if there is: "private slots: void foo();"
|
||||
if (fun->isSlot() && fun->isPrivate()) {
|
||||
if (ITextEditable *editable = editableAt(docFileName, fun->line(), fun->column()))
|
||||
editable->insert(declaration + QLatin1String(" "));
|
||||
const int line = fun->line(); // [1..n]
|
||||
const int column = fun->column();
|
||||
if (ITextEditable *editable = editableAt(docFileName, line, column)) {
|
||||
// Figure out indentation (symbol - len("void ")) and insert after
|
||||
editable->gotoLine(line + 1, 1);
|
||||
editable->position(ITextEditor::StartOfLine);
|
||||
const QString indentation = QString(qMax(0, column - 6), QLatin1Char(' '));
|
||||
editable->insert(indentation + declaration);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -483,7 +506,7 @@ static ClassDocumentPtrPair
|
||||
unsigned maxIncludeDepth, QString *namespaceName)
|
||||
{
|
||||
if (Designer::Constants::Internal::debug)
|
||||
qDebug() << Q_FUNC_INFO << doc->fileName() << maxIncludeDepth;
|
||||
qDebug() << Q_FUNC_INFO << doc->fileName() << className << maxIncludeDepth;
|
||||
// Check document
|
||||
if (const Class *cl = findClass(doc->globalNamespace(), className, namespaceName))
|
||||
return ClassDocumentPtrPair(cl, doc);
|
||||
@@ -523,6 +546,9 @@ static inline QString uiClassName(QString formObjectName)
|
||||
return formObjectName;
|
||||
}
|
||||
|
||||
// Goto slot invoked by the designer context menu. Either navigates
|
||||
// to an existing slot function or create a new one.
|
||||
|
||||
bool WorkbenchIntegration::navigateToSlot(const QString &objectName,
|
||||
const QString &signalSignature,
|
||||
const QStringList ¶meterNames,
|
||||
@@ -538,7 +564,7 @@ bool WorkbenchIntegration::navigateToSlot(const QString &objectName,
|
||||
const QFileInfo fi(currentUiFile);
|
||||
const QString uicedName = QLatin1String("ui_") + fi.baseName() + QLatin1String(".h");
|
||||
|
||||
// take all docs
|
||||
// take all docs, find the ones that include the ui_xx.h.
|
||||
|
||||
const CPlusPlus::Snapshot docTable = cppModelManagerInstance()->snapshot();
|
||||
QList<Document::Ptr> docList = findDocumentsIncluding(docTable, uicedName, true); // change to false when we know the absolute path to generated ui_<>.h file
|
||||
@@ -546,7 +572,7 @@ bool WorkbenchIntegration::navigateToSlot(const QString &objectName,
|
||||
if (Designer::Constants::Internal::debug)
|
||||
qDebug() << Q_FUNC_INFO << objectName << signalSignature << "Looking for " << uicedName << " returned " << docList.size();
|
||||
if (docList.isEmpty()) {
|
||||
*errorMessage = tr("No documents matching %1 could be found.").arg(uicedName);
|
||||
*errorMessage = tr("No documents matching '%1' could be found.\nRebuilding the project might help.").arg(uicedName);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -557,8 +583,8 @@ bool WorkbenchIntegration::navigateToSlot(const QString &objectName,
|
||||
if (Designer::Constants::Internal::debug)
|
||||
qDebug() << "Checking docs for " << uiClass;
|
||||
|
||||
// Find the class definition in the file itself or in the directly
|
||||
// included files (order 1).
|
||||
// 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;
|
||||
@@ -578,6 +604,8 @@ bool WorkbenchIntegration::navigateToSlot(const QString &objectName,
|
||||
|
||||
Overview o;
|
||||
const QString className = namespaceName + o.prettyName(cl->name());
|
||||
if (Designer::Constants::Internal::debug)
|
||||
qDebug() << "Found class " << className << doc->fileName();
|
||||
|
||||
const QString functionName = QLatin1String("on_") + objectName + QLatin1Char('_') + signalSignature;
|
||||
const QString functionNameWithParameterNames = addParameterNames(functionName, parameterNames);
|
||||
|
||||
Reference in New Issue
Block a user