23 #include "configurationdialog.h" 24 #include "ui_configurationdialog.h" 26 #include "configpage.h" 27 #include "qtmetapointer.h" 29 #include <QAbstractButton> 32 #include <QStandardItem> 33 #include <QStandardItemModel> 37 DClass<ConfigurationDialog> :
public Ui::ConfigurationDialog
49 QList<ConfigPage *> configPages;
52 QModelIndex findPageModelIndex(
const QModelIndex &rootIndex,
ConfigPage *page)
54 auto model =
static_cast<QStandardItemModel *
>(tvOptionsList->model());
55 for (
int row = 0; row < model->rowCount(rootIndex); ++row)
57 QModelIndex index = model->index(row, COL_META, rootIndex);
58 ConfigPage *pageAtIndex = pageFromIndex(index);
59 if (pageAtIndex == page)
61 QModelIndex childIndex = findPageModelIndex(index, page);
62 if (childIndex.isValid())
68 ConfigPage *pageFromIndex(
const QModelIndex &index)
70 QModelIndex pageIndex = index.sibling(index.row(), COL_META);
72 void *pointer = metaPointer;
81 return QIcon(
":icons/exclamation_16.png");
95 auto model =
new QStandardItemModel(
this);
97 column < PrivData<ConfigurationDialog>::COLSIZE; ++column)
99 model->setHorizontalHeaderItem(column,
new QStandardItem());
101 d->tvOptionsList->setModel(model);
103 d->tvOptionsList->header()->setSectionResizeMode(
105 d->tvOptionsList->header()->setSectionResizeMode(
108 d->currentlyDisplayedPage =
nullptr;
109 connect(d->buttonBox, SIGNAL(clicked(QAbstractButton*)),
this, SLOT (btnClicked(QAbstractButton*)));
110 this->connect(d->tvOptionsList->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
111 SLOT(switchToItem(QModelIndex,QModelIndex)));
114 ConfigurationDialog::~ConfigurationDialog()
116 for (
int i = 0; i < d->configPages.count(); ++i)
117 delete d->configPages[i];
121 QStandardItem *rootItem,
ConfigPage *configPage,
int position)
123 if (!canConfigPageBeAdded(configPage))
126 auto pModel = (QStandardItemModel *)d->tvOptionsList->model();
127 if (rootItem ==
nullptr)
128 rootItem = pModel->invisibleRootItem();
130 if (!this->hasItemOnList(rootItem))
133 QList<QStandardItem *> row;
135 QStandardItem *nameItem =
new QStandardItem(configPage->
name());
136 nameItem->setIcon(configPage->
icon());
141 nameItem->setData(qVariantFromValue(metaPointer), Qt::UserRole);
146 rootItem->appendRow(row);
148 rootItem->insertRow(position, row);
150 d->configPages << configPage;
151 this->connect(configPage, SIGNAL(validationRequested()),
152 SLOT(onPageValidationRequested()));
156 validatePage(configPage);
163 auto pModel = (QStandardItemModel *)d->tvOptionsList->model();
164 if (rootItem ==
nullptr)
165 rootItem = pModel->invisibleRootItem();
167 if (!this->hasItemOnList(rootItem))
171 QVariant variantMetaPointer = qVariantFromValue(metaPointer);
173 QList<QStandardItem *> row;
175 auto nameItem =
new QStandardItem(label);
176 nameItem->setData(variantMetaPointer, Qt::UserRole);
181 rootItem->appendRow(row);
183 rootItem->insertRow(position, row);
188 void ConfigurationDialog::btnClicked(QAbstractButton *button)
191 switch (d->buttonBox->standardButton(button))
196 case QDialogButtonBox::Ok:
197 if (this->validate())
200 this->saveSettings();
204 case QDialogButtonBox::Apply:
205 if (this->validate())
206 this->saveSettings();
209 case QDialogButtonBox::Cancel:
215 bool ConfigurationDialog::canConfigPageBeAdded(
ConfigPage *configPage)
217 return isConfigPageValid(configPage) && !hasConfigPage(configPage);
220 QModelIndex ConfigurationDialog::findPageModelIndex(
ConfigPage *page)
222 auto model =
static_cast<QStandardItemModel *
>(d->tvOptionsList->model());
223 return d->findPageModelIndex(model->indexFromItem(model->invisibleRootItem()), page);
226 bool ConfigurationDialog::isConfigPageValid(
ConfigPage *configPage)
228 return configPage !=
nullptr && !configPage->
name().isEmpty();
231 bool ConfigurationDialog::hasConfigPage(
ConfigPage *configPage)
235 if (configPage == addedPage)
242 void ConfigurationDialog::keyPressEvent(QKeyEvent *e)
254 QDialog::keyPressEvent(e);
258 bool ConfigurationDialog::hasItemOnList(QStandardItem *pItem)
const 260 if (pItem ==
nullptr)
263 auto pModel = (QStandardItemModel *)d->tvOptionsList->model();
268 return pModel->invisibleRootItem() == pItem
269 || pModel->indexFromItem(pItem).isValid();
272 void ConfigurationDialog::onPageValidationRequested()
274 auto page = qobject_cast<
ConfigPage *>(sender());
275 assert(page !=
nullptr);
279 void ConfigurationDialog::reject()
288 void ConfigurationDialog::switchToItem(
const QModelIndex ¤t,
const QModelIndex &previous)
290 if (current.isValid() && current != previous)
292 ConfigPage *configPage = d->pageFromIndex(current);
296 if (isConfigPageValid(configPage))
303 return d->tvOptionsList;
306 void ConfigurationDialog::saveSettings()
309 for (
int i = 0; i < d->configPages.count(); ++i)
310 d->configPages[i]->save();
317 for (
int i = 0; i < d->configPages.count(); ++i)
319 d->configPages[i]->read();
320 validatePage(d->configPages[i]);
327 if (d->currentlyDisplayedPage !=
nullptr)
329 validatePage(d->currentlyDisplayedPage);
330 d->currentlyDisplayedPage->hide();
331 d->mainPanel->setTitle(QString());
333 d->currentlyDisplayedPage = page;
339 d->mainPanel->layout()->addWidget(page);
340 d->mainPanel->setTitle(page->
title());
345 void ConfigurationDialog::validatePage(
ConfigPage *page)
347 assert(page !=
nullptr);
348 QModelIndex pageIndex = findPageModelIndex(page);
349 assert(pageIndex.isValid());
352 assert(validationIndex.isValid());
354 auto model =
static_cast<QStandardItemModel *
>(d->tvOptionsList->model());
355 QStandardItem *validationItem = model->itemFromIndex(validationIndex);
356 validationItem->setIcon(d->validationIcon(page->
validate()));
Validation
Result of validate()
virtual QString name() const =0
Reimplement this to return a list-displayable name for this ConfigPage.
QTreeView * optionsTree()
Returns pointer to the tree widget that contains configuration sections list.
virtual QString title() const
Page title, by default returns the same string as name().
virtual QStandardItem * addConfigPage(QStandardItem *rootItem, ConfigPage *configPage, int position=-1)
Adds a new configuration page to the options tree view.
void read()
Read configuration from persistence to page contents.
bool areSettingsAlreadyRead()
true if settings for this page have already been loaded at least once.
QStandardItem * addLabel(QStandardItem *rootItem, const QString &label, int position=-1)
Adds a label node to the options tree view.
void setAllowSave(bool b)
Change whether settings on this page can be stored in persisting configuration.
virtual Validation validate()
Validate settings on this page.
Validation detected at least one problem.
virtual QIcon icon() const =0
Reimplement this to return a displayable icon for the ConfigPage.
Base class for configuration pages.
void showConfigPage(ConfigPage *widget)