To-do plugin added.

Change-Id: Ideaf91b2f9ce3d9252ca40b7224a2ab4238341f1
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
Reviewed-by: Eike Ziller <eike.ziller@nokia.com>
This commit is contained in:
Dmitry Savchenko
2011-10-25 23:14:27 +03:00
committed by Eike Ziller
parent edb3094fa3
commit 5623e520d8
52 changed files with 2981 additions and 1235 deletions

View File

@@ -43,7 +43,8 @@ SUBDIRS = plugin_coreplugin \
plugin_qmlprofiler \ plugin_qmlprofiler \
plugin_remotelinux \ plugin_remotelinux \
plugin_madde \ plugin_madde \
plugin_valgrind plugin_valgrind \
plugin_todo
isEmpty(IDE_PACKAGE_MODE) { isEmpty(IDE_PACKAGE_MODE) {
SUBDIRS += plugin_helloworld \ SUBDIRS += plugin_helloworld \
@@ -51,7 +52,6 @@ isEmpty(IDE_PACKAGE_MODE) {
} else:!isEmpty(UPDATEINFO_ENABLE) { } else:!isEmpty(UPDATEINFO_ENABLE) {
SUBDIRS += plugin_updateinfo SUBDIRS += plugin_updateinfo
} }
linux-* { linux-* {
SUBDIRS += debugger/ptracepreload.pro SUBDIRS += debugger/ptracepreload.pro
} }
@@ -306,3 +306,9 @@ plugin_macros.depends = plugin_texteditor
plugin_macros.depends += plugin_find plugin_macros.depends += plugin_find
plugin_macros.depends += plugin_locator plugin_macros.depends += plugin_locator
plugin_macros.depends += plugin_coreplugin plugin_macros.depends += plugin_coreplugin
plugin_todo.subdir = todo
plugin_todo.depends = plugin_coreplugin
plugin_todo.depends += plugin_projectexplorer
plugin_todo.depends += plugin_texteditor
plugin_todo.depends += plugin_cpptools

View File

@@ -1,7 +0,0 @@
Installation.
1. Download QtCreator sources.
2. Build QtCreator from sources or download and install binary.
3. Change todoplugin.pro, You need QTC_BUILD_DIR set to your path to qtcreator binary and set QTC_SOURCE_DIR your path to qtcreator source
4. Build plugin:
qmake
make

View File

@@ -1,20 +0,0 @@
Copyright (c) 2010, Vasiliy Sorokin
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the vsorokin nor the names of its contributors may be used to endorse or
promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -0,0 +1,20 @@
<plugin name=\"Todo\" version=\"$$QTCREATOR_VERSION\" compatVersion=\"$$QTCREATOR_VERSION\">
<vendor>Dmitry Savchenko</vendor>
<copyright>(C) 2012 Dmitry Savchenko, (C) 2010 Vasiliy Sorokin</copyright>
<license>
Commercial Usage
Licensees holding valid Qt Commercial licenses may use this plugin in accordance with the Qt Commercial License Agreement provided with the Software or, alternatively, in accordance with the terms contained in a written agreement between you and Nokia.
GNU Lesser General Public License Usage
Alternatively, this plugin may be used under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation. 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.
</license>
<description>Adds pane that lists all TODO, FIXME, etc. entries in comments.</description>
<url>http://qt.nokia.com/</url>
<dependencyList>
<dependency name=\"Core\" version=\"$$QTCREATOR_VERSION\"/>
<dependency name=\"ProjectExplorer\" version=\"$$QTCREATOR_VERSION\"/>
<dependency name=\"TextEditor\" version=\"$$QTCREATOR_VERSION\"/>
</dependencyList>
</plugin>

View File

@@ -1,42 +0,0 @@
#include "addkeyworddialog.h"
#include "ui_addkeyworddialog.h"
#include <QColorDialog>
AddKeywordDialog::AddKeywordDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::AddKeywordDialog)
{
ui->setupUi(this);
this->ui->listWidget->setViewMode(QListWidget::IconMode);
this->ui->listWidget->addItem(new QListWidgetItem(QIcon(":/info"), "information"));
this->ui->listWidget->addItem(new QListWidgetItem(QIcon(":/warning"), "warning"));
this->ui->listWidget->addItem(new QListWidgetItem(QIcon(":/error"), "error"));
connect(this->ui->pushButton, SIGNAL(clicked()), this, SLOT(chooseColor()));
}
AddKeywordDialog::~AddKeywordDialog()
{
delete ui;
}
QString AddKeywordDialog::keywordName()
{
return this->ui->lineEdit->text();
}
QColor AddKeywordDialog::keywordColor()
{
return QColor(this->ui->colorEdit->text());
}
QIcon AddKeywordDialog::keywordIcon()
{
return this->ui->listWidget->currentItem()->icon();
}
void AddKeywordDialog::chooseColor()
{
QColorDialog *dialog = new QColorDialog(QColor(this->ui->colorEdit->text()),this);
this->ui->colorEdit->setText(dialog->getColor().name());
}

View File

@@ -1,28 +0,0 @@
#ifndef ADDKEYWORDDIALOG_H
#define ADDKEYWORDDIALOG_H
#include <QDialog>
namespace Ui {
class AddKeywordDialog;
}
class AddKeywordDialog : public QDialog
{
Q_OBJECT
public:
explicit AddKeywordDialog(QWidget *parent = 0);
~AddKeywordDialog();
QString keywordName();
QColor keywordColor();
QIcon keywordIcon();
public slots:
void chooseColor();
private:
Ui::AddKeywordDialog *ui;
};
#endif // ADDKEYWORDDIALOG_H

View File

@@ -0,0 +1,92 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Dmitry Savchenko.
** Copyright (c) 2010 Vasiliy Sorokin.
**
** 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 CONSTANTS_H
#define CONSTANTS_H
#include <QtGlobal>
namespace Todo {
namespace Constants {
// Default todo item background colors
const char COLOR_TODO_BG[] = "#ccffcc";
const char COLOR_WARNING_BG[] = "#ffffcc";
const char COLOR_FIXME_BG[] = "#ffcccc";
const char COLOR_BUG_BG[] = "#ffcccc";
const char COLOR_NOTE_BG[] = "#e0ebff";
// Todo item icons
// http://en.wikipedia.org/wiki/File:Information_icon_with_gradient_background.svg,
// public domain, tuned a bit
const char ICON_INFO[] = ":/todoplugin/images/info.png";
// Dummy, needs to be changed
const char ICON_TODO[] = ":/todoplugin/images/todo.png";
const char ICON_WARNING[] = ":/projectexplorer/images/compile_warning.png";
const char ICON_ERROR[] = ":/projectexplorer/images/compile_error.png";
// Public domain, Im the author
const char ICON_CURRENT_FILE[] = ":/todoplugin/images/current-file.png";
const char ICON_WHOLE_PROJECT[] = ":/todoplugin/images/whole-project.png";
// Settings entries
const char SETTINGS_GROUP[] = "TodoPlugin";
const char SCANNING_SCOPE[] = "ScanningScope";
const char ITEMS_DISPLAY_PLACE[] = "ItemsDisplayPlace";
const char KEYWORDS_LIST[] = "Keywords";
// TODO Output TreeWidget columns
enum OutputColumnIndex {
OUTPUT_COLUMN_TEXT,
OUTPUT_COLUMN_FILE,
OUTPUT_COLUMN_LINE,
OUTPUT_COLUMN_LAST
};
const char OUPTUT_COLUMN_TEXT_TITLE[] = QT_TRANSLATE_NOOP("TodoOutputPane", "Description");
const char OUTPUT_COLUMN_FILE_TITLE[] = QT_TRANSLATE_NOOP("TodoOutputPane", "File");
const char OUTPUT_COLUMN_LINE_TITLE[] = QT_TRANSLATE_NOOP("TodoOutputPane", "Line");
const int OUTPUT_TOOLBAR_SPACER_WIDHT = 25;
const int OUTPUT_PANE_UPDATE_INTERVAL = 2000;
const char OUTPUT_PANE_TITLE[] = QT_TRANSLATE_NOOP("TodoOutputPane", "To-Do Entries");
} // namespace Constants
} // namespace Todo
#endif // CONSTANTS_H

View File

@@ -0,0 +1,113 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Dmitry Savchenko.
** Copyright (c) 2010 Vasiliy Sorokin.
**
** 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 "cpptodoitemsscanner.h"
#include <projectexplorer/project.h>
#include <TranslationUnit.h>
namespace Todo {
namespace Internal {
CppTodoItemsScanner::CppTodoItemsScanner(const KeywordList &keywordList, QObject *parent) :
TodoItemsScanner(keywordList, parent)
{
CPlusPlus::CppModelManagerInterface *modelManager = CPlusPlus::CppModelManagerInterface::instance();
connect(modelManager, SIGNAL(documentUpdated(CPlusPlus::Document::Ptr)), this,
SLOT(documentUpdated(CPlusPlus::Document::Ptr)), Qt::DirectConnection);
}
bool CppTodoItemsScanner::shouldProcessFile(const QString &fileName)
{
CPlusPlus::CppModelManagerInterface *modelManager = CPlusPlus::CppModelManagerInterface::instance();
foreach (const CPlusPlus::CppModelManagerInterface::ProjectInfo &info, modelManager->projectInfos())
if (info.project().data()->files(ProjectExplorer::Project::ExcludeGeneratedFiles).contains(fileName))
return true;
return false;
}
void CppTodoItemsScanner::keywordListChanged()
{
// 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.
CPlusPlus::CppModelManagerInterface *modelManager = CPlusPlus::CppModelManagerInterface::instance();
QStringList filesToBeUpdated;
foreach (const CPlusPlus::CppModelManagerInterface::ProjectInfo &info, modelManager->projectInfos())
filesToBeUpdated << info.project().data()->files(ProjectExplorer::Project::ExcludeGeneratedFiles);
modelManager->updateSourceFiles(filesToBeUpdated);
}
void CppTodoItemsScanner::documentUpdated(CPlusPlus::Document::Ptr doc)
{
if (shouldProcessFile(doc->fileName()))
processDocument(doc);
}
void CppTodoItemsScanner::processDocument(CPlusPlus::Document::Ptr doc)
{
QList<TodoItem> itemList;
CPlusPlus::TranslationUnit *translationUnit = doc->translationUnit();
for (unsigned i = 0; i < translationUnit->commentCount(); ++i) {
// Get comment source
CPlusPlus::Token token = doc->translationUnit()->commentAt(i);
QByteArray source = doc->utf8Source().mid(token.begin(), token.length()).trimmed();
if ((token.kind() == CPlusPlus::T_COMMENT) || (token.kind() == CPlusPlus::T_DOXY_COMMENT)) {
// Remove trailing "*/"
source = source.left(source.length() - 2);
}
// Process every line of the comment
// TODO: Do not create QStringList, just iterate through a string tracking line endings.
QStringList commentLines = QString::fromUtf8(source).split("\n", QString::SkipEmptyParts);
unsigned lineNumber = 0;
translationUnit->getPosition(token.begin(), &lineNumber);
for (int j = 0; j < commentLines.count(); ++j) {
const QString &commentLine = commentLines.at(j);
processCommentLine(doc->fileName(), commentLine, lineNumber + j, itemList);
}
}
emit itemsFetched(doc->fileName(), itemList);
}
}
}

View File

@@ -0,0 +1,65 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Dmitry Savchenko.
** Copyright (c) 2010 Vasiliy Sorokin.
**
** 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 CPPTODOITEMSSCANNER_H
#define CPPTODOITEMSSCANNER_H
#include "todoitemsscanner.h"
#include <cplusplus/ModelManagerInterface.h>
namespace Todo {
namespace Internal {
class CppTodoItemsScanner : public TodoItemsScanner
{
Q_OBJECT
public:
explicit CppTodoItemsScanner(const KeywordList &keywordList, QObject *parent = 0);
protected:
bool shouldProcessFile(const QString &fileName);
void keywordListChanged();
private slots:
void documentUpdated(CPlusPlus::Document::Ptr doc);
private:
void processDocument(CPlusPlus::Document::Ptr doc);
};
}
}
#endif // CPPTODOITEMSSCANNER_H

View File

@@ -1,8 +0,0 @@
<RCC>
<qresource prefix="/">
<file alias="error">images/error.png</file>
<file alias="info">images/info.png</file>
<file alias="warning">images/warning.png</file>
<file alias="todo">images/todo.png</file>
</qresource>
</RCC>

Binary file not shown.

After

Width:  |  Height:  |  Size: 257 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 640 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 856 B

After

Width:  |  Height:  |  Size: 854 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 195 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 511 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 317 B

View File

@@ -1,26 +1,61 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Dmitry Savchenko.
** Copyright (c) 2010 Vasiliy Sorokin.
**
** 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 "keyword.h" #include "keyword.h"
Keyword::Keyword() namespace Todo {
namespace Internal {
Keyword::Keyword() : color(Qt::white)
{ {
} }
Keyword::Keyword(QString name_, QIcon icon_, QColor warningColor_) : bool Keyword::equals(const Keyword &other) const
name(name_), icon(icon_), warningColor(warningColor_)
{ {
return (this->name == other.name)
&& (this->iconResource == other.iconResource)
&& (this->color == other.color);
} }
QDataStream &operator<<(QDataStream &out, const Keyword &myObj) bool operator ==(Keyword &k1, Keyword &k2)
{ {
out << myObj.name; return k1.equals(k2);
out << myObj.icon;
out << myObj.warningColor;
return out;
} }
QDataStream &operator>>(QDataStream &in, Keyword &myObj) bool operator !=(Keyword &k1, Keyword &k2)
{ {
in >> myObj.name; return !k1.equals(k2);
in >> myObj.icon;
in >> myObj.warningColor;
return in;
} }
} // namespace Internal
} // namespace Todo

View File

@@ -1,3 +1,36 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Dmitry Savchenko.
** Copyright (c) 2010 Vasiliy Sorokin.
**
** 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 KEYWORD_H #ifndef KEYWORD_H
#define KEYWORD_H #define KEYWORD_H
@@ -7,23 +40,26 @@
#include <QList> #include <QList>
#include <QMetaType> #include <QMetaType>
namespace Todo {
namespace Internal {
class Keyword class Keyword
{ {
public: public:
Keyword(); Keyword();
Keyword(QString name_, QIcon icon_, QColor warningColor_);
QString name; QString name;
QIcon icon; QString iconResource;
QColor warningColor; QColor color;
bool equals(const Keyword &other) const;
}; };
typedef QList<Keyword> KeywordsList; typedef QList<Keyword> KeywordList;
QDataStream &operator<<(QDataStream &out, const Keyword &myObj); bool operator ==(Keyword &k1, Keyword &k2);
QDataStream &operator>>(QDataStream &in, Keyword &myObj); bool operator !=(Keyword &k1, Keyword &k2);
} // namespace Internal
Q_DECLARE_METATYPE(KeywordsList) } // namespace Todo
Q_DECLARE_METATYPE(Keyword)
#endif // KEYWORD_H #endif // KEYWORD_H

View File

@@ -0,0 +1,106 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Dmitry Savchenko.
** Copyright (c) 2010 Vasiliy Sorokin.
**
** 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 "keyworddialog.h"
#include "ui_keyworddialog.h"
#include "constants.h"
#include <QColorDialog>
namespace Todo {
namespace Internal {
KeywordDialog::KeywordDialog(const Keyword &keyword, QWidget *parent) :
QDialog(parent),
ui(new Ui::AddKeywordDialog)
{
ui->setupUi(this);
setupListWidget(keyword.iconResource);
setupColorWidgets(keyword.color);
ui->keywordNameEdit->setText(keyword.name);
}
KeywordDialog::~KeywordDialog()
{
delete ui;
}
Keyword KeywordDialog::keyword()
{
Keyword result;
result.name = ui->keywordNameEdit->text();
result.iconResource = ui->listWidget->currentItem()->data(Qt::UserRole).toString();
result.color = ui->colorEdit->text();
return result;
}
void KeywordDialog::colorSelected(const QColor &color)
{
ui->colorEdit->setText(color.name());
}
void KeywordDialog::setupListWidget(const QString &selectedIcon)
{
ui->listWidget->setViewMode(QListWidget::IconMode);
QListWidgetItem *item = new QListWidgetItem(QIcon(Constants::ICON_INFO), "information");
item->setData(Qt::UserRole, Constants::ICON_INFO);
ui->listWidget->addItem(item);
item = new QListWidgetItem(QIcon(Constants::ICON_WARNING), "warning");
item->setData(Qt::UserRole, Constants::ICON_WARNING);
ui->listWidget->addItem(item);
item = new QListWidgetItem(QIcon(Constants::ICON_ERROR), "error");
item->setData(Qt::UserRole, Constants::ICON_ERROR);
ui->listWidget->addItem(item);
for (int i = 0; i < ui->listWidget->count(); ++i) {
item = ui->listWidget->item(i);
if (item->data(Qt::UserRole).toString() == selectedIcon) {
ui->listWidget->setCurrentItem(item);
break;
}
}
}
void KeywordDialog::setupColorWidgets(const QColor &color)
{
ui->colorButton->setColor(color);
ui->colorEdit->setText(color.name());
connect(ui->colorButton, SIGNAL(colorChanged(QColor)), SLOT(colorSelected(QColor)));
}
} // namespace Internal
} // namespace Todo

View File

@@ -0,0 +1,69 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Dmitry Savchenko.
** Copyright (c) 2010 Vasiliy Sorokin.
**
** 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 ADDKEYWORDDIALOG_H
#define ADDKEYWORDDIALOG_H
#include "keyword.h"
#include <QDialog>
namespace Todo {
namespace Internal {
namespace Ui {
class AddKeywordDialog;
}
class KeywordDialog : public QDialog
{
Q_OBJECT
public:
KeywordDialog(const Keyword &keyword, QWidget *parent = 0);
~KeywordDialog();
Keyword keyword();
private slots:
void colorSelected(const QColor &color);
private:
void setupListWidget(const QString &selectedIcon);
void setupColorWidgets(const QColor &color);
Ui::AddKeywordDialog *ui;
};
} // namespace Internal
} // namespace Todo
#endif // ADDKEYWORDDIALOG_H

View File

@@ -1,23 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"> <ui version="4.0">
<class>AddKeywordDialog</class> <class>Todo::Internal::AddKeywordDialog</class>
<widget class="QDialog" name="AddKeywordDialog"> <widget class="QDialog" name="Todo::Internal::AddKeywordDialog">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>379</width> <width>379</width>
<height>225</height> <height>233</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>Dialog</string> <string>Keyword</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_3"> <layout class="QVBoxLayout" name="verticalLayout_3">
<item> <item>
<widget class="QLabel" name="label"> <widget class="QLabel" name="label">
<property name="text"> <property name="text">
<string>Icons</string> <string>Icon</string>
</property> </property>
</widget> </widget>
</item> </item>
@@ -33,11 +33,8 @@
<property name="title"> <property name="title">
<string>Color</string> <string>Color</string>
</property> </property>
<layout class="QFormLayout" name="formLayout"> <layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="fieldGrowthPolicy"> <item>
<enum>QFormLayout::ExpandingFieldsGrow</enum>
</property>
<item row="2" column="0">
<widget class="QLineEdit" name="colorEdit"> <widget class="QLineEdit" name="colorEdit">
<property name="inputMask"> <property name="inputMask">
<string>\#HHHHHH; </string> <string>\#HHHHHH; </string>
@@ -47,10 +44,19 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="1"> <item>
<widget class="QPushButton" name="pushButton"> <widget class="Utils::QtColorButton" name="colorButton">
<property name="text"> <property name="sizePolicy">
<string>Choose</string> <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>64</width>
<height>0</height>
</size>
</property> </property>
</widget> </widget>
</item> </item>
@@ -64,7 +70,7 @@
</property> </property>
<layout class="QHBoxLayout" name="horizontalLayout"> <layout class="QHBoxLayout" name="horizontalLayout">
<item> <item>
<widget class="QLineEdit" name="lineEdit"/> <widget class="QLineEdit" name="keywordNameEdit"/>
</item> </item>
</layout> </layout>
</widget> </widget>
@@ -85,12 +91,19 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<customwidgets>
<customwidget>
<class>Utils::QtColorButton</class>
<extends>QToolButton</extends>
<header location="global">utils/qtcolorbutton.h</header>
</customwidget>
</customwidgets>
<resources/> <resources/>
<connections> <connections>
<connection> <connection>
<sender>buttonBox</sender> <sender>buttonBox</sender>
<signal>accepted()</signal> <signal>accepted()</signal>
<receiver>AddKeywordDialog</receiver> <receiver>Todo::Internal::AddKeywordDialog</receiver>
<slot>accept()</slot> <slot>accept()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">
@@ -106,7 +119,7 @@
<connection> <connection>
<sender>buttonBox</sender> <sender>buttonBox</sender>
<signal>rejected()</signal> <signal>rejected()</signal>
<receiver>AddKeywordDialog</receiver> <receiver>Todo::Internal::AddKeywordDialog</receiver>
<slot>reject()</slot> <slot>reject()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">

View File

@@ -0,0 +1,148 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Dmitry Savchenko.
** Copyright (c) 2010 Vasiliy Sorokin.
**
** 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 "lineparser.h"
#include <QMap>
namespace Todo {
namespace Internal {
LineParser::LineParser()
{
}
LineParser::LineParser(const KeywordList &keywordList)
{
setKeywordList(keywordList);
}
void LineParser::setKeywordList(const KeywordList &keywordList)
{
m_keywords = keywordList;
}
QList<TodoItem> LineParser::parse(const QString &line)
{
QMap<int, int> entryCandidates = findKeywordEntryCandidates(line);
QList<KeywordEntry> entries = keywordEntriesFromCandidates(entryCandidates, line);
return todoItemsFromKeywordEntries(entries);
}
LineParser::KeywordEntryCandidates LineParser::findKeywordEntryCandidates(const QString &line)
{
KeywordEntryCandidates entryCandidates;
for (int i = 0; i < m_keywords.count(); ++i) {
int searchFrom = -1;
forever {
int index = line.lastIndexOf(m_keywords.at(i).name + ":", searchFrom);
if (index == -1)
break; // 'forever' loop exit condition
searchFrom = index - line.length() - 1;
if (!isFirstCharOfTheWord(index, line))
continue;
entryCandidates.insert(index, i);
}
}
return entryCandidates;
}
bool LineParser::isFirstCharOfTheWord(int index, const QString &line)
{
return (index == 0) || !line.at(index - 1).isLetterOrNumber();
}
QList<LineParser::KeywordEntry> LineParser::keywordEntriesFromCandidates(
const QMap<int, int> &candidates, const QString &line)
{
// Ensure something is found
if (candidates.isEmpty())
return QList<KeywordEntry>();
// Convert candidates to entries
QList<KeywordEntry> entries;
QMapIterator<int, int> i(candidates);
i.toBack();
while (i.hasPrevious()) {
i.previous();
KeywordEntry entry;
entry.keywordStart = i.key();
entry.keywordIndex = i.value();
int keywordLength = m_keywords.at(entry.keywordIndex).name.length() + 1; // include colon
int entryTextLength = -1;
if (!entries.empty())
entryTextLength = entries.last().keywordStart - (entry.keywordStart + keywordLength);
entry.text = line.mid(entry.keywordStart + keywordLength, entryTextLength).trimmed();
if (entry.text.isEmpty() && !entries.empty())
// Take the text form the previous entry, consider:
// '<keyword1>: <keyword2>: <some text>'
entry.text = entries.last().text;
entries << entry;
}
return entries;
}
QList<TodoItem> LineParser::todoItemsFromKeywordEntries(const QList<KeywordEntry> &entries)
{
QList<TodoItem> todoItems;
foreach (const KeywordEntry &entry, entries) {
TodoItem item;
item.text = QString("%1: %2")
.arg(m_keywords.at(entry.keywordIndex).name)
.arg(entry.text);
item.color = m_keywords.at(entry.keywordIndex).color;
item.iconResource = m_keywords.at(entry.keywordIndex).iconResource;
todoItems << item;
}
return todoItems;
}
} // namespace Internal
} // namespace Todo

View File

@@ -0,0 +1,75 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Dmitry Savchenko.
** Copyright (c) 2010 Vasiliy Sorokin.
**
** 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 LINEPARSER_H
#define LINEPARSER_H
#include "keyword.h"
#include "todoitem.h"
namespace Todo {
namespace Internal {
class LineParser
{
public:
LineParser();
explicit LineParser(const KeywordList &keywordList);
void setKeywordList(const KeywordList &keywordList);
QList<TodoItem> parse(const QString &line);
private:
// map key here is keyword start position in the text line
// and map value is keyword index in m_keywords
typedef QMap<int, int> KeywordEntryCandidates;
struct KeywordEntry {
int keywordIndex;
int keywordStart;
QString text;
};
KeywordEntryCandidates findKeywordEntryCandidates(const QString &line);
bool isFirstCharOfTheWord(int index, const QString &line);
QList<KeywordEntry> keywordEntriesFromCandidates(const QMap<int, int> &candidates, const QString &line);
QList<TodoItem> todoItemsFromKeywordEntries(const QList<KeywordEntry> &entries);
KeywordList m_keywords;
};
} // namespace Internal
} // namespace Todo
#endif // LINEPARSER_H

View File

@@ -0,0 +1,160 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Dmitry Savchenko.
** Copyright (c) 2010 Vasiliy Sorokin.
**
** 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 "optionsdialog.h"
#include "ui_optionsdialog.h"
#include "keyworddialog.h"
#include "constants.h"
namespace Todo {
namespace Internal {
OptionsDialog::OptionsDialog(QWidget *parent) :
QWidget(parent),
ui(new Ui::OptionsDialog)
{
ui->setupUi(this);
setButtonsEnabled();
connect(ui->addButton, SIGNAL(clicked()), SLOT(addButtonClicked()));
connect(ui->removeButton, SIGNAL(clicked()), SLOT(removeButtonClicked()));
connect(ui->editButton, SIGNAL(clicked()), SLOT(editButtonClicked()));
connect(ui->resetButton, SIGNAL(clicked()), SLOT(resetButtonClicked()));
}
OptionsDialog::~OptionsDialog()
{
delete ui;
}
void OptionsDialog::setSettings(const Settings &settings)
{
uiFromSettings(settings);
}
void OptionsDialog::addToKeywordsList(const Keyword &keyword)
{
QListWidgetItem *item = new QListWidgetItem(QIcon(keyword.iconResource), keyword.name);
item->setData(Qt::UserRole, keyword.iconResource);
item->setBackgroundColor(keyword.color);
ui->keywordsList->addItem(item);
}
Settings OptionsDialog::settings()
{
return settingsFromUi();
}
void OptionsDialog::addButtonClicked()
{
Keyword keyword;
KeywordDialog *addKeywordDialog = new KeywordDialog(keyword, this);
if (addKeywordDialog->exec() == QDialog::Accepted) {
keyword = addKeywordDialog->keyword();
addToKeywordsList(keyword);
}
}
void OptionsDialog::editButtonClicked()
{
QListWidgetItem *item = ui->keywordsList->currentItem();
Keyword keyword;
keyword.name = item->text();
keyword.iconResource = item->data(Qt::UserRole).toString();
keyword.color = item->backgroundColor();
KeywordDialog *addKeywordDialog = new KeywordDialog(keyword, this);
if (addKeywordDialog->exec() == QDialog::Accepted) {
keyword = addKeywordDialog->keyword();
item->setIcon(QIcon(keyword.iconResource));
item->setText(keyword.name);
item->setData(Qt::UserRole, keyword.iconResource);
item->setBackgroundColor(keyword.color);
}
}
void OptionsDialog::removeButtonClicked()
{
ui->keywordsList->takeItem(ui->keywordsList->currentRow());
}
void OptionsDialog::resetButtonClicked()
{
Settings newSettings;
newSettings.setDefault();
uiFromSettings(newSettings);
}
void OptionsDialog::setButtonsEnabled()
{
bool isSomethingSelected = ui->keywordsList->selectedItems().count() != 0;
ui->removeButton->setEnabled(isSomethingSelected);
ui->editButton->setEnabled(isSomethingSelected);
}
void OptionsDialog::uiFromSettings(const Settings &settings)
{
ui->scanInCurrentFileRadioButton->setChecked(settings.scanningScope == ScanningScopeCurrentFile);
ui->scanInProjectRadioButton->setChecked(settings.scanningScope == ScanningScopeProject);
ui->keywordsList->clear();
foreach (const Keyword &keyword, settings.keywords)
addToKeywordsList(keyword);
}
Settings OptionsDialog::settingsFromUi()
{
Settings settings;
if (ui->scanInCurrentFileRadioButton->isChecked())
settings.scanningScope = ScanningScopeCurrentFile;
else
settings.scanningScope = ScanningScopeProject;
settings.keywords.clear();
for (int i = 0; i < ui->keywordsList->count(); ++i) {
QListWidgetItem *item = ui->keywordsList->item(i);
Keyword keyword;
keyword.name = item->text();
keyword.iconResource = item->data(Qt::UserRole).toString();
keyword.color = item->backgroundColor();
settings.keywords << keyword;
}
return settings;
}
} // namespace Internal
} // namespace Todo

View File

@@ -0,0 +1,77 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Dmitry Savchenko.
** Copyright (c) 2010 Vasiliy Sorokin.
**
** 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 OPTIONSDIALOG_H
#define OPTIONSDIALOG_H
#include "keyword.h"
#include "settings.h"
#include <QWidget>
namespace Todo {
namespace Internal {
namespace Ui {
class OptionsDialog;
}
class OptionsDialog : public QWidget
{
Q_OBJECT
public:
explicit OptionsDialog(QWidget *parent = 0);
~OptionsDialog();
void setSettings(const Settings &settings);
Settings settings();
private slots:
void addButtonClicked();
void editButtonClicked();
void removeButtonClicked();
void resetButtonClicked();
void setButtonsEnabled();
private:
void uiFromSettings(const Settings &settings);
Settings settingsFromUi();
void addToKeywordsList(const Keyword &keyword);
Ui::OptionsDialog *ui;
};
} // namespace Internal
} // namespace Todo
#endif // OPTIONSDIALOG_H

View File

@@ -0,0 +1,131 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Todo::Internal::OptionsDialog</class>
<widget class="QWidget" name="Todo::Internal::OptionsDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>377</width>
<height>299</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Keywords</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QListWidget" name="keywordsList">
<property name="sortingEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="addButton">
<property name="text">
<string>Add</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="editButton">
<property name="text">
<string>Edit</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="removeButton">
<property name="text">
<string>Remove</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="resetButton">
<property name="text">
<string>Reset</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="scanningScopeGroupBox">
<property name="title">
<string>Scanning scope</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QRadioButton" name="scanInProjectRadioButton">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Scan in the whole project</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="scanInCurrentFileRadioButton">
<property name="text">
<string>Scan in the current opened file</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>keywordsList</sender>
<signal>itemSelectionChanged()</signal>
<receiver>Todo::Internal::OptionsDialog</receiver>
<slot>setButtonsEnabled()</slot>
<hints>
<hint type="sourcelabel">
<x>247</x>
<y>176</y>
</hint>
<hint type="destinationlabel">
<x>5</x>
<y>137</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>setButtonsEnabled()</slot>
</slots>
</ui>

View File

@@ -0,0 +1,127 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Dmitry Savchenko.
** Copyright (c) 2010 Vasiliy Sorokin.
**
** 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 "optionspage.h"
#include "constants.h"
#include <coreplugin/icore.h>
#include <QList>
#include <QMessageBox>
Todo::Internal::OptionsDialog *some = 0;
namespace Todo {
namespace Internal {
OptionsPage::OptionsPage(const Settings &settings, QObject *parent) :
IOptionsPage(parent),
m_dialog(0)
{
setSettings(settings);
}
OptionsPage::~OptionsPage()
{
}
void OptionsPage::setSettings(const Settings &settings)
{
m_settings = settings;
}
QString OptionsPage::id() const
{
return "TodoSettings";
}
QString OptionsPage::trName() const
{
return tr("To-Do");
}
QString OptionsPage::category() const
{
return "To-Do";
}
QString OptionsPage::trCategory() const
{
return tr("To-Do");
}
QString OptionsPage::displayName() const
{
return trName();
}
QString OptionsPage::displayCategory() const
{
return trCategory();
}
QIcon OptionsPage::categoryIcon() const
{
return QIcon(Constants::ICON_TODO);
}
QWidget *OptionsPage::createPage(QWidget *parent)
{
m_dialog = new OptionsDialog(parent);
m_dialog->setSettings(m_settings);
return m_dialog;
}
void OptionsPage::apply()
{
Settings newSettings = m_dialog->settings();
if (newSettings != m_settings) {
m_settings = newSettings;
emit settingsChanged(m_settings);
}
}
void OptionsPage::finish()
{
}
bool OptionsPage::matches(const QString &searchKeyWord) const
{
return searchKeyWord == QString("todo");
}
} // namespace Internal
} // namespace Todo

View File

@@ -0,0 +1,77 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Dmitry Savchenko.
** Copyright (c) 2010 Vasiliy Sorokin.
**
** 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 SETTINGSPAGE_H
#define SETTINGSPAGE_H
#include "optionsdialog.h"
#include "settings.h"
#include <coreplugin/dialogs/ioptionspage.h>
namespace Todo {
namespace Internal {
class OptionsPage : public Core::IOptionsPage
{
Q_OBJECT
public:
OptionsPage(const Settings &settings, QObject *parent = 0);
~OptionsPage();
void setSettings(const Settings &settings);
QString id() const;
QString trName() const;
QString category() const;
QString trCategory() const;
QString displayName() const;
QIcon categoryIcon() const;
QString displayCategory() const;
QWidget *createPage(QWidget *parent);
void apply();
void finish();
bool matches(const QString &searchKeyWord) const;
signals:
void settingsChanged(const Settings &settings);
private:
OptionsDialog *m_dialog;
Settings m_settings;
};
} // namespace Internal
} // namespace Todo
#endif // SETTINGSPAGE_H

View File

@@ -0,0 +1,102 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Dmitry Savchenko.
** Copyright (c) 2010 Vasiliy Sorokin.
**
** 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 "qmljstodoitemsscanner.h"
#include <projectexplorer/project.h>
namespace Todo {
namespace Internal {
QmlJsTodoItemsScanner::QmlJsTodoItemsScanner(const KeywordList &keywordList, QObject *parent) :
TodoItemsScanner(keywordList, parent)
{
QmlJS::ModelManagerInterface *model = QmlJS::ModelManagerInterface::instance();
connect(model, SIGNAL(documentUpdated(QmlJS::Document::Ptr)),
this, SLOT(documentUpdated(QmlJS::Document::Ptr)), Qt::DirectConnection);
}
bool QmlJsTodoItemsScanner::shouldProcessFile(const QString &fileName)
{
QmlJS::ModelManagerInterface *modelManager = QmlJS::ModelManagerInterface::instance();
foreach (const QmlJS::ModelManagerInterface::ProjectInfo &info, modelManager->projectInfos())
if (info.project->files(ProjectExplorer::Project::ExcludeGeneratedFiles).contains(fileName))
return true;
return false;
}
void QmlJsTodoItemsScanner::keywordListChanged()
{
// 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.
QmlJS::ModelManagerInterface *modelManager = QmlJS::ModelManagerInterface::instance();
QStringList filesToBeUpdated;
foreach (const QmlJS::ModelManagerInterface::ProjectInfo &info, modelManager->projectInfos())
filesToBeUpdated << info.project->files(ProjectExplorer::Project::ExcludeGeneratedFiles);
modelManager->updateSourceFiles(filesToBeUpdated, false);
}
void QmlJsTodoItemsScanner::documentUpdated(QmlJS::Document::Ptr doc)
{
if (shouldProcessFile(doc->fileName()))
processDocument(doc);
}
void QmlJsTodoItemsScanner::processDocument(QmlJS::Document::Ptr doc)
{
QList<TodoItem> itemList;
foreach (const QmlJS::AST::SourceLocation &sourceLocation, doc->engine()->comments()) {
QString source = doc->source().mid(sourceLocation.begin(), sourceLocation.length).trimmed();
// Process every line
// TODO: Do not create QStringList, just iterate through a string tracking line endings.
QStringList commentLines = source.split("\n", QString::SkipEmptyParts);
quint32 startLine = sourceLocation.startLine;
for (int j = 0; j < commentLines.count(); ++j) {
const QString &commentLine = commentLines.at(j);
processCommentLine(doc->fileName(), commentLine, startLine + j, itemList);
}
}
emit itemsFetched(doc->fileName(), itemList);
}
}
}

View File

@@ -0,0 +1,64 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Dmitry Savchenko.
** Copyright (c) 2010 Vasiliy Sorokin.
**
** 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 QMLJSTODOITEMSSCANNER_H
#define QMLJSTODOITEMSSCANNER_H
#include "todoitemsscanner.h"
#include <qmljs/qmljsmodelmanagerinterface.h>
namespace Todo {
namespace Internal {
class QmlJsTodoItemsScanner : public TodoItemsScanner
{
Q_OBJECT
public:
explicit QmlJsTodoItemsScanner(const KeywordList &keywordList, QObject *parent = 0);
protected:
bool shouldProcessFile(const QString &fileName);
void keywordListChanged();
private slots:
void documentUpdated(QmlJS::Document::Ptr doc);
private:
void processDocument(QmlJS::Document::Ptr doc);
};
}
}
#endif // QMLJSTODOITEMSSCANNER_H

View File

@@ -0,0 +1,138 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Dmitry Savchenko.
** Copyright (c) 2010 Vasiliy Sorokin.
**
** 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 "settings.h"
#include "constants.h"
namespace Todo {
namespace Internal {
void Settings::save(QSettings *settings) const
{
settings->beginGroup(Constants::SETTINGS_GROUP);
settings->setValue(Constants::SCANNING_SCOPE, scanningScope);
settings->beginWriteArray(Constants::KEYWORDS_LIST);
for (int i = 0; i < keywords.size(); ++i) {
settings->setArrayIndex(i);
settings->setValue("name", keywords.at(i).name);
settings->setValue("color", keywords.at(i).color);
settings->setValue("iconResource", keywords.at(i).iconResource);
}
settings->endArray();
settings->endGroup();
settings->sync();
}
void Settings::load(QSettings *settings)
{
setDefault();
settings->beginGroup(Constants::SETTINGS_GROUP);
scanningScope = static_cast<ScanningScope>(settings->value(Constants::SCANNING_SCOPE,
scanningScope).toInt());
KeywordList newKeywords;
int size = settings->beginReadArray(Constants::KEYWORDS_LIST);
if (size > 0) {
for (int i = 0; i < size; ++i) {
settings->setArrayIndex(i);
Keyword keyword;
keyword.name = settings->value("name").toString();
keyword.color = settings->value("color").value<QColor>();
keyword.iconResource = settings->value("iconResource").toString();
newKeywords << keyword;
}
keywords = newKeywords;
}
settings->endArray();
settings->endGroup();
}
void Settings::setDefault()
{
scanningScope = ScanningScopeCurrentFile;
keywords.clear();
Keyword keyword;
keyword.name = QLatin1String("TODO");
keyword.iconResource = QLatin1String(Constants::ICON_WARNING);
keyword.color = QColor(QLatin1String(Constants::COLOR_TODO_BG));
keywords.append(keyword);
keyword.name = QLatin1String("NOTE");
keyword.iconResource = QLatin1String(Constants::ICON_INFO);
keyword.color = QColor(QLatin1String(Constants::COLOR_NOTE_BG));
keywords.append(keyword);
keyword.name = QLatin1String("FIXME");
keyword.iconResource = QLatin1String(Constants::ICON_ERROR);
keyword.color = QColor(QLatin1String(Constants::COLOR_FIXME_BG));
keywords.append(keyword);
keyword.name = QLatin1String("BUG");
keyword.iconResource = QLatin1String(Constants::ICON_ERROR);
keyword.color = QColor(QLatin1String(Constants::COLOR_BUG_BG));
keywords.append(keyword);
keyword.name = QLatin1String("WARNING");
keyword.iconResource = QLatin1String(Constants::ICON_WARNING);
keyword.color = QColor(QLatin1String(Constants::COLOR_WARNING_BG));
keywords.append(keyword);
}
bool Settings::equals(const Settings &other) const
{
return (keywords == other.keywords)
&& (scanningScope == other.scanningScope);
}
bool operator ==(Settings &s1, Settings &s2)
{
return s1.equals(s2);
}
bool operator !=(Settings &s1, Settings &s2)
{
return !s1.equals(s2);
}
} // namespace Internal
} // namespace Todo

View File

@@ -0,0 +1,66 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Dmitry Savchenko.
** Copyright (c) 2010 Vasiliy Sorokin.
**
** 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 SETTINGS_H
#define SETTINGS_H
#include "keyword.h"
#include <QSettings>
namespace Todo {
namespace Internal {
enum ScanningScope {
ScanningScopeCurrentFile,
ScanningScopeProject
};
struct Settings {
KeywordList keywords;
ScanningScope scanningScope;
void save(QSettings *settings) const;
void load(QSettings *settings);
void setDefault();
bool equals(const Settings &other) const;
};
bool operator ==(Settings &s1, Settings &s2);
bool operator !=(Settings &s1, Settings &s2);
} // namespace Internal
} // namespace Todo
Q_DECLARE_METATYPE(Todo::Internal::ScanningScope)
#endif // SETTINGS_H

View File

@@ -1,138 +0,0 @@
#include "settingsdialog.h"
#include "ui_settingsdialog.h"
#include "addkeyworddialog.h"
SettingsDialog::SettingsDialog(QWidget *parent) :
QWidget(parent),
ui(new Ui::SettingsDialog)
{
ui->setupUi(this);
connect(this->ui->addButton, SIGNAL(clicked()), this, SLOT(addButtonClicked()));
connect(this->ui->removeButton, SIGNAL(clicked()), this, SLOT(removeButtonClicked()));
connect(this->ui->resetButton, SIGNAL(clicked()), this, SLOT(resetButtonClicked()));
connect(this->ui->buildIssuesRadioButton, SIGNAL(toggled(bool)), this, SIGNAL(settingsChanged()));
connect(this->ui->todoOutputRadioButton, SIGNAL(toggled(bool)), this, SIGNAL(settingsChanged()));
connect(this->ui->projectRadioButton, SIGNAL(toggled(bool)), this, SIGNAL(settingsChanged()));
connect(this->ui->currentFileRadioButton, SIGNAL(toggled(bool)), this, SIGNAL(settingsChanged()));
}
SettingsDialog::~SettingsDialog()
{
delete ui;
}
void SettingsDialog::setProjectRadioButtonEnabled(bool what)
{
this->ui->projectRadioButton->setChecked(what);
}
void SettingsDialog::setCurrentFileRadioButtonEnabled(bool what)
{
this->ui->currentFileRadioButton->setChecked(what);
}
void SettingsDialog::setBuildIssuesRadioButtonEnabled(bool what)
{
this->ui->buildIssuesRadioButton->setChecked(what);
}
void SettingsDialog::setTodoOutputRadioButtonEnabled(bool what)
{
this->ui->todoOutputRadioButton->setChecked(what);
}
void SettingsDialog::addToKeywordsList(Keyword keyword)
{
QListWidgetItem *item = new QListWidgetItem(keyword.icon, keyword.name);
item->setBackgroundColor(keyword.warningColor);
this->ui->keywordsList->addItem(item);
}
void SettingsDialog::setKeywordsList(KeywordsList list)
{
if (!list.count())
{
resetButtonClicked();
}
else
{
for (int i = 0; i < list.count(); ++i)
{
addToKeywordsList(list.at(i));
}
}
}
bool SettingsDialog::projectRadioButtonEnabled()
{
return this->ui->projectRadioButton->isChecked();
}
bool SettingsDialog::currentFileRadioButtonEnabled()
{
return this->ui->currentFileRadioButton->isChecked();
}
bool SettingsDialog::buildIssuesRadioButtonEnabled()
{
return this->ui->buildIssuesRadioButton->isChecked();
}
bool SettingsDialog::todoOutputRadioButtonEnabled()
{
return this->ui->todoOutputRadioButton->isChecked();
}
KeywordsList SettingsDialog::keywordsList()
{
KeywordsList list;
for (int i = 0; i < this->ui->keywordsList->count(); ++i)
{
Keyword keyword;
keyword.name = this->ui->keywordsList->item(i)->text();
keyword.icon = this->ui->keywordsList->item(i)->icon();
keyword.warningColor = this->ui->keywordsList->item(i)->backgroundColor();
list.append(keyword);
}
return list;
}
void SettingsDialog::clearKeywordsList()
{
this->ui->keywordsList->clear();
}
void SettingsDialog::addButtonClicked()
{
Keyword keyword;
AddKeywordDialog *addKeywordDialog = new AddKeywordDialog(this);
if (addKeywordDialog->exec() == QDialog::Accepted)
{
keyword.name = addKeywordDialog->keywordName();
keyword.icon = addKeywordDialog->keywordIcon();
keyword.warningColor = addKeywordDialog->keywordColor();
addToKeywordsList(keyword);
emit settingsChanged();
}
}
void SettingsDialog::removeButtonClicked()
{
this->ui->keywordsList->takeItem(this->ui->keywordsList->currentRow());
emit settingsChanged();
}
void SettingsDialog::resetButtonClicked()
{
clearKeywordsList();
addToKeywordsList(Keyword("TODO", QIcon(":/warning"), QColor("#BFFFC8")));
addToKeywordsList(Keyword("NOTE", QIcon(":/info"), QColor("#E2DFFF")));
addToKeywordsList(Keyword("FIXME", QIcon(":/error"), QColor("#FFBFBF")));
addToKeywordsList(Keyword("BUG", QIcon(":/error"), QColor("#FFDFDF")));
addToKeywordsList(Keyword("HACK", QIcon(":/info"), QColor("#FFFFAA")));
emit settingsChanged();
}

View File

@@ -1,45 +0,0 @@
#ifndef SETTINGSDIALOG_H
#define SETTINGSDIALOG_H
#include <QWidget>
#include "keyword.h"
namespace Ui {
class SettingsDialog;
}
class SettingsDialog : public QWidget
{
Q_OBJECT
public:
explicit SettingsDialog(QWidget *parent = 0);
~SettingsDialog();
void setProjectRadioButtonEnabled(bool what);
void setCurrentFileRadioButtonEnabled(bool what);
void setBuildIssuesRadioButtonEnabled(bool what);
void setTodoOutputRadioButtonEnabled(bool what);
void addToKeywordsList(Keyword);
void setKeywordsList(KeywordsList);
bool projectRadioButtonEnabled();
bool currentFileRadioButtonEnabled();
bool buildIssuesRadioButtonEnabled();
bool todoOutputRadioButtonEnabled();
KeywordsList keywordsList();
signals:
void settingsChanged();
private slots:
void clearKeywordsList();
void addButtonClicked();
void removeButtonClicked();
void resetButtonClicked();
private:
Ui::SettingsDialog *ui;
};
#endif // SETTINGSDIALOG_H

View File

@@ -1,143 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SettingsDialog</class>
<widget class="QWidget" name="SettingsDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>740</width>
<height>423</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_6"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QListWidget" name="keywordsList"/>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QPushButton" name="addButton">
<property name="text">
<string>Add</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="removeButton">
<property name="text">
<string>Remove</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="resetButton">
<property name="text">
<string>Reset</string>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="projectGroupBox">
<property name="title">
<string>View options</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QRadioButton" name="currentFileRadioButton">
<property name="text">
<string>From current opened file</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="projectRadioButton">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>From projects</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="paneGroupBox">
<property name="title">
<string>Pane options</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QRadioButton" name="todoOutputRadioButton">
<property name="text">
<string>Show in &quot;TODO Output&quot;</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="buildIssuesRadioButton">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Show in &quot;Build Issues&quot;</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Icons and Colors show on
TODO Output pane only</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -1,118 +0,0 @@
#include "settingspage.h"
#include <coreplugin/icore.h>
#include <QList>
#include <QMessageBox>
SettingsPage::SettingsPage(KeywordsList keywords, int projectOptions, int paneOptions, QObject *parent) : IOptionsPage(parent)
{
this->keywords = keywords;
this->projectOptions = projectOptions;
this->paneOptions = paneOptions;
}
SettingsPage::~SettingsPage()
{
delete dialog;
}
QString SettingsPage::id() const
{
return "TodoSettings";
}
QString SettingsPage::trName() const
{
return tr("TODO Plugin");
}
QString SettingsPage::category() const
{
return "TODO";
}
QString SettingsPage::trCategory() const
{
return tr("TODO");
}
QString SettingsPage::displayName() const
{
return trName();
}
QString SettingsPage::displayCategory() const
{
return trCategory();
}
QIcon SettingsPage::categoryIcon() const
{
return QIcon(":/todo");
}
QWidget *SettingsPage::createPage(QWidget *parent)
{
settingsStatus = false;
dialog = new SettingsDialog(parent);
dialog->setKeywordsList(keywords);
switch (projectOptions)
{
case 0:
dialog->setProjectRadioButtonEnabled(false);
dialog->setCurrentFileRadioButtonEnabled(true);
break;
case 1:
default:
dialog->setProjectRadioButtonEnabled(true);
dialog->setCurrentFileRadioButtonEnabled(false);
break;
}
switch (paneOptions)
{
case 0:
dialog->setBuildIssuesRadioButtonEnabled(false);
dialog->setTodoOutputRadioButtonEnabled(true);
break;
case 1:
default:
dialog->setBuildIssuesRadioButtonEnabled(true);
dialog->setTodoOutputRadioButtonEnabled(false);
break;
}
connect(dialog, SIGNAL(settingsChanged()), this, SLOT(settingsChanged()));
return dialog;
}
void SettingsPage::apply()
{
if (settingsStatus)
{
QSettings *settings = Core::ICore::instance()->settings();
settings->beginGroup("TODOPlugin");
projectOptions = dialog->currentFileRadioButtonEnabled() ? 0 : 1;
paneOptions = dialog->todoOutputRadioButtonEnabled() ? 0 : 1;
keywords = dialog->keywordsList();
settings->setValue("project_options", projectOptions);
settings->setValue("pane_options", paneOptions);
settings->setValue("keywords", qVariantFromValue(keywords));
settings->endGroup();
settings->sync();
QMessageBox::information(dialog, tr("Information"), tr("The TODO plugin settings change will take effect after a restart of Qt Creator."));
settingsStatus = false;
}
}
void SettingsPage::finish()
{
//apply();
}
void SettingsPage::settingsChanged()
{
settingsStatus = true;
}

View File

@@ -1,39 +0,0 @@
#ifndef SETTINGSPAGE_H
#define SETTINGSPAGE_H
#include <QIcon>
#include <coreplugin/dialogs/ioptionspage.h>
#include "settingsdialog.h"
class SettingsPage : public Core::IOptionsPage
{
Q_OBJECT
public:
SettingsPage(KeywordsList keywords = KeywordsList(), int projectOptions = 0, int paneOptions = 0, QObject *parent = 0);
~SettingsPage();
QString id() const;
QString trName() const;
QString category() const;
QString trCategory() const;
QString displayName() const;
QIcon categoryIcon() const;
QString displayCategory() const;
QWidget *createPage(QWidget *parent);
void apply();
void finish();
public slots:
void settingsChanged();
private:
SettingsDialog *dialog;
bool settingsStatus;
int projectOptions;
int paneOptions;
KeywordsList keywords;
};
#endif // SETTINGSPAGE_H

43
src/plugins/todo/todo.pro Normal file
View File

@@ -0,0 +1,43 @@
TEMPLATE = lib
TARGET = Todo
include(../../qtcreatorplugin.pri)
include(todo_dependencies.pri)
HEADERS += todoplugin.h \
keyword.h \
constants.h \
todooutputpane.h \
todoitem.h \
settings.h \
optionspage.h \
optionsdialog.h\
keyworddialog.h \
todoitemsprovider.h \
todoitemsmodel.h \
todoitemsscanner.h \
cpptodoitemsscanner.h \
qmljstodoitemsscanner.h \
lineparser.h
SOURCES += todoplugin.cpp \
keyword.cpp \
todooutputpane.cpp \
optionspage.cpp \
settings.cpp \
optionsdialog.cpp \
keyworddialog.cpp \
todoitemsprovider.cpp \
todoitemsmodel.cpp \
todoitemsscanner.cpp \
cpptodoitemsscanner.cpp \
qmljstodoitemsscanner.cpp \
lineparser.cpp
OTHER_FILES += \
Todo.pluginspec.in
RESOURCES += \
todoplugin.qrc
FORMS += \
optionsdialog.ui \
keyworddialog.ui

View File

@@ -0,0 +1,5 @@
include(../../plugins/coreplugin/coreplugin.pri)
include(../../plugins/projectexplorer/projectexplorer.pri)
include(../../plugins/texteditor/texteditor.pri)
include(../../plugins/cpptools/cpptools.pri)
include(../../libs/qmljs/qmljs.pri)

View File

@@ -0,0 +1,99 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Dmitry Savchenko.
** Copyright (c) 2010 Vasiliy Sorokin.
**
** 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 TODOITEM_H
#define TODOITEM_H
#include "constants.h"
#include <QMetaType>
#include <QString>
#include <QIcon>
namespace Todo {
namespace Internal {
struct TodoItem
{
QString text;
QString file;
int line;
QString iconResource;
QColor color;
};
class TodoItemSortPredicate
{
public:
explicit TodoItemSortPredicate(Constants::OutputColumnIndex columnIndex, Qt::SortOrder order) :
m_columnIndex(columnIndex),
m_order(order)
{}
inline bool operator()(const TodoItem &t1, const TodoItem &t2)
{
if (m_order == Qt::AscendingOrder)
return lessThan(t1, t2);
else
return lessThan(t2, t1);
}
inline bool lessThan(const TodoItem &t1, const TodoItem &t2)
{
switch (m_columnIndex) {
case Constants::OUTPUT_COLUMN_TEXT:
return t1.text < t2.text;
case Constants::OUTPUT_COLUMN_LINE:
return t1.line < t2.line;
case Constants::OUTPUT_COLUMN_FILE:
return t1.file < t2.file;
default:
Q_ASSERT(false);
return false;
}
}
private:
Constants::OutputColumnIndex m_columnIndex;
Qt::SortOrder m_order;
};
} // namespace Internal
} // namespace Todo
Q_DECLARE_METATYPE(Todo::Internal::TodoItem)
#endif // TODOITEM_H

View File

@@ -0,0 +1,152 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Dmitry Savchenko.
** Copyright (c) 2010 Vasiliy Sorokin.
**
** 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 "todoitemsmodel.h"
#include "constants.h"
namespace Todo {
namespace Internal {
TodoItemsModel::TodoItemsModel(QObject *parent) :
QAbstractTableModel(parent),
m_todoItemsList(0),
m_currentSortColumn(Constants::OutputColumnIndex(0)),
m_currentSortOrder(Qt::AscendingOrder)
{
}
void TodoItemsModel::setTodoItemsList(QList<TodoItem> *list)
{
m_todoItemsList = list;
todoItemsListUpdated();
}
int TodoItemsModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
// There's only one level of hierarchy
if (parent.isValid())
return 0;
if (!m_todoItemsList)
return 0;
return m_todoItemsList->count();
}
int TodoItemsModel::columnCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return Constants::OUTPUT_COLUMN_LAST;
}
QVariant TodoItemsModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
TodoItem item = m_todoItemsList->at(index.row());
if (role == Qt::BackgroundColorRole)
return item.color;
switch (index.column()) {
case Constants::OUTPUT_COLUMN_TEXT:
switch (role) {
case Qt::DisplayRole:
return item.text;
case Qt::DecorationRole:
return QVariant::fromValue(QIcon(item.iconResource));
}
break;
case Constants::OUTPUT_COLUMN_FILE:
if (role == Qt::DisplayRole)
return item.file;
break;
case Constants::OUTPUT_COLUMN_LINE:
if (role == Qt::DisplayRole)
return item.line;
break;
}
return QVariant();
}
QVariant TodoItemsModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (orientation == Qt::Vertical)
return QVariant();
if (role != Qt::DisplayRole)
return QVariant();
switch (section) {
case Constants::OUTPUT_COLUMN_TEXT:
return tr(Constants::OUPTUT_COLUMN_TEXT_TITLE);
case Constants::OUTPUT_COLUMN_FILE:
return tr(Constants::OUTPUT_COLUMN_FILE_TITLE);
case Constants::OUTPUT_COLUMN_LINE:
return tr(Constants::OUTPUT_COLUMN_LINE_TITLE);
default:
return QVariant();
}
}
void TodoItemsModel::sort(int column, Qt::SortOrder order)
{
m_currentSortColumn = Constants::OutputColumnIndex(column);
m_currentSortOrder = order;
TodoItemSortPredicate predicate(m_currentSortColumn, m_currentSortOrder);
qSort(m_todoItemsList->begin(), m_todoItemsList->end(), predicate);
emit layoutChanged();
}
void TodoItemsModel::todoItemsListUpdated()
{
if (!m_todoItemsList)
return;
sort(m_currentSortColumn, m_currentSortOrder);
}
}
}

View File

@@ -0,0 +1,73 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Dmitry Savchenko.
** Copyright (c) 2010 Vasiliy Sorokin.
**
** 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 TODOITEMSMODEL_H
#define TODOITEMSMODEL_H
#include "todoitem.h"
#include <QAbstractTableModel>
#include <QList>
namespace Todo {
namespace Internal {
class TodoItemsModel : public QAbstractTableModel
{
Q_OBJECT
public:
explicit TodoItemsModel(QObject *parent = 0);
void setTodoItemsList(QList<TodoItem> *list);
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const;
QVariant data(const QModelIndex &index, int role) const;
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
void sort(int column, Qt::SortOrder order = Qt::AscendingOrder);
public slots:
void todoItemsListUpdated();
private:
QList<TodoItem> *m_todoItemsList;
Constants::OutputColumnIndex m_currentSortColumn;
Qt::SortOrder m_currentSortOrder;
};
}
}
#endif // TODOITEMSMODEL_H

View File

@@ -0,0 +1,188 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Dmitry Savchenko.
** Copyright (c) 2010 Vasiliy Sorokin.
**
** 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 "todoitemsprovider.h"
#include "constants.h"
#include "cpptodoitemsscanner.h"
#include "qmljstodoitemsscanner.h"
#include <projectexplorer/projectexplorer.h>
#include <coreplugin/editormanager/editormanager.h>
#include <projectexplorer/session.h>
#include <QTimer>
namespace Todo {
namespace Internal {
TodoItemsProvider::TodoItemsProvider(Settings settings, QObject *parent) :
QObject(parent),
m_settings(settings)
{
setupItemsModel();
setupStartupProjectBinding();
setupCurrentEditorBinding();
setupUpdateListTimer();
createScanners();
}
TodoItemsModel *TodoItemsProvider::todoItemsModel()
{
return m_itemsModel;
}
void TodoItemsProvider::settingsChanged(const Settings &newSettings)
{
if (newSettings.keywords != m_settings.keywords)
foreach (TodoItemsScanner *scanner, m_scanners)
scanner->setKeywordList(newSettings.keywords);
m_settings = newSettings;
updateList();
}
void TodoItemsProvider::updateList()
{
m_itemsList.clear();
// Show only items of the current file if any
if (m_settings.scanningScope == ScanningScopeCurrentFile) {
if (m_currentEditor)
m_itemsList = m_itemsHash.value(m_currentEditor->document()->fileName());
}
// Show only items of the startup project if any
else {
if (m_startupProject)
setItemsListWithinStartupProject();
}
m_itemsModel->todoItemsListUpdated();
}
void TodoItemsProvider::createScanners()
{
qRegisterMetaType<QList<TodoItem> >("QList<TodoItem>");
if (CPlusPlus::CppModelManagerInterface::instance())
m_scanners << new CppTodoItemsScanner(m_settings.keywords, this);
if (QmlJS::ModelManagerInterface::instance())
m_scanners << new QmlJsTodoItemsScanner(m_settings.keywords, this);
foreach (TodoItemsScanner *scanner, m_scanners)
connect(scanner, SIGNAL(itemsFetched(QString,QList<TodoItem>)), this,
SLOT(itemsFetched(QString,QList<TodoItem>)), Qt::QueuedConnection);
}
void TodoItemsProvider::setItemsListWithinStartupProject()
{
QHashIterator<QString, QList<TodoItem> > it(m_itemsHash);
QStringList fileNames = m_startupProject->files(ProjectExplorer::Project::ExcludeGeneratedFiles);
while (it.hasNext()) {
it.next();
if (fileNames.contains(it.key()))
m_itemsList << it.value();
}
}
void TodoItemsProvider::itemsFetched(const QString &fileName, const QList<TodoItem> &items)
{
// Replace old items with new ones
m_itemsHash.insert(fileName, items);
m_shouldUpdateList = true;
}
void TodoItemsProvider::startupProjectChanged(ProjectExplorer::Project *project)
{
m_startupProject = project;
updateList();
}
void TodoItemsProvider::projectsFilesChanged()
{
updateList();
}
void TodoItemsProvider::currentEditorChanged(Core::IEditor *editor)
{
m_currentEditor = editor;
if (m_settings.scanningScope == ScanningScopeCurrentFile)
updateList();
}
void TodoItemsProvider::updateListTimeoutElapsed()
{
if (m_shouldUpdateList) {
m_shouldUpdateList = false;
updateList();
}
}
void TodoItemsProvider::setupStartupProjectBinding()
{
ProjectExplorer::ProjectExplorerPlugin *projectExplorerPlugin = ProjectExplorer::ProjectExplorerPlugin::instance();
m_startupProject = projectExplorerPlugin->startupProject();
connect(projectExplorerPlugin->session(), SIGNAL(startupProjectChanged(ProjectExplorer::Project*)),
SLOT(startupProjectChanged(ProjectExplorer::Project*)));
connect(projectExplorerPlugin, SIGNAL(fileListChanged()), SLOT(projectsFilesChanged()));
}
void TodoItemsProvider::setupCurrentEditorBinding()
{
Core::EditorManager *editorManager = Core::EditorManager::instance();
m_currentEditor = editorManager->currentEditor();
connect(editorManager, SIGNAL(currentEditorChanged(Core::IEditor*)),
SLOT(currentEditorChanged(Core::IEditor*)));
}
void TodoItemsProvider::setupUpdateListTimer()
{
m_shouldUpdateList = false;
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), SLOT(updateListTimeoutElapsed()));
timer->start(Constants::OUTPUT_PANE_UPDATE_INTERVAL);
}
void TodoItemsProvider::setupItemsModel()
{
m_itemsModel = new TodoItemsModel(this);
m_itemsModel->setTodoItemsList(&m_itemsList);
}
}
}

View File

@@ -0,0 +1,101 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Dmitry Savchenko.
** Copyright (c) 2010 Vasiliy Sorokin.
**
** 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 TODOITEMSPROVIDER_H
#define TODOITEMSPROVIDER_H
#include "todoitem.h"
#include "settings.h"
#include "todoitemsmodel.h"
#include "todoitemsscanner.h"
#include <projectexplorer/project.h>
#include <coreplugin/editormanager/ieditor.h>
#include <QHash>
#include <QList>
namespace Todo {
namespace Internal {
class TodoItemsProvider : public QObject
{
Q_OBJECT
public:
explicit TodoItemsProvider(Settings settings, QObject *parent = 0);
TodoItemsModel *todoItemsModel();
public slots:
void settingsChanged(const Settings &newSettings);
signals:
void itemsUpdated();
private:
Settings m_settings;
TodoItemsModel *m_itemsModel;
// All to-do items are stored here regardless current scanning scope
QHash<QString, QList<TodoItem> > m_itemsHash;
// This list contains only those to-do items that are within current scanning scope
QList<TodoItem> m_itemsList;
QList<TodoItemsScanner *> m_scanners;
ProjectExplorer::Project *m_startupProject;
Core::IEditor* m_currentEditor;
bool m_shouldUpdateList;
void setupItemsModel();
void setupStartupProjectBinding();
void setupCurrentEditorBinding();
void setupUpdateListTimer();
void updateList();
void createScanners();
void setItemsListWithinStartupProject();
private slots:
void itemsFetched(const QString &fileName, const QList<TodoItem> &items);
void startupProjectChanged(ProjectExplorer::Project *project);
void projectsFilesChanged();
void currentEditorChanged(Core::IEditor *editor);
void updateListTimeoutElapsed();
};
}
}
#endif // TODOITEMSPROVIDER_H

View File

@@ -0,0 +1,76 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Dmitry Savchenko.
** Copyright (c) 2010 Vasiliy Sorokin.
**
** 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 "todoitemsscanner.h"
#include "lineparser.h"
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/project.h>
namespace Todo {
namespace Internal {
TodoItemsScanner::TodoItemsScanner(const KeywordList &keywordList, QObject *parent) :
QObject(parent)
{
setKeywordList(keywordList);
}
void TodoItemsScanner::setKeywordList(const KeywordList &keywordList)
{
m_keywordList = keywordList;
keywordListChanged();
}
// Descendants can override and make a request for full rescan here if needed
void TodoItemsScanner::keywordListChanged()
{
}
// Descendants can use this to process comment lines
void TodoItemsScanner::processCommentLine(const QString &fileName, const QString &comment,
unsigned lineNumber, QList<TodoItem> &outItemList)
{
LineParser parser(m_keywordList);
QList<TodoItem> newItemList = parser.parse(comment);
for (int i = 0; i < newItemList.count(); ++i) {
newItemList[i].line = lineNumber;
newItemList[i].file = fileName;
}
outItemList << newItemList;
}
}
}

View File

@@ -0,0 +1,69 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Dmitry Savchenko.
** Copyright (c) 2010 Vasiliy Sorokin.
**
** 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 TODOITEMSSCANNER_H
#define TODOITEMSSCANNER_H
#include "todoitem.h"
#include "settings.h"
#include <QObject>
namespace Todo {
namespace Internal {
// TodoItemsScanner is an abstract class
class TodoItemsScanner : public QObject
{
Q_OBJECT
public:
explicit TodoItemsScanner(const KeywordList &keywordList, QObject *parent = 0);
void setKeywordList(const KeywordList &keywordList);
signals:
void itemsFetched(const QString &fileName, const QList<TodoItem> &items);
protected:
KeywordList m_keywordList;
virtual void keywordListChanged();
void processCommentLine(const QString &fileName, const QString &comment, unsigned lineNumber,
QList<TodoItem> &outItemList);
};
}
}
#endif // TODOITEMSSCANNER_H

View File

@@ -1,174 +1,248 @@
/* /**************************************************************************
* **
* TODO plugin - Add pane with list all TODO, FIXME, etc. comments. ** This file is part of Qt Creator
* **
* Copyright (C) 2010 VasiliySorokin ** Copyright (c) 2012 Dmitry Savchenko.
* ** Copyright (c) 2010 Vasiliy Sorokin.
* Authors: Vasiliy Sorokin <sorokin.vasiliy@gmail.com> **
* ** Contact: Nokia Corporation (qt-info@nokia.com)
* This file is part of TODO plugin for QtCreator. **
* **
* Redistribution and use in source and binary forms, with or without modification, ** GNU Lesser General Public License Usage
* are permitted provided that the following conditions are met: **
* * Redistributions of source code must retain the above copyright notice, ** This file may be used under the terms of the GNU Lesser General Public
* this list of conditions and the following disclaimer. ** License version 2.1 as published by the Free Software Foundation and
* * Redistributions in binary form must reproduce the above copyright notice, ** appearing in the file LICENSE.LGPL included in the packaging of this file.
* this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. ** Please review the following information to ensure the GNU Lesser General
* * Neither the name of the vsorokin nor the names of its contributors may be used to endorse or ** Public License version 2.1 requirements will be met:
* promote products derived from this software without specific prior written permission. ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
* **
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ** In addition, as a special exception, Nokia gives you certain additional
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND ** rights. These rights are described in the Nokia Qt LGPL Exception
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, **
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ** Other Usage
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, **
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY ** Alternatively, this file may be used in accordance with the terms and
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** 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 "todooutputpane.h" #include "todooutputpane.h"
#include <QListWidgetItem> #include "constants.h"
#include <QRegExp>
#include <QIcon> #include <QIcon>
#include <QHeaderView>
// TODO: make fix namespace Todo {
// NOTE: make note namespace Internal {
// HACK: make hack
// BUG: make bug
TodoOutputPane::TodoOutputPane(QObject *parent) : IOutputPane(parent) TodoOutputPane::TodoOutputPane(TodoItemsModel *todoItemsModel, QObject *parent) :
IOutputPane(parent),
m_todoItemsModel(todoItemsModel)
{ {
todoList = new QListWidget(); createTreeView();
todoList->setFlow(QListView::TopToBottom); createScopeButtons();
todoList->setFrameStyle(QFrame::NoFrame); setScanningScope(ScanningScopeCurrentFile); // default
lastCurrentRow = 0; connect(m_todoItemsModel, SIGNAL(layoutChanged()), SIGNAL(navigateStateUpdate()));
} }
TodoOutputPane::~TodoOutputPane() TodoOutputPane::~TodoOutputPane()
{ {
delete todoList; freeTreeView();
freeScopeButtons();
} }
void TodoOutputPane::addItem(const QString &text, const QString &file, const int rowNumber, const QIcon &icon, const QColor &color) QWidget *TodoOutputPane::outputWidget(QWidget *parent)
{ {
QListWidgetItem *newItem = new QListWidgetItem(); Q_UNUSED(parent)
newItem->setBackgroundColor(color); return m_todoTreeView;
newItem->setIcon(icon);
newItem->setData(Qt::UserRole + 1, file);
newItem->setData(Qt::UserRole + 2, rowNumber);
newItem->setToolTip(file + ":" + QString::number(rowNumber));
newItem->setText(file.right(file.size() - file.lastIndexOf("/") - 1) + ":" + QString::number(rowNumber) + ": " + text);
todoList->addItem(newItem);
}
QListWidget *TodoOutputPane::getTodoList() const
{
return todoList;
}
QWidget *TodoOutputPane::outputWidget(QWidget */*parent*/)
{
return todoList;
} }
QList<QWidget*> TodoOutputPane::toolBarWidgets() const QList<QWidget*> TodoOutputPane::toolBarWidgets() const
{ {
return QList<QWidget*>(); return QList<QWidget*>()
} << m_spacer
<< m_currentFileButton
QString TodoOutputPane::name() const << m_wholeProjectButton;
{
return tr("TODO Output");
} }
QString TodoOutputPane::displayName() const QString TodoOutputPane::displayName() const
{ {
return name(); return tr(Constants::OUTPUT_PANE_TITLE);
} }
int TodoOutputPane::priorityInStatusBar() const int TodoOutputPane::priorityInStatusBar() const
{ {
return 1; return 1;
} }
void TodoOutputPane::clearContents() void TodoOutputPane::clearContents()
{ {
todoList->clear();
} }
void TodoOutputPane::clearContents(QString filename)
{
int i = 0;
lastCurrentRow = 0;
while (i < todoList->count())
{
if (!filename.compare(todoList->item(i)->data(Qt::UserRole + 1).toString()))
{
if (lastCurrentRow == 0)
lastCurrentRow = todoList->currentRow();
todoList->takeItem(i);
}
else
{
++i;
}
}
}
void TodoOutputPane::visibilityChanged(bool visible) void TodoOutputPane::visibilityChanged(bool visible)
{ {
todoList->setVisible(visible); Q_UNUSED(visible)
} }
void TodoOutputPane::setFocus() void TodoOutputPane::setFocus()
{ {
todoList->setFocus(); m_todoTreeView->setFocus();
} }
bool TodoOutputPane::hasFocus() bool TodoOutputPane::hasFocus() const
{ {
return todoList->hasFocus(); return m_todoTreeView->hasFocus();
} }
bool TodoOutputPane::canFocus() bool TodoOutputPane::canFocus() const
{ {
return true; return true;
} }
bool TodoOutputPane::canNavigate() bool TodoOutputPane::canNavigate() const
{ {
return todoList->count() > 1; return true;
} }
bool TodoOutputPane::canNext() bool TodoOutputPane::canNext() const
{ {
return todoList->currentRow() < todoList->count() && todoList->count() > 1; return m_todoTreeView->model()->rowCount() > 1;
} }
bool TodoOutputPane::canPrevious() bool TodoOutputPane::canPrevious() const
{ {
return todoList->currentRow() > 0 && todoList->count() > 1; return m_todoTreeView->model()->rowCount() > 1;
} }
void TodoOutputPane::goToNext() void TodoOutputPane::goToNext()
{ {
todoList->setCurrentRow(todoList->currentRow() + 1); m_todoTreeView->selectionModel()->select(nextModelIndex(), QItemSelectionModel::SelectCurrent);
} }
void TodoOutputPane::goToPrev() void TodoOutputPane::goToPrev()
{ {
todoList->setCurrentRow(todoList->currentRow() - 1); m_todoTreeView->selectionModel()->select(previousModelIndex(), QItemSelectionModel::SelectCurrent);
} }
void TodoOutputPane::sort() void TodoOutputPane::setScanningScope(ScanningScope scanningScope)
{ {
todoList->sortItems(Qt::AscendingOrder); if (scanningScope == ScanningScopeCurrentFile)
if (todoList->count() > 0) m_currentFileButton->setChecked(true);
todoList->setCurrentRow(lastCurrentRow < todoList->count() ? lastCurrentRow : todoList->count() - 1); else if (scanningScope == ScanningScopeProject)
m_wholeProjectButton->setChecked(true);
else
Q_ASSERT_X(false, "Updating scanning scope buttons", "Unknown scanning scope enum value");
} }
void TodoOutputPane::scopeButtonClicked(QAbstractButton* button)
{
if (button == m_currentFileButton)
emit scanningScopeChanged(ScanningScopeCurrentFile);
else if (button == m_wholeProjectButton)
emit scanningScopeChanged(ScanningScopeProject);
}
void TodoOutputPane::todoTreeViewClicked(QModelIndex index)
{
// Create a to-do item and notify that it was clicked on
int row = index.row();
TodoItem item;
item.text = index.sibling(row, Constants::OUTPUT_COLUMN_TEXT).data().toString();
item.file = index.sibling(row, Constants::OUTPUT_COLUMN_FILE).data().toString();
item.line = index.sibling(row, Constants::OUTPUT_COLUMN_LINE).data().toInt();
item.color = index.data(Qt::BackgroundColorRole).value<QColor>();
item.iconResource = index.sibling(row, Constants::OUTPUT_COLUMN_TEXT).data(Qt::DecorationRole).toString();
emit todoItemClicked(item);
}
void TodoOutputPane::createTreeView()
{
m_todoTreeView = new QTreeView();
m_todoTreeView->setRootIsDecorated(false);
m_todoTreeView->setFrameStyle(QFrame::NoFrame);
m_todoTreeView->setSortingEnabled(true);
m_todoTreeView->setModel(m_todoItemsModel);
QHeaderView *header = m_todoTreeView->header();
header->setResizeMode(Constants::OUTPUT_COLUMN_TEXT, QHeaderView::Stretch);
header->setResizeMode(Constants::OUTPUT_COLUMN_LINE, QHeaderView::ResizeToContents);
header->setResizeMode(Constants::OUTPUT_COLUMN_FILE, QHeaderView::ResizeToContents);
header->setStretchLastSection(false);
header->setMovable(false);
connect(m_todoTreeView, SIGNAL(clicked(QModelIndex)), SLOT(todoTreeViewClicked(QModelIndex)));
}
void TodoOutputPane::freeTreeView()
{
delete m_todoTreeView;
}
void TodoOutputPane::createScopeButtons()
{
m_currentFileButton = new QToolButton();
m_currentFileButton->setIcon(QIcon(QString(Constants::ICON_CURRENT_FILE)));
m_currentFileButton->setCheckable(true);
m_currentFileButton->setToolTip(tr("Scan in the current opened file"));
m_wholeProjectButton = new QToolButton();
m_wholeProjectButton->setIcon(QIcon(QString(Constants::ICON_WHOLE_PROJECT)));
m_wholeProjectButton->setCheckable(true);
m_wholeProjectButton->setToolTip(tr("Scan in the whole project"));
m_scopeButtons = new QButtonGroup();
m_scopeButtons->addButton(m_wholeProjectButton);
m_scopeButtons->addButton(m_currentFileButton);
connect(m_scopeButtons, SIGNAL(buttonClicked(QAbstractButton*)), SLOT(scopeButtonClicked(QAbstractButton*)));
m_spacer = new QWidget;
m_spacer->setMinimumWidth(Constants::OUTPUT_TOOLBAR_SPACER_WIDHT);
}
void TodoOutputPane::freeScopeButtons()
{
delete m_currentFileButton;
delete m_wholeProjectButton;
delete m_scopeButtons;
delete m_spacer;
}
QModelIndex TodoOutputPane::selectedModelIndex()
{
QModelIndexList selectedIndexes = m_todoTreeView->selectionModel()->selectedIndexes();
if (selectedIndexes.isEmpty())
return QModelIndex();
else
// There is only one item selected
return selectedIndexes.first();
}
QModelIndex TodoOutputPane::nextModelIndex()
{
QModelIndex indexToBeSelected = m_todoTreeView->indexBelow(selectedModelIndex());
if (!indexToBeSelected.isValid())
return m_todoTreeView->model()->index(0, 0);
else
return indexToBeSelected;
}
QModelIndex TodoOutputPane::previousModelIndex()
{
QModelIndex indexToBeSelected = m_todoTreeView->indexAbove(selectedModelIndex());
if (!indexToBeSelected.isValid())
return m_todoTreeView->model()->index(m_todoTreeView->model()->rowCount() - 1, 0);
else
return indexToBeSelected;
}
} // namespace Internal
} // namespace Todo

View File

@@ -1,76 +1,106 @@
/* /**************************************************************************
* **
* TODO plugin - Add pane with list all TODO, FIXME, etc. comments. ** This file is part of Qt Creator
* **
* Copyright (C) 2010 VasiliySorokin ** Copyright (c) 2012 Dmitry Savchenko.
* ** Copyright (c) 2010 Vasiliy Sorokin.
* Authors: Vasiliy Sorokin <sorokin.vasiliy@gmail.com> **
* ** Contact: Nokia Corporation (qt-info@nokia.com)
* This file is part of TODO plugin for QtCreator. **
* **
* Redistribution and use in source and binary forms, with or without modification, ** GNU Lesser General Public License Usage
* are permitted provided that the following conditions are met: **
* * Redistributions of source code must retain the above copyright notice, ** This file may be used under the terms of the GNU Lesser General Public
* this list of conditions and the following disclaimer. ** License version 2.1 as published by the Free Software Foundation and
* * Redistributions in binary form must reproduce the above copyright notice, ** appearing in the file LICENSE.LGPL included in the packaging of this file.
* this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. ** Please review the following information to ensure the GNU Lesser General
* * Neither the name of the vsorokin nor the names of its contributors may be used to endorse or ** Public License version 2.1 requirements will be met:
* promote products derived from this software without specific prior written permission. ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
* **
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ** In addition, as a special exception, Nokia gives you certain additional
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND ** rights. These rights are described in the Nokia Qt LGPL Exception
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, **
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ** Other Usage
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, **
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY ** Alternatively, this file may be used in accordance with the terms and
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** 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 TODOOUTPUTPANE_H #ifndef TODOOUTPUTPANE_H
#define TODOOUTPUTPANE_H #define TODOOUTPUTPANE_H
#include "keyword.h" #include "keyword.h"
#include "todoitem.h"
#include "settings.h"
#include "todoitemsmodel.h"
#include <coreplugin/ioutputpane.h> #include <coreplugin/ioutputpane.h>
#include <QObject>
#include <QListWidget> #include <QTreeView>
#include <QToolButton>
#include <QButtonGroup>
namespace Todo {
namespace Internal {
class TodoOutputPane : public Core::IOutputPane class TodoOutputPane : public Core::IOutputPane
{ {
Q_OBJECT
public: public:
TodoOutputPane(QObject *parent); TodoOutputPane(TodoItemsModel *m_todoItemsModel, QObject *parent = 0);
~TodoOutputPane(); ~TodoOutputPane();
QWidget *outputWidget(QWidget *parent); QWidget *outputWidget(QWidget *parent);
QList<QWidget*> toolBarWidgets() const; QList<QWidget*> toolBarWidgets() const;
QString name() const;
QString displayName() const; QString displayName() const;
int priorityInStatusBar() const; int priorityInStatusBar() const;
void clearContents(); void clearContents();
void clearContents(QString filename);
void visibilityChanged(bool visible); void visibilityChanged(bool visible);
void setFocus(); void setFocus();
bool hasFocus(); bool hasFocus() const;
bool canFocus(); bool canFocus() const;
bool canNavigate() const;
bool canNavigate(); bool canNext() const;
bool canNext(); bool canPrevious() const;
bool canPrevious();
void goToNext(); void goToNext();
void goToPrev(); void goToPrev();
void sort(); void setScanningScope(ScanningScope scanningScope);
void addItem(const QString &text, const QString &file, const int rowNumber, const QIcon &icon, const QColor &color); signals:
QListWidget *getTodoList() const; void todoItemClicked(const TodoItem &item);
void scanningScopeChanged(ScanningScope scanningScope);
private slots:
void scopeButtonClicked(QAbstractButton *button);
void todoTreeViewClicked(QModelIndex index);
private: private:
QListWidget *todoList; QTreeView *m_todoTreeView;
int lastCurrentRow; QToolButton *m_currentFileButton;
QToolButton *m_wholeProjectButton;
QWidget *m_spacer;
QButtonGroup *m_scopeButtons;
QList<TodoItem> *items;
TodoItemsModel *m_todoItemsModel;
void createTreeView();
void freeTreeView();
void createScopeButtons();
void freeScopeButtons();
QModelIndex selectedModelIndex();
QModelIndex nextModelIndex();
QModelIndex previousModelIndex();
}; };
} // namespace Internal
} // namespace Todo
#endif // TODOOUTPUTPANE_H #endif // TODOOUTPUTPANE_H

View File

@@ -1,376 +1,129 @@
/* /**************************************************************************
* **
* TODO plugin - Add pane with list all TODO, FIXME, etc. comments. ** This file is part of Qt Creator
* **
* Copyright (C) 2010 VasiliySorokin ** Copyright (c) 2012 Dmitry Savchenko.
* ** Copyright (c) 2010 Vasiliy Sorokin.
* Authors: Vasiliy Sorokin <sorokin.vasiliy@gmail.com> **
* ** Contact: Nokia Corporation (qt-info@nokia.com)
* This file is part of TODO plugin for QtCreator. **
* **
* Redistribution and use in source and binary forms, with or without modification, ** GNU Lesser General Public License Usage
* are permitted provided that the following conditions are met: **
* * Redistributions of source code must retain the above copyright notice, ** This file may be used under the terms of the GNU Lesser General Public
* this list of conditions and the following disclaimer. ** License version 2.1 as published by the Free Software Foundation and
* * Redistributions in binary form must reproduce the above copyright notice, ** appearing in the file LICENSE.LGPL included in the packaging of this file.
* this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. ** Please review the following information to ensure the GNU Lesser General
* * Neither the name of the vsorokin nor the names of its contributors may be used to endorse or ** Public License version 2.1 requirements will be met:
* promote products derived from this software without specific prior written permission. ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
* **
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ** In addition, as a special exception, Nokia gives you certain additional
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND ** rights. These rights are described in the Nokia Qt LGPL Exception
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, **
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ** Other Usage
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, **
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY ** Alternatively, this file may be used in accordance with the terms and
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** 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 "todoplugin.h" #include "todoplugin.h"
#include <QtPlugin> #include "constants.h"
#include <QStringList>
#include <QtConcurrentRun>
#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 <qtconcurrent/runextensions.h>
#include <texteditor/basetexteditor.h>
#include <texteditor/itexteditor.h>
#include <coreplugin/ifile.h>
#include <extensionsystem/pluginmanager.h>
#include <QKeySequence>
#include <QAction>
#include <QFile>
#include <QFileInfo>
#include <QDataStream>
#include <QSettings>
#include <QMessageBox>
#include <QTextCodec>
#include <coreplugin/progressmanager/progressmanager.h>
#include <coreplugin/progressmanager/futureprogress.h>
TodoPlugin::TodoPlugin() #include <QtPlugin>
#include <QFileInfo>
#include <QSettings>
namespace Todo {
namespace Internal {
TodoPlugin::TodoPlugin() :
m_todoOutputPane(0),
m_optionsPage(0),
m_todoItemsProvider(0)
{ {
qRegisterMetaTypeStreamOperators<Keyword>("Keyword"); qRegisterMetaType<TodoItem>("TodoItem");
qRegisterMetaTypeStreamOperators<KeywordsList>("KeywordsList");
currentProject = 0;
inReading = false;
readSettings();
} }
TodoPlugin::~TodoPlugin() TodoPlugin::~TodoPlugin()
{ {
// Do notning m_settings.save(Core::ICore::settings());
}
void TodoPlugin::readSettings()
{
QSettings *settings = Core::ICore::instance()->settings();
settings->beginGroup("TODOPlugin");
projectOptions = settings->value("project_options", 0).toInt();
paneOptions = settings->value("pane_options", 0).toInt();
KeywordsList defaultKeywords;
defaultKeywords.append(Keyword("TODO", QIcon(":/warning"), QColor("#BFFFC8")));
defaultKeywords.append(Keyword("NOTE", QIcon(":/info"), QColor("#E2DFFF")));
defaultKeywords.append(Keyword("FIXME", QIcon(":/error"), QColor("#FFBFBF")));
defaultKeywords.append(Keyword("BUG", QIcon(":/error"), QColor("#FFDFDF")));
defaultKeywords.append(Keyword("HACK", QIcon(":/info"), QColor("#FFFFAA")));
keywords = settings->value("keywords", qVariantFromValue(defaultKeywords)).value<KeywordsList>();
settings->endGroup();
} }
bool TodoPlugin::initialize(const QStringList& args, QString *errMsg) bool TodoPlugin::initialize(const QStringList& args, QString *errMsg)
{ {
Q_UNUSED(args); Q_UNUSED(args);
Q_UNUSED(errMsg); Q_UNUSED(errMsg);
patternString = generatePatternString();
settingsPage = new SettingsPage(keywords, projectOptions, paneOptions, this);
if (paneOptions == 0)
{
outPane = new TodoOutputPane(this);
addAutoReleasedObject(outPane);
connect(outPane->getTodoList(), SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(gotoToRowInFile(QListWidgetItem*)));
connect(outPane->getTodoList(), SIGNAL(itemActivated(QListWidgetItem*)), this, SLOT(gotoToRowInFile(QListWidgetItem*)));
}
else
{
ExtensionSystem::PluginManager* pluginManager = ExtensionSystem::PluginManager::instance();
taskHub = pluginManager->getObject<ProjectExplorer::TaskHub>();
if (!taskHub)
{
paneOptions = 1;
outPane = new TodoOutputPane(this);
addAutoReleasedObject(outPane);
connect(outPane->getTodoList(), SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(gotoToRowInFile(QListWidgetItem*)));
connect(outPane->getTodoList(), SIGNAL(itemActivated(QListWidgetItem*)), this, SLOT(gotoToRowInFile(QListWidgetItem*)));
QMessageBox::warning((QWidget *)Core::ICore::instance()->mainWindow(), tr("TODO plugin"), tr("Task window object not found.\nWork in TODO Output pane."));
}
else
{
taskHub->addCategory("todoplugin", tr("TODOs comments"));
}
} m_settings.load(Core::ICore::settings());
addAutoReleasedObject(settingsPage);
createOptionsPage();
createItemsProvider();
createTodoOutputPane();
connect(Core::EditorManager::instance(), SIGNAL(currentEditorChanged(Core::IEditor*)), this, SLOT(currentEditorChanged(Core::IEditor*)));
if (projectOptions != 0)
{
connect(ProjectExplorer::ProjectExplorerPlugin::instance(), SIGNAL(currentProjectChanged(ProjectExplorer::Project*)), this, SLOT(projectChanged(ProjectExplorer::Project *)));
}
return true; return true;
} }
void TodoPlugin::extensionsInitialized() void TodoPlugin::extensionsInitialized()
{ {
// Do nothing
} }
void TodoPlugin::shutdown() void TodoPlugin::settingsChanged(const Settings &settings)
{ {
// Do nothing settings.save(Core::ICore::settings());
m_settings = settings;
m_todoItemsProvider->settingsChanged(m_settings);
m_todoOutputPane->setScanningScope(m_settings.scanningScope);
m_optionsPage->setSettings(m_settings);
} }
void TodoPlugin::showPane() void TodoPlugin::scanningScopeChanged(ScanningScope scanningScope)
{ {
if (paneOptions == 0) Settings newSettings = m_settings;
{ newSettings.scanningScope = scanningScope;
outPane->visibilityChanged(true); settingsChanged(newSettings);
outPane->setFocus();
}
} }
void TodoPlugin::gotoToRowInFile(QListWidgetItem *item) void TodoPlugin::todoItemClicked(const TodoItem &item)
{ {
int row = item->data(Qt::UserRole + 2).toInt(); if (QFileInfo(item.file).exists()) {
QString file = item->data(Qt::UserRole + 1).toString(); Core::IEditor *editor = Core::EditorManager::instance()->openEditor(item.file);
editor->gotoLine(item.line);
if (QFileInfo(file).exists())
{
Core::IEditor *editor = Core::EditorManager::instance()->openEditor(file);
editor->gotoLine(row);
} }
} }
void TodoPlugin::currentEditorChanged(Core::IEditor *editor) void TodoPlugin::createItemsProvider()
{ {
if (inReading) m_todoItemsProvider = new TodoItemsProvider(m_settings);
return; addAutoReleasedObject(m_todoItemsProvider);
if (projectOptions == 0)
{
if (paneOptions == 0)
{
outPane->clearContents();
}
else
{
taskHub->clearTasks("todoplugin");
}
}
if (!editor)
{
return;
}
connect(editor->file(), SIGNAL(changed()), this, SLOT(fileChanged()));
QString fileName = editor->file()->fileName();
if (projectOptions == 0)
readFile(fileName);
} }
void TodoPlugin::removeFromLocalTasks(QString filename) void TodoPlugin::createTodoOutputPane()
{ {
for (int i = 0; i < tasks.count(); ++i) m_todoOutputPane = new TodoOutputPane(m_todoItemsProvider->todoItemsModel());
{ addAutoReleasedObject(m_todoOutputPane);
if (!tasks.at(i).file.compare(filename)) m_todoOutputPane->setScanningScope(m_settings.scanningScope);
{ connect(m_todoOutputPane, SIGNAL(scanningScopeChanged(ScanningScope)), SLOT(scanningScopeChanged(ScanningScope)));
tasks.removeAt(i); connect(m_todoOutputPane, SIGNAL(todoItemClicked(TodoItem)), SLOT(todoItemClicked(TodoItem)));
}
}
} }
void TodoPlugin::addLocalTaskToTaskWindow() void TodoPlugin::createOptionsPage()
{ {
for (int i = 0; i < tasks.count(); ++i) m_optionsPage = new OptionsPage(m_settings);
{ addAutoReleasedObject(m_optionsPage);
taskHub->addTask(tasks.at(i)); connect(m_optionsPage, SIGNAL(settingsChanged(Settings)), SLOT(settingsChanged(Settings)));
}
} }
void TodoPlugin::fileChanged() Q_EXPORT_PLUGIN2(Todo, TodoPlugin)
{
Core::IFile *file = (Core::IFile *)sender();
if (file)
{
if (projectOptions == 0)
{
if (paneOptions == 0)
{
outPane->clearContents();
}
else
{
taskHub->clearTasks("todoplugin");
}
}
else
{
if (paneOptions == 0)
{
outPane->clearContents(file->fileName());
}
else
{
taskHub->clearTasks("todoplugin");
removeFromLocalTasks(file->fileName());
}
}
readFile(file->fileName());
}
}
Keyword TodoPlugin::prepareOutputString(QString &text) } // namespace Internal
{ } // namespace Todo
Keyword keyword;
for(int i = 0; i < keywords.count(); ++i)
{
QRegExp keywordExp("//\\s*" + keywords.at(i).name + "(:|\\s)", Qt::CaseInsensitive);
if (text.contains(keywordExp))
{
text = text.replace("\n", "");
text = text.replace("\r", "");
text = text.replace(keywordExp, keywords.at(i).name + ": ");
text = text.trimmed();
keyword = keywords.at(i);
break;
}
}
return keyword;
}
void TodoPlugin::readFile(QString fileName)
{
QFile file(fileName);
if (!file.open(QFile::ReadOnly | QFile::Text))
return;
int i = 1;
while (!file.atEnd())
{
QString currentLine = file.readLine();
if (currentLine.contains(QRegExp(patternString, Qt::CaseInsensitive)))
{
Keyword resultKeyword = prepareOutputString(currentLine);
QTextCodec *unicodeCodec = QTextCodec::codecForLocale();
currentLine = unicodeCodec->toUnicode(currentLine.toAscii());
if (paneOptions == 0)
{
outPane->addItem(currentLine, fileName, i, resultKeyword.icon, resultKeyword.warningColor);
if (!inReading)
outPane->sort();
}
else
{
ProjectExplorer::Task task(ProjectExplorer::Task::Unknown, currentLine, fileName, i, "todoplugin");
tasks.append(task);
}
}
++i;
}
if (paneOptions != 0 && !inReading)
{
qSort(tasks.begin(), tasks.end(), TodoPlugin::taskLessThan);
addLocalTaskToTaskWindow();
}
}
QString TodoPlugin::generatePatternString()
{
QString result = "";
if (keywords.count())
{
for (int i = 0; i < keywords.count() - 1; ++i)
{
result += "//\\s*" + keywords.at(i).name + "(:|\\s)|";
}
result += "//\\s*" + keywords.at(keywords.count() - 1).name + "(:|\\s)";
}
return result;
}
void TodoPlugin::projectChanged(ProjectExplorer::Project *project)
{
if (!project)
return;
if (inReading)
return;
currentProject = project;
if (paneOptions == 0)
{
outPane->clearContents();
}
else
{
taskHub->clearTasks("todoplugin");
}
inReading = true;
QFuture<void> result = QtConcurrent::run(&TodoPlugin::readCurrentProject, this);
Core::ICore::instance()->progressManager()->addTask(result, tr("Todoscan"), "Todo.Plugin.Scanning");
}
void TodoPlugin::readCurrentProject(QFutureInterface<void> &future, TodoPlugin *instance)
{
QStringList filesList = instance->currentProject->files(ProjectExplorer::Project::ExcludeGeneratedFiles);
future.setProgressRange(0, filesList.count()-1);
for (int i = 0; i < filesList.count(); ++i)
{
instance->readFile(filesList.at(i));
future.setProgressValue(i);
}
if (instance->paneOptions == 0)
{
instance->outPane->sort();
}
else
{
qSort(instance->tasks.begin(), instance->tasks.end(), TodoPlugin::taskLessThan);
instance->addLocalTaskToTaskWindow();
}
instance->inReading = false;
future.reportFinished();
}
bool TodoPlugin::taskLessThan(const ProjectExplorer::Task &t1, const ProjectExplorer::Task &t2)
{
if (!t1.file.right(t1.file.size() - t1.file.lastIndexOf("/") - 1).compare(t2.file.right(t2.file.size() - t2.file.lastIndexOf("/") - 1)))
{
if (t1.line < t2.line)
{
return true;
}
else
{
return false;
}
}
else
{
return t1.file.right(t1.file.size() - t1.file.lastIndexOf("/") - 1).compare(t2.file.right(t2.file.size() - t2.file.lastIndexOf("/") - 1)) < 0;
}
}
Q_EXPORT_PLUGIN(TodoPlugin)

View File

@@ -1,47 +1,51 @@
/* /**************************************************************************
* **
* TODO plugin - Add pane with list all TODO, FIXME, etc. comments. ** This file is part of Qt Creator
* **
* Copyright (C) 2010 VasiliySorokin ** Copyright (c) 2012 Dmitry Savchenko.
* ** Copyright (c) 2010 Vasiliy Sorokin.
* Authors: Vasiliy Sorokin <sorokin.vasiliy@gmail.com> **
* ** Contact: Nokia Corporation (qt-info@nokia.com)
* This file is part of TODO plugin for QtCreator. **
* **
* Redistribution and use in source and binary forms, with or without modification, ** GNU Lesser General Public License Usage
* are permitted provided that the following conditions are met: **
* * Redistributions of source code must retain the above copyright notice, ** This file may be used under the terms of the GNU Lesser General Public
* this list of conditions and the following disclaimer. ** License version 2.1 as published by the Free Software Foundation and
* * Redistributions in binary form must reproduce the above copyright notice, ** appearing in the file LICENSE.LGPL included in the packaging of this file.
* this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. ** Please review the following information to ensure the GNU Lesser General
* * Neither the name of the vsorokin nor the names of its contributors may be used to endorse or ** Public License version 2.1 requirements will be met:
* promote products derived from this software without specific prior written permission. ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
* **
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ** In addition, as a special exception, Nokia gives you certain additional
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND ** rights. These rights are described in the Nokia Qt LGPL Exception
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, **
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ** Other Usage
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, **
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY ** Alternatively, this file may be used in accordance with the terms and
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** 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 TODOPLUGIN_H #ifndef TODOPLUGIN_H
#define TODOPLUGIN_H #define TODOPLUGIN_H
#include <QFuture>
#include <QList>
#include <extensionsystem/iplugin.h>
#include <coreplugin/editormanager/editormanager.h>
#include <projectexplorer/task.h>
#include <projectexplorer/taskhub.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/project.h>
#include "todooutputpane.h"
#include "settingspage.h"
#include "keyword.h"
#include "optionspage.h"
#include "keyword.h"
#include "todooutputpane.h"
#include "settings.h"
#include "todoitemsprovider.h"
#include <extensionsystem/iplugin.h>
#include <QStringList>
namespace Todo {
namespace Internal {
class TodoPlugin : public ExtensionSystem::IPlugin class TodoPlugin : public ExtensionSystem::IPlugin
{ {
@@ -49,43 +53,28 @@ class TodoPlugin : public ExtensionSystem::IPlugin
public: public:
TodoPlugin(); TodoPlugin();
~TodoPlugin(); ~TodoPlugin();
void extensionsInitialized(); void extensionsInitialized();
bool initialize(const QStringList & arguments, QString * errorString); bool initialize(const QStringList &arguments, QString *errorString);
void shutdown();
public slots: private slots:
void showPane(); void settingsChanged(const Settings &m_settings);
void gotoToRowInFile(QListWidgetItem *); void scanningScopeChanged(ScanningScope scanningScope);
void currentEditorChanged(Core::IEditor *editor); void todoItemClicked(const TodoItem &item);
void fileChanged();
void projectChanged(ProjectExplorer::Project *);
signals:
void updateFutureValue(int value);
void setFutureRange(int, int);
private: private:
void readFile(QString); void createItemsProvider();
static void readCurrentProject(QFutureInterface<void> &future, TodoPlugin* instance); void createTodoOutputPane();
void removeFromLocalTasks(QString filename); void createOptionsPage();
void addLocalTaskToTaskWindow();
static bool taskLessThan(const ProjectExplorer::Task &t1, const ProjectExplorer::Task &t2); Settings m_settings;
TodoOutputPane *m_todoOutputPane;
Keyword prepareOutputString(QString &text); OptionsPage *m_optionsPage;
QString generatePatternString(); TodoItemsProvider *m_todoItemsProvider;
void readSettings();
TodoOutputPane *outPane;
ProjectExplorer::TaskHub *taskHub;
SettingsPage *settingsPage;
QString patternString;
KeywordsList keywords;
int projectOptions;
int paneOptions;
ProjectExplorer::Project *currentProject;
QList<ProjectExplorer::Task> tasks;
bool inReading;
QFutureInterface<void> *progressObject;
}; };
} // namespace Internal
} // namespace Todo
#endif // TODOPLUGIN_H #endif // TODOPLUGIN_H

View File

@@ -1,46 +0,0 @@
CONFIG += release
TEMPLATE = lib
TARGET = todo
PROVIDER = vsorokin
QTC_SOURCE_DIR = /home/vass/qt-creator
IDE_SOURCE_TREE = $$QTC_SOURCE_DIR
QTC_BUILD_DIR = /opt/qtcreator-2.1.81
DESTDIR = $$QTC_BUILD_DIR/lib/qtcreator/plugins/$$(PROVIDER)
IDE_BUILD_TREE = $$QTC_BUILD_DIR
LIBS += -L$$IDE_BUILD_TREE/lib/qtcreator/ \
-L$$IDE_BUILD_TREE/lib/qtcreator/plugins/Nokia
include( $$IDE_SOURCE_TREE/src/qtcreatorplugin.pri )
include( $$IDE_SOURCE_TREE/src/plugins/coreplugin/coreplugin.pri )
include( $$IDE_SOURCE_TREE/src/plugins/projectexplorer/projectexplorer.pri )
include( $$IDE_SOURCE_TREE/src/plugins/texteditor/texteditor.pri )
INCLUDEPATH += $$IDE_SOURCE_TREE/src \
$$IDE_SOURCE_TREE/src/plugins \
$$IDE_SOURCE_TREE/src/libs \
$$IDE_SOURCE_TREE/src/libs/extensionsystem
HEADERS += todoplugin.h \
todooutputpane.h \
settingsdialog.h \
settingspage.h \
addkeyworddialog.h \
keyword.h
SOURCES += todoplugin.cpp \
todooutputpane.cpp \
settingsdialog.cpp \
settingspage.cpp \
addkeyworddialog.cpp \
keyword.cpp
OTHER_FILES += todo.pluginspec
RESOURCES += \
icons.qrc
FORMS += \
settingsdialog.ui \
addkeyworddialog.ui

View File

@@ -0,0 +1,8 @@
<RCC>
<qresource prefix="/todoplugin">
<file>images/todo.png</file>
<file>images/info.png</file>
<file>images/current-file.png</file>
<file>images/whole-project.png</file>
</qresource>
</RCC>