diff --git a/.gitignore b/.gitignore index 0f3b119423db74e21ab8914f97c254e51436f672..f140cb47ca629d575e58f819b212b4340d137f7b 100644 --- a/.gitignore +++ b/.gitignore @@ -68,8 +68,8 @@ src/corelib/lib src/network/lib src/xml/lib/ -# Files copied by syncIde -# ----------------------- +# Binaries +# -------- bin/Aggregation.dll bin/CodeModel.dll bin/ExtensionSystem.dll @@ -77,24 +77,4 @@ bin/QtConcurrent.dll bin/Utils.dll bin/qtcreator bin/qtcreator.exe -shared/help/bookmarkdialog.ui -shared/help/bookmarkmanager.cpp -shared/help/bookmarkmanager.h -shared/help/contentwindow.cpp -shared/help/contentwindow.h -shared/help/filternamedialog.cpp -shared/help/filternamedialog.h -shared/help/filternamedialog.ui -shared/help/helpviewer.cpp -shared/help/helpviewer.h -shared/help/indexwindow.cpp -shared/help/indexwindow.h -shared/help/topicchooser.cpp -shared/help/topicchooser.h -shared/help/topicchooser.ui -shared/proparser/abstractproitemvisitor.h -shared/proparser/profileevaluator.cpp -shared/proparser/profileevaluator.h -shared/proparser/proitems.cpp -shared/proparser/proitems.h -shared/proparser/proparserutils.h +tests/manual/cplusplus/cplusplus0 diff --git a/shared/cplusplus/Parser.cpp b/shared/cplusplus/Parser.cpp index 46618dd112b8c653b33652ba41100a4109d31538..13fbaa0160b6185e3a9609085d10c13f708fa97c 100644 --- a/shared/cplusplus/Parser.cpp +++ b/shared/cplusplus/Parser.cpp @@ -1191,6 +1191,11 @@ bool Parser::parseClassSpecifier(SpecifierAST *&node) NameAST *name = 0; parseName(name); + bool parsed = false; + + const bool previousInFunctionBody = _inFunctionBody; + _inFunctionBody = false; + if (LA() == T_COLON || LA() == T_LBRACE) { BaseSpecifierAST *base_clause = 0; if (LA() == T_COLON) { @@ -1233,9 +1238,12 @@ bool Parser::parseClassSpecifier(SpecifierAST *&node) } } node = ast; - return true; + parsed = true; } - return false; + + _inFunctionBody = previousInFunctionBody; + + return parsed; } bool Parser::parseAccessSpecifier(SpecifierAST *&node) diff --git a/src/libs/cplusplus/CppDocument.cpp b/src/libs/cplusplus/CppDocument.cpp index 782c14ff6d556ecac284d71a567d619d1e52d145..3a280416d9b881631dac42e8486f7a9834a1ec0d 100644 --- a/src/libs/cplusplus/CppDocument.cpp +++ b/src/libs/cplusplus/CppDocument.cpp @@ -153,6 +153,11 @@ void Document::appendMacro(const QByteArray ¯oName, const QByteArray &text) _definedMacros += text; } +void Document::addMacroUse(unsigned offset, unsigned length) +{ + _macroUses.append(Block(offset, offset + length)); +} + TranslationUnit *Document::translationUnit() const { return _translationUnit; diff --git a/src/libs/cplusplus/CppDocument.h b/src/libs/cplusplus/CppDocument.h index 17762200fa03c99fdde3871c5c9398c07720f411..e952913a07b7d75e37648b7af0117e180845f4cb 100644 --- a/src/libs/cplusplus/CppDocument.h +++ b/src/libs/cplusplus/CppDocument.h @@ -68,6 +68,8 @@ public: void appendMacro(const QByteArray ¯oName, const QByteArray &text); + void addMacroUse(unsigned offset, unsigned length); + Control *control() const; TranslationUnit *translationUnit() const; @@ -176,6 +178,9 @@ public: QList<Block> skippedBlocks() const { return _skippedBlocks; } + QList<Block> macroUses() const + { return _macroUses; } + private: Symbol *findSymbolAt(unsigned line, unsigned column, Scope *scope) const; @@ -189,6 +194,7 @@ private: QByteArray _definedMacros; QSet<QByteArray> _macroNames; QList<Block> _skippedBlocks; + QList<Block> _macroUses; }; } // end of namespace CPlusPlus diff --git a/src/libs/utils/filesearch.cpp b/src/libs/utils/filesearch.cpp index 6286b780d30db94e67f85d7f1cafe87c2c2712d4..153b9531742b3f5f5345d57e8b7844e050f650da 100644 --- a/src/libs/utils/filesearch.cpp +++ b/src/libs/utils/filesearch.cpp @@ -165,7 +165,7 @@ void runFileSearchRegExp(QFutureInterface<FileSearchResult> &future, int numFilesSearched = 0; int numMatches = 0; if (flags & QTextDocument::FindWholeWords) - searchTerm = QString("\b%1\b").arg(searchTerm); + searchTerm = QString("\\b%1\\b").arg(searchTerm); Qt::CaseSensitivity caseSensitivity = (flags & QTextDocument::FindCaseSensitively) ? Qt::CaseSensitive : Qt::CaseInsensitive; QRegExp expression(searchTerm, caseSensitivity); diff --git a/src/libs/utils/filewizarddialog.cpp b/src/libs/utils/filewizarddialog.cpp index 8608fed73ec6a0ed0bba88bce98cca01dcb29d9b..8441cdb86380e7add0b1f572296e5bd79d723f70 100644 --- a/src/libs/utils/filewizarddialog.cpp +++ b/src/libs/utils/filewizarddialog.cpp @@ -44,6 +44,8 @@ FileWizardDialog::FileWizardDialog(QWidget *parent) : m_filePage(new FileWizardPage) { setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); + setOption(QWizard::NoCancelButton, false); + setOption(QWizard::NoDefaultButton, false); setPixmap(QWizard::WatermarkPixmap, QPixmap(QLatin1String(":/qworkbench/images/qtwatermark.png"))); addPage(m_filePage); connect(m_filePage, SIGNAL(activated()), button(QWizard::FinishButton), SLOT(animateClick())); diff --git a/src/plugins/coreplugin/basefilewizard.cpp b/src/plugins/coreplugin/basefilewizard.cpp index f72353743b8852ec1b30750bc3aeb9e807020446..58030ba20c9ad8e0c7aaef03c266ff694fbbc3d6 100644 --- a/src/plugins/coreplugin/basefilewizard.cpp +++ b/src/plugins/coreplugin/basefilewizard.cpp @@ -509,6 +509,8 @@ QPixmap BaseFileWizard::watermark() void BaseFileWizard::setupWizard(QWizard *w) { w->setPixmap(QWizard::WatermarkPixmap, watermark()); + w->setOption(QWizard::NoCancelButton, false); + w->setOption(QWizard::NoDefaultButton, false); } bool BaseFileWizard::postGenerateFiles(const GeneratedFiles &l, QString *errorMessage) diff --git a/src/plugins/coreplugin/coreconstants.h b/src/plugins/coreplugin/coreconstants.h index ee1488d40dc0097a8d6ce2857775f406931cd2a5..c2a703a2d6f66bb1633be393637b5ec53071f287 100644 --- a/src/plugins/coreplugin/coreconstants.h +++ b/src/plugins/coreplugin/coreconstants.h @@ -94,6 +94,7 @@ const char * const C_WELCOME_MODE = "Core.WelcomeMode"; const char * const C_EDIT_MODE = "Core.EditMode"; const char * const C_EDITORMANAGER = "Core.EditorManager"; const char * const C_NAVIGATION_PANE = "Core.NavigationPane"; +const char * const C_PROBLEM_PANE = "Core.ProblemPane"; //default editor kind const char * const K_DEFAULT_TEXT_EDITOR = "Plain Text Editor"; diff --git a/src/plugins/coreplugin/editormanager/editormanager.cpp b/src/plugins/coreplugin/editormanager/editormanager.cpp index 1593847ef858a8d992ce95d4d83868a677d7a3c0..29798b25c010e9202f09cd2c27d38e6278ff9900 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.cpp +++ b/src/plugins/coreplugin/editormanager/editormanager.cpp @@ -1003,29 +1003,32 @@ bool EditorManager::saveFile(IEditor *editor) return success; } -namespace { - enum ReadOnlyAction { RO_Cancel, RO_OpenSCC, RO_MakeWriteable, RO_SaveAs }; -} - -static ReadOnlyAction promptReadOnly(const QString &fileName, bool hasSCC, QWidget *parent) +EditorManager::ReadOnlyAction + EditorManager::promptReadOnlyFile(const QString &fileName, + const IVersionControl *versionControl, + QWidget *parent, + bool displaySaveAsButton) { QMessageBox msgBox(QMessageBox::Question, QObject::tr("File is Read Only"), QObject::tr("The file %1 is read only.").arg(fileName), QMessageBox::Cancel, parent); QPushButton *sccButton = 0; - if (hasSCC) - sccButton = msgBox.addButton(QObject::tr("Open with SCC"), QMessageBox::AcceptRole); + if (versionControl && versionControl->supportsOperation(IVersionControl::OpenOperation)) + sccButton = msgBox.addButton(QObject::tr("Open with VCS (%1)").arg(versionControl->name()), QMessageBox::AcceptRole); + QPushButton *makeWritableButton = msgBox.addButton(QObject::tr("Make writable"), QMessageBox::AcceptRole); - QPushButton *saveAsButton = msgBox.addButton(QObject::tr("Save as ..."), QMessageBox::ActionRole); - if (hasSCC) - msgBox.setDefaultButton(sccButton); - else - msgBox.setDefaultButton(makeWritableButton); + + QPushButton *saveAsButton = 0; + if (displaySaveAsButton) + msgBox.addButton(QObject::tr("Save as ..."), QMessageBox::ActionRole); + + msgBox.setDefaultButton(sccButton ? sccButton : makeWritableButton); msgBox.exec(); + QAbstractButton *clickedButton = msgBox.clickedButton(); if (clickedButton == sccButton) - return RO_OpenSCC; + return RO_OpenVCS; if (clickedButton == makeWritableButton) return RO_MakeWriteable; if (clickedButton == saveAsButton) @@ -1042,8 +1045,8 @@ EditorManager::makeEditorWritable(IEditor *editor) IFile *file = editor->file(); const QString &fileName = file->fileName(); - switch (promptReadOnly(fileName, versionControl, m_d->m_core->mainWindow())) { - case RO_OpenSCC: + switch (promptReadOnlyFile(fileName, versionControl, m_d->m_core->mainWindow(), true)) { + case RO_OpenVCS: if (!versionControl->vcsOpen(fileName)) { QMessageBox::warning(m_d->m_core->mainWindow(), tr("Failed!"), tr("Could not open the file for edit with SCC.")); return Failed; diff --git a/src/plugins/coreplugin/editormanager/editormanager.h b/src/plugins/coreplugin/editormanager/editormanager.h index b71791f36bfaae03145b5eda8dd2804f48cfa1b2..b9da2e055ff2478a83487564c9593792d7199903 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.h +++ b/src/plugins/coreplugin/editormanager/editormanager.h @@ -55,6 +55,7 @@ class IEditorFactory; class MimeType; class IFile; class IMode; +class IVersionControl; enum MakeWritableResult { OpenedWithVersionControl, @@ -159,6 +160,16 @@ public: QString defaultExternalEditor() const; QString externalEditorHelpText() const; + + // Helper to display a message dialog when encountering a read-only + // file, prompting the user about how to make it writeable. + enum ReadOnlyAction { RO_Cancel, RO_OpenVCS, RO_MakeWriteable, RO_SaveAs }; + + static ReadOnlyAction promptReadOnlyFile(const QString &fileName, + const IVersionControl *versionControl, + QWidget *parent, + bool displaySaveAsButton = false); + signals: void currentEditorChanged(Core::IEditor *editor); void editorCreated(Core::IEditor *editor, const QString &fileName); diff --git a/src/plugins/coreplugin/iversioncontrol.h b/src/plugins/coreplugin/iversioncontrol.h index b90f9d79c659536d31be68d962c5c12794ab6282..0962c5537e8cf6b1594fdcd84b1b4ff449fc955f 100644 --- a/src/plugins/coreplugin/iversioncontrol.h +++ b/src/plugins/coreplugin/iversioncontrol.h @@ -45,51 +45,53 @@ class CORE_EXPORT IVersionControl : public QObject { Q_OBJECT public: + enum Operation { AddOperation, DeleteOperation, OpenOperation }; + IVersionControl(QObject *parent = 0) : QObject(parent) {} virtual ~IVersionControl() {} - // Returns wheter files in this directory should be managed with this + virtual QString name() const = 0; + + // Enable the VCS, that is, make its menu actions visible. + virtual bool isEnabled() const = 0; + virtual void setEnabled(bool enabled) = 0; + + // Returns whether files in this directory should be managed with this // version control. virtual bool managesDirectory(const QString &filename) const = 0; - // This function should return the topmost directory, for - // which this IVersionControl should be used. - // The VCSManager assumes that all files in the returned directory - // are managed by the same IVersionControl + // This function should return the topmost directory, for which this + // IVersionControl should be used. The VCSManager assumes that all files + // in the returned directory are managed by the same IVersionControl // Note that this is used as an optimization, so that the VCSManager // doesn't need to call managesDirectory(..) for each directory - // This function is called after finding out that the directory is managed by - // a specific version control + // This function is called after finding out that the directory is managed + // by a specific version control. virtual QString findTopLevelForDirectory(const QString &directory) const = 0; - // Called prior to save, if the file is read only. - // Should be implemented if the scc requires a operation before editing the file - // E.g. p4 edit - // Note: The EditorManager calls this for the editors + // Called to query whether a VCS supports the respective operations. + virtual bool supportsOperation(Operation operation) const = 0; + + // Called prior to save, if the file is read only. Should be implemented + // if the scc requires a operation before editing the file, e.g. 'p4 edit' + // Note: The EditorManager calls this for the editors. virtual bool vcsOpen(const QString &fileName) = 0; - // Called after a file has been added to a project - // If the version control needs to know which files it needs to track - // you should reimplement this function - // E.g. p4 add, cvs add, svn add - // Note: This function should be called from IProject subclasses after files - // are added to the project + // Called after a file has been added to a project If the version control + // needs to know which files it needs to track you should reimplement this + // function, e.g. 'p4 add', 'cvs add', 'svn add'. + // Note: This function should be called from IProject subclasses after + // files are added to the project virtual bool vcsAdd(const QString &filename) = 0; - // Called after a file has been removed from the project (if the user wants) - // E.g. p4 delete, svn delete - // You probably want to call SccManager::showDeleteDialog, which asks the user to - // confirm the deletion + // Called after a file has been removed from the project (if the user + // wants), e.g. 'p4 delete', 'svn delete'. + // You probably want to call VcsManager::showDeleteDialog, which asks the + // user to confirm the deletion virtual bool vcsDelete(const QString &filename) = 0; // TODO: ADD A WAY TO DETECT WHETHER A FILE IS MANAGED, e.g // virtual bool sccManaged(const QStryng &filename) = 0; - - // TODO - // we probably want to have a function supports( enum Operation ) or - // something which describes which "kind" of revision control system it is. - // That is to check wheter a given operation is needed. - // But well I don't know yet how all different version control systems work }; } // namespace Core diff --git a/src/plugins/coreplugin/vcsmanager.cpp b/src/plugins/coreplugin/vcsmanager.cpp index a0e1cc19c0ad2663899efcf53a566deeeba574da..02475a0d0e66cfb5369327ec1c5f2827f43aa167 100644 --- a/src/plugins/coreplugin/vcsmanager.cpp +++ b/src/plugins/coreplugin/vcsmanager.cpp @@ -45,8 +45,18 @@ #include <QtCore/QFileInfo> #include <QtGui/QMessageBox> +enum { debug = 0 }; + namespace Core { +typedef QList<IVersionControl *> VersionControlList; + +static inline VersionControlList allVersionControls() +{ + return ExtensionSystem::PluginManager::instance()->getObjects<IVersionControl>(); +} + +// ---- VCSManagerPrivate struct VCSManagerPrivate { QMap<QString, IVersionControl *> m_cachedMatches; }; @@ -61,31 +71,54 @@ VCSManager::~VCSManager() delete m_d; } +void VCSManager::setVCSEnabled(const QString &directory) +{ + if (debug) + qDebug() << Q_FUNC_INFO << directory; + IVersionControl* managingVCS = findVersionControlForDirectory(directory); + const VersionControlList versionControls = allVersionControls(); + foreach(IVersionControl *versionControl, versionControls) { + const bool newEnabled = versionControl == managingVCS; + if (newEnabled != versionControl->isEnabled()) + versionControl->setEnabled(newEnabled); + } +} + +void VCSManager::setAllVCSEnabled() +{ + if (debug) + qDebug() << Q_FUNC_INFO; + const VersionControlList versionControls = allVersionControls(); + foreach(IVersionControl *versionControl, versionControls) + if (!versionControl->isEnabled()) + versionControl->setEnabled(true); +} + IVersionControl* VCSManager::findVersionControlForDirectory(const QString &directory) { - // first look into the cache - int pos = 0; - { // First try the whole name - QMap<QString, IVersionControl *>::const_iterator it = m_d->m_cachedMatches.constFind(directory); - if (it != m_d->m_cachedMatches.constEnd()) { + // first look into the cache, check the whole name + + { + const QMap<QString, IVersionControl *>::const_iterator it = m_d->m_cachedMatches.constFind(directory); + if (it != m_d->m_cachedMatches.constEnd()) return it.value(); - } } + int pos = 0; + const QChar slash = QLatin1Char('/'); while(true) { - int index = directory.indexOf('/', pos); + int index = directory.indexOf(slash, pos); if (index == -1) break; - QString directoryPart = directory.left(index); + const QString directoryPart = directory.left(index); QMap<QString, IVersionControl *>::const_iterator it = m_d->m_cachedMatches.constFind(directoryPart); - if (it != m_d->m_cachedMatches.constEnd()) { + if (it != m_d->m_cachedMatches.constEnd()) return it.value(); - } pos = index+1; } // ah nothing so ask the IVersionControls directly - QList<IVersionControl *> versionControls = ExtensionSystem::PluginManager::instance()->getObjects<IVersionControl>(); + const VersionControlList versionControls = allVersionControls(); foreach(IVersionControl * versionControl, versionControls) { if (versionControl->managesDirectory(directory)) { m_d->m_cachedMatches.insert(versionControl->findTopLevelForDirectory(directory), versionControl); @@ -95,20 +128,20 @@ IVersionControl* VCSManager::findVersionControlForDirectory(const QString &direc return 0; } -void VCSManager::showDeleteDialog(const QString &fileName) +bool VCSManager::showDeleteDialog(const QString &fileName) { IVersionControl *vc = findVersionControlForDirectory(QFileInfo(fileName).absolutePath()); - if (!vc) - return; + if (!vc || !vc->supportsOperation(IVersionControl::DeleteOperation)) + return true; const QString title = QCoreApplication::translate("VCSManager", "Version Control"); const QString msg = QCoreApplication::translate("VCSManager", - "Would you like to remove this file from the version control system?\n" - "Note: This might remove the local file."); + "Would you like to remove this file from the version control system (%1)?\n" + "Note: This might remove the local file.").arg(vc->name()); const QMessageBox::StandardButton button = QMessageBox::question(0, title, msg, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); - if (button == QMessageBox::Yes) { - vc->vcsDelete(fileName); - } + if (button != QMessageBox::Yes) + return true; + return vc->vcsDelete(fileName); } } // namespace Core diff --git a/src/plugins/coreplugin/vcsmanager.h b/src/plugins/coreplugin/vcsmanager.h index 92e4f35d1540a2a2282b1fb361ae35ea231a75ef..a3afca96d6adef219ad847fcc7427d8818b92814 100644 --- a/src/plugins/coreplugin/vcsmanager.h +++ b/src/plugins/coreplugin/vcsmanager.h @@ -45,12 +45,12 @@ class IVersionControl; // The VCSManager has only one notable function: // findVersionControlFor(), which returns the IVersionControl * for a given -// filename. Note that the VCSManager assumes that if a IVersionControl * +// filename. Note that the VCSManager assumes that if a IVersionControl * // manages a directory, then it also manages all the files and all the // subdirectories. // // It works by asking all IVersionControl * if they manage the file, and ask -// for the topmost directory it manages. This information is cached and +// for the topmost directory it manages. This information is cached and // VCSManager thus knows pretty fast which IVersionControl * is responsible. class CORE_EXPORT VCSManager @@ -62,10 +62,16 @@ public: IVersionControl *findVersionControlForDirectory(const QString &directory); - // Shows a confirmation dialog, - // wheter the file should also be deleted from revision control - // Calls sccDelete on the file - void showDeleteDialog(const QString &fileName); + // Enable the VCS managing a certain directory only. This should + // be used by project manager classes. + void setVCSEnabled(const QString &directory); + // Enable all VCS. + void setAllVCSEnabled(); + + // Shows a confirmation dialog, whether the file should also be deleted + // from revision control Calls sccDelete on the file. Returns false + // if a failure occurs + bool showDeleteDialog(const QString &fileName); private: VCSManagerPrivate *m_d; diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp index 1708e62de35b26c5aae7bf7c25d4f5129505278b..ccaff0bcfe5cf2e40a43a815004953f11c9a3607 100644 --- a/src/plugins/cpptools/cppmodelmanager.cpp +++ b/src/plugins/cpptools/cppmodelmanager.cpp @@ -253,6 +253,25 @@ protected: m_currentDoc->appendMacro(macroName, macroText); } + virtual void startExpandingMacro(unsigned offset, + const rpp::Macro ¯o, + const QByteArray &originalText) + { + if (! m_currentDoc) + return; + + //qDebug() << "start expanding:" << macro.name << "text:" << originalText; + m_currentDoc->addMacroUse(offset, originalText.length()); + } + + virtual void stopExpandingMacro(unsigned offset, const rpp::Macro ¯o) + { + if (! m_currentDoc) + return; + + //qDebug() << "stop expanding:" << macro.name; + } + void mergeEnvironment(Document::Ptr doc) { QSet<QString> processed; @@ -505,7 +524,7 @@ CppModelManager::ProjectInfo *CppModelManager::projectInfo(ProjectExplorer::Proj QFuture<void> CppModelManager::refreshSourceFiles(const QStringList &sourceFiles) { - if (qgetenv("QTCREATOR_NO_CODE_INDEXER").isNull()) { + if (! sourceFiles.isEmpty() && qgetenv("QTCREATOR_NO_CODE_INDEXER").isNull()) { const QMap<QString, QByteArray> workingCopy = buildWorkingCopyList(); QFuture<void> result = QtConcurrent::run(&CppModelManager::parse, this, @@ -595,6 +614,22 @@ void CppModelManager::onDocumentUpdated(Document::Ptr doc) QList<QTextEdit::ExtraSelection> selections; +#ifdef QTCREATOR_WITH_MACRO_HIGHLIGHTING + // set up the format for the macros + QTextCharFormat macroFormat; + macroFormat.setUnderlineStyle(QTextCharFormat::SingleUnderline); + + QTextCursor c = ed->textCursor(); + foreach (const Document::Block block, doc->macroUses()) { + QTextEdit::ExtraSelection sel; + sel.cursor = c; + sel.cursor.setPosition(block.begin()); + sel.cursor.setPosition(block.end(), QTextCursor::KeepAnchor); + sel.format = macroFormat; + selections.append(sel); + } +#endif // QTCREATOR_WITH_MACRO_HIGHLIGHTING + // set up the format for the errors QTextCharFormat errorFormat; errorFormat.setUnderlineStyle(QTextCharFormat::WaveUnderline); @@ -657,6 +692,8 @@ void CppModelManager::parse(QFutureInterface<void> &future, QStringList files, QMap<QString, QByteArray> workingCopy) { + Q_ASSERT(! files.isEmpty()); + // Change the priority of the background parser thread to idle. QThread::currentThread()->setPriority(QThread::IdlePriority); @@ -698,6 +735,8 @@ void CppModelManager::parse(QFutureInterface<void> &future, #endif } + future.setProgressValue(files.size()); + // Restore the previous thread priority. QThread::currentThread()->setPriority(QThread::NormalPriority); } diff --git a/src/plugins/cpptools/rpp/pp-client.h b/src/plugins/cpptools/rpp/pp-client.h index 073fc44c3627ad3643e18eef4be96c2e565a8f40..974004a6ce50ec85aeb2df035d63c686df19b444 100644 --- a/src/plugins/cpptools/rpp/pp-client.h +++ b/src/plugins/cpptools/rpp/pp-client.h @@ -40,6 +40,8 @@ namespace rpp { +class Macro; + class Client { Client(const Client &other); @@ -61,6 +63,13 @@ public: virtual void macroAdded(const QByteArray ¯oId, const QByteArray &text) = 0; virtual void sourceNeeded(QString &fileName, IncludeType mode) = 0; // ### FIX the signature. + virtual void startExpandingMacro(unsigned offset, + const Macro ¯o, + const QByteArray &originalTextt) = 0; + + virtual void stopExpandingMacro(unsigned offset, + const Macro ¯o) = 0; + virtual void startSkippingBlocks(unsigned offset) = 0; virtual void stopSkippingBlocks(unsigned offset) = 0; }; diff --git a/src/plugins/cpptools/rpp/pp-engine.cpp b/src/plugins/cpptools/rpp/pp-engine.cpp index 3a3e9245b30229a330fe9f3ea894eb5ec9a66b29..66e8957f355e5dc28c25c755b4d86e83d49f5a04 100644 --- a/src/plugins/cpptools/rpp/pp-engine.cpp +++ b/src/plugins/cpptools/rpp/pp-engine.cpp @@ -575,7 +575,17 @@ void pp::operator()(const QByteArray &source, QByteArray *result) const QByteArray spell = tokenSpell(*identifierToken); if (env.isBuiltinMacro(spell)) { + const Macro trivial; + + if (client) + client->startExpandingMacro(identifierToken->offset, + trivial, spell); + expand(spell.constBegin(), spell.constEnd(), result); + + if (client) + client->stopExpandingMacro(_dot->offset, trivial); + continue; } @@ -585,18 +595,36 @@ void pp::operator()(const QByteArray &source, QByteArray *result) } else { if (! m->function_like) { if (_dot->isNot(T_LPAREN)) { + if (client) + client->startExpandingMacro(identifierToken->offset, + *m, spell); + m->hidden = true; + expand(m->definition.constBegin(), m->definition.constEnd(), result); + + if (client) + client->stopExpandingMacro(_dot->offset, *m); + m->hidden = false; continue; } else { QByteArray tmp; m->hidden = true; + + if (client) + client->startExpandingMacro(identifierToken->offset, + *m, spell); + expand(m->definition.constBegin(), m->definition.constEnd(), &tmp); + + if (client) + client->stopExpandingMacro(_dot->offset, *m); + m->hidden = false; m = 0; // reset the active the macro @@ -640,9 +668,20 @@ void pp::operator()(const QByteArray &source, QByteArray *result) const char *beginOfText = startOfToken(*identifierToken); const char *endOfText = endOfToken(*_dot); ++_dot; // skip T_RPAREN - //m->hidden = true; + + if (client) { + const QByteArray text = + QByteArray::fromRawData(beginOfText, + endOfText - beginOfText); + + client->startExpandingMacro(identifierToken->offset, + *m, text); + } + expand(beginOfText, endOfText, result); - //m->hidden = false; + + if (client) + client->stopExpandingMacro(_dot->offset, *m); } } } diff --git a/src/plugins/debugger/breakhandler.cpp b/src/plugins/debugger/breakhandler.cpp index 8199d4ab518ddc3a1884cb009c5d688b6096ba55..f4b528c50fa9816f896ab3941c062e5f44e0ac2e 100644 --- a/src/plugins/debugger/breakhandler.cpp +++ b/src/plugins/debugger/breakhandler.cpp @@ -231,6 +231,11 @@ BreakHandler::BreakHandler(QObject *parent) { } +BreakHandler::~BreakHandler() +{ + clear(); +} + int BreakHandler::columnCount(const QModelIndex &parent) const { return parent.isValid() ? 0 : 6; diff --git a/src/plugins/debugger/breakhandler.h b/src/plugins/debugger/breakhandler.h index 4581e3a4de97552328dfda23835a41124214ec54..95743f6df50d4727741ffa1f0b4f15d508eff287 100644 --- a/src/plugins/debugger/breakhandler.h +++ b/src/plugins/debugger/breakhandler.h @@ -113,6 +113,7 @@ class BreakHandler : public QAbstractItemModel public: explicit BreakHandler(QObject *parent = 0); + ~BreakHandler(); void removeAllBreakpoints(); void setAllPending(); diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp index f696d728467654a5df68124e060c28f030c97fcc..42551168fe20e1e72e0e934797bfd9c7b0c16ffe 100644 --- a/src/plugins/debugger/debuggermanager.cpp +++ b/src/plugins/debugger/debuggermanager.cpp @@ -622,7 +622,7 @@ void DebuggerManager::notifyInferiorPidChanged(int pid) void DebuggerManager::showApplicationOutput(const QString &prefix, const QString &str) { - applicationOutputAvailable(prefix, str); + emit applicationOutputAvailable(prefix, str); } void DebuggerManager::shutdown() diff --git a/src/plugins/debugger/debuggerrunner.cpp b/src/plugins/debugger/debuggerrunner.cpp index c161c9bad9881f49f5bbe555b27a0f3afe0c734d..90c8c4e9f7d6dc53acf6bfe7dfcbc415b596b0e1 100644 --- a/src/plugins/debugger/debuggerrunner.cpp +++ b/src/plugins/debugger/debuggerrunner.cpp @@ -44,6 +44,7 @@ #include <QtCore/QDebug> #include <QtCore/QDir> #include <QtCore/QFileInfo> +#include <QtGui/QTextDocument> using namespace Debugger::Internal; @@ -140,8 +141,8 @@ void DebuggerRunControl::slotAddToOutputWindow(const QString &prefix, const QStr { Q_UNUSED(prefix); foreach (const QString &l, line.split('\n')) - emit addToOutputWindow(this, prefix + l); - //emit addToOutputWindow(this, prefix + line); + emit addToOutputWindow(this, prefix + Qt::escape(l)); + //emit addToOutputWindow(this, prefix + Qt::escape(line)); } void DebuggerRunControl::stop() diff --git a/src/plugins/debugger/gdbengine.cpp b/src/plugins/debugger/gdbengine.cpp index df0eaa9f0b293d0379236ebc67172daf095aba40..80d0a046fc3179f334fa054f8ba1abcd59500cdd 100644 --- a/src/plugins/debugger/gdbengine.cpp +++ b/src/plugins/debugger/gdbengine.cpp @@ -110,7 +110,6 @@ enum GdbCommandType GdbFileExecAndSymbols, GdbQueryPwd, GdbQuerySources, - GdbQuerySources2, GdbAsyncOutput2, GdbExecRun, GdbExecRunToFunction, @@ -126,7 +125,6 @@ enum GdbCommandType GdbInfoProc, GdbQueryDataDumper1, GdbQueryDataDumper2, - GdbInitializeSocket1, BreakCondition = 200, BreakEnablePending, @@ -444,7 +442,7 @@ void GdbEngine::handleResponse() break; } - if (token == -1 && *from != '&' && *from != '~') { + if (token == -1 && *from != '&' && *from != '~' && *from != '*') { // FIXME: On Linux the application's std::out is merged in here. // High risk of falsely interpreting this as MI output. // We assume that we _always_ use tokens, so not finding a token @@ -493,8 +491,10 @@ void GdbEngine::handleResponse() m_inbuffer = QByteArray(from, to - from); if (asyncClass == "stopped") { handleAsyncOutput(record); + } else if (asyncClass == "running") { + // Archer has 'thread-id="all"' here } else { - qDebug() << "INGNORED ASYNC OUTPUT " << record.toString(); + qDebug() << "IGNORED ASYNC OUTPUT " << record.toString(); } break; } @@ -633,18 +633,10 @@ void GdbEngine::readGdbStandardOutput() { // This is the function called whenever the Gdb process created // output. As a rule of thumb, stdout contains _real_ Gdb output - // as responses to our command (with exception of the data dumpers) + // as responses to our command // and "spontaneous" events like messages on loaded shared libraries. - // Otoh, stderr contains application output produced by qDebug etc. - // There is no organized way to pass application stdout output - - // The result of custom data dumpers arrives over the socket _before_ - // the corresponding Gdb "^done" message arrives here over stdout - // and is merged into the response via m_pendingCustomValueContents. - - // Note that this code here runs syncronized to the arriving - // output. The completed response will be signalled by a queued - // connection to the handlers. + // OTOH, stderr contains application output produced by qDebug etc. + // There is no organized way to pass application stdout output. QByteArray out = m_gdbProc.readAllStandardOutput(); @@ -765,19 +757,12 @@ void GdbEngine::handleResultRecord(const GdbResultRecord &record) //qDebug() << "TOKEN: " << record.token // << " ACCEPTABLE: " << m_oldestAcceptableToken; //qDebug() << ""; - //qDebug() << qPrintable(currentTime()) << "Reading response: " - // << record.toString() << "\n"; //qDebug() << "\nRESULT" << record.token << record.toString(); int token = record.token; if (token == -1) return; - if (!m_cookieForToken.contains(token)) { - qDebug() << "NO SUCH TOKEN (ANYMORE): " << token; - return; - } - GdbCookie cmd = m_cookieForToken.take(token); // FIXME: this falsely rejects results from the custom dumper recognition @@ -788,12 +773,6 @@ void GdbEngine::handleResultRecord(const GdbResultRecord &record) return; } - // We get _two_ results for a '-exec-foo' command: First a - // 'running' notification, then a 'stopped' or similar. - // So put it back. - if (record.resultClass == GdbResultRunning) - m_cookieForToken[token] = cmd; - #if 0 qDebug() << "# handleOutput, " << "cmd type: " << cmd.type @@ -858,18 +837,12 @@ void GdbEngine::handleResult(const GdbResultRecord & record, int type, case GdbQuerySources: handleQuerySources(record); break; - case GdbQuerySources2: - handleQuerySources2(record, cookie); - break; case GdbAsyncOutput2: handleAsyncOutput2(cookie.value<GdbMi>()); break; case GdbInfoShared: handleInfoShared(record); break; - case GdbInitializeSocket1: - //qDebug() << " INIT SOCKET" << record.toString(); - break; case GdbQueryDataDumper1: handleQueryDataDumper1(record); break; @@ -1072,13 +1045,6 @@ void GdbEngine::handleInfoShared(const GdbResultRecord &record) } } -void GdbEngine::handleQuerySources2(const GdbResultRecord &record, - const QVariant &cookie) -{ - if (record.resultClass == GdbResultDone) - handleAsyncOutput2(cookie.value<GdbMi>()); -} - void GdbEngine::handleExecJumpToLine(const GdbResultRecord &record) { // FIXME: remove this special case as soon as 'jump' @@ -3681,11 +3647,16 @@ void GdbEngine::handleStackListLocals(const GdbResultRecord &record) // stage 2/2 // There could be shadowed variables - QHash<QString, int> seen; QList<GdbMi> locals = record.data.findChild("locals").children(); locals += m_currentFunctionArgs; + setLocals(locals); +} + +void GdbEngine::setLocals(const QList<GdbMi> &locals) +{ //qDebug() << m_varToType; + QHash<QString, int> seen; foreach (const GdbMi &item, locals) { #ifdef Q_OS_MAC diff --git a/src/plugins/debugger/gdbengine.h b/src/plugins/debugger/gdbengine.h index 45eafcdb92c6172f62fa634f4fb450b79e87f29c..b3e13233526754ac0d0c41bec3992bd668f19913 100644 --- a/src/plugins/debugger/gdbengine.h +++ b/src/plugins/debugger/gdbengine.h @@ -206,8 +206,6 @@ private: void handleShowVersion(const GdbResultRecord &response); void handleQueryPwd(const GdbResultRecord &response); void handleQuerySources(const GdbResultRecord &response); - void handleQuerySources2(const GdbResultRecord &response, - const QVariant &); QByteArray m_inbuffer; @@ -219,7 +217,6 @@ private: QByteArray m_pendingConsoleStreamOutput; QByteArray m_pendingTargetStreamOutput; QByteArray m_pendingLogStreamOutput; - //QByteArray m_pendingCustomValueContents; QString m_pwd; // contains the first token number for the current round @@ -329,6 +326,7 @@ private: void handleVarListChildrenHelper(const GdbMi &child, const WatchData &parent); void setWatchDataType(WatchData &data, const GdbMi &mi); + void setLocals(const QList<GdbMi> &locals); QString m_editedData; int m_pendingRequests; diff --git a/src/plugins/find/finddialog.ui b/src/plugins/find/finddialog.ui index 7240551772071624b06dcf80b47e75b3af48b97e..479299316f6d6b68d2ed4259593a5a814f215464 100644 --- a/src/plugins/find/finddialog.ui +++ b/src/plugins/find/finddialog.ui @@ -1,7 +1,8 @@ -<ui version="4.0" > +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> <class>Find::Internal::FindDialog</class> - <widget class="QDialog" name="Find::Internal::FindDialog" > - <property name="geometry" > + <widget class="QDialog" name="Find::Internal::FindDialog"> + <property name="geometry"> <rect> <x>0</x> <y>0</y> @@ -9,109 +10,109 @@ <height>168</height> </rect> </property> - <property name="sizePolicy" > - <sizepolicy vsizetype="Minimum" hsizetype="Minimum" > + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> - <property name="windowTitle" > + <property name="windowTitle"> <string>Search for...</string> </property> - <property name="sizeGripEnabled" > + <property name="sizeGripEnabled"> <bool>false</bool> </property> - <layout class="QVBoxLayout" name="verticalLayout" > + <layout class="QVBoxLayout" name="verticalLayout"> <item> - <layout class="QGridLayout" name="gridLayout" > - <item row="0" column="0" > - <widget class="QLabel" name="label" > - <property name="sizePolicy" > - <sizepolicy vsizetype="Preferred" hsizetype="Fixed" > + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> - <property name="minimumSize" > + <property name="minimumSize"> <size> <width>80</width> <height>0</height> </size> </property> - <property name="text" > + <property name="text"> <string>Sc&ope:</string> </property> - <property name="alignment" > + <property name="alignment"> <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> </property> - <property name="buddy" > + <property name="buddy"> <cstring>filterList</cstring> </property> </widget> </item> - <item row="0" column="1" > - <widget class="QComboBox" name="filterList" > - <property name="sizePolicy" > - <sizepolicy vsizetype="Fixed" hsizetype="Expanding" > + <item row="0" column="1"> + <widget class="QComboBox" name="filterList"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> </widget> </item> - <item row="0" column="2" > - <widget class="QPushButton" name="searchButton" > - <property name="text" > + <item row="0" column="2"> + <widget class="QPushButton" name="searchButton"> + <property name="text"> <string>&Search</string> </property> - <property name="default" > + <property name="default"> <bool>true</bool> </property> </widget> </item> - <item row="1" column="0" > - <widget class="QLabel" name="label_2" > - <property name="text" > + <item row="1" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> <string>Search &for:</string> </property> - <property name="alignment" > + <property name="alignment"> <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> </property> - <property name="buddy" > + <property name="buddy"> <cstring>searchTerm</cstring> </property> </widget> </item> - <item row="1" column="1" > - <widget class="QLineEdit" name="searchTerm" /> + <item row="1" column="1"> + <widget class="QLineEdit" name="searchTerm"/> </item> - <item row="1" column="2" > - <widget class="QPushButton" name="closeButton" > - <property name="text" > - <string>&Close</string> + <item row="1" column="2"> + <widget class="QPushButton" name="closeButton"> + <property name="text"> + <string>Close</string> </property> </widget> </item> - <item row="4" column="0" colspan="2" > - <widget class="QWidget" native="1" name="configWidget" > - <property name="sizePolicy" > - <sizepolicy vsizetype="Fixed" hsizetype="Preferred" > + <item row="4" column="0" colspan="2"> + <widget class="QWidget" name="configWidget" native="true"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> <horstretch>0</horstretch> <verstretch>10</verstretch> </sizepolicy> </property> </widget> </item> - <item row="2" column="1" > - <widget class="QCheckBox" name="matchCase" > - <property name="text" > - <string>Match &case</string> + <item row="2" column="1"> + <widget class="QCheckBox" name="matchCase"> + <property name="text"> + <string>&Case sensitive</string> </property> </widget> </item> - <item row="3" column="1" > - <widget class="QCheckBox" name="wholeWords" > - <property name="text" > + <item row="3" column="1"> + <widget class="QCheckBox" name="wholeWords"> + <property name="text"> <string>&Whole words only</string> </property> </widget> @@ -119,11 +120,11 @@ </layout> </item> <item> - <spacer name="verticalSpacer_2" > - <property name="orientation" > + <spacer name="verticalSpacer_2"> + <property name="orientation"> <enum>Qt::Vertical</enum> </property> - <property name="sizeHint" stdset="0" > + <property name="sizeHint" stdset="0"> <size> <width>0</width> <height>0</height> diff --git a/src/plugins/git/git.pro b/src/plugins/git/git.pro index 258639dcbe3416cce70579750af6d0b4dd600c12..3c4ca176cb5aa8bfce855a81e380b780ac0739c2 100644 --- a/src/plugins/git/git.pro +++ b/src/plugins/git/git.pro @@ -17,7 +17,9 @@ HEADERS += gitplugin.h \ giteditor.h \ annotationhighlighter.h \ gitsubmiteditorwidget.h \ - gitsubmiteditor.h + gitsubmiteditor.h \ + gitversioncontrol.h \ + gitsettings.h SOURCES += gitplugin.cpp \ gitoutputwindow.cpp \ @@ -28,7 +30,9 @@ SOURCES += gitplugin.cpp \ giteditor.cpp \ annotationhighlighter.cpp \ gitsubmiteditorwidget.cpp \ - gitsubmiteditor.cpp + gitsubmiteditor.cpp \ + gitversioncontrol.cpp \ + gitsettings.cpp FORMS += changeselectiondialog.ui \ settingspage.ui \ diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index fb73d4fe5e2b41a2a750f4ab656d3966baab951c..7d87ce27827838b4971155378b8b4281695a5151 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -49,6 +49,7 @@ #include <QtCore/QRegExp> #include <QtCore/QTemporaryFile> #include <QtCore/QFuture> +#include <QtCore/QTime> #include <QtGui/QErrorMessage> @@ -76,22 +77,25 @@ inline Core::IEditor* locateEditor(const Core::ICore *core, const char *property return 0; } +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(GitPlugin* plugin, Core::ICore *core) : m_msgWait(tr("Waiting for data...")), m_plugin(plugin), m_core(core) { + if (QSettings *s = m_core->settings()) + m_settings.fromSettings(s); } GitClient::~GitClient() { } -bool GitClient::vcsOpen(const QString &fileName) -{ - return m_plugin->vcsOpen(fileName); -} - QString GitClient::findRepositoryForFile(const QString &fileName) { const QString gitDirectory = QLatin1String(kGitDirectoryC); @@ -176,7 +180,7 @@ void GitClient::diff(const QString &workingDirectory, const QStringList &fileNam const QString title = tr("Git Diff"); VCSBase::VCSBaseEditor *editor = createVCSEditor(kind, title, workingDirectory, true, "originalFileName", workingDirectory); - executeGit(workingDirectory, arguments, m_plugin->m_outputWindow, editor); + executeGit(workingDirectory, arguments, m_plugin->outputWindow(), editor); } @@ -194,27 +198,26 @@ void GitClient::diff(const QString &workingDirectory, const QString &fileName) const QString sourceFile = source(workingDirectory, fileName); VCSBase::VCSBaseEditor *editor = createVCSEditor(kind, title, sourceFile, true, "originalFileName", sourceFile); - executeGit(workingDirectory, arguments, m_plugin->m_outputWindow, editor); + executeGit(workingDirectory, arguments, m_plugin->outputWindow(), editor); } void GitClient::status(const QString &workingDirectory) { QStringList statusArgs(QLatin1String("status")); statusArgs << QLatin1String("-u"); - executeGit(workingDirectory, statusArgs, m_plugin->m_outputWindow, 0,true); + executeGit(workingDirectory, statusArgs, m_plugin->outputWindow(), 0,true); } void GitClient::log(const QString &workingDirectory, const QString &fileName) { if (Git::Constants::debug) qDebug() << "log" << workingDirectory << fileName; - QStringList arguments; - int logCount = 10; - if (m_plugin->m_settingsPage && m_plugin->m_settingsPage->logCount() > 0) - logCount = m_plugin->m_settingsPage->logCount(); - arguments << QLatin1String("log") << QLatin1String("-n") - << QString::number(logCount); + QStringList arguments(QLatin1String("log")); + + if (m_settings.logCount > 0) + arguments << QLatin1String("-n") << QString::number(m_settings.logCount); + if (!fileName.isEmpty()) arguments << fileName; @@ -222,7 +225,7 @@ void GitClient::log(const QString &workingDirectory, const QString &fileName) const QString kind = QLatin1String(Git::Constants::GIT_LOG_EDITOR_KIND); const QString sourceFile = source(workingDirectory, fileName); VCSBase::VCSBaseEditor *editor = createVCSEditor(kind, title, sourceFile, false, "logFileName", sourceFile); - executeGit(workingDirectory, arguments, m_plugin->m_outputWindow, editor); + executeGit(workingDirectory, arguments, m_plugin->outputWindow(), editor); } void GitClient::show(const QString &source, const QString &id) @@ -238,7 +241,7 @@ void GitClient::show(const QString &source, const QString &id) const QFileInfo sourceFi(source); const QString workDir = sourceFi.isDir() ? sourceFi.absoluteFilePath() : sourceFi.absolutePath(); - executeGit(workDir, arguments, m_plugin->m_outputWindow, editor); + executeGit(workDir, arguments, m_plugin->outputWindow(), editor); } void GitClient::blame(const QString &workingDirectory, const QString &fileName) @@ -253,7 +256,7 @@ void GitClient::blame(const QString &workingDirectory, const QString &fileName) const QString sourceFile = source(workingDirectory, fileName); VCSBase::VCSBaseEditor *editor = createVCSEditor(kind, title, sourceFile, true, "blameFileName", sourceFile); - executeGit(workingDirectory, arguments, m_plugin->m_outputWindow, editor); + executeGit(workingDirectory, arguments, m_plugin->outputWindow(), editor); } void GitClient::checkout(const QString &workingDirectory, const QString &fileName) @@ -267,7 +270,7 @@ void GitClient::checkout(const QString &workingDirectory, const QString &fileNam arguments << QLatin1String("checkout") << QLatin1String("HEAD") << QLatin1String("--") << fileName; - executeGit(workingDirectory, arguments, m_plugin->m_outputWindow, 0,true); + executeGit(workingDirectory, arguments, m_plugin->outputWindow(), 0,true); } void GitClient::hardReset(const QString &workingDirectory, const QString &commit) @@ -277,7 +280,7 @@ void GitClient::hardReset(const QString &workingDirectory, const QString &commit if (!commit.isEmpty()) arguments << commit; - executeGit(workingDirectory, arguments, m_plugin->m_outputWindow, 0,true); + executeGit(workingDirectory, arguments, m_plugin->outputWindow(), 0,true); } void GitClient::addFile(const QString &workingDirectory, const QString &fileName) @@ -285,7 +288,7 @@ void GitClient::addFile(const QString &workingDirectory, const QString &fileName QStringList arguments; arguments << QLatin1String("add") << fileName; - executeGit(workingDirectory, arguments, m_plugin->m_outputWindow, 0,true); + executeGit(workingDirectory, arguments, m_plugin->outputWindow(), 0,true); } bool GitClient::synchronousAdd(const QString &workingDirectory, const QStringList &files) @@ -300,8 +303,8 @@ bool GitClient::synchronousAdd(const QString &workingDirectory, const QStringLis if (!rc) { const QString errorMessage = tr("Unable to add %n file(s) to %1: %2", 0, files.size()). arg(workingDirectory, QString::fromLocal8Bit(errorText)); - m_plugin->m_outputWindow->append(errorMessage); - m_plugin->m_outputWindow->popup(false); + m_plugin->outputWindow()->append(errorMessage); + m_plugin->outputWindow()->popup(false); } return rc; } @@ -317,14 +320,14 @@ bool GitClient::synchronousReset(const QString &workingDirectory, arguments << QLatin1String("reset") << QLatin1String("HEAD") << QLatin1String("--") << files; const bool rc = synchronousGit(workingDirectory, arguments, &outputText, &errorText); const QString output = QString::fromLocal8Bit(outputText); - m_plugin->m_outputWindow->popup(false); - m_plugin->m_outputWindow->append(output); + m_plugin->outputWindow()->popup(false); + m_plugin->outputWindow()->append(output); // 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->m_outputWindow->append(errorMessage); + m_plugin->outputWindow()->append(errorMessage); return false; } return true; @@ -336,13 +339,14 @@ void GitClient::executeGit(const QString &workingDirectory, const QStringList &a { if (Git::Constants::debug) qDebug() << "executeGit" << workingDirectory << arguments << editor; - outputWindow->clearContents(); + + m_plugin->outputWindow()->append(formatCommand(QLatin1String(kGitCommand), arguments)); QProcess process; ProjectExplorer::Environment environment = ProjectExplorer::Environment::systemEnvironment(); - if (m_plugin->m_settingsPage && !m_plugin->m_settingsPage->adoptEnvironment()) - environment.set(QLatin1String("PATH"), m_plugin->m_settingsPage->path()); + if (m_settings.adoptPath) + environment.set(QLatin1String("PATH"), m_settings.path); GitCommand* command = new GitCommand(); if (outputToWindow) { @@ -368,16 +372,19 @@ bool GitClient::synchronousGit(const QString &workingDirectory { if (Git::Constants::debug) qDebug() << "synchronousGit" << workingDirectory << arguments; - QProcess process; + const QString binary = QLatin1String(kGitCommand); + m_plugin->outputWindow()->append(formatCommand(binary, arguments)); + + QProcess process; process.setWorkingDirectory(workingDirectory); ProjectExplorer::Environment environment = ProjectExplorer::Environment::systemEnvironment(); - if (m_plugin->m_settingsPage && !m_plugin->m_settingsPage->adoptEnvironment()) - environment.set(QLatin1String("PATH"), m_plugin->m_settingsPage->path()); + if (m_settings.adoptPath) + environment.set(QLatin1String("PATH"), m_settings.path); process.setEnvironment(environment.toStringList()); - process.start(QLatin1String(kGitCommand), arguments); + process.start(binary, arguments); if (!process.waitForFinished()) { if (errorText) *errorText = "Error: Git timed out"; @@ -411,6 +418,34 @@ static inline QString trimFileSpecification(QString fileSpec) return fileSpec; } +GitClient::StatusResult GitClient::gitStatus(const QString &workingDirectory, + bool untracked, + QString *output, + QString *errorMessage) +{ + // Run 'status'. Note that git returns exitcode 1 if there are no added files. + QByteArray outputText; + QByteArray errorText; + QStringList statusArgs(QLatin1String("status")); + if (untracked) + statusArgs << QLatin1String("-u"); + const bool statusRc = synchronousGit(workingDirectory, statusArgs, &outputText, &errorText); + if (output) + *output = QString::fromLocal8Bit(outputText).remove(QLatin1Char('\r')); + // Is it something really fatal? + if (!statusRc && !outputText.contains(kBranchIndicatorC)) { + if (errorMessage) { + const QString error = QString::fromLocal8Bit(errorText).remove(QLatin1Char('\r')); + *errorMessage = tr("Unable to obtain the status: %1").arg(error); + } + return StatusFailed; + } + // Unchanged? + if (outputText.contains("nothing to commit")) + return StatusUnchanged; + return StatusChanged; +} + /* Parse a git status file list: * \code # Changes to be committed: @@ -482,6 +517,9 @@ bool GitClient::getCommitData(const QString &workingDirectory, CommitData *d, QString *errorMessage) { + if (Git::Constants::debug) + qDebug() << Q_FUNC_INFO << workingDirectory; + d->clear(); // Find repo @@ -508,23 +546,15 @@ bool GitClient::getCommitData(const QString &workingDirectory, } // Run status. Note that it has exitcode 1 if there are no added files. - QByteArray outputText; - QByteArray errorText; - QStringList statusArgs(QLatin1String("status")); - if (untrackedFilesInCommit) - statusArgs << QLatin1String("-u"); - const bool statusRc = synchronousGit(workingDirectory, statusArgs, &outputText, &errorText); - if (!statusRc) { - // Something fatal - if (!outputText.contains(kBranchIndicatorC)) { - *errorMessage = tr("Unable to obtain the project status: %1").arg(QString::fromLocal8Bit(errorText)); - return false; - } - // All unchanged - if (outputText.contains("nothing to commit")) { - *errorMessage = tr("There are no modified files."); - return false; - } + QString output; + switch (gitStatus(repoDirectory, untrackedFilesInCommit, &output, errorMessage)) { + case StatusChanged: + break; + case StatusUnchanged: + *errorMessage = tr("There are no modified files."); + return false; + case StatusFailed: + return false; } // Output looks like: @@ -545,7 +575,7 @@ bool GitClient::getCommitData(const QString &workingDirectory, // # // # list of files... - const QStringList lines = QString::fromLocal8Bit(outputText).remove(QLatin1Char('\r')).split(QLatin1Char('\n')); + const QStringList lines = output.split(QLatin1Char('\n')); if (!parseFiles(lines, d)) { *errorMessage = tr("Unable to parse the file output."); return false; @@ -570,24 +600,24 @@ bool GitClient::getCommitData(const QString &workingDirectory, } // addAndCommit: -bool GitClient::addAndCommit(const QString &workingDirectory, +bool GitClient::addAndCommit(const QString &repositoryDirectory, const GitSubmitEditorPanelData &data, const QString &messageFile, const QStringList &checkedFiles, const QStringList &origCommitFiles) { if (Git::Constants::debug) - qDebug() << "GitClient::addAndCommit:" << workingDirectory << checkedFiles << origCommitFiles; + qDebug() << "GitClient::addAndCommit:" << repositoryDirectory << checkedFiles << origCommitFiles; // Do we need to reset any files that had been added before // (did the user uncheck any previously added files) const QSet<QString> resetFiles = origCommitFiles.toSet().subtract(checkedFiles.toSet()); if (!resetFiles.empty()) - if (!synchronousReset(workingDirectory, resetFiles.toList())) + if (!synchronousReset(repositoryDirectory, resetFiles.toList())) return false; // Re-add all to make sure we have the latest changes - if (!synchronousAdd(workingDirectory, checkedFiles)) + if (!synchronousAdd(repositoryDirectory, checkedFiles)) return false; // Do the final commit @@ -598,24 +628,64 @@ bool GitClient::addAndCommit(const QString &workingDirectory, QByteArray outputText; QByteArray errorText; - const bool rc = synchronousGit(workingDirectory, args, &outputText, &errorText); + const bool rc = synchronousGit(repositoryDirectory, args, &outputText, &errorText); const QString message = rc ? - tr("Committed %n file(s).", 0, checkedFiles.size()) : - tr("Unable to commit %n file(s): %1", 0, checkedFiles.size()).arg(QString::fromLocal8Bit(errorText)); + tr("Committed %n file(s).\n", 0, checkedFiles.size()) : + tr("Unable to commit %n file(s): %1\n", 0, checkedFiles.size()).arg(QString::fromLocal8Bit(errorText)); - m_plugin->m_outputWindow->append(message); - m_plugin->m_outputWindow->popup(false); + m_plugin->outputWindow()->append(message); + m_plugin->outputWindow()->popup(false); return rc; } void GitClient::pull(const QString &workingDirectory) { - executeGit(workingDirectory, QStringList(QLatin1String("pull")), m_plugin->m_outputWindow, 0,true); + executeGit(workingDirectory, QStringList(QLatin1String("pull")), m_plugin->outputWindow(), 0, true); } void GitClient::push(const QString &workingDirectory) { - executeGit(workingDirectory, QStringList(QLatin1String("push")), m_plugin->m_outputWindow, 0,true); + executeGit(workingDirectory, QStringList(QLatin1String("push")), m_plugin->outputWindow(), 0, true); +} + +void GitClient::stash(const QString &workingDirectory) +{ + // Check for changes and stash + QString errorMessage; + switch (gitStatus(workingDirectory, false, 0, &errorMessage)) { + case StatusChanged: + 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()->popup(); + break; + case StatusFailed: + m_plugin->outputWindow()->append(errorMessage); + m_plugin->outputWindow()->popup(); + break; + } +} + +void GitClient::stashPop(const QString &workingDirectory) +{ + QStringList arguments(QLatin1String("stash")); + arguments << QLatin1String("pop"); + executeGit(workingDirectory, arguments, m_plugin->outputWindow(), 0, true); +} + +void GitClient::branchList(const QString &workingDirectory) +{ + QStringList arguments(QLatin1String("branch")); + arguments << QLatin1String("-r"); + executeGit(workingDirectory, arguments, m_plugin->outputWindow(), 0, true); +} + +void GitClient::stashList(const QString &workingDirectory) +{ + QStringList arguments(QLatin1String("stash")); + arguments << QLatin1String("list"); + executeGit(workingDirectory, arguments, m_plugin->outputWindow(), 0, true); } QString GitClient::readConfig(const QString &workingDirectory, const QStringList &configVar) @@ -635,6 +705,21 @@ QString GitClient::readConfigValue(const QString &workingDirectory, const QStrin return readConfig(workingDirectory, QStringList(configVar)).remove(QLatin1Char('\n')); } +GitSettings GitClient::settings() const +{ + return m_settings; +} + +void GitClient::setSettings(const GitSettings &s) +{ + if (s != m_settings) { + m_settings = s; + if (QSettings *s = m_core->settings()) + m_settings.toSettings(s); + } +} + +// ------------------------ GitCommand GitCommand::GitCommand() { } diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h index 1a7ebe8c983a8f83dd970e1019b02ca4c2e8286b..5be276a7877f6d1f1fc82149d74fe0f812b74017 100644 --- a/src/plugins/git/gitclient.h +++ b/src/plugins/git/gitclient.h @@ -34,6 +34,8 @@ #ifndef GITCLIENT_H #define GITCLIENT_H +#include "gitsettings.h" + #include <coreplugin/iversioncontrol.h> #include <coreplugin/editormanager/ieditor.h> #include <projectexplorer/environment.h> @@ -62,17 +64,14 @@ class GitCommand; struct CommitData; struct GitSubmitEditorPanelData; -class GitClient : public Core::IVersionControl +class GitClient : public QObject { Q_OBJECT public: - GitClient(GitPlugin *plugin, Core::ICore *core); + explicit GitClient(GitPlugin *plugin, Core::ICore *core); ~GitClient(); - bool vcsOpen(const QString &fileName); - bool vcsAdd(const QString &) { return false; } - bool vcsDelete(const QString &) { return false; } bool managesDirectory(const QString &) const { return false; } QString findTopLevelForDirectory(const QString &) const { return QString(); } @@ -94,6 +93,11 @@ public: void pull(const QString &workingDirectory); void push(const QString &workingDirectory); + void stash(const QString &workingDirectory); + void stashPop(const QString &workingDirectory); + void branchList(const QString &workingDirectory); + void stashList(const QString &workingDirectory); + QString readConfig(const QString &workingDirectory, const QStringList &configVar); QString readConfigValue(const QString &workingDirectory, const QString &configVar); @@ -109,10 +113,19 @@ 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); + VCSBase::VCSBaseEditor *createVCSEditor(const QString &kind, QString title, const QString &source, @@ -135,6 +148,7 @@ private: const QString m_msgWait; GitPlugin *m_plugin; Core::ICore *m_core; + GitSettings m_settings; }; class GitCommand : public QObject diff --git a/src/plugins/git/gitoutputwindow.cpp b/src/plugins/git/gitoutputwindow.cpp index a321449b1e22614c5367d0138e0502ede392a5f8..375be9095973414a65bf715b3c2c38e7a394ffd0 100644 --- a/src/plugins/git/gitoutputwindow.cpp +++ b/src/plugins/git/gitoutputwindow.cpp @@ -104,6 +104,7 @@ void GitOutputWindow::append(const QString &text) const QStringList lines = text.split(QLatin1Char('\n')); foreach (const QString &s, lines) m_outputListWidget->addItem(s); + m_outputListWidget->scrollToBottom(); popup(); } diff --git a/src/plugins/git/gitplugin.cpp b/src/plugins/git/gitplugin.cpp index 6209996edc141052ff75a4571df052fdb3d85144..ef57b9bb12a830b97c6870e2aadb7889a47ff04b 100644 --- a/src/plugins/git/gitplugin.cpp +++ b/src/plugins/git/gitplugin.cpp @@ -33,6 +33,7 @@ #include "gitplugin.h" #include "gitclient.h" +#include "gitversioncontrol.h" #include "giteditor.h" #include "gitconstants.h" #include "changeselectiondialog.h" @@ -125,6 +126,10 @@ GitPlugin::GitPlugin() : m_diffSelectedFilesAction(0), m_undoAction(0), m_redoAction(0), + m_stashAction(0), + m_stashPopAction(0), + m_stashListAction(0), + m_branchListAction(0), m_projectExplorer(0), m_gitClient(0), m_outputWindow(0), @@ -132,6 +137,7 @@ GitPlugin::GitPlugin() : m_settingsPage(0), m_coreListener(0), m_submitEditorFactory(0), + m_versionControl(0), m_changeTmpFile(0) { Q_ASSERT(m_instance == 0); @@ -170,6 +176,12 @@ GitPlugin::~GitPlugin() m_submitEditorFactory = 0; } + if (m_versionControl) { + removeObject(m_versionControl); + delete m_versionControl; + m_versionControl = 0; + } + cleanChangeTmpFile(); delete m_gitClient; m_instance = 0; @@ -198,6 +210,15 @@ static const VCSBase::VCSBaseSubmitEditorParameters submitParameters = { Git::Constants::DIFF_SELECTED }; +static inline Core::ICommand *createSeparator(Core::ActionManagerInterface *am, + const QList<int> &context, + const QString &id, + QObject *parent) +{ + QAction *a = new QAction(parent); + a->setSeparator(true); + return am->registerAction(a, id, context); +} bool GitPlugin::initialize(const QStringList &arguments, QString *error_message) { @@ -235,6 +256,9 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *error_message) m_submitEditorFactory = new GitSubmitEditorFactory(&submitParameters); addObject(m_submitEditorFactory); + m_versionControl = new GitVersionControl(m_gitClient); + addObject(m_versionControl); + //register actions Core::ActionManagerInterface *actionManager = m_core->actionManager(); @@ -245,9 +269,12 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *error_message) actionManager->createMenu(QLatin1String("Git")); gitContainer->menu()->setTitle(tr("&Git")); toolsContainer->addMenu(gitContainer); + if (QAction *ma = gitContainer->menu()->menuAction()) { + ma->setEnabled(m_versionControl->isEnabled()); + connect(m_versionControl, SIGNAL(enabledChanged(bool)), ma, SLOT(setVisible(bool))); + } Core::ICommand *command; - QAction *tmpaction; m_diffAction = new QAction(tr("Diff current file"), this); command = actionManager->registerAction(m_diffAction, "Git.Diff", globalcontext); @@ -291,10 +318,7 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *error_message) connect(m_addAction, SIGNAL(triggered()), this, SLOT(addFile())); gitContainer->addAction(command); - tmpaction = new QAction(this); - tmpaction->setSeparator(true); - command = actionManager->registerAction(tmpaction, QLatin1String("Git.Sep.Project"), globalcontext); - gitContainer->addAction(command); + gitContainer->addAction(createSeparator(actionManager, globalcontext, QLatin1String("Git.Sep.Project"), this)); m_diffProjectAction = new QAction(tr("Diff current project"), this); command = actionManager->registerAction(m_diffProjectAction, "Git.DiffProject", globalcontext); @@ -322,15 +346,26 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *error_message) connect(m_undoProjectAction, SIGNAL(triggered()), this, SLOT(undoProjectChanges())); gitContainer->addAction(command); - tmpaction = new QAction(this); - tmpaction->setSeparator(true); - command = actionManager->registerAction(tmpaction, QLatin1String("Git.Sep.Global"), globalcontext); + gitContainer->addAction(createSeparator(actionManager, globalcontext, QLatin1String("Git.Sep.Global"), this)); + + m_stashAction = new QAction(tr("Stash"), this); + m_stashAction->setToolTip("Saves the current state of your work."); + command = actionManager->registerAction(m_stashAction, "Git.Stash", globalcontext); + command->setAttribute(Core::ICommand::CA_UpdateText); + connect(m_stashAction, SIGNAL(triggered()), this, SLOT(stash())); gitContainer->addAction(command); - m_showAction = new QAction(tr("Show commit..."), this); - command = actionManager->registerAction(m_showAction, "Git.ShowCommit", globalcontext); + m_pullAction = new QAction(tr("Pull"), this); + command = actionManager->registerAction(m_pullAction, "Git.Pull", globalcontext); command->setAttribute(Core::ICommand::CA_UpdateText); - connect(m_showAction, SIGNAL(triggered()), this, SLOT(showCommit())); + connect(m_pullAction, SIGNAL(triggered()), this, SLOT(pull())); + gitContainer->addAction(command); + + m_stashPopAction = new QAction(tr("Stash pop"), this); + m_stashAction->setToolTip("Restores changes saved to the stash list using \"Stash\"."); + command = actionManager->registerAction(m_stashPopAction, "Git.StashPop", globalcontext); + command->setAttribute(Core::ICommand::CA_UpdateText); + connect(m_stashPopAction, SIGNAL(triggered()), this, SLOT(stashPop())); gitContainer->addAction(command); m_commitAction = new QAction(tr("Commit..."), this); @@ -340,24 +375,37 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *error_message) connect(m_commitAction, SIGNAL(triggered()), this, SLOT(startCommit())); gitContainer->addAction(command); - m_pullAction = new QAction(tr("Pull"), this); - command = actionManager->registerAction(m_pullAction, "Git.Pull", globalcontext); - command->setAttribute(Core::ICommand::CA_UpdateText); - connect(m_pullAction, SIGNAL(triggered()), this, SLOT(pull())); - gitContainer->addAction(command); - m_pushAction = new QAction(tr("Push"), this); command = actionManager->registerAction(m_pushAction, "Git.Push", globalcontext); command->setAttribute(Core::ICommand::CA_UpdateText); connect(m_pushAction, SIGNAL(triggered()), this, SLOT(push())); gitContainer->addAction(command); + gitContainer->addAction(createSeparator(actionManager, globalcontext, QLatin1String("Git.Sep.Branch"), this)); + + m_branchListAction = new QAction(tr("List branches"), this); + command = actionManager->registerAction(m_branchListAction, "Git.BranchList", globalcontext); + command->setAttribute(Core::ICommand::CA_UpdateText); + connect(m_branchListAction, SIGNAL(triggered()), this, SLOT(branchList())); + gitContainer->addAction(command); + + m_stashListAction = new QAction(tr("List stashes"), this); + command = actionManager->registerAction(m_stashListAction, "Git.StashList", globalcontext); + command->setAttribute(Core::ICommand::CA_UpdateText); + connect(m_stashListAction, SIGNAL(triggered()), this, SLOT(stashList())); + gitContainer->addAction(command); + + m_showAction = new QAction(tr("Show commit..."), this); + command = actionManager->registerAction(m_showAction, "Git.ShowCommit", globalcontext); + command->setAttribute(Core::ICommand::CA_UpdateText); + connect(m_showAction, SIGNAL(triggered()), this, SLOT(showCommit())); + gitContainer->addAction(command); + // Submit editor QList<int> submitContext; submitContext.push_back(m_core->uniqueIDManager()->uniqueIdentifier(QLatin1String(Constants::C_GITSUBMITEDITOR))); m_submitCurrentAction = new QAction(VCSBase::VCSBaseSubmitEditor::submitIcon(), tr("Commit"), this); command = actionManager->registerAction(m_submitCurrentAction, Constants::SUBMIT_CURRENT, submitContext); - // TODO connect(m_submitCurrentAction, SIGNAL(triggered()), this, SLOT(submitCurrentLog())); m_diffSelectedFilesAction = new QAction(VCSBase::VCSBaseSubmitEditor::diffIcon(), tr("Diff Selected Files"), this); @@ -383,12 +431,6 @@ void GitPlugin::extensionsInitialized() m_projectExplorer = ExtensionSystem::PluginManager::instance()->getObject<ProjectExplorer::ProjectExplorerPlugin>(); } -bool GitPlugin::vcsOpen(const QString &fileName) -{ - Q_UNUSED(fileName); - return false; -} - void GitPlugin::submitEditorDiff(const QStringList &files) { if (files.empty()) @@ -412,7 +454,7 @@ void GitPlugin::diffCurrentProject() m_gitClient->diff(workingDirectory, QString()); } -QFileInfo GitPlugin::currentFile() +QFileInfo GitPlugin::currentFile() const { QString fileName = m_core->fileManager()->currentFile(); QFileInfo fileInfo(fileName); @@ -627,26 +669,52 @@ bool GitPlugin::editorAboutToClose(Core::IEditor *iEditor) void GitPlugin::pull() { - QString workingDirectory = getWorkingDirectory(); - if (workingDirectory.isEmpty()) - return; - m_gitClient->pull(workingDirectory); + const QString workingDirectory = getWorkingDirectory(); + if (!workingDirectory.isEmpty()) + m_gitClient->pull(workingDirectory); } void GitPlugin::push() { - QString workingDirectory = getWorkingDirectory(); - if (workingDirectory.isEmpty()) - return; - m_gitClient->push(workingDirectory); + const QString workingDirectory = getWorkingDirectory(); + if (!workingDirectory.isEmpty()) + m_gitClient->push(workingDirectory); +} + +void GitPlugin::stash() +{ + const QString workingDirectory = getWorkingDirectory(); + if (!workingDirectory.isEmpty()) + m_gitClient->stash(workingDirectory); +} + +void GitPlugin::stashPop() +{ + const QString workingDirectory = getWorkingDirectory(); + if (!workingDirectory.isEmpty()) + m_gitClient->stashPop(workingDirectory); +} + +void GitPlugin::branchList() +{ + const QString workingDirectory = getWorkingDirectory(); + if (!workingDirectory.isEmpty()) + m_gitClient->branchList(workingDirectory); +} + +void GitPlugin::stashList() +{ + const QString workingDirectory = getWorkingDirectory(); + if (!workingDirectory.isEmpty()) + m_gitClient->stashList(workingDirectory); } void GitPlugin::updateActions() { - QFileInfo current = currentFile(); + const QFileInfo current = currentFile(); const QString fileName = current.fileName(); const QString currentDirectory = getWorkingDirectory(); - QString repository = m_gitClient->findRepositoryForFile(current.absoluteFilePath()); + const QString repository = m_gitClient->findRepositoryForFile(current.absoluteFilePath()); // First check for file commands and if the current file is inside // a Git-repository m_diffAction->setText(tr("Diff %1").arg(fileName)); @@ -684,7 +752,7 @@ void GitPlugin::updateActions() if (m_projectExplorer && m_projectExplorer->currentNode() && m_projectExplorer->currentNode()->projectNode()) { - QString name = QFileInfo(m_projectExplorer->currentNode()->projectNode()->path()).baseName(); + const QString name = QFileInfo(m_projectExplorer->currentNode()->projectNode()->path()).baseName(); m_diffProjectAction->setEnabled(true); m_diffProjectAction->setText(tr("Diff Project %1").arg(name)); m_statusProjectAction->setEnabled(true); @@ -720,4 +788,19 @@ void GitPlugin::showCommit() m_gitClient->show(m_changeSelectionDialog->m_ui.repositoryEdit->text(), change); } +GitOutputWindow *GitPlugin::outputWindow() const +{ + return m_outputWindow; +} + +GitSettings GitPlugin::settings() const +{ + return m_gitClient->settings(); +} + +void GitPlugin::setSettings(const GitSettings &s) +{ + m_gitClient->setSettings(s); +} + Q_EXPORT_PLUGIN(GitPlugin) diff --git a/src/plugins/git/gitplugin.h b/src/plugins/git/gitplugin.h index 51846c71d66650bb197b63ae58e0769b62d9289a..3da8ff26cec6c1ad194613864a02f330a7edf7a2 100644 --- a/src/plugins/git/gitplugin.h +++ b/src/plugins/git/gitplugin.h @@ -55,6 +55,7 @@ QT_END_NAMESPACE namespace Core { class IEditorFactory; class ICore; + class IVersionControl; } namespace Git { @@ -65,6 +66,7 @@ namespace Internal { class ChangeSelectionDialog; class GitSubmitEditor; struct CommitData; + struct GitSettings; // Just a proxy for GitPlugin class CoreListener : public Core::ICoreListener @@ -87,14 +89,17 @@ public: ~GitPlugin(); static GitPlugin *instance(); - bool vcsOpen(const QString &fileName); - bool initialize(const QStringList &arguments , QString *error_message); void extensionsInitialized(); QString getWorkingDirectory(); + GitOutputWindow *outputWindow() const; + + GitSettings settings() const; + void setSettings(const GitSettings &s); + public slots: void updateActions(); bool editorAboutToClose(Core::IEditor *editor); @@ -115,12 +120,15 @@ private slots: void showCommit(); void startCommit(); + void stash(); + void stashPop(); + void branchList(); + void stashList(); void pull(); void push(); private: - friend class GitClient; - QFileInfo currentFile(); + QFileInfo currentFile() const; Core::IEditor *openSubmitEditor(const QString &fileName, const CommitData &cd); void cleanChangeTmpFile(); @@ -145,6 +153,10 @@ private: QAction *m_diffSelectedFilesAction; QAction *m_undoAction; QAction *m_redoAction; + QAction *m_stashAction; + QAction *m_stashPopAction; + QAction *m_stashListAction; + QAction *m_branchListAction; ProjectExplorer::ProjectExplorerPlugin *m_projectExplorer; GitClient *m_gitClient; @@ -154,6 +166,7 @@ private: QList<Core::IEditorFactory*> m_editorFactories; CoreListener *m_coreListener; Core::IEditorFactory *m_submitEditorFactory; + Core::IVersionControl *m_versionControl; QString m_submitRepository; QStringList m_submitOrigCommitFiles; QTemporaryFile *m_changeTmpFile; diff --git a/src/plugins/git/gitsettings.cpp b/src/plugins/git/gitsettings.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f4473e1fd92e222539cc2d82d99cff9168873454 --- /dev/null +++ b/src/plugins/git/gitsettings.cpp @@ -0,0 +1,79 @@ +/*************************************************************************** +** +** 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 "gitsettings.h" + +#include <QtCore/QSettings> +#include <QtCore/QTextStream> + +static const char *groupC = "Git"; +static const char *sysEnvKeyC = "SysEnv"; +static const char *pathKeyC = "Path"; +static const char *logCountKeyC = "LogCount"; + +enum { defaultLogCount = 10 }; + +namespace Git { +namespace Internal { + +GitSettings::GitSettings() : + adoptPath(false), + logCount(defaultLogCount) +{ +} + +void GitSettings::fromSettings(QSettings *settings) +{ + settings->beginGroup(QLatin1String(groupC)); + adoptPath = settings->value(QLatin1String(sysEnvKeyC), false).toBool(); + path = settings->value(QLatin1String(pathKeyC), QString()).toString(); + logCount = settings->value(QLatin1String(logCountKeyC), defaultLogCount).toInt(); + settings->endGroup(); +} + +void GitSettings::toSettings(QSettings *settings) const +{ + settings->beginGroup(QLatin1String(groupC)); + settings->setValue(QLatin1String(sysEnvKeyC), adoptPath); + settings->setValue(QLatin1String(pathKeyC), path); + settings->setValue(QLatin1String(logCountKeyC), logCount); + settings->endGroup(); +} + +bool GitSettings::equals(const GitSettings &s) const +{ + return adoptPath == s.adoptPath && path == s.path && logCount == s.logCount; +} + +} +} diff --git a/src/plugins/git/gitsettings.h b/src/plugins/git/gitsettings.h new file mode 100644 index 0000000000000000000000000000000000000000..1b07f4437963f89496af0d75fae7b9439bf3a021 --- /dev/null +++ b/src/plugins/git/gitsettings.h @@ -0,0 +1,69 @@ +/*************************************************************************** +** +** 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 GITSETTINGS_H +#define GITSETTINGS_H + +#include <QtCore/QStringList> + +QT_BEGIN_NAMESPACE +class QSettings; +QT_END_NAMESPACE + +namespace Git { +namespace Internal { + +// Todo: Add user name and password? +struct GitSettings +{ + GitSettings(); + + void fromSettings(QSettings *); + void toSettings(QSettings *) const; + + bool equals(const GitSettings &s) const; + + bool adoptPath; + QString path; + int logCount; +}; + +inline bool operator==(const GitSettings &p1, const GitSettings &p2) + { return p1.equals(p2); } +inline bool operator!=(const GitSettings &p1, const GitSettings &p2) + { return !p1.equals(p2); } + +} // namespace Internal +} // namespace Git + +#endif // GITSETTINGS_H diff --git a/src/plugins/git/settingspage.cpp b/src/plugins/git/settingspage.cpp index 7b0c37284aa1793bd82b7ff74ca58c8715164e4f..e1b14cb9ccc627c31fff00065d560f8f7fa7e31e 100644 --- a/src/plugins/git/settingspage.cpp +++ b/src/plugins/git/settingspage.cpp @@ -32,35 +32,44 @@ ***************************************************************************/ #include "settingspage.h" +#include "gitsettings.h" +#include "gitplugin.h" -#include <coreplugin/icore.h> -#include <extensionsystem/pluginmanager.h> - -#include <QtCore/QSettings> -#include <QtGui/QLineEdit> -#include <QtGui/QFileDialog> #include <QtCore/QDebug> using namespace Git::Internal; -static const char *groupC = "Git"; -static const char *sysEnvKeyC = "SysEnv"; -static const char *pathKeyC = "Path"; -static const char *logCountKeyC = "LogCount"; +SettingsPageWidget::SettingsPageWidget(QWidget *parent) : + QWidget(parent) +{ + m_ui.setupUi(this); + connect(m_ui.adoptButton, SIGNAL(clicked()), this, SLOT(setSystemPath())); +} -SettingsPage::SettingsPage() +GitSettings SettingsPageWidget::settings() const { - Core::ICore *coreIFace = ExtensionSystem::PluginManager::instance()->getObject<Core::ICore>(); - if (coreIFace) - m_settings = coreIFace->settings(); + GitSettings rc; + rc.path = m_ui.pathLineEdit->text(); + rc.adoptPath = m_ui.environmentGroupBox->isChecked() && !rc.path.isEmpty(); + rc.logCount = m_ui.logCountSpinBox->value(); + return rc; +} - if (m_settings) { - m_settings->beginGroup(QLatin1String(groupC)); - m_adopt = m_settings->value(QLatin1String(sysEnvKeyC), true).toBool(); - m_path = m_settings->value(QLatin1String(pathKeyC), QString()).toString(); - m_logCount = m_settings->value(QLatin1String(logCountKeyC), 10).toInt(); - m_settings->endGroup(); - } +void SettingsPageWidget::setSettings(const GitSettings &s) +{ + m_ui.environmentGroupBox->setChecked(s.adoptPath); + m_ui.pathLineEdit->setText(s.path); + m_ui.logCountSpinBox->setValue(s.logCount); +} + +void SettingsPageWidget::setSystemPath() +{ + m_ui.pathLineEdit->setText(QLatin1String(qgetenv("PATH"))); +} + +// -------- SettingsPage +SettingsPage::SettingsPage() +{ } QString SettingsPage::name() const @@ -68,7 +77,7 @@ QString SettingsPage::name() const return tr("General"); } -QString SettingsPage::category() const + QString SettingsPage::category() const { return QLatin1String("Git"); } @@ -80,37 +89,17 @@ QString SettingsPage::trCategory() const QWidget *SettingsPage::createPage(QWidget *parent) { - QWidget *w = new QWidget(parent); - m_ui.setupUi(w); - m_ui.adoptCheckBox->setChecked(m_adopt); - m_ui.pathLineEdit->setText(m_path); - m_ui.logLineEdit->setText(QString::number(m_logCount)); - - connect(m_ui.adoptButton, SIGNAL(clicked()), this, SLOT(setSystemPath())); - return w; + if (!m_widget) + m_widget = new SettingsPageWidget(parent); + m_widget->setSettings(GitPlugin::instance()->settings()); + return m_widget; } void SettingsPage::finished(bool accepted) { - if (!accepted) + if (!accepted || !m_widget) return; - m_adopt = m_ui.adoptCheckBox->isChecked(); - m_path = m_ui.pathLineEdit->text(); - m_logCount = m_ui.logLineEdit->text().toInt(); - - if (!m_settings) - return; - - m_settings->beginGroup(QLatin1String(groupC)); - m_settings->setValue(QLatin1String(sysEnvKeyC), m_adopt); - m_settings->setValue(QLatin1String(pathKeyC), m_path); - m_settings->setValue(QLatin1String(logCountKeyC), m_logCount); - m_settings->endGroup(); + GitPlugin::instance()->setSettings(m_widget->settings()); } -void SettingsPage::setSystemPath() -{ - m_path = qgetenv("PATH"); - m_ui.pathLineEdit->setText(m_path); -} diff --git a/src/plugins/git/settingspage.h b/src/plugins/git/settingspage.h index 95147cf6552e1a1ae50bf0e75218dd3bf678da51..c1f1403c4c909336fcba3b373fbb036e7c897aab 100644 --- a/src/plugins/git/settingspage.h +++ b/src/plugins/git/settingspage.h @@ -35,6 +35,7 @@ #define SETTINGSPAGE_H #include <QtGui/QWidget> +#include <QtCore/QPointer> #include <coreplugin/dialogs/ioptionspage.h> @@ -47,6 +48,23 @@ QT_END_NAMESPACE namespace Git { namespace Internal { +struct GitSettings; + +class SettingsPageWidget : public QWidget { + Q_OBJECT +public: + explicit SettingsPageWidget(QWidget *parent = 0); + + GitSettings settings() const; + void setSettings(const GitSettings &); + +private slots: + void setSystemPath(); + +private: + Ui::SettingsPage m_ui; +}; + class SettingsPage : public Core::IOptionsPage { Q_OBJECT @@ -61,20 +79,8 @@ public: QWidget *createPage(QWidget *parent); void finished(bool accepted); - bool adoptEnvironment() const { return m_adopt; } - int logCount() const { return m_logCount; } - QString path() const { return m_path; } - -private slots: - void setSystemPath(); - private: - Ui_SettingsPage m_ui; - QSettings *m_settings; - - bool m_adopt; - QString m_path; - int m_logCount; + QPointer<SettingsPageWidget> m_widget; }; } // namespace Internal diff --git a/src/plugins/git/settingspage.ui b/src/plugins/git/settingspage.ui index 738413e676f87c3e0405d20baf4a58befa82f780..aa2337605b8bf95f21521e9e0fdb8fb790ace6d8 100644 --- a/src/plugins/git/settingspage.ui +++ b/src/plugins/git/settingspage.ui @@ -6,103 +6,113 @@ <rect> <x>0</x> <y>0</y> - <width>345</width> - <height>177</height> + <width>436</width> + <height>186</height> </rect> </property> <property name="windowTitle"> <string>Form</string> </property> - <layout class="QVBoxLayout" name="verticalLayout"> + <layout class="QHBoxLayout" name="horizontalLayout"> <item> - <widget class="QCheckBox" name="adoptCheckBox"> - <property name="text"> - <string>Use System Environment</string> - </property> - </widget> - </item> - <item> - <widget class="QGroupBox" name="groupBox"> - <property name="enabled"> - <bool>true</bool> - </property> - <property name="title"> - <string>Environment variables</string> - </property> - <property name="checkable"> - <bool>false</bool> - </property> - <layout class="QGridLayout" name="gridLayout"> - <item row="0" column="0"> - <widget class="QLabel" name="label"> - <property name="text"> - <string>PATH:</string> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QLineEdit" name="pathLineEdit"/> - </item> - <item row="0" column="2"> - <widget class="QPushButton" name="adoptButton"> - <property name="text"> - <string>Adopt</string> - </property> - </widget> - </item> - <item row="1" column="0"> - <spacer name="horizontalSpacer"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>52</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item row="1" column="1" colspan="2"> - <widget class="QLabel" name="label_2"> - <property name="text"> - <string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Note</span><span style=" font-size:8pt;"> that Git needs Perl in the environment as well</span></p></body></html></string> - </property> - </widget> - </item> - </layout> - </widget> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout"> + <layout class="QVBoxLayout" name="verticalLayout"> <item> - <widget class="QLabel" name="label_3"> - <property name="text"> - <string>Commit display count:</string> + <widget class="QGroupBox" name="environmentGroupBox"> + <property name="enabled"> + <bool>true</bool> </property> + <property name="title"> + <string>Environment variables</string> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + <layout class="QFormLayout" name="formLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="pathlabel"> + <property name="text"> + <string>PATH:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QLineEdit" name="pathLineEdit"/> + </item> + <item> + <widget class="QPushButton" name="adoptButton"> + <property name="text"> + <string>From system</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="noteLabel"> + <property name="text"> + <string><b>Note:</b></string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLabel" name="noteFieldlabel"> + <property name="text"> + <string>Git needs to find Perl in the environment as well.</string> + </property> + </widget> + </item> + </layout> </widget> </item> <item> - <widget class="QLineEdit" name="logLineEdit"> - <property name="toolTip"> - <string>Note that huge amount of commits might take some time.</string> + <layout class="QFormLayout" name="logFormLayout"> + <property name="fieldGrowthPolicy"> + <enum>QFormLayout::ExpandingFieldsGrow</enum> </property> - </widget> + <item row="0" column="1"> + <widget class="QSpinBox" name="logCountSpinBox"> + <property name="toolTip"> + <string>Note that huge amount of commits might take some time.</string> + </property> + <property name="maximum"> + <number>1000</number> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="logCountLabel"> + <property name="text"> + <string>Log commit display count:</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> </item> </layout> </item> <item> - <spacer> + <spacer name="horizontalSpacer"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> - <width>141</width> + <width>40</width> <height>20</height> </size> </property> @@ -114,22 +124,5 @@ p, li { white-space: pre-wrap; } <tabstop>pathLineEdit</tabstop> </tabstops> <resources/> - <connections> - <connection> - <sender>adoptCheckBox</sender> - <signal>toggled(bool)</signal> - <receiver>groupBox</receiver> - <slot>setDisabled(bool)</slot> - <hints> - <hint type="sourcelabel"> - <x>144</x> - <y>33</y> - </hint> - <hint type="destinationlabel"> - <x>139</x> - <y>65</y> - </hint> - </hints> - </connection> - </connections> + <connections/> </ui> diff --git a/src/plugins/perforce/perforceplugin.cpp b/src/plugins/perforce/perforceplugin.cpp index 7f71282fbbf71df8d7ea6d6bcef2e50c41073ce2..2de31700a867462dba9d8a17017cf8d81e990096 100644 --- a/src/plugins/perforce/perforceplugin.cpp +++ b/src/plugins/perforce/perforceplugin.cpp @@ -235,6 +235,10 @@ bool PerforcePlugin::initialize(const QStringList & /*arguments*/, QString *erro am->createMenu(QLatin1String(PERFORCE_MENU)); mperforce->menu()->setTitle(tr("&Perforce")); mtools->addMenu(mperforce); + if (QAction *ma = mperforce->menu()->menuAction()) { + ma->setEnabled(m_versionControl->isEnabled()); + connect(m_versionControl, SIGNAL(enabledChanged(bool)), ma, SLOT(setVisible(bool))); + } QList<int> globalcontext; globalcontext << Core::Constants::C_GLOBAL_ID; diff --git a/src/plugins/perforce/perforceversioncontrol.cpp b/src/plugins/perforce/perforceversioncontrol.cpp index a51930c1e6daf254994442a27bfd9e25d3007d1e..98379024bc04858b349778ae904133d3b5d62c23 100644 --- a/src/plugins/perforce/perforceversioncontrol.cpp +++ b/src/plugins/perforce/perforceversioncontrol.cpp @@ -38,10 +38,41 @@ namespace Perforce { namespace Internal { PerforceVersionControl::PerforceVersionControl(PerforcePlugin *plugin) : + m_enabled(true), m_plugin(plugin) { } +QString PerforceVersionControl::name() const +{ + return QLatin1String("perforce"); +} + +bool PerforceVersionControl::isEnabled() const +{ + return m_enabled; +} + +void PerforceVersionControl::setEnabled(bool enabled) +{ + if (m_enabled != enabled) { + m_enabled = enabled; + emit enabledChanged(m_enabled); + } +} + +bool PerforceVersionControl::supportsOperation(Operation operation) const +{ + bool rc = true; + switch (operation) { + case AddOperation: + case DeleteOperation: + case OpenOperation: + break; + } + return rc; +} + bool PerforceVersionControl::vcsOpen(const QString &fileName) { return m_plugin->vcsOpen(fileName); diff --git a/src/plugins/perforce/perforceversioncontrol.h b/src/plugins/perforce/perforceversioncontrol.h index d87a7f15ae4ef86de7870d1662d062965d331b95..0e8a1ea6539d6aaaa1465bbca2be2d25ba96cc83 100644 --- a/src/plugins/perforce/perforceversioncontrol.h +++ b/src/plugins/perforce/perforceversioncontrol.h @@ -46,13 +46,25 @@ class PerforceVersionControl : public Core::IVersionControl Q_OBJECT public: explicit PerforceVersionControl(PerforcePlugin *plugin); + + virtual QString name() const; + + virtual bool isEnabled() const; + virtual void setEnabled(bool enabled); + bool managesDirectory(const QString &directory) const; virtual QString findTopLevelForDirectory(const QString &directory) const; + + virtual bool supportsOperation(Operation operation) const; virtual bool vcsOpen(const QString &fileName); virtual bool vcsAdd(const QString &fileName); virtual bool vcsDelete(const QString &filename); +signals: + void enabledChanged(bool); + private: + bool m_enabled; PerforcePlugin *m_plugin; }; diff --git a/src/plugins/projectexplorer/abstractprocessstep.cpp b/src/plugins/projectexplorer/abstractprocessstep.cpp index 09bd73fe7676effdca5524515f2941679b29057a..06b40135c1262da635ecd62f21b5ec24364c7e5f 100644 --- a/src/plugins/projectexplorer/abstractprocessstep.cpp +++ b/src/plugins/projectexplorer/abstractprocessstep.cpp @@ -39,6 +39,7 @@ #include <QtCore/QEventLoop> #include <QtCore/QDebug> #include <QtCore/QTimer> +#include <QtGui/QTextDocument> using namespace ProjectExplorer; @@ -165,7 +166,7 @@ void AbstractProcessStep::run(QFutureInterface<bool> & fi) void AbstractProcessStep::processStarted() { - emit addToOutputWindow(tr("<font color=\"#0000ff\">Starting: %1 %2</font>\n").arg(m_command, m_arguments.join(" "))); + emit addToOutputWindow(tr("<font color=\"#0000ff\">Starting: %1 %2</font>\n").arg(m_command, Qt::escape(m_arguments.join(" ")))); } bool AbstractProcessStep::processFinished(int exitCode, QProcess::ExitStatus status) @@ -196,7 +197,7 @@ void AbstractProcessStep::processReadyReadStdOutput() void AbstractProcessStep::stdOut(const QString &line) { - emit addToOutputWindow(line); + emit addToOutputWindow(Qt::escape(line)); } void AbstractProcessStep::processReadyReadStdError() @@ -211,7 +212,7 @@ void AbstractProcessStep::processReadyReadStdError() void AbstractProcessStep::stdError(const QString &line) { - emit addToOutputWindow(QLatin1String("<font color=\"#ff0000\">") + line + QLatin1String("</font>")); + emit addToOutputWindow(QLatin1String("<font color=\"#ff0000\">") + Qt::escape(line) + QLatin1String("</font>")); } void AbstractProcessStep::checkForCancel() diff --git a/src/plugins/projectexplorer/allprojectsfind.cpp b/src/plugins/projectexplorer/allprojectsfind.cpp index f892f5ff39900c8c98ee67b1660635346d194199..be7d9d96ee452ae48e8c82ac2ef386a8a986e859 100644 --- a/src/plugins/projectexplorer/allprojectsfind.cpp +++ b/src/plugins/projectexplorer/allprojectsfind.cpp @@ -108,12 +108,14 @@ QWidget *AllProjectsFind::createConfigWidget() gridLayout->setMargin(0); m_configWidget->setLayout(gridLayout); gridLayout->addWidget(createRegExpWidget(), 0, 1); - QLabel * const filePatternLabel = new QLabel(tr("File pattern:")); + QLabel * const filePatternLabel = new QLabel(tr("File &pattern:")); filePatternLabel->setMinimumWidth(80); filePatternLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); filePatternLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter); + QWidget *patternWidget = createPatternWidget(); + filePatternLabel->setBuddy(patternWidget); gridLayout->addWidget(filePatternLabel, 1, 0, Qt::AlignRight); - gridLayout->addWidget(createPatternWidget(), 1, 1); + gridLayout->addWidget(patternWidget, 1, 1); m_configWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); } return m_configWidget; diff --git a/src/plugins/projectexplorer/applicationrunconfiguration.cpp b/src/plugins/projectexplorer/applicationrunconfiguration.cpp index ba459d563c1f7338e1f248d207898251d354ad09..30b9a7f7caab9ec98223e647ef13ccd392e9f71b 100644 --- a/src/plugins/projectexplorer/applicationrunconfiguration.cpp +++ b/src/plugins/projectexplorer/applicationrunconfiguration.cpp @@ -38,6 +38,7 @@ #include <projectexplorer/projectexplorerconstants.h> #include <QtGui/QLabel> +#include <QtGui/QTextDocument> #include <QDebug> using namespace ProjectExplorer; @@ -160,7 +161,7 @@ void ApplicationRunControl::slotError(const QString & err) void ApplicationRunControl::slotAddToOutputWindow(const QString &line) { - emit addToOutputWindow(this, line); + emit addToOutputWindow(this, Qt::escape(line)); } void ApplicationRunControl::processExited(int exitCode) diff --git a/src/plugins/projectexplorer/currentprojectfind.cpp b/src/plugins/projectexplorer/currentprojectfind.cpp index 58300f4ca83f7adcb6dcaa5359cc0930f74fe1e4..fb55df3e0fd7a6f1e9710e9cf0884b6ea288111c 100644 --- a/src/plugins/projectexplorer/currentprojectfind.cpp +++ b/src/plugins/projectexplorer/currentprojectfind.cpp @@ -104,12 +104,14 @@ QWidget *CurrentProjectFind::createConfigWidget() layout->setMargin(0); m_configWidget->setLayout(layout); layout->addWidget(createRegExpWidget(), 0, 1); - QLabel * const filePatternLabel = new QLabel(tr("File pattern:")); + QLabel * const filePatternLabel = new QLabel(tr("File &pattern:")); filePatternLabel->setMinimumWidth(80); filePatternLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); filePatternLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter); + QWidget *patternWidget = createPatternWidget(); + filePatternLabel->setBuddy(patternWidget); layout->addWidget(filePatternLabel, 1, 0, Qt::AlignRight); - layout->addWidget(createPatternWidget(), 1, 1); + layout->addWidget(patternWidget, 1, 1); m_configWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); } return m_configWidget; diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 1a9c24b994d3e11fa49d01769068d000309d8e81..b95d5c19463d46a20a554fa4381b49ef178bf661 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -76,6 +76,7 @@ #include <coreplugin/welcomemode.h> #include <coreplugin/vcsmanager.h> #include <coreplugin/iversioncontrol.h> +#include <coreplugin/vcsmanager.h> #include <utils/listutils.h> #include <QtCore/qplugin.h> @@ -1153,6 +1154,13 @@ void ProjectExplorerPlugin::setCurrent(Project *project, QString filePath, Node if (projectChanged) { if (debug) qDebug() << "ProjectExplorer - currentProjectChanged(" << (project ? project->name() : "0") << ")"; + // Enable the right VCS + if (const Core::IFile *projectFile = project ? project->file() : static_cast<const Core::IFile *>(0)) { + m_core->vcsManager()->setVCSEnabled(QFileInfo(projectFile->fileName()).absolutePath()); + } else { + m_core->vcsManager()->setAllVCSEnabled(); + } + emit currentProjectChanged(project); updateActions(); } @@ -1565,27 +1573,28 @@ void ProjectExplorerPlugin::addExistingFiles() fileNames.removeOne(file); } - if (Core::IVersionControl *vcManager = m_core->vcsManager()->findVersionControlForDirectory(dir)) { - const QString files = fileNames.join("\n"); - QMessageBox::StandardButton button = + if (Core::IVersionControl *vcManager = m_core->vcsManager()->findVersionControlForDirectory(dir)) + if (vcManager->supportsOperation(Core::IVersionControl::AddOperation)) { + const QString files = fileNames.join(QString(QLatin1Char('\n'))); + QMessageBox::StandardButton button = QMessageBox::question(m_core->mainWindow(), tr("Add to Version Control"), - tr("Add files\n%1\nto version control?").arg(files), + tr("Add files\n%1\nto version control (%2)?").arg(files, vcManager->name()), QMessageBox::Yes | QMessageBox::No); - if (button == QMessageBox::Yes) { - QStringList notAddedToVc; - foreach (const QString file, fileNames) { - if (!vcManager->vcsAdd(file)) - notAddedToVc << file; - } + if (button == QMessageBox::Yes) { + QStringList notAddedToVc; + foreach (const QString &file, fileNames) { + if (!vcManager->vcsAdd(file)) + notAddedToVc << file; + } - if (!notAddedToVc.isEmpty()) { - const QString message = tr("Could not add following files to version control\n"); - const QString filesNotAdded = notAddedToVc.join("\n"); - QMessageBox::warning(m_core->mainWindow(), tr("Add files to version control failed"), - message + filesNotAdded); + if (!notAddedToVc.isEmpty()) { + const QString message = tr("Could not add following files to version control (%1)\n").arg(vcManager->name()); + const QString filesNotAdded = notAddedToVc.join(QString(QLatin1Char('\n'))); + QMessageBox::warning(m_core->mainWindow(), tr("Add files to version control failed"), + message + filesNotAdded); + } } } - } } void ProjectExplorerPlugin::openFile() diff --git a/src/plugins/projectexplorer/projectfilewizardextension.cpp b/src/plugins/projectexplorer/projectfilewizardextension.cpp index 2cd220ef58e3e9c1eb4cf7b39699871d92098718..7445d4799c7e7a304d421f6ce4545e2bf084eaaf 100644 --- a/src/plugins/projectexplorer/projectfilewizardextension.cpp +++ b/src/plugins/projectexplorer/projectfilewizardextension.cpp @@ -118,7 +118,11 @@ void ProjectFileWizardExtension::firstExtensionPageShown(const QList<Core::Gener m_context->versionControl = m_core->vcsManager()->findVersionControlForDirectory(directory); m_context->page->setFilesDisplay(fileNames); - m_context->page->setAddToVersionControlEnabled(m_context->versionControl != 0); + + const bool canAddToVCS = m_context->versionControl && m_context->versionControl->supportsOperation(Core::IVersionControl::AddOperation); + if (m_context->versionControl) + m_context->page->setVCSDisplay(m_context->versionControl->name()); + m_context->page->setAddToVersionControlEnabled(canAddToVCS); } static ProjectNode *currentProject() diff --git a/src/plugins/projectexplorer/projectwizardpage.cpp b/src/plugins/projectexplorer/projectwizardpage.cpp index 8a2873c336db953bbfc3e2eac0a00938683f5518..8912fbb9e948e02c1c505fd56b8ca699cb8f9aab 100644 --- a/src/plugins/projectexplorer/projectwizardpage.cpp +++ b/src/plugins/projectexplorer/projectwizardpage.cpp @@ -108,6 +108,11 @@ void ProjectWizardPage::changeEvent(QEvent *e) } } +void ProjectWizardPage::setVCSDisplay(const QString &vcsName) +{ + m_ui->addToVersionControlLabel->setText(tr("Add to &VCS (%1)").arg(vcsName)); +} + void ProjectWizardPage::setFilesDisplay(const QStringList &files) { QString fileMessage; { diff --git a/src/plugins/projectexplorer/projectwizardpage.h b/src/plugins/projectexplorer/projectwizardpage.h index 2031923d37c8a3c7adf4404c321f931f7e490463..bc86bb6fa7eccc52ca0af34bf910a78077a29f2a 100644 --- a/src/plugins/projectexplorer/projectwizardpage.h +++ b/src/plugins/projectexplorer/projectwizardpage.h @@ -69,6 +69,7 @@ public: bool addToVersionControl() const; void setAddToVersionControlEnabled(bool b); + void setVCSDisplay(const QString &vcsName); void setFilesDisplay(const QStringList &files); protected: diff --git a/src/plugins/projectexplorer/taskwindow.cpp b/src/plugins/projectexplorer/taskwindow.cpp index b69d37541ee4d54865089981e68abb3ced71d249..309e8ab983693116aff611f19822792519565785 100644 --- a/src/plugins/projectexplorer/taskwindow.cpp +++ b/src/plugins/projectexplorer/taskwindow.cpp @@ -37,6 +37,7 @@ #include <coreplugin/actionmanager/actionmanager.h> #include <coreplugin/editormanager/editormanager.h> #include <coreplugin/coreconstants.h> +#include <coreplugin/uniqueidmanager.h> #include <texteditor/itexteditor.h> #include <texteditor/basetexteditor.h> #include <projectexplorerconstants.h> @@ -47,6 +48,8 @@ #include <QtGui/QListView> #include <QtGui/QPainter> #include <QtCore/QAbstractItemModel> +#include <QtGui/QApplication> +#include <QtGui/QClipboard> #include <QtGui/QFont> #include <QtGui/QFontMetrics> #include <QtGui/QTextLayout> @@ -81,7 +84,7 @@ public: QModelIndex firstError() const; void setFileNotFound(const QModelIndex &index, bool b); - enum Roles { File = Qt::UserRole, Line, Description, FileNotFound }; + enum Roles { File = Qt::UserRole, Line, Description, FileNotFound, Type }; private: QList<TaskItem> m_items; int m_maxSizeOfFileName; @@ -196,6 +199,8 @@ QVariant TaskModel::data(const QModelIndex &index, int role) const return m_items.at(index.row()).description; else if (role == TaskModel::FileNotFound) return m_items.at(index.row()).fileNotFound; + else if (role == TaskModel::Type) + return (int)m_items.at(index.row()).type; else if (role == Qt::DecorationRole) { if (m_items.at(index.row()).type == ProjectExplorer::BuildParserInterface::Error) { return QIcon(":/projectexplorer/images/compile_error.png"); @@ -257,6 +262,15 @@ TaskWindow::TaskWindow() TaskDelegate *tld = new TaskDelegate(this); m_listview->setItemDelegate(tld); m_listview->setWindowIcon(QIcon(":/qt4projectmanager/images/window.png")); + m_listview->setContextMenuPolicy(Qt::ActionsContextMenu); + + m_taskWindowContext = new TaskWindowContext(m_listview); + m_coreIFace->addContextObject(m_taskWindowContext); + + m_copyAction = new QAction(QIcon(Core::Constants::ICON_COPY), tr("&Copy"), this); + m_coreIFace->actionManager()-> + registerAction(m_copyAction, Core::Constants::COPY, m_taskWindowContext->context()); + m_listview->addAction(m_copyAction); connect(m_listview->selectionModel(), SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)), tld, SLOT(currentChanged(const QModelIndex &, const QModelIndex &))); @@ -266,12 +280,15 @@ TaskWindow::TaskWindow() connect(m_listview, SIGNAL(clicked(const QModelIndex &)), this, SLOT(showTaskInFile(const QModelIndex &))); + connect(m_copyAction, SIGNAL(triggered()), SLOT(copy())); + m_errorCount = 0; m_currentTask = -1; } TaskWindow::~TaskWindow() { + m_coreIFace->removeContextObject(m_taskWindowContext); delete m_listview; delete m_model; } @@ -291,6 +308,7 @@ void TaskWindow::clearContents() m_errorCount = 0; m_currentTask = -1; m_model->clear(); + m_copyAction->setEnabled(false); emit tasksChanged(); } @@ -305,6 +323,7 @@ void TaskWindow::addItem(ProjectExplorer::BuildParserInterface::PatternType type m_model->addTask(type, description, file, line); if (type == ProjectExplorer::BuildParserInterface::Error) ++m_errorCount; + m_copyAction->setEnabled(true); emit tasksChanged(); } @@ -327,6 +346,25 @@ void TaskWindow::showTaskInFile(const QModelIndex &index) m_listview->selectionModel()->select(index, QItemSelectionModel::ClearAndSelect); } +void TaskWindow::copy() +{ + QModelIndex index = m_listview->selectionModel()->currentIndex(); + QString file = index.data(TaskModel::File).toString(); + QString line = index.data(TaskModel::Line).toString(); + QString description = index.data(TaskModel::Description).toString(); + QString type; + switch (index.data(TaskModel::Type).toInt()) { + case ProjectExplorer::BuildParserInterface::Error: + type = "error: "; + break; + case ProjectExplorer::BuildParserInterface::Warning: + type = "warning: "; + break; + } + + QApplication::clipboard()->setText(file + ':' + line + ": " + type + description); +} + int TaskWindow::numberOfTasks() const { return m_model->rowCount(QModelIndex()); @@ -483,7 +521,7 @@ void TaskDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, painter->fillRect(width, 2 + opt.rect.top(), gwidth, fm.height() + 1, lg); } } else { - // Descritption + // Description QString description = index.data(TaskModel::Description).toString(); // Layout the description int leading = fm.leading(); @@ -536,3 +574,21 @@ void TaskDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, painter->drawLine(0, opt.rect.bottom(), opt.rect.right(), opt.rect.bottom()); painter->restore(); } + +TaskWindowContext::TaskWindowContext(QWidget *widget) + : m_taskList(widget) +{ + Core::ICore *core = ExtensionSystem::PluginManager::instance()->getObject<Core::ICore>(); + m_context << core->uniqueIDManager()->uniqueIdentifier(Core::Constants::C_PROBLEM_PANE); +} + +QList<int> TaskWindowContext::context() const +{ + return m_context; +} + +QWidget *TaskWindowContext::widget() +{ + return m_taskList; +} + diff --git a/src/plugins/projectexplorer/taskwindow.h b/src/plugins/projectexplorer/taskwindow.h index efd2752469e24ad2a0af89b4103382a4e23d9c92..702534115309eb1b95c137dd9c34025faa5f42af 100644 --- a/src/plugins/projectexplorer/taskwindow.h +++ b/src/plugins/projectexplorer/taskwindow.h @@ -37,6 +37,7 @@ #include "buildparserinterface.h" #include <coreplugin/ioutputpane.h> +#include <coreplugin/icontext.h> #include <coreplugin/icore.h> #include <QtGui/QTreeWidget> @@ -49,6 +50,7 @@ namespace Internal { class TaskModel; class TaskView; +class TaskWindowContext; class TaskWindow : public Core::IOutputPane { @@ -82,6 +84,7 @@ signals: private slots: void showTaskInFile(const QModelIndex &index); + void copy(); private: int sizeHintForColumn(int column) const; @@ -92,6 +95,8 @@ private: TaskModel *m_model; TaskView *m_listview; + TaskWindowContext *m_taskWindowContext; + QAction *m_copyAction; }; class TaskView : public QListView @@ -122,6 +127,17 @@ private: void generateGradientPixmap(int width, int height, QColor color, bool selected) const; }; +class TaskWindowContext : public Core::IContext +{ +public: + TaskWindowContext(QWidget *widget); + virtual QList<int> context() const; + virtual QWidget *widget(); +private: + QWidget *m_taskList; + QList<int> m_context; +}; + } //namespace Internal } //namespace ProjectExplorer diff --git a/src/plugins/qt4projectmanager/gccparser.cpp b/src/plugins/qt4projectmanager/gccparser.cpp index de69904ac80d66807e82b6316a839d326b0356d7..a208fc63052dfb4accd20b768ead5ee18aa5cda3 100644 --- a/src/plugins/qt4projectmanager/gccparser.cpp +++ b/src/plugins/qt4projectmanager/gccparser.cpp @@ -40,13 +40,13 @@ using namespace Qt4ProjectManager; GccParser::GccParser() { - m_regExp.setPattern("^([^\\(\\)]+[^\\d]):(\\d+):(\\d+:)*(\\s(warning|error):)?(.+)$"); + m_regExp.setPattern("^([^\\(\\)]+[^\\d]):(\\d+):(\\d+:)*(\\s(warning|error):)?\\s(.+)$"); m_regExp.setMinimal(true); m_regExpIncluded.setPattern("^.*from\\s([^:]+):(\\d+)(,|:)$"); m_regExpIncluded.setMinimal(true); - m_regExpLinker.setPattern("^(\\S+)\\(\\S+\\):(.+)$"); + m_regExpLinker.setPattern("^(\\S+)\\(\\S+\\):\\s(.+)$"); m_regExpLinker.setMinimal(true); //make[4]: Entering directory `/home/kkoehne/dev/ide-explorer/src/plugins/qtscripteditor' diff --git a/src/plugins/qt4projectmanager/qt4nodes.cpp b/src/plugins/qt4projectmanager/qt4nodes.cpp index e67172eb7fb362220584ee4d4153b2757229d8c0..8c4010aac5ea9603646b662d3faed8e80ddba377 100644 --- a/src/plugins/qt4projectmanager/qt4nodes.cpp +++ b/src/plugins/qt4projectmanager/qt4nodes.cpp @@ -265,46 +265,18 @@ bool Qt4PriFileNode::changeIncludes(ProFile *includeFile, const QStringList &pro return false; } - -namespace { - enum ReadOnlyAction { RO_Cancel, RO_OpenSCC, RO_MakeWriteable }; -} - -static ReadOnlyAction promptReadOnly(const QString &fileName, bool hasSCC, QWidget *parent) -{ - QMessageBox msgBox(QMessageBox::Question, QObject::tr("File is Read Only"), - QObject::tr("The file %1 is read only.").arg(fileName), - QMessageBox::Cancel, parent); - - QPushButton *sccButton = 0; - if (hasSCC) - sccButton = msgBox.addButton(QObject::tr("Open with SCC"), QMessageBox::AcceptRole); - QPushButton *makeWritableButton = msgBox.addButton(QObject::tr("Make writable"), QMessageBox::AcceptRole); - if (hasSCC) - msgBox.setDefaultButton(sccButton); - else - msgBox.setDefaultButton(makeWritableButton); - msgBox.exec(); - QAbstractButton *clickedButton = msgBox.clickedButton(); - if (clickedButton == sccButton) - return RO_OpenSCC; - if (clickedButton == makeWritableButton) - return RO_MakeWriteable; - return RO_Cancel; -} - bool Qt4PriFileNode::priFileWritable(const QString &path) { const QString dir = QFileInfo(path).dir().path(); Core::IVersionControl *versionControl = m_core->vcsManager()->findVersionControlForDirectory(dir); - switch (promptReadOnly(path, versionControl != 0, m_core->mainWindow())) { - case RO_OpenSCC: + switch (Core::EditorManager::promptReadOnlyFile(path, versionControl, m_core->mainWindow(), false)) { + case Core::EditorManager::RO_OpenVCS: if (!versionControl->vcsOpen(path)) { QMessageBox::warning(m_core->mainWindow(), tr("Failed!"), tr("Could not open the file for edit with SCC.")); return false; } break; - case RO_MakeWriteable: { + case Core::EditorManager::RO_MakeWriteable: { const bool permsOk = QFile::setPermissions(path, QFile::permissions(path) | QFile::WriteUser); if (!permsOk) { QMessageBox::warning(m_core->mainWindow(), tr("Failed!"), tr("Could not set permissions to writable.")); @@ -312,10 +284,10 @@ bool Qt4PriFileNode::priFileWritable(const QString &path) } break; } - case RO_Cancel: { + case Core::EditorManager::RO_SaveAs: + case Core::EditorManager::RO_Cancel: return false; } - } return true; } @@ -457,7 +429,8 @@ void Qt4PriFileNode::save() if (modifiedFileHandle) fileManager->blockFileChange(modifiedFileHandle); ProWriter pw; - bool ok = pw.write(m_includeFile, m_includeFile->fileName()); + const bool ok = pw.write(m_includeFile, m_includeFile->fileName()); + Q_UNUSED(ok) m_includeFile->setModified(false); m_project->qt4ProjectManager()->notifyChanged(m_includeFile->fileName()); if (modifiedFileHandle) diff --git a/src/plugins/subversion/subversioncontrol.cpp b/src/plugins/subversion/subversioncontrol.cpp index ba2a2f2e8e92dcfa8b5af88c36b308418aa05f32..56ad229954743e3719088985e4eecc15be726919 100644 --- a/src/plugins/subversion/subversioncontrol.cpp +++ b/src/plugins/subversion/subversioncontrol.cpp @@ -38,10 +38,43 @@ using namespace Subversion; using namespace Subversion::Internal; SubversionControl::SubversionControl(SubversionPlugin *plugin) : + m_enabled(true), m_plugin(plugin) { } +QString SubversionControl::name() const +{ + return QLatin1String("subversion"); +} + +bool SubversionControl::isEnabled() const +{ + return m_enabled; +} + +void SubversionControl::setEnabled(bool enabled) +{ + if (m_enabled != enabled) { + m_enabled = enabled; + emit enabledChanged(m_enabled); + } +} + +bool SubversionControl::supportsOperation(Operation operation) const +{ + bool rc = true; + switch (operation) { + case AddOperation: + case DeleteOperation: + break; + case OpenOperation: + rc = false; + break; + } + return rc; +} + bool SubversionControl::vcsOpen(const QString & /* fileName */) { // Open for edit: N/A diff --git a/src/plugins/subversion/subversioncontrol.h b/src/plugins/subversion/subversioncontrol.h index f293852a3a11e4917dd912d1d767ef324ef8afd4..c4a2f8aa79c69d5145438a9182fd6737821e1443 100644 --- a/src/plugins/subversion/subversioncontrol.h +++ b/src/plugins/subversion/subversioncontrol.h @@ -47,13 +47,24 @@ class SubversionControl : public Core::IVersionControl Q_OBJECT public: explicit SubversionControl(SubversionPlugin *plugin); + virtual QString name() const; + + virtual bool isEnabled() const; + virtual void setEnabled(bool enabled); + virtual bool managesDirectory(const QString &directory) const; virtual QString findTopLevelForDirectory(const QString &directory) const; + + virtual bool supportsOperation(Operation operation) const; virtual bool vcsOpen(const QString &fileName); virtual bool vcsAdd(const QString &fileName); virtual bool vcsDelete(const QString &filename); +signals: + void enabledChanged(bool); + private: + bool m_enabled; SubversionPlugin *m_plugin; }; diff --git a/src/plugins/subversion/subversionplugin.cpp b/src/plugins/subversion/subversionplugin.cpp index 6532a9d43357775f8de4e8ba199f447c60039979..a24bb7d3d06bbb0e652143e6a73cc134332f97a1 100644 --- a/src/plugins/subversion/subversionplugin.cpp +++ b/src/plugins/subversion/subversionplugin.cpp @@ -276,6 +276,10 @@ bool SubversionPlugin::initialize(const QStringList & /*arguments*/, QString *er ami->createMenu(QLatin1String(SUBVERSION_MENU)); subversionMenu->menu()->setTitle(tr("&Subversion")); toolsContainer->addMenu(subversionMenu); + if (QAction *ma = subversionMenu->menu()->menuAction()) { + ma->setEnabled(m_versionControl->isEnabled()); + connect(m_versionControl, SIGNAL(enabledChanged(bool)), ma, SLOT(setVisible(bool))); + } QList<int> globalcontext; globalcontext << m_coreInstance->uniqueIDManager()->uniqueIdentifier(C_GLOBAL); diff --git a/src/plugins/texteditor/basefilefind.cpp b/src/plugins/texteditor/basefilefind.cpp index 43606bf205a5cab80cde45f9f9a00f806404ba2d..4811e4e4c18454cc8b4eca3637e49e2092e352a8 100644 --- a/src/plugins/texteditor/basefilefind.cpp +++ b/src/plugins/texteditor/basefilefind.cpp @@ -146,7 +146,7 @@ QWidget *BaseFileFind::createPatternWidget() */ QString filterToolTip = tr("List of comma separated wildcard filters"); /* - QLabel *label = new QLabel(tr("File pattern:")); + QLabel *label = new QLabel(tr("File &pattern:")); label->setToolTip(filterToolTip); */ /* @@ -163,6 +163,7 @@ QWidget *BaseFileFind::createPatternWidget() m_filterCombo->setToolTip(filterToolTip); syncComboWithSettings(m_filterCombo, m_filterSetting); /* + label->setBuddy(m_filterCombo); hlayout->addWidget(m_filterCombo); */ return m_filterCombo; @@ -170,7 +171,7 @@ QWidget *BaseFileFind::createPatternWidget() QWidget *BaseFileFind::createRegExpWidget() { - m_useRegExpCheckBox = new QCheckBox(tr("Use Regular Expressions")); + m_useRegExpCheckBox = new QCheckBox(tr("Use Regular E&xpressions")); m_useRegExpCheckBox->setChecked(m_useRegExp); connect(m_useRegExpCheckBox, SIGNAL(toggled(bool)), this, SLOT(syncRegExpSetting(bool))); return m_useRegExpCheckBox; diff --git a/src/plugins/texteditor/findinfiles.cpp b/src/plugins/texteditor/findinfiles.cpp index 55ecd01e5ad380b7589dabd2c52b86ecbef77b2e..a67dbebe11065c0b7ad2c4e4e8fc5bbd633c8b6b 100644 --- a/src/plugins/texteditor/findinfiles.cpp +++ b/src/plugins/texteditor/findinfiles.cpp @@ -88,7 +88,8 @@ QWidget *FindInFiles::createConfigWidget() m_configWidget->setLayout(gridLayout); gridLayout->addWidget(createRegExpWidget(), 0, 1, 1, 2); - gridLayout->addWidget(new QLabel(tr("Directory:")), 1, 0, Qt::AlignRight); + QLabel *dirLabel = new QLabel(tr("&Directory:")); + gridLayout->addWidget(dirLabel, 1, 0, Qt::AlignRight); m_directory = new QComboBox; m_directory->setEditable(true); m_directory->setMaxCount(30); @@ -98,17 +99,20 @@ QWidget *FindInFiles::createConfigWidget() m_directory->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); m_directory->setModel(&m_directoryStrings); syncComboWithSettings(m_directory, m_directorySetting); + dirLabel->setBuddy(m_directory); gridLayout->addWidget(m_directory, 1, 1); - QPushButton *browseButton = new QPushButton(tr("Browse")); + QPushButton *browseButton = new QPushButton(tr("&Browse")); gridLayout->addWidget(browseButton, 1, 2); connect(browseButton, SIGNAL(clicked()), this, SLOT(openFileBrowser())); - QLabel * const filePatternLabel = new QLabel(tr("File pattern:")); + QLabel * const filePatternLabel = new QLabel(tr("File &pattern:")); filePatternLabel->setMinimumWidth(80); filePatternLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); filePatternLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter); + QWidget *patternWidget = createPatternWidget(); + filePatternLabel->setBuddy(patternWidget); gridLayout->addWidget(filePatternLabel, 2, 0); - gridLayout->addWidget(createPatternWidget(), 2, 1, 1, 2); + gridLayout->addWidget(patternWidget, 2, 1, 1, 2); m_configWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); } return m_configWidget;