00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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 struct Icons
00041 {
00042 Icons()
00043 : readyPixmap( KIcon( QLatin1String( "user-online" ) ).pixmap( QSize( 16, 16 ) ) )
00044 , syncPixmap( KIcon( QLatin1String( "network-connect" ) ).pixmap( QSize( 16, 16 ) ) )
00045 , errorPixmap( KIcon( QLatin1String( "dialog-error" ) ).pixmap( QSize( 16, 16 ) ) )
00046 , offlinePixmap( KIcon( QLatin1String( "network-disconnect" ) ).pixmap( QSize( 16, 16 ) ) )
00047 {
00048 }
00049 QPixmap readyPixmap, syncPixmap, errorPixmap, offlinePixmap;
00050 };
00051
00052 K_GLOBAL_STATIC( Icons, s_icons )
00053
00054
00057 class AgentInstanceWidgetDelegate : public QAbstractItemDelegate
00058 {
00059 public:
00060 AgentInstanceWidgetDelegate( QObject *parent = 0 );
00061
00062 virtual void paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const;
00063 virtual QSize sizeHint( const QStyleOptionViewItem &option, const QModelIndex &index ) const;
00064
00065 private:
00066 void drawFocus( QPainter*, const QStyleOptionViewItem&, const QRect& ) const;
00067
00068 QTextDocument* document( const QStyleOptionViewItem &option, const QModelIndex &index ) const;
00069 };
00070
00071 }
00072
00073 using Akonadi::Internal::AgentInstanceWidgetDelegate;
00074
00078 class AgentInstanceWidget::Private
00079 {
00080 public:
00081 Private( AgentInstanceWidget *parent )
00082 : mParent( parent )
00083 {
00084 }
00085
00086 void currentAgentInstanceChanged( const QModelIndex&, const QModelIndex& );
00087 void currentAgentInstanceDoubleClicked( const QModelIndex& );
00088
00089 AgentInstanceWidget *mParent;
00090 QListView *mView;
00091 AgentInstanceModel *mModel;
00092 AgentFilterProxyModel *proxy;
00093 };
00094
00095 void AgentInstanceWidget::Private::currentAgentInstanceChanged( const QModelIndex ¤tIndex, const QModelIndex &previousIndex )
00096 {
00097 AgentInstance currentInstance;
00098 if ( currentIndex.isValid() )
00099 currentInstance = currentIndex.data( AgentInstanceModel::InstanceRole ).value<AgentInstance>();
00100
00101 AgentInstance previousInstance;
00102 if ( previousIndex.isValid() )
00103 previousInstance = previousIndex.data( AgentInstanceModel::InstanceRole ).value<AgentInstance>();
00104
00105 emit mParent->currentChanged( currentInstance, previousInstance );
00106 }
00107
00108 void AgentInstanceWidget::Private::currentAgentInstanceDoubleClicked( const QModelIndex ¤tIndex )
00109 {
00110 AgentInstance currentInstance;
00111 if ( currentIndex.isValid() )
00112 currentInstance = currentIndex.data( AgentInstanceModel::InstanceRole ).value<AgentInstance>();
00113
00114 emit mParent->doubleClicked( currentInstance );
00115 }
00116
00117 AgentInstanceWidget::AgentInstanceWidget( QWidget *parent )
00118 : QWidget( parent ), d( new Private( this ) )
00119 {
00120 QHBoxLayout *layout = new QHBoxLayout( this );
00121 layout->setMargin( 0 );
00122
00123 d->mView = new QListView( this );
00124 d->mView->setContextMenuPolicy( Qt::NoContextMenu );
00125 d->mView->setItemDelegate( new Internal::AgentInstanceWidgetDelegate( d->mView ) );
00126 d->mView->setVerticalScrollMode( QAbstractItemView::ScrollPerPixel );
00127 d->mView->setAlternatingRowColors( true );
00128 d->mView->setSelectionMode( QAbstractItemView::ExtendedSelection );
00129 layout->addWidget( d->mView );
00130
00131 d->mModel = new AgentInstanceModel( this );
00132
00133 d->proxy = new AgentFilterProxyModel( this );
00134 d->proxy->setSourceModel( d->mModel );
00135 d->mView->setModel( d->proxy );
00136
00137 d->mView->selectionModel()->setCurrentIndex( d->mView->model()->index( 0, 0 ), QItemSelectionModel::Select );
00138 d->mView->scrollTo( d->mView->model()->index( 0, 0 ) );
00139
00140 connect( d->mView->selectionModel(), SIGNAL( currentChanged( const QModelIndex&, const QModelIndex& ) ),
00141 this, SLOT( currentAgentInstanceChanged( const QModelIndex&, const QModelIndex& ) ) );
00142 connect( d->mView, SIGNAL( doubleClicked( const QModelIndex& ) ),
00143 this, SLOT( currentAgentInstanceDoubleClicked( const QModelIndex& ) ) );
00144 }
00145
00146 AgentInstanceWidget::~AgentInstanceWidget()
00147 {
00148 delete d;
00149 }
00150
00151 AgentInstance AgentInstanceWidget::currentAgentInstance() const
00152 {
00153 QItemSelectionModel *selectionModel = d->mView->selectionModel();
00154 if ( !selectionModel )
00155 return AgentInstance();
00156
00157 QModelIndex index = selectionModel->currentIndex();
00158 if ( !index.isValid() )
00159 return AgentInstance();
00160
00161 return index.data( AgentInstanceModel::InstanceRole ).value<AgentInstance>();
00162 }
00163
00164 QList<AgentInstance> AgentInstanceWidget::selectedAgentInstances() const
00165 {
00166 QList<AgentInstance> list;
00167 QItemSelectionModel *selectionModel = d->mView->selectionModel();
00168 if ( !selectionModel )
00169 return list;
00170
00171 QModelIndexList indexes = selectionModel->selection().indexes();
00172
00173 foreach (const QModelIndex &index, indexes )
00174 {
00175 list.append( index.data( AgentInstanceModel::InstanceRole ).value<AgentInstance>() );
00176 }
00177
00178 return list;
00179 }
00180
00181 QAbstractItemView* AgentInstanceWidget::view() const
00182 {
00183 return d->mView;
00184 }
00185
00186
00187 AgentFilterProxyModel* AgentInstanceWidget::agentFilterProxyModel() const
00188 {
00189 return d->proxy;
00190 }
00191
00192
00193
00194
00195
00196 AgentInstanceWidgetDelegate::AgentInstanceWidgetDelegate( QObject *parent )
00197 : QAbstractItemDelegate( parent )
00198 {
00199 }
00200
00201 QTextDocument* AgentInstanceWidgetDelegate::document( const QStyleOptionViewItem &option, const QModelIndex &index ) const
00202 {
00203 if ( !index.isValid() )
00204 return 0;
00205
00206 const QString name = index.model()->data( index, Qt::DisplayRole ).toString();
00207 int status = index.model()->data( index, AgentInstanceModel::StatusRole ).toInt();
00208 uint progress = index.model()->data( index, AgentInstanceModel::ProgressRole ).toUInt();
00209 const QString statusMessage = index.model()->data( index, AgentInstanceModel::StatusMessageRole ).toString();
00210 const QStringList capabilities = index.model()->data( index, AgentInstanceModel::CapabilitiesRole ).toStringList();
00211
00212 QTextDocument *document = new QTextDocument( 0 );
00213
00214 const QVariant data = index.model()->data( index, Qt::DecorationRole );
00215 if ( data.isValid() && data.type() == QVariant::Icon ) {
00216 document->addResource( QTextDocument::ImageResource, QUrl( QLatin1String( "agent_icon" ) ),
00217 qvariant_cast<QIcon>( data ).pixmap( QSize( 64, 64 ) ) );
00218 }
00219
00220 if ( !index.data( AgentInstanceModel::OnlineRole ).toBool() )
00221 document->addResource( QTextDocument::ImageResource, QUrl( QLatin1String( "status_icon" ) ), s_icons->offlinePixmap );
00222 else if ( status == AgentInstance::Idle )
00223 document->addResource( QTextDocument::ImageResource, QUrl( QLatin1String( "status_icon" ) ), s_icons->readyPixmap );
00224 else if ( status == AgentInstance::Running )
00225 document->addResource( QTextDocument::ImageResource, QUrl( QLatin1String( "status_icon" ) ), s_icons->syncPixmap );
00226 else
00227 document->addResource( QTextDocument::ImageResource, QUrl( QLatin1String( "status_icon" ) ), s_icons->errorPixmap );
00228
00229
00230 QPalette::ColorGroup cg = option.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
00231 if ( cg == QPalette::Normal && !(option.state & QStyle::State_Active) )
00232 cg = QPalette::Inactive;
00233
00234 QColor textColor;
00235 if ( option.state & QStyle::State_Selected ) {
00236 textColor = option.palette.color( cg, QPalette::HighlightedText );
00237 } else {
00238 textColor = option.palette.color( cg, QPalette::Text );
00239 }
00240
00241 QString content = QString::fromLatin1(
00242 "<html style=\"color:%1\">"
00243 "<body>"
00244 "<table>"
00245 "<tr>"
00246 "<td rowspan=\"2\"><img src=\"agent_icon\"> </td>"
00247 "<td><b>%2</b></td>"
00248 "</tr>" ).arg(textColor.name().toUpper()).arg( name )
00249 + QString::fromLatin1(
00250 "<tr>"
00251 "<td><img src=\"status_icon\"/> %1 %2</td>"
00252 "</tr>" ).arg( statusMessage ).arg( status == 1 ? QString( QLatin1String( "(%1%)" ) ).arg( progress ) : QLatin1String( "" ) )
00253 + QLatin1String( "</table></body></html>" );
00254
00255 document->setHtml( content );
00256
00257 return document;
00258 }
00259
00260 void AgentInstanceWidgetDelegate::paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const
00261 {
00262 if ( !index.isValid() )
00263 return;
00264
00265 QTextDocument *doc = document( option, index );
00266 if ( !doc )
00267 return;
00268
00269 painter->setRenderHint( QPainter::Antialiasing );
00270
00271 QPen pen = painter->pen();
00272
00273 QPalette::ColorGroup cg = option.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
00274 if ( cg == QPalette::Normal && !(option.state & QStyle::State_Active) )
00275 cg = QPalette::Inactive;
00276
00277 QStyleOptionViewItemV4 opt(option);
00278 opt.showDecorationSelected = true;
00279 QApplication::style()->drawPrimitive( QStyle::PE_PanelItemViewItem, &opt, painter );
00280
00281 painter->save();
00282 painter->translate( option.rect.topLeft() );
00283 doc->drawContents( painter );
00284 delete doc;
00285 painter->restore();
00286
00287 painter->setPen(pen);
00288
00289 drawFocus( painter, option, option.rect );
00290 }
00291
00292 QSize AgentInstanceWidgetDelegate::sizeHint( const QStyleOptionViewItem &option, const QModelIndex &index ) const
00293 {
00294 if ( !index.isValid() )
00295 return QSize( 0, 0 );
00296
00297 QTextDocument *doc = document( option, index );
00298 if ( !doc )
00299 return QSize( 0, 0 );
00300
00301 const QSize size = doc->documentLayout()->documentSize().toSize();
00302 delete doc;
00303
00304 return size;
00305 }
00306
00307 void AgentInstanceWidgetDelegate::drawFocus( QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect ) const
00308 {
00309 if ( option.state & QStyle::State_HasFocus ) {
00310 QStyleOptionFocusRect o;
00311 o.QStyleOption::operator=( option );
00312 o.rect = rect;
00313 o.state |= QStyle::State_KeyboardFocusChange;
00314 QPalette::ColorGroup cg = (option.state & QStyle::State_Enabled) ? QPalette::Normal : QPalette::Disabled;
00315 o.backgroundColor = option.palette.color( cg, (option.state & QStyle::State_Selected)
00316 ? QPalette::Highlight : QPalette::Background );
00317 QApplication::style()->drawPrimitive( QStyle::PE_FrameFocusRect, &o, painter );
00318 }
00319 }
00320
00321 }
00322
00323 #include "agentinstancewidget.moc"