diff --git a/dist/changes-2.0.0 b/dist/changes-2.0.0 index 1a9ab1cbbc9..eef365f6f90 100644 --- a/dist/changes-2.0.0 +++ b/dist/changes-2.0.0 @@ -36,6 +36,11 @@ Editing the syntax highlighting. * Block selection defines a find & replace scope * Added customizable default file encoding (in addition to the project setting) + * Added syntax highlighting for CMake project files + * Fixed .pro files being reformatted if files have been added or removed. + In addition, whitespace is preserved + * Fixed the file system sidebar to update automatically + * Fixed updating code completion for generated UI header files CodePaster * Implemented new protocol of pastebin.com including list functionality @@ -55,6 +60,9 @@ Project support * Allow changing the build environment for Generic Projects * Added context menu options to open file manager or terminal in a files directory + * Fixed the DEFINES and INCLUDES set in .pro files to be dealt with + on a file-specific level and enabled the handling of DEFINES. + Also, the .qmake.cache is now parsed Debugging * Add on-device debugging for the Symbian platform using gdb @@ -72,6 +80,10 @@ Debugging names * pdb: Added some basic debugging for Python scripts based on pdb * Improvements in the dialogs, status messages, and general appearance + * Fixed debugging helpers to work while debugging applications on devices + * On Linux and Windows, enabled installing Qt with one user account and + then using it with another without workarounds + * Fixed all data types to work in the Watch Window of CDB Help diff --git a/doc/images/qtcreator-gs-build-example-targets.png b/doc/images/qtcreator-gs-build-example-targets.png index c039bd03cc1..4e5fcce5393 100644 Binary files a/doc/images/qtcreator-gs-build-example-targets.png and b/doc/images/qtcreator-gs-build-example-targets.png differ diff --git a/doc/images/qtcreator-qt4-qtversions-win-symbian.png b/doc/images/qtcreator-qt4-qtversions-win-symbian.png index eaf9beaaa00..ccde01f4d05 100644 Binary files a/doc/images/qtcreator-qt4-qtversions-win-symbian.png and b/doc/images/qtcreator-qt4-qtversions-win-symbian.png differ diff --git a/doc/images/qtcreator-qt4-s60sdks.png b/doc/images/qtcreator-qt4-s60sdks.png index 71256929c23..c7f70c0cc6f 100644 Binary files a/doc/images/qtcreator-qt4-s60sdks.png and b/doc/images/qtcreator-qt4-s60sdks.png differ diff --git a/doc/qtcreator.qdoc b/doc/qtcreator.qdoc index e9359f6b1ed..687be168e25 100644 --- a/doc/qtcreator.qdoc +++ b/doc/qtcreator.qdoc @@ -1787,7 +1787,7 @@ \image qtcreator-qt4-qtversions-win-msvc.png \endlist - If you are using \bold{Qt for Symbian} and your S60 SDK is registered + If you are using \bold{Qt for Symbian} and your Symbian SDK is registered with devices.exe, Qt Creator automatically detects the Qt version. To add a Qt for Symbian version: \list 1 @@ -1804,7 +1804,7 @@ the \c{PATH} environment variable. \o To build an application for the emulator (WINSCW toolchain), enter the path to your Carbide C++ installation directory in - \gui{Carbide Directory}. + \gui{Carbide directory}. \note You need to have Carbide C++ version 2.0 or later installed. \endlist @@ -2142,7 +2142,7 @@ \list \o You selected the Symbian Device target for building the application. \o The settings for the Qt version you use to build your project are - correct. The path to the S60 SDK must point to the S60 SDK + correct. The path to the Symbian SDK must point to the Symbian SDK installation directory. Select \gui Tools > \gui Options... > \gui Debugger > \gui{Symbian TRK} and check if it points to the debugger toolchain. @@ -2697,12 +2697,12 @@ \o Click \inlineimage{qtcreator-run.png} - to build the application for Qt Simulator. + to build the application and run it in Qt Simulator. \o To see the compilation progress, press \key{Alt+4} to open the \gui Compile Output pane. - The gui Build progress bar on the toolbar turns green when the project + The \gui Build progress bar on the toolbar turns green when the project is successfully built. The application opens in Qt Simulator. \image {qt-simulator.png} "Qt Simulator" @@ -5025,7 +5025,7 @@ specified in the \c CMake project file. Known issues for the current version can be found - \l{Known Issues of version 2.0.80}{here}. + \l{Known Issues}{here}. \section1 Adding External Libraries to a CMake Project @@ -5782,6 +5782,32 @@ \image qtcreator-mad-developer-screenshot.png \endlist + \section1 Installing Qt Mobility APIs + + To develop applications that use the Qt Mobility APIs, you must install the + APIs on the devices. The APIs are not available in the Nokia N900 package + manager, and therefore, you must install them from the command line as the + root user. To become the root user you must first install \c rootsh from the + application manager. + + \list 1 + + \o On the device, install \c rootsh from the \gui {Application Manager}. + + \o In \gui Programs, select \c {X Terminal} to open a terminal window. + + \o To switch to the root user, enter the following command: + \c{sudo gainroot} + + \o To install Qt Mobility libraries, enter the following command: + \c{apt-get install libqtm-*} + + \o To confirm the installation, enter: \c Y + + \o Close the terminal. + + \endlist + \section1 Setting Up Network Connectivity on Development PC Use the network configuration tools on your platform to specify the @@ -5879,6 +5905,13 @@ necessary software is installed and configured automatically and you only need to configure a connection to the device. + By default, you create the connection as the \e developer user. This + protects real user data on the device from getting corrupted during + testing. If you write applications that use Mobility APIs, you might want + to test them with real user data. To create a connection as a user, specify + the \gui Username and \gui Password in Qt Creator. For more information, see + \l{Testing with User Data}. + You can protect the connections between Qt Creator and the Maemo emulator or a device by using either a password or an SSH key. You must always use a password for the initial connection, but can then deploy an SSH @@ -6000,6 +6033,30 @@ \endlist + \section2 Testing with User Data + + To run your application as the default user, you must first assign a password + for the user account and then create the connection to the device as the + user: + + \list 1 + + \o On the device, in \gui Programs, select \c {X Terminal} to open a + terminal window. + + \o To switch to the root user, enter the following command: + \c{sudo gainroot} + + \o To specify the password, enter the following command: + \c {passwd user} + + \o In Qt Creator, Select \gui Tools > \gui Options... > \gui Projects > + \gui{Maemo Device Configurations}. + + \o Specify the username \c user and the password in the device configuration. + + \endlist + \section2 Generating SSH Keys If you do not have an SSH public and private key pair, you can generate it @@ -6186,7 +6243,9 @@ \o The \l{http://tools.ext.nokia.com/trk/}{App TRK} application for your device \o The \e{qt_installer.sis} package installed on the device, that is - delivered with the Qt SDK. + delivered with the Qt SDK + \o \e {Qt Mobility APIs} installed on the device, if you use them in + applications \endlist To run your applications in the Symbian emulator, you also need @@ -6221,6 +6280,10 @@ \endlist + \note If errors occur during the installation, copy the .sis files from + \c {\Symbian\sis} to the device using USB storage + mode. Then install them from the file manager on the device. + \section1 Adding Symbian Platform SDKs Nokia Qt SDK contains all the tools you need for developing Qt applications for @@ -6230,33 +6293,33 @@ \list \o \l{http://www.forum.nokia.com/main/resources/tools_and_sdks/S60SDK/} {S60 Platform SDK 3rd Edition FP1 or higher}. - \o Either the GCCE ARM Toolchain that is included in the S60 Platform + \o Either the GCCE ARM Toolchain that is included in the Symbian SDKs, or RVCT 2.2 [build 686] or later (which is not available free of charge)(Your environment needs to find the compiler in the PATH). - \o Qt for Symbian 4.6.2 or later, installed into the S60 SDKs you want + \o Qt for Symbian 4.6.2 or later, installed into the Symbian SDKs you want to use. \endlist \section2 Setting Up Qt Creator - When you run Qt Creator after installing the S60 Platform SDK and Qt for + When you run Qt Creator after installing the Symbian SDK and Qt for Symbian, the installed SDKs and their corresponding Qt versions are - automatically detected. For each detected S60 SDK with Qt, a special entry + automatically detected. For each detected Symbian SDK with Qt, a special entry is made in the Qt version management settings in \gui{Tools} > \gui{Options...} > \gui{Qt4} > \gui{Qt Versions}. \note If you manually add a Qt version for Symbian, you must - also manually specify the S60 SDK to use for this version. + also manually specify the Symbian SDK to use for this version. \image qtcreator-qt4-qtversions-win-symbian.png If you want to run your applications in the Symbian emulator, you need to point Qt Creator to the Metrowerks Compiler that you want to use, by - setting the \gui{Carbide Directory} of the Qt version to the corresponding + setting the \gui{Carbide directory} of the Qt version to the corresponding Carbide.c++ installation directory. - You can check what S60 SDKs and corresponding Qt versions are found in the + You can check which Symbian SDKs and corresponding Qt versions are found in the \gui{Tools} > \gui{Options...} > \gui{Qt4} > \gui{S60 SDKs} preference page. @@ -7100,41 +7163,16 @@ \title Known Issues - There are some known issues with Qt Creator. - The development team is aware of them, there is no need to report them as bugs. + This section lists known issues in Qt Creator version 2.0.0. + The development team is aware of them, and therefore, you do not need to + report them as bugs. - \section1 Known Issues of Version 2.0.80 + For a list of fixed issues and added features, see the changelog file in + the qtcreator\dist folder or the \l{http://bugreports.qt.nokia.com}{Qt Bug Tracker}. + + \section1 General \list - \o On Windows, debugging a MinGW-built console application (with \gui{Run in terminal} - checked) using gdb does not work due to a bug in gdb related to attaching to - stopped processes (see \l{http://bugreports.qt.nokia.com/browse/QTCREATORBUG-1020}). - - \o Debugging Helper does not work while performing On-Device Debugging. - - \o QML Preview (Run Project) only works if built against Qt with - Declarative UI. - - \o Setting breakpoints in code that is compiled into the binary more - than once does not work. - - \o On Linux and Windows, installing Qt with one user account and - then using it with another requires other users to manually set - the Qt version. On Windows, setting the MinGW location is - required as well. The same applies to the location of GDB for Symbian. - A workaround is to copy %APPDATA%/Nokia/qtcreator.ini (Windows) or - $HOME/.config/Nokia/QtCreator.ini (Linux) from the directory - of the user who installed Qt Creator to the other user. - This issue does not exist on Mac OS X. - \endlist - - \section1 Known Issues of Version 1.2.0 and 1.2.1 - - \list - \o Gdb on Windows may not work if the 'Embassy \reg Security Center' software - by 'Wave \reg Systems' is installed and active (causing crashes in \c{vxvault.dll)}). - - \o Only simple data types (POD) work in the Watch Window of CDB. \o Qt Creator uses SQLite for storing some of its settings. SQLite is known to have problems with certain NFS servers (most notably the @@ -7143,9 +7181,18 @@ NFS share and you encounter this issue, one option would be to switch to the nfs-kernel-server, or create a symlink so that the settings are stored locally. + \endlist - \section1 Known Issues of Version 1.1.0 + \section1 Editing + + \list + + \o Code completion does not support typedefs for nested classes. + + \endlist + + \section1 Projects \list \o Paths or file names containing spaces or special characters, e.g., @@ -7156,59 +7203,39 @@ items with names consisting of plain characters, numbers, underscores, and hyphens. - \o \c{.pro} files are reformatted if files have been added or removed. - Whitespace is not preserved. - - \o There is no IDE support for adding files to include (\c .pri) files. - \o There is no IDE support for adding/removing sub-projects. Project hierarchies (SUBDIRS template) have to be created manually. - \o The file system sidebar does not update automatically. As a - workaround, switch to another directory and then back. + \o Creating new \c CMake projects with Qt Creator is not supported. - \o Loading KDE4 designer plugins breaks the style in KDE < 4.2.1 - due to a bug in KDE. + \endlist - \o The DEFINES and INCLUDES set in \c{.pro} files are not dealt with - on a file-specific level. Because of this, handling of DEFINES has - been disabled completely. Also the \c{.qmake.cache} is not being - parsed. In general, the \c{.pro} file parser is incomplete and - problems are still to be expected. + \section1 Debugging - \o Code completion for generated UI header files is updated only - after a build. + \list - \o Code completion does not support typedefs for nested classes. + \o When debugging executables created by the GNU Compiler version 4.5.0 + (all platforms), some data types will not be displayed in the + \gui{Locals and Watchers} view due to missing debug information. - \o There is a kernel bug essentially making debugging unreliable on - 2.6.24 kernels for i386 (which is, unfortunately, the default on - Ubuntu 8.04). See - \l{https://bugs.launchpad.net/ubuntu/+source/gdb/+bug/230315/} for - details. The only solution to this problem is to boot another - kernel. + \o On Windows, debugging a MinGW-built console application (with \gui{Run in terminal} + checked) using gdb does not work due to a bug in gdb related to attaching to + stopped processes (see \l{http://bugreports.qt.nokia.com/browse/QTCREATORBUG-1020}). + + \o Gdb on Windows may not work if the 'Embassy \reg Security Center' software + by 'Wave \reg Systems' is installed and active (causing crashes in \c{vxvault.dll)}). \o Gdb may take long to load debugging symbols, especially from large libraries like \c libQtWebKit. Starting the debugging module can take up to several minutes without visible progress. + \o Setting breakpoints in code that is compiled into the binary more + than once does not work. + \o Setting breakpoints in files that do not have unique absolute paths may fail. For example, remounting parts of a file system using the --bind mount option. - \o There is no syntax highlighting for \c CMake project files. - - \o Project files included from \c{CMakeLists.txt} are not shown in the - navigation tree. - - \o Using the Visual Studio Compiler with \c CMake is not supported. - - \o Creating new \c CMake projects with Qt Creator is not supported. - - \o Having more than one build directory for \c CMake is not supported. - - \o Changing the build directory for \c CMake after the initial import - is disabled. \endlist */ diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp index b69b5d4c833..d83c78166bf 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp @@ -62,7 +62,6 @@ CMakeBuildConfiguration::CMakeBuildConfiguration(CMakeTarget *parent, CMakeBuild m_msvcVersion(source->m_msvcVersion) { cloneSteps(source); - m_buildDirectory = cmakeTarget()->defaultBuildDirectory(); } QVariantMap CMakeBuildConfiguration::toMap() const diff --git a/src/plugins/coreplugin/coreimpl.cpp b/src/plugins/coreplugin/coreimpl.cpp index d072e8df091..99d76f35395 100644 --- a/src/plugins/coreplugin/coreimpl.cpp +++ b/src/plugins/coreplugin/coreimpl.cpp @@ -144,6 +144,11 @@ MimeDatabase *CoreImpl::mimeDatabase() const return m_mainwindow->mimeDatabase(); } +HelpManager *CoreImpl::helpManager() const +{ + return m_mainwindow->helpManager(); +} + QSettings *CoreImpl::settings(QSettings::Scope scope) const { return m_mainwindow->settings(scope); diff --git a/src/plugins/coreplugin/coreimpl.h b/src/plugins/coreplugin/coreimpl.h index 50a8a673fbd..efd971f3b6b 100644 --- a/src/plugins/coreplugin/coreimpl.h +++ b/src/plugins/coreplugin/coreimpl.h @@ -67,6 +67,7 @@ public: VCSManager *vcsManager() const; ModeManager *modeManager() const; MimeDatabase *mimeDatabase() const; + HelpManager *helpManager() const; QSettings *settings(QSettings::Scope scope = QSettings::UserScope) const; SettingsDatabase *settingsDatabase() const; diff --git a/src/plugins/coreplugin/coreplugin.pro b/src/plugins/coreplugin/coreplugin.pro index d5b30647137..3b607d037b6 100644 --- a/src/plugins/coreplugin/coreplugin.pro +++ b/src/plugins/coreplugin/coreplugin.pro @@ -6,6 +6,7 @@ QT += xml \ script \ svg \ sql +CONFIG += help include(../../qtcreatorplugin.pri) include(../../libs/utils/utils.pri) include(../../shared/scriptwrapper/scriptwrapper.pri) @@ -86,7 +87,8 @@ SOURCES += mainwindow.cpp \ editortoolbar.cpp \ ssh/ne7sshobject.cpp \ ssh/sshconnection.cpp \ - ssh/sshkeygenerator.cpp + ssh/sshkeygenerator.cpp \ + helpmanager.cpp HEADERS += mainwindow.h \ editmode.h \ @@ -171,7 +173,8 @@ HEADERS += mainwindow.h \ editortoolbar.h \ ssh/ne7sshobject.h \ ssh/sshconnection.h \ - ssh/sshkeygenerator.h + ssh/sshkeygenerator.h \ + helpmanager.h FORMS += dialogs/newdialog.ui \ actionmanager/commandmappings.ui \ diff --git a/src/plugins/coreplugin/helpmanager.cpp b/src/plugins/coreplugin/helpmanager.cpp new file mode 100644 index 00000000000..85cf89a1a51 --- /dev/null +++ b/src/plugins/coreplugin/helpmanager.cpp @@ -0,0 +1,321 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "helpmanager.h" + +#include "icore.h" + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +namespace Core { + +HelpManager *HelpManager::m_instance = 0; + +static const char linksForKeyQuery[] = "SELECT d.Title, f.Name, e.Name, " + "d.Name, a.Anchor FROM IndexTable a, FileNameTable d, FolderTable e, " + "NamespaceTable f WHERE a.FileId=d.FileId AND d.FolderId=e.Id AND " + "a.NamespaceId=f.Id AND a.Name='%1'"; + +// -- DbCleaner + +struct DbCleaner { + DbCleaner(const QString &dbName) + : name(dbName) {} + ~DbCleaner() { + QSqlDatabase::removeDatabase(name); + } + QString name; +}; + +// -- HelpManager + +HelpManager::HelpManager(QObject *parent) + : QObject(parent) + , m_needsSetup(true) + , m_helpEngine(0) +{ + Q_ASSERT(!m_instance); + m_instance = this; + + connect(Core::ICore::instance(), SIGNAL(coreOpened()), this, + SLOT(setupHelpManager())); +} + +HelpManager::~HelpManager() +{ + delete m_helpEngine; + m_helpEngine = 0; + + m_instance = 0; +} + +HelpManager* HelpManager::instance() +{ + Q_ASSERT(m_instance); + return m_instance; +} + +QString HelpManager::collectionFilePath() +{ + const QFileInfo fi(Core::ICore::instance()->settings()->fileName()); + const QDir directory(fi.absolutePath() + QLatin1String("/qtcreator")); + if (!directory.exists()) + directory.mkpath(directory.absolutePath()); + return QDir::cleanPath(directory.absolutePath() + QLatin1String("/helpcollection.qhc")); +} + +void HelpManager::registerDocumentation(const QStringList &files) +{ + if (m_needsSetup) { + m_filesToRegister.append(files); + return; + } + + bool docsChanged = false; + foreach (const QString &file, files) { + const QString &nameSpace = m_helpEngine->namespaceName(file); + if (nameSpace.isEmpty()) + continue; + if (!m_helpEngine->registeredDocumentations().contains(nameSpace)) { + if (m_helpEngine->registerDocumentation(file)) { + docsChanged = true; + } else { + qWarning() << "Error registering namespace '" << nameSpace + << "' from file '" << file << "':" << m_helpEngine->error(); + } + } + } + if (docsChanged) + emit documentationChanged(); +} + +void HelpManager::unregisterDocumentation(const QStringList &nameSpaces) +{ + if (m_needsSetup) { + m_nameSpacesToUnregister.append(nameSpaces); + return; + } + + bool docsChanged = false; + foreach (const QString &nameSpace, nameSpaces) { + if (m_helpEngine->unregisterDocumentation(nameSpace)) { + docsChanged = true; + } else { + qWarning() << "Error unregistering namespace '" << nameSpace + << "' from file '" << m_helpEngine->documentationFileName(nameSpace) + << "': " << m_helpEngine->error(); + } + } + if (docsChanged) + emit documentationChanged(); +} + +QUrl buildQUrl(const QString &nameSpace, const QString &folder, + const QString &relFileName, const QString &anchor) +{ + QUrl url; + url.setScheme(QLatin1String("qthelp")); + url.setAuthority(nameSpace); + url.setPath(folder + QLatin1Char('/') + relFileName); + url.setFragment(anchor); + return url; +} + +// This should go into Qt 4.8 once we start using it for Qt Creator +QMap HelpManager::linksForKeyword(const QString &key) const +{ + QMap links; + if (m_needsSetup) + return links; + + const QLatin1String sqlite("QSQLITE"); + const QLatin1String name("HelpManager::linksForKeyword"); + + DbCleaner cleaner(name); + QSqlDatabase db = QSqlDatabase::addDatabase(sqlite, name); + if (db.driver() && db.driver()->lastError().type() == QSqlError::NoError) { + const QStringList ®isteredDocs = m_helpEngine->registeredDocumentations(); + foreach (const QString &nameSpace, registeredDocs) { + db.setDatabaseName(m_helpEngine->documentationFileName(nameSpace)); + if (db.open()) { + QSqlQuery query = QSqlQuery(db); + query.setForwardOnly(true); + query.exec(QString::fromLatin1(linksForKeyQuery).arg(key)); + while (query.next()) { + QString title = query.value(0).toString(); + if (title.isEmpty()) // generate a title + corresponding path + title = key + QLatin1String(" : ") + query.value(3).toString(); + links.insertMulti(title, buildQUrl(query.value(1).toString(), + query.value(2).toString(), query.value(3).toString(), + query.value(4).toString())); + } + } + } + } + return links; +} + +QMap HelpManager::linksForIdentifier(const QString &id) const +{ + if (m_needsSetup) + return QMap(); + return m_helpEngine->linksForIdentifier(id); +} + +// This should go into Qt 4.8 once we start using it for Qt Creator +QStringList HelpManager::findKeywords(const QString &key, int maxHits) const +{ + QStringList keywords; + if (m_needsSetup) + return keywords; + + const QLatin1String sqlite("QSQLITE"); + const QLatin1String name("HelpManager::findKeywords"); + + DbCleaner cleaner(name); + QSqlDatabase db = QSqlDatabase::addDatabase(sqlite, name); + if (db.driver() && db.driver()->lastError().type() == QSqlError::NoError) { + const QStringList ®isteredDocs = m_helpEngine->registeredDocumentations(); + foreach (const QString &nameSpace, registeredDocs) { + db.setDatabaseName(m_helpEngine->documentationFileName(nameSpace)); + if (db.open()) { + QSqlQuery query = QSqlQuery(db); + query.setForwardOnly(true); + query.exec(QString::fromLatin1("SELECT DISTINCT Name FROM " + "IndexTable WHERE Name LIKE '%%1%'").arg(key)); + while (query.next()) { + const QString &key = query.value(0).toString(); + if (!key.isEmpty()) { + keywords.append(key); + if (keywords.count() == maxHits) + return keywords; + } + } + } + } + } + return keywords; +} + +QUrl HelpManager::findFile(const QUrl &url) const +{ + if (m_needsSetup) + return QUrl(); + return m_helpEngine->findFile(url); +} + +void HelpManager::handleHelpRequest(const QString &url) +{ + emit helpRequested(QUrl(url)); +} + +QStringList HelpManager::registeredNamespaces() const +{ + if (m_needsSetup) + return QStringList(); + return m_helpEngine->registeredDocumentations(); +} + +QString HelpManager::namespaceFromFile(const QString &file) const +{ + if (m_needsSetup) + return QString(); + return m_helpEngine->namespaceName(file); +} + +QString HelpManager::fileFromNamespace(const QString &nameSpace) const +{ + if (m_needsSetup) + return QString(); + return m_helpEngine->documentationFileName(nameSpace); +} + +// -- private slots + +void HelpManager::setupHelpManager() +{ + if (!m_needsSetup) + return; + m_needsSetup = false; + + m_helpEngine = new QHelpEngineCore(collectionFilePath(), this); + m_helpEngine->setAutoSaveFilter(false); + m_helpEngine->setCurrentFilter(tr("Unfiltered")); + m_helpEngine->setupData(); + + verifyDocumenation(); + + if (!m_nameSpacesToUnregister.isEmpty()) { + unregisterDocumentation(m_nameSpacesToUnregister); + m_nameSpacesToUnregister.clear(); + } + + // this might come from the installer + const QLatin1String key("AddedDocs"); + const QString &addedDocs = m_helpEngine->customValue(key).toString(); + if (!addedDocs.isEmpty()) { + m_helpEngine->removeCustomValue(key); + m_filesToRegister += addedDocs.split(QLatin1Char(';')); + } + + if (!m_filesToRegister.isEmpty()) { + registerDocumentation(m_filesToRegister); + m_filesToRegister.clear(); + } + + emit setupFinished(); +} + +// -- private + +void HelpManager::verifyDocumenation() +{ + QStringList nameSpacesToUnregister; + const QStringList ®isteredDocs = m_helpEngine->registeredDocumentations(); + foreach (const QString &nameSpace, registeredDocs) { + const QString &file = m_helpEngine->documentationFileName(nameSpace); + if (!QFileInfo(file).exists()) + nameSpacesToUnregister.append(nameSpace); + } + + if (!nameSpacesToUnregister.isEmpty()) + unregisterDocumentation(nameSpacesToUnregister); +} + +} // Core diff --git a/src/plugins/coreplugin/helpmanager.h b/src/plugins/coreplugin/helpmanager.h new file mode 100644 index 00000000000..7df6c55659c --- /dev/null +++ b/src/plugins/coreplugin/helpmanager.h @@ -0,0 +1,96 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef HELPMANAGER_H +#define HELPMANAGER_H + +#include "core_global.h" + +#include +#include +#include +#include +#include +#include + +QT_FORWARD_DECLARE_CLASS(QHelpEngineCore) +QT_FORWARD_DECLARE_CLASS(QSqlQuery) + +namespace Core { + +class CORE_EXPORT HelpManager : public QObject +{ + Q_OBJECT + Q_DISABLE_COPY(HelpManager) + +public: + explicit HelpManager(QObject *parent = 0); + virtual ~HelpManager(); + + static HelpManager* instance(); + static QString collectionFilePath(); + + void registerDocumentation(const QStringList &fileNames); + void unregisterDocumentation(const QStringList &nameSpaces); + + QMap linksForKeyword(const QString &key) const; + QMap linksForIdentifier(const QString &id) const; + QStringList findKeywords(const QString &key, int maxHits = INT_MAX) const; + + QUrl findFile(const QUrl &url) const; + void handleHelpRequest(const QString &url); + + QStringList registeredNamespaces() const; + QString namespaceFromFile(const QString &file) const; + QString fileFromNamespace(const QString &nameSpace) const; + +signals: + void setupFinished(); + void documentationChanged(); + void helpRequested(const QUrl &url); + +private slots: + void setupHelpManager(); + +private: + void verifyDocumenation(); + +private: + bool m_needsSetup; + QHelpEngineCore *m_helpEngine; + + QStringList m_filesToRegister; + QStringList m_nameSpacesToUnregister; + + static HelpManager *m_instance; +}; + +} // Core + +#endif // HELPMANAGER_H diff --git a/src/plugins/coreplugin/icore.h b/src/plugins/coreplugin/icore.h index cae3da1b4d9..4eb3c897186 100644 --- a/src/plugins/coreplugin/icore.h +++ b/src/plugins/coreplugin/icore.h @@ -50,6 +50,7 @@ namespace Core { class ActionManager; class EditorManager; class FileManager; +class HelpManager; class IContext; class MessageManager; class MimeDatabase; @@ -96,6 +97,7 @@ public: virtual VCSManager *vcsManager() const = 0; virtual ModeManager *modeManager() const = 0; virtual MimeDatabase *mimeDatabase() const = 0; + virtual HelpManager *helpManager() const = 0; virtual QSettings *settings(QSettings::Scope scope = QSettings::UserScope) const = 0; virtual SettingsDatabase *settingsDatabase() const = 0; diff --git a/src/plugins/coreplugin/mainwindow.cpp b/src/plugins/coreplugin/mainwindow.cpp index b4410acee84..4f8703fb067 100644 --- a/src/plugins/coreplugin/mainwindow.cpp +++ b/src/plugins/coreplugin/mainwindow.cpp @@ -37,6 +37,7 @@ #include "fancytabwidget.h" #include "filemanager.h" #include "generalsettings.h" +#include "helpmanager.h" #include "ifilefactory.h" #include "messagemanager.h" #include "modemanager.h" @@ -132,6 +133,7 @@ MainWindow::MainWindow() : m_statusBarManager(0), m_modeManager(0), m_mimeDatabase(new MimeDatabase), + m_helpManager(new HelpManager), m_navigationWidget(0), m_rightPaneWidget(0), m_versionDialog(0), @@ -288,6 +290,9 @@ MainWindow::~MainWindow() m_modeManager = 0; delete m_mimeDatabase; m_mimeDatabase = 0; + + delete m_helpManager; + m_helpManager = 0; } bool MainWindow::init(QString *errorMessage) @@ -1021,6 +1026,11 @@ MimeDatabase *MainWindow::mimeDatabase() const return m_mimeDatabase; } +HelpManager *MainWindow::helpManager() const +{ + return m_helpManager; +} + IContext *MainWindow::contextObject(QWidget *widget) { return m_contextWidgets.value(widget); @@ -1078,8 +1088,8 @@ void MainWindow::updateFocusWidget(QWidget *old, QWidget *now) { Q_UNUSED(old) - // Prevent changing the context object just because the menu is activated - if (qobject_cast(now)) + // Prevent changing the context object just because the menu or a menu item is activated + if (qobject_cast(now) || qobject_cast(now)) return; IContext *newContext = 0; diff --git a/src/plugins/coreplugin/mainwindow.h b/src/plugins/coreplugin/mainwindow.h index 60b911ba1d1..3b890439b01 100644 --- a/src/plugins/coreplugin/mainwindow.h +++ b/src/plugins/coreplugin/mainwindow.h @@ -52,6 +52,7 @@ class ActionManager; class StatusBarWidget; class EditorManager; class FileManager; +class HelpManager; class IContext; class IWizard; class MessageManager; @@ -107,6 +108,7 @@ public: Core::VariableManager *variableManager() const; Core::ModeManager *modeManager() const; Core::MimeDatabase *mimeDatabase() const; + Core::HelpManager *helpManager() const; VCSManager *vcsManager() const; QSettings *settings(QSettings::Scope scope) const; @@ -193,6 +195,7 @@ private: StatusBarManager *m_statusBarManager; ModeManager *m_modeManager; MimeDatabase *m_mimeDatabase; + HelpManager *m_helpManager; FancyTabWidget *m_modeStack; NavigationWidget *m_navigationWidget; RightPaneWidget *m_rightPaneWidget; diff --git a/src/plugins/cppeditor/cppeditor.pro b/src/plugins/cppeditor/cppeditor.pro index 13f532e57a6..e9f4f0d0f4d 100644 --- a/src/plugins/cppeditor/cppeditor.pro +++ b/src/plugins/cppeditor/cppeditor.pro @@ -1,7 +1,6 @@ TEMPLATE = lib TARGET = CppEditor DEFINES += CPPEDITOR_LIBRARY -CONFIG += help include(../../qtcreatorplugin.pri) include(../../libs/utils/utils.pri) include(../../shared/indenter/indenter.pri) diff --git a/src/plugins/cppeditor/cpphoverhandler.cpp b/src/plugins/cppeditor/cpphoverhandler.cpp index 2f7bd051790..bfc03815001 100644 --- a/src/plugins/cppeditor/cpphoverhandler.cpp +++ b/src/plugins/cppeditor/cpphoverhandler.cpp @@ -32,6 +32,7 @@ #include "cppplugin.h" #include +#include #include #include #include @@ -60,7 +61,6 @@ #include #include #include -#include using namespace CppEditor::Internal; using namespace CPlusPlus; @@ -68,27 +68,11 @@ using namespace Core; CppHoverHandler::CppHoverHandler(QObject *parent) : QObject(parent) - , m_helpEngineNeedsSetup(false) { m_modelManager = ExtensionSystem::PluginManager::instance()->getObject(); - ICore *core = ICore::instance(); - QFileInfo fi(core->settings()->fileName()); - // FIXME shouldn't the help engine create the directory if it doesn't exist? - QDir directory(fi.absolutePath()+"/qtcreator"); - if (!directory.exists()) - directory.mkpath(directory.absolutePath()); - - m_helpEngine = new QHelpEngineCore(directory.absolutePath() - + QLatin1String("/helpcollection.qhc"), this); - if (!m_helpEngine->setupData()) - qWarning() << "Could not initialize help engine:" << m_helpEngine->error(); - m_helpEngine->setAutoSaveFilter(false); - m_helpEngine->setCurrentFilter(tr("Unfiltered")); - m_helpEngineNeedsSetup = m_helpEngine->registeredDocumentations().count() == 0; - // Listen for editor opened events in order to connect to tooltip/helpid requests - connect(core->editorManager(), SIGNAL(editorOpened(Core::IEditor *)), + connect(ICore::instance()->editorManager(), SIGNAL(editorOpened(Core::IEditor *)), this, SLOT(editorOpened(Core::IEditor *))); } @@ -221,19 +205,13 @@ void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, in } } - if (m_helpEngineNeedsSetup - && m_helpEngine->registeredDocumentations().count() > 0) { - m_helpEngine->setupData(); - m_helpEngineNeedsSetup = false; - } QMap helpLinks; - if (m_toolTip.isEmpty()) { foreach (const Document::Include &incl, doc->includes()) { if (incl.line() == lineNumber) { m_toolTip = QDir::toNativeSeparators(incl.fileName()); m_helpId = QFileInfo(incl.fileName()).fileName(); - helpLinks = m_helpEngine->linksForIdentifier(m_helpId); + helpLinks = Core::HelpManager::instance()->linksForIdentifier(m_helpId); break; } } @@ -309,7 +287,7 @@ void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, in // To show their help anyway, try stripping scopes until we find something. const QString startHelpId = m_helpId; while (!m_helpId.isEmpty()) { - helpLinks = m_helpEngine->linksForIdentifier(m_helpId); + helpLinks = Core::HelpManager::instance()->linksForIdentifier(m_helpId); if (!helpLinks.isEmpty()) break; diff --git a/src/plugins/cppeditor/cpphoverhandler.h b/src/plugins/cppeditor/cpphoverhandler.h index d0f5b11dc5d..311b8292236 100644 --- a/src/plugins/cppeditor/cpphoverhandler.h +++ b/src/plugins/cppeditor/cpphoverhandler.h @@ -33,7 +33,6 @@ #include QT_BEGIN_NAMESPACE -class QHelpEngineCore; class QPoint; QT_END_NAMESPACE @@ -70,10 +69,8 @@ private: void updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, int pos); CppTools::CppModelManagerInterface *m_modelManager; - QHelpEngineCore *m_helpEngine; QString m_helpId; QString m_toolTip; - bool m_helpEngineNeedsSetup; }; } // namespace Internal diff --git a/src/plugins/debugger/debuggeractions.cpp b/src/plugins/debugger/debuggeractions.cpp index 7a8d7a3c485..ba95f5f380e 100644 --- a/src/plugins/debugger/debuggeractions.cpp +++ b/src/plugins/debugger/debuggeractions.cpp @@ -227,6 +227,7 @@ DebuggerSettings *DebuggerSettings::instance() "operation mode. In this mode, stepping operates on single " "instructions and the source location view also shows the " "disassembled instructions.")); + item->setIconVisibleInMenu(false); instance->insertItem(OperateByInstruction, item); item = new SavedAction(instance); diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp index 2090d46c89e..65442aac131 100644 --- a/src/plugins/debugger/debuggermanager.cpp +++ b/src/plugins/debugger/debuggermanager.cpp @@ -566,6 +566,7 @@ void DebuggerManager::init() d->m_actions.reverseDirectionAction->setChecked(false); d->m_actions.reverseDirectionAction->setIcon( QIcon(":/debugger/images/debugger_reversemode_16.png")); + d->m_actions.reverseDirectionAction->setIconVisibleInMenu(false); d->m_actions.frameDownAction = new QAction(tr("Move to Called Frame"), this); diff --git a/src/plugins/debugger/gdb/classicgdbengine.cpp b/src/plugins/debugger/gdb/classicgdbengine.cpp index e59c0cfa2f6..daf61213030 100644 --- a/src/plugins/debugger/gdb/classicgdbengine.cpp +++ b/src/plugins/debugger/gdb/classicgdbengine.cpp @@ -852,7 +852,7 @@ void GdbEngine::handleVarListChildrenHelperClassic(const GdbMi &item, data.type = tr(""); } else { // A structure. Hope there's nothing else... - data.exp = parent.exp + '.' + data.name.toLatin1(); + data.exp = '(' + parent.exp + ")." + data.name.toLatin1(); } if (hasDebuggingHelperForType(data.type)) { diff --git a/src/plugins/designer/formeditorw.cpp b/src/plugins/designer/formeditorw.cpp index 7ac31008452..54779835b5a 100644 --- a/src/plugins/designer/formeditorw.cpp +++ b/src/plugins/designer/formeditorw.cpp @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -282,14 +283,8 @@ void FormEditorW::fullInit() m_integration = new QtCreatorIntegration(m_formeditor, this); m_formeditor->setIntegration(m_integration); // Connect Qt Designer help request to HelpManager. - // TODO: Use Core::HelpManager once it has been introduced. - foreach(QObject *object, ExtensionSystem::PluginManager::instance()->allObjects()) { - if (!qstrcmp(object->metaObject()->className(), "Help::HelpManager")) { - connect(m_integration, SIGNAL(creatorHelpRequested(QString)), - object, SLOT(handleHelpRequest(QString))); - break; - } - } + connect(m_integration, SIGNAL(creatorHelpRequested(QUrl)), + Core::HelpManager::instance(), SIGNAL(helpRequested(QUrl))); /** * This will initialize our TabOrder, Signals and slots and Buddy editors. diff --git a/src/plugins/designer/qtcreatorintegration.cpp b/src/plugins/designer/qtcreatorintegration.cpp index 18f5b19916e..25014480dc2 100644 --- a/src/plugins/designer/qtcreatorintegration.cpp +++ b/src/plugins/designer/qtcreatorintegration.cpp @@ -61,6 +61,7 @@ #include #include +#include enum { indentation = 4 }; @@ -101,7 +102,8 @@ QtCreatorIntegration::QtCreatorIntegration(QDesignerFormEditorInterface *core, F void QtCreatorIntegration::slotDesignerHelpRequested(const QString &manual, const QString &document) { // Pass on as URL. - emit creatorHelpRequested(QString::fromLatin1("qthelp://com.trolltech.%1/qdoc/%2").arg(manual, document)); + emit creatorHelpRequested(QUrl(QString::fromLatin1("qthelp://com.trolltech.%1/qdoc/%2") + .arg(manual, document))); } void QtCreatorIntegration::updateSelection() diff --git a/src/plugins/designer/qtcreatorintegration.h b/src/plugins/designer/qtcreatorintegration.h index c667ea8504d..a246a283c3c 100644 --- a/src/plugins/designer/qtcreatorintegration.h +++ b/src/plugins/designer/qtcreatorintegration.h @@ -34,6 +34,8 @@ #include "qt_private/qdesigner_integration_p.h" +QT_FORWARD_DECLARE_CLASS(QUrl) + namespace Designer { namespace Internal { @@ -49,7 +51,7 @@ public: bool supportsToSlotNavigation() { return true; } signals: - void creatorHelpRequested(const QString &url); + void creatorHelpRequested(const QUrl &url); public slots: void updateSelection(); diff --git a/src/plugins/help/centralwidget.cpp b/src/plugins/help/centralwidget.cpp index 22215f3100f..57e8a281f7c 100644 --- a/src/plugins/help/centralwidget.cpp +++ b/src/plugins/help/centralwidget.cpp @@ -45,7 +45,6 @@ #include #include -#include #include using namespace Help::Internal; @@ -85,7 +84,7 @@ CentralWidget::~CentralWidget() } } - QHelpEngineCore *engine = &HelpManager::helpEngineCore(); + QHelpEngineCore *engine = &LocalHelpManager::helpEngine(); engine->setCustomValue(QLatin1String("LastShownPages"), currentPages); engine->setCustomValue(QLatin1String("LastShownPagesZoom"), zoomFactors); engine->setCustomValue(QLatin1String("LastTabPage"), currentIndex()); @@ -313,7 +312,7 @@ void CentralWidget::highlightSearchTerms() { if (HelpViewer *viewer = currentHelpViewer()) { QHelpSearchEngine *searchEngine = - HelpManager::instance().helpEngine().searchEngine(); + LocalHelpManager::helpEngine().searchEngine(); QList queryList = searchEngine->query(); QStringList terms; diff --git a/src/plugins/help/docsettingspage.cpp b/src/plugins/help/docsettingspage.cpp index 4933f53dd4e..a860446ba5c 100644 --- a/src/plugins/help/docsettingspage.cpp +++ b/src/plugins/help/docsettingspage.cpp @@ -29,7 +29,8 @@ #include "docsettingspage.h" #include "helpconstants.h" -#include "helpmanager.h" + +#include #include @@ -37,8 +38,6 @@ #include #include -#include - using namespace Help::Internal; DocSettingsPage::DocSettingsPage() @@ -80,10 +79,10 @@ QWidget *DocSettingsPage::createPage(QWidget *parent) m_ui.docsListWidget->installEventFilter(this); - QHelpEngineCore *engine = &HelpManager::helpEngineCore(); - const QStringList &nameSpaces = engine->registeredDocumentations(); + Core::HelpManager *manager = Core::HelpManager::instance(); + const QStringList &nameSpaces = manager->registeredNamespaces(); foreach (const QString &nameSpace, nameSpaces) - addItem(nameSpace, engine->documentationFileName(nameSpace)); + addItem(nameSpace, manager->fileFromNamespace(nameSpace)); m_filesToRegister.clear(); m_filesToUnregister.clear(); @@ -103,11 +102,11 @@ void DocSettingsPage::addDocumentation() return; m_recentDialogPath = QFileInfo(files.first()).canonicalPath(); - const QHelpEngineCore &engine = HelpManager::helpEngineCore(); - const QStringList &nameSpaces = engine.registeredDocumentations(); + Core::HelpManager *manager = Core::HelpManager::instance(); + const QStringList &nameSpaces = manager->registeredNamespaces(); foreach (const QString &file, files) { - const QString &nameSpace = engine.namespaceName(file); + const QString &nameSpace = manager->namespaceFromFile(file); if (nameSpace.isEmpty()) continue; @@ -130,14 +129,10 @@ void DocSettingsPage::removeDocumentation() void DocSettingsPage::apply() { - HelpManager* manager = &HelpManager::instance(); + Core::HelpManager *manager = Core::HelpManager::instance(); + manager->unregisterDocumentation(m_filesToUnregister.keys()); manager->registerDocumentation(m_filesToRegister.values()); - if (manager->guiEngineNeedsUpdate()) { - // emit this signal to the help plugin, since we don't want - // to force gui help engine setup if we are not in help mode - emit documentationChanged(); - } m_filesToRegister.clear(); m_filesToUnregister.clear(); @@ -172,10 +167,10 @@ void DocSettingsPage::removeDocumentation(const QList items) return; int row = 0; - QHelpEngineCore *engine = &HelpManager::helpEngineCore(); + Core::HelpManager *manager = Core::HelpManager::instance(); foreach (QListWidgetItem* item, items) { const QString &nameSpace = item->text(); - const QString &docPath = engine->documentationFileName(nameSpace); + const QString &docPath = manager->fileFromNamespace(nameSpace); if (m_filesToRegister.value(nameSpace) != docPath) { if (!m_filesToUnregister.contains(nameSpace)) diff --git a/src/plugins/help/docsettingspage.h b/src/plugins/help/docsettingspage.h index 66de3ac8ae3..7d292b2fee0 100644 --- a/src/plugins/help/docsettingspage.h +++ b/src/plugins/help/docsettingspage.h @@ -55,9 +55,6 @@ public: void finish() {} virtual bool matches(const QString &s) const; -signals: - void documentationChanged(); - private slots: void addDocumentation(); void removeDocumentation(); diff --git a/src/plugins/help/filtersettingspage.cpp b/src/plugins/help/filtersettingspage.cpp index 8577b42960e..ccdde31a262 100644 --- a/src/plugins/help/filtersettingspage.cpp +++ b/src/plugins/help/filtersettingspage.cpp @@ -33,16 +33,19 @@ #include "helpconstants.h" #include "helpmanager.h" +#include + #include #include #include -#include +#include using namespace Help::Internal; FilterSettingsPage::FilterSettingsPage() + : m_helpManager(0) { } @@ -76,6 +79,7 @@ QWidget *FilterSettingsPage::createPage(QWidget *parent) QWidget *widget = new QWidget(parent); m_ui.setupUi(widget); + m_helpManager->setupGuiHelpEngine(); updateFilterPage(); // does call setupData on the engine connect(m_ui.attributeWidget, SIGNAL(itemChanged(QTreeWidgetItem*, int)), @@ -86,6 +90,8 @@ QWidget *FilterSettingsPage::createPage(QWidget *parent) connect(m_ui.filterAddButton, SIGNAL(clicked()), this, SLOT(addFilter())); connect(m_ui.filterRemoveButton, SIGNAL(clicked()), this, SLOT(removeFilter())); + connect(Core::HelpManager::instance(), SIGNAL(documentationChanged()), + this, SLOT(updateFilterPage())); if (m_searchKeywords.isEmpty()) { m_searchKeywords = m_ui.filterGroupBox->title() + QLatin1Char(' ') @@ -100,7 +106,7 @@ void FilterSettingsPage::updateFilterPage() m_ui.attributeWidget->clear(); m_filterMapBackup.clear(); - const QHelpEngineCore &engine = HelpManager::helpEngineCore(); + const QHelpEngineCore &engine = LocalHelpManager::helpEngine(); const QStringList &filters = engine.customFilters(); foreach (const QString &filter, filters) { const QStringList &attributes = engine.filterAttributes(filter); @@ -114,8 +120,10 @@ void FilterSettingsPage::updateFilterPage() foreach (const QString &attribute, attributes) new QTreeWidgetItem(m_ui.attributeWidget, QStringList(attribute)); - if (m_filterMap.keys().count()) + if (m_filterMap.keys().isEmpty()) { m_ui.filterWidget->setCurrentRow(0); + updateAttributes(m_ui.filterWidget->currentItem()); + } } void FilterSettingsPage::updateAttributes(QListWidgetItem *item) @@ -208,7 +216,7 @@ void FilterSettingsPage::apply() } if (changed) { - QHelpEngineCore *engine = &HelpManager::helpEngineCore(); + QHelpEngineCore *engine = &LocalHelpManager::helpEngine(); foreach (const QString &filter, m_removedFilters) engine->removeCustomFilter(filter); @@ -226,3 +234,8 @@ bool FilterSettingsPage::matches(const QString &s) const { return m_searchKeywords.contains(s, Qt::CaseInsensitive); } + +void FilterSettingsPage::setHelpManager(LocalHelpManager *manager) +{ + m_helpManager = manager; +} diff --git a/src/plugins/help/filtersettingspage.h b/src/plugins/help/filtersettingspage.h index b8f74d5359d..96b2a57778d 100644 --- a/src/plugins/help/filtersettingspage.h +++ b/src/plugins/help/filtersettingspage.h @@ -36,6 +36,8 @@ namespace Help { namespace Internal { +class LocalHelpManager; + class FilterSettingsPage : public Core::IOptionsPage { Q_OBJECT @@ -55,6 +57,8 @@ public: void finish() {} virtual bool matches(const QString &s) const; + void setHelpManager(LocalHelpManager *manager); + signals: void filtersChanged(); @@ -73,6 +77,8 @@ private: QString m_searchKeywords; QStringList m_removedFilters; + + LocalHelpManager *m_helpManager; }; } // namespace Help diff --git a/src/plugins/help/generalsettingspage.cpp b/src/plugins/help/generalsettingspage.cpp index edc20b511b7..2703f9a8103 100644 --- a/src/plugins/help/generalsettingspage.cpp +++ b/src/plugins/help/generalsettingspage.cpp @@ -44,7 +44,7 @@ #include #include -#include +#include #if !defined(QT_NO_WEBKIT) #include @@ -94,7 +94,7 @@ QWidget *GeneralSettingsPage::createPage(QWidget *parent) m_ui.sizeComboBox->setEditable(false); m_ui.styleComboBox->setEditable(false); - const QHelpEngineCore &engine = HelpManager::helpEngineCore(); + const QHelpEngineCore &engine = LocalHelpManager::helpEngine(); m_font = qVariantValue(engine.customValue(QLatin1String("font"), m_font)); updateFontSize(); @@ -163,7 +163,7 @@ void GeneralSettingsPage::apply() if (weight >= 0) // Weight < 0 asserts... newFont.setWeight(weight); - QHelpEngineCore *engine = &HelpManager::helpEngineCore(); + QHelpEngineCore *engine = &LocalHelpManager::helpEngine(); engine->setCustomValue(QLatin1String("font"), newFont); if (newFont != m_font) @@ -197,7 +197,7 @@ void GeneralSettingsPage::setBlankPage() void GeneralSettingsPage::setDefaultPage() { - const QString &defaultHomePage = HelpManager::helpEngineCore() + const QString &defaultHomePage = LocalHelpManager::helpEngine() .customValue(QLatin1String("DefaultHomePage"), QString()).toString(); m_ui.homePageLineEdit->setText(defaultHomePage); } @@ -214,7 +214,7 @@ void GeneralSettingsPage::importBookmarks() QFile file(fileName); if (file.open(QIODevice::ReadOnly)) { - const BookmarkManager &manager = HelpManager::bookmarkManager(); + const BookmarkManager &manager = LocalHelpManager::bookmarkManager(); XbelReader reader(manager.treeBookmarkModel(), manager.listBookmarkModel()); if (reader.readFromFile(&file)) return; @@ -237,7 +237,7 @@ void GeneralSettingsPage::exportBookmarks() QFile file(fileName); if (file.open(QIODevice::WriteOnly)) { - XbelWriter writer(HelpManager::bookmarkManager().treeBookmarkModel()); + XbelWriter writer(LocalHelpManager::bookmarkManager().treeBookmarkModel()); writer.writeToFile(&file); } } diff --git a/src/plugins/help/helpindexfilter.cpp b/src/plugins/help/helpindexfilter.cpp index ff148efade6..411d823691b 100644 --- a/src/plugins/help/helpindexfilter.cpp +++ b/src/plugins/help/helpindexfilter.cpp @@ -28,197 +28,28 @@ **************************************************************************/ #include "helpindexfilter.h" -#include "helpmanager.h" #include #include +#include #include -#include -#include - -#include -#include -#include -#include - using namespace Locator; using namespace Help; using namespace Help::Internal; Q_DECLARE_METATYPE(ILocatorFilter*); -static const char linksForKeyQuery[] = "SELECT d.Title, f.Name, e.Name, " - "d.Name, a.Anchor FROM IndexTable a, FileNameTable d, FolderTable e, " - "NamespaceTable f WHERE a.FileId=d.FileId AND d.FolderId=e.Id AND " - "a.NamespaceId=f.Id AND a.Name='%1'"; - -// -- HelpIndexFilter::HelpFileReader - -class HelpIndexFilter::HelpFileReader -{ - struct dbCleaner { - dbCleaner(const QString &dbName) - : name(dbName) {} - ~dbCleaner() { - QSqlDatabase::removeDatabase(name); - } - QString name; - }; - -public: - HelpFileReader(); - ~HelpFileReader(); - -public: - void updateHelpFiles(); - QMap linksForKey(const QString &key); - QList matchesFor(const QString &entry, ILocatorFilter *locator, - int maxHits = INT_MAX); - -private: - QIcon m_icon; - bool m_initialized; - QStringList m_helpFiles; -}; - -HelpIndexFilter::HelpFileReader::HelpFileReader() - : m_initialized(false) -{ - m_icon = QIcon(QLatin1String(":/help/images/bookmark.png")); -} - -HelpIndexFilter::HelpFileReader::~HelpFileReader() -{ -} - -void HelpIndexFilter::HelpFileReader::updateHelpFiles() -{ - m_helpFiles.clear(); - const QLatin1String id("HelpIndexFilter::HelpFileReader::helpFiles"); - { - QSqlDatabase db = QSqlDatabase::addDatabase(QLatin1String("QSQLITE"), id); - if (db.driver() - && db.driver()->lastError().type() == QSqlError::NoError) { - db.setDatabaseName(HelpManager::collectionFilePath()); - if (db.open()) { - QSqlQuery query = QSqlQuery(db); - query.exec(QLatin1String("SELECT a.FilePath FROM NamespaceTable a")); - while (query.next()) - m_helpFiles.append(query.value(0).toString()); - } - } - } - QSqlDatabase::removeDatabase(id); -} - -QUrl buildQUrl(const QString &nameSpace, const QString &folder, - const QString &relFileName, const QString &anchor) -{ - QUrl url; - url.setScheme(QLatin1String("qthelp")); - url.setAuthority(nameSpace); - url.setPath(folder + QLatin1Char('/') + relFileName); - url.setFragment(anchor); - return url; -} - -QMapHelpIndexFilter::HelpFileReader::linksForKey(const QString &key) -{ - if (!m_initialized) { - updateHelpFiles(); - m_initialized = true; - } - - QMap links; - const QLatin1String sqlite("QSQLITE"); - const QLatin1String name("HelpIndexFilter::HelpFileReader::linksForKey"); - - dbCleaner cleaner(name); - QSqlDatabase db = QSqlDatabase::addDatabase(sqlite, name); - if (db.driver() && db.driver()->lastError().type() == QSqlError::NoError) { - foreach(const QString &file, m_helpFiles) { - if (!QFile::exists(file)) - continue; - db.setDatabaseName(file); - if (db.open()) { - QSqlQuery query = QSqlQuery(db); - query.setForwardOnly(true); - query.exec(QString::fromLatin1(linksForKeyQuery).arg(key)); - while (query.next()) { - QString title = query.value(0).toString(); - if (title.isEmpty()) // generate a title + corresponding path - title = key + QLatin1String(" : ") + query.value(3).toString(); - links.insertMulti(title, buildQUrl(query.value(1).toString(), - query.value(2).toString(), query.value(3).toString(), - query.value(4).toString())); - } - } - } - } - return links; -} - -QList HelpIndexFilter::HelpFileReader::matchesFor(const QString &id, - ILocatorFilter *locator, int maxHits) -{ - if (!m_initialized) { - updateHelpFiles(); - m_initialized = true; - } - - QList entries; - const QLatin1String sqlite("QSQLITE"); - const QLatin1String name("HelpIndexFilter::HelpFileReader::matchesFor"); - - dbCleaner cleaner(name); - QSqlDatabase db = QSqlDatabase::addDatabase(sqlite, name); - if (db.driver() && db.driver()->lastError().type() == QSqlError::NoError) { - foreach(const QString &file, m_helpFiles) { - if (!QFile::exists(file)) - continue; - db.setDatabaseName(file); - if (db.open()) { - QSqlQuery query = QSqlQuery(db); - query.setForwardOnly(true); - query.exec(QString::fromLatin1("SELECT DISTINCT Name FROM " - "IndexTable WHERE Name LIKE '%%1%'").arg(id)); - while (query.next()) { - const QString &key = query.value(0).toString(); - if (!key.isEmpty()) { - entries.append(FilterEntry(locator, key, QVariant(), - m_icon)); - if (entries.count() == maxHits) - return entries; - } - } - } - } - } - return entries; -} - -// -- HelpIndexFilter - HelpIndexFilter::HelpIndexFilter() - : m_fileReader(new HelpFileReader) { setIncludedByDefault(false); setShortcutString(QString(QLatin1Char('?'))); - - connect(&HelpManager::helpEngineCore(), SIGNAL(setupFinished()), this, - SLOT(updateHelpFiles())); + m_icon = QIcon(QLatin1String(":/help/images/bookmark.png")); } HelpIndexFilter::~HelpIndexFilter() { - delete m_fileReader; -} - -void HelpIndexFilter::updateHelpFiles() -{ - m_fileReader->updateHelpFiles(); } QString HelpIndexFilter::displayName() const @@ -238,15 +69,23 @@ ILocatorFilter::Priority HelpIndexFilter::priority() const QList HelpIndexFilter::matchesFor(const QString &entry) { + QStringList keywords; if (entry.length() < 2) - return m_fileReader->matchesFor(entry, this, 300); - return m_fileReader->matchesFor(entry, this); + keywords = Core::HelpManager::instance()->findKeywords(entry, 300); + else + keywords = Core::HelpManager::instance()->findKeywords(entry); + + QList entries; + foreach (const QString &keyword, keywords) + entries.append(FilterEntry(this, keyword, QVariant(), m_icon)); + + return entries; } void HelpIndexFilter::accept(FilterEntry selection) const { const QString &key = selection.displayName; - const QMap &links = m_fileReader->linksForKey(key); + const QMap &links = Core::HelpManager::instance()->linksForKeyword(key); if (links.size() == 1) { emit linkActivated(links.begin().value()); } else if (!links.isEmpty()) { diff --git a/src/plugins/help/helpindexfilter.h b/src/plugins/help/helpindexfilter.h index 9c3a6de4659..859dc5a056a 100644 --- a/src/plugins/help/helpindexfilter.h +++ b/src/plugins/help/helpindexfilter.h @@ -32,6 +32,8 @@ #include +#include + namespace Help { namespace Internal { @@ -40,7 +42,6 @@ class HelpPlugin; class HelpIndexFilter : public Locator::ILocatorFilter { Q_OBJECT - class HelpFileReader; public: HelpIndexFilter(); @@ -58,11 +59,8 @@ signals: void linkActivated(const QUrl &link) const; void linksActivated(const QMap &urls, const QString &keyword) const; -private slots: - void updateHelpFiles(); - private: - HelpFileReader *m_fileReader; + QIcon m_icon; }; } // namespace Internal diff --git a/src/plugins/help/helpmanager.cpp b/src/plugins/help/helpmanager.cpp index bc5bef0a465..10f4197ab96 100644 --- a/src/plugins/help/helpmanager.cpp +++ b/src/plugins/help/helpmanager.cpp @@ -30,38 +30,29 @@ #include "helpmanager.h" #include "bookmarkmanager.h" -#include +#include +#include -#include -#include -#include #include #include -#include -using namespace Help; +using namespace Help::Internal; -bool HelpManager::m_guiNeedsSetup = true; -bool HelpManager::m_needsCollectionFile = true; +QMutex LocalHelpManager::m_guiMutex; +QHelpEngine* LocalHelpManager::m_guiEngine = 0; -QMutex HelpManager::m_guiMutex; -QHelpEngine* HelpManager::m_guiEngine = 0; +QMutex LocalHelpManager::m_bkmarkMutex; +BookmarkManager* LocalHelpManager::m_bookmarkManager = 0; -QMutex HelpManager::m_coreMutex; -QHelpEngineCore* HelpManager::m_coreEngine = 0; - -HelpManager* HelpManager::m_helpManager = 0; -BookmarkManager* HelpManager::m_bookmarkManager = 0; - -HelpManager::HelpManager(QObject *parent) +LocalHelpManager::LocalHelpManager(QObject *parent) : QObject(parent) + , m_guiNeedsSetup(true) + , m_needsCollectionFile(true) { - Q_ASSERT(!m_helpManager); - m_helpManager = this; } -HelpManager::~HelpManager() +LocalHelpManager::~LocalHelpManager() { if (m_bookmarkManager) { m_bookmarkManager->saveBookmarks(); @@ -71,88 +62,27 @@ HelpManager::~HelpManager() delete m_guiEngine; m_guiEngine = 0; - - delete m_coreEngine; - m_coreEngine = 0; } -HelpManager& HelpManager::instance() -{ - Q_ASSERT(m_helpManager); - return *m_helpManager; -} - -void HelpManager::setupGuiHelpEngine() +void LocalHelpManager::setupGuiHelpEngine() { if (m_needsCollectionFile) { m_needsCollectionFile = false; - (&helpEngine())->setCollectionFile(collectionFilePath()); + helpEngine().setCollectionFile(Core::HelpManager::collectionFilePath()); } if (m_guiNeedsSetup) { m_guiNeedsSetup = false; - (&helpEngine())->setupData(); + helpEngine().setupData(); } } -bool HelpManager::guiEngineNeedsUpdate() const +void LocalHelpManager::setEngineNeedsUpdate() { - return m_guiNeedsSetup; + m_guiNeedsSetup = true; } -void HelpManager::handleHelpRequest(const QString &url) -{ - emit helpRequested(QUrl(url)); -} - -void HelpManager::verifyDocumenation() -{ - QStringList nameSpacesToUnregister; - QHelpEngineCore *engine = &helpEngineCore(); - const QStringList ®isteredDocs = engine->registeredDocumentations(); - foreach (const QString &nameSpace, registeredDocs) { - const QString &file = engine->documentationFileName(nameSpace); - if (!QFileInfo(file).exists()) - nameSpacesToUnregister.append(nameSpace); - } - - if (!nameSpacesToUnregister.isEmpty()) - unregisterDocumentation(nameSpacesToUnregister); -} - -void HelpManager::registerDocumentation(const QStringList &files) -{ - QHelpEngineCore *engine = &helpEngineCore(); - foreach (const QString &file, files) { - const QString &nameSpace = engine->namespaceName(file); - if (nameSpace.isEmpty()) - continue; - if (!engine->registeredDocumentations().contains(nameSpace)) { - if (engine->registerDocumentation(file)) { - m_guiNeedsSetup = true; - } else { - qWarning() << "Error registering namespace '" << nameSpace - << "' from file '" << file << "':" << engine->error(); - } - } - } -} - -void HelpManager::unregisterDocumentation(const QStringList &nameSpaces) -{ - QHelpEngineCore *engine = &helpEngineCore(); - foreach (const QString &nameSpace, nameSpaces) { - const QString &file = engine->documentationFileName(nameSpace); - if (engine->unregisterDocumentation(nameSpace)) { - m_guiNeedsSetup = true; - } else { - qWarning() << "Error unregistering namespace '" << nameSpace - << "' from file '" << file << "': " << engine->error(); - } - } -} - -QHelpEngine &HelpManager::helpEngine() +QHelpEngine &LocalHelpManager::helpEngine() { if (!m_guiEngine) { QMutexLocker _(&m_guiMutex); @@ -164,34 +94,18 @@ QHelpEngine &HelpManager::helpEngine() return *m_guiEngine; } -QString HelpManager::collectionFilePath() -{ - const QFileInfo fi(Core::ICore::instance()->settings()->fileName()); - const QDir directory(fi.absolutePath() + QLatin1String("/qtcreator")); - if (!directory.exists()) - directory.mkpath(directory.absolutePath()); - return QDir::cleanPath(directory.absolutePath() + QLatin1String("/helpcollection.qhc")); -} - -QHelpEngineCore& HelpManager::helpEngineCore() -{ - if (!m_coreEngine) { - QMutexLocker _(&m_coreMutex); - if (!m_coreEngine) { - m_coreEngine = new QHelpEngineCore(collectionFilePath()); - m_coreEngine->setAutoSaveFilter(false); - m_coreEngine->setCurrentFilter(tr("Unfiltered")); - m_coreEngine->setupData(); - } - } - return *m_coreEngine; -} - -BookmarkManager& HelpManager::bookmarkManager() +BookmarkManager& LocalHelpManager::bookmarkManager() { if (!m_bookmarkManager) { - m_bookmarkManager = new BookmarkManager; - m_bookmarkManager->setupBookmarkModels(); + QMutexLocker _(&m_bkmarkMutex); + if (!m_bookmarkManager) { + m_bookmarkManager = new BookmarkManager; + m_bookmarkManager->setupBookmarkModels(); + const QString &url = QString::fromLatin1("qthelp://com.nokia.qtcreator." + "%1%2%3/doc/index.html").arg(IDE_VERSION_MAJOR).arg(IDE_VERSION_MINOR) + .arg(IDE_VERSION_RELEASE); + helpEngine().setCustomValue(QLatin1String("DefaultHomePage"), url); + } } return *m_bookmarkManager; } diff --git a/src/plugins/help/helpmanager.h b/src/plugins/help/helpmanager.h index 18a36bcd08a..3dc333d405f 100644 --- a/src/plugins/help/helpmanager.h +++ b/src/plugins/help/helpmanager.h @@ -27,66 +27,44 @@ ** **************************************************************************/ -#ifndef HELPMANAGER_H -#define HELPMANAGER_H - -#include "help_global.h" +#ifndef LOCALHELPMANAGER_H +#define LOCALHELPMANAGER_H #include #include QT_FORWARD_DECLARE_CLASS(QHelpEngine) -QT_FORWARD_DECLARE_CLASS(QHelpEngineCore) -QT_FORWARD_DECLARE_CLASS(QString) -QT_FORWARD_DECLARE_CLASS(QStringList) -QT_FORWARD_DECLARE_CLASS(QUrl) class BookmarkManager; namespace Help { + namespace Internal { -class HELP_EXPORT HelpManager : public QObject +class LocalHelpManager : public QObject { Q_OBJECT -public: - HelpManager(QObject *parent = 0); - ~HelpManager(); - static HelpManager& instance(); +public: + LocalHelpManager(QObject *parent = 0); + ~LocalHelpManager(); void setupGuiHelpEngine(); - bool guiEngineNeedsUpdate() const; - - void verifyDocumenation(); - void registerDocumentation(const QStringList &fileNames); - void unregisterDocumentation(const QStringList &nameSpaces); + void setEngineNeedsUpdate(); static QHelpEngine& helpEngine(); - static QString collectionFilePath(); - static QHelpEngineCore& helpEngineCore(); - static BookmarkManager& bookmarkManager(); -public slots: - void handleHelpRequest(const QString &url); - -signals: - void helpRequested(const QUrl &url); - private: - static bool m_guiNeedsSetup; - static bool m_needsCollectionFile; + bool m_guiNeedsSetup; + bool m_needsCollectionFile; static QMutex m_guiMutex; static QHelpEngine *m_guiEngine; - static QMutex m_coreMutex; - static QHelpEngineCore *m_coreEngine; - - static HelpManager *m_helpManager; + static QMutex m_bkmarkMutex; static BookmarkManager *m_bookmarkManager; }; - + } // Internal } // Help -#endif // HELPMANAGER_H +#endif // LOCALHELPMANAGER_H diff --git a/src/plugins/help/helpplugin.cpp b/src/plugins/help/helpplugin.cpp index 7f55ddd0d5c..c254cee1a5e 100644 --- a/src/plugins/help/helpplugin.cpp +++ b/src/plugins/help/helpplugin.cpp @@ -54,6 +54,7 @@ #include #include #include +#include #include #include #include @@ -78,10 +79,8 @@ #include #include -#include using namespace Core::Constants; -using namespace Help; using namespace Help::Internal; const char * const SB_INDEX = QT_TRANSLATE_NOOP("Help::Internal::HelpPlugin", "Index"); @@ -141,22 +140,20 @@ bool HelpPlugin::initialize(const QStringList &arguments, QString *error) qApp->installTranslator(qhelptr); } - addAutoReleasedObject(m_helpManager = new HelpManager(this)); + addAutoReleasedObject(m_helpManager = new LocalHelpManager(this)); addAutoReleasedObject(m_openPagesManager = new OpenPagesManager(this)); - addAutoReleasedObject(m_docSettingsPage = new DocSettingsPage()); addAutoReleasedObject(m_filterSettingsPage = new FilterSettingsPage()); addAutoReleasedObject(m_generalSettingsPage = new GeneralSettingsPage()); - connect(m_docSettingsPage, SIGNAL(documentationChanged()), m_filterSettingsPage, - SLOT(updateFilterPage())); connect(m_generalSettingsPage, SIGNAL(fontChanged()), this, SLOT(fontChanged())); - connect(m_helpManager, SIGNAL(helpRequested(QUrl)), this, + connect(Core::HelpManager::instance(), SIGNAL(helpRequested(QUrl)), this, SLOT(handleHelpRequest(QUrl))); + m_filterSettingsPage->setHelpManager(m_helpManager); connect(m_filterSettingsPage, SIGNAL(filtersChanged()), this, SLOT(setupHelpEngineIfNeeded())); - connect(m_docSettingsPage, SIGNAL(documentationChanged()), this, + connect(Core::HelpManager::instance(), SIGNAL(documentationChanged()), this, SLOT(setupHelpEngineIfNeeded())); m_splitter = new Core::MiniSplitter; @@ -314,30 +311,20 @@ bool HelpPlugin::initialize(const QStringList &arguments, QString *error) void HelpPlugin::extensionsInitialized() { - const QString &filterInternal = QString::fromLatin1("Qt Creator %1.%2.%3") - .arg(IDE_VERSION_MAJOR).arg(IDE_VERSION_MINOR).arg(IDE_VERSION_RELEASE); - const QRegExp filterRegExp(QLatin1String("Qt Creator \\d*\\.\\d*\\.\\d*")); - - QHelpEngineCore *engine = &m_helpManager->helpEngineCore(); - const QStringList &filters = engine->customFilters(); - foreach (const QString &filter, filters) { - if (filterRegExp.exactMatch(filter) && filter != filterInternal) - engine->removeCustomFilter(filter); - } - - const QString &docInternal = QString::fromLatin1("com.nokia.qtcreator.%1%2%3") + const QString &nsInternal = QString::fromLatin1("com.nokia.qtcreator.%1%2%3") .arg(IDE_VERSION_MAJOR).arg(IDE_VERSION_MINOR).arg(IDE_VERSION_RELEASE); - foreach (const QString &ns, engine->registeredDocumentations()) { + Core::HelpManager *helpManager = Core::HelpManager::instance(); + foreach (const QString &ns, helpManager->registeredNamespaces()) { if (ns.startsWith(QLatin1String("com.nokia.qtcreator.")) - && ns != docInternal) - m_helpManager->unregisterDocumentation(QStringList() << ns); + && ns != nsInternal) + helpManager->unregisterDocumentation(QStringList() << ns); } QStringList filesToRegister; // Explicitly register qml.qch if located in creator directory. This is only // needed for the creator-qml package, were we want to ship the documentation - // without a qt development version. + // without a qt development version. TODO: is this still really needed, remove const QString &appPath = QCoreApplication::applicationDirPath(); filesToRegister.append(QDir::cleanPath(QDir::cleanPath(appPath + QLatin1String(DOCPATH "qml.qch")))); @@ -345,24 +332,6 @@ void HelpPlugin::extensionsInitialized() // we might need to register creators inbuild help filesToRegister.append(QDir::cleanPath(appPath + QLatin1String(DOCPATH "qtcreator.qch"))); - - // this comes from the installer - const QLatin1String key("AddedDocs"); - const QString &addedDocs = engine->customValue(key).toString(); - if (!addedDocs.isEmpty()) { - engine->removeCustomValue(key); - filesToRegister += addedDocs.split(QLatin1Char(';')); - } - - updateFilterComboBox(); - m_helpManager->verifyDocumenation(); - m_helpManager->registerDocumentation(filesToRegister); - - const QString &url = QString::fromLatin1("qthelp://com.nokia.qtcreator." - "%1%2%3/doc/index.html").arg(IDE_VERSION_MAJOR).arg(IDE_VERSION_MINOR) - .arg(IDE_VERSION_RELEASE); - engine->setCustomValue(QLatin1String("DefaultHomePage"), url); - connect(engine, SIGNAL(setupFinished()), this, SLOT(updateFilterComboBox())); } void HelpPlugin::aboutToShutdown() @@ -425,7 +394,7 @@ void HelpPlugin::setupUi() // connect(shortcut, SIGNAL(activated()), this, SLOT(activateSearch())); // shortcutMap.insert(QLatin1String(SB_SEARCH), cmd); - BookmarkManager *manager = &HelpManager::bookmarkManager(); + BookmarkManager *manager = &LocalHelpManager::bookmarkManager(); BookmarkWidget *bookmarkWidget = new BookmarkWidget(manager, 0, false); bookmarkWidget->setWindowTitle(tr(SB_BOOKMARKS)); m_bookmarkItem = new Core::SideBarItem(bookmarkWidget, QLatin1String(SB_BOOKMARKS)); @@ -470,24 +439,36 @@ void HelpPlugin::setupUi() void HelpPlugin::resetFilter() { + const QString &filterInternal = QString::fromLatin1("Qt Creator %1.%2.%3") + .arg(IDE_VERSION_MAJOR).arg(IDE_VERSION_MINOR).arg(IDE_VERSION_RELEASE); + const QRegExp filterRegExp(QLatin1String("Qt Creator \\d*\\.\\d*\\.\\d*")); + + QHelpEngineCore *engine = &LocalHelpManager::helpEngine(); + const QStringList &filters = engine->customFilters(); + foreach (const QString &filter, filters) { + if (filterRegExp.exactMatch(filter) && filter != filterInternal) + engine->removeCustomFilter(filter); + } + const QLatin1String weAddedFilterKey("UnfilteredFilterInserted"); const QLatin1String previousFilterNameKey("UnfilteredFilterName"); - - QHelpEngineCore *core = &m_helpManager->helpEngineCore(); - if (core->customValue(weAddedFilterKey).toInt() == 1) { + if (engine->customValue(weAddedFilterKey).toInt() == 1) { // we added a filter at some point, remove previously added filter - const QString &filter = core->customValue(previousFilterNameKey).toString(); + const QString &filter = engine->customValue(previousFilterNameKey).toString(); if (!filter.isEmpty()) - core->removeCustomFilter(filter); + engine->removeCustomFilter(filter); } // potentially remove a filter with new name const QString filterName = tr("Unfiltered"); - core->removeCustomFilter(filterName); - core->addCustomFilter(filterName, QStringList()); - core->setCustomValue(weAddedFilterKey, 1); - core->setCustomValue(previousFilterNameKey, filterName); - (&m_helpManager->helpEngine())->setCurrentFilter(filterName); + engine->removeCustomFilter(filterName); + engine->addCustomFilter(filterName, QStringList()); + engine->setCustomValue(weAddedFilterKey, 1); + engine->setCustomValue(previousFilterNameKey, filterName); + engine->setCurrentFilter(filterName); + + updateFilterComboBox(); + connect(engine, SIGNAL(setupFinished()), this, SLOT(updateFilterComboBox())); } void HelpPlugin::createRightPaneContextViewer() @@ -595,9 +576,9 @@ void HelpPlugin::modeChanged(Core::IMode *mode) qApp->processEvents(); qApp->setOverrideCursor(Qt::WaitCursor); + m_helpManager->setupGuiHelpEngine(); setupUi(); resetFilter(); - m_helpManager->setupGuiHelpEngine(); OpenPagesManager::instance().setupInitialPages(); qApp->restoreOverrideCursor(); @@ -633,7 +614,7 @@ void HelpPlugin::fontChanged() if (!m_helpViewerForSideBar) createRightPaneContextViewer(); - const QHelpEngineCore &engine = m_helpManager->helpEngineCore(); + const QHelpEngine &engine = LocalHelpManager::helpEngine(); QFont font = qVariantValue(engine.customValue(QLatin1String("font"), m_helpViewerForSideBar->viewerFont())); @@ -647,7 +628,8 @@ void HelpPlugin::fontChanged() void HelpPlugin::setupHelpEngineIfNeeded() { - if (Core::ICore::instance()->modeManager()->currentMode() == m_mode) + m_helpManager->setEngineNeedsUpdate(); + if (Core::ModeManager::instance()->currentMode() == m_mode) m_helpManager->setupGuiHelpEngine(); } @@ -656,7 +638,7 @@ HelpViewer* HelpPlugin::viewerForContextMode() using namespace Core; bool showSideBySide = false; - const QHelpEngineCore &engine = m_helpManager->helpEngineCore(); + const QHelpEngineCore &engine = LocalHelpManager::helpEngine(); RightPanePlaceHolder *placeHolder = RightPanePlaceHolder::current(); switch (engine.customValue(QLatin1String("ContextHelpOption"), 0).toInt()) { case 0: { @@ -713,7 +695,7 @@ void HelpPlugin::activateContext() // Find out what to show if (IContext *context = m_core->currentContextObject()) { id = context->contextHelpId(); - links = m_helpManager->helpEngineCore().linksForIdentifier(id); + links = Core::HelpManager::instance()->linksForIdentifier(id); } if (HelpViewer* viewer = viewerForContextMode()) { @@ -803,7 +785,7 @@ QToolBar *HelpPlugin::createToolBar() void HelpPlugin::updateFilterComboBox() { - const QHelpEngine &engine = m_helpManager->helpEngine(); + const QHelpEngine &engine = LocalHelpManager::helpEngine(); QString curFilter = m_filterComboBox->currentText(); if (curFilter.isEmpty()) curFilter = engine.currentFilter(); @@ -817,7 +799,7 @@ void HelpPlugin::updateFilterComboBox() void HelpPlugin::filterDocumentation(const QString &customFilter) { - (&m_helpManager->helpEngine())->setCurrentFilter(customFilter); + LocalHelpManager::helpEngine().setCurrentFilter(customFilter); } void HelpPlugin::addBookmark() @@ -828,7 +810,7 @@ void HelpPlugin::addBookmark() if (url.isEmpty() || url == Help::Constants::AboutBlank) return; - BookmarkManager *manager = &HelpManager::bookmarkManager(); + BookmarkManager *manager = &LocalHelpManager::bookmarkManager(); manager->showBookmarkDialog(m_centralWidget, viewer->title(), url); } @@ -837,7 +819,7 @@ void HelpPlugin::handleHelpRequest(const QUrl &url) if (HelpViewer::launchWithExternalApp(url)) return; - if (m_helpManager->helpEngineCore().findFile(url).isValid()) { + if (Core::HelpManager::instance()->findFile(url).isValid()) { if (url.queryItemValue(QLatin1String("view")) == QLatin1String("split")) { if (HelpViewer* viewer = viewerForContextMode()) viewer->setSource(url); diff --git a/src/plugins/help/helpplugin.h b/src/plugins/help/helpplugin.h index 1ac051cdfb1..9ad6644eb08 100644 --- a/src/plugins/help/helpplugin.h +++ b/src/plugins/help/helpplugin.h @@ -49,8 +49,6 @@ class SideBarItem; } // Core namespace Help { -class HelpManager; - namespace Internal { class CentralWidget; class DocSettingsPage; @@ -58,6 +56,7 @@ class FilterSettingsPage; class GeneralSettingsPage; class HelpMode; class HelpViewer; +class LocalHelpManager; class OpenPagesManager; class SearchWidget; @@ -129,7 +128,7 @@ private: Core::SideBar *m_sideBar; bool m_firstModeChange; - HelpManager *m_helpManager; + LocalHelpManager *m_helpManager; OpenPagesManager *m_openPagesManager; Core::MiniSplitter *m_splitter; diff --git a/src/plugins/help/helpviewer.cpp b/src/plugins/help/helpviewer.cpp index 3fa9fcc9481..d351a982265 100644 --- a/src/plugins/help/helpviewer.cpp +++ b/src/plugins/help/helpviewer.cpp @@ -40,7 +40,7 @@ #include #include -#include +#include using namespace Help::Internal; @@ -126,7 +126,7 @@ QString HelpViewer::mimeFromUrl(const QUrl &url) bool HelpViewer::launchWithExternalApp(const QUrl &url) { if (isLocalUrl(url)) { - const QHelpEngineCore &helpEngine = Help::HelpManager::helpEngineCore(); + const QHelpEngineCore &helpEngine = LocalHelpManager::helpEngine(); const QUrl &resolvedUrl = helpEngine.findFile(url); if (!resolvedUrl.isValid()) return false; @@ -155,7 +155,7 @@ bool HelpViewer::launchWithExternalApp(const QUrl &url) void HelpViewer::home() { - const QHelpEngineCore &engine = Help::HelpManager::helpEngineCore(); + const QHelpEngineCore &engine = LocalHelpManager::helpEngine(); QString homepage = engine.customValue(QLatin1String("HomePage"), QLatin1String("")).toString(); diff --git a/src/plugins/help/helpviewer_qwv.cpp b/src/plugins/help/helpviewer_qwv.cpp index 499a5277746..3708611ccb4 100644 --- a/src/plugins/help/helpviewer_qwv.cpp +++ b/src/plugins/help/helpviewer_qwv.cpp @@ -44,7 +44,7 @@ #include #include -#include +#include #include #include @@ -125,7 +125,7 @@ QNetworkReply *HelpNetworkAccessManager::createRequest(Operation /*op*/, const QNetworkRequest &request, QIODevice* /*outgoingData*/) { QString url = request.url().toString(); - const QHelpEngineCore &engine = HelpManager::helpEngineCore(); + const QHelpEngineCore &engine = LocalHelpManager::helpEngine(); // TODO: For some reason the url to load is already wrong (passed from webkit) // though the css file and the references inside should work that way. One // possible problem might be that the css is loaded at the same level as the @@ -266,7 +266,7 @@ QFont HelpViewer::viewerFont() const QWebSettings* webSettings = QWebSettings::globalSettings(); QFont font(QApplication::font().family(), webSettings->fontSize(QWebSettings::DefaultFontSize)); - const QHelpEngineCore &engine = HelpManager::helpEngineCore(); + const QHelpEngineCore &engine = LocalHelpManager::helpEngine(); return qVariantValue(engine.customValue(QLatin1String("font"), font)); } diff --git a/src/plugins/help/openpagesmanager.cpp b/src/plugins/help/openpagesmanager.cpp index 5396f05aac2..5762ee7686a 100644 --- a/src/plugins/help/openpagesmanager.cpp +++ b/src/plugins/help/openpagesmanager.cpp @@ -41,7 +41,7 @@ #include #include -#include +#include using namespace Help::Internal; @@ -118,7 +118,7 @@ QStringList splitString(const QVariant &value) void OpenPagesManager::setupInitialPages() { - const QHelpEngineCore &engine = HelpManager::helpEngineCore(); + const QHelpEngineCore &engine = LocalHelpManager::helpEngine(); const int option = engine.customValue(QLatin1String("StartOption"), Help::Constants::ShowLastPages).toInt(); QString homePage = engine.customValue(QLatin1String("DefaultHomePage"), diff --git a/src/plugins/help/searchwidget.cpp b/src/plugins/help/searchwidget.cpp index 933abd36890..5e564388a78 100644 --- a/src/plugins/help/searchwidget.cpp +++ b/src/plugins/help/searchwidget.cpp @@ -100,7 +100,7 @@ void SearchWidget::showEvent(QShowEvent *event) QVBoxLayout *vLayout = new QVBoxLayout(this); vLayout->setMargin(4); - searchEngine = (&HelpManager::helpEngine())->searchEngine(); + searchEngine = (&LocalHelpManager::helpEngine())->searchEngine(); resultWidget = searchEngine->resultWidget(); QHelpSearchQueryWidget *queryWidget = searchEngine->queryWidget(); @@ -126,7 +126,7 @@ void SearchWidget::showEvent(QShowEvent *event) connect(searchEngine, SIGNAL(indexingFinished()), this, SLOT(indexingFinished())); - QMetaObject::invokeMethod(&HelpManager::helpEngine(), "setupFinished", + QMetaObject::invokeMethod(&LocalHelpManager::helpEngine(), "setupFinished", Qt::QueuedConnection); } } diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro index 156d5ce9f8f..f59ddb97a4d 100644 --- a/src/plugins/plugins.pro +++ b/src/plugins/plugins.pro @@ -114,7 +114,6 @@ plugin_qt4projectmanager.depends = plugin_texteditor plugin_qt4projectmanager.depends += plugin_projectexplorer plugin_qt4projectmanager.depends += plugin_cpptools plugin_qt4projectmanager.depends += plugin_cppeditor -plugin_qt4projectmanager.depends += plugin_help plugin_qt4projectmanager.depends += plugin_designer plugin_qt4projectmanager.depends += plugin_debugger diff --git a/src/plugins/projectexplorer/abstractprocessstep.cpp b/src/plugins/projectexplorer/abstractprocessstep.cpp index a6d5c13bd9f..64983b99729 100644 --- a/src/plugins/projectexplorer/abstractprocessstep.cpp +++ b/src/plugins/projectexplorer/abstractprocessstep.cpp @@ -248,7 +248,7 @@ void AbstractProcessStep::stdOutput(const QString &line) if (m_outputParserChain) m_outputParserChain->stdOutput(line); QTextCharFormat textCharFormat; - emit addOutput(Qt::escape(line), textCharFormat); + emit addOutput(line, textCharFormat); } void AbstractProcessStep::processReadyReadStdError() diff --git a/src/plugins/projectexplorer/buildmanager.cpp b/src/plugins/projectexplorer/buildmanager.cpp index 2a2ef6ec1d9..272e38e0bed 100644 --- a/src/plugins/projectexplorer/buildmanager.cpp +++ b/src/plugins/projectexplorer/buildmanager.cpp @@ -151,8 +151,8 @@ void BuildManager::cancel() disconnect(m_currentBuildStep, SIGNAL(addTask(ProjectExplorer::Task)), this, SLOT(addToTaskWindow(ProjectExplorer::Task))); - disconnect(m_currentBuildStep, SIGNAL(addOutput(QString)), - this, SLOT(addToOutputWindow(QString))); + disconnect(m_currentBuildStep, SIGNAL(addOutput(QString, QTextCharFormat)), + this, SLOT(addToOutputWindow(QString, QTextCharFormat))); decrementActiveBuildSteps(m_currentBuildStep->buildConfiguration()->target()->project()); m_progressFutureInterface->setProgressValueAndText(m_progress*100, "Build canceled"); //TODO NBS fix in qtconcurrent @@ -191,8 +191,8 @@ void BuildManager::clearBuildQueue() decrementActiveBuildSteps(bs->buildConfiguration()->target()->project()); disconnect(bs, SIGNAL(addTask(ProjectExplorer::Task)), this, SLOT(addToTaskWindow(ProjectExplorer::Task))); - disconnect(bs, SIGNAL(addOutput(QString)), - this, SLOT(addToOutputWindow(QString))); + disconnect(bs, SIGNAL(addOutput(QString, QTextCharFormat)), + this, SLOT(addToOutputWindow(QString, QTextCharFormat))); } m_buildQueue.clear(); @@ -344,7 +344,7 @@ void BuildManager::nextStep() const QString projectName = m_currentBuildStep->buildConfiguration()->target()->project()->displayName(); QTextCharFormat textCharFormat; textCharFormat.setFontWeight(QFont::Bold); - addToOutputWindow(tr("Running build steps for project %2...") + addToOutputWindow(tr("Running build steps for project %1...") .arg(projectName), textCharFormat); m_previousBuildStepProject = m_currentBuildStep->buildConfiguration()->target()->project(); } diff --git a/src/plugins/projectexplorer/taskwindow.h b/src/plugins/projectexplorer/taskwindow.h index 50441e7595e..89c42743788 100644 --- a/src/plugins/projectexplorer/taskwindow.h +++ b/src/plugins/projectexplorer/taskwindow.h @@ -69,12 +69,14 @@ struct PROJECTEXPLORER_EXPORT Task { QString file; int line; QString category; - // Having a QList in Task isn't that great. It would be - // cleaner to split up the text into the logical hunks and then assemble - // them again (That is diffrent consumers of tasks could show them in - // different ways!). But then again, the wording of the text most likely - // doesn't work if you split it up, nor are our parsers anywhere near being - // that good. + // Having a QList in Task isn't that great + // It would be cleaner to split up the text into + // the logical hunks and then assemble them again + // (That is different consumers of tasks could show them in + // different ways!) + // But then again, the wording of the text most likely + // doesn't work if you split it up, nor are our parsers + // anywhere near being that good QList formats; }; diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp b/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp index 1904c0bec20..3488be937ab 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp +++ b/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp @@ -235,7 +235,7 @@ FormEditorWidget *FormEditorView::widget() const void FormEditorView::nodeIdChanged(const ModelNode& node, const QString& newId, const QString& oldId) { - nodeInstanceView()->nodeIdChanged(node, newId, oldId); + QmlModelView::nodeIdChanged(node, newId, oldId); } void FormEditorView::selectedNodesChanged(const QList &selectedNodeList, @@ -258,6 +258,12 @@ void FormEditorView::selectedNodesChanged(const QList &selectedNodeLi m_scene->update(); } +void FormEditorView::scriptFunctionsChanged(const ModelNode &node, const QStringList &scriptFunctionList) +{ + QmlModelView::scriptFunctionsChanged(node, scriptFunctionList); +} + + AbstractFormEditorTool* FormEditorView::currentTool() const { return m_currentTool; diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorview.h b/src/plugins/qmldesigner/components/formeditor/formeditorview.h index 1c7d787c351..4123ffdd7e0 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorview.h +++ b/src/plugins/qmldesigner/components/formeditor/formeditorview.h @@ -77,6 +77,7 @@ public: void selectedNodesChanged(const QList &selectedNodeList, const QList &lastSelectedNodeList); + void scriptFunctionsChanged(const ModelNode &node, const QStringList &scriptFunctionList); // FormEditorView FormEditorWidget *widget() const; diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp b/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp index cde79f3dd96..6c125bc5d4b 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp +++ b/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp @@ -123,7 +123,7 @@ FormEditorWidget::FormEditorWidget(FormEditorView *view) m_selectOnlyContentItemsAction->setShortcut(Qt::Key_S); m_selectOnlyContentItemsAction->setShortcutContext(Qt::WidgetWithChildrenShortcut); m_selectOnlyContentItemsAction->setCheckable(true); - m_selectOnlyContentItemsAction->setChecked(true); + m_selectOnlyContentItemsAction->setChecked(false); m_selectOnlyContentItemsAction->setIcon(QPixmap(":/icon/selection/selectonlycontentitems.png")); addAction(m_selectOnlyContentItemsAction.data()); diff --git a/src/plugins/qmldesigner/components/formeditor/movemanipulator.cpp b/src/plugins/qmldesigner/components/formeditor/movemanipulator.cpp index b318a3037f2..76df3d4ecc1 100644 --- a/src/plugins/qmldesigner/components/formeditor/movemanipulator.cpp +++ b/src/plugins/qmldesigner/components/formeditor/movemanipulator.cpp @@ -145,15 +145,29 @@ void MoveManipulator::begin(const QPointF &beginPoint) -QPointF MoveManipulator::findSnappingOffset(const QList &boundingRectList) +QPointF MoveManipulator::findSnappingOffset(const QHash &boundingRectHash) { QPointF offset; QMap verticalOffsetMap; - foreach (const QRectF &boundingRect, boundingRectList) { - double verticalOffset = m_snapper.snappedVerticalOffset(boundingRect); - if (verticalOffset < std::numeric_limits::max()) - verticalOffsetMap.insert(qAbs(verticalOffset), verticalOffset); + QMap horizontalOffsetMap; + + QHashIterator hashIterator(boundingRectHash); + while(hashIterator.hasNext()) { + hashIterator.next(); + FormEditorItem *formEditorItem = hashIterator.key(); + QRectF boundingRect = hashIterator.value(); + if (!formEditorItem->qmlItemNode().hasBindingProperty("x")) { + double verticalOffset = m_snapper.snappedVerticalOffset(boundingRect); + if (verticalOffset < std::numeric_limits::max()) + verticalOffsetMap.insert(qAbs(verticalOffset), verticalOffset); + } + + if (!formEditorItem->qmlItemNode().hasBindingProperty("y")) { + double horizontalOffset = m_snapper.snappedHorizontalOffset(boundingRect); + if (horizontalOffset < std::numeric_limits::max()) + horizontalOffsetMap.insert(qAbs(horizontalOffset), horizontalOffset); + } } @@ -161,15 +175,6 @@ QPointF MoveManipulator::findSnappingOffset(const QList &boundingRectLis offset.rx() = verticalOffsetMap.begin().value(); - - QMap horizontalOffsetMap; - foreach (const QRectF &boundingRect, boundingRectList) { - double horizontalOffset = m_snapper.snappedHorizontalOffset(boundingRect); - if (horizontalOffset < std::numeric_limits::max()) - horizontalOffsetMap.insert(qAbs(horizontalOffset), horizontalOffset); - } - - if (!horizontalOffsetMap.isEmpty()) offset.ry() = horizontalOffsetMap.begin().value(); @@ -177,22 +182,33 @@ QPointF MoveManipulator::findSnappingOffset(const QList &boundingRectLis } -void MoveManipulator::generateSnappingLines(const QList &boundingRectList) +void MoveManipulator::generateSnappingLines(const QHash &boundingRectHash) { - m_graphicsLineList = m_snapper.generateSnappingLines(boundingRectList, + m_graphicsLineList = m_snapper.generateSnappingLines(boundingRectHash.values(), m_layerItem.data(), m_snapper.transformtionSpaceFormEditorItem()->sceneTransform()); } -QList MoveManipulator::tanslatedBoundingRects(const QList &boundingRectList, const QPointF& offsetVector) +QHash MoveManipulator::tanslatedBoundingRects(const QHash &boundingRectHash, const QPointF& offsetVector) { - QList translatedBoundingRectList; - foreach (const QRectF &boundingRect, boundingRectList) - translatedBoundingRectList.append(boundingRect.translated(offsetVector)); + QHash translatedBoundingRectHash; - return translatedBoundingRectList; + QHashIterator hashIterator(boundingRectHash); + while(hashIterator.hasNext()) { + QPointF alignedOffset(offsetVector); + hashIterator.next(); + FormEditorItem *formEditorItem = hashIterator.key(); + QRectF boundingRect = hashIterator.value(); + if (formEditorItem->qmlItemNode().hasBindingProperty("x")) + alignedOffset.setX(0); + if (formEditorItem->qmlItemNode().hasBindingProperty("y")) + alignedOffset.setY(0); + translatedBoundingRectHash.insert(formEditorItem, boundingRect.translated(offsetVector)); + } + + return translatedBoundingRectHash; } @@ -220,8 +236,8 @@ void MoveManipulator::update(const QPointF& updatePoint, Snapping useSnapping, S } if (useSnapping == UseSnapping || useSnapping == UseSnappingAndAnchoring) { - offsetVector -= findSnappingOffset(tanslatedBoundingRects(m_beginItemRectHash.values(), offsetVector)); - generateSnappingLines(tanslatedBoundingRects(m_beginItemRectHash.values(), offsetVector)); + offsetVector -= findSnappingOffset(tanslatedBoundingRects(m_beginItemRectHash, offsetVector)); + generateSnappingLines(tanslatedBoundingRects(m_beginItemRectHash, offsetVector)); } foreach (FormEditorItem* item, m_itemList) { @@ -255,7 +271,7 @@ void MoveManipulator::update(const QPointF& updatePoint, Snapping useSnapping, S anchors.setMargin(AnchorLine::VerticalCenter, m_beginVerticalCenterHash.value(item) + offsetVector.y()); } - item->qmlItemNode().setPosition(positionInContainerSpace); + setPosition(item->qmlItemNode(), positionInContainerSpace); } else { item->qmlItemNode().modelNode().variantProperty("x").setValue(qRound(positionInContainerSpace.x())); item->qmlItemNode().modelNode().variantProperty("y").setValue(qRound(positionInContainerSpace.y())); @@ -345,8 +361,8 @@ void MoveManipulator::moveBy(double deltaX, double deltaY) anchors.setMargin(AnchorLine::VerticalCenter, anchors.instanceMargin(AnchorLine::VerticalCenter) + deltaY); } - item->qmlItemNode().setPosition(QPointF(item->qmlItemNode().instanceValue("x").toDouble() + deltaX, - item->qmlItemNode().instanceValue("y").toDouble() + deltaY)); + setPosition(item->qmlItemNode(), QPointF(item->qmlItemNode().instanceValue("x").toDouble() + deltaX, + item->qmlItemNode().instanceValue("y").toDouble() + deltaY)); } } @@ -381,4 +397,13 @@ bool MoveManipulator::isActive() const return m_isActive; } +void MoveManipulator::setPosition(QmlItemNode itemNode, const QPointF &position) +{ + if (!itemNode.hasBindingProperty("x")) + itemNode.setVariantProperty("x", qRound(position.x())); + + if (!itemNode.hasBindingProperty("y")) + itemNode.setVariantProperty("y", qRound(position.y())); +} + } diff --git a/src/plugins/qmldesigner/components/formeditor/movemanipulator.h b/src/plugins/qmldesigner/components/formeditor/movemanipulator.h index 976a4e71ac0..00d7f847e03 100644 --- a/src/plugins/qmldesigner/components/formeditor/movemanipulator.h +++ b/src/plugins/qmldesigner/components/formeditor/movemanipulator.h @@ -86,19 +86,21 @@ public: protected: void setOpacityForAllElements(qreal opacity); - QPointF findSnappingOffset(const QList &boundingRectList); + QPointF findSnappingOffset(const QHash &boundingRectHash); void deleteSnapLines(); - QList tanslatedBoundingRects(const QList &boundingRectList, const QPointF& offset); + QHash tanslatedBoundingRects(const QHash &boundingRectHash, const QPointF& offset); QPointF calculateBoundingRectMovementOffset(const QPointF& updatePoint); QRectF boundingRect(FormEditorItem* item, const QPointF& updatePoint); - void generateSnappingLines(const QList &boundingRectList); + void generateSnappingLines(const QHash &boundingRectHash); void updateHashes(); bool itemsCanReparented() const; + void setPosition(QmlItemNode itemNode, const QPointF &position); + private: Snapper m_snapper; QWeakPointer m_layerItem; diff --git a/src/plugins/qmldesigner/components/formeditor/resizemanipulator.cpp b/src/plugins/qmldesigner/components/formeditor/resizemanipulator.cpp index 4fe8ffd1ae5..7229c786245 100644 --- a/src/plugins/qmldesigner/components/formeditor/resizemanipulator.cpp +++ b/src/plugins/qmldesigner/components/formeditor/resizemanipulator.cpp @@ -146,7 +146,7 @@ void ResizeManipulator::update(const QPointF& updatePoint, Snapping useSnapping) if (boundingRect.height() < minimumHeight) boundingRect.setHeight(minimumHeight); - formEditorItem->qmlItemNode().setSize(boundingRect.size()); + setSize(formEditorItem->qmlItemNode(), boundingRect.size()); if (anchors.instanceHasAnchor(AnchorLine::Bottom)) { @@ -186,8 +186,8 @@ void ResizeManipulator::update(const QPointF& updatePoint, Snapping useSnapping) if (boundingRect.height() < minimumHeight) boundingRect.setTop(boundingRect.top() - minimumHeight + boundingRect.height()); - formEditorItem->qmlItemNode().setSize(boundingRect.size()); - formEditorItem->qmlItemNode().setPositionWithBorder(m_beginToParentTransform.map(boundingRect.topLeft())); + setSize(formEditorItem->qmlItemNode(), boundingRect.size()); + setPosition(formEditorItem->qmlItemNode(), m_beginToParentTransform.map(boundingRect.topLeft())); if (anchors.instanceHasAnchor(AnchorLine::Top)) { @@ -227,8 +227,8 @@ void ResizeManipulator::update(const QPointF& updatePoint, Snapping useSnapping) if (boundingRect.width() < minimumWidth) boundingRect.setWidth(minimumWidth); - formEditorItem->qmlItemNode().setSize(boundingRect.size()); - formEditorItem->qmlItemNode().setPositionWithBorder(m_beginToParentTransform.map(boundingRect.topLeft())); + setSize(formEditorItem->qmlItemNode(), boundingRect.size()); + setPosition(formEditorItem->qmlItemNode(), m_beginToParentTransform.map(boundingRect.topLeft())); if (anchors.instanceHasAnchor(AnchorLine::Top)) { anchors.setMargin(AnchorLine::Top, @@ -267,8 +267,8 @@ void ResizeManipulator::update(const QPointF& updatePoint, Snapping useSnapping) if (boundingRect.width() < minimumWidth) boundingRect.setLeft(boundingRect.left() - minimumWidth + boundingRect.width()); - formEditorItem->qmlItemNode().setSize(boundingRect.size()); - formEditorItem->qmlItemNode().setPositionWithBorder(m_beginToParentTransform.map(boundingRect.topLeft())); + setSize(formEditorItem->qmlItemNode(), boundingRect.size()); + setPosition(formEditorItem->qmlItemNode(), m_beginToParentTransform.map(boundingRect.topLeft())); if (anchors.instanceHasAnchor(AnchorLine::Left)) { anchors.setMargin(AnchorLine::Left, @@ -297,7 +297,7 @@ void ResizeManipulator::update(const QPointF& updatePoint, Snapping useSnapping) if (boundingRect.height() < minimumHeight) boundingRect.setHeight(minimumHeight); - formEditorItem->qmlItemNode().setSize(boundingRect.size()); + setSize(formEditorItem->qmlItemNode(), boundingRect.size()); if (anchors.instanceHasAnchor(AnchorLine::Bottom)) { anchors.setMargin(AnchorLine::Bottom, @@ -321,8 +321,8 @@ void ResizeManipulator::update(const QPointF& updatePoint, Snapping useSnapping) if (boundingRect.height() < minimumHeight) boundingRect.setTop(boundingRect.top() - minimumHeight + boundingRect.height()); - formEditorItem->qmlItemNode().setSize(boundingRect.size()); - formEditorItem->qmlItemNode().setPositionWithBorder(m_beginToParentTransform.map(boundingRect.topLeft())); + setSize(formEditorItem->qmlItemNode(), boundingRect.size()); + setPosition(formEditorItem->qmlItemNode(), m_beginToParentTransform.map(boundingRect.topLeft())); if (anchors.instanceHasAnchor(AnchorLine::Top)) { anchors.setMargin(AnchorLine::Top, @@ -346,7 +346,7 @@ void ResizeManipulator::update(const QPointF& updatePoint, Snapping useSnapping) if (boundingRect.width() < minimumWidth) boundingRect.setWidth(minimumWidth); - formEditorItem->qmlItemNode().setSize(boundingRect.size()); + setSize(formEditorItem->qmlItemNode(), boundingRect.size()); if (anchors.instanceHasAnchor(AnchorLine::Right)) { @@ -371,8 +371,8 @@ void ResizeManipulator::update(const QPointF& updatePoint, Snapping useSnapping) if (boundingRect.width() < minimumWidth) boundingRect.setLeft(boundingRect.left() - minimumWidth + boundingRect.width()); - formEditorItem->qmlItemNode().setSize(boundingRect.size()); - formEditorItem->qmlItemNode().setPositionWithBorder(m_beginToParentTransform.map(boundingRect.topLeft())); + setSize(formEditorItem->qmlItemNode(), boundingRect.size()); + setPosition(formEditorItem->qmlItemNode(), m_beginToParentTransform.map(boundingRect.topLeft())); if (anchors.instanceHasAnchor(AnchorLine::Left)) { anchors.setMargin(AnchorLine::Left, @@ -503,4 +503,23 @@ void ResizeManipulator::clear() removeHandle(); } +void ResizeManipulator::setSize(QmlItemNode itemNode, const QSizeF &size) +{ + int penWidth = (itemNode.instancePenWidth() / 2) * 2; + + if (!itemNode.hasBindingProperty("width")) + itemNode.setVariantProperty("width", qRound(size.width()) - penWidth); + + if (!itemNode.hasBindingProperty("height")) + itemNode.setVariantProperty("height", qRound(size.height()) - penWidth); +} + +void ResizeManipulator::setPosition(QmlItemNode itemNode, const QPointF &position) +{ + if (!itemNode.hasBindingProperty("x")) + itemNode.setVariantProperty("x", qRound(position.x()) + (itemNode.instancePenWidth() / 2)); + + if (!itemNode.hasBindingProperty("y")) + itemNode.setVariantProperty("y", qRound(position.y()) + (itemNode.instancePenWidth() / 2)); +} } diff --git a/src/plugins/qmldesigner/components/formeditor/resizemanipulator.h b/src/plugins/qmldesigner/components/formeditor/resizemanipulator.h index c673563e07f..43a73910dab 100644 --- a/src/plugins/qmldesigner/components/formeditor/resizemanipulator.h +++ b/src/plugins/qmldesigner/components/formeditor/resizemanipulator.h @@ -68,6 +68,8 @@ protected: bool isInvalidSize(const QSizeF & size); void deleteSnapLines(); ResizeHandleItem *resizeHandle(); + void setSize(QmlItemNode itemNode, const QSizeF &size); + void setPosition(QmlItemNode itemNode, const QPointF &position); private: Snapper m_snapper; diff --git a/src/plugins/qmldesigner/components/formeditor/selectiontool.cpp b/src/plugins/qmldesigner/components/formeditor/selectiontool.cpp index 7c42af95bb4..b4175612f6a 100644 --- a/src/plugins/qmldesigner/components/formeditor/selectiontool.cpp +++ b/src/plugins/qmldesigner/components/formeditor/selectiontool.cpp @@ -50,7 +50,7 @@ SelectionTool::SelectionTool(FormEditorView *editorView) m_singleSelectionManipulator(editorView), m_selectionIndicator(editorView->scene()->manipulatorLayerItem()), m_resizeIndicator(editorView->scene()->manipulatorLayerItem()), - m_selectOnlyContentItems(true) + m_selectOnlyContentItems(false) { // view()->setCursor(Qt::CrossCursor); } diff --git a/src/plugins/qmldesigner/components/integration/componentview.cpp b/src/plugins/qmldesigner/components/integration/componentview.cpp index 8d52c3c4a2e..af8a9181e8f 100644 --- a/src/plugins/qmldesigner/components/integration/componentview.cpp +++ b/src/plugins/qmldesigner/components/integration/componentview.cpp @@ -159,6 +159,7 @@ void ComponentView::propertiesRemoved(const QList& /*propertyL void ComponentView::variantPropertiesChanged(const QList& /*propertyList*/, PropertyChangeFlags /*propertyChange*/) {} void ComponentView::bindingPropertiesChanged(const QList& /*propertyList*/, PropertyChangeFlags /*propertyChange*/) {} void ComponentView::rootNodeTypeChanged(const QString &/*type*/, int /*majorVersion*/, int /*minorVersion*/) {} +void ComponentView::scriptFunctionsChanged(const ModelNode &/*node*/, const QStringList &/*scriptFunctionList*/) {} diff --git a/src/plugins/qmldesigner/components/integration/componentview.h b/src/plugins/qmldesigner/components/integration/componentview.h index f4f553d6ef8..b1028b23e2f 100644 --- a/src/plugins/qmldesigner/components/integration/componentview.h +++ b/src/plugins/qmldesigner/components/integration/componentview.h @@ -66,7 +66,7 @@ public: void variantPropertiesChanged(const QList& propertyList, PropertyChangeFlags propertyChange); void bindingPropertiesChanged(const QList& propertyList, PropertyChangeFlags propertyChange); void rootNodeTypeChanged(const QString &type, int majorVersion, int minorVersion); - + void scriptFunctionsChanged(const ModelNode &node, const QStringList &scriptFunctionList); void selectedNodesChanged(const QList &selectedNodeList, diff --git a/src/plugins/qmldesigner/components/integration/designdocumentcontroller.cpp b/src/plugins/qmldesigner/components/integration/designdocumentcontroller.cpp index 5c38be2dcbd..f68dfa0fef4 100644 --- a/src/plugins/qmldesigner/components/integration/designdocumentcontroller.cpp +++ b/src/plugins/qmldesigner/components/integration/designdocumentcontroller.cpp @@ -459,7 +459,7 @@ void DesignDocumentController::deleteSelected() void DesignDocumentController::copySelected() { - QScopedPointer model(Model::create("import Qt 4.7; Qt/Rectangle")); + QScopedPointer model(Model::create("Qt/Rectangle")); model->setMetaInfo(m_d->model->metaInfo()); model->setFileUrl(m_d->model->fileUrl()); diff --git a/src/plugins/qmldesigner/components/integration/designdocumentcontrollerview.cpp b/src/plugins/qmldesigner/components/integration/designdocumentcontrollerview.cpp index e3d695d8885..dc5244f79f3 100644 --- a/src/plugins/qmldesigner/components/integration/designdocumentcontrollerview.cpp +++ b/src/plugins/qmldesigner/components/integration/designdocumentcontrollerview.cpp @@ -56,6 +56,11 @@ void DesignDocumentControllerView::selectedNodesChanged(const QList & void DesignDocumentControllerView::nodeOrderChanged(const NodeListProperty & /*listProperty*/, const ModelNode & /*movedNode*/, int /*oldIndex*/) {}; +void DesignDocumentControllerView::scriptFunctionsChanged(const ModelNode &/*node*/, const QStringList &/*scriptFunctionList*/) +{ +} + + static QStringList arrayToStringList(const QByteArray &byteArray) { QString str(QString::fromLatin1(byteArray)); diff --git a/src/plugins/qmldesigner/components/integration/designdocumentcontrollerview.h b/src/plugins/qmldesigner/components/integration/designdocumentcontrollerview.h index 7a167555883..9632c3569a2 100644 --- a/src/plugins/qmldesigner/components/integration/designdocumentcontrollerview.h +++ b/src/plugins/qmldesigner/components/integration/designdocumentcontrollerview.h @@ -57,6 +57,7 @@ public: const QList &lastSelectedNodeList); virtual void nodeOrderChanged(const NodeListProperty &listProperty, const ModelNode &movedNode, int oldIndex); + virtual void scriptFunctionsChanged(const ModelNode &node, const QStringList &scriptFunctionList); ModelNode insertModel(const ModelNode &modelNode) { return m_modelMerger.insertModel(modelNode); } diff --git a/src/plugins/qmldesigner/components/navigator/navigatorview.cpp b/src/plugins/qmldesigner/components/navigator/navigatorview.cpp index bdbdd634878..44e940b3a6d 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatorview.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatorview.cpp @@ -186,6 +186,11 @@ void NavigatorView::auxiliaryDataChanged(const ModelNode &node, const QString & } } +void NavigatorView::scriptFunctionsChanged(const ModelNode &/*node*/, const QStringList &/*scriptFunctionList*/) +{ +} + + void NavigatorView::nodeOrderChanged(const NodeListProperty &/*listProperty*/, const ModelNode &node, int /*oldIndex*/) { if (m_treeModel->isInTree(node)) diff --git a/src/plugins/qmldesigner/components/navigator/navigatorview.h b/src/plugins/qmldesigner/components/navigator/navigatorview.h index 791498297c6..27ffbb47bc8 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatorview.h +++ b/src/plugins/qmldesigner/components/navigator/navigatorview.h @@ -80,6 +80,7 @@ public: void selectedNodesChanged(const QList &selectedNodeList, const QList &lastSelectedNodeList); void auxiliaryDataChanged(const ModelNode &node, const QString &name, const QVariant &data); + void scriptFunctionsChanged(const ModelNode &node, const QStringList &scriptFunctionList); private slots: diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.cpp index 613f2272888..b4061b1d2b4 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.cpp @@ -798,6 +798,11 @@ void PropertyEditor::nodeIdChanged(const ModelNode& node, const QString& newId, } } +void PropertyEditor::scriptFunctionsChanged(const ModelNode &node, const QStringList &scriptFunctionList) +{ + QmlModelView::scriptFunctionsChanged(node, scriptFunctionList); +} + void PropertyEditor::select(const ModelNode &node) { if (QmlItemNode(node).isValid()) diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.h b/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.h index a3e0bb65710..70cdedda179 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.h +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.h @@ -101,6 +101,7 @@ public: void bindingPropertiesChanged(const QList& propertyList, PropertyChangeFlags propertyChange); void nodeIdChanged(const ModelNode& node, const QString& newId, const QString& oldId); + void scriptFunctionsChanged(const ModelNode &node, const QStringList &scriptFunctionList); protected: void timerEvent(QTimerEvent *event); diff --git a/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp b/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp index 0c76cd254fe..6b0834fed7d 100644 --- a/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp +++ b/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp @@ -399,6 +399,15 @@ void StatesEditorView::customNotification(const AbstractView * view, const QStri QmlModelView::customNotification(view, identifier, nodeList, data); } +void StatesEditorView::scriptFunctionsChanged(const ModelNode &node, const QStringList &scriptFunctionList) +{ + if (debug) + qDebug() << __FUNCTION__; + + QmlModelView::scriptFunctionsChanged(node, scriptFunctionList); +} + + QPixmap StatesEditorView::renderState(int i) { if (debug) diff --git a/src/plugins/qmldesigner/components/stateseditor/stateseditorview.h b/src/plugins/qmldesigner/components/stateseditor/stateseditorview.h index cab2badec75..9e5098c76f4 100644 --- a/src/plugins/qmldesigner/components/stateseditor/stateseditorview.h +++ b/src/plugins/qmldesigner/components/stateseditor/stateseditorview.h @@ -57,7 +57,6 @@ public: void nodeInstancePropertyChanged(const ModelNode &node, const QString &propertyName); -protected: // AbstractView void modelAttached(Model *model); void modelAboutToBeDetached(Model *model); @@ -76,6 +75,7 @@ protected: void otherPropertyChanged(const QmlObjectNode &qmlObjectNode, const QString &propertyName); void customNotification(const AbstractView *view, const QString &identifier, const QList &nodeList, const QList &data); + void scriptFunctionsChanged(const ModelNode &node, const QStringList &scriptFunctionList); protected: diff --git a/src/plugins/qmldesigner/designercore/filemanager/changeimportsvisitor.cpp b/src/plugins/qmldesigner/designercore/filemanager/changeimportsvisitor.cpp index c79e115af62..55534d5d9a2 100644 --- a/src/plugins/qmldesigner/designercore/filemanager/changeimportsvisitor.cpp +++ b/src/plugins/qmldesigner/designercore/filemanager/changeimportsvisitor.cpp @@ -62,7 +62,7 @@ bool ChangeImportsVisitor::add(QmlJS::AST::UiProgram *ast, const Import &import) if (!c.isSpace() && c != QLatin1Char(';')) break; } - replace(insertionPoint, 0, QLatin1String("\n") + import.toString(false)); + replace(insertionPoint+1, 0, QLatin1String("\n") + import.toString(false)); } else { replace(0, 0, import.toString(false) + QLatin1String("\n\n")); } diff --git a/src/plugins/qmldesigner/designercore/include/abstractview.h b/src/plugins/qmldesigner/designercore/include/abstractview.h index 155f18eaff3..1351f83e922 100644 --- a/src/plugins/qmldesigner/designercore/include/abstractview.h +++ b/src/plugins/qmldesigner/designercore/include/abstractview.h @@ -129,6 +129,8 @@ public: virtual void customNotification(const AbstractView *view, const QString &identifier, const QList &nodeList, const QList &data); + virtual void scriptFunctionsChanged(const ModelNode &node, const QStringList &scriptFunctionList) = 0; + QmlModelView *toQmlModelView(); void changeRootNodeType(const QString &type, int majorVersion, int minorVersion); diff --git a/src/plugins/qmldesigner/designercore/include/forwardview.h b/src/plugins/qmldesigner/designercore/include/forwardview.h index 7edeae303ca..a08dcda19c9 100644 --- a/src/plugins/qmldesigner/designercore/include/forwardview.h +++ b/src/plugins/qmldesigner/designercore/include/forwardview.h @@ -76,6 +76,7 @@ public: void auxiliaryDataChanged(const ModelNode &node, const QString &name, const QVariant &data); + void scriptFunctionsChanged(const ModelNode &node, const QStringList &scriptFunctionList); protected: void appendView(ViewType *view); @@ -245,6 +246,13 @@ void ForwardView::auxiliaryDataChanged(const ModelNode &node, const QS view->auxiliaryDataChanged(ModelNode(node, view.data()), name, data); } +template + void ForwardView::scriptFunctionsChanged(const ModelNode &node, const QStringList &scriptFunctionList) +{ + foreach (const ViewTypePointer &view, m_targetViewList) + view->scriptFunctionsChanged(node, scriptFunctionList); +} + template void ForwardView::appendView(ViewType *view) { diff --git a/src/plugins/qmldesigner/designercore/include/model.h b/src/plugins/qmldesigner/designercore/include/model.h index 641c1cd5744..a8523623d9e 100644 --- a/src/plugins/qmldesigner/designercore/include/model.h +++ b/src/plugins/qmldesigner/designercore/include/model.h @@ -96,7 +96,7 @@ public: // Editing sub-components: // Imports: - QSet imports() const; + QList imports() const; void addImport(const Import &import); void removeImport(const Import &import); diff --git a/src/plugins/qmldesigner/designercore/include/modelnode.h b/src/plugins/qmldesigner/designercore/include/modelnode.h index 1e6ec3b3db0..8d0e9033203 100644 --- a/src/plugins/qmldesigner/designercore/include/modelnode.h +++ b/src/plugins/qmldesigner/designercore/include/modelnode.h @@ -135,6 +135,10 @@ public: bool hasNodeProperty(const QString &name) const; bool hasNodeListProperty(const QString &name) const; + + void setScriptFunctions(const QStringList &scriptFunctionList); + QStringList scriptFunctions() const; + //### void destroy(); diff --git a/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h b/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h index 6483f55c7b8..64835fbe367 100644 --- a/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h +++ b/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h @@ -84,6 +84,8 @@ public: void nodeIdChanged(const ModelNode& node, const QString& newId, const QString& oldId); void nodeOrderChanged(const NodeListProperty &listProperty, const ModelNode &movedNode, int oldIndex); void selectedNodesChanged(const QList &selectedNodeList, const QList &lastSelectedNodeList); + void scriptFunctionsChanged(const ModelNode &node, const QStringList &scriptFunctionList); + QList instances() const; NodeInstance instanceForNode(const ModelNode &node); diff --git a/src/plugins/qmldesigner/designercore/include/qmlitemnode.h b/src/plugins/qmldesigner/designercore/include/qmlitemnode.h index 07f0d48889b..28e927af089 100644 --- a/src/plugins/qmldesigner/designercore/include/qmlitemnode.h +++ b/src/plugins/qmldesigner/designercore/include/qmlitemnode.h @@ -71,13 +71,11 @@ public: QTransform instanceSceneTransform() const; QPointF instancePosition() const; QSizeF instanceSize() const; + int instancePenWidth() const; + void paintInstance(QPainter *painter) const; - void setSize(const QSizeF &size); - void setPosition(const QPointF &position); - void setPositionWithBorder(const QPointF &position); - void selectNode(); void deselectNode(); bool isSelected() const; diff --git a/src/plugins/qmldesigner/designercore/include/rewriterview.h b/src/plugins/qmldesigner/designercore/include/rewriterview.h index 2e4cd1e0257..77875ff64fb 100644 --- a/src/plugins/qmldesigner/designercore/include/rewriterview.h +++ b/src/plugins/qmldesigner/designercore/include/rewriterview.h @@ -124,6 +124,7 @@ public: void nodeOrderChanged(const NodeListProperty &listProperty, const ModelNode &movedNode, int oldIndex); void rootNodeTypeChanged(const QString &type, int majorVersion, int minorVersion); void customNotification(const AbstractView *view, const QString &identifier, const QList &nodeList, const QList &data); + void scriptFunctionsChanged(const ModelNode &node, const QStringList &scriptFunctionList); void importAdded(const Import &import); void importRemoved(const Import &import); diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstancesignalspy.cpp b/src/plugins/qmldesigner/designercore/instances/nodeinstancesignalspy.cpp index f28a8768ab5..d47bf05fe37 100644 --- a/src/plugins/qmldesigner/designercore/instances/nodeinstancesignalspy.cpp +++ b/src/plugins/qmldesigner/designercore/instances/nodeinstancesignalspy.cpp @@ -26,10 +26,16 @@ void NodeInstanceSignalSpy::setObjectNodeInstance(const ObjectNodeInstance::Poin void NodeInstanceSignalSpy::registerObject(QObject *spiedObject, const QString &prefix) { + if (registeredObjectList.contains(spiedObject)) // prevent cycles + return; + + registeredObjectList.append(spiedObject); for (int index = QObject::staticMetaObject.propertyOffset(); index < spiedObject->metaObject()->propertyCount(); index++) { QMetaProperty metaProperty = spiedObject->metaObject()->property(index); + + // handle dot properties and connect the signals to the object if (metaProperty.isReadable() && !metaProperty.isWritable() && QDeclarativeMetaType::isQObject(metaProperty.userType())) { @@ -43,6 +49,28 @@ void NodeInstanceSignalSpy::registerObject(QObject *spiedObject, const QString & m_indexPropertyHash.insert(methodeOffset, prefix + metaProperty.name()); methodeOffset++; } + + // search recursive in objects + if (metaProperty.isReadable() + && metaProperty.isWritable() + && QDeclarativeMetaType::isQObject(metaProperty.userType())) { + QObject *propertyObject = QDeclarativeMetaType::toQObject(metaProperty.read(spiedObject)); + if (propertyObject) + registerObject(propertyObject, prefix + metaProperty.name() + "/"); + } + + // search recursive in objects list + if (metaProperty.isReadable() + && QDeclarativeMetaType::isList(metaProperty.userType())) { + QDeclarativeListReference list(spiedObject, metaProperty.name()); + if (list.canCount() && list.canAt()) { + for (int i = 0; i < list.count(); i++) { + QObject *propertyObject = list.at(i); + if (propertyObject) + registerObject(propertyObject, prefix + metaProperty.name() + "/"); + } + } + } } } diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstancesignalspy.h b/src/plugins/qmldesigner/designercore/instances/nodeinstancesignalspy.h index ff33b8cdbef..94cef6d2321 100644 --- a/src/plugins/qmldesigner/designercore/instances/nodeinstancesignalspy.h +++ b/src/plugins/qmldesigner/designercore/instances/nodeinstancesignalspy.h @@ -27,6 +27,7 @@ protected: private: int methodeOffset; QHash m_indexPropertyHash; + QObjectList registeredObjectList; ObjectNodeInstanceWeakPointer m_objectNodeInstance; }; diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp index 39876a08a78..443c189d0c9 100644 --- a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp +++ b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp @@ -374,6 +374,10 @@ void NodeInstanceView::selectedNodesChanged(const QList &/*selectedNo { } +void NodeInstanceView::scriptFunctionsChanged(const ModelNode &/*node*/, const QStringList &/*scriptFunctionList*/) +{ + +} //\} diff --git a/src/plugins/qmldesigner/designercore/instances/qmlgraphicsitemnodeinstance.cpp b/src/plugins/qmldesigner/designercore/instances/qmlgraphicsitemnodeinstance.cpp index 4f7c39d9db4..121b6e03113 100644 --- a/src/plugins/qmldesigner/designercore/instances/qmlgraphicsitemnodeinstance.cpp +++ b/src/plugins/qmldesigner/designercore/instances/qmlgraphicsitemnodeinstance.cpp @@ -196,6 +196,9 @@ QRectF QmlGraphicsItemNodeInstance::boundingRect() const void QmlGraphicsItemNodeInstance::setPropertyVariant(const QString &name, const QVariant &value) { + if (name == "state") + return; // states are only set by us + if (name == "height") { if (value.isValid()) m_hasHeight = true; @@ -215,6 +218,9 @@ void QmlGraphicsItemNodeInstance::setPropertyVariant(const QString &name, const void QmlGraphicsItemNodeInstance::setPropertyBinding(const QString &name, const QString &expression) { + if (name == "state") + return; // states are only set by us + GraphicsObjectNodeInstance::setPropertyBinding(name, expression); } diff --git a/src/plugins/qmldesigner/designercore/model/internalnode.cpp b/src/plugins/qmldesigner/designercore/model/internalnode.cpp index 9d4d5ac0ff9..442e67c3aee 100644 --- a/src/plugins/qmldesigner/designercore/model/internalnode.cpp +++ b/src/plugins/qmldesigner/designercore/model/internalnode.cpp @@ -313,5 +313,15 @@ bool operator <(const InternalNode::Pointer &firstNode, const InternalNode::Poin return firstNode.data() < secondNode.data(); } +void InternalNode::setScriptFunctions(const QStringList &scriptFunctionList) +{ + m_scriptFunctionList = scriptFunctionList; +} + +QStringList InternalNode::scriptFunctions() const +{ + return m_scriptFunctionList; +} + } } diff --git a/src/plugins/qmldesigner/designercore/model/internalnode_p.h b/src/plugins/qmldesigner/designercore/model/internalnode_p.h index 840744738d6..8c5e317e487 100644 --- a/src/plugins/qmldesigner/designercore/model/internalnode_p.h +++ b/src/plugins/qmldesigner/designercore/model/internalnode_p.h @@ -34,6 +34,7 @@ #include #include #include +#include #include "internalproperty.h" #include "internalvariantproperty.h" #include "internalbindingproperty.h" @@ -112,6 +113,9 @@ public: QList allSubNodes() const; QList allDirectSubNodes() const; + void setScriptFunctions(const QStringList &scriptFunctionList); + QStringList scriptFunctions() const; + protected: Pointer internalPointer() const; void setInternalWeakPointer(const Pointer &pointer); @@ -133,6 +137,7 @@ private: bool m_valid; QHash m_namePropertyHash; + QStringList m_scriptFunctionList; }; uint qHash(const InternalNodePointer& node); diff --git a/src/plugins/qmldesigner/designercore/model/model.cpp b/src/plugins/qmldesigner/designercore/model/model.cpp index 3cfafe5008c..7c0bc1d90f2 100644 --- a/src/plugins/qmldesigner/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/designercore/model/model.cpp @@ -122,13 +122,13 @@ void ModelPrivate::addImport(const Import &import) if (m_imports.contains(import)) return; - m_imports.insert(import); + m_imports.append(import); notifyImportAdded(import); } void ModelPrivate::removeImport(const Import &import) { - if (!m_imports.remove(import)) + if (!m_imports.removeOne(import)) return; notifyImportRemoved(import); @@ -531,6 +531,29 @@ void ModelPrivate::notifyBindingPropertiesChanged(const QList &view, m_viewList) { + Q_ASSERT(view != 0); + + + ModelNode node(internalNodePointer, model(), view.data()); + try { + view->scriptFunctionsChanged(node, scriptFunctionList); + } catch (RewritingException &e) { + description = e.description(); + resetModel = true; + } + } + if (resetModel) { + resetModelByRewriter(description); + } +} + + void ModelPrivate::notifyVariantPropertiesChanged(const InternalNodePointer &internalNodePointer, const QStringList& propertyNameList, AbstractView::PropertyChangeFlags propertyChange) { bool resetModel = false; @@ -840,6 +863,13 @@ void ModelPrivate::changeRootNodeType(const QString &type, int majorVersion, int notifyRootNodeTypeChanged(type, majorVersion, minorVersion); } +void ModelPrivate::setScriptFunctions(const InternalNode::Pointer &internalNode, const QStringList &scriptFunctionList) +{ + internalNode->setScriptFunctions(scriptFunctionList); + + notifyScriptFunctionsChanged(internalNode, scriptFunctionList); +} + void ModelPrivate::changeNodeOrder(const InternalNode::Pointer &internalParentNode, const QString &listPropertyName, int from, int to) { InternalNodeListProperty::Pointer nodeList(internalParentNode->nodeListProperty(listPropertyName)); @@ -1004,7 +1034,7 @@ Model *Model::create(QString type, int major, int minor) // return subModel; //} -QSet Model::imports() const +QList Model::imports() const { return m_d->imports(); } diff --git a/src/plugins/qmldesigner/designercore/model/model_p.h b/src/plugins/qmldesigner/designercore/model/model_p.h index fcd38b37166..f678e362db7 100644 --- a/src/plugins/qmldesigner/designercore/model/model_p.h +++ b/src/plugins/qmldesigner/designercore/model/model_p.h @@ -132,6 +132,7 @@ public: void notifyPropertiesAboutToBeRemoved(const QList &propertyList); void notifyBindingPropertiesChanged(const QList &propertyList, AbstractView::PropertyChangeFlags propertyChange); void notifyVariantPropertiesChanged(const InternalNodePointer &internalNodePointer, const QStringList& propertyNameList, AbstractView::PropertyChangeFlags propertyChange); + void notifyScriptFunctionsChanged(const InternalNodePointer &internalNodePointer, const QStringList &scriptFunctionList); void notifyNodeOrderChanged(const InternalNodeListPropertyPointer &internalListPropertyPointer, const InternalNodePointer &internalNodePointer, int oldIndex); void notifyAuxiliaryDataChanged(const InternalNodePointer &internalNode, const QString &name, const QVariant &data); @@ -140,6 +141,8 @@ public: void notifyCustomNotification(const AbstractView *senderView, const QString &identifier, const QList &nodeList, const QList &data); + + void setSelectedNodes(const QList &selectedNodeList); void clearSelectedNodes(); QList selectedNodes() const; @@ -154,7 +157,7 @@ public: // Imports: - QSet imports() const { return m_imports; } + QList imports() const { return m_imports; } void addImport(const Import &import); void removeImport(const Import &import); void notifyImportAdded(const Import &import) const; @@ -176,6 +179,7 @@ public: void checkPropertyName(const QString &propertyName); void clearParent(const InternalNodePointer &internalNode); void changeRootNodeType(const QString &type, int majorVersion, int minorVersion); + void setScriptFunctions(const InternalNodePointer &internalNode, const QStringList &scriptFunctionList); InternalNodePointer nodeForId(const QString &id) const; bool hasId(const QString &id) const; @@ -197,7 +201,7 @@ private: Model *m_q; MetaInfo m_metaInfo; - QSet m_imports; + QList m_imports; QList > m_viewList; QList m_selectedNodeList; QHash m_idNodeHash; diff --git a/src/plugins/qmldesigner/designercore/model/modelmerger.cpp b/src/plugins/qmldesigner/designercore/model/modelmerger.cpp index 549b9861ee8..7e9290cda76 100644 --- a/src/plugins/qmldesigner/designercore/model/modelmerger.cpp +++ b/src/plugins/qmldesigner/designercore/model/modelmerger.cpp @@ -170,9 +170,8 @@ void ModelMerger::replaceModel(const ModelNode &modelNode) { RewriterTransaction transaction(view()->beginRewriterTransaction()); -// foreach (const Import &import, modelNode.model()->imports()) { - //view()->model()->addImport(import); //### -// } + foreach (const Import &import, modelNode.model()->imports()) + view()->model()->addImport(import); view()->model()->setFileUrl(modelNode.model()->fileUrl()); ModelNode rootNode(view()->rootModelNode()); diff --git a/src/plugins/qmldesigner/designercore/model/modelnode.cpp b/src/plugins/qmldesigner/designercore/model/modelnode.cpp index ec8c6e36515..722f93777f3 100644 --- a/src/plugins/qmldesigner/designercore/model/modelnode.cpp +++ b/src/plugins/qmldesigner/designercore/model/modelnode.cpp @@ -908,4 +908,14 @@ bool ModelNode::hasAuxiliaryData(const QString &name) const return internalNode()->hasAuxiliaryData(name); } +void ModelNode::setScriptFunctions(const QStringList &scriptFunctionList) +{ + model()->m_d->setScriptFunctions(internalNode(), scriptFunctionList); +} + +QStringList ModelNode::scriptFunctions() const +{ + return internalNode()->scriptFunctions(); +} + } diff --git a/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp b/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp index c9e22350802..746d3ffa916 100644 --- a/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp +++ b/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp @@ -191,34 +191,17 @@ QSizeF QmlItemNode::instanceSize() const return nodeInstance().size(); } +int QmlItemNode::instancePenWidth() const +{ + return nodeInstance().penWidth(); +} + void QmlItemNode::paintInstance(QPainter *painter) const { if (nodeInstance().isValid()) nodeInstance().paint(painter); } -void QmlItemNode::setSize(const QSizeF &size) -{ - int penWidth = (nodeInstance().penWidth() / 2) * 2; - RewriterTransaction transaction = qmlModelView()->beginRewriterTransaction(); - setVariantProperty("width", qRound(size.width()) - penWidth); - setVariantProperty("height", qRound(size.height()) - penWidth); -} - -void QmlItemNode::setPosition(const QPointF &position) -{ - RewriterTransaction transaction = qmlModelView()->beginRewriterTransaction(); - setVariantProperty("x", qRound(position.x())); - setVariantProperty("y", qRound(position.y())); -} - -void QmlItemNode::setPositionWithBorder(const QPointF &position) -{ - RewriterTransaction transaction = qmlModelView()->beginRewriterTransaction(); - setVariantProperty("x", qRound(position.x()) + (nodeInstance().penWidth() / 2)); - setVariantProperty("y", qRound(position.y()) + (nodeInstance().penWidth() / 2)); -} - void QmlItemNode::selectNode() { modelNode().selectNode(); diff --git a/src/plugins/qmldesigner/designercore/model/qmlmodelview.cpp b/src/plugins/qmldesigner/designercore/model/qmlmodelview.cpp index d11d5f93ab0..ad888c5ae49 100644 --- a/src/plugins/qmldesigner/designercore/model/qmlmodelview.cpp +++ b/src/plugins/qmldesigner/designercore/model/qmlmodelview.cpp @@ -98,6 +98,24 @@ QmlItemNode QmlModelView::createQmlItemNodeFromImage(const QString &imageName, c QmlItemNode newNode; RewriterTransaction transaction = beginRewriterTransaction(); { + const QString newImportUrl = QLatin1String("Qt"); + const QString newImportVersion = QLatin1String("4.7"); + Import newImport = Import::createLibraryImport(newImportUrl, newImportVersion); + + foreach (const Import &import, model()->imports()) { + if (import.isLibraryImport() + && import.url() == newImport.url() + && import.version() == newImport.version()) { + // reuse this import + newImport = import; + break; + } + } + + if (!model()->imports().contains(newImport)) { + model()->addImport(newImport); + } + QList > propertyPairList; propertyPairList.append(qMakePair(QString("x"), QVariant( round(position.x(), 4)))); propertyPairList.append(qMakePair(QString("y"), QVariant( round(position.y(), 4)))); @@ -111,7 +129,7 @@ QmlItemNode QmlModelView::createQmlItemNodeFromImage(const QString &imageName, c } propertyPairList.append(qMakePair(QString("source"), QVariant(relativeImageName))); - newNode = createQmlItemNode("Qt/Image",4, 7, propertyPairList); + newNode = createQmlItemNode("Qt/Image", 4, 7, propertyPairList); parentNode.nodeAbstractProperty("data").reparentHere(newNode); Q_ASSERT(newNode.isValid()); @@ -146,10 +164,29 @@ QmlItemNode QmlModelView::createQmlItemNode(const ItemLibraryEntry &itemLibraryE Q_ASSERT(parentNode.isValid()); - QmlItemNode newNode; RewriterTransaction transaction = beginRewriterTransaction(); { + if (itemLibraryEntry.typeName().contains('.')) { + const QString newImportUrl = itemLibraryEntry.typeName().split('/').first(); + const QString newImportVersion = QString("%1.%2").arg(QString::number(itemLibraryEntry.majorVersion()), QString::number(itemLibraryEntry.minorVersion())); + Import newImport = Import::createLibraryImport(newImportUrl, newImportVersion); + + foreach (const Import &import, model()->imports()) { + if (import.isLibraryImport() + && import.url() == newImport.url() + && import.version() == newImport.version()) { + // reuse this import + newImport = import; + break; + } + } + + if (!model()->imports().contains(newImport)) { + model()->addImport(newImport); + } + } + QList > propertyPairList; propertyPairList.append(qMakePair(QString("x"), QVariant(round(position.x(), 4)))); propertyPairList.append(qMakePair(QString("y"), QVariant(round(position.y(), 4)))); diff --git a/src/plugins/qmldesigner/designercore/model/qmltextgenerator.cpp b/src/plugins/qmldesigner/designercore/model/qmltextgenerator.cpp index 8ad16ab0b5e..f912214db8f 100644 --- a/src/plugins/qmldesigner/designercore/model/qmltextgenerator.cpp +++ b/src/plugins/qmldesigner/designercore/model/qmltextgenerator.cpp @@ -35,6 +35,7 @@ #include "nodelistproperty.h" #include "qmltextgenerator.h" #include "variantproperty.h" +#include "model.h" using namespace QmlDesigner; using namespace QmlDesigner::Internal; @@ -122,11 +123,31 @@ QString QmlTextGenerator::toQml(const AbstractProperty &property, int indentDept QString QmlTextGenerator::toQml(const ModelNode &node, int indentDepth) const { QString type = node.type(); - int lastSlashIndex = type.lastIndexOf('/'); - if (lastSlashIndex != -1) - type = type.mid(lastSlashIndex + 1); + QString url; + if (type.contains('/')) { + QStringList nameComponents = type.split("/"); + url = nameComponents.first(); + type = nameComponents.last(); + } - QString result = type; + QString alias; + if (!url.isEmpty()) { + const QString &versionUrl = QString("%1.%2").arg(QString::number(node.majorVersion()), QString::number(node.minorVersion())); + foreach (const Import &import, node.model()->imports()) { + if (import.url() == url + && import.version() == versionUrl) { + alias = import.alias(); + break; + } + } + } + + QString result; + + if (!alias.isEmpty()) + result = alias + "."; + + result += type; result += QLatin1String(" {\n"); const int propertyIndentDepth = indentDepth + 4; diff --git a/src/plugins/qmldesigner/designercore/model/rewriteaction.cpp b/src/plugins/qmldesigner/designercore/model/rewriteaction.cpp index 6475137688b..1d344887ad5 100644 --- a/src/plugins/qmldesigner/designercore/model/rewriteaction.cpp +++ b/src/plugins/qmldesigner/designercore/model/rewriteaction.cpp @@ -369,7 +369,7 @@ QString AddImportRewriteAction::info() const bool RemoveImportRewriteAction::execute(QmlDesigner::QmlRefactoring &refactoring, ModelNodePositionStorage &/*positionStore*/) { - const bool result = refactoring.addImport(m_import); + const bool result = refactoring.removeImport(m_import); if (!result) qDebug() << "*** RemoveImportRewriteAction::execute failed in changeImports (" diff --git a/src/plugins/qmldesigner/designercore/model/rewriterview.cpp b/src/plugins/qmldesigner/designercore/model/rewriterview.cpp index 31a29ae8046..6b0ea3517c3 100644 --- a/src/plugins/qmldesigner/designercore/model/rewriterview.cpp +++ b/src/plugins/qmldesigner/designercore/model/rewriterview.cpp @@ -352,6 +352,10 @@ void RewriterView::customNotification(const AbstractView * /*view*/, const QStri } } +void RewriterView::scriptFunctionsChanged(const ModelNode &/*node*/, const QStringList &/*scriptFunctionList*/) +{ +} + void RewriterView::selectedNodesChanged(const QList & /* selectedNodeList, */, const QList & /*lastSelectedNodeList */) { } diff --git a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp index a95e1be6282..af5b789c838 100644 --- a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp +++ b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp @@ -491,7 +491,7 @@ bool TextToModelMerger::isActive() const void TextToModelMerger::setupImports(const Document::Ptr &doc, DifferenceHandler &differenceHandler) { - QSet existingImports = m_rewriterView->model()->imports(); + QList existingImports = m_rewriterView->model()->imports(); for (UiImportList *iter = doc->qmlProgram()->imports; iter; iter = iter->next) { UiImport *import = iter->import; @@ -510,13 +510,13 @@ void TextToModelMerger::setupImports(const Document::Ptr &doc, const Import newImport = Import::createFileImport(strippedFileName, version, as); - if (!existingImports.remove(newImport)) + if (!existingImports.removeOne(newImport)) differenceHandler.modelMissesImport(newImport); } else { const Import newImport = - Import::createLibraryImport(flatten(import->importUri), as, version); + Import::createLibraryImport(flatten(import->importUri), version, as); - if (!existingImports.remove(newImport)) + if (!existingImports.removeOne(newImport)) differenceHandler.modelMissesImport(newImport); } } diff --git a/src/plugins/qmldesigner/designercore/model/viewlogger.cpp b/src/plugins/qmldesigner/designercore/model/viewlogger.cpp index 4f4c02896c3..9fb44e8e1b3 100644 --- a/src/plugins/qmldesigner/designercore/model/viewlogger.cpp +++ b/src/plugins/qmldesigner/designercore/model/viewlogger.cpp @@ -192,6 +192,12 @@ void ViewLogger::customNotification(const AbstractView *view, const QString &ide m_output << time() << indent("data: ") << variant.toString() << endl; } +void ViewLogger::scriptFunctionsChanged(const ModelNode &node, const QStringList &/*scriptFunctionList*/) +{ + m_output << time() << indent("function scripts changed:") << node << endl; + +} + } // namespace Internal } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/model/viewlogger.h b/src/plugins/qmldesigner/designercore/model/viewlogger.h index 321e41fce5a..cdadd623734 100644 --- a/src/plugins/qmldesigner/designercore/model/viewlogger.h +++ b/src/plugins/qmldesigner/designercore/model/viewlogger.h @@ -70,6 +70,7 @@ public: void auxiliaryDataChanged(const ModelNode &node, const QString &name, const QVariant &data); void customNotification(const AbstractView *view, const QString &identifier, const QList &nodeList, const QList &data); + void scriptFunctionsChanged(const ModelNode &node, const QStringList &scriptFunctionList); protected: QString time() const; diff --git a/src/plugins/qmljseditor/qmljseditor.pro b/src/plugins/qmljseditor/qmljseditor.pro index acd9da1afaf..0058d8b9bb9 100644 --- a/src/plugins/qmljseditor/qmljseditor.pro +++ b/src/plugins/qmljseditor/qmljseditor.pro @@ -3,7 +3,6 @@ TARGET = QmlJSEditor include(../../qtcreatorplugin.pri) include(qmljseditor_dependencies.pri) -CONFIG += help DEFINES += \ QMLJSEDITOR_LIBRARY \ QT_CREATOR diff --git a/src/plugins/qmljseditor/qmljshoverhandler.cpp b/src/plugins/qmljseditor/qmljshoverhandler.cpp index 2810fdb4c36..31e923b40c2 100644 --- a/src/plugins/qmljseditor/qmljshoverhandler.cpp +++ b/src/plugins/qmljseditor/qmljshoverhandler.cpp @@ -32,6 +32,7 @@ #include "qmljshoverhandler.h" #include +#include #include #include #include @@ -52,7 +53,6 @@ #include #include #include -#include using namespace Core; using namespace QmlJS; @@ -61,27 +61,11 @@ using namespace QmlJSEditor::Internal; HoverHandler::HoverHandler(QObject *parent) : QObject(parent) - , m_helpEngineNeedsSetup(false) { m_modelManager = ExtensionSystem::PluginManager::instance()->getObject(); - ICore *core = ICore::instance(); - QFileInfo fi(core->settings()->fileName()); - // FIXME shouldn't the help engine create the directory if it doesn't exist? - QDir directory(fi.absolutePath()+"/qtcreator"); - if (!directory.exists()) - directory.mkpath(directory.absolutePath()); - - m_helpEngine = new QHelpEngineCore(directory.absolutePath() - + QLatin1String("/helpcollection.qhc"), this); - if (!m_helpEngine->setupData()) - qWarning() << "Could not initialize help engine:" << m_helpEngine->error(); - m_helpEngine->setAutoSaveFilter(false); - m_helpEngine->setCurrentFilter(tr("Unfiltered")); - m_helpEngineNeedsSetup = m_helpEngine->registeredDocumentations().count() == 0; - // Listen for editor opened events in order to connect to tooltip/helpid requests - connect(core->editorManager(), SIGNAL(editorOpened(Core::IEditor *)), + connect(ICore::instance()->editorManager(), SIGNAL(editorOpened(Core::IEditor *)), this, SLOT(editorOpened(Core::IEditor *))); } @@ -151,11 +135,6 @@ void HoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, int p const Snapshot snapshot = semanticInfo.snapshot; const Document::Ptr qmlDocument = semanticInfo.document; - if (m_helpEngineNeedsSetup && m_helpEngine->registeredDocumentations().count() > 0) { - m_helpEngine->setupData(); - m_helpEngineNeedsSetup = false; - } - // We only want to show F1 if the tooltip matches the help id bool showF1 = true; @@ -188,7 +167,7 @@ void HoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, int p QString helpId = QLatin1String("QML."); helpId += baseClass; - if (! m_helpEngine->linksForIdentifier(helpId).isEmpty()) { + if (!Core::HelpManager::instance()->linksForIdentifier(helpId).isEmpty()) { m_helpId = helpId; break; } diff --git a/src/plugins/qmljseditor/qmljshoverhandler.h b/src/plugins/qmljseditor/qmljshoverhandler.h index f8a1f282ddf..29fbd20ba00 100644 --- a/src/plugins/qmljseditor/qmljshoverhandler.h +++ b/src/plugins/qmljseditor/qmljshoverhandler.h @@ -34,7 +34,6 @@ #include QT_BEGIN_NAMESPACE -class QHelpEngineCore; class QPoint; class QStringList; QT_END_NAMESPACE @@ -79,10 +78,8 @@ private: private: QmlJS::ModelManagerInterface *m_modelManager; - QHelpEngineCore *m_helpEngine; QString m_helpId; QString m_toolTip; - bool m_helpEngineNeedsSetup; }; } // namespace Internal diff --git a/src/plugins/qt4projectmanager/Qt4ProjectManager.pluginspec b/src/plugins/qt4projectmanager/Qt4ProjectManager.pluginspec index 91bf0fb3f09..b5aec34cd0b 100644 --- a/src/plugins/qt4projectmanager/Qt4ProjectManager.pluginspec +++ b/src/plugins/qt4projectmanager/Qt4ProjectManager.pluginspec @@ -18,7 +18,6 @@ Alternatively, this plugin may be used under the terms of the GNU Lesser General - diff --git a/src/plugins/qt4projectmanager/gettingstartedwelcomepagewidget.cpp b/src/plugins/qt4projectmanager/gettingstartedwelcomepagewidget.cpp index 1e82fc64e0e..c84cd25a884 100644 --- a/src/plugins/qt4projectmanager/gettingstartedwelcomepagewidget.cpp +++ b/src/plugins/qt4projectmanager/gettingstartedwelcomepagewidget.cpp @@ -31,6 +31,7 @@ #include "ui_gettingstartedwelcomepagewidget.h" #include +#include #include #include @@ -38,8 +39,6 @@ #include -#include - #include #include #include @@ -338,15 +337,13 @@ void GettingStartedWelcomePageWidget::slotOpenExample() void GettingStartedWelcomePageWidget::slotOpenHelpPage(const QString& url) { - Help::HelpManager *helpManager - = ExtensionSystem::PluginManager::instance()->getObject(); + Core::HelpManager *helpManager = Core::HelpManager::instance(); Q_ASSERT(helpManager); helpManager->handleHelpRequest(url); } void GettingStartedWelcomePageWidget::slotOpenContextHelpPage(const QString& url) { - Help::HelpManager *helpManager - = ExtensionSystem::PluginManager::instance()->getObject(); + Core::HelpManager *helpManager = Core::HelpManager::instance(); Q_ASSERT(helpManager); helpManager->handleHelpRequest(url % QLatin1String("?view=split")); } diff --git a/src/plugins/qt4projectmanager/qmakestep.cpp b/src/plugins/qt4projectmanager/qmakestep.cpp index 12629bf2961..12cbf8ab28b 100644 --- a/src/plugins/qt4projectmanager/qmakestep.cpp +++ b/src/plugins/qt4projectmanager/qmakestep.cpp @@ -176,23 +176,26 @@ bool QMakeStep::init() setEnvironment(qt4bc->environment()); setOutputParser(new QMakeParser); + + Qt4Project *pro = qt4BuildConfiguration()->qt4Target()->qt4Project(); + QString proFile = pro->file()->fileName(); + m_tasks = qt4BuildConfiguration()->qtVersion()->reportIssues(proFile); + m_scriptTemplate = pro->rootProjectNode()->projectType() == ScriptTemplate; + return AbstractProcessStep::init(); } void QMakeStep::run(QFutureInterface &fi) { - Qt4Project *pro = qt4BuildConfiguration()->qt4Target()->qt4Project(); - if (pro->rootProjectNode()->projectType() == ScriptTemplate) { + if (m_scriptTemplate) { fi.reportResult(true); return; } // Warn on common error conditions: - QList issues = - qt4BuildConfiguration()->qtVersion()->reportIssues(qt4BuildConfiguration()->qt4Target()-> - qt4Project()->file()->fileName()); + bool canContinue = true; - foreach (const ProjectExplorer::Task &t, issues) { + foreach (const ProjectExplorer::Task &t, m_tasks) { addTask(t); if (t.type == Task::Error) canContinue = false; diff --git a/src/plugins/qt4projectmanager/qmakestep.h b/src/plugins/qt4projectmanager/qmakestep.h index 79156622d18..bc0de0f4b9a 100644 --- a/src/plugins/qt4projectmanager/qmakestep.h +++ b/src/plugins/qt4projectmanager/qmakestep.h @@ -110,6 +110,8 @@ private: bool m_forced; bool m_needToRunQMake; // set in init(), read in run() QStringList m_userArgs; + bool m_scriptTemplate; + QList m_tasks; }; diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationstep.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationstep.cpp index ffd6750e53e..0b0eeee5428 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationstep.cpp +++ b/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationstep.cpp @@ -59,6 +59,8 @@ #include #include +namespace { const QLatin1String PackagingEnabledKey("Packaging Enabled"); } + using namespace ProjectExplorer::Constants; using ProjectExplorer::BuildConfiguration; using ProjectExplorer::BuildStepConfigWidget; @@ -69,14 +71,16 @@ namespace Internal { MaemoPackageCreationStep::MaemoPackageCreationStep(BuildConfiguration *buildConfig) : ProjectExplorer::BuildStep(buildConfig, CreatePackageId), - m_packageContents(new MaemoPackageContents(this)) + m_packageContents(new MaemoPackageContents(this)), + m_packagingEnabled(true) { } MaemoPackageCreationStep::MaemoPackageCreationStep(BuildConfiguration *buildConfig, MaemoPackageCreationStep *other) : BuildStep(buildConfig, other), - m_packageContents(new MaemoPackageContents(this)) + m_packageContents(new MaemoPackageContents(this)), + m_packagingEnabled(other->m_packagingEnabled) { @@ -90,18 +94,20 @@ bool MaemoPackageCreationStep::init() QVariantMap MaemoPackageCreationStep::toMap() const { QVariantMap map(ProjectExplorer::BuildStep::toMap()); + map.insert(PackagingEnabledKey, m_packagingEnabled); return map.unite(m_packageContents->toMap()); } bool MaemoPackageCreationStep::fromMap(const QVariantMap &map) { m_packageContents->fromMap(map); + m_packagingEnabled = map.value(PackagingEnabledKey, true).toBool(); return ProjectExplorer::BuildStep::fromMap(map); } void MaemoPackageCreationStep::run(QFutureInterface &fi) { - fi.reportResult(createPackage()); + fi.reportResult(m_packagingEnabled ? createPackage() : true); } BuildStepConfigWidget *MaemoPackageCreationStep::createConfigWidget() diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationstep.h b/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationstep.h index f0945db1ddf..7e64737fa3c 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationstep.h +++ b/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationstep.h @@ -69,6 +69,9 @@ public: MaemoPackageContents *packageContents() const { return m_packageContents; } const Qt4BuildConfiguration *qt4BuildConfiguration() const; + bool isPackagingEnabled() const { return m_packagingEnabled; } + void setPackagingEnabled(bool enabled) { m_packagingEnabled = enabled; } + private: MaemoPackageCreationStep(ProjectExplorer::BuildConfiguration *buildConfig, MaemoPackageCreationStep *other); @@ -94,6 +97,7 @@ private: static const QLatin1String CreatePackageId; MaemoPackageContents *const m_packageContents; + bool m_packagingEnabled; }; } // namespace Internal diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationwidget.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationwidget.cpp index e837b21b840..5a51e1e6307 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationwidget.cpp +++ b/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationwidget.cpp @@ -65,6 +65,8 @@ MaemoPackageCreationWidget::MaemoPackageCreationWidget(MaemoPackageCreationStep { m_ui->setupUi(this); m_ui->packageContentsView->setWordWrap(false); + m_ui->skipCheckBox->setChecked(!m_step->isPackagingEnabled()); + m_ui->packageContentsView->setEnabled(m_step->isPackagingEnabled()); m_ui->packageContentsView->setModel(step->packageContents()); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); connect(step->packageContents(), SIGNAL(dataChanged(QModelIndex,QModelIndex)), @@ -138,5 +140,11 @@ void MaemoPackageCreationWidget::enableOrDisableRemoveButton() && selectedRows.first().row() != 0); } +void MaemoPackageCreationWidget::handleSkipButtonToggled(bool checked) +{ + m_step->setPackagingEnabled(!checked); + m_ui->packageContentsView->setEnabled(m_step->isPackagingEnabled()); +} + } // namespace Internal } // namespace Qt4ProjectManager diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationwidget.h b/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationwidget.h index 3c8d10d79c1..ead07fac55f 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationwidget.h +++ b/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationwidget.h @@ -67,6 +67,7 @@ private slots: void addFile(); void removeFile(); void enableOrDisableRemoveButton(); + void handleSkipButtonToggled(bool checked); private: MaemoPackageCreationStep * const m_step; diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationwidget.ui b/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationwidget.ui index a650baa0cbc..ef1ed2334d1 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationwidget.ui +++ b/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationwidget.ui @@ -17,6 +17,20 @@ + + 6 + + + + + Check this if you build the package externally. It still needs to be at the location listed above +and the remote executable is assumed to be in the directory mentioned below. + + + Skip Packaging Step + + + @@ -126,8 +140,8 @@ addFile() - 712 - 44 + 729 + 88 732 @@ -142,8 +156,8 @@ removeFile() - 723 - 77 + 729 + 124 735 @@ -151,9 +165,26 @@ + + skipCheckBox + clicked(bool) + MaemoPackageCreationWidget + handleSkipButtonToggled(bool) + + + 129 + 18 + + + 240 + 31 + + + addFile() removeFile() + handleSkipButtonToggled(bool) diff --git a/src/plugins/qt4projectmanager/qt4project.cpp b/src/plugins/qt4projectmanager/qt4project.cpp index 838be24856d..c09fc97532f 100644 --- a/src/plugins/qt4projectmanager/qt4project.cpp +++ b/src/plugins/qt4projectmanager/qt4project.cpp @@ -320,6 +320,7 @@ bool Qt4Project::fromMap(const QVariantMap &map) updateFileList(); // This might be incorrect, need a full update updateCodeModel(); + createApplicationProjects(); foreach (Target *t, targets()) @@ -1005,10 +1006,26 @@ void Qt4Project::createApplicationProjects() target->removeRunConfiguration(rc); } + // We use the list twice + QList profiles = applicationProFiles(); + QStringList paths; + foreach (Qt4ProFileNode *pro, profiles) + paths << pro->path(); + + foreach (RunConfiguration *rc, target->runConfigurations()) { + if (Qt4RunConfiguration *qt4rc = qobject_cast(rc)) { + if (!paths.contains(qt4rc->proFilePath())) { + // A deleted .pro file? or a change template + // We do remove those though + target->removeRunConfiguration(rc); + } + } + } + // Only add new runconfigurations if there are none. if (target->runConfigurations().isEmpty()) { Qt4Target *qt4Target = static_cast(target); - foreach (Qt4ProFileNode *qt4proFile, applicationProFiles()) { + foreach (Qt4ProFileNode *qt4proFile, profiles) { qt4Target->addRunConfigurationForPath(qt4proFile->path()); } } diff --git a/src/plugins/qt4projectmanager/qt4projectmanager_dependencies.pri b/src/plugins/qt4projectmanager/qt4projectmanager_dependencies.pri index 5e11deb8b51..e40eac29c4b 100644 --- a/src/plugins/qt4projectmanager/qt4projectmanager_dependencies.pri +++ b/src/plugins/qt4projectmanager/qt4projectmanager_dependencies.pri @@ -1,7 +1,6 @@ include(../../plugins/projectexplorer/projectexplorer.pri) include(../../plugins/cpptools/cpptools.pri) include(../../plugins/cppeditor/cppeditor.pri) -include(../../plugins/help/help.pri) include(../../plugins/designer/designer.pri) include(../../plugins/debugger/debugger.pri) include(../../libs/symbianutils/symbianutils.pri) diff --git a/src/plugins/qt4projectmanager/qtversionmanager.cpp b/src/plugins/qt4projectmanager/qtversionmanager.cpp index 9f1fe292f34..39e58e80da6 100644 --- a/src/plugins/qt4projectmanager/qtversionmanager.cpp +++ b/src/plugins/qt4projectmanager/qtversionmanager.cpp @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -211,8 +212,7 @@ QSet QtVersionManager::supportedTargetIds() const void QtVersionManager::updateDocumentation() { - Help::HelpManager *helpManager - = ExtensionSystem::PluginManager::instance()->getObject(); + Core::HelpManager *helpManager = Core::HelpManager::instance(); Q_ASSERT(helpManager); QStringList files; foreach (QtVersion *version, m_versions) { diff --git a/src/shared/help/bookmarkmanager.cpp b/src/shared/help/bookmarkmanager.cpp index e8619922e00..21406b06470 100644 --- a/src/shared/help/bookmarkmanager.cpp +++ b/src/shared/help/bookmarkmanager.cpp @@ -50,10 +50,11 @@ #include #include #include -#include #include #include +#include + using namespace Help::Internal; BookmarkDialog::BookmarkDialog(BookmarkManager *manager, const QString &title, @@ -646,7 +647,7 @@ void BookmarkManager::saveBookmarks() QDataStream stream(&bookmarks, QIODevice::WriteOnly); readBookmarksRecursive(treeModel->invisibleRootItem(), stream, 0); - (&Help::HelpManager::helpEngineCore())->setCustomValue(QLatin1String("Bookmarks"), + (&LocalHelpManager::helpEngine())->setCustomValue(QLatin1String("Bookmarks"), bookmarks); } @@ -765,7 +766,7 @@ void BookmarkManager::setupBookmarkModels() QList lastDepths; QList parents; - QByteArray ba = Help::HelpManager::helpEngineCore() + QByteArray ba = LocalHelpManager::helpEngine() .customValue(QLatin1String("Bookmarks")).toByteArray(); QDataStream stream(ba); while (!stream.atEnd()) { diff --git a/src/shared/help/contentwindow.cpp b/src/shared/help/contentwindow.cpp index a8ed1f1613a..ef3479f170d 100644 --- a/src/shared/help/contentwindow.cpp +++ b/src/shared/help/contentwindow.cpp @@ -45,7 +45,7 @@ ContentWindow::ContentWindow() : m_contentWidget(0) , m_expandDepth(-2) { - m_contentWidget = (&Help::HelpManager::helpEngine())->contentWidget(); + m_contentWidget = (&LocalHelpManager::helpEngine())->contentWidget(); m_contentWidget->installEventFilter(this); m_contentWidget->viewport()->installEventFilter(this); m_contentWidget->setContextMenuPolicy(Qt::CustomContextMenu); diff --git a/src/shared/help/indexwindow.cpp b/src/shared/help/indexwindow.cpp index 1bc86d60ecf..b12d517c6d3 100644 --- a/src/shared/help/indexwindow.cpp +++ b/src/shared/help/indexwindow.cpp @@ -80,7 +80,7 @@ IndexWindow::IndexWindow() toolbar->setLayout(tbLayout); layout->addWidget(toolbar); - QHelpEngine *engine = &Help::HelpManager::helpEngine(); + QHelpEngine *engine = &LocalHelpManager::helpEngine(); m_indexWidget = engine->indexWidget(); m_indexWidget->installEventFilter(this); connect(engine->indexModel(), SIGNAL(indexCreationStarted()), this, diff --git a/src/shared/proparser/ioutils.cpp b/src/shared/proparser/ioutils.cpp index f43c29aa9ae..5ed9ea50220 100644 --- a/src/shared/proparser/ioutils.cpp +++ b/src/shared/proparser/ioutils.cpp @@ -46,7 +46,7 @@ IoUtils::FileType IoUtils::fileType(const QString &fileName) { Q_ASSERT(fileName.isEmpty() || isAbsolutePath(fileName)); #ifdef Q_OS_WIN - DWORD attr = GetFileAttributesW((WCHAR*)fileName.constData()); + DWORD attr = GetFileAttributesW((WCHAR*)fileName.utf16()); if (attr == INVALID_FILE_ATTRIBUTES) return FileNotFound; return (attr & FILE_ATTRIBUTE_DIRECTORY) ? FileIsDir : FileIsRegular; diff --git a/tests/auto/qml/qmldesigner/coretests/testcore.cpp b/tests/auto/qml/qmldesigner/coretests/testcore.cpp index b3a36212ce4..8ff2caba1bc 100644 --- a/tests/auto/qml/qmldesigner/coretests/testcore.cpp +++ b/tests/auto/qml/qmldesigner/coretests/testcore.cpp @@ -767,6 +767,131 @@ void TestCore::testRewriterActionCompression() QCOMPARE(textEdit.toPlainText(), expected); } +void TestCore::testRewriterImports() +{ + QString fileName = QString(QTCREATORDIR) + "/tests/auto/qml/qmldesigner/data/fx/imports.qml"; + QFile file(fileName); + QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text)); + + QPlainTextEdit textEdit; + textEdit.setPlainText(file.readAll()); + NotIndentingTextEditModifier modifier(&textEdit); + + QScopedPointer model(Model::create("Qt/Item")); + model->setFileUrl(QUrl::fromLocalFile(fileName)); + + QScopedPointer testRewriterView(new TestRewriterView()); + testRewriterView->setTextModifier(&modifier); + model->attachView(testRewriterView.data()); + + QVERIFY(testRewriterView->errors().isEmpty()); + + QVERIFY(model->imports().size() == 3); + + // import Qt 4.7 + Import import = model->imports().at(0); + QVERIFY(import.isLibraryImport()); + QCOMPARE(import.url(), QString("Qt")); + QVERIFY(import.hasVersion()); + QCOMPARE(import.version(), QString("4.7")); + QVERIFY(!import.hasAlias()); + + // import "subitems" + import = model->imports().at(1); + QVERIFY(import.isFileImport()); + QCOMPARE(import.file(), QString("subitems")); + QVERIFY(!import.hasVersion()); + QVERIFY(!import.hasAlias()); + + // import org.webkit 1.0 as Web + import = model->imports().at(2); + QVERIFY(import.isLibraryImport()); + QCOMPARE(import.url(), QString("org.webkit")); + QVERIFY(import.hasVersion()); + QCOMPARE(import.version(), QString("1.0")); + QVERIFY(import.hasAlias()); + QCOMPARE(import.alias(), QString("Web")); +} + +void TestCore::testRewriterChangeImports() +{ + const QLatin1String qmlString("\n" + "import Qt 4.7\n" + "\n" + "Rectangle {}\n"); + + QPlainTextEdit textEdit; + textEdit.setPlainText(qmlString); + NotIndentingTextEditModifier modifier(&textEdit); + + QScopedPointer model(Model::create("Qt/Rectangle")); + + QScopedPointer testRewriterView(new TestRewriterView(0, RewriterView::Amend)); + testRewriterView->setTextModifier(&modifier); + model->attachView(testRewriterView.data()); + + QVERIFY(testRewriterView->errors().isEmpty()); + + // + // Add / Remove an import in the model + // + Import webkitImport = Import::createLibraryImport("org.webkit", "1.0"); + model->addImport(webkitImport); + + const QLatin1String qmlWithImport("\n" + "import Qt 4.7\n" + "import org.webkit 1.0\n" + "\n" + "Rectangle {}\n"); + QCOMPARE(textEdit.toPlainText(), qmlWithImport); + + model->removeImport(webkitImport); + + QCOMPARE(model->imports().size(), 1); + QCOMPARE(model->imports().first(), Import::createLibraryImport("Qt", "4.7")); + + QCOMPARE(textEdit.toPlainText(), qmlString); + + + // + // Add / Remove an import in the model (with alias) + // + webkitImport = Import::createLibraryImport("org.webkit", "1.0", "Web"); + model->addImport(webkitImport); + + const QLatin1String qmlWithAliasImport("\n" + "import Qt 4.7\n" + "import org.webkit 1.0 as Web\n" + "\n" + "Rectangle {}\n"); + QCOMPARE(textEdit.toPlainText(), qmlWithAliasImport); + + model->removeImport(webkitImport); + + QCOMPARE(model->imports().size(), 1); + QCOMPARE(model->imports().first(), Import::createLibraryImport("Qt", "4.7")); + + QCOMPARE(textEdit.toPlainText(), qmlString); + + + // + // Add / Remove an import in text + // + textEdit.setPlainText(qmlWithImport); + QCOMPARE(model->imports().size(), 2); + QCOMPARE(model->imports().first(), Import::createLibraryImport("Qt", "4.7")); + QCOMPARE(model->imports().last(), Import::createLibraryImport("org.webkit", "1.0")); + + textEdit.setPlainText(qmlWithAliasImport); + QCOMPARE(model->imports().size(), 2); + QCOMPARE(model->imports().first(), Import::createLibraryImport("Qt", "4.7")); + QCOMPARE(model->imports().last(), Import::createLibraryImport("org.webkit", "1.0", "Web")); + + textEdit.setPlainText(qmlString); + QCOMPARE(model->imports().size(), 1); + QCOMPARE(model->imports().first(), Import::createLibraryImport("Qt", "4.7")); +} + void TestCore::testRewriterForGradientMagic() { const QLatin1String qmlString("\n" diff --git a/tests/auto/qml/qmldesigner/coretests/testcore.h b/tests/auto/qml/qmldesigner/coretests/testcore.h index 685a1e6a729..3f29d22be15 100644 --- a/tests/auto/qml/qmldesigner/coretests/testcore.h +++ b/tests/auto/qml/qmldesigner/coretests/testcore.h @@ -129,6 +129,8 @@ private slots: void testRewriterGroupedProperties(); void testRewriterPreserveOrder(); void testRewriterActionCompression(); + void testRewriterImports(); + void testRewriterChangeImports(); // // unit tests QmlModelNodeFacade/QmlModelState diff --git a/tests/auto/qml/qmldesigner/data/fx/imports.qml b/tests/auto/qml/qmldesigner/data/fx/imports.qml new file mode 100644 index 00000000000..0c528046e0f --- /dev/null +++ b/tests/auto/qml/qmldesigner/data/fx/imports.qml @@ -0,0 +1,6 @@ +import Qt 4.7 +import "subitems" +import org.webkit 1.0 as Web + +Rectangle { +}