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>
|
<class>%CLASS%Class</class>
|
||||||
<widget class="%BASECLASS%" name="%CLASS%Class" >
|
<widget class="%BASECLASS%" name="%CLASS%Class" >
|
||||||
<property name="objectName" >
|
|
||||||
<cstring>%CLASS%Class</cstring>
|
|
||||||
</property>
|
|
||||||
<property name="geometry" >
|
<property name="geometry" >
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
#include "formtemplatewizardpage.h"
|
#include "formtemplatewizardpage.h"
|
||||||
#include "formeditorw.h"
|
#include "formeditorw.h"
|
||||||
|
#include "designerconstants.h"
|
||||||
|
|
||||||
#include <qt_private/abstractnewformwidget_p.h>
|
#include <qt_private/abstractnewformwidget_p.h>
|
||||||
|
|
||||||
@@ -278,6 +279,8 @@ namespace {
|
|||||||
|
|
||||||
QString FormTemplateWizardPage::changeUiClassName(const QString &uiXml, const QString &newUiClassName)
|
QString FormTemplateWizardPage::changeUiClassName(const QString &uiXml, const QString &newUiClassName)
|
||||||
{
|
{
|
||||||
|
if (Designer::Constants::Internal::debug)
|
||||||
|
qDebug() << '>' << Q_FUNC_INFO << newUiClassName;
|
||||||
QDomDocument domUi;
|
QDomDocument domUi;
|
||||||
if (!domUi.setContent(uiXml)) {
|
if (!domUi.setContent(uiXml)) {
|
||||||
qWarning("Failed to parse:\n%s", uiXml.toUtf8().constData());
|
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();
|
const QString rc = domUi.toString();
|
||||||
|
if (Designer::Constants::Internal::debug > 1)
|
||||||
|
qDebug() << '<' << Q_FUNC_INFO << newUiClassName << rc;
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
#endif // USE_XSLT
|
#endif // USE_XSLT
|
||||||
|
|||||||
@@ -36,14 +36,14 @@ using namespace Designer::Internal;
|
|||||||
|
|
||||||
void SettingsManager::beginGroup(const QString &prefix)
|
void SettingsManager::beginGroup(const QString &prefix)
|
||||||
{
|
{
|
||||||
if (Designer::Constants::Internal::debug)
|
if (Designer::Constants::Internal::debug > 1)
|
||||||
qDebug() << Q_FUNC_INFO << addPrefix(prefix);
|
qDebug() << Q_FUNC_INFO << addPrefix(prefix);
|
||||||
m_settings.beginGroup(addPrefix(prefix));
|
m_settings.beginGroup(addPrefix(prefix));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsManager::endGroup()
|
void SettingsManager::endGroup()
|
||||||
{
|
{
|
||||||
if (Designer::Constants::Internal::debug)
|
if (Designer::Constants::Internal::debug > 1)
|
||||||
qDebug() << Q_FUNC_INFO;
|
qDebug() << Q_FUNC_INFO;
|
||||||
m_settings.endGroup();
|
m_settings.endGroup();
|
||||||
}
|
}
|
||||||
@@ -55,7 +55,7 @@ bool SettingsManager::contains(const QString &key) const
|
|||||||
|
|
||||||
void SettingsManager::setValue(const QString &key, const QVariant &value)
|
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;
|
qDebug() << Q_FUNC_INFO << addPrefix(key) << ": " << value;
|
||||||
m_settings.setValue(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 SettingsManager::value(const QString &key, const QVariant &defaultValue) const
|
||||||
{
|
{
|
||||||
QVariant result = m_settings.value(addPrefix(key), defaultValue);
|
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;
|
qDebug() << Q_FUNC_INFO << addPrefix(key) << ": " << result;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -125,6 +125,16 @@ static QList<Document::Ptr> findDocumentsIncluding(const CPlusPlus::Snapshot &do
|
|||||||
return docList;
|
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.
|
// 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
|
// So, haystack can be shorter (can have some namespaces omitted because of a
|
||||||
// "using namespace" declaration, for example, comparing
|
// "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(':');
|
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)
|
static const Class *findClass(const Namespace *parentNameSpace, const QString &className, QString *namespaceName)
|
||||||
{
|
{
|
||||||
if (Designer::Constants::Internal::debug)
|
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);
|
const Symbol *sym = parentNameSpace->memberAt(i);
|
||||||
// we have found a class - we are interested in classes only
|
// we have found a class - we are interested in classes only
|
||||||
if (const Class *cl = sym->asClass()) {
|
if (const Class *cl = sym->asClass()) {
|
||||||
|
// 1) we go through class members
|
||||||
const unsigned classMemberCount = cl->memberCount();
|
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()) {
|
if (const Declaration *decl = cl->memberAt(j)->asDeclaration()) {
|
||||||
// we want to know if the class contains a member (so we look into
|
// we want to know if the class contains a member (so we look into
|
||||||
// a declaration) of uiClassName type
|
// 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())))
|
if (nt && matchMemberClassName(className, o.prettyName(nt->name())))
|
||||||
return cl;
|
return cl;
|
||||||
} // decl
|
} // decl
|
||||||
|
// 2) does it inherit the desired class
|
||||||
|
if (inherits(o, cl, className))
|
||||||
|
return cl;
|
||||||
} else {
|
} else {
|
||||||
// Check namespaces
|
// Check namespaces
|
||||||
if (const Namespace *ns = sym->asNamespace()) {
|
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
|
// fun->column() returns always 0, what can cause trouble in case in one
|
||||||
// line if there is: "private slots: void foo();"
|
// line if there is: "private slots: void foo();"
|
||||||
if (fun->isSlot() && fun->isPrivate()) {
|
if (fun->isSlot() && fun->isPrivate()) {
|
||||||
if (ITextEditable *editable = editableAt(docFileName, fun->line(), fun->column()))
|
const int line = fun->line(); // [1..n]
|
||||||
editable->insert(declaration + QLatin1String(" "));
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -483,7 +506,7 @@ static ClassDocumentPtrPair
|
|||||||
unsigned maxIncludeDepth, QString *namespaceName)
|
unsigned maxIncludeDepth, QString *namespaceName)
|
||||||
{
|
{
|
||||||
if (Designer::Constants::Internal::debug)
|
if (Designer::Constants::Internal::debug)
|
||||||
qDebug() << Q_FUNC_INFO << doc->fileName() << maxIncludeDepth;
|
qDebug() << Q_FUNC_INFO << doc->fileName() << className << maxIncludeDepth;
|
||||||
// Check document
|
// Check document
|
||||||
if (const Class *cl = findClass(doc->globalNamespace(), className, namespaceName))
|
if (const Class *cl = findClass(doc->globalNamespace(), className, namespaceName))
|
||||||
return ClassDocumentPtrPair(cl, doc);
|
return ClassDocumentPtrPair(cl, doc);
|
||||||
@@ -523,6 +546,9 @@ static inline QString uiClassName(QString formObjectName)
|
|||||||
return 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,
|
bool WorkbenchIntegration::navigateToSlot(const QString &objectName,
|
||||||
const QString &signalSignature,
|
const QString &signalSignature,
|
||||||
const QStringList ¶meterNames,
|
const QStringList ¶meterNames,
|
||||||
@@ -538,7 +564,7 @@ bool WorkbenchIntegration::navigateToSlot(const QString &objectName,
|
|||||||
const QFileInfo fi(currentUiFile);
|
const QFileInfo fi(currentUiFile);
|
||||||
const QString uicedName = QLatin1String("ui_") + fi.baseName() + QLatin1String(".h");
|
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();
|
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
|
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)
|
if (Designer::Constants::Internal::debug)
|
||||||
qDebug() << Q_FUNC_INFO << objectName << signalSignature << "Looking for " << uicedName << " returned " << docList.size();
|
qDebug() << Q_FUNC_INFO << objectName << signalSignature << "Looking for " << uicedName << " returned " << docList.size();
|
||||||
if (docList.isEmpty()) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -557,8 +583,8 @@ bool WorkbenchIntegration::navigateToSlot(const QString &objectName,
|
|||||||
if (Designer::Constants::Internal::debug)
|
if (Designer::Constants::Internal::debug)
|
||||||
qDebug() << "Checking docs for " << uiClass;
|
qDebug() << "Checking docs for " << uiClass;
|
||||||
|
|
||||||
// Find the class definition in the file itself or in the directly
|
// Find the class definition (ui class defined as member or base class)
|
||||||
// included files (order 1).
|
// in the file itself or in the directly included files (order 1).
|
||||||
QString namespaceName;
|
QString namespaceName;
|
||||||
const Class *cl = 0;
|
const Class *cl = 0;
|
||||||
Document::Ptr doc;
|
Document::Ptr doc;
|
||||||
@@ -578,6 +604,8 @@ bool WorkbenchIntegration::navigateToSlot(const QString &objectName,
|
|||||||
|
|
||||||
Overview o;
|
Overview o;
|
||||||
const QString className = namespaceName + o.prettyName(cl->name());
|
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 functionName = QLatin1String("on_") + objectName + QLatin1Char('_') + signalSignature;
|
||||||
const QString functionNameWithParameterNames = addParameterNames(functionName, parameterNames);
|
const QString functionNameWithParameterNames = addParameterNames(functionName, parameterNames);
|
||||||
|
|||||||
Reference in New Issue
Block a user