diff --git a/doc/images/completion/class.png b/doc/images/completion/class.png new file mode 100644 index 00000000000..88432d2cb10 Binary files /dev/null and b/doc/images/completion/class.png differ diff --git a/doc/images/completion/enum.png b/doc/images/completion/enum.png new file mode 100644 index 00000000000..42a9e83bc76 Binary files /dev/null and b/doc/images/completion/enum.png differ diff --git a/doc/images/completion/enumerator.png b/doc/images/completion/enumerator.png new file mode 100644 index 00000000000..25fc49c6598 Binary files /dev/null and b/doc/images/completion/enumerator.png differ diff --git a/doc/images/completion/func.png b/doc/images/completion/func.png new file mode 100644 index 00000000000..e515e76e61f Binary files /dev/null and b/doc/images/completion/func.png differ diff --git a/doc/images/completion/func_priv.png b/doc/images/completion/func_priv.png new file mode 100644 index 00000000000..49dda7dfea0 Binary files /dev/null and b/doc/images/completion/func_priv.png differ diff --git a/doc/images/completion/func_prot.png b/doc/images/completion/func_prot.png new file mode 100644 index 00000000000..f8add65e073 Binary files /dev/null and b/doc/images/completion/func_prot.png differ diff --git a/doc/images/completion/keyword.png b/doc/images/completion/keyword.png new file mode 100644 index 00000000000..e5a51858d9e Binary files /dev/null and b/doc/images/completion/keyword.png differ diff --git a/doc/images/completion/macro.png b/doc/images/completion/macro.png new file mode 100644 index 00000000000..53e42af63d2 Binary files /dev/null and b/doc/images/completion/macro.png differ diff --git a/doc/images/completion/namespace.png b/doc/images/completion/namespace.png new file mode 100644 index 00000000000..18d2941572e Binary files /dev/null and b/doc/images/completion/namespace.png differ diff --git a/doc/images/completion/signal.png b/doc/images/completion/signal.png new file mode 100644 index 00000000000..a4de5dddfe5 Binary files /dev/null and b/doc/images/completion/signal.png differ diff --git a/doc/images/completion/slot.png b/doc/images/completion/slot.png new file mode 100644 index 00000000000..5534bbfe087 Binary files /dev/null and b/doc/images/completion/slot.png differ diff --git a/doc/images/completion/slot_priv.png b/doc/images/completion/slot_priv.png new file mode 100644 index 00000000000..8f585e875d1 Binary files /dev/null and b/doc/images/completion/slot_priv.png differ diff --git a/doc/images/completion/slot_prot.png b/doc/images/completion/slot_prot.png new file mode 100644 index 00000000000..469e9c18d06 Binary files /dev/null and b/doc/images/completion/slot_prot.png differ diff --git a/doc/images/completion/var.png b/doc/images/completion/var.png new file mode 100644 index 00000000000..089cfb45e5f Binary files /dev/null and b/doc/images/completion/var.png differ diff --git a/doc/images/completion/var_priv.png b/doc/images/completion/var_priv.png new file mode 100644 index 00000000000..8c6cf64fe7b Binary files /dev/null and b/doc/images/completion/var_priv.png differ diff --git a/doc/images/completion/var_prot.png b/doc/images/completion/var_prot.png new file mode 100644 index 00000000000..a7496aada00 Binary files /dev/null and b/doc/images/completion/var_prot.png differ diff --git a/doc/qtcreator.qdoc b/doc/qtcreator.qdoc index 89b22fdb1cf..86067cbbcce 100644 --- a/doc/qtcreator.qdoc +++ b/doc/qtcreator.qdoc @@ -293,6 +293,63 @@ \gui{Edit -> Advanced} menu. \endtable + \section1 Code Completion + + The completion popup shows possible completions to a certain statement. + These completions include classes, namespaces, functions, variables, + macros and keywords. Listed below are the icons used in the completion box + and their meaning. + + \table + \row + \i \inlineimage completion/class.png + \i A class + \row + \i \inlineimage completion/enum.png + \i An enum + \row + \i \inlineimage completion/enumerator.png + \i An enumerator (value of an enum) + \row + \i \inlineimage completion/func.png + \i A function + \row + \i \inlineimage completion/func_priv.png + \i A private function + \row + \i \inlineimage completion/func_prot.png + \i A protected function + \row + \i \inlineimage completion/var.png + \i A variable + \row + \i \inlineimage completion/var_priv.png + \i A private variable + \row + \i \inlineimage completion/var_prot.png + \i A protected variable + \row + \i \inlineimage completion/signal.png + \i A signal + \row + \i \inlineimage completion/slot.png + \i A slot + \row + \i \inlineimage completion/slot_priv.png + \i A private slot + \row + \i \inlineimage completion/slot_prot.png + \i A protected slot + \row + \i \inlineimage completion/keyword.png + \i A keyword + \row + \i \inlineimage completion/macro.png + \i A macro + \row + \i \inlineimage completion/namespace.png + \i A namespace + \endtable */ diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index 3544cf3f2d3..cc28c720e91 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -75,6 +75,7 @@ #include #include #include +#include using namespace CPlusPlus; using namespace CppEditor::Internal; @@ -243,7 +244,22 @@ void CPPEditor::createToolBar(CPPEditorEditable *editable) m_methodCombo->setMaxVisibleItems(20); m_overviewModel = new OverviewModel(this); - m_methodCombo->setModel(m_overviewModel); + m_proxyModel = new QSortFilterProxyModel(this); + m_proxyModel->setSourceModel(m_overviewModel); + if (CppPlugin::instance()->sortedMethodOverview()) + m_proxyModel->sort(0, Qt::AscendingOrder); + else + m_proxyModel->sort(-1, Qt::AscendingOrder); // don't sort yet, but set column for sortedMethodOverview() + m_proxyModel->setDynamicSortFilter(true); + m_proxyModel->setSortCaseSensitivity(Qt::CaseInsensitive); + m_methodCombo->setModel(m_proxyModel); + + m_methodCombo->setContextMenuPolicy(Qt::ActionsContextMenu); + m_sortAction = new QAction(tr("Sort alphabetically"), m_methodCombo); + m_sortAction->setCheckable(true); + m_sortAction->setChecked(sortedMethodOverview()); + connect(m_sortAction, SIGNAL(toggled(bool)), CppPlugin::instance(), SLOT(setSortedMethodOverview(bool))); + m_methodCombo->addAction(m_sortAction); connect(m_methodCombo, SIGNAL(activated(int)), this, SLOT(jumpToMethod(int))); connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(updateMethodBoxIndex())); @@ -366,7 +382,7 @@ void CPPEditor::updateFileName() void CPPEditor::jumpToMethod(int) { - QModelIndex index = m_methodCombo->view()->currentIndex(); + QModelIndex index = m_proxyModel->mapToSource(m_methodCombo->view()->currentIndex()); Symbol *symbol = m_overviewModel->symbolFromIndex(index); if (! symbol) return; @@ -374,6 +390,25 @@ void CPPEditor::jumpToMethod(int) openCppEditorAt(linkToSymbol(symbol)); } +void CPPEditor::setSortedMethodOverview(bool sort) +{ + if (sort != sortedMethodOverview()) { + if (sort) + m_proxyModel->sort(0, Qt::AscendingOrder); + else + m_proxyModel->sort(-1, Qt::AscendingOrder); + bool block = m_sortAction->blockSignals(true); + m_sortAction->setChecked(m_proxyModel->sortColumn() == 0); + m_sortAction->blockSignals(block); + updateMethodBoxIndex(); + } +} + +bool CPPEditor::sortedMethodOverview() const +{ + return (m_proxyModel->sortColumn() == 0); +} + void CPPEditor::updateMethodBoxIndex() { int line = 0, column = 0; @@ -394,7 +429,7 @@ void CPPEditor::updateMethodBoxIndex() if (lastIndex.isValid()) { bool blocked = m_methodCombo->blockSignals(true); - m_methodCombo->setCurrentIndex(lastIndex.row()); + m_methodCombo->setCurrentIndex(m_proxyModel->mapFromSource(lastIndex).row()); updateMethodBoxToolTip(); (void) m_methodCombo->blockSignals(blocked); } diff --git a/src/plugins/cppeditor/cppeditor.h b/src/plugins/cppeditor/cppeditor.h index ae352b8d6d5..efae361e0e6 100644 --- a/src/plugins/cppeditor/cppeditor.h +++ b/src/plugins/cppeditor/cppeditor.h @@ -37,6 +37,7 @@ QT_BEGIN_NAMESPACE class QComboBox; +class QSortFilterProxyModel; QT_END_NAMESPACE namespace CPlusPlus { @@ -86,6 +87,7 @@ public: public slots: virtual void setFontSettings(const TextEditor::FontSettings &); + void setSortedMethodOverview(bool sort); void switchDeclarationDefinition(); void jumpToDefinition(); @@ -94,7 +96,6 @@ public slots: void deleteStartOfToken(); void deleteEndOfToken(); - protected: void contextMenuEvent(QContextMenuEvent *); void mouseMoveEvent(QMouseEvent *); @@ -115,6 +116,7 @@ private slots: void onDocumentUpdated(CPlusPlus::Document::Ptr doc); private: + bool sortedMethodOverview() const; CPlusPlus::Symbol *findDefinition(CPlusPlus::Symbol *symbol); virtual void indentBlock(QTextDocument *doc, QTextBlock block, QChar typedChar); @@ -161,6 +163,8 @@ private: QList m_contexts; QComboBox *m_methodCombo; CPlusPlus::OverviewModel *m_overviewModel; + QSortFilterProxyModel *m_proxyModel; + QAction *m_sortAction; }; } // namespace Internal diff --git a/src/plugins/cppeditor/cppplugin.cpp b/src/plugins/cppeditor/cppplugin.cpp index 29ad6731451..9e17083c219 100644 --- a/src/plugins/cppeditor/cppplugin.cpp +++ b/src/plugins/cppeditor/cppplugin.cpp @@ -106,7 +106,8 @@ CppPlugin *CppPlugin::m_instance = 0; CppPlugin::CppPlugin() : m_actionHandler(0), - m_factory(0) + m_factory(0), + m_sortedMethodOverview(false) { m_instance = this; } @@ -133,6 +134,20 @@ void CppPlugin::initializeEditor(CPPEditor *editor) // auto completion connect(editor, SIGNAL(requestAutoCompletion(ITextEditable*, bool)), TextEditor::Internal::CompletionSupport::instance(), SLOT(autoComplete(ITextEditable*, bool))); + // method combo box sorting + connect(this, SIGNAL(methodOverviewSortingChanged(bool)), + editor, SLOT(setSortedMethodOverview(bool))); +} + +void CppPlugin::setSortedMethodOverview(bool sorted) +{ + m_sortedMethodOverview = sorted; + emit methodOverviewSortingChanged(sorted); +} + +bool CppPlugin::sortedMethodOverview() const +{ + return m_sortedMethodOverview; } bool CppPlugin::initialize(const QStringList & /*arguments*/, QString *errorMessage) @@ -194,14 +209,30 @@ bool CppPlugin::initialize(const QStringList & /*arguments*/, QString *errorMess | TextEditor::TextEditorActionHandler::UnCommentSelection | TextEditor::TextEditorActionHandler::UnCollapseAll); + readSettings(); return true; } +void CppPlugin::readSettings() +{ + m_sortedMethodOverview = Core::ICore::instance()->settings()->value("CppTools/SortedMethodOverview", false).toBool(); +} + +void CppPlugin::writeSettings() +{ + Core::ICore::instance()->settings()->setValue("CppTools/SortedMethodOverview", m_sortedMethodOverview); +} + void CppPlugin::extensionsInitialized() { m_actionHandler->initializeActions(); } +void CppPlugin::shutdown() +{ + writeSettings(); +} + void CppPlugin::switchDeclarationDefinition() { Core::EditorManager *em = Core::EditorManager::instance(); diff --git a/src/plugins/cppeditor/cppplugin.h b/src/plugins/cppeditor/cppplugin.h index 151eda38885..4ad8400342b 100644 --- a/src/plugins/cppeditor/cppplugin.h +++ b/src/plugins/cppeditor/cppplugin.h @@ -58,10 +58,19 @@ public: bool initialize(const QStringList &arguments, QString *error_message = 0); void extensionsInitialized(); + void shutdown(); // Connect editor to settings changed signals. void initializeEditor(CPPEditor *editor); + bool sortedMethodOverview() const; + +signals: + void methodOverviewSortingChanged(bool sort); + +public slots: + void setSortedMethodOverview(bool sorted); + private slots: void switchDeclarationDefinition(); void jumpToDefinition(); @@ -69,11 +78,14 @@ private slots: private: friend class CppEditorFactory; Core::IEditor *createEditor(QWidget *parent); + void writeSettings(); + void readSettings(); static CppPlugin *m_instance; TextEditor::TextEditorActionHandler *m_actionHandler; CppEditorFactory *m_factory; + bool m_sortedMethodOverview; }; class CppEditorFactory : public Core::IEditorFactory diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp index 77d35fcdb52..ada99dc501c 100644 --- a/src/plugins/texteditor/basetexteditor.cpp +++ b/src/plugins/texteditor/basetexteditor.cpp @@ -1513,7 +1513,7 @@ QRect BaseTextEditor::collapseBox() return QRect(); QTextBlock begin = document()->findBlockByNumber(d->m_highlightBlocksInfo.open.last()); - QTextBlock end= document()->findBlockByNumber(d->m_highlightBlocksInfo.close.first()); + QTextBlock end = document()->findBlockByNumber(d->m_highlightBlocksInfo.close.first()); if (!begin.isValid() || !end.isValid()) return QRect(); QRectF br = blockBoundingGeometry(begin).translated(contentOffset()); @@ -2349,7 +2349,11 @@ void BaseTextEditor::extraAreaPaintEvent(QPaintEvent *e) const QString &number = QString::number(blockNumber + 1); if (blockNumber == cursorBlockNumber) { painter.save(); - painter.setPen(pal.color(QPalette::Background).value() < 128 ? Qt::white : Qt::black); + QFont f = painter.font(); + f.setBold(d->m_currentLineNumberFormat.font().bold()); + f.setItalic(d->m_currentLineNumberFormat.font().italic()); + painter.setFont(f); + painter.setPen(d->m_currentLineNumberFormat.foreground().color()); } painter.drawText(markWidth, top, extraAreaWidth - markWidth - 4, fm.height(), Qt::AlignRight, number); if (blockNumber == cursorBlockNumber) @@ -2365,7 +2369,7 @@ void BaseTextEditor::extraAreaPaintEvent(QPaintEvent *e) extraAreaWidth, viewport()->height()); painter.drawLine(extraAreaWidth + collapseBoxWidth - 1, 0, extraAreaWidth + collapseBoxWidth - 1, viewport()->height()); - QRect cb = collapseBox(); +// QRect cb = collapseBox(); // if (!cb.isEmpty()) { // QPen pen(baseColor.value() < 128 ? Qt::white : Qt::black); // pen.setWidth(2); @@ -2428,10 +2432,17 @@ void BaseTextEditor::slotCursorPositionChanged() } else if (d->m_contentsChanged) { saveCurrentCursorPositionForNavigation(); } + + if (d->m_parenthesesMatchingEnabled) { + // Delay update when no matching is displayed yet, to avoid flicker + if (extraSelections(ParenthesesMatchingSelection).isEmpty()) { + d->m_parenthesesMatchingTimer->start(50); + } else { + _q_matchParentheses(); + } + } + QList extraSelections; - setExtraSelections(ParenthesesMatchingSelection, extraSelections); // clear - if (d->m_parenthesesMatchingEnabled) - d->m_parenthesesMatchingTimer->start(50); if (d->m_highlightCurrentLine) { QTextEdit::ExtraSelection sel; @@ -2445,7 +2456,7 @@ void BaseTextEditor::slotCursorPositionChanged() setExtraSelections(CurrentLineSelection, extraSelections); if (d->m_highlightBlocks) { - QTextCursor cursor = textCursor(); + QTextCursor cursor = textCursor(); d->extraAreaHighlightCollapseBlockNumber = cursor.blockNumber(); d->extraAreaHighlightCollapseColumn = cursor.position() - cursor.block().position(); d->m_highlightBlocksTimer->start(100); @@ -3333,11 +3344,13 @@ void BaseTextEditor::_q_matchParentheses() const TextBlockUserData::MatchType backwardMatchType = TextBlockUserData::matchCursorBackward(&backwardMatch); const TextBlockUserData::MatchType forwardMatchType = TextBlockUserData::matchCursorForward(&forwardMatch); - if (backwardMatchType == TextBlockUserData::NoMatch && forwardMatchType == TextBlockUserData::NoMatch) - return; - QList extraSelections; + if (backwardMatchType == TextBlockUserData::NoMatch && forwardMatchType == TextBlockUserData::NoMatch) { + setExtraSelections(ParenthesesMatchingSelection, extraSelections); // clear + return; + } + if (backwardMatch.hasSelection()) { QTextEdit::ExtraSelection sel; if (backwardMatchType == TextBlockUserData::Mismatch) { @@ -3538,10 +3551,11 @@ void BaseTextEditor::setFontSettings(const TextEditor::FontSettings &fs) const QTextCharFormat selectionFormat = fs.toTextCharFormat(QLatin1String(Constants::C_SELECTION)); const QTextCharFormat lineNumberFormat = fs.toTextCharFormat(QLatin1String(Constants::C_LINE_NUMBER)); const QTextCharFormat searchResultFormat = fs.toTextCharFormat(QLatin1String(Constants::C_SEARCH_RESULT)); - const QTextCharFormat searchScopeFormat = fs.toTextCharFormat(QLatin1String(Constants::C_SEARCH_SCOPE)); + d->m_searchScopeFormat = fs.toTextCharFormat(QLatin1String(Constants::C_SEARCH_SCOPE)); const QTextCharFormat parenthesesFormat = fs.toTextCharFormat(QLatin1String(Constants::C_PARENTHESES)); - const QTextCharFormat currentLineFormat = fs.toTextCharFormat(QLatin1String(Constants::C_CURRENT_LINE)); - const QTextCharFormat ifdefedOutFormat = fs.toTextCharFormat(QLatin1String(Constants::C_DISABLED_CODE)); + d->m_currentLineFormat = fs.toTextCharFormat(QLatin1String(Constants::C_CURRENT_LINE)); + d->m_currentLineNumberFormat = fs.toTextCharFormat(QLatin1String(Constants::C_CURRENT_LINE_NUMBER)); + d->m_ifdefedOutFormat = fs.toTextCharFormat(QLatin1String(Constants::C_DISABLED_CODE)); QFont font(textFormat.font()); const QColor foreground = textFormat.foreground().color(); @@ -3569,16 +3583,11 @@ void BaseTextEditor::setFontSettings(const TextEditor::FontSettings &fs) // Search results d->m_searchResultFormat.setBackground(searchResultFormat.background()); - d->m_searchScopeFormat.setBackground(searchScopeFormat.background()); - d->m_currentLineFormat.setBackground(currentLineFormat.background()); // Matching braces d->m_matchFormat.setForeground(parenthesesFormat.foreground()); d->m_rangeFormat.setBackground(parenthesesFormat.background()); - // Disabled code - d->m_ifdefedOutFormat.setForeground(ifdefedOutFormat.foreground()); - slotUpdateExtraAreaWidth(); } diff --git a/src/plugins/texteditor/basetexteditor_p.h b/src/plugins/texteditor/basetexteditor_p.h index 1372087f00d..27baa0851c0 100644 --- a/src/plugins/texteditor/basetexteditor_p.h +++ b/src/plugins/texteditor/basetexteditor_p.h @@ -207,6 +207,7 @@ public: QTextCharFormat m_searchResultFormat; QTextCharFormat m_searchScopeFormat; QTextCharFormat m_currentLineFormat; + QTextCharFormat m_currentLineNumberFormat; void highlightSearchResults(const QTextBlock &block, QVector *selections); diff --git a/src/plugins/texteditor/fontsettingspage.cpp b/src/plugins/texteditor/fontsettingspage.cpp index 8f776f04b00..aec2acb241a 100644 --- a/src/plugins/texteditor/fontsettingspage.cpp +++ b/src/plugins/texteditor/fontsettingspage.cpp @@ -137,9 +137,9 @@ QString FormatDescription::trName() const QColor FormatDescription::foreground() const { - if (m_name == QLatin1String("LineNumber")) + if (m_name == QLatin1String(Constants::C_LINE_NUMBER)) return QApplication::palette().dark().color(); - if (m_name == QLatin1String("Parentheses")) + if (m_name == QLatin1String(Constants::C_PARENTHESES)) return QColor(Qt::red); return m_format.foreground(); } diff --git a/src/plugins/texteditor/texteditorconstants.h b/src/plugins/texteditor/texteditorconstants.h index e598a891148..a8dfac2b5c0 100644 --- a/src/plugins/texteditor/texteditorconstants.h +++ b/src/plugins/texteditor/texteditorconstants.h @@ -72,6 +72,7 @@ const char * const C_SEARCH_RESULT = "SearchResult"; const char * const C_SEARCH_SCOPE = "SearchScope"; const char * const C_PARENTHESES = "Parentheses"; const char * const C_CURRENT_LINE = "CurrentLine"; +const char * const C_CURRENT_LINE_NUMBER = "CurrentLineNumber"; const char * const C_NUMBER = "Number"; const char * const C_STRING = "String"; diff --git a/src/plugins/texteditor/texteditorsettings.cpp b/src/plugins/texteditor/texteditorsettings.cpp index 31204648a1d..ca562d0df18 100644 --- a/src/plugins/texteditor/texteditorsettings.cpp +++ b/src/plugins/texteditor/texteditorsettings.cpp @@ -72,6 +72,7 @@ TextEditorSettings::TextEditorSettings(QObject *parent) formatDescriptions.push_back(FormatDescription(QLatin1String(C_SEARCH_SCOPE), tr("Search Scope"))); formatDescriptions.push_back(FormatDescription(QLatin1String(C_PARENTHESES), tr("Parentheses"))); formatDescriptions.push_back(FormatDescription(QLatin1String(C_CURRENT_LINE), tr("Current Line"))); + formatDescriptions.push_back(FormatDescription(QLatin1String(C_CURRENT_LINE_NUMBER), tr("Current Line Number"), Qt::darkGray)); // Standard categories formatDescriptions.push_back(FormatDescription(QLatin1String(C_NUMBER), tr("Number"), Qt::darkBlue));