1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 Dmitry Savchenko
4 ** Copyright (C) 2016 Vasiliy Sorokin
5 ** Contact: https://www.qt.io/licensing/
6 **
7 ** This file is part of Qt Creator.
8 **
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21 ** included in the packaging of this file. Please review the following
22 ** information to ensure the GNU General Public License requirements will
23 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24 **
25 ****************************************************************************/
26
27 #include "optionsdialog.h"
28 #include "ui_optionsdialog.h"
29 #include "keyworddialog.h"
30 #include "keyword.h"
31 #include "settings.h"
32 #include "constants.h"
33
34 namespace Todo {
35 namespace Internal {
36
37 class OptionsDialog final : public Core::IOptionsPageWidget
38 {
39 Q_DECLARE_TR_FUNCTIONS(Todo::Internal::TodoOptionsPage)
40
41 public:
42 OptionsDialog(Settings *settings, const std::function<void ()> &onApply);
43
44 void apply() final;
45
46 void setSettings(const Settings &settings);
47
48 private:
49 void addKeywordButtonClicked();
50 void editKeywordButtonClicked();
51 void removeKeywordButtonClicked();
52 void resetKeywordsButtonClicked();
53 void setKeywordsButtonsEnabled();
54 Settings settingsFromUi();
55 void addToKeywordsList(const Keyword &keyword);
56 void editKeyword(QListWidgetItem *item);
57 QSet<QString> keywordNames();
58
59 Ui::OptionsDialog ui;
60 Settings *m_settings = nullptr;
61 std::function<void()> m_onApply;
62 };
63
OptionsDialog(Settings * settings,const std::function<void ()> & onApply)64 OptionsDialog::OptionsDialog(Settings *settings, const std::function<void ()> &onApply)
65 : m_settings(settings), m_onApply(onApply)
66 {
67 ui.setupUi(this);
68 ui.keywordsList->setIconSize(QSize(16, 16));
69 setKeywordsButtonsEnabled();
70 connect(ui.addKeywordButton, &QAbstractButton::clicked,
71 this, &OptionsDialog::addKeywordButtonClicked);
72 connect(ui.removeKeywordButton, &QAbstractButton::clicked,
73 this, &OptionsDialog::removeKeywordButtonClicked);
74 connect(ui.editKeywordButton, &QAbstractButton::clicked,
75 this, &OptionsDialog::editKeywordButtonClicked);
76 connect(ui.resetKeywordsButton, &QAbstractButton::clicked,
77 this, &OptionsDialog::resetKeywordsButtonClicked);
78 connect(ui.keywordsList, &QListWidget::itemDoubleClicked,
79 this, &OptionsDialog::editKeyword);
80 connect(ui.keywordsList, &QListWidget::itemSelectionChanged,
81 this, &OptionsDialog::setKeywordsButtonsEnabled);
82
83 setSettings(*m_settings);
84 }
85
addToKeywordsList(const Keyword & keyword)86 void OptionsDialog::addToKeywordsList(const Keyword &keyword)
87 {
88 auto item = new QListWidgetItem(icon(keyword.iconType), keyword.name);
89 item->setData(Qt::UserRole, static_cast<int>(keyword.iconType));
90 item->setForeground(keyword.color);
91 ui.keywordsList->addItem(item);
92 }
93
keywordNames()94 QSet<QString> OptionsDialog::keywordNames()
95 {
96 const KeywordList keywords = settingsFromUi().keywords;
97
98 QSet<QString> result;
99 for (const Keyword &keyword : keywords)
100 result << keyword.name;
101
102 return result;
103 }
104
addKeywordButtonClicked()105 void OptionsDialog::addKeywordButtonClicked()
106 {
107 Keyword keyword;
108 KeywordDialog keywordDialog(keyword, keywordNames(), this);
109 if (keywordDialog.exec() == QDialog::Accepted) {
110 keyword = keywordDialog.keyword();
111 addToKeywordsList(keyword);
112 }
113 }
114
editKeywordButtonClicked()115 void OptionsDialog::editKeywordButtonClicked()
116 {
117 QListWidgetItem *item = ui.keywordsList->currentItem();
118 editKeyword(item);
119 }
120
editKeyword(QListWidgetItem * item)121 void OptionsDialog::editKeyword(QListWidgetItem *item)
122 {
123 Keyword keyword;
124 keyword.name = item->text();
125 keyword.iconType = static_cast<IconType>(item->data(Qt::UserRole).toInt());
126 keyword.color = item->foreground().color();
127
128 QSet<QString> keywordNamesButThis = keywordNames();
129 keywordNamesButThis.remove(keyword.name);
130
131 KeywordDialog keywordDialog(keyword, keywordNamesButThis, this);
132 if (keywordDialog.exec() == QDialog::Accepted) {
133 keyword = keywordDialog.keyword();
134 item->setIcon(icon(keyword.iconType));
135 item->setText(keyword.name);
136 item->setData(Qt::UserRole, static_cast<int>(keyword.iconType));
137 item->setForeground(keyword.color);
138 }
139 }
140
removeKeywordButtonClicked()141 void OptionsDialog::removeKeywordButtonClicked()
142 {
143 delete ui.keywordsList->takeItem(ui.keywordsList->currentRow());
144 }
145
resetKeywordsButtonClicked()146 void OptionsDialog::resetKeywordsButtonClicked()
147 {
148 Settings newSettings;
149 newSettings.setDefault();
150 setSettings(newSettings);
151 }
152
setKeywordsButtonsEnabled()153 void OptionsDialog::setKeywordsButtonsEnabled()
154 {
155 const bool isSomethingSelected = !ui.keywordsList->selectedItems().isEmpty();
156 ui.removeKeywordButton->setEnabled(isSomethingSelected);
157 ui.editKeywordButton->setEnabled(isSomethingSelected);
158 }
159
setSettings(const Settings & settings)160 void OptionsDialog::setSettings(const Settings &settings)
161 {
162 ui.scanInCurrentFileRadioButton->setChecked(settings.scanningScope == ScanningScopeCurrentFile);
163 ui.scanInProjectRadioButton->setChecked(settings.scanningScope == ScanningScopeProject);
164 ui.scanInSubprojectRadioButton->setChecked(settings.scanningScope == ScanningScopeSubProject);
165
166 ui.keywordsList->clear();
167 for (const Keyword &keyword : qAsConst(settings.keywords))
168 addToKeywordsList(keyword);
169 }
170
settingsFromUi()171 Settings OptionsDialog::settingsFromUi()
172 {
173 Settings settings;
174
175 if (ui.scanInCurrentFileRadioButton->isChecked())
176 settings.scanningScope = ScanningScopeCurrentFile;
177 else if (ui.scanInSubprojectRadioButton->isChecked())
178 settings.scanningScope = ScanningScopeSubProject;
179 else
180 settings.scanningScope = ScanningScopeProject;
181
182 settings.keywords.clear();
183 for (int i = 0; i < ui.keywordsList->count(); ++i) {
184 QListWidgetItem *item = ui.keywordsList->item(i);
185
186 Keyword keyword;
187 keyword.name = item->text();
188 keyword.iconType = static_cast<IconType>(item->data(Qt::UserRole).toInt());
189 keyword.color = item->foreground().color();
190
191 settings.keywords << keyword;
192 }
193
194 return settings;
195 }
196
apply()197 void OptionsDialog::apply()
198 {
199 Settings newSettings = settingsFromUi();
200
201 // "apply" itself is interpreted as "use these keywords, also for other themes".
202 newSettings.keywordsEdited = true;
203
204 if (newSettings == *m_settings)
205 return;
206
207 *m_settings = newSettings;
208 m_onApply();
209 }
210
211 // TodoOptionsPage
212
TodoOptionsPage(Settings * settings,const std::function<void ()> & onApply)213 TodoOptionsPage::TodoOptionsPage(Settings *settings, const std::function<void ()> &onApply)
214 {
215 setId("TodoSettings");
216 setDisplayName(OptionsDialog::tr("To-Do"));
217 setCategory("To-Do");
218 setDisplayCategory(OptionsDialog::tr("To-Do"));
219 setCategoryIconPath(":/todoplugin/images/settingscategory_todo.png");
220 setWidgetCreator([settings, onApply] { return new OptionsDialog(settings, onApply); });
221 }
222
223 } // namespace Internal
224 } // namespace Todo
225