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()
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()) );
431 connect( agenda, TQ_SIGNAL(newStartSelectSignal()),
432 otherAgenda, TQ_SLOT(clearSelection()) );
433 connect( agenda, TQ_SIGNAL(newStartSelectSignal()),
434 TQ_SIGNAL(timeSpanSelectionChanged()) );
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 *)),
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)),
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);
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 );
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()
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();
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 );
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);
1305 ( ( todo && !KOPrefs::instance()->showAllDayTodo() ) ) ) {
1309 displayIncidence( incidence );
1312 void KOAgendaView::changeIncidenceDisplay(
Incidence *incidence,
int mode )
1315 case KOGlobals::INCIDENCEADDED:
1322 changeIncidenceDisplayAdded( incidence );
1326 case KOGlobals::INCIDENCEEDITED:
1328 if ( mAllowAgendaUpdate ) {
1329 removeIncidence( incidence );
1330 changeIncidenceDisplayAdded( incidence );
1335 case KOGlobals::INCIDENCEDELETED:
1337 removeIncidence( incidence );
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() );
1383 mMinY.resize( mSelectedDates.count() );
1384 mMaxY.resize( mSelectedDates.count() );
1386 mAgenda->setDateList( mSelectedDates );
1388 bool somethingReselected =
false;
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();
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()
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 );
1557 if ( existingTodo ) {
1558 kdDebug(5850) <<
"Drop existing Todo" << endl;
1565 mChanger->changeIncidence( oldTodo, existingTodo,
1566 KOGlobals::DATE_MODIFIED,
this );
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();
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();
1746 bool KOAgendaView::filterByResource(
Incidence *incidence )
1755 TQString calmatch =
"/.INBOX.directory/Calendar";
1756 TQString i18nmatch =
"/.INBOX.directory/" + i18n(
"Calendar" );
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;
This is the main calendar widget.
bool filterIncidence(Incidence *) const
ResourceCalendar * resource(Incidence *incidence)
virtual Incidence::List incidences()
virtual Todo * todo(const TQString &uid)=0
void registerObserver(Observer *observer)
void unregisterObserver(Observer *observer)
virtual TQDateTime dtEnd() const
void setDtEnd(const TQDateTime &dtEnd)
virtual TQDateTime dtStart() const
virtual Incidence * clone()=0
virtual TQDateTime dtEnd() const
virtual void setDtStart(const TQDateTime &dtStart)
Recurrence * recurrence() const
DateTimeList timesInInterval(const TQDateTime &start, const TQDateTime &end) const
virtual TQString subresourceIdentifier(Incidence *incidence)
bool hasStartDate() const
void setDtDue(const TQDateTime &dtDue, bool first=false)
TQDateTime dtStart(bool first=false) const
void setDtStart(const TQDateTime &dtStart)
TQDateTime dtDue(bool first=false) const
void setHasDueDate(bool hasDueDate)
bool selectedIsSingleCell()
returns if only a single cell is selected, or a range of cells
void doUpdateItem()
update just the display of the given incidence, called by a single-shot timer
void newTimeSpanSelectedAllDay(const TQPoint &start, const TQPoint &end)
Updates data for selected timespan for all day event.
void fillAgenda()
Fill agenda using the current set value for the start date.
TQDateTime selectionEnd()
end-datetime of selection
virtual int maxDatesHint()
Returns maximum number of days supported by the koagendaview.
void clearView()
Remove all events from view.
void createDayLabels(bool force)
Create labels for the selected dates.
void updateEventIndicators()
Updates the event indicators after a certain incidence was modified or removed.
void setHolidayMasks()
Set the masks on the agenda widgets indicating, which days are holidays.
TQDateTime selectionStart()
start-datetime of selection
void updateEventDates(KOAgendaItem *item)
Update event belonging to agenda item.
virtual DateList selectedIncidenceDates()
returns the currently selected events
void newTimeSpanSelected(const TQPoint &start, const TQPoint &end)
Updates data for selected timespan.
virtual int currentDateCount()
Returns number of currently shown dates.
void slotTodoDropped(Todo *, const TQPoint &, bool)
reschedule the todo to the given x- and y- coordinates.
virtual bool eventDurationHint(TQDateTime &startDt, TQDateTime &endDt, bool &allDay)
return the default start/end date/time for new events
void deleteSelectedDateTime()
make selected start/end invalid
virtual Incidence::List selectedIncidences()
returns the currently selected events
bool selectedIsAllDay()
returns true if selection is for whole day
Base class for single/multi agenda views.
void editIncidenceSignal(Incidence *, const TQDate &)
instructs the receiver to begin editing the incidence specified in some manner.
ResourceCalendar * resourceCalendar()
Return resourceCalendar of this view.
void deleteIncidenceSignal(Incidence *)
instructs the receiver to delete the Incidence in some manner; some possibilities include automatical...
void newEventSignal(ResourceCalendar *res, const TQString &subResource)
instructs the receiver to create a new event.
TQString subResourceCalendar() const
Return subResourceCalendar of this view.
void showIncidenceSignal(Incidence *, const TQDate &)
instructs the receiver to show the incidence in read-only mode.
virtual Calendar * calendar()
Return calendar object of this view.
This class provides the interface for a date dependent decoration.
virtual TQString shortText(const TQDate &)
Return a short text for a given date, ususally only a few words.
virtual TQWidget * smallWidget(TQWidget *, const TQDate &)
Return a small widget.