TODO plugin: Add file patterns to exclude from parsing

Additional list of regular expressions added to TODO plugin settings
to allow set patterns to be excluded from file list to parse by this plugin.

Change-Id: I718f111ac7592557a6aa86865283468c53d58078
Reviewed-by: Nikolai Kosjar <nikolai.kosjar@theqtcompany.com>
This commit is contained in:
Denis Kormalev
2015-05-18 22:47:20 +03:00
parent 4f5a02d596
commit a429ef3d50
19 changed files with 455 additions and 95 deletions

View File

@@ -54,6 +54,8 @@ const char ITEMS_DISPLAY_PLACE[] = "ItemsDisplayPlace";
const char KEYWORDS_LIST[] = "Keywords"; const char KEYWORDS_LIST[] = "Keywords";
const char OUTPUT_PANE_TEXT_WIDTH[] = "OutputPaneTextColumnWidth"; const char OUTPUT_PANE_TEXT_WIDTH[] = "OutputPaneTextColumnWidth";
const char OUTPUT_PANE_FILE_WIDTH[] = "OutputPaneFileColumnWidth"; const char OUTPUT_PANE_FILE_WIDTH[] = "OutputPaneFileColumnWidth";
const char SETTINGS_NAME_KEY[] = "TodoProjectSettings";
const char EXCLUDES_LIST_KEY[] = "ExcludesList";
// TODO Output TreeWidget columns // TODO Output TreeWidget columns
enum OutputColumnIndex { enum OutputColumnIndex {

View File

@@ -46,9 +46,11 @@ CppTodoItemsScanner::CppTodoItemsScanner(const KeywordList &keywordList, QObject
connect(modelManager, &CppTools::CppModelManager::documentUpdated, connect(modelManager, &CppTools::CppModelManager::documentUpdated,
this, &CppTodoItemsScanner::documentUpdated, Qt::DirectConnection); this, &CppTodoItemsScanner::documentUpdated, Qt::DirectConnection);
setParams(keywordList);
} }
void CppTodoItemsScanner::keywordListChanged() void CppTodoItemsScanner::scannerParamsChanged()
{ {
// We need to rescan everything known to the code model // We need to rescan everything known to the code model
// TODO: It would be nice to only tokenize the source files, not update the code model entirely. // TODO: It would be nice to only tokenize the source files, not update the code model entirely.
@@ -72,7 +74,6 @@ void CppTodoItemsScanner::documentUpdated(CPlusPlus::Document::Ptr doc)
void CppTodoItemsScanner::processDocument(CPlusPlus::Document::Ptr doc) void CppTodoItemsScanner::processDocument(CPlusPlus::Document::Ptr doc)
{ {
QList<TodoItem> itemList; QList<TodoItem> itemList;
CPlusPlus::TranslationUnit *translationUnit = doc->translationUnit(); CPlusPlus::TranslationUnit *translationUnit = doc->translationUnit();
for (unsigned i = 0; i < translationUnit->commentCount(); ++i) { for (unsigned i = 0; i < translationUnit->commentCount(); ++i) {

View File

@@ -47,7 +47,7 @@ public:
explicit CppTodoItemsScanner(const KeywordList &keywordList, QObject *parent = 0); explicit CppTodoItemsScanner(const KeywordList &keywordList, QObject *parent = 0);
protected: protected:
void keywordListChanged(); void scannerParamsChanged();
private slots: private slots:
void documentUpdated(CPlusPlus::Document::Ptr doc); void documentUpdated(CPlusPlus::Document::Ptr doc);

View File

@@ -44,12 +44,12 @@ OptionsDialog::OptionsDialog(QWidget *parent) :
ui(new Ui::OptionsDialog) ui(new Ui::OptionsDialog)
{ {
ui->setupUi(this); ui->setupUi(this);
setButtonsEnabled(); setKeywordsButtonsEnabled();
connect(ui->addButton, SIGNAL(clicked()), SLOT(addButtonClicked())); connect(ui->addKeywordButton, SIGNAL(clicked()), SLOT(addKeywordButtonClicked()));
connect(ui->removeButton, SIGNAL(clicked()), SLOT(removeButtonClicked())); connect(ui->removeKeywordButton, SIGNAL(clicked()), SLOT(removeKeywordButtonClicked()));
connect(ui->editButton, SIGNAL(clicked()), SLOT(editButtonClicked())); connect(ui->editKeywordButton, SIGNAL(clicked()), SLOT(editKeywordButtonClicked()));
connect(ui->resetButton, SIGNAL(clicked()), SLOT(resetButtonClicked())); connect(ui->resetKeywordsButton, SIGNAL(clicked()), SLOT(resetKeywordsButtonClicked()));
connect(ui->keywordsList, SIGNAL(itemDoubleClicked(QListWidgetItem*)), SLOT(itemDoubleClicked(QListWidgetItem*))); connect(ui->keywordsList, SIGNAL(itemDoubleClicked(QListWidgetItem*)), SLOT(keywordDoubleClicked(QListWidgetItem*)));
} }
OptionsDialog::~OptionsDialog() OptionsDialog::~OptionsDialog()
@@ -57,9 +57,9 @@ OptionsDialog::~OptionsDialog()
delete ui; delete ui;
} }
void OptionsDialog::itemDoubleClicked(QListWidgetItem *item) void OptionsDialog::keywordDoubleClicked(QListWidgetItem *item)
{ {
editItem(item); editKeyword(item);
} }
void OptionsDialog::setSettings(const Settings &settings) void OptionsDialog::setSettings(const Settings &settings)
@@ -91,7 +91,7 @@ Settings OptionsDialog::settings()
return settingsFromUi(); return settingsFromUi();
} }
void OptionsDialog::addButtonClicked() void OptionsDialog::addKeywordButtonClicked()
{ {
Keyword keyword; Keyword keyword;
KeywordDialog *keywordDialog = new KeywordDialog(keyword, keywordNames(), this); KeywordDialog *keywordDialog = new KeywordDialog(keyword, keywordNames(), this);
@@ -101,13 +101,13 @@ void OptionsDialog::addButtonClicked()
} }
} }
void OptionsDialog::editButtonClicked() void OptionsDialog::editKeywordButtonClicked()
{ {
QListWidgetItem *item = ui->keywordsList->currentItem(); QListWidgetItem *item = ui->keywordsList->currentItem();
editItem(item); editKeyword(item);
} }
void OptionsDialog::editItem(QListWidgetItem *item) void OptionsDialog::editKeyword(QListWidgetItem *item)
{ {
Keyword keyword; Keyword keyword;
keyword.name = item->text(); keyword.name = item->text();
@@ -127,58 +127,58 @@ void OptionsDialog::editItem(QListWidgetItem *item)
} }
} }
void OptionsDialog::removeButtonClicked() void OptionsDialog::removeKeywordButtonClicked()
{ {
ui->keywordsList->takeItem(ui->keywordsList->currentRow()); delete ui->keywordsList->takeItem(ui->keywordsList->currentRow());
} }
void OptionsDialog::resetButtonClicked() void OptionsDialog::resetKeywordsButtonClicked()
{ {
Settings newSettings; Settings newSettings;
newSettings.setDefault(); newSettings.setDefault();
uiFromSettings(newSettings); uiFromSettings(newSettings);
} }
void OptionsDialog::setButtonsEnabled() void OptionsDialog::setKeywordsButtonsEnabled()
{ {
bool isSomethingSelected = ui->keywordsList->selectedItems().count() != 0; bool isSomethingSelected = ui->keywordsList->selectedItems().count() != 0;
ui->removeButton->setEnabled(isSomethingSelected); ui->removeKeywordButton->setEnabled(isSomethingSelected);
ui->editButton->setEnabled(isSomethingSelected); ui->editKeywordButton->setEnabled(isSomethingSelected);
} }
void OptionsDialog::uiFromSettings(const Settings &settings) void OptionsDialog::uiFromSettings(const Settings &settings)
{ {
ui->scanInCurrentFileRadioButton->setChecked(settings.scanningScope == ScanningScopeCurrentFile); ui->scanInCurrentFileRadioButton->setChecked(settings.scanningScope == ScanningScopeCurrentFile);
ui->scanInProjectRadioButton->setChecked(settings.scanningScope == ScanningScopeProject); ui->scanInProjectRadioButton->setChecked(settings.scanningScope == ScanningScopeProject);
ui->keywordsList->clear(); ui->keywordsList->clear();
foreach (const Keyword &keyword, settings.keywords) foreach (const Keyword &keyword, settings.keywords)
addToKeywordsList(keyword); addToKeywordsList(keyword);
} }
Settings OptionsDialog::settingsFromUi() Settings OptionsDialog::settingsFromUi()
{ {
Settings settings; Settings settings;
if (ui->scanInCurrentFileRadioButton->isChecked()) if (ui->scanInCurrentFileRadioButton->isChecked())
settings.scanningScope = ScanningScopeCurrentFile; settings.scanningScope = ScanningScopeCurrentFile;
else else
settings.scanningScope = ScanningScopeProject; settings.scanningScope = ScanningScopeProject;
settings.keywords.clear(); settings.keywords.clear();
for (int i = 0; i < ui->keywordsList->count(); ++i) { for (int i = 0; i < ui->keywordsList->count(); ++i) {
QListWidgetItem *item = ui->keywordsList->item(i); QListWidgetItem *item = ui->keywordsList->item(i);
Keyword keyword; Keyword keyword;
keyword.name = item->text(); keyword.name = item->text();
keyword.iconResource = item->data(Qt::UserRole).toString(); keyword.iconResource = item->data(Qt::UserRole).toString();
keyword.color = item->backgroundColor(); keyword.color = item->backgroundColor();
settings.keywords << keyword; settings.keywords << keyword;
} }
return settings; return settings;
} }
} // namespace Internal } // namespace Internal
} // namespace Todo } // namespace Todo

View File

@@ -57,18 +57,18 @@ public:
Settings settings(); Settings settings();
private slots: private slots:
void addButtonClicked(); void addKeywordButtonClicked();
void editButtonClicked(); void editKeywordButtonClicked();
void removeButtonClicked(); void removeKeywordButtonClicked();
void resetButtonClicked(); void resetKeywordsButtonClicked();
void setButtonsEnabled(); void setKeywordsButtonsEnabled();
void itemDoubleClicked(QListWidgetItem *item); void keywordDoubleClicked(QListWidgetItem *item);
private: private:
void uiFromSettings(const Settings &settings); void uiFromSettings(const Settings &settings);
Settings settingsFromUi(); Settings settingsFromUi();
void addToKeywordsList(const Keyword &keyword); void addToKeywordsList(const Keyword &keyword);
void editItem(QListWidgetItem *item); void editKeyword(QListWidgetItem *item);
QSet<QString> keywordNames(); QSet<QString> keywordNames();
Ui::OptionsDialog *ui; Ui::OptionsDialog *ui;

View File

@@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>377</width> <width>444</width>
<height>299</height> <height>482</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@@ -30,28 +30,28 @@
<item> <item>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<item> <item>
<widget class="QPushButton" name="addButton"> <widget class="QPushButton" name="addKeywordButton">
<property name="text"> <property name="text">
<string>Add</string> <string>Add</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="editButton"> <widget class="QPushButton" name="editKeywordButton">
<property name="text"> <property name="text">
<string>Edit</string> <string>Edit</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="removeButton"> <widget class="QPushButton" name="removeKeywordButton">
<property name="text"> <property name="text">
<string>Remove</string> <string>Remove</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="resetButton"> <widget class="QPushButton" name="resetKeywordsButton">
<property name="text"> <property name="text">
<string>Reset</string> <string>Reset</string>
</property> </property>
@@ -112,7 +112,7 @@
<sender>keywordsList</sender> <sender>keywordsList</sender>
<signal>itemSelectionChanged()</signal> <signal>itemSelectionChanged()</signal>
<receiver>Todo::Internal::OptionsDialog</receiver> <receiver>Todo::Internal::OptionsDialog</receiver>
<slot>setButtonsEnabled()</slot> <slot>setKeywordsButtonsEnabled()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">
<x>247</x> <x>247</x>
@@ -126,6 +126,6 @@
</connection> </connection>
</connections> </connections>
<slots> <slots>
<slot>setButtonsEnabled()</slot> <slot>setKeywordsButtonsEnabled()</slot>
</slots> </slots>
</ui> </ui>

View File

@@ -44,19 +44,22 @@ QmlJsTodoItemsScanner::QmlJsTodoItemsScanner(const KeywordList &keywordList, QOb
QmlJS::ModelManagerInterface *model = QmlJS::ModelManagerInterface::instance(); QmlJS::ModelManagerInterface *model = QmlJS::ModelManagerInterface::instance();
connect(model, &QmlJS::ModelManagerInterface::documentUpdated, connect(model, &QmlJS::ModelManagerInterface::documentUpdated,
this, &QmlJsTodoItemsScanner::documentUpdated, Qt::DirectConnection); this, &QmlJsTodoItemsScanner::documentUpdated, Qt::DirectConnection);
setParams(keywordList);
} }
bool QmlJsTodoItemsScanner::shouldProcessFile(const QString &fileName) bool QmlJsTodoItemsScanner::shouldProcessFile(const QString &fileName)
{ {
QmlJS::ModelManagerInterface *modelManager = QmlJS::ModelManagerInterface::instance(); QmlJS::ModelManagerInterface *modelManager = QmlJS::ModelManagerInterface::instance();
foreach (const QmlJS::ModelManagerInterface::ProjectInfo &info, modelManager->projectInfos()) foreach (const QmlJS::ModelManagerInterface::ProjectInfo &info, modelManager->projectInfos()) {
if (info.sourceFiles.contains(fileName)) if (info.sourceFiles.contains(fileName))
return true; return true;
}
return false; return false;
} }
void QmlJsTodoItemsScanner::keywordListChanged() void QmlJsTodoItemsScanner::scannerParamsChanged()
{ {
// We need to rescan everything known to the code model // We need to rescan everything known to the code model
// TODO: It would be nice to only tokenize the source files, not update the code model entirely. // TODO: It would be nice to only tokenize the source files, not update the code model entirely.
@@ -81,7 +84,6 @@ void QmlJsTodoItemsScanner::processDocument(QmlJS::Document::Ptr doc)
QList<TodoItem> itemList; QList<TodoItem> itemList;
foreach (const QmlJS::AST::SourceLocation &sourceLocation, doc->engine()->comments()) { foreach (const QmlJS::AST::SourceLocation &sourceLocation, doc->engine()->comments()) {
QString source = doc->source().mid(sourceLocation.begin(), sourceLocation.length).trimmed(); QString source = doc->source().mid(sourceLocation.begin(), sourceLocation.length).trimmed();
// Process every line // Process every line

View File

@@ -48,7 +48,7 @@ public:
protected: protected:
bool shouldProcessFile(const QString &fileName); bool shouldProcessFile(const QString &fileName);
void keywordListChanged(); void scannerParamsChanged() override;
private slots: private slots:
void documentUpdated(QmlJS::Document::Ptr doc); void documentUpdated(QmlJS::Document::Ptr doc);

View File

@@ -72,12 +72,12 @@ void Settings::load(QSettings *settings)
scanningScope).toInt()); scanningScope).toInt());
KeywordList newKeywords; KeywordList newKeywords;
const int size = settings->beginReadArray(QLatin1String(Constants::KEYWORDS_LIST)); const int keywordsSize = settings->beginReadArray(QLatin1String(Constants::KEYWORDS_LIST));
if (size > 0) { if (keywordsSize > 0) {
const QString nameKey = QLatin1String("name"); const QString nameKey = QLatin1String("name");
const QString colorKey = QLatin1String("color"); const QString colorKey = QLatin1String("color");
const QString iconResourceKey = QLatin1String("iconResource"); const QString iconResourceKey = QLatin1String("iconResource");
for (int i = 0; i < size; ++i) { for (int i = 0; i < keywordsSize; ++i) {
settings->setArrayIndex(i); settings->setArrayIndex(i);
Keyword keyword; Keyword keyword;
keyword.name = settings->value(nameKey).toString(); keyword.name = settings->value(nameKey).toString();
@@ -129,8 +129,7 @@ void Settings::setDefault()
bool Settings::equals(const Settings &other) const bool Settings::equals(const Settings &other) const
{ {
return (keywords == other.keywords) return (keywords == other.keywords)
&& (scanningScope == other.scanningScope); && (scanningScope == other.scanningScope);
} }
bool operator ==(Settings &s1, Settings &s2) bool operator ==(Settings &s1, Settings &s2)

View File

@@ -16,7 +16,9 @@ HEADERS += todoplugin.h \
qmljstodoitemsscanner.h \ qmljstodoitemsscanner.h \
lineparser.h \ lineparser.h \
todooutputtreeview.h \ todooutputtreeview.h \
todooutputtreeviewdelegate.h todooutputtreeviewdelegate.h \
todoprojectsettingswidget.h
SOURCES += todoplugin.cpp \ SOURCES += todoplugin.cpp \
keyword.cpp \ keyword.cpp \
todooutputpane.cpp \ todooutputpane.cpp \
@@ -31,11 +33,13 @@ SOURCES += todoplugin.cpp \
qmljstodoitemsscanner.cpp \ qmljstodoitemsscanner.cpp \
lineparser.cpp \ lineparser.cpp \
todooutputtreeview.cpp \ todooutputtreeview.cpp \
todooutputtreeviewdelegate.cpp todooutputtreeviewdelegate.cpp \
todoprojectsettingswidget.cpp
RESOURCES += \ RESOURCES += \
todoplugin.qrc todoplugin.qrc
FORMS += \ FORMS += \
optionsdialog.ui \ optionsdialog.ui \
keyworddialog.ui keyworddialog.ui \
todoprojectsettingswidget.ui

View File

@@ -26,6 +26,9 @@ QtcPlugin {
"optionsdialog.cpp", "optionsdialog.cpp",
"optionsdialog.h", "optionsdialog.h",
"optionsdialog.ui", "optionsdialog.ui",
"todoprojectsettingswidget.cpp",
"todoprojectsettingswidget.h",
"todoprojectsettingswidget.ui",
"optionspage.cpp", "optionspage.cpp",
"optionspage.h", "optionspage.h",
"qmljstodoitemsscanner.cpp", "qmljstodoitemsscanner.cpp",

View File

@@ -66,15 +66,22 @@ TodoItemsModel *TodoItemsProvider::todoItemsModel()
void TodoItemsProvider::settingsChanged(const Settings &newSettings) void TodoItemsProvider::settingsChanged(const Settings &newSettings)
{ {
if (newSettings.keywords != m_settings.keywords) if (newSettings.keywords != m_settings.keywords) {
foreach (TodoItemsScanner *scanner, m_scanners) foreach (TodoItemsScanner *scanner, m_scanners)
scanner->setKeywordList(newSettings.keywords); scanner->setParams(newSettings.keywords);
}
m_settings = newSettings; m_settings = newSettings;
updateList(); updateList();
} }
void TodoItemsProvider::projectSettingsChanged(Project *project)
{
Q_UNUSED(project);
updateList();
}
void TodoItemsProvider::updateList() void TodoItemsProvider::updateList()
{ {
m_itemsList.clear(); m_itemsList.clear();
@@ -84,9 +91,8 @@ void TodoItemsProvider::updateList()
if (m_currentEditor) if (m_currentEditor)
m_itemsList = m_itemsHash.value(m_currentEditor->document()->filePath().toString()); m_itemsList = m_itemsHash.value(m_currentEditor->document()->filePath().toString());
// Show only items of the startup project if any // Show only items of the startup project if any
} else { } else if (m_startupProject) {
if (m_startupProject) setItemsListWithinStartupProject();
setItemsListWithinStartupProject();
} }
m_itemsModel->todoItemsListUpdated(); m_itemsModel->todoItemsListUpdated();
@@ -102,19 +108,34 @@ void TodoItemsProvider::createScanners()
if (QmlJS::ModelManagerInterface::instance()) if (QmlJS::ModelManagerInterface::instance())
m_scanners << new QmlJsTodoItemsScanner(m_settings.keywords, this); m_scanners << new QmlJsTodoItemsScanner(m_settings.keywords, this);
foreach (TodoItemsScanner *scanner, m_scanners) foreach (TodoItemsScanner *scanner, m_scanners) {
connect(scanner, SIGNAL(itemsFetched(QString,QList<TodoItem>)), this, connect(scanner, SIGNAL(itemsFetched(QString,QList<TodoItem>)), this,
SLOT(itemsFetched(QString,QList<TodoItem>)), Qt::QueuedConnection); SLOT(itemsFetched(QString,QList<TodoItem>)), Qt::QueuedConnection);
}
} }
void TodoItemsProvider::setItemsListWithinStartupProject() void TodoItemsProvider::setItemsListWithinStartupProject()
{ {
QHashIterator<QString, QList<TodoItem> > it(m_itemsHash); QHashIterator<QString, QList<TodoItem> > it(m_itemsHash);
QSet<QString> fileNames = QSet<QString>::fromList(m_startupProject->files(Project::ExcludeGeneratedFiles)); QSet<QString> fileNames = QSet<QString>::fromList(m_startupProject->files(Project::ExcludeGeneratedFiles));
QVariantMap settings = m_startupProject->namedSettings(QLatin1String(Constants::SETTINGS_NAME_KEY)).toMap();
while (it.hasNext()) { while (it.hasNext()) {
it.next(); it.next();
if (fileNames.contains(it.key())) QString fileName = it.key();
m_itemsList << it.value(); if (fileNames.contains(fileName)) {
bool skip = false;
for (const QVariant &pattern : settings[QLatin1String(Constants::EXCLUDES_LIST_KEY)].toList()) {
QRegExp re(pattern.toString());
if (re.indexIn(fileName) != -1) {
skip = true;
break;
}
}
if (!skip)
m_itemsList << it.value();
}
} }
} }

View File

@@ -57,6 +57,7 @@ public:
public slots: public slots:
void settingsChanged(const Settings &newSettings); void settingsChanged(const Settings &newSettings);
void projectSettingsChanged(ProjectExplorer::Project *project);
signals: signals:
void itemsUpdated(); void itemsUpdated();

View File

@@ -39,25 +39,20 @@ namespace Todo {
namespace Internal { namespace Internal {
TodoItemsScanner::TodoItemsScanner(const KeywordList &keywordList, QObject *parent) : TodoItemsScanner::TodoItemsScanner(const KeywordList &keywordList, QObject *parent) :
QObject(parent) QObject(parent), m_keywordList(keywordList)
{ {
setKeywordList(keywordList);
} }
void TodoItemsScanner::setKeywordList(const KeywordList &keywordList) void TodoItemsScanner::setParams(const KeywordList &keywordList)
{ {
m_keywordList = keywordList; m_keywordList = keywordList;
keywordListChanged(); scannerParamsChanged();
} }
// Descendants can override and make a request for full rescan here if needed
void TodoItemsScanner::keywordListChanged()
{
}
// Descendants can use this to process comment lines // Descendants can use this to process comment lines
void TodoItemsScanner::processCommentLine(const QString &fileName, const QString &comment, void TodoItemsScanner::processCommentLine(const QString &fileName, const QString &comment,
unsigned lineNumber, QList<TodoItem> &outItemList) unsigned lineNumber, QList<TodoItem> &outItemList)
{ {
LineParser parser(m_keywordList); LineParser parser(m_keywordList);
QList<TodoItem> newItemList = parser.parse(comment); QList<TodoItem> newItemList = parser.parse(comment);

View File

@@ -37,6 +37,10 @@
#include <QObject> #include <QObject>
namespace ProjectExplorer {
class Project;
}
namespace Todo { namespace Todo {
namespace Internal { namespace Internal {
@@ -48,7 +52,7 @@ class TodoItemsScanner : public QObject
public: public:
explicit TodoItemsScanner(const KeywordList &keywordList, QObject *parent = 0); explicit TodoItemsScanner(const KeywordList &keywordList, QObject *parent = 0);
void setKeywordList(const KeywordList &keywordList); void setParams(const KeywordList &keywordList);
signals: signals:
void itemsFetched(const QString &fileName, const QList<TodoItem> &items); void itemsFetched(const QString &fileName, const QList<TodoItem> &items);
@@ -56,9 +60,11 @@ signals:
protected: protected:
KeywordList m_keywordList; KeywordList m_keywordList;
virtual void keywordListChanged(); // Descendants can override and make a request for full rescan here if needed
void processCommentLine(const QString &fileName, const QString &comment, unsigned lineNumber, virtual void scannerParamsChanged() = 0;
QList<TodoItem> &outItemList);
void processCommentLine(const QString &fileName, const QString &comment,
unsigned lineNumber, QList<TodoItem> &outItemList);
}; };
} }

View File

@@ -35,10 +35,12 @@
#include "keyword.h" #include "keyword.h"
#include "todooutputpane.h" #include "todooutputpane.h"
#include "todoitemsprovider.h" #include "todoitemsprovider.h"
#include "todoprojectsettingswidget.h"
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <coreplugin/editormanager/editormanager.h> #include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/editormanager/ieditor.h> #include <coreplugin/editormanager/ieditor.h>
#include <projectexplorer/projectpanelfactory.h>
#include <QtPlugin> #include <QtPlugin>
#include <QFileInfo> #include <QFileInfo>
@@ -71,6 +73,23 @@ bool TodoPlugin::initialize(const QStringList& args, QString *errMsg)
createItemsProvider(); createItemsProvider();
createTodoOutputPane(); createTodoOutputPane();
auto panelFactory = new ProjectExplorer::ProjectPanelFactory();
panelFactory->setPriority(100);
panelFactory->setDisplayName(TodoProjectSettingsWidget::tr("To-Do Settings"));
panelFactory->setCreateWidgetFunction([this, panelFactory](ProjectExplorer::Project *project) -> QWidget * {
auto *panel = new ProjectExplorer::PropertiesPanel;
panel->setDisplayName(panelFactory->displayName());
auto *widget = new TodoProjectSettingsWidget(project);
connect(widget, &TodoProjectSettingsWidget::projectSettingsChanged,
m_todoItemsProvider, [this, project](){m_todoItemsProvider->projectSettingsChanged(project);});
panel->setWidget(widget);
auto *panelsWidget = new ProjectExplorer::PanelsWidget();
panelsWidget->addPropertiesPanel(panel);
panelsWidget->setFocusProxy(widget);
return panelsWidget;
});
ProjectExplorer::ProjectPanelFactory::registerFactory(panelFactory);
return true; return true;
} }

View File

@@ -0,0 +1,136 @@
/**************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "todoprojectsettingswidget.h"
#include "ui_todoprojectsettingswidget.h"
#include "constants.h"
#include <projectexplorer/project.h>
namespace Todo {
namespace Internal {
static const QString EXCLUDE_PLACEHOLDER = QObject::tr("<Enter regular expression to exclude>");
TodoProjectSettingsWidget::TodoProjectSettingsWidget(ProjectExplorer::Project *project) :
QWidget(0),
ui(new Ui::TodoProjectSettingsWidget),
m_project(project)
{
ui->setupUi(this);
setExcludedPatternsButtonsEnabled();
connect(ui->addExcludedPatternButton, &QPushButton::clicked,
this, &TodoProjectSettingsWidget::addExcludedPatternButtonClicked);
connect(ui->removeExcludedPatternButton, &QPushButton::clicked,
this, &TodoProjectSettingsWidget::removeExcludedPatternButtonClicked);
connect(ui->excludedPatternsList, &QListWidget::itemChanged,
this, &TodoProjectSettingsWidget::excludedPatternChanged, Qt::QueuedConnection);
loadSettings();
}
TodoProjectSettingsWidget::~TodoProjectSettingsWidget()
{
delete ui;
}
QListWidgetItem *TodoProjectSettingsWidget::addToExcludedPatternsList(const QString &pattern)
{
QListWidgetItem *item = new QListWidgetItem(pattern);
item->setFlags(item->flags() | Qt::ItemIsEditable);
prepareItem(item);
ui->excludedPatternsList->addItem(item);
return item;
}
void TodoProjectSettingsWidget::loadSettings()
{
QVariant s = m_project->namedSettings(QLatin1String(Constants::SETTINGS_NAME_KEY));
QVariantMap settings = s.toMap();
ui->excludedPatternsList->clear();
for (const QVariant &pattern : settings[QLatin1String(Constants::EXCLUDES_LIST_KEY)].toList())
addToExcludedPatternsList(pattern.toString());
}
void TodoProjectSettingsWidget::saveSettings()
{
QVariantMap settings;
QVariantList excludes;
for (int i = 0; i < ui->excludedPatternsList->count(); ++i)
excludes << ui->excludedPatternsList->item(i)->text();
settings[QLatin1String(Constants::EXCLUDES_LIST_KEY)] = excludes;
m_project->setNamedSettings(QLatin1String(Constants::SETTINGS_NAME_KEY), settings);
emit projectSettingsChanged();
}
void TodoProjectSettingsWidget::prepareItem(QListWidgetItem *item) const
{
if (QRegExp(item->text()).isValid())
item->setForeground(QBrush(ui->excludedPatternsList->palette().color(QPalette::Active, QPalette::Text)));
else
item->setForeground(QBrush(Qt::red));
}
void TodoProjectSettingsWidget::addExcludedPatternButtonClicked()
{
if (ui->excludedPatternsList->findItems(EXCLUDE_PLACEHOLDER, Qt::MatchFixedString).count())
return;
ui->excludedPatternsList->editItem(addToExcludedPatternsList(EXCLUDE_PLACEHOLDER));
}
void TodoProjectSettingsWidget::removeExcludedPatternButtonClicked()
{
delete ui->excludedPatternsList->takeItem(ui->excludedPatternsList->currentRow());
saveSettings();
}
void TodoProjectSettingsWidget::setExcludedPatternsButtonsEnabled()
{
bool isSomethingSelected = ui->excludedPatternsList->selectedItems().count() != 0;
ui->removeExcludedPatternButton->setEnabled(isSomethingSelected);
}
void TodoProjectSettingsWidget::excludedPatternChanged(QListWidgetItem *item)
{
if (item->text().isEmpty() || item->text() == EXCLUDE_PLACEHOLDER) {
ui->excludedPatternsList->removeItemWidget(item);
delete item;
} else {
prepareItem(item);
}
saveSettings();
ui->excludedPatternsList->setCurrentItem(nullptr);
}
} // namespace Internal
} // namespace Todo

View File

@@ -0,0 +1,80 @@
/**************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef TODO_INTERNAL_TODOPROJECTSETTINGSWIDGET_H
#define TODO_INTERNAL_TODOPROJECTSETTINGSWIDGET_H
#include <QWidget>
QT_BEGIN_NAMESPACE
class QListWidgetItem;
QT_END_NAMESPACE
namespace ProjectExplorer {
class Project;
}
namespace Todo {
namespace Internal {
namespace Ui {
class TodoProjectSettingsWidget;
}
class TodoProjectSettingsWidget : public QWidget
{
Q_OBJECT
public:
explicit TodoProjectSettingsWidget(ProjectExplorer::Project *project);
~TodoProjectSettingsWidget();
signals:
void projectSettingsChanged();
private slots:
void addExcludedPatternButtonClicked();
void removeExcludedPatternButtonClicked();
void setExcludedPatternsButtonsEnabled();
void excludedPatternChanged(QListWidgetItem *item);
private:
QListWidgetItem *addToExcludedPatternsList(const QString &pattern);
void loadSettings();
void saveSettings();
void prepareItem(QListWidgetItem *item) const;
Ui::TodoProjectSettingsWidget *ui;
ProjectExplorer::Project *m_project;
};
} // namespace Internal
} // namespace Todo
#endif // TODO_INTERNAL_TODOPROJECTSETTINGSWIDGET_H

View File

@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Todo::Internal::TodoProjectSettingsWidget</class>
<widget class="QWidget" name="Todo::Internal::TodoProjectSettingsWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>814</width>
<height>330</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="excludedPatternsBox">
<property name="title">
<string>Excluded Files</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QListWidget" name="excludedPatternsList">
<property name="toolTip">
<string>Regular expressions for file paths to be excluded from scanning.</string>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QPushButton" name="addExcludedPatternButton">
<property name="text">
<string>Add</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="removeExcludedPatternButton">
<property name="text">
<string>Remove</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>excludedPatternsList</sender>
<signal>itemSelectionChanged()</signal>
<receiver>Todo::Internal::TodoProjectSettingsWidget</receiver>
<slot>setExcludedPatternsButtonsEnabled()</slot>
<hints>
<hint type="sourcelabel">
<x>170</x>
<y>381</y>
</hint>
<hint type="destinationlabel">
<x>221</x>
<y>240</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>setExcludedPatternsButtonsEnabled()</slot>
</slots>
</ui>