30#ifndef KORG_NOSPLITTER
31#include <tqsplitter.h>
34#include <tqfontmetrics.h>
35#include <tqpopupmenu.h>
38#include <tqpushbutton.h>
40#include <tqbitarray.h>
42#include <tdeapplication.h>
44#include <tdestandarddirs.h>
45#include <kiconloader.h>
49#include <tdeglobalsettings.h>
53#include <libkcal/icaldrag.h>
54#include <libkcal/dndfactory.h>
55#include <libkcal/calfilter.h>
57#include <kcalendarsystem.h>
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"
79EventIndicator::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());
92EventIndicator::~EventIndicator()
96void 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);
114void EventIndicator::changeColumns(
int columns)
117 mEnabled.resize(mColumns);
122void EventIndicator::enableColumn(
int column,
bool enable)
124 mEnabled[column] = enable;
128#include <libkcal/incidence.h>
135KOAlternateLabel::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();
145KOAlternateLabel::~KOAlternateLabel()
149void KOAlternateLabel::useShortText()
151 mTextTypeFixed =
true;
152 TQLabel::setText( mShortText );
153 TQToolTip::remove(
this );
154 TQToolTip::add(
this, mExtensiveText );
158void KOAlternateLabel::useLongText()
160 mTextTypeFixed =
true;
161 TQLabel::setText( mLongText );
162 TQToolTip::remove(
this );
163 TQToolTip::add(
this, mExtensiveText );
167void KOAlternateLabel::useExtensiveText()
169 mTextTypeFixed =
true;
170 TQLabel::setText( mExtensiveText );
171 TQToolTip::remove(
this );
172 TQToolTip::add(
this,
"" );
176void KOAlternateLabel::useDefaultText()
178 mTextTypeFixed =
false;
179 squeezeTextToLabel();
182KOAlternateLabel::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 )
196void KOAlternateLabel::setFixedType( TextType type )
200 case Extensive: useExtensiveText();
break;
201 case Long: useLongText();
break;
202 case Short: useShortText();
break;
206void 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 );
233void KOAlternateLabel::resizeEvent( TQResizeEvent * )
235 squeezeTextToLabel();
238TQSize KOAlternateLabel::minimumSizeHint()
const
240 TQSize sh = TQLabel::minimumSizeHint();
249KOAgendaView::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);
405KOAgendaView::~KOAgendaView()
410 delete mAllDayAgendaPopup;
413void 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()) );
427 connect( agenda, TQ_SIGNAL(newStartSelectSignal()),
428 otherAgenda, TQ_SLOT(clearSelection()) );
429 connect( agenda, TQ_SIGNAL(newStartSelectSignal()),
430 TQ_SIGNAL(timeSpanSelectionChanged()) );
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 *)),
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)),
466void KOAgendaView::zoomInVertically( )
468 if ( !mIsSideBySide )
469 KOPrefs::instance()->mHourSize++;
470 mAgenda->updateConfig();
471 mAgenda->checkScrollBoundaries();
473 mTimeLabels->updateConfig();
474 mTimeLabels->positionChanged();
475 mTimeLabels->repaint();
480void 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();
498void 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 );
530void 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 );
559void 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() ) );
684void 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);
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 );
762 return ( secs <= 24*60*60/mAgenda->rows() );
767void KOAgendaView::updateView()
778void 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()
807void KOAgendaView::updateTimeBarWidth()
811 width = mDummyAllDayLeft->fontMetrics().width( i18n(
"All Day") );
812 width = TQMAX( width, mTimeLabels->width() );
814 mDummyAllDayLeft->setFixedWidth( width );
815 mTimeLabels->setFixedWidth( width );
818void 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 );
836void 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();
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 );
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 );
1148void 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;
1170void KOAgendaView::showIncidences(
const Incidence::List &,
const TQDate & )
1172 kdDebug(5850) <<
"KOAgendaView::showIncidences( const Incidence::List & ) is not yet implemented" << endl;
1175void 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;
1296void KOAgendaView::changeIncidenceDisplayAdded(
Incidence *incidence )
1298 Todo *todo =
dynamic_cast<Todo *
>(incidence);
1301 ( ( todo && !KOPrefs::instance()->showAllDayTodo() ) ) ) {
1305 displayIncidence( incidence );
1308void KOAgendaView::changeIncidenceDisplay(
Incidence *incidence,
int mode )
1311 case KOGlobals::INCIDENCEADDED:
1318 changeIncidenceDisplayAdded( incidence );
1322 case KOGlobals::INCIDENCEEDITED:
1324 if ( mAllowAgendaUpdate ) {
1325 removeIncidence( incidence );
1326 changeIncidenceDisplayAdded( incidence );
1331 case KOGlobals::INCIDENCEDELETED:
1333 removeIncidence( incidence );
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() );
1379 mMinY.resize( mSelectedDates.count() );
1380 mMaxY.resize( mSelectedDates.count() );
1382 mAgenda->setDateList( mSelectedDates );
1384 bool somethingReselected =
false;
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();
1412 if( !somethingReselected ) {
1413 emit incidenceSelected( 0, TQDate() );
1417void 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();
1520CalPrinterBase::PrintType KOAgendaView::printType()
1523 else return CalPrinterBase::Week;
1526void KOAgendaView::updateEventIndicatorTop(
int newY )
1529 for( i = 0; i < mMinY.size(); ++i ) {
1530 mEventIndicatorTop->enableColumn( i, newY > mMinY[i] );
1532 mEventIndicatorTop->update();
1535void 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 );
1553 if ( existingTodo ) {
1554 kdDebug(5850) <<
"Drop existing Todo" << endl;
1561 mChanger->changeIncidence( oldTodo, existingTodo,
1562 KOGlobals::DATE_MODIFIED,
this );
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 );
1581void KOAgendaView::startDrag(
Incidence *incidence )
1585 ICalDrag *vd = factory.createDrag( incidence,
this );
1587 kdDebug(5850) <<
"KOAgendaView::startDrag(): Delete drag source" << endl;
1592void KOAgendaView::readSettings()
1594 readSettings(KOGlobals::self()->config());
1597void 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);
1613void 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 );
1646void KOAgendaView::setContentsPos(
int y )
1648 mAgenda->setContentsPos( 0, y );
1651void KOAgendaView::setExpandedButton(
bool expanded )
1653 if ( !mExpandButton )
return;
1656 mExpandButton->setPixmap( mExpandedPixmap );
1658 mExpandButton->setPixmap( mNotExpandedPixmap );
1662void KOAgendaView::clearSelection()
1664 mAgenda->deselectItem();
1665 mAllDayAgenda->deselectItem();
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;
1700void KOAgendaView::setTypeAheadReceiver( TQObject *o )
1702 mAgenda->setTypeAheadReceiver( o );
1703 mAllDayAgenda->setTypeAheadReceiver( o );
1706void KOAgendaView::finishTypeAhead()
1708 mAgenda->finishTypeAhead();
1709 mAllDayAgenda->finishTypeAhead();
1712void 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() );
1728void KOAgendaView::setIncidenceChanger( IncidenceChangerBase *changer )
1731 mAgenda->setIncidenceChanger( changer );
1732 mAllDayAgenda->setIncidenceChanger( changer );
1735void KOAgendaView::clearTimeSpanSelection()
1737 mAgenda->clearSelection();
1738 mAllDayAgenda->clearSelection();
1742bool KOAgendaView::filterByResource(
Incidence *incidence )
1751 TQString calmatch =
"/.INBOX.directory/Calendar";
1752 TQString i18nmatch =
"/.INBOX.directory/" + i18n(
"Calendar" );
1775void KOAgendaView::resourcesChanged()
1777 mPendingChanges =
true;
1780void KOAgendaView::calendarIncidenceAdded(
Incidence * incidence)
1782 Q_UNUSED( incidence );
1783 mPendingChanges =
true;
1786void KOAgendaView::calendarIncidenceChanged(
Incidence * incidence)
1788 Q_UNUSED( incidence );
1789 mPendingChanges =
true;
1792void KOAgendaView::calendarIncidenceDeleted(
Incidence * incidence)
1794 Q_UNUSED( incidence );
1795 mPendingChanges =
true;
This is the main calendar widget.
bool filterIncidence(Incidence *) const
ResourceCalendar * resource(Incidence *incidence)
virtual Incidence::List incidences()
void registerObserver(Observer *observer)
virtual Todo * todo(const TQString &uid)=0
void unregisterObserver(Observer *observer)
virtual TQDateTime dtEnd() const
void setDtEnd(const TQDateTime &dtEnd)
virtual TQDateTime dtStart() const
virtual TQDateTime dtEnd() const
virtual Incidence * clone()=0
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.
virtual Calendar * calendar()
Return calendar object of this view.
void editIncidenceSignal(Incidence *, const TQDate &)
instructs the receiver to begin editing the incidence specified in some manner.
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.
ResourceCalendar * resourceCalendar()
Return resourceCalendar of this view.
This class provides the interface for a date dependent decoration.
virtual TQWidget * smallWidget(TQWidget *, const TQDate &)
Return a small widget.
virtual TQString shortText(const TQDate &)
Return a short text for a given date, ususally only a few words.