mirror of
https://bitbucket.org/smil3y/kde-playground.git
synced 2025-02-23 18:32:51 +00:00
615 lines
17 KiB
C++
615 lines
17 KiB
C++
/*
|
|
This file is part of libkresources.
|
|
|
|
Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
|
|
Copyright (c) 2002 Jan-Pascal van Best <janpascal@vanbest.org>
|
|
Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Library General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Library General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
Boston, MA 02110-1301, USA.
|
|
*/
|
|
/**
|
|
@file
|
|
This file is part of the KDE resource framework and defines the
|
|
ConfigPage class.
|
|
|
|
@brief
|
|
A resource configuration page.
|
|
|
|
@author Tobias Koenig
|
|
@author Jan-Pascal van Best
|
|
@author Cornelius Schumacher
|
|
*/
|
|
|
|
#include "configpage.h"
|
|
|
|
#include <QGroupBox>
|
|
#include <QLabel>
|
|
#include <QLayout>
|
|
#include <QTreeWidget>
|
|
#include <QTreeWidgetItem>
|
|
|
|
#include <kcombobox.h>
|
|
#include <kdebug.h>
|
|
#include <klocalizedstring.h>
|
|
#include <kmessagebox.h>
|
|
#include <kconfig.h>
|
|
#include <kstandarddirs.h>
|
|
#include <kurlrequester.h>
|
|
#include <kdialogbuttonbox.h>
|
|
#include <kservicetypetrader.h>
|
|
#include <kinputdialog.h>
|
|
#include <QtCore/QList>
|
|
|
|
#include "resource.h"
|
|
#include "configdialog.h"
|
|
|
|
namespace KRES {
|
|
|
|
class ResourcePageInfo::Private
|
|
{
|
|
};
|
|
|
|
ResourcePageInfo::ResourcePageInfo() : d( new KRES::ResourcePageInfo::Private )
|
|
{
|
|
mManager = 0;
|
|
mConfig = 0;
|
|
}
|
|
|
|
ResourcePageInfo::~ResourcePageInfo()
|
|
{
|
|
//delete mManager;
|
|
mManager = 0;
|
|
//delete mConfig;
|
|
mConfig = 0;
|
|
delete d;
|
|
}
|
|
|
|
class ConfigViewItem : public QTreeWidgetItem
|
|
{
|
|
public:
|
|
ConfigViewItem( QTreeWidget *parent, Resource *resource ) :
|
|
QTreeWidgetItem( parent ), mResource( resource ), mIsStandard( false )
|
|
{
|
|
updateItem();
|
|
}
|
|
|
|
void setStandard( bool value )
|
|
{
|
|
setText( 2, ( value ? i18nc( "yes, a standard resource", "Yes" ) : QString() ) );
|
|
mIsStandard = value;
|
|
}
|
|
|
|
bool standard() const { return mIsStandard; }
|
|
bool readOnly() const { return mResource->readOnly(); }
|
|
|
|
Resource *resource() { return mResource; }
|
|
|
|
void updateItem()
|
|
{
|
|
setCheckState( 0, mResource->isActive() ? Qt::Checked : Qt::Unchecked );
|
|
setText( 0, mResource->resourceName() );
|
|
setText( 1, mResource->type() );
|
|
setText( 2, mIsStandard ? i18nc( "yes, a standard resource", "Yes" ) : QString() );
|
|
}
|
|
|
|
bool isOn()
|
|
{
|
|
return checkState( 0 ) == Qt::Checked;
|
|
}
|
|
|
|
private:
|
|
Resource *mResource;
|
|
bool mIsStandard;
|
|
};
|
|
|
|
class ConfigPage::Private
|
|
{
|
|
public:
|
|
void loadManager( const QString &family, ConfigPage *page );
|
|
void saveResourceSettings( ConfigPage *page );
|
|
|
|
Manager<Resource> *mCurrentManager;
|
|
KConfig *mCurrentConfig;
|
|
KConfigGroup *mConfigGroup;
|
|
QString mFamily;
|
|
QStringList mFamilyMap;
|
|
QList<KSharedPtr<ResourcePageInfo> > mInfoMap;
|
|
|
|
KComboBox *mFamilyCombo;
|
|
QTreeWidget *mListView;
|
|
QPushButton *mAddButton;
|
|
QPushButton *mRemoveButton;
|
|
QPushButton *mEditButton;
|
|
QPushButton *mStandardButton;
|
|
|
|
QTreeWidgetItem *mLastItem;
|
|
};
|
|
|
|
ConfigPage::ConfigPage( QWidget *parent )
|
|
: QWidget( parent ), d( new KRES::ConfigPage::Private )
|
|
{
|
|
setWindowTitle( i18n( "Resource Configuration" ) );
|
|
|
|
QVBoxLayout *mainLayout = new QVBoxLayout( this );
|
|
mainLayout->setMargin( 0 );
|
|
|
|
QGroupBox *groupBox = new QGroupBox( i18n( "Resources" ), this );
|
|
QGridLayout *groupBoxLayout = new QGridLayout();
|
|
groupBox->setLayout( groupBoxLayout );
|
|
|
|
d->mFamilyCombo = new KComboBox( false, groupBox );
|
|
groupBoxLayout->addWidget( d->mFamilyCombo, 0, 0, 1, 2 );
|
|
|
|
d->mCurrentManager = 0;
|
|
d->mCurrentConfig = 0;
|
|
d->mListView = new QTreeWidget( groupBox );
|
|
d->mListView->setColumnCount( 3 );
|
|
QStringList headerLabels;
|
|
headerLabels << i18nc( "@title:column resource name", "Name" )
|
|
<< i18nc( "@title:column resource type", "Type" )
|
|
<< i18nc( "@title:column a standard resource?", "Standard" );
|
|
d->mListView->setHeaderItem( new QTreeWidgetItem( headerLabels ) );
|
|
|
|
groupBoxLayout->addWidget( d->mListView, 1, 0 );
|
|
connect( d->mListView, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)),
|
|
this, SLOT(slotEdit()) );
|
|
|
|
KDialogButtonBox *buttonBox = new KDialogButtonBox( groupBox, Qt::Vertical );
|
|
d->mAddButton = buttonBox->addButton( i18n( "&Add..." ),
|
|
KDialogButtonBox::ActionRole,
|
|
this, SLOT(slotAdd()) );
|
|
|
|
d->mRemoveButton = buttonBox->addButton( i18n( "&Remove" ),
|
|
KDialogButtonBox::ActionRole,
|
|
this, SLOT(slotRemove()) );
|
|
d->mRemoveButton->setEnabled( false );
|
|
|
|
d->mEditButton = buttonBox->addButton( i18n( "&Edit..." ),
|
|
KDialogButtonBox::ActionRole,
|
|
this, SLOT(slotEdit()) );
|
|
d->mEditButton->setEnabled( false );
|
|
|
|
d->mStandardButton = buttonBox->addButton( i18n( "&Use as Standard" ),
|
|
KDialogButtonBox::ActionRole,
|
|
this, SLOT(slotStandard()) );
|
|
d->mStandardButton->setEnabled( false );
|
|
|
|
buttonBox->layout();
|
|
groupBoxLayout->addWidget( buttonBox, 1, 1 );
|
|
|
|
mainLayout->addWidget( groupBox );
|
|
|
|
connect( d->mFamilyCombo, SIGNAL(activated(int)),
|
|
SLOT(slotFamilyChanged(int)) );
|
|
connect( d->mListView, SIGNAL(itemSelectionChanged()),
|
|
SLOT(slotSelectionChanged()) );
|
|
connect( d->mListView, SIGNAL(itemClicked(QTreeWidgetItem*,int)),
|
|
SLOT(slotItemClicked(QTreeWidgetItem*)) );
|
|
|
|
d->mLastItem = 0;
|
|
|
|
d->mConfigGroup = new KConfigGroup( new KConfig( QLatin1String("kcmkresourcesrc") ), "General" );
|
|
|
|
load();
|
|
}
|
|
|
|
ConfigPage::~ConfigPage()
|
|
{
|
|
QList<KSharedPtr<ResourcePageInfo> >::Iterator it;
|
|
for ( it = d->mInfoMap.begin(); it != d->mInfoMap.end(); ++it ) {
|
|
( *it )->mManager->removeObserver( this );
|
|
}
|
|
|
|
d->mConfigGroup->writeEntry( "CurrentFamily", d->mFamilyCombo->currentIndex() );
|
|
delete d->mConfigGroup->config();
|
|
delete d->mConfigGroup;
|
|
d->mConfigGroup = 0;
|
|
delete d;
|
|
}
|
|
|
|
void ConfigPage::load()
|
|
{
|
|
kDebug();
|
|
|
|
d->mListView->clear();
|
|
d->mFamilyMap.clear();
|
|
d->mInfoMap.clear();
|
|
QStringList familyDisplayNames;
|
|
|
|
// KDE-3.3 compatibility code: get families from the plugins
|
|
QStringList compatFamilyNames;
|
|
const KService::List plugins = KServiceTypeTrader::self()->query( QLatin1String("KResources/Plugin") );
|
|
KService::List::ConstIterator it = plugins.begin();
|
|
KService::List::ConstIterator end = plugins.end();
|
|
for ( ; it != end; ++it ) {
|
|
const QString family = ( *it )->property( QLatin1String("X-KDE-ResourceFamily") ).toString();
|
|
if ( compatFamilyNames.indexOf( family ) == -1 ) {
|
|
compatFamilyNames.append( family );
|
|
}
|
|
}
|
|
|
|
const KService::List managers = KServiceTypeTrader::self()->query( QLatin1String("KResources/Manager") );
|
|
KService::List::ConstIterator m_it;
|
|
for ( m_it = managers.begin(); m_it != managers.end(); ++m_it ) {
|
|
QString displayName = ( *m_it )->property( QLatin1String("Name") ).toString();
|
|
familyDisplayNames.append( displayName );
|
|
QString family = ( *m_it )->property( QLatin1String("X-KDE-ResourceFamily") ).toString();
|
|
if ( !family.isEmpty() ) {
|
|
compatFamilyNames.removeAll( family );
|
|
d->mFamilyMap.append( family );
|
|
kDebug() << "Loading manager for family " << family;
|
|
d->loadManager( family, this );
|
|
kDebug() << "Manager for family " << family << " loaded.";
|
|
}
|
|
}
|
|
|
|
// Rest of the kde-3.3 compat code
|
|
QStringList::ConstIterator cfit = compatFamilyNames.constBegin();
|
|
for ( ; cfit != compatFamilyNames.constEnd(); ++cfit ) {
|
|
d->mFamilyMap.append( *cfit );
|
|
familyDisplayNames.append( *cfit );
|
|
d->loadManager( *cfit, this );
|
|
}
|
|
|
|
d->mCurrentManager = 0;
|
|
|
|
d->mFamilyCombo->clear();
|
|
d->mFamilyCombo->insertItems( 0, familyDisplayNames );
|
|
|
|
int currentFamily = d->mConfigGroup->readEntry( "CurrentFamily", 0 );
|
|
d->mFamilyCombo->setCurrentIndex( currentFamily );
|
|
slotFamilyChanged( currentFamily );
|
|
emit changed( false );
|
|
}
|
|
|
|
void ConfigPage::Private::loadManager( const QString &family, ConfigPage *page )
|
|
{
|
|
mCurrentManager = new Manager<Resource>( family );
|
|
if ( mCurrentManager ) {
|
|
mCurrentManager->addObserver( page );
|
|
|
|
ResourcePageInfo *info = new ResourcePageInfo;
|
|
info->mManager = mCurrentManager;
|
|
info->mConfig = new KConfig( KRES::ManagerImpl::defaultConfigFile( family ) );
|
|
info->mManager->readConfig( info->mConfig );
|
|
|
|
mInfoMap.append( KSharedPtr<ResourcePageInfo>( info ) );
|
|
}
|
|
}
|
|
|
|
void ConfigPage::save()
|
|
{
|
|
d->saveResourceSettings( this );
|
|
|
|
QList<KSharedPtr<ResourcePageInfo> >::Iterator it;
|
|
for ( it = d->mInfoMap.begin(); it != d->mInfoMap.end(); ++it ) {
|
|
( *it )->mManager->writeConfig( ( *it )->mConfig );
|
|
}
|
|
|
|
emit changed( false );
|
|
}
|
|
|
|
void ConfigPage::defaults()
|
|
{
|
|
}
|
|
|
|
void ConfigPage::slotFamilyChanged( int pos )
|
|
{
|
|
if ( pos < 0 || pos >= (int)d->mFamilyMap.count() ) {
|
|
return;
|
|
}
|
|
|
|
d->saveResourceSettings( this );
|
|
|
|
d->mFamily = d->mFamilyMap[ pos ];
|
|
|
|
d->mCurrentManager = d->mInfoMap[ pos ]->mManager;
|
|
d->mCurrentConfig = d->mInfoMap[ pos ]->mConfig;
|
|
|
|
if ( !d->mCurrentManager ) {
|
|
kDebug() << "ERROR: cannot create ResourceManager<Resource>( mFamily )";
|
|
}
|
|
|
|
d->mListView->clear();
|
|
|
|
if ( d->mCurrentManager->isEmpty() ) {
|
|
defaults();
|
|
}
|
|
|
|
Resource *standardResource = d->mCurrentManager->standardResource();
|
|
|
|
Manager<Resource>::Iterator it;
|
|
for ( it = d->mCurrentManager->begin(); it != d->mCurrentManager->end(); ++it ) {
|
|
ConfigViewItem *item = new ConfigViewItem( d->mListView, *it );
|
|
if ( *it == standardResource ) {
|
|
item->setStandard( true );
|
|
}
|
|
}
|
|
|
|
if ( d->mListView->topLevelItemCount() == 0 ) {
|
|
defaults();
|
|
emit changed( true );
|
|
d->mCurrentManager->writeConfig( d->mCurrentConfig );
|
|
} else {
|
|
if ( !standardResource ) {
|
|
KMessageBox::sorry( this, i18n( "There is no standard resource. Please select one." ) );
|
|
}
|
|
|
|
emit changed( false );
|
|
}
|
|
}
|
|
|
|
void ConfigPage::slotAdd()
|
|
{
|
|
if ( !d->mCurrentManager ) {
|
|
return;
|
|
}
|
|
|
|
QStringList types = d->mCurrentManager->resourceTypeNames();
|
|
QStringList descs = d->mCurrentManager->resourceTypeDescriptions();
|
|
bool ok = false;
|
|
QString desc = KInputDialog::getItem( i18n( "Resource Configuration" ),
|
|
i18n( "Please select type of the new resource:" ), descs,
|
|
0, false, &ok, this );
|
|
if ( !ok ) {
|
|
return;
|
|
}
|
|
|
|
QString type = types[ descs.indexOf( desc ) ];
|
|
|
|
// Create new resource
|
|
Resource *resource = d->mCurrentManager->createResource( type );
|
|
if ( !resource ) {
|
|
KMessageBox::error(
|
|
this, i18n( "Unable to create resource of type '%1'.", type ) );
|
|
return;
|
|
}
|
|
|
|
resource->setResourceName( type + QLatin1String("-resource") );
|
|
|
|
ConfigDialog dlg( this, d->mFamily, resource );
|
|
|
|
if ( dlg.exec() ) { //krazy:exclude=crashy
|
|
d->mCurrentManager->add( resource );
|
|
|
|
ConfigViewItem *item = new ConfigViewItem( d->mListView, resource );
|
|
|
|
d->mLastItem = item;
|
|
|
|
// if there are only read-only resources we'll set this resource
|
|
// as standard resource
|
|
if ( !resource->readOnly() ) {
|
|
bool onlyReadOnly = true;
|
|
for ( int i = 0; i < d->mListView->topLevelItemCount(); ++i ) {
|
|
ConfigViewItem *confIt = static_cast<ConfigViewItem*>( d->mListView->topLevelItem( i ) );
|
|
if ( !confIt->readOnly() && confIt != item ) {
|
|
onlyReadOnly = false;
|
|
}
|
|
}
|
|
|
|
if ( onlyReadOnly ) {
|
|
item->setStandard( true );
|
|
}
|
|
}
|
|
|
|
emit changed( true );
|
|
} else {
|
|
delete resource;
|
|
resource = 0;
|
|
}
|
|
}
|
|
|
|
void ConfigPage::slotRemove()
|
|
{
|
|
if ( !d->mCurrentManager ) {
|
|
return;
|
|
}
|
|
|
|
QTreeWidgetItem *item = d->mListView->currentItem();
|
|
ConfigViewItem *confItem = static_cast<ConfigViewItem*>( item );
|
|
|
|
if ( !confItem ) {
|
|
return;
|
|
}
|
|
|
|
if ( confItem->standard() ) {
|
|
KMessageBox::sorry( this,
|
|
i18n( "You cannot remove your standard resource. "
|
|
"Please select a new standard resource first." ) );
|
|
return;
|
|
}
|
|
|
|
d->mCurrentManager->remove( confItem->resource() );
|
|
|
|
if ( item == d->mLastItem ) {
|
|
d->mLastItem = 0;
|
|
}
|
|
|
|
d->mListView->takeTopLevelItem( d->mListView->indexOfTopLevelItem( item ) );
|
|
delete item;
|
|
|
|
emit changed( true );
|
|
}
|
|
|
|
void ConfigPage::slotEdit()
|
|
{
|
|
if ( !d->mCurrentManager ) {
|
|
return;
|
|
}
|
|
|
|
QTreeWidgetItem *item = d->mListView->currentItem();
|
|
ConfigViewItem *configItem = static_cast<ConfigViewItem*>( item );
|
|
if ( !configItem ) {
|
|
return;
|
|
}
|
|
|
|
Resource *resource = configItem->resource();
|
|
|
|
ConfigDialog dlg( this, d->mFamily, resource );
|
|
|
|
if ( dlg.exec() ) { //krazy:exclude=crashy
|
|
configItem->setText( 0, resource->resourceName() );
|
|
configItem->setText( 1, resource->type() );
|
|
|
|
if ( configItem->standard() && configItem->readOnly() ) {
|
|
KMessageBox::sorry( this, i18n( "You cannot use a read-only resource as standard." ) );
|
|
configItem->setStandard( false );
|
|
}
|
|
|
|
d->mCurrentManager->change( resource );
|
|
emit changed( true );
|
|
}
|
|
}
|
|
|
|
void ConfigPage::slotStandard()
|
|
{
|
|
if ( !d->mCurrentManager ) {
|
|
return;
|
|
}
|
|
|
|
ConfigViewItem *item = static_cast<ConfigViewItem*>( d->mListView->currentItem() );
|
|
if ( !item ) {
|
|
return;
|
|
}
|
|
|
|
if ( item->readOnly() ) {
|
|
KMessageBox::sorry( this, i18n( "You cannot use a read-only resource as standard." ) );
|
|
return;
|
|
}
|
|
|
|
if ( !item->isOn() ) {
|
|
KMessageBox::sorry( this, i18n( "You cannot use an inactive resource as standard." ) );
|
|
return;
|
|
}
|
|
|
|
for ( int i = 0; i < d->mListView->topLevelItemCount(); ++i ) {
|
|
ConfigViewItem *configItem = static_cast<ConfigViewItem*>( d->mListView->topLevelItem( i ) );
|
|
if ( configItem->standard() ) {
|
|
configItem->setStandard( false );
|
|
}
|
|
}
|
|
|
|
item->setStandard( true );
|
|
d->mCurrentManager->setStandardResource( item->resource() );
|
|
|
|
emit changed( true );
|
|
}
|
|
|
|
void ConfigPage::slotSelectionChanged()
|
|
{
|
|
bool state = ( d->mListView->currentItem() != 0 );
|
|
|
|
d->mRemoveButton->setEnabled( state );
|
|
d->mEditButton->setEnabled( state );
|
|
d->mStandardButton->setEnabled( state );
|
|
}
|
|
|
|
void ConfigPage::resourceAdded( Resource *resource )
|
|
{
|
|
kDebug() << resource->resourceName();
|
|
|
|
ConfigViewItem *item = new ConfigViewItem( d->mListView, resource );
|
|
|
|
item->setCheckState( 0, resource->isActive()? Qt::Checked : Qt::Unchecked );
|
|
|
|
d->mLastItem = item;
|
|
|
|
emit changed( true );
|
|
}
|
|
|
|
void ConfigPage::resourceModified( Resource *resource )
|
|
{
|
|
kDebug() << resource->resourceName();
|
|
ConfigViewItem *item = findItem( resource );
|
|
if ( !item ) {
|
|
return;
|
|
}
|
|
|
|
// TODO: Reread resource config. Otherwise we won't see the modification.
|
|
|
|
item->updateItem();
|
|
}
|
|
|
|
void ConfigPage::resourceDeleted( Resource *resource )
|
|
{
|
|
kDebug() << resource->resourceName();
|
|
|
|
ConfigViewItem *item = findItem( resource );
|
|
if ( !item ) {
|
|
return;
|
|
}
|
|
|
|
delete item;
|
|
}
|
|
|
|
ConfigViewItem *ConfigPage::findItem( Resource *resource )
|
|
{
|
|
for ( int i = 0; i < d->mListView->topLevelItemCount(); ++i ) {
|
|
ConfigViewItem *item = static_cast<ConfigViewItem *>( d->mListView->topLevelItem( i ) );
|
|
if ( item->resource() == resource ) {
|
|
return item;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void ConfigPage::slotItemClicked( QTreeWidgetItem *item )
|
|
{
|
|
ConfigViewItem *configItem = static_cast<ConfigViewItem *>( item );
|
|
if ( !configItem ) {
|
|
return;
|
|
}
|
|
|
|
if ( configItem->standard() && !configItem->isOn() ) {
|
|
KMessageBox::sorry( this,
|
|
i18n( "You cannot deactivate the standard resource. "
|
|
"Choose another standard resource first." ) );
|
|
configItem->setCheckState( 0, Qt::Checked );
|
|
return;
|
|
}
|
|
|
|
if ( configItem->isOn() != configItem->resource()->isActive() ) {
|
|
emit changed( true );
|
|
}
|
|
}
|
|
|
|
void ConfigPage::Private::saveResourceSettings( ConfigPage *page )
|
|
{
|
|
if ( mCurrentManager ) {
|
|
for ( int i = 0; i < mListView->topLevelItemCount(); ++i ) {
|
|
ConfigViewItem *configItem = static_cast<ConfigViewItem *>( mListView->topLevelItem( i ) );
|
|
// check if standard resource
|
|
if ( configItem->standard() && !configItem->readOnly() &&
|
|
configItem->isOn() ) {
|
|
mCurrentManager->setStandardResource( configItem->resource() );
|
|
}
|
|
|
|
// check if active or passive resource
|
|
configItem->resource()->setActive( configItem->isOn() );
|
|
}
|
|
mCurrentManager->writeConfig( mCurrentConfig );
|
|
|
|
if ( !mCurrentManager->standardResource() ) {
|
|
KMessageBox::sorry( page,
|
|
i18n( "There is no valid standard resource. "
|
|
"Please select one which is neither read-only nor inactive." ) );
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|