00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "resourceview.h"
00026
00027 #include <kcolordialog.h>
00028 #include <kdialog.h>
00029 #include <klistview.h>
00030 #include <klocale.h>
00031 #include <kdebug.h>
00032 #include <kglobal.h>
00033 #include <kmessagebox.h>
00034 #include <kresources/resource.h>
00035 #include <kresources/configdialog.h>
00036 #include <kinputdialog.h>
00037 #include <libkcal/calendarresources.h>
00038 #include <resourceremote.h>
00039
00040 #include <qhbox.h>
00041 #include <qlayout.h>
00042 #include <qlabel.h>
00043 #include <qpushbutton.h>
00044 #include <qpopupmenu.h>
00045 #include <qpainter.h>
00046
00047 #include "koprefs.h"
00048
00049 using namespace KCal;
00050
00051 ResourceViewFactory::ResourceViewFactory( KCal::CalendarResources *calendar,
00052 CalendarView *view )
00053 : mCalendar( calendar ), mView( view ), mResourceView( 0 )
00054 {
00055 }
00056
00057 CalendarViewExtension *ResourceViewFactory::create( QWidget *parent )
00058 {
00059 mResourceView = new ResourceView( mCalendar, parent );
00060
00061 QObject::connect( mResourceView, SIGNAL( resourcesChanged() ),
00062 mView, SLOT( updateView() ) );
00063 QObject::connect( mResourceView, SIGNAL( resourcesChanged() ),
00064 mView, SLOT( updateCategories() ) );
00065
00066 QObject::connect( mCalendar,
00067 SIGNAL( signalResourceAdded( ResourceCalendar * ) ),
00068 mResourceView,
00069 SLOT( addResourceItem( ResourceCalendar * ) ) );
00070 QObject::connect( mCalendar,
00071 SIGNAL( signalResourceModified( ResourceCalendar * ) ),
00072 mResourceView,
00073 SLOT( updateResourceItem( ResourceCalendar * ) ) );
00074 QObject::connect( mCalendar, SIGNAL( signalResourceAdded( ResourceCalendar * ) ),
00075 mView, SLOT( updateCategories() ) );
00076 QObject::connect( mCalendar, SIGNAL( signalResourceModified( ResourceCalendar * ) ),
00077 mView, SLOT( updateCategories() ) );
00078
00079 return mResourceView;
00080 }
00081
00082 ResourceView *ResourceViewFactory::resourceView() const
00083 {
00084 return mResourceView;
00085 }
00086
00087 ResourceItem::ResourceItem( ResourceCalendar *resource, ResourceView *view,
00088 KListView *parent )
00089 : QCheckListItem( parent, resource->resourceName(), CheckBox ),
00090 mResource( resource ), mView( view ), mBlockStateChange( false ),
00091 mIsSubresource( false ), mResourceIdentifier(),
00092 mSubItemsCreated( false )
00093 {
00094 mResourceColor = QColor();
00095 setGuiState();
00096
00097 if ( mResource->isActive() ) {
00098 createSubresourceItems();
00099 }
00100 }
00101
00102 void ResourceItem::createSubresourceItems() {
00103 const QStringList subresources = mResource->subresources();
00104 if ( !subresources.isEmpty() ) {
00105 setOpen( true );
00106 setExpandable( true );
00107
00108 QStringList::ConstIterator it;
00109 for ( it=subresources.begin(); it!=subresources.end(); ++it ) {
00110 ResourceItem *item = new ResourceItem( mResource, *it, mResource->labelForSubresource( *it ),
00111 mView, this );
00112 QColor resourceColor = *KOPrefs::instance()->resourceColor( *it );
00113 item->setResourceColor( resourceColor );
00114 item->update();
00115 }
00116 }
00117 mSubItemsCreated = true;
00118 }
00119
00120 ResourceItem::ResourceItem( KCal::ResourceCalendar *resource,
00121 const QString& sub, const QString& label,
00122 ResourceView *view, ResourceItem* parent )
00123
00124 : QCheckListItem( parent, label, CheckBox ), mResource( resource ),
00125 mView( view ), mBlockStateChange( false ), mIsSubresource( true ),
00126 mSubItemsCreated( false )
00127 {
00128 mResourceColor = QColor();
00129 mResourceIdentifier = sub;
00130 setGuiState();
00131 }
00132
00133 void ResourceItem::setGuiState()
00134 {
00135 mBlockStateChange = true;
00136 if ( mIsSubresource )
00137 setOn( mResource->subresourceActive( mResourceIdentifier ) );
00138 else
00139 setOn( mResource->isActive() );
00140 mBlockStateChange = false;
00141 }
00142
00143 void ResourceItem::stateChange( bool active )
00144 {
00145 if ( mBlockStateChange ) return;
00146
00147 if ( mIsSubresource ) {
00148 mResource->setSubresourceActive( mResourceIdentifier, active );
00149 } else {
00150 if ( active ) {
00151 if ( mResource->load() ) {
00152 mResource->setActive( true );
00153 if ( !mSubItemsCreated )
00154 createSubresourceItems();
00155 }
00156 } else {
00157 if ( mResource->save() ) mResource->setActive( false );
00158 mView->requestClose( mResource );
00159 }
00160
00161 setOpen( mResource->isActive() && childCount() > 0 );
00162
00163 setGuiState();
00164 }
00165
00166 mView->emitResourcesChanged();
00167 }
00168
00169 void ResourceItem::update()
00170 {
00171 setGuiState();
00172 }
00173
00174 void ResourceItem::setResourceColor(QColor& color)
00175 {
00176 if ( color.isValid() ) {
00177 if ( mResourceColor != color ) {
00178 QPixmap px(height()-4,height()-4);
00179 mResourceColor = color;
00180 px.fill(color);
00181 setPixmap(0,px);
00182 }
00183 } else {
00184 mResourceColor = color ;
00185 setPixmap(0,0);
00186 }
00187 }
00188
00189 void ResourceItem::paintCell(QPainter *p, const QColorGroup &cg,
00190 int column, int width, int alignment)
00191 {
00192 QFont oldFont = p->font();
00193 QFont newFont = oldFont;
00194 p->setFont( newFont );
00195 QCheckListItem::paintCell( p, cg, column, width, alignment );
00196 p->setFont( oldFont );
00197
00198
00199
00200 }
00201
00202
00203
00204 ResourceView::ResourceView( KCal::CalendarResources *calendar,
00205 QWidget *parent, const char *name )
00206 : CalendarViewExtension( parent, name ), mCalendar( calendar )
00207 {
00208 QBoxLayout *topLayout = new QVBoxLayout( this );
00209
00210 mListView = new KListView( this );
00211 mListView->addColumn( i18n("Calendar") );
00212 mListView->setResizeMode( QListView::LastColumn );
00213 topLayout->addWidget( mListView );
00214
00215 QHBox *buttonBox = new QHBox( this );
00216 topLayout->addWidget( buttonBox );
00217
00218 mAddButton = new QPushButton( i18n("Add..."), buttonBox, "add" );
00219 mEditButton = new QPushButton( i18n("Edit..."), buttonBox, "edit" );
00220 mDeleteButton = new QPushButton( i18n("Remove"), buttonBox, "del" );
00221 mEditButton->setDisabled( true );
00222
00223 connect( mListView, SIGNAL( clicked( QListViewItem * ) ),
00224 SLOT( currentChanged( QListViewItem * ) ) );
00225 connect( mAddButton, SIGNAL( clicked() ), SLOT( addResource() ) );
00226 connect( mDeleteButton, SIGNAL( clicked() ), SLOT( removeResource() ) );
00227 connect( mEditButton, SIGNAL( clicked() ), SLOT( editResource() ) );
00228 connect( mListView, SIGNAL( doubleClicked ( QListViewItem *, const QPoint &,
00229 int ) ),
00230 SLOT( editResource() ) );
00231 connect( mListView, SIGNAL( contextMenuRequested ( QListViewItem *,
00232 const QPoint &, int ) ),
00233 SLOT( contextMenuRequested( QListViewItem *, const QPoint &,
00234 int ) ) );
00235 updateView();
00236 }
00237
00238 ResourceView::~ResourceView()
00239 {
00240 }
00241
00242 void ResourceView::updateView()
00243 {
00244 mListView->clear();
00245
00246 KCal::CalendarResourceManager *manager = mCalendar->resourceManager();
00247
00248 KCal::CalendarResourceManager::Iterator it;
00249 for( it = manager->begin(); it != manager->end(); ++it ) {
00250 addResourceItem( *it );
00251 }
00252 }
00253
00254 void ResourceView::emitResourcesChanged()
00255 {
00256 emit resourcesChanged();
00257 }
00258
00259 void ResourceView::addResource()
00260 {
00261 bool ok = false;
00262 KCal::CalendarResourceManager *manager = mCalendar->resourceManager();
00263 ResourceItem *i = static_cast<ResourceItem*>( mListView->selectedItem() );
00264 if ( i && ( i->isSubresource() || i->resource()->canHaveSubresources() ) ) {
00265 const QString folderName = KInputDialog::getText( i18n( "Add Subresource" ),
00266 i18n( "Please enter a name for the new subresource" ), QString::null,
00267 &ok, this );
00268 if ( !ok )
00269 return;
00270 const QString parentId = i->isSubresource() ? i->resourceIdentifier() : QString:: null;
00271 if ( !i->resource()->addSubresource( folderName, parentId ) ) {
00272 KMessageBox::error( this, i18n("<qt>Unable to create subresource <b>%1</b>.</qt>")
00273 .arg( folderName ) );
00274 }
00275 return;
00276 }
00277
00278 QStringList types = manager->resourceTypeNames();
00279 QStringList descs = manager->resourceTypeDescriptions();
00280 QString desc = KInputDialog::getItem( i18n( "Resource Configuration" ),
00281 i18n( "Please select type of the new resource:" ), descs, 0, false, &ok,
00282 this );
00283 if ( !ok )
00284 return;
00285
00286 QString type = types[ descs.findIndex( desc ) ];
00287
00288
00289 ResourceCalendar *resource = manager->createResource( type );
00290 if( !resource ) {
00291 KMessageBox::error( this, i18n("<qt>Unable to create resource of type <b>%1</b>.</qt>")
00292 .arg( type ) );
00293 return;
00294 }
00295
00296 resource->setResourceName( i18n("%1 resource").arg( type ) );
00297
00298 KRES::ConfigDialog dlg( this, QString("calendar"), resource,
00299 "KRES::ConfigDialog" );
00300
00301 if ( dlg.exec() ) {
00302 resource->setTimeZoneId( KOPrefs::instance()->mTimeZoneId );
00303 if ( resource->isActive() ) {
00304 resource->open();
00305 resource->load();
00306 }
00307 manager->add( resource );
00308 addResourceItem( resource );
00309 } else {
00310 delete resource;
00311 resource = 0;
00312 }
00313 }
00314
00315 void ResourceView::addResourceItem( ResourceCalendar *resource )
00316 {
00317
00318 ResourceItem *item=new ResourceItem( resource, this, mListView );
00319
00320 QColor resourceColor;
00321
00322 resourceColor= *KOPrefs::instance()->resourceColor(resource->identifier());
00323 item->setResourceColor(resourceColor);
00324 item->update();
00325
00326 connect( resource, SIGNAL( signalSubresourceAdded( ResourceCalendar *,
00327 const QString &,
00328 const QString &,
00329 const QString & ) ),
00330 SLOT( slotSubresourceAdded( ResourceCalendar *, const QString &,
00331 const QString &, const QString & ) ) );
00332
00333 connect( resource, SIGNAL( signalSubresourceAdded( ResourceCalendar *,
00334 const QString &,
00335 const QString & ) ),
00336 SLOT( slotSubresourceAdded( ResourceCalendar *, const QString &,
00337 const QString & ) ) );
00338
00339 connect( resource, SIGNAL( signalSubresourceRemoved( ResourceCalendar *,
00340 const QString &,
00341 const QString & ) ),
00342 SLOT( slotSubresourceRemoved( ResourceCalendar *, const QString &,
00343 const QString & ) ) );
00344
00345 connect( resource, SIGNAL( resourceSaved( ResourceCalendar * ) ),
00346 SLOT( closeResource( ResourceCalendar * ) ) );
00347
00348 emitResourcesChanged();
00349 }
00350
00351
00352
00353 void ResourceView::slotSubresourceAdded( ResourceCalendar *calendar,
00354 const QString& type,
00355 const QString& resource )
00356 {
00357 slotSubresourceAdded( calendar, type, resource, resource );
00358 }
00359
00360
00361 void ResourceView::slotSubresourceAdded( ResourceCalendar *calendar,
00362 const QString& ,
00363 const QString& resource,
00364 const QString& label)
00365 {
00366 QListViewItem *i = mListView->findItem( calendar->resourceName(), 0 );
00367 if ( !i )
00368
00369 return;
00370
00371 if ( findItemByIdentifier( resource ) ) return;
00372
00373 ResourceItem *item = static_cast<ResourceItem *>( i );
00374 ResourceItem *newItem = new ResourceItem( calendar, resource, label, this, item );
00375 QColor resourceColor = *KOPrefs::instance()->resourceColor( resource );
00376 newItem->setResourceColor( resourceColor );
00377 }
00378
00379
00380 void ResourceView::slotSubresourceRemoved( ResourceCalendar *,
00381 const QString &,
00382 const QString &resource )
00383 {
00384 delete findItemByIdentifier( resource );
00385 emitResourcesChanged();
00386 }
00387
00388 void ResourceView::closeResource( ResourceCalendar *r )
00389 {
00390 if ( mResourcesToClose.find( r ) >= 0 ) {
00391 r->close();
00392 mResourcesToClose.remove( r );
00393 }
00394 }
00395
00396 void ResourceView::updateResourceItem( ResourceCalendar *resource )
00397 {
00398 ResourceItem *item = findItem( resource );
00399 if ( item ) {
00400 item->update();
00401 }
00402 }
00403
00404 ResourceItem *ResourceView::currentItem()
00405 {
00406 QListViewItem *item = mListView->currentItem();
00407 ResourceItem *rItem = static_cast<ResourceItem *>( item );
00408 return rItem;
00409 }
00410
00411 void ResourceView::removeResource()
00412 {
00413 ResourceItem *item = currentItem();
00414 if ( !item ) return;
00415
00416 const QString warningMsg = item->isSubresource() ?
00417 i18n("<qt>Do you really want to remove the subresource <b>%1</b>? "
00418 "Note that its contents will be completely deleted. This "
00419 "operation cannot be undone. </qt>").arg( item->text( 0 ) ) :
00420 i18n("<qt>Do you really want to remove the resource <b>%1</b>?</qt>").arg( item->text( 0 ) );
00421
00422 int km = KMessageBox::warningContinueCancel( this, warningMsg, "",
00423 KGuiItem( i18n("&Remove" ), "editdelete") );
00424 if ( km == KMessageBox::Cancel ) return;
00425
00426
00427 #if 0
00428 if ( item->resource() == mCalendar->resourceManager()->standardResource() ) {
00429 KMessageBox::sorry( this,
00430 i18n( "You cannot remove your standard resource." ) );
00431 return;
00432 }
00433 #endif
00434 if ( item->isSubresource() ) {
00435 if ( !item->resource()->removeSubresource( item->resourceIdentifier() ) )
00436 KMessageBox::sorry( this,
00437 i18n ("<qt>Failed to remove the subresource <b>%1</b>. The "
00438 "reason could be that it is a built-in one which cannot "
00439 "be removed, or that the removal of the underlying storage "
00440 "folder failed.</qt>").arg( item->resource()->name() ) );
00441 return;
00442 } else {
00443 mCalendar->resourceManager()->remove( item->resource() );
00444 }
00445 mListView->takeItem( item );
00446 delete item;
00447 emitResourcesChanged();
00448 }
00449
00450 void ResourceView::editResource()
00451 {
00452 ResourceItem *item = currentItem();
00453
00454 ResourceCalendar *resource = item->resource();
00455
00456 KRES::ConfigDialog dlg( this, QString("calendar"), resource,
00457 "KRES::ConfigDialog" );
00458
00459 if ( dlg.exec() ) {
00460 item->setText( 0, resource->resourceName() );
00461
00462 mCalendar->resourceManager()->change( resource );
00463 }
00464 }
00465
00466 void ResourceView::currentChanged( QListViewItem *item)
00467 {
00468 ResourceItem *i = currentItem();
00469 if ( !item || i->isSubresource() ) {
00470 mEditButton->setEnabled( false );
00471 } else {
00472 mEditButton->setEnabled( true );
00473 }
00474 }
00475
00476 ResourceItem *ResourceView::findItem( ResourceCalendar *r )
00477 {
00478 QListViewItem *item;
00479 ResourceItem *i = 0;
00480 for( item = mListView->firstChild(); item; item = item->nextSibling() ) {
00481 i = static_cast<ResourceItem *>( item );
00482 if ( i->resource() == r ) break;
00483 }
00484 return i;
00485 }
00486
00487 ResourceItem *ResourceView::findItemByIdentifier( const QString& id )
00488 {
00489 QListViewItem *item;
00490 ResourceItem *i = 0;
00491 for( item = mListView->firstChild(); item; item = item->itemBelow() ) {
00492 i = static_cast<ResourceItem *>( item );
00493 if ( i->resourceIdentifier() == id )
00494 return i;
00495 }
00496 return 0;
00497 }
00498
00499
00500 void ResourceView::contextMenuRequested ( QListViewItem *i,
00501 const QPoint &pos, int )
00502 {
00503 ResourceItem *item = static_cast<ResourceItem *>( i );
00504
00505 QPopupMenu *menu = new QPopupMenu( this );
00506 connect( menu, SIGNAL( aboutToHide() ), menu, SLOT( deleteLater() ) );
00507 if ( item ) {
00508 int reloadId = menu->insertItem( i18n("Reload"), this,
00509 SLOT( reloadResource() ) );
00510 menu->setItemEnabled( reloadId, item->resource()->isActive() );
00511 int saveId = menu->insertItem( i18n("Save"), this,
00512 SLOT( saveResource() ) );
00513 menu->setItemEnabled( saveId, item->resource()->isActive() );
00514 menu->insertSeparator();
00515
00516 menu->insertItem( i18n("Show &Info"), this, SLOT( showInfo() ) );
00517
00518 if ( KOPrefs::instance()->agendaViewUsesResourceColor() ) {
00519 QPopupMenu *assignMenu= new QPopupMenu( menu );
00520 assignMenu->insertItem( i18n( "&Assign Color" ), this, SLOT( assignColor() ) );
00521 if ( item->resourceColor().isValid() )
00522 assignMenu->insertItem( i18n( "&Disable Color" ), this, SLOT( disableColor() ) );
00523 menu->insertItem( i18n( "Resources Colors" ), assignMenu );
00524 }
00525
00526 menu->insertItem( i18n("&Edit..."), this, SLOT( editResource() ) );
00527 menu->insertItem( i18n("&Remove"), this, SLOT( removeResource() ) );
00528
00529 menu->insertSeparator();
00530 }
00531 menu->insertItem( i18n("Add..."), this, SLOT( addResource() ) );
00532
00533 menu->popup( pos );
00534 }
00535
00536 void ResourceView::assignColor()
00537 {
00538 ResourceItem *item = currentItem();
00539 if ( !item )
00540 return;
00541
00542 QColor myColor;
00543 KCal::ResourceCalendar *cal = item->resource();
00544
00545 QString identifier = cal->identifier();
00546 if ( item->isSubresource() )
00547 identifier = item->resourceIdentifier();
00548
00549 QColor defaultColor =*KOPrefs::instance()->resourceColor( identifier );
00550
00551 int result = KColorDialog::getColor( myColor,defaultColor);
00552
00553 if ( result == KColorDialog::Accepted ) {
00554 KOPrefs::instance()->setResourceColor( identifier, myColor );
00555 item->setResourceColor( myColor );
00556 item->update();
00557 emitResourcesChanged();
00558 }
00559 }
00560
00561 void ResourceView::disableColor()
00562 {
00563 ResourceItem *item = currentItem();
00564 if ( !item )
00565 return;
00566 QColor colorInvalid;
00567 KCal::ResourceCalendar *cal = item->resource();
00568 QString identifier = cal->identifier();
00569 if ( item->isSubresource() )
00570 identifier = item->resourceIdentifier();
00571 KOPrefs::instance()->setResourceColor( identifier, colorInvalid );
00572 item->setResourceColor( colorInvalid );
00573 item->update();
00574 emitResourcesChanged();
00575 }
00576 void ResourceView::showInfo()
00577 {
00578 ResourceItem *item = currentItem();
00579 if ( !item ) return;
00580
00581 QString txt = "<qt>" + item->resource()->infoText() + "</qt>";
00582 KMessageBox::information( this, txt );
00583 }
00584
00585 void ResourceView::reloadResource()
00586 {
00587 ResourceItem *item = currentItem();
00588 if ( !item ) return;
00589
00590 ResourceCalendar *r = item->resource();
00591 r->load();
00592 }
00593
00594 void ResourceView::saveResource()
00595 {
00596 ResourceItem *item = currentItem();
00597 if ( !item ) return;
00598
00599 ResourceCalendar *r = item->resource();
00600 r->save();
00601 }
00602
00603 void ResourceView::showButtons( bool visible )
00604 {
00605 if ( visible ) {
00606 mAddButton->show();
00607 mDeleteButton->show();
00608 mEditButton->show();
00609 } else {
00610 mAddButton->hide();
00611 mDeleteButton->hide();
00612 mEditButton->hide();
00613 }
00614 }
00615
00616 void ResourceView::requestClose( ResourceCalendar *r )
00617 {
00618 mResourcesToClose.append( r );
00619 }
00620
00621 #include "resourceview.moc"