-rw-r--r-- | korganizer/koagendaview.cpp | 1436 |
1 files changed, 1436 insertions, 0 deletions
diff --git a/korganizer/koagendaview.cpp b/korganizer/koagendaview.cpp new file mode 100644 index 0000000..9e057e4 --- a/dev/null +++ b/korganizer/koagendaview.cpp | |||
@@ -0,0 +1,1436 @@ | |||
1 | /* | ||
2 | This file is part of KOrganizer. | ||
3 | Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org> | ||
4 | |||
5 | This program is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published by | ||
7 | the Free Software Foundation; either version 2 of the License, or | ||
8 | (at your option) any later version. | ||
9 | |||
10 | This program is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with this program; if not, write to the Free Software | ||
17 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
18 | |||
19 | As a special exception, permission is given to link this program | ||
20 | with any edition of Qt, and distribute the resulting executable, | ||
21 | without including the source code for Qt in the source distribution. | ||
22 | */ | ||
23 | |||
24 | #include <qhbox.h> | ||
25 | #include <qvbox.h> | ||
26 | #include <qlabel.h> | ||
27 | #include <qframe.h> | ||
28 | #include <qlayout.h> | ||
29 | #ifndef KORG_NOSPLITTER | ||
30 | #include <qsplitter.h> | ||
31 | #endif | ||
32 | #include <qfont.h> | ||
33 | #include <qfontmetrics.h> | ||
34 | #include <qpopupmenu.h> | ||
35 | #include <qtooltip.h> | ||
36 | #include <qpainter.h> | ||
37 | #include <qpushbutton.h> | ||
38 | #include <qapplication.h> | ||
39 | |||
40 | #include <kapplication.h> | ||
41 | #include <KDGanttMinimizeSplitter.h> | ||
42 | #include <kdebug.h> | ||
43 | #include <kstandarddirs.h> | ||
44 | #include <kiconloader.h> | ||
45 | #include <klocale.h> | ||
46 | #include <kconfig.h> | ||
47 | #include <kglobal.h> | ||
48 | #include "calendarview.h" | ||
49 | #include "koviewmanager.h" | ||
50 | |||
51 | #include <libkcal/calendar.h> | ||
52 | #include <libkcal/icaldrag.h> | ||
53 | #include <libkcal/dndfactory.h> | ||
54 | |||
55 | #include <kcalendarsystem.h> | ||
56 | |||
57 | #include "koglobals.h" | ||
58 | #ifndef KORG_NOPLUGINS | ||
59 | #include "kocore.h" | ||
60 | #endif | ||
61 | #include "koprefs.h" | ||
62 | #include "koagenda.h" | ||
63 | #include "koagendaitem.h" | ||
64 | #ifndef KORG_NOPRINTER | ||
65 | #include "calprinter.h" | ||
66 | #endif | ||
67 | |||
68 | #include "koagendaview.h" | ||
69 | #include "koagendaview.moc" | ||
70 | |||
71 | //extern bool globalFlagBlockPainting; | ||
72 | extern int globalFlagBlockAgenda; | ||
73 | extern int globalFlagBlockStartup; | ||
74 | extern int globalFlagBlockAgendaItemPaint; | ||
75 | extern int globalFlagBlockAgendaItemUpdate; | ||
76 | extern int globalFlagBlockLabel; | ||
77 | using namespace KOrg; | ||
78 | |||
79 | TimeLabels::TimeLabels(int rows,QWidget *parent,const char *name,WFlags f) : | ||
80 | QScrollView(parent,name,f) | ||
81 | { | ||
82 | mRows = rows; | ||
83 | |||
84 | setMinimumHeight( 20 ); | ||
85 | mCellHeight = KOPrefs::instance()->mHourSize*4; | ||
86 | |||
87 | enableClipper(true); | ||
88 | |||
89 | setHScrollBarMode(AlwaysOff); | ||
90 | setVScrollBarMode(AlwaysOff); | ||
91 | |||
92 | resizeContents(50,mRows * mCellHeight); | ||
93 | |||
94 | viewport()->setBackgroundMode( PaletteBackground ); | ||
95 | } | ||
96 | |||
97 | void TimeLabels::setCellHeight(int height) | ||
98 | { | ||
99 | mCellHeight = height; | ||
100 | } | ||
101 | |||
102 | /* | ||
103 | Optimization so that only the "dirty" portion of the scroll view | ||
104 | is redrawn. Unfortunately, this is not called by default paintEvent() method. | ||
105 | */ | ||
106 | void TimeLabels::drawContents(QPainter *p,int cx, int cy, int cw, int ch) | ||
107 | { | ||
108 | |||
109 | // if ( globalFlagBlockAgenda ) | ||
110 | // return; | ||
111 | // bug: the parameters cx, cy, cw, ch are the areas that need to be | ||
112 | // redrawn, not the area of the widget. unfortunately, this | ||
113 | // code assumes the latter... | ||
114 | |||
115 | // now, for a workaround... | ||
116 | // these two assignments fix the weird redraw bug | ||
117 | cx = contentsX() + 2; | ||
118 | cw = contentsWidth() - 2; | ||
119 | // end of workaround | ||
120 | |||
121 | int cell = ((int)(cy/mCellHeight)); | ||
122 | int y = cell * mCellHeight; | ||
123 | QFontMetrics fm = fontMetrics(); | ||
124 | QString hour; | ||
125 | QString suffix; | ||
126 | QString fullTime; | ||
127 | int tW = fm.width("24:00i"); | ||
128 | |||
129 | while (y < cy + ch) { | ||
130 | p->drawLine(cx,y,cx+tW,y); | ||
131 | hour.setNum(cell); | ||
132 | suffix = "am"; | ||
133 | |||
134 | // handle 24h and am/pm time formats | ||
135 | if (KGlobal::locale()->use12Clock()) { | ||
136 | if (cell > 11) suffix = "pm"; | ||
137 | if (cell == 0) hour.setNum(12); | ||
138 | if (cell > 12) hour.setNum(cell - 12); | ||
139 | } else { | ||
140 | suffix = ":00"; | ||
141 | } | ||
142 | |||
143 | // create string in format of "XX:XX" or "XXpm/am" | ||
144 | fullTime = hour + suffix; | ||
145 | |||
146 | // center and draw the time label | ||
147 | int timeWidth = fm.width(fullTime+"i"); | ||
148 | int offset = this->width() - timeWidth; | ||
149 | int borderWidth = 5; | ||
150 | int timeHeight = fm.height(); | ||
151 | timeHeight = timeHeight + 2 - ( timeHeight / 4 ); | ||
152 | p->drawText(cx -borderWidth + offset, y+ timeHeight, fullTime); | ||
153 | |||
154 | // increment indices | ||
155 | y += mCellHeight; | ||
156 | cell++; | ||
157 | } | ||
158 | } | ||
159 | |||
160 | /** | ||
161 | Calculates the minimum width. | ||
162 | */ | ||
163 | int TimeLabels::minimumWidth() const | ||
164 | { | ||
165 | QFontMetrics fm = fontMetrics(); | ||
166 | |||
167 | //TODO: calculate this value | ||
168 | int borderWidth = 4; | ||
169 | |||
170 | // the maximum width possible | ||
171 | int width = fm.width("88:88x") + borderWidth; | ||
172 | |||
173 | return width; | ||
174 | } | ||
175 | |||
176 | /** updates widget's internal state */ | ||
177 | void TimeLabels::updateConfig() | ||
178 | { | ||
179 | // set the font | ||
180 | // config->setGroup("Fonts"); | ||
181 | // QFont font = config->readFontEntry("TimeBar Font"); | ||
182 | setFont(KOPrefs::instance()->mTimeBarFont); | ||
183 | |||
184 | // update geometry restrictions based on new settings | ||
185 | setFixedWidth(minimumWidth()); | ||
186 | |||
187 | // update HourSize | ||
188 | mCellHeight = KOPrefs::instance()->mHourSize*4; | ||
189 | resizeContents(50,mRows * mCellHeight); | ||
190 | } | ||
191 | |||
192 | /** update time label positions */ | ||
193 | void TimeLabels::positionChanged() | ||
194 | { | ||
195 | int adjustment = mAgenda->contentsY(); | ||
196 | setContentsPos(0, adjustment); | ||
197 | } | ||
198 | |||
199 | /** */ | ||
200 | void TimeLabels::setAgenda(KOAgenda* agenda) | ||
201 | { | ||
202 | mAgenda = agenda; | ||
203 | } | ||
204 | |||
205 | |||
206 | /** This is called in response to repaint() */ | ||
207 | void TimeLabels::paintEvent(QPaintEvent*) | ||
208 | { | ||
209 | |||
210 | // kdDebug() << "paintevent..." << endl; | ||
211 | // this is another hack! | ||
212 | // QPainter painter(this); | ||
213 | //QString c | ||
214 | repaintContents(contentsX(), contentsY(), visibleWidth(), visibleHeight()); | ||
215 | } | ||
216 | |||
217 | //////////////////////////////////////////////////////////////////////////// | ||
218 | |||
219 | EventIndicator::EventIndicator(Location loc,QWidget *parent,const char *name) | ||
220 | : QFrame(parent,name) | ||
221 | { | ||
222 | mColumns = 1; | ||
223 | mTopBox = 0; | ||
224 | mLocation = loc; | ||
225 | mTopLayout = 0; | ||
226 | mPaintWidget = 0; | ||
227 | mXOffset = 0; | ||
228 | if (mLocation == Top) mPixmap = SmallIcon("1uparrow"); | ||
229 | else mPixmap = SmallIcon("1downarrow"); | ||
230 | mEnabled.resize(mColumns); | ||
231 | if (mLocation == Top) | ||
232 | setMaximumHeight(0); | ||
233 | else | ||
234 | setMinimumHeight(mPixmap.height()); | ||
235 | } | ||
236 | |||
237 | EventIndicator::~EventIndicator() | ||
238 | { | ||
239 | } | ||
240 | |||
241 | void EventIndicator::drawContents(QPainter *p) | ||
242 | { | ||
243 | |||
244 | // kdDebug() << "======== top: " << contentsRect().top() << " bottom " << // contentsRect().bottom() << " left " << contentsRect().left() << " right " << contentsRect().right() << endl; | ||
245 | KDGanttSplitterHandle* han = 0; | ||
246 | if ( mPaintWidget ) | ||
247 | han = mPaintWidget->firstHandle(); | ||
248 | if ( ! han ) { | ||
249 | int i; | ||
250 | for(i=0;i<mColumns;++i) { | ||
251 | if (mEnabled[i]) { | ||
252 | int cellWidth = contentsRect().right()/mColumns; | ||
253 | int xOffset = KOGlobals::self()->reverseLayout() ? | ||
254 | (mColumns - 1 - i)*cellWidth + cellWidth/2 -mPixmap.width()/2 : | ||
255 | i*cellWidth + cellWidth/2 -mPixmap.width()/2; | ||
256 | p->drawPixmap(QPoint(xOffset,0),mPixmap); | ||
257 | } | ||
258 | } | ||
259 | } else { | ||
260 | han->repaint(); | ||
261 | //mPaintWidget->setBackgroundColor( red ); | ||
262 | |||
263 | QPainter pa( han ); | ||
264 | int i; | ||
265 | bool setColor = false; | ||
266 | for(i=0;i<mColumns;++i) { | ||
267 | if (mEnabled[i]) { | ||
268 | setColor = true; | ||
269 | |||
270 | int cellWidth = contentsRect().right()/mColumns; | ||
271 | int xOffset = KOGlobals::self()->reverseLayout() ? | ||
272 | (mColumns - 1 - i)*cellWidth + cellWidth/2 -mPixmap.width()/2 : | ||
273 | i*cellWidth + cellWidth/2 -mPixmap.width()/2; | ||
274 | pa.drawPixmap(QPoint(mXOffset + xOffset,0),mPixmap); | ||
275 | //qDebug("222draw pix %d ",xOffset ); | ||
276 | |||
277 | } | ||
278 | |||
279 | } | ||
280 | pa.end(); | ||
281 | |||
282 | } | ||
283 | } | ||
284 | |||
285 | void EventIndicator::setXOffset( int x ) | ||
286 | { | ||
287 | mXOffset = x; | ||
288 | } | ||
289 | void EventIndicator::setPaintWidget( KDGanttMinimizeSplitter * w ) | ||
290 | { | ||
291 | mPaintWidget = w; | ||
292 | } | ||
293 | void EventIndicator::changeColumns(int columns) | ||
294 | { | ||
295 | mColumns = columns; | ||
296 | mEnabled.resize(mColumns); | ||
297 | |||
298 | update(); | ||
299 | } | ||
300 | |||
301 | void EventIndicator::enableColumn(int column, bool enable) | ||
302 | { | ||
303 | mEnabled[column] = enable; | ||
304 | } | ||
305 | |||
306 | |||
307 | //////////////////////////////////////////////////////////////////////////// | ||
308 | //////////////////////////////////////////////////////////////////////////// | ||
309 | //////////////////////////////////////////////////////////////////////////// | ||
310 | |||
311 | KOAgendaView::KOAgendaView(Calendar *cal,QWidget *parent,const char *name) : | ||
312 | KOEventView (cal,parent,name) | ||
313 | { | ||
314 | mBlockUpdating = true; | ||
315 | mStartHour = 8; | ||
316 | mSelectedDates.append(QDate::currentDate()); | ||
317 | |||
318 | mLayoutDayLabels = 0; | ||
319 | mDayLabelsFrame = 0; | ||
320 | mDayLabels = 0; | ||
321 | bool isRTL = KOGlobals::self()->reverseLayout(); | ||
322 | |||
323 | if ( KOPrefs::instance()->mVerticalScreen ) { | ||
324 | mExpandedPixmap = SmallIcon( "1downarrow" ); | ||
325 | mNotExpandedPixmap = SmallIcon( "1uparrow" ); | ||
326 | } else { | ||
327 | mExpandedPixmap = SmallIcon( isRTL ? "1leftarrow" : "1rightarrow" ); | ||
328 | mNotExpandedPixmap = SmallIcon( isRTL ? "1rightarrow" : "1leftarrow" ); | ||
329 | } | ||
330 | |||
331 | QBoxLayout *topLayout = new QVBoxLayout(this); | ||
332 | |||
333 | // Create day name labels for agenda columns | ||
334 | mDayLabelsFrame = new QHBox(this); | ||
335 | topLayout->addWidget(mDayLabelsFrame); | ||
336 | mDayLabels = new QFrame (mDayLabelsFrame); | ||
337 | mLayoutDayLabels = new QHBoxLayout(mDayLabels); | ||
338 | // Create agenda splitter | ||
339 | #ifndef KORG_NOSPLITTER | ||
340 | mSplitterAgenda = new QSplitter(Vertical,this); | ||
341 | topLayout->addWidget(mSplitterAgenda); | ||
342 | mSplitterAgenda->setOpaqueResize(); | ||
343 | |||
344 | mAllDayFrame = new QHBox(mSplitterAgenda); | ||
345 | |||
346 | QWidget *agendaFrame = new QWidget(mSplitterAgenda); | ||
347 | #else | ||
348 | #if 0 | ||
349 | QWidget *mainBox = new QWidget( this ); | ||
350 | topLayout->addWidget( mainBox ); | ||
351 | QBoxLayout *mainLayout = new QVBoxLayout(mainBox); | ||
352 | mAllDayFrame = new QHBox(mainBox); | ||
353 | mainLayout->addWidget(mAllDayFrame); | ||
354 | mainLayout->setStretchFactor( mAllDayFrame, 0 ); | ||
355 | mAllDayFrame->setFocusPolicy(NoFocus); | ||
356 | QWidget *agendaFrame = new QWidget(mainBox); | ||
357 | mainLayout->addWidget(agendaFrame); | ||
358 | mainLayout->setStretchFactor( agendaFrame, 10 ); | ||
359 | |||
360 | agendaFrame->setFocusPolicy(NoFocus); | ||
361 | #endif | ||
362 | mSplitterAgenda = new KDGanttMinimizeSplitter( Qt::Vertical, this); | ||
363 | mSplitterAgenda->setMinimizeDirection ( KDGanttMinimizeSplitter::Up ); | ||
364 | topLayout->addWidget( mSplitterAgenda ); | ||
365 | mAllDayFrame = new QHBox(mSplitterAgenda); | ||
366 | mAllDayFrame->setFocusPolicy(NoFocus); | ||
367 | QWidget *agendaFrame = new QWidget(mSplitterAgenda); | ||
368 | agendaFrame->setFocusPolicy(NoFocus); | ||
369 | |||
370 | #endif | ||
371 | |||
372 | // Create all-day agenda widget | ||
373 | mDummyAllDayLeft = new QVBox( mAllDayFrame ); | ||
374 | |||
375 | mExpandButton = new QPushButton(mDummyAllDayLeft); | ||
376 | mExpandButton->setPixmap( mNotExpandedPixmap ); | ||
377 | mExpandButton->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, | ||
378 | QSizePolicy::Fixed ) ); | ||
379 | connect( mExpandButton, SIGNAL( clicked() ), SIGNAL( toggleExpand() ) ); | ||
380 | mExpandButton->setFocusPolicy(NoFocus); | ||
381 | mAllDayAgenda = new KOAgenda(1,mAllDayFrame); | ||
382 | mAllDayAgenda->setFocusPolicy(NoFocus); | ||
383 | QWidget *dummyAllDayRight = new QWidget(mAllDayFrame); | ||
384 | |||
385 | // Create event context menu for all day agenda | ||
386 | mAllDayAgendaPopup = eventPopup(); | ||
387 | connect(mAllDayAgenda,SIGNAL(showIncidencePopupSignal(Incidence *)), | ||
388 | mAllDayAgendaPopup,SLOT(showIncidencePopup(Incidence *))); | ||
389 | |||
390 | // Create agenda frame | ||
391 | QGridLayout *agendaLayout = new QGridLayout(agendaFrame,3,3); | ||
392 | // QHBox *agendaFrame = new QHBox(splitterAgenda); | ||
393 | |||
394 | // create event indicator bars | ||
395 | mEventIndicatorTop = new EventIndicator(EventIndicator::Top,agendaFrame); | ||
396 | agendaLayout->addWidget(mEventIndicatorTop,0,1); | ||
397 | mEventIndicatorTop->setPaintWidget( mSplitterAgenda ); | ||
398 | mEventIndicatorBottom = new EventIndicator(EventIndicator::Bottom, | ||
399 | agendaFrame); | ||
400 | agendaLayout->addWidget(mEventIndicatorBottom,2,1); | ||
401 | QWidget *dummyAgendaRight = new QWidget(agendaFrame); | ||
402 | agendaLayout->addWidget(dummyAgendaRight,0,2); | ||
403 | |||
404 | // Create time labels | ||
405 | mTimeLabels = new TimeLabels(24,agendaFrame); | ||
406 | agendaLayout->addWidget(mTimeLabels,1,0); | ||
407 | |||
408 | // Create agenda | ||
409 | mAgenda = new KOAgenda(1,96,KOPrefs::instance()->mHourSize,agendaFrame); | ||
410 | agendaLayout->addMultiCellWidget(mAgenda,1,1,1,2); | ||
411 | agendaLayout->setColStretch(1,1); | ||
412 | mAgenda->setFocusPolicy(NoFocus); | ||
413 | // Create event context menu for agenda | ||
414 | mAgendaPopup = eventPopup(); | ||
415 | |||
416 | mAgendaPopup->addAdditionalItem(QIconSet(SmallIcon("bell")), | ||
417 | i18n("Toggle Alarm"),mAgenda, | ||
418 | SLOT(popupAlarm()),true); | ||
419 | |||
420 | |||
421 | connect(mAgenda,SIGNAL(showIncidencePopupSignal(Incidence *)), | ||
422 | mAgendaPopup,SLOT(showIncidencePopup(Incidence *))); | ||
423 | |||
424 | // make connections between dependent widgets | ||
425 | mTimeLabels->setAgenda(mAgenda); | ||
426 | |||
427 | // Update widgets to reflect user preferences | ||
428 | // updateConfig(); | ||
429 | |||
430 | // createDayLabels(); | ||
431 | |||
432 | // these blank widgets make the All Day Event box line up with the agenda | ||
433 | dummyAllDayRight->setFixedWidth(mAgenda->verticalScrollBar()->width()); | ||
434 | dummyAgendaRight->setFixedWidth(mAgenda->verticalScrollBar()->width()); | ||
435 | mDummyAllDayLeft->setFixedWidth(mTimeLabels->width()); | ||
436 | |||
437 | // Scrolling | ||
438 | connect(mAgenda->verticalScrollBar(),SIGNAL(valueChanged(int)), | ||
439 | mTimeLabels, SLOT(positionChanged())); | ||
440 | connect(mTimeLabels->verticalScrollBar(),SIGNAL(valueChanged(int)), | ||
441 | SLOT(setContentsPos(int))); | ||
442 | |||
443 | // Create/Show/Edit/Delete Event | ||
444 | connect(mAgenda,SIGNAL(newEventSignal(int,int)), | ||
445 | SLOT(newEvent(int,int))); | ||
446 | connect(mAgenda,SIGNAL(newEventSignal(int,int,int,int)), | ||
447 | SLOT(newEvent(int,int,int,int))); | ||
448 | connect(mAllDayAgenda,SIGNAL(newEventSignal(int,int)), | ||
449 | SLOT(newEventAllDay(int,int))); | ||
450 | connect(mAllDayAgenda,SIGNAL(newEventSignal(int,int,int,int)), | ||
451 | SLOT(newEventAllDay(int,int))); | ||
452 | connect(mAgenda,SIGNAL(newTimeSpanSignal(int,int,int,int)), | ||
453 | SLOT(newTimeSpanSelected(int,int,int,int))); | ||
454 | connect(mAllDayAgenda,SIGNAL(newTimeSpanSignal(int,int,int,int)), | ||
455 | SLOT(newTimeSpanSelectedAllDay(int,int,int,int))); | ||
456 | connect(mAgenda,SIGNAL(newStartSelectSignal()),SLOT(updateView())); | ||
457 | connect(mAllDayAgenda,SIGNAL(newStartSelectSignal()),SLOT(updateView())); | ||
458 | |||
459 | connect(mAgenda,SIGNAL(editIncidenceSignal(Incidence *)), | ||
460 | SIGNAL(editIncidenceSignal(Incidence *))); | ||
461 | connect(mAllDayAgenda,SIGNAL(editIncidenceSignal(Incidence *)), | ||
462 | SIGNAL(editIncidenceSignal(Incidence *))); | ||
463 | connect(mAgenda,SIGNAL(showIncidenceSignal(Incidence *)), | ||
464 | SIGNAL(showIncidenceSignal(Incidence *))); | ||
465 | connect(mAllDayAgenda,SIGNAL(showIncidenceSignal(Incidence *)), | ||
466 | SIGNAL(showIncidenceSignal(Incidence *))); | ||
467 | connect(mAgenda,SIGNAL(deleteIncidenceSignal(Incidence *)), | ||
468 | SIGNAL(deleteIncidenceSignal(Incidence *))); | ||
469 | connect(mAllDayAgenda,SIGNAL(deleteIncidenceSignal(Incidence *)), | ||
470 | SIGNAL(deleteIncidenceSignal(Incidence *))); | ||
471 | |||
472 | connect(mAgenda,SIGNAL(itemModified(KOAgendaItem *, int )), | ||
473 | SLOT(updateEventDates(KOAgendaItem *, int ))); | ||
474 | connect(mAllDayAgenda,SIGNAL(itemModified(KOAgendaItem *, int )), | ||
475 | SLOT(updateEventDates(KOAgendaItem *, int))); | ||
476 | |||
477 | // event indicator update | ||
478 | connect(mAgenda,SIGNAL(lowerYChanged(int)), | ||
479 | SLOT(updateEventIndicatorTop(int))); | ||
480 | connect(mAgenda,SIGNAL(upperYChanged(int)), | ||
481 | SLOT(updateEventIndicatorBottom(int))); | ||
482 | // drag signals | ||
483 | /* | ||
484 | connect(mAgenda,SIGNAL(startDragSignal(Event *)), | ||
485 | SLOT(startDrag(Event *))); | ||
486 | connect(mAllDayAgenda,SIGNAL(startDragSignal(Event *)), | ||
487 | SLOT(startDrag(Event *))); | ||
488 | */ | ||
489 | // synchronize selections | ||
490 | connect( mAgenda, SIGNAL( incidenceSelected( Incidence * ) ), | ||
491 | mAllDayAgenda, SLOT( deselectItem() ) ); | ||
492 | connect( mAllDayAgenda, SIGNAL( incidenceSelected( Incidence * ) ), | ||
493 | mAgenda, SLOT( deselectItem() ) ); | ||
494 | connect( mAgenda, SIGNAL( incidenceSelected( Incidence * ) ), | ||
495 | SIGNAL( incidenceSelected( Incidence * ) ) ); | ||
496 | connect( mAllDayAgenda, SIGNAL( incidenceSelected( Incidence * ) ), | ||
497 | SIGNAL( incidenceSelected( Incidence * ) ) ); | ||
498 | connect( mAgenda, SIGNAL( resizedSignal() ), | ||
499 | SLOT( updateConfig( ) ) ); | ||
500 | connect( mAgenda, SIGNAL( addToCalSignal(Incidence *, Incidence *) ), | ||
501 | SLOT( addToCalSlot(Incidence *, Incidence * ) ) ); | ||
502 | connect( mAllDayAgenda, SIGNAL( addToCalSignal(Incidence * ,Incidence *) ), | ||
503 | SLOT( addToCalSlot(Incidence * , Incidence *) ) ); | ||
504 | // connect( mAgenda, SIGNAL( cloneIncidenceSignal(Incidence *) ), SIGNAL( cloneIncidenceSignal(Incidence *) ) ); | ||
505 | //connect( mAllDayAgenda, SIGNAL( cloneIncidenceSignal(Incidence *) ), SIGNAL( cloneIncidenceSignal(Incidence *) ) ); | ||
506 | |||
507 | |||
508 | } | ||
509 | |||
510 | void KOAgendaView::toggleAllDay() | ||
511 | { | ||
512 | if ( mSplitterAgenda->firstHandle() ) | ||
513 | mSplitterAgenda->firstHandle()->toggle(); | ||
514 | } | ||
515 | void KOAgendaView::addToCalSlot(Incidence * inc, Incidence * incOld ) | ||
516 | { | ||
517 | calendar()->addIncidence( inc ); | ||
518 | |||
519 | if ( incOld ) { | ||
520 | if ( incOld->type() == "Todo" ) | ||
521 | emit todoMoved((Todo*)incOld, KOGlobals::EVENTEDITED ); | ||
522 | else | ||
523 | emit incidenceChanged(incOld, KOGlobals::EVENTEDITED); | ||
524 | } | ||
525 | |||
526 | } | ||
527 | |||
528 | KOAgendaView::~KOAgendaView() | ||
529 | { | ||
530 | delete mAgendaPopup; | ||
531 | delete mAllDayAgendaPopup; | ||
532 | delete KOAgendaItem::paintPix(); | ||
533 | delete KOAgendaItem::paintPixSel(); | ||
534 | } | ||
535 | void KOAgendaView::resizeEvent( QResizeEvent* e ) | ||
536 | { | ||
537 | //qDebug("KOAgendaView::resizeEvent( QResizeEvent* e ) %d ", e->size().width()); | ||
538 | bool uc = false; | ||
539 | int ow = e->oldSize().width(); | ||
540 | int oh = e->oldSize().height(); | ||
541 | int w = e->size().width(); | ||
542 | int h = e->size().height(); | ||
543 | if ( (ow > oh && w< h ) || (ow < oh && w > h ) ) { | ||
544 | if ( ! mBlockUpdating && !globalFlagBlockStartup && !globalFlagBlockAgenda ) | ||
545 | uc = true; | ||
546 | //qDebug("view changed %d %d %d %d ", ow, oh , w , h); | ||
547 | } | ||
548 | mUpcomingWidth = e->size().width() ; | ||
549 | if ( mBlockUpdating || uc ) { | ||
550 | mBlockUpdating = false; | ||
551 | //mAgenda->setMinimumSize(800 , 600 ); | ||
552 | //qDebug("mAgenda->resize+++++++++++++++ "); | ||
553 | updateConfig(); | ||
554 | //qDebug("KOAgendaView::Updating now possible "); | ||
555 | } else | ||
556 | createDayLabels(); | ||
557 | //qDebug("resizeEvent end "); | ||
558 | |||
559 | } | ||
560 | void KOAgendaView::createDayLabels() | ||
561 | { | ||
562 | |||
563 | if ( mBlockUpdating || globalFlagBlockLabel == 1) { | ||
564 | // qDebug(" KOAgendaView::createDayLabels() blocked "); | ||
565 | return; | ||
566 | |||
567 | } | ||
568 | int newHight; | ||
569 | |||
570 | // ### Before deleting and recreating we could check if mSelectedDates changed... | ||
571 | // It would remove some flickering and gain speed (since this is called by | ||
572 | // each updateView() call) | ||
573 | |||
574 | int maxWid = mUpcomingWidth - mTimeLabels->width()- mAgenda->verticalScrollBar()->width() - 2; | ||
575 | mDayLabelsFrame->setMaximumWidth( mUpcomingWidth ); | ||
576 | if ( maxWid < 0 ) | ||
577 | maxWid = 20; | ||
578 | |||
579 | QFont dlf = KOPrefs::instance()->mTimeLabelsFont; | ||
580 | QFontMetrics fm ( dlf ); | ||
581 | int selCount = mSelectedDates.count(); | ||
582 | QString dayTest = "Mon 20"; | ||
583 | int wid = fm.width( dayTest ); | ||
584 | maxWid -= ( selCount * 3 ); | ||
585 | if ( maxWid < 0 ) | ||
586 | maxWid = 20; | ||
587 | int needWid = wid * selCount; | ||
588 | //qDebug("++++++++Needed : %d MaxWidth: %d", needWid, maxWid ); | ||
589 | //if ( needWid > maxWid ) | ||
590 | // qDebug("DAYLABELS TOOOOOOO BIG "); | ||
591 | while ( needWid > maxWid ) { | ||
592 | dayTest = dayTest.left( dayTest.length() - 1 ); | ||
593 | wid = fm.width( dayTest ); | ||
594 | needWid = wid * selCount; | ||
595 | } | ||
596 | int maxLen = dayTest.length(); | ||
597 | int fontPoint = dlf.pointSize(); | ||
598 | if ( maxLen < 2 ) { | ||
599 | int fontPoint = dlf.pointSize(); | ||
600 | while ( fontPoint > 4 ) { | ||
601 | --fontPoint; | ||
602 | dlf.setPointSize( fontPoint ); | ||
603 | QFontMetrics f( dlf ); | ||
604 | wid = f.width( "20" ); | ||
605 | needWid = wid * selCount; | ||
606 | if ( needWid < maxWid ) | ||
607 | break; | ||
608 | } | ||
609 | maxLen = 2; | ||
610 | } | ||
611 | //qDebug("Max len %d ", dayTest.length() ); | ||
612 | |||
613 | QFontMetrics tempF( dlf ); | ||
614 | newHight = tempF.height(); | ||
615 | mDayLabels->setFont( dlf ); | ||
616 | // mLayoutDayLabels = new QHBoxLayout(mDayLabels);; | ||
617 | // mLayoutDayLabels->addSpacing(mTimeLabels->width()); | ||
618 | //mLayoutDayLabels->addSpacing( 2 ); | ||
619 | // QFont lFont = dlf; | ||
620 | bool appendLabels = false; | ||
621 | QLabel *dayLabel; | ||
622 | dayLabel = mDayLabelsList.first(); | ||
623 | if ( !dayLabel ) { | ||
624 | appendLabels = true; | ||
625 | dayLabel = new QLabel(mDayLabels); | ||
626 | mDayLabelsList.append( dayLabel ); | ||
627 | mLayoutDayLabels->addWidget(dayLabel); | ||
628 | } | ||
629 | dayLabel->setFixedWidth( mTimeLabels->width()+2 ); | ||
630 | dayLabel->setFont( dlf ); | ||
631 | dayLabel->setAlignment(QLabel::AlignHCenter); | ||
632 | dayLabel->setText( KOGlobals::self()->calendarSystem()->monthName( mSelectedDates.first(), true ) ); | ||
633 | dayLabel->show(); | ||
634 | DateList::ConstIterator dit; | ||
635 | for( dit = mSelectedDates.begin(); dit != mSelectedDates.end(); ++dit ) { | ||
636 | QDate date = *dit; | ||
637 | // QBoxLayout *dayLayout = new QVBoxLayout(mLayoutDayLabels); | ||
638 | if ( ! appendLabels ) { | ||
639 | dayLabel = mDayLabelsList.next(); | ||
640 | if ( !dayLabel ) | ||
641 | appendLabels = true; | ||
642 | } | ||
643 | if ( appendLabels ) { | ||
644 | dayLabel = new QLabel(mDayLabels); | ||
645 | mDayLabelsList.append( dayLabel ); | ||
646 | mLayoutDayLabels->addWidget(dayLabel); | ||
647 | } | ||
648 | dayLabel->setMinimumWidth( 1 ); | ||
649 | dayLabel->setMaximumWidth( 2048 ); | ||
650 | dayLabel->setFont( dlf ); | ||
651 | dayLabel->show(); | ||
652 | QString str; | ||
653 | int dW = KOGlobals::self()->calendarSystem()->dayOfWeek(date); | ||
654 | QString dayName = KOGlobals::self()->calendarSystem()->weekDayName( dW, true ); | ||
655 | switch ( maxLen ) { | ||
656 | case 2: | ||
657 | str = QString::number( date.day() ); | ||
658 | break; | ||
659 | |||
660 | case 3: | ||
661 | str = dayName.left( 1 ) +QString::number( date.day()); | ||
662 | |||
663 | break; | ||
664 | case 4: | ||
665 | str = dayName.left( 1 ) + " " +QString::number( date.day()); | ||
666 | |||
667 | break; | ||
668 | case 5: | ||
669 | str = dayName.left( 2 ) + " " +QString::number( date.day()); | ||
670 | |||
671 | break; | ||
672 | case 6: | ||
673 | str = dayName.left( 3 ) + " " +QString::number( date.day()); | ||
674 | break; | ||
675 | |||
676 | default: | ||
677 | break; | ||
678 | } | ||
679 | |||
680 | dayLabel->setText(str); | ||
681 | dayLabel->setAlignment(QLabel::AlignHCenter); | ||
682 | if (date == QDate::currentDate()) { | ||
683 | QFont bFont = dlf; | ||
684 | bFont.setBold( true ); | ||
685 | dayLabel->setFont(bFont); | ||
686 | } | ||
687 | //dayLayout->addWidget(dayLabel); | ||
688 | |||
689 | #ifndef KORG_NOPLUGINS | ||
690 | CalendarDecoration::List cds = KOCore::self()->calendarDecorations(); | ||
691 | CalendarDecoration *it; | ||
692 | for(it = cds.first(); it; it = cds.next()) { | ||
693 | QString text = it->shortText( date ); | ||
694 | if ( !text.isEmpty() ) { | ||
695 | QLabel *label = new QLabel(text,mDayLabels); | ||
696 | label->setAlignment(AlignCenter); | ||
697 | dayLayout->addWidget(label); | ||
698 | } | ||
699 | } | ||
700 | |||
701 | for(it = cds.first(); it; it = cds.next()) { | ||
702 | QWidget *wid = it->smallWidget(mDayLabels,date); | ||
703 | if ( wid ) { | ||
704 | // wid->setHeight(20); | ||
705 | dayLayout->addWidget(wid); | ||
706 | } | ||
707 | } | ||
708 | #endif | ||
709 | } | ||
710 | if ( ! appendLabels ) { | ||
711 | dayLabel = mDayLabelsList.next(); | ||
712 | if ( !dayLabel ) | ||
713 | appendLabels = true; | ||
714 | } | ||
715 | if ( appendLabels ) { | ||
716 | dayLabel = new QLabel(mDayLabels); | ||
717 | mDayLabelsList.append( dayLabel ); | ||
718 | mLayoutDayLabels->addWidget(dayLabel); | ||
719 | } | ||
720 | //dayLabel->hide();//test only | ||
721 | |||
722 | int offset = (mAgenda->width() - mAgenda->verticalScrollBar()->width()-3 ) % mSelectedDates.count() ; | ||
723 | if ( offset < 0 ) offset = 0; | ||
724 | //qDebug("mLayoutDayLabels->addSpacing %d ", mAgenda->verticalScrollBar()->width()+offset+2 ); | ||
725 | dayLabel->setText("");//QString::number ( mSelectedDates.first().month() ) ); | ||
726 | dayLabel->show(); | ||
727 | dayLabel->setFixedWidth( mAgenda->verticalScrollBar()->width()+ offset ); | ||
728 | //qDebug("setToFixed %d ", mAgenda->verticalScrollBar()->width()+ offset+2); | ||
729 | //mLayoutDayLabels->addSpacing(mAgenda->verticalScrollBar()->width()+ offset+2); | ||
730 | if ( !appendLabels ) { | ||
731 | dayLabel = mDayLabelsList.next(); | ||
732 | while ( dayLabel ) { | ||
733 | //qDebug("!dayLabel %d",dayLabel ); | ||
734 | dayLabel->hide(); | ||
735 | dayLabel = mDayLabelsList.next(); | ||
736 | } | ||
737 | } | ||
738 | //mDayLabelsFrame->show(); | ||
739 | //mDayLabels->show(); | ||
740 | //qDebug("heigt %d %d %d ",mDayLabelsFrame->height(), mDayLabelsFrame->sizeHint().height(), newHight); | ||
741 | //mDayLabelsFrame->resize( mAgenda->visibleWidth(), newHight ); | ||
742 | mDayLabelsFrame->setFixedHeight( newHight ); | ||
743 | } | ||
744 | |||
745 | int KOAgendaView::maxDatesHint() | ||
746 | { | ||
747 | // Not sure about the max number of events, so return 0 for now. | ||
748 | return 0; | ||
749 | } | ||
750 | |||
751 | int KOAgendaView::currentDateCount() | ||
752 | { | ||
753 | return mSelectedDates.count(); | ||
754 | } | ||
755 | |||
756 | QPtrList<Incidence> KOAgendaView::selectedIncidences() | ||
757 | { | ||
758 | QPtrList<Incidence> selected; | ||
759 | Incidence *incidence; | ||
760 | |||
761 | incidence = mAgenda->selectedIncidence(); | ||
762 | if (incidence) selected.append(incidence); | ||
763 | |||
764 | incidence = mAllDayAgenda->selectedIncidence(); | ||
765 | if (incidence) selected.append(incidence); | ||
766 | |||
767 | return selected; | ||
768 | } | ||
769 | |||
770 | DateList KOAgendaView::selectedDates() | ||
771 | { | ||
772 | DateList selected; | ||
773 | QDate qd; | ||
774 | |||
775 | qd = mAgenda->selectedIncidenceDate(); | ||
776 | if (qd.isValid()) selected.append(qd); | ||
777 | |||
778 | qd = mAllDayAgenda->selectedIncidenceDate(); | ||
779 | if (qd.isValid()) selected.append(qd); | ||
780 | |||
781 | return selected; | ||
782 | } | ||
783 | |||
784 | |||
785 | void KOAgendaView::updateView() | ||
786 | { | ||
787 | if ( mBlockUpdating ) | ||
788 | return; | ||
789 | // kdDebug() << "KOAgendaView::updateView()" << endl; | ||
790 | fillAgenda(); | ||
791 | |||
792 | } | ||
793 | |||
794 | |||
795 | /* | ||
796 | Update configuration settings for the agenda view. This method is not | ||
797 | complete. | ||
798 | */ | ||
799 | void KOAgendaView::updateConfig() | ||
800 | { | ||
801 | if ( mBlockUpdating ) | ||
802 | return; | ||
803 | // kdDebug() << "KOAgendaView::updateConfig()" << endl; | ||
804 | |||
805 | // update config for children | ||
806 | mTimeLabels->updateConfig(); | ||
807 | mAgenda->storePosition(); | ||
808 | mAgenda->updateConfig(); | ||
809 | mAllDayAgenda->updateConfig(); | ||
810 | // widget synchronization | ||
811 | //TODO: find a better way, maybe signal/slot | ||
812 | mTimeLabels->positionChanged(); | ||
813 | |||
814 | // for some reason, this needs to be called explicitly | ||
815 | mTimeLabels->repaint(); | ||
816 | |||
817 | mDummyAllDayLeft->setFixedWidth(mTimeLabels->width()); | ||
818 | |||
819 | // ToolTips displaying summary of events | ||
820 | KOAgendaItem::toolTipGroup()->setEnabled(KOPrefs::instance() | ||
821 | ->mEnableToolTips); | ||
822 | |||
823 | //setHolidayMasks(); | ||
824 | |||
825 | //createDayLabels(); called by via updateView(); | ||
826 | mEventIndicatorTop->setXOffset(mTimeLabels->width() + mAgenda->frameWidth()); | ||
827 | updateView(); | ||
828 | mAgenda->restorePosition(); | ||
829 | } | ||
830 | |||
831 | |||
832 | void KOAgendaView::updateEventDates(KOAgendaItem *item, int type) | ||
833 | { | ||
834 | // kdDebug() << "KOAgendaView::updateEventDates(): " << item->text() << endl; | ||
835 | //qDebug("KOAgendaView::updateEventDates "); | ||
836 | QDateTime startDt,endDt; | ||
837 | QDate startDate; | ||
838 | int lenInSecs; | ||
839 | // if ( type == KOAgenda::RESIZETOP ) | ||
840 | // qDebug("RESIZETOP "); | ||
841 | // if ( type == KOAgenda::RESIZEBOTTOM ) | ||
842 | // qDebug("RESIZEBOTTOM "); | ||
843 | // if ( type == KOAgenda::MOVE ) | ||
844 | // qDebug("MOVE "); | ||
845 | if ( item->incidence()->type() == "Event" ) { | ||
846 | startDt =item->incidence()->dtStart(); | ||
847 | endDt = item->incidence()->dtEnd(); | ||
848 | lenInSecs = startDt.secsTo( endDt ); | ||
849 | } | ||
850 | |||
851 | // emit incidenceItemChanged( item->incidence(), KOGlobals::EVENTEDITED ); | ||
852 | |||
853 | if ( item->incidence()->type()=="Todo" && item->mLastMoveXPos > 0 ) { | ||
854 | startDate = mSelectedDates[item->mLastMoveXPos]; | ||
855 | } else { | ||
856 | if (item->cellX() < 0) { | ||
857 | startDate = (mSelectedDates.first()).addDays(item->cellX()); | ||
858 | } else { | ||
859 | startDate = mSelectedDates[item->cellX()]; | ||
860 | } | ||
861 | } | ||
862 | startDt.setDate(startDate); | ||
863 | |||
864 | if (item->incidence()->doesFloat()) { | ||
865 | endDt.setDate(startDate.addDays(item->cellWidth() - 1)); | ||
866 | } else { | ||
867 | if ( type == KOAgenda::RESIZETOP || type == KOAgenda::MOVE ) | ||
868 | startDt.setTime(mAgenda->gyToTime(item->cellYTop())); | ||
869 | if ( item->incidence()->type() == "Event" ) { | ||
870 | if ( type == KOAgenda::MOVE ) { | ||
871 | endDt = startDt.addSecs(lenInSecs); | ||
872 | |||
873 | } else if ( type == KOAgenda::RESIZEBOTTOM ) { | ||
874 | if (item->lastMultiItem()) { | ||
875 | endDt.setTime(mAgenda->gyToTime(item->lastMultiItem()->cellYBottom()+1)); | ||
876 | endDt.setDate(startDate. | ||
877 | addDays(item->lastMultiItem()->cellX() - item->cellX())); | ||
878 | } else { | ||
879 | endDt.setTime(mAgenda->gyToTime(item->cellYBottom()+1)); | ||
880 | endDt.setDate(startDate); | ||
881 | } | ||
882 | } | ||
883 | } else { | ||
884 | // todo | ||
885 | if (item->lastMultiItem()) { | ||
886 | endDt.setTime(mAgenda->gyToTime(item->lastMultiItem()->cellYBottom()+1)); | ||
887 | endDt.setDate(startDate. | ||
888 | addDays(item->lastMultiItem()->cellX() - item->cellX())); | ||
889 | } else { | ||
890 | //qDebug("tem->cellYBottom() %d",item->cellYBottom() ); | ||
891 | if ( item->cellYBottom() > 0 ) | ||
892 | endDt.setTime(mAgenda->gyToTime(item->cellYBottom()+1)); | ||
893 | else | ||
894 | endDt.setTime((static_cast<Todo*>(item->incidence()))->dtDue().time()); | ||
895 | endDt.setDate(startDate); | ||
896 | } | ||
897 | } | ||
898 | } | ||
899 | |||
900 | |||
901 | if ( item->incidence()->type() == "Event" ) { | ||
902 | item->incidence()->setDtStart(startDt); | ||
903 | (static_cast<Event*>(item->incidence()))->setDtEnd(endDt); | ||
904 | } else if ( item->incidence()->type() == "Todo" ) { | ||
905 | (static_cast<Todo*>(item->incidence()))->setDtDue(endDt); | ||
906 | } | ||
907 | //qDebug("KOAgendaView::updateEventDates stsart %s end %s ", startDt.toString().latin1(), endDt.toString().latin1() ); | ||
908 | item->incidence()->setRevision(item->incidence()->revision()+1); | ||
909 | item->setItemDate(startDt.date()); | ||
910 | //item->updateItem(); | ||
911 | if ( item->incidence()->type() == "Todo" ) { | ||
912 | emit todoMoved((Todo*)item->incidence(), KOGlobals::EVENTEDITED ); | ||
913 | |||
914 | } | ||
915 | else | ||
916 | emit incidenceChanged(item->incidence(), KOGlobals::EVENTEDITED); | ||
917 | item->updateItem(); | ||
918 | } | ||
919 | |||
920 | void KOAgendaView::showDates( const QDate &start, const QDate &end ) | ||
921 | { | ||
922 | // kdDebug() << "KOAgendaView::selectDates" << endl; | ||
923 | |||
924 | mSelectedDates.clear(); | ||
925 | // qDebug("KOAgendaView::showDates "); | ||
926 | QDate d = start; | ||
927 | while (d <= end) { | ||
928 | mSelectedDates.append(d); | ||
929 | d = d.addDays( 1 ); | ||
930 | } | ||
931 | |||
932 | // and update the view | ||
933 | fillAgenda(); | ||
934 | } | ||
935 | |||
936 | |||
937 | void KOAgendaView::showEvents(QPtrList<Event>) | ||
938 | { | ||
939 | kdDebug() << "KOAgendaView::showEvents() is not yet implemented" << endl; | ||
940 | } | ||
941 | |||
942 | void KOAgendaView::changeEventDisplay(Event *, int) | ||
943 | { | ||
944 | // qDebug("KOAgendaView::changeEventDisplay "); | ||
945 | // kdDebug() << "KOAgendaView::changeEventDisplay" << endl; | ||
946 | // this should be re-written to be MUCH smarter. Right now we | ||
947 | // are just playing dumb. | ||
948 | fillAgenda(); | ||
949 | } | ||
950 | |||
951 | void KOAgendaView::fillAgenda(const QDate &) | ||
952 | { | ||
953 | // qDebug("KOAgendaView::fillAgenda "); | ||
954 | fillAgenda(); | ||
955 | } | ||
956 | |||
957 | void KOAgendaView::fillAgenda() | ||
958 | { | ||
959 | if ( globalFlagBlockStartup ) | ||
960 | return; | ||
961 | if ( globalFlagBlockAgenda == 1 ) | ||
962 | return; | ||
963 | //if ( globalFlagBlockAgenda == 2 ) | ||
964 | //globalFlagBlockAgenda = 0; | ||
965 | // globalFlagBlockPainting = false; | ||
966 | if ( globalFlagBlockAgenda == 0 ) | ||
967 | globalFlagBlockAgenda = 1; | ||
968 | // clearView(); | ||
969 | //qDebug("fillAgenda()++++ "); | ||
970 | globalFlagBlockAgendaItemPaint = 1; | ||
971 | mAllDayAgenda->changeColumns(mSelectedDates.count()); | ||
972 | mAgenda->changeColumns(mSelectedDates.count()); | ||
973 | qApp->processEvents(); | ||
974 | mEventIndicatorTop->changeColumns(mSelectedDates.count()); | ||
975 | mEventIndicatorBottom->changeColumns(mSelectedDates.count()); | ||
976 | setHolidayMasks(); | ||
977 | |||
978 | //mAgenda->hideUnused(); | ||
979 | //mAllDayAgenda->hideUnused(); | ||
980 | |||
981 | // mAgenda->blockNextRepaint( false ); | ||
982 | // mAgenda->viewport()->repaint(); | ||
983 | // mAgenda->blockNextRepaint( true ); | ||
984 | mMinY.resize(mSelectedDates.count()); | ||
985 | mMaxY.resize(mSelectedDates.count()); | ||
986 | |||
987 | QPtrList<Event> dayEvents; | ||
988 | |||
989 | // ToDo items shall be displayed for the day they are due, but only showed today if they are already overdue. | ||
990 | // Therefore, get all of them. | ||
991 | QPtrList<Todo> todos = calendar()->todos(); | ||
992 | |||
993 | mAgenda->setDateList(mSelectedDates); | ||
994 | |||
995 | QDate today = QDate::currentDate(); | ||
996 | |||
997 | DateList::ConstIterator dit; | ||
998 | int curCol = 0; | ||
999 | for( dit = mSelectedDates.begin(); dit != mSelectedDates.end(); ++dit ) { | ||
1000 | QDate currentDate = *dit; | ||
1001 | // kdDebug() << "KOAgendaView::fillAgenda(): " << currentDate.toString() | ||
1002 | // << endl; | ||
1003 | |||
1004 | dayEvents = calendar()->events(currentDate,true); | ||
1005 | |||
1006 | // Default values, which can never be reached | ||
1007 | mMinY[curCol] = mAgenda->timeToY(QTime(23,59)) + 1; | ||
1008 | mMaxY[curCol] = mAgenda->timeToY(QTime(0,0)) - 1; | ||
1009 | |||
1010 | unsigned int numEvent; | ||
1011 | for(numEvent=0;numEvent<dayEvents.count();++numEvent) { | ||
1012 | Event *event = dayEvents.at(numEvent); | ||
1013 | if ( !KOPrefs::instance()->mShowSyncEvents && event->uid().left(21) == QString("last-syncEvent-device") ) | ||
1014 | continue; | ||
1015 | // kdDebug() << " Event: " << event->summary() << endl; | ||
1016 | |||
1017 | int beginX = currentDate.daysTo(event->dtStart().date()) + curCol; | ||
1018 | int endX = currentDate.daysTo(event->dtEnd().date()) + curCol; | ||
1019 | |||
1020 | // kdDebug() << " beginX: " << beginX << " endX: " << endX << endl; | ||
1021 | |||
1022 | if (event->doesFloat()) { | ||
1023 | if (event->recurrence()->doesRecur()) { | ||
1024 | mAllDayAgenda->insertAllDayItem(event,currentDate,curCol,curCol); | ||
1025 | } else { | ||
1026 | if (beginX <= 0 && curCol == 0) { | ||
1027 | mAllDayAgenda->insertAllDayItem(event,currentDate,beginX,endX); | ||
1028 | } else if (beginX == curCol) { | ||
1029 | mAllDayAgenda->insertAllDayItem(event,currentDate,beginX,endX); | ||
1030 | } | ||
1031 | } | ||
1032 | } else if (event->isMultiDay()) { | ||
1033 | if ( event->doesRecur () ) { | ||
1034 | QDate dateit = currentDate; | ||
1035 | int count = 0; | ||
1036 | int max = event->dtStart().daysTo( event->dtEnd() ) +2; | ||
1037 | while (! event->recursOn( dateit ) && count <= max ) { | ||
1038 | ++count; | ||
1039 | dateit = dateit.addDays( -1 ); | ||
1040 | } | ||
1041 | bool ok; | ||
1042 | QDateTime nextOcstart = event->getNextOccurence( QDateTime(dateit) ,&ok ); | ||
1043 | if ( ok ) | ||
1044 | { | ||
1045 | int secs = event->dtStart().secsTo( event->dtEnd() ); | ||
1046 | QDateTime nextOcend =nextOcstart.addSecs( secs ); ; | ||
1047 | beginX = currentDate.daysTo(nextOcstart.date()) + curCol; | ||
1048 | endX = currentDate.daysTo(nextOcend.date()) + curCol; | ||
1049 | |||
1050 | } | ||
1051 | } | ||
1052 | int startY = mAgenda->timeToY(event->dtStart().time()); | ||
1053 | int endY = mAgenda->timeToY(event->dtEnd().time()) - 1; | ||
1054 | //qDebug("insert %d %d %d %d %d ",beginX,endX,startY,endY , curCol ); | ||
1055 | if ((beginX <= 0 && curCol == 0) || beginX == curCol) { | ||
1056 | //qDebug("insert!!! "); | ||
1057 | mAgenda->insertMultiItem(event,currentDate,beginX,endX,startY,endY); | ||
1058 | } | ||
1059 | if (beginX == curCol) { | ||
1060 | mMaxY[curCol] = mAgenda->timeToY(QTime(23,59)); | ||
1061 | if (startY < mMinY[curCol]) mMinY[curCol] = startY; | ||
1062 | } else if (endX == curCol) { | ||
1063 | mMinY[curCol] = mAgenda->timeToY(QTime(0,0)); | ||
1064 | if (endY > mMaxY[curCol]) mMaxY[curCol] = endY; | ||
1065 | } else { | ||
1066 | mMinY[curCol] = mAgenda->timeToY(QTime(0,0)); | ||
1067 | mMaxY[curCol] = mAgenda->timeToY(QTime(23,59)); | ||
1068 | } | ||
1069 | } else { | ||
1070 | int startY = mAgenda->timeToY(event->dtStart().time()); | ||
1071 | int endY = mAgenda->timeToY(event->dtEnd().time()) - 1; | ||
1072 | if (endY < startY) endY = startY; | ||
1073 | mAgenda->insertItem(event,currentDate,curCol,startY,endY); | ||
1074 | if (startY < mMinY[curCol]) mMinY[curCol] = startY; | ||
1075 | if (endY > mMaxY[curCol]) mMaxY[curCol] = endY; | ||
1076 | } | ||
1077 | } | ||
1078 | // ---------- [display Todos -------------- | ||
1079 | unsigned int numTodo; | ||
1080 | for (numTodo = 0; numTodo < todos.count(); ++numTodo) { | ||
1081 | Todo *todo = todos.at(numTodo); | ||
1082 | |||
1083 | if ( ! todo->hasDueDate() ) continue; // todo shall not be displayed if it has no date | ||
1084 | |||
1085 | // ToDo items shall be displayed for the day they are due, but only showed today if they are already overdue. | ||
1086 | // Already completed items can be displayed on their original due date | ||
1087 | //if not KOPrefs::instance()->mShowTodoInAgenda, show overdue in agenda | ||
1088 | bool overdue = (!todo->isCompleted()) && (todo->dtDue() < today) && KOPrefs::instance()->mShowTodoInAgenda; | ||
1089 | |||
1090 | if ( ((todo->dtDue().date() == currentDate) && !overdue) || | ||
1091 | ((currentDate == today) && overdue) ) { | ||
1092 | if ( todo->doesFloat() || overdue ) { // Todo has no due-time set or is already overdue | ||
1093 | if ( KOPrefs::instance()->mShowTodoInAgenda ) | ||
1094 | mAllDayAgenda->insertAllDayItem(todo, currentDate, curCol, curCol); | ||
1095 | } | ||
1096 | else { | ||
1097 | |||
1098 | int endY = mAgenda->timeToY(todo->dtDue().time()) - 1; | ||
1099 | int hi = (18/KOPrefs::instance()->mHourSize); | ||
1100 | //qDebug("hei %d ",KOPrefs::instance()->mHourSize); | ||
1101 | int startY = endY -hi; | ||
1102 | |||
1103 | mAgenda->insertItem(todo,currentDate,curCol,startY,endY); | ||
1104 | |||
1105 | if (startY < mMinY[curCol]) mMinY[curCol] = startY; | ||
1106 | if (endY > mMaxY[curCol]) mMaxY[curCol] = endY; | ||
1107 | } | ||
1108 | } | ||
1109 | } | ||
1110 | // ---------- display Todos] -------------- | ||
1111 | |||
1112 | ++curCol; | ||
1113 | } | ||
1114 | mAgenda->hideUnused(); | ||
1115 | mAllDayAgenda->hideUnused(); | ||
1116 | mAgenda->checkScrollBoundaries(); | ||
1117 | |||
1118 | deleteSelectedDateTime(); | ||
1119 | |||
1120 | createDayLabels(); | ||
1121 | emit incidenceSelected( 0 ); | ||
1122 | |||
1123 | if ( globalFlagBlockAgenda == 2 ) { | ||
1124 | if ( KOPrefs::instance()->mSetTimeToDayStartAt ) | ||
1125 | setStartHour( KOPrefs::instance()->mDayBegins ); | ||
1126 | else if ( KOPrefs::instance()->mCenterOnCurrentTime ) | ||
1127 | setStartHour( QTime::currentTime ().hour() ); | ||
1128 | // qApp->processEvents(); | ||
1129 | } | ||
1130 | qApp->processEvents(); | ||
1131 | //qDebug("qApp->processEvents(); END "); | ||
1132 | globalFlagBlockAgenda = 0; | ||
1133 | |||
1134 | // mAgenda->hideUnused(); | ||
1135 | //mAllDayAgenda->hideUnused(); | ||
1136 | mAllDayAgenda->drawContentsToPainter(); | ||
1137 | mAgenda->drawContentsToPainter(); | ||
1138 | repaintAgenda(); | ||
1139 | // mAgenda->finishUpdate(); | ||
1140 | //mAllDayAgenda->finishUpdate(); | ||
1141 | |||
1142 | // repaintAgenda(); | ||
1143 | //qApp->processEvents(); | ||
1144 | // globalFlagBlockAgenda = 0; | ||
1145 | } | ||
1146 | void KOAgendaView::repaintAgenda() | ||
1147 | { | ||
1148 | // mAllDayAgenda->drawContentsToPainter(); | ||
1149 | // mAllDayAgenda->viewport()->repaint( false ); | ||
1150 | // mAgenda->drawContentsToPainter(); | ||
1151 | // mAgenda->viewport()->repaint( false ); | ||
1152 | // qApp->processEvents(); | ||
1153 | |||
1154 | //qDebug("KOAgendaView::repaintAgenda() "); | ||
1155 | //qApp->processEvents(); | ||
1156 | mAgenda->viewport()->repaint( false ); | ||
1157 | mAllDayAgenda->viewport()->repaint( false ); | ||
1158 | mAgenda->finishUpdate(); | ||
1159 | mAllDayAgenda->finishUpdate(); | ||
1160 | } | ||
1161 | |||
1162 | |||
1163 | void KOAgendaView::clearView() | ||
1164 | { | ||
1165 | // kdDebug() << "ClearView" << endl; | ||
1166 | mAllDayAgenda->clear(); | ||
1167 | mAgenda->clear(); | ||
1168 | } | ||
1169 | |||
1170 | void KOAgendaView::printPreview(CalPrinter *calPrinter, const QDate &fd, | ||
1171 | const QDate &td) | ||
1172 | { | ||
1173 | #ifndef KORG_NOPRINTER | ||
1174 | if (fd == td) | ||
1175 | calPrinter->preview(CalPrinter::Day, fd, td); | ||
1176 | else | ||
1177 | calPrinter->preview(CalPrinter::Week, fd, td); | ||
1178 | #endif | ||
1179 | } | ||
1180 | |||
1181 | // void KOAgendaView::updateMovedTodo() | ||
1182 | // { | ||
1183 | // // updateConfig(); | ||
1184 | // // emit updateTodoViews(); | ||
1185 | // } | ||
1186 | |||
1187 | void KOAgendaView::newEvent(int gx, int gy) | ||
1188 | { | ||
1189 | if (!mSelectedDates.count()) return; | ||
1190 | |||
1191 | QDate day = mSelectedDates[gx]; | ||
1192 | |||
1193 | QTime time = mAgenda->gyToTime(gy); | ||
1194 | QDateTime dt(day,time); | ||
1195 | // if ( dt < QDateTime::currentDateTime () ) | ||
1196 | // dt = QDateTime::currentDateTime ().addSecs( 3600 ); | ||
1197 | emit newEventSignal(dt); | ||
1198 | } | ||
1199 | |||
1200 | void KOAgendaView::newEvent(int gxStart, int gyStart, int gxEnd, int gyEnd) | ||
1201 | { | ||
1202 | if (!mSelectedDates.count()) return; | ||
1203 | |||
1204 | QDate dayStart = mSelectedDates[gxStart]; | ||
1205 | QDate dayEnd = mSelectedDates[gxEnd]; | ||
1206 | |||
1207 | QTime timeStart = mAgenda->gyToTime(gyStart); | ||
1208 | QTime timeEnd = mAgenda->gyToTime( gyEnd + 1 ); | ||
1209 | |||
1210 | QDateTime dtStart(dayStart,timeStart); | ||
1211 | QDateTime dtEnd(dayEnd,timeEnd); | ||
1212 | |||
1213 | emit newEventSignal(dtStart,dtEnd); | ||
1214 | } | ||
1215 | |||
1216 | void KOAgendaView::newEventAllDay(int gx, int ) | ||
1217 | { | ||
1218 | if (!mSelectedDates.count()) return; | ||
1219 | |||
1220 | QDate day = mSelectedDates[gx]; | ||
1221 | |||
1222 | emit newEventSignal(day); | ||
1223 | } | ||
1224 | |||
1225 | void KOAgendaView::updateEventIndicatorTop(int newY) | ||
1226 | { | ||
1227 | uint i; | ||
1228 | for(i=0;i<mMinY.size();++i) { | ||
1229 | if (newY >= mMinY.at(i)) mEventIndicatorTop->enableColumn(i,true); | ||
1230 | else mEventIndicatorTop->enableColumn(i,false); | ||
1231 | } | ||
1232 | |||
1233 | mEventIndicatorTop->update(); | ||
1234 | } | ||
1235 | |||
1236 | void KOAgendaView::updateEventIndicatorBottom(int newY) | ||
1237 | { | ||
1238 | uint i; | ||
1239 | for(i=0;i<mMaxY.size();++i) { | ||
1240 | if (newY <= mMaxY.at(i)) mEventIndicatorBottom->enableColumn(i,true); | ||
1241 | else mEventIndicatorBottom->enableColumn(i,false); | ||
1242 | } | ||
1243 | |||
1244 | mEventIndicatorBottom->update(); | ||
1245 | } | ||
1246 | |||
1247 | void KOAgendaView::startDrag(Event *event) | ||
1248 | { | ||
1249 | #ifndef KORG_NODND | ||
1250 | DndFactory factory( calendar() ); | ||
1251 | ICalDrag *vd = factory.createDrag(event,this); | ||
1252 | if (vd->drag()) { | ||
1253 | kdDebug() << "KOAgendaView::startDrag(): Delete drag source" << endl; | ||
1254 | } | ||
1255 | #endif | ||
1256 | } | ||
1257 | |||
1258 | void KOAgendaView::readSettings() | ||
1259 | { | ||
1260 | readSettings(KOGlobals::config()); | ||
1261 | } | ||
1262 | |||
1263 | void KOAgendaView::readSettings(KConfig *config) | ||
1264 | { | ||
1265 | // kdDebug() << "KOAgendaView::readSettings()" << endl; | ||
1266 | |||
1267 | config->setGroup("Views"); | ||
1268 | |||
1269 | //#ifndef KORG_NOSPLITTER | ||
1270 | QValueList<int> sizes = config->readIntListEntry("Separator AgendaView"); | ||
1271 | if (sizes.count() == 2) { | ||
1272 | if ( sizes[0] < 20 ) { | ||
1273 | sizes[1] = sizes[1] +20 - sizes[0]; | ||
1274 | sizes[0] = 20; | ||
1275 | } | ||
1276 | mSplitterAgenda->setSizes(sizes); | ||
1277 | // qDebug("read %d %d ",sizes[0],sizes[1] ); | ||
1278 | } | ||
1279 | //#endif | ||
1280 | |||
1281 | // updateConfig(); | ||
1282 | } | ||
1283 | |||
1284 | void KOAgendaView::writeSettings(KConfig *config) | ||
1285 | { | ||
1286 | // kdDebug() << "KOAgendaView::writeSettings()" << endl; | ||
1287 | |||
1288 | config->setGroup("Views"); | ||
1289 | |||
1290 | //#ifndef KORG_NOSPLITTER | ||
1291 | QValueList<int> list = mSplitterAgenda->sizes(); | ||
1292 | config->writeEntry("Separator AgendaView",list); | ||
1293 | //qDebug("write %d %d ", list[0],list[1] ); | ||
1294 | //#endif | ||
1295 | } | ||
1296 | |||
1297 | void KOAgendaView::setHolidayMasks() | ||
1298 | { | ||
1299 | mHolidayMask.resize(mSelectedDates.count()); | ||
1300 | |||
1301 | uint i; | ||
1302 | for(i=0;i<mSelectedDates.count();++i) { | ||
1303 | QDate date = mSelectedDates[i]; | ||
1304 | bool showSaturday = KOPrefs::instance()->mExcludeSaturdays && (date.dayOfWeek() == 6); | ||
1305 | bool showSunday = KOPrefs::instance()->mExcludeHolidays && (date.dayOfWeek() == 7); | ||
1306 | #ifndef KORG_NOPLUGINS | ||
1307 | bool showHoliday = KOPrefs::instance()->mExcludeHolidays && | ||
1308 | !KOCore::self()->holiday(date).isEmpty(); | ||
1309 | bool showDay = showSaturday || showSunday || showHoliday; | ||
1310 | #else | ||
1311 | bool showDay = showSaturday || showSunday; | ||
1312 | #endif | ||
1313 | if (showDay) { | ||
1314 | mHolidayMask.at(i) = true; | ||
1315 | } else { | ||
1316 | mHolidayMask.at(i) = false; | ||
1317 | } | ||
1318 | } | ||
1319 | |||
1320 | mAgenda->setHolidayMask(&mHolidayMask); | ||
1321 | mAllDayAgenda->setHolidayMask(&mHolidayMask); | ||
1322 | } | ||
1323 | |||
1324 | void KOAgendaView::setContentsPos(int y) | ||
1325 | { | ||
1326 | mAgenda->setContentsPos(0,y); | ||
1327 | } | ||
1328 | |||
1329 | void KOAgendaView::setExpandedButton( bool expanded ) | ||
1330 | { | ||
1331 | if ( expanded ) { | ||
1332 | mExpandButton->setPixmap( mExpandedPixmap ); | ||
1333 | } else { | ||
1334 | mExpandButton->setPixmap( mNotExpandedPixmap ); | ||
1335 | } | ||
1336 | } | ||
1337 | |||
1338 | void KOAgendaView::clearSelection() | ||
1339 | { | ||
1340 | mAgenda->deselectItem(); | ||
1341 | mAllDayAgenda->deselectItem(); | ||
1342 | } | ||
1343 | |||
1344 | void KOAgendaView::newTimeSpanSelectedAllDay(int gxStart, int gyStart, | ||
1345 | int gxEnd, int gyEnd) | ||
1346 | { | ||
1347 | mTimeSpanInAllDay = true; | ||
1348 | newTimeSpanSelected(gxStart,gyStart,gxEnd,gyEnd); | ||
1349 | } | ||
1350 | |||
1351 | |||
1352 | |||
1353 | |||
1354 | void KOAgendaView::newTimeSpanSelected(int gxStart, int gyStart, | ||
1355 | int gxEnd, int gyEnd) | ||
1356 | { | ||
1357 | if (!mSelectedDates.count()) return; | ||
1358 | |||
1359 | QDate dayStart = mSelectedDates[gxStart]; | ||
1360 | QDate dayEnd = mSelectedDates[gxEnd]; | ||
1361 | |||
1362 | QTime timeStart = mAgenda->gyToTime(gyStart); | ||
1363 | QTime timeEnd = mAgenda->gyToTime( gyEnd + 1 ); | ||
1364 | |||
1365 | QDateTime dtStart(dayStart,timeStart); | ||
1366 | QDateTime dtEnd(dayEnd,timeEnd); | ||
1367 | |||
1368 | mTimeSpanBegin = dtStart; | ||
1369 | mTimeSpanEnd = dtEnd; | ||
1370 | |||
1371 | } | ||
1372 | |||
1373 | void KOAgendaView::deleteSelectedDateTime() | ||
1374 | { | ||
1375 | mTimeSpanBegin.setDate(QDate()); | ||
1376 | mTimeSpanEnd.setDate(QDate()); | ||
1377 | mTimeSpanInAllDay = false; | ||
1378 | } | ||
1379 | |||
1380 | void KOAgendaView::keyPressEvent ( QKeyEvent * e ) | ||
1381 | { | ||
1382 | e->ignore(); | ||
1383 | } | ||
1384 | |||
1385 | void KOAgendaView::scrollOneHourUp() | ||
1386 | { | ||
1387 | |||
1388 | mAgenda->scrollBy ( 0, -mAgenda->contentsHeight () / 24 ); | ||
1389 | } | ||
1390 | void KOAgendaView::scrollOneHourDown() | ||
1391 | { | ||
1392 | mAgenda->scrollBy ( 0, mAgenda->contentsHeight () / 24 ); | ||
1393 | } | ||
1394 | |||
1395 | void KOAgendaView::setStartHour( int h ) | ||
1396 | { | ||
1397 | mAgenda->setStartHour( h ); | ||
1398 | |||
1399 | } | ||
1400 | |||
1401 | void KOAgendaView::updateTodo( Todo * t, int ) | ||
1402 | { | ||
1403 | |||
1404 | bool remove = false; | ||
1405 | bool removeAD = false; | ||
1406 | if ( ! t->hasDueDate() ) { | ||
1407 | remove = true; | ||
1408 | removeAD = true; | ||
1409 | } | ||
1410 | else { | ||
1411 | bool overdue = (!t->isCompleted()) && (t->dtDue() < QDate::currentDate()) && KOPrefs::instance()->mShowTodoInAgenda ; | ||
1412 | if ( overdue && | ||
1413 | QDate::currentDate() >= mSelectedDates.first() && | ||
1414 | QDate::currentDate() <= mSelectedDates.last()) { | ||
1415 | removeAD = false; | ||
1416 | remove = true; | ||
1417 | } | ||
1418 | else { | ||
1419 | if ( t->dtDue().date() < mSelectedDates.first() || | ||
1420 | t->dtDue().date() > mSelectedDates.last() ) { | ||
1421 | remove = true; | ||
1422 | removeAD = true; | ||
1423 | } else { | ||
1424 | remove = t->doesFloat(); | ||
1425 | removeAD = !remove; | ||
1426 | } | ||
1427 | } | ||
1428 | } | ||
1429 | int days = mSelectedDates.first().daysTo( t->dtDue().date() ); | ||
1430 | // qDebug("daysto %d ", days ); | ||
1431 | mAgenda->updateTodo( t , days, remove); | ||
1432 | if ( KOPrefs::instance()->mShowTodoInAgenda ) | ||
1433 | mAllDayAgenda->updateTodo( t , days, removeAD); | ||
1434 | //qDebug("KOAgendaView::updateTodo( Todo *, int ) "); | ||
1435 | |||
1436 | } | ||