korganizer

kodaymatrix.cpp
1/*
2 This file is part of KOrganizer.
3
4 Copyright (c) 2001 Eitzenberger Thomas <thomas.eitzenberger@siemens.at>
5 Parts of the source code have been copied from kdpdatebutton.cpp
6
7 Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
8 Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23
24 As a special exception, permission is given to link this program
25 with any edition of TQt, and distribute the resulting executable,
26 without including the source code for TQt in the source distribution.
27*/
28
29#include <tqevent.h>
30#include <tqpainter.h>
31#include <tqptrlist.h>
32
33#include <tdeglobal.h>
34#include <kdebug.h>
35#include <tdelocale.h>
36#include <kiconloader.h>
37
38#include <libkcal/vcaldrag.h>
39#include <libkcal/icaldrag.h>
40#include <libkcal/dndfactory.h>
42#include <libkcal/resourcecalendar.h>
43
44#include <kcalendarsystem.h>
45
46#include "koprefs.h"
47#include "koglobals.h"
48#include "kodialogmanager.h"
49
50#include "kodaymatrix.h"
51#include "kodaymatrix.moc"
52
53#ifndef NODND
54#include <tqcursor.h>
55#include <tdepopupmenu.h>
56#include <X11/Xlib.h>
57#undef FocusIn
58#undef KeyPress
59#undef None
60#undef Status
61#endif
62
63// ============================================================================
64// D Y N A M I C T I P
65// ============================================================================
66
67DynamicTip::DynamicTip( TQWidget * parent )
68 : TQToolTip( parent )
69{
70 mMatrix = static_cast<KODayMatrix *>( parent );
71}
72
73
74void DynamicTip::maybeTip( const TQPoint &pos )
75{
76 //calculate which cell of the matrix the mouse is in
77 TQRect sz = mMatrix->frameRect();
78 int dheight = sz.height() * 7 / 42;
79 int dwidth = sz.width() / 7;
80 int row = pos.y() / dheight;
81 int col = pos.x() / dwidth;
82
83 TQRect rct( col * dwidth, row * dheight, dwidth, dheight );
84
85// kdDebug(5850) << "DynamicTip::maybeTip matrix cell index [" <<
86// col << "][" << row << "] => " <<(col+row*7) << endl;
87
88 //show holiday names only
89 TQString str = mMatrix->getHolidayLabel( col + row * 7 );
90 if ( str.isEmpty() ) return;
91 tip( rct, str );
92}
93
94
95// ============================================================================
96// K O D A Y M A T R I X
97// ============================================================================
98
99const int KODayMatrix::NOSELECTION = -1000;
100const int KODayMatrix::NUMDAYS = 42;
101
102KODayMatrix::KODayMatrix( TQWidget *parent, const char *name )
103 : TQFrame( parent, name ), mCalendar( 0 ), mStartDate(), mPendingChanges( false )
104{
105 // initialize dynamic arrays
106 mDays = new TQDate[ NUMDAYS ];
107 mDayLabels = new TQString[ NUMDAYS ];
108 mEvents = new int[ NUMDAYS ];
109 mToolTip = new DynamicTip( this );
110
111 mTodayMarginWidth = 2;
112 mSelEnd = mSelStart = NOSELECTION;
113 setBackgroundMode( NoBackground );
115}
116
118{
119 if ( mCalendar ) {
120 mCalendar->unregisterObserver( this );
121 mCalendar->disconnect( this );
122 }
123
124 mCalendar = cal;
125 mCalendar->registerObserver( this );
126 CalendarResources *calres = dynamic_cast<CalendarResources*>( cal );
127 if ( calres ) {
128 connect( calres, TQ_SIGNAL(signalResourceAdded(ResourceCalendar *)), TQ_SLOT(resourcesChanged()) );
129 connect( calres, TQ_SIGNAL(signalResourceModified( ResourceCalendar *)), TQ_SLOT(resourcesChanged()) );
130 connect( calres, TQ_SIGNAL(signalResourceDeleted(ResourceCalendar *)), TQ_SLOT(resourcesChanged()) );
131 }
132
133 setAcceptDrops( mCalendar );
134
135 updateEvents();
136}
137
138TQColor KODayMatrix::getShadedColor( const TQColor &color )
139{
140 TQColor shaded;
141 int h = 0;
142 int s = 0;
143 int v = 0;
144 color.hsv( &h, &s, &v );
145 s = s / 4;
146 v = 192 + v / 4;
147 shaded.setHsv( h, s, v );
148
149 return shaded;
150}
151
153{
154 if ( mCalendar )
155 mCalendar->unregisterObserver( this );
156 delete [] mDays;
157 delete [] mDayLabels;
158 delete [] mEvents;
159 delete mToolTip;
160}
161
162void KODayMatrix::addSelectedDaysTo( DateList &selDays )
163{
164 kdDebug(5850) << "KODayMatrix::addSelectedDaysTo() - " << "mSelStart:" << mSelStart << endl;
165
166 if ( mSelStart == NOSELECTION ) {
167 return;
168 }
169
170 // cope with selection being out of matrix limits at top (< 0)
171 int i0 = mSelStart;
172 if ( i0 < 0 ) {
173 for ( int i = i0; i < 0; i++ ) {
174 selDays.append( mDays[ 0 ].addDays( i ) );
175 }
176 i0 = 0;
177 }
178
179 // cope with selection being out of matrix limits at bottom (> NUMDAYS-1)
180 if ( mSelEnd > NUMDAYS-1 ) {
181 for ( int i = i0; i <= NUMDAYS - 1; i++ ) {
182 selDays.append( mDays[ i ] );
183 }
184 for ( int i = NUMDAYS; i < mSelEnd; i++ ) {
185 selDays.append( mDays[ 0 ].addDays( i ) );
186 }
187 } else {
188 // apply normal routine to selection being entirely within matrix limits
189 for ( int i = i0; i <= mSelEnd; i++ ) {
190 selDays.append( mDays[ i ] );
191 }
192 }
193}
194
195void KODayMatrix::setSelectedDaysFrom( const TQDate &start, const TQDate &end )
196{
197 if ( mStartDate.isValid() ) {
198 mSelStart = mStartDate.daysTo( start );
199 mSelEnd = mStartDate.daysTo( end );
200 }
201}
202
204{
205 mSelEnd = mSelStart = NOSELECTION;
206}
207
209{
210 if ( !mStartDate.isValid() ) return;
211 mToday = -1;
212 for ( int i = 0; i < NUMDAYS; i++ ) {
213 mDays[ i ] = mStartDate.addDays( i );
214 mDayLabels[ i ] = TQString::number( KOGlobals::self()->calendarSystem()->day( mDays[i] ));
215
216 // if today is in the currently displayed month, hilight today
217 if ( mDays[ i ].year() == TQDate::currentDate().year() &&
218 mDays[ i ].month() == TQDate::currentDate().month() &&
219 mDays[ i ].day() == TQDate::currentDate().day() ) {
220 mToday = i;
221 }
222 }
223 // kdDegug(5850) << "Today is visible at "<< today << "." << endl;
224}
225
226/* slot */ void KODayMatrix::updateView()
227{
228 updateView( mStartDate );
229}
230
231void KODayMatrix::setUpdateNeeded()
232{
233 mPendingChanges = true;
234}
235
236void KODayMatrix::updateView( const TQDate &actdate )
237{
238 kdDebug(5850) << "KODayMatrix::updateView() " << actdate << ", day start="<<mStartDate<< endl;
239 if ( !actdate.isValid() ) return;
240 //flag to indicate if the starting day of the matrix has changed by this call
241 bool daychanged = false;
242
243 // if a new startdate is to be set then apply Cornelius's calculation
244 // of the first day to be shown
245 if ( actdate != mStartDate ) {
246 // reset index of selection according to shift of starting date from startdate to actdate
247 if ( mSelStart != NOSELECTION ) {
248 int tmp = actdate.daysTo( mStartDate );
249 //kdDebug(5850) << "Shift of Selection1: " << mSelStart << " - " << mSelEnd << " -> " << tmp << "(" << offset << ")" << endl;
250 // shift selection if new one would be visible at least partly !
251
252 if ( mSelStart + tmp < NUMDAYS && mSelEnd + tmp >= 0 ) {
253 // nested if is required for next X display pushed from a different month - correction required
254 // otherwise, for month forward and backward, it must be avoided
255 if( mSelStart > NUMDAYS || mSelStart < 0 )
256 mSelStart = mSelStart + tmp;
257 if( mSelEnd > NUMDAYS || mSelEnd < 0 )
258 mSelEnd = mSelEnd + tmp;
259 }
260 }
261
262 mStartDate = actdate;
263 daychanged = true;
264 }
265
266 if ( daychanged ) {
268 }
269
270 // the calendar hasn't changed in the meantime and the selected range is still the same
271 // so we can safe the expensive updateEvents() call
272 if ( !daychanged && !mPendingChanges )
273 return;
274
275 // TODO_Recurrence: If we just change the selection, but not the data, there's
276 // no need to update the whole list of events... This is just a waste of
277 // computational power (and it takes forever!)
278 updateEvents();
279 for( int i = 0; i < NUMDAYS; i++ ) {
280 //if it is a holy day then draw it red. Sundays are consider holidays, too
281 TQStringList holidays = KOGlobals::self()->holiday( mDays[ i ] );
282 TQString holiStr = TQString();
283
284 if ( ( KOGlobals::self()->calendarSystem()->dayOfWeek( mDays[ i ] ) ==
285 KOGlobals::self()->calendarSystem()->weekDayOfPray() ) ||
286 !holidays.isEmpty() ) {
287 if ( !holidays.isEmpty() ) holiStr = holidays.join( i18n("delimiter for joining holiday names", ", " ) );
288 if ( holiStr.isNull() ) holiStr = "";
289 }
290 mHolidays[ i ] = holiStr;
291 }
292}
293
295{
296 kdDebug( 5850 ) << k_funcinfo << endl;
297 if ( !mCalendar ) return;
298
299 for( int i = 0; i < NUMDAYS; i++ ) {
300 // if events are set for the day then remember to draw it bold
301 Event::List eventlist = mCalendar->events( mDays[ i ] );
302 int numEvents = eventlist.count();
303 Event::List::ConstIterator it;
304 for( it = eventlist.begin(); it != eventlist.end(); ++it ) {
305 Event *event = *it;
306 ushort recurType = event->recurrenceType();
307 if ( ( recurType == Recurrence::rDaily &&
308 !KOPrefs::instance()->mDailyRecur ) ||
309 ( recurType == Recurrence::rWeekly &&
310 !KOPrefs::instance()->mWeeklyRecur ) ) {
311 numEvents--;
312 }
313 }
314 mEvents[ i ] = numEvents;
315 }
316
317 mPendingChanges = false;
318}
319
320const TQDate& KODayMatrix::getDate( int offset )
321{
322 if ( offset < 0 || offset > NUMDAYS - 1 ) {
323 kdDebug(5850) << "Wrong offset (" << offset << ") in KODayMatrix::getDate(int)" << endl;
324 return mDays[ 0 ];
325 }
326 return mDays[ offset ];
327}
328
329TQString KODayMatrix::getHolidayLabel( int offset )
330{
331 if ( offset < 0 || offset > NUMDAYS - 1 ) {
332 kdDebug(5850) << "Wrong offset (" << offset << ") in KODayMatrix::getHolidayLabel(int)" << endl;
333 return 0;
334 }
335 return mHolidays[ offset ];
336}
337
338int KODayMatrix::getDayIndexFrom( int x, int y )
339{
340 return 7 * ( y / mDaySize.height() ) +
341 ( KOGlobals::self()->reverseLayout() ?
342 6 - x / mDaySize.width() : x / mDaySize.width() );
343}
344
345void KODayMatrix::calendarIncidenceAdded(Incidence * incidence)
346{
347 Q_UNUSED( incidence );
348 mPendingChanges = true;
349}
350
351void KODayMatrix::calendarIncidenceChanged(Incidence * incidence)
352{
353 Q_UNUSED( incidence );
354 mPendingChanges = true;
355}
356
357void KODayMatrix::calendarIncidenceDeleted(Incidence * incidence)
358{
359 Q_UNUSED( incidence );
360 mPendingChanges = true;
361}
362
364{
365 mPendingChanges = true;
366}
367
368
369// ----------------------------------------------------------------------------
370// M O U S E E V E N T H A N D L I N G
371// ----------------------------------------------------------------------------
372
373void KODayMatrix::mousePressEvent( TQMouseEvent *e )
374{
375 mSelStart = getDayIndexFrom(e->x(), e->y());
376 if (mSelStart > NUMDAYS-1) mSelStart=NUMDAYS-1;
377 mSelInit = mSelStart;
378}
379
380void KODayMatrix::mouseReleaseEvent( TQMouseEvent *e )
381{
382 int tmp = getDayIndexFrom(e->x(), e->y());
383 if (tmp > NUMDAYS-1) tmp=NUMDAYS-1;
384
385 if (mSelInit > tmp) {
386 mSelEnd = mSelInit;
387 if (tmp != mSelStart) {
388 mSelStart = tmp;
389 repaint();
390 }
391 } else {
392 mSelStart = mSelInit;
393
394 //repaint only if selection has changed
395 if (tmp != mSelEnd) {
396 mSelEnd = tmp;
397 repaint();
398 }
399 }
400
401 DateList daylist;
402 if ( mSelStart < 0 ) mSelStart = 0;
403 for ( int i = mSelStart; i <= mSelEnd; ++i ) {
404 daylist.append( mDays[i] );
405 }
406 emit selected((const DateList)daylist);
407}
408
409void KODayMatrix::mouseMoveEvent( TQMouseEvent *e )
410{
411 int tmp = getDayIndexFrom(e->x(), e->y());
412 if (tmp > NUMDAYS-1) tmp=NUMDAYS-1;
413
414 if (mSelInit > tmp) {
415 mSelEnd = mSelInit;
416 if ( tmp != mSelStart ) {
417 mSelStart = tmp;
418 repaint();
419 }
420 } else {
421 mSelStart = mSelInit;
422
423 //repaint only if selection has changed
424 if ( tmp != mSelEnd ) {
425 mSelEnd = tmp;
426 repaint();
427 }
428 }
429}
430
431// ----------------------------------------------------------------------------
432// D R A G ' N D R O P H A N D L I N G
433// ----------------------------------------------------------------------------
434
435//-----------------------------------------------------------------------------
436// Drag and Drop handling -- based on the Troll Tech dirview example
437
438enum {
439 DRAG_COPY = 0,
440 DRAG_MOVE = 1,
441 DRAG_CANCEL = 2
442};
443
444void KODayMatrix::dragEnterEvent( TQDragEnterEvent *e )
445{
446#ifndef KORG_NODND
447 if ( !ICalDrag::canDecode( e ) && !VCalDrag::canDecode( e ) ) {
448 e->ignore();
449 return;
450 }
451
452 // some visual feedback
453// oldPalette = palette();
454// setPalette(my_HilitePalette);
455// update();
456#endif
457}
458
459void KODayMatrix::dragMoveEvent( TQDragMoveEvent *e )
460{
461#ifndef KORG_NODND
462 if ( !ICalDrag::canDecode( e ) && !VCalDrag::canDecode( e ) ) {
463 e->ignore();
464 return;
465 }
466
467 e->accept();
468#endif
469}
470
471void KODayMatrix::dragLeaveEvent( TQDragLeaveEvent * /*dl*/ )
472{
473#ifndef KORG_NODND
474// setPalette(oldPalette);
475// update();
476#endif
477}
478
479void KODayMatrix::dropEvent( TQDropEvent *e )
480{
481#ifndef KORG_NODND
482 kdDebug(5850) << "KODayMatrix::dropEvent(e) begin" << endl;
483
484 if ( !mCalendar ||
485 ( !ICalDrag::canDecode( e ) && !VCalDrag::canDecode( e ) ) ) {
486 e->ignore();
487 return;
488 }
489
490 DndFactory factory( mCalendar );
491 Event *event = factory.createDrop( e );
492 Todo *todo = factory.createDropTodo( e );
493 if ( !event && !todo ) {
494 e->ignore();
495 return;
496 }
497
498 Todo *existingTodo = 0;
499 Event *existingEvent = 0;
500
501 // Find the incidence in the calendar, then we don't need the drag object any more
502 if ( event ) existingEvent = mCalendar->event( event->uid() );
503 if ( todo ) existingTodo = mCalendar->todo( todo->uid() );
504
505 int action = DRAG_CANCEL;
506
507 int root_x, root_y, win_x, win_y;
508 uint keybstate;
509 Window rootw, childw;
510 XQueryPointer( tqt_xdisplay(), tqt_xrootwin(), &rootw, &childw,
511 &root_x, &root_y, &win_x, &win_y, &keybstate );
512
513 if ( keybstate & ControlMask ) {
514 action = DRAG_COPY;
515 } else if ( keybstate & ShiftMask ) {
516 action = DRAG_MOVE;
517 } else {
518 TDEPopupMenu *menu = new TDEPopupMenu( this );
519 if ( existingEvent || existingTodo ) {
520 menu->insertItem( i18n("Move"), DRAG_MOVE, 0 );
521 if (existingEvent)
522 menu->insertItem( KOGlobals::self()->smallIcon("edit-copy"), i18n("Copy"), DRAG_COPY, 1 );
523 } else {
524 menu->insertItem( i18n("Add"), DRAG_MOVE, 0 );
525 }
526 menu->insertSeparator();
527 menu->insertItem( KOGlobals::self()->smallIcon("cancel"), i18n("Cancel"), DRAG_CANCEL, 3 );
528 action = menu->exec( TQCursor::pos(), 0 );
529 }
530
531 if ( action == DRAG_COPY || action == DRAG_MOVE ) {
532 e->accept();
533 int idx = getDayIndexFrom( e->pos().x(), e->pos().y() );
534
535 if ( action == DRAG_COPY ) {
536 if ( event ) emit incidenceDropped( event, mDays[idx] );
537 if ( todo ) emit incidenceDropped( todo, mDays[idx] );
538 } else if ( action == DRAG_MOVE ) {
539 if ( event ) emit incidenceDroppedMove( event, mDays[idx] );
540 if ( todo ) emit incidenceDroppedMove( todo, mDays[idx] );
541 }
542 }
543 delete event;
544 delete todo;
545#endif
546}
547
548// ----------------------------------------------------------------------------
549// P A I N T E V E N T H A N D L I N G
550// ----------------------------------------------------------------------------
551
552void KODayMatrix::paintEvent( TQPaintEvent * )
553{
554// kdDebug(5850) << "KODayMatrix::paintEvent() BEGIN" << endl;
555
556 TQPainter p;
557 TQRect sz = frameRect();
558 TQPixmap pm( sz.size() );
559 int dheight = mDaySize.height();
560 int dwidth = mDaySize.width();
561 int row,col;
562 int selw, selh;
563 bool isRTL = KOGlobals::self()->reverseLayout();
564
565 TQColorGroup cg = palette().active();
566
567 p.begin( &pm, this );
568 pm.fill( cg.base() );
569
570 // draw topleft frame
571 p.setPen( cg.mid() );
572 p.drawRect(0, 0, sz.width()-1, sz.height()-1);
573 // don't paint over borders
574 p.translate(1,1);
575
576 // draw selected days with highlighted background color
577 if (mSelStart != NOSELECTION) {
578
579 row = mSelStart/7;
580 // fix larger selections starting in the previous month
581 if ( row < 0 && mSelEnd > 0 ) row = 0;
582 col = mSelStart -row*7;
583 TQColor selcol = KOPrefs::instance()->mHighlightColor;
584
585 if ( row < 6 && row >= 0 ) {
586 if (row == mSelEnd/7) {
587 // Single row selection
588 p.fillRect(isRTL ? (7 - (mSelEnd-mSelStart+1) - col)*dwidth : col*dwidth,
589 row*dheight, (mSelEnd-mSelStart+1)*dwidth, dheight, selcol);
590 } else {
591 // draw first row to the right
592 p.fillRect(isRTL ? 0 : col*dwidth, row*dheight, (7-col)*dwidth,
593 dheight, selcol);
594 // draw full block till last line
595 selh = mSelEnd/7-row;
596 if ( selh + row >= 6 ) selh = 6-row;
597 if ( selh > 1 ) {
598 p.fillRect(0, (row+1)*dheight, 7*dwidth, (selh-1)*dheight,selcol);
599 }
600 // draw last block from left to mSelEnd
601 if ( mSelEnd/7 < 6 ) {
602 selw = mSelEnd-7*(mSelEnd/7)+1;
603 p.fillRect(isRTL ? (7-selw)*dwidth : 0, (row+selh)*dheight,
604 selw*dwidth, dheight, selcol);
605 }
606 }
607 }
608 }
609
610 // iterate over all days in the matrix and draw the day label in appropriate colors
611 TQColor textColor = cg.text();
612 TQColor textColorShaded = getShadedColor( textColor );
613 TQColor actcol = textColorShaded;
614 p.setPen(actcol);
615 TQPen tmppen;
616 for ( int i = 0; i < NUMDAYS; ++i ) {
617 row = i/7;
618 col = isRTL ? 6-(i-row*7) : i-row*7;
619
620 // if it is the first day of a month switch color from normal to shaded and vice versa
621 if ( KOGlobals::self()->calendarSystem()->day( mDays[i] ) == 1) {
622 if (actcol == textColorShaded) {
623 actcol = textColor;
624 } else {
625 actcol = textColorShaded;
626 }
627 p.setPen(actcol);
628 }
629
630 //Reset pen color after selected days block
631 if (i == mSelEnd+1) {
632 p.setPen(actcol);
633 }
634
635 bool holiday = ! KOGlobals::self()->isWorkDay( mDays[ i ] );
636
637 TQColor holidayColorShaded = getShadedColor( KOPrefs::instance()->mHolidayColor );
638 // if today then draw rectangle around day
639 if (mToday == i) {
640 tmppen = p.pen();
641 TQPen mTodayPen(p.pen());
642
643 mTodayPen.setWidth(mTodayMarginWidth);
644 //draw red rectangle for holidays
645 if (holiday) {
646 if (actcol == textColor) {
647 mTodayPen.setColor(KOPrefs::instance()->mHolidayColor);
648 } else {
649 mTodayPen.setColor(holidayColorShaded);
650 }
651 }
652 //draw gray rectangle for today if in selection
653 if (i >= mSelStart && i <= mSelEnd) {
654 TQColor grey("grey");
655 mTodayPen.setColor(grey);
656 }
657 p.setPen(mTodayPen);
658 p.drawRect(col*dwidth, row*dheight, dwidth, dheight);
659 p.setPen(tmppen);
660 }
661
662 // if any events are on that day then draw it using a bold font
663 if (mEvents[i] > 0) {
664 TQFont myFont = font();
665 myFont.setBold(true);
666 p.setFont(myFont);
667 }
668
669 // if it is a holiday then use the default holiday color
670 if (holiday) {
671 if (actcol == textColor) {
672 p.setPen(KOPrefs::instance()->mHolidayColor);
673 } else {
674 p.setPen(holidayColorShaded);
675 }
676 }
677
678 // draw selected days with special color
679 if ( i >= mSelStart && i <= mSelEnd && !holiday ) {
680 p.setPen( TQColor( "white" ) );
681 }
682
683 p.drawText(col*dwidth, row*dheight, dwidth, dheight,
684 TQt::AlignHCenter | TQt::AlignVCenter, mDayLabels[i]);
685
686 // reset color to actual color
687 if ( holiday ) {
688 p.setPen(actcol);
689 }
690 // reset bold font to plain font
691 if (mEvents[i] > 0) {
692 TQFont myFont = font();
693 myFont.setBold(false);
694 p.setFont(myFont);
695 }
696 }
697 p.end();
698 bitBlt( this, 0, 0, &pm );
699}
700
701// ----------------------------------------------------------------------------
702// R E SI Z E E V E N T H A N D L I N G
703// ----------------------------------------------------------------------------
704
705void KODayMatrix::resizeEvent( TQResizeEvent * )
706{
707 TQRect sz = frameRect();
708 mDaySize.setHeight( sz.height() * 7 / NUMDAYS );
709 mDaySize.setWidth( sz.width() / 7 );
710}
711
712/* static */
713TQPair<TQDate,TQDate> KODayMatrix::matrixLimits( const TQDate &month )
714{
715 const KCalendarSystem *calSys = KOGlobals::self()->calendarSystem();
716 TQDate d = month;
717 calSys->setYMD( d, calSys->year( month ), calSys->month( month ), 1 );
718
719 const int dayOfWeek = calSys->dayOfWeek( d );
720 const int weekstart = TDEGlobal::locale()->weekStartDay();
721
722 d = d.addDays( weekstart - dayOfWeek );
723
724 if ( dayOfWeek == weekstart ) {
725 d = d.addDays( -7 ); // Start on the second line
726 }
727
728 return qMakePair( d, d.addDays( NUMDAYS-1 ) );
729}
small helper class to dynamically show tooltips inside the day matrix.
Definition: kodaymatrix.h:57
void maybeTip(const TQPoint &pos)
TQt's callback to ask the object to provide an approrpiate text for the tooltip to be shown.
Definition: kodaymatrix.cpp:74
DynamicTip(TQWidget *parent)
Constructor that expects a KODayMatrix object as parent.
Definition: kodaymatrix.cpp:67
void registerObserver(Observer *observer)
virtual Todo * todo(const TQString &uid)=0
void unregisterObserver(Observer *observer)
virtual Event::List events(EventSortField sortField=EventSortUnsorted, SortDirection sortDirection=SortDirectionAscending)
virtual Event * event(const TQString &uid)=0
TQString uid() const
Replacement for kdpdatebuton.cpp that used 42 widgets for the day matrix to be displayed.
Definition: kodaymatrix.h:106
void selected(const KCal::DateList &daylist)
emitted if the user selects a block of days with the mouse by dragging a rectangle inside the matrix
void updateView()
Recalculates all the flags of the days in the matrix like holidays or events on a day (Actually calls...
void incidenceDropped(Incidence *incidence, const TQDate &dt)
emitted if the user has dropped an incidence (event or todo) inside the matrix
void setCalendar(Calendar *)
Associate a calendar with this day matrix.
void updateEvents()
Update event states of dates.
~KODayMatrix()
destructor that deallocates all dynamically allocated private members.
static TQPair< TQDate, TQDate > matrixLimits(const TQDate &month)
returns the first and last date of the 6*7 matrix that displays month
void setSelectedDaysFrom(const TQDate &start, const TQDate &end)
sets the actual to be displayed selection in the day matrix starting from start and ending with end.
TQString getHolidayLabel(int offset)
returns the official name of this holy day or 0 if there is no label for this day.
void incidenceDroppedMove(Incidence *oldincidence, const TQDate &dt)
emitted if the user has dropped an event inside the matrix and chose to move it instead of copy
void addSelectedDaysTo(DateList &)
adds all actual selected days from mSelStart to mSelEnd to the supplied DateList.
const TQDate & getDate(int offset)
returns the TQDate object associated with day indexed by the supplied offset.
void recalculateToday()
Calculate which square in the matrix should be hilighted to indicate it's today.
KODayMatrix(TQWidget *parent, const char *name)
constructor to create a day matrix widget.
void clearSelection()
Clear all selections.
void resourcesChanged()
Handle resource changes.