SVN_SILENT made messages (.desktop file)
[kdepim.git] / korganizer / datenavigatorcontainer.cpp
blob77fa3c5a372a9f3fcd0f95b7da05173165246c90
1 /*
2 This file is part of KOrganizer.
4 Copyright (c) 2001,2002,2003 Cornelius Schumacher <schumacher@kde.org>
5 Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
7 Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.net>
8 Author: Sergio Martins <sergio@kdab.com>
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.
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.
20 You should have received a copy of the GNU General Public License along
21 with this program; if not, write to the Free Software Foundation, Inc.,
22 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24 As a special exception, permission is given to link this program
25 with any edition of Qt, and distribute the resulting executable,
26 without including the source code for Qt in the source distribution.
29 #include "datenavigatorcontainer.h"
30 #include "kdatenavigator.h"
31 #include "kodaymatrix.h"
32 #include "koglobals.h"
33 #include "navigatorbar.h"
35 #include <KCalendarSystem>
37 #include <QTimer>
39 DateNavigatorContainer::DateNavigatorContainer(QWidget *parent)
40 : QFrame(parent),
41 mHorizontalCount(1), mVerticalCount(1),
42 mIgnoreNavigatorUpdates(false)
44 mNavigatorView = new KDateNavigator(this);
45 mNavigatorView->setWhatsThis(
46 i18n("<qt><p>Select the dates you want to "
47 "display in KOrganizer's main view here. Hold the "
48 "mouse button to select more than one day.</p>"
49 "<p>Press the top buttons to browse to the next "
50 "/ previous months or years.</p>"
51 "<p>Each line shows a week. The number in the left "
52 "column is the number of the week in the year. "
53 "Press it to select the whole week.</p>"
54 "</qt>"));
56 connectNavigatorView(mNavigatorView);
59 DateNavigatorContainer::~DateNavigatorContainer()
61 qDeleteAll(mExtraViews);
64 void DateNavigatorContainer::connectNavigatorView(KDateNavigator *v)
66 connect(v, SIGNAL(datesSelected(KCalCore::DateList)),
67 SLOT(handleDatesSelectedSignal(KCalCore::DateList)));
69 connect(v, SIGNAL(incidenceDropped(Akonadi::Item,QDate)),
70 SIGNAL(incidenceDropped(Akonadi::Item,QDate)));
71 connect(v, SIGNAL(incidenceDroppedMove(Akonadi::Item,QDate)),
72 SIGNAL(incidenceDroppedMove(Akonadi::Item,QDate)));
74 connect(v, SIGNAL(newEventSignal(QDate)),
75 SIGNAL(newEventSignal(QDate)));
76 connect(v, SIGNAL(newTodoSignal(QDate)),
77 SIGNAL(newTodoSignal(QDate)));
78 connect(v, SIGNAL(newJournalSignal(QDate)),
79 SIGNAL(newJournalSignal(QDate)));
81 connect(v, SIGNAL(weekClicked(QDate,QDate)),
82 SLOT(handleWeekClickedSignal(QDate,QDate)));
84 connect(v, SIGNAL(goPrevious()), SIGNAL(goPrevious()));
85 connect(v, SIGNAL(goNext()), SIGNAL(goNext()));
87 connect(v, SIGNAL(nextYearClicked()), SIGNAL(nextYearClicked()));
88 connect(v, SIGNAL(prevYearClicked()), SIGNAL(prevYearClicked()));
90 connect(v, SIGNAL(prevMonthClicked()), SLOT(goPrevMonth()));
91 connect(v, SIGNAL(nextMonthClicked()), SLOT(goNextMonth()));
93 connect(v, SIGNAL(monthSelected(int)), SIGNAL(monthSelected(int)));
94 connect(v, SIGNAL(yearSelected(int)), SIGNAL(yearSelected(int)));
97 void DateNavigatorContainer::setCalendar(const Akonadi::ETMCalendar::Ptr &calendar)
99 mCalendar = calendar;
100 mNavigatorView->setCalendar(calendar);
101 foreach (KDateNavigator *n, mExtraViews) {
102 if (n) {
103 n->setCalendar(calendar);
108 // TODO_Recurrence: let the navigators update just once, and tell them that
109 // if data has changed or just the selection (because then the list of dayss
110 // with events doesn't have to be updated if the month stayed the same
111 void DateNavigatorContainer::updateDayMatrix()
113 mNavigatorView->updateDayMatrix();
114 foreach (KDateNavigator *n, mExtraViews) {
115 if (n) {
116 n->updateDayMatrix();
121 void DateNavigatorContainer::updateToday()
123 mNavigatorView->updateToday();
124 foreach (KDateNavigator *n, mExtraViews) {
125 if (n) {
126 n->updateToday();
131 void DateNavigatorContainer::setUpdateNeeded()
133 mNavigatorView->setUpdateNeeded();
134 foreach (KDateNavigator *n, mExtraViews) {
135 if (n) {
136 n->setUpdateNeeded();
141 void DateNavigatorContainer::updateView()
143 mNavigatorView->updateView();
144 foreach (KDateNavigator *n, mExtraViews) {
145 if (n) {
146 n->setUpdateNeeded();
151 void DateNavigatorContainer::updateConfig()
153 mNavigatorView->updateConfig();
154 foreach (KDateNavigator *n, mExtraViews) {
155 if (n) {
156 n->updateConfig();
161 void DateNavigatorContainer::selectDates(const KCalCore::DateList &dateList,
162 const QDate &preferredMonth)
164 if (!dateList.isEmpty()) {
165 QDate start(dateList.first());
166 QDate end(dateList.last());
167 QDate navfirst(mNavigatorView->startDate());
168 QDate navsecond; // start of the second shown month if existent
169 QDate navlast;
170 if (!mExtraViews.isEmpty()) {
171 navlast = mExtraViews.last()->endDate();
172 navsecond = mExtraViews.first()->startDate();
173 } else {
174 navlast = mNavigatorView->endDate();
175 navsecond = navfirst;
178 const KCalendarSystem *calSys = KOGlobals::self()->calendarSystem();
180 // If the datelist crosses months we won't know which month to show
181 // so we read what's in preferredMonth
182 const bool changingMonth =
183 (preferredMonth.isValid() &&
184 calSys->month(mNavigatorView->month()) != calSys->month(preferredMonth));
186 if (start < navfirst || // <- start should always be visible
187 // end is not visible and we have a spare month at the beginning:
188 (end > navlast && start >= navsecond) ||
189 changingMonth) {
191 if (preferredMonth.isValid()) {
192 setBaseDates(preferredMonth);
193 } else {
194 setBaseDates(start);
198 if (!mIgnoreNavigatorUpdates) {
199 mNavigatorView->selectDates(dateList);
200 foreach (KDateNavigator *n, mExtraViews) {
201 if (n) {
202 n->selectDates(dateList);
209 void DateNavigatorContainer::setBaseDates(const QDate &start)
211 QDate baseDate = start;
212 if (!mIgnoreNavigatorUpdates) {
213 mNavigatorView->setBaseDate(baseDate);
216 foreach (KDateNavigator *n, mExtraViews) {
217 baseDate = KOGlobals::self()->calendarSystem()->addMonths(baseDate, 1);
218 if (!mIgnoreNavigatorUpdates) {
219 n->setBaseDate(baseDate);
224 void DateNavigatorContainer::resizeEvent(QResizeEvent *)
226 #if 0
227 qCDebug(KORGANIZER_LOG) << "DateNavigatorContainer::resizeEvent()";
228 qCDebug(KORGANIZER_LOG) << " CURRENT SIZE:" << size();
229 qCDebug(KORGANIZER_LOG) << " MINIMUM SIZEHINT:" << minimumSizeHint();
230 qCDebug(KORGANIZER_LOG) << " SIZEHINT:" << sizeHint();
231 qCDebug(KORGANIZER_LOG) << " MINIMUM SIZE:" << minimumSize();
232 #endif
233 QTimer::singleShot(0, this, SLOT(resizeAllContents()));
236 void DateNavigatorContainer::resizeAllContents()
238 QSize minSize = mNavigatorView->minimumSizeHint();
240 // qCDebug(KORGANIZER_LOG) << " NAVIGATORVIEW minimumSizeHint:" << minSize;
242 int verticalCount = size().height() / minSize.height();
243 int horizontalCount = size().width() / minSize.width();
245 if (horizontalCount != mHorizontalCount || verticalCount != mVerticalCount) {
246 int count = horizontalCount * verticalCount;
247 if (count == 0) {
248 return;
251 while (count > (mExtraViews.count() + 1)) {
252 KDateNavigator *n = new KDateNavigator(this);
253 mExtraViews.append(n);
254 n->setCalendar(mCalendar);
255 connectNavigatorView(n);
258 while (count < (mExtraViews.count() + 1)) {
259 delete(mExtraViews.last());
260 mExtraViews.removeLast();
263 mHorizontalCount = horizontalCount;
264 mVerticalCount = verticalCount;
265 setBaseDates(mNavigatorView->selectedDates().first());
266 selectDates(mNavigatorView->selectedDates());
267 foreach (KDateNavigator *n, mExtraViews) {
268 if (n) {
269 n->show();
274 int height = size().height() / verticalCount;
275 int width = size().width() / horizontalCount;
277 NavigatorBar *bar = mNavigatorView->navigatorBar();
278 if (horizontalCount > 1) {
279 bar->showButtons(true, false);
280 } else {
281 bar->showButtons(true, true);
284 mNavigatorView->setGeometry((((KOGlobals::self()->reverseLayout()) ?
285 (horizontalCount - 1) : 0) * width),
286 0, width, height);
287 for (int i = 0; i < mExtraViews.count(); ++i) {
288 int x = (i + 1) % horizontalCount;
289 int y = (i + 1) / horizontalCount;
291 KDateNavigator *view = mExtraViews.at(i);
292 bar = view->navigatorBar();
293 if (y > 0) {
294 bar->showButtons(false, false);
295 } else {
296 if (x + 1 == horizontalCount) {
297 bar->showButtons(false, true);
298 } else {
299 bar->showButtons(false, false);
302 view->setGeometry((((KOGlobals::self()->reverseLayout()) ?
303 (horizontalCount - 1 - x) : x) * width),
304 y * height, width, height);
309 QSize DateNavigatorContainer::minimumSizeHint() const
311 return mNavigatorView->minimumSizeHint();
314 QSize DateNavigatorContainer::sizeHint() const
316 return mNavigatorView->sizeHint();
319 void DateNavigatorContainer::setHighlightMode(bool highlightEvents,
320 bool highlightTodos,
321 bool highlightJournals) const
324 mNavigatorView->setHighlightMode(highlightEvents, highlightTodos, highlightJournals);
326 foreach (KDateNavigator *n, mExtraViews) {
327 if (n) {
328 n->setHighlightMode(highlightEvents, highlightTodos, highlightJournals);
334 void DateNavigatorContainer::goNextMonth()
336 const QPair<QDate, QDate> p = dateLimits(1);
338 emit nextMonthClicked(mNavigatorView->month(),
339 p.first,
340 p.second);
343 void DateNavigatorContainer::goPrevMonth()
345 const QPair<QDate, QDate> p = dateLimits(-1);
347 emit prevMonthClicked(mNavigatorView->month(),
348 p.first,
349 p.second);
352 QPair<QDate, QDate> DateNavigatorContainer::dateLimits(int offset) const
354 const KCalendarSystem *calSys = KOGlobals::self()->calendarSystem();
355 QDate firstMonth, lastMonth;
356 if (mExtraViews.isEmpty()) {
357 lastMonth = mNavigatorView->month();
358 } else {
359 lastMonth = mExtraViews.last()->month();
362 firstMonth = calSys->addMonths(mNavigatorView->month(), offset);
363 lastMonth = calSys->addMonths(lastMonth, offset);
365 QPair<QDate, QDate> firstMonthBoundary = KODayMatrix::matrixLimits(firstMonth);
366 QPair<QDate, QDate> lastMonthBoundary = KODayMatrix::matrixLimits(lastMonth);
368 return qMakePair(firstMonthBoundary.first, lastMonthBoundary.second);
371 QDate DateNavigatorContainer::monthOfNavigator(int navigatorIndex) const
373 if (navigatorIndex == 0) {
374 return mNavigatorView->month();
377 if (navigatorIndex <= mExtraViews.count() && navigatorIndex >= 0) {
378 return mExtraViews[navigatorIndex - 1]->month();
379 } else {
380 return QDate();
384 void DateNavigatorContainer::handleDatesSelectedSignal(const KCalCore::DateList &dateList)
386 Q_ASSERT(sender());
387 // When we have more than one KDateNavigator, both can have the
388 // same selection ( because they can share weeks )
389 // The month that we send in the datesSelected() signal should be
390 // the one belonging to the KDatenavigator with the earliest month
391 const QDate firstDate = dateList.first();
392 KDateNavigator *navigator = firstNavigatorForDate(firstDate);
393 navigator = navigator ? navigator : qobject_cast<KDateNavigator *>(sender());
395 emit datesSelected(dateList, navigator->month());
398 void DateNavigatorContainer::handleWeekClickedSignal(const QDate &week, const QDate &)
400 Q_ASSERT(sender());
401 KDateNavigator *navigator = firstNavigatorForDate(week);
402 navigator = navigator ? navigator : qobject_cast<KDateNavigator *>(sender());
404 emit weekClicked(week, navigator->month());
407 KDateNavigator *DateNavigatorContainer::firstNavigatorForDate(const QDate &date) const
409 KDateNavigator *navigator = Q_NULLPTR;
410 if (date.isValid()) {
411 QPair<QDate, QDate> limits = KODayMatrix::matrixLimits(mNavigatorView->month());
413 if (date >= limits.first && date <= limits.second) {
414 // The date is in the first navigator
415 navigator = mNavigatorView;
416 } else {
417 foreach (KDateNavigator *nav, mExtraViews) {
418 if (nav) {
419 limits = KODayMatrix::matrixLimits(nav->month());
420 if (date >= limits.first && date <= limits.second) {
421 navigator = nav;
422 break;
429 return navigator;