From 676739a87af932a472df757250442f2930a5d7e0 Mon Sep 17 00:00:00 2001 From: Hugues Delorme <delorme.hugues@fougsys.fr> Date: Mon, 5 Dec 2011 15:37:19 +0100 Subject: [PATCH] VCS: auto-completion in the description text edit In the description field of the commit editor, class VCSBaseSubmitEditor provides completion of file names and C++ entities (based on QtCreator's internal C++ code model). Change-Id: Ie5323714dbf6f6e635953dfbb35596201d86fc37 Reviewed-by: Tobias Hunger <tobias.hunger@nokia.com> Reviewed-by: Hugues Delorme <delorme.hugues@fougsys.fr> --- src/libs/utils/completingtextedit.cpp | 178 +++++++++++++++++++ src/libs/utils/completingtextedit.h | 68 +++++++ src/libs/utils/submiteditorwidget.cpp | 2 +- src/libs/utils/submiteditorwidget.h | 4 +- src/libs/utils/submiteditorwidget.ui | 9 +- src/libs/utils/utils-lib.pri | 6 +- src/plugins/bazaar/bazaarplugin.cpp | 3 +- src/plugins/bazaar/commiteditor.cpp | 8 +- src/plugins/bazaar/commiteditor.h | 2 +- src/plugins/git/gitsubmiteditor.cpp | 2 +- src/plugins/mercurial/commiteditor.cpp | 2 +- src/plugins/vcsbase/vcsbase_dependencies.pri | 1 + src/plugins/vcsbase/vcsbasesubmiteditor.cpp | 134 +++++++++++++- src/plugins/vcsbase/vcsbasesubmiteditor.h | 2 +- 14 files changed, 405 insertions(+), 16 deletions(-) create mode 100644 src/libs/utils/completingtextedit.cpp create mode 100644 src/libs/utils/completingtextedit.h diff --git a/src/libs/utils/completingtextedit.cpp b/src/libs/utils/completingtextedit.cpp new file mode 100644 index 00000000000..b870995668f --- /dev/null +++ b/src/libs/utils/completingtextedit.cpp @@ -0,0 +1,178 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +**************************************************************************/ + +#include "completingtextedit.h" + +#include <QtGui/QAbstractItemView> +#include <QtGui/QCompleter> +#include <QtGui/QKeyEvent> +#include <QtGui/QScrollBar> + +static bool isEndOfWordChar(const QChar &c) +{ + return !c.isLetterOrNumber() && c.category() != QChar::Punctuation_Connector; +} + +/*! \class Utils::CompletingTextEdit + + \brief A QTextEdit with auto-completion support + + Excerpted from Qt examples/tools/customcompleter +*/ + +namespace Utils { + +class CompletingTextEditPrivate +{ +public: + CompletingTextEditPrivate(CompletingTextEdit *textEdit); + + void insertCompletion(const QString &completion); + QString textUnderCursor() const; + + QCompleter *m_completer; + +private: + CompletingTextEdit *m_backPointer; +}; + +CompletingTextEditPrivate::CompletingTextEditPrivate(CompletingTextEdit *textEdit) + : m_completer(0), + m_backPointer(textEdit) +{ +} + +void CompletingTextEditPrivate::insertCompletion(const QString &completion) +{ + if (m_completer->widget() != m_backPointer) + return; + QTextCursor tc = m_backPointer->textCursor(); + int extra = completion.length() - m_completer->completionPrefix().length(); + tc.movePosition(QTextCursor::Left); + tc.movePosition(QTextCursor::EndOfWord); + tc.insertText(completion.right(extra)); + m_backPointer->setTextCursor(tc); +} + +QString CompletingTextEditPrivate::textUnderCursor() const +{ + QTextCursor tc = m_backPointer->textCursor(); + tc.select(QTextCursor::WordUnderCursor); + return tc.selectedText(); +} + +CompletingTextEdit::CompletingTextEdit(QWidget *parent) + : QTextEdit(parent), + d(new CompletingTextEditPrivate(this)) +{ +} + +CompletingTextEdit::~CompletingTextEdit() +{ + delete d; +} + +void CompletingTextEdit::setCompleter(QCompleter *c) +{ + if (completer()) + disconnect(completer(), 0, this, 0); + + d->m_completer = c; + + if (!c) + return; + + completer()->setWidget(this); + completer()->setCompletionMode(QCompleter::PopupCompletion); + connect(completer(), SIGNAL(activated(QString)), this, SLOT(insertCompletion(QString))); +} + +QCompleter *CompletingTextEdit::completer() const +{ + return d->m_completer; +} + +void CompletingTextEdit::keyPressEvent(QKeyEvent *e) +{ + if (completer() && completer()->popup()->isVisible()) { + // The following keys are forwarded by the completer to the widget + switch (e->key()) { + case Qt::Key_Enter: + case Qt::Key_Return: + case Qt::Key_Escape: + case Qt::Key_Tab: + case Qt::Key_Backtab: + e->ignore(); + return; // let the completer do default behavior + default: + break; + } + } + + const bool isShortcut = ((e->modifiers() & Qt::ControlModifier) && e->key() == Qt::Key_E); // CTRL+E + if (completer() == 0 || !isShortcut) // do not process the shortcut when we have a completer + QTextEdit::keyPressEvent(e); + + const bool ctrlOrShift = e->modifiers() & (Qt::ControlModifier | Qt::ShiftModifier); + if (completer() == 0 || (ctrlOrShift && e->text().isEmpty())) + return; + + const bool hasModifier = (e->modifiers() != Qt::NoModifier) && !ctrlOrShift; + const QString newCompletionPrefix = d->textUnderCursor(); + const QChar lastChar = e->text().isEmpty() ? QChar() : e->text().right(1).at(0); + + if (!isShortcut && (hasModifier || e->text().isEmpty() || newCompletionPrefix.length() < 3 + || isEndOfWordChar(lastChar))) { + completer()->popup()->hide(); + return; + } + + if (newCompletionPrefix != completer()->completionPrefix()) { + completer()->setCompletionPrefix(newCompletionPrefix); + completer()->popup()->setCurrentIndex(completer()->completionModel()->index(0, 0)); + } + QRect cr = cursorRect(); + cr.setWidth(completer()->popup()->sizeHintForColumn(0) + + completer()->popup()->verticalScrollBar()->sizeHint().width()); + completer()->complete(cr); // popup it up! +} + +void CompletingTextEdit::focusInEvent(QFocusEvent *e) +{ + if (completer() != 0) + completer()->setWidget(this); + QTextEdit::focusInEvent(e); +} + +} // namespace Utils + +#include "moc_completingtextedit.cpp" diff --git a/src/libs/utils/completingtextedit.h b/src/libs/utils/completingtextedit.h new file mode 100644 index 00000000000..9c69150f357 --- /dev/null +++ b/src/libs/utils/completingtextedit.h @@ -0,0 +1,68 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +**************************************************************************/ + +#ifndef COMPLETINGTEXTEDIT_H +#define COMPLETINGTEXTEDIT_H + +#include "utils_global.h" + +#include <QtGui/QTextEdit> + +QT_BEGIN_NAMESPACE +class QCompleter; +QT_END_NAMESPACE + +namespace Utils { + +class QTCREATOR_UTILS_EXPORT CompletingTextEdit : public QTextEdit +{ + Q_OBJECT + +public: + CompletingTextEdit(QWidget *parent = 0); + ~CompletingTextEdit(); + + void setCompleter(QCompleter *c); + QCompleter *completer() const; + +protected: + void keyPressEvent(QKeyEvent *e); + void focusInEvent(QFocusEvent *e); + +private: + class CompletingTextEditPrivate *d; + Q_PRIVATE_SLOT(d, void insertCompletion(const QString &)) +}; + +} // namespace Utils + +#endif // COMPLETINGTEXTEDIT_H diff --git a/src/libs/utils/submiteditorwidget.cpp b/src/libs/utils/submiteditorwidget.cpp index 5b59a90fbd9..321f502c0cc 100644 --- a/src/libs/utils/submiteditorwidget.cpp +++ b/src/libs/utils/submiteditorwidget.cpp @@ -457,7 +457,7 @@ QStringList SubmitEditorWidget::checkedFiles() const return rc; } -QTextEdit *SubmitEditorWidget::descriptionEdit() const +CompletingTextEdit *SubmitEditorWidget::descriptionEdit() const { return d->m_ui.description; } diff --git a/src/libs/utils/submiteditorwidget.h b/src/libs/utils/submiteditorwidget.h index 4fec4faadd3..3a0b286c82a 100644 --- a/src/libs/utils/submiteditorwidget.h +++ b/src/libs/utils/submiteditorwidget.h @@ -34,12 +34,12 @@ #define SUBMITEDITORWIDGET_H #include "utils_global.h" +#include "completingtextedit.h" #include <QtGui/QWidget> #include <QtGui/QAbstractItemView> QT_BEGIN_NAMESPACE -class QTextEdit; class QListWidgetItem; class QAction; class QAbstractItemModel; @@ -102,7 +102,7 @@ public: // Selected files for diff QStringList selectedFiles() const; - QTextEdit *descriptionEdit() const; + CompletingTextEdit *descriptionEdit() const; void addDescriptionEditContextMenuAction(QAction *a); void insertDescriptionEditContextMenuAction(int pos, QAction *a); diff --git a/src/libs/utils/submiteditorwidget.ui b/src/libs/utils/submiteditorwidget.ui index 9f12c073532..2c5459fed0c 100644 --- a/src/libs/utils/submiteditorwidget.ui +++ b/src/libs/utils/submiteditorwidget.ui @@ -24,7 +24,7 @@ </property> <layout class="QVBoxLayout" name="verticalLayout"> <item> - <widget class="QTextEdit" name="description"> + <widget class="Utils::CompletingTextEdit" name="description"> <property name="acceptRichText"> <bool>false</bool> </property> @@ -77,6 +77,13 @@ </item> </layout> </widget> + <customwidgets> + <customwidget> + <class>Utils::CompletingTextEdit</class> + <extends>QTextEdit</extends> + <header>utils/completingtextedit.h</header> + </customwidget> + </customwidgets> <resources/> <connections/> </ui> diff --git a/src/libs/utils/utils-lib.pri b/src/libs/utils/utils-lib.pri index 3277e46240a..395882b8393 100644 --- a/src/libs/utils/utils-lib.pri +++ b/src/libs/utils/utils-lib.pri @@ -91,7 +91,8 @@ SOURCES += $$PWD/environment.cpp \ $$PWD/outputformatter.cpp \ $$PWD/flowlayout.cpp \ $$PWD/networkaccessmanager.cpp \ - $$PWD/persistentsettings.cpp + $$PWD/persistentsettings.cpp \ + $$PWD/completingtextedit.cpp win32 { SOURCES += \ @@ -197,7 +198,8 @@ HEADERS += \ $$PWD/outputformat.h \ $$PWD/flowlayout.h \ $$PWD/networkaccessmanager.h \ - $$PWD/persistentsettings.h + $$PWD/persistentsettings.h \ + $$PWD/completingtextedit.h FORMS += $$PWD/filewizardpage.ui \ $$PWD/projectintropage.ui \ diff --git a/src/plugins/bazaar/bazaarplugin.cpp b/src/plugins/bazaar/bazaarplugin.cpp index bdc33c94af8..f1f0f8f7787 100644 --- a/src/plugins/bazaar/bazaarplugin.cpp +++ b/src/plugins/bazaar/bazaarplugin.cpp @@ -596,7 +596,8 @@ void BazaarPlugin::showCommitWidget(const QList<VCSBase::VCSBaseClient::StatusIt commitEditor->setDisplayName(msg); const BranchInfo branch = m_client->synchronousBranchQuery(m_submitRepository); - commitEditor->setFields(branch, m_bazaarSettings.stringValue(BazaarSettings::userNameKey), + commitEditor->setFields(m_submitRepository, branch, + m_bazaarSettings.stringValue(BazaarSettings::userNameKey), m_bazaarSettings.stringValue(BazaarSettings::userEmailKey), status); } diff --git a/src/plugins/bazaar/commiteditor.cpp b/src/plugins/bazaar/commiteditor.cpp index 20ca57df0a1..dda7dbed86e 100644 --- a/src/plugins/bazaar/commiteditor.cpp +++ b/src/plugins/bazaar/commiteditor.cpp @@ -60,9 +60,9 @@ BazaarCommitWidget *CommitEditor::commitWidget() return static_cast<BazaarCommitWidget *>(widget()); } -void CommitEditor::setFields(const BranchInfo &branch, - const QString &userName, const QString &email, - const QList<VCSBase::VCSBaseClient::StatusItem> &repoStatus) +void CommitEditor::setFields(const QString &repositoryRoot, + const BranchInfo &branch, const QString &userName, + const QString &email, const QList<VCSBase::VCSBaseClient::StatusItem> &repoStatus) { BazaarCommitWidget *bazaarWidget = commitWidget(); if (!bazaarWidget) @@ -74,5 +74,5 @@ void CommitEditor::setFields(const BranchInfo &branch, foreach (const VCSBase::VCSBaseClient::StatusItem &item, repoStatus) if (item.flags != QLatin1String("Unknown")) m_fileModel->addFile(item.file, item.flags, true); - setFileModel(m_fileModel); + setFileModel(m_fileModel, repositoryRoot); } diff --git a/src/plugins/bazaar/commiteditor.h b/src/plugins/bazaar/commiteditor.h index 489bc4d663e..2e1048a0dce 100644 --- a/src/plugins/bazaar/commiteditor.h +++ b/src/plugins/bazaar/commiteditor.h @@ -54,7 +54,7 @@ public: explicit CommitEditor(const VCSBase::VCSBaseSubmitEditorParameters *parameters, QWidget *parent); - void setFields(const BranchInfo &branch, + void setFields(const QString &repositoryRoot, const BranchInfo &branch, const QString &userName, const QString &email, const QList<VCSBase::VCSBaseClient::StatusItem> &repoStatus); diff --git a/src/plugins/git/gitsubmiteditor.cpp b/src/plugins/git/gitsubmiteditor.cpp index 8c5c64c5c0e..3924c591798 100644 --- a/src/plugins/git/gitsubmiteditor.cpp +++ b/src/plugins/git/gitsubmiteditor.cpp @@ -78,7 +78,7 @@ void GitSubmitEditor::setCommitData(const CommitData &d) QVariant(static_cast<int>(state))); } } - setFileModel(m_model); + setFileModel(m_model, d.panelInfo.repository); } void GitSubmitEditor::slotDiffSelected(const QStringList &files) diff --git a/src/plugins/mercurial/commiteditor.cpp b/src/plugins/mercurial/commiteditor.cpp index fc422a2f9a2..5b1e975aa30 100644 --- a/src/plugins/mercurial/commiteditor.cpp +++ b/src/plugins/mercurial/commiteditor.cpp @@ -85,7 +85,7 @@ void CommitEditor::setFields(const QFileInfo &repositoryRoot, const QString &bra } } - setFileModel(fileModel); + setFileModel(fileModel, repositoryRoot.absoluteFilePath()); } QString CommitEditor::committerInfo() diff --git a/src/plugins/vcsbase/vcsbase_dependencies.pri b/src/plugins/vcsbase/vcsbase_dependencies.pri index 3a68ac96009..672a4f65cf4 100644 --- a/src/plugins/vcsbase/vcsbase_dependencies.pri +++ b/src/plugins/vcsbase/vcsbase_dependencies.pri @@ -2,3 +2,4 @@ include(../../plugins/coreplugin/coreplugin.pri) include(../../plugins/texteditor/texteditor.pri) include(../../plugins/projectexplorer/projectexplorer.pri) include(../../plugins/find/find.pri) +include(../../libs/cplusplus/cplusplus.pri) diff --git a/src/plugins/vcsbase/vcsbasesubmiteditor.cpp b/src/plugins/vcsbase/vcsbasesubmiteditor.cpp index ffa75517fb3..81653407573 100644 --- a/src/plugins/vcsbase/vcsbasesubmiteditor.cpp +++ b/src/plugins/vcsbase/vcsbasesubmiteditor.cpp @@ -39,11 +39,20 @@ #include "submiteditorfile.h" #include <aggregation/aggregate.h> +#include <cplusplus/Control.h> +#include <cplusplus/CoreTypes.h> +#include <cplusplus/FullySpecifiedType.h> +#include <cplusplus/Literals.h> +#include <cplusplus/ModelManagerInterface.h> +#include <cplusplus/Symbol.h> +#include <cplusplus/Symbols.h> +#include <cplusplus/TranslationUnit.h> #include <coreplugin/ifile.h> #include <coreplugin/icore.h> #include <coreplugin/editormanager/editormanager.h> #include <coreplugin/id.h> #include <coreplugin/actionmanager/actionmanager.h> +#include <utils/completingtextedit.h> #include <utils/submiteditorwidget.h> #include <utils/checkablemessagebox.h> #include <utils/synchronousprocess.h> @@ -64,6 +73,7 @@ #include <QtCore/QFile> #include <QtCore/QFileInfo> #include <QtCore/QPointer> +#include <QtGui/QStringListModel> #include <QtCore/QTextStream> #include <QtGui/QStyle> #include <QtGui/QToolBar> @@ -78,6 +88,59 @@ enum { debug = 0 }; enum { wantToolBar = 0 }; +// Return true if word is meaningful and can be added to a completion model +static bool acceptsWordForCompletion(const char *word) +{ + return !(word == 0 || word[0] == 0 || word[1] == 0 || word[2] == 0); +} + +// Return the class name which function belongs to +static const char *belongingClassName(const CPlusPlus::Function *function) +{ + if (function == 0) + return 0; + + const CPlusPlus::Name *funcName = function->name(); + if (funcName != 0 && funcName->asQualifiedNameId() != 0) { + const CPlusPlus::Name *funcBaseName = funcName->asQualifiedNameId()->base(); + if (funcBaseName != 0 && funcBaseName->identifier() != 0) + return funcBaseName->identifier()->chars(); + } + + return 0; +} + +// Recursively return the core element type +static const CPlusPlus::Type *pointerAndReferenceSimplified(const CPlusPlus::Type *type) +{ + const CPlusPlus::PointerType *ptrType = type != 0 ? type->asPointerType() : 0; + if (ptrType != 0) { + return pointerAndReferenceSimplified(ptrType->elementType().type()); + } + else { + const CPlusPlus::ReferenceType *refType = type != 0 ? type->asReferenceType() : 0; + if (refType != 0) + return pointerAndReferenceSimplified(refType->elementType().type()); + else + return type; + } +} + +// Return the core and non-primitive type name (not void, int, float, pointer, ...) +static const char *nonPrimitiveTypeName(const CPlusPlus::Type *type) +{ + if (type == 0) + return 0; + + const CPlusPlus::Type *coreType = pointerAndReferenceSimplified(type); + const CPlusPlus::Name *coreTypeName = + coreType != 0 && coreType->isNamedType() ? coreType->asNamedType()->name() : 0; + if (coreTypeName != 0 && coreTypeName->identifier() != 0) + return coreTypeName->identifier()->chars(); + + return 0; +} + /*! \struct VCSBase::VCSBaseSubmitEditorParameters @@ -147,6 +210,10 @@ VCSBaseSubmitEditorPrivate::VCSBaseSubmitEditorPrivate(const VCSBaseSubmitEditor m_file(new VCSBase::Internal::SubmitEditorFile(QLatin1String(parameters->mimeType), q)), m_nickNameDialog(0) { + QCompleter *completer = new QCompleter(q); + completer->setCaseSensitivity(Qt::CaseInsensitive); + completer->setModelSorting(QCompleter::CaseSensitivelySortedModel); + m_widget->descriptionEdit()->setCompleter(completer); } VCSBaseSubmitEditor::VCSBaseSubmitEditor(const VCSBaseSubmitEditorParameters *parameters, @@ -437,9 +504,74 @@ QStringList VCSBaseSubmitEditor::checkedFiles() const return d->m_widget->checkedFiles(); } -void VCSBaseSubmitEditor::setFileModel(QAbstractItemModel *m) +void VCSBaseSubmitEditor::setFileModel(QAbstractItemModel *m, const QString &repositoryDirectory) { d->m_widget->setFileModel(m); + + QSet<QString> uniqueSymbols; + const CPlusPlus::Snapshot cppSnapShot = CPlusPlus::CppModelManagerInterface::instance()->snapshot(); + + // Iterate over the files and get interesting symbols + for (int row = 0; row < m->rowCount(); ++row) { + const QString fileName = m->data(m->index(row, d->m_widget->fileNameColumn())).toString(); + const QFileInfo fileInfo(repositoryDirectory, fileName); + + // Add file name + uniqueSymbols.insert(fileInfo.fileName()); + + const QString filePath = fileInfo.absoluteFilePath(); + // Add symbols from the C++ code model + const CPlusPlus::Document::Ptr doc = cppSnapShot.document(filePath); + if (!doc.isNull() && doc->control() != 0) { + const CPlusPlus::Control *ctrl = doc->control(); + CPlusPlus::Symbol **symPtr = ctrl->firstSymbol(); // Read-only + while (symPtr != ctrl->lastSymbol()) { + const CPlusPlus::Symbol *sym = *symPtr; + + // Regular identifiers + if (sym->identifier() != 0 && acceptsWordForCompletion(sym->identifier()->chars())) + uniqueSymbols.insert(sym->identifier()->chars()); + + // Handle specific cases + if (sym->isFunction()) { + const CPlusPlus::Function *symFunc = sym->asFunction(); + + // Get "Foo" in "void Foo::function() {}" + if (!symFunc->isDeclaration()) { + const char *className = belongingClassName(symFunc); + if (acceptsWordForCompletion(className)) + uniqueSymbols.insert(className); + } + + // Insert symbol for the return type + const char *retTypeName = nonPrimitiveTypeName(symFunc->returnType().type()); + if (acceptsWordForCompletion(retTypeName)) + uniqueSymbols.insert(retTypeName); + } + else if (sym->isArgument()) { + const char *typeName = nonPrimitiveTypeName(sym->asArgument()->type().type()); + if (acceptsWordForCompletion(typeName)) + uniqueSymbols.insert(typeName); + } + + ++symPtr; + } + + // Insert macros + foreach (const CPlusPlus::Macro ¯o, doc->definedMacros()) { + if (acceptsWordForCompletion(macro.name().constData())) + uniqueSymbols.insert(macro.name()); + } + } + } + + // Populate completer with symbols + if (!uniqueSymbols.isEmpty()) { + QCompleter *completer = d->m_widget->descriptionEdit()->completer(); + QStringList symbolsList = uniqueSymbols.toList(); + symbolsList.sort(); + completer->setModel(new QStringListModel(symbolsList, completer)); + } } QAbstractItemModel *VCSBaseSubmitEditor::fileModel() const diff --git a/src/plugins/vcsbase/vcsbasesubmiteditor.h b/src/plugins/vcsbase/vcsbasesubmiteditor.h index 6cc477bba36..552e304d8b5 100644 --- a/src/plugins/vcsbase/vcsbasesubmiteditor.h +++ b/src/plugins/vcsbase/vcsbasesubmiteditor.h @@ -134,7 +134,7 @@ public: QStringList checkedFiles() const; - void setFileModel(QAbstractItemModel *m); + void setFileModel(QAbstractItemModel *m, const QString &repositoryDirectory = QString()); QAbstractItemModel *fileModel() const; // Utilities returning some predefined icons for actions -- GitLab