kwin/tabbox/clientmodel.cpp
Martin Gräßlin 76f17e6de1 Here comes the new TabBox. It is a complete rewrite using a MVC approach. Here some highlights:
* Models and Delegates for Clients and Desktops
 * Horizontal, vertical and tabular layout
 * Layout of one item can be configured by an XML definition
 * A desktop item can include a client list
 * An optional second list view showing only the selected item
 * A new KCM "kwintabbox"
 * An alternative TabBox with independent settings and keybindings
 * Optional Highlight Windows effect integration
 * List scrolls instead of removing items
 * Scroll wheel support
 * Cursor key support
 * Middle click on item closes window
BUG: 195745
BUG: 197187
BUG: 201103
FEATURE: 118184
FEATURE: 156723
FEATURE: 177441
FEATURE: 182897
FEATURE: 193882
GUI:

svn path=/trunk/KDE/kdebase/workspace/; revision=1022861
2009-09-13 11:36:45 +00:00

231 lines
6.7 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/>.
*********************************************************************/
// own
#include "clientmodel.h"
// tabbox
#include "tabboxconfig.h"
#include "tabboxhandler.h"
// Qt
#include <QTextStream>
// KDE
#include <KLocale>
// other
#include <math.h>
namespace KWin
{
namespace TabBox
{
ClientModel::ClientModel( QObject* parent )
: QAbstractItemModel( parent )
{
}
ClientModel::~ClientModel()
{
}
QVariant ClientModel::data( const QModelIndex& index, int role ) const
{
if( !index.isValid() )
return QVariant();
if( m_clientList.isEmpty() )
{
if( role == EmptyRole )
return true;
else
return i18n("*** No Windows ***");
}
int clientIndex = index.row()*columnCount() + index.column();
if( clientIndex >= m_clientList.count() )
return QVariant();
switch( role )
{
case Qt::DisplayRole:
case CaptionRole:
return m_clientList[ clientIndex ]->caption();
case ClientRole:
return qVariantFromValue( (void*)m_clientList[ clientIndex ] );
case DesktopNameRole:
{
return tabBox->desktopName( m_clientList[ clientIndex ] );
}
case EmptyRole:
return false;
case WIdRole:
return qulonglong(m_clientList[ clientIndex ]->window());
case MinimizedRole:
return m_clientList[ clientIndex ]->isMinimized();
default:
return QVariant();
}
}
int ClientModel::columnCount( const QModelIndex& parent ) const
{
Q_UNUSED( parent )
int count;
switch( tabBox->config().layout() )
{
case TabBoxConfig::HorizontalLayout:
count = m_clientList.count();
break;
case TabBoxConfig::VerticalLayout:
count = 1;
break;
case TabBoxConfig::HorizontalVerticalLayout:
count = qRound( sqrt( m_clientList.count() ) );
if( count * count < m_clientList.count() )
count++;
break;
}
return qMax( count, 1 );
}
int ClientModel::rowCount( const QModelIndex& parent ) const
{
Q_UNUSED( parent )
int count;
switch( tabBox->config().layout() )
{
case TabBoxConfig::HorizontalLayout:
count = 1;
break;
case TabBoxConfig::VerticalLayout:
count = m_clientList.count();
break;
case TabBoxConfig::HorizontalVerticalLayout:
count = qRound( sqrt( m_clientList.count() ) );
break;
}
return qMax( count, 1 );
}
QModelIndex ClientModel::parent( const QModelIndex& child ) const
{
Q_UNUSED( child )
return QModelIndex();
}
QModelIndex ClientModel::index( int row, int column, const QModelIndex& parent ) const
{
Q_UNUSED( parent )
int index = row * columnCount() + column;
if( index >= m_clientList.count() && !m_clientList.isEmpty() )
return QModelIndex();
return createIndex( row, column );
}
QModelIndex ClientModel::index( TabBoxClient* client ) const
{
if( !m_clientList.contains( client ) )
return QModelIndex();
int index = m_clientList.indexOf( client );
int row = index / columnCount();
int column = index % columnCount();
return createIndex( row, column );
}
void ClientModel::createClientList( bool partialReset )
{
createClientList( tabBox->currentDesktop(), partialReset );
}
void ClientModel::createClientList( int desktop, bool partialReset )
{
reset();
TabBoxClient* start = tabBox->activeClient();
// TODO: new clients are not added at correct position
if( partialReset && !m_clientList.isEmpty() )
start = m_clientList.first();
m_clientList.clear();
switch (tabBox->config().clientSwitchingMode() )
{
case TabBoxConfig::FocusChainSwitching:
{
TabBoxClient* c = tabBox->nextClientFocusChain( start );
TabBoxClient* stop = c;
while ( c )
{
TabBoxClient* add = tabBox->clientToAddToList( c, desktop,
tabBox->config().clientListMode() == TabBoxConfig::AllDesktopsClientList );
if( add != NULL )
{
if ( start == add )
{
m_clientList.removeAll( add );
m_clientList.prepend( add );
}
else
m_clientList += add;
}
c = tabBox->nextClientFocusChain( c );
if ( c == stop )
break;
}
break;
}
case TabBoxConfig::StackingOrderSwitching:
{
// TODO: needs improvement
TabBoxClientList stacking = tabBox->stackingOrder();
TabBoxClient* c = stacking.first();
TabBoxClient* stop = c;
int index = 0;
while ( c )
{
TabBoxClient* add = tabBox->clientToAddToList( c, desktop,
tabBox->config().clientListMode() == TabBoxConfig::AllDesktopsClientList );
if( add != NULL )
{
if ( start == add )
{
m_clientList.removeAll( add );
m_clientList.prepend( add );
}
else
m_clientList += add;
}
if( index >= stacking.size() - 1 )
{
c = NULL;
}
else
{
c = stacking[++index];
}
if ( c == stop )
break;
}
break;
}
}
}
} // namespace Tabbox
} // namespace KWin