/* ====================================================================
* 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 <qlayout.h>
#include <qlistview.h>
#include <qwidgetstack.h>
#include <qpushbutton.h>
#include <qgroupbox.h>
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<SettingsLvi*>(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 );
}
}
syntax highlighted by Code2HTML, v. 0.9.1