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 ) ) ) {
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 ) );
virtual Event * event(const TQString &uid)=0
void clearSelection()
Clear all selections.
~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 setCalendar(Calendar *)
Associate a calendar with this 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...
Todo * createDropTodo(TQDropEvent *de)
TQString getHolidayLabel(int offset)
returns the official name of this holy day or 0 if there is no label for this day.
virtual Todo * todo(const TQString &uid)=0
small helper class to dynamically show tooltips inside the day matrix.
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...
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 updateView()
Recalculates all the flags of the days in the matrix like holidays or events on a day (Actually calls...
KODayMatrix(TQWidget *parent, const char *name)
constructor to create a day matrix widget.
void updateEvents()
Update event states of dates.
void resourcesChanged()
Handle resource changes.
DynamicTip(TQWidget *parent)
Constructor that expects a KODayMatrix object as parent.
void registerObserver(Observer *observer)
Event * createDrop(TQDropEvent *de)
void incidenceDropped(Incidence *incidence, const TQDate &dt)
emitted if the user has dropped an incidence (event or todo) inside the matrix
Replacement for kdpdatebuton.cpp that used 42 widgets for the day matrix to be displayed.
const TQDate & getDate(int offset)
returns the TQDate object associated with day indexed by the supplied offset.
virtual Event::List events(EventSortField sortField=EventSortUnsorted, SortDirection sortDirection=SortDirectionAscending)
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 recalculateToday()
Calculate which square in the matrix should be hilighted to indicate it's today.
void addSelectedDaysTo(DateList &)
adds all actual selected days from mSelStart to mSelEnd to the supplied DateList. ...
void unregisterObserver(Observer *observer)