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 <kstandarddirs.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 #if KDE_IS_VERSION( 3, 1, 93 )
291 mSplitterAgenda->setOpaqueResize( TDEGlobalSettings::opaqueResize() );
293 mSplitterAgenda->setOpaqueResize();
296 mAllDayFrame =
new TQHBox(mSplitterAgenda);
298 TQWidget *agendaFrame =
new TQWidget(mSplitterAgenda);
300 TQVBox *mainBox =
new TQVBox(
this );
301 topLayout->addWidget( mainBox );
303 mAllDayFrame =
new TQHBox(mainBox);
305 TQWidget *agendaFrame =
new TQWidget(mainBox);
309 mDummyAllDayLeft =
new TQVBox( mAllDayFrame );
311 mDummyAllDayLeft->hide();
313 if ( KOPrefs::instance()->compactDialogs() ) {
314 mExpandButton =
new TQPushButton(mDummyAllDayLeft);
315 mExpandButton->setPixmap( mNotExpandedPixmap );
316 mExpandButton->setSizePolicy( TQSizePolicy( TQSizePolicy::Fixed,
317 TQSizePolicy::Fixed ) );
318 connect( mExpandButton, TQ_SIGNAL( clicked() ), TQ_SIGNAL( toggleExpand() ) );
320 TQLabel *label =
new TQLabel( i18n(
"All Day"), mDummyAllDayLeft );
321 label->setAlignment( TQt::AlignRight | TQt::AlignVCenter | TQt::WordBreak );
324 mAllDayAgenda =
new KOAgenda( 1, calendarView, mAllDayFrame );
325 mAllDayAgenda->setCalendar( calendar() );
326 TQWidget *dummyAllDayRight =
new TQWidget(mAllDayFrame);
329 TQGridLayout *agendaLayout =
new TQGridLayout(agendaFrame,3,3);
333 mEventIndicatorTop =
new EventIndicator(EventIndicator::Top,agendaFrame);
334 agendaLayout->addWidget(mEventIndicatorTop,0,1);
335 mEventIndicatorBottom =
new EventIndicator(EventIndicator::Bottom,
337 agendaLayout->addWidget(mEventIndicatorBottom,2,1);
338 TQWidget *dummyAgendaRight =
new TQWidget(agendaFrame);
339 agendaLayout->addWidget(dummyAgendaRight,0,2);
342 mTimeLabels =
new TimeLabels(24,agendaFrame);
343 agendaLayout->addWidget(mTimeLabels,1,0);
346 mAgenda =
new KOAgenda( 1, 96, KOPrefs::instance()->mHourSize, calendarView, agendaFrame );
347 mAgenda->setCalendar( calendar() );
348 agendaLayout->addMultiCellWidget(mAgenda,1,1,1,2);
349 agendaLayout->setColStretch(1,1);
352 mAgendaPopup = eventPopup();
355 mAllDayAgendaPopup = eventPopup();
358 mTimeLabels->setAgenda(mAgenda);
365 createDayLabels(
true );
367 if ( !isSideBySide ) {
369 dummyAllDayRight->setFixedWidth(mAgenda->verticalScrollBar()->width());
370 dummyAgendaRight->setFixedWidth(mAgenda->verticalScrollBar()->width());
373 updateTimeBarWidth();
376 connect(mAgenda->verticalScrollBar(),TQ_SIGNAL(valueChanged(
int)),
377 mTimeLabels, TQ_SLOT(positionChanged()));
380 TQ_SIGNAL( zoomView(
const int,
const TQPoint & ,
const TQt::Orientation ) ),
381 TQ_SLOT( zoomView(
const int,
const TQPoint &,
const TQt::Orientation ) ) );
383 connect(mTimeLabels->verticalScrollBar(),TQ_SIGNAL(valueChanged(
int)),
384 TQ_SLOT(setContentsPos(
int)));
387 connect( mAgenda, TQ_SIGNAL(newTimeSpanSignal(
const TQPoint &,
const TQPoint &)),
388 TQ_SLOT(newTimeSpanSelected(
const TQPoint &,
const TQPoint &)));
389 connect( mAllDayAgenda, TQ_SIGNAL(newTimeSpanSignal(
const TQPoint &,
const TQPoint &)),
390 TQ_SLOT(newTimeSpanSelectedAllDay(
const TQPoint &,
const TQPoint &)));
393 connect( mAgenda, TQ_SIGNAL(lowerYChanged(
int)),
394 TQ_SLOT(updateEventIndicatorTop(
int)));
395 connect( mAgenda, TQ_SIGNAL(upperYChanged(
int)),
396 TQ_SLOT(updateEventIndicatorBottom(
int)));
399 connectAgenda( mAgenda, mAgendaPopup, mAllDayAgenda );
400 connectAgenda( mAllDayAgenda, mAllDayAgendaPopup, mAgenda);
409 KOAgendaView::~KOAgendaView()
412 calendar()->unregisterObserver(
this );
414 delete mAllDayAgendaPopup;
417 void KOAgendaView::connectAgenda( KOAgenda *agenda, TQPopupMenu *popup,
418 KOAgenda *otherAgenda )
420 connect( agenda, TQ_SIGNAL(showIncidencePopupSignal(
Calendar *,
Incidence *,
const TQDate &)),
423 connect( agenda, TQ_SIGNAL(showNewEventPopupSignal()),
424 TQ_SLOT(showNewEventPopup()) );
428 connect( agenda, TQ_SIGNAL(newEventSignal(
ResourceCalendar *,
const TQString &)),
431 connect( agenda, TQ_SIGNAL(newStartSelectSignal()),
432 otherAgenda, TQ_SLOT(clearSelection()) );
433 connect( agenda, TQ_SIGNAL(newStartSelectSignal()),
434 TQ_SIGNAL(timeSpanSelectionChanged()) );
436 connect( agenda, TQ_SIGNAL(editIncidenceSignal(
Incidence *,
const TQDate &)),
437 TQ_SIGNAL(editIncidenceSignal(
Incidence *,
const TQDate &)) );
438 connect( agenda, TQ_SIGNAL(showIncidenceSignal(
Incidence *,
const TQDate &)),
439 TQ_SIGNAL(showIncidenceSignal(
Incidence *,
const TQDate &)) );
440 connect( agenda, TQ_SIGNAL(deleteIncidenceSignal(
Incidence *)),
441 TQ_SIGNAL(deleteIncidenceSignal(
Incidence *)) );
443 connect( agenda, TQ_SIGNAL(startMultiModify(
const TQString &)),
444 TQ_SIGNAL(startMultiModify(
const TQString &)) );
445 connect( agenda, TQ_SIGNAL(endMultiModify()),
446 TQ_SIGNAL(endMultiModify()) );
448 connect( agenda, TQ_SIGNAL(itemModified(KOAgendaItem *)),
449 TQ_SLOT(updateEventDates(KOAgendaItem *)) );
451 connect( agenda, TQ_SIGNAL(enableAgendaUpdate(
bool)),
452 TQ_SLOT(enableAgendaUpdate(
bool)) );
455 connect( agenda, TQ_SIGNAL(startDragSignal(
Incidence *)),
459 connect( agenda, TQ_SIGNAL(incidenceSelected(
Incidence *,
const TQDate &)),
460 otherAgenda, TQ_SLOT(deselectItem()) );
461 connect( agenda, TQ_SIGNAL(incidenceSelected(
Incidence *,
const TQDate &)),
462 TQ_SIGNAL(incidenceSelected(
Incidence *,
const TQDate &)) );
465 connect( agenda, TQ_SIGNAL(droppedToDo(
Todo *,
const TQPoint &,
bool)),
466 TQ_SLOT(slotTodoDropped(
Todo *,
const TQPoint &,
bool)) );
470 void KOAgendaView::zoomInVertically( )
472 if ( !mIsSideBySide )
473 KOPrefs::instance()->mHourSize++;
474 mAgenda->updateConfig();
475 mAgenda->checkScrollBoundaries();
477 mTimeLabels->updateConfig();
478 mTimeLabels->positionChanged();
479 mTimeLabels->repaint();
484 void KOAgendaView::zoomOutVertically( )
487 if ( KOPrefs::instance()->mHourSize > 4 || mIsSideBySide ) {
489 if ( !mIsSideBySide )
490 KOPrefs::instance()->mHourSize--;
491 mAgenda->updateConfig();
492 mAgenda->checkScrollBoundaries();
494 mTimeLabels->updateConfig();
495 mTimeLabels->positionChanged();
496 mTimeLabels->repaint();
502 void KOAgendaView::zoomInHorizontally(
const TQDate &date)
506 TQDate dateToZoom = date;
509 begin = mSelectedDates.first();
510 ndays = begin.daysTo( mSelectedDates.last() );
513 if ( ! dateToZoom.isValid () )
514 dateToZoom=mAgenda->selectedIncidenceDate();
516 if( !dateToZoom.isValid() ) {
518 newBegin=begin.addDays(1);
520 emit zoomViewHorizontally ( newBegin , count );
524 newBegin = dateToZoom;
527 newBegin = dateToZoom.addDays( -ndays/2 +1 );
530 emit zoomViewHorizontally ( newBegin , count );
534 void KOAgendaView::zoomOutHorizontally(
const TQDate &date )
538 TQDate dateToZoom = date;
541 begin = mSelectedDates.first();
542 ndays = begin.daysTo( mSelectedDates.last() );
545 if ( ! dateToZoom.isValid () )
546 dateToZoom=mAgenda->selectedIncidenceDate();
548 if ( !dateToZoom.isValid() ) {
549 newBegin = begin.addDays(-1);
552 newBegin = dateToZoom.addDays( -ndays/2-1 );
556 if ( abs( count ) >= 31 )
557 kdDebug(5850) <<
"change to the mounth view?"<<endl;
560 emit zoomViewHorizontally( newBegin, count );
563 void KOAgendaView::zoomView(
const int delta,
const TQPoint &pos,
564 const TQt::Orientation orient )
566 static TQDate zoomDate;
567 static TQTimer *t =
new TQTimer(
this );
572 if ( orient == TQt::Horizontal ) {
573 TQDate date=mAgenda->selectedIncidenceDate();
574 if ( date.isValid() )
577 if ( !t->isActive() ) {
578 zoomDate= mSelectedDates[pos.x()];
580 t->start ( 1000,
true );
583 zoomOutHorizontally( zoomDate );
585 zoomInHorizontally( zoomDate );
588 TQPoint posConstentsOld = mAgenda->gridToContents(pos);
594 TQPoint posConstentsNew = mAgenda->gridToContents(pos);
595 mAgenda->scrollBy( 0, posConstentsNew.y() - posConstentsOld.y() );
605 if ( !force && mSaveSelectedDates == mSelectedDates ) {
608 mSaveSelectedDates = mSelectedDates;
611 mDateDayLabels.clear();
613 mDayLabels =
new TQFrame (mDayLabelsFrame);
614 mLayoutDayLabels =
new TQHBoxLayout(mDayLabels);
615 if ( !mIsSideBySide )
616 mLayoutDayLabels->addSpacing(mTimeLabels->width());
618 const KCalendarSystem*calsys=KOGlobals::self()->calendarSystem();
620 DateList::ConstIterator dit;
621 for( dit = mSelectedDates.begin(); dit != mSelectedDates.end(); ++dit ) {
623 TQBoxLayout *dayLayout =
new TQVBoxLayout(mLayoutDayLabels);
624 mLayoutDayLabels->setStretchFactor(dayLayout, 1);
627 int dW = calsys->dayOfWeek(date);
628 TQString veryLongStr = TDEGlobal::locale()->formatDate( date );
629 TQString longstr = i18n(
"short_weekday date (e.g. Mon 13)",
"%1 %2" )
630 .arg( calsys->weekDayName( dW,
true ) )
631 .arg( calsys->day(date) );
632 TQString shortstr = TQString::number(calsys->day(date));
634 KOAlternateLabel *dayLabel =
new KOAlternateLabel(shortstr,
635 longstr, veryLongStr, mDayLabels);
636 dayLabel->useShortText();
637 dayLabel->setMinimumWidth(1);
638 dayLabel->setAlignment(TQLabel::AlignHCenter);
639 if (date == TQDate::currentDate()) {
640 TQFont font = dayLabel->font();
642 dayLabel->setFont(font);
644 dayLayout->addWidget(dayLabel);
645 mDateDayLabels.append( dayLabel );
648 TQStringList texts = KOGlobals::self()->holiday( date );
649 TQStringList::ConstIterator textit = texts.begin();
650 for ( ; textit != texts.end(); ++textit ) {
652 KOAlternateLabel*label =
new KOAlternateLabel( (*textit), (*textit), TQString(), mDayLabels );
653 label->setMinimumWidth(1);
654 label->setAlignment(AlignCenter);
655 dayLayout->addWidget(label);
658 #ifndef KORG_NOPLUGINS
659 CalendarDecoration::List cds = KOCore::self()->calendarDecorations();
661 for(it = cds.first(); it; it = cds.next()) {
663 if ( !text.isEmpty() ) {
665 KOAlternateLabel*label =
new KOAlternateLabel( text, text, TQString(), mDayLabels );
666 label->setMinimumWidth(1);
667 label->setAlignment(AlignCenter);
668 dayLayout->addWidget(label);
672 for(it = cds.first(); it; it = cds.next()) {
676 dayLayout->addWidget(wid);
682 if ( !mIsSideBySide )
683 mLayoutDayLabels->addSpacing(mAgenda->verticalScrollBar()->width());
685 TQTimer::singleShot( 0,
this, TQ_SLOT( updateDayLabelSizes() ) );
688 void KOAgendaView::enableAgendaUpdate(
bool enable )
690 mAllowAgendaUpdate = enable;
701 return mSelectedDates.count();
706 Incidence::List selected;
709 incidence = mAgenda->selectedIncidence();
710 if (incidence) selected.append(incidence);
712 incidence = mAllDayAgenda->selectedIncidence();
713 if (incidence) selected.append(incidence);
723 qd = mAgenda->selectedIncidenceDate();
724 if (qd.isValid()) selected.append(qd);
726 qd = mAllDayAgenda->selectedIncidenceDate();
727 if (qd.isValid()) selected.append(qd);
735 if ( selectionStart().isValid() ) {
736 TQDateTime start = selectionStart();
737 TQDateTime end = selectionEnd();
739 if ( start.secsTo( end ) == 15*60 ) {
742 TQTime defaultDuration( KOPrefs::instance()->mDefaultDuration.time() );
743 int addSecs = ( defaultDuration.hour()*3600 ) +
744 ( defaultDuration.minute()*60 );
745 end = start.addSecs( addSecs );
750 allDay = selectedIsAllDay();
759 if ( !selectionStart().isValid() || !selectionEnd().isValid() )
return false;
761 if (selectedIsAllDay()) {
762 int days = selectionStart().daysTo(selectionEnd());
765 int secs = selectionStart().secsTo(selectionEnd());
766 return ( secs <= 24*60*60/mAgenda->rows() );
771 void KOAgendaView::updateView()
782 void KOAgendaView::updateConfig()
787 mTimeLabels->updateConfig();
788 mAgenda->updateConfig();
789 mAllDayAgenda->updateConfig();
793 mTimeLabels->positionChanged();
796 mTimeLabels->repaint();
798 updateTimeBarWidth();
801 KOAgendaItem::toolTipGroup()->setEnabled(KOPrefs::instance()
806 createDayLabels(
true );
811 void KOAgendaView::updateTimeBarWidth()
815 width = mDummyAllDayLeft->fontMetrics().width( i18n(
"All Day") );
816 width = TQMAX( width, mTimeLabels->width() );
818 mDummyAllDayLeft->setFixedWidth( width );
819 mTimeLabels->setFixedWidth( width );
822 void KOAgendaView::updateDayLabelSizes()
825 KOAlternateLabel::TextType overallType = KOAlternateLabel::Extensive;
826 TQPtrList<KOAlternateLabel>::const_iterator it = mDateDayLabels.constBegin();
827 for( ; it != mDateDayLabels.constEnd(); it++ ) {
828 KOAlternateLabel::TextType type = (*it)->largestFittingTextType();
829 if ( type < overallType )
834 it = mDateDayLabels.constBegin();
835 for( ; it != mDateDayLabels.constEnd(); it++ ) {
836 (*it)->setFixedType( overallType );
840 void KOAgendaView::resizeEvent( TQResizeEvent *resizeEvent )
842 updateDayLabelSizes();
843 KOrg::AgendaView::resizeEvent( resizeEvent );
848 kdDebug(5850) <<
"KOAgendaView::updateEventDates(): " << item->text()
849 <<
"; item->cellXLeft(): " << item->cellXLeft()
850 <<
"; item->cellYTop(): " << item->cellYTop()
851 <<
"; item->lastMultiItem(): " << item->lastMultiItem()
852 <<
"; item->itemPos(): " << item->itemPos()
853 <<
"; item->itemCount(): " << item->itemCount()
856 TQDateTime startDt, endDt;
863 if ( item->cellXLeft() < 0 ) {
864 thisDate = ( mSelectedDates.first() ).addDays( item->cellXLeft() );
866 thisDate = mSelectedDates[ item->cellXLeft() ];
868 TQDate oldThisDate( item->itemDate() );
869 const int daysOffset = oldThisDate.daysTo( thisDate );
874 Incidence *incidence = item->incidence();
879 !mChanger->beginChange( incidence, resourceCalendar(), subResourceCalendar() ) ) {
884 TQTime startTime( 0, 0, 0 ), endTime( 0, 0, 0 );
886 daysLength = item->cellWidth() - 1;
888 startTime = mAgenda->gyToTime( item->cellYTop() );
889 if ( item->lastMultiItem() ) {
890 endTime = mAgenda->gyToTime( item->lastMultiItem()->cellYBottom() + 1 );
891 daysLength = item->lastMultiItem()->cellXLeft() - item->cellXLeft();
892 kdDebug(5850) <<
"item->lastMultiItem()->cellXLeft(): " << item->lastMultiItem()->cellXLeft()
894 }
else if ( item->itemPos() == item->itemCount() && item->itemCount() > 1 ) {
905 endTime = mAgenda->gyToTime( item->cellYBottom() + 1 );
906 daysLength = item->itemCount() - 1;
907 startTime = incidence->
dtStart().time();
908 }
else if ( item->itemPos() == 1 && item->itemCount() > 1 ) {
910 endTime = incidence->
dtEnd().time();
911 daysLength = item->itemCount() - 1;
913 endTime = mAgenda->gyToTime( item->cellYBottom() + 1 );
917 kdDebug(5850) <<
"daysLength: " << daysLength <<
"; startTime: " << startTime
918 <<
"; endTime: " << endTime <<
"; thisDate: " << thisDate
919 <<
"; incidence->dtStart(): " << incidence->
dtStart() << endl;
922 if ( incidence->type() ==
"Event" ) {
923 startDt = incidence->
dtStart();
924 startDt = startDt.addDays( daysOffset );
925 startDt.setTime( startTime );
926 endDt = startDt.addDays( daysLength );
927 endDt.setTime( endTime );
929 if ( incidence->
dtStart() == startDt && ev->
dtEnd() == endDt ) {
936 }
else if ( incidence->type() ==
"Todo" ) {
937 Todo *td =
static_cast<Todo*
>( incidence );
939 startDt = thisDate.addDays( td->
dtDue().daysTo( startDt ) );
940 startDt.setTime( startTime );
941 endDt.setDate( thisDate );
942 endDt.setTime( endTime );
944 if( td->
dtDue() == endDt ) {
1097 if ( incidence->type() ==
"Event" ) {
1099 static_cast<Event*
>( incidence )->setDtEnd( endDt );
1100 }
else if ( incidence->type() ==
"Todo" ) {
1101 Todo *td =
static_cast<Todo*
>( incidence );
1108 item->setItemDate( startDt.date() );
1110 KOIncidenceToolTip::remove( item );
1113 const bool result = mChanger->changeIncidence( oldIncidence, incidence,
1114 KOGlobals::DATE_MODIFIED,
this );
1115 mChanger->endChange( incidence, resourceCalendar(), subResourceCalendar() );
1116 delete oldIncidence;
1119 mPendingChanges =
true;
1120 TQTimer::singleShot( 0,
this, TQ_SLOT(updateView()) );
1127 enableAgendaUpdate(
false );
1133 mUpdateItem = incidence;
1134 TQTimer::singleShot( 0,
this, TQ_SLOT( doUpdateItem() ) );
1137 enableAgendaUpdate(
true );
1144 if ( mUpdateItem ) {
1145 changeIncidenceDisplay( mUpdateItem, KOGlobals::INCIDENCEEDITED );
1152 void KOAgendaView::showDates(
const TQDate &start,
const TQDate &end )
1155 if ( !mSelectedDates.isEmpty() && mSelectedDates.first() == start
1156 && mSelectedDates.last() == end && !mPendingChanges )
1159 mSelectedDates.clear();
1162 while ( d <= end ) {
1163 mSelectedDates.append( d );
1167 mAreDatesInitialized =
true;
1174 void KOAgendaView::showIncidences(
const Incidence::List &,
const TQDate & )
1176 kdDebug(5850) <<
"KOAgendaView::showIncidences( const Incidence::List & ) is not yet implemented" << endl;
1179 void KOAgendaView::insertIncidence(
Incidence *incidence,
const TQDate &curDate )
1181 if ( !filterByResource( incidence ) ) {
1186 Event *
event =
dynamic_cast<Event *
>( incidence );
1187 Todo *todo =
dynamic_cast<Todo *
>( incidence );
1189 int curCol = mSelectedDates.first().daysTo( curDate );
1197 if ( curCol >=
int( mSelectedDates.count() ) ) {
1202 mMinY[curCol] = mAgenda->timeToY( TQTime( 23, 59 ) ) + 1;
1203 mMaxY[curCol] = mAgenda->timeToY( TQTime( 0, 0 ) ) - 1;
1209 TQDate firstVisibleDate = mSelectedDates.first();
1211 if ( curDate < firstVisibleDate ) {
1212 beginX = curCol + firstVisibleDate.daysTo( curDate );
1213 endX = beginX +
event->
dtStart().daysTo( event->dtEnd() );
1214 columnDate = firstVisibleDate;
1217 endX = beginX +
event->dtStart().daysTo( event->dtEnd() );
1218 columnDate = curDate;
1220 }
else if ( todo ) {
1224 columnDate = curDate;
1225 beginX = endX = curCol;
1231 mAllDayAgenda->insertAllDayItem( incidence, columnDate, curCol, curCol );
1234 !todo->
dtDue().isValid() ) ) {
1235 mAllDayAgenda->insertAllDayItem( incidence, columnDate, beginX, endX );
1236 }
else if ( event && event->isMultiDay() ) {
1237 int startY = mAgenda->timeToY( event->dtStart().time() );
1238 TQTime endtime =
event->dtEnd().time();
1239 if ( endtime == TQTime( 0, 0, 0 ) ) {
1240 endtime = TQTime( 23, 59, 59 );
1242 int endY = mAgenda->timeToY( endtime ) - 1;
1243 if ( ( beginX <= 0 && curCol == 0 ) || beginX == curCol ) {
1244 mAgenda->insertMultiItem( event, columnDate, beginX, endX, startY, endY );
1247 if ( beginX == curCol ) {
1248 mMaxY[curCol] = mAgenda->timeToY( TQTime( 23, 59 ) );
1249 if ( startY < mMinY[curCol] ) {
1250 mMinY[curCol] = startY;
1252 }
else if ( endX == curCol ) {
1253 mMinY[curCol] = mAgenda->timeToY( TQTime( 0, 0 ) );
1254 if ( endY > mMaxY[curCol] ) {
1255 mMaxY[curCol] = endY;
1258 mMinY[curCol] = mAgenda->timeToY( TQTime( 0, 0 ) );
1259 mMaxY[curCol] = mAgenda->timeToY( TQTime( 23, 59 ) );
1262 int startY = 0, endY = 0;
1264 startY = mAgenda->timeToY( incidence->
dtStart().time() );
1265 TQTime endtime =
event->dtEnd().time();
1266 if ( endtime == TQTime( 0, 0, 0 ) ) {
1267 endtime = TQTime( 23, 59, 59 );
1269 endY = mAgenda->timeToY( endtime ) - 1;
1272 TQTime t = todo->
dtDue().time();
1274 if ( t == TQTime( 0, 0 ) ) {
1275 t = TQTime( 23, 59 );
1278 int halfHour = 1800;
1279 if ( t.addSecs( -halfHour ) < t ) {
1280 startY = mAgenda->timeToY( t.addSecs( -halfHour ) );
1281 endY = mAgenda->timeToY( t ) - 1;
1284 endY = mAgenda->timeToY( t.addSecs( halfHour ) ) - 1;
1287 if ( endY < startY ) {
1290 mAgenda->insertItem( incidence, columnDate, curCol, startY, endY, 1, 1 );
1291 if ( startY < mMinY[curCol] ) {
1292 mMinY[curCol] = startY;
1294 if ( endY > mMaxY[curCol] ) {
1295 mMaxY[curCol] = endY;
1300 void KOAgendaView::changeIncidenceDisplayAdded(
Incidence *incidence )
1302 Todo *todo =
dynamic_cast<Todo *
>(incidence);
1303 CalFilter *filter = calendar()->filter();
1305 ( ( todo && !KOPrefs::instance()->showAllDayTodo() ) ) ) {
1309 displayIncidence( incidence );
1312 void KOAgendaView::changeIncidenceDisplay(
Incidence *incidence,
int mode )
1315 case KOGlobals::INCIDENCEADDED:
1322 changeIncidenceDisplayAdded( incidence );
1323 updateEventIndicators();
1326 case KOGlobals::INCIDENCEEDITED:
1328 if ( mAllowAgendaUpdate ) {
1329 removeIncidence( incidence );
1330 changeIncidenceDisplayAdded( incidence );
1332 updateEventIndicators();
1335 case KOGlobals::INCIDENCEDELETED:
1337 removeIncidence( incidence );
1338 updateEventIndicators();
1361 if ( !mAreDatesInitialized ) {
1365 mPendingChanges =
false;
1369 const TQString &selectedAgendaUid = mAgenda->lastSelectedUid();
1370 const TQString &selectedAllDayAgendaUid = mAllDayAgenda->lastSelectedUid();
1372 enableAgendaUpdate(
true );
1375 mAllDayAgenda->changeColumns( mSelectedDates.count() );
1376 mAgenda->changeColumns( mSelectedDates.count() );
1377 mEventIndicatorTop->changeColumns( mSelectedDates.count() );
1378 mEventIndicatorBottom->changeColumns( mSelectedDates.count() );
1380 createDayLabels(
false );
1383 mMinY.resize( mSelectedDates.count() );
1384 mMaxY.resize( mSelectedDates.count() );
1386 mAgenda->setDateList( mSelectedDates );
1388 bool somethingReselected =
false;
1389 Incidence::List incidences = calendar()->incidences();
1391 for ( Incidence::List::ConstIterator it = incidences.begin(); it!=incidences.constEnd(); ++it ) {
1393 displayIncidence( incidence );
1395 if( incidence->
uid() == selectedAgendaUid && !selectedAgendaUid.isNull() ) {
1396 mAgenda->selectItemByUID( incidence->
uid() );
1397 somethingReselected =
true;
1400 if( incidence->
uid() == selectedAllDayAgendaUid && !selectedAllDayAgendaUid.isNull() ) {
1401 mAllDayAgenda->selectItemByUID( incidence->
uid() );
1402 somethingReselected =
true;
1407 mAgenda->checkScrollBoundaries();
1408 updateEventIndicators();
1414 deleteSelectedDateTime();
1416 if( !somethingReselected ) {
1417 emit incidenceSelected( 0, TQDate() );
1421 void KOAgendaView::displayIncidence(
Incidence *incidence )
1423 TQDate today = TQDate::currentDate();
1424 DateTimeList::iterator t;
1427 Todo *todo =
dynamic_cast<Todo *
>( incidence );
1428 Event *
event =
dynamic_cast<Event *
>( incidence );
1430 TQDateTime firstVisibleDateTime = mSelectedDates.first();
1431 TQDateTime lastVisibleDateTime = mSelectedDates.last();
1433 lastVisibleDateTime.setTime( TQTime( 23, 59, 59, 59 ) );
1434 firstVisibleDateTime.setTime( TQTime( 0, 0 ) );
1435 DateTimeList dateTimeList;
1437 TQDateTime incDtStart = incidence->
dtStart();
1438 TQDateTime incDtEnd = incidence->
dtEnd();
1441 ( !KOPrefs::instance()->showAllDayTodo() || !todo->
hasDueDate() ) ) {
1446 int eventDuration =
event ? incDtStart.daysTo( incDtEnd ) : 0;
1451 TQDateTime startDateTimeWithOffset = firstVisibleDateTime.addDays( -eventDuration );
1454 lastVisibleDateTime );
1456 TQDateTime dateToAdd;
1457 TQDateTime incidenceStart;
1458 TQDateTime incidenceEnd;
1462 dateToAdd = todo->
dtDue();
1466 if ( !todo->
doesFloat() && dateToAdd.time() == TQTime( 0, 0 ) ) {
1467 dateToAdd = dateToAdd.addSecs( -1 );
1470 incidenceEnd = dateToAdd;
1471 }
else if ( event ) {
1472 dateToAdd = incDtStart;
1473 incidenceEnd = incDtEnd;
1478 dateToAdd.setTime( TQTime( 0, 0 ) );
1479 incidenceEnd.setTime( TQTime( 23, 59, 59, 59 ) );
1482 if ( dateToAdd <= lastVisibleDateTime && incidenceEnd > firstVisibleDateTime ) {
1483 dateTimeList += dateToAdd;
1488 TQDateTime dateTimeToday = today;
1491 dateTimeToday >= firstVisibleDateTime &&
1492 dateTimeToday <= lastVisibleDateTime ) {
1499 for ( t = dateTimeList.begin(); t != dateTimeList.end(); ++t ) {
1500 if ( (*t).date() == today ) {
1508 dateTimeList += dateTimeToday;
1512 for ( t = dateTimeList.begin(); t != dateTimeList.end(); ++t ) {
1513 insertIncidence( incidence, (*t).date() );
1520 mAllDayAgenda->clear();
1524 CalPrinterBase::PrintType KOAgendaView::printType()
1526 if ( currentDateCount() == 1 )
return CalPrinterBase::Day;
1527 else return CalPrinterBase::Week;
1530 void KOAgendaView::updateEventIndicatorTop(
int newY )
1533 for( i = 0; i < mMinY.size(); ++i ) {
1534 mEventIndicatorTop->enableColumn( i, newY > mMinY[i] );
1536 mEventIndicatorTop->update();
1539 void KOAgendaView::updateEventIndicatorBottom(
int newY )
1542 for( i = 0; i < mMaxY.size(); ++i ) {
1543 mEventIndicatorBottom->enableColumn( i, newY <= mMaxY[i] );
1545 mEventIndicatorBottom->update();
1550 if ( gpos.x()<0 || gpos.y()<0 )
return;
1551 TQDate day = mSelectedDates[gpos.x()];
1552 TQTime time = mAgenda->gyToTime( gpos.y() );
1553 TQDateTime newTime( day, time );
1556 Todo *existingTodo = calendar()->todo( todo->
uid() );
1557 if ( existingTodo ) {
1558 kdDebug(5850) <<
"Drop existing Todo" << endl;
1561 mChanger->beginChange( existingTodo, resourceCalendar(), subResourceCalendar() ) ) {
1565 mChanger->changeIncidence( oldTodo, existingTodo,
1566 KOGlobals::DATE_MODIFIED,
this );
1567 mChanger->endChange( existingTodo, resourceCalendar(), subResourceCalendar() );
1569 KMessageBox::sorry(
this, i18n(
"Unable to modify this to-do, "
1570 "because it cannot be locked.") );
1574 kdDebug(5850) <<
"Drop new Todo" << endl;
1578 if ( !mChanger->addIncidence( todo, 0, TQString(),
this ) ) {
1579 KODialogManager::errorSaveIncidence(
this, todo );
1585 void KOAgendaView::startDrag(
Incidence *incidence )
1589 ICalDrag *vd = factory.createDrag( incidence,
this );
1591 kdDebug(5850) <<
"KOAgendaView::startDrag(): Delete drag source" << endl;
1596 void KOAgendaView::readSettings()
1598 readSettings(KOGlobals::self()->config());
1601 void KOAgendaView::readSettings(TDEConfig *config)
1605 config->setGroup(
"Views");
1607 #ifndef KORG_NOSPLITTER
1608 TQValueList<int> sizes = config->readIntListEntry(
"Separator AgendaView");
1609 if (sizes.count() == 2) {
1610 mSplitterAgenda->setSizes(sizes);
1617 void KOAgendaView::writeSettings(TDEConfig *config)
1621 config->setGroup(
"Views");
1623 #ifndef KORG_NOSPLITTER
1624 TQValueList<int> list = mSplitterAgenda->sizes();
1625 config->writeEntry(
"Separator AgendaView",list);
1631 if ( mSelectedDates.isEmpty() || !mSelectedDates[0].isValid() ) {
1635 mHolidayMask.resize( mSelectedDates.count() + 1 );
1637 for( uint i = 0; i < mSelectedDates.count(); ++i ) {
1638 mHolidayMask[i] = !KOGlobals::self()->isWorkDay( mSelectedDates[ i ] );
1643 bool showDay = !KOGlobals::self()->isWorkDay( mSelectedDates[ 0 ].addDays( -1 ) );
1644 mHolidayMask[ mSelectedDates.count() ] = showDay;
1646 mAgenda->setHolidayMask( &mHolidayMask );
1647 mAllDayAgenda->setHolidayMask( &mHolidayMask );
1650 void KOAgendaView::setContentsPos(
int y )
1652 mAgenda->setContentsPos( 0, y );
1655 void KOAgendaView::setExpandedButton(
bool expanded )
1657 if ( !mExpandButton )
return;
1660 mExpandButton->setPixmap( mExpandedPixmap );
1662 mExpandButton->setPixmap( mNotExpandedPixmap );
1666 void KOAgendaView::clearSelection()
1668 mAgenda->deselectItem();
1669 mAllDayAgenda->deselectItem();
1674 newTimeSpanSelected( start, end );
1675 mTimeSpanInAllDay =
true;
1680 if (!mSelectedDates.count())
return;
1682 mTimeSpanInAllDay =
false;
1684 TQDate dayStart = mSelectedDates[ kClamp( start.x(), 0, (
int)mSelectedDates.size() - 1 ) ];
1685 TQDate dayEnd = mSelectedDates[ kClamp( end.x(), 0, (
int)mSelectedDates.size() - 1 ) ];
1687 TQTime timeStart = mAgenda->gyToTime(start.y());
1688 TQTime timeEnd = mAgenda->gyToTime( end.y() + 1 );
1690 TQDateTime dtStart(dayStart,timeStart);
1691 TQDateTime dtEnd(dayEnd,timeEnd);
1693 mTimeSpanBegin = dtStart;
1694 mTimeSpanEnd = dtEnd;
1699 mTimeSpanBegin.setDate(TQDate());
1700 mTimeSpanEnd.setDate(TQDate());
1701 mTimeSpanInAllDay =
false;
1704 void KOAgendaView::setTypeAheadReceiver( TQObject *o )
1706 mAgenda->setTypeAheadReceiver( o );
1707 mAllDayAgenda->setTypeAheadReceiver( o );
1710 void KOAgendaView::finishTypeAhead()
1712 mAgenda->finishTypeAhead();
1713 mAllDayAgenda->finishTypeAhead();
1716 void KOAgendaView::removeIncidence(
Incidence *incidence )
1718 mAgenda->removeIncidence( incidence );
1719 mAllDayAgenda->removeIncidence( incidence );
1724 mMinY = mAgenda->minContentsY();
1725 mMaxY = mAgenda->maxContentsY();
1727 mAgenda->checkScrollBoundaries();
1728 updateEventIndicatorTop( mAgenda->visibleContentsYMin() );
1729 updateEventIndicatorBottom( mAgenda->visibleContentsYMax() );
1732 void KOAgendaView::setIncidenceChanger( IncidenceChangerBase *changer )
1735 mAgenda->setIncidenceChanger( changer );
1736 mAllDayAgenda->setIncidenceChanger( changer );
1739 void KOAgendaView::clearTimeSpanSelection()
1741 mAgenda->clearSelection();
1742 mAllDayAgenda->clearSelection();
1743 deleteSelectedDateTime();
1746 bool KOAgendaView::filterByResource(
Incidence *incidence )
1752 if ( resourceCalendar() && incidence->type() ==
"Todo" ) {
1753 TQString subRes = resourceCalendar()->subresourceIdentifier( incidence );
1754 if ( resourceCalendar()->subresourceType( subRes ) ==
"todo" ) {
1755 TQString calmatch =
"/.INBOX.directory/Calendar";
1756 TQString i18nmatch =
"/.INBOX.directory/" + i18n(
"Calendar" );
1757 if ( subResourceCalendar().contains( calmatch ) ||
1758 subResourceCalendar().contains( i18nmatch ) ) {
1765 if ( !resourceCalendar() )
1770 if ( calRes->
resource( incidence ) != resourceCalendar() )
1772 if ( !subResourceCalendar().isEmpty() ) {
1773 if ( resourceCalendar()->subresourceIdentifier( incidence ) != subResourceCalendar() )
1779 void KOAgendaView::resourcesChanged()
1781 mPendingChanges =
true;
1784 void KOAgendaView::calendarIncidenceAdded(
Incidence * incidence)
1786 Q_UNUSED( incidence );
1787 mPendingChanges =
true;
1790 void KOAgendaView::calendarIncidenceChanged(
Incidence * incidence)
1792 Q_UNUSED( incidence );
1793 mPendingChanges =
true;
1796 void KOAgendaView::calendarIncidenceDeleted(
Incidence * incidence)
1798 Q_UNUSED( incidence );
1799 mPendingChanges =
true;