diff --git a/src/plugins/todo/INSTALL b/src/plugins/todo/INSTALL new file mode 100644 index 00000000000..e992d0a0271 --- /dev/null +++ b/src/plugins/todo/INSTALL @@ -0,0 +1,7 @@ +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 diff --git a/src/plugins/todo/LICENSE.BSD b/src/plugins/todo/LICENSE.BSD new file mode 100644 index 00000000000..a3c72c27b54 --- /dev/null +++ b/src/plugins/todo/LICENSE.BSD @@ -0,0 +1,20 @@ +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. diff --git a/src/plugins/todo/addkeyworddialog.cpp b/src/plugins/todo/addkeyworddialog.cpp new file mode 100644 index 00000000000..436a185627a --- /dev/null +++ b/src/plugins/todo/addkeyworddialog.cpp @@ -0,0 +1,42 @@ +#include "addkeyworddialog.h" +#include "ui_addkeyworddialog.h" +#include + + +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()); +} diff --git a/src/plugins/todo/addkeyworddialog.h b/src/plugins/todo/addkeyworddialog.h new file mode 100644 index 00000000000..39c8e0d5721 --- /dev/null +++ b/src/plugins/todo/addkeyworddialog.h @@ -0,0 +1,28 @@ +#ifndef ADDKEYWORDDIALOG_H +#define ADDKEYWORDDIALOG_H + +#include + +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 diff --git a/src/plugins/todo/addkeyworddialog.ui b/src/plugins/todo/addkeyworddialog.ui new file mode 100644 index 00000000000..3d7c0269870 --- /dev/null +++ b/src/plugins/todo/addkeyworddialog.ui @@ -0,0 +1,123 @@ + + + AddKeywordDialog + + + + 0 + 0 + 379 + 225 + + + + Dialog + + + + + + Icons + + + + + + + + + + + + + + Color + + + + QFormLayout::ExpandingFieldsGrow + + + + + \#HHHHHH; + + + #000000 + + + + + + + Choose + + + + + + + + + + Keyword + + + + + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + AddKeywordDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + AddKeywordDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/plugins/todo/icons.qrc b/src/plugins/todo/icons.qrc new file mode 100755 index 00000000000..045f39daa08 --- /dev/null +++ b/src/plugins/todo/icons.qrc @@ -0,0 +1,8 @@ + + + images/error.png + images/info.png + images/warning.png + images/todo.png + + diff --git a/src/plugins/todo/images/error.png b/src/plugins/todo/images/error.png new file mode 100755 index 00000000000..87cd0b0125d Binary files /dev/null and b/src/plugins/todo/images/error.png differ diff --git a/src/plugins/todo/images/info.png b/src/plugins/todo/images/info.png new file mode 100755 index 00000000000..f6af9f83f4d Binary files /dev/null and b/src/plugins/todo/images/info.png differ diff --git a/src/plugins/todo/images/todo.png b/src/plugins/todo/images/todo.png new file mode 100644 index 00000000000..78e6b5840db Binary files /dev/null and b/src/plugins/todo/images/todo.png differ diff --git a/src/plugins/todo/images/warning.png b/src/plugins/todo/images/warning.png new file mode 100755 index 00000000000..0bc86a3d12b Binary files /dev/null and b/src/plugins/todo/images/warning.png differ diff --git a/src/plugins/todo/keyword.cpp b/src/plugins/todo/keyword.cpp new file mode 100644 index 00000000000..a1d549c34a4 --- /dev/null +++ b/src/plugins/todo/keyword.cpp @@ -0,0 +1,26 @@ +#include "keyword.h" + +Keyword::Keyword() +{ +} + +Keyword::Keyword(QString name_, QIcon icon_, QColor warningColor_) : + name(name_), icon(icon_), warningColor(warningColor_) +{ +} + +QDataStream &operator<<(QDataStream &out, const Keyword &myObj) +{ + out << myObj.name; + out << myObj.icon; + out << myObj.warningColor; + return out; +} + +QDataStream &operator>>(QDataStream &in, Keyword &myObj) +{ + in >> myObj.name; + in >> myObj.icon; + in >> myObj.warningColor; + return in; +} diff --git a/src/plugins/todo/keyword.h b/src/plugins/todo/keyword.h new file mode 100644 index 00000000000..41a59dc3b2d --- /dev/null +++ b/src/plugins/todo/keyword.h @@ -0,0 +1,29 @@ +#ifndef KEYWORD_H +#define KEYWORD_H + +#include +#include +#include +#include +#include + +class Keyword +{ +public: + Keyword(); + Keyword(QString name_, QIcon icon_, QColor warningColor_); + QString name; + QIcon icon; + QColor warningColor; +}; + +typedef QList KeywordsList; + +QDataStream &operator<<(QDataStream &out, const Keyword &myObj); +QDataStream &operator>>(QDataStream &in, Keyword &myObj); + + +Q_DECLARE_METATYPE(KeywordsList) +Q_DECLARE_METATYPE(Keyword) + +#endif // KEYWORD_H diff --git a/src/plugins/todo/settingsdialog.cpp b/src/plugins/todo/settingsdialog.cpp new file mode 100644 index 00000000000..0efd8dc86aa --- /dev/null +++ b/src/plugins/todo/settingsdialog.cpp @@ -0,0 +1,138 @@ +#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(); +} diff --git a/src/plugins/todo/settingsdialog.h b/src/plugins/todo/settingsdialog.h new file mode 100644 index 00000000000..316137d3477 --- /dev/null +++ b/src/plugins/todo/settingsdialog.h @@ -0,0 +1,45 @@ +#ifndef SETTINGSDIALOG_H +#define SETTINGSDIALOG_H + +#include +#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 diff --git a/src/plugins/todo/settingsdialog.ui b/src/plugins/todo/settingsdialog.ui new file mode 100644 index 00000000000..521a24c1ccb --- /dev/null +++ b/src/plugins/todo/settingsdialog.ui @@ -0,0 +1,143 @@ + + + SettingsDialog + + + + 0 + 0 + 740 + 423 + + + + Form + + + + + + + + + + + + + + + + Add + + + + + + + Remove + + + + + + + Reset + + + + + + + View options + + + + + + + + From current opened file + + + true + + + + + + + true + + + From projects + + + + + + + + + + + + Pane options + + + + + + + + Show in "TODO Output" + + + true + + + + + + + true + + + Show in "Build Issues" + + + + + + + + + + + + Icons and Colors show on +TODO Output pane only + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + diff --git a/src/plugins/todo/settingspage.cpp b/src/plugins/todo/settingspage.cpp new file mode 100644 index 00000000000..ef55cd1b1e9 --- /dev/null +++ b/src/plugins/todo/settingspage.cpp @@ -0,0 +1,118 @@ +#include "settingspage.h" +#include +#include +#include + +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; +} diff --git a/src/plugins/todo/settingspage.h b/src/plugins/todo/settingspage.h new file mode 100644 index 00000000000..4f43f8afa88 --- /dev/null +++ b/src/plugins/todo/settingspage.h @@ -0,0 +1,39 @@ +#ifndef SETTINGSPAGE_H +#define SETTINGSPAGE_H + +#include +#include +#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 diff --git a/src/plugins/todo/todooutputpane.cpp b/src/plugins/todo/todooutputpane.cpp new file mode 100755 index 00000000000..57fe83fba50 --- /dev/null +++ b/src/plugins/todo/todooutputpane.cpp @@ -0,0 +1,174 @@ +/* + * + * TODO plugin - Add pane with list all TODO, FIXME, etc. comments. + * + * Copyright (C) 2010 VasiliySorokin + * + * Authors: Vasiliy Sorokin + * + * This file is part of TODO plugin for QtCreator. + * + * 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. + * +*/ +#include "todooutputpane.h" +#include +#include +#include + +// TODO: make fix +// NOTE: make note +// HACK: make hack +// BUG: make bug + +TodoOutputPane::TodoOutputPane(QObject *parent) : IOutputPane(parent) +{ + todoList = new QListWidget(); + todoList->setFlow(QListView::TopToBottom); + todoList->setFrameStyle(QFrame::NoFrame); + lastCurrentRow = 0; +} + +TodoOutputPane::~TodoOutputPane() +{ + delete todoList; +} + +void TodoOutputPane::addItem(const QString &text, const QString &file, const int rowNumber, const QIcon &icon, const QColor &color) +{ + QListWidgetItem *newItem = new QListWidgetItem(); + newItem->setBackgroundColor(color); + 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 TodoOutputPane::toolBarWidgets() const +{ + return QList(); +} + +QString TodoOutputPane::name() const +{ + return tr("TODO Output"); +} + +QString TodoOutputPane::displayName() const +{ + return name(); +} + +int TodoOutputPane::priorityInStatusBar() const +{ + return 1; +} + +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) +{ + todoList->setVisible(visible); +} + +void TodoOutputPane::setFocus() +{ + todoList->setFocus(); +} + +bool TodoOutputPane::hasFocus() +{ + return todoList->hasFocus(); +} + +bool TodoOutputPane::canFocus() +{ + return true; +} + +bool TodoOutputPane::canNavigate() +{ + return todoList->count() > 1; +} + +bool TodoOutputPane::canNext() +{ + return todoList->currentRow() < todoList->count() && todoList->count() > 1; +} + +bool TodoOutputPane::canPrevious() +{ + return todoList->currentRow() > 0 && todoList->count() > 1; +} + +void TodoOutputPane::goToNext() +{ + todoList->setCurrentRow(todoList->currentRow() + 1); +} + +void TodoOutputPane::goToPrev() +{ + todoList->setCurrentRow(todoList->currentRow() - 1); +} + +void TodoOutputPane::sort() +{ + todoList->sortItems(Qt::AscendingOrder); + if (todoList->count() > 0) + todoList->setCurrentRow(lastCurrentRow < todoList->count() ? lastCurrentRow : todoList->count() - 1); +} diff --git a/src/plugins/todo/todooutputpane.h b/src/plugins/todo/todooutputpane.h new file mode 100755 index 00000000000..2192eecc83a --- /dev/null +++ b/src/plugins/todo/todooutputpane.h @@ -0,0 +1,76 @@ +/* + * + * TODO plugin - Add pane with list all TODO, FIXME, etc. comments. + * + * Copyright (C) 2010 VasiliySorokin + * + * Authors: Vasiliy Sorokin + * + * This file is part of TODO plugin for QtCreator. + * + * 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. + * +*/ + +#ifndef TODOOUTPUTPANE_H +#define TODOOUTPUTPANE_H + +#include "keyword.h" +#include +#include +#include + +class TodoOutputPane : public Core::IOutputPane +{ +public: + TodoOutputPane(QObject *parent); + ~TodoOutputPane(); + + QWidget *outputWidget(QWidget *parent); + QList toolBarWidgets() const; + QString name() const; + QString displayName() const; + + int priorityInStatusBar() const; + + void clearContents(); + void clearContents(QString filename); + void visibilityChanged(bool visible); + + void setFocus(); + bool hasFocus(); + bool canFocus(); + + bool canNavigate(); + bool canNext(); + bool canPrevious(); + void goToNext(); + void goToPrev(); + + void sort(); + + void addItem(const QString &text, const QString &file, const int rowNumber, const QIcon &icon, const QColor &color); + QListWidget *getTodoList() const; + +private: + QListWidget *todoList; + int lastCurrentRow; +}; + +#endif // TODOOUTPUTPANE_H diff --git a/src/plugins/todo/todoplugin.cpp b/src/plugins/todo/todoplugin.cpp new file mode 100755 index 00000000000..79c8df7fe29 --- /dev/null +++ b/src/plugins/todo/todoplugin.cpp @@ -0,0 +1,376 @@ +/* + * + * TODO plugin - Add pane with list all TODO, FIXME, etc. comments. + * + * Copyright (C) 2010 VasiliySorokin + * + * Authors: Vasiliy Sorokin + * + * This file is part of TODO plugin for QtCreator. + * + * 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. + * +*/ + +#include "todoplugin.h" +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +TodoPlugin::TodoPlugin() +{ + qRegisterMetaTypeStreamOperators("Keyword"); + qRegisterMetaTypeStreamOperators("KeywordsList"); + currentProject = 0; + inReading = false; + readSettings(); +} + +TodoPlugin::~TodoPlugin() +{ +// Do notning +} + +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(); + settings->endGroup(); +} + +bool TodoPlugin::initialize(const QStringList& args, QString *errMsg) +{ + Q_UNUSED(args); + 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(); + 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")); + } + + } + addAutoReleasedObject(settingsPage); + + 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; +} + +void TodoPlugin::extensionsInitialized() +{ +// Do nothing +} + +void TodoPlugin::shutdown() +{ +// Do nothing +} + +void TodoPlugin::showPane() +{ + if (paneOptions == 0) + { + outPane->visibilityChanged(true); + outPane->setFocus(); + } +} + +void TodoPlugin::gotoToRowInFile(QListWidgetItem *item) +{ + int row = item->data(Qt::UserRole + 2).toInt(); + QString file = item->data(Qt::UserRole + 1).toString(); + + if (QFileInfo(file).exists()) + { + Core::IEditor *editor = Core::EditorManager::instance()->openEditor(file); + editor->gotoLine(row); + } +} + +void TodoPlugin::currentEditorChanged(Core::IEditor *editor) +{ + if (inReading) + return; + 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) +{ + for (int i = 0; i < tasks.count(); ++i) + { + if (!tasks.at(i).file.compare(filename)) + { + tasks.removeAt(i); + } + } +} + +void TodoPlugin::addLocalTaskToTaskWindow() +{ + for (int i = 0; i < tasks.count(); ++i) + { + taskHub->addTask(tasks.at(i)); + } +} + +void TodoPlugin::fileChanged() +{ + 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) +{ + 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 result = QtConcurrent::run(&TodoPlugin::readCurrentProject, this); + Core::ICore::instance()->progressManager()->addTask(result, tr("Todoscan"), "Todo.Plugin.Scanning"); + +} + +void TodoPlugin::readCurrentProject(QFutureInterface &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) + + diff --git a/src/plugins/todo/todoplugin.h b/src/plugins/todo/todoplugin.h new file mode 100755 index 00000000000..1623ac83f34 --- /dev/null +++ b/src/plugins/todo/todoplugin.h @@ -0,0 +1,91 @@ +/* + * + * TODO plugin - Add pane with list all TODO, FIXME, etc. comments. + * + * Copyright (C) 2010 VasiliySorokin + * + * Authors: Vasiliy Sorokin + * + * This file is part of TODO plugin for QtCreator. + * + * 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. + * +*/ + +#ifndef TODOPLUGIN_H +#define TODOPLUGIN_H +#include +#include +#include +#include +#include +#include +#include +#include +#include "todooutputpane.h" +#include "settingspage.h" +#include "keyword.h" + + +class TodoPlugin : public ExtensionSystem::IPlugin +{ + Q_OBJECT +public: + TodoPlugin(); + ~TodoPlugin(); + void extensionsInitialized(); + bool initialize(const QStringList & arguments, QString * errorString); + void shutdown(); + +public slots: + void showPane(); + void gotoToRowInFile(QListWidgetItem *); + void currentEditorChanged(Core::IEditor *editor); + void fileChanged(); + void projectChanged(ProjectExplorer::Project *); + +signals: + void updateFutureValue(int value); + void setFutureRange(int, int); + +private: + void readFile(QString); + static void readCurrentProject(QFutureInterface &future, TodoPlugin* instance); + void removeFromLocalTasks(QString filename); + void addLocalTaskToTaskWindow(); + + static bool taskLessThan(const ProjectExplorer::Task &t1, const ProjectExplorer::Task &t2); + + Keyword prepareOutputString(QString &text); + QString generatePatternString(); + void readSettings(); + TodoOutputPane *outPane; + ProjectExplorer::TaskHub *taskHub; + SettingsPage *settingsPage; + QString patternString; + KeywordsList keywords; + int projectOptions; + int paneOptions; + ProjectExplorer::Project *currentProject; + QList tasks; + bool inReading; + QFutureInterface *progressObject; +}; +#endif // TODOPLUGIN_H + diff --git a/src/plugins/todo/todoplugin.pro b/src/plugins/todo/todoplugin.pro new file mode 100755 index 00000000000..83ce31cda10 --- /dev/null +++ b/src/plugins/todo/todoplugin.pro @@ -0,0 +1,46 @@ +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