• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.14.38 API Reference
  • KDE Home
  • Contact Us
 

KDEUI

  • kdeui
  • widgets
kdatetable.cpp
Go to the documentation of this file.
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 (C) 2007 John Layt <john@layt.net>
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.
20*/
21
22#include "kdatetable.h"
23
24#include <kconfig.h>
25#include <kcolorscheme.h>
26#include <kglobal.h>
27#include <kglobalsettings.h>
28#include <kdebug.h>
29#include <knotification.h>
30#include <kcalendarsystem.h>
31#include <klocalizeddate.h>
32#include <kshortcut.h>
33#include <kstandardshortcut.h>
34#include "kdatepicker.h"
35#include "kmenu.h"
36#include "kactioncollection.h"
37#include "kaction.h"
38#include <kdeversion.h>
39
40#include <QtCore/QDate>
41#include <QtCore/QCharRef>
42#include <QtGui/QPen>
43#include <QtGui/QPainter>
44#include <QtGui/QStyle>
45#include <QtGui/QStyleOptionViewItem>
46#include <QtGui/QDialog>
47#include <QtGui/QActionEvent>
48#include <QtCore/QHash>
49#include <QtGui/QApplication>
50#include <assert.h>
51
52#include <cmath>
53
54class KDateTable::KDateTablePrivate
55{
56public:
57 KDateTablePrivate( KDateTable *q ): q( q )
58 {
59 m_popupMenuEnabled = false;
60 m_useCustomColors = false;
61 m_hoveredPos = -1;
62 setDate( QDate::currentDate() );
63 }
64
65 ~KDateTablePrivate()
66 {
67 }
68
69 void setDate( const QDate& date );
70 void nextMonth();
71 void previousMonth();
72 void beginningOfMonth();
73 void endOfMonth();
74 void beginningOfWeek();
75 void endOfWeek();
76
77 KDateTable *q;
78
82 int fontsize;
83
87 KLocalizedDate m_date;
88 // Need to keep a QDate copy as the "const QDate &date() const;" method returns a reference
89 // and returning m_date.date() creates a temporary leading to crashes. Doh!
90 QDate m_refDate;
91
95 int m_weekDayFirstOfMonth;
96
100 int m_numDaysThisMonth;
101
105 QRectF m_maxCell;
106
110 int m_numWeekRows;
111
115 int m_numDayColumns;
116
117 bool m_popupMenuEnabled;
118 bool m_useCustomColors;
119
120 struct DatePaintingMode
121 {
122 QColor fgColor;
123 QColor bgColor;
124 BackgroundMode bgMode;
125 };
126 QHash <int, DatePaintingMode> m_customPaintingModes;
127
128 int m_hoveredPos;
129};
130
131
132class KPopupFrame::KPopupFramePrivate
133{
134public:
135 KPopupFramePrivate( KPopupFrame *q );
136 ~KPopupFramePrivate();
137
138 KPopupFrame *q;
139
143 int result;
144
148 QWidget *main;
149
150 // ### KDE 5: Remove this, add a hideEvent() reimplementation instead.
151 class OutsideClickCatcher;
152 OutsideClickCatcher *outsideClickCatcher;
153};
154
155
156class KPopupFrame::KPopupFramePrivate::OutsideClickCatcher
157 : public QObject
158{
159public:
160 OutsideClickCatcher(QObject *parent = 0)
161 : QObject(parent), m_popup(0) { }
162 ~OutsideClickCatcher() { }
163
164 void setPopupFrame(KPopupFrame *popup)
165 {
166 m_popup = popup;
167 popup->installEventFilter(this);
168 }
169
170 KPopupFrame *m_popup;
171
172 bool eventFilter(QObject *object, QEvent *event)
173 {
174 Q_UNUSED(object);
175
176 // To catch outside clicks, it is sufficient to check for
177 // hide events on Qt::Popup type widgets
178 if (event->type() == QEvent::Hide && m_popup) {
179 // do not set d->result here, because the popup
180 // hides itself after leaving the event loop.
181 emit m_popup->leaveModality();
182 }
183 return false;
184 }
185};
186
187
188KPopupFrame::KPopupFramePrivate::KPopupFramePrivate( KPopupFrame *q ):
189 q( q ),
190 result( 0 ), // rejected
191 main( 0 ),
192 outsideClickCatcher(new OutsideClickCatcher)
193{
194 outsideClickCatcher->setPopupFrame(q);
195}
196
197KPopupFrame::KPopupFramePrivate::~KPopupFramePrivate()
198{
199 delete outsideClickCatcher;
200}
201
202
203class KDateValidator::KDateValidatorPrivate
204{
205public:
206 KDateValidatorPrivate( KDateValidator *q ): q( q )
207 {
208 }
209
210 ~KDateValidatorPrivate()
211 {
212 }
213
214 KDateValidator *q;
215};
216
217KDateValidator::KDateValidator( QWidget *parent ) : QValidator( parent ), d( 0 )
218{
219}
220
221QValidator::State KDateValidator::validate( QString &text, int &unused ) const
222{
223 Q_UNUSED( unused );
224
225 QDate temp;
226 // ----- everything is tested in date():
227 return date( text, temp );
228}
229
230QValidator::State KDateValidator::date( const QString &text, QDate &d ) const
231{
232 //FIXME This is wrong if the widget is not using the global!
233 QDate tmp = KGlobal::locale()->readDate( text );
234 if ( KGlobal::locale()->calendar()->isValid( tmp ) ) {
235 d = tmp;
236 return Acceptable;
237 } else {
238 return QValidator::Intermediate;
239 }
240}
241
242void KDateValidator::fixup( QString& ) const
243{
244}
245
246KDateTable::KDateTable( const QDate& date, QWidget* parent )
247 : QWidget( parent ),
248 d( new KDateTablePrivate( this ) )
249{
250 init( date );
251}
252
253KDateTable::KDateTable( QWidget *parent )
254 : QWidget( parent ),
255 d( new KDateTablePrivate( this ) )
256{
257 init( QDate::currentDate() );
258}
259
260KDateTable::~KDateTable()
261{
262 delete d;
263}
264
265void KDateTable::init( const QDate &date )
266{
267 d->m_numWeekRows = 7;
268
269 setFontSize( 10 );
270 setFocusPolicy( Qt::StrongFocus );
271 setBackgroundRole(QPalette::Base);
272 setAutoFillBackground(true);
273 initAccels();
274 setAttribute(Qt::WA_Hover, true);
275
276 setDate( date );
277}
278
279void KDateTable::initAccels()
280{
281 KActionCollection * localCollection = new KActionCollection( this );
282
283 KAction* next = localCollection->addAction( QLatin1String( "next" ) );
284 next->setShortcuts( KStandardShortcut::next() );
285 connect( next, SIGNAL(triggered(bool)), SLOT(nextMonth()) );
286
287 KAction* prior = localCollection->addAction( QLatin1String( "prior" ) );
288 prior->setShortcuts( KStandardShortcut::prior() );
289 connect( prior, SIGNAL(triggered(bool)), SLOT(previousMonth()) );
290
291 KAction* beginMonth = localCollection->addAction( QLatin1String( "beginMonth" ) );
292 beginMonth->setShortcuts( KStandardShortcut::begin() );
293 connect( beginMonth, SIGNAL(triggered(bool)), SLOT(beginningOfMonth()) );
294
295 KAction* endMonth = localCollection->addAction( QLatin1String( "endMonth" ) );
296 endMonth->setShortcuts( KStandardShortcut::end() );
297 connect( endMonth, SIGNAL(triggered(bool)), SLOT(endOfMonth()) );
298
299 KAction* beginWeek = localCollection->addAction( QLatin1String( "beginWeek" ) );
300 beginWeek->setShortcuts( KStandardShortcut::beginningOfLine() );
301 connect( beginWeek, SIGNAL(triggered(bool)), SLOT(beginningOfWeek()) );
302
303 KAction* endWeek = localCollection->addAction( "endWeek" );
304 endWeek->setShortcuts( KStandardShortcut::endOfLine() );
305 connect( endWeek, SIGNAL(triggered(bool)), SLOT(endOfWeek()) );
306
307 localCollection->readSettings();
308 localCollection->addAssociatedWidget( this );
309 foreach (QAction* action, localCollection->actions()) {
310 action->setShortcutContext(Qt::WidgetWithChildrenShortcut);
311 }
312}
313
314int KDateTable::posFromDate( const QDate &date )
315{
316 int initialPosition = calendar()->day( date );
317 int offset = ( d->m_weekDayFirstOfMonth - calendar()->weekStartDay() + d->m_numDayColumns ) % d->m_numDayColumns;
318
319 // make sure at least one day of the previous month is visible.
320 // adjust this < 1 if more days should be forced visible:
321 if ( offset < 1 ) {
322 offset += d->m_numDayColumns;
323 }
324
325 return initialPosition + offset;
326}
327
328QDate KDateTable::dateFromPos( int position )
329{
330 int offset = ( d->m_weekDayFirstOfMonth - calendar()->weekStartDay() + d->m_numDayColumns ) % d->m_numDayColumns;
331
332 // make sure at least one day of the previous month is visible.
333 // adjust this < 1 if more days should be forced visible:
334 if ( offset < 1 ) {
335 offset += d->m_numDayColumns;
336 }
337
338 return d->m_date.firstDayOfMonth().addDays( position - offset ).date();
339}
340
341void KDateTable::paintEvent( QPaintEvent *e )
342{
343 QPainter p( this );
344 KColorScheme colorScheme(palette().currentColorGroup(), KColorScheme::View);
345 const QRect &rectToUpdate = e->rect();
346 double cellWidth = width() / ( double ) d->m_numDayColumns;
347 double cellHeight = height() / ( double ) d->m_numWeekRows;
348 int leftCol = ( int )std::floor( rectToUpdate.left() / cellWidth );
349 int topRow = ( int )std::floor( rectToUpdate.top() / cellHeight );
350 int rightCol = ( int )std::ceil( rectToUpdate.right() / cellWidth );
351 int bottomRow = ( int )std::ceil( rectToUpdate.bottom() / cellHeight );
352 bottomRow = qMin( bottomRow, d->m_numWeekRows - 1 );
353 rightCol = qMin( rightCol, d->m_numDayColumns - 1 );
354 if ( layoutDirection() == Qt::RightToLeft ) {
355 p.translate( ( d->m_numDayColumns - leftCol - 1 ) * cellWidth, topRow * cellHeight );
356 } else {
357 p.translate( leftCol * cellWidth, topRow * cellHeight );
358 }
359 for ( int i = leftCol; i <= rightCol; ++i ) {
360 for ( int j = topRow; j <= bottomRow; ++j ) {
361 paintCell( &p, j, i, colorScheme );
362 p.translate( 0, cellHeight );
363 }
364 if ( layoutDirection() == Qt::RightToLeft ) {
365 p.translate( -cellWidth, 0 );
366 } else {
367 p.translate( cellWidth, 0 );
368 }
369 p.translate( 0, -cellHeight * ( bottomRow - topRow + 1 ) );
370 }
371}
372
373void KDateTable::paintCell( QPainter *painter, int row, int col, const KColorScheme &colorScheme )
374{
375 double w = ( width() / ( double ) d->m_numDayColumns ) - 1;
376 double h = ( height() / ( double ) d->m_numWeekRows ) - 1;
377 QRectF cell = QRectF( 0, 0, w, h );
378 QString cellText;
379 QPen pen;
380 QColor cellBackgroundColor, cellTextColor;
381 QFont cellFont = KGlobalSettings::generalFont();
382 bool workingDay = false;
383 int cellWeekDay, pos;
384 BackgroundMode cellBackgroundMode = RectangleMode;
385
386 //Calculate the position of the cell in the grid
387 pos = d->m_numDayColumns * ( row - 1 ) + col;
388
389 //Calculate what day of the week the cell is
390 if ( col + calendar()->weekStartDay() <= d->m_numDayColumns ) {
391 cellWeekDay = col + calendar()->weekStartDay();
392 } else {
393 cellWeekDay = col + calendar()->weekStartDay() - d->m_numDayColumns;
394 }
395
396 //FIXME This is wrong if the widget is not using the global!
397 //See if cell day is normally a working day
398 if ( KGlobal::locale()->workingWeekStartDay() <= KGlobal::locale()->workingWeekEndDay() ) {
399 if ( cellWeekDay >= KGlobal::locale()->workingWeekStartDay() &&
400 cellWeekDay <= KGlobal::locale()->workingWeekEndDay() ) {
401 workingDay = true;
402 }
403 } else {
404 if ( cellWeekDay >= KGlobal::locale()->workingWeekStartDay() ||
405 cellWeekDay <= KGlobal::locale()->workingWeekEndDay() ) {
406 workingDay = true;
407 }
408 }
409
410 if( row == 0 ) {
411
412 //We are drawing a header cell
413
414 //If not a normal working day, then use "do not work today" color
415 if ( workingDay ) {
416 cellTextColor = palette().color(QPalette::WindowText);
417 } else {
418 KColorScheme colorScheme(palette().currentColorGroup(), KColorScheme::Window);
419 cellTextColor = colorScheme.foreground(KColorScheme::NegativeText).color();
420 }
421 cellBackgroundColor = palette().color(QPalette::Window);
422
423 //Set the text to the short day name and bold it
424 cellFont.setBold( true );
425 cellText = calendar()->weekDayName( cellWeekDay, KCalendarSystem::ShortDayName );
426
427 } else {
428
429 //We are drawing a day cell
430
431 //Calculate the date the cell represents
432 //Copy current date to get same calendar system & locale
433 KLocalizedDate cellDate = d->m_date;
434 cellDate = dateFromPos( pos );
435
436 bool validDay = cellDate.isValid();
437
438 // Draw the day number in the cell, if the date is not valid then we don't want to show it
439 if ( validDay ) {
440 cellText = cellDate.formatDate( KLocale::Day, KLocale::ShortNumber );
441 } else {
442 cellText = "";
443 }
444
445 if( ! validDay || cellDate.month() != d->m_date.month() ) {
446 // we are either
447 // ° painting an invalid day
448 // ° painting a day of the previous month or
449 // ° painting a day of the following month or
450 cellBackgroundColor = palette().color(backgroundRole());
451 cellTextColor = colorScheme.foreground(KColorScheme::InactiveText).color();
452 } else {
453 //Paint a day of the current month
454
455 // Background Colour priorities will be (high-to-low):
456 // * Selected Day Background Colour
457 // * Customized Day Background Colour
458 // * Normal Day Background Colour
459
460 // Background Shape priorities will be (high-to-low):
461 // * Customized Day Shape
462 // * Normal Day Shape
463
464 // Text Colour priorities will be (high-to-low):
465 // * Customized Day Colour
466 // * Day of Pray Colour (Red letter)
467 // * Selected Day Colour
468 // * Normal Day Colour
469
470 //Determine various characteristics of the cell date
471 bool selectedDay = ( cellDate == date() );
472 bool currentDay = ( cellDate == QDate::currentDate() );
473 bool dayOfPray = ( cellDate.dayOfWeek() == calendar()->locale()->weekDayOfPray() );
474 bool customDay = ( d->m_useCustomColors && d->m_customPaintingModes.contains(cellDate.toJulianDay()) );
475
476 //Default values for a normal cell
477 cellBackgroundColor = palette().color( backgroundRole() );
478 cellTextColor = palette().color( foregroundRole() );
479
480 // If we are drawing the current date, then draw it bold and active
481 if ( currentDay ) {
482 cellFont.setBold( true );
483 cellTextColor = colorScheme.foreground(KColorScheme::ActiveText).color();
484 }
485
486 // if we are drawing the day cell currently selected in the table
487 if ( selectedDay ) {
488 // set the background to highlighted
489 cellBackgroundColor = palette().color( QPalette::Highlight );
490 cellTextColor = palette().color( QPalette::HighlightedText );
491 }
492
493 //If custom colors or shape are required for this date
494 if ( customDay ) {
495 KDateTablePrivate::DatePaintingMode mode = d->m_customPaintingModes[cellDate.toJulianDay()];
496 if ( mode.bgMode != NoBgMode ) {
497 cellBackgroundMode = mode.bgMode;
498 if (!selectedDay) cellBackgroundColor = mode.bgColor;
499 }
500 cellTextColor = mode.fgColor;
501 }
502
503 //If the cell day is the day of religious observance, then always color text red unless Custom overrides
504 if ( ! customDay && dayOfPray ) {
505 KColorScheme colorScheme(palette().currentColorGroup(),
506 selectedDay ? KColorScheme::Selection : KColorScheme::View);
507 cellTextColor = colorScheme.foreground(KColorScheme::NegativeText).color();
508 }
509
510 }
511 }
512
513 //Draw the background
514 if (row == 0) {
515 painter->setPen( cellBackgroundColor );
516 painter->setBrush( cellBackgroundColor );
517 painter->drawRect( cell );
518 } else if (cellBackgroundColor != palette().color(backgroundRole()) || pos == d->m_hoveredPos) {
519 QStyleOptionViewItemV4 opt;
520 opt.initFrom(this);
521 opt.rect = cell.toRect();
522 if (cellBackgroundColor != palette().color(backgroundRole())) {
523 opt.palette.setBrush(QPalette::Highlight, cellBackgroundColor);
524 opt.state |= QStyle::State_Selected;
525 }
526 if (pos == d->m_hoveredPos && opt.state & QStyle::State_Enabled) {
527 opt.state |= QStyle::State_MouseOver;
528 } else {
529 opt.state &= ~QStyle::State_MouseOver;
530 }
531 opt.showDecorationSelected = true;
532 opt.viewItemPosition = QStyleOptionViewItemV4::OnlyOne;
533 style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, this);
534 }
535
536 //Draw the text
537 painter->setPen( cellTextColor );
538 painter->setFont( cellFont );
539 painter->drawText( cell, Qt::AlignCenter, cellText, &cell );
540
541 //Draw the base line
542 if (row == 0) {
543 painter->setPen( palette().color(foregroundRole()) );
544 painter->drawLine( QPointF( 0, h ), QPointF( w, h ) );
545 }
546
547 // If the day cell we just drew is bigger than the current max cell sizes,
548 // then adjust the max to the current cell
549 if ( cell.width() > d->m_maxCell.width() ) d->m_maxCell.setWidth( cell.width() );
550 if ( cell.height() > d->m_maxCell.height() ) d->m_maxCell.setHeight( cell.height() );
551}
552
553void KDateTable::KDateTablePrivate::nextMonth()
554{
555 // setDate does validity checking for us
556 q->setDate( m_date.addMonths( 1 ).date() );
557}
558
559void KDateTable::KDateTablePrivate::previousMonth()
560{
561 // setDate does validity checking for us
562 q->setDate( m_date.addMonths( -1 ).date() );
563}
564
565void KDateTable::KDateTablePrivate::beginningOfMonth()
566{
567 // setDate does validity checking for us
568 q->setDate( m_date.firstDayOfMonth().date() );
569}
570
571void KDateTable::KDateTablePrivate::endOfMonth()
572{
573 // setDate does validity checking for us
574 q->setDate( m_date.lastDayOfMonth().date() );
575}
576
577// JPL Do these make the assumption that first day of week is weekday 1? As it may not be.
578void KDateTable::KDateTablePrivate::beginningOfWeek()
579{
580 // setDate does validity checking for us
581 q->setDate( m_date.addDays( 1 - m_date.dayOfWeek() ).date() );
582}
583
584// JPL Do these make the assumption that first day of week is weekday 1? As it may not be.
585void KDateTable::KDateTablePrivate::endOfWeek()
586{
587 // setDate does validity checking for us
588 q->setDate( m_date.addDays( m_date.daysInWeek() - m_date.dayOfWeek() ).date() );
589}
590
591void KDateTable::keyPressEvent( QKeyEvent *e )
592{
593 switch( e->key() ) {
594 case Qt::Key_Up:
595 // setDate does validity checking for us
596 setDate( d->m_date.addDays( - d->m_numDayColumns ).date() );
597 break;
598 case Qt::Key_Down:
599 // setDate does validity checking for us
600 setDate( d->m_date.addDays( d->m_numDayColumns ).date() );
601 break;
602 case Qt::Key_Left:
603 // setDate does validity checking for us
604 setDate( d->m_date.addDays( -1 ).date() );
605 break;
606 case Qt::Key_Right:
607 // setDate does validity checking for us
608 setDate( d->m_date.addDays( 1 ).date() );
609 break;
610 case Qt::Key_Minus:
611 // setDate does validity checking for us
612 setDate( d->m_date.addDays( -1 ).date() );
613 break;
614 case Qt::Key_Plus:
615 // setDate does validity checking for us
616 setDate( d->m_date.addDays( 1 ).date() );
617 break;
618 case Qt::Key_N:
619 // setDate does validity checking for us
620 setDate( QDate::currentDate() );
621 break;
622 case Qt::Key_Return:
623 case Qt::Key_Enter:
624 emit tableClicked();
625 break;
626 case Qt::Key_Control:
627 case Qt::Key_Alt:
628 case Qt::Key_Meta:
629 case Qt::Key_Shift:
630 // Don't beep for modifiers
631 break;
632 default:
633 if ( !e->modifiers() ) { // hm
634 KNotification::beep();
635 }
636 }
637}
638
639void KDateTable::setFontSize( int size )
640{
641 QFontMetricsF metrics( fontMetrics() );
642 QRectF rect;
643 // ----- store rectangles:
644 d->fontsize = size;
645 // ----- find largest day name:
646 d->m_maxCell.setWidth( 0 );
647 d->m_maxCell.setHeight( 0 );
648 for( int weekday = 1; weekday <= d->m_date.daysInWeek(); ++weekday ) {
649 rect = metrics.boundingRect( calendar()->weekDayName( weekday, KCalendarSystem::ShortDayName ) );
650 d->m_maxCell.setWidth( qMax( d->m_maxCell.width(), rect.width() ) );
651 d->m_maxCell.setHeight( qMax( d->m_maxCell.height(), rect.height() ) );
652 }
653 // ----- compare with a real wide number and add some space:
654 rect = metrics.boundingRect( QLatin1String( "88" ) );
655 d->m_maxCell.setWidth( qMax( d->m_maxCell.width() + 2, rect.width() ) );
656 d->m_maxCell.setHeight( qMax( d->m_maxCell.height() + 4, rect.height() ) );
657}
658
659void KDateTable::wheelEvent ( QWheelEvent * e )
660{
661 setDate( d->m_date.addMonths( -( int )( e->delta() / 120 ) ).date() );
662 e->accept();
663}
664
665bool KDateTable::event(QEvent *ev)
666{
667 switch (ev->type()) {
668 case QEvent::HoverMove:
669 {
670 QHoverEvent *e = static_cast<QHoverEvent *>(ev);
671 const int row = e->pos().y() * d->m_numWeekRows / height();
672 int col;
673 if ( layoutDirection() == Qt::RightToLeft ) {
674 col = d->m_numDayColumns - ( e->pos().x() * d->m_numDayColumns / width() ) - 1;
675 } else {
676 col = e->pos().x() * d->m_numDayColumns / width();
677 }
678
679 const int pos = row < 1 ? -1 : (d->m_numDayColumns * (row - 1)) + col;
680
681 if (pos != d->m_hoveredPos) {
682 d->m_hoveredPos = pos;
683 update();
684 }
685 break;
686 }
687 case QEvent::HoverLeave:
688 if (d->m_hoveredPos != -1) {
689 d->m_hoveredPos = -1;
690 update();
691 }
692 break;
693 default:
694 break;
695 }
696 return QWidget::event(ev);
697}
698
699void KDateTable::mousePressEvent( QMouseEvent *e )
700{
701 if( e->type() != QEvent::MouseButtonPress ) { // the KDatePicker only reacts on mouse press events:
702 return;
703 }
704
705 if( !isEnabled() ) {
706 KNotification::beep();
707 return;
708 }
709
710 int row, col, pos, temp;
711
712 QPoint mouseCoord = e->pos();
713 row = mouseCoord.y() * d->m_numWeekRows / height();
714 if ( layoutDirection() == Qt::RightToLeft ) {
715 col = d->m_numDayColumns - ( mouseCoord.x() * d->m_numDayColumns / width() ) - 1;
716 } else {
717 col = mouseCoord.x() * d->m_numDayColumns / width();
718 }
719
720 if( row < 1 || col < 0 ) { // the user clicked on the frame of the table
721 return;
722 }
723
724 // Rows and columns are zero indexed. The (row - 1) below is to avoid counting
725 // the row with the days of the week in the calculation.
726
727 // old selected date:
728 temp = posFromDate( date() );
729
730 // new position and date
731 pos = ( d->m_numDayColumns * ( row - 1 ) ) + col;
732 QDate clickedDate = dateFromPos( pos );
733
734 // set the new date. If it is in the previous or next month, the month will
735 // automatically be changed, no need to do that manually...
736 // validity checking done inside setDate
737 setDate( clickedDate );
738
739 // This could be optimized to only call update over the regions
740 // of old and new cell, but 99% of times there is also a call to
741 // setDate that already calls update() so no need to optimize that
742 // much here
743 update();
744
745 emit tableClicked();
746
747 if ( e->button() == Qt::RightButton && d->m_popupMenuEnabled ) {
748 KMenu * menu = new KMenu();
749 menu->addTitle( d->m_date.formatDate() );
750 emit aboutToShowContextMenu( menu, clickedDate );
751 menu->popup( e->globalPos() );
752 }
753}
754
755void KDateTable::KDateTablePrivate::setDate( const QDate& date )
756{
757 m_date.setDate( date );
758 m_refDate = date;
759 m_weekDayFirstOfMonth = m_date.firstDayOfMonth().dayOfWeek();
760 m_numDaysThisMonth = m_date.daysInMonth();
761 m_numDayColumns = m_date.daysInWeek();
762}
763
764bool KDateTable::setDate( const QDate& toDate )
765{
766 if ( !calendar()->isValid( toDate ) ) {
767 return false;
768 }
769
770 if ( toDate == date() ) {
771 return true;
772 }
773
774 QDate oldDate = date();
775 d->setDate( toDate );
776 emit( dateChanged( date(), oldDate ) );
777 emit( dateChanged( date() ) );
778 update();
779
780 return true;
781}
782
783const QDate &KDateTable::date() const
784{
785 return d->m_refDate;
786}
787
788const KCalendarSystem *KDateTable::calendar() const
789{
790 return d->m_date.calendar();
791}
792
793bool KDateTable::setCalendar( KCalendarSystem *newCalendar )
794{
795 QDate oldDate = date();
796 d->m_date = KLocalizedDate( oldDate, newCalendar );
797 return setDate( oldDate );
798}
799
800bool KDateTable::setCalendar( const QString &newCalendarType )
801{
802 return setCalendarSystem( KCalendarSystem::calendarSystem( newCalendarType ) );
803}
804
805bool KDateTable::setCalendarSystem( KLocale::CalendarSystem newCalendarSystem )
806{
807 d->m_date.setCalendarSystem( newCalendarSystem );
808 return true;
809}
810
811void KDateTable::focusInEvent( QFocusEvent *e )
812{
813 QWidget::focusInEvent( e );
814}
815
816void KDateTable::focusOutEvent( QFocusEvent *e )
817{
818 QWidget::focusOutEvent( e );
819}
820
821QSize KDateTable::sizeHint() const
822{
823 if( d->m_maxCell.height() > 0 && d->m_maxCell.width() > 0 ) {
824 return QSize( qRound( d->m_maxCell.width() * d->m_numDayColumns ),
825 ( qRound( d->m_maxCell.height() + 2 ) * d->m_numWeekRows ) );
826 } else {
827 kDebug() << "KDateTable::sizeHint: obscure failure - " << endl;
828 return QSize( -1, -1 );
829 }
830}
831
832void KDateTable::setPopupMenuEnabled( bool enable )
833{
834 d->m_popupMenuEnabled = enable;
835}
836
837bool KDateTable::popupMenuEnabled() const
838{
839 return d->m_popupMenuEnabled;
840}
841
842void KDateTable::setCustomDatePainting( const QDate &date, const QColor &fgColor, BackgroundMode bgMode, const QColor &bgColor )
843{
844 if ( !fgColor.isValid() ) {
845 unsetCustomDatePainting( date );
846 return;
847 }
848
849 KDateTablePrivate::DatePaintingMode mode;
850 mode.bgMode = bgMode;
851 mode.fgColor = fgColor;
852 mode.bgColor = bgColor;
853
854 d->m_customPaintingModes.insert( date.toJulianDay(), mode );
855 d->m_useCustomColors = true;
856 update();
857}
858
859void KDateTable::unsetCustomDatePainting( const QDate &date )
860{
861 d->m_customPaintingModes.remove( date.toJulianDay() );
862 if ( d->m_customPaintingModes.isEmpty() ) d->m_useCustomColors = false;
863 update();
864}
865
866
867// JPL Shouldn't this be in own file as is used in a couple of places? Or moved to private in KDE5?
868
869KPopupFrame::KPopupFrame( QWidget* parent )
870 : QFrame( parent, Qt::Popup ), d( new KPopupFramePrivate( this ) )
871{
872 setFrameStyle( QFrame::Box | QFrame::Raised );
873 setMidLineWidth( 2 );
874}
875
876KPopupFrame::~KPopupFrame()
877{
878 delete d;
879}
880
881void KPopupFrame::keyPressEvent( QKeyEvent* e )
882{
883 if( e->key() == Qt::Key_Escape ) {
884 d->result = 0; // rejected
885 emit leaveModality();
886 //qApp->exit_loop();
887 }
888}
889
890void KPopupFrame::close( int r )
891{
892 d->result = r;
893 emit leaveModality();
894 //qApp->exit_loop();
895}
896
897void KPopupFrame::setMainWidget( QWidget *m )
898{
899 d->main = m;
900 if( d->main ) {
901 resize( d->main->width() + 2 * frameWidth(), d->main->height() + 2 * frameWidth() );
902 }
903}
904
905void KPopupFrame::resizeEvent( QResizeEvent *e )
906{
907 Q_UNUSED( e );
908
909 if( d->main ) {
910 d->main->setGeometry( frameWidth(), frameWidth(),
911 width() - 2 * frameWidth(), height() - 2 * frameWidth() );
912 }
913}
914
915void KPopupFrame::popup( const QPoint &pos )
916{
917 // Make sure the whole popup is visible.
918 QRect desktopGeometry = KGlobalSettings::desktopGeometry( pos );
919
920 int x = pos.x();
921 int y = pos.y();
922 int w = width();
923 int h = height();
924 if ( x + w > desktopGeometry.x() + desktopGeometry.width() ) {
925 x = desktopGeometry.width() - w;
926 }
927 if ( y + h > desktopGeometry.y() + desktopGeometry.height() ) {
928 y = desktopGeometry.height() - h;
929 }
930 if ( x < desktopGeometry.x() ) {
931 x = 0;
932 }
933 if ( y < desktopGeometry.y() ) {
934 y = 0;
935 }
936
937 // Pop the thingy up.
938 move( x, y );
939 show();
940 d->main->setFocus();
941}
942
943int KPopupFrame::exec( const QPoint &pos )
944{
945 popup( pos );
946 repaint();
947 d->result = 0; // rejected
948 QEventLoop eventLoop;
949 connect( this, SIGNAL(leaveModality()),
950 &eventLoop, SLOT(quit()) );
951 eventLoop.exec();
952
953 hide();
954 return d->result;
955}
956
957int KPopupFrame::exec( int x, int y )
958{
959 return exec( QPoint( x, y ) );
960}
961
962#include "kdatetable.moc"
KActionCollection
A container for a set of QAction objects.
Definition: kactioncollection.h:57
KActionCollection::addAction
QAction * addAction(const QString &name, QAction *action)
Add an action under the given name to the collection.
Definition: kactioncollection.cpp:217
KActionCollection::addAssociatedWidget
void addAssociatedWidget(QWidget *widget)
Associate all actions in this collection to the given widget, including any actions added after this ...
Definition: kactioncollection.cpp:708
KActionCollection::readSettings
void readSettings(KConfigGroup *config=0)
Read all key associations from config.
Definition: kactioncollection.cpp:413
KActionCollection::actions
QList< QAction * > actions() const
Returns the list of KActions which belong to this action collection.
Definition: kactioncollection.cpp:186
KAction
Class to encapsulate user-driven action or event.
Definition: kaction.h:217
KAction::setShortcuts
void setShortcuts(const QList< QKeySequence > &shortcuts, ShortcutTypes type=ShortcutTypes(ActiveShortcut|DefaultShortcut))
Definition: kaction.cpp:224
KCalendarSystem
KCalendarSystem::day
virtual int day(const QDate &date) const
KCalendarSystem::weekStartDay
virtual int weekStartDay() const
KCalendarSystem::locale
const KLocale * locale() const
KCalendarSystem::ShortDayName
ShortDayName
KCalendarSystem::weekDayName
virtual QString weekDayName(const QDate &date, WeekDayNameFormat format=LongDayName) const
KCalendarSystem::calendarSystem
KLocale::CalendarSystem calendarSystem() const
KColorScheme
A set of methods used to work with colors.
Definition: kcolorscheme.h:71
KColorScheme::ActiveText
@ ActiveText
Third color; for example items which are new, active, requesting attention, etc.
Definition: kcolorscheme.h:215
KColorScheme::InactiveText
@ InactiveText
Second color; for example, comments, items which are old, inactive or disabled.
Definition: kcolorscheme.h:210
KColorScheme::NegativeText
@ NegativeText
Sixth color; for example, errors, untrusted content, deletions, etc.
Definition: kcolorscheme.h:234
KColorScheme::View
@ View
Views; for example, frames, input fields, etc.
Definition: kcolorscheme.h:87
KColorScheme::Window
@ Window
Non-editable window elements; for example, menus.
Definition: kcolorscheme.h:93
KColorScheme::Selection
@ Selection
Selected items in views.
Definition: kcolorscheme.h:109
KColorScheme::foreground
QBrush foreground(ForegroundRole=NormalText) const
Retrieve the requested foreground brush.
Definition: kcolorscheme.cpp:459
KDateTable
Date selection table.
Definition: kdatetable.h:140
KDateTable::setCalendar
bool setCalendar(KCalendarSystem *calendar=0)
Changes the calendar system to use.
Definition: kdatetable.cpp:793
KDateTable::focusInEvent
virtual void focusInEvent(QFocusEvent *e)
Definition: kdatetable.cpp:811
KDateTable::setFontSize
void setFontSize(int size)
Set the font size of the date table.
Definition: kdatetable.cpp:639
KDateTable::~KDateTable
~KDateTable()
The destructor.
Definition: kdatetable.cpp:260
KDateTable::event
virtual bool event(QEvent *e)
Cell highlight on mouse hovering.
Definition: kdatetable.cpp:665
KDateTable::setCalendarSystem
bool setCalendarSystem(KLocale::CalendarSystem calendarSystem)
Definition: kdatetable.cpp:805
KDateTable::setCustomDatePainting
void setCustomDatePainting(const QDate &date, const QColor &fgColor, BackgroundMode bgMode=NoBgMode, const QColor &bgColor=QColor())
Makes a given date be painted with a given foregroundColor, and background (a rectangle,...
Definition: kdatetable.cpp:842
KDateTable::setPopupMenuEnabled
void setPopupMenuEnabled(bool enable)
Enables a popup menu when right clicking on a date.
Definition: kdatetable.cpp:832
KDateTable::posFromDate
virtual int posFromDate(const QDate &date)
calculate the position of the cell in the matrix for the given date.
Definition: kdatetable.cpp:314
KDateTable::keyPressEvent
virtual void keyPressEvent(QKeyEvent *e)
Definition: kdatetable.cpp:591
KDateTable::mousePressEvent
virtual void mousePressEvent(QMouseEvent *e)
React on mouse clicks that select a date.
Definition: kdatetable.cpp:699
KDateTable::dateFromPos
virtual QDate dateFromPos(int pos)
calculate the date that is displayed at a given cell in the matrix.
Definition: kdatetable.cpp:328
KDateTable::unsetCustomDatePainting
void unsetCustomDatePainting(const QDate &date)
Unsets the custom painting of a date so that the date is painted as usual.
Definition: kdatetable.cpp:859
KDateTable::popupMenuEnabled
bool popupMenuEnabled() const
Returns if the popup menu is enabled or not.
Definition: kdatetable.cpp:837
KDateTable::focusOutEvent
virtual void focusOutEvent(QFocusEvent *e)
Definition: kdatetable.cpp:816
KDateTable::sizeHint
virtual QSize sizeHint() const
Returns a recommended size for the widget.
Definition: kdatetable.cpp:821
KDateTable::aboutToShowContextMenu
void aboutToShowContextMenu(KMenu *menu, const QDate &date)
A popup menu for a given date is about to be shown (as when the user right clicks on that date and th...
KDateTable::dateChanged
void dateChanged(const QDate &date)
The selected date changed.
KDateTable::wheelEvent
virtual void wheelEvent(QWheelEvent *e)
Definition: kdatetable.cpp:659
KDateTable::calendar
const KCalendarSystem * calendar() const
Returns the currently selected calendar system.
Definition: kdatetable.cpp:788
KDateTable::date
QDate date
Definition: kdatetable.h:142
KDateTable::paintEvent
virtual void paintEvent(QPaintEvent *e)
Definition: kdatetable.cpp:341
KDateTable::tableClicked
void tableClicked()
A date has been selected by clicking on the table.
KDateTable::setDate
bool setDate(const QDate &date)
Select and display this date.
Definition: kdatetable.cpp:764
KDateTable::BackgroundMode
BackgroundMode
Definition: kdatetable.h:235
KDateTable::KDateTable
KDateTable(QWidget *parent=0)
The constructor.
Definition: kdatetable.cpp:253
KDateValidator
Validates user-entered dates.
Definition: kdatetable.h:113
KDateValidator::date
State date(const QString &text, QDate &date) const
Definition: kdatetable.cpp:230
KDateValidator::KDateValidator
KDateValidator(QWidget *parent=0)
Definition: kdatetable.cpp:217
KDateValidator::fixup
virtual void fixup(QString &input) const
Definition: kdatetable.cpp:242
KDateValidator::validate
virtual State validate(QString &text, int &e) const
Definition: kdatetable.cpp:221
KGlobalSettings::desktopGeometry
static QRect desktopGeometry(const QPoint &point)
This function returns the desktop geometry for an application that needs to set the geometry of a wid...
Definition: kglobalsettings.cpp:732
KGlobalSettings::generalFont
static QFont generalFont()
Returns the default general font.
Definition: kglobalsettings.cpp:446
KLocale::Day
Day
KLocale::CalendarSystem
CalendarSystem
KLocale::weekDayOfPray
int weekDayOfPray() const
KLocale::readDate
QDate readDate(const QString &intstr, const QString &fmt, bool *ok=0) const
KLocale::ShortNumber
ShortNumber
KLocalizedDate
KLocalizedDate::month
int month() const
KLocalizedDate::dayOfWeek
int dayOfWeek() const
KLocalizedDate::toJulianDay
int toJulianDay() const
KLocalizedDate::isValid
bool isValid() const
KLocalizedDate::formatDate
QString formatDate(const QString &formatString, KLocale::DateTimeFormatStandard formatStandard=KLocale::KdeFormat) const
KMenu
A menu with keyboard searching.
Definition: kmenu.h:42
KMenu::addTitle
QAction * addTitle(const QString &text, QAction *before=0L)
Inserts a title item with no icon.
Definition: kmenu.cpp:170
KNotification::beep
static void beep(const QString &reason=QString(), QWidget *widget=0L)
This is a simple substitution for QApplication::beep()
Definition: knotification.cpp:352
KPopupFrame
Frame with popup menu behavior.
Definition: kdatetable.h:42
KPopupFrame::KPopupFrame
KPopupFrame(QWidget *parent=0)
The contructor.
Definition: kdatetable.cpp:869
KPopupFrame::setMainWidget
void setMainWidget(QWidget *m)
Set the main widget.
Definition: kdatetable.cpp:897
KPopupFrame::close
void close(int r)
Close the popup window.
Definition: kdatetable.cpp:890
KPopupFrame::keyPressEvent
virtual void keyPressEvent(QKeyEvent *e)
Catch key press events.
Definition: kdatetable.cpp:881
KPopupFrame::~KPopupFrame
~KPopupFrame()
The destructor.
Definition: kdatetable.cpp:876
KPopupFrame::resizeEvent
virtual void resizeEvent(QResizeEvent *resize)
The resize event.
Definition: kdatetable.cpp:905
KPopupFrame::popup
void popup(const QPoint &pos)
Open the popup window at position pos.
Definition: kdatetable.cpp:915
KPopupFrame::leaveModality
void leaveModality()
KPopupFrame::exec
int exec(const QPoint &p)
Execute the popup window.
Definition: kdatetable.cpp:943
QAction
QFrame
QObject
QValidator
QWidget
kDebug
#define kDebug
kaction.h
kactioncollection.h
kcalendarsystem.h
kcolorscheme.h
kconfig.h
kdatepicker.h
kdatetable.h
kdebug.h
kglobal.h
kglobalsettings.h
klocalizeddate.h
kmenu.h
knotification.h
kshortcut.h
Defines platform-independent classes for keyboard shortcut handling.
kstandardshortcut.h
KGlobal::locale
KLocale * locale()
KStandardAction::next
KAction * next(const QObject *recvr, const char *slot, QObject *parent)
Scroll down one page.
Definition: kstandardaction.cpp:414
KStandardAction::prior
KAction * prior(const QObject *recvr, const char *slot, QObject *parent)
Scroll up one page.
Definition: kstandardaction.cpp:409
KStandardShortcut::prior
const KShortcut & prior()
Scroll up one page.
Definition: kstandardshortcut.cpp:351
KStandardShortcut::endOfLine
const KShortcut & endOfLine()
Goto end of current line.
Definition: kstandardshortcut.cpp:350
KStandardShortcut::beginningOfLine
const KShortcut & beginningOfLine()
Goto beginning of current line.
Definition: kstandardshortcut.cpp:349
KStandardShortcut::begin
const KShortcut & begin()
Goto beginning of the document.
Definition: kstandardshortcut.cpp:347
KStandardShortcut::end
const KShortcut & end()
Goto end of the document.
Definition: kstandardshortcut.cpp:348
KStandardShortcut::next
const KShortcut & next()
Scroll down one page.
Definition: kstandardshortcut.cpp:352
main
int main(int argc, char **argv)
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDEUI

Skip menu "KDEUI"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdelibs-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal