Fixed some bugs added with Plasma::SpinBox.
[kdebase.git] / workspace / libs / plasmaclock / calendar.cpp
blobe480fbc6346ebf98892dd0bf12b240d77e2809ea
1 /*
2 * Copyright 2008 Davide Bettio <davide.bettio@kdemail.net>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Library General Public License as
6 * published by the Free Software Foundation; either version 2, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details
14 * You should have received a copy of the GNU Library General Public
15 * License along with this program; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 #include "calendar.h"
22 //Qt
23 #include <QtCore/QDate>
24 #include <QtGui/QGraphicsSceneWheelEvent>
25 #include <QtGui/QGraphicsLinearLayout>
26 #include <QtGui/QGraphicsProxyWidget>
27 #include <QtGui/QLabel>
28 #include <QtGui/QMenu>
29 #include <QtGui/QSpinBox>
30 #include <QtGui/QToolButton>
32 //KDECore
33 #include <KCalendarSystem>
34 #include <KDebug>
35 #include <KGlobal>
36 #include <KIcon>
37 #include <KLineEdit>
38 #include <KLocale>
39 #include <KIntSpinBox>
41 //Plasma
42 #include <Plasma/Label>
43 #include <Plasma/LineEdit>
44 #include <Plasma/SpinBox>
45 #include <Plasma/ToolButton>
47 namespace Plasma
50 class CalendarPrivate
52 public:
53 ToolButton *back;
54 Plasma::Label *spacer0;
55 Plasma::ToolButton *month;
56 Plasma::SpinBox *yearSpinBox;
57 Plasma::ToolButton *year;
58 Plasma::Label *spacer1;
59 Plasma::ToolButton *forward;
60 Plasma::CalendarTable *calendarTable;
61 Plasma::LineEdit *dateText;
62 ToolButton *jumpToday;
63 QMenu *monthMenu;
64 Plasma::SpinBox *weekSpinBox;
67 //TODO
68 Calendar::Calendar(const QDate &, QGraphicsWidget *parent)
69 : QGraphicsWidget(parent), d(new CalendarPrivate())
74 Calendar::Calendar(QGraphicsWidget *parent)
75 : QGraphicsWidget(parent), d(new CalendarPrivate())
77 QGraphicsLinearLayout *m_layout = new QGraphicsLinearLayout(Qt::Vertical, this);
78 QGraphicsLinearLayout *m_hLayout = new QGraphicsLinearLayout(m_layout);
79 QGraphicsLinearLayout *m_layoutTools = new QGraphicsLinearLayout(m_layout);
81 d->calendarTable = new Plasma::CalendarTable(this);
82 d->calendarTable->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
84 d->back = new Plasma::ToolButton(this);
85 d->back->setText("<");
86 d->back->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
87 connect(d->back, SIGNAL(clicked()), this, SLOT(prevMonth()));
88 m_hLayout->addItem(d->back);
90 m_hLayout->addStretch();
92 d->month = new Plasma::ToolButton(this);
93 d->month->setText(d->calendarTable->calendar()->monthName(d->calendarTable->calendar()->month(d->calendarTable->date()), d->calendarTable->calendar()->year(d->calendarTable->date())));
94 d->month->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
95 connect(d->month, SIGNAL(clicked()), this, SLOT(monthsPopup()));
96 m_hLayout->addItem(d->month);
98 d->year = new Plasma::ToolButton(this);
99 d->year->setText(QString::number(d->calendarTable->calendar()->year(d->calendarTable->date())));
100 d->year->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
101 connect(d->year, SIGNAL(clicked()), this, SLOT(showYearSpinBox()));
102 m_hLayout->addItem(d->year);
104 d->yearSpinBox = new Plasma::SpinBox(this);
105 d->yearSpinBox->setRange(d->calendarTable->calendar()->year(d->calendarTable->calendar()->earliestValidDate()), d->calendarTable->calendar()->year(d->calendarTable->calendar()->latestValidDate()));
106 d->yearSpinBox->setValue(d->calendarTable->calendar()->year(d->calendarTable->date()));
107 d->yearSpinBox->hide();
108 connect(d->yearSpinBox->nativeWidget(), SIGNAL(editingFinished()), this, SLOT(hideYearSpinBox()));
110 m_hLayout->addStretch();
112 d->forward = new Plasma::ToolButton(this);
113 d->forward->setText(">");
114 d->forward->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
115 connect(d->forward, SIGNAL(clicked()), this, SLOT(nextMonth()));
116 m_hLayout->addItem(d->forward);
118 m_layout->addItem(m_hLayout);
120 m_layout->addItem(d->calendarTable);
122 d->jumpToday = new Plasma::ToolButton(this);
123 d->jumpToday->nativeWidget()->setIcon(KIcon("go-jump-today"));
124 d->jumpToday->nativeWidget()->setMinimumWidth(25);
125 connect(d->jumpToday, SIGNAL(clicked()), this, SLOT(goToToday()));
126 m_layoutTools->addItem(d->jumpToday);
127 m_layoutTools->addStretch();
129 d->dateText = new Plasma::LineEdit(this);
130 connect(d->calendarTable, SIGNAL(dateChanged(const QDate &)), this, SLOT(dateUpdated(const QDate &)));
131 connect(d->dateText->nativeWidget(), SIGNAL(returnPressed()), this, SLOT(manualDateChange()));
132 m_layoutTools->addItem(d->dateText);
133 m_layoutTools->addStretch();
135 d->weekSpinBox = new Plasma::SpinBox(this);
136 d->weekSpinBox->setMinimum(1);
137 d->weekSpinBox->setMaximum(d->calendarTable->calendar()->weeksInYear(d->calendarTable->date()));
138 connect(d->weekSpinBox, SIGNAL(valueChanged(int)), this, SLOT(goToWeek(int)));
139 m_layoutTools->addItem(d->weekSpinBox);
141 m_layout->addItem(m_layoutTools);
143 d->monthMenu = 0;
145 dateUpdated(d->calendarTable->date());
148 Calendar::~Calendar()
150 delete d->monthMenu;
151 delete d;
154 void Calendar::manualDateChange()
156 QDate date = KGlobal::locale()->readDate(((QLineEdit*)sender())->text());
157 if(date.isValid()) {
158 setDate(date);
162 void Calendar::goToToday()
164 setDate(QDate::currentDate());
167 bool Calendar::setCalendar(KCalendarSystem *calendar)
169 return d->calendarTable->setCalendar(calendar);
172 bool Calendar::setDate(const QDate &date)
174 bool r = d->calendarTable->setDate(date);
175 dateUpdated(date);
176 return r;
179 const QDate& Calendar::date() const
181 return d->calendarTable->date();
184 void Calendar::dateUpdated(const QDate &date)
186 QString formatted = KGlobal::locale()->formatDate( date, KLocale::ShortDate );
187 d->month->setText(d->calendarTable->calendar()->monthName(date));
188 d->year->setText(QString::number(d->calendarTable->calendar()->year(date)));
189 d->dateText->setText(formatted);
190 d->weekSpinBox->setValue(d->calendarTable->calendar()->weekNumber(date));
193 void Calendar::prevMonth()
195 const KCalendarSystem *calendar = d->calendarTable->calendar();
197 QDate tmpDate = d->calendarTable->date();
198 QDate newDate;
200 int month = calendar->month(tmpDate);
201 int year = calendar->year(tmpDate);
203 if (month == 1){
204 month = 12;
205 year--;
206 }else{
207 month--;
210 if (calendar->setYMD(newDate, year, month, calendar->day(tmpDate))){
211 setDate(newDate);
212 }else if (calendar->setYMD(newDate, year, month, 1)){
213 setDate(newDate);
217 void Calendar::nextMonth()
219 const KCalendarSystem *calendar = d->calendarTable->calendar();
221 QDate tmpDate = d->calendarTable->date();
222 QDate newDate;
224 int month = calendar->month(tmpDate);
225 int year = calendar->year(tmpDate);
227 if (month == 12){
228 month = 1;
229 year++;
230 }else{
231 month++;
234 if (calendar->setYMD(newDate, year, month, calendar->day(tmpDate))){
235 setDate(newDate);
236 }else if (calendar->setYMD(newDate, year, month, 1)){
237 setDate(newDate);
241 void Calendar::monthsPopup()
243 delete d->monthMenu;
244 d->monthMenu = new QMenu();
246 int year = d->calendarTable->calendar()->year(d->calendarTable->date());
248 for (int i = 1; i <= 12; i++){
249 QAction *tmpAction = new QAction(d->calendarTable->calendar()->monthName(i, year), d->monthMenu);
250 tmpAction->setProperty("month", i);
251 connect(tmpAction, SIGNAL(triggered()), this, SLOT(monthTriggered()));
252 d->monthMenu->addAction(tmpAction);
255 d->monthMenu->popup(QCursor::pos());
258 void Calendar::monthTriggered()
260 QAction *action = dynamic_cast<QAction*> (sender());
261 if (!action || action->property("month").type() != QVariant::Int) return;
262 int month = action->property("month").toInt();
264 const KCalendarSystem *calendar = d->calendarTable->calendar();
265 QDate tmpDate = d->calendarTable->date();
266 QDate newDate;
268 int year = calendar->year(tmpDate);
270 if (calendar->setYMD(newDate, year, month, calendar->day(tmpDate))){
271 setDate(newDate);
272 }else if (calendar->setYMD(newDate, year, month, 1)){
273 setDate(newDate);
277 void Calendar::goToWeek(int week)
279 const KCalendarSystem *calendar = d->calendarTable->calendar();
281 if (calendar->weekNumber(d->calendarTable->date()) != week){
282 QDate firstDayOfWeek;
283 calendar->setYMD(firstDayOfWeek, calendar->year(d->calendarTable->date()), 1, 1);
284 int weeksInYear = calendar->weeksInYear(d->calendarTable->date());
286 for (int i = 1; i < weeksInYear; i++){
287 if (week == calendar->weekNumber(firstDayOfWeek)) //TODO: Check year
288 break;
290 firstDayOfWeek= calendar->addDays(firstDayOfWeek, calendar->daysInWeek(firstDayOfWeek));
293 setDate(firstDayOfWeek);
297 void Calendar::showYearSpinBox()
299 d->yearSpinBox->setValue(d->calendarTable->calendar()->year(d->calendarTable->date()));
300 d->yearSpinBox->setGeometry(d->year->geometry());
301 d->year->hide();
302 d->yearSpinBox->show();
303 d->yearSpinBox->nativeWidget()->setFocus(Qt::MouseFocusReason);
306 void Calendar::hideYearSpinBox()
308 d->yearSpinBox->hide();
310 const KCalendarSystem *calendar = d->calendarTable->calendar();
311 QDate newDate;
312 if (calendar->setYMD(newDate, d->yearSpinBox->value(), calendar->month(d->calendarTable->date()), calendar->day(d->calendarTable->date()))){
313 setDate(newDate);
316 d->year->show();
319 CalendarTable *Calendar::calendarTable() const
321 return d->calendarTable;
325 #include "calendar.moc"