korganizer

multiagendaview.cpp

00001 /*
00002     Copyright (c) 2007 Volker Krause <vkrause@kde.org>
00003 
00004     This program is free software; you can redistribute it and/or modify
00005     it under the terms of the GNU General Public License as published by
00006     the Free Software Foundation; either version 2 of the License, or
00007     (at your option) any later version.
00008 
00009     This program is distributed in the hope that it will be useful,
00010     but WITHOUT ANY WARRANTY; without even the implied warranty of
00011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00012     GNU General Public License for more details.
00013 
00014     You should have received a copy of the GNU General Public License
00015     along with this program; if not, write to the Free Software
00016     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017 */
00018 
00019 #include "multiagendaview.h"
00020 
00021 #include "koagendaview.h"
00022 #include "koagenda.h"
00023 #include "koprefs.h"
00024 #include "timelabels.h"
00025 
00026 #include <libkcal/calendarresources.h>
00027 
00028 #include <kglobalsettings.h>
00029 
00030 #include <qlayout.h>
00031 #include <qvbox.h>
00032 #include <qobjectlist.h>
00033 #include <qheader.h>
00034 
00035 #define FOREACH_VIEW(av) \
00036 for(QValueList<KOAgendaView*>::ConstIterator it = mAgendaViews.constBegin(); \
00037   it != mAgendaViews.constEnd();) \
00038   for(KOAgendaView* av = (it != mAgendaViews.constEnd() ? (*it) : 0); \
00039       it != mAgendaViews.constEnd(); ++it, av = (*it)  )
00040 
00041 using namespace KOrg;
00042 
00043 MultiAgendaView::MultiAgendaView( Calendar * cal, CalendarView *calendarView,
00044                                  QWidget * parent, const char *name ) :
00045     AgendaView( cal, parent, name ),
00046     mSelectedAgendaView( 0 ),
00047     mLastMovedSplitter( 0 ),
00048     mUpdateOnShow( false ),
00049     mPendingChanges( true ),
00050     mCalendarView( calendarView )
00051 {
00052   QBoxLayout *topLevelLayout = new QHBoxLayout( this );
00053 
00054   QFontMetrics fm( font() );
00055   int topLabelHeight = 2 * fm.height() + fm.lineSpacing();
00056 
00057   QVBox *topSideBox = new QVBox( this );
00058   mLeftTopSpacer = new QWidget( topSideBox );
00059   mLeftTopSpacer->setFixedHeight( topLabelHeight );
00060   mLeftSplitter = new QSplitter( Qt::Vertical, topSideBox );
00061   mLeftSplitter->setOpaqueResize( KGlobalSettings::opaqueResize() );
00062   QLabel *label = new QLabel( i18n("All Day"), mLeftSplitter );
00063   label->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::WordBreak );
00064   QVBox *sideBox = new QVBox( mLeftSplitter );
00065   EventIndicator *eiSpacer = new EventIndicator( EventIndicator::Top, sideBox );
00066   eiSpacer->changeColumns( 0 );
00067   mTimeLabels = new TimeLabels( 24, sideBox );
00068   eiSpacer = new EventIndicator( EventIndicator::Bottom, sideBox );
00069   eiSpacer->changeColumns( 0 );
00070   mLeftBottomSpacer = new QWidget( topSideBox );
00071   topLevelLayout->addWidget( topSideBox );
00072 
00073   mScrollView = new QScrollView( this );
00074   mScrollView->setResizePolicy( QScrollView::Manual );
00075   mScrollView->setVScrollBarMode( QScrollView::AlwaysOff );
00076   mScrollView->setFrameShape( QFrame::NoFrame );
00077   topLevelLayout->addWidget( mScrollView, 100 );
00078   mTopBox = new QHBox( mScrollView->viewport() );
00079   mScrollView->addChild( mTopBox );
00080 
00081   topSideBox = new QVBox( this );
00082   mRightTopSpacer = new QWidget( topSideBox );
00083   mRightTopSpacer->setFixedHeight( topLabelHeight );
00084   mRightSplitter = new QSplitter( Qt::Vertical, topSideBox );
00085   mRightSplitter->setOpaqueResize( KGlobalSettings::opaqueResize() );
00086   new QWidget( mRightSplitter );
00087   sideBox = new QVBox( mRightSplitter );
00088   eiSpacer = new EventIndicator( EventIndicator::Top, sideBox );
00089   eiSpacer->setFixedHeight( eiSpacer->minimumHeight() );
00090   eiSpacer->changeColumns( 0 );
00091   mScrollBar = new QScrollBar( Qt::Vertical, sideBox );
00092   eiSpacer = new EventIndicator( EventIndicator::Bottom, sideBox );
00093   eiSpacer->setFixedHeight( eiSpacer->minimumHeight() );
00094   eiSpacer->changeColumns( 0 );
00095   mRightBottomSpacer = new QWidget( topSideBox );
00096   topLevelLayout->addWidget( topSideBox );
00097 
00098   recreateViews();
00099 }
00100 
00101 void MultiAgendaView::recreateViews()
00102 {
00103   if ( !mPendingChanges )
00104     return;
00105   mPendingChanges = false;
00106 
00107   deleteViews();
00108 
00109   CalendarResources *calres = dynamic_cast<CalendarResources*>( calendar() );
00110   if ( !calres ) {
00111     // fallback to single-agenda
00112     KOAgendaView* av = new KOAgendaView( calendar(), mCalendarView, mTopBox );
00113     mAgendaViews.append( av );
00114     mAgendaWidgets.append( av );
00115     mSelectedAgendaView = av;
00116     av->show();
00117   } else {
00118     CalendarResourceManager *manager = calres->resourceManager();
00119     for ( CalendarResourceManager::ActiveIterator it = manager->activeBegin(); it != manager->activeEnd(); ++it ) {
00120       if ( (*it)->canHaveSubresources() ) {
00121         QStringList subResources = (*it)->subresources();
00122         for ( QStringList::ConstIterator subit = subResources.constBegin(); subit != subResources.constEnd(); ++subit ) {
00123           QString type = (*it)->subresourceType( *subit );
00124           if ( !(*it)->subresourceActive( *subit ) || (!type.isEmpty() && type != "event") )
00125             continue;
00126           addView( (*it)->labelForSubresource( *subit ), *it, *subit );
00127         }
00128       } else {
00129         addView( (*it)->resourceName(), *it );
00130       }
00131     }
00132   }
00133 
00134   // no resources activated, so stop here to avoid crashing somewhere down the line, TODO: show a nice message instead
00135   if ( mAgendaViews.isEmpty() )
00136     return;
00137 
00138   setupViews();
00139   QTimer::singleShot( 0, this, SLOT(slotResizeScrollView()) );
00140   mTimeLabels->updateConfig();
00141 
00142   connect( mTimeLabels->verticalScrollBar(), SIGNAL(valueChanged(int)),
00143            mScrollBar, SLOT(setValue(int)) );
00144   connect( mScrollBar, SIGNAL(valueChanged(int)),
00145            mTimeLabels, SLOT(positionChanged(int)) );
00146 
00147   installSplitterEventFilter( mLeftSplitter );
00148   installSplitterEventFilter( mRightSplitter );
00149 
00150   QValueList<int> sizes = KOGlobals::self()->config()->readIntListEntry("Separator AgendaView");
00151   if (sizes.count() != 2) {
00152     sizes = mLeftSplitter->sizes();
00153   }
00154   FOREACH_VIEW( agenda ) {
00155     agenda->splitter()->setSizes( sizes );
00156   }
00157   mLeftSplitter->setSizes( sizes );
00158   mRightSplitter->setSizes( sizes );
00159 
00160   QTimer::singleShot( 0, this, SLOT(setupScrollBar()) );
00161 
00162   mTimeLabels->positionChanged();
00163 }
00164 
00165 void MultiAgendaView::deleteViews()
00166 {
00167   for ( QValueList<QWidget*>::ConstIterator it = mAgendaWidgets.constBegin();
00168         it != mAgendaWidgets.constEnd(); ++it ) {
00169     delete *it;
00170   }
00171   mAgendaViews.clear();
00172   mAgendaWidgets.clear();
00173   mLastMovedSplitter = 0;
00174 }
00175 
00176 void MultiAgendaView::setupViews()
00177 {
00178   FOREACH_VIEW( agenda ) {
00179     if ( !agenda->readOnly() ) {
00180       connect( agenda,
00181                SIGNAL(newEventSignal(ResourceCalendar *,const QString &)),
00182                SIGNAL(newEventSignal(ResourceCalendar *,const QString &)) );
00183       connect( agenda,
00184                SIGNAL(newEventSignal(ResourceCalendar *,const QString &,const QDate &)),
00185                SIGNAL(newEventSignal(ResourceCalendar *,const QString &,const QDate &)) );
00186       connect( agenda,
00187                SIGNAL(newEventSignal(ResourceCalendar *,const QString &,const QDateTime &)),
00188                SIGNAL(newEventSignal(ResourceCalendar *,const QString &,const QDateTime &)) );
00189       connect( agenda,
00190                SIGNAL(newEventSignal(ResourceCalendar *,const QString &,const QDateTime &,const QDateTime &)),
00191                SIGNAL(newEventSignal(ResourceCalendar *,const QString &,const QDateTime &,const QDateTime&)) );
00192 
00193       connect( agenda,
00194                SIGNAL(newTodoSignal(ResourceCalendar *,const QString &,const QDate &)),
00195                SIGNAL(newTodoSignal(ResourceCalendar *,const QString &,const QDate &)) );
00196 
00197       connect( agenda,
00198                SIGNAL(editIncidenceSignal(Incidence *,const QDate &)),
00199                SIGNAL(editIncidenceSignal(Incidence *,const QDate &)) );
00200       connect( agenda,
00201                SIGNAL(deleteIncidenceSignal(Incidence *)),
00202                SIGNAL(deleteIncidenceSignal(Incidence *)) );
00203       connect( agenda,
00204                SIGNAL(startMultiModify(const QString &)),
00205                SIGNAL(startMultiModify(const QString &)) );
00206       connect( agenda,
00207                SIGNAL(endMultiModify()),
00208                SIGNAL(endMultiModify()) );
00209 
00210       connect( agenda,
00211                SIGNAL(cutIncidenceSignal(Incidence*)),
00212                SIGNAL(cutIncidenceSignal(Incidence*)) );
00213       connect( agenda,
00214                SIGNAL(pasteIncidenceSignal()),
00215                SIGNAL(pasteIncidenceSignal()) );
00216       connect( agenda,
00217                SIGNAL(toggleAlarmSignal(Incidence*)),
00218                SIGNAL(toggleAlarmSignal(Incidence*)) );
00219       connect( agenda,
00220                SIGNAL(dissociateOccurrenceSignal(Incidence*, const QDate&)),
00221                SIGNAL(dissociateOccurrenceSignal(Incidence*, const QDate&)) );
00222       connect( agenda,
00223                SIGNAL(dissociateFutureOccurrenceSignal(Incidence*, const QDate&)),
00224                SIGNAL(dissociateFutureOccurrenceSignal(Incidence*, const QDate&)) );
00225     }
00226 
00227     connect( agenda,
00228              SIGNAL(copyIncidenceSignal(Incidence*)),
00229              SIGNAL(copyIncidenceSignal(Incidence*)) );
00230     connect( agenda,
00231              SIGNAL(showIncidenceSignal(Incidence *,const QDate &)),
00232              SIGNAL(showIncidenceSignal(Incidence *,const QDate &)) );
00233     connect( agenda,
00234              SIGNAL(incidenceSelected(Incidence *,const QDate &)),
00235              SIGNAL(incidenceSelected(Incidence *,const QDate &)) );
00236     connect( agenda,
00237              SIGNAL(incidenceSelected(Incidence*,const QDate &)),
00238              SLOT(slotSelectionChanged()) );
00239 
00240     connect( agenda,
00241              SIGNAL(timeSpanSelectionChanged()),
00242              SLOT(slotClearTimeSpanSelection()) );
00243 
00244     disconnect( agenda->agenda(),
00245                 SIGNAL(zoomView(const int,const QPoint&,const Qt::Orientation)),
00246                 agenda, 0 );
00247     connect( agenda->agenda(),
00248              SIGNAL(zoomView(const int,const QPoint&,const Qt::Orientation)),
00249              SLOT(zoomView(const int,const QPoint&,const Qt::Orientation)) );
00250   }
00251 
00252   KOAgenda *anAgenda = mAgendaViews.first()->agenda();
00253   connect( anAgenda, SIGNAL(lowerYChanged(int) ), SLOT(resizeSpacers(int)) );
00254 
00255   FOREACH_VIEW( agenda ) {
00256     agenda->readSettings();
00257   }
00258 
00259   int minWidth = 0;
00260   for ( QValueList<QWidget*>::ConstIterator it = mAgendaWidgets.constBegin(); it != mAgendaWidgets.constEnd(); ++it )
00261     minWidth = QMAX( minWidth, (*it)->minimumSizeHint().width() );
00262   for ( QValueList<QWidget*>::ConstIterator it = mAgendaWidgets.constBegin(); it != mAgendaWidgets.constEnd(); ++it )
00263     (*it)->setMinimumWidth( minWidth );
00264 }
00265 
00266 MultiAgendaView::~ MultiAgendaView()
00267 {
00268 }
00269 
00270 Incidence::List MultiAgendaView::selectedIncidences()
00271 {
00272   Incidence::List list;
00273   FOREACH_VIEW(agendaView) {
00274     list += agendaView->selectedIncidences();
00275   }
00276   return list;
00277 }
00278 
00279 DateList MultiAgendaView::selectedIncidenceDates()
00280 {
00281   DateList list;
00282   FOREACH_VIEW(agendaView) {
00283     list += agendaView->selectedIncidenceDates();
00284   }
00285   return list;
00286 }
00287 
00288 int MultiAgendaView::currentDateCount()
00289 {
00290   FOREACH_VIEW( agendaView )
00291     return agendaView->currentDateCount();
00292   return 0;
00293 }
00294 
00295 void MultiAgendaView::showDates(const QDate & start, const QDate & end)
00296 {
00297   mStartDate = start;
00298   mEndDate = end;
00299   recreateViews();
00300   FOREACH_VIEW( agendaView )
00301     agendaView->showDates( start, end );
00302 }
00303 
00304 void MultiAgendaView::showIncidences(const Incidence::List & incidenceList, const QDate &date)
00305 {
00306   FOREACH_VIEW( agendaView )
00307     agendaView->showIncidences( incidenceList, date );
00308 }
00309 
00310 void MultiAgendaView::updateView()
00311 {
00312   recreateViews();
00313   FOREACH_VIEW( agendaView )
00314     agendaView->updateView();
00315 }
00316 
00317 void MultiAgendaView::changeIncidenceDisplay(Incidence * incidence, int mode)
00318 {
00319   FOREACH_VIEW( agendaView )
00320     agendaView->changeIncidenceDisplay( incidence, mode );
00321 }
00322 
00323 int MultiAgendaView::maxDatesHint()
00324 {
00325   FOREACH_VIEW( agendaView )
00326     return agendaView->maxDatesHint();
00327   return 0;
00328 }
00329 
00330 void MultiAgendaView::slotSelectionChanged()
00331 {
00332   FOREACH_VIEW( agenda ) {
00333     if ( agenda != sender() )
00334       agenda->clearSelection();
00335   }
00336 }
00337 
00338 bool MultiAgendaView::eventDurationHint(QDateTime & startDt, QDateTime & endDt, bool & allDay)
00339 {
00340   FOREACH_VIEW( agenda ) {
00341     bool valid = agenda->eventDurationHint( startDt, endDt, allDay );
00342     if ( valid )
00343       return true;
00344   }
00345   return false;
00346 }
00347 
00348 void MultiAgendaView::slotClearTimeSpanSelection()
00349 {
00350   FOREACH_VIEW( agenda ) {
00351     if ( agenda != sender() )
00352       agenda->clearTimeSpanSelection();
00353   }
00354 }
00355 
00356 void MultiAgendaView::setTypeAheadReceiver(QObject * o)
00357 {
00358   FOREACH_VIEW( agenda )
00359     agenda->setTypeAheadReceiver( o );
00360 }
00361 
00362 void MultiAgendaView::finishTypeAhead()
00363 {
00364   FOREACH_VIEW( agenda )
00365     agenda->finishTypeAhead();
00366 }
00367 
00368 void MultiAgendaView::addView( const QString &label, KCal::ResourceCalendar * res, const QString & subRes )
00369 {
00370   bool readOnlyView = false;
00371 
00372   QVBox *box = new QVBox( mTopBox );
00373 
00374   // First, the calendar folder title
00375   QHeader *title = new QHeader( 1, box );
00376   title->setClickEnabled( false );
00377   title->setStretchEnabled( true );
00378   if ( res->readOnly() || !res->subresourceWritable( subRes ) ) {
00379     readOnlyView = true;
00380     title->setLabel( 0, QIconSet( KOGlobals::self()->smallIcon( "readonlyevent" ) ), label );
00381   } else {
00382     QColor resColor;
00383     if ( subRes.isEmpty() ) {
00384       resColor = *KOPrefs::instance()->resourceColor( res->identifier() );
00385     } else {
00386       resColor = *KOPrefs::instance()->resourceColor( subRes );
00387     }
00388     QFontMetrics fm = fontMetrics();
00389     QPixmap px( fm.height(), fm.height() );
00390     px.fill( resColor );
00391     title->setLabel( 0, QIconSet( px, QIconSet::Small ), label );
00392   }
00393 
00394   // Now, the sub agenda view
00395   KOAgendaView* av = new KOAgendaView( calendar(), mCalendarView, box, 0, true );
00396   mSelectedAgendaView = av;
00397   av->setReadOnly( readOnlyView );
00398   av->setResource( res, subRes );
00399   av->setIncidenceChanger( mChanger );
00400   av->agenda()->setVScrollBarMode( QScrollView::AlwaysOff );
00401   mAgendaViews.append( av );
00402   mAgendaWidgets.append( box );
00403   box->show();
00404   mTimeLabels->setAgenda( av->agenda() );
00405 
00406   connect( av->agenda()->verticalScrollBar(), SIGNAL(valueChanged(int)),
00407            mTimeLabels, SLOT(positionChanged(int)) );
00408   connect( mTimeLabels->verticalScrollBar(), SIGNAL(valueChanged(int)),
00409            av, SLOT(setContentsPos(int)) );
00410 
00411   av->installEventFilter( this );
00412   installSplitterEventFilter( av->splitter() );
00413 }
00414 
00415 void MultiAgendaView::resizeEvent(QResizeEvent * ev)
00416 {
00417   resizeScrollView( ev->size() );
00418   AgendaView::resizeEvent( ev );
00419 }
00420 
00421 void MultiAgendaView::resizeScrollView(const QSize & size)
00422 {
00423   const int widgetWidth = size.width() - mTimeLabels->width() - mScrollBar->width();
00424   int width = QMAX( mTopBox->sizeHint().width(), widgetWidth );
00425   int height = size.height();
00426   if ( width > widgetWidth ) {
00427     const int sbHeight = mScrollView->horizontalScrollBar()->height();
00428     height -= sbHeight;
00429     mLeftBottomSpacer->setFixedHeight( sbHeight );
00430     mRightBottomSpacer->setFixedHeight( sbHeight );
00431   } else {
00432     mLeftBottomSpacer->setFixedHeight( 0 );
00433     mRightBottomSpacer->setFixedHeight( 0 );
00434   }
00435   mScrollView->resizeContents( width, height );
00436   mTopBox->resize( width, height );
00437 }
00438 
00439 void MultiAgendaView::setIncidenceChanger(IncidenceChangerBase * changer)
00440 {
00441   AgendaView::setIncidenceChanger( changer );
00442   FOREACH_VIEW( agenda )
00443     agenda->setIncidenceChanger( changer );
00444 }
00445 
00446 void MultiAgendaView::updateConfig()
00447 {
00448   AgendaView::updateConfig();
00449   mTimeLabels->updateConfig();
00450   FOREACH_VIEW( agenda )
00451     agenda->updateConfig();
00452 }
00453 
00454 bool MultiAgendaView::eventFilter(QObject * obj, QEvent * event)
00455 {
00456   if ( obj->className() == QCString("QSplitterHandle") ) {
00457     // KDE4: not needed anymore, QSplitter has a moved signal there
00458     if ( (event->type() == QEvent::MouseMove && KGlobalSettings::opaqueResize())
00459            || event->type() == QEvent::MouseButtonRelease ) {
00460       FOREACH_VIEW( agenda ) {
00461         if ( agenda->splitter() == obj->parent() )
00462           mLastMovedSplitter = agenda->splitter();
00463       }
00464       if ( mLeftSplitter == obj->parent() )
00465         mLastMovedSplitter = mLeftSplitter;
00466       else if ( mRightSplitter == obj->parent() )
00467         mLastMovedSplitter = mRightSplitter;
00468       QTimer::singleShot( 0, this, SLOT(resizeSplitters()) );
00469     }
00470   }
00471 
00472   if ( obj->className() == QCString( "KOAgendaView" ) ) {
00473     if ( event->type() == QEvent::Enter ) {
00474       mSelectedAgendaView = (KOAgendaView *)obj;
00475     }
00476   }
00477 
00478   return AgendaView::eventFilter( obj, event );
00479 }
00480 
00481 void MultiAgendaView::resizeSplitters()
00482 {
00483   if ( !mLastMovedSplitter )
00484     mLastMovedSplitter = mAgendaViews.first()->splitter();
00485   FOREACH_VIEW( agenda ) {
00486     if ( agenda->splitter() == mLastMovedSplitter )
00487       continue;
00488     agenda->splitter()->setSizes( mLastMovedSplitter->sizes() );
00489   }
00490   if ( mLastMovedSplitter != mLeftSplitter )
00491     mLeftSplitter->setSizes( mLastMovedSplitter->sizes() );
00492   if ( mLastMovedSplitter != mRightSplitter )
00493     mRightSplitter->setSizes( mLastMovedSplitter->sizes() );
00494 }
00495 
00496 void MultiAgendaView::resizeSpacers( int newY )
00497 {
00498   // this slot is needed because the Agenda view's day labels frame height
00499   // can change depending if holidays are shown. When this happens, all
00500   // the widgets move down except the timelabels, so we need to change
00501   // the top spacer height accordingly to move the timelabels up/down.
00502   // kolab/issue2656
00503   Q_UNUSED( newY );
00504   QFontMetrics fm( font() );
00505   int topLabelHeight = mAgendaViews.first()->dayLabels()->height() +
00506                        fm.height() + mLeftSplitter->handleWidth();
00507   mLeftTopSpacer->setFixedHeight( topLabelHeight );
00508   mRightTopSpacer->setFixedHeight( topLabelHeight );
00509 }
00510 
00511 void MultiAgendaView::zoomView( const int delta, const QPoint & pos, const Qt::Orientation ori )
00512 {
00513   if ( ori == Qt::Vertical ) {
00514     if ( delta > 0 ) {
00515       if ( KOPrefs::instance()->mHourSize > 4 )
00516         KOPrefs::instance()->mHourSize--;
00517     } else {
00518       KOPrefs::instance()->mHourSize++;
00519     }
00520   }
00521 
00522   FOREACH_VIEW( agenda )
00523     agenda->zoomView( delta, pos, ori );
00524 
00525   mTimeLabels->updateConfig();
00526   mTimeLabels->positionChanged();
00527   mTimeLabels->repaint();
00528 }
00529 
00530 // KDE4: not needed, use existing QSplitter signals instead
00531 void MultiAgendaView::installSplitterEventFilter(QSplitter * splitter)
00532 {
00533   QObjectList *objlist = splitter->queryList( "QSplitterHandle" );
00534   // HACK: when not being visible, the splitter handle is sometimes not found
00535   // for unknown reasons, so trigger an update when we are shown again
00536   if ( objlist->count() == 0 && !isVisible() )
00537     mUpdateOnShow = true;
00538   QObjectListIt it( *objlist );
00539   QObject *obj;
00540   while ( (obj = it.current()) != 0 ) {
00541     obj->removeEventFilter( this );
00542     obj->installEventFilter( this );
00543     ++it;
00544   }
00545   delete objlist;
00546 }
00547 
00548 void MultiAgendaView::slotResizeScrollView()
00549 {
00550   resizeScrollView( size() );
00551 }
00552 
00553 void MultiAgendaView::show()
00554 {
00555   AgendaView::show();
00556   if ( mUpdateOnShow ) {
00557     mUpdateOnShow = false;
00558     mPendingChanges = true; // force a full view recreation
00559     showDates( mStartDate, mEndDate );
00560   }
00561 }
00562 
00563 void MultiAgendaView::resourcesChanged()
00564 {
00565   mPendingChanges = true;
00566   FOREACH_VIEW( agenda )
00567     agenda->resourcesChanged();
00568 }
00569 
00570 void MultiAgendaView::setupScrollBar()
00571 {
00572   QScrollBar *scrollBar = mAgendaViews.first()->agenda()->verticalScrollBar();
00573   mScrollBar->setMinValue( scrollBar->minValue() );
00574   mScrollBar->setMaxValue( scrollBar->maxValue() );
00575   mScrollBar->setLineStep( scrollBar->lineStep() );
00576   mScrollBar->setPageStep( scrollBar->pageStep() );
00577   mScrollBar->setValue( scrollBar->value() );
00578 }
00579 
00580 #include "multiagendaview.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys