kwin/kcmkwin/kwindecoration/decorationmodel.cpp
Martin Gräßlin c9df18ab98 New decoration kcm:
* Displays list with previews instead of a dropdown with just the name.
* Configuration is moved into an own dialog accessible via a configure button for each decoration
* Button configuration is moved into a dialog, by that the tabs are removed
* Aurorae themes are listed just like normal decorations
* GHNS support to download Aurorae themes
* Semi-live preview of changed: when configure dialog is closed the preview is updated
* About Dialog added for each decoration (needs updates in desktop files - the information is missing)

svn path=/trunk/KDE/kdebase/workspace/; revision=1077141
2010-01-19 13:44:22 +00:00

313 lines
11 KiB
C++

/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2009 Martin Gräßlin <kde@martin-graesslin.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#include "decorationmodel.h"
#include "preview.h"
#include "auroraepreview.h"
// kwin
#include <kdecorationfactory.h>
// Qt
#include <QtCore/QDir>
#include <QtCore/QFileInfo>
// KDE
#include <KConfigGroup>
#include <KDesktopFile>
#include <KStandardDirs>
namespace KWin
{
DecorationModel::DecorationModel( KSharedConfigPtr config, QObject* parent )
: QAbstractListModel( parent )
, m_plugins( new KDecorationPreviewPlugins( config ) )
, m_preview( new KDecorationPreview() )
, m_customButtons( false )
, m_leftButtons( QString() )
, m_rightButtons( QString() )
{
findDecorations();
}
DecorationModel::~DecorationModel()
{
delete m_preview;
delete m_plugins;
}
void DecorationModel::reload()
{
m_decorations.clear();
findDecorations();
}
// Find all theme desktop files in all 'data' dirs owned by kwin.
// And insert these into a DecorationInfo structure
void DecorationModel::findDecorations()
{
beginResetModel();
const QStringList dirList = KGlobal::dirs()->findDirs("data", "kwin");
foreach( const QString &dir, dirList )
{
QDir d( dir );
if( d.exists() )
{
foreach( const QFileInfo& fi, d.entryInfoList() )
{
const QString filename( fi.absoluteFilePath() );
if( KDesktopFile::isDesktopFile(filename) )
{
const KDesktopFile desktopFile( filename );
const QString libName = desktopFile.desktopGroup().readEntry( "X-KDE-Library" );
if( !libName.isEmpty() && libName.startsWith( "kwin3_" ) )
{
if( libName == "kwin3_aurorae" )
{
// read the Aurorae themes
findAuroraeThemes();
continue;
}
DecorationModelData data;
data.name = desktopFile.readName();
data.libraryName = libName;
data.type = DecorationModelData::NativeDecoration;
data.aurorae = NULL;
data.borderSize = KDecorationDefines::BorderNormal;
metaData( data, desktopFile );
m_decorations.append(data);
}
}
}
}
}
qSort( m_decorations.begin(), m_decorations.end(), DecorationModelData::less );
endResetModel();
}
void DecorationModel::findAuroraeThemes()
{
// get all desktop themes
QStringList themes = KGlobal::dirs()->findAllResources("data",
"aurorae/themes/*/metadata.desktop",
KStandardDirs::NoDuplicates);
foreach(const QString &theme, themes)
{
int themeSepIndex = theme.lastIndexOf( '/', -1 );
QString themeRoot = theme.left( themeSepIndex );
int themeNameSepIndex = themeRoot.lastIndexOf( '/', -1 );
QString packageName = themeRoot.right( themeRoot.length() - themeNameSepIndex - 1 );
KDesktopFile df( theme );
QString name = df.readName();
if( name.isEmpty() )
{
name = packageName;
}
DecorationModelData data;
data.name = name;
data.libraryName = "kwin3_aurorae";
data.type = DecorationModelData::AuroraeDecoration;
data.auroraeName = packageName;
data.aurorae = new AuroraePreview( name, packageName, themeRoot, this );
data.borderSize = KDecorationDefines::BorderNormal;
metaData( data, df );
m_decorations.append(data);
}
}
void DecorationModel::metaData( DecorationModelData& data, const KDesktopFile& df )
{
data.comment = df.readComment();
data.author = df.desktopGroup().readEntry( "X-KDE-PluginInfo-Author", QString() );
data.email = df.desktopGroup().readEntry( "X-KDE-PluginInfo-Email", QString() );
data.version = df.desktopGroup().readEntry( "X-KDE-PluginInfo-Version", QString() );
data.license = df.desktopGroup().readEntry( "X-KDE-PluginInfo-License", QString() );
data.website = df.desktopGroup().readEntry( "X-KDE-PluginInfo-Website", QString() );
}
int DecorationModel::rowCount( const QModelIndex& parent ) const
{
Q_UNUSED( parent )
return m_decorations.count();
}
QVariant DecorationModel::data( const QModelIndex& index, int role ) const
{
if( !index.isValid() )
return QVariant();
switch( role )
{
case Qt::DisplayRole:
case NameRole:
return m_decorations[ index.row() ].name;
case LibraryNameRole:
return m_decorations[ index.row() ].libraryName;
case PixmapRole:
return m_decorations[ index.row() ].preview;
case TypeRole:
return m_decorations[ index.row() ].type;
case AuroraeNameRole:
return m_decorations[ index.row() ].auroraeName;
case PackageDescriptionRole:
return m_decorations[ index.row() ].comment;
case PackageAuthorRole:
return m_decorations[ index.row() ].author;
case PackageEmailRole:
return m_decorations[ index.row() ].email;
case PackageWebsiteRole:
return m_decorations[ index.row() ].website;
case PackageVersionRole:
return m_decorations[ index.row() ].version;
case PackageLicenseRole:
return m_decorations[ index.row() ].license;
case BorderSizeRole:
return static_cast< int >( m_decorations[ index.row() ].borderSize );
case BorderSizesRole:
{
QList< QVariant > sizes;
if( m_plugins->loadPlugin( m_decorations[ index.row() ].libraryName ) &&
m_plugins->factory() != NULL )
{
foreach( KDecorationDefines::BorderSize size, m_plugins->factory()->borderSizes() )
sizes << int(size) ;
}
return sizes;
}
default:
return QVariant();
}
}
void DecorationModel::changeButtons( bool custom, const QString& left, const QString& right )
{
bool regenerate = (custom != m_customButtons);
if( !regenerate && custom )
regenerate = (left != m_leftButtons) || (right != m_rightButtons);
m_customButtons = custom;
m_leftButtons = left;
m_rightButtons = right;
if( regenerate )
regeneratePreviews();
}
void DecorationModel::setButtons(bool custom, const QString& left, const QString& right)
{
m_customButtons = custom;
m_leftButtons = left;
m_rightButtons = right;
}
void DecorationModel::regeneratePreviews()
{
QList<DecorationModelData>::iterator it = m_decorations.begin();
for( int i=0; i<m_decorations.count(); i++ )
{
regeneratePreview( index( i ), m_decorations.at(i).preview.size() );
}
}
void DecorationModel::regeneratePreview( const QModelIndex& index, const QSize& size )
{
DecorationModelData& data = m_decorations[ index.row() ];
switch( data.type )
{
case DecorationModelData::NativeDecoration:
m_plugins->reset( KDecoration::SettingDecoration );
if ( m_plugins->loadPlugin( data.libraryName ) &&
m_preview->recreateDecoration( m_plugins ) )
m_preview->enablePreview();
else
m_preview->disablePreview();
m_plugins->destroyPreviousPlugin();
m_preview->resize( size );
m_preview->setTempButtons( m_plugins, m_customButtons, m_leftButtons, m_rightButtons );
m_preview->setTempBorderSize( m_plugins, data.borderSize );
data.preview = m_preview->preview();
break;
case DecorationModelData::AuroraeDecoration:
data.preview = data.aurorae->preview( size, m_customButtons, m_leftButtons, m_rightButtons );
break;
default:
// nothing
break;
}
emit dataChanged( index, index );
}
void DecorationModel::regeneratePreview( const QModelIndex& index )
{
regeneratePreview( index, m_decorations.at( index.row() ).preview.size() );
}
QModelIndex DecorationModel::indexOfLibrary( const QString& libraryName ) const
{
for( int i=0; i<m_decorations.count(); i++ )
{
if( m_decorations.at( i ).libraryName.compare( libraryName ) == 0 )
return index( i );
}
return QModelIndex();
}
QModelIndex DecorationModel::indexOfName( const QString& decoName ) const
{
for( int i=0; i<m_decorations.count(); i++ )
{
if( m_decorations.at( i ).name.compare( decoName ) == 0 )
return index( i );
}
return QModelIndex();
}
QModelIndex DecorationModel::indexOfAuroraeName( const QString& auroraeName ) const
{
for( int i=0; i<m_decorations.count(); i++ )
{
const DecorationModelData& data = m_decorations.at( i );
if( data.type == DecorationModelData::AuroraeDecoration &&
data.auroraeName.compare( auroraeName ) == 0 )
return index( i );
}
return QModelIndex();
}
void DecorationModel::setBorderSize( const QModelIndex& index, KDecorationDefines::BorderSize size )
{
if( !index.isValid() )
return;
m_decorations[ index.row() ].borderSize = size;
}
void DecorationModel::resetAuroraeBorderSizes( KDecorationDefines::BorderSize size )
{
QList<DecorationModelData>::iterator it = m_decorations.begin();
while( it != m_decorations.end() )
{
if( (*it).type == DecorationModelData::AuroraeDecoration )
(*it).borderSize = size;
++it;
}
}
} // namespace KWin