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 layout->setSpacing( 0 );
00118
00119 d->mView = new QListView( this );
00120 d->mView->setItemDelegate( new AgentInstanceWidgetDelegate( d->mView ) );
00121 layout->addWidget( d->mView );
00122
00123 d->mModel = new AgentInstanceModel( this );
00124
00125 d->proxy = new AgentFilterProxyModel( this );
00126 d->proxy->setSourceModel( d->mModel );
00127 d->mView->setModel( d->proxy );
00128
00129 d->mView->selectionModel()->setCurrentIndex( d->mView->model()->index( 0, 0 ), QItemSelectionModel::Select );
00130 d->mView->scrollTo( d->mView->model()->index( 0, 0 ) );
00131
00132 connect( d->mView->selectionModel(), SIGNAL( currentChanged( const QModelIndex&, const QModelIndex& ) ),
00133 this, SLOT( currentAgentInstanceChanged( const QModelIndex&, const QModelIndex& ) ) );
00134 connect( d->mView, SIGNAL( doubleClicked( const QModelIndex& ) ),
00135 this, SLOT( currentAgentInstanceDoubleClicked( const QModelIndex& ) ) );
00136 }
00137
00138 AgentInstanceWidget::~AgentInstanceWidget()
00139 {
00140 delete d;
00141 }
00142
00143 AgentInstance AgentInstanceWidget::currentAgentInstance() const
00144 {
00145 QItemSelectionModel *selectionModel = d->mView->selectionModel();
00146 if ( !selectionModel )
00147 return AgentInstance();
00148
00149 QModelIndex index = selectionModel->currentIndex();
00150 if ( !index.isValid() )
00151 return AgentInstance();
00152
00153 return index.data( AgentInstanceModel::InstanceRole ).value<AgentInstance>();
00154 }
00155
00156 AgentFilterProxyModel* AgentInstanceWidget::agentFilterProxyModel() const
00157 {
00158 return d->proxy;
00159 }
00160
00161
00162
00163
00164
00165 AgentInstanceWidgetDelegate::AgentInstanceWidgetDelegate( QObject *parent )
00166 : QAbstractItemDelegate( parent )
00167 {
00168 }
00169
00170 QTextDocument* AgentInstanceWidgetDelegate::document( const QStyleOptionViewItem &option, const QModelIndex &index ) const
00171 {
00172 if ( !index.isValid() )
00173 return 0;
00174
00175 const QString name = index.model()->data( index, Qt::DisplayRole ).toString();
00176 int status = index.model()->data( index, AgentInstanceModel::StatusRole ).toInt();
00177 uint progress = index.model()->data( index, AgentInstanceModel::ProgressRole ).toUInt();
00178 const QString statusMessage = index.model()->data( index, AgentInstanceModel::StatusMessageRole ).toString();
00179 const QStringList capabilities = index.model()->data( index, AgentInstanceModel::CapabilitiesRole ).toStringList();
00180
00181 QTextDocument *document = new QTextDocument( 0 );
00182
00183 const QVariant data = index.model()->data( index, Qt::DecorationRole );
00184 if ( data.isValid() && data.type() == QVariant::Icon ) {
00185 document->addResource( QTextDocument::ImageResource, QUrl( QLatin1String( "agent_icon" ) ),
00186 qvariant_cast<QIcon>( data ).pixmap( QSize( 64, 64 ) ) );
00187 }
00188
00189 if ( !index.data( AgentInstanceModel::OnlineRole ).toBool() )
00190 document->addResource( QTextDocument::ImageResource, QUrl( QLatin1String( "status_icon" ) ), s_icons->offlinePixmap );
00191 else if ( status == AgentInstance::Idle )
00192 document->addResource( QTextDocument::ImageResource, QUrl( QLatin1String( "status_icon" ) ), s_icons->readyPixmap );
00193 else if ( status == AgentInstance::Running )
00194 document->addResource( QTextDocument::ImageResource, QUrl( QLatin1String( "status_icon" ) ), s_icons->syncPixmap );
00195 else
00196 document->addResource( QTextDocument::ImageResource, QUrl( QLatin1String( "status_icon" ) ), s_icons->errorPixmap );
00197
00198
00199 QPalette::ColorGroup cg = option.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
00200 if ( cg == QPalette::Normal && !(option.state & QStyle::State_Active) )
00201 cg = QPalette::Inactive;
00202
00203 QColor textColor;
00204 if ( option.state & QStyle::State_Selected ) {
00205 textColor = option.palette.color( cg, QPalette::HighlightedText );
00206 } else {
00207 textColor = option.palette.color( cg, QPalette::Text );
00208 }
00209
00210 QString content = QString::fromLatin1(
00211 "<html style=\"color:%1\">"
00212 "<body>"
00213 "<table>"
00214 "<tr>"
00215 "<td rowspan=\"2\"><img src=\"agent_icon\"></td>"
00216 "<td><b>%2</b></td>"
00217 "</tr>" ).arg(textColor.name().toUpper()).arg( name );
00218 if ( capabilities.contains( QLatin1String( "Resource" ) ) ) {
00219 content += QString::fromLatin1(
00220 "<tr>"
00221 "<td><img src=\"status_icon\"/> %1 %2</td>"
00222 "</tr>" ).arg( statusMessage ).arg( status == 1 ? QString( QLatin1String( "(%1%)" ) ).arg( progress ) : QLatin1String( "" ) );
00223 }
00224 content += 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 if ( option.state & QStyle::State_Selected ) {
00249 painter->fillRect( option.rect, option.palette.brush( cg, QPalette::Highlight ) );
00250 painter->setPen( option.palette.color( cg, QPalette::HighlightedText ) );
00251 } else {
00252 painter->setPen(option.palette.color( cg, QPalette::Text ) );
00253 }
00254
00255 painter->save();
00256 painter->translate( option.rect.topLeft() );
00257 doc->drawContents( painter );
00258 delete doc;
00259 painter->restore();
00260
00261 painter->setPen(pen);
00262
00263 drawFocus( painter, option, option.rect );
00264 }
00265
00266 QSize AgentInstanceWidgetDelegate::sizeHint( const QStyleOptionViewItem &option, const QModelIndex &index ) const
00267 {
00268 if ( !index.isValid() )
00269 return QSize( 0, 0 );
00270
00271 QTextDocument *doc = document( option, index );
00272 if ( !doc )
00273 return QSize( 0, 0 );
00274
00275 const QSize size = doc->documentLayout()->documentSize().toSize();
00276 delete doc;
00277
00278 return size;
00279 }
00280
00281 void AgentInstanceWidgetDelegate::drawFocus( QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect ) const
00282 {
00283 if ( option.state & QStyle::State_HasFocus ) {
00284 QStyleOptionFocusRect o;
00285 o.QStyleOption::operator=( option );
00286 o.rect = rect;
00287 o.state |= QStyle::State_KeyboardFocusChange;
00288 QPalette::ColorGroup cg = (option.state & QStyle::State_Enabled) ? QPalette::Normal : QPalette::Disabled;
00289 o.backgroundColor = option.palette.color( cg, (option.state & QStyle::State_Selected)
00290 ? QPalette::Highlight : QPalette::Background );
00291 QApplication::style()->drawPrimitive( QStyle::PE_FrameFocusRect, &o, painter );
00292 }
00293 }
00294
00295 #include "agentinstancewidget.moc"