23 #include "configurationdialog.h"
24 #include "ui_configurationdialog.h"
25 #include "gui/commongui.h"
27 #include "configpage.h"
28 #include "qtmetapointer.h"
30 #include <QAbstractButton>
33 #include <QStandardItem>
34 #include <QStandardItemModel>
38 DClass<ConfigurationDialog> :
public Ui::ConfigurationDialog
50 QList<ConfigPage *> configPages;
53 QModelIndex findPageModelIndex(
const QModelIndex &rootIndex,
ConfigPage *page)
55 auto model =
static_cast<QStandardItemModel *
>(tvOptionsList->model());
56 for (
int row = 0; row < model->rowCount(rootIndex); ++row)
58 QModelIndex index = model->index(row, COL_META, rootIndex);
59 ConfigPage *pageAtIndex = pageFromIndex(index);
60 if (pageAtIndex == page)
62 QModelIndex childIndex = findPageModelIndex(index, page);
63 if (childIndex.isValid())
69 ConfigPage *pageFromIndex(
const QModelIndex &index)
71 QModelIndex pageIndex = index.sibling(index.row(), COL_META);
73 void *pointer = metaPointer;
82 return QIcon(
":icons/exclamation_16.png");
97 auto model =
new QStandardItemModel(
this);
99 column < PrivData<ConfigurationDialog>::COLSIZE; ++column)
101 model->setHorizontalHeaderItem(column,
new QStandardItem());
103 d->tvOptionsList->setModel(model);
105 d->tvOptionsList->header()->setSectionResizeMode(
107 d->tvOptionsList->header()->setSectionResizeMode(
110 d->currentlyDisplayedPage =
nullptr;
111 connect(d->buttonBox, SIGNAL(clicked(QAbstractButton*)),
this, SLOT (btnClicked(QAbstractButton*)));
112 this->connect(d->tvOptionsList->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
113 SLOT(switchToItem(QModelIndex,QModelIndex)));
116 ConfigurationDialog::~ConfigurationDialog()
118 for (
int i = 0; i < d->configPages.count(); ++i)
119 delete d->configPages[i];
123 QStandardItem *rootItem,
ConfigPage *configPage,
int position)
125 if (!canConfigPageBeAdded(configPage))
128 auto pModel = (QStandardItemModel *)d->tvOptionsList->model();
129 if (rootItem ==
nullptr)
130 rootItem = pModel->invisibleRootItem();
132 if (!this->hasItemOnList(rootItem))
135 QList<QStandardItem *> row;
137 QStandardItem *nameItem =
new QStandardItem(configPage->
name());
138 nameItem->setIcon(configPage->
icon());
139 nameItem->setToolTip(configPage->
title());
144 nameItem->setData(QVariant::fromValue(metaPointer), Qt::UserRole);
149 rootItem->appendRow(row);
151 rootItem->insertRow(position, row);
153 d->configPages << configPage;
154 this->connect(configPage, SIGNAL(validationRequested()),
155 SLOT(onPageValidationRequested()));
159 validatePage(configPage);
166 auto pModel = (QStandardItemModel *)d->tvOptionsList->model();
167 if (rootItem ==
nullptr)
168 rootItem = pModel->invisibleRootItem();
170 if (!this->hasItemOnList(rootItem))
174 QVariant variantMetaPointer = QVariant::fromValue(metaPointer);
176 QList<QStandardItem *> row;
178 auto nameItem =
new QStandardItem(label);
179 nameItem->setData(variantMetaPointer, Qt::UserRole);
184 rootItem->appendRow(row);
186 rootItem->insertRow(position, row);
191 void ConfigurationDialog::btnClicked(QAbstractButton *button)
194 switch (d->buttonBox->standardButton(button))
199 case QDialogButtonBox::Ok:
200 if (this->validate())
203 this->saveSettings();
207 case QDialogButtonBox::Apply:
208 if (this->validate())
209 this->saveSettings();
212 case QDialogButtonBox::Cancel:
218 bool ConfigurationDialog::canConfigPageBeAdded(
ConfigPage *configPage)
220 return isConfigPageValid(configPage) && !hasConfigPage(configPage);
223 QModelIndex ConfigurationDialog::findPageModelIndex(
ConfigPage *page)
225 auto model =
static_cast<QStandardItemModel *
>(d->tvOptionsList->model());
226 return d->findPageModelIndex(model->indexFromItem(model->invisibleRootItem()), page);
229 bool ConfigurationDialog::isConfigPageValid(
ConfigPage *configPage)
231 return configPage !=
nullptr && !configPage->
name().isEmpty();
234 bool ConfigurationDialog::hasConfigPage(
ConfigPage *configPage)
238 if (configPage == addedPage)
245 void ConfigurationDialog::keyPressEvent(QKeyEvent *e)
257 QDialog::keyPressEvent(e);
261 bool ConfigurationDialog::hasItemOnList(QStandardItem *pItem)
const
263 if (pItem ==
nullptr)
266 auto pModel = (QStandardItemModel *)d->tvOptionsList->model();
271 return pModel->invisibleRootItem() == pItem
272 || pModel->indexFromItem(pItem).isValid();
275 void ConfigurationDialog::onPageValidationRequested()
277 auto page = qobject_cast<
ConfigPage *>(sender());
278 assert(page !=
nullptr);
282 void ConfigurationDialog::reject()
291 void ConfigurationDialog::switchToItem(
const QModelIndex ¤t,
const QModelIndex &previous)
293 if (current.isValid() && current != previous)
295 ConfigPage *configPage = d->pageFromIndex(current);
296 if (isConfigPageValid(configPage))
305 return d->tvOptionsList;
308 void ConfigurationDialog::saveSettings()
311 for (
int i = 0; i < d->configPages.count(); ++i)
312 d->configPages[i]->save();
319 for (
int i = 0; i < d->configPages.count(); ++i)
321 d->configPages[i]->read();
322 validatePage(d->configPages[i]);
329 if (d->currentlyDisplayedPage !=
nullptr)
331 validatePage(d->currentlyDisplayedPage);
332 d->currentlyDisplayedPage->hide();
333 d->mainPanel->setTitle(QString());
335 d->currentlyDisplayedPage = page;
341 d->mainPanel->layout()->addWidget(page);
342 d->mainPanel->setTitle(page->
title());
345 auto *selectionModel = d->tvOptionsList->selectionModel();
346 QModelIndex index = findPageModelIndex(page);
347 if (index.isValid() && index != selectionModel->currentIndex())
349 selectionModel->blockSignals(
true);
350 selectionModel->setCurrentIndex(index, QItemSelectionModel::ClearAndSelect);
351 selectionModel->blockSignals(
false);
356 void ConfigurationDialog::validatePage(
ConfigPage *page)
358 assert(page !=
nullptr);
359 QModelIndex pageIndex = findPageModelIndex(page);
360 assert(pageIndex.isValid());
363 assert(validationIndex.isValid());
365 auto model =
static_cast<QStandardItemModel *
>(d->tvOptionsList->model());
366 QStandardItem *validationItem = model->itemFromIndex(validationIndex);
367 validationItem->setIcon(d->validationIcon(page->
validate()));