Commit a429ef3d authored by Denis Kormalev's avatar Denis Kormalev

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: default avatarNikolai Kosjar <nikolai.kosjar@theqtcompany.com>
parent 4f5a02d5
...@@ -54,6 +54,8 @@ const char ITEMS_DISPLAY_PLACE[] = "ItemsDisplayPlace"; ...@@ -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 {
......
...@@ -46,9 +46,11 @@ CppTodoItemsScanner::CppTodoItemsScanner(const KeywordList &keywordList, QObject ...@@ -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) ...@@ -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) {
......
...@@ -47,7 +47,7 @@ public: ...@@ -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);
......
...@@ -44,12 +44,12 @@ OptionsDialog::OptionsDialog(QWidget *parent) : ...@@ -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() ...@@ -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() ...@@ -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() ...@@ -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) ...@@ -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
...@@ -57,18 +57,18 @@ public: ...@@ -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;
......
...@@ -6,8 +6,8 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -126,6 +126,6 @@
</connection> </connection>
</connections> </connections>
<slots> <slots>
<slot>setButtonsEnabled()</slot> <slot>setKeywordsButtonsEnabled()</slot>
</slots> </slots>
</ui> </ui>
...@@ -44,19 +44,22 @@ QmlJsTodoItemsScanner::QmlJsTodoItemsScanner(const KeywordList &keywordList, QOb ...@@ -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) ...@@ -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
......
...@@ -48,7 +48,7 @@ public: ...@@ -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);
......
...@@ -72,12 +72,12 @@ void Settings::load(QSettings *settings) ...@@ -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() ...@@ -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)
......
...@@ -16,7 +16,9 @@ HEADERS += todoplugin.h \ ...@@ -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 \ ...@@ -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
...@@ -26,6 +26,9 @@ QtcPlugin { ...@@ -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",
......
...@@ -66,15 +66,22 @@ TodoItemsModel *TodoItemsProvider::todoItemsModel() ...@@ -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() ...@@ -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() ...@@ -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();
}
} }
}