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 {
00046 }
00047 QPixmap readyPixmap, syncPixmap, errorPixmap;
00048 };
00049
00050 K_GLOBAL_STATIC( Icons, s_icons )
00051
00052
00055 class AgentInstanceWidgetDelegate : public QAbstractItemDelegate
00056 {
00057 public:
00058 AgentInstanceWidgetDelegate( QObject *parent = 0 );
00059
00060 virtual void paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const;
00061 virtual QSize sizeHint( const QStyleOptionViewItem &option, const QModelIndex &index ) const;
00062
00063 private:
00064 void drawFocus( QPainter*, const QStyleOptionViewItem&, const QRect& ) const;
00065
00066 QTextDocument* document( const QStyleOptionViewItem &option, const QModelIndex &index ) const;
00067 };
00068
00072 class AgentInstanceWidget::Private
00073 {
00074 public:
00075 Private( AgentInstanceWidget *parent )
00076 : mParent( parent )
00077 {
00078 }
00079
00080 void currentAgentInstanceChanged( const QModelIndex&, const QModelIndex& );
00081 void currentAgentInstanceDoubleClicked( const QModelIndex& );
00082
00083 AgentInstanceWidget *mParent;
00084 QListView *mView;
00085 AgentInstanceModel *mModel;
00086 AgentFilterProxyModel *proxy;
00087 };
00088
00089 void AgentInstanceWidget::Private::currentAgentInstanceChanged( const QModelIndex ¤tIndex, const QModelIndex &previousIndex )
00090 {
00091 AgentInstance currentInstance;
00092 if ( currentIndex.isValid() )
00093 currentInstance = currentIndex.data( AgentInstanceModel::InstanceRole ).value<AgentInstance>();
00094
00095 AgentInstance previousInstance;
00096 if ( previousIndex.isValid() )
00097 previousInstance = previousIndex.data( AgentInstanceModel::InstanceRole ).value<AgentInstance>();
00098
00099 emit mParent->currentChanged( currentInstance, previousInstance );
00100 }
00101
00102 void AgentInstanceWidget::Private::currentAgentInstanceDoubleClicked( const QModelIndex ¤tIndex )
00103 {
00104 AgentInstance currentInstance;
00105 if ( currentIndex.isValid() )
00106 currentInstance = currentIndex.data( AgentInstanceModel::InstanceRole ).value<AgentInstance>();
00107
00108 emit mParent->doubleClicked( currentInstance );
00109 }
00110
00111 AgentInstanceWidget::AgentInstanceWidget( QWidget *parent )
00112 : QWidget( parent ), d( new Private( this ) )
00113 {
00114 QHBoxLayout *layout = new QHBoxLayout( this );
00115 layout->setMargin( 0 );
00116 layout->setSpacing( 0 );
00117
00118 d->mView = new QListView( this );
00119 d->mView->setItemDelegate( new AgentInstanceWidgetDelegate( d->mView ) );
00120 layout->addWidget( d->mView );
00121
00122 d->mModel = new AgentInstanceModel( this );
00123
00124 d->proxy = new AgentFilterProxyModel( this );
00125 d->proxy->setSourceModel( d->mModel );
00126 d->mView->setModel( d->proxy );
00127
00128 d->mView->selectionModel()->setCurrentIndex( d->mView->model()->index( 0, 0 ), QItemSelectionModel::Select );
00129 d->mView->scrollTo( d->mView->model()->index( 0, 0 ) );
00130
00131 connect( d->mView->selectionModel(), SIGNAL( currentChanged( const QModelIndex&, const QModelIndex& ) ),
00132 this, SLOT( currentAgentInstanceChanged( const QModelIndex&, const QModelIndex& ) ) );
00133 connect( d->mView, SIGNAL( doubleClicked( const QModelIndex& ) ),
00134 this, SLOT( currentAgentInstanceDoubleClicked( const QModelIndex& ) ) );
00135 }
00136
00137 AgentInstanceWidget::~AgentInstanceWidget()
00138 {
00139 delete d;
00140 }
00141
00142 AgentInstance AgentInstanceWidget::currentAgentInstance() const
00143 {
00144 QItemSelectionModel *selectionModel = d->mView->selectionModel();
00145 if ( !selectionModel )
00146 return AgentInstance();
00147
00148 QModelIndex index = selectionModel->currentIndex();
00149 if ( !index.isValid() )
00150 return AgentInstance();
00151
00152 return index.data( AgentInstanceModel::InstanceRole ).value<AgentInstance>();
00153 }
00154
00155 AgentFilterProxyModel* AgentInstanceWidget::agentFilterProxyModel() const
00156 {
00157 return d->proxy;
00158 }
00159
00160
00161
00162
00163
00164 AgentInstanceWidgetDelegate::AgentInstanceWidgetDelegate( QObject *parent )
00165 : QAbstractItemDelegate( parent )
00166 {
00167 }
00168
00169 QTextDocument* AgentInstanceWidgetDelegate::document( const QStyleOptionViewItem &option, const QModelIndex &index ) const
00170 {
00171 if ( !index.isValid() )
00172 return 0;
00173
00174 const QString name = index.model()->data( index, Qt::DisplayRole ).toString();
00175 int status = index.model()->data( index, AgentInstanceModel::StatusRole ).toInt();
00176 uint progress = index.model()->data( index, AgentInstanceModel::ProgressRole ).toUInt();
00177 const QString statusMessage = index.model()->data( index, AgentInstanceModel::StatusMessageRole ).toString();
00178 const QStringList capabilities = index.model()->data( index, AgentInstanceModel::CapabilitiesRole ).toStringList();
00179
00180 QTextDocument *document = new QTextDocument( 0 );
00181
00182 const QVariant data = index.model()->data( index, Qt::DecorationRole );
00183 if ( data.isValid() && data.type() == QVariant::Icon ) {
00184 document->addResource( QTextDocument::ImageResource, QUrl( QLatin1String( "agent_icon" ) ),
00185 qvariant_cast<QIcon>( data ).pixmap( QSize( 64, 64 ) ) );
00186 }
00187
00188 if ( status == 0 )
00189 document->addResource( QTextDocument::ImageResource, QUrl( QLatin1String( "status_icon" ) ), s_icons->readyPixmap );
00190 else if ( status == 1 )
00191 document->addResource( QTextDocument::ImageResource, QUrl( QLatin1String( "status_icon" ) ), s_icons->syncPixmap );
00192 else
00193 document->addResource( QTextDocument::ImageResource, QUrl( QLatin1String( "status_icon" ) ), s_icons->errorPixmap );
00194
00195
00196 QPalette::ColorGroup cg = option.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
00197 if ( cg == QPalette::Normal && !(option.state & QStyle::State_Active) )
00198 cg = QPalette::Inactive;
00199
00200 QColor textColor;
00201 if ( option.state & QStyle::State_Selected ) {
00202 textColor = option.palette.color( cg, QPalette::HighlightedText );
00203 } else {
00204 textColor = option.palette.color( cg, QPalette::Text );
00205 }
00206
00207 QString content = QString::fromLatin1(
00208 "<html style=\"color:%1\">"
00209 "<body>"
00210 "<table>"
00211 "<tr>"
00212 "<td rowspan=\"2\"><img src=\"agent_icon\"></td>"
00213 "<td><b>%2</b></td>"
00214 "</tr>" ).arg(textColor.name().toUpper()).arg( name );
00215 if ( capabilities.contains( QLatin1String( "Resource" ) ) ) {
00216 content += QString::fromLatin1(
00217 "<tr>"
00218 "<td><img src=\"status_icon\"/> %1 %2</td>"
00219 "</tr>" ).arg( statusMessage ).arg( status == 1 ? QString( QLatin1String( "(%1%)" ) ).arg( progress ) : QLatin1String( "" ) );
00220 }
00221 content += QLatin1String( "</table></body></html>" );
00222
00223 document->setHtml( content );
00224
00225 return document;
00226 }
00227
00228 void AgentInstanceWidgetDelegate::paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const
00229 {
00230 if ( !index.isValid() )
00231 return;
00232
00233 QTextDocument *doc = document( option, index );
00234 if ( !doc )
00235 return;
00236
00237 painter->setRenderHint( QPainter::Antialiasing );
00238
00239 QPen pen = painter->pen();
00240
00241 QPalette::ColorGroup cg = option.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
00242 if ( cg == QPalette::Normal && !(option.state & QStyle::State_Active) )
00243 cg = QPalette::Inactive;
00244
00245 if ( option.state & QStyle::State_Selected ) {
00246 painter->fillRect( option.rect, option.palette.brush( cg, QPalette::Highlight ) );
00247 painter->setPen( option.palette.color( cg, QPalette::HighlightedText ) );
00248 } else {
00249 painter->setPen(option.palette.color( cg, QPalette::Text ) );
00250 }
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"