summaryrefslogtreecommitdiff
path: root/noncore/apps/tinykate/libkate/microkde/kdatetbl.cpp
Unidiff
Diffstat (limited to 'noncore/apps/tinykate/libkate/microkde/kdatetbl.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/apps/tinykate/libkate/microkde/kdatetbl.cpp718
1 files changed, 718 insertions, 0 deletions
diff --git a/noncore/apps/tinykate/libkate/microkde/kdatetbl.cpp b/noncore/apps/tinykate/libkate/microkde/kdatetbl.cpp
new file mode 100644
index 0000000..c56991d
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/microkde/kdatetbl.cpp
@@ -0,0 +1,718 @@
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/////////////////// KDateTable widget class //////////////////////
22//
23// Copyright (C) 1997 Tim D. Gilman
24// (C) 1998-2001 Mirko Boehm
25// Written using Qt (http://www.troll.no) for the
26// KDE project (http://www.kde.org)
27//
28// This is a support class for the KDatePicker class. It just
29// draws the calender table without titles, but could theoretically
30// be used as a standalone.
31//
32// When a date is selected by the user, it emits a signal:
33// dateSelected(QDate)
34
35#include <kglobal.h>
36#include <kglobalsettings.h>
37#include <kapplication.h>
38#include <klocale.h>
39#include <kdebug.h>
40#include <knotifyclient.h>
41#include "kdatetbl.h"
42#include <qdatetime.h>
43#include <qstring.h>
44#include <qpen.h>
45#include <qpainter.h>
46#include <qdialog.h>
47#include <assert.h>
48#include <qapplication.h>
49
50KDateValidator::KDateValidator(QWidget* parent, const char* name)
51 : QValidator(parent, name)
52{
53}
54
55QValidator::State
56KDateValidator::validate(QString& text, int&) const
57{
58 QDate temp;
59 // ----- everything is tested in date():
60 return date(text, temp);
61}
62
63QValidator::State
64KDateValidator::date(const QString& text, QDate& d) const
65{
66 QDate tmp = KGlobal::locale()->readDate(text);
67 if (!tmp.isNull())
68 {
69 d = tmp;
70 return Acceptable;
71 } else
72 return Valid;
73}
74
75void
76KDateValidator::fixup( QString& ) const
77{
78
79}
80
81KDateTable::KDateTable(QWidget *parent, QDate date_, const char* name, WFlags f)
82 : QGridView(parent, name, f)
83{
84 setFontSize(10);
85 if(!date_.isValid())
86 {
87 kdDebug() << "KDateTable ctor: WARNING: Given date is invalid, using current date." << endl;
88 date_=QDate::currentDate();
89 }
90 setFocusPolicy( QWidget::StrongFocus );
91 setNumRows(7); // 6 weeks max + headline
92 setNumCols(7); // 7 days a week
93 setHScrollBarMode(AlwaysOff);
94 setVScrollBarMode(AlwaysOff);
95#if 0
96 viewport()->setEraseColor(lightGray);
97#endif
98 setDate(date_); // this initializes firstday, numdays, numDaysPrevMonth
99}
100
101void
102KDateTable::paintCell(QPainter *painter, int row, int col)
103{
104 QRect rect;
105 QString text;
106 QPen pen;
107 int w=cellWidth();
108 int h=cellHeight();
109 int pos;
110 QBrush brushBlue(blue);
111 QBrush brushLightblue(lightGray);
112 QFont font=KGlobalSettings::generalFont();
113 // -----
114 font.setPointSize(fontsize);
115 if(row==0)
116 { // we are drawing the headline
117 font.setBold(true);
118 painter->setFont(font);
119 bool normalday = true;
120 QString daystr;
121 if (KGlobal::locale()->weekStartsMonday())
122 {
123 daystr = KGlobal::locale()->weekDayName(col+1, true);
124 if (col == 5 || col == 6)
125 normalday = false;
126 } else {
127 daystr = KGlobal::locale()->weekDayName(col==0? 7 : col, true);
128 if (col == 0 || col == 6)
129 normalday = false;
130 }
131 if (!normalday)
132 {
133 painter->setPen(lightGray);
134 painter->setBrush(brushLightblue);
135 painter->drawRect(0, 0, w, h);
136 painter->setPen(blue);
137 } else {
138 painter->setPen(blue);
139 painter->setBrush(brushBlue);
140 painter->drawRect(0, 0, w, h);
141 painter->setPen(white);
142 }
143 painter->drawText(0, 0, w, h-1, AlignCenter,
144 daystr, -1, &rect);
145 painter->setPen(black);
146 painter->moveTo(0, h-1);
147 painter->lineTo(w-1, h-1);
148 // ----- draw the weekday:
149 } else {
150 painter->setFont(font);
151 pos=7*(row-1)+col;
152 if (KGlobal::locale()->weekStartsMonday())
153 pos++;
154 if(pos<firstday || (firstday+numdays<=pos))
155 { // we are either
156 // ° painting a day of the previous month or
157 // ° painting a day of the following month
158 if(pos<firstday)
159 { // previous month
160 text.setNum(numDaysPrevMonth+pos-firstday+1);
161 } else { // following month
162 text.setNum(pos-firstday-numdays+1);
163 }
164 painter->setPen(gray);
165 } else { // paint a day of the current month
166 text.setNum(pos-firstday+1);
167 painter->setPen(black);
168 }
169
170 pen=painter->pen();
171 if(firstday+date.day()-1==pos)
172 {
173 if(hasFocus())
174 { // draw the currently selected date
175 painter->setPen(red);
176 painter->setBrush(darkRed);
177 pen=white;
178 } else {
179 painter->setPen(darkGray);
180 painter->setBrush(darkGray);
181 pen=white;
182 }
183 } else {
184 painter->setBrush(lightGray);
185 painter->setPen(lightGray);
186 }
187 painter->drawRect(0, 0, w, h);
188 painter->setPen(pen);
189 painter->drawText(0, 0, w, h, AlignCenter, text, -1, &rect);
190 }
191 if(rect.width()>maxCell.width()) maxCell.setWidth(rect.width());
192 if(rect.height()>maxCell.height()) maxCell.setHeight(rect.height());
193}
194
195void
196KDateTable::keyPressEvent( QKeyEvent *e )
197{
198 if ( e->key() == Qt::Key_Prior ) {
199 if ( date.month() == 1 ) {
200 KNotifyClient::beep();
201 return;
202 }
203 int day = date.day();
204 if ( day > 27 )
205 while ( !QDate::isValid( date.year(), date.month()-1, day ) )
206 day--;
207 setDate(QDate(date.year(), date.month()-1, day));
208 return;
209 }
210 if ( e->key() == Qt::Key_Next ) {
211 if ( date.month() == 12 ) {
212 KNotifyClient::beep();
213 return;
214 }
215 int day = date.day();
216 if ( day > 27 )
217 while ( !QDate::isValid( date.year(), date.month()+1, day ) )
218 day--;
219 setDate(QDate(date.year(), date.month()+1, day));
220 return;
221 }
222
223 int dayoff = KGlobal::locale()->weekStartsMonday() ? 1 : 0;
224
225 int temp=firstday+date.day()-dayoff;
226 int pos = temp;
227
228 if ( e->key() == Qt::Key_Up ) {
229 pos -= 7;
230 }
231 if ( e->key() == Qt::Key_Down ) {
232 pos += 7;
233 }
234 if ( e->key() == Qt::Key_Left ) {
235 pos--;
236 }
237 if ( e->key() == Qt::Key_Right ) {
238 pos++;
239 }
240
241 if(pos+dayoff<=firstday)
242 { // this day is in the previous month
243 KNotifyClient::beep();
244 return;
245 }
246 if(firstday+numdays<pos+dayoff)
247 { // this date is in the next month
248 KNotifyClient::beep(i18n( "Month not long enough" ));
249 return;
250 }
251
252 if ( pos == temp )
253 return;
254
255 setDate(QDate(date.year(), date.month(), pos-firstday+dayoff));
256 updateCell(temp/7+1, temp%7); // Update the previously selected cell
257 updateCell(pos/7+1, pos%7); // Update the selected cell
258 assert(QDate(date.year(), date.month(), pos-firstday+dayoff).isValid());
259}
260
261void
262KDateTable::viewportResizeEvent(QResizeEvent * e)
263{
264 QGridView::viewportResizeEvent(e);
265
266 setCellWidth(viewport()->width()/7);
267 setCellHeight(viewport()->height()/7);
268}
269
270void
271KDateTable::setFontSize(int size)
272{
273 int count;
274 QFontMetrics metrics(fontMetrics());
275 QRect rect;
276 // ----- store rectangles:
277 fontsize=size;
278 // ----- find largest day name:
279 maxCell.setWidth(0);
280 maxCell.setHeight(0);
281 for(count=0; count<7; ++count)
282 {
283 rect=metrics.boundingRect(KGlobal::locale()->weekDayName(count+1, true));
284 maxCell.setWidth(QMAX(maxCell.width(), rect.width()));
285 maxCell.setHeight(QMAX(maxCell.height(), rect.height()));
286 }
287 // ----- compare with a real wide number and add some space:
288 rect=metrics.boundingRect(QString::fromLatin1("88"));
289 maxCell.setWidth(QMAX(maxCell.width()+2, rect.width()));
290 maxCell.setHeight(QMAX(maxCell.height()+4, rect.height()));
291}
292
293void
294KDateTable::contentsMousePressEvent(QMouseEvent *e)
295{
296 if(e->type()!=QEvent::MouseButtonPress)
297 { // the KDatePicker only reacts on mouse press events:
298 return;
299 }
300 if(!isEnabled())
301 {
302 KNotifyClient::beep();
303 return;
304 }
305
306 int dayoff = KGlobal::locale()->weekStartsMonday() ? 1 : 0;
307 // -----
308 int row, col, pos, temp;
309 QPoint mouseCoord;
310 // -----
311 mouseCoord = e->pos();
312 row=rowAt(mouseCoord.y());
313 col=columnAt(mouseCoord.x());
314 if(row<0 || col<0)
315 { // the user clicked on the frame of the table
316 return;
317 }
318 pos=7*(row-1)+col+1;
319 if(pos+dayoff<=firstday)
320 { // this day is in the previous month
321 KNotifyClient::beep();
322 return;
323 }
324 if(firstday+numdays<pos+dayoff)
325 { // this date is in the next month
326 KNotifyClient::beep();
327 return;
328 }
329 temp=firstday+date.day()-dayoff-1;
330 setDate(QDate(date.year(), date.month(), pos-firstday+dayoff));
331 updateCell(temp/7+1, temp%7); // Update the previously selected cell
332 updateCell(row, col); // Update the selected cell
333 // assert(QDate(date.year(), date.month(), pos-firstday+dayoff).isValid());
334 emit(tableClicked());
335}
336
337bool
338KDateTable::setDate(const QDate& date_)
339{
340 bool changed=false;
341 QDate temp;
342 // -----
343 if(!date_.isValid())
344 {
345 kdDebug() << "KDateTable::setDate: refusing to set invalid date." << endl;
346 return false;
347 }
348 if(date!=date_)
349 {
350 date=date_;
351 changed=true;
352 }
353 temp.setYMD(date.year(), date.month(), 1);
354 firstday=temp.dayOfWeek();
355 if(firstday==1) firstday=8;
356 numdays=date.daysInMonth();
357 if(date.month()==1)
358 { // set to december of previous year
359 temp.setYMD(date.year()-1, 12, 1);
360 } else { // set to previous month
361 temp.setYMD(date.year(), date.month()-1, 1);
362 }
363 numDaysPrevMonth=temp.daysInMonth();
364 if(changed)
365 {
366 repaintContents(false);
367 }
368 emit(dateChanged(date));
369 return true;
370}
371
372const QDate&
373KDateTable::getDate() const
374{
375 return date;
376}
377
378void KDateTable::focusInEvent( QFocusEvent *e )
379{
380 repaintContents(false);
381 QGridView::focusInEvent( e );
382}
383
384void KDateTable::focusOutEvent( QFocusEvent *e )
385{
386 repaintContents(false);
387 QGridView::focusOutEvent( e );
388}
389
390QSize
391KDateTable::sizeHint() const
392{
393 if(maxCell.height()>0 && maxCell.width()>0)
394 {
395 return QSize(maxCell.width()*numCols()+2*frameWidth(),
396 (maxCell.height()+2)*numRows()+2*frameWidth());
397 } else {
398 kdDebug() << "KDateTable::sizeHint: obscure failure - " << endl;
399 return QSize(-1, -1);
400 }
401}
402
403KDateInternalMonthPicker::KDateInternalMonthPicker
404(int fontsize, QWidget* parent, const char* name)
405 : QGridView(parent, name),
406 result(0) // invalid
407{
408 QRect rect;
409 QFont font;
410 // -----
411 activeCol = -1;
412 activeRow = -1;
413 font=KGlobalSettings::generalFont();
414 font.setPointSize(fontsize);
415 setFont(font);
416 setHScrollBarMode(AlwaysOff);
417 setVScrollBarMode(AlwaysOff);
418 setFrameStyle(QFrame::NoFrame);
419 setNumRows(4);
420 setNumCols(3);
421 // enable to find drawing failures:
422 // setTableFlags(Tbl_clipCellPainting);
423#if 0
424 viewport()->setEraseColor(lightGray); // for consistency with the datepicker
425#endif
426 // ----- find the preferred size
427 // (this is slow, possibly, but unfortunatly it is needed here):
428 QFontMetrics metrics(font);
429 for(int i=1; i <= 12; ++i)
430 {
431 rect=metrics.boundingRect(KGlobal::locale()->monthName(i, false));
432 if(max.width()<rect.width()) max.setWidth(rect.width());
433 if(max.height()<rect.height()) max.setHeight(rect.height());
434 }
435
436}
437
438QSize
439KDateInternalMonthPicker::sizeHint() const
440{
441 return QSize((max.width()+6)*numCols()+2*frameWidth(),
442 (max.height()+6)*numRows()+2*frameWidth());
443}
444
445int
446KDateInternalMonthPicker::getResult() const
447{
448 return result;
449}
450
451void
452KDateInternalMonthPicker::setupPainter(QPainter *p)
453{
454 p->setPen(black);
455}
456
457void
458KDateInternalMonthPicker::viewportResizeEvent(QResizeEvent*)
459{
460 setCellWidth(width()/3);
461 setCellHeight(height()/4);
462}
463
464void
465KDateInternalMonthPicker::paintCell(QPainter* painter, int row, int col)
466{
467 int index;
468 QString text;
469 // ----- find the number of the cell:
470 index=3*row+col+1;
471 text=KGlobal::locale()->monthName(index, false);
472 painter->drawText(0, 0, cellWidth(), cellHeight(), AlignCenter, text);
473 if ( activeCol == col && activeRow == row )
474 painter->drawRect( 0, 0, cellWidth(), cellHeight() );
475}
476
477void
478KDateInternalMonthPicker::contentsMousePressEvent(QMouseEvent *e)
479{
480 if(!isEnabled() || e->button() != LeftButton)
481 {
482 KNotifyClient::beep();
483 return;
484 }
485 // -----
486 int row, col;
487 QPoint mouseCoord;
488 // -----
489 mouseCoord = e->pos();
490 row=rowAt(mouseCoord.y());
491 col=columnAt(mouseCoord.x());
492
493 if(row<0 || col<0)
494 { // the user clicked on the frame of the table
495 activeCol = -1;
496 activeRow = -1;
497 } else {
498 activeCol = col;
499 activeRow = row;
500 updateCell( row, col /*, false */ );
501 }
502}
503
504void
505KDateInternalMonthPicker::contentsMouseMoveEvent(QMouseEvent *e)
506{
507 if (e->state() & LeftButton)
508 {
509 int row, col;
510 QPoint mouseCoord;
511 // -----
512 mouseCoord = e->pos();
513 row=rowAt(mouseCoord.y());
514 col=columnAt(mouseCoord.x());
515 int tmpRow = -1, tmpCol = -1;
516 if(row<0 || col<0)
517 { // the user clicked on the frame of the table
518 if ( activeCol > -1 )
519 {
520 tmpRow = activeRow;
521 tmpCol = activeCol;
522 }
523 activeCol = -1;
524 activeRow = -1;
525 } else {
526 bool differentCell = (activeRow != row || activeCol != col);
527 if ( activeCol > -1 && differentCell)
528 {
529 tmpRow = activeRow;
530 tmpCol = activeCol;
531 }
532 if ( differentCell)
533 {
534 activeRow = row;
535 activeCol = col;
536 updateCell( row, col /*, false */ ); // mark the new active cell
537 }
538 }
539 if ( tmpRow > -1 ) // repaint the former active cell
540 updateCell( tmpRow, tmpCol /*, true */ );
541 }
542}
543
544void
545KDateInternalMonthPicker::contentsMouseReleaseEvent(QMouseEvent *e)
546{
547 if(!isEnabled())
548 {
549 return;
550 }
551 // -----
552 int row, col, pos;
553 QPoint mouseCoord;
554 // -----
555 mouseCoord = e->pos();
556 row=rowAt(mouseCoord.y());
557 col=columnAt(mouseCoord.x());
558 if(row<0 || col<0)
559 { // the user clicked on the frame of the table
560 emit(closeMe(0));
561 }
562 pos=3*row+col+1;
563 result=pos;
564 emit(closeMe(1));
565}
566
567
568
569KDateInternalYearSelector::KDateInternalYearSelector
570(int fontsize, QWidget* parent, const char* name)
571 : QLineEdit(parent, name),
572 val(new QIntValidator(this)),
573 result(0)
574{
575 QFont font;
576 // -----
577 font=KGlobalSettings::generalFont();
578 font.setPointSize(fontsize);
579 setFont(font);
580#if 0
581 setFrameStyle(QFrame::NoFrame);
582#endif
583 // we have to respect the limits of QDate here, I fear:
584 val->setRange(0, 8000);
585 setValidator(val);
586 connect(this, SIGNAL(returnPressed()), SLOT(yearEnteredSlot()));
587}
588
589void
590KDateInternalYearSelector::yearEnteredSlot()
591{
592 bool ok;
593 int year;
594 QDate date;
595 // ----- check if this is a valid year:
596 year=text().toInt(&ok);
597 if(!ok)
598 {
599 KNotifyClient::beep();
600 return;
601 }
602 date.setYMD(year, 1, 1);
603 if(!date.isValid())
604 {
605 KNotifyClient::beep();
606 return;
607 }
608 result=year;
609 emit(closeMe(1));
610}
611
612int
613KDateInternalYearSelector::getYear()
614{
615 return result;
616}
617
618void
619KDateInternalYearSelector::setYear(int year)
620{
621 QString temp;
622 // -----
623 temp.setNum(year);
624 setText(temp);
625}
626
627KPopupFrame::KPopupFrame(QWidget* parent, const char* name)
628 : QFrame(parent, name, WType_Popup),
629 result(0), // rejected
630 main(0)
631{
632 setFrameStyle(QFrame::Box|QFrame::Raised);
633 setMidLineWidth(2);
634}
635
636void
637KPopupFrame::keyPressEvent(QKeyEvent* e)
638{
639 if(e->key()==Key_Escape)
640 {
641 result=0; // rejected
642 qApp->exit_loop();
643 }
644}
645
646void
647KPopupFrame::close(int r)
648{
649 result=r;
650 qApp->exit_loop();
651}
652
653void
654KPopupFrame::setMainWidget(QWidget* m)
655{
656 main=m;
657 if(main!=0)
658 {
659 resize(main->width()+2*frameWidth(), main->height()+2*frameWidth());
660 }
661}
662
663void
664KPopupFrame::resizeEvent(QResizeEvent*)
665{
666 if(main!=0)
667 {
668 main->setGeometry(frameWidth(), frameWidth(),
669 width()-2*frameWidth(), height()-2*frameWidth());
670 }
671}
672
673void
674KPopupFrame::popup(const QPoint &pos)
675{
676 // Make sure the whole popup is visible.
677 QRect d = QApplication::desktop()->frameGeometry();
678 int x = pos.x();
679 int y = pos.y();
680 int w = width();
681 int h = height();
682 if (x+w > d.x()+d.width())
683 x = d.width() - w;
684 if (y+h > d.y()+d.height())
685 y = d.height() - h;
686 if (x < d.x())
687 x = 0;
688 if (y < d.y())
689 y = 0;
690
691 // Pop the thingy up.
692 move(x, y);
693 show();
694}
695
696int
697KPopupFrame::exec(QPoint pos)
698{
699 popup(pos);
700 repaint();
701 qApp->enter_loop();
702 hide();
703 return result;
704}
705
706int
707KPopupFrame::exec(int x, int y)
708{
709 return exec(QPoint(x, y));
710}
711
712void KPopupFrame::virtual_hook( int, void* )
713{ /*BASE::virtual_hook( id, data );*/ }
714
715void KDateTable::virtual_hook( int, void* )
716{ /*BASE::virtual_hook( id, data );*/ }
717
718#include "kdatetbl.moc"