• Skip to content
  • Skip to link menu
KDE 4.6 API Reference
  • KDE API Reference
  • KDE-PIM Libraries
  • KDE Home
  • Contact Us
 

akonadi

agentinstancewidget.cpp
00001 /*
00002     Copyright (c) 2006-2008 Tobias Koenig <tokoe@kde.org>
00003 
00004     This library is free software; you can redistribute it and/or modify it
00005     under the terms of the GNU Library General Public License as published by
00006     the Free Software Foundation; either version 2 of the License, or (at your
00007     option) any later version.
00008 
00009     This library is distributed in the hope that it will be useful, but WITHOUT
00010     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00011     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00012     License for more details.
00013 
00014     You should have received a copy of the GNU Library General Public License
00015     along with this library; see the file COPYING.LIB.  If not, write to the
00016     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00017     02110-1301, USA.
00018 */
00019 
00020 #include "agentinstancewidget.h"
00021 
00022 #include "agentfilterproxymodel.h"
00023 #include "agentinstance.h"
00024 #include "agentinstancemodel.h"
00025 
00026 #include <KIcon>
00027 #include <KGlobal>
00028 
00029 #include <QtCore/QUrl>
00030 #include <QtGui/QAbstractTextDocumentLayout>
00031 #include <QtGui/QApplication>
00032 #include <QtGui/QHBoxLayout>
00033 #include <QtGui/QListView>
00034 #include <QtGui/QPainter>
00035 #include <QtGui/QTextDocument>
00036 
00037 namespace Akonadi {
00038 namespace Internal {
00039 
00040 static void iconsEarlyCleanup();
00041 
00042 struct Icons
00043 {
00044   Icons()
00045    : readyPixmap( KIcon( QLatin1String( "user-online" ) ).pixmap( QSize( 16, 16 ) ) )
00046    , syncPixmap( KIcon( QLatin1String( "network-connect" ) ).pixmap( QSize( 16, 16 ) ) )
00047    , errorPixmap( KIcon( QLatin1String( "dialog-error" ) ).pixmap( QSize( 16, 16 ) ) )
00048    , offlinePixmap( KIcon( QLatin1String( "network-disconnect" ) ).pixmap( QSize( 16, 16 ) ) )
00049   {
00050     qAddPostRoutine( iconsEarlyCleanup );
00051   }
00052   QPixmap readyPixmap, syncPixmap, errorPixmap, offlinePixmap;
00053 };
00054 
00055 K_GLOBAL_STATIC( Icons, s_icons )
00056 
00057 // called as a Qt post routine, to prevent pixmap leaking
00058 void iconsEarlyCleanup() {
00059   Icons * const ic = s_icons;
00060   ic->readyPixmap = ic->syncPixmap = ic->errorPixmap = ic->offlinePixmap = QPixmap();
00061 }
00062 
00066 class AgentInstanceWidgetDelegate : public QAbstractItemDelegate
00067 {
00068   public:
00069     AgentInstanceWidgetDelegate( QObject *parent = 0 );
00070 
00071     virtual void paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const;
00072     virtual QSize sizeHint( const QStyleOptionViewItem &option, const QModelIndex &index ) const;
00073 
00074   private:
00075     void drawFocus( QPainter*, const QStyleOptionViewItem&, const QRect& ) const;
00076 
00077     QTextDocument* document( const QStyleOptionViewItem &option, const QModelIndex &index ) const;
00078 };
00079 
00080 }
00081 
00082 using Akonadi::Internal::AgentInstanceWidgetDelegate;
00083 
00087 class AgentInstanceWidget::Private
00088 {
00089   public:
00090     Private( AgentInstanceWidget *parent )
00091       : mParent( parent )
00092     {
00093     }
00094 
00095     void currentAgentInstanceChanged( const QModelIndex&, const QModelIndex& );
00096     void currentAgentInstanceDoubleClicked( const QModelIndex& );
00097 
00098     AgentInstanceWidget *mParent;
00099     QListView *mView;
00100     AgentInstanceModel *mModel;
00101     AgentFilterProxyModel *proxy;
00102 };
00103 
00104 void AgentInstanceWidget::Private::currentAgentInstanceChanged( const QModelIndex &currentIndex, const QModelIndex &previousIndex )
00105 {
00106   AgentInstance currentInstance;
00107   if ( currentIndex.isValid() )
00108     currentInstance = currentIndex.data( AgentInstanceModel::InstanceRole ).value<AgentInstance>();
00109 
00110   AgentInstance previousInstance;
00111   if ( previousIndex.isValid() )
00112     previousInstance = previousIndex.data( AgentInstanceModel::InstanceRole ).value<AgentInstance>();
00113 
00114   emit mParent->currentChanged( currentInstance, previousInstance );
00115 }
00116 
00117 void AgentInstanceWidget::Private::currentAgentInstanceDoubleClicked( const QModelIndex &currentIndex )
00118 {
00119   AgentInstance currentInstance;
00120   if ( currentIndex.isValid() )
00121     currentInstance = currentIndex.data( AgentInstanceModel::InstanceRole ).value<AgentInstance>();
00122 
00123   emit mParent->doubleClicked( currentInstance );
00124 }
00125 
00126 AgentInstanceWidget::AgentInstanceWidget( QWidget *parent )
00127   : QWidget( parent ), d( new Private( this ) )
00128 {
00129   QHBoxLayout *layout = new QHBoxLayout( this );
00130   layout->setMargin( 0 );
00131 
00132   d->mView = new QListView( this );
00133   d->mView->setContextMenuPolicy( Qt::NoContextMenu );
00134   d->mView->setItemDelegate( new Internal::AgentInstanceWidgetDelegate( d->mView ) );
00135   d->mView->setVerticalScrollMode( QAbstractItemView::ScrollPerPixel );
00136   d->mView->setAlternatingRowColors( true );
00137   d->mView->setSelectionMode( QAbstractItemView::ExtendedSelection );
00138   layout->addWidget( d->mView );
00139 
00140   d->mModel = new AgentInstanceModel( this );
00141 
00142   d->proxy = new AgentFilterProxyModel( this );
00143   d->proxy->setSourceModel( d->mModel );
00144   d->mView->setModel( d->proxy );
00145 
00146   d->mView->selectionModel()->setCurrentIndex( d->mView->model()->index( 0, 0 ), QItemSelectionModel::Select );
00147   d->mView->scrollTo( d->mView->model()->index( 0, 0 ) );
00148 
00149   connect( d->mView->selectionModel(), SIGNAL( currentChanged( const QModelIndex&, const QModelIndex& ) ),
00150            this, SLOT( currentAgentInstanceChanged( const QModelIndex&, const QModelIndex& ) ) );
00151   connect( d->mView, SIGNAL( doubleClicked( const QModelIndex& ) ),
00152            this, SLOT( currentAgentInstanceDoubleClicked( const QModelIndex& ) ) );
00153 }
00154 
00155 AgentInstanceWidget::~AgentInstanceWidget()
00156 {
00157   delete d;
00158 }
00159 
00160 AgentInstance AgentInstanceWidget::currentAgentInstance() const
00161 {
00162   QItemSelectionModel *selectionModel = d->mView->selectionModel();
00163   if ( !selectionModel )
00164     return AgentInstance();
00165 
00166   QModelIndex index = selectionModel->currentIndex();
00167   if ( !index.isValid() )
00168     return AgentInstance();
00169 
00170   return index.data( AgentInstanceModel::InstanceRole ).value<AgentInstance>();
00171 }
00172 
00173 QList<AgentInstance> AgentInstanceWidget::selectedAgentInstances() const
00174 {
00175   QList<AgentInstance> list;
00176   QItemSelectionModel *selectionModel = d->mView->selectionModel();
00177   if ( !selectionModel )
00178     return list;
00179 
00180   QModelIndexList indexes = selectionModel->selection().indexes();
00181 
00182   foreach (const QModelIndex &index, indexes )
00183   {
00184     list.append( index.data( AgentInstanceModel::InstanceRole ).value<AgentInstance>() );
00185   }
00186 
00187   return list;
00188 }
00189 
00190 QAbstractItemView* AgentInstanceWidget::view() const
00191 {
00192   return d->mView;
00193 }
00194 
00195 
00196 AgentFilterProxyModel* AgentInstanceWidget::agentFilterProxyModel() const
00197 {
00198   return d->proxy;
00199 }
00200 
00201 
00202 
00203 
00204 
00205 AgentInstanceWidgetDelegate::AgentInstanceWidgetDelegate( QObject *parent )
00206  : QAbstractItemDelegate( parent )
00207 {
00208 }
00209 
00210 QTextDocument* AgentInstanceWidgetDelegate::document( const QStyleOptionViewItem &option, const QModelIndex &index ) const
00211 {
00212   if ( !index.isValid() )
00213     return 0;
00214 
00215   const QString name = index.model()->data( index, Qt::DisplayRole ).toString();
00216   int status = index.model()->data( index, AgentInstanceModel::StatusRole ).toInt();
00217   uint progress = index.model()->data( index, AgentInstanceModel::ProgressRole ).toUInt();
00218   const QString statusMessage = index.model()->data( index, AgentInstanceModel::StatusMessageRole ).toString();
00219   const QStringList capabilities = index.model()->data( index, AgentInstanceModel::CapabilitiesRole ).toStringList();
00220 
00221   QTextDocument *document = new QTextDocument( 0 );
00222 
00223   const QVariant data = index.model()->data( index, Qt::DecorationRole );
00224   if ( data.isValid() && data.type() == QVariant::Icon ) {
00225     document->addResource( QTextDocument::ImageResource, QUrl( QLatin1String( "agent_icon" ) ),
00226                            qvariant_cast<QIcon>( data ).pixmap( QSize( 64, 64 ) ) );
00227   }
00228 
00229   if ( !index.data( AgentInstanceModel::OnlineRole ).toBool() )
00230     document->addResource( QTextDocument::ImageResource, QUrl( QLatin1String( "status_icon" ) ), s_icons->offlinePixmap );
00231   else if ( status == AgentInstance::Idle )
00232     document->addResource( QTextDocument::ImageResource, QUrl( QLatin1String( "status_icon" ) ), s_icons->readyPixmap );
00233   else if ( status == AgentInstance::Running )
00234     document->addResource( QTextDocument::ImageResource, QUrl( QLatin1String( "status_icon" ) ), s_icons->syncPixmap );
00235   else
00236     document->addResource( QTextDocument::ImageResource, QUrl( QLatin1String( "status_icon" ) ), s_icons->errorPixmap );
00237 
00238 
00239   QPalette::ColorGroup cg = option.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
00240   if ( cg == QPalette::Normal && !(option.state & QStyle::State_Active) )
00241     cg = QPalette::Inactive;
00242 
00243   QColor textColor;
00244   if ( option.state & QStyle::State_Selected ) {
00245     textColor = option.palette.color( cg, QPalette::HighlightedText );
00246   } else {
00247     textColor = option.palette.color( cg, QPalette::Text );
00248   }
00249 
00250   QString content = QString::fromLatin1(
00251      "<html style=\"color:%1\">"
00252      "<body>"
00253      "<table>"
00254      "<tr>"
00255      "<td rowspan=\"2\"><img src=\"agent_icon\">&nbsp;&nbsp;</td>"
00256      "<td><b>%2</b></td>"
00257      "</tr>" ).arg(textColor.name().toUpper()).arg( name )
00258      + QString::fromLatin1(
00259      "<tr>"
00260      "<td><img src=\"status_icon\"/> %1 %2</td>"
00261      "</tr>" ).arg( statusMessage ).arg( status == 1 ? QString( QLatin1String( "(%1%)" ) ).arg( progress ) : QLatin1String( "" ) )
00262      + QLatin1String( "</table></body></html>" );
00263 
00264   document->setHtml( content );
00265 
00266   return document;
00267 }
00268 
00269 void AgentInstanceWidgetDelegate::paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const
00270 {
00271   if ( !index.isValid() )
00272     return;
00273 
00274   QTextDocument *doc = document( option, index );
00275   if ( !doc )
00276     return;
00277 
00278   painter->setRenderHint( QPainter::Antialiasing );
00279 
00280   QPen pen = painter->pen();
00281 
00282   QPalette::ColorGroup cg = option.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
00283   if ( cg == QPalette::Normal && !(option.state & QStyle::State_Active) )
00284     cg = QPalette::Inactive;
00285 
00286   QStyleOptionViewItemV4 opt(option);
00287   opt.showDecorationSelected = true;
00288   QApplication::style()->drawPrimitive( QStyle::PE_PanelItemViewItem, &opt, painter );
00289 
00290   painter->save();
00291   painter->translate( option.rect.topLeft() );
00292   doc->drawContents( painter );
00293   delete doc;
00294   painter->restore();
00295 
00296   painter->setPen(pen);
00297 
00298   drawFocus( painter, option, option.rect );
00299 }
00300 
00301 QSize AgentInstanceWidgetDelegate::sizeHint( const QStyleOptionViewItem &option, const QModelIndex &index ) const
00302 {
00303   if ( !index.isValid() )
00304     return QSize( 0, 0 );
00305 
00306   QTextDocument *doc = document( option, index );
00307   if ( !doc )
00308     return QSize( 0, 0 );
00309 
00310   const QSize size = doc->documentLayout()->documentSize().toSize();
00311   delete doc;
00312 
00313   return size;
00314 }
00315 
00316 void AgentInstanceWidgetDelegate::drawFocus( QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect ) const
00317 {
00318   if ( option.state & QStyle::State_HasFocus ) {
00319     QStyleOptionFocusRect o;
00320     o.QStyleOption::operator=( option );
00321     o.rect = rect;
00322     o.state |= QStyle::State_KeyboardFocusChange;
00323     QPalette::ColorGroup cg = (option.state & QStyle::State_Enabled) ? QPalette::Normal : QPalette::Disabled;
00324     o.backgroundColor = option.palette.color( cg, (option.state & QStyle::State_Selected)
00325                                                   ? QPalette::Highlight : QPalette::Background );
00326     QApplication::style()->drawPrimitive( QStyle::PE_FrameFocusRect, &o, painter );
00327   }
00328 }
00329 
00330 }
00331 
00332 #include "agentinstancewidget.moc"

akonadi

Skip menu "akonadi"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

KDE-PIM Libraries

Skip menu "KDE-PIM Libraries"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Generated for KDE-PIM Libraries by doxygen 1.7.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal