30 #include <tqpainter.h>
31 #include <tqptrlist.h>
33 #include <tdeglobal.h>
35 #include <tdelocale.h>
36 #include <kiconloader.h>
38 #include <libkcal/vcaldrag.h>
39 #include <libkcal/icaldrag.h>
40 #include <libkcal/dndfactory.h>
42 #include <libkcal/resourcecalendar.h>
44 #include <kcalendarsystem.h>
47 #include "koglobals.h"
48 #include "kodialogmanager.h"
50 #include "kodaymatrix.h"
51 #include "kodaymatrix.moc"
55 #include <tdepopupmenu.h>
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;
83 TQRect rct( col * dwidth, row * dheight, dwidth, dheight );
90 if ( str.isEmpty() )
return;
99 const int KODayMatrix::NOSELECTION = -1000;
100 const int KODayMatrix::NUMDAYS = 42;
103 : TQFrame( parent, name ), mCalendar( 0 ), mStartDate(), mPendingChanges( false )
106 mDays =
new TQDate[ NUMDAYS ];
107 mDayLabels =
new TQString[ NUMDAYS ];
108 mEvents =
new int[ NUMDAYS ];
111 mTodayMarginWidth = 2;
112 mSelEnd = mSelStart = NOSELECTION;
113 setBackgroundMode( NoBackground );
121 mCalendar->disconnect(
this );
133 setAcceptDrops( mCalendar );
138 TQColor KODayMatrix::getShadedColor(
const TQColor &color )
144 color.hsv( &h, &s, &v );
147 shaded.setHsv( h, s, v );
157 delete [] mDayLabels;
164 kdDebug(5850) <<
"KODayMatrix::addSelectedDaysTo() - " <<
"mSelStart:" << mSelStart << endl;
166 if ( mSelStart == NOSELECTION ) {
173 for (
int i = i0; i < 0; i++ ) {
174 selDays.append( mDays[ 0 ].addDays( i ) );
180 if ( mSelEnd > NUMDAYS-1 ) {
181 for (
int i = i0; i <= NUMDAYS - 1; i++ ) {
182 selDays.append( mDays[ i ] );
184 for (
int i = NUMDAYS; i < mSelEnd; i++ ) {
185 selDays.append( mDays[ 0 ].addDays( i ) );
189 for (
int i = i0; i <= mSelEnd; i++ ) {
190 selDays.append( mDays[ i ] );
197 if ( mStartDate.isValid() ) {
198 mSelStart = mStartDate.daysTo( start );
199 mSelEnd = mStartDate.daysTo( end );
205 mSelEnd = mSelStart = NOSELECTION;
210 if ( !mStartDate.isValid() )
return;
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] ));
217 if ( mDays[ i ].year() == TQDate::currentDate().year() &&
218 mDays[ i ].month() == TQDate::currentDate().month() &&
219 mDays[ i ].day() == TQDate::currentDate().day() ) {
231 void KODayMatrix::setUpdateNeeded()
233 mPendingChanges =
true;
238 kdDebug(5850) <<
"KODayMatrix::updateView() " << actdate <<
", day start="<<mStartDate<< endl;
239 if ( !actdate.isValid() )
return;
241 bool daychanged =
false;
245 if ( actdate != mStartDate ) {
247 if ( mSelStart != NOSELECTION ) {
248 int tmp = actdate.daysTo( mStartDate );
252 if ( mSelStart + tmp < NUMDAYS && mSelEnd + tmp >= 0 ) {
255 if( mSelStart > NUMDAYS || mSelStart < 0 )
256 mSelStart = mSelStart + tmp;
257 if( mSelEnd > NUMDAYS || mSelEnd < 0 )
258 mSelEnd = mSelEnd + tmp;
262 mStartDate = actdate;
272 if ( !daychanged && !mPendingChanges )
279 for(
int i = 0; i < NUMDAYS; i++ ) {
281 TQStringList holidays = KOGlobals::self()->holiday( mDays[ i ] );
282 TQString holiStr = TQString();
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 =
"";
290 mHolidays[ i ] = holiStr;
296 kdDebug( 5850 ) << k_funcinfo << endl;
297 if ( !mCalendar )
return;
299 for(
int i = 0; i < NUMDAYS; i++ ) {
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 ) {
306 ushort recurType =
event->recurrenceType();
307 if ( ( recurType == Recurrence::rDaily &&
308 !KOPrefs::instance()->mDailyRecur ) ||
309 ( recurType == Recurrence::rWeekly &&
310 !KOPrefs::instance()->mWeeklyRecur ) ) {
314 mEvents[ i ] = numEvents;
317 mPendingChanges =
false;
322 if ( offset < 0 || offset > NUMDAYS - 1 ) {
323 kdDebug(5850) <<
"Wrong offset (" << offset <<
") in KODayMatrix::getDate(int)" << endl;
326 return mDays[ offset ];
331 if ( offset < 0 || offset > NUMDAYS - 1 ) {
332 kdDebug(5850) <<
"Wrong offset (" << offset <<
") in KODayMatrix::getHolidayLabel(int)" << endl;
335 return mHolidays[ offset ];
338 int KODayMatrix::getDayIndexFrom(
int x,
int y )
340 return 7 * ( y / mDaySize.height() ) +
341 ( KOGlobals::self()->reverseLayout() ?
342 6 - x / mDaySize.width() : x / mDaySize.width() );
345 void KODayMatrix::calendarIncidenceAdded(
Incidence * incidence)
347 Q_UNUSED( incidence );
348 mPendingChanges =
true;
351 void KODayMatrix::calendarIncidenceChanged(
Incidence * incidence)
353 Q_UNUSED( incidence );
354 mPendingChanges =
true;
357 void KODayMatrix::calendarIncidenceDeleted(
Incidence * incidence)
359 Q_UNUSED( incidence );
360 mPendingChanges =
true;
365 mPendingChanges =
true;
373 void KODayMatrix::mousePressEvent( TQMouseEvent *e )
375 mSelStart = getDayIndexFrom(e->x(), e->y());
376 if (mSelStart > NUMDAYS-1) mSelStart=NUMDAYS-1;
377 mSelInit = mSelStart;
380 void KODayMatrix::mouseReleaseEvent( TQMouseEvent *e )
382 int tmp = getDayIndexFrom(e->x(), e->y());
383 if (tmp > NUMDAYS-1) tmp=NUMDAYS-1;
385 if (mSelInit > tmp) {
387 if (tmp != mSelStart) {
392 mSelStart = mSelInit;
395 if (tmp != mSelEnd) {
402 if ( mSelStart < 0 ) mSelStart = 0;
403 for (
int i = mSelStart; i <= mSelEnd; ++i ) {
404 daylist.append( mDays[i] );
406 emit
selected((
const DateList)daylist);
409 void KODayMatrix::mouseMoveEvent( TQMouseEvent *e )
411 int tmp = getDayIndexFrom(e->x(), e->y());
412 if (tmp > NUMDAYS-1) tmp=NUMDAYS-1;
414 if (mSelInit > tmp) {
416 if ( tmp != mSelStart ) {
421 mSelStart = mSelInit;
424 if ( tmp != mSelEnd ) {
444 void KODayMatrix::dragEnterEvent( TQDragEnterEvent *e )
447 if ( !ICalDrag::canDecode( e ) && !VCalDrag::canDecode( e ) ) {
459 void KODayMatrix::dragMoveEvent( TQDragMoveEvent *e )
462 if ( !ICalDrag::canDecode( e ) && !VCalDrag::canDecode( e ) ) {
471 void KODayMatrix::dragLeaveEvent( TQDragLeaveEvent * )
479 void KODayMatrix::dropEvent( TQDropEvent *e )
482 kdDebug(5850) <<
"KODayMatrix::dropEvent(e) begin" << endl;
485 ( !ICalDrag::canDecode( e ) && !VCalDrag::canDecode( e ) ) ) {
491 Event *
event = factory.createDrop( e );
492 Todo *todo = factory.createDropTodo( e );
493 if ( !event && !todo ) {
498 Todo *existingTodo = 0;
499 Event *existingEvent = 0;
502 if ( event ) existingEvent = mCalendar->
event( event->uid() );
503 if ( todo ) existingTodo = mCalendar->
todo( todo->
uid() );
505 int action = DRAG_CANCEL;
507 int root_x, root_y, win_x, win_y;
509 Window rootw, childw;
510 XQueryPointer( tqt_xdisplay(), tqt_xrootwin(), &rootw, &childw,
511 &root_x, &root_y, &win_x, &win_y, &keybstate );
513 if ( keybstate & ControlMask ) {
515 }
else if ( keybstate & ShiftMask ) {
518 TDEPopupMenu *menu =
new TDEPopupMenu(
this );
519 if ( existingEvent || existingTodo ) {
520 menu->insertItem( i18n(
"Move"), DRAG_MOVE, 0 );
522 menu->insertItem( KOGlobals::self()->smallIcon(
"edit-copy"), i18n(
"Copy"), DRAG_COPY, 1 );
524 menu->insertItem( i18n(
"Add"), DRAG_MOVE, 0 );
526 menu->insertSeparator();
527 menu->insertItem( KOGlobals::self()->smallIcon(
"cancel"), i18n(
"Cancel"), DRAG_CANCEL, 3 );
528 action = menu->exec( TQCursor::pos(), 0 );
531 if ( action == DRAG_COPY || action == DRAG_MOVE ) {
533 int idx = getDayIndexFrom( e->pos().x(), e->pos().y() );
535 if ( action == DRAG_COPY ) {
538 }
else if ( action == DRAG_MOVE ) {
552 void KODayMatrix::paintEvent( TQPaintEvent * )
557 TQRect sz = frameRect();
558 TQPixmap pm( sz.size() );
559 int dheight = mDaySize.height();
560 int dwidth = mDaySize.width();
563 bool isRTL = KOGlobals::self()->reverseLayout();
565 TQColorGroup cg = palette().active();
567 p.begin( &pm,
this );
568 pm.fill( cg.base() );
571 p.setPen( cg.mid() );
572 p.drawRect(0, 0, sz.width()-1, sz.height()-1);
577 if (mSelStart != NOSELECTION) {
581 if ( row < 0 && mSelEnd > 0 ) row = 0;
582 col = mSelStart -row*7;
583 TQColor selcol = KOPrefs::instance()->mHighlightColor;
585 if ( row < 6 && row >= 0 ) {
586 if (row == mSelEnd/7) {
588 p.fillRect(isRTL ? (7 - (mSelEnd-mSelStart+1) - col)*dwidth : col*dwidth,
589 row*dheight, (mSelEnd-mSelStart+1)*dwidth, dheight, selcol);
592 p.fillRect(isRTL ? 0 : col*dwidth, row*dheight, (7-col)*dwidth,
595 selh = mSelEnd/7-row;
596 if ( selh + row >= 6 ) selh = 6-row;
598 p.fillRect(0, (row+1)*dheight, 7*dwidth, (selh-1)*dheight,selcol);
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);
611 TQColor textColor = cg.text();
612 TQColor textColorShaded = getShadedColor( textColor );
613 TQColor actcol = textColorShaded;
616 for (
int i = 0; i < NUMDAYS; ++i ) {
618 col = isRTL ? 6-(i-row*7) : i-row*7;
621 if ( KOGlobals::self()->calendarSystem()->day( mDays[i] ) == 1) {
622 if (actcol == textColorShaded) {
625 actcol = textColorShaded;
631 if (i == mSelEnd+1) {
635 bool holiday = ! KOGlobals::self()->isWorkDay( mDays[ i ] );
637 TQColor holidayColorShaded = getShadedColor( KOPrefs::instance()->mHolidayColor );
641 TQPen mTodayPen(p.pen());
643 mTodayPen.setWidth(mTodayMarginWidth);
646 if (actcol == textColor) {
647 mTodayPen.setColor(KOPrefs::instance()->mHolidayColor);
649 mTodayPen.setColor(holidayColorShaded);
653 if (i >= mSelStart && i <= mSelEnd) {
654 TQColor grey(
"grey");
655 mTodayPen.setColor(grey);
658 p.drawRect(col*dwidth, row*dheight, dwidth, dheight);
663 if (mEvents[i] > 0) {
664 TQFont myFont = font();
665 myFont.setBold(
true);
671 if (actcol == textColor) {
672 p.setPen(KOPrefs::instance()->mHolidayColor);
674 p.setPen(holidayColorShaded);
679 if ( i >= mSelStart && i <= mSelEnd && !holiday ) {
680 p.setPen( TQColor(
"white" ) );
683 p.drawText(col*dwidth, row*dheight, dwidth, dheight,
684 TQt::AlignHCenter | TQt::AlignVCenter, mDayLabels[i]);
691 if (mEvents[i] > 0) {
692 TQFont myFont = font();
693 myFont.setBold(
false);
698 bitBlt(
this, 0, 0, &pm );
705 void KODayMatrix::resizeEvent( TQResizeEvent * )
707 TQRect sz = frameRect();
708 mDaySize.setHeight( sz.height() * 7 / NUMDAYS );
709 mDaySize.setWidth( sz.width() / 7 );
715 const KCalendarSystem *calSys = KOGlobals::self()->calendarSystem();
717 calSys->setYMD( d, calSys->year( month ), calSys->month( month ), 1 );
719 const int dayOfWeek = calSys->dayOfWeek( d );
720 const int weekstart = TDEGlobal::locale()->weekStartDay();
722 d = d.addDays( weekstart - dayOfWeek );
724 if ( dayOfWeek == weekstart ) {
728 return qMakePair( d, d.addDays( NUMDAYS-1 ) );
small helper class to dynamically show tooltips inside the day matrix.
void maybeTip(const TQPoint &pos)
TQt's callback to ask the object to provide an approrpiate text for the tooltip to be shown.
DynamicTip(TQWidget *parent)
Constructor that expects a KODayMatrix object as parent.
virtual Todo * todo(const TQString &uid)=0
void registerObserver(Observer *observer)
virtual Event * event(const TQString &uid)=0
void unregisterObserver(Observer *observer)
virtual Event::List events(EventSortField sortField=EventSortUnsorted, SortDirection sortDirection=SortDirectionAscending)
Replacement for kdpdatebuton.cpp that used 42 widgets for the day matrix to be displayed.
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.