From c37f4d05d84857a0004829dc296b34349f26446a Mon Sep 17 00:00:00 2001 From: Patrick Star Date: Thu, 4 Dec 2008 13:44:15 +0100 Subject: [PATCH 01/25] Fixes: - missing F1 in tooltip on first IDE start --- src/plugins/cpptools/cpphoverhandler.cpp | 9 ++++++++- src/plugins/cpptools/cpphoverhandler.h | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/plugins/cpptools/cpphoverhandler.cpp b/src/plugins/cpptools/cpphoverhandler.cpp index 37b63bda9c2..16ed8a92150 100644 --- a/src/plugins/cpptools/cpphoverhandler.cpp +++ b/src/plugins/cpptools/cpphoverhandler.cpp @@ -60,7 +60,7 @@ using namespace CppTools::Internal; CppHoverHandler::CppHoverHandler(CppModelManager *manager, QObject *parent) - : QObject(parent), m_manager(manager) + : QObject(parent), m_manager(manager), m_helpEngineNeedsSetup(false) { QFileInfo fi(ExtensionSystem::PluginManager::instance()->getObject()->settings()->fileName()); m_helpEngine = new QHelpEngineCore(fi.absolutePath() @@ -68,6 +68,7 @@ CppHoverHandler::CppHoverHandler(CppModelManager *manager, QObject *parent) //m_helpEngine->setAutoSaveFilter(false); m_helpEngine->setupData(); m_helpEngine->setCurrentFilter(tr("Unfiltered")); + m_helpEngineNeedsSetup = m_helpEngine->registeredDocumentations().count() == 0; } void CppHoverHandler::updateContextHelpId(TextEditor::ITextEditor *editor, int pos) @@ -234,6 +235,12 @@ void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, in } } + if (m_helpEngineNeedsSetup + && m_helpEngine->registeredDocumentations().count() > 0) { + m_helpEngine->setupData(); + m_helpEngineNeedsSetup = false; + } + if (!m_helpId.isEmpty() && !m_helpEngine->linksForIdentifier(m_helpId).isEmpty()) { m_toolTip = QString(QLatin1String("" "
%1
")).arg(Qt::escape(m_toolTip)); diff --git a/src/plugins/cpptools/cpphoverhandler.h b/src/plugins/cpptools/cpphoverhandler.h index 9aaa17cb0f8..d1de5277b12 100644 --- a/src/plugins/cpptools/cpphoverhandler.h +++ b/src/plugins/cpptools/cpphoverhandler.h @@ -68,6 +68,7 @@ private: QHelpEngineCore *m_helpEngine; QString m_helpId; QString m_toolTip; + bool m_helpEngineNeedsSetup; }; } // namespace Internal From f93d2d80e0201821e7bba15f1ed46e234cbc18a7 Mon Sep 17 00:00:00 2001 From: Roberto Raggi Date: Thu, 4 Dec 2008 14:38:44 +0100 Subject: [PATCH 02/25] We don't use the uses, so just ifdef-out the code for now. --- shared/cplusplus/Scope.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/shared/cplusplus/Scope.cpp b/shared/cplusplus/Scope.cpp index 2c1b986b2c9..47221da121f 100644 --- a/shared/cplusplus/Scope.cpp +++ b/shared/cplusplus/Scope.cpp @@ -292,6 +292,7 @@ Use *Scope::useAt(unsigned index) const void Scope::addUse(unsigned sourceOffset, Name *name) { +#ifdef CPLUSPLUS_WITH_USES if (++_useCount == _allocatedUses) { _allocatedUses += 4; _uses = reinterpret_cast(realloc(_uses, _allocatedUses * sizeof(Use))); @@ -303,6 +304,7 @@ void Scope::addUse(unsigned sourceOffset, Name *name) else lastVisibleSymbol = _symbols[_symbolCount]; _uses[_useCount].init(sourceOffset, name, lastVisibleSymbol); +#endif } CPLUSPLUS_END_NAMESPACE From 4d60687b6698f9f119d221bd262135642425af7d Mon Sep 17 00:00:00 2001 From: Patrick Star Date: Thu, 4 Dec 2008 15:03:57 +0100 Subject: [PATCH 03/25] Fixes: - use indexwindow from shared --- shared/help/help.pri | 5 ++- src/plugins/help/help.pro | 5 ++- src/plugins/help/indexwindow.h | 82 ---------------------------------- 3 files changed, 6 insertions(+), 86 deletions(-) delete mode 100644 src/plugins/help/indexwindow.h diff --git a/shared/help/help.pri b/shared/help/help.pri index 9503d085938..dff0ae7699b 100644 --- a/shared/help/help.pri +++ b/shared/help/help.pri @@ -9,7 +9,8 @@ HEADERS += \ $$PWD/helpviewer.h \ $$PWD/contentwindow.h \ $$PWD/bookmarkmanager.h \ - $$PWD/../namespace_global.h + $$PWD/../namespace_global.h \ + $$PWD/indexwindow.h SOURCES += \ $$PWD/filternamedialog.cpp \ @@ -19,7 +20,7 @@ SOURCES += \ $$PWD/contentwindow.cpp \ $$PWD/bookmarkmanager.cpp -FORMS += \ +FORMS += \ $$PWD/filternamedialog.ui \ $$PWD/topicchooser.ui \ $$PWD/bookmarkdialog.ui diff --git a/src/plugins/help/help.pro b/src/plugins/help/help.pro index 1148606cab7..b2e9a1dbd61 100644 --- a/src/plugins/help/help.pro +++ b/src/plugins/help/help.pro @@ -16,8 +16,8 @@ HEADERS += helpplugin.h \ searchwidget.h \ helpfindsupport.h \ help_global.h \ - helpindexfilter.h \ - indexwindow.h + helpindexfilter.h + SOURCES += helpplugin.cpp \ docsettingspage.cpp \ filtersettingspage.cpp \ @@ -26,6 +26,7 @@ SOURCES += helpplugin.cpp \ searchwidget.cpp \ helpfindsupport.cpp \ helpindexfilter.cpp + FORMS += docsettingspage.ui \ filtersettingspage.ui RESOURCES += help.qrc diff --git a/src/plugins/help/indexwindow.h b/src/plugins/help/indexwindow.h deleted file mode 100644 index 51ebb06653d..00000000000 --- a/src/plugins/help/indexwindow.h +++ /dev/null @@ -1,82 +0,0 @@ -/*************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). -** -** Contact: Qt Software Information (qt-info@nokia.com) -** -** -** Non-Open Source Usage -** -** Licensees may use this file in accordance with the Qt Beta Version -** License Agreement, Agreement version 2.2 provided with the Software or, -** alternatively, in accordance with the terms contained in a written -** agreement between you and Nokia. -** -** GNU General Public License Usage -** -** Alternatively, this file may be used under the terms of the GNU General -** Public License versions 2.0 or 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the packaging -** of this file. Please review the following information to ensure GNU -** General Public Licensing requirements will be met: -** -** http://www.fsf.org/licensing/licenses/info/GPLv2.html and -** http://www.gnu.org/copyleft/gpl.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt GPL Exception -** version 1.2, included in the file GPL_EXCEPTION.txt in this package. -** -***************************************************************************/ - -#ifndef INDEXWINDOW_H -#define INDEXWINDOW_H - -#include -#include -#include - -QT_BEGIN_NAMESPACE - -class QHelpIndexWidget; -class QHelpEngine; - -class IndexWindow : public QWidget -{ - Q_OBJECT - -public: - IndexWindow(QHelpEngine *helpEngine, QWidget *parent = 0); - ~IndexWindow(); - - void setSearchLineEditText(const QString &text); - QString searchLineEditText() const - { - return m_searchLineEdit->text(); - } - -signals: - void linkActivated(const QUrl &link); - void linksActivated(const QMap &links, - const QString &keyword); - void escapePressed(); - -private slots: - void filterIndices(const QString &filter); - void enableSearchLineEdit(); - void disableSearchLineEdit(); - -private: - bool eventFilter(QObject *obj, QEvent *e); - void focusInEvent(QFocusEvent *e); - - QLineEdit *m_searchLineEdit; - QHelpIndexWidget *m_indexWidget; - QHelpEngine *m_helpEngine; -}; - -QT_END_NAMESPACE - -#endif // INDEXWINDOW_H From c149046b155b6d7f2d8eea5a04d86c7017678068 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 4 Dec 2008 15:35:16 +0100 Subject: [PATCH 04/25] Fixes: Add revert to git, name stage options according to git gui --- src/plugins/git/commitdata.cpp | 8 +- src/plugins/git/commitdata.h | 4 +- src/plugins/git/gitclient.cpp | 216 +++++++++++++++++++++++++--- src/plugins/git/gitclient.h | 29 ++-- src/plugins/git/gitplugin.cpp | 60 ++++++-- src/plugins/git/gitplugin.h | 8 +- src/plugins/git/gitsubmiteditor.cpp | 4 +- 7 files changed, 275 insertions(+), 54 deletions(-) diff --git a/src/plugins/git/commitdata.cpp b/src/plugins/git/commitdata.cpp index 60e2173a660..7ea937233c7 100644 --- a/src/plugins/git/commitdata.cpp +++ b/src/plugins/git/commitdata.cpp @@ -80,16 +80,16 @@ void CommitData::clear() panelInfo.clear(); panelData.clear(); - commitFiles.clear(); - notUpdatedFiles.clear(); + stagedFiles.clear(); + unstagedFiles.clear(); untrackedFiles.clear(); } QDebug operator<<(QDebug d, const CommitData &data) { d << data.panelInfo << data.panelData; - d.nospace() << "Commit: " << data.commitFiles << " Not updated: " - << data.notUpdatedFiles << " Untracked: " << data.untrackedFiles; + d.nospace() << "Commit: " << data.stagedFiles << " Not updated: " + << data.unstagedFiles << " Untracked: " << data.untrackedFiles; return d; } diff --git a/src/plugins/git/commitdata.h b/src/plugins/git/commitdata.h index 9cd5a83eb16..b535168f6f3 100644 --- a/src/plugins/git/commitdata.h +++ b/src/plugins/git/commitdata.h @@ -71,8 +71,8 @@ struct CommitData void clear(); GitSubmitEditorPanelInfo panelInfo; GitSubmitEditorPanelData panelData; - QStringList commitFiles; - QStringList notUpdatedFiles; + QStringList stagedFiles; + QStringList unstagedFiles; QStringList untrackedFiles; }; diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 7d87ce27827..a1668e60ceb 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -35,6 +35,7 @@ #include "gitplugin.h" #include "gitconstants.h" #include "commitdata.h" +#include "gitsubmiteditor.h" #include #include @@ -51,7 +52,9 @@ #include #include -#include +#include +#include // for msg box parent +#include using namespace Git; using namespace Git::Internal; @@ -77,12 +80,24 @@ inline Core::IEditor* locateEditor(const Core::ICore *core, const char *property return 0; } +static inline QString msgRepositoryNotFound(const QString &dir) +{ + return GitClient::tr("Unable to determine the repository for %1.").arg(dir); +} + +static inline QString msgParseFilesFailed() +{ + return GitClient::tr("Unable to parse the file output."); +} + +// Format a command for the status window static QString formatCommand(const QString &binary, const QStringList &args) { const QString timeStamp = QTime::currentTime().toString(QLatin1String("HH:mm")); return GitClient::tr("%1 Executing: %2 %3\n").arg(timeStamp, binary, args.join(QString(QLatin1Char(' ')))); } +// ---------------- GitClient GitClient::GitClient(GitPlugin* plugin, Core::ICore *core) : m_msgWait(tr("Waiting for data...")), m_plugin(plugin), @@ -311,6 +326,19 @@ bool GitClient::synchronousAdd(const QString &workingDirectory, const QStringLis bool GitClient::synchronousReset(const QString &workingDirectory, const QStringList &files) +{ + QString errorMessage; + const bool rc = synchronousReset(workingDirectory, files, &errorMessage); + if (!rc) { + m_plugin->outputWindow()->append(errorMessage); + m_plugin->outputWindow()->popup(false); + } + return rc; +} + +bool GitClient::synchronousReset(const QString &workingDirectory, + const QStringList &files, + QString *errorMessage) { if (Git::Constants::debug) qDebug() << Q_FUNC_INFO << workingDirectory << files; @@ -325,9 +353,25 @@ bool GitClient::synchronousReset(const QString &workingDirectory, // Note that git exits with 1 even if the operation is successful // Assume real failure if the output does not contain "foo.cpp modified" if (!rc && !output.contains(QLatin1String("modified"))) { - const QString errorMessage = tr("Unable to reset %n file(s) in %1: %2", 0, files.size()). - arg(workingDirectory, QString::fromLocal8Bit(errorText)); - m_plugin->outputWindow()->append(errorMessage); + *errorMessage = tr("Unable to reset %n file(s) in %1: %2", 0, files.size()).arg(workingDirectory, QString::fromLocal8Bit(errorText)); + return false; + } + return true; +} + +bool GitClient::synchronousCheckout(const QString &workingDirectory, + const QStringList &files, + QString *errorMessage) +{ + if (Git::Constants::debug) + qDebug() << Q_FUNC_INFO << workingDirectory << files; + QByteArray outputText; + QByteArray errorText; + QStringList arguments; + arguments << QLatin1String("checkout") << QLatin1String("--") << files; + const bool rc = synchronousGit(workingDirectory, arguments, &outputText, &errorText); + if (!rc) { + *errorMessage = tr("Unable to checkout %n file(s) in %1: %2", 0, files.size()).arg(workingDirectory, QString::fromLocal8Bit(errorText)); return false; } return true; @@ -365,16 +409,18 @@ void GitClient::executeGit(const QString &workingDirectory, const QStringList &a command->execute(arguments, workingDirectory, environment); } -bool GitClient::synchronousGit(const QString &workingDirectory - , const QStringList &arguments - , QByteArray* outputText - , QByteArray* errorText) +bool GitClient::synchronousGit(const QString &workingDirectory, + const QStringList &arguments, + QByteArray* outputText, + QByteArray* errorText, + bool logCommandToWindow) { if (Git::Constants::debug) qDebug() << "synchronousGit" << workingDirectory << arguments; const QString binary = QLatin1String(kGitCommand); - m_plugin->outputWindow()->append(formatCommand(binary, arguments)); + if (logCommandToWindow) + m_plugin->outputWindow()->append(formatCommand(binary, arguments)); QProcess process; process.setWorkingDirectory(workingDirectory); @@ -456,10 +502,11 @@ GitClient::StatusResult GitClient::gitStatus(const QString &workingDirectory, #modified:git.pro \endcode */ -static bool parseFiles(const QStringList &lines, CommitData *d) +static bool parseFiles(const QString &output, CommitData *d) { enum State { None, CommitFiles, NotUpdatedFiles, UntrackedFiles }; + const QStringList lines = output.split(QLatin1Char('\n')); const QString branchIndicator = QLatin1String(kBranchIndicatorC); const QString commitIndicator = QLatin1String("# Changes to be committed:"); const QString notUpdatedIndicator = QLatin1String("# Changed but not updated:"); @@ -492,10 +539,10 @@ static bool parseFiles(const QStringList &lines, CommitData *d) const QString fileSpec = line.mid(2).trimmed(); switch (s) { case CommitFiles: - d->commitFiles.push_back(trimFileSpecification(fileSpec)); + d->stagedFiles.push_back(trimFileSpecification(fileSpec)); break; case NotUpdatedFiles: - d->notUpdatedFiles.push_back(trimFileSpecification(fileSpec)); + d->unstagedFiles.push_back(trimFileSpecification(fileSpec)); break; case UntrackedFiles: d->untrackedFiles.push_back(QLatin1String("untracked: ") + fileSpec); @@ -509,7 +556,7 @@ static bool parseFiles(const QStringList &lines, CommitData *d) } } } - return !d->commitFiles.empty() || !d->notUpdatedFiles.empty() || !d->untrackedFiles.empty(); + return !d->stagedFiles.empty() || !d->unstagedFiles.empty() || !d->untrackedFiles.empty(); } bool GitClient::getCommitData(const QString &workingDirectory, @@ -525,7 +572,7 @@ bool GitClient::getCommitData(const QString &workingDirectory, // Find repo const QString repoDirectory = GitClient::findRepositoryForDirectory(workingDirectory); if (repoDirectory.isEmpty()) { - *errorMessage = tr("Unable to determine the repository for %1.").arg(workingDirectory); + *errorMessage = msgRepositoryNotFound(workingDirectory); return false; } @@ -551,7 +598,7 @@ bool GitClient::getCommitData(const QString &workingDirectory, case StatusChanged: break; case StatusUnchanged: - *errorMessage = tr("There are no modified files."); + *errorMessage = msgNoChangedFiles(); return false; case StatusFailed: return false; @@ -575,9 +622,8 @@ bool GitClient::getCommitData(const QString &workingDirectory, // # // # list of files... - const QStringList lines = output.split(QLatin1Char('\n')); - if (!parseFiles(lines, d)) { - *errorMessage = tr("Unable to parse the file output."); + if (!parseFiles(output, d)) { + *errorMessage = msgParseFilesFailed(); return false; } @@ -638,6 +684,129 @@ bool GitClient::addAndCommit(const QString &repositoryDirectory, return rc; } +static inline bool askWithInformativeText(QWidget *parent, + const QString &title, + const QString &msg, + const QString &inf, + bool defaultValue) +{ + QMessageBox msgBox(QMessageBox::Question, title, msg, QMessageBox::Yes|QMessageBox::No, parent); + msgBox.setInformativeText(inf); + msgBox.setDefaultButton(defaultValue ? QMessageBox::Yes : QMessageBox::No); + return msgBox.exec() == QMessageBox::Yes; +} + +/* Revert: This function can be called with a file list (to revert single + * files) or a single directory (revert all). Qt Creator currently has only + * 'revert single' in its VCS menus, but the code is prepared to deal with + * reverting a directory pending a sophisticated selection dialog in the + * VCSBase plugin. */ + +GitClient::RevertResult GitClient::revertI(QStringList files, bool *ptrToIsDirectory, QString *errorMessage) +{ + if (Git::Constants::debug) + qDebug() << Q_FUNC_INFO << files; + + if (files.empty()) + return RevertCanceled; + + // Figure out the working directory + const QFileInfo firstFile(files.front()); + const bool isDirectory = firstFile.isDir(); + if (ptrToIsDirectory) + *ptrToIsDirectory = isDirectory; + const QString workingDirectory = isDirectory ? firstFile.absoluteFilePath() : firstFile.absolutePath(); + + const QString repoDirectory = GitClient::findRepositoryForDirectory(workingDirectory); + if (repoDirectory.isEmpty()) { + *errorMessage = msgRepositoryNotFound(workingDirectory); + return RevertFailed; + } + + // Check for changes + QString output; + switch (gitStatus(repoDirectory, false, &output, errorMessage)) { + case StatusChanged: + break; + case StatusUnchanged: + return RevertUnchanged; + case StatusFailed: + return RevertFailed; + } + CommitData d; + if (!parseFiles(output, &d)) { + *errorMessage = msgParseFilesFailed(); + return RevertFailed; + } + + // If we are looking at files, make them relative to the repository + // directory to match them in the status output list. + if (!isDirectory) { + const QDir repoDir(repoDirectory); + const QStringList::iterator cend = files.end(); + for (QStringList::iterator it = files.begin(); it != cend; ++it) + *it = repoDir.relativeFilePath(*it); + } + + // From the status output, determine all modified [un]staged files. + const QString modifiedPattern = QLatin1String("modified: "); + const QStringList allStagedFiles = GitSubmitEditor::statusListToFileList(d.stagedFiles.filter(modifiedPattern)); + const QStringList allUnstagedFiles = GitSubmitEditor::statusListToFileList(d.unstagedFiles.filter(modifiedPattern)); + // Unless a directory was passed, filter all modified files for the + // argument file list. + QStringList stagedFiles = allStagedFiles; + QStringList unstagedFiles = allUnstagedFiles; + if (!isDirectory) { + const QSet filesSet = files.toSet(); + stagedFiles = allStagedFiles.toSet().intersect(filesSet).toList(); + unstagedFiles = allUnstagedFiles.toSet().intersect(filesSet).toList(); + } + if (Git::Constants::debug) + qDebug() << Q_FUNC_INFO << d.stagedFiles << d.unstagedFiles << allStagedFiles << allUnstagedFiles << stagedFiles << unstagedFiles; + + if (stagedFiles.empty() && unstagedFiles.empty()) + return RevertUnchanged; + + // Ask to revert (to do: Handle lists with a selection dialog) + const QMessageBox::StandardButton answer + = QMessageBox::question(m_core->mainWindow(), + tr("Revert"), + tr("The file has been changed. Do you want to revert it?"), + QMessageBox::Yes|QMessageBox::No, + QMessageBox::No); + if (answer == QMessageBox::No) + return RevertCanceled; + + // Unstage the staged files + if (!stagedFiles.empty() && !synchronousReset(repoDirectory, stagedFiles, errorMessage)) + return RevertFailed; + // Finally revert! + if (!synchronousCheckout(repoDirectory, stagedFiles + unstagedFiles, errorMessage)) + return RevertFailed; + return RevertOk; +} + +void GitClient::revert(const QStringList &files) +{ + bool isDirectory; + QString errorMessage; + switch (revertI(files, &isDirectory, &errorMessage)) { + case RevertOk: + case RevertCanceled: + break; + case RevertUnchanged: { + const QString msg = (isDirectory || files.size() > 1) ? msgNoChangedFiles() : tr("The file is not modified."); + m_plugin->outputWindow()->append(msg); + m_plugin->outputWindow()->popup(); + } + break; + case RevertFailed: + m_plugin->outputWindow()->append(errorMessage); + m_plugin->outputWindow()->popup(); + break; + } +} + void GitClient::pull(const QString &workingDirectory) { executeGit(workingDirectory, QStringList(QLatin1String("pull")), m_plugin->outputWindow(), 0, true); @@ -648,6 +817,11 @@ void GitClient::push(const QString &workingDirectory) executeGit(workingDirectory, QStringList(QLatin1String("push")), m_plugin->outputWindow(), 0, true); } +QString GitClient::msgNoChangedFiles() +{ + return tr("There are no modified files."); +} + void GitClient::stash(const QString &workingDirectory) { // Check for changes and stash @@ -657,7 +831,7 @@ void GitClient::stash(const QString &workingDirectory) executeGit(workingDirectory, QStringList(QLatin1String("stash")), m_plugin->outputWindow(), 0, true); break; case StatusUnchanged: - m_plugin->outputWindow()->append(tr("There are no modified files.")); + m_plugin->outputWindow()->append(msgNoChangedFiles()); m_plugin->outputWindow()->popup(); break; case StatusFailed: @@ -694,8 +868,8 @@ QString GitClient::readConfig(const QString &workingDirectory, const QStringList arguments << QLatin1String("config") << configVar; QByteArray outputText; - if (synchronousGit(workingDirectory, arguments, &outputText)) - return QString::fromLocal8Bit(outputText); + if (synchronousGit(workingDirectory, arguments, &outputText, 0, false)) + return QString::fromLocal8Bit(outputText).remove(QLatin1Char('\r')); return QString(); } diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h index 5be276a7877..efc767e5409 100644 --- a/src/plugins/git/gitclient.h +++ b/src/plugins/git/gitclient.h @@ -90,11 +90,14 @@ public: void addFile(const QString &workingDirectory, const QString &fileName); bool synchronousAdd(const QString &workingDirectory, const QStringList &files); bool synchronousReset(const QString &workingDirectory, const QStringList &files); + bool synchronousReset(const QString &workingDirectory, const QStringList &files, QString *errorMessage); + bool synchronousCheckout(const QString &workingDirectory, const QStringList &files, QString *errorMessage); void pull(const QString &workingDirectory); void push(const QString &workingDirectory); void stash(const QString &workingDirectory); void stashPop(const QString &workingDirectory); + void revert(const QStringList &files); void branchList(const QString &workingDirectory); void stashList(const QString &workingDirectory); @@ -113,19 +116,21 @@ public: const QStringList &checkedFiles, const QStringList &origCommitFiles); - GitSettings settings() const; - void setSettings(const GitSettings &s); - -public slots: - void show(const QString &source, const QString &id); - -private: enum StatusResult { StatusChanged, StatusUnchanged, StatusFailed }; StatusResult gitStatus(const QString &workingDirectory, bool untracked, QString *output = 0, QString *errorMessage = 0); + GitSettings settings() const; + void setSettings(const GitSettings &s); + + static QString msgNoChangedFiles(); + +public slots: + void show(const QString &source, const QString &id); + +private: VCSBase::VCSBaseEditor *createVCSEditor(const QString &kind, QString title, const QString &source, @@ -141,9 +146,13 @@ private: bool outputToWindow = false); bool synchronousGit(const QString &workingDirectory, - const QStringList &arguments, - QByteArray* outputText = 0, - QByteArray* errorText = 0); + const QStringList &arguments, + QByteArray* outputText = 0, + QByteArray* errorText = 0, + bool logCommandToWindow = true); + + enum RevertResult { RevertOk, RevertUnchanged, RevertCanceled, RevertFailed }; + RevertResult revertI(QStringList files, bool *isDirectory, QString *errorMessage); const QString m_msgWait; GitPlugin *m_plugin; diff --git a/src/plugins/git/gitplugin.cpp b/src/plugins/git/gitplugin.cpp index ef57b9bb12a..ebce0f7c452 100644 --- a/src/plugins/git/gitplugin.cpp +++ b/src/plugins/git/gitplugin.cpp @@ -118,7 +118,9 @@ GitPlugin::GitPlugin() : m_undoFileAction(0), m_undoProjectAction(0), m_showAction(0), - m_addAction(0), + m_stageAction(0), + m_unstageAction(0), + m_revertAction(0), m_commitAction(0), m_pullAction(0), m_pushAction(0), @@ -311,11 +313,23 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *error_message) connect(m_undoFileAction, SIGNAL(triggered()), this, SLOT(undoFileChanges())); gitContainer->addAction(command); - m_addAction = new QAction(tr("Add File"), this); - command = actionManager->registerAction(m_addAction, "Git.Add", globalcontext); + m_stageAction = new QAction(tr("Stage file for commit"), this); + command = actionManager->registerAction(m_stageAction, "Git.Stage", globalcontext); command->setDefaultKeySequence(QKeySequence(tr("Alt+G,Alt+A"))); command->setAttribute(Core::ICommand::CA_UpdateText); - connect(m_addAction, SIGNAL(triggered()), this, SLOT(addFile())); + connect(m_stageAction, SIGNAL(triggered()), this, SLOT(stageFile())); + gitContainer->addAction(command); + + m_unstageAction = new QAction(tr("Unstage file from commit"), this); + command = actionManager->registerAction(m_unstageAction, "Git.Unstage", globalcontext); + command->setAttribute(Core::ICommand::CA_UpdateText); + connect(m_unstageAction, SIGNAL(triggered()), this, SLOT(unstageFile())); + gitContainer->addAction(command); + + m_revertAction = new QAction(tr("Revert..."), this); + command = actionManager->registerAction(m_revertAction, "Git.Revert", globalcontext); + command->setAttribute(Core::ICommand::CA_UpdateText); + connect(m_revertAction, SIGNAL(triggered()), this, SLOT(revertFile())); gitContainer->addAction(command); gitContainer->addAction(createSeparator(actionManager, globalcontext, QLatin1String("Git.Sep.Project"), this)); @@ -537,14 +551,28 @@ void GitPlugin::undoProjectChanges() m_gitClient->hardReset(workingDirectory, QString()); } -void GitPlugin::addFile() +void GitPlugin::stageFile() { - QFileInfo fileInfo = currentFile(); - QString fileName = fileInfo.fileName(); - QString workingDirectory = fileInfo.absolutePath(); + const QFileInfo fileInfo = currentFile(); + const QString fileName = fileInfo.fileName(); + const QString workingDirectory = fileInfo.absolutePath(); m_gitClient->addFile(workingDirectory, fileName); } +void GitPlugin::unstageFile() +{ + const QFileInfo fileInfo = currentFile(); + const QString fileName = fileInfo.fileName(); + const QString workingDirectory = fileInfo.absolutePath(); + m_gitClient->synchronousReset(workingDirectory, QStringList(fileName)); +} + +void GitPlugin::revertFile() +{ + const QFileInfo fileInfo = currentFile(); + m_gitClient->revert(QStringList(fileInfo.absoluteFilePath())); +} + void GitPlugin::startCommit() { if (m_changeTmpFile) { @@ -570,7 +598,7 @@ void GitPlugin::startCommit() // Store repository for diff and the original list of // files to be able to unstage files the user unchecks m_submitRepository = data.panelInfo.repository; - m_submitOrigCommitFiles = GitSubmitEditor::statusListToFileList(data.commitFiles); + m_submitOrigCommitFiles = GitSubmitEditor::statusListToFileList(data.stagedFiles); if (Git::Constants::debug) qDebug() << Q_FUNC_INFO << data << commitTemplate; @@ -602,7 +630,7 @@ Core::IEditor *GitPlugin::openSubmitEditor(const QString &fileName, const Commit Q_ASSERT(submitEditor); // The actions are for some reason enabled by the context switching // mechanism. Disable them correctly. - m_submitCurrentAction->setEnabled(!cd.commitFiles.empty()); + m_submitCurrentAction->setEnabled(!cd.stagedFiles.empty()); m_diffSelectedFilesAction->setEnabled(false); m_undoAction->setEnabled(false); m_redoAction->setEnabled(false); @@ -722,7 +750,9 @@ void GitPlugin::updateActions() m_logAction->setText(tr("Log %1").arg(fileName)); m_blameAction->setText(tr("Blame %1").arg(fileName)); m_undoFileAction->setText(tr("Undo changes for %1").arg(fileName)); - m_addAction->setText(tr("Add %1").arg(fileName)); + m_stageAction->setText(tr("Stage %1 for commit").arg(fileName)); + m_unstageAction->setText(tr("Unstage %1 from commit").arg(fileName)); + m_revertAction->setText(tr("Revert %1...").arg(fileName)); if (repository.isEmpty()) { // If the file is not in a repository, the corresponding project will // be neither and we can disable everything and return @@ -731,7 +761,9 @@ void GitPlugin::updateActions() m_logAction->setEnabled(false); m_blameAction->setEnabled(false); m_undoFileAction->setEnabled(false); - m_addAction->setEnabled(false); + m_stageAction->setEnabled(false); + m_unstageAction->setEnabled(false); + m_revertAction->setEnabled(false); m_diffProjectAction->setEnabled(false); m_diffProjectAction->setText(tr("Diff Project")); m_statusProjectAction->setText(tr("Status Project")); @@ -747,7 +779,9 @@ void GitPlugin::updateActions() m_logAction->setEnabled(true); m_blameAction->setEnabled(true); m_undoFileAction->setEnabled(true); - m_addAction->setEnabled(true); + m_stageAction->setEnabled(true); + m_unstageAction->setEnabled(true); + m_revertAction->setEnabled(true); } if (m_projectExplorer && m_projectExplorer->currentNode() diff --git a/src/plugins/git/gitplugin.h b/src/plugins/git/gitplugin.h index 3da8ff26cec..adff899e505 100644 --- a/src/plugins/git/gitplugin.h +++ b/src/plugins/git/gitplugin.h @@ -116,7 +116,9 @@ private slots: void logProject(); void undoFileChanges(); void undoProjectChanges(); - void addFile(); + void stageFile(); + void unstageFile(); + void revertFile(); void showCommit(); void startCommit(); @@ -144,7 +146,9 @@ private: QAction *m_undoFileAction; QAction *m_undoProjectAction; QAction *m_showAction; - QAction *m_addAction; + QAction *m_stageAction; + QAction *m_unstageAction; + QAction *m_revertAction; QAction *m_commitAction; QAction *m_pullAction; QAction *m_pushAction; diff --git a/src/plugins/git/gitsubmiteditor.cpp b/src/plugins/git/gitsubmiteditor.cpp index 516dc6570b7..db854f3e3c6 100644 --- a/src/plugins/git/gitsubmiteditor.cpp +++ b/src/plugins/git/gitsubmiteditor.cpp @@ -67,9 +67,9 @@ void GitSubmitEditor::setCommitData(const CommitData &d) submitEditorWidget()->setPanelData(d.panelData); submitEditorWidget()->setPanelInfo(d.panelInfo); - addFiles(d.commitFiles, true, true); + addFiles(d.stagedFiles, true, true); // Not Updated: Initially unchecked - addFiles(d.notUpdatedFiles, false, true); + addFiles(d.unstagedFiles, false, true); addFiles(d.untrackedFiles, false, true); } From 5489c83d715acb78b550f70d3035b60c9ce6508c Mon Sep 17 00:00:00 2001 From: Roberto Raggi Date: Thu, 4 Dec 2008 15:52:17 +0100 Subject: [PATCH 05/25] Visit the left child not of a binary expression. --- src/libs/cplusplus/ResolveExpression.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/cplusplus/ResolveExpression.cpp b/src/libs/cplusplus/ResolveExpression.cpp index 019cbfff1ff..cfcd06cacd7 100644 --- a/src/libs/cplusplus/ResolveExpression.cpp +++ b/src/libs/cplusplus/ResolveExpression.cpp @@ -235,9 +235,9 @@ bool ResolveExpression::visit(ExpressionListAST *) return false; } -bool ResolveExpression::visit(BinaryExpressionAST *) +bool ResolveExpression::visit(BinaryExpressionAST *ast) { - // nothing to do. + accept(ast->left_expression); return false; } From 6e2b066187c2bcb0663aa69a008bfc4e44e0ba54 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 4 Dec 2008 16:16:50 +0100 Subject: [PATCH 06/25] add a few explanations to some obscure actions --- src/plugins/debugger/debuggermanager.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp index 42551168fe2..b1e62ada3c8 100644 --- a/src/plugins/debugger/debuggermanager.cpp +++ b/src/plugins/debugger/debuggermanager.cpp @@ -317,10 +317,20 @@ void DebuggerManager::init() m_debugDumpersAction = new QAction(this); m_debugDumpersAction->setText(tr("Debug Custom Dumpers")); + m_debugDumpersAction->setText(tr("This is an internal tool to " + "make debugging the Custom Data Dumper code easier. " + "Using this action is in general not needed unless you " + "want do debug Qt Creator itself.")); m_debugDumpersAction->setCheckable(true); m_skipKnownFramesAction = new QAction(this); m_skipKnownFramesAction->setText(tr("Skip Known Frames When Stepping")); + m_skipKnownFramesAction->setToolTip(tr("After checking this option" + "'Step Into' combines in certain situations several steps, " + "leading to 'less noisy' debugging. So will, e.g., the atomic " + "reference counting code be skipped, and a single 'Step Into' " + "for a signal emission will end up directly in the slot connected " + "to it")); m_skipKnownFramesAction->setCheckable(true); m_useCustomDumpersAction = new QAction(this); @@ -330,13 +340,6 @@ void DebuggerManager::init() m_useCustomDumpersAction->setCheckable(true); m_useCustomDumpersAction->setChecked(true); - m_useCustomDumpersAction = new QAction(this); - m_useCustomDumpersAction->setText(tr("Use Custom Display for Qt Objects")); - m_useCustomDumpersAction->setToolTip(tr("Checking this will make the debugger " - "try to use code to format certain data (QObject, QString, ...) nicely. ")); - m_useCustomDumpersAction->setCheckable(true); - m_useCustomDumpersAction->setChecked(true); - m_useFastStartAction = new QAction(this); m_useFastStartAction->setText(tr("Fast Debugger Start")); m_useFastStartAction->setToolTip(tr("Checking this will make the debugger " From f59964d19cfa8e3cecd049b765f846160db04542 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 4 Dec 2008 16:24:15 +0100 Subject: [PATCH 07/25] Fixes: Console wizard has finalPage set, wrong options for wizard, quieten p4 when quering the project directory --- src/plugins/perforce/perforceplugin.cpp | 84 +++++++++++-------- src/plugins/perforce/perforceplugin.h | 8 +- .../wizards/consoleappwizarddialog.cpp | 3 +- .../wizards/guiappwizarddialog.cpp | 1 - 4 files changed, 55 insertions(+), 41 deletions(-) diff --git a/src/plugins/perforce/perforceplugin.cpp b/src/plugins/perforce/perforceplugin.cpp index 2de31700a86..dc28901b705 100644 --- a/src/plugins/perforce/perforceplugin.cpp +++ b/src/plugins/perforce/perforceplugin.cpp @@ -405,17 +405,17 @@ void PerforcePlugin::extensionsInitialized() void PerforcePlugin::openCurrentFile() { - runP4Cmd(QStringList() << QLatin1String("edit") << currentFileName(), QStringList(), true); + vcsOpen(currentFileName()); } void PerforcePlugin::addCurrentFile() { - runP4Cmd(QStringList() << QLatin1String("add") << currentFileName(), QStringList(), true); + vcsAdd(currentFileName()); } void PerforcePlugin::deleteCurrentFile() { - runP4Cmd(QStringList() << QLatin1String("delete") << currentFileName(), QStringList(), true); + vcsDelete(currentFileName()); } void PerforcePlugin::revertCurrentFile() @@ -426,7 +426,7 @@ void PerforcePlugin::revertCurrentFile() QTextCodec *codec = VCSBase::VCSBaseEditor::getCodec(m_coreInstance, fileName); QStringList args; args << QLatin1String("diff") << QLatin1String("-sa"); - PerforceResponse result = runP4Cmd(args, QStringList(), false, true, codec); + PerforceResponse result = runP4Cmd(args, QStringList(), CommandToWindow|StdErrToWindow|ErrorToWindow, codec); if (result.error) return; @@ -444,7 +444,7 @@ void PerforcePlugin::revertCurrentFile() foreach (Core::IFile *file, files) { fm->blockFileChange(file); } - PerforceResponse result2 = runP4Cmd(QStringList() << QLatin1String("revert") << fileName, QStringList(), true); + PerforceResponse result2 = runP4Cmd(QStringList() << QLatin1String("revert") << fileName, QStringList(), CommandToWindow|StdOutToWindow|StdErrToWindow|ErrorToWindow); Core::IFile::ReloadBehavior tempBehavior = Core::IFile::ReloadAll; foreach (Core::IFile *file, files) { @@ -489,7 +489,7 @@ void PerforcePlugin::printOpenedFileList() Core::IEditor *e = m_coreInstance->editorManager()->currentEditor(); if (e) e->widget()->setFocus(); - PerforceResponse result = runP4Cmd(QStringList() << QLatin1String("opened"), QStringList(), true); + PerforceResponse result = runP4Cmd(QStringList() << QLatin1String("opened"), QStringList(), CommandToWindow|StdOutToWindow|StdErrToWindow|ErrorToWindow); } #ifdef USE_P4_API @@ -522,7 +522,8 @@ void PerforcePlugin::submit() return; } - PerforceResponse result = runP4Cmd(QStringList()<< QLatin1String("change") << QLatin1String("-o"), QStringList(), false); + PerforceResponse result = runP4Cmd(QStringList()<< QLatin1String("change") << QLatin1String("-o"), QStringList(), + CommandToWindow|StdErrToWindow|ErrorToWindow); if (result.error) { delete m_changeTmpFile; m_changeTmpFile = 0; @@ -550,7 +551,8 @@ void PerforcePlugin::submit() foreach (const QString &f, files) nativeFiles << QDir::toNativeSeparators(f); - PerforceResponse result2 = runP4Cmd(QStringList(QLatin1String("fstat")), nativeFiles, false); + PerforceResponse result2 = runP4Cmd(QStringList(QLatin1String("fstat")), nativeFiles, + CommandToWindow|StdErrToWindow|ErrorToWindow); if (result2.error) { delete m_changeTmpFile; m_changeTmpFile = 0; @@ -597,8 +599,10 @@ void PerforcePlugin::printPendingChanges() PendingChangesDialog dia(pendingChangesData(), m_coreInstance->mainWindow()); qApp->restoreOverrideCursor(); if (dia.exec() == QDialog::Accepted) { - int i = dia.changeNumber(); - PerforceResponse result = runP4Cmd(QStringList()<<"submit"<<"-c"<append(response.message, true); - - + if (response.error) { + if (Perforce::Constants::debug) + qDebug() << response.message; + if (logFlags & ErrorToWindow) + m_perforceOutputWindow->append(response.message, true); + } return response; } @@ -923,7 +937,7 @@ void PerforcePlugin::p4Diff(const QStringList &files, QString diffname) } } - const PerforceResponse result = runP4Cmd(QStringList() << QLatin1String("diff") << QLatin1String("-du"), files, false, codec); + const PerforceResponse result = runP4Cmd(QStringList() << QLatin1String("diff") << QLatin1String("-du"), files, CommandToWindow|StdErrToWindow|ErrorToWindow, codec); if (result.error) return; @@ -948,7 +962,7 @@ void PerforcePlugin::describe(const QString & source, const QString &n) QTextCodec *codec = source.isEmpty() ? static_cast(0) : VCSBase::VCSBaseEditor::getCodec(m_coreInstance, source); QStringList args; args << QLatin1String("describe") << QLatin1String("-du") << n; - const PerforceResponse result = runP4Cmd(args, QStringList(), codec); + const PerforceResponse result = runP4Cmd(args, QStringList(), CommandToWindow|StdErrToWindow|ErrorToWindow, codec); if (!result.error) showOutputInEditor(tr("p4 describe %1").arg(n), result.stdOut, VCSBase::DiffOutput, codec); } diff --git a/src/plugins/perforce/perforceplugin.h b/src/plugins/perforce/perforceplugin.h index 4c088563324..7a4e2307779 100644 --- a/src/plugins/perforce/perforceplugin.h +++ b/src/plugins/perforce/perforceplugin.h @@ -86,7 +86,6 @@ private: struct PerforceResponse { bool error; - QString command; QString stdOut; QString stdErr; QString message; @@ -161,12 +160,15 @@ private: Core::IEditor *showOutputInEditor(const QString& title, const QString output, int editorType, QTextCodec *codec = 0); + + // Verbosity flags for runP4Cmd. + enum RunLogFlags { CommandToWindow = 0x1, StdOutToWindow = 0x2, StdErrToWindow = 0x4, ErrorToWindow = 0x8 }; + // args are passed as command line arguments // extra args via a tempfile and the option -x "temp-filename" PerforceResponse runP4Cmd(const QStringList &args, const QStringList &extraArgs = QStringList(), - bool showStdOutInOutputWindow = false, - bool showStdErrInOutputWindow = true, + unsigned logFlags = CommandToWindow|StdErrToWindow|ErrorToWindow, QTextCodec *outputCodec = 0) const; void openFiles(const QStringList &files); diff --git a/src/plugins/qt4projectmanager/wizards/consoleappwizarddialog.cpp b/src/plugins/qt4projectmanager/wizards/consoleappwizarddialog.cpp index 14965f50187..1090673284f 100644 --- a/src/plugins/qt4projectmanager/wizards/consoleappwizarddialog.cpp +++ b/src/plugins/qt4projectmanager/wizards/consoleappwizarddialog.cpp @@ -35,6 +35,7 @@ #include "consoleappwizard.h" #include "modulespage.h" +#include #include namespace Qt4ProjectManager { @@ -51,13 +52,11 @@ ConsoleAppWizardDialog::ConsoleAppWizardDialog(const QString &templateName, setWindowIcon(icon); setWindowTitle(templateName); Core::BaseFileWizard::setupWizard(this); - setOptions(QWizard::IndependentPages | QWizard::HaveNextButtonOnLastPage); m_introPage->setDescription(tr("This wizard generates a Qt4 console application " "project. The application derives from QCoreApplication and does not " "present a GUI. You can press 'Finish' at any point in time.")); - m_introPage->setFinalPage(true); addPage(m_introPage); m_modulesPage->setModuleSelected(QLatin1String("core")); diff --git a/src/plugins/qt4projectmanager/wizards/guiappwizarddialog.cpp b/src/plugins/qt4projectmanager/wizards/guiappwizarddialog.cpp index 7b1ba073d34..621a3b6ba92 100644 --- a/src/plugins/qt4projectmanager/wizards/guiappwizarddialog.cpp +++ b/src/plugins/qt4projectmanager/wizards/guiappwizarddialog.cpp @@ -63,7 +63,6 @@ GuiAppWizardDialog::GuiAppWizardDialog(const QString &templateName, setWindowIcon(icon); setWindowTitle(templateName); Core::BaseFileWizard::setupWizard(this); - setOptions(QWizard::IndependentPages); m_introPage->setDescription(tr("This wizard generates a Qt4 GUI application " "project. The application derives by default from QApplication " From c5a261b1f8d68163f6c64e3f32d11bb663782d18 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 4 Dec 2008 16:26:44 +0100 Subject: [PATCH 08/25] setText + setToolTip works better than setText + setText... --- src/plugins/debugger/debuggermanager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp index b1e62ada3c8..a94b1fb0931 100644 --- a/src/plugins/debugger/debuggermanager.cpp +++ b/src/plugins/debugger/debuggermanager.cpp @@ -317,7 +317,7 @@ void DebuggerManager::init() m_debugDumpersAction = new QAction(this); m_debugDumpersAction->setText(tr("Debug Custom Dumpers")); - m_debugDumpersAction->setText(tr("This is an internal tool to " + m_debugDumpersAction->setToolTip(tr("This is an internal tool to " "make debugging the Custom Data Dumper code easier. " "Using this action is in general not needed unless you " "want do debug Qt Creator itself.")); From 31d8116f32d7a373945a65653006a8bd4bbea070 Mon Sep 17 00:00:00 2001 From: con Date: Wed, 3 Dec 2008 17:38:53 +0100 Subject: [PATCH 09/25] Fixes: - Make about dialog a non-modal dialog --- src/plugins/coreplugin/mainwindow.cpp | 17 +++++++++++++++-- src/plugins/coreplugin/mainwindow.h | 3 +++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/plugins/coreplugin/mainwindow.cpp b/src/plugins/coreplugin/mainwindow.cpp index 59222acc419..1d905070549 100644 --- a/src/plugins/coreplugin/mainwindow.cpp +++ b/src/plugins/coreplugin/mainwindow.cpp @@ -127,6 +127,7 @@ MainWindow::MainWindow() : m_mimeDatabase(new MimeDatabase), m_navigationWidget(0), m_rightPaneWidget(0), + m_versionDialog(0), m_activeContext(0), m_pluginManager(0), m_outputPane(new OutputPane(m_globalContext)), @@ -1085,8 +1086,20 @@ void MainWindow::openRecentFile() void MainWindow::aboutQtCreator() { - VersionDialog versionDialog(this); - versionDialog.exec(); + if (!m_versionDialog) { + m_versionDialog = new VersionDialog(this); + connect(m_versionDialog, SIGNAL(finished(int)), + this, SLOT(destroyVersionDialog())); + } + m_versionDialog->show(); +} + +void MainWindow::destroyVersionDialog() +{ + if (m_versionDialog) { + m_versionDialog->deleteLater(); + m_versionDialog = 0; + } } void MainWindow::aboutPlugins() diff --git a/src/plugins/coreplugin/mainwindow.h b/src/plugins/coreplugin/mainwindow.h index 180b932d710..a8edd089972 100644 --- a/src/plugins/coreplugin/mainwindow.h +++ b/src/plugins/coreplugin/mainwindow.h @@ -83,6 +83,7 @@ class OutputPane; class ProgressManager; class ShortcutSettings; class ViewManager; +class VersionDialog; class CORE_EXPORT MainWindow : public QMainWindow { @@ -160,6 +161,7 @@ private slots: void aboutPlugins(); void updateFocusWidget(QWidget *old, QWidget *now); void toggleNavigation(); + void destroyVersionDialog(); private: void updateContextObject(IContext *context); @@ -190,6 +192,7 @@ private: NavigationWidget *m_navigationWidget; RightPaneWidget *m_rightPaneWidget; Core::BaseView *m_outputView; + VersionDialog *m_versionDialog; IContext * m_activeContext; From 79f244c2eacc70b783acc1c3d6c886dec5fe70d1 Mon Sep 17 00:00:00 2001 From: con Date: Thu, 4 Dec 2008 17:06:44 +0100 Subject: [PATCH 10/25] Fixes: - Give method combo box the current item as tool tip as well --- src/plugins/cppeditor/cppeditor.cpp | 7 +++++++ src/plugins/cppeditor/cppeditor.h | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index 254e9341de6..da52bb3d601 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -206,6 +206,7 @@ void CPPEditor::createToolBar(CPPEditorEditable *editable) connect(m_methodCombo, SIGNAL(activated(int)), this, SLOT(jumpToMethod(int))); connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(updateMethodBoxIndex())); + connect(m_methodCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(updateMethodBoxToolTip())); connect(file(), SIGNAL(changed()), this, SLOT(updateFileName())); @@ -355,10 +356,16 @@ void CPPEditor::updateMethodBoxIndex() if (lastIndex.isValid()) { bool blocked = m_methodCombo->blockSignals(true); m_methodCombo->setCurrentIndex(lastIndex.row()); + updateMethodBoxToolTip(); (void) m_methodCombo->blockSignals(blocked); } } +void CPPEditor::updateMethodBoxToolTip() +{ + m_methodCombo->setToolTip(m_methodCombo->currentText()); +} + static bool isCompatible(Name *name, Name *otherName) { if (NameId *nameId = name->asNameId()) { diff --git a/src/plugins/cppeditor/cppeditor.h b/src/plugins/cppeditor/cppeditor.h index e6c6d1aa863..2420bcf4e5e 100644 --- a/src/plugins/cppeditor/cppeditor.h +++ b/src/plugins/cppeditor/cppeditor.h @@ -115,7 +115,7 @@ private slots: void updateFileName(); void jumpToMethod(int index); void updateMethodBoxIndex(); - + void updateMethodBoxToolTip(); void onDocumentUpdated(CPlusPlus::Document::Ptr doc); private: From c4fa71ba3695805d90bfa8203d3343e659f3e85c Mon Sep 17 00:00:00 2001 From: Roberto Raggi Date: Thu, 4 Dec 2008 16:20:27 +0100 Subject: [PATCH 11/25] Removed some warnings. --- src/plugins/cpptools/cppmodelmanager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp index ccaff0bcfe5..f6b5384b457 100644 --- a/src/plugins/cpptools/cppmodelmanager.cpp +++ b/src/plugins/cpptools/cppmodelmanager.cpp @@ -254,7 +254,7 @@ protected: } virtual void startExpandingMacro(unsigned offset, - const rpp::Macro ¯o, + const rpp::Macro &, const QByteArray &originalText) { if (! m_currentDoc) @@ -264,7 +264,7 @@ protected: m_currentDoc->addMacroUse(offset, originalText.length()); } - virtual void stopExpandingMacro(unsigned offset, const rpp::Macro ¯o) + virtual void stopExpandingMacro(unsigned, const rpp::Macro &) { if (! m_currentDoc) return; From a418183596f039063cc66652e786874bb58b3d25 Mon Sep 17 00:00:00 2001 From: Roberto Raggi Date: Thu, 4 Dec 2008 17:07:43 +0100 Subject: [PATCH 12/25] Some cleanup in the CppPreprocessor. --- src/plugins/cpptools/cppmodelmanager.cpp | 59 +++++++++++++++--------- src/plugins/cpptools/cppmodelmanager.h | 59 ++++++++++++++++++++---- 2 files changed, 88 insertions(+), 30 deletions(-) diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp index f6b5384b457..b3f9fb604c3 100644 --- a/src/plugins/cpptools/cppmodelmanager.cpp +++ b/src/plugins/cpptools/cppmodelmanager.cpp @@ -129,9 +129,12 @@ public: void setProjectFiles(const QStringList &files) { m_projectFiles = files; } - void operator()(QString &fileName) + void run(QString &fileName) { sourceNeeded(fileName, IncludeGlobal); } + void operator()(QString &fileName) + { run(fileName); } + protected: bool includeFile(const QString &absoluteFilePath, QByteArray *result) { @@ -409,6 +412,8 @@ CppModelManager::CppModelManager(QObject *parent) : CppModelManagerInterface(parent), m_core(ExtensionSystem::PluginManager::instance()->getObject()) { + m_dirty = true; + m_projectExplorer = ExtensionSystem::PluginManager::instance() ->getObject(); @@ -417,6 +422,9 @@ CppModelManager::CppModelManager(QObject *parent) : ProjectExplorer::SessionManager *session = m_projectExplorer->session(); Q_ASSERT(session != 0); + connect(session, SIGNAL(projectAdded(ProjectExplorer::Project*)), + this, SLOT(onProjectAdded(ProjectExplorer::Project*))); + connect(session, SIGNAL(aboutToRemoveProject(ProjectExplorer::Project *)), this, SLOT(onAboutToRemoveProject(ProjectExplorer::Project *))); @@ -448,7 +456,7 @@ Document::Ptr CppModelManager::document(const QString &fileName) CppModelManager::DocumentTable CppModelManager::documents() { return m_documents; } -QStringList CppModelManager::projectFiles() const +QStringList CppModelManager::updateProjectFiles() const { QStringList files; QMapIterator it(m_projects); @@ -460,7 +468,7 @@ QStringList CppModelManager::projectFiles() const return files; } -QStringList CppModelManager::includePaths() const +QStringList CppModelManager::updateIncludePaths() const { QStringList includePaths; QMapIterator it(m_projects); @@ -472,7 +480,7 @@ QStringList CppModelManager::includePaths() const return includePaths; } -QStringList CppModelManager::frameworkPaths() const +QStringList CppModelManager::updateFrameworkPaths() const { QStringList frameworkPaths; QMapIterator it(m_projects); @@ -484,7 +492,7 @@ QStringList CppModelManager::frameworkPaths() const return frameworkPaths; } -QByteArray CppModelManager::definedMacros() const +QByteArray CppModelManager::updateDefinedMacros() const { QByteArray macros; QMapIterator it(m_projects); @@ -496,7 +504,7 @@ QByteArray CppModelManager::definedMacros() const return macros; } -QMap CppModelManager::buildWorkingCopyList() const +QMap CppModelManager::buildWorkingCopyList() { QMap workingCopy; QMapIterator it(m_editorSupport); @@ -527,8 +535,14 @@ QFuture CppModelManager::refreshSourceFiles(const QStringList &sourceFiles if (! sourceFiles.isEmpty() && qgetenv("QTCREATOR_NO_CODE_INDEXER").isNull()) { const QMap workingCopy = buildWorkingCopyList(); - QFuture result = QtConcurrent::run(&CppModelManager::parse, this, - sourceFiles, workingCopy); + CppPreprocessor *preproc = new CppPreprocessor(this); + preproc->setProjectFiles(projectFiles()); + preproc->setIncludePaths(includePaths()); + preproc->setFrameworkPaths(frameworkPaths()); + preproc->setWorkingCopy(workingCopy); + + QFuture result = QtConcurrent::run(&CppModelManager::parse, + preproc, sourceFiles); if (sourceFiles.count() > 1) { m_core->progressManager()->addTask(result, tr("Indexing"), @@ -675,22 +689,29 @@ void CppModelManager::onDocumentUpdated(Document::Ptr doc) } } +void CppModelManager::onProjectAdded(ProjectExplorer::Project *) +{ + m_dirty = true; +} + void CppModelManager::onAboutToRemoveProject(ProjectExplorer::Project *project) { + m_dirty = true; m_projects.remove(project); GC(); } void CppModelManager::onSessionUnloaded() { - if (m_core->progressManager()) + if (m_core->progressManager()) { m_core->progressManager()->cancelTasks(CppTools::Constants::TASK_INDEX); + m_dirty = true; + } } void CppModelManager::parse(QFutureInterface &future, - CppModelManager *model, - QStringList files, - QMap workingCopy) + CppPreprocessor *preproc, + QStringList files) { Q_ASSERT(! files.isEmpty()); @@ -699,14 +720,8 @@ void CppModelManager::parse(QFutureInterface &future, future.setProgressRange(0, files.size()); - CppPreprocessor preproc(model); - preproc.setWorkingCopy(workingCopy); - preproc.setProjectFiles(model->projectFiles()); - preproc.setIncludePaths(model->includePaths()); - preproc.setFrameworkPaths(model->frameworkPaths()); - QString conf = QLatin1String(pp_configuration_file); - (void) preproc(conf); + (void) preproc->run(conf); const int STEP = 10; @@ -725,7 +740,7 @@ void CppModelManager::parse(QFutureInterface &future, #endif QString fileName = files.at(i); - preproc(fileName); + preproc->run(fileName); if (! (i % STEP)) // Yields execution of the current thread. QThread::yieldCurrentThread(); @@ -739,6 +754,8 @@ void CppModelManager::parse(QFutureInterface &future, // Restore the previous thread priority. QThread::currentThread()->setPriority(QThread::NormalPriority); + + delete preproc; } void CppModelManager::GC() @@ -746,7 +763,7 @@ void CppModelManager::GC() DocumentTable documents = m_documents; QSet processed; - QStringList todo = m_projectFiles; + QStringList todo = projectFiles(); while (! todo.isEmpty()) { QString fn = todo.last(); diff --git a/src/plugins/cpptools/cppmodelmanager.h b/src/plugins/cpptools/cppmodelmanager.h index 187187cc5d3..a91a414e480 100644 --- a/src/plugins/cpptools/cppmodelmanager.h +++ b/src/plugins/cpptools/cppmodelmanager.h @@ -58,6 +58,7 @@ namespace CppTools { namespace Internal { class CppEditorSupport; +class CppPreprocessor; class CppHoverHandler; class CppModelManager : public CppModelManagerInterface @@ -97,18 +98,54 @@ private Q_SLOTS: void onDocumentUpdated(CPlusPlus::Document::Ptr doc); void onAboutToRemoveProject(ProjectExplorer::Project *project); void onSessionUnloaded(); + void onProjectAdded(ProjectExplorer::Project *project); private: - QMap buildWorkingCopyList() const; - QStringList projectFiles() const; - QStringList includePaths() const; - QStringList frameworkPaths() const; - QByteArray definedMacros() const; + QMap buildWorkingCopyList(); + + QStringList projectFiles() + { + ensureUpdated(); + return m_projectFiles; + } + + QStringList includePaths() + { + ensureUpdated(); + return m_includePaths; + } + + QStringList frameworkPaths() + { + ensureUpdated(); + return m_frameworkPaths; + } + + QByteArray definedMacros() + { + ensureUpdated(); + return m_definedMacros; + } + + QStringList updateProjectFiles() const; + QStringList updateIncludePaths() const; + QStringList updateFrameworkPaths() const; + QByteArray updateDefinedMacros() const; + + void ensureUpdated() { + if (! m_dirty) + return; + + m_projectFiles = updateProjectFiles(); + m_includePaths = updateIncludePaths(); + m_frameworkPaths = updateFrameworkPaths(); + m_definedMacros = updateDefinedMacros(); + m_dirty = false; + } static void parse(QFutureInterface &future, - CppModelManager *model, - QStringList files, - QMap workingCopy); + CppPreprocessor *preproc, + QStringList files); private: Core::ICore *m_core; @@ -116,8 +153,12 @@ private: CppHoverHandler *m_hoverHandler; DocumentTable m_documents; - // List of available source files + // cache + bool m_dirty; QStringList m_projectFiles; + QStringList m_includePaths; + QStringList m_frameworkPaths; + QByteArray m_definedMacros; // editor integration QMap m_editorSupport; From c9f88bf08ea5115ce0b93521cb3391840c11250a Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 4 Dec 2008 17:17:16 +0100 Subject: [PATCH 13/25] Fixes: Synchronous process hangs on Windows if executable not present Details: StartFailed is triggered before the event loop starts on Windows. --- src/libs/utils/synchronousprocess.cpp | 52 +++++++++++++++++---------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/src/libs/utils/synchronousprocess.cpp b/src/libs/utils/synchronousprocess.cpp index 078373aa208..6a1b2efa840 100644 --- a/src/libs/utils/synchronousprocess.cpp +++ b/src/libs/utils/synchronousprocess.cpp @@ -125,6 +125,7 @@ struct SynchronousProcessPrivate { SynchronousProcessResponse m_result; int m_hangTimerCount; int m_maxHangTimerCount; + bool m_startFailure; ChannelBuffer m_stdOut; ChannelBuffer m_stdErr; @@ -133,7 +134,8 @@ struct SynchronousProcessPrivate { SynchronousProcessPrivate::SynchronousProcessPrivate() : m_stdOutCodec(0), m_hangTimerCount(0), - m_maxHangTimerCount(defaultMaxHangTimerCount) + m_maxHangTimerCount(defaultMaxHangTimerCount), + m_startFailure(false) { } @@ -143,6 +145,7 @@ void SynchronousProcessPrivate::clearForRun() m_stdOut.clearForRun(); m_stdErr.clearForRun(); m_result.clear(); + m_startFailure = false; } // ----------- SynchronousProcess @@ -221,23 +224,27 @@ SynchronousProcessResponse SynchronousProcess::run(const QString &binary, qDebug() << '>' << Q_FUNC_INFO << binary << args; m_d->clearForRun(); - m_d->m_timer.start(); - - QApplication::setOverrideCursor(Qt::WaitCursor); + // On Windows, start failure is triggered immediately if the + // executable cannot be found in the path. Do not start the + // event loop in that case. m_d->m_process.start(binary, args, QIODevice::ReadOnly); - m_d->m_eventLoop.exec(QEventLoop::ExcludeUserInputEvents); - if (m_d->m_result.result == SynchronousProcessResponse::Finished || m_d->m_result.result == SynchronousProcessResponse::FinishedError) { - processStdOut(false); - processStdErr(false); + if (!m_d->m_startFailure) { + m_d->m_timer.start(); + QApplication::setOverrideCursor(Qt::WaitCursor); + m_d->m_eventLoop.exec(QEventLoop::ExcludeUserInputEvents); + if (m_d->m_result.result == SynchronousProcessResponse::Finished || m_d->m_result.result == SynchronousProcessResponse::FinishedError) { + processStdOut(false); + processStdErr(false); + } + + m_d->m_result.stdOut = convertStdOut(m_d->m_stdOut.data); + m_d->m_result.stdErr = convertStdErr(m_d->m_stdErr.data); + + m_d->m_timer.stop(); + QApplication::restoreOverrideCursor(); } - m_d->m_result.stdOut = convertStdOut(m_d->m_stdOut.data); - m_d->m_result.stdErr = convertStdErr(m_d->m_stdErr.data); - - m_d->m_timer.stop(); - QApplication::restoreOverrideCursor(); - if (debug) qDebug() << '<' << Q_FUNC_INFO << binary << m_d->m_result; return m_d->m_result; @@ -246,12 +253,14 @@ SynchronousProcessResponse SynchronousProcess::run(const QString &binary, void SynchronousProcess::slotTimeout() { if (++m_d->m_hangTimerCount > m_d->m_maxHangTimerCount) { + if (debug) + qDebug() << Q_FUNC_INFO << "HANG detected, killing"; m_d->m_process.kill(); m_d->m_result.result = SynchronousProcessResponse::Hang; + } else { + if (debug) + qDebug() << Q_FUNC_INFO << m_d->m_hangTimerCount; } - - if (debug) - qDebug() << Q_FUNC_INFO << m_d->m_hangTimerCount; } void SynchronousProcess::finished(int exitCode, QProcess::ExitStatus e) @@ -265,7 +274,9 @@ void SynchronousProcess::finished(int exitCode, QProcess::ExitStatus e) m_d->m_result.exitCode = exitCode; break; case QProcess::CrashExit: - m_d->m_result.result = SynchronousProcessResponse::TerminatedAbnormally; + // Was hang detected before and killed? + if (m_d->m_result.result != SynchronousProcessResponse::Hang) + m_d->m_result.result = SynchronousProcessResponse::TerminatedAbnormally; m_d->m_result.exitCode = -1; break; } @@ -277,7 +288,10 @@ void SynchronousProcess::error(QProcess::ProcessError e) m_d->m_hangTimerCount = 0; if (debug) qDebug() << Q_FUNC_INFO << e; - m_d->m_result.result = SynchronousProcessResponse::StartFailed; + // Was hang detected before and killed? + if (m_d->m_result.result != SynchronousProcessResponse::Hang) + m_d->m_result.result = SynchronousProcessResponse::StartFailed; + m_d->m_startFailure = true; m_d->m_eventLoop.quit(); } From cecd5023ddc7c0ed56541d9a7e1f4473acef05d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorbj=C3=B8rn=20Lindeijer?= Date: Fri, 28 Nov 2008 15:36:54 +0100 Subject: [PATCH 14/25] First incarnation of classes quickopen filter Invokable with 'c', currently shows all classes it can find. --- src/plugins/cpptools/cppclassesfilter.cpp | 49 ++++++ src/plugins/cpptools/cppclassesfilter.h | 58 +++++++ src/plugins/cpptools/cppquickopenfilter.cpp | 168 +----------------- src/plugins/cpptools/cppquickopenfilter.h | 48 ++---- src/plugins/cpptools/cpptools.cpp | 2 + src/plugins/cpptools/cpptools.pro | 25 ++- src/plugins/cpptools/searchsymbols.cpp | 178 ++++++++++++++++++++ src/plugins/cpptools/searchsymbols.h | 128 ++++++++++++++ src/plugins/texteditor/basetexteditor.cpp | 3 +- 9 files changed, 441 insertions(+), 218 deletions(-) create mode 100644 src/plugins/cpptools/cppclassesfilter.cpp create mode 100644 src/plugins/cpptools/cppclassesfilter.h create mode 100644 src/plugins/cpptools/searchsymbols.cpp create mode 100644 src/plugins/cpptools/searchsymbols.h diff --git a/src/plugins/cpptools/cppclassesfilter.cpp b/src/plugins/cpptools/cppclassesfilter.cpp new file mode 100644 index 00000000000..3d8da9a7387 --- /dev/null +++ b/src/plugins/cpptools/cppclassesfilter.cpp @@ -0,0 +1,49 @@ +/*************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** +** Non-Open Source Usage +** +** Licensees may use this file in accordance with the Qt Beta Version +** License Agreement, Agreement version 2.2 provided with the Software or, +** alternatively, in accordance with the terms contained in a written +** agreement between you and Nokia. +** +** GNU General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the packaging +** of this file. Please review the following information to ensure GNU +** General Public Licensing requirements will be met: +** +** http://www.fsf.org/licensing/licenses/info/GPLv2.html and +** http://www.gnu.org/copyleft/gpl.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt GPL Exception +** version 1.2, included in the file GPL_EXCEPTION.txt in this package. +** +***************************************************************************/ + +#include "cppclassesfilter.h" + +using namespace CppTools::Internal; + +CppClassesFilter::CppClassesFilter(CppModelManager *manager, Core::EditorManager *editorManager) + : CppQuickOpenFilter(manager, editorManager) +{ + setShortcutString("c"); + setIncludedByDefault(false); + + search.setSymbolsToSearchFor(SearchSymbols::Classes); +} + +CppClassesFilter::~CppClassesFilter() +{ +} diff --git a/src/plugins/cpptools/cppclassesfilter.h b/src/plugins/cpptools/cppclassesfilter.h new file mode 100644 index 00000000000..ba936eab869 --- /dev/null +++ b/src/plugins/cpptools/cppclassesfilter.h @@ -0,0 +1,58 @@ +/*************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** +** Non-Open Source Usage +** +** Licensees may use this file in accordance with the Qt Beta Version +** License Agreement, Agreement version 2.2 provided with the Software or, +** alternatively, in accordance with the terms contained in a written +** agreement between you and Nokia. +** +** GNU General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the packaging +** of this file. Please review the following information to ensure GNU +** General Public Licensing requirements will be met: +** +** http://www.fsf.org/licensing/licenses/info/GPLv2.html and +** http://www.gnu.org/copyleft/gpl.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt GPL Exception +** version 1.2, included in the file GPL_EXCEPTION.txt in this package. +** +***************************************************************************/ + +#ifndef CPPCLASSESFILTER_H +#define CPPCLASSESFILTER_H + +#include + +namespace CppTools { +namespace Internal { + +class CppClassesFilter : public CppQuickOpenFilter +{ + Q_OBJECT + +public: + CppClassesFilter(CppModelManager *manager, Core::EditorManager *editorManager); + ~CppClassesFilter(); + + QString trName() const { return tr("Classes"); } + QString name() const { return QLatin1String("Classes"); } + Priority priority() const { return Medium; } +}; + +} // namespace Internal +} // namespace CppTools + +#endif // CPPCLASSESFILTER_H diff --git a/src/plugins/cpptools/cppquickopenfilter.cpp b/src/plugins/cpptools/cppquickopenfilter.cpp index 9470ec46039..a1f1a9b3713 100644 --- a/src/plugins/cpptools/cppquickopenfilter.cpp +++ b/src/plugins/cpptools/cppquickopenfilter.cpp @@ -32,172 +32,13 @@ ***************************************************************************/ #include "cppquickopenfilter.h" +#include "cppmodelmanager.h" -#include -#include -#include -#include -#include -#include - +#include #include #include #include -#include - -#include - -using namespace CPlusPlus; - -namespace CppTools { -namespace Internal { - -class SearchSymbols: public std::unary_function >, - protected SymbolVisitor -{ - Overview overview; - Icons icons; - QList items; - -public: - QList operator()(Document::Ptr doc) - { return operator()(doc, QString()); } - - QList operator()(Document::Ptr doc, const QString &scope) - { - QString previousScope = switchScope(scope); - items.clear(); - for (unsigned i = 0; i < doc->globalSymbolCount(); ++i) { - accept(doc->globalSymbolAt(i)); - } - (void) switchScope(previousScope); - return items; - } - -protected: - using SymbolVisitor::visit; - - void accept(Symbol *symbol) - { Symbol::visitSymbol(symbol, this); } - - QString switchScope(const QString &scope) - { - QString previousScope = _scope; - _scope = scope; - return previousScope; - } - - virtual bool visit(Enum *symbol) - { - QString name = symbolName(symbol); - QString previousScope = switchScope(name); - QIcon icon = icons.iconForSymbol(symbol); - Scope *members = symbol->members(); - items.append(ModelItemInfo(name, QString(), ModelItemInfo::Enum, - QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()), - symbol->line(), - icon)); - for (unsigned i = 0; i < members->symbolCount(); ++i) { - accept(members->symbolAt(i)); - } - (void) switchScope(previousScope); - return false; - } - - virtual bool visit(Function *symbol) - { - QString name = symbolName(symbol); - QString type = overview.prettyType(symbol->type()); - QIcon icon = icons.iconForSymbol(symbol); - items.append(ModelItemInfo(name, type, ModelItemInfo::Method, - QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()), - symbol->line(), - icon)); - return false; - } - - virtual bool visit(Namespace *symbol) - { - QString name = symbolName(symbol); - QString previousScope = switchScope(name); - Scope *members = symbol->members(); - for (unsigned i = 0; i < members->symbolCount(); ++i) { - accept(members->symbolAt(i)); - } - (void) switchScope(previousScope); - return false; - } -#if 0 - // This visit method would make function declaration be included in QuickOpen - virtual bool visit(Declaration *symbol) - { - if (symbol->type()->isFunction()) { - QString name = symbolName(symbol); - QString type = overview.prettyType(symbol->type()); - //QIcon icon = ...; - items.append(ModelItemInfo(name, type, ModelItemInfo::Method, - QString::fromUtf8(symbol->fileName(), symbol->line()), - symbol->line())); - } - return false; - } -#endif - virtual bool visit(Class *symbol) - { - QString name = symbolName(symbol); - QString previousScope = switchScope(name); - QIcon icon = icons.iconForSymbol(symbol); - items.append(ModelItemInfo(name, QString(), ModelItemInfo::Class, - QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()), - symbol->line(), - icon)); - Scope *members = symbol->members(); - for (unsigned i = 0; i < members->symbolCount(); ++i) { - accept(members->symbolAt(i)); - } - (void) switchScope(previousScope); - return false; - } - - QString symbolName(Symbol *symbol) const - { - QString name = _scope; - if (! name.isEmpty()) - name += QLatin1String("::"); - QString symbolName = overview.prettyName(symbol->name()); - if (symbolName.isEmpty()) { - QString type; - if (symbol->isNamespace()) { - type = QLatin1String("namespace"); - } else if (symbol->isEnum()) { - type = QLatin1String("enum"); - } else if (Class *c = symbol->asClass()) { - if (c->isUnion()) { - type = QLatin1String("union"); - } else if (c->isStruct()) { - type = QLatin1String("struct"); - } else { - type = QLatin1String("class"); - } - } else { - type = QLatin1String("symbol"); - } - symbolName = QLatin1String(""); - } - name += symbolName; - return name; - } - -private: - QString _scope; -}; - -} // namespace Internal -} // namespace CppTools - using namespace CppTools::Internal; CppQuickOpenFilter::CppQuickOpenFilter(CppModelManager *manager, Core::EditorManager *editorManager) @@ -225,9 +66,8 @@ void CppQuickOpenFilter::onDocumentUpdated(CPlusPlus::Document::Ptr doc) void CppQuickOpenFilter::onAboutToRemoveFiles(const QStringList &files) { - foreach (QString file, files) { + foreach (const QString &file, files) m_searchList.remove(file); - } } void CppQuickOpenFilter::refresh(QFutureInterface &future) @@ -245,7 +85,6 @@ QList CppQuickOpenFilter::matchesFor(const QString &orig return entries; bool hasWildcard = (entry.contains('*') || entry.contains('?')); - SearchSymbols search; QMutableMapIterator it(m_searchList); while (it.hasNext()) { it.next(); @@ -276,6 +115,5 @@ QList CppQuickOpenFilter::matchesFor(const QString &orig void CppQuickOpenFilter::accept(QuickOpen::FilterEntry selection) const { ModelItemInfo info = qvariant_cast(selection.internalData); - TextEditor::BaseTextEditor::openEditorAt(info.fileName, info.line); } diff --git a/src/plugins/cpptools/cppquickopenfilter.h b/src/plugins/cpptools/cppquickopenfilter.h index bf6696a02af..12eaacb3f98 100644 --- a/src/plugins/cpptools/cppquickopenfilter.h +++ b/src/plugins/cpptools/cppquickopenfilter.h @@ -34,45 +34,18 @@ #ifndef CPPQUICKOPENFILTER_H #define CPPQUICKOPENFILTER_H -#include "cppmodelmanager.h" -#include -#include +#include "searchsymbols.h" + #include -#include -#include -#include + +namespace Core { +class EditorManager; +} namespace CppTools { namespace Internal { -struct ModelItemInfo -{ - enum ItemType { Enum, Class, Method }; - - ModelItemInfo() - { } - - ModelItemInfo(const QString &symbolName, - const QString &symbolType, - ItemType type, - const QString &fileName, - int line, - const QIcon &icon) - : symbolName(symbolName), - symbolType(symbolType), - type(type), - fileName(fileName), - line(line), - icon(icon) - { } - - QString symbolName; - QString symbolType; - ItemType type; - QString fileName; - int line; - QIcon icon; -}; +class CppModelManager; class CppQuickOpenFilter : public QuickOpen::IQuickOpenFilter { @@ -82,12 +55,15 @@ public: ~CppQuickOpenFilter(); QString trName() const { return tr("Classes and Methods"); } - QString name() const { return "Classes and Methods"; } + QString name() const { return QLatin1String("Classes and Methods"); } Priority priority() const { return Medium; } QList matchesFor(const QString &entry); void accept(QuickOpen::FilterEntry selection) const; void refresh(QFutureInterface &future); +protected: + SearchSymbols search; + private slots: void onDocumentUpdated(CPlusPlus::Document::Ptr doc); void onAboutToRemoveFiles(const QStringList &files); @@ -114,6 +90,4 @@ private: } // namespace Internal } // namespace CppTools -Q_DECLARE_METATYPE(CppTools::Internal::ModelItemInfo) - #endif // CPPQUICKOPENFILTER_H diff --git a/src/plugins/cpptools/cpptools.cpp b/src/plugins/cpptools/cpptools.cpp index 423ddf3016d..957f0cae9b0 100644 --- a/src/plugins/cpptools/cpptools.cpp +++ b/src/plugins/cpptools/cpptools.cpp @@ -32,6 +32,7 @@ ***************************************************************************/ #include "cpptools.h" +#include "cppclassesfilter.h" #include "cppcodecompletion.h" #include "cpphoverhandler.h" #include "cppmodelmanager.h" @@ -87,6 +88,7 @@ bool CppToolsPlugin::initialize(const QStringList & /*arguments*/, QString *) CppQuickOpenFilter *quickOpenFilter = new CppQuickOpenFilter(m_modelManager, m_core->editorManager()); addAutoReleasedObject(quickOpenFilter); + addAutoReleasedObject(new CppClassesFilter(m_modelManager, m_core->editorManager())); // Menus Core::IActionContainer *mtools = am->actionContainer(Core::Constants::M_TOOLS); diff --git a/src/plugins/cpptools/cpptools.pro b/src/plugins/cpptools/cpptools.pro index 17b72496a92..8a096900ebf 100644 --- a/src/plugins/cpptools/cpptools.pro +++ b/src/plugins/cpptools/cpptools.pro @@ -4,31 +4,27 @@ include(../../qworkbenchplugin.pri) include(../../plugins/quickopen/quickopen.pri) include(cpptools_dependencies.pri) -#DEFINES += QT_NO_CAST_FROM_ASCII +# DEFINES += QT_NO_CAST_FROM_ASCII DEFINES += QT_NO_CAST_TO_ASCII -unix:QMAKE_CXXFLAGS_DEBUG+=-O3 - +unix:QMAKE_CXXFLAGS_DEBUG += -O3 INCLUDEPATH += . - DEFINES += CPPTOOLS_LIBRARY - CONFIG += help include(rpp/rpp.pri)|error("Can't find RPP") - -HEADERS += \ - cpptools_global.h \ - cppquickopenfilter.h - -SOURCES += \ - cppquickopenfilter.cpp \ - cpptoolseditorsupport.cpp +HEADERS += cpptools_global.h \ + cppquickopenfilter.h \ + cppclassesfilter.h \ + searchsymbols.h +SOURCES += cppquickopenfilter.cpp \ + cpptoolseditorsupport.cpp \ + cppclassesfilter.cpp \ + searchsymbols.cpp # Input SOURCES += cpptools.cpp \ cppmodelmanager.cpp \ cppcodecompletion.cpp \ cpphoverhandler.cpp - HEADERS += cpptools.h \ cppmodelmanager.h \ cppcodecompletion.h \ @@ -36,5 +32,4 @@ HEADERS += cpptools.h \ cppmodelmanagerinterface.h \ cpptoolseditorsupport.h \ cpptoolsconstants.h - RESOURCES += cpptools.qrc diff --git a/src/plugins/cpptools/searchsymbols.cpp b/src/plugins/cpptools/searchsymbols.cpp new file mode 100644 index 00000000000..c0d29aae18a --- /dev/null +++ b/src/plugins/cpptools/searchsymbols.cpp @@ -0,0 +1,178 @@ +/*************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** +** Non-Open Source Usage +** +** Licensees may use this file in accordance with the Qt Beta Version +** License Agreement, Agreement version 2.2 provided with the Software or, +** alternatively, in accordance with the terms contained in a written +** agreement between you and Nokia. +** +** GNU General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the packaging +** of this file. Please review the following information to ensure GNU +** General Public Licensing requirements will be met: +** +** http://www.fsf.org/licensing/licenses/info/GPLv2.html and +** http://www.gnu.org/copyleft/gpl.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt GPL Exception +** version 1.2, included in the file GPL_EXCEPTION.txt in this package. +** +***************************************************************************/ + +#include "searchsymbols.h" + +#include +#include + +using namespace CPlusPlus; +using namespace CppTools::Internal; + +SearchSymbols::SearchSymbols(): + symbolsToSearchFor(ClassesMethodsFunctionsAndEnums) +{ +} + +void SearchSymbols::setSymbolsToSearchFor(SymbolType type) +{ + symbolsToSearchFor = type; +} + +QList SearchSymbols::operator()(Document::Ptr doc, const QString &scope) +{ + QString previousScope = switchScope(scope); + items.clear(); + for (unsigned i = 0; i < doc->globalSymbolCount(); ++i) { + accept(doc->globalSymbolAt(i)); + } + (void) switchScope(previousScope); + return items; +} + +QString SearchSymbols::switchScope(const QString &scope) +{ + QString previousScope = _scope; + _scope = scope; + return previousScope; +} + +bool SearchSymbols::visit(Enum *symbol) +{ + if (symbolsToSearchFor != ClassesMethodsFunctionsAndEnums) + return false; + + QString name = symbolName(symbol); + QString previousScope = switchScope(name); + QIcon icon = icons.iconForSymbol(symbol); + Scope *members = symbol->members(); + items.append(ModelItemInfo(name, QString(), ModelItemInfo::Enum, + QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()), + symbol->line(), + icon)); + for (unsigned i = 0; i < members->symbolCount(); ++i) { + accept(members->symbolAt(i)); + } + (void) switchScope(previousScope); + return false; +} + +bool SearchSymbols::visit(Function *symbol) +{ + if (symbolsToSearchFor != ClassesMethodsFunctionsAndEnums) + return false; + + QString name = symbolName(symbol); + QString type = overview.prettyType(symbol->type()); + QIcon icon = icons.iconForSymbol(symbol); + items.append(ModelItemInfo(name, type, ModelItemInfo::Method, + QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()), + symbol->line(), + icon)); + return false; +} + +bool SearchSymbols::visit(Namespace *symbol) +{ + QString name = symbolName(symbol); + QString previousScope = switchScope(name); + Scope *members = symbol->members(); + for (unsigned i = 0; i < members->symbolCount(); ++i) { + accept(members->symbolAt(i)); + } + (void) switchScope(previousScope); + return false; +} + +#if 0 +bool SearchSymbols::visit(Declaration *symbol) +{ + if (symbol->type()->isFunction()) { + QString name = symbolName(symbol); + QString type = overview.prettyType(symbol->type()); + //QIcon icon = ...; + items.append(ModelItemInfo(name, type, ModelItemInfo::Method, + QString::fromUtf8(symbol->fileName(), symbol->line()), + symbol->line())); + } + return false; +} +#endif + +bool SearchSymbols::visit(Class *symbol) +{ + QString name = symbolName(symbol); + QString previousScope = switchScope(name); + QIcon icon = icons.iconForSymbol(symbol); + items.append(ModelItemInfo(name, QString(), ModelItemInfo::Class, + QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()), + symbol->line(), + icon)); + Scope *members = symbol->members(); + for (unsigned i = 0; i < members->symbolCount(); ++i) { + accept(members->symbolAt(i)); + } + (void) switchScope(previousScope); + return false; +} + +QString SearchSymbols::symbolName(const Symbol *symbol) const +{ + QString name = _scope; + if (! name.isEmpty()) + name += QLatin1String("::"); + QString symbolName = overview.prettyName(symbol->name()); + if (symbolName.isEmpty()) { + QString type; + if (symbol->isNamespace()) { + type = QLatin1String("namespace"); + } else if (symbol->isEnum()) { + type = QLatin1String("enum"); + } else if (const Class *c = symbol->asClass()) { + if (c->isUnion()) { + type = QLatin1String("union"); + } else if (c->isStruct()) { + type = QLatin1String("struct"); + } else { + type = QLatin1String("class"); + } + } else { + type = QLatin1String("symbol"); + } + symbolName = QLatin1String(""); + } + name += symbolName; + return name; +} diff --git a/src/plugins/cpptools/searchsymbols.h b/src/plugins/cpptools/searchsymbols.h new file mode 100644 index 00000000000..d9b678e026f --- /dev/null +++ b/src/plugins/cpptools/searchsymbols.h @@ -0,0 +1,128 @@ +/*************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** +** Non-Open Source Usage +** +** Licensees may use this file in accordance with the Qt Beta Version +** License Agreement, Agreement version 2.2 provided with the Software or, +** alternatively, in accordance with the terms contained in a written +** agreement between you and Nokia. +** +** GNU General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the packaging +** of this file. Please review the following information to ensure GNU +** General Public Licensing requirements will be met: +** +** http://www.fsf.org/licensing/licenses/info/GPLv2.html and +** http://www.gnu.org/copyleft/gpl.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt GPL Exception +** version 1.2, included in the file GPL_EXCEPTION.txt in this package. +** +***************************************************************************/ + +#ifndef SEARCHSYMBOLS_H +#define SEARCHSYMBOLS_H + +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace CppTools { +namespace Internal { + +struct ModelItemInfo +{ + enum ItemType { Enum, Class, Method }; + + ModelItemInfo() + { } + + ModelItemInfo(const QString &symbolName, + const QString &symbolType, + ItemType type, + const QString &fileName, + int line, + const QIcon &icon) + : symbolName(symbolName), + symbolType(symbolType), + type(type), + fileName(fileName), + line(line), + icon(icon) + { } + + QString symbolName; + QString symbolType; + ItemType type; + QString fileName; + int line; + QIcon icon; +}; + +class SearchSymbols: public std::unary_function >, + protected CPlusPlus::SymbolVisitor +{ +public: + // TODO: Probably should use QFlags + enum SymbolType { + Classes, + ClassesMethodsFunctionsAndEnums + }; + + SearchSymbols(); + + void setSymbolsToSearchFor(SymbolType type); + + QList operator()(CPlusPlus::Document::Ptr doc) + { return operator()(doc, QString()); } + + QList operator()(CPlusPlus::Document::Ptr doc, const QString &scope); + +protected: + using SymbolVisitor::visit; + + void accept(CPlusPlus::Symbol *symbol) + { CPlusPlus::Symbol::visitSymbol(symbol, this); } + + QString switchScope(const QString &scope); + virtual bool visit(CPlusPlus::Enum *symbol); + virtual bool visit(CPlusPlus::Function *symbol); + virtual bool visit(CPlusPlus::Namespace *symbol); +#if 0 + // This visit method would make function declaration be included in QuickOpen + virtual bool visit(CPlusPlus::Declaration *symbol); +#endif + virtual bool visit(CPlusPlus::Class *symbol); + QString symbolName(const CPlusPlus::Symbol *symbol) const; + +private: + QString _scope; + CPlusPlus::Overview overview; + CPlusPlus::Icons icons; + QList items; + SymbolType symbolsToSearchFor; +}; + +} // namespace Internal +} // namespace CppTools + +Q_DECLARE_METATYPE(CppTools::Internal::ModelItemInfo) + +#endif // SEARCHSYMBOLS_H diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp index df5fe410808..bc9627df963 100644 --- a/src/plugins/texteditor/basetexteditor.cpp +++ b/src/plugins/texteditor/basetexteditor.cpp @@ -501,7 +501,8 @@ void BaseTextEditor::currentEditorChanged(Core::IEditor *editor) if (editor == d->m_editable) { if (d->m_document->hasDecodingError()) { Core::EditorManager::instance()->showEditorInfoBar(QLatin1String(Constants::SELECT_ENCODING), - tr("Error: Could not decode \"%1\" with \"%2\"-encoding. Editing not possible.").arg(displayName()).arg(QString::fromLatin1(d->m_document->codec()->name())), + tr("Error: Could not decode \"%1\" with \"%2\"-encoding. Editing not possible.") + .arg(displayName()).arg(QString::fromLatin1(d->m_document->codec()->name())), tr("Select Encoding"), this, SLOT(selectEncoding())); } From e9ad023def7e6edb3f1c6ec2f99faa3584f615eb Mon Sep 17 00:00:00 2001 From: mae Date: Thu, 4 Dec 2008 18:37:02 +0100 Subject: [PATCH 15/25] block navigation and selection (bound to Ctrl+[]{} --- src/plugins/find/basetextfind.cpp | 5 +- src/plugins/texteditor/basetexteditor.cpp | 118 +++++++++++++++++- src/plugins/texteditor/basetexteditor.h | 10 ++ .../texteditor/texteditoractionhandler.cpp | 90 +++++++------ .../texteditor/texteditoractionhandler.h | 8 ++ src/plugins/texteditor/texteditorconstants.h | 6 + 6 files changed, 187 insertions(+), 50 deletions(-) diff --git a/src/plugins/find/basetextfind.cpp b/src/plugins/find/basetextfind.cpp index 63740d36527..6598a47e6f3 100644 --- a/src/plugins/find/basetextfind.cpp +++ b/src/plugins/find/basetextfind.cpp @@ -162,7 +162,10 @@ int BaseTextFind::replaceAll(const QString &before, const QString &after, QTextDocument::FindFlags findFlags) { QTextCursor editCursor = textCursor(); - editCursor.movePosition(QTextCursor::Start); + if (!m_findScope.isNull()) + editCursor.setPosition(m_findScope.selectionStart()); + else + editCursor.movePosition(QTextCursor::Start); editCursor.beginEditBlock(); int count = 0; QTextCursor found; diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp index df5fe410808..a0cf9dee3b0 100644 --- a/src/plugins/texteditor/basetexteditor.cpp +++ b/src/plugins/texteditor/basetexteditor.cpp @@ -531,7 +531,6 @@ void BaseTextEditor::selectEncoding() } } - void DocumentMarker::updateMark(ITextMark *mark) { TextEditDocumentLayout *documentLayout = qobject_cast(document->documentLayout()); @@ -600,6 +599,36 @@ void BaseTextEditor::slotSelectionChanged() d->m_blockSelectionExtraX = 0; } +void BaseTextEditor::gotoBlockStart() +{ + QTextCursor cursor = textCursor(); + if (TextBlockUserData::findPreviousOpenParenthesis(&cursor, false)) + setTextCursor(cursor); +} + +void BaseTextEditor::gotoBlockEnd() +{ + QTextCursor cursor = textCursor(); + if (TextBlockUserData::findNextClosingParenthesis(&cursor, false)) + setTextCursor(cursor); +} + +void BaseTextEditor::gotoBlockStartWithSelection() +{ + QTextCursor cursor = textCursor(); + if (TextBlockUserData::findPreviousOpenParenthesis(&cursor, true)) + setTextCursor(cursor); +} + +void BaseTextEditor::gotoBlockEndWithSelection() +{ + QTextCursor cursor = textCursor(); + if (TextBlockUserData::findNextClosingParenthesis(&cursor, true)) + setTextCursor(cursor); +} + + + void BaseTextEditor::keyPressEvent(QKeyEvent *e) { @@ -633,6 +662,11 @@ void BaseTextEditor::keyPressEvent(QKeyEvent *e) e->accept(); return; } + } else if (e == QKeySequence::Paste) { + if (!ro) { + d->removeBlockSelection(); + // continue + } } } @@ -693,6 +727,8 @@ void BaseTextEditor::keyPressEvent(QKeyEvent *e) break; case Qt::Key_Home: if (!(e == QKeySequence::MoveToStartOfDocument) && !(e == QKeySequence::SelectStartOfDocument)) { + if ((e->modifiers() & (Qt::AltModifier | Qt::ShiftModifier)) == (Qt::AltModifier | Qt::ShiftModifier)) + d->m_lastEventWasBlockSelectionEvent = true; handleHomeKey(e->modifiers() & Qt::ShiftModifier); e->accept(); return; @@ -708,6 +744,7 @@ void BaseTextEditor::keyPressEvent(QKeyEvent *e) return; } // fall through + case Qt::Key_End: case Qt::Key_Right: case Qt::Key_Left: #ifndef Q_OS_MAC @@ -795,6 +832,15 @@ skip_event: delete e; } +void BaseTextEditor::setTextCursor(const QTextCursor &cursor) +{ + // workaround for QTextControl bug + bool selectionChange = cursor.hasSelection() || textCursor().hasSelection(); + QPlainTextEdit::setTextCursor(cursor); + if (selectionChange) + slotSelectionChanged(); +} + void BaseTextEditor::gotoLine(int line, int column) { const int blockNumber = line - 1; @@ -2908,6 +2954,61 @@ TextBlockUserData::MatchType TextBlockUserData::checkClosedParenthesis(QTextCurs } } + +bool TextBlockUserData::findPreviousOpenParenthesis(QTextCursor *cursor, bool select) +{ + QTextBlock block = cursor->block(); + int position = cursor->position(); + int ignore = 0; + while (block.isValid()) { + Parentheses parenList = TextEditDocumentLayout::parentheses(block); + if (!parenList.isEmpty()) { + for (int i = parenList.count()-1; i >= 0; --i) { + Parenthesis paren = parenList.at(i); + if (block == cursor->block() && position - block.position() <= paren.pos + 1) + continue; + if (paren.type == Parenthesis::Closed) { + ++ignore; + } else if (ignore > 0) { + --ignore; + } else { + cursor->setPosition(block.position() + paren.pos, select ? QTextCursor::KeepAnchor : QTextCursor::MoveAnchor); + return true; + } + } + } + block = block.previous(); + } + return false; +} + +bool TextBlockUserData::findNextClosingParenthesis(QTextCursor *cursor, bool select) +{ + QTextBlock block = cursor->block(); + int position = cursor->position(); + int ignore = 0; + while (block.isValid()) { + Parentheses parenList = TextEditDocumentLayout::parentheses(block); + if (!parenList.isEmpty()) { + for (int i = 0; i < parenList.count(); ++i) { + Parenthesis paren = parenList.at(i); + if (block == cursor->block() && position - block.position() >= paren.pos) + continue; + if (paren.type == Parenthesis::Opened) { + ++ignore; + } else if (ignore > 0) { + --ignore; + } else { + cursor->setPosition(block.position() + paren.pos+1, select ? QTextCursor::KeepAnchor : QTextCursor::MoveAnchor); + return true; + } + } + } + block = block.next(); + } + return false; +} + TextBlockUserData::MatchType TextBlockUserData::matchCursorBackward(QTextCursor *cursor) { cursor->clearSelection(); @@ -3152,13 +3253,16 @@ void BaseTextEditor::collapse() TextEditDocumentLayout *documentLayout = qobject_cast(doc->documentLayout()); Q_ASSERT(documentLayout); QTextBlock block = textCursor().block(); + qDebug() << "collapse at block" << block.blockNumber(); while (block.isValid()) { - if (TextBlockUserData::canCollapse(block)) { - if ((block.next().userState()) >> 8 == (textCursor().block().userState() >> 8)) + qDebug() << "test block" << block.blockNumber(); + if (TextBlockUserData::canCollapse(block) && block.next().isVisible()) { + if ((block.next().userState()) >> 8 <= (textCursor().block().userState() >> 8)) break; } block = block.previous(); } + qDebug() << "found" << block.blockNumber(); if (block.isValid()) { TextBlockUserData::doCollapse(block, false); d->moveCursorVisible(); @@ -3238,6 +3342,14 @@ void BaseTextEditor::cut() QPlainTextEdit::cut(); } +void BaseTextEditor::paste() +{ + if (d->m_inBlockSelectionMode) { + d->removeBlockSelection(); + } + QPlainTextEdit::paste(); +} + QMimeData *BaseTextEditor::createMimeDataFromSelection() const { if (d->m_inBlockSelectionMode) { diff --git a/src/plugins/texteditor/basetexteditor.h b/src/plugins/texteditor/basetexteditor.h index ced22900030..54e4728c4b4 100644 --- a/src/plugins/texteditor/basetexteditor.h +++ b/src/plugins/texteditor/basetexteditor.h @@ -169,6 +169,8 @@ public: static MatchType checkClosedParenthesis(QTextCursor *cursor, QChar c); static MatchType matchCursorBackward(QTextCursor *cursor); static MatchType matchCursorForward(QTextCursor *cursor); + static bool findPreviousOpenParenthesis(QTextCursor *cursor, bool select = false); + static bool findNextClosingParenthesis(QTextCursor *cursor, bool select = false); private: @@ -298,6 +300,8 @@ public: void setReadOnly(bool b); + void setTextCursor(const QTextCursor &cursor); + public slots: void setDisplayName(const QString &title); virtual void setFontSettings(const TextEditor::FontSettings &); @@ -305,6 +309,7 @@ public slots: virtual void unCommentSelection(); virtual void setStorageSettings(const TextEditor::StorageSettings &); + void paste(); void cut(); void zoomIn(int range = 1); @@ -316,6 +321,11 @@ public slots: void expand(); void selectEncoding(); + void gotoBlockStart(); + void gotoBlockEnd(); + void gotoBlockStartWithSelection(); + void gotoBlockEndWithSelection(); + signals: void changed(); diff --git a/src/plugins/texteditor/texteditoractionhandler.cpp b/src/plugins/texteditor/texteditoractionhandler.cpp index 94cdca6cfda..a9e955eae36 100644 --- a/src/plugins/texteditor/texteditoractionhandler.cpp +++ b/src/plugins/texteditor/texteditoractionhandler.cpp @@ -67,6 +67,8 @@ TextEditorActionHandler::TextEditorActionHandler(Core::ICore *core, = m_collapseAction = m_expandAction = m_deleteLineAction = m_selectEncodingAction = m_increaseFontSizeAction = m_decreaseFontSizeAction + = m_gotoBlockStartAction = m_gotoBlockStartWithSelectionAction + = m_gotoBlockEndAction = m_gotoBlockEndWithSelectionAction = 0; m_contextId << m_core->uniqueIDManager()->uniqueIdentifier(context); @@ -185,6 +187,27 @@ void TextEditorActionHandler::createActions() command->setDefaultKeySequence(QKeySequence(tr("Ctrl+-"))); connect(m_decreaseFontSizeAction, SIGNAL(triggered()), this, SLOT(decreaseFontSize())); advancedMenu->addAction(command); + + m_gotoBlockStartAction = new QAction(tr("Goto Block Start"), this); + command = am->registerAction(m_gotoBlockStartAction, Constants::GOTO_BLOCK_START, m_contextId); + command->setDefaultKeySequence(QKeySequence(tr("Ctrl+["))); + connect(m_gotoBlockStartAction, SIGNAL(triggered()), this, SLOT(gotoBlockStart())); + + m_gotoBlockEndAction = new QAction(tr("Goto Block End"), this); + command = am->registerAction(m_gotoBlockEndAction, Constants::GOTO_BLOCK_END, m_contextId); + command->setDefaultKeySequence(QKeySequence(tr("Ctrl+]"))); + connect(m_gotoBlockEndAction, SIGNAL(triggered()), this, SLOT(gotoBlockEnd())); + + m_gotoBlockStartWithSelectionAction = new QAction(tr("Goto Block Start With Selection"), this); + command = am->registerAction(m_gotoBlockStartWithSelectionAction, Constants::GOTO_BLOCK_START_WITH_SELECTION, m_contextId); + command->setDefaultKeySequence(QKeySequence(tr("Ctrl+{"))); + connect(m_gotoBlockStartWithSelectionAction, SIGNAL(triggered()), this, SLOT(gotoBlockStartWithSelection())); + + m_gotoBlockEndWithSelectionAction = new QAction(tr("Goto Block End With Selection"), this); + command = am->registerAction(m_gotoBlockEndWithSelectionAction, Constants::GOTO_BLOCK_END_WITH_SELECTION, m_contextId); + command->setDefaultKeySequence(QKeySequence(tr("Ctrl+}"))); + connect(m_gotoBlockEndWithSelectionAction, SIGNAL(triggered()), this, SLOT(gotoBlockEndWithSelection())); + } bool TextEditorActionHandler::supportsAction(const QString & /*id */) const @@ -365,54 +388,29 @@ void TextEditorActionHandler::setTextWrapping(bool checked) } } -void TextEditorActionHandler::unCommentSelection() -{ - if (m_currentEditor) - m_currentEditor->unCommentSelection(); -} - -void TextEditorActionHandler::deleteLine() -{ - if (m_currentEditor) - m_currentEditor->deleteLine(); -} - -void TextEditorActionHandler::unCollapseAll() -{ - if (m_currentEditor) - m_currentEditor->unCollapseAll(); -} - -void TextEditorActionHandler::collapse() -{ - if (m_currentEditor) - m_currentEditor->collapse(); -} - -void TextEditorActionHandler::expand() -{ - if (m_currentEditor) - m_currentEditor->expand(); -} - -void TextEditorActionHandler::selectEncoding() -{ - if (m_currentEditor) - m_currentEditor->selectEncoding(); -} - -void TextEditorActionHandler::increaseFontSize() -{ - if (m_currentEditor) - m_currentEditor->zoomIn(); -} - -void TextEditorActionHandler::decreaseFontSize() -{ - if (m_currentEditor) - m_currentEditor->zoomOut(); +#define FUNCTION(funcname) void TextEditorActionHandler::funcname ()\ +{\ + if (m_currentEditor)\ + m_currentEditor->funcname ();\ +} +#define FUNCTION2(funcname, funcname2) void TextEditorActionHandler::funcname ()\ +{\ + if (m_currentEditor)\ + m_currentEditor->funcname2 ();\ } +FUNCTION(unCommentSelection) +FUNCTION(deleteLine) +FUNCTION(unCollapseAll) +FUNCTION(collapse) +FUNCTION(expand) +FUNCTION2(increaseFontSize, zoomIn) +FUNCTION2(decreaseFontSize, zoomOut) +FUNCTION(selectEncoding) +FUNCTION(gotoBlockStart) +FUNCTION(gotoBlockEnd) +FUNCTION(gotoBlockStartWithSelection) +FUNCTION(gotoBlockEndWithSelection) void TextEditorActionHandler::updateCurrentEditor(Core::IContext *object) { diff --git a/src/plugins/texteditor/texteditoractionhandler.h b/src/plugins/texteditor/texteditoractionhandler.h index 79ac67c2178..f9fe9f249af 100644 --- a/src/plugins/texteditor/texteditoractionhandler.h +++ b/src/plugins/texteditor/texteditoractionhandler.h @@ -109,6 +109,10 @@ private slots: void selectEncoding(); void increaseFontSize(); void decreaseFontSize(); + void gotoBlockStart(); + void gotoBlockEnd(); + void gotoBlockStartWithSelection(); + void gotoBlockEndWithSelection(); void updateCurrentEditor(Core::IContext *object); private: @@ -131,6 +135,10 @@ private: QAction *m_selectEncodingAction; QAction *m_increaseFontSizeAction; QAction *m_decreaseFontSizeAction; + QAction *m_gotoBlockStartAction; + QAction *m_gotoBlockEndAction; + QAction *m_gotoBlockStartWithSelectionAction; + QAction *m_gotoBlockEndWithSelectionAction; uint m_optionalActions; QPointer m_currentEditor; diff --git a/src/plugins/texteditor/texteditorconstants.h b/src/plugins/texteditor/texteditorconstants.h index 8313f61fc3d..9415d732da9 100644 --- a/src/plugins/texteditor/texteditorconstants.h +++ b/src/plugins/texteditor/texteditorconstants.h @@ -48,9 +48,15 @@ const char * const UN_COLLAPSE_ALL = "TextEditor.UnCollapseAll"; const char * const AUTO_INDENT_SELECTION = "TextEditor.AutoIndentSelection"; const char * const INCREASE_FONT_SIZE = "TextEditor.IncreaseFontSize"; const char * const DECREASE_FONT_SIZE = "TextEditor.DecreaseFontSize"; +const char * const GOTO_BLOCK_START = "TextEditor.GotoBlockStart"; +const char * const GOTO_BLOCK_START_WITH_SELECTION = "TextEditor.GotoBlockStartWithSelection"; +const char * const GOTO_BLOCK_END = "TextEditor.GotoBlockEnd"; +const char * const GOTO_BLOCK_END_WITH_SELECTION = "TextEditor.GotoBlockEndWithSelection"; const char * const DELETE_LINE = "TextEditor.DeleteLine"; const char * const DELETE_WORD = "TextEditor.DeleteWord"; const char * const SELECT_ENCODING = "TextEditor.SelectEncoding"; +const char * const GOTO_OPENING_PARENTHESIS = "TextEditor.GotoOpeningParenthesis"; +const char * const GOTO_CLOSING_PARENTHESIS = "TextEditor.GotoOpeningParenthesis"; const char * const C_TEXTEDITOR_MIMETYPE_TEXT = "text/plain"; const char * const C_TEXTEDITOR_MIMETYPE_XML = "application/xml"; From e594815842132661f4e4661db70d6bd059d37f4c Mon Sep 17 00:00:00 2001 From: mae Date: Thu, 4 Dec 2008 19:25:20 +0100 Subject: [PATCH 16/25] two new actions: "select block up" and "select block down", current default is Ctrl+U --- src/plugins/texteditor/basetexteditor.cpp | 41 ++++++++++++ src/plugins/texteditor/basetexteditor.h | 3 + src/plugins/texteditor/basetexteditor_p.h | 1 + .../texteditor/texteditoractionhandler.cpp | 67 ++++++++++--------- .../texteditor/texteditoractionhandler.h | 4 ++ src/plugins/texteditor/texteditorconstants.h | 2 + 6 files changed, 87 insertions(+), 31 deletions(-) diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp index a0cf9dee3b0..dc9f9282c1a 100644 --- a/src/plugins/texteditor/basetexteditor.cpp +++ b/src/plugins/texteditor/basetexteditor.cpp @@ -597,6 +597,8 @@ void BaseTextEditor::slotSelectionChanged() viewport()->update(); if (!d->m_inBlockSelectionMode) d->m_blockSelectionExtraX = 0; + if (!d->m_selectBlockAnchor.isNull() && !textCursor().hasSelection()) + d->m_selectBlockAnchor = QTextCursor(); } void BaseTextEditor::gotoBlockStart() @@ -627,6 +629,45 @@ void BaseTextEditor::gotoBlockEndWithSelection() setTextCursor(cursor); } +void BaseTextEditor::selectBlockUp() +{ + QTextCursor cursor = textCursor(); + if (!cursor.hasSelection()) + d->m_selectBlockAnchor = cursor; + else + cursor.setPosition(cursor.selectionStart()); + + + if (!TextBlockUserData::findPreviousOpenParenthesis(&cursor, false)) + return; + if (!TextBlockUserData::findNextClosingParenthesis(&cursor, true)) + return; + setTextCursor(cursor); +} + +void BaseTextEditor::selectBlockDown() +{ + QTextCursor tc = textCursor(); + QTextCursor cursor = d->m_selectBlockAnchor; + + if (!tc.hasSelection() || cursor.isNull()) + return; + tc.setPosition(tc.selectionStart()); + + forever { + QTextCursor ahead = cursor; + if (!TextBlockUserData::findPreviousOpenParenthesis(&ahead, false)) + break; + if (ahead.position() <= tc.position()) + break; + cursor = ahead; + } + if ( cursor != d->m_selectBlockAnchor) + TextBlockUserData::findNextClosingParenthesis(&cursor, true); + + setTextCursor(cursor); +} + void BaseTextEditor::keyPressEvent(QKeyEvent *e) diff --git a/src/plugins/texteditor/basetexteditor.h b/src/plugins/texteditor/basetexteditor.h index 54e4728c4b4..23b9951ccb0 100644 --- a/src/plugins/texteditor/basetexteditor.h +++ b/src/plugins/texteditor/basetexteditor.h @@ -326,6 +326,9 @@ public slots: void gotoBlockStartWithSelection(); void gotoBlockEndWithSelection(); + void selectBlockUp(); + void selectBlockDown(); + signals: void changed(); diff --git a/src/plugins/texteditor/basetexteditor_p.h b/src/plugins/texteditor/basetexteditor_p.h index 87d1af0de0f..56b1071e1c6 100644 --- a/src/plugins/texteditor/basetexteditor_p.h +++ b/src/plugins/texteditor/basetexteditor_p.h @@ -216,6 +216,7 @@ public: void removeBlockSelection(const QString &text = QString()); QTextCursor m_findScope; + QTextCursor m_selectBlockAnchor; void moveCursorVisible(); }; diff --git a/src/plugins/texteditor/texteditoractionhandler.cpp b/src/plugins/texteditor/texteditoractionhandler.cpp index a9e955eae36..635f9654576 100644 --- a/src/plugins/texteditor/texteditoractionhandler.cpp +++ b/src/plugins/texteditor/texteditoractionhandler.cpp @@ -69,6 +69,7 @@ TextEditorActionHandler::TextEditorActionHandler(Core::ICore *core, = m_increaseFontSizeAction = m_decreaseFontSizeAction = m_gotoBlockStartAction = m_gotoBlockStartWithSelectionAction = m_gotoBlockEndAction = m_gotoBlockEndWithSelectionAction + = m_selectBlockUpAction = m_selectBlockDownAction = 0; m_contextId << m_core->uniqueIDManager()->uniqueIdentifier(context); @@ -163,13 +164,11 @@ void TextEditorActionHandler::createActions() command = am->registerAction(m_collapseAction, Constants::COLLAPSE, m_contextId); command->setDefaultKeySequence(QKeySequence(tr("Ctrl+<"))); connect(m_collapseAction, SIGNAL(triggered()), this, SLOT(collapse())); - advancedMenu->addAction(command); m_expandAction = new QAction(tr("Expand"), this); command = am->registerAction(m_expandAction, Constants::EXPAND, m_contextId); command->setDefaultKeySequence(QKeySequence(tr("Ctrl+>"))); connect(m_expandAction, SIGNAL(triggered()), this, SLOT(expand())); - advancedMenu->addAction(command); m_unCollapseAllAction = new QAction(tr("(Un)&Collapse All"), this); command = am->registerAction(m_unCollapseAllAction, Constants::UN_COLLAPSE_ALL, m_contextId); @@ -208,6 +207,15 @@ void TextEditorActionHandler::createActions() command->setDefaultKeySequence(QKeySequence(tr("Ctrl+}"))); connect(m_gotoBlockEndWithSelectionAction, SIGNAL(triggered()), this, SLOT(gotoBlockEndWithSelection())); + m_selectBlockUpAction= new QAction(tr("Select Block Up"), this); + command = am->registerAction(m_selectBlockUpAction, Constants::SELECT_BLOCK_UP, m_contextId); + command->setDefaultKeySequence(QKeySequence(tr("Ctrl+U"))); + connect(m_selectBlockUpAction, SIGNAL(triggered()), this, SLOT(selectBlockUp())); + + m_selectBlockDownAction= new QAction(tr("Select Block Down"), this); + command = am->registerAction(m_selectBlockDownAction, Constants::SELECT_BLOCK_DOWN, m_contextId); + command->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+U"))); + connect(m_selectBlockDownAction, SIGNAL(triggered()), this, SLOT(selectBlockDown())); } bool TextEditorActionHandler::supportsAction(const QString & /*id */) const @@ -252,35 +260,30 @@ void TextEditorActionHandler::updateActions() void TextEditorActionHandler::updateActions(UpdateMode um) { - if (m_pasteAction) - m_pasteAction->setEnabled(um != NoEditor); - if (m_selectAllAction) - m_selectAllAction->setEnabled(um != NoEditor); - if (m_gotoAction) - m_gotoAction->setEnabled(um != NoEditor); - if (m_selectEncodingAction) - m_selectEncodingAction->setEnabled(um != NoEditor); - if (m_printAction) - m_printAction->setEnabled(um != NoEditor); - if (m_formatAction) - m_formatAction->setEnabled((m_optionalActions & Format) && um != NoEditor); - if (m_unCommentSelectionAction) - m_unCommentSelectionAction->setEnabled((m_optionalActions & UnCommentSelection) && um != NoEditor); - if (m_collapseAction) - m_collapseAction->setEnabled(um != NoEditor); - if (m_expandAction) - m_expandAction->setEnabled(um != NoEditor); - if (m_unCollapseAllAction) - m_unCollapseAllAction->setEnabled((m_optionalActions & UnCollapseAll) && um != NoEditor); - if (m_decreaseFontSizeAction) - m_decreaseFontSizeAction->setEnabled(um != NoEditor); - if (m_increaseFontSizeAction) - m_increaseFontSizeAction->setEnabled(um != NoEditor); - if (m_visualizeWhitespaceAction) { - m_visualizeWhitespaceAction->setEnabled(um != NoEditor); - if (m_currentEditor) - m_visualizeWhitespaceAction->setChecked(m_currentEditor->displaySettings().m_visualizeWhitespace); - } + if (!m_initialized) + return; + m_pasteAction->setEnabled(um != NoEditor); + m_selectAllAction->setEnabled(um != NoEditor); + m_gotoAction->setEnabled(um != NoEditor); + m_selectEncodingAction->setEnabled(um != NoEditor); + m_printAction->setEnabled(um != NoEditor); + m_formatAction->setEnabled((m_optionalActions & Format) && um != NoEditor); + m_unCommentSelectionAction->setEnabled((m_optionalActions & UnCommentSelection) && um != NoEditor); + m_collapseAction->setEnabled(um != NoEditor); + m_expandAction->setEnabled(um != NoEditor); + m_unCollapseAllAction->setEnabled((m_optionalActions & UnCollapseAll) && um != NoEditor); + m_decreaseFontSizeAction->setEnabled(um != NoEditor); + m_increaseFontSizeAction->setEnabled(um != NoEditor); + m_gotoBlockStartAction->setEnabled(um != NoEditor); + m_gotoBlockStartWithSelectionAction->setEnabled(um != NoEditor); + m_gotoBlockEndAction->setEnabled(um != NoEditor); + m_gotoBlockEndWithSelectionAction->setEnabled(um != NoEditor); + m_selectBlockUpAction->setEnabled(um != NoEditor); + m_selectBlockDownAction->setEnabled(um != NoEditor); + + m_visualizeWhitespaceAction->setEnabled(um != NoEditor); + if (m_currentEditor) + m_visualizeWhitespaceAction->setChecked(m_currentEditor->displaySettings().m_visualizeWhitespace); if (m_textWrappingAction) { m_textWrappingAction->setEnabled(um != NoEditor); if (m_currentEditor) @@ -411,6 +414,8 @@ FUNCTION(gotoBlockStart) FUNCTION(gotoBlockEnd) FUNCTION(gotoBlockStartWithSelection) FUNCTION(gotoBlockEndWithSelection) +FUNCTION(selectBlockUp) +FUNCTION(selectBlockDown) void TextEditorActionHandler::updateCurrentEditor(Core::IContext *object) { diff --git a/src/plugins/texteditor/texteditoractionhandler.h b/src/plugins/texteditor/texteditoractionhandler.h index f9fe9f249af..9a8c7b9f57c 100644 --- a/src/plugins/texteditor/texteditoractionhandler.h +++ b/src/plugins/texteditor/texteditoractionhandler.h @@ -113,6 +113,8 @@ private slots: void gotoBlockEnd(); void gotoBlockStartWithSelection(); void gotoBlockEndWithSelection(); + void selectBlockUp(); + void selectBlockDown(); void updateCurrentEditor(Core::IContext *object); private: @@ -139,6 +141,8 @@ private: QAction *m_gotoBlockEndAction; QAction *m_gotoBlockStartWithSelectionAction; QAction *m_gotoBlockEndWithSelectionAction; + QAction *m_selectBlockUpAction; + QAction *m_selectBlockDownAction; uint m_optionalActions; QPointer m_currentEditor; diff --git a/src/plugins/texteditor/texteditorconstants.h b/src/plugins/texteditor/texteditorconstants.h index 9415d732da9..9ac9fdff0e4 100644 --- a/src/plugins/texteditor/texteditorconstants.h +++ b/src/plugins/texteditor/texteditorconstants.h @@ -52,6 +52,8 @@ const char * const GOTO_BLOCK_START = "TextEditor.GotoBlockStart"; const char * const GOTO_BLOCK_START_WITH_SELECTION = "TextEditor.GotoBlockStartWithSelection"; const char * const GOTO_BLOCK_END = "TextEditor.GotoBlockEnd"; const char * const GOTO_BLOCK_END_WITH_SELECTION = "TextEditor.GotoBlockEndWithSelection"; +const char * const SELECT_BLOCK_UP = "TextEditor.SelectBlockUp"; +const char * const SELECT_BLOCK_DOWN = "TextEditor.SelectBlockDown"; const char * const DELETE_LINE = "TextEditor.DeleteLine"; const char * const DELETE_WORD = "TextEditor.DeleteWord"; const char * const SELECT_ENCODING = "TextEditor.SelectEncoding"; From 4fd9f1e6f77d4bc0a1fd2e925fb9ae389b8a9075 Mon Sep 17 00:00:00 2001 From: mae Date: Thu, 4 Dec 2008 19:33:23 +0100 Subject: [PATCH 17/25] new signal: BaseTextEditor::lineContextMenuRequested(TextEditor::ITextEditor *editor, int line, QMenu *menu); To be useful and used by the bookmarkmanager, this has to move to ITextEditor. --- src/plugins/texteditor/basetexteditor.cpp | 6 ++++++ src/plugins/texteditor/basetexteditor.h | 1 + 2 files changed, 7 insertions(+) diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp index dc9f9282c1a..4dda8f7b952 100644 --- a/src/plugins/texteditor/basetexteditor.cpp +++ b/src/plugins/texteditor/basetexteditor.cpp @@ -79,6 +79,7 @@ #include #include #include +#include using namespace TextEditor; using namespace TextEditor::Internal; @@ -2430,6 +2431,11 @@ void BaseTextEditor::extraAreaMouseEvent(QMouseEvent *e) } else { d->extraAreaToggleMarkBlockNumber = cursor.blockNumber(); } + } else if (e->button() == Qt::RightButton) { + QMenu * contextMenu = new QMenu(this); + emit lineContextMenuRequested(editableInterface(), cursor.blockNumber(), contextMenu); + if (!contextMenu->isEmpty()) + contextMenu->exec(e->globalPos()); } } else if (d->extraAreaSelectionAnchorBlockNumber >= 0) { QTextCursor selection = cursor; diff --git a/src/plugins/texteditor/basetexteditor.h b/src/plugins/texteditor/basetexteditor.h index 23b9951ccb0..a6cc14f36e4 100644 --- a/src/plugins/texteditor/basetexteditor.h +++ b/src/plugins/texteditor/basetexteditor.h @@ -432,6 +432,7 @@ protected slots: signals: void markRequested(TextEditor::ITextEditor *editor, int line); + void lineContextMenuRequested(TextEditor::ITextEditor *editor, int line, QMenu *menu); void requestBlockUpdate(const QTextBlock &); void requestAutoCompletion(ITextEditable *editor, bool forced); From 4e76b54decc6222a4f1e7c6cf473519b21983e9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorbj=C3=B8rn=20Lindeijer?= Date: Fri, 5 Dec 2008 09:02:08 +0100 Subject: [PATCH 18/25] Use QFlags for indicating symbols to search for --- src/plugins/cpptools/searchsymbols.cpp | 13 ++++++++----- src/plugins/cpptools/searchsymbols.h | 13 ++++++++----- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/plugins/cpptools/searchsymbols.cpp b/src/plugins/cpptools/searchsymbols.cpp index c0d29aae18a..4b1e48abdf7 100644 --- a/src/plugins/cpptools/searchsymbols.cpp +++ b/src/plugins/cpptools/searchsymbols.cpp @@ -40,13 +40,13 @@ using namespace CPlusPlus; using namespace CppTools::Internal; SearchSymbols::SearchSymbols(): - symbolsToSearchFor(ClassesMethodsFunctionsAndEnums) + symbolsToSearchFor(Classes | Functions | Enums) { } -void SearchSymbols::setSymbolsToSearchFor(SymbolType type) +void SearchSymbols::setSymbolsToSearchFor(SymbolTypes types) { - symbolsToSearchFor = type; + symbolsToSearchFor = types; } QList SearchSymbols::operator()(Document::Ptr doc, const QString &scope) @@ -69,7 +69,7 @@ QString SearchSymbols::switchScope(const QString &scope) bool SearchSymbols::visit(Enum *symbol) { - if (symbolsToSearchFor != ClassesMethodsFunctionsAndEnums) + if (!(symbolsToSearchFor & Enums)) return false; QString name = symbolName(symbol); @@ -89,7 +89,7 @@ bool SearchSymbols::visit(Enum *symbol) bool SearchSymbols::visit(Function *symbol) { - if (symbolsToSearchFor != ClassesMethodsFunctionsAndEnums) + if (!(symbolsToSearchFor & Functions)) return false; QString name = symbolName(symbol); @@ -131,6 +131,9 @@ bool SearchSymbols::visit(Declaration *symbol) bool SearchSymbols::visit(Class *symbol) { + if (!(symbolsToSearchFor & Classes)) + return false; + QString name = symbolName(symbol); QString previousScope = switchScope(name); QIcon icon = icons.iconForSymbol(symbol); diff --git a/src/plugins/cpptools/searchsymbols.h b/src/plugins/cpptools/searchsymbols.h index d9b678e026f..948f9d78e84 100644 --- a/src/plugins/cpptools/searchsymbols.h +++ b/src/plugins/cpptools/searchsymbols.h @@ -80,15 +80,16 @@ class SearchSymbols: public std::unary_function operator()(CPlusPlus::Document::Ptr doc) { return operator()(doc, QString()); } @@ -117,9 +118,11 @@ private: CPlusPlus::Overview overview; CPlusPlus::Icons icons; QList items; - SymbolType symbolsToSearchFor; + SymbolTypes symbolsToSearchFor; }; +Q_DECLARE_OPERATORS_FOR_FLAGS(SearchSymbols::SymbolTypes) + } // namespace Internal } // namespace CppTools From a48ee6f7a8cb8d1d2c49724e9cf2f86957f9c3ce Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 5 Dec 2008 10:39:08 +0100 Subject: [PATCH 19/25] Fixes: Allow directories to be entered into the class wizard file names Task: 237390 Details: Add 'allowDirectories' property to the widgets involved. --- src/libs/utils/filenamevalidatinglineedit.cpp | 86 ++++++++++++++----- src/libs/utils/filenamevalidatinglineedit.h | 13 ++- src/libs/utils/filewizardpage.cpp | 2 +- src/libs/utils/newclasswidget.cpp | 15 ++++ src/libs/utils/newclasswidget.h | 4 +- .../utils/projectnamevalidatinglineedit.cpp | 2 +- src/plugins/cppeditor/cppclasswizard.cpp | 1 + .../designer/cpp/formclasswizardpage.cpp | 1 + 8 files changed, 96 insertions(+), 28 deletions(-) diff --git a/src/libs/utils/filenamevalidatinglineedit.cpp b/src/libs/utils/filenamevalidatinglineedit.cpp index 57a0ed7a5f9..5b308f5ce47 100644 --- a/src/libs/utils/filenamevalidatinglineedit.cpp +++ b/src/libs/utils/filenamevalidatinglineedit.cpp @@ -33,26 +33,65 @@ #include "filenamevalidatinglineedit.h" +#include +#include + namespace Core { namespace Utils { -FileNameValidatingLineEdit::FileNameValidatingLineEdit(QWidget *parent) : - BaseValidatingLineEdit(parent) -{ - -} - -/* Validate a file base name, check for forbidden characters/strings. */ - -static const char *notAllowedChars = "/?:&\\*\"|#%<> "; -static const char *notAllowedSubStrings[] = {".."}; - // Naming a file like a device name will break on Windows, even if it is // "com1.txt". Since we are cross-platform, we generally disallow such file // names. -static const char *notAllowedStrings[] = {"CON", "AUX", "PRN", "COM1", "COM2", "LPT1", "LPT2" }; +static const QRegExp &windowsDeviceNoSubDirPattern() +{ + static const QRegExp rc(QLatin1String("CON|AUX|PRN|COM1|COM2|LPT1|LPT2|NUL"), + Qt::CaseInsensitive); + Q_ASSERT(rc.isValid()); + return rc; +} -bool FileNameValidatingLineEdit::validateFileName(const QString &name, QString *errorMessage /* = 0*/) +static const QRegExp &windowsDeviceSubDirPattern() +{ + static const QRegExp rc(QLatin1String(".*[/\\\\]CON|.*[/\\\\]AUX|.*[/\\\\]PRN|.*[/\\\\]COM1|.*[/\\\\]COM2|.*[/\\\\]LPT1|.*[/\\\\]LPT2|.*[/\\\\]NUL"), + Qt::CaseInsensitive); + Q_ASSERT(rc.isValid()); + return rc; +} + +// ----------- FileNameValidatingLineEdit +FileNameValidatingLineEdit::FileNameValidatingLineEdit(QWidget *parent) : + BaseValidatingLineEdit(parent), + m_allowDirectories(false), + m_unused(0) +{ +} + +bool FileNameValidatingLineEdit::allowDirectories() const +{ + return m_allowDirectories; +} + +void FileNameValidatingLineEdit::setAllowDirectories(bool v) +{ + m_allowDirectories = v; +} + +/* Validate a file base name, check for forbidden characters/strings. */ + +#ifdef Q_OS_WIN +# define SLASHES "/\\" +#else +# define SLASHES "/" +#endif + +static const char *notAllowedCharsSubDir = "?:&*\"|#%<> "; +static const char *notAllowedCharsNoSubDir = "?:&*\"|#%<> "SLASHES; + +static const char *notAllowedSubStrings[] = {".."}; + +bool FileNameValidatingLineEdit::validateFileName(const QString &name, + bool allowDirectories, + QString *errorMessage /* = 0*/) { if (name.isEmpty()) { if (errorMessage) @@ -60,6 +99,7 @@ bool FileNameValidatingLineEdit::validateFileName(const QString &name, QString * return false; } // Characters + const char *notAllowedChars = allowDirectories ? notAllowedCharsSubDir : notAllowedCharsNoSubDir; for (const char *c = notAllowedChars; *c; c++) if (name.contains(QLatin1Char(*c))) { if (errorMessage) @@ -76,22 +116,22 @@ bool FileNameValidatingLineEdit::validateFileName(const QString &name, QString * return false; } } - // Strings - const int notAllowedStringCount = sizeof(notAllowedStrings)/sizeof(const char *); - for (int s = 0; s < notAllowedStringCount; s++) { - const QLatin1String notAllowedString(notAllowedStrings[s]); - if (name == notAllowedString) { - if (errorMessage) - *errorMessage = tr("The name must not be '%1'.").arg(QString(notAllowedString)); - return false; - } + // Windows devices + bool matchesWinDevice = windowsDeviceNoSubDirPattern().exactMatch(name); + if (!matchesWinDevice && allowDirectories) + matchesWinDevice = windowsDeviceSubDirPattern().exactMatch(name); + if (matchesWinDevice) { + if (errorMessage) + *errorMessage = tr("The name must not match that of a MS Windows device. (%1)."). + arg(windowsDeviceNoSubDirPattern().pattern().replace(QLatin1Char('|'), QLatin1Char(','))); + return false; } return true; } bool FileNameValidatingLineEdit::validate(const QString &value, QString *errorMessage) const { - return validateFileName(value, errorMessage); + return validateFileName(value, m_allowDirectories, errorMessage); } } // namespace Utils diff --git a/src/libs/utils/filenamevalidatinglineedit.h b/src/libs/utils/filenamevalidatinglineedit.h index 5476e3cd5e9..042a48fc5f1 100644 --- a/src/libs/utils/filenamevalidatinglineedit.h +++ b/src/libs/utils/filenamevalidatinglineedit.h @@ -43,14 +43,23 @@ class QWORKBENCH_UTILS_EXPORT FileNameValidatingLineEdit : public BaseValidating { Q_OBJECT Q_DISABLE_COPY(FileNameValidatingLineEdit) - + Q_PROPERTY(bool allowDirectories READ allowDirectories WRITE setAllowDirectories) public: explicit FileNameValidatingLineEdit(QWidget *parent = 0); - static bool validateFileName(const QString &name, QString *errorMessage /* = 0*/); + static bool validateFileName(const QString &name, + bool allowDirectories = false, + QString *errorMessage = 0); + + bool allowDirectories() const; + void setAllowDirectories(bool v); protected: virtual bool validate(const QString &value, QString *errorMessage) const; + +private: + bool m_allowDirectories; + void *m_unused; }; } // namespace Utils diff --git a/src/libs/utils/filewizardpage.cpp b/src/libs/utils/filewizardpage.cpp index 8a12e4c0f3c..3e85b34d44b 100644 --- a/src/libs/utils/filewizardpage.cpp +++ b/src/libs/utils/filewizardpage.cpp @@ -123,7 +123,7 @@ void FileWizardPage::slotActivated() bool FileWizardPage::validateBaseName(const QString &name, QString *errorMessage /* = 0*/) { - return FileNameValidatingLineEdit::validateFileName(name, errorMessage); + return FileNameValidatingLineEdit::validateFileName(name, false, errorMessage); } } // namespace Utils diff --git a/src/libs/utils/newclasswidget.cpp b/src/libs/utils/newclasswidget.cpp index df7d81e7b39..b34ee40d4fe 100644 --- a/src/libs/utils/newclasswidget.cpp +++ b/src/libs/utils/newclasswidget.cpp @@ -346,6 +346,21 @@ void NewClassWidget::setFormExtension(const QString &e) m_d->m_formExtension = fixSuffix(e); } +bool NewClassWidget::allowDirectories() const +{ + return m_d->m_ui.headerFileLineEdit->allowDirectories(); +} + +void NewClassWidget::setAllowDirectories(bool v) +{ + // We keep all in sync + if (allowDirectories() != v) { + m_d->m_ui.sourceFileLineEdit->setAllowDirectories(v); + m_d->m_ui.headerFileLineEdit->setAllowDirectories(v); + m_d->m_ui.formFileLineEdit->setAllowDirectories(v); + } +} + void NewClassWidget::slotValidChanged() { const bool newValid = isValid(); diff --git a/src/libs/utils/newclasswidget.h b/src/libs/utils/newclasswidget.h index 04c2aaf58a4..40c850d28e9 100644 --- a/src/libs/utils/newclasswidget.h +++ b/src/libs/utils/newclasswidget.h @@ -73,6 +73,7 @@ class QWORKBENCH_UTILS_EXPORT NewClassWidget : public QWidget Q_PROPERTY(QString formExtension READ formExtension WRITE setFormExtension DESIGNABLE true) Q_PROPERTY(bool formInputCheckable READ formInputCheckable WRITE setFormInputCheckable DESIGNABLE true) Q_PROPERTY(bool formInputChecked READ formInputChecked WRITE setFormInputChecked DESIGNABLE true) + Q_PROPERTY(bool allowDirectories READ allowDirectories WRITE setAllowDirectories) // Utility "USER" property for wizards containing file names. Q_PROPERTY(QStringList files READ files DESIGNABLE false USER true) public: @@ -97,7 +98,7 @@ public: QString sourceExtension() const; QString headerExtension() const; QString formExtension() const; - + bool allowDirectories() const; bool isValid(QString *error = 0) const; @@ -125,6 +126,7 @@ public slots: void setSourceExtension(const QString &e); void setHeaderExtension(const QString &e); void setFormExtension(const QString &e); + void setAllowDirectories(bool v); /* Suggest a class name from the base class by stripping the leading 'Q' * character. This will happen automagically if the base class combo diff --git a/src/libs/utils/projectnamevalidatinglineedit.cpp b/src/libs/utils/projectnamevalidatinglineedit.cpp index df77af8e832..4160bc18792 100644 --- a/src/libs/utils/projectnamevalidatinglineedit.cpp +++ b/src/libs/utils/projectnamevalidatinglineedit.cpp @@ -45,7 +45,7 @@ ProjectNameValidatingLineEdit::ProjectNameValidatingLineEdit(QWidget *parent) bool ProjectNameValidatingLineEdit::validateProjectName(const QString &name, QString *errorMessage /* = 0*/) { // Validation is file name + checking for dots - if (!FileNameValidatingLineEdit::validateFileName(name, errorMessage)) + if (!FileNameValidatingLineEdit::validateFileName(name, false, errorMessage)) return false; // We don't want dots in the directory name for some legacy Windows diff --git a/src/plugins/cppeditor/cppclasswizard.cpp b/src/plugins/cppeditor/cppclasswizard.cpp index 6730f5b9ed9..652eec535f1 100644 --- a/src/plugins/cppeditor/cppclasswizard.cpp +++ b/src/plugins/cppeditor/cppclasswizard.cpp @@ -73,6 +73,7 @@ ClassNamePage::ClassNamePage(const QString &sourceSuffix, m_newClassWidget->setBaseClassEditable(true); m_newClassWidget->setFormInputVisible(false); m_newClassWidget->setNamespacesEnabled(true); + m_newClassWidget->setAllowDirectories(true); connect(m_newClassWidget, SIGNAL(validChanged()), this, SLOT(slotValidChanged())); diff --git a/src/plugins/designer/cpp/formclasswizardpage.cpp b/src/plugins/designer/cpp/formclasswizardpage.cpp index d076753374b..eac7271b404 100644 --- a/src/plugins/designer/cpp/formclasswizardpage.cpp +++ b/src/plugins/designer/cpp/formclasswizardpage.cpp @@ -63,6 +63,7 @@ FormClassWizardPage::FormClassWizardPage(QWidget * parent) : m_ui->newClassWidget->setBaseClassInputVisible(false); m_ui->newClassWidget->setNamespacesEnabled(true); + m_ui->newClassWidget->setAllowDirectories(true); connect(m_ui->newClassWidget, SIGNAL(validChanged()), this, SLOT(slotValidChanged())); From f9fbfb8f8322b8c8d7eb22100cb2c9e27b7ca871 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 5 Dec 2008 11:24:18 +0100 Subject: [PATCH 20/25] increas alert time for breakpoints to 300 --- src/plugins/debugger/gdbengine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/debugger/gdbengine.cpp b/src/plugins/debugger/gdbengine.cpp index 80d0a046fc3..1802c018001 100644 --- a/src/plugins/debugger/gdbengine.cpp +++ b/src/plugins/debugger/gdbengine.cpp @@ -1276,7 +1276,7 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data) m_currentFrame = frame.findChild("addr").data() + '%' + frame.findChild("func").data() + '%'; - QApplication::alert(q->mainWindow(), 200); + QApplication::alert(q->mainWindow(), 3000); sendCommand("-file-list-exec-source-files", GdbQuerySources); sendCommand("-break-list", BreakList); QVariant var = QVariant::fromValue(data); From 0c3a7df7465890a4634051aa2dad83ce9eeb0c0a Mon Sep 17 00:00:00 2001 From: Kavindra Palaraja Date: Thu, 4 Dec 2008 17:27:29 +0100 Subject: [PATCH 21/25] Fixes: More documentation fixes (cherry picked from commit a02c5e61962a64ca3ebe455f9b7f1b67cb338515) --- doc/qtcreator.qdoc | 80 ++++++++++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 38 deletions(-) diff --git a/doc/qtcreator.qdoc b/doc/qtcreator.qdoc index a1f7ab3ed6f..4521b7e2fa4 100644 --- a/doc/qtcreator.qdoc +++ b/doc/qtcreator.qdoc @@ -814,21 +814,26 @@ a pointer to some private data structure, you will see a list of children, signals and slots. - Similarily, instead of showing a bunch of pointers and ints, - a QHash or QMap will display its contents in an orderly fashion, - a QFileInfo will expose e.g. access data, and the otherwise - "opaque" QVariant gives access to the "real" contents. + Similarly, instead of displaying many pointers and integers, Qt Creator's + debugger will display the contents of a QHash or QMap in an orderly manner. + Also, the debugger will display access data for QFileInfo and provide + access to the "real" contents of QVariant. - The \gui{Locals and Watchers View} can be used to change the - contents of variables of simple data types like int or float - while the program is stopped. To do so, click into the 'Value' - column, modify the value there, and hit \key{Return}. + The \gui{Locals and Watchers} view can be used to change the contents of + variables of simple data types such as \c int or \c float when the program + is stopped. To do so, click on the \gui Value column, modify the value + with the inplace editor, and hit \key Enter (or \key Return). - \section2 Modules - The \gui{Modules View} is hidden by default and only useful in + By default, the \gui Modules view is hidden as it is only useful with the + experimental delayed debug information loading feature. You can turn this + feature on by selecting \gui{Fast Debugger Start} + + + + The \gui Modules view is hidden by default and only useful in connection with the experimental feature of delayed debug information loading. This feature is accessible by selecting \gui{Debug} and \gui{Fast Debugger Start}. When using the @@ -849,29 +854,28 @@ commands + \section1 A Walkthrough for the Debugger Frontend - \section1 A short walk through the debugger frontend - - In our \l{Writing a Simple Program with Qt Creator}{TextFinder} - example, we read a text file into a QString and then display it with a - QTextEdit. Suppose, you would like to look at this QString, \c{line}, - and see what data it actually stores. Follow the steps described below - to place a break point and view the QString object's data. + In our \l{Writing a Simple Program with Qt Creator}{TextFinder} example, we + read a text file into a QString and then display it with a QTextEdit. + Suppose, you would like to look at this QString, \c{line}, and see what + data it actually stores. Follow the steps described below to place a + breakpoint and view the QString object's data. \table \row - \i \inlineimage qtcreator-setting-breakpoint1.png + \i \inlineimage qtcreator-setting-breakpoint1.png \i \bold{Setting a Breakpoint} First, we set a breakpoint on the line where we invoke - \l{QTextEdit::}{setPlainText()} by clicking between the line number and - the window border. Then, select \gui{Start Debugging} from the - \gui{Debug} menu or press \key{F5}. + \l{QTextEdit::}{setPlainText()} by clicking between the line number and the + window border. Then, select \gui{Start Debugging} from the \gui{Debug} menu + or press \key{F5}. \endtable Breakpoints are visible in the \gui{Breakpoints} view, shown below, in - \gui{Debug} mode. If you wish to remove a breakpoint, simply right - click on it and select \gui{Delete breakpoint} from the context menu. + \gui{Debug} mode. If you wish to remove a breakpoint, simply right-click on + it and select \gui{Delete breakpoint} from the context menu. \image qtcreator-setting-breakpoint2.png @@ -880,10 +884,10 @@ \image qtcreator-watcher.png - Suppose we modify our \c{on_findButton_clicked()} function to move back - to the start of the document and continue searching once the cursor - hits the end of the document. Adding this functionality can be done - with the code snippet below: + Suppose we modify our \c{on_findButton_clicked()} function to move back to + the start of the document and continue searching once the cursor hits the + end of the document. Adding this functionality can be done with the code + snippet below: \code void TextFinder::on_findButton_clicked() @@ -915,9 +919,9 @@ } \endcode - However, if you compile and run this code, the application will not - work correctly due to a logic error. To locate this logic error, you - can step through the code using the following buttons: + However, if you compile and run this code, the application will not work + correctly due to a logic error. To locate this logic error, you can step + through the code using the following buttons: \image qtcreator-debugging-buttons.png */ @@ -931,20 +935,20 @@ \title Tips and Tricks - \bold{Quick mode switch} + \bold{Quickly Switching between Modes} You can quickly switch between modes by pressing \key{Ctrl+1}, - \key{Ctrl+2}, etc. + \key{Ctrl+2}, and so on. - \bold{Other keyboard shortcuts} + \bold{Keyboard Shortcuts} - There are a lot of other \l{keyboard-shortcuts}{keyboard shortcuts}. + Qt Creator provides a lot of useful keyboard shortcuts. A complete list can + be found \l{Keyboard Shortcuts}{here}. - \bold{Command line} + \bold{Running Qt Creator from the Command Line} - You can start Qt Creator from a command prompt with an already - existing session or \c{.pro} file by giving the name as argument on the - command line. + You can start Qt Creator from a command prompt with an existing session or + \c{.pro} file by giving the name as argument on the command line. \bold{Sidebar} From 786e183aa67729e4d465bab77c77c394a231b85f Mon Sep 17 00:00:00 2001 From: mae Date: Fri, 5 Dec 2008 12:12:20 +0100 Subject: [PATCH 22/25] markContextMenuRequested signal in ITextEditor --- src/plugins/texteditor/basetexteditor.cpp | 9 +++------ src/plugins/texteditor/basetexteditor.h | 2 -- src/plugins/texteditor/itexteditor.h | 2 ++ 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp index 1e6a266e6da..ea9da5cb6bd 100644 --- a/src/plugins/texteditor/basetexteditor.cpp +++ b/src/plugins/texteditor/basetexteditor.cpp @@ -488,10 +488,6 @@ ITextEditable *BaseTextEditor::editableInterface() const d->m_editable, SIGNAL(contentsChanged())); connect(this, SIGNAL(changed()), d->m_editable, SIGNAL(changed())); - connect(this, - SIGNAL(markRequested(TextEditor::ITextEditor *, int)), - d->m_editable, - SIGNAL(markRequested(TextEditor::ITextEditor *, int))); } return d->m_editable; } @@ -2434,9 +2430,10 @@ void BaseTextEditor::extraAreaMouseEvent(QMouseEvent *e) } } else if (e->button() == Qt::RightButton) { QMenu * contextMenu = new QMenu(this); - emit lineContextMenuRequested(editableInterface(), cursor.blockNumber(), contextMenu); + emit d->m_editable->markContextMenuRequested(editableInterface(), cursor.blockNumber(), contextMenu); if (!contextMenu->isEmpty()) contextMenu->exec(e->globalPos()); + delete contextMenu; } } else if (d->extraAreaSelectionAnchorBlockNumber >= 0) { QTextCursor selection = cursor; @@ -2471,7 +2468,7 @@ void BaseTextEditor::extraAreaMouseEvent(QMouseEvent *e) d->extraAreaToggleMarkBlockNumber = -1; if (cursor.blockNumber() == n) { int line = n + 1; - emit markRequested(editableInterface(), line); + emit d->m_editable->markRequested(editableInterface(), line); } } } diff --git a/src/plugins/texteditor/basetexteditor.h b/src/plugins/texteditor/basetexteditor.h index a6cc14f36e4..714b1a507c8 100644 --- a/src/plugins/texteditor/basetexteditor.h +++ b/src/plugins/texteditor/basetexteditor.h @@ -431,8 +431,6 @@ protected slots: signals: - void markRequested(TextEditor::ITextEditor *editor, int line); - void lineContextMenuRequested(TextEditor::ITextEditor *editor, int line, QMenu *menu); void requestBlockUpdate(const QTextBlock &); void requestAutoCompletion(ITextEditable *editor, bool forced); diff --git a/src/plugins/texteditor/itexteditor.h b/src/plugins/texteditor/itexteditor.h index 432c3c9c585..514f311472a 100644 --- a/src/plugins/texteditor/itexteditor.h +++ b/src/plugins/texteditor/itexteditor.h @@ -44,6 +44,7 @@ #include QT_BEGIN_NAMESPACE +class QMenu; class QTextBlock; QT_END_NAMESPACE @@ -124,6 +125,7 @@ public: signals: void contentsChanged(); void markRequested(TextEditor::ITextEditor *editor, int line); + void markContextMenuRequested(TextEditor::ITextEditor *editor, int line, QMenu *menu); void tooltipRequested(TextEditor::ITextEditor *editor, const QPoint &globalPos, int position); void contextHelpIdRequested(TextEditor::ITextEditor *editor, int position); }; From 5c6be3a83cf5045b2584a46fe1661a09251df851 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 5 Dec 2008 12:19:04 +0100 Subject: [PATCH 23/25] Fixes: Do not display f1, f2 while waiting for wizard extension page data --- src/plugins/projectexplorer/projectwizardpage.ui | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/plugins/projectexplorer/projectwizardpage.ui b/src/plugins/projectexplorer/projectwizardpage.ui index bc31f8c49e1..7c21ec5a910 100644 --- a/src/plugins/projectexplorer/projectwizardpage.ui +++ b/src/plugins/projectexplorer/projectwizardpage.ui @@ -104,8 +104,9 @@ The following files will be added: -f1 -f2 + + + From 6d37029be86594ce1721452c49a04d04d6e5b879 Mon Sep 17 00:00:00 2001 From: mae Date: Fri, 5 Dec 2008 13:19:57 +0100 Subject: [PATCH 24/25] support different selection kinds in basetexteditor. enum ExtraSelectionKind { CurrentLineSelection, ParenthesesMatchingSelection, CodeWarningsSelection, CodeSemanticsSelection, OtherSelection, NExtraSelectionKinds }; void setExtraSelections(ExtraSelectionKind kind, const QList &selections); QList extraSelections(ExtraSelectionKind kind) const; This is mainly for the benefit of the cppmodelmanager. --- src/plugins/cpptools/cppmodelmanager.cpp | 2 +- src/plugins/texteditor/basetexteditor.cpp | 30 +++++++++++++---------- src/plugins/texteditor/basetexteditor.h | 13 +++++++--- src/plugins/texteditor/basetexteditor_p.h | 3 +-- src/plugins/vcsbase/vcsbaseeditor.cpp | 21 ++++------------ 5 files changed, 34 insertions(+), 35 deletions(-) diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp index b3f9fb604c3..042b93cc74d 100644 --- a/src/plugins/cpptools/cppmodelmanager.cpp +++ b/src/plugins/cpptools/cppmodelmanager.cpp @@ -683,7 +683,7 @@ void CppModelManager::onDocumentUpdated(Document::Ptr doc) sel.cursor = c; selections.append(sel); } - ed->setExtraExtraSelections(selections); + ed->setExtraSelections(TextEditor::BaseTextEditor::CodeWarningsSelection, selections); break; } } diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp index ea9da5cb6bd..49d29b75c93 100644 --- a/src/plugins/texteditor/basetexteditor.cpp +++ b/src/plugins/texteditor/basetexteditor.cpp @@ -2477,6 +2477,9 @@ void BaseTextEditor::extraAreaMouseEvent(QMouseEvent *e) void BaseTextEditor::slotCursorPositionChanged() { QList extraSelections; + setExtraSelections(ParenthesesMatchingSelection, extraSelections); // clear + if (d->m_parenthesesMatchingEnabled) + d->m_parenthesesMatchingTimer->start(50); if (d->m_highlightCurrentLine) { QTextEdit::ExtraSelection sel; @@ -2487,11 +2490,7 @@ void BaseTextEditor::slotCursorPositionChanged() extraSelections.append(sel); } - if (d->m_parenthesesMatchingEnabled) - d->m_parenthesesMatchingTimer->start(50); - - d->m_extraSelections = extraSelections; - setExtraSelections(d->m_extraSelections + d->m_extraExtraSelections); + setExtraSelections(CurrentLineSelection, extraSelections); } QTextBlock TextBlockUserData::testCollapse(const QTextBlock& block) @@ -3133,7 +3132,7 @@ void BaseTextEditor::_q_matchParentheses() if (backwardMatchType == TextBlockUserData::NoMatch && forwardMatchType == TextBlockUserData::NoMatch) return; - QList extraSelections = d->m_extraSelections; + QList extraSelections; if (backwardMatch.hasSelection()) { QTextEdit::ExtraSelection sel; @@ -3186,8 +3185,7 @@ void BaseTextEditor::_q_matchParentheses() } extraSelections.append(sel); } - d->m_extraSelections = extraSelections; - setExtraSelections(d->m_extraSelections + d->m_extraExtraSelections); + setExtraSelections(ParenthesesMatchingSelection, extraSelections); } void BaseTextEditor::setActionHack(QObject *hack) @@ -3234,15 +3232,21 @@ void BaseTextEditor::deleteLine() cut(); } -void BaseTextEditor::setExtraExtraSelections(const QList &selections) +void BaseTextEditor::setExtraSelections(ExtraSelectionKind kind, const QList &selections) { - d->m_extraExtraSelections = selections; - setExtraSelections(d->m_extraSelections + d->m_extraExtraSelections); + if (selections.isEmpty() && d->m_extraSelections[kind].isEmpty()) + return; + d->m_extraSelections[kind] = selections; + + QList all; + for (int i = 0; i < NExtraSelectionKinds; ++i) + all += d->m_extraSelections[i]; + QPlainTextEdit::setExtraSelections(all); } -QList BaseTextEditor::extraExtraSelections() const +QList BaseTextEditor::extraSelections(ExtraSelectionKind kind) const { - return d->m_extraExtraSelections; + return d->m_extraSelections[kind]; } diff --git a/src/plugins/texteditor/basetexteditor.h b/src/plugins/texteditor/basetexteditor.h index 714b1a507c8..40454a9c7d4 100644 --- a/src/plugins/texteditor/basetexteditor.h +++ b/src/plugins/texteditor/basetexteditor.h @@ -369,7 +369,6 @@ private: Internal::BaseTextEditorPrivate *d; friend class Internal::BaseTextEditorPrivate; - public: QWidget *extraArea() const; virtual int extraAreaWidth(int *markWidthPtr = 0) const; @@ -385,8 +384,16 @@ public: void ensureCursorVisible(); - void setExtraExtraSelections(const QList &selections); - QList extraExtraSelections() const; + enum ExtraSelectionKind { + CurrentLineSelection, + ParenthesesMatchingSelection, + CodeWarningsSelection, + CodeSemanticsSelection, + OtherSelection, + NExtraSelectionKinds + }; + void setExtraSelections(ExtraSelectionKind kind, const QList &selections); + QList extraSelections(ExtraSelectionKind kind) const; struct BlockRange { BlockRange():first(0), last(-1){} diff --git a/src/plugins/texteditor/basetexteditor_p.h b/src/plugins/texteditor/basetexteditor_p.h index 56b1071e1c6..9f1e5a7eb67 100644 --- a/src/plugins/texteditor/basetexteditor_p.h +++ b/src/plugins/texteditor/basetexteditor_p.h @@ -204,8 +204,7 @@ public: QObject *m_actionHack; - QList m_extraSelections; - QList m_extraExtraSelections; + QList m_extraSelections[BaseTextEditor::NExtraSelectionKinds]; // block selection mode bool m_inBlockSelectionMode; diff --git a/src/plugins/vcsbase/vcsbaseeditor.cpp b/src/plugins/vcsbase/vcsbaseeditor.cpp index dcfe55d195b..eb65457c109 100644 --- a/src/plugins/vcsbase/vcsbaseeditor.cpp +++ b/src/plugins/vcsbase/vcsbaseeditor.cpp @@ -225,23 +225,12 @@ void VCSBaseEditor::mouseMoveEvent(QMouseEvent *e) sel.format.setFontUnderline(true); change = changeUnderCursor(cursor); sel.format.setProperty(QTextFormat::UserProperty, change); - bool found = false; - foreach (QTextEdit::ExtraSelection es, extraSelections()) { - if (es.format.stringProperty(QTextFormat::UserProperty) == sel.format.stringProperty(QTextFormat::UserProperty)) { - found = true; - break; - } - } - if (!found) { - setExtraSelections(QList() << sel); - viewport()->setCursor(Qt::PointingHandCursor); - } - } else { - if (!extraSelections().isEmpty()) { - setExtraSelections(QList()); - viewport()->setCursor(Qt::IBeamCursor); - } + setExtraSelections(OtherSelection, QList() << sel); + viewport()->setCursor(Qt::PointingHandCursor); } + } else { + setExtraSelections(OtherSelection, QList()); + viewport()->setCursor(Qt::IBeamCursor); } TextEditor::BaseTextEditor::mouseMoveEvent(e); } From ecfb77d469e3410f06c093a7696fe8939f4f0632 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorbj=C3=B8rn=20Lindeijer?= Date: Fri, 5 Dec 2008 12:21:18 +0100 Subject: [PATCH 25/25] Separate scope in classes quickopen filter The scope of the classes is now separated and displayed in the second column, and not included in the search. --- src/libs/cplusplus/Icons.cpp | 4 +- src/libs/cplusplus/Icons.h | 2 +- src/libs/utils/pathchooser.h | 1 + src/plugins/cpptools/cppclassesfilter.cpp | 1 + src/plugins/cpptools/searchsymbols.cpp | 79 +++++++++++++++-------- src/plugins/cpptools/searchsymbols.h | 14 ++++ 6 files changed, 70 insertions(+), 31 deletions(-) diff --git a/src/libs/cplusplus/Icons.cpp b/src/libs/cplusplus/Icons.cpp index 94b6469ea46..3b7ee24da3c 100644 --- a/src/libs/cplusplus/Icons.cpp +++ b/src/libs/cplusplus/Icons.cpp @@ -61,11 +61,11 @@ Icons::Icons() { } -QIcon Icons::iconForSymbol(Symbol *symbol) const +QIcon Icons::iconForSymbol(const Symbol *symbol) const { if (symbol->isFunction() || (symbol->isDeclaration() && symbol->type()->isFunction())) { - Function *function = symbol->asFunction(); + const Function *function = symbol->asFunction(); if (!function) function = symbol->type()->asFunction(); diff --git a/src/libs/cplusplus/Icons.h b/src/libs/cplusplus/Icons.h index c49bcde12d1..6d4e0bb25d6 100644 --- a/src/libs/cplusplus/Icons.h +++ b/src/libs/cplusplus/Icons.h @@ -47,7 +47,7 @@ class CPLUSPLUS_EXPORT Icons public: Icons(); - QIcon iconForSymbol(Symbol *symbol) const; + QIcon iconForSymbol(const Symbol *symbol) const; QIcon keywordIcon() const; QIcon macroIcon() const; diff --git a/src/libs/utils/pathchooser.h b/src/libs/utils/pathchooser.h index 7ae60a255bf..ab821d5df1e 100644 --- a/src/libs/utils/pathchooser.h +++ b/src/libs/utils/pathchooser.h @@ -30,6 +30,7 @@ ** version 1.2, included in the file GPL_EXCEPTION.txt in this package. ** ***************************************************************************/ + #ifndef PATHCHOOSER_H #define PATHCHOOSER_H diff --git a/src/plugins/cpptools/cppclassesfilter.cpp b/src/plugins/cpptools/cppclassesfilter.cpp index 3d8da9a7387..6aa6734fca9 100644 --- a/src/plugins/cpptools/cppclassesfilter.cpp +++ b/src/plugins/cpptools/cppclassesfilter.cpp @@ -42,6 +42,7 @@ CppClassesFilter::CppClassesFilter(CppModelManager *manager, Core::EditorManager setIncludedByDefault(false); search.setSymbolsToSearchFor(SearchSymbols::Classes); + search.setSeparateScope(true); } CppClassesFilter::~CppClassesFilter() diff --git a/src/plugins/cpptools/searchsymbols.cpp b/src/plugins/cpptools/searchsymbols.cpp index 4b1e48abdf7..670d0d6d471 100644 --- a/src/plugins/cpptools/searchsymbols.cpp +++ b/src/plugins/cpptools/searchsymbols.cpp @@ -40,7 +40,8 @@ using namespace CPlusPlus; using namespace CppTools::Internal; SearchSymbols::SearchSymbols(): - symbolsToSearchFor(Classes | Functions | Enums) + symbolsToSearchFor(Classes | Functions | Enums), + separateScope(false) { } @@ -49,6 +50,11 @@ void SearchSymbols::setSymbolsToSearchFor(SymbolTypes types) symbolsToSearchFor = types; } +void SearchSymbols::setSeparateScope(bool separateScope) +{ + this->separateScope = separateScope; +} + QList SearchSymbols::operator()(Document::Ptr doc, const QString &scope) { QString previousScope = switchScope(scope); @@ -73,13 +79,12 @@ bool SearchSymbols::visit(Enum *symbol) return false; QString name = symbolName(symbol); - QString previousScope = switchScope(name); - QIcon icon = icons.iconForSymbol(symbol); + QString scopedName = scopedSymbolName(name); + QString previousScope = switchScope(scopedName); + appendItem(separateScope ? name : scopedName, + separateScope ? previousScope : QString(), + ModelItemInfo::Enum, symbol); Scope *members = symbol->members(); - items.append(ModelItemInfo(name, QString(), ModelItemInfo::Enum, - QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()), - symbol->line(), - icon)); for (unsigned i = 0; i < members->symbolCount(); ++i) { accept(members->symbolAt(i)); } @@ -93,18 +98,18 @@ bool SearchSymbols::visit(Function *symbol) return false; QString name = symbolName(symbol); - QString type = overview.prettyType(symbol->type()); - QIcon icon = icons.iconForSymbol(symbol); - items.append(ModelItemInfo(name, type, ModelItemInfo::Method, - QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()), - symbol->line(), - icon)); + QString scopedName = scopedSymbolName(name); + QString type = overview.prettyType(symbol->type(), + separateScope ? symbol->name() : 0); + appendItem(separateScope ? type : scopedName, + separateScope ? _scope : type, + ModelItemInfo::Method, symbol); return false; } bool SearchSymbols::visit(Namespace *symbol) { - QString name = symbolName(symbol); + QString name = findOrInsert(scopedSymbolName(symbol)); QString previousScope = switchScope(name); Scope *members = symbol->members(); for (unsigned i = 0; i < members->symbolCount(); ++i) { @@ -118,12 +123,9 @@ bool SearchSymbols::visit(Namespace *symbol) bool SearchSymbols::visit(Declaration *symbol) { if (symbol->type()->isFunction()) { - QString name = symbolName(symbol); + QString name = scopedSymbolName(symbol); QString type = overview.prettyType(symbol->type()); - //QIcon icon = ...; - items.append(ModelItemInfo(name, type, ModelItemInfo::Method, - QString::fromUtf8(symbol->fileName(), symbol->line()), - symbol->line())); + appendItems(name, type, ModelItemInfo::Method, symbol->fileName()); } return false; } @@ -135,12 +137,11 @@ bool SearchSymbols::visit(Class *symbol) return false; QString name = symbolName(symbol); - QString previousScope = switchScope(name); - QIcon icon = icons.iconForSymbol(symbol); - items.append(ModelItemInfo(name, QString(), ModelItemInfo::Class, - QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()), - symbol->line(), - icon)); + QString scopedName = scopedSymbolName(name); + QString previousScope = switchScope(scopedName); + appendItem(separateScope ? name : scopedName, + separateScope ? previousScope : QString(), + ModelItemInfo::Class, symbol); Scope *members = symbol->members(); for (unsigned i = 0; i < members->symbolCount(); ++i) { accept(members->symbolAt(i)); @@ -149,11 +150,22 @@ bool SearchSymbols::visit(Class *symbol) return false; } -QString SearchSymbols::symbolName(const Symbol *symbol) const +QString SearchSymbols::scopedSymbolName(const QString &symbolName) const { QString name = _scope; if (! name.isEmpty()) name += QLatin1String("::"); + name += symbolName; + return name; +} + +QString SearchSymbols::scopedSymbolName(const Symbol *symbol) const +{ + return scopedSymbolName(symbolName(symbol)); +} + +QString SearchSymbols::symbolName(const Symbol *symbol) const +{ QString symbolName = overview.prettyName(symbol->name()); if (symbolName.isEmpty()) { QString type; @@ -176,6 +188,17 @@ QString SearchSymbols::symbolName(const Symbol *symbol) const symbolName += type; symbolName += QLatin1String(">"); } - name += symbolName; - return name; + return symbolName; +} + +void SearchSymbols::appendItem(const QString &name, + const QString &info, + ModelItemInfo::ItemType type, + const CPlusPlus::Symbol *symbol) +{ + const QIcon icon = icons.iconForSymbol(symbol); + items.append(ModelItemInfo(name, info, type, + QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()), + symbol->line(), + icon)); } diff --git a/src/plugins/cpptools/searchsymbols.h b/src/plugins/cpptools/searchsymbols.h index 948f9d78e84..d82f2859721 100644 --- a/src/plugins/cpptools/searchsymbols.h +++ b/src/plugins/cpptools/searchsymbols.h @@ -90,6 +90,7 @@ public: SearchSymbols(); void setSymbolsToSearchFor(SymbolTypes types); + void setSeparateScope(bool separateScope); QList operator()(CPlusPlus::Document::Ptr doc) { return operator()(doc, QString()); } @@ -111,14 +112,27 @@ protected: virtual bool visit(CPlusPlus::Declaration *symbol); #endif virtual bool visit(CPlusPlus::Class *symbol); + + QString scopedSymbolName(const QString &symbolName) const; + QString scopedSymbolName(const CPlusPlus::Symbol *symbol) const; QString symbolName(const CPlusPlus::Symbol *symbol) const; + void appendItem(const QString &name, + const QString &info, + ModelItemInfo::ItemType type, + const CPlusPlus::Symbol *symbol); private: + QString findOrInsert(const QString &s) + { return *strings.insert(s); } + + QSet strings; // Used to avoid QString duplication + QString _scope; CPlusPlus::Overview overview; CPlusPlus::Icons icons; QList items; SymbolTypes symbolsToSearchFor; + bool separateScope; }; Q_DECLARE_OPERATORS_FOR_FLAGS(SearchSymbols::SymbolTypes)