38 #include <kdeversion.h>
40 #include <QtCore/QDate>
41 #include <QtCore/QCharRef>
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>
59 m_popupMenuEnabled =
false;
60 m_useCustomColors =
false;
62 setDate( QDate::currentDate() );
72 void beginningOfMonth();
74 void beginningOfWeek();
95 int m_weekDayFirstOfMonth;
100 int m_numDaysThisMonth;
117 bool m_popupMenuEnabled;
118 bool m_useCustomColors;
120 struct DatePaintingMode
151 class OutsideClickCatcher;
152 OutsideClickCatcher *outsideClickCatcher;
156 class KPopupFrame::KPopupFramePrivate::OutsideClickCatcher
160 OutsideClickCatcher(
QObject *parent = 0)
161 :
QObject(parent), m_popup(0) { }
162 ~OutsideClickCatcher() { }
167 popup->installEventFilter(
this);
172 bool eventFilter(
QObject *
object, QEvent *event)
178 if (event->type() == QEvent::Hide && m_popup) {
181 emit m_popup->leaveModality();
188 KPopupFrame::KPopupFramePrivate::KPopupFramePrivate(
KPopupFrame *q ):
192 outsideClickCatcher(new OutsideClickCatcher)
194 outsideClickCatcher->setPopupFrame(q);
197 KPopupFrame::KPopupFramePrivate::~KPopupFramePrivate()
199 delete outsideClickCatcher;
227 return date( text, temp );
238 return QValidator::Intermediate;
248 d( new KDateTablePrivate( this ) )
255 d( new KDateTablePrivate( this ) )
257 init( QDate::currentDate() );
265 void KDateTable::init(
const QDate &date )
267 d->m_numWeekRows = 7;
270 setFocusPolicy( Qt::StrongFocus );
271 setBackgroundRole(QPalette::Base);
272 setAutoFillBackground(
true);
274 setAttribute(Qt::WA_Hover,
true);
279 void KDateTable::initAccels()
285 connect( next, SIGNAL(triggered(
bool)), SLOT(nextMonth()) );
289 connect( prior, SIGNAL(triggered(
bool)), SLOT(previousMonth()) );
291 KAction* beginMonth = localCollection->
addAction( QLatin1String(
"beginMonth" ) );
293 connect( beginMonth, SIGNAL(triggered(
bool)), SLOT(beginningOfMonth()) );
295 KAction* endMonth = localCollection->
addAction( QLatin1String(
"endMonth" ) );
297 connect( endMonth, SIGNAL(triggered(
bool)), SLOT(endOfMonth()) );
299 KAction* beginWeek = localCollection->
addAction( QLatin1String(
"beginWeek" ) );
301 connect( beginWeek, SIGNAL(triggered(
bool)), SLOT(beginningOfWeek()) );
305 connect( endWeek, SIGNAL(triggered(
bool)), SLOT(endOfWeek()) );
310 action->setShortcutContext(Qt::WidgetWithChildrenShortcut);
317 int offset = ( d->m_weekDayFirstOfMonth -
calendar()->
weekStartDay() + d->m_numDayColumns ) % d->m_numDayColumns;
322 offset += d->m_numDayColumns;
325 return initialPosition + offset;
330 int offset = ( d->m_weekDayFirstOfMonth -
calendar()->
weekStartDay() + d->m_numDayColumns ) % d->m_numDayColumns;
335 offset += d->m_numDayColumns;
338 return d->m_date.firstDayOfMonth().addDays( position - offset ).date();
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 );
357 p.translate( leftCol * cellWidth, topRow * cellHeight );
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 );
364 if ( layoutDirection() == Qt::RightToLeft ) {
365 p.translate( -cellWidth, 0 );
367 p.translate( cellWidth, 0 );
369 p.translate( 0, -cellHeight * ( bottomRow - topRow + 1 ) );
373 void KDateTable::paintCell( QPainter *painter,
int row,
int col,
const KColorScheme &colorScheme )
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 );
380 QColor cellBackgroundColor, cellTextColor;
382 bool workingDay =
false;
383 int cellWeekDay, pos;
387 pos = d->m_numDayColumns * ( row - 1 ) + col;
416 cellTextColor = palette().color(QPalette::WindowText);
421 cellBackgroundColor = palette().color(QPalette::Window);
424 cellFont.setBold(
true );
436 bool validDay = cellDate.
isValid();
445 if( ! validDay || cellDate.
month() != d->m_date.month() ) {
450 cellBackgroundColor = palette().color(backgroundRole());
471 bool selectedDay = ( cellDate ==
date() );
472 bool currentDay = ( cellDate == QDate::currentDate() );
474 bool customDay = ( d->m_useCustomColors && d->m_customPaintingModes.contains(cellDate.
toJulianDay()) );
477 cellBackgroundColor = palette().color( backgroundRole() );
478 cellTextColor = palette().color( foregroundRole() );
482 cellFont.setBold(
true );
489 cellBackgroundColor = palette().color( QPalette::Highlight );
490 cellTextColor = palette().color( QPalette::HighlightedText );
495 KDateTablePrivate::DatePaintingMode mode = d->m_customPaintingModes[cellDate.
toJulianDay()];
497 cellBackgroundMode = mode.bgMode;
498 if (!selectedDay) cellBackgroundColor = mode.bgColor;
500 cellTextColor = mode.fgColor;
504 if ( ! customDay && dayOfPray ) {
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;
521 opt.rect = cell.toRect();
522 if (cellBackgroundColor != palette().color(backgroundRole())) {
523 opt.palette.setBrush(QPalette::Highlight, cellBackgroundColor);
524 opt.state |= QStyle::State_Selected;
526 if (pos == d->m_hoveredPos && opt.state & QStyle::State_Enabled) {
527 opt.state |= QStyle::State_MouseOver;
529 opt.state &= ~QStyle::State_MouseOver;
531 opt.showDecorationSelected =
true;
532 opt.viewItemPosition = QStyleOptionViewItemV4::OnlyOne;
533 style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter,
this);
537 painter->setPen( cellTextColor );
538 painter->setFont( cellFont );
539 painter->drawText( cell, Qt::AlignCenter, cellText, &cell );
543 painter->setPen( palette().color(foregroundRole()) );
544 painter->drawLine( QPointF( 0, h ), QPointF( w, h ) );
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() );
553 void KDateTable::KDateTablePrivate::nextMonth()
556 q->setDate( m_date.addMonths( 1 ).date() );
559 void KDateTable::KDateTablePrivate::previousMonth()
562 q->setDate( m_date.addMonths( -1 ).date() );
565 void KDateTable::KDateTablePrivate::beginningOfMonth()
568 q->setDate( m_date.firstDayOfMonth().date() );
571 void KDateTable::KDateTablePrivate::endOfMonth()
574 q->setDate( m_date.lastDayOfMonth().date() );
578 void KDateTable::KDateTablePrivate::beginningOfWeek()
581 q->setDate( m_date.addDays( 1 - m_date.dayOfWeek() ).date() );
585 void KDateTable::KDateTablePrivate::endOfWeek()
588 q->setDate( m_date.addDays( m_date.daysInWeek() - m_date.dayOfWeek() ).date() );
596 setDate( d->m_date.addDays( - d->m_numDayColumns ).date() );
600 setDate( d->m_date.addDays( d->m_numDayColumns ).date() );
604 setDate( d->m_date.addDays( -1 ).date() );
608 setDate( d->m_date.addDays( 1 ).date() );
612 setDate( d->m_date.addDays( -1 ).date() );
616 setDate( d->m_date.addDays( 1 ).date() );
620 setDate( QDate::currentDate() );
626 case Qt::Key_Control:
633 if ( !e->modifiers() ) {
641 QFontMetricsF metrics( fontMetrics() );
646 d->m_maxCell.setWidth( 0 );
647 d->m_maxCell.setHeight( 0 );
648 for(
int weekday = 1; weekday <= d->m_date.daysInWeek(); ++weekday ) {
650 d->m_maxCell.setWidth( qMax( d->m_maxCell.width(), rect.width() ) );
651 d->m_maxCell.setHeight( qMax( d->m_maxCell.height(), rect.height() ) );
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() ) );
661 setDate( d->m_date.addMonths( -(
int )( e->delta() / 120 ) ).date() );
667 switch (ev->type()) {
668 case QEvent::HoverMove:
670 QHoverEvent *e =
static_cast<QHoverEvent *
>(ev);
671 const int row = e->pos().y() * d->m_numWeekRows / height();
673 if ( layoutDirection() == Qt::RightToLeft ) {
674 col = d->m_numDayColumns - ( e->pos().x() * d->m_numDayColumns / width() ) - 1;
676 col = e->pos().x() * d->m_numDayColumns / width();
679 const int pos = row < 1 ? -1 : (d->m_numDayColumns * (row - 1)) + col;
681 if (pos != d->m_hoveredPos) {
682 d->m_hoveredPos = pos;
687 case QEvent::HoverLeave:
688 if (d->m_hoveredPos != -1) {
689 d->m_hoveredPos = -1;
696 return QWidget::event(ev);
701 if( e->type() != QEvent::MouseButtonPress ) {
710 int row, col, pos, temp;
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;
717 col = mouseCoord.x() * d->m_numDayColumns / width();
720 if( row < 1 || col < 0 ) {
731 pos = ( d->m_numDayColumns * ( row - 1 ) ) + col;
747 if ( e->button() == Qt::RightButton && d->m_popupMenuEnabled ) {
749 menu->
addTitle( d->m_date.formatDate() );
751 menu->popup( e->globalPos() );
755 void KDateTable::KDateTablePrivate::setDate(
const QDate& date )
757 m_date.setDate( date );
759 m_weekDayFirstOfMonth = m_date.firstDayOfMonth().dayOfWeek();
760 m_numDaysThisMonth = m_date.daysInMonth();
761 m_numDayColumns = m_date.daysInWeek();
766 if ( !
calendar()->isValid( toDate ) ) {
770 if ( toDate ==
date() ) {
774 QDate oldDate =
date();
775 d->setDate( toDate );
790 return d->m_date.calendar();
795 QDate oldDate =
date();
807 d->m_date.setCalendarSystem( newCalendarSystem );
813 QWidget::focusInEvent( e );
818 QWidget::focusOutEvent( e );
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 ) );
827 kDebug() <<
"KDateTable::sizeHint: obscure failure - " << endl;
828 return QSize( -1, -1 );
834 d->m_popupMenuEnabled = enable;
839 return d->m_popupMenuEnabled;
844 if ( !fgColor.isValid() ) {
849 KDateTablePrivate::DatePaintingMode mode;
850 mode.bgMode = bgMode;
851 mode.fgColor = fgColor;
852 mode.bgColor = bgColor;
854 d->m_customPaintingModes.insert( date.toJulianDay(), mode );
855 d->m_useCustomColors =
true;
861 d->m_customPaintingModes.remove( date.toJulianDay() );
862 if ( d->m_customPaintingModes.isEmpty() ) d->m_useCustomColors =
false;
870 :
QFrame( parent, Qt::Popup ), d( new KPopupFramePrivate( this ) )
872 setFrameStyle( QFrame::Box | QFrame::Raised );
873 setMidLineWidth( 2 );
883 if( e->key() == Qt::Key_Escape ) {
901 resize( d->main->width() + 2 * frameWidth(), d->main->height() + 2 * frameWidth() );
910 d->main->setGeometry( frameWidth(), frameWidth(),
911 width() - 2 * frameWidth(), height() - 2 * frameWidth() );
924 if ( x + w > desktopGeometry.x() + desktopGeometry.width() ) {
925 x = desktopGeometry.width() - w;
927 if ( y + h > desktopGeometry.y() + desktopGeometry.height() ) {
928 y = desktopGeometry.height() - h;
930 if ( x < desktopGeometry.x() ) {
933 if ( y < desktopGeometry.y() ) {
948 QEventLoop eventLoop;
950 &eventLoop, SLOT(
quit()) );
962 #include "kdatetable.moc"
virtual QDate dateFromPos(int pos)
calculate the date that is displayed at a given cell in the matrix.
A container for a set of QAction objects.
void setFontSize(int size)
Set the font size of the date table.
void setShortcuts(const QList< QKeySequence > &shortcuts, ShortcutTypes type=ShortcutTypes(ActiveShortcut|DefaultShortcut))
void setPopupMenuEnabled(bool enable)
Enables a popup menu when right clicking on a date.
const KShortcut & next()
Scroll down one page.
Sixth color; for example, errors, untrusted content, deletions, etc.
bool popupMenuEnabled() const
Returns if the popup menu is enabled or not.
friend class KDateValidatorPrivate
KDateTable(QWidget *parent=0)
The constructor.
virtual int weekStartDay() const
Third color; for example items which are new, active, requesting attention, etc.
KAction * prior(const QObject *recvr, const char *slot, QObject *parent)
Scroll up one page.
Defines platform-independent classes for keyboard shortcut handling.
virtual int day(const QDate &date) const
QAction * addAction(const QString &name, QAction *action)
Add an action under the given name to the collection.
friend class KDateTablePrivate
static QRect desktopGeometry(const QPoint &point)
This function returns the desktop geometry for an application that needs to set the geometry of a wid...
Second color; for example, comments, items which are old, inactive or disabled.
KDateValidator(QWidget *parent=0)
KLocale::CalendarSystem calendarSystem() const
QDate readDate(const QString &str, bool *ok=0) const
static QDebug kDebug(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
Non-editable window elements; for example, menus.
void tableClicked()
A date has been selected by clicking on the table.
QBrush foreground(ForegroundRole=NormalText) const
Retrieve the requested foreground brush.
virtual int posFromDate(const QDate &date)
calculate the position of the cell in the matrix for the given date.
virtual QSize sizeHint() const
Returns a recommended size for the widget.
const QDate & date() const
bool setCalendar(KCalendarSystem *calendar=0)
Changes the calendar system to use.
const KShortcut & endOfLine()
Goto end of current line.
virtual void paintEvent(QPaintEvent *e)
QList< QAction * > actions() const
Returns the list of KActions which belong to this action collection.
const KShortcut & beginningOfLine()
Goto beginning of current line.
static void beep(const QString &reason=QString(), QWidget *widget=0L)
This is a simple substitution for QApplication::beep()
~KDateTable()
The destructor.
Views; for example, frames, input fields, etc.
const KLocale * locale() const
virtual bool event(QEvent *e)
Cell highlight on mouse hovering.
virtual void wheelEvent(QWheelEvent *e)
Validates user-entered dates.
QString formatDate(KLocale::DateFormat dateFormat=KLocale::LongDate) const
KAction * next(const QObject *recvr, const char *slot, QObject *parent)
Scroll down one page.
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...
int weekDayOfPray() const
virtual void fixup(QString &input) const
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, or a circle/ellipse) in a given color.
const KCalendarSystem * calendar() const
Returns the currently selected calendar system.
virtual void focusInEvent(QFocusEvent *e)
static QFont generalFont()
Returns the default general font.
virtual void keyPressEvent(QKeyEvent *e)
bool setCalendarSystem(KLocale::CalendarSystem calendarSystem)
const KShortcut & prior()
Scroll up one page.
A set of methods used to work with colors.
virtual void focusOutEvent(QFocusEvent *e)
Class to encapsulate user-driven action or event.
virtual State validate(QString &text, int &e) const
virtual void mousePressEvent(QMouseEvent *e)
React on mouse clicks that select a date.
void addAssociatedWidget(QWidget *widget)
Associate all actions in this collection to the given widget, including any actions added after this ...
State date(const QString &text, QDate &date) const
KAction * quit(const QObject *recvr, const char *slot, QObject *parent)
Quit the program.
const KShortcut & end()
Goto end of the document.
void readSettings(KConfigGroup *config=0)
Read all key associations from config.
void dateChanged(const QDate &date)
The selected date changed.
int main(int argc, char **argv)
virtual QString weekDayName(int weekDay, WeekDayNameFormat format=LongDayName) const =0
bool setDate(const QDate &date)
Select and display this date.
const KShortcut & begin()
Goto beginning of the document.
void unsetCustomDatePainting(const QDate &date)
Unsets the custom painting of a date so that the date is painted as usual.