korganizer Library API Documentation

resourceview.cpp

00001 /*
00002     This file is part of KOrganizer.
00003 
00004     Copyright (c) 2003,2004 Cornelius Schumacher <schumacher@kde.org>
00005 
00006     This program is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation; either version 2 of the License, or
00009     (at your option) any later version.
00010 
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00014     GNU General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this program; if not, write to the Free Software
00018     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00019 
00020     As a special exception, permission is given to link this program
00021     with any edition of Qt, and distribute the resulting executable,
00022     without including the source code for Qt in the source distribution.
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     // This resource has subresources
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 /*  QColorGroup _cg = cg;
00198   if(!mResource) return;
00199   _cg.setColor(QColorGroup::Base, getTextColor(mResourceColor));*/
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   // Create new resource
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 // FIXME proko2: merge once we are back in HEAD by porting imap resource
00353 void ResourceView::slotSubresourceAdded( ResourceCalendar *calendar,
00354                                          const QString& type,
00355                                          const QString& resource )
00356 {
00357    slotSubresourceAdded( calendar, type, resource, resource );
00358 }
00359 
00360 // Add a new entry
00361 void ResourceView::slotSubresourceAdded( ResourceCalendar *calendar,
00362                                          const QString& /*type*/,
00363                                          const QString& resource,
00364                                          const QString& label)
00365 {
00366   QListViewItem *i = mListView->findItem( calendar->resourceName(), 0 );
00367   if ( !i )
00368     // Not found
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 // Remove an entry
00380 void ResourceView::slotSubresourceRemoved( ResourceCalendar */*calendar*/,
00381                                            const QString &/*type*/,
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 // Don't be so restricitve
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     //FIXME: This is better on the resource dialog
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   // A color without initialized is a color invalid
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"
KDE Logo
This file is part of the documentation for korganizer Library Version 3.3.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Aug 23 18:22:15 2007 by doxygen 1.4.2 written by Dimitri van Heesch, © 1997-2003