1 /****************************************************************************
3 ** Copyright (C) Qxt Foundation. Some rights reserved.
5 ** This file is part of the QxtGui module of the Qt eXTension library
7 ** This library is free software; you can redistribute it and/or modify it
8 ** under the terms of th Common Public License, version 1.0, as published by
11 ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
12 ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
13 ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
14 ** FITNESS FOR A PARTICULAR PURPOSE.
16 ** You should have received a copy of the CPL along with this file.
17 ** See the LICENSE file and the cpl1.0.txt file included with the source
18 ** distribution for more information. If you did not receive a copy of the
19 ** license, contact the Qxt Foundation.
21 ** <http://libqxt.sourceforge.net> <foundation@libqxt.org>
23 ****************************************************************************/
24 #include "qxtconfigdialog.h"
25 #include "qxtconfigdialog_p.h"
26 #if QT_VERSION >= 0x040200
27 #include <QDialogButtonBox>
28 #else // QT_VERSION >= 0x040200
29 #include <QHBoxLayout>
30 #include <QPushButton>
32 #include <QStackedWidget>
33 #include <QGridLayout>
34 #include <QListWidget>
37 QxtConfigListWidget::QxtConfigListWidget(QWidget* parent) : QListWidget(parent)
39 setItemDelegate(new QxtConfigDelegate(this));
40 viewport()->setAttribute(Qt::WA_Hover, true);
43 void QxtConfigListWidget::invalidate()
49 QSize QxtConfigListWidget::minimumSizeHint() const
54 QSize QxtConfigListWidget::sizeHint() const
58 const QStyleOptionViewItem options = viewOptions();
59 const bool vertical = (flow() == QListView::TopToBottom);
60 for (int i = 0; i < count(); ++i)
62 const QSize size = itemDelegate()->sizeHint(options, model()->index(i, 0));
64 hint = hint.expandedTo(size);
66 hint += QSize(0, size.height());
68 hint += QSize(size.width(), 0);
70 hint += QSize(2 * frameWidth(), 2 * frameWidth());
75 bool QxtConfigListWidget::hasHoverEffect() const
77 return static_cast<QxtConfigDelegate*>(itemDelegate())->hover;
80 void QxtConfigListWidget::setHoverEffect(bool enabled)
82 static_cast<QxtConfigDelegate*>(itemDelegate())->hover = enabled;
85 void QxtConfigListWidget::scrollContentsBy(int dx, int dy)
92 QxtConfigDelegate::QxtConfigDelegate(QObject* parent)
93 : QItemDelegate(parent), hover(true)
96 void QxtConfigDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
98 QStyleOptionViewItem opt = option;
101 QPalette::ColorGroup cg = (option.state & QStyle::State_Enabled) ? QPalette::Normal : QPalette::Disabled;
102 if (cg == QPalette::Normal && !(option.state & QStyle::State_Active))
103 cg = QPalette::Inactive;
105 if (option.state & QStyle::State_Selected)
107 painter->fillRect(option.rect, option.palette.brush(cg, QPalette::Highlight));
109 else if ((option.state & QStyle::State_MouseOver) && (option.state & QStyle::State_Enabled))
111 QColor color = option.palette.color(cg, QPalette::Highlight).light();
112 if (color == option.palette.color(cg, QPalette::Base))
113 color = option.palette.color(cg, QPalette::AlternateBase);
114 painter->fillRect(option.rect, color);
117 opt.showDecorationSelected = false;
118 opt.state &= ~QStyle::State_HasFocus;
120 QItemDelegate::paint(painter, opt, index);
123 void QxtConfigDialogPrivate::init(QxtConfigDialog::IconPosition position)
125 QxtConfigDialog* p = &qxt_p();
126 grid = new QGridLayout(p);
127 list = new QxtConfigListWidget(p);
128 stack = new QStackedWidget(p);
130 QObject::connect(list, SIGNAL(currentRowChanged(int)), stack, SLOT(setCurrentIndex(int)));
131 QObject::connect(stack, SIGNAL(currentChanged(int)), p, SIGNAL(currentIndexChanged(int)));
133 #if QT_VERSION >= 0x040200
134 buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, p);
135 QObject::connect(buttons, SIGNAL(accepted()), p, SLOT(accept()));
136 QObject::connect(buttons, SIGNAL(rejected()), p, SLOT(reject()));
137 #else // QT_VERSION >= 0x040200
138 buttons = new QWidget(p);
139 QHBoxLayout* layout = new QHBoxLayout(buttons);
140 QPushButton* okButton = new QPushButton(QxtConfigDialog::tr("&OK"));
141 QPushButton* cancelButton = new QPushButton(QxtConfigDialog::tr("&Cancel"));
142 QObject::connect(okButton, SIGNAL(clicked()), p, SLOT(accept()));
143 QObject::connect(cancelButton, SIGNAL(clicked()), p, SLOT(reject()));
144 layout->addStretch();
145 layout->addWidget(okButton);
146 layout->addWidget(cancelButton);
153 void QxtConfigDialogPrivate::initList()
156 list->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
157 list->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
159 list->setEditTriggers(QAbstractItemView::NoEditTriggers);
160 // convenient navigation
161 list->setTabKeyNavigation(true);
163 list->setAcceptDrops(false);
164 list->setDragEnabled(false);
166 list->setMovement(QListView::Static);
167 list->setWrapping(false);
168 list->setResizeMode(QListView::Fixed);
169 list->setViewMode(QListView::IconMode);
170 // list->setWordWrap(false); 4.2
171 // list->setSortingEnabled(false); 4.2
174 void QxtConfigDialogPrivate::relayout()
177 grid->setEnabled(false);
180 while (grid->takeAt(0));
185 case QxtConfigDialog::North:
193 grid->addWidget(list, 0, 0);
194 grid->addWidget(stack, 1, 0);
195 grid->addWidget(buttons, 3, 0);
198 case QxtConfigDialog::West:
208 grid->addWidget(list, 0, 0);
209 grid->addWidget(stack, 0, 1);
210 grid->addWidget(buttons, 2, 0, 1, 2);
213 case QxtConfigDialog::East:
223 grid->addWidget(stack, 0, 0);
224 grid->addWidget(list, 0, 1);
225 grid->addWidget(buttons, 2, 0, 1, 2);
229 qWarning("QxtConfigDialogPrivate::relayout(): unknown position");
233 if (pos == QxtConfigDialog::North)
235 list->setFlow(QListView::LeftToRight);
236 list->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
240 list->setFlow(QListView::TopToBottom);
241 list->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
246 grid->setEnabled(true);
250 \class QxtConfigDialog QxtConfigDialog
252 \brief A configuration dialog.
254 QxtConfigDialog provides a convenient interface for building
255 common configuration dialogs. QxtConfigDialog consists of a
256 list of icons and a stack of pages.
260 QxtConfigDialog dialog;
261 dialog.addPage(new ConfigurationPage(&dialog), QIcon(":/images/config.png"), tr("Configuration"));
262 dialog.addPage(new UpdatePage(&dialog), QIcon(":/images/update.png"), tr("Update"));
263 dialog.addPage(new QueryPage(&dialog), QIcon(":/images/query.png"), tr("Query"));
267 \image html qxtconfigdialog.png "QxtConfigDialog with page icons on the left (QxtConfigDialog::West)."
271 \enum IconPosition::IconPosition
273 This enum describes the page icon position.
275 \sa QxtCheckComboBox::iconPosition
279 \var QxtConfigDialog::IconPosition QxtConfigDialog::North
281 The icons are located above the pages.
285 \var QxtConfigDialog::IconPosition QxtConfigDialog::West
287 The icons are located to the left of the pages.
291 \var QxtConfigDialog::IconPosition QxtConfigDialog::East
293 The icons are located to the right of the pages.
297 \fn QxtConfigDialog::currentIndexChanged(int index)
299 This signal is emitted whenever the current page \a index changes.
305 Constructs a new QxtConfigDialog with \a parent and \a flags.
307 QxtConfigDialog::QxtConfigDialog(QWidget* parent, Qt::WindowFlags flags)
308 : QDialog(parent, flags)
310 QXT_INIT_PRIVATE(QxtConfigDialog);
315 Constructs a new QxtConfigDialog with icon \a position, \a parent and \a flags.
317 QxtConfigDialog::QxtConfigDialog(QxtConfigDialog::IconPosition position, QWidget* parent, Qt::WindowFlags flags)
318 : QDialog(parent, flags)
320 QXT_INIT_PRIVATE(QxtConfigDialog);
321 qxt_d().init(position);
325 Destructs the config dialog.
327 QxtConfigDialog::~QxtConfigDialog()
331 \return The dialog button box.
333 The default buttons are \b QDialogButtonBox::Ok and \b QDialogButtonBox::Cancel.
335 \note QDialogButtonBox is available in Qt 4.2 or newer.
337 \sa setDialogButtonBox()
339 #if QT_VERSION >= 0x040200
340 QDialogButtonBox* QxtConfigDialog::dialogButtonBox() const
342 return qxt_d().buttons;
347 Sets the dialog \a buttonBox.
349 \sa dialogButtonBox()
351 #if QT_VERSION >= 0x040200
352 void QxtConfigDialog::setDialogButtonBox(QDialogButtonBox* buttonBox)
354 if (qxt_d().buttons != buttonBox)
356 if (qxt_d().buttons && qxt_d().buttons->parent() == this)
358 delete qxt_d().buttons;
360 qxt_d().buttons = buttonBox;
367 \property QxtConfigDialog::hoverEffect
368 \brief This property holds whether a hover effect is shown for page icons
370 The default value is \b true.
372 \note Hovered (but not selected) icons are highlighted with lightened \b QPalette::Highlight
373 (whereas selected icons are highlighted with \b QPalette::Highlight). In case lightened
374 \b QPalette::Highlight ends up same as \b QPalette::Base, \b QPalette::AlternateBase is used
375 as a fallback color for the hover effect. This usually happens when \b QPalette::Highlight
376 already is a light color (eg. light gray).
378 bool QxtConfigDialog::hasHoverEffect() const
380 return qxt_d().list->hasHoverEffect();
383 void QxtConfigDialog::setHoverEffect(bool enabled)
385 qxt_d().list->setHoverEffect(enabled);
389 \property QxtConfigDialog::iconPosition
390 \brief This property holds the position of page icons
392 QxtConfigDialog::IconPosition QxtConfigDialog::iconPosition() const
397 void QxtConfigDialog::setIconPosition(QxtConfigDialog::IconPosition position)
399 if (qxt_d().pos != position)
401 qxt_d().pos = position;
407 \property QxtConfigDialog::iconSize
408 \brief This property holds the size of page icons
410 QSize QxtConfigDialog::iconSize() const
412 return qxt_d().list->iconSize();
415 void QxtConfigDialog::setIconSize(const QSize& size)
417 qxt_d().list->setIconSize(size);
421 Adds a \a page with \a icon and \a title.
423 In case \a title is an empty string, \b QWidget::windowTitle is used.
425 \return The index of added page.
427 \warning Adding and removing pages dynamically at run time might cause flicker.
431 int QxtConfigDialog::addPage(QWidget* page, const QIcon& icon, const QString& title)
433 return insertPage(-1, page, icon, title);
437 Inserts a \a page with \a icon and \a title.
439 In case \a title is an empty string, \b QWidget::windowTitle is used.
441 \return The index of inserted page.
443 \warning Inserting and removing pages dynamically at run time might cause flicker.
447 int QxtConfigDialog::insertPage(int index, QWidget* page, const QIcon& icon, const QString& title)
451 qWarning("QxtConfigDialog::insertPage(): Attempt to insert null page");
455 index = qxt_d().stack->insertWidget(index, page);
456 const QString label = !title.isEmpty() ? title : page->windowTitle();
458 qWarning("QxtConfigDialog::insertPage(): Inserting a page with an empty title");
459 QListWidgetItem* item = new QListWidgetItem(icon, label);
460 qxt_d().list->insertItem(index, item);
461 qxt_d().list->invalidate();
466 Removes the page at \a index.
468 \note Does not delete the page widget.
470 void QxtConfigDialog::removePage(int index)
472 if (QWidget* page = qxt_d().stack->widget(index))
474 qxt_d().stack->removeWidget(page);
475 delete qxt_d().list->takeItem(index);
476 qxt_d().list->invalidate();
480 qWarning("QxtConfigDialog::removePage(): Unknown index");
485 \property QxtConfigDialog::count
486 \brief This property holds the number of pages
488 int QxtConfigDialog::count() const
490 return qxt_d().stack->count();
494 \property QxtConfigDialog::currentIndex
495 \brief This property holds the index of current page
497 int QxtConfigDialog::currentIndex() const
499 return qxt_d().stack->currentIndex();
502 void QxtConfigDialog::setCurrentIndex(int index)
504 qxt_d().list->setCurrentRow(index);
505 qxt_d().stack->setCurrentIndex(index);
509 \return The current page.
511 \sa currentIndex(), setCurrentPage()
513 QWidget* QxtConfigDialog::currentPage() const
515 return qxt_d().stack->currentWidget();
519 Sets the current \a page.
521 \sa currentPage(), currentIndex()
523 void QxtConfigDialog::setCurrentPage(QWidget* page)
525 setCurrentIndex(qxt_d().stack->indexOf(page));
529 \return The index of \a page or \b -1 if the page is unknown.
531 int QxtConfigDialog::indexOf(QWidget* page) const
533 return qxt_d().stack->indexOf(page);
537 \return The page at \a index or \b 0 if the \a index is out of range.
539 QWidget* QxtConfigDialog::page(int index) const
541 return qxt_d().stack->widget(index);
545 \return \b true if the page at \a index is enabled; otherwise \b false.
547 \sa setPageEnabled(), QWidget::isEnabled()
549 bool QxtConfigDialog::isPageEnabled(int index) const
551 const QListWidgetItem* item = qxt_d().list->item(index);
552 return (item && (item->flags() & Qt::ItemIsEnabled));
556 Sets the page at \a index \a enabled. The corresponding
557 page icon is also \a enabled.
559 \sa isPageEnabled(), QWidget::setEnabled()
561 void QxtConfigDialog::setPageEnabled(int index, bool enabled)
563 QWidget* page = qxt_d().stack->widget(index);
564 QListWidgetItem* item = qxt_d().list->item(index);
567 page->setEnabled(enabled);
569 item->setFlags(item->flags() | Qt::ItemIsEnabled);
571 item->setFlags(item->flags() & ~Qt::ItemIsEnabled);
575 qWarning("QxtConfigDialog::setPageEnabled(): Unknown index");
580 \return \b true if the page at \a index is hidden; otherwise \b false.
582 \sa setPageHidden(), QWidget::isVisible()
584 bool QxtConfigDialog::isPageHidden(int index) const
586 const QListWidgetItem* item = qxt_d().list->item(index);
587 #if QT_VERSION >= 0x040200
588 return (item && item->isHidden());
590 return (item && qxt_d().list->isItemHidden(item));
595 Sets the page at \a index \a hidden. The corresponding
596 page icon is also \a hidden.
598 \sa isPageHidden(), QWidget::setVisible()
600 void QxtConfigDialog::setPageHidden(int index, bool hidden)
602 QListWidgetItem* item = qxt_d().list->item(index);
605 #if QT_VERSION >= 0x040200
606 item->setHidden(hidden);
608 qxt_d().list->setItemHidden(item, hidden);
613 qWarning("QxtConfigDialog::setPageHidden(): Unknown index");
618 \return The icon of page at \a index.
622 QIcon QxtConfigDialog::pageIcon(int index) const
624 const QListWidgetItem* item = qxt_d().list->item(index);
625 return (item ? item->icon() : QIcon());
629 Sets the \a icon of page at \a index.
633 void QxtConfigDialog::setPageIcon(int index, const QIcon& icon)
635 QListWidgetItem* item = qxt_d().list->item(index);
642 qWarning("QxtConfigDialog::setPageIcon(): Unknown index");
647 \return The title of page at \a index.
651 QString QxtConfigDialog::pageTitle(int index) const
653 const QListWidgetItem* item = qxt_d().list->item(index);
654 return (item ? item->text() : QString());
658 Sets the \a title of page at \a index.
662 void QxtConfigDialog::setPageTitle(int index, const QString& title)
664 QListWidgetItem* item = qxt_d().list->item(index);
667 item->setText(title);
671 qWarning("QxtConfigDialog::setPageTitle(): Unknown index");
676 \return The tooltip of page at \a index.
680 QString QxtConfigDialog::pageToolTip(int index) const
682 const QListWidgetItem* item = qxt_d().list->item(index);
683 return (item ? item->toolTip() : QString());
687 Sets the \a tooltip of page at \a index.
691 void QxtConfigDialog::setPageToolTip(int index, const QString& tooltip)
693 QListWidgetItem* item = qxt_d().list->item(index);
696 item->setToolTip(tooltip);
700 qWarning("QxtConfigDialog::setPageToolTip(): Unknown index");
705 \return The what's this of page at \a index.
707 \sa setPageWhatsThis()
709 QString QxtConfigDialog::pageWhatsThis(int index) const
711 const QListWidgetItem* item = qxt_d().list->item(index);
712 return (item ? item->whatsThis() : QString());
716 Sets the \a whatsthis of page at \a index.
720 void QxtConfigDialog::setPageWhatsThis(int index, const QString& whatsthis)
722 QListWidgetItem* item = qxt_d().list->item(index);
725 item->setWhatsThis(whatsthis);
729 qWarning("QxtConfigDialog::setPageWhatsThis(): Unknown index");
734 \return The internal list widget used for showing page icons.
738 QListWidget* QxtConfigDialog::listWidget() const
744 \return The internal stacked widget used for stacking pages.
748 QStackedWidget* QxtConfigDialog::stackedWidget() const
750 return qxt_d().stack;