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)