30 #ifndef KORG_NOSPLITTER
31 #include <tqsplitter.h>
34 #include <tqfontmetrics.h>
35 #include <tqpopupmenu.h>
36 #include <tqtooltip.h>
37 #include <tqpainter.h>
38 #include <tqpushbutton.h>
40 #include <tqbitarray.h>
42 #include <tdeapplication.h>
44 #include <tdestandarddirs.h>
45 #include <kiconloader.h>
46 #include <tdelocale.h>
47 #include <tdeconfig.h>
48 #include <tdeglobal.h>
49 #include <tdeglobalsettings.h>
50 #include <kholidays.h>
53 #include <libkcal/icaldrag.h>
54 #include <libkcal/dndfactory.h>
55 #include <libkcal/calfilter.h>
57 #include <kcalendarsystem.h>
59 #include "koglobals.h"
60 #ifndef KORG_NOPLUGINS
65 #include "koagendaitem.h"
66 #include "timelabels.h"
68 #include "koincidencetooltip.h"
69 #include "kogroupware.h"
70 #include "kodialogmanager.h"
71 #include "koeventpopupmenu.h"
73 #include "koagendaview.h"
74 #include "koagendaview.moc"
79 EventIndicator::EventIndicator(Location loc,TQWidget *parent,
const char *name)
80 : TQFrame(parent,name)
83 mEnabled.resize( mColumns );
86 if (mLocation == Top) mPixmap = KOGlobals::self()->smallIcon(
"upindicator");
87 else mPixmap = KOGlobals::self()->smallIcon(
"downindicator");
89 setMinimumHeight(mPixmap.height());
92 EventIndicator::~EventIndicator()
96 void EventIndicator::drawContents(TQPainter *p)
103 for(i=0;i<mColumns;++i) {
105 int cellWidth = contentsRect().right()/mColumns;
106 int xOffset = KOGlobals::self()->reverseLayout() ?
107 (mColumns - 1 - i)*cellWidth + cellWidth/2 -mPixmap.width()/2 :
108 i*cellWidth + cellWidth/2 -mPixmap.width()/2;
109 p->drawPixmap(TQPoint(xOffset,0),mPixmap);
114 void EventIndicator::changeColumns(
int columns)
117 mEnabled.resize(mColumns);
122 void EventIndicator::enableColumn(
int column,
bool enable)
124 mEnabled[column] = enable;
128 #include <libkcal/incidence.h>
135 KOAlternateLabel::KOAlternateLabel(
const TQString &shortlabel,
const TQString &longlabel,
136 const TQString &extensivelabel, TQWidget *parent,
const char *name )
137 : TQLabel(parent, name), mTextTypeFixed(false), mShortText(shortlabel),
138 mLongText(longlabel), mExtensiveText(extensivelabel)
140 setSizePolicy(TQSizePolicy( TQSizePolicy::Expanding, TQSizePolicy::Fixed ));
141 if (mExtensiveText.isEmpty()) mExtensiveText = mLongText;
142 squeezeTextToLabel();
145 KOAlternateLabel::~KOAlternateLabel()
149 void KOAlternateLabel::useShortText()
151 mTextTypeFixed =
true;
152 TQLabel::setText( mShortText );
153 TQToolTip::remove(
this );
154 TQToolTip::add(
this, mExtensiveText );
158 void KOAlternateLabel::useLongText()
160 mTextTypeFixed =
true;
161 TQLabel::setText( mLongText );
162 TQToolTip::remove(
this );
163 TQToolTip::add(
this, mExtensiveText );
167 void KOAlternateLabel::useExtensiveText()
169 mTextTypeFixed =
true;
170 TQLabel::setText( mExtensiveText );
171 TQToolTip::remove(
this );
172 TQToolTip::add(
this,
"" );
176 void KOAlternateLabel::useDefaultText()
178 mTextTypeFixed =
false;
179 squeezeTextToLabel();
182 KOAlternateLabel::TextType KOAlternateLabel::largestFittingTextType()
const
184 TQFontMetrics fm( fontMetrics() );
185 const int labelWidth = size().width();
186 const int longTextWidth = fm.width( mLongText );
187 const int extensiveTextWidth = fm.width( mExtensiveText );
188 if ( extensiveTextWidth <= labelWidth )
190 else if ( longTextWidth <= labelWidth )
196 void KOAlternateLabel::setFixedType( TextType type )
200 case Extensive: useExtensiveText();
break;
201 case Long: useLongText();
break;
202 case Short: useShortText();
break;
206 void KOAlternateLabel::squeezeTextToLabel()
208 if ( mTextTypeFixed )
211 const TextType type = largestFittingTextType();
215 TQLabel::setText( mExtensiveText );
216 TQToolTip::remove(
this );
217 TQToolTip::add(
this,
"" );
220 TQLabel::setText( mLongText );
221 TQToolTip::remove(
this );
222 TQToolTip::add(
this, mExtensiveText );
225 TQLabel::setText( mShortText );
226 TQToolTip::remove(
this );
227 TQToolTip::add(
this, mExtensiveText );
233 void KOAlternateLabel::resizeEvent( TQResizeEvent * )
235 squeezeTextToLabel();
238 TQSize KOAlternateLabel::minimumSizeHint()
const
240 TQSize sh = TQLabel::minimumSizeHint();
249 KOAgendaView::KOAgendaView(
Calendar *cal,
253 bool isSideBySide ) :
254 KOrg::
AgendaView (cal, parent,name), mExpandButton( 0 ),
255 mAllowAgendaUpdate( true ),
257 mIsSideBySide( isSideBySide ),
258 mPendingChanges( true ),
259 mAreDatesInitialized( false )
261 mSelectedDates.append(TQDate::currentDate());
263 mLayoutDayLabels = 0;
267 bool isRTL = KOGlobals::self()->reverseLayout();
269 if ( KOPrefs::instance()->compactDialogs() ) {
270 if ( KOPrefs::instance()->mVerticalScreen ) {
271 mExpandedPixmap = KOGlobals::self()->smallIcon(
"1downarrow" );
272 mNotExpandedPixmap = KOGlobals::self()->smallIcon(
"1uparrow" );
274 mExpandedPixmap = KOGlobals::self()->smallIcon( isRTL ?
"1leftarrow" :
"1rightarrow" );
275 mNotExpandedPixmap = KOGlobals::self()->smallIcon( isRTL ?
"1rightarrow" :
"1leftarrow" );
279 TQBoxLayout *topLayout =
new TQVBoxLayout(
this);
282 mDayLabelsFrame =
new TQHBox(
this);
283 topLayout->addWidget(mDayLabelsFrame);
286 #ifndef KORG_NOSPLITTER
287 mSplitterAgenda =
new TQSplitter(TQt::Vertical,
this);
288 topLayout->addWidget(mSplitterAgenda);
290 mSplitterAgenda->setOpaqueResize( TDEGlobalSettings::opaqueResize() );
292 mAllDayFrame =
new TQHBox(mSplitterAgenda);
294 TQWidget *agendaFrame =
new TQWidget(mSplitterAgenda);
296 TQVBox *mainBox =
new TQVBox(
this );
297 topLayout->addWidget( mainBox );
299 mAllDayFrame =
new TQHBox(mainBox);
301 TQWidget *agendaFrame =
new TQWidget(mainBox);
305 mDummyAllDayLeft =
new TQVBox( mAllDayFrame );
307 mDummyAllDayLeft->hide();
309 if ( KOPrefs::instance()->compactDialogs() ) {
310 mExpandButton =
new TQPushButton(mDummyAllDayLeft);
311 mExpandButton->setPixmap( mNotExpandedPixmap );
312 mExpandButton->setSizePolicy( TQSizePolicy( TQSizePolicy::Fixed,
313 TQSizePolicy::Fixed ) );
314 connect( mExpandButton, TQ_SIGNAL( clicked() ), TQ_SIGNAL( toggleExpand() ) );
316 TQLabel *label =
new TQLabel( i18n(
"All Day"), mDummyAllDayLeft );
317 label->setAlignment( TQt::AlignRight | TQt::AlignVCenter | TQt::WordBreak );
320 mAllDayAgenda =
new KOAgenda( 1, calendarView, mAllDayFrame );
321 mAllDayAgenda->setCalendar( calendar() );
322 TQWidget *dummyAllDayRight =
new TQWidget(mAllDayFrame);
325 TQGridLayout *agendaLayout =
new TQGridLayout(agendaFrame,3,3);
329 mEventIndicatorTop =
new EventIndicator(EventIndicator::Top,agendaFrame);
330 agendaLayout->addWidget(mEventIndicatorTop,0,1);
331 mEventIndicatorBottom =
new EventIndicator(EventIndicator::Bottom,
333 agendaLayout->addWidget(mEventIndicatorBottom,2,1);
334 TQWidget *dummyAgendaRight =
new TQWidget(agendaFrame);
335 agendaLayout->addWidget(dummyAgendaRight,0,2);
338 mTimeLabels =
new TimeLabels(24,agendaFrame);
339 agendaLayout->addWidget(mTimeLabels,1,0);
342 mAgenda =
new KOAgenda( 1, 96, KOPrefs::instance()->mHourSize, calendarView, agendaFrame );
343 mAgenda->setCalendar( calendar() );
344 agendaLayout->addMultiCellWidget(mAgenda,1,1,1,2);
345 agendaLayout->setColStretch(1,1);
348 mAgendaPopup = eventPopup();
351 mAllDayAgendaPopup = eventPopup();
354 mTimeLabels->setAgenda(mAgenda);
361 createDayLabels(
true );
363 if ( !isSideBySide ) {
365 dummyAllDayRight->setFixedWidth(mAgenda->verticalScrollBar()->width());
366 dummyAgendaRight->setFixedWidth(mAgenda->verticalScrollBar()->width());
369 updateTimeBarWidth();
372 connect(mAgenda->verticalScrollBar(),TQ_SIGNAL(valueChanged(
int)),
373 mTimeLabels, TQ_SLOT(positionChanged()));
376 TQ_SIGNAL( zoomView(
const int,
const TQPoint & ,
const TQt::Orientation ) ),
377 TQ_SLOT( zoomView(
const int,
const TQPoint &,
const TQt::Orientation ) ) );
379 connect(mTimeLabels->verticalScrollBar(),TQ_SIGNAL(valueChanged(
int)),
380 TQ_SLOT(setContentsPos(
int)));
383 connect( mAgenda, TQ_SIGNAL(newTimeSpanSignal(
const TQPoint &,
const TQPoint &)),
384 TQ_SLOT(newTimeSpanSelected(
const TQPoint &,
const TQPoint &)));
385 connect( mAllDayAgenda, TQ_SIGNAL(newTimeSpanSignal(
const TQPoint &,
const TQPoint &)),
386 TQ_SLOT(newTimeSpanSelectedAllDay(
const TQPoint &,
const TQPoint &)));
389 connect( mAgenda, TQ_SIGNAL(lowerYChanged(
int)),
390 TQ_SLOT(updateEventIndicatorTop(
int)));
391 connect( mAgenda, TQ_SIGNAL(upperYChanged(
int)),
392 TQ_SLOT(updateEventIndicatorBottom(
int)));
395 connectAgenda( mAgenda, mAgendaPopup, mAllDayAgenda );
396 connectAgenda( mAllDayAgenda, mAllDayAgendaPopup, mAgenda);
405 KOAgendaView::~KOAgendaView()
408 calendar()->unregisterObserver(
this );
410 delete mAllDayAgendaPopup;
413 void KOAgendaView::connectAgenda( KOAgenda *agenda, TQPopupMenu *popup,
414 KOAgenda *otherAgenda )
416 connect( agenda, TQ_SIGNAL(showIncidencePopupSignal(
Calendar *,
Incidence *,
const TQDate &)),
419 connect( agenda, TQ_SIGNAL(showNewEventPopupSignal()),
420 TQ_SLOT(showNewEventPopup()) );
424 connect( agenda, TQ_SIGNAL(newEventSignal(
ResourceCalendar *,
const TQString &)),
427 connect( agenda, TQ_SIGNAL(newStartSelectSignal()),
428 otherAgenda, TQ_SLOT(clearSelection()) );
429 connect( agenda, TQ_SIGNAL(newStartSelectSignal()),
430 TQ_SIGNAL(timeSpanSelectionChanged()) );
432 connect( agenda, TQ_SIGNAL(editIncidenceSignal(
Incidence *,
const TQDate &)),
433 TQ_SIGNAL(editIncidenceSignal(
Incidence *,
const TQDate &)) );
434 connect( agenda, TQ_SIGNAL(showIncidenceSignal(
Incidence *,
const TQDate &)),
435 TQ_SIGNAL(showIncidenceSignal(
Incidence *,
const TQDate &)) );
436 connect( agenda, TQ_SIGNAL(deleteIncidenceSignal(
Incidence *)),
437 TQ_SIGNAL(deleteIncidenceSignal(
Incidence *)) );
439 connect( agenda, TQ_SIGNAL(startMultiModify(
const TQString &)),
440 TQ_SIGNAL(startMultiModify(
const TQString &)) );
441 connect( agenda, TQ_SIGNAL(endMultiModify()),
442 TQ_SIGNAL(endMultiModify()) );
444 connect( agenda, TQ_SIGNAL(itemModified(KOAgendaItem *)),
445 TQ_SLOT(updateEventDates(KOAgendaItem *)) );
447 connect( agenda, TQ_SIGNAL(enableAgendaUpdate(
bool)),
448 TQ_SLOT(enableAgendaUpdate(
bool)) );
451 connect( agenda, TQ_SIGNAL(startDragSignal(
Incidence *)),
455 connect( agenda, TQ_SIGNAL(incidenceSelected(
Incidence *,
const TQDate &)),
456 otherAgenda, TQ_SLOT(deselectItem()) );
457 connect( agenda, TQ_SIGNAL(incidenceSelected(
Incidence *,
const TQDate &)),
458 TQ_SIGNAL(incidenceSelected(
Incidence *,
const TQDate &)) );
461 connect( agenda, TQ_SIGNAL(droppedToDo(
Todo *,
const TQPoint &,
bool)),
462 TQ_SLOT(slotTodoDropped(
Todo *,
const TQPoint &,
bool)) );
466 void KOAgendaView::zoomInVertically( )
468 if ( !mIsSideBySide )
469 KOPrefs::instance()->mHourSize++;
470 mAgenda->updateConfig();
471 mAgenda->checkScrollBoundaries();
473 mTimeLabels->updateConfig();
474 mTimeLabels->positionChanged();
475 mTimeLabels->repaint();
480 void KOAgendaView::zoomOutVertically( )
483 if ( KOPrefs::instance()->mHourSize > 4 || mIsSideBySide ) {
485 if ( !mIsSideBySide )
486 KOPrefs::instance()->mHourSize--;
487 mAgenda->updateConfig();
488 mAgenda->checkScrollBoundaries();
490 mTimeLabels->updateConfig();
491 mTimeLabels->positionChanged();
492 mTimeLabels->repaint();
498 void KOAgendaView::zoomInHorizontally(
const TQDate &date)
502 TQDate dateToZoom = date;
505 begin = mSelectedDates.first();
506 ndays = begin.daysTo( mSelectedDates.last() );
509 if ( ! dateToZoom.isValid () )
510 dateToZoom=mAgenda->selectedIncidenceDate();
512 if( !dateToZoom.isValid() ) {
514 newBegin=begin.addDays(1);
516 emit zoomViewHorizontally ( newBegin , count );
520 newBegin = dateToZoom;
523 newBegin = dateToZoom.addDays( -ndays/2 +1 );
526 emit zoomViewHorizontally ( newBegin , count );
530 void KOAgendaView::zoomOutHorizontally(
const TQDate &date )
534 TQDate dateToZoom = date;
537 begin = mSelectedDates.first();
538 ndays = begin.daysTo( mSelectedDates.last() );
541 if ( ! dateToZoom.isValid () )
542 dateToZoom=mAgenda->selectedIncidenceDate();
544 if ( !dateToZoom.isValid() ) {
545 newBegin = begin.addDays(-1);
548 newBegin = dateToZoom.addDays( -ndays/2-1 );
552 if ( abs( count ) >= 31 )
553 kdDebug(5850) <<
"change to the mounth view?"<<endl;
556 emit zoomViewHorizontally( newBegin, count );
559 void KOAgendaView::zoomView(
const int delta,
const TQPoint &pos,
560 const TQt::Orientation orient )
562 static TQDate zoomDate;
563 static TQTimer *t =
new TQTimer(
this );
568 if ( orient == TQt::Horizontal ) {
569 TQDate date=mAgenda->selectedIncidenceDate();
570 if ( date.isValid() )
573 if ( !t->isActive() ) {
574 zoomDate= mSelectedDates[pos.x()];
576 t->start ( 1000,
true );
579 zoomOutHorizontally( zoomDate );
581 zoomInHorizontally( zoomDate );
584 TQPoint posConstentsOld = mAgenda->gridToContents(pos);
590 TQPoint posConstentsNew = mAgenda->gridToContents(pos);
591 mAgenda->scrollBy( 0, posConstentsNew.y() - posConstentsOld.y() );
601 if ( !force && mSaveSelectedDates == mSelectedDates ) {
604 mSaveSelectedDates = mSelectedDates;
607 mDateDayLabels.clear();
609 mDayLabels =
new TQFrame (mDayLabelsFrame);
610 mLayoutDayLabels =
new TQHBoxLayout(mDayLabels);
611 if ( !mIsSideBySide )
612 mLayoutDayLabels->addSpacing(mTimeLabels->width());
614 const KCalendarSystem*calsys=KOGlobals::self()->calendarSystem();
616 DateList::ConstIterator dit;
617 for( dit = mSelectedDates.begin(); dit != mSelectedDates.end(); ++dit ) {
619 TQBoxLayout *dayLayout =
new TQVBoxLayout(mLayoutDayLabels);
620 mLayoutDayLabels->setStretchFactor(dayLayout, 1);
623 int dW = calsys->dayOfWeek(date);
624 TQString veryLongStr = TDEGlobal::locale()->formatDate( date );
625 TQString longstr = i18n(
"short_weekday date (e.g. Mon 13)",
"%1 %2" )
626 .arg( calsys->weekDayName( dW,
true ) )
627 .arg( calsys->day(date) );
628 TQString shortstr = TQString::number(calsys->day(date));
630 KOAlternateLabel *dayLabel =
new KOAlternateLabel(shortstr,
631 longstr, veryLongStr, mDayLabels);
632 dayLabel->useShortText();
633 dayLabel->setMinimumWidth(1);
634 dayLabel->setAlignment(TQLabel::AlignHCenter);
635 if (date == TQDate::currentDate()) {
636 TQFont font = dayLabel->font();
638 dayLabel->setFont(font);
640 dayLayout->addWidget(dayLabel);
641 mDateDayLabels.append( dayLabel );
644 TQStringList texts = KOGlobals::self()->holiday( date );
645 TQStringList::ConstIterator textit = texts.begin();
646 for ( ; textit != texts.end(); ++textit ) {
648 KOAlternateLabel*label =
new KOAlternateLabel( (*textit), (*textit), TQString(), mDayLabels );
649 label->setMinimumWidth(1);
650 label->setAlignment(AlignCenter);
651 dayLayout->addWidget(label);
654 #ifndef KORG_NOPLUGINS
655 CalendarDecoration::List cds = KOCore::self()->calendarDecorations();
657 for(it = cds.first(); it; it = cds.next()) {
659 if ( !text.isEmpty() ) {
661 KOAlternateLabel*label =
new KOAlternateLabel( text, text, TQString(), mDayLabels );
662 label->setMinimumWidth(1);
663 label->setAlignment(AlignCenter);
664 dayLayout->addWidget(label);
668 for(it = cds.first(); it; it = cds.next()) {
672 dayLayout->addWidget(wid);
678 if ( !mIsSideBySide )
679 mLayoutDayLabels->addSpacing(mAgenda->verticalScrollBar()->width());
681 TQTimer::singleShot( 0,
this, TQ_SLOT( updateDayLabelSizes() ) );
684 void KOAgendaView::enableAgendaUpdate(
bool enable )
686 mAllowAgendaUpdate = enable;
697 return mSelectedDates.count();
702 Incidence::List selected;
705 incidence = mAgenda->selectedIncidence();
706 if (incidence) selected.append(incidence);
708 incidence = mAllDayAgenda->selectedIncidence();
709 if (incidence) selected.append(incidence);
719 qd = mAgenda->selectedIncidenceDate();
720 if (qd.isValid()) selected.append(qd);
722 qd = mAllDayAgenda->selectedIncidenceDate();
723 if (qd.isValid()) selected.append(qd);
731 if ( selectionStart().isValid() ) {
732 TQDateTime start = selectionStart();
733 TQDateTime end = selectionEnd();
735 if ( start.secsTo( end ) == 15*60 ) {
738 TQTime defaultDuration( KOPrefs::instance()->mDefaultDuration.time() );
739 int addSecs = ( defaultDuration.hour()*3600 ) +
740 ( defaultDuration.minute()*60 );
741 end = start.addSecs( addSecs );
746 allDay = selectedIsAllDay();
755 if ( !selectionStart().isValid() || !selectionEnd().isValid() )
return false;
757 if (selectedIsAllDay()) {
758 int days = selectionStart().daysTo(selectionEnd());
761 int secs = selectionStart().secsTo(selectionEnd());
762 return ( secs <= 24*60*60/mAgenda->rows() );
767 void KOAgendaView::updateView()
778 void KOAgendaView::updateConfig()
783 mTimeLabels->updateConfig();
784 mAgenda->updateConfig();
785 mAllDayAgenda->updateConfig();
789 mTimeLabels->positionChanged();
792 mTimeLabels->repaint();
794 updateTimeBarWidth();
797 KOAgendaItem::toolTipGroup()->setEnabled(KOPrefs::instance()
802 createDayLabels(
true );
807 void KOAgendaView::updateTimeBarWidth()
811 width = mDummyAllDayLeft->fontMetrics().width( i18n(
"All Day") );
812 width = TQMAX( width, mTimeLabels->width() );
814 mDummyAllDayLeft->setFixedWidth( width );
815 mTimeLabels->setFixedWidth( width );
818 void KOAgendaView::updateDayLabelSizes()
821 KOAlternateLabel::TextType overallType = KOAlternateLabel::Extensive;
822 TQPtrList<KOAlternateLabel>::const_iterator it = mDateDayLabels.constBegin();
823 for( ; it != mDateDayLabels.constEnd(); it++ ) {
824 KOAlternateLabel::TextType type = (*it)->largestFittingTextType();
825 if ( type < overallType )
830 it = mDateDayLabels.constBegin();
831 for( ; it != mDateDayLabels.constEnd(); it++ ) {
832 (*it)->setFixedType( overallType );
836 void KOAgendaView::resizeEvent( TQResizeEvent *resizeEvent )
838 updateDayLabelSizes();
839 KOrg::AgendaView::resizeEvent( resizeEvent );
844 kdDebug(5850) <<
"KOAgendaView::updateEventDates(): " << item->text()
845 <<
"; item->cellXLeft(): " << item->cellXLeft()
846 <<
"; item->cellYTop(): " << item->cellYTop()
847 <<
"; item->lastMultiItem(): " << item->lastMultiItem()
848 <<
"; item->itemPos(): " << item->itemPos()
849 <<
"; item->itemCount(): " << item->itemCount()
852 TQDateTime startDt, endDt;
859 if ( item->cellXLeft() < 0 ) {
860 thisDate = ( mSelectedDates.first() ).addDays( item->cellXLeft() );
862 thisDate = mSelectedDates[ item->cellXLeft() ];
864 TQDate oldThisDate( item->itemDate() );
865 const int daysOffset = oldThisDate.daysTo( thisDate );
870 Incidence *incidence = item->incidence();
875 !mChanger->beginChange( incidence, resourceCalendar(), subResourceCalendar() ) ) {
880 TQTime startTime( 0, 0, 0 ), endTime( 0, 0, 0 );
882 daysLength = item->cellWidth() - 1;
884 startTime = mAgenda->gyToTime( item->cellYTop() );
885 if ( item->lastMultiItem() ) {
886 endTime = mAgenda->gyToTime( item->lastMultiItem()->cellYBottom() + 1 );
887 daysLength = item->lastMultiItem()->cellXLeft() - item->cellXLeft();
888 kdDebug(5850) <<
"item->lastMultiItem()->cellXLeft(): " << item->lastMultiItem()->cellXLeft()
890 }
else if ( item->itemPos() == item->itemCount() && item->itemCount() > 1 ) {
901 endTime = mAgenda->gyToTime( item->cellYBottom() + 1 );
902 daysLength = item->itemCount() - 1;
903 startTime = incidence->
dtStart().time();
904 }
else if ( item->itemPos() == 1 && item->itemCount() > 1 ) {
906 endTime = incidence->
dtEnd().time();
907 daysLength = item->itemCount() - 1;
909 endTime = mAgenda->gyToTime( item->cellYBottom() + 1 );
913 kdDebug(5850) <<
"daysLength: " << daysLength <<
"; startTime: " << startTime
914 <<
"; endTime: " << endTime <<
"; thisDate: " << thisDate
915 <<
"; incidence->dtStart(): " << incidence->
dtStart() << endl;
918 if ( incidence->type() ==
"Event" ) {
919 startDt = incidence->
dtStart();
920 startDt = startDt.addDays( daysOffset );
921 startDt.setTime( startTime );
922 endDt = startDt.addDays( daysLength );
923 endDt.setTime( endTime );
925 if ( incidence->
dtStart() == startDt && ev->
dtEnd() == endDt ) {
932 }
else if ( incidence->type() ==
"Todo" ) {
933 Todo *td =
static_cast<Todo*
>( incidence );
935 startDt = thisDate.addDays( td->
dtDue().daysTo( startDt ) );
936 startDt.setTime( startTime );
937 endDt.setDate( thisDate );
938 endDt.setTime( endTime );
940 if( td->
dtDue() == endDt ) {
1093 if ( incidence->type() ==
"Event" ) {
1095 static_cast<Event*
>( incidence )->setDtEnd( endDt );
1096 }
else if ( incidence->type() ==
"Todo" ) {
1097 Todo *td =
static_cast<Todo*
>( incidence );
1104 item->setItemDate( startDt.date() );
1106 KOIncidenceToolTip::remove( item );
1109 const bool result = mChanger->changeIncidence( oldIncidence, incidence,
1110 KOGlobals::DATE_MODIFIED,
this );
1111 mChanger->endChange( incidence, resourceCalendar(), subResourceCalendar() );
1112 delete oldIncidence;
1115 mPendingChanges =
true;
1116 TQTimer::singleShot( 0,
this, TQ_SLOT(updateView()) );
1123 enableAgendaUpdate(
false );
1129 mUpdateItem = incidence;
1130 TQTimer::singleShot( 0,
this, TQ_SLOT( doUpdateItem() ) );
1133 enableAgendaUpdate(
true );
1140 if ( mUpdateItem ) {
1141 changeIncidenceDisplay( mUpdateItem, KOGlobals::INCIDENCEEDITED );
1148 void KOAgendaView::showDates(
const TQDate &start,
const TQDate &end )
1151 if ( !mSelectedDates.isEmpty() && mSelectedDates.first() == start
1152 && mSelectedDates.last() == end && !mPendingChanges )
1155 mSelectedDates.clear();
1158 while ( d <= end ) {
1159 mSelectedDates.append( d );
1163 mAreDatesInitialized =
true;
1170 void KOAgendaView::showIncidences(
const Incidence::List &,
const TQDate & )
1172 kdDebug(5850) <<
"KOAgendaView::showIncidences( const Incidence::List & ) is not yet implemented" << endl;
1175 void KOAgendaView::insertIncidence(
Incidence *incidence,
const TQDate &curDate )
1177 if ( !filterByResource( incidence ) ) {
1182 Event *
event =
dynamic_cast<Event *
>( incidence );
1183 Todo *todo =
dynamic_cast<Todo *
>( incidence );
1185 int curCol = mSelectedDates.first().daysTo( curDate );
1193 if ( curCol >=
int( mSelectedDates.count() ) ) {
1198 mMinY[curCol] = mAgenda->timeToY( TQTime( 23, 59 ) ) + 1;
1199 mMaxY[curCol] = mAgenda->timeToY( TQTime( 0, 0 ) ) - 1;
1205 TQDate firstVisibleDate = mSelectedDates.first();
1207 if ( curDate < firstVisibleDate ) {
1208 beginX = curCol + firstVisibleDate.daysTo( curDate );
1209 endX = beginX +
event->
dtStart().daysTo( event->dtEnd() );
1210 columnDate = firstVisibleDate;
1213 endX = beginX +
event->dtStart().daysTo( event->dtEnd() );
1214 columnDate = curDate;
1216 }
else if ( todo ) {
1220 columnDate = curDate;
1221 beginX = endX = curCol;
1227 mAllDayAgenda->insertAllDayItem( incidence, columnDate, curCol, curCol );
1230 !todo->
dtDue().isValid() ) ) {
1231 mAllDayAgenda->insertAllDayItem( incidence, columnDate, beginX, endX );
1232 }
else if ( event && event->isMultiDay() ) {
1233 int startY = mAgenda->timeToY( event->dtStart().time() );
1234 TQTime endtime =
event->dtEnd().time();
1235 if ( endtime == TQTime( 0, 0, 0 ) ) {
1236 endtime = TQTime( 23, 59, 59 );
1238 int endY = mAgenda->timeToY( endtime ) - 1;
1239 if ( ( beginX <= 0 && curCol == 0 ) || beginX == curCol ) {
1240 mAgenda->insertMultiItem( event, columnDate, beginX, endX, startY, endY );
1243 if ( beginX == curCol ) {
1244 mMaxY[curCol] = mAgenda->timeToY( TQTime( 23, 59 ) );
1245 if ( startY < mMinY[curCol] ) {
1246 mMinY[curCol] = startY;
1248 }
else if ( endX == curCol ) {
1249 mMinY[curCol] = mAgenda->timeToY( TQTime( 0, 0 ) );
1250 if ( endY > mMaxY[curCol] ) {
1251 mMaxY[curCol] = endY;
1254 mMinY[curCol] = mAgenda->timeToY( TQTime( 0, 0 ) );
1255 mMaxY[curCol] = mAgenda->timeToY( TQTime( 23, 59 ) );
1258 int startY = 0, endY = 0;
1260 startY = mAgenda->timeToY( incidence->
dtStart().time() );
1261 TQTime endtime =
event->dtEnd().time();
1262 if ( endtime == TQTime( 0, 0, 0 ) ) {
1263 endtime = TQTime( 23, 59, 59 );
1265 endY = mAgenda->timeToY( endtime ) - 1;
1268 TQTime t = todo->
dtDue().time();
1270 if ( t == TQTime( 0, 0 ) ) {
1271 t = TQTime( 23, 59 );
1274 int halfHour = 1800;
1275 if ( t.addSecs( -halfHour ) < t ) {
1276 startY = mAgenda->timeToY( t.addSecs( -halfHour ) );
1277 endY = mAgenda->timeToY( t ) - 1;
1280 endY = mAgenda->timeToY( t.addSecs( halfHour ) ) - 1;
1283 if ( endY < startY ) {
1286 mAgenda->insertItem( incidence, columnDate, curCol, startY, endY, 1, 1 );
1287 if ( startY < mMinY[curCol] ) {
1288 mMinY[curCol] = startY;
1290 if ( endY > mMaxY[curCol] ) {
1291 mMaxY[curCol] = endY;
1296 void KOAgendaView::changeIncidenceDisplayAdded(
Incidence *incidence )
1298 Todo *todo =
dynamic_cast<Todo *
>(incidence);
1299 CalFilter *filter = calendar()->filter();
1301 ( ( todo && !KOPrefs::instance()->showAllDayTodo() ) ) ) {
1305 displayIncidence( incidence );
1308 void KOAgendaView::changeIncidenceDisplay(
Incidence *incidence,
int mode )
1311 case KOGlobals::INCIDENCEADDED:
1318 changeIncidenceDisplayAdded( incidence );
1319 updateEventIndicators();
1322 case KOGlobals::INCIDENCEEDITED:
1324 if ( mAllowAgendaUpdate ) {
1325 removeIncidence( incidence );
1326 changeIncidenceDisplayAdded( incidence );
1328 updateEventIndicators();
1331 case KOGlobals::INCIDENCEDELETED:
1333 removeIncidence( incidence );
1334 updateEventIndicators();
1357 if ( !mAreDatesInitialized ) {
1361 mPendingChanges =
false;
1365 const TQString &selectedAgendaUid = mAgenda->lastSelectedUid();
1366 const TQString &selectedAllDayAgendaUid = mAllDayAgenda->lastSelectedUid();
1368 enableAgendaUpdate(
true );
1371 mAllDayAgenda->changeColumns( mSelectedDates.count() );
1372 mAgenda->changeColumns( mSelectedDates.count() );
1373 mEventIndicatorTop->changeColumns( mSelectedDates.count() );
1374 mEventIndicatorBottom->changeColumns( mSelectedDates.count() );
1376 createDayLabels(
false );
1379 mMinY.resize( mSelectedDates.count() );
1380 mMaxY.resize( mSelectedDates.count() );
1382 mAgenda->setDateList( mSelectedDates );
1384 bool somethingReselected =
false;
1385 Incidence::List incidences = calendar()->incidences();
1387 for ( Incidence::List::ConstIterator it = incidences.begin(); it!=incidences.constEnd(); ++it ) {
1389 displayIncidence( incidence );
1391 if( incidence->
uid() == selectedAgendaUid && !selectedAgendaUid.isNull() ) {
1392 mAgenda->selectItemByUID( incidence->
uid() );
1393 somethingReselected =
true;
1396 if( incidence->
uid() == selectedAllDayAgendaUid && !selectedAllDayAgendaUid.isNull() ) {
1397 mAllDayAgenda->selectItemByUID( incidence->
uid() );
1398 somethingReselected =
true;
1403 mAgenda->checkScrollBoundaries();
1404 updateEventIndicators();
1410 deleteSelectedDateTime();
1412 if( !somethingReselected ) {
1413 emit incidenceSelected( 0, TQDate() );
1417 void KOAgendaView::displayIncidence(
Incidence *incidence )
1419 TQDate today = TQDate::currentDate();
1420 DateTimeList::iterator t;
1423 Todo *todo =
dynamic_cast<Todo *
>( incidence );
1424 Event *
event =
dynamic_cast<Event *
>( incidence );
1426 TQDateTime firstVisibleDateTime = mSelectedDates.first();
1427 TQDateTime lastVisibleDateTime = mSelectedDates.last();
1429 lastVisibleDateTime.setTime( TQTime( 23, 59, 59, 59 ) );
1430 firstVisibleDateTime.setTime( TQTime( 0, 0 ) );
1431 DateTimeList dateTimeList;
1433 TQDateTime incDtStart = incidence->
dtStart();
1434 TQDateTime incDtEnd = incidence->
dtEnd();
1437 ( !KOPrefs::instance()->showAllDayTodo() || !todo->
hasDueDate() ) ) {
1442 int eventDuration =
event ? incDtStart.daysTo( incDtEnd ) : 0;
1447 TQDateTime startDateTimeWithOffset = firstVisibleDateTime.addDays( -eventDuration );
1450 lastVisibleDateTime );
1452 TQDateTime dateToAdd;
1453 TQDateTime incidenceStart;
1454 TQDateTime incidenceEnd;
1458 dateToAdd = todo->
dtDue();
1462 if ( !todo->
doesFloat() && dateToAdd.time() == TQTime( 0, 0 ) ) {
1463 dateToAdd = dateToAdd.addSecs( -1 );
1466 incidenceEnd = dateToAdd;
1467 }
else if ( event ) {
1468 dateToAdd = incDtStart;
1469 incidenceEnd = incDtEnd;
1474 dateToAdd.setTime( TQTime( 0, 0 ) );
1475 incidenceEnd.setTime( TQTime( 23, 59, 59, 59 ) );
1478 if ( dateToAdd <= lastVisibleDateTime && incidenceEnd > firstVisibleDateTime ) {
1479 dateTimeList += dateToAdd;
1484 TQDateTime dateTimeToday = today;
1487 dateTimeToday >= firstVisibleDateTime &&
1488 dateTimeToday <= lastVisibleDateTime ) {
1495 for ( t = dateTimeList.begin(); t != dateTimeList.end(); ++t ) {
1496 if ( (*t).date() == today ) {
1504 dateTimeList += dateTimeToday;
1508 for ( t = dateTimeList.begin(); t != dateTimeList.end(); ++t ) {
1509 insertIncidence( incidence, (*t).date() );
1516 mAllDayAgenda->clear();
1520 CalPrinterBase::PrintType KOAgendaView::printType()
1522 if ( currentDateCount() == 1 )
return CalPrinterBase::Day;
1523 else return CalPrinterBase::Week;
1526 void KOAgendaView::updateEventIndicatorTop(
int newY )
1529 for( i = 0; i < mMinY.size(); ++i ) {
1530 mEventIndicatorTop->enableColumn( i, newY > mMinY[i] );
1532 mEventIndicatorTop->update();
1535 void KOAgendaView::updateEventIndicatorBottom(
int newY )
1538 for( i = 0; i < mMaxY.size(); ++i ) {
1539 mEventIndicatorBottom->enableColumn( i, newY <= mMaxY[i] );
1541 mEventIndicatorBottom->update();
1546 if ( gpos.x()<0 || gpos.y()<0 )
return;
1547 TQDate day = mSelectedDates[gpos.x()];
1548 TQTime time = mAgenda->gyToTime( gpos.y() );
1549 TQDateTime newTime( day, time );
1552 Todo *existingTodo = calendar()->todo( todo->
uid() );
1553 if ( existingTodo ) {
1554 kdDebug(5850) <<
"Drop existing Todo" << endl;
1557 mChanger->beginChange( existingTodo, resourceCalendar(), subResourceCalendar() ) ) {
1561 mChanger->changeIncidence( oldTodo, existingTodo,
1562 KOGlobals::DATE_MODIFIED,
this );
1563 mChanger->endChange( existingTodo, resourceCalendar(), subResourceCalendar() );
1565 KMessageBox::sorry(
this, i18n(
"Unable to modify this to-do, "
1566 "because it cannot be locked.") );
1570 kdDebug(5850) <<
"Drop new Todo" << endl;
1574 if ( !mChanger->addIncidence( todo, 0, TQString(),
this ) ) {
1575 KODialogManager::errorSaveIncidence(
this, todo );
1581 void KOAgendaView::startDrag(
Incidence *incidence )
1585 ICalDrag *vd = factory.createDrag( incidence,
this );
1587 kdDebug(5850) <<
"KOAgendaView::startDrag(): Delete drag source" << endl;
1592 void KOAgendaView::readSettings()
1594 readSettings(KOGlobals::self()->config());
1597 void KOAgendaView::readSettings(TDEConfig *config)
1601 config->setGroup(
"Views");
1603 #ifndef KORG_NOSPLITTER
1604 TQValueList<int> sizes = config->readIntListEntry(
"Separator AgendaView");
1605 if (sizes.count() == 2) {
1606 mSplitterAgenda->setSizes(sizes);
1613 void KOAgendaView::writeSettings(TDEConfig *config)
1617 config->setGroup(
"Views");
1619 #ifndef KORG_NOSPLITTER
1620 TQValueList<int> list = mSplitterAgenda->sizes();
1621 config->writeEntry(
"Separator AgendaView",list);
1627 if ( mSelectedDates.isEmpty() || !mSelectedDates[0].isValid() ) {
1631 mHolidayMask.resize( mSelectedDates.count() + 1 );
1633 for( uint i = 0; i < mSelectedDates.count(); ++i ) {
1634 mHolidayMask[i] = !KOGlobals::self()->isWorkDay( mSelectedDates[ i ] );
1639 bool showDay = !KOGlobals::self()->isWorkDay( mSelectedDates[ 0 ].addDays( -1 ) );
1640 mHolidayMask[ mSelectedDates.count() ] = showDay;
1642 mAgenda->setHolidayMask( &mHolidayMask );
1643 mAllDayAgenda->setHolidayMask( &mHolidayMask );
1646 void KOAgendaView::setContentsPos(
int y )
1648 mAgenda->setContentsPos( 0, y );
1651 void KOAgendaView::setExpandedButton(
bool expanded )
1653 if ( !mExpandButton )
return;
1656 mExpandButton->setPixmap( mExpandedPixmap );
1658 mExpandButton->setPixmap( mNotExpandedPixmap );
1662 void KOAgendaView::clearSelection()
1664 mAgenda->deselectItem();
1665 mAllDayAgenda->deselectItem();
1670 newTimeSpanSelected( start, end );
1671 mTimeSpanInAllDay =
true;
1676 if (!mSelectedDates.count())
return;
1678 mTimeSpanInAllDay =
false;
1680 TQDate dayStart = mSelectedDates[ kClamp( start.x(), 0, (
int)mSelectedDates.size() - 1 ) ];
1681 TQDate dayEnd = mSelectedDates[ kClamp( end.x(), 0, (
int)mSelectedDates.size() - 1 ) ];
1683 TQTime timeStart = mAgenda->gyToTime(start.y());
1684 TQTime timeEnd = mAgenda->gyToTime( end.y() + 1 );
1686 TQDateTime dtStart(dayStart,timeStart);
1687 TQDateTime dtEnd(dayEnd,timeEnd);
1689 mTimeSpanBegin = dtStart;
1690 mTimeSpanEnd = dtEnd;
1695 mTimeSpanBegin.setDate(TQDate());
1696 mTimeSpanEnd.setDate(TQDate());
1697 mTimeSpanInAllDay =
false;
1700 void KOAgendaView::setTypeAheadReceiver( TQObject *o )
1702 mAgenda->setTypeAheadReceiver( o );
1703 mAllDayAgenda->setTypeAheadReceiver( o );
1706 void KOAgendaView::finishTypeAhead()
1708 mAgenda->finishTypeAhead();
1709 mAllDayAgenda->finishTypeAhead();
1712 void KOAgendaView::removeIncidence(
Incidence *incidence )
1714 mAgenda->removeIncidence( incidence );
1715 mAllDayAgenda->removeIncidence( incidence );
1720 mMinY = mAgenda->minContentsY();
1721 mMaxY = mAgenda->maxContentsY();
1723 mAgenda->checkScrollBoundaries();
1724 updateEventIndicatorTop( mAgenda->visibleContentsYMin() );
1725 updateEventIndicatorBottom( mAgenda->visibleContentsYMax() );
1728 void KOAgendaView::setIncidenceChanger( IncidenceChangerBase *changer )
1731 mAgenda->setIncidenceChanger( changer );
1732 mAllDayAgenda->setIncidenceChanger( changer );
1735 void KOAgendaView::clearTimeSpanSelection()
1737 mAgenda->clearSelection();
1738 mAllDayAgenda->clearSelection();
1739 deleteSelectedDateTime();
1742 bool KOAgendaView::filterByResource(
Incidence *incidence )
1748 if ( resourceCalendar() && incidence->type() ==
"Todo" ) {
1749 TQString subRes = resourceCalendar()->subresourceIdentifier( incidence );
1750 if ( resourceCalendar()->subresourceType( subRes ) ==
"todo" ) {
1751 TQString calmatch =
"/.INBOX.directory/Calendar";
1752 TQString i18nmatch =
"/.INBOX.directory/" + i18n(
"Calendar" );
1753 if ( subResourceCalendar().contains( calmatch ) ||
1754 subResourceCalendar().contains( i18nmatch ) ) {
1761 if ( !resourceCalendar() )
1766 if ( calRes->
resource( incidence ) != resourceCalendar() )
1768 if ( !subResourceCalendar().isEmpty() ) {
1769 if ( resourceCalendar()->subresourceIdentifier( incidence ) != subResourceCalendar() )
1775 void KOAgendaView::resourcesChanged()
1777 mPendingChanges =
true;
1780 void KOAgendaView::calendarIncidenceAdded(
Incidence * incidence)
1782 Q_UNUSED( incidence );
1783 mPendingChanges =
true;
1786 void KOAgendaView::calendarIncidenceChanged(
Incidence * incidence)
1788 Q_UNUSED( incidence );
1789 mPendingChanges =
true;
1792 void KOAgendaView::calendarIncidenceDeleted(
Incidence * incidence)
1794 Q_UNUSED( incidence );
1795 mPendingChanges =
true;