00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "qxtconfigdialog.h"
00026 #include "qxtconfigdialog_p.h"
00027 #if QT_VERSION >= 0x040200
00028 #include <QDialogButtonBox>
00029 #else // QT_VERSION >= 0x040200
00030 #include <QHBoxLayout>
00031 #include <QPushButton>
00032 #endif // QT_VERSION
00033 #include <QStackedWidget>
00034 #include <QApplication>
00035 #include <QTableWidget>
00036 #include <QHeaderView>
00037 #include <QVBoxLayout>
00038 #include <QSplitter>
00039 #include <QPainter>
00040
00041 QxtConfigTableWidget::QxtConfigTableWidget(QWidget* parent) : QTableWidget(parent)
00042 {
00043 int pm = style()->pixelMetric(QStyle::PM_LargeIconSize);
00044 setIconSize(QSize(pm, pm));
00045 setItemDelegate(new QxtConfigDelegate(this));
00046 viewport()->setAttribute(Qt::WA_Hover, true);
00047 }
00048
00049 QStyleOptionViewItem QxtConfigTableWidget::viewOptions() const
00050 {
00051 QStyleOptionViewItem option = QTableWidget::viewOptions();
00052 option.displayAlignment = Qt::AlignHCenter | Qt::AlignTop;
00053 option.decorationAlignment = Qt::AlignHCenter | Qt::AlignTop;
00054 option.decorationPosition = QStyleOptionViewItem::Top;
00055 option.showDecorationSelected = false;
00056 return option;
00057 }
00058
00059 QSize QxtConfigTableWidget::sizeHint() const
00060 {
00061 return QSize(sizeHintForColumn(0), sizeHintForRow(0));
00062 }
00063
00064 bool QxtConfigTableWidget::hasHoverEffect() const
00065 {
00066 return static_cast<QxtConfigDelegate*>(itemDelegate())->hover;
00067 }
00068
00069 void QxtConfigTableWidget::setHoverEffect(bool enabled)
00070 {
00071 static_cast<QxtConfigDelegate*>(itemDelegate())->hover = enabled;
00072 }
00073
00074 QxtConfigDelegate::QxtConfigDelegate(QObject* parent)
00075 : QItemDelegate(parent), hover(true)
00076 {
00077 }
00078
00079 void QxtConfigDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
00080 {
00081 QStyleOptionViewItem opt = option;
00082 if (hover)
00083 {
00084 QPalette::ColorGroup cg = (option.state & QStyle::State_Enabled) ? QPalette::Normal : QPalette::Disabled;
00085 if (cg == QPalette::Normal && !(option.state & QStyle::State_Active))
00086 cg = QPalette::Inactive;
00087
00088 if (option.state & QStyle::State_Selected)
00089 painter->fillRect(opt.rect, option.palette.brush(cg, QPalette::Highlight));
00090 else if ((option.state & QStyle::State_MouseOver) && (option.state & QStyle::State_Enabled))
00091 {
00092 QColor color = option.palette.color(cg, QPalette::Highlight).light();
00093 if (color == option.palette.color(cg, QPalette::Base))
00094 color = option.palette.color(cg, QPalette::AlternateBase);
00095 painter->fillRect(opt.rect, color);
00096 }
00097 else
00098 painter->fillRect(opt.rect, option.palette.brush(cg, QPalette::Base));
00099
00100 opt.showDecorationSelected = false;
00101 opt.state &= ~QStyle::State_HasFocus;
00102 opt.state &= ~QStyle::State_Selected;
00103 }
00104 QItemDelegate::paint(painter, opt, index);
00105 }
00106
00107 QSize QxtConfigDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
00108 {
00109 int margin = qApp->style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1;
00110 int textWidth = option.fontMetrics.width(index.data().toString());
00111 int width = qMax(textWidth, option.decorationSize.width()) + 2 * margin;
00112 int height = option.fontMetrics.height() + option.decorationSize.height() + margin;
00113 return QSize(width, height);
00114 }
00115
00116 void QxtConfigDialogPrivate::init(QxtConfigDialog::IconPosition position)
00117 {
00118 QxtConfigDialog* p = &qxt_p();
00119 splitter = new QSplitter(p);
00120 stack = new QStackedWidget(p);
00121 table = new QxtConfigTableWidget(p);
00122 pos = position;
00123 QObject::connect(table, SIGNAL(currentCellChanged(int, int, int, int)), this, SLOT(setCurrentIndex(int, int)));
00124 QObject::connect(stack, SIGNAL(currentChanged(int)), p, SIGNAL(currentIndexChanged(int)));
00125
00126 #if QT_VERSION >= 0x040200
00127 buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, p);
00128 QObject::connect(buttons, SIGNAL(accepted()), p, SLOT(accept()));
00129 QObject::connect(buttons, SIGNAL(rejected()), p, SLOT(reject()));
00130 #else // QT_VERSION >= 0x040200
00131 buttons = new QWidget(p);
00132 QHBoxLayout* layout = new QHBoxLayout(buttons);
00133 QPushButton* okButton = new QPushButton(QxtConfigDialog::tr("&OK"));
00134 QPushButton* cancelButton = new QPushButton(QxtConfigDialog::tr("&Cancel"));
00135 QObject::connect(okButton, SIGNAL(clicked()), p, SLOT(accept()));
00136 QObject::connect(cancelButton, SIGNAL(clicked()), p, SLOT(reject()));
00137 layout->addStretch();
00138 layout->addWidget(okButton);
00139 layout->addWidget(cancelButton);
00140 #endif
00141 QVBoxLayout* layout = new QVBoxLayout(p);
00142 layout->addWidget(splitter);
00143 layout->addWidget(buttons);
00144 initTable();
00145 relayout();
00146 }
00147
00148 void QxtConfigDialogPrivate::initTable()
00149 {
00150 table->horizontalHeader()->hide();
00151 table->verticalHeader()->hide();
00152 table->setEditTriggers(QAbstractItemView::NoEditTriggers);
00153 table->setTabKeyNavigation(true);
00154 table->setAcceptDrops(false);
00155 table->setDragEnabled(false);
00156 table->setShowGrid(false);
00157 table->setSelectionMode(QAbstractItemView::SingleSelection);
00158 }
00159
00160 void QxtConfigDialogPrivate::relayout()
00161 {
00162 if (pos == QxtConfigDialog::North)
00163 {
00164 splitter->setOrientation(Qt::Vertical);
00165 table->setRowCount(1);
00166 table->setColumnCount(0);
00167 table->horizontalHeader()->setResizeMode(QHeaderView::ResizeToContents);
00168 table->verticalHeader()->setResizeMode(QHeaderView::Stretch);
00169 table->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
00170 table->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
00171 }
00172 else
00173 {
00174 splitter->setOrientation(Qt::Horizontal);
00175 table->setRowCount(0);
00176 table->setColumnCount(1);
00177 table->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
00178 table->verticalHeader()->setResizeMode(QHeaderView::ResizeToContents);
00179 table->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
00180 table->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
00181 }
00182
00183
00184 for (int i = splitter->count() - 1; i >= 0; --i)
00185 {
00186 splitter->widget(i)->setParent(0);
00187 }
00188
00189
00190 switch (pos)
00191 {
00192 case QxtConfigDialog::North:
00193
00194
00195
00196
00197
00198
00199
00200 splitter->addWidget(table);
00201 splitter->addWidget(stack);
00202 break;
00203
00204 case QxtConfigDialog::West:
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214 splitter->addWidget(table);
00215 splitter->addWidget(stack);
00216 break;
00217
00218 case QxtConfigDialog::East:
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228 splitter->addWidget(stack);
00229 splitter->addWidget(table);
00230 break;
00231
00232 default:
00233 qWarning("QxtConfigDialogPrivate::relayout(): unknown position");
00234 break;
00235 }
00236
00237 if (pos == QxtConfigDialog::East)
00238 {
00239 splitter->setStretchFactor(0, 10);
00240 splitter->setStretchFactor(1, 1);
00241 }
00242 else
00243 {
00244 splitter->setStretchFactor(0, 1);
00245 splitter->setStretchFactor(1, 10);
00246 }
00247 }
00248
00249 QTableWidgetItem* QxtConfigDialogPrivate::item(int index) const
00250 {
00251 return pos == QxtConfigDialog::North ? table->item(0, index) : table->item(index, 0);
00252 }
00253
00254 void QxtConfigDialogPrivate::setCurrentIndex(int row, int column)
00255 {
00256 if (pos == QxtConfigDialog::North)
00257 setCurrentIndex(column);
00258 else
00259 setCurrentIndex(row);
00260 }
00261
00262 void QxtConfigDialogPrivate::setCurrentIndex(int index)
00263 {
00264 int previousIndex = stack->currentIndex();
00265 if (previousIndex != -1 && previousIndex != index)
00266 qxt_p().cleanupPage(previousIndex);
00267
00268 stack->setCurrentIndex(index);
00269 table->setCurrentItem(item(index));
00270
00271 if (index != -1)
00272 qxt_p().initializePage(index);
00273 }
00274
00333 QxtConfigDialog::QxtConfigDialog(QWidget* parent, Qt::WindowFlags flags)
00334 : QDialog(parent, flags)
00335 {
00336 QXT_INIT_PRIVATE(QxtConfigDialog);
00337 qxt_d().init();
00338 }
00339
00343 QxtConfigDialog::QxtConfigDialog(QxtConfigDialog::IconPosition position, QWidget* parent, Qt::WindowFlags flags)
00344 : QDialog(parent, flags)
00345 {
00346 QXT_INIT_PRIVATE(QxtConfigDialog);
00347 qxt_d().init(position);
00348 }
00349
00353 QxtConfigDialog::~QxtConfigDialog()
00354 {}
00355
00365 #if QT_VERSION >= 0x040200
00366 QDialogButtonBox* QxtConfigDialog::dialogButtonBox() const
00367 {
00368 return qxt_d().buttons;
00369 }
00370 #endif // QT_VERSION
00371
00377 #if QT_VERSION >= 0x040200
00378 void QxtConfigDialog::setDialogButtonBox(QDialogButtonBox* buttonBox)
00379 {
00380 if (qxt_d().buttons != buttonBox)
00381 {
00382 if (qxt_d().buttons && qxt_d().buttons->parent() == this)
00383 {
00384 delete qxt_d().buttons;
00385 }
00386 qxt_d().buttons = buttonBox;
00387 qxt_d().relayout();
00388 }
00389 }
00390 #endif // QT_VERSION
00391
00404 bool QxtConfigDialog::hasHoverEffect() const
00405 {
00406 return qxt_d().table->hasHoverEffect();
00407 }
00408
00409 void QxtConfigDialog::setHoverEffect(bool enabled)
00410 {
00411 qxt_d().table->setHoverEffect(enabled);
00412 }
00413
00418 QxtConfigDialog::IconPosition QxtConfigDialog::iconPosition() const
00419 {
00420 return qxt_d().pos;
00421 }
00422
00423 void QxtConfigDialog::setIconPosition(QxtConfigDialog::IconPosition position)
00424 {
00425 if (qxt_d().pos != position)
00426 {
00427 qxt_d().pos = position;
00428 qxt_d().relayout();
00429 }
00430 }
00431
00436 QSize QxtConfigDialog::iconSize() const
00437 {
00438 return qxt_d().table->iconSize();
00439 }
00440
00441 void QxtConfigDialog::setIconSize(const QSize& size)
00442 {
00443 qxt_d().table->setIconSize(size);
00444 }
00445
00457 int QxtConfigDialog::addPage(QWidget* page, const QIcon& icon, const QString& title)
00458 {
00459 return insertPage(-1, page, icon, title);
00460 }
00461
00473 int QxtConfigDialog::insertPage(int index, QWidget* page, const QIcon& icon, const QString& title)
00474 {
00475 if (!page)
00476 {
00477 qWarning("QxtConfigDialog::insertPage(): Attempt to insert null page");
00478 return -1;
00479 }
00480
00481 index = qxt_d().stack->insertWidget(index, page);
00482 const QString label = !title.isEmpty() ? title : page->windowTitle();
00483 if (label.isEmpty())
00484 qWarning("QxtConfigDialog::insertPage(): Inserting a page with an empty title");
00485 QTableWidgetItem* item = new QTableWidgetItem(icon, label);
00486 item->setToolTip(label);
00487 if (qxt_d().pos == QxtConfigDialog::North)
00488 {
00489 qxt_d().table->model()->insertColumn(index);
00490 qxt_d().table->setItem(0, index, item);
00491 qxt_d().table->resizeRowToContents(0);
00492 }
00493 else
00494 {
00495 qxt_d().table->model()->insertRow(index);
00496 qxt_d().table->setItem(index, 0, item);
00497 qxt_d().table->resizeColumnToContents(0);
00498 }
00499 qxt_d().table->updateGeometry();
00500 return index;
00501 }
00502
00508 QWidget* QxtConfigDialog::takePage(int index)
00509 {
00510 if (QWidget* page = qxt_d().stack->widget(index))
00511 {
00512 qxt_d().stack->removeWidget(page);
00513 delete qxt_d().item(index);
00514 return page;
00515 }
00516 else
00517 {
00518 qWarning("QxtConfigDialog::removePage(): Unknown index");
00519 return 0;
00520 }
00521 }
00522
00527 int QxtConfigDialog::count() const
00528 {
00529 return qxt_d().stack->count();
00530 }
00531
00536 int QxtConfigDialog::currentIndex() const
00537 {
00538 return qxt_d().stack->currentIndex();
00539 }
00540
00541 void QxtConfigDialog::setCurrentIndex(int index)
00542 {
00543 qxt_d().setCurrentIndex(index);
00544 }
00545
00551 QWidget* QxtConfigDialog::currentPage() const
00552 {
00553 return qxt_d().stack->currentWidget();
00554 }
00555
00561 void QxtConfigDialog::setCurrentPage(QWidget* page)
00562 {
00563 qxt_d().setCurrentIndex(qxt_d().stack->indexOf(page));
00564 }
00565
00569 int QxtConfigDialog::indexOf(QWidget* page) const
00570 {
00571 return qxt_d().stack->indexOf(page);
00572 }
00573
00577 QWidget* QxtConfigDialog::page(int index) const
00578 {
00579 return qxt_d().stack->widget(index);
00580 }
00581
00587 bool QxtConfigDialog::isPageEnabled(int index) const
00588 {
00589 const QWidget* widget = page(index);
00590 return widget && widget->isEnabled();
00591 }
00592
00599 void QxtConfigDialog::setPageEnabled(int index, bool enabled)
00600 {
00601 QWidget* page = qxt_d().stack->widget(index);
00602 QTableWidgetItem* item = qxt_d().item(index);
00603 if (page && item)
00604 {
00605 page->setEnabled(enabled);
00606 if (enabled)
00607 item->setFlags(item->flags() | Qt::ItemIsEnabled);
00608 else
00609 item->setFlags(item->flags() & ~Qt::ItemIsEnabled);
00610 }
00611 else
00612 {
00613 qWarning("QxtConfigDialog::setPageEnabled(): Unknown index");
00614 }
00615 }
00616
00622 bool QxtConfigDialog::isPageHidden(int index) const
00623 {
00624 if (qxt_d().pos == QxtConfigDialog::North)
00625 return qxt_d().table->isColumnHidden(index);
00626 return qxt_d().table->isRowHidden(index);
00627 }
00628
00635 void QxtConfigDialog::setPageHidden(int index, bool hidden)
00636 {
00637 if (qxt_d().pos == QxtConfigDialog::North)
00638 qxt_d().table->setColumnHidden(index, hidden);
00639 else
00640 qxt_d().table->setRowHidden(index, hidden);
00641 }
00642
00648 QIcon QxtConfigDialog::pageIcon(int index) const
00649 {
00650 const QTableWidgetItem* item = qxt_d().item(index);
00651 return (item ? item->icon() : QIcon());
00652 }
00653
00659 void QxtConfigDialog::setPageIcon(int index, const QIcon& icon)
00660 {
00661 QTableWidgetItem* item = qxt_d().item(index);
00662 if (item)
00663 {
00664 item->setIcon(icon);
00665 }
00666 else
00667 {
00668 qWarning("QxtConfigDialog::setPageIcon(): Unknown index");
00669 }
00670 }
00671
00677 QString QxtConfigDialog::pageTitle(int index) const
00678 {
00679 const QTableWidgetItem* item = qxt_d().item(index);
00680 return (item ? item->text() : QString());
00681 }
00682
00688 void QxtConfigDialog::setPageTitle(int index, const QString& title)
00689 {
00690 QTableWidgetItem* item = qxt_d().item(index);
00691 if (item)
00692 {
00693 item->setText(title);
00694 }
00695 else
00696 {
00697 qWarning("QxtConfigDialog::setPageTitle(): Unknown index");
00698 }
00699 }
00700
00706 QString QxtConfigDialog::pageToolTip(int index) const
00707 {
00708 const QTableWidgetItem* item = qxt_d().item(index);
00709 return (item ? item->toolTip() : QString());
00710 }
00711
00717 void QxtConfigDialog::setPageToolTip(int index, const QString& tooltip)
00718 {
00719 QTableWidgetItem* item = qxt_d().item(index);
00720 if (item)
00721 {
00722 item->setToolTip(tooltip);
00723 }
00724 else
00725 {
00726 qWarning("QxtConfigDialog::setPageToolTip(): Unknown index");
00727 }
00728 }
00729
00735 QString QxtConfigDialog::pageWhatsThis(int index) const
00736 {
00737 const QTableWidgetItem* item = qxt_d().item(index);
00738 return (item ? item->whatsThis() : QString());
00739 }
00740
00746 void QxtConfigDialog::setPageWhatsThis(int index, const QString& whatsthis)
00747 {
00748 QTableWidgetItem* item = qxt_d().item(index);
00749 if (item)
00750 {
00751 item->setWhatsThis(whatsthis);
00752 }
00753 else
00754 {
00755 qWarning("QxtConfigDialog::setPageWhatsThis(): Unknown index");
00756 }
00757 }
00758
00767 void QxtConfigDialog::accept()
00768 {
00769 Q_ASSERT(qxt_d().stack);
00770 for (int i = 0; i < qxt_d().stack->count(); ++i)
00771 {
00772 QMetaObject::invokeMethod(qxt_d().stack->widget(i), "accept");
00773 }
00774 QDialog::accept();
00775 }
00776
00785 void QxtConfigDialog::reject()
00786 {
00787 Q_ASSERT(qxt_d().stack);
00788 for (int i = 0; i < qxt_d().stack->count(); ++i)
00789 {
00790 QMetaObject::invokeMethod(qxt_d().stack->widget(i), "reject");
00791 }
00792 QDialog::reject();
00793 }
00794
00800 QTableWidget* QxtConfigDialog::tableWidget() const
00801 {
00802 return qxt_d().table;
00803 }
00804
00810 QStackedWidget* QxtConfigDialog::stackedWidget() const
00811 {
00812 return qxt_d().stack;
00813 }
00814
00824 void QxtConfigDialog::cleanupPage(int index)
00825 {
00826 Q_ASSERT(qxt_d().stack);
00827 QMetaObject::invokeMethod(qxt_d().stack->widget(index), "cleanup");
00828 }
00829
00839 void QxtConfigDialog::initializePage(int index)
00840 {
00841 Q_ASSERT(qxt_d().stack);
00842 QMetaObject::invokeMethod(qxt_d().stack->widget(index), "initialize");
00843 }