/* ==================================================================== * Copyright (c) 2003-2006, Martin Hauner * http://subcommander.tigris.org * * Subcommander is licensed as described in the file doc/COPYING, which * you should have received as part of this distribution. * ==================================================================== */ // sc #include "config.h" #include "SettingsDialog.h" #include "SettingsWidget.h" #include "SettingsInfo.h" #include "sublib/Gui.h" #include "util/Compare.h" // qt #include #include #include #include #include class SettingsLvi : public QListViewItem { typedef QListViewItem super; public: SettingsLvi( SettingsInfo* info, QListView* lv ) : super( lv, info->getTitle() ), _info(info) { } SettingsLvi( SettingsInfo* info, QListViewItem* lvi ) : super( lvi, info->getTitle() ), _info(info) { } void paintCell( QPainter *p, const QColorGroup & cg, int column, int width, int alignment ) { QColorGroup g(cg); if( isModified() ) { g.setColor( QColorGroup::Base, QColor(200,200,230) ); } super::paintCell(p,g,column,width,alignment); } SettingsInfo* getInfo() const { return _info; } bool isModified() { bool modified = _info->isModified(); if( isOpen() == false ) { SettingsLvi* child = (SettingsLvi*)firstChild(); while( child ) { modified |= child->isModified(); child = (SettingsLvi*)child->nextSibling(); } } return modified; } int compare( QListViewItem * i, int col, bool ascending ) const { SettingsLvi* lvi = dynamic_cast(i); return compare3( getInfo()->getSortIndex(), lvi->getInfo()->getSortIndex() ); } private: SettingsInfo* _info; }; SettingsDialog::SettingsDialog( const QString& title, QWidget *parent, const char *name ) : super( parent, name, true, Qt::WStyle_Customize | Qt::WStyle_Dialog | Qt::WStyle_NormalBorder | Qt::WStyle_Title | Qt::WStyle_SysMenu ), _curInfo(0) { setCaption( title ); QVBoxLayout *vbl = new QVBoxLayout(this,5,8); vbl->setSpacing(10); { QGridLayout* gl = new QGridLayout( vbl, 2, 2, 0, 0 ); gl->setMargin(5); gl->setSpacing(10); { _categories = new QListView(this); gl->addWidget( _categories, 0, 0 ); { _categories->setRootIsDecorated(true); _categories->setSorting(0,true); _categories->setTreeStepSize(11); _categories->addColumn( _q("category") ); _categories->setColumnWidthMode( 0, QListView::Maximum ); _categories->setResizeMode( QListView::LastColumn ); _categories->setSizePolicy( QSizePolicy(QSizePolicy::Fixed,QSizePolicy::Preferred) ); } connect( _categories, SIGNAL(clicked(QListViewItem*)), SLOT(clicked(QListViewItem*)) ); _box = new QGroupBox( 1, Qt::Horizontal, _q("no settings selected: "), this ); _box->setMargin(10); _box->setInsideMargin(10); gl->addWidget( _box, 0, 1 ); { _stack = new QWidgetStack(_box); _stack->setSizePolicy( QSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding) ); { _stack->addWidget( new QWidget(), 0 ); } } QHBoxLayout* hl = new QHBoxLayout; vbl->addLayout( hl ); { // eats up any extra space, so the buttons keep their size hl->addStretch(1); _ok = new QPushButton(this); _ok->setText( _q("&Ok") ); //_ok->setDefault(true); _ok->setEnabled(false); hl->addWidget(_ok); _apply = new QPushButton(this); _apply->setText( _q("&Apply") ); _apply->setEnabled(false); hl->addWidget(_apply); QPushButton* ca = new QPushButton(this); ca->setDefault(true); ca->setFocus(); ca->setText( _q("&Close") ); hl->addWidget(ca); hl->addSpacing(getSizeGripSpacing()); connect( _ok, SIGNAL(clicked()), SLOT(ok()) ); connect( _apply, SIGNAL(clicked()), SLOT(apply()) ); connect( ca, SIGNAL(clicked()), SLOT(cancel()) ); } } } } SettingsDialog::~SettingsDialog() { } void SettingsDialog::addSettingsInfo( SettingsInfo* info, const QString& parentTitle ) { SettingsLvi* lvi = 0; Lvis::iterator it = _lvis.find( parentTitle ); if( it == _lvis.end() ) { // toplevel.. lvi = new SettingsLvi( info, _categories ); } else { // childlevel.. lvi = new SettingsLvi( info, (*it).second ); } int newSize = (lvi->depth()+ 4/*?*/) * _categories->treeStepSize() + lvi->width( QFontMetrics(_categories->font()), _categories, 0 ); if( newSize > _categories->minimumWidth() ) { _categories->setMinimumWidth( newSize ); } _lvis.insert( Lvis::value_type(info->getTitle(),lvi) ); if( info->getSelected() ) { lvi->setSelected(true); clicked(lvi); QListViewItem* p = lvi; if( (p = p->parent()) ) { p->setOpen(true); } } } void SettingsDialog::addSettingsWidget( const QString& settingsId, SettingsWidget* sw ) { _stack->addWidget( sw ); _widgets.insert( Widgets::value_type(settingsId,sw) ); connect( sw, SIGNAL(modified()), SLOT(modified()) ); } void SettingsDialog::ok() { for( Lvis::iterator it = _lvis.begin(); it != _lvis.end(); it++ ) { SettingsLvi* lvi = (*it).second; lvi->getInfo()->ok(); } accept(); } void SettingsDialog::apply() { _curInfo->apply(); modified(); } void SettingsDialog::cancel() { for( Lvis::iterator it = _lvis.begin(); it != _lvis.end(); it++ ) { SettingsLvi* lvi = (*it).second; lvi->getInfo()->cancel(); } reject(); } void SettingsDialog::modified() { _curInfo->storeWidgetData( (SettingsWidget*)_stack->visibleWidget() ); _apply->setEnabled(_curInfo->isModified()); _ok ->setEnabled(isModified()); } bool SettingsDialog::isModified() { bool modified = false; for( Lvis::iterator it = _lvis.begin(); it != _lvis.end(); it++ ) { SettingsLvi* lvi = (*it).second; modified |= lvi->isModified(); } return modified; } void SettingsDialog::clicked( QListViewItem* item ) { if( ! item ) { return; } // remember data from current SettingsWidget.. if( _curInfo ) { SettingsWidget* sw = (SettingsWidget*)_stack->visibleWidget(); _curInfo->storeWidgetData( sw ); } // set new SettingsWidget... SettingsLvi* lvi = (SettingsLvi*)item; SettingsInfo* info = lvi->getInfo(); _apply->setDisabled( ! info->isModified() ); Widgets::iterator it = _widgets.find( info->getSettingsId() ); if( it == _widgets.end() ) { _box->setTitle( _q("no settings selected: ") ); _stack->raiseWidget(0); _curInfo = 0; } else { SettingsWidget* sw = (*it).second; _box->setTitle( info->getSettingsId() + ": " ); _curInfo = info; _stack->raiseWidget( sw ); info->initWidgetData( sw ); } }