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