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