diff --git a/doc/qtcreator.qdoc b/doc/qtcreator.qdoc index 0db515fe434..b8d38a60c9a 100644 --- a/doc/qtcreator.qdoc +++ b/doc/qtcreator.qdoc @@ -23,6 +23,8 @@ \o \inlineimage qtcreator.png \o Qt Creator includes a wide range of useful features. Among them are: \list 1 + \o \bold{Smart Code Editor}: The code editor provides syntax + highlighting as well as code completion. \o \bold{Qt4 Project Generating Wizard}: This wizard allows the user to generate a project for a console application, a GUI application, or a C++ library. @@ -48,7 +50,7 @@ \o \l{Creating a Project in Qt Creator} \o \l{Build Settings} \o \l{Writing a Simple Program with Qt Creator} - \o \l{Quick Navigation} + \o \l{Navigating Quickly Around Your Code} \o \l{Debugging with Qt Creator} \o \l{Tips and Tricks} \o \l{Glossary} @@ -64,86 +66,85 @@ \title A Quick Tour Around Qt Creator - The labeled screenshot below shows some of the components of Qt Creator, - in \gui Edit mode. + The labeled screenshot below shows some of the components of Qt Creator, in + \gui Edit mode. \image qtcreator-breakdown.png \section1 The Mode Selectors - When working in Qt Creator, you can be in one of five modes: \bold Project, - \bold Edit, \bold Debug, \bold Help, and \bold Output. + When working in Qt Creator, you can be in one of six modes: \bold Welcome, + \bold Edit, \bold Debug, \bold Projects, \bold Help, and \bold Output. - Mode selectors allow you to quickly switch between tasks: Editing, - browsing the Qt manual, setting up the build environment, etc. You can + Mode selectors allow you to quickly switch between tasks: Editing, browsing + the Qt Creator manual, setting up the build environment, etc. You can activate a mode by either clicking on its mode selector, or using the \l{keyboard-shortcuts}{corresponding shortcut}. Certain actions also trigger a mode change, e.g., \gui{Debug}/\gui{Start Debugging} will switch to the \gui Debug mode. - \list \o \gui{Welcome Mode} - Displays a welcome screen allowing you to quickly - load recent sessions or individual projects. This is the first mode - displayed if Qt Creator is run without command line switches. + load recent sessions or individual projects. This is the mode you will see + if Qt Creator is run without command line switches. - \o \gui{Edit Mode} - You can edit both project and source files here. An - optional sidebar on the left provides different views to navigate between - files. + \o \gui{Edit Mode} - Lets you edit both project and source files. A sidebar + on the left provides different views to navigate between files. \o \gui{Debug Mode} - Provides various ways to inspect the state of the program while debugging. See \l{qtcreator-debugging}{Debugging With Qt - Creator} for a hands-on description of the mode. + Creator} for a hands-on description of how to use this mode. - \o \gui{Build & Run Mode} - Lets you configure how projects can be built - and executed. Under the list of projects, there are tabs to configure the - build and run settings. + \o \gui{Projects Mode} - Lets you configure how projects can be built and + executed. Under the list of projects, there are tabs to configure the + build, run, and editor settings. \o \gui{Help Mode} - Shows any documentation registered by Qt Assistant, such as the Qt library and Qt Creator documentation. - \o \gui{Output Mode} - Lets you examine various logs in detail, for example - the task list, the compiler and application output. Some of these logs can - also be viewed in the output panes. + \o \gui{Output Mode} - Lets you examine various data in detail, for example + build issues as well as compile and application output. This information + is also available in the output panes. \endlist \section1 The Output Panes - The task pane in Qt Creator can display one out of four different panes: - Task List, Search Results, Application Output, and Compile Output. These - panes are available in all modes. + The task pane in Qt Creator can display one of four different panes: + \gui{Build Issues}, \gui{Search Results}, \gui{Application Output}, and + \gui{Compile}. These panes are available in all modes. - \section2 Task List + \section2 Build Issues - The Task List provides a list of important tasks such as error messages - that need to be fixed. It filters out irrelevant output from the compiler - and collects them in the form of tasks. + The {Build Issues} pane provides a list of issues, e.g., error messages or + warnings that need to be fixed. It filters out irrelevant output from the + compiler and collects them in an organized way. - \image qtcreator-task-list.png + \image qtcreator-build-issues.png \section2 Search Results - The Search Results pane displays the results for global searches such as - searching within a current document, files on disk, or all projects. - In the screenshot below, we searched for all occurrences of \c{textfinder} - within the "/TextFinder" folder. + The \gui{Search Results} pane displays the results for global searches such + as searching within a current document, files on disk, or all projects. In + the screenshot below, we searched for all occurrences of \c{textfinder} + within the \c{"/TextFinder"} folder. \image qtcreator-search-pane.png \section2 Application Output - This pane displays the status of the program when it is executed, as - well as debug output, for example, output from qDebug(). + The \gui{Application Output} pane displays the status of the program when + it is executed and debug output, e.g., output from qDebug(). \image qtcreator-application-output.png - \section2 Compile Output + \section2 Compile - The Compile Output provides all the output from the compiler. In other - words, it is a more verbose version of the Task List. + The \gui{Compile} pane provides all the output from the compiler. In other + words, it is a more verbose version of information displayed in the + \gui{Build Issues} \image qtcreator-compile-pane.png @@ -521,7 +522,7 @@ \page creator-navigation.html \nextpage creator-debugging.html - \title Quick Navigation + \title Navigating Quickly Around Your Code With Qt Creator, navigating to different locations in your project or on your disk, such as files, classes and methods, is trivial using the input diff --git a/src/app/main.cpp b/src/app/main.cpp index ad61ab0c750..eedc9e13653 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -69,7 +69,7 @@ static const char *HELP_OPTION4 = "--help"; static const char *VERSION_OPTION = "-version"; static const char *CLIENT_OPTION = "-client"; -typedef QSet PluginSpecSet; +typedef QList PluginSpecSet; // Helpers for displaying messages. Note that there is no console on Windows. #ifdef Q_WS_WIN diff --git a/src/libs/cplusplus/CppDocument.cpp b/src/libs/cplusplus/CppDocument.cpp index e67214f63b8..d670e7e0018 100644 --- a/src/libs/cplusplus/CppDocument.cpp +++ b/src/libs/cplusplus/CppDocument.cpp @@ -131,12 +131,16 @@ QString Document::fileName() const QStringList Document::includedFiles() const { - return _includedFiles; + QStringList files; + foreach (const Include &i, _includes) + files.append(i.fileName()); + files.removeDuplicates(); + return files; } -void Document::addIncludeFile(const QString &fileName) +void Document::addIncludeFile(const QString &fileName, unsigned line) { - _includedFiles.append(fileName); + _includes.append(Include(fileName, line)); } void Document::appendMacro(const Macro ¯o) diff --git a/src/libs/cplusplus/CppDocument.h b/src/libs/cplusplus/CppDocument.h index aaca36c18ee..b31f0d2bc64 100644 --- a/src/libs/cplusplus/CppDocument.h +++ b/src/libs/cplusplus/CppDocument.h @@ -65,7 +65,7 @@ public: QString fileName() const; QStringList includedFiles() const; - void addIncludeFile(const QString &fileName); + void addIncludeFile(const QString &fileName, unsigned line); void appendMacro(const Macro ¯o); void addMacroUse(const Macro ¯o, unsigned offset, unsigned length); @@ -181,6 +181,22 @@ public: { return pos >= _begin && pos < _end; } }; + class Include { + QString _fileName; + unsigned _line; + + public: + Include(const QString &fileName, unsigned line) + : _fileName(fileName), _line(line) + { } + + QString fileName() const + { return _fileName; } + + unsigned line() const + { return _line; } + }; + class MacroUse: public Block { Macro _macro; @@ -196,6 +212,9 @@ public: { return _macro; } }; + QList includes() const + { return _includes; } + QList skippedBlocks() const { return _skippedBlocks; } @@ -207,11 +226,11 @@ private: private: QString _fileName; - QStringList _includedFiles; Control *_control; TranslationUnit *_translationUnit; Namespace *_globalNamespace; QList _diagnosticMessages; + QList _includes; QList _definedMacros; QList _skippedBlocks; QList _macroUses; diff --git a/src/libs/cplusplus/TypeOfExpression.cpp b/src/libs/cplusplus/TypeOfExpression.cpp index 487c9f8a469..53fa7e78396 100644 --- a/src/libs/cplusplus/TypeOfExpression.cpp +++ b/src/libs/cplusplus/TypeOfExpression.cpp @@ -37,6 +37,7 @@ #include #include #include +#include using namespace CPlusPlus; @@ -53,9 +54,13 @@ void TypeOfExpression::setDocuments(const QMap &document QList TypeOfExpression::operator()(const QString &expression, Document::Ptr document, - Symbol *lastVisibleSymbol) + Symbol *lastVisibleSymbol, + PreprocessMode mode) { - Document::Ptr expressionDoc = documentForExpression(expression); + QString code = expression; + if (mode == Preprocess) + code = preprocessedExpression(expression, m_documents, document); + Document::Ptr expressionDoc = documentForExpression(code); m_ast = extractExpressionAST(expressionDoc); m_lookupContext = LookupContext(lastVisibleSymbol, expressionDoc, @@ -97,3 +102,34 @@ Document::Ptr TypeOfExpression::documentForExpression(const QString &expression) doc->parse(Document::ParseExpression); return doc; } + +void TypeOfExpression::processEnvironment(QMap documents, + Document::Ptr doc, Environment *env, + QSet *processed) const +{ + if (processed->contains(doc->fileName())) + return; + processed->insert(doc->fileName()); + foreach (const Document::Include &incl, doc->includes()) { + processEnvironment(documents, + documents.value(incl.fileName()), + env, processed); + } + foreach (const Macro ¯o, doc->definedMacros()) + env->bind(macro); +} + +QString TypeOfExpression::preprocessedExpression(const QString &expression, + QMap documents, + Document::Ptr thisDocument) const +{ + Environment env; + QSet processed; + processEnvironment(documents, thisDocument, + &env, &processed); + const QByteArray code = expression.toUtf8(); + pp preproc(0, env); + QByteArray preprocessedCode; + preproc("", code, &preprocessedCode); + return QString::fromUtf8(preprocessedCode); +} diff --git a/src/libs/cplusplus/TypeOfExpression.h b/src/libs/cplusplus/TypeOfExpression.h index cd7a23441fd..e6a9a7f4b66 100644 --- a/src/libs/cplusplus/TypeOfExpression.h +++ b/src/libs/cplusplus/TypeOfExpression.h @@ -43,6 +43,9 @@ namespace CPlusPlus { +class Environment; +class Macro; + class CPLUSPLUS_EXPORT TypeOfExpression { public: @@ -60,6 +63,11 @@ public: */ void setDocuments(const QMap &documents); + enum PreprocessMode { + NoPreprocess, + Preprocess + }; + /** * Returns a list of possible fully specified types associated with the * given expression. @@ -73,7 +81,8 @@ public: * @param lastVisibleSymbol The last visible symbol in the document. */ QList operator()(const QString &expression, Document::Ptr document, - Symbol *lastVisibleSymbol); + Symbol *lastVisibleSymbol, + PreprocessMode mode = NoPreprocess); /** * Returns the AST of the last evaluated expression. @@ -91,6 +100,14 @@ private: ExpressionAST *extractExpressionAST(Document::Ptr doc) const; Document::Ptr documentForExpression(const QString &expression) const; + void processEnvironment(QMap documents, + CPlusPlus::Document::Ptr doc, CPlusPlus::Environment *env, + QSet *processed) const; + + QString preprocessedExpression(const QString &expression, + QMap documents, + CPlusPlus::Document::Ptr thisDocument) const; + QMap m_documents; ExpressionAST *m_ast; LookupContext m_lookupContext; diff --git a/src/libs/cplusplus/pp-client.h b/src/libs/cplusplus/pp-client.h index 2fc781f22f5..eead5bf4600 100644 --- a/src/libs/cplusplus/pp-client.h +++ b/src/libs/cplusplus/pp-client.h @@ -63,7 +63,8 @@ public: { } virtual void macroAdded(const Macro ¯o) = 0; - virtual void sourceNeeded(QString &fileName, IncludeType mode) = 0; // ### FIX the signature. + virtual void sourceNeeded(QString &fileName, IncludeType mode, + unsigned line) = 0; // ### FIX the signature. virtual void startExpandingMacro(unsigned offset, const Macro ¯o, diff --git a/src/libs/cplusplus/pp-engine.cpp b/src/libs/cplusplus/pp-engine.cpp index 83386e8079c..c33fc8cb151 100644 --- a/src/libs/cplusplus/pp-engine.cpp +++ b/src/libs/cplusplus/pp-engine.cpp @@ -818,7 +818,7 @@ void pp::processInclude(bool skipCurentPath, QString fn = QString::fromUtf8(path.constData(), path.length()); if (client) - client->sourceNeeded(fn, Client::IncludeGlobal); + client->sourceNeeded(fn, Client::IncludeGlobal, firstToken->lineno); } else if (tk->is(T_ANGLE_STRING_LITERAL) || tk->is(T_STRING_LITERAL)) { const QByteArray spell = tokenSpell(*tk); const char *beginOfPath = spell.constBegin(); @@ -831,7 +831,7 @@ void pp::processInclude(bool skipCurentPath, QString fn = QString::fromUtf8(path.constData(), path.length()); if (client) - client->sourceNeeded(fn, Client::IncludeLocal); + client->sourceNeeded(fn, Client::IncludeLocal, firstToken->lineno); } } } diff --git a/src/libs/extensionsystem/optionsparser.cpp b/src/libs/extensionsystem/optionsparser.cpp index 8884cb378ce..09dbaa59b72 100644 --- a/src/libs/extensionsystem/optionsparser.cpp +++ b/src/libs/extensionsystem/optionsparser.cpp @@ -129,7 +129,7 @@ bool OptionsParser::checkForNoLoadOption() "The plugin '%1' does not exist.").arg(m_currentArg); m_hasError = true; } else { - m_pmPrivate->pluginSpecs.remove(spec); + m_pmPrivate->pluginSpecs.removeAll(spec); delete spec; m_isDependencyRefreshNeeded = true; } diff --git a/src/libs/extensionsystem/pluginmanager.cpp b/src/libs/extensionsystem/pluginmanager.cpp index 3f7ba386e4e..90e6e4bb004 100644 --- a/src/libs/extensionsystem/pluginmanager.cpp +++ b/src/libs/extensionsystem/pluginmanager.cpp @@ -48,7 +48,7 @@ #include #endif -typedef QSet PluginSpecSet; +typedef QList PluginSpecSet; enum { debugLeaks = 0 }; @@ -162,6 +162,11 @@ enum { debugLeaks = 0 }; using namespace ExtensionSystem; using namespace ExtensionSystem::Internal; +static bool lessThanByPluginName(const PluginSpec *one, const PluginSpec *two) +{ + return one->name() < two->name(); +} + PluginManager *PluginManager::m_instance = 0; /*! @@ -306,7 +311,7 @@ QStringList PluginManager::arguments() const } /*! - \fn QSet PluginManager::plugins() const + \fn QList PluginManager::plugins() const List of all plugin specifications that have been found in the plugin search paths. This list is valid directly after the setPluginPaths() call. The plugin specifications contain the information from the plugins' xml description files @@ -315,7 +320,7 @@ QStringList PluginManager::arguments() const \sa setPluginPaths() */ -QSet PluginManager::plugins() const +QList PluginManager::plugins() const { return d->pluginSpecs; } @@ -703,9 +708,11 @@ void PluginManagerPrivate::readPluginPaths() foreach (const QString &specFile, specFiles) { PluginSpec *spec = new PluginSpec; spec->d->read(specFile); - pluginSpecs.insert(spec); + pluginSpecs.append(spec); } resolveDependencies(); + // ensure deterministic plugin load order by sorting + qSort(pluginSpecs.begin(), pluginSpecs.end(), lessThanByPluginName); emit q->pluginsChanged(); } diff --git a/src/libs/extensionsystem/pluginmanager.h b/src/libs/extensionsystem/pluginmanager.h index e46451901e9..e621fbea17f 100644 --- a/src/libs/extensionsystem/pluginmanager.h +++ b/src/libs/extensionsystem/pluginmanager.h @@ -101,7 +101,7 @@ public: void loadPlugins(); QStringList pluginPaths() const; void setPluginPaths(const QStringList &paths); - QSet plugins() const; + QList plugins() const; void setFileExtension(const QString &extension); QString fileExtension() const; diff --git a/src/libs/extensionsystem/pluginmanager_p.h b/src/libs/extensionsystem/pluginmanager_p.h index 74cb84c8678..b286fdf2b1d 100644 --- a/src/libs/extensionsystem/pluginmanager_p.h +++ b/src/libs/extensionsystem/pluginmanager_p.h @@ -66,7 +66,7 @@ public: void loadPlugin(PluginSpec *spec, PluginSpec::State destState); void resolveDependencies(); - QSet pluginSpecs; + QList pluginSpecs; QList testSpecs; QStringList pluginPaths; QString extension; diff --git a/src/libs/extensionsystem/pluginspec.cpp b/src/libs/extensionsystem/pluginspec.cpp index 170cd72ba0b..a8694e29677 100644 --- a/src/libs/extensionsystem/pluginspec.cpp +++ b/src/libs/extensionsystem/pluginspec.cpp @@ -693,10 +693,10 @@ int PluginSpecPrivate::versionCompare(const QString &version1, const QString &ve } /*! - \fn bool PluginSpecPrivate::resolveDependencies(const QSet &specs) + \fn bool PluginSpecPrivate::resolveDependencies(const QList &specs) \internal */ -bool PluginSpecPrivate::resolveDependencies(const QSet &specs) +bool PluginSpecPrivate::resolveDependencies(const QList &specs) { if (hasError) return false; diff --git a/src/libs/extensionsystem/pluginspec_p.h b/src/libs/extensionsystem/pluginspec_p.h index 922fe36d05d..b4fefc59b32 100644 --- a/src/libs/extensionsystem/pluginspec_p.h +++ b/src/libs/extensionsystem/pluginspec_p.h @@ -56,7 +56,7 @@ public: bool read(const QString &fileName); bool provides(const QString &pluginName, const QString &version) const; - bool resolveDependencies(const QSet &specs); + bool resolveDependencies(const QList &specs); bool loadLibrary(); bool initializePlugin(); bool initializeExtensions(); diff --git a/src/plugins/coreplugin/mainwindow.cpp b/src/plugins/coreplugin/mainwindow.cpp index 4eab3fb5571..228c58a94ac 100644 --- a/src/plugins/coreplugin/mainwindow.cpp +++ b/src/plugins/coreplugin/mainwindow.cpp @@ -186,6 +186,15 @@ MainWindow::MainWindow() : QCoreApplication::setOrganizationName(QLatin1String("Nokia")); QSettings::setDefaultFormat(QSettings::IniFormat); QString baseName = qApp->style()->objectName(); + if (baseName == "windows") { + // Sometimes we get the standard windows 95 style as a fallback + // e.g. if we are running on a KDE4 desktop + QByteArray desktopEnvironment = qgetenv("DESKTOP_SESSION"); + if (desktopEnvironment == "kde") + baseName = "plastique"; + else + baseName = "cleanlooks"; + } qApp->setStyle(new ManhattanStyle(baseName)); statusBar()->setProperty("p_styled", true); } diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index 8d4a36178ce..e3bf12757bd 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -480,13 +480,23 @@ void CPPEditor::jumpToDefinition() Document::Ptr doc = m_modelManager->document(file()->fileName()); if (!doc) return; + + QTextCursor tc = textCursor(); + unsigned lineno = tc.blockNumber() + 1; + foreach (const Document::Include &incl, doc->includes()) { + if (incl.line() == lineno) { + if (openCppEditorAt(incl.fileName(), 0, 0)) + return; // done + break; + } + } + Symbol *lastSymbol = doc->findSymbolAt(line, column); if (!lastSymbol) return; // Get the expression under the cursor const int endOfName = endOfNameUnderCursor(); - QTextCursor tc = textCursor(); tc.setPosition(endOfName); ExpressionUnderCursor expressionUnderCursor; const QString expression = expressionUnderCursor(tc); @@ -515,7 +525,7 @@ void CPPEditor::jumpToDefinition() QList candidates = context.resolve(namedType->name()); if (!candidates.isEmpty()) { Symbol *s = candidates.takeFirst(); - openEditorAt(s->fileName(), s->line(), s->column()); + openCppEditorAt(s->fileName(), s->line(), s->column()); } #endif } @@ -524,7 +534,7 @@ void CPPEditor::jumpToDefinition() if (use.contains(endOfName - 1)) { const Macro ¯o = use.macro(); const QString fileName = QString::fromUtf8(macro.fileName); - if (TextEditor::BaseTextEditor::openEditorAt(fileName, macro.line, 0)) + if (openCppEditorAt(fileName, macro.line, 0)) return; // done } } @@ -826,8 +836,15 @@ int CPPEditor::endOfNameUnderCursor() return pos; } +TextEditor::ITextEditor *CPPEditor::openCppEditorAt(const QString &fileName, + int line, int column) +{ + return TextEditor::BaseTextEditor::openEditorAt(fileName, line, column, + Constants::C_CPPEDITOR); +} + bool CPPEditor::openEditorAt(Symbol *s) { const QString fileName = QString::fromUtf8(s->fileName(), s->fileNameLength()); - return TextEditor::BaseTextEditor::openEditorAt(fileName, s->line(), s->column()); + return openCppEditorAt(fileName, s->line(), s->column()); } diff --git a/src/plugins/cppeditor/cppeditor.h b/src/plugins/cppeditor/cppeditor.h index 05f2c5d9c74..2dd88d34993 100644 --- a/src/plugins/cppeditor/cppeditor.h +++ b/src/plugins/cppeditor/cppeditor.h @@ -123,6 +123,9 @@ private: CPlusPlus::Symbol *findDefinition(CPlusPlus::Symbol *symbol); virtual void indentBlock(QTextDocument *doc, QTextBlock block, QChar typedChar); + TextEditor::ITextEditor *openCppEditorAt(const QString &fileName, int line, + int column = 0); + int previousBlockState(QTextBlock block) const; QTextCursor moveToPreviousToken(QTextCursor::MoveMode mode) const; QTextCursor moveToNextToken(QTextCursor::MoveMode mode) const; diff --git a/src/plugins/cpptools/cppcodecompletion.cpp b/src/plugins/cpptools/cppcodecompletion.cpp index 35206c2633b..4606bd948f3 100644 --- a/src/plugins/cpptools/cppcodecompletion.cpp +++ b/src/plugins/cpptools/cppcodecompletion.cpp @@ -439,7 +439,8 @@ int CppCodeCompletion::startCompletion(TextEditor::ITextEditable *editor) typeOfExpression.setDocuments(m_manager->documents()); - QList resolvedTypes = typeOfExpression(expression, thisDocument, symbol); + QList resolvedTypes = typeOfExpression(expression, thisDocument, symbol, + TypeOfExpression::Preprocess); LookupContext context = typeOfExpression.lookupContext(); if (!typeOfExpression.expressionAST() && (! m_completionOperator || diff --git a/src/plugins/cpptools/cpphoverhandler.cpp b/src/plugins/cpptools/cpphoverhandler.cpp index 338123bc5e6..f3831e5394d 100644 --- a/src/plugins/cpptools/cpphoverhandler.cpp +++ b/src/plugins/cpptools/cpphoverhandler.cpp @@ -177,6 +177,16 @@ void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, in } } + if (m_toolTip.isEmpty()) { + unsigned lineno = tc.blockNumber() + 1; + foreach (const Document::Include &incl, doc->includes()) { + if (lineno == incl.line()) { + m_toolTip = incl.fileName(); + break; + } + } + } + if (m_toolTip.isEmpty()) { // Move to the end of a qualified name bool stop = false; diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp index 40888d99f3f..9adc892713d 100644 --- a/src/plugins/cpptools/cppmodelmanager.cpp +++ b/src/plugins/cpptools/cppmodelmanager.cpp @@ -138,7 +138,8 @@ protected: virtual void stopExpandingMacro(unsigned offset, const Macro ¯o); virtual void startSkippingBlocks(unsigned offset); virtual void stopSkippingBlocks(unsigned offset); - virtual void sourceNeeded(QString &fileName, IncludeType type); + virtual void sourceNeeded(QString &fileName, IncludeType type, + unsigned line); private: QPointer m_modelManager; @@ -176,7 +177,7 @@ void CppPreprocessor::setProjectFiles(const QStringList &files) { m_projectFiles = files; } void CppPreprocessor::run(QString &fileName) -{ sourceNeeded(fileName, IncludeGlobal); } +{ sourceNeeded(fileName, IncludeGlobal, /*line = */ 0); } void CppPreprocessor::operator()(QString &fileName) { run(fileName); } @@ -361,7 +362,8 @@ void CppPreprocessor::stopSkippingBlocks(unsigned offset) m_currentDoc->stopSkippingBlocks(offset); } -void CppPreprocessor::sourceNeeded(QString &fileName, IncludeType type) +void CppPreprocessor::sourceNeeded(QString &fileName, IncludeType type, + unsigned line) { if (fileName.isEmpty()) return; @@ -369,7 +371,7 @@ void CppPreprocessor::sourceNeeded(QString &fileName, IncludeType type) QByteArray contents = tryIncludeFile(fileName, type); if (m_currentDoc) { - m_currentDoc->addIncludeFile(fileName); + m_currentDoc->addIncludeFile(fileName, line); if (contents.isEmpty() && ! QFileInfo(fileName).isAbsolute()) { QString msg; msg += fileName; diff --git a/src/plugins/debugger/gdboptionpage.h b/src/plugins/debugger/gdboptionpage.h index 684bd789771..b9da4ea0111 100644 --- a/src/plugins/debugger/gdboptionpage.h +++ b/src/plugins/debugger/gdboptionpage.h @@ -88,7 +88,6 @@ public: void finished(bool accepted); private slots: - void onScriptButton(); void onAddButton(); void onDelButton(); void currentItemChanged(QTreeWidgetItem *item); diff --git a/src/plugins/debugger/gdbtypemacros.cpp b/src/plugins/debugger/gdbtypemacros.cpp index 8610d01e39d..89178af268f 100644 --- a/src/plugins/debugger/gdbtypemacros.cpp +++ b/src/plugins/debugger/gdbtypemacros.cpp @@ -109,6 +109,8 @@ QWidget *TypeMacroPage::createPage(QWidget *parent) m_widget = new QWidget(parent); m_ui.setupUi(m_widget); + m_ui.scriptFile->setPromptDialogTitle(tr("Select Gdb Script")); + m_ui.scriptFile->setExpectedKind(Core::Utils::PathChooser::File); connect(m_ui.addButton, SIGNAL(clicked()), this, SLOT(onAddButton())); @@ -116,8 +118,8 @@ QWidget *TypeMacroPage::createPage(QWidget *parent) connect(m_ui.delButton, SIGNAL(clicked()), this, SLOT(onDelButton())); - connect(m_ui.scriptButton, SIGNAL(clicked()), - this, SLOT(onScriptButton())); + connect(m_ui.scriptFile, SIGNAL(validChanged()), + this, SLOT(updateButtonState())); connect(m_ui.treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), this, SLOT(currentItemChanged(QTreeWidgetItem *))); @@ -139,7 +141,7 @@ QWidget *TypeMacroPage::createPage(QWidget *parent) ++i; } - m_ui.scriptEdit->setText(m_settings->m_scriptFile); + m_ui.scriptFile->setPath(m_settings->m_scriptFile); updateButtonState(); @@ -152,7 +154,7 @@ void TypeMacroPage::finished(bool accepted) return; m_settings->m_typeMacros.clear(); - m_settings->m_scriptFile = m_ui.scriptEdit->text(); + m_settings->m_scriptFile = m_ui.scriptFile->path(); for (int i = 0; i < m_ui.treeWidget->topLevelItemCount(); ++i) { QTreeWidgetItem *item = m_ui.treeWidget->topLevelItem(i); @@ -172,13 +174,6 @@ void TypeMacroPage::finished(bool accepted) } } -void TypeMacroPage::onScriptButton() -{ - QString fileName = QFileDialog::getOpenFileName(m_widget, tr("Select Gdb Script")); - m_ui.scriptEdit->setText(fileName); - updateButtonState(); -} - void TypeMacroPage::onAddButton() { if (m_ui.typeEdit->text().isEmpty() || m_ui.macroEdit->text().isEmpty()) diff --git a/src/plugins/projectexplorer/projectmodels.cpp b/src/plugins/projectexplorer/projectmodels.cpp index e5a2e702650..de4f851e5ce 100644 --- a/src/plugins/projectexplorer/projectmodels.cpp +++ b/src/plugins/projectexplorer/projectmodels.cpp @@ -626,7 +626,7 @@ QList DetailedModel::recursiveSubFolders(FolderNode *parentFolder) FlatModel::FlatModel(SessionNode *rootNode, QObject *parent) : QAbstractItemModel(parent), - m_filterProjects(true), + m_filterProjects(false), m_filterGeneratedFiles(true), m_rootNode(rootNode), m_startupProject(0), @@ -914,6 +914,8 @@ QModelIndex FlatModel::indexForNode(const Node *node_) void FlatModel::setProjectFilterEnabled(bool filter) { + if (filter == m_filterProjects) + return; m_filterProjects = filter; reset(); } diff --git a/src/plugins/projectexplorer/projecttreewidget.cpp b/src/plugins/projectexplorer/projecttreewidget.cpp index 6285bb81dee..c2197a2dc7c 100644 --- a/src/plugins/projectexplorer/projecttreewidget.cpp +++ b/src/plugins/projectexplorer/projecttreewidget.cpp @@ -90,6 +90,20 @@ protected: if (event->reason() != Qt::PopupFocusReason) QTreeView::focusOutEvent(event); } + +#ifdef Q_OS_MAC + void keyPressEvent(QKeyEvent *event) + { + if ((event->key() == Qt::Key_Return + || event->key() == Qt::Key_Enter) + && event->modifiers() == 0 + && currentIndex().isValid()) { + emit activated(currentIndex()); + return; + } + QTreeView::keyPressEvent(event); + } +#endif }; /*! diff --git a/src/plugins/quickopen/filesystemfilter.cpp b/src/plugins/quickopen/filesystemfilter.cpp index 8265f6a07ef..386523ebc43 100644 --- a/src/plugins/quickopen/filesystemfilter.cpp +++ b/src/plugins/quickopen/filesystemfilter.cpp @@ -54,14 +54,7 @@ QList FileSystemFilter::matchesFor(const QString &entry) QString name = entryInfo.fileName(); QString directory = entryInfo.path(); QString filePath = entryInfo.filePath(); - bool isDrive = false; - foreach (const QFileInfo &drive, QDir::drives()) { - if (filePath.startsWith(drive.path())) { - isDrive = true; - break; - } - } - if (!isDrive) { + if (entryInfo.isRelative()) { if (filePath.startsWith("~/")) { directory.replace(0, 1, QDir::homePath()); } else { diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp index db5413c3446..59ee2c005a4 100644 --- a/src/plugins/texteditor/basetexteditor.cpp +++ b/src/plugins/texteditor/basetexteditor.cpp @@ -128,12 +128,13 @@ protected: ITextEditor *BaseTextEditor::openEditorAt(const QString &fileName, int line, - int column) + int column, + const QString &editorKind) { Core::EditorManager *editorManager = ExtensionSystem::PluginManager::instance()->getObject()->editorManager(); editorManager->addCurrentPositionToNavigationHistory(true); - Core::IEditor *editor = editorManager->openEditor(fileName, QString(), true); + Core::IEditor *editor = editorManager->openEditor(fileName, editorKind, true); TextEditor::ITextEditor *texteditor = qobject_cast(editor); if (texteditor) { texteditor->gotoLine(line, column); @@ -684,6 +685,64 @@ void BaseTextEditor::selectBlockDown() _q_matchParentheses(); } +void BaseTextEditor::moveLineUp() +{ + moveLineUpDown(true); +} + +void BaseTextEditor::moveLineDown() +{ + moveLineUpDown(false); +} + +void BaseTextEditor::moveLineUpDown(bool up) +{ + QTextCursor cursor = textCursor(); + QTextCursor move = cursor; + move.beginEditBlock(); + + bool hasSelection = cursor.hasSelection(); + + if (cursor.hasSelection()) { + move.setPosition(cursor.selectionStart()); + move.movePosition(QTextCursor::StartOfBlock); + move.setPosition(cursor.selectionEnd(), QTextCursor::KeepAnchor); + move.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); + } else { + move.movePosition(QTextCursor::StartOfBlock); + move.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); + } + QString text = move.selectedText(); + move.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor); + move.removeSelectedText(); + + if (up) { + move.movePosition(QTextCursor::PreviousBlock); + move.insertBlock(); + move.movePosition(QTextCursor::Left); + } else { + move.movePosition(QTextCursor::EndOfBlock); + if (move.atBlockStart()) { // empty block + move.movePosition(QTextCursor::NextBlock); + move.insertBlock(); + move.movePosition(QTextCursor::Left); + } else { + move.insertBlock(); + } + } + + int start = move.position(); + move.clearSelection(); + move.insertText(text); + int end = move.position(); + move.endEditBlock(); + if (hasSelection) { + move.setPosition(start); + move.setPosition(end, QTextCursor::KeepAnchor); + } + + setTextCursor(move); +} void BaseTextEditor::cleanWhitespace() { @@ -740,9 +799,13 @@ void BaseTextEditor::keyPressEvent(QKeyEvent *e) QTextCursor cursor = textCursor(); if (d->m_inBlockSelectionMode) cursor.clearSelection(); - cursor.insertBlock(); if (d->m_document->tabSettings().m_autoIndent) { + cursor.beginEditBlock(); + cursor.insertBlock(); indent(document(), cursor, QChar::Null); + cursor.endEditBlock(); + } else { + cursor.insertBlock(); } e->accept(); setTextCursor(cursor); @@ -3314,7 +3377,7 @@ void BaseTextEditorPrivate::moveCursorVisible() if (!cursor.block().isVisible()) { cursor.setVisualNavigation(true); cursor.movePosition(QTextCursor::PreviousBlock); - q->setTextCursor(cursor); + q->setTextCursor(cursor); } q->ensureCursorVisible(); } diff --git a/src/plugins/texteditor/basetexteditor.h b/src/plugins/texteditor/basetexteditor.h index 1219439fc98..d75e174fea2 100644 --- a/src/plugins/texteditor/basetexteditor.h +++ b/src/plugins/texteditor/basetexteditor.h @@ -230,7 +230,8 @@ public: BaseTextEditor(QWidget *parent); ~BaseTextEditor(); - static ITextEditor *openEditorAt(const QString &fileName, int line, int column = 0); + static ITextEditor *openEditorAt(const QString &fileName, int line, int column = 0, + const QString &editorKind = QString()); // EditorInterface Core::IFile * file(); @@ -329,6 +330,9 @@ public slots: void selectBlockUp(); void selectBlockDown(); + void moveLineUp(); + void moveLineDown(); + void cleanWhitespace(); signals: @@ -447,6 +451,7 @@ private: void indentOrUnindent(bool doIndent); void handleHomeKey(bool anchor); void handleBackspaceKey(); + void moveLineUpDown(bool up); void toggleBlockVisible(const QTextBlock &block); QRect collapseBox(const QTextBlock &block); diff --git a/src/plugins/texteditor/texteditoractionhandler.cpp b/src/plugins/texteditor/texteditoractionhandler.cpp index 12fc7d1fac5..39a12ee93fd 100644 --- a/src/plugins/texteditor/texteditoractionhandler.cpp +++ b/src/plugins/texteditor/texteditoractionhandler.cpp @@ -71,6 +71,7 @@ TextEditorActionHandler::TextEditorActionHandler(Core::ICore *core, = m_gotoBlockStartAction = m_gotoBlockStartWithSelectionAction = m_gotoBlockEndAction = m_gotoBlockEndWithSelectionAction = m_selectBlockUpAction = m_selectBlockDownAction + = m_moveLineUpAction = m_moveLineDownAction = 0; m_contextId << m_core->uniqueIDManager()->uniqueIdentifier(context); @@ -223,6 +224,16 @@ void TextEditorActionHandler::createActions() command = am->registerAction(m_selectBlockDownAction, Constants::SELECT_BLOCK_DOWN, m_contextId); command->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+U"))); connect(m_selectBlockDownAction, SIGNAL(triggered()), this, SLOT(selectBlockDown())); + + m_moveLineUpAction= new QAction(tr("Move Line Up"), this); + command = am->registerAction(m_moveLineUpAction, Constants::MOVE_LINE_UP, m_contextId); + command->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+Up"))); + connect(m_moveLineUpAction, SIGNAL(triggered()), this, SLOT(moveLineUp())); + + m_moveLineDownAction= new QAction(tr("Move Line Down"), this); + command = am->registerAction(m_moveLineDownAction, Constants::MOVE_LINE_DOWN, m_contextId); + command->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+Down"))); + connect(m_moveLineDownAction, SIGNAL(triggered()), this, SLOT(moveLineDown())); } bool TextEditorActionHandler::supportsAction(const QString & /*id */) const @@ -287,6 +298,8 @@ void TextEditorActionHandler::updateActions(UpdateMode um) m_gotoBlockEndWithSelectionAction->setEnabled(um != NoEditor); m_selectBlockUpAction->setEnabled(um != NoEditor); m_selectBlockDownAction->setEnabled(um != NoEditor); + m_moveLineUpAction->setEnabled(um != NoEditor); + m_moveLineDownAction->setEnabled(um != NoEditor); m_visualizeWhitespaceAction->setEnabled(um != NoEditor); if (m_currentEditor) @@ -390,6 +403,8 @@ FUNCTION(gotoBlockStartWithSelection) FUNCTION(gotoBlockEndWithSelection) FUNCTION(selectBlockUp) FUNCTION(selectBlockDown) +FUNCTION(moveLineUp) +FUNCTION(moveLineDown) void TextEditorActionHandler::updateCurrentEditor(Core::IContext *object) { diff --git a/src/plugins/texteditor/texteditoractionhandler.h b/src/plugins/texteditor/texteditoractionhandler.h index 520ae26ddf6..98e8c9198a9 100644 --- a/src/plugins/texteditor/texteditoractionhandler.h +++ b/src/plugins/texteditor/texteditoractionhandler.h @@ -116,6 +116,8 @@ private slots: void gotoBlockEndWithSelection(); void selectBlockUp(); void selectBlockDown(); + void moveLineUp(); + void moveLineDown(); void updateCurrentEditor(Core::IContext *object); private: @@ -145,6 +147,8 @@ private: QAction *m_gotoBlockEndWithSelectionAction; QAction *m_selectBlockUpAction; QAction *m_selectBlockDownAction; + QAction *m_moveLineUpAction; + QAction *m_moveLineDownAction; uint m_optionalActions; QPointer m_currentEditor; diff --git a/src/plugins/texteditor/texteditorconstants.h b/src/plugins/texteditor/texteditorconstants.h index 192a07c257e..d9147a9a9e9 100644 --- a/src/plugins/texteditor/texteditorconstants.h +++ b/src/plugins/texteditor/texteditorconstants.h @@ -55,6 +55,8 @@ const char * const GOTO_BLOCK_END = "TextEditor.GotoBlockEnd"; const char * const GOTO_BLOCK_END_WITH_SELECTION = "TextEditor.GotoBlockEndWithSelection"; const char * const SELECT_BLOCK_UP = "TextEditor.SelectBlockUp"; const char * const SELECT_BLOCK_DOWN = "TextEditor.SelectBlockDown"; +const char * const MOVE_LINE_UP = "TextEditor.MoveLineUp"; +const char * const MOVE_LINE_DOWN = "TextEditor.MoveLineDown"; const char * const DELETE_LINE = "TextEditor.DeleteLine"; const char * const DELETE_WORD = "TextEditor.DeleteWord"; const char * const SELECT_ENCODING = "TextEditor.SelectEncoding";