-rw-r--r-- | libkdepim/kdatepicker.cpp | 472 |
1 files changed, 472 insertions, 0 deletions
diff --git a/libkdepim/kdatepicker.cpp b/libkdepim/kdatepicker.cpp new file mode 100644 index 0000000..6e5ec0f --- a/dev/null +++ b/libkdepim/kdatepicker.cpp | |||
@@ -0,0 +1,472 @@ | |||
1 | /* -*- C++ -*- | ||
2 | This file is part of the KDE libraries | ||
3 | Copyright (C) 1997 Tim D. Gilman (tdgilman@best.org) | ||
4 | (C) 1998-2001 Mirko Boehm (mirko@kde.org) | ||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Library General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library 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 GNU | ||
13 | Library General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Library General Public License | ||
16 | along with this library; see the file COPYING.LIB. If not, write to | ||
17 | the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | #include "kdatepicker.h" | ||
22 | #include <kglobal.h> | ||
23 | #include <kapplication.h> | ||
24 | #include <klocale.h> | ||
25 | #include <kiconloader.h> | ||
26 | #include <qframe.h> | ||
27 | #include <qpainter.h> | ||
28 | #include <qdialog.h> | ||
29 | #include <qtoolbutton.h> | ||
30 | #include <qfont.h> | ||
31 | #include <qapplication.h> | ||
32 | #include <qlineedit.h> | ||
33 | #include <qvalidator.h> | ||
34 | #include <kdebug.h> | ||
35 | #include <knotifyclient.h> | ||
36 | #include "kdatetbl.h" | ||
37 | #include "kdateedit.h" | ||
38 | #include "kdatepicker.moc" | ||
39 | |||
40 | |||
41 | KDatePicker::KDatePicker(QWidget *parent, QDate dt, const char *name) | ||
42 | : QFrame(parent,name), | ||
43 | yearForward(new QToolButton(this)), | ||
44 | yearBackward(new QToolButton(this)), | ||
45 | monthForward(new QToolButton(this)), | ||
46 | monthBackward(new QToolButton(this)), | ||
47 | selectMonth(new QToolButton(this)), | ||
48 | selectYear(new QToolButton(this)), | ||
49 | //line(new QLineEdit(this)), | ||
50 | val(new KDateValidator(this)) | ||
51 | //table(new KDateTable(this)), | ||
52 | //fontsize(1) | ||
53 | { | ||
54 | // ----- | ||
55 | int size = 12; | ||
56 | if ( QApplication::desktop()->width() >= 480 ) | ||
57 | size = 18; | ||
58 | fontsize = size; | ||
59 | setFont ( QFont("helvetica",size) ); | ||
60 | table = new KDateTable(this); | ||
61 | setFontSize(size); | ||
62 | //line->setValidator(val); | ||
63 | lineDate = new KDateEdit( this, "dateediipicker", true ); | ||
64 | yearForward->setPixmap(SmallIcon("2rightarrowB")); | ||
65 | yearBackward->setPixmap(SmallIcon("2leftarrowB")); | ||
66 | monthForward->setPixmap(SmallIcon("1rightarrowB")); | ||
67 | monthBackward->setPixmap(SmallIcon("1leftarrowB")); | ||
68 | |||
69 | setDate(dt); // set button texts | ||
70 | connect(table, SIGNAL(dateChanged(QDate)), SLOT(dateChangedSlot(QDate))); | ||
71 | connect(table, SIGNAL(tableClicked()), SLOT(tableClickedSlot())); | ||
72 | connect(monthForward, SIGNAL(clicked()), SLOT(monthForwardClicked())); | ||
73 | connect(monthBackward, SIGNAL(clicked()), SLOT(monthBackwardClicked())); | ||
74 | connect(yearForward, SIGNAL(clicked()), SLOT(yearForwardClicked())); | ||
75 | connect(yearBackward, SIGNAL(clicked()), SLOT(yearBackwardClicked())); | ||
76 | connect(selectMonth, SIGNAL(clicked()), SLOT(selectMonthClicked())); | ||
77 | connect(selectYear, SIGNAL(clicked()), SLOT(selectYearClicked())); | ||
78 | //connect(line, SIGNAL(returnPressed()), SLOT(lineEnterPressed())); | ||
79 | connect(lineDate, SIGNAL(dateChanged(QDate)), SLOT(slotSetDate(QDate))); | ||
80 | connect(lineDate, SIGNAL(returnPressed()), SLOT(lineEnterPressed())); | ||
81 | table->setFocus(); | ||
82 | |||
83 | } | ||
84 | |||
85 | KDatePicker::~KDatePicker() | ||
86 | { | ||
87 | } | ||
88 | |||
89 | void | ||
90 | KDatePicker::resizeEvent(QResizeEvent*) | ||
91 | { | ||
92 | QWidget *buttons[] = { | ||
93 | yearBackward, | ||
94 | monthBackward, | ||
95 | selectMonth, | ||
96 | selectYear, | ||
97 | monthForward, | ||
98 | yearForward }; | ||
99 | const int NoOfButtons=sizeof(buttons)/sizeof(buttons[0]); | ||
100 | QSize sizes[NoOfButtons]; | ||
101 | int buttonHeight=0; | ||
102 | int count; | ||
103 | int w; | ||
104 | int x=0; | ||
105 | // ----- calculate button row height: | ||
106 | for(count=0; count<NoOfButtons; ++count) { | ||
107 | int xS = buttons[count]->sizeHint().width(); | ||
108 | int yS = buttons[count]->sizeHint().height(); | ||
109 | sizes[count]=QSize ( xS+10, yS ); | ||
110 | buttonHeight=QMAX(buttonHeight, sizes[count].height()); | ||
111 | } | ||
112 | buttonHeight += 10; | ||
113 | // ----- calculate size of the month button: | ||
114 | w=0; | ||
115 | for(count=0; count<NoOfButtons; ++count) { | ||
116 | if(buttons[count]!=selectMonth) | ||
117 | { | ||
118 | w+=sizes[count].width(); | ||
119 | } else { | ||
120 | x=count; | ||
121 | } | ||
122 | } | ||
123 | sizes[x].setWidth(width()-w); // stretch the month button | ||
124 | // ----- place the buttons: | ||
125 | x=0; | ||
126 | for(count=0; count<NoOfButtons; ++count) | ||
127 | { | ||
128 | w=sizes[count].width(); | ||
129 | buttons[count]->setGeometry(x, 0, w, buttonHeight); | ||
130 | x+=w; | ||
131 | } | ||
132 | // ----- place the line edit for direct input: | ||
133 | sizes[0]=lineDate->sizeHint(); | ||
134 | //line->setGeometry(0, height()-sizes[0].height(), width(), sizes[0].height()); | ||
135 | lineDate->setGeometry(0, height()-sizes[0].height(), width(), sizes[0].height()); | ||
136 | // ----- adjust the table: | ||
137 | table->setGeometry(0, buttonHeight, width(), | ||
138 | height()-buttonHeight-sizes[0].height()); | ||
139 | } | ||
140 | |||
141 | void | ||
142 | KDatePicker::dateChangedSlot(QDate date) | ||
143 | { | ||
144 | lineDate->setDate( date );//(KGlobal::locale()->formatDate(date, true)); | ||
145 | //line->setText(KGlobal::locale()->formatDate(date, true)); | ||
146 | emit(dateChanged(date)); | ||
147 | } | ||
148 | |||
149 | void | ||
150 | KDatePicker::tableClickedSlot() | ||
151 | { | ||
152 | |||
153 | emit(dateSelected(table->getDate())); | ||
154 | emit(tableClicked()); | ||
155 | } | ||
156 | |||
157 | const QDate& | ||
158 | KDatePicker::getDate() const | ||
159 | { | ||
160 | return table->getDate(); | ||
161 | } | ||
162 | |||
163 | const QDate & | ||
164 | KDatePicker::date() const | ||
165 | { | ||
166 | return table->getDate(); | ||
167 | } | ||
168 | |||
169 | void KDatePicker::slotSetDate( QDate date ) | ||
170 | { | ||
171 | |||
172 | if(date.isValid()) { | ||
173 | QString temp; | ||
174 | // ----- | ||
175 | table->setDate(date); | ||
176 | selectMonth->setText(KGlobal::locale()->monthName(date.month(), false)); | ||
177 | temp.setNum(date.year()); | ||
178 | selectYear->setText(temp); | ||
179 | //line->setText(KGlobal::locale()->formatDate(date, true)); | ||
180 | lineDate->setDate( date ); | ||
181 | } | ||
182 | |||
183 | } | ||
184 | bool | ||
185 | KDatePicker::setDate(const QDate& date) | ||
186 | { | ||
187 | table->setFocus(); | ||
188 | if(date.isValid()) { | ||
189 | QString temp; | ||
190 | // ----- | ||
191 | table->setDate(date); | ||
192 | selectMonth->setText(KGlobal::locale()->monthName(date.month(), false)); | ||
193 | temp.setNum(date.year()); | ||
194 | selectYear->setText(temp); | ||
195 | //line->setText(KGlobal::locale()->formatDate(date, true)); | ||
196 | lineDate->setDate( date ); | ||
197 | return true; | ||
198 | } else { | ||
199 | |||
200 | return false; | ||
201 | } | ||
202 | |||
203 | |||
204 | } | ||
205 | |||
206 | void | ||
207 | KDatePicker::monthForwardClicked() | ||
208 | { | ||
209 | QDate temp=table->getDate(); | ||
210 | int day=temp.day(); | ||
211 | // ----- | ||
212 | if(temp.month()==12) { | ||
213 | temp.setYMD(temp.year()+1, 1, 1); | ||
214 | } else { | ||
215 | temp.setYMD(temp.year(), temp.month()+1, 1); | ||
216 | } | ||
217 | if(temp.daysInMonth()<day) { | ||
218 | temp.setYMD(temp.year(), temp.month(), temp.daysInMonth()); | ||
219 | } else { | ||
220 | temp.setYMD(temp.year(), temp.month(), day); | ||
221 | } | ||
222 | // assert(temp.isValid()); | ||
223 | setDate(temp); | ||
224 | } | ||
225 | |||
226 | void | ||
227 | KDatePicker::monthBackwardClicked() | ||
228 | { | ||
229 | QDate temp=table->getDate(); | ||
230 | int day=temp.day(); | ||
231 | // ----- | ||
232 | if(temp.month()==1) | ||
233 | { | ||
234 | temp.setYMD(temp.year()-1, 12, 1); | ||
235 | } else { | ||
236 | temp.setYMD(temp.year(), temp.month()-1, 1); | ||
237 | } | ||
238 | if(temp.daysInMonth()<day) | ||
239 | { | ||
240 | temp.setYMD(temp.year(), temp.month(), temp.daysInMonth()); | ||
241 | } else { | ||
242 | temp.setYMD(temp.year(), temp.month(), day); | ||
243 | } | ||
244 | // assert(temp.isValid()); | ||
245 | setDate(temp); | ||
246 | } | ||
247 | |||
248 | void | ||
249 | KDatePicker::yearForwardClicked() | ||
250 | { | ||
251 | QDate temp=table->getDate(); | ||
252 | int day=temp.day(); | ||
253 | // ----- | ||
254 | temp.setYMD(temp.year()+1, temp.month(), 1); | ||
255 | if(temp.daysInMonth()<day) | ||
256 | { | ||
257 | temp.setYMD(temp.year(), temp.month(), temp.daysInMonth()); | ||
258 | } else { | ||
259 | temp.setYMD(temp.year(), temp.month(), day); | ||
260 | } | ||
261 | // assert(temp.isValid()); | ||
262 | setDate(temp); | ||
263 | } | ||
264 | |||
265 | void | ||
266 | KDatePicker::yearBackwardClicked() | ||
267 | { | ||
268 | QDate temp=table->getDate(); | ||
269 | int day=temp.day(); | ||
270 | // ----- | ||
271 | temp.setYMD(temp.year()-1, temp.month(), 1); | ||
272 | if(temp.daysInMonth()<day) | ||
273 | { | ||
274 | temp.setYMD(temp.year(), temp.month(), temp.daysInMonth()); | ||
275 | } else { | ||
276 | temp.setYMD(temp.year(), temp.month(), day); | ||
277 | } | ||
278 | // assert(temp.isValid()); | ||
279 | setDate(temp); | ||
280 | } | ||
281 | |||
282 | void | ||
283 | KDatePicker::selectMonthClicked() | ||
284 | { | ||
285 | int month; | ||
286 | KPopupFrame* popup = new KPopupFrame(this); | ||
287 | KDateInternalMonthPicker* picker = new KDateInternalMonthPicker(fontsize, popup); | ||
288 | // ----- | ||
289 | picker->resize(picker->sizeHint()); | ||
290 | popup->setMainWidget(picker); | ||
291 | picker->setFocus(); | ||
292 | connect(picker, SIGNAL(closeMe(int)), popup, SLOT(close(int))); | ||
293 | if(popup->exec(selectMonth->mapToGlobal(QPoint(0, selectMonth->height())))) | ||
294 | { | ||
295 | QDate date; | ||
296 | int day; | ||
297 | // ----- | ||
298 | month=picker->getResult(); | ||
299 | date=table->getDate(); | ||
300 | day=date.day(); | ||
301 | // ----- construct a valid date in this month: | ||
302 | date.setYMD(date.year(), month, 1); | ||
303 | date.setYMD(date.year(), month, QMIN(day, date.daysInMonth())); | ||
304 | // ----- set this month | ||
305 | setDate(date); | ||
306 | } else { | ||
307 | KNotifyClient::beep(); | ||
308 | } | ||
309 | delete popup; | ||
310 | } | ||
311 | |||
312 | void | ||
313 | KDatePicker::selectYearClicked() | ||
314 | { | ||
315 | int year; | ||
316 | KPopupFrame* popup = new KPopupFrame(this); | ||
317 | KDateInternalYearSelector* picker = new KDateInternalYearSelector(fontsize, popup); | ||
318 | // ----- | ||
319 | picker->resize(picker->sizeHint()); | ||
320 | popup->setMainWidget(picker); | ||
321 | connect(picker, SIGNAL(closeMe(int)), popup, SLOT(close(int))); | ||
322 | picker->setFocus(); | ||
323 | if(popup->exec(selectYear->mapToGlobal(QPoint(0, selectMonth->height())))) | ||
324 | { | ||
325 | QDate date; | ||
326 | int day; | ||
327 | // ----- | ||
328 | year=picker->getYear(); | ||
329 | date=table->getDate(); | ||
330 | day=date.day(); | ||
331 | // ----- construct a valid date in this month: | ||
332 | date.setYMD(year, date.month(), 1); | ||
333 | date.setYMD(year, date.month(), QMIN(day, date.daysInMonth())); | ||
334 | // ----- set this month | ||
335 | setDate(date); | ||
336 | } else { | ||
337 | KNotifyClient::beep(); | ||
338 | } | ||
339 | delete popup; | ||
340 | } | ||
341 | |||
342 | void | ||
343 | KDatePicker::setEnabled(bool enable) | ||
344 | { | ||
345 | QWidget *widgets[]= { | ||
346 | yearForward, yearBackward, monthForward, monthBackward, | ||
347 | selectMonth, selectYear, | ||
348 | lineDate, table }; | ||
349 | const int Size=sizeof(widgets)/sizeof(widgets[0]); | ||
350 | int count; | ||
351 | // ----- | ||
352 | for(count=0; count<Size; ++count) | ||
353 | { | ||
354 | widgets[count]->setEnabled(enable); | ||
355 | } | ||
356 | } | ||
357 | |||
358 | void | ||
359 | KDatePicker::lineEnterPressed() | ||
360 | { | ||
361 | QDate temp; | ||
362 | // ----- | ||
363 | temp = lineDate->date(); | ||
364 | //if(val->date(line->text(), temp)==QValidator::Acceptable) | ||
365 | //{ | ||
366 | emit(dateEntered(temp)); | ||
367 | setDate(temp); | ||
368 | // } else { | ||
369 | // KNotifyClient::beep(); | ||
370 | // } | ||
371 | } | ||
372 | |||
373 | QSize | ||
374 | KDatePicker::sizeHint() const | ||
375 | { | ||
376 | QSize tableSize=table->sizeHint(); | ||
377 | QWidget *buttons[]={ | ||
378 | yearBackward, | ||
379 | monthBackward, | ||
380 | selectMonth, | ||
381 | selectYear, | ||
382 | monthForward, | ||
383 | yearForward }; | ||
384 | const int NoOfButtons=sizeof(buttons)/sizeof(buttons[0]); | ||
385 | QSize sizes[NoOfButtons]; | ||
386 | int cx=0, cy=0, count; | ||
387 | // ----- store the size hints: | ||
388 | for(count=0; count<NoOfButtons; ++count) | ||
389 | { | ||
390 | sizes[count]=buttons[count]->sizeHint(); | ||
391 | if(buttons[count]==selectMonth) | ||
392 | { | ||
393 | cx+=maxMonthRect.width()+15; | ||
394 | } else { | ||
395 | cx+=sizes[count].width()+15; | ||
396 | } | ||
397 | cy=QMAX(sizes[count].height(), cy); | ||
398 | } | ||
399 | // ----- calculate width hint: | ||
400 | cx=QMAX(cx, tableSize.width()); // line edit ignored | ||
401 | if ( cx > QApplication::desktop()->width() -5 ) | ||
402 | cx = QApplication::desktop()->width() -5; | ||
403 | // ----- calculate height hint: | ||
404 | cy+=tableSize.height()+lineDate->sizeHint().height(); | ||
405 | |||
406 | return QSize(cx, cy); | ||
407 | } | ||
408 | |||
409 | void | ||
410 | KDatePicker::setFontSize(int s) | ||
411 | { | ||
412 | QWidget *buttons[]= { | ||
413 | // yearBackward, | ||
414 | // monthBackward, | ||
415 | selectMonth, | ||
416 | selectYear, | ||
417 | // monthForward, | ||
418 | // yearForward | ||
419 | }; | ||
420 | const int NoOfButtons=sizeof(buttons)/sizeof(buttons[0]); | ||
421 | int count; | ||
422 | QFont font; | ||
423 | QRect r; | ||
424 | // ----- | ||
425 | fontsize=s; | ||
426 | for(count=0; count<NoOfButtons; ++count) | ||
427 | { | ||
428 | font=buttons[count]->font(); | ||
429 | font.setPointSize(s); | ||
430 | buttons[count]->setFont(font); | ||
431 | } | ||
432 | QFontMetrics metrics(selectMonth->fontMetrics()); | ||
433 | for(int i=1; i <= 12; ++i) | ||
434 | { // maxMonthRect is used by sizeHint() | ||
435 | r=metrics.boundingRect(KGlobal::locale()->monthName(i, false)); | ||
436 | maxMonthRect.setWidth(QMAX(r.width(), maxMonthRect.width())); | ||
437 | maxMonthRect.setHeight(QMAX(r.height(), maxMonthRect.height())); | ||
438 | } | ||
439 | table->setFontSize(s); | ||
440 | } | ||
441 | |||
442 | void KDatePicker::virtual_hook( int id, void* data ) | ||
443 | { /*BASE::virtual_hook( id, data );*/ } | ||
444 | |||
445 | void KDatePicker::keyPressEvent ( QKeyEvent * e ) | ||
446 | { | ||
447 | switch ( e->key() ) { | ||
448 | case Qt::Key_Right: | ||
449 | monthForwardClicked(); | ||
450 | break; | ||
451 | case Qt::Key_Left: | ||
452 | monthBackwardClicked(); | ||
453 | break; | ||
454 | |||
455 | case Qt::Key_Down: | ||
456 | yearForwardClicked(); | ||
457 | |||
458 | break; | ||
459 | |||
460 | case Qt::Key_Up: | ||
461 | yearBackwardClicked(); | ||
462 | break; | ||
463 | |||
464 | case Qt::Key_Return: | ||
465 | tableClickedSlot(); | ||
466 | break; | ||
467 | |||
468 | default: | ||
469 | break; | ||
470 | } | ||
471 | |||
472 | } | ||