Todo: Pimpl plugin and move OptionPage to new scheme

Change-Id: I75409ff14697f0edf505328e19483a4dda8f6062
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
This commit is contained in:
hjk
2020-02-07 17:50:21 +01:00
parent 8228d43579
commit 9a42382fd1
9 changed files with 134 additions and 281 deletions

View File

@@ -8,7 +8,6 @@ add_qtc_plugin(Todo
keyworddialog.cpp keyworddialog.h keyworddialog.ui keyworddialog.cpp keyworddialog.h keyworddialog.ui
lineparser.cpp lineparser.h lineparser.cpp lineparser.h
optionsdialog.cpp optionsdialog.h optionsdialog.ui optionsdialog.cpp optionsdialog.h optionsdialog.ui
optionspage.cpp optionspage.h
qmljstodoitemsscanner.cpp qmljstodoitemsscanner.h qmljstodoitemsscanner.cpp qmljstodoitemsscanner.h
settings.cpp settings.h settings.cpp settings.h
todoicons.cpp todoicons.h todoicons.cpp todoicons.h

View File

@@ -34,66 +34,74 @@
namespace Todo { namespace Todo {
namespace Internal { namespace Internal {
OptionsDialog::OptionsDialog() : class OptionsDialog final : public Core::IOptionsPageWidget
ui(new Ui::OptionsDialog)
{ {
ui->setupUi(this); Q_DECLARE_TR_FUNCTIONS(Todo::Internal::TodoOptionsPage)
ui->keywordsList->setIconSize(QSize(16, 16));
public:
OptionsDialog(Settings *settings, const std::function<void ()> &onApply);
void apply() final;
void setSettings(const Settings &settings);
private:
void addKeywordButtonClicked();
void editKeywordButtonClicked();
void removeKeywordButtonClicked();
void resetKeywordsButtonClicked();
void setKeywordsButtonsEnabled();
Settings settingsFromUi();
void addToKeywordsList(const Keyword &keyword);
void editKeyword(QListWidgetItem *item);
QSet<QString> keywordNames();
Ui::OptionsDialog ui;
Settings *m_settings = nullptr;
std::function<void()> m_onApply;
};
OptionsDialog::OptionsDialog(Settings *settings, const std::function<void ()> &onApply)
: m_settings(settings), m_onApply(onApply)
{
ui.setupUi(this);
ui.keywordsList->setIconSize(QSize(16, 16));
setKeywordsButtonsEnabled(); setKeywordsButtonsEnabled();
connect(ui->addKeywordButton, &QAbstractButton::clicked, connect(ui.addKeywordButton, &QAbstractButton::clicked,
this, &OptionsDialog::addKeywordButtonClicked); this, &OptionsDialog::addKeywordButtonClicked);
connect(ui->removeKeywordButton, &QAbstractButton::clicked, connect(ui.removeKeywordButton, &QAbstractButton::clicked,
this, &OptionsDialog::removeKeywordButtonClicked); this, &OptionsDialog::removeKeywordButtonClicked);
connect(ui->editKeywordButton, &QAbstractButton::clicked, connect(ui.editKeywordButton, &QAbstractButton::clicked,
this, &OptionsDialog::editKeywordButtonClicked); this, &OptionsDialog::editKeywordButtonClicked);
connect(ui->resetKeywordsButton, &QAbstractButton::clicked, connect(ui.resetKeywordsButton, &QAbstractButton::clicked,
this, &OptionsDialog::resetKeywordsButtonClicked); this, &OptionsDialog::resetKeywordsButtonClicked);
connect(ui->keywordsList, &QListWidget::itemDoubleClicked, connect(ui.keywordsList, &QListWidget::itemDoubleClicked,
this, &OptionsDialog::keywordDoubleClicked); this, &OptionsDialog::editKeyword);
connect(ui->keywordsList, &QListWidget::itemSelectionChanged, connect(ui.keywordsList, &QListWidget::itemSelectionChanged,
this, &OptionsDialog::setKeywordsButtonsEnabled); this, &OptionsDialog::setKeywordsButtonsEnabled);
}
OptionsDialog::~OptionsDialog() setSettings(*m_settings);
{
delete ui;
}
void OptionsDialog::keywordDoubleClicked(QListWidgetItem *item)
{
editKeyword(item);
}
void OptionsDialog::setSettings(const Settings &settings)
{
uiFromSettings(settings);
} }
void OptionsDialog::addToKeywordsList(const Keyword &keyword) void OptionsDialog::addToKeywordsList(const Keyword &keyword)
{ {
QListWidgetItem *item = new QListWidgetItem( auto item = new QListWidgetItem(icon(keyword.iconType), keyword.name);
icon(keyword.iconType), keyword.name);
item->setData(Qt::UserRole, static_cast<int>(keyword.iconType)); item->setData(Qt::UserRole, static_cast<int>(keyword.iconType));
item->setForeground(keyword.color); item->setForeground(keyword.color);
ui->keywordsList->addItem(item); ui.keywordsList->addItem(item);
} }
QSet<QString> OptionsDialog::keywordNames() QSet<QString> OptionsDialog::keywordNames()
{ {
KeywordList keywords = settingsFromUi().keywords; const KeywordList keywords = settingsFromUi().keywords;
QSet<QString> result; QSet<QString> result;
foreach (const Keyword &keyword, keywords) for (const Keyword &keyword : keywords)
result << keyword.name; result << keyword.name;
return result; return result;
} }
Settings OptionsDialog::settings()
{
return settingsFromUi();
}
void OptionsDialog::addKeywordButtonClicked() void OptionsDialog::addKeywordButtonClicked()
{ {
Keyword keyword; Keyword keyword;
@@ -106,7 +114,7 @@ void OptionsDialog::addKeywordButtonClicked()
void OptionsDialog::editKeywordButtonClicked() void OptionsDialog::editKeywordButtonClicked()
{ {
QListWidgetItem *item = ui->keywordsList->currentItem(); QListWidgetItem *item = ui.keywordsList->currentItem();
editKeyword(item); editKeyword(item);
} }
@@ -132,31 +140,31 @@ void OptionsDialog::editKeyword(QListWidgetItem *item)
void OptionsDialog::removeKeywordButtonClicked() void OptionsDialog::removeKeywordButtonClicked()
{ {
delete ui->keywordsList->takeItem(ui->keywordsList->currentRow()); delete ui.keywordsList->takeItem(ui.keywordsList->currentRow());
} }
void OptionsDialog::resetKeywordsButtonClicked() void OptionsDialog::resetKeywordsButtonClicked()
{ {
Settings newSettings; Settings newSettings;
newSettings.setDefault(); newSettings.setDefault();
uiFromSettings(newSettings); setSettings(newSettings);
} }
void OptionsDialog::setKeywordsButtonsEnabled() void OptionsDialog::setKeywordsButtonsEnabled()
{ {
const bool isSomethingSelected = !ui->keywordsList->selectedItems().isEmpty(); const bool isSomethingSelected = !ui.keywordsList->selectedItems().isEmpty();
ui->removeKeywordButton->setEnabled(isSomethingSelected); ui.removeKeywordButton->setEnabled(isSomethingSelected);
ui->editKeywordButton->setEnabled(isSomethingSelected); ui.editKeywordButton->setEnabled(isSomethingSelected);
} }
void OptionsDialog::uiFromSettings(const Settings &settings) void OptionsDialog::setSettings(const Settings &settings)
{ {
ui->scanInCurrentFileRadioButton->setChecked(settings.scanningScope == ScanningScopeCurrentFile); ui.scanInCurrentFileRadioButton->setChecked(settings.scanningScope == ScanningScopeCurrentFile);
ui->scanInProjectRadioButton->setChecked(settings.scanningScope == ScanningScopeProject); ui.scanInProjectRadioButton->setChecked(settings.scanningScope == ScanningScopeProject);
ui->scanInSubprojectRadioButton->setChecked(settings.scanningScope == ScanningScopeSubProject); ui.scanInSubprojectRadioButton->setChecked(settings.scanningScope == ScanningScopeSubProject);
ui->keywordsList->clear(); ui.keywordsList->clear();
foreach (const Keyword &keyword, settings.keywords) for (const Keyword &keyword : qAsConst(settings.keywords))
addToKeywordsList(keyword); addToKeywordsList(keyword);
} }
@@ -164,16 +172,16 @@ Settings OptionsDialog::settingsFromUi()
{ {
Settings settings; Settings settings;
if (ui->scanInCurrentFileRadioButton->isChecked()) if (ui.scanInCurrentFileRadioButton->isChecked())
settings.scanningScope = ScanningScopeCurrentFile; settings.scanningScope = ScanningScopeCurrentFile;
else if (ui->scanInSubprojectRadioButton->isChecked()) else if (ui.scanInSubprojectRadioButton->isChecked())
settings.scanningScope = ScanningScopeSubProject; settings.scanningScope = ScanningScopeSubProject;
else else
settings.scanningScope = ScanningScopeProject; settings.scanningScope = ScanningScopeProject;
settings.keywords.clear(); settings.keywords.clear();
for (int i = 0; i < ui->keywordsList->count(); ++i) { for (int i = 0; i < ui.keywordsList->count(); ++i) {
QListWidgetItem *item = ui->keywordsList->item(i); QListWidgetItem *item = ui.keywordsList->item(i);
Keyword keyword; Keyword keyword;
keyword.name = item->text(); keyword.name = item->text();
@@ -186,5 +194,31 @@ Settings OptionsDialog::settingsFromUi()
return settings; return settings;
} }
void OptionsDialog::apply()
{
Settings newSettings = settingsFromUi();
// "apply" itself is interpreted as "use these keywords, also for other themes".
newSettings.keywordsEdited = true;
if (newSettings == *m_settings)
return;
*m_settings = newSettings;
m_onApply();
}
// TodoOptionsPage
TodoOptionsPage::TodoOptionsPage(Settings *settings, const std::function<void ()> &onApply)
{
setId("TodoSettings");
setDisplayName(OptionsDialog::tr("To-Do"));
setCategory("To-Do");
setDisplayCategory(OptionsDialog::tr("To-Do"));
setCategoryIconPath(":/todoplugin/images/settingscategory_todo.png");
setWidgetCreator([settings, onApply] { return new OptionsDialog(settings, onApply); });
}
} // namespace Internal } // namespace Internal
} // namespace Todo } // namespace Todo

View File

@@ -26,43 +26,17 @@
#pragma once #pragma once
#include <QWidget> #include <coreplugin/dialogs/ioptionspage.h>
QT_BEGIN_NAMESPACE
class QListWidgetItem;
QT_END_NAMESPACE
namespace Todo { namespace Todo {
namespace Internal { namespace Internal {
namespace Ui { class OptionsDialog; }
class Settings; class Settings;
class Keyword;
class OptionsDialog : public QWidget class TodoOptionsPage final : public Core::IOptionsPage
{ {
public: public:
OptionsDialog(); TodoOptionsPage(Settings *settings, const std::function<void()> &onApply);
~OptionsDialog() override;
void setSettings(const Settings &settings);
Settings settings();
private:
void addKeywordButtonClicked();
void editKeywordButtonClicked();
void removeKeywordButtonClicked();
void resetKeywordsButtonClicked();
void setKeywordsButtonsEnabled();
void keywordDoubleClicked(QListWidgetItem *item);
void uiFromSettings(const Settings &settings);
Settings settingsFromUi();
void addToKeywordsList(const Keyword &keyword);
void editKeyword(QListWidgetItem *item);
QSet<QString> keywordNames();
Ui::OptionsDialog *ui;
}; };
} // namespace Internal } // namespace Internal

View File

@@ -1,88 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 Dmitry Savchenko
** Copyright (C) 2016 Vasiliy Sorokin
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "optionspage.h"
#include "constants.h"
#include "optionsdialog.h"
#include <coreplugin/icore.h>
#include <QList>
#include <QIcon>
#include <QMessageBox>
Todo::Internal::OptionsDialog *some = nullptr;
namespace Todo {
namespace Internal {
OptionsPage::OptionsPage(const Settings &settings, QObject *parent) :
IOptionsPage(parent)
{
setSettings(settings);
setId("TodoSettings");
setDisplayName(tr("To-Do"));
setCategory("To-Do");
setDisplayCategory(tr("To-Do"));
setCategoryIconPath(":/todoplugin/images/settingscategory_todo.png");
}
void OptionsPage::setSettings(const Settings &settings)
{
m_settings = settings;
}
QWidget *OptionsPage::widget()
{
if (!m_widget) {
m_widget = new OptionsDialog;
m_widget->setSettings(m_settings);
}
return m_widget;
}
void OptionsPage::apply()
{
Settings newSettings = m_widget->settings();
// "apply" itself is interpreted as "use these keywords, also for other themes".
newSettings.keywordsEdited = true;
if (newSettings != m_settings) {
m_settings = newSettings;
emit settingsChanged(m_settings);
}
}
void OptionsPage::finish()
{
delete m_widget;
}
} // namespace Internal
} // namespace Todo

View File

@@ -1,62 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 Dmitry Savchenko
** Copyright (C) 2016 Vasiliy Sorokin
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include "settings.h"
#include <coreplugin/dialogs/ioptionspage.h>
#include <QPointer>
namespace Todo {
namespace Internal {
class OptionsDialog;
class OptionsPage : public Core::IOptionsPage
{
Q_OBJECT
public:
OptionsPage(const Settings &settings, QObject *parent = nullptr);
void setSettings(const Settings &settings);
QWidget *widget() override;
void apply() override;
void finish() override;
signals:
void settingsChanged(const Settings &settings);
private:
QPointer<OptionsDialog> m_widget;
Settings m_settings;
};
} // namespace Internal
} // namespace Todo

View File

@@ -6,7 +6,6 @@ HEADERS += todoplugin.h \
todooutputpane.h \ todooutputpane.h \
todoitem.h \ todoitem.h \
settings.h \ settings.h \
optionspage.h \
optionsdialog.h\ optionsdialog.h\
keyworddialog.h \ keyworddialog.h \
todoitemsprovider.h \ todoitemsprovider.h \
@@ -23,7 +22,6 @@ HEADERS += todoplugin.h \
SOURCES += todoplugin.cpp \ SOURCES += todoplugin.cpp \
keyword.cpp \ keyword.cpp \
todooutputpane.cpp \ todooutputpane.cpp \
optionspage.cpp \
settings.cpp \ settings.cpp \
optionsdialog.cpp \ optionsdialog.cpp \
keyworddialog.cpp \ keyworddialog.cpp \

View File

@@ -29,8 +29,6 @@ QtcPlugin {
"todoprojectsettingswidget.cpp", "todoprojectsettingswidget.cpp",
"todoprojectsettingswidget.h", "todoprojectsettingswidget.h",
"todoprojectsettingswidget.ui", "todoprojectsettingswidget.ui",
"optionspage.cpp",
"optionspage.h",
"qmljstodoitemsscanner.cpp", "qmljstodoitemsscanner.cpp",
"qmljstodoitemsscanner.h", "qmljstodoitemsscanner.h",
"settings.cpp", "settings.cpp",

View File

@@ -26,7 +26,7 @@
#include "todoplugin.h" #include "todoplugin.h"
#include "constants.h" #include "constants.h"
#include "optionspage.h" #include "optionsdialog.h"
#include "keyword.h" #include "keyword.h"
#include "todooutputpane.h" #include "todooutputpane.h"
#include "todoitemsprovider.h" #include "todoitemsprovider.h"
@@ -38,28 +38,35 @@
#include <projectexplorer/projectpanelfactory.h> #include <projectexplorer/projectpanelfactory.h>
#include <QtPlugin>
#include <QFileInfo> #include <QFileInfo>
#include <QSettings> #include <QSettings>
namespace Todo { namespace Todo {
namespace Internal { namespace Internal {
TodoPlugin::TodoPlugin() class TodoPluginPrivate : public QObject
{ {
qRegisterMetaType<TodoItem>("TodoItem"); Q_DECLARE_TR_FUNCTIONS(Todo::Internal::TodoPlugin)
}
TodoPlugin::~TodoPlugin() = default; public:
TodoPluginPrivate();
bool TodoPlugin::initialize(const QStringList& args, QString *errMsg) void settingsChanged(const Settings &settings);
void scanningScopeChanged(ScanningScope scanningScope);
void todoItemClicked(const TodoItem &item);
void createItemsProvider();
void createTodoOutputPane();
Settings m_settings;
TodoOutputPane *m_todoOutputPane = nullptr;
TodoOptionsPage m_optionsPage{&m_settings, [this] { settingsChanged(m_settings); }};
TodoItemsProvider *m_todoItemsProvider = nullptr;
};
TodoPluginPrivate::TodoPluginPrivate()
{ {
Q_UNUSED(args)
Q_UNUSED(errMsg)
m_settings.load(Core::ICore::settings()); m_settings.load(Core::ICore::settings());
createOptionsPage();
createItemsProvider(); createItemsProvider();
createTodoOutputPane(); createTodoOutputPane();
@@ -75,53 +82,63 @@ bool TodoPlugin::initialize(const QStringList& args, QString *errMsg)
ProjectExplorer::ProjectPanelFactory::registerFactory(panelFactory); ProjectExplorer::ProjectPanelFactory::registerFactory(panelFactory);
connect(Core::ICore::instance(), &Core::ICore::saveSettingsRequested, connect(Core::ICore::instance(), &Core::ICore::saveSettingsRequested,
this, [this] { m_settings.save(Core::ICore::settings()); }); this, [this] { m_settings.save(Core::ICore::settings()); });
return true;
} }
void TodoPlugin::settingsChanged(const Settings &settings) void TodoPluginPrivate::settingsChanged(const Settings &settings)
{ {
settings.save(Core::ICore::settings()); settings.save(Core::ICore::settings());
m_settings = settings; m_settings = settings;
m_todoItemsProvider->settingsChanged(m_settings); m_todoItemsProvider->settingsChanged(m_settings);
m_todoOutputPane->setScanningScope(m_settings.scanningScope); m_todoOutputPane->setScanningScope(m_settings.scanningScope);
m_optionsPage->setSettings(m_settings);
} }
void TodoPlugin::scanningScopeChanged(ScanningScope scanningScope) void TodoPluginPrivate::scanningScopeChanged(ScanningScope scanningScope)
{ {
Settings newSettings = m_settings; Settings newSettings = m_settings;
newSettings.scanningScope = scanningScope; newSettings.scanningScope = scanningScope;
settingsChanged(newSettings); settingsChanged(newSettings);
} }
void TodoPlugin::todoItemClicked(const TodoItem &item) void TodoPluginPrivate::todoItemClicked(const TodoItem &item)
{ {
if (item.file.exists()) if (item.file.exists())
Core::EditorManager::openEditorAt(item.file.toString(), item.line); Core::EditorManager::openEditorAt(item.file.toString(), item.line);
} }
void TodoPlugin::createItemsProvider() void TodoPluginPrivate::createItemsProvider()
{ {
m_todoItemsProvider = new TodoItemsProvider(m_settings, this); m_todoItemsProvider = new TodoItemsProvider(m_settings, this);
} }
void TodoPlugin::createTodoOutputPane() void TodoPluginPrivate::createTodoOutputPane()
{ {
m_todoOutputPane = new TodoOutputPane(m_todoItemsProvider->todoItemsModel(), &m_settings, this); m_todoOutputPane = new TodoOutputPane(m_todoItemsProvider->todoItemsModel(), &m_settings, this);
m_todoOutputPane->setScanningScope(m_settings.scanningScope); m_todoOutputPane->setScanningScope(m_settings.scanningScope);
connect(m_todoOutputPane, &TodoOutputPane::scanningScopeChanged, connect(m_todoOutputPane, &TodoOutputPane::scanningScopeChanged,
this, &TodoPlugin::scanningScopeChanged); this, &TodoPluginPrivate::scanningScopeChanged);
connect(m_todoOutputPane, &TodoOutputPane::todoItemClicked, connect(m_todoOutputPane, &TodoOutputPane::todoItemClicked,
this, &TodoPlugin::todoItemClicked); this, &TodoPluginPrivate::todoItemClicked);
} }
void TodoPlugin::createOptionsPage() TodoPlugin::TodoPlugin()
{ {
m_optionsPage = new OptionsPage(m_settings, this); qRegisterMetaType<TodoItem>("TodoItem");
connect(m_optionsPage, &OptionsPage::settingsChanged, }
this, &TodoPlugin::settingsChanged);
TodoPlugin::~TodoPlugin()
{
delete d;
}
bool TodoPlugin::initialize(const QStringList& args, QString *errMsg)
{
Q_UNUSED(args)
Q_UNUSED(errMsg)
d = new TodoPluginPrivate;
return true;
} }
} // namespace Internal } // namespace Internal

View File

@@ -26,41 +26,24 @@
#pragma once #pragma once
#include "settings.h"
#include <extensionsystem/iplugin.h> #include <extensionsystem/iplugin.h>
namespace Todo { namespace Todo {
namespace Internal { namespace Internal {
class TodoOutputPane; class TodoPlugin final : public ExtensionSystem::IPlugin
class OptionsPage;
class TodoItemsProvider;
class TodoItem;
class TodoPlugin : public ExtensionSystem::IPlugin
{ {
Q_OBJECT Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "Todo.json") Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "Todo.json")
public: public:
TodoPlugin(); TodoPlugin();
~TodoPlugin() override; ~TodoPlugin() final;
bool initialize(const QStringList &arguments, QString *errorString) override; bool initialize(const QStringList &arguments, QString *errorString) final;
private: private:
void settingsChanged(const Settings &settings); class TodoPluginPrivate *d = nullptr;
void scanningScopeChanged(ScanningScope scanningScope);
void todoItemClicked(const TodoItem &item);
void createItemsProvider();
void createTodoOutputPane();
void createOptionsPage();
Settings m_settings;
TodoOutputPane *m_todoOutputPane = nullptr;
OptionsPage *m_optionsPage = nullptr;
TodoItemsProvider *m_todoItemsProvider = nullptr;
}; };
} // namespace Internal } // namespace Internal