1 /*
2 * LibrePCB - Professional EDA for everyone!
3 * Copyright (C) 2013 LibrePCB Developers, see AUTHORS.md for contributors.
4 * https://librepcb.org/
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 /*******************************************************************************
21 * Includes
22 ******************************************************************************/
23 #include "workspacesettingsdialog.h"
24
25 #include "../workspace.h"
26 #include "ui_workspacesettingsdialog.h"
27 #include "workspacesettings.h"
28
29 #include <librepcb/common/application.h>
30 #include <librepcb/common/model/comboboxdelegate.h>
31 #include <librepcb/common/model/editablelistmodel.h>
32 #include <librepcb/common/norms.h>
33 #include <librepcb/common/toolbox.h>
34
35 #include <QtCore>
36 #include <QtWidgets>
37
38 /*******************************************************************************
39 * Namespace
40 ******************************************************************************/
41 namespace librepcb {
42 namespace workspace {
43
44 /*******************************************************************************
45 * Constructors / Destructor
46 ******************************************************************************/
47
WorkspaceSettingsDialog(WorkspaceSettings & settings,QWidget * parent)48 WorkspaceSettingsDialog::WorkspaceSettingsDialog(WorkspaceSettings& settings,
49 QWidget* parent)
50 : QDialog(parent),
51 mSettings(settings),
52 mLibLocaleOrderModel(new LibraryLocaleOrderModel()),
53 mLibNormOrderModel(new LibraryNormOrderModel()),
54 mRepositoryUrlsModel(new RepositoryUrlModel()),
55 mUi(new Ui::WorkspaceSettingsDialog) {
56 mUi->setupUi(this);
57
58 // Initialize application locale widgets
59 {
60 mUi->cbxAppLocale->addItem(tr("System Language"), QString(""));
61 QMap<QString, QString> map; // map will be sorted by key
62 foreach (const QString& locale, qApp->getAvailableTranslationLocales()) {
63 map.insert(Toolbox::prettyPrintLocale(locale), locale);
64 }
65 QMap<QString, QString>::const_iterator i = map.constBegin();
66 while (i != map.constEnd()) {
67 mUi->cbxAppLocale->addItem(i.key(), i.value());
68 ++i;
69 }
70 }
71
72 // Initialize library locale order widgets
73 {
74 QList<QLocale> locales = QLocale::matchingLocales(
75 QLocale::AnyLanguage, QLocale::AnyScript, QLocale::AnyCountry);
76 QStringList localesStr;
77 foreach (const QLocale& l, locales) { localesStr.append(l.name()); }
78 mLibLocaleOrderModel->setPlaceholderText(tr("Click here to add a locale"));
79 mLibLocaleOrderModel->setDefaultValue(QString(""));
80 mLibLocaleOrderModel->setChoices(localesStr);
81 mUi->tblLibLocaleOrder->setShowMoveButtons(true);
82 mUi->tblLibLocaleOrder->setModel(mLibLocaleOrderModel.data());
83 mUi->tblLibLocaleOrder->setItemDelegateForColumn(
84 LibraryLocaleOrderModel::COLUMN_TEXT,
85 new ComboBoxDelegate(false, this));
86 mUi->tblLibLocaleOrder->horizontalHeader()->setSectionResizeMode(
87 LibraryLocaleOrderModel::COLUMN_TEXT, QHeaderView::Stretch);
88 mUi->tblLibLocaleOrder->horizontalHeader()->setSectionResizeMode(
89 LibraryLocaleOrderModel::COLUMN_ACTIONS, QHeaderView::ResizeToContents);
90 connect(mUi->tblLibLocaleOrder, &EditableTableWidget::btnAddClicked,
91 mLibLocaleOrderModel.data(), &LibraryLocaleOrderModel::addItem);
92 connect(mUi->tblLibLocaleOrder, &EditableTableWidget::btnRemoveClicked,
93 mLibLocaleOrderModel.data(), &LibraryLocaleOrderModel::removeItem);
94 connect(mUi->tblLibLocaleOrder, &EditableTableWidget::btnMoveUpClicked,
95 mLibLocaleOrderModel.data(), &LibraryLocaleOrderModel::moveItemUp);
96 connect(mUi->tblLibLocaleOrder, &EditableTableWidget::btnMoveDownClicked,
97 mLibLocaleOrderModel.data(),
98 &LibraryLocaleOrderModel::moveItemDown);
99 }
100
101 // Initialize library norm order widgets
102 {
103 mLibNormOrderModel->setPlaceholderText(tr("Click here to add a norm"));
104 mLibNormOrderModel->setDefaultValue(QString(""));
105 mLibNormOrderModel->setChoices(getAvailableNorms());
106 mUi->tblLibNormOrder->setShowMoveButtons(true);
107 mUi->tblLibNormOrder->setModel(mLibNormOrderModel.data());
108 mUi->tblLibNormOrder->setItemDelegateForColumn(
109 LibraryNormOrderModel::COLUMN_TEXT, new ComboBoxDelegate(true, this));
110 mUi->tblLibNormOrder->horizontalHeader()->setSectionResizeMode(
111 LibraryNormOrderModel::COLUMN_TEXT, QHeaderView::Stretch);
112 mUi->tblLibNormOrder->horizontalHeader()->setSectionResizeMode(
113 LibraryNormOrderModel::COLUMN_ACTIONS, QHeaderView::ResizeToContents);
114 connect(mUi->tblLibNormOrder, &EditableTableWidget::btnAddClicked,
115 mLibNormOrderModel.data(), &LibraryNormOrderModel::addItem);
116 connect(mUi->tblLibNormOrder, &EditableTableWidget::btnRemoveClicked,
117 mLibNormOrderModel.data(), &LibraryNormOrderModel::removeItem);
118 connect(mUi->tblLibNormOrder, &EditableTableWidget::btnMoveUpClicked,
119 mLibNormOrderModel.data(), &LibraryNormOrderModel::moveItemUp);
120 connect(mUi->tblLibNormOrder, &EditableTableWidget::btnMoveDownClicked,
121 mLibNormOrderModel.data(), &LibraryNormOrderModel::moveItemDown);
122 }
123
124 // Initialize repository URL widgets
125 {
126 mRepositoryUrlsModel->setPlaceholderText(tr("Click here a add an URL"));
127 mUi->tblRepositoryUrls->setShowMoveButtons(true);
128 mUi->tblRepositoryUrls->setModel(mRepositoryUrlsModel.data());
129 mUi->tblRepositoryUrls->horizontalHeader()->setSectionResizeMode(
130 RepositoryUrlModel::COLUMN_TEXT, QHeaderView::Stretch);
131 mUi->tblRepositoryUrls->horizontalHeader()->setSectionResizeMode(
132 RepositoryUrlModel::COLUMN_ACTIONS, QHeaderView::ResizeToContents);
133 connect(mUi->tblRepositoryUrls, &EditableTableWidget::btnAddClicked,
134 mRepositoryUrlsModel.data(), &RepositoryUrlModel::addItem);
135 connect(mUi->tblRepositoryUrls, &EditableTableWidget::btnRemoveClicked,
136 mRepositoryUrlsModel.data(), &RepositoryUrlModel::removeItem);
137 connect(mUi->tblRepositoryUrls, &EditableTableWidget::btnMoveUpClicked,
138 mRepositoryUrlsModel.data(), &RepositoryUrlModel::moveItemUp);
139 connect(mUi->tblRepositoryUrls, &EditableTableWidget::btnMoveDownClicked,
140 mRepositoryUrlsModel.data(), &RepositoryUrlModel::moveItemDown);
141 }
142
143 // Now load all current settings
144 loadSettings();
145
146 // Load the window geometry
147 QSettings clientSettings;
148 restoreGeometry(
149 clientSettings.value("workspace_settings_dialog/window_geometry")
150 .toByteArray());
151
152 // Just in case that the wrong tab is selected in the UI designer:
153 mUi->tabWidget->setCurrentIndex(0);
154
155 // Connect event handlers
156 connect(mUi->buttonBox, &QDialogButtonBox::clicked, this,
157 &WorkspaceSettingsDialog::buttonBoxClicked);
158 }
159
~WorkspaceSettingsDialog()160 WorkspaceSettingsDialog::~WorkspaceSettingsDialog() {
161 // Save the window geometry
162 QSettings clientSettings;
163 clientSettings.setValue("workspace_settings_dialog/window_geometry",
164 saveGeometry());
165 }
166
167 /*******************************************************************************
168 * Private Slots for the GUI elements
169 ******************************************************************************/
170
buttonBoxClicked(QAbstractButton * button)171 void WorkspaceSettingsDialog::buttonBoxClicked(
172 QAbstractButton* button) noexcept {
173 switch (mUi->buttonBox->buttonRole(button)) {
174 case QDialogButtonBox::RejectRole: {
175 reject();
176 break;
177 }
178
179 case QDialogButtonBox::AcceptRole: {
180 saveSettings();
181 accept();
182 break;
183 }
184
185 case QDialogButtonBox::ApplyRole: {
186 saveSettings();
187 break;
188 }
189
190 case QDialogButtonBox::ResetRole: {
191 int answer = QMessageBox::question(
192 this, tr("Restore default settings"),
193 tr("Are you sure to reset all settings to their default values?\n\n"
194 "Attention: This will be applied immediately and cannot be "
195 "undone!"));
196 if (answer == QMessageBox::Yes) {
197 mSettings.restoreDefaults();
198 loadSettings(); // updating all widgets with the new values
199 saveSettings(); // save now since "cancel" does not revert!
200 }
201 break;
202 }
203
204 default:
205 Q_ASSERT(false);
206 break;
207 }
208 }
209
loadSettings()210 void WorkspaceSettingsDialog::loadSettings() noexcept {
211 // User Name
212 mUi->edtUserName->setText(mSettings.userName.get());
213
214 // Application Locale
215 mUi->cbxAppLocale->setCurrentIndex(
216 mUi->cbxAppLocale->findData(mSettings.applicationLocale.get()));
217
218 // Default Length Unit
219 mUi->cbxDefaultLengthUnit->clear();
220 foreach (const LengthUnit& unit, LengthUnit::getAllUnits()) {
221 mUi->cbxDefaultLengthUnit->addItem(unit.toStringTr(), unit.getIndex());
222 }
223 mUi->cbxDefaultLengthUnit->setCurrentIndex(
224 mSettings.defaultLengthUnit.get().getIndex());
225
226 // Autosave Interval
227 mUi->spbAutosaveInterval->setValue(
228 mSettings.projectAutosaveIntervalSeconds.get());
229
230 // Use OpenGL
231 mUi->cbxUseOpenGl->setChecked(mSettings.useOpenGl.get());
232
233 // Library Locale Order
234 mLibLocaleOrderModel->setValues(mSettings.libraryLocaleOrder.get());
235
236 // Library Norm Order
237 mLibNormOrderModel->setValues(mSettings.libraryNormOrder.get());
238
239 // Repository URLs
240 mRepositoryUrlsModel->setValues(mSettings.repositoryUrls.get());
241 }
242
saveSettings()243 void WorkspaceSettingsDialog::saveSettings() noexcept {
244 try {
245 // User Name
246 mSettings.userName.set(mUi->edtUserName->text().trimmed());
247
248 // Application Locale
249 if (mUi->cbxAppLocale->currentIndex() >= 0) {
250 mSettings.applicationLocale.set(
251 mUi->cbxAppLocale->currentData().toString());
252 }
253
254 // Default Length Unit
255 if (mUi->cbxDefaultLengthUnit->currentIndex() >= 0) {
256 mSettings.defaultLengthUnit.set(LengthUnit::fromIndex(
257 mUi->cbxDefaultLengthUnit->currentIndex())); // can throw
258 }
259
260 // Autosave Interval
261 mSettings.projectAutosaveIntervalSeconds.set(
262 mUi->spbAutosaveInterval->value());
263
264 // Use OpenGL
265 mSettings.useOpenGl.set(mUi->cbxUseOpenGl->isChecked());
266
267 // Library Locale Order
268 mSettings.libraryLocaleOrder.set(mLibLocaleOrderModel->getValues());
269
270 // Library Norm Order
271 mSettings.libraryNormOrder.set(mLibNormOrderModel->getValues());
272
273 // Repository URLs
274 mSettings.repositoryUrls.set(mRepositoryUrlsModel->getValues());
275
276 mSettings.saveToFile(); // can throw
277 } catch (const Exception& e) {
278 QMessageBox::critical(this, tr("Error"), e.getMsg());
279 }
280 }
281
282 /*******************************************************************************
283 * End of File
284 ******************************************************************************/
285
286 } // namespace workspace
287 } // namespace librepcb
288