|
|
/* -*- C++ -*-
|
|
|
This file is part of the KDE libraries
|
|
|
Copyright (C) 1997 Tim D. Gilman (tdgilman@best.org)
|
|
|
(C) 1998-2001 Mirko Boehm (mirko@kde.org)
|
|
|
This library is free software; you can redistribute it and/or
|
|
|
modify it under the terms of the GNU Library General Public
|
|
|
License as published by the Free Software Foundation; either
|
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
Library General Public License for more details.
|
|
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
|
Boston, MA 02110-1301, USA.
|
|
|
*/
|
|
|
|
|
|
/////////////////// KDateTable widget class //////////////////////
|
|
|
//
|
|
|
// Copyright (C) 1997 Tim D. Gilman
|
|
|
// (C) 1998-2001 Mirko Boehm
|
|
|
// Written using Qt (http://www.troll.no) for the
|
|
|
// KDE project (http://www.kde.org)
|
|
|
//
|
|
|
// This is a support class for the KDatePicker class. It just
|
|
|
// draws the calender table without titles, but could theoretically
|
|
|
// be used as a standalone.
|
|
|
//
|
|
|
// When a date is selected by the user, it emits a signal:
|
|
|
// dateSelected(TQDate)
|
|
|
|
|
|
#include <kconfig.h>
|
|
|
#include <kglobal.h>
|
|
|
#include <kglobalsettings.h>
|
|
|
#include <kapplication.h>
|
|
|
#include <kaccel.h>
|
|
|
#include <klocale.h>
|
|
|
#include <kdebug.h>
|
|
|
#include <knotifyclient.h>
|
|
|
#include <kcalendarsystem.h>
|
|
|
#include <kshortcut.h>
|
|
|
#include <kstdaccel.h>
|
|
|
#include "kdatepicker.h"
|
|
|
#include "kdatetbl.h"
|
|
|
#include "kpopupmenu.h"
|
|
|
#include <tqdatetime.h>
|
|
|
#include <tqguardedptr.h>
|
|
|
#include <tqstring.h>
|
|
|
#include <tqpen.h>
|
|
|
#include <tqpainter.h>
|
|
|
#include <tqdialog.h>
|
|
|
#include <tqdict.h>
|
|
|
#include <assert.h>
|
|
|
|
|
|
|
|
|
class KDateTable::KDateTablePrivate
|
|
|
{
|
|
|
public:
|
|
|
KDateTablePrivate()
|
|
|
{
|
|
|
popupMenuEnabled=false;
|
|
|
useCustomColors=false;
|
|
|
}
|
|
|
|
|
|
~KDateTablePrivate()
|
|
|
{
|
|
|
}
|
|
|
|
|
|
bool popupMenuEnabled;
|
|
|
bool useCustomColors;
|
|
|
|
|
|
struct DatePaintingMode
|
|
|
{
|
|
|
TQColor fgColor;
|
|
|
TQColor bgColor;
|
|
|
BackgroundMode bgMode;
|
|
|
};
|
|
|
TQDict <DatePaintingMode> customPaintingModes;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
KDateValidator::KDateValidator(TQWidget* parent, const char* name)
|
|
|
: TQValidator(TQT_TQOBJECT(parent), name)
|
|
|
{
|
|
|
}
|
|
|
|
|
|
TQValidator::State
|
|
|
KDateValidator::validate(TQString& text, int&) const
|
|
|
{
|
|
|
TQDate temp;
|
|
|
// ----- everything is tested in date():
|
|
|
return date(text, temp);
|
|
|
}
|
|
|
|
|
|
TQValidator::State
|
|
|
KDateValidator::date(const TQString& text, TQDate& d) const
|
|
|
{
|
|
|
TQDate tmp = KGlobal::locale()->readDate(text);
|
|
|
if (!tmp.isNull())
|
|
|
{
|
|
|
d = tmp;
|
|
|
return Acceptable;
|
|
|
} else
|
|
|
return Valid;
|
|
|
}
|
|
|
|
|
|
void
|
|
|
KDateValidator::fixup( TQString& ) const
|
|
|
{
|
|
|
|
|
|
}
|
|
|
|
|
|
KDateTable::KDateTable(TQWidget *parent, TQDate date_, const char* name, WFlags f)
|
|
|
: TQGridView(parent, name, (f | TQt::WNoAutoErase))
|
|
|
{
|
|
|
d = new KDateTablePrivate;
|
|
|
setFontSize(10);
|
|
|
if(!date_.isValid())
|
|
|
{
|
|
|
kdDebug() << "KDateTable ctor: WARNING: Given date is invalid, using current date." << endl;
|
|
|
date_=TQDate::currentDate();
|
|
|
}
|
|
|
setFocusPolicy( TQ_StrongFocus );
|
|
|
setNumRows(7); // 6 weeks max + headline
|
|
|
setNumCols(7); // 7 days a week
|
|
|
setHScrollBarMode(AlwaysOff);
|
|
|
setVScrollBarMode(AlwaysOff);
|
|
|
viewport()->setEraseColor(KGlobalSettings::baseColor());
|
|
|
setDate(date_); // this initializes firstday, numdays, numDaysPrevMonth
|
|
|
|
|
|
initAccels();
|
|
|
}
|
|
|
|
|
|
KDateTable::KDateTable(TQWidget *parent, const char* name, WFlags f)
|
|
|
: TQGridView(parent, name, (f | TQt::WNoAutoErase))
|
|
|
{
|
|
|
d = new KDateTablePrivate;
|
|
|
setFontSize(10);
|
|
|
setFocusPolicy( TQ_StrongFocus );
|
|
|
setNumRows(7); // 6 weeks max + headline
|
|
|
setNumCols(7); // 7 days a week
|
|
|
setHScrollBarMode(AlwaysOff);
|
|
|
setVScrollBarMode(AlwaysOff);
|
|
|
viewport()->setEraseColor(KGlobalSettings::baseColor());
|
|
|
setDate(TQDate::currentDate()); // this initializes firstday, numdays, numDaysPrevMonth
|
|
|
initAccels();
|
|
|
}
|
|
|
|
|
|
KDateTable::~KDateTable()
|
|
|
{
|
|
|
delete d;
|
|
|
}
|
|
|
|
|
|
void KDateTable::initAccels()
|
|
|
{
|
|
|
KAccel* accel = new KAccel(this, "date table accel");
|
|
|
accel->insert(KStdAccel::Next, TQT_TQOBJECT(this), TQT_SLOT(nextMonth()));
|
|
|
accel->insert(KStdAccel::Prior, TQT_TQOBJECT(this), TQT_SLOT(previousMonth()));
|
|
|
accel->insert(KStdAccel::Home, TQT_TQOBJECT(this), TQT_SLOT(beginningOfMonth()));
|
|
|
accel->insert(KStdAccel::End, TQT_TQOBJECT(this), TQT_SLOT(endOfMonth()));
|
|
|
accel->insert(KStdAccel::BeginningOfLine, TQT_TQOBJECT(this), TQT_SLOT(beginningOfWeek()));
|
|
|
accel->insert(KStdAccel::EndOfLine, TQT_TQOBJECT(this), TQT_SLOT(endOfWeek()));
|
|
|
accel->readSettings();
|
|
|
}
|
|
|
|
|
|
int KDateTable::posFromDate( const TQDate &dt )
|
|
|
{
|
|
|
const KCalendarSystem * calendar = KGlobal::locale()->calendar();
|
|
|
const int firstWeekDay = KGlobal::locale()->weekStartDay();
|
|
|
int pos = calendar->day( dt );
|
|
|
int offset = (firstday - firstWeekDay + 7) % 7;
|
|
|
// make sure at least one day of the previous month is visible.
|
|
|
// adjust this <1 if more days should be forced visible:
|
|
|
if ( offset < 1 ) offset += 7;
|
|
|
return pos + offset;
|
|
|
}
|
|
|
|
|
|
TQDate KDateTable::dateFromPos( int pos )
|
|
|
{
|
|
|
TQDate pCellDate;
|
|
|
const KCalendarSystem * calendar = KGlobal::locale()->calendar();
|
|
|
calendar->setYMD(pCellDate, calendar->year(date), calendar->month(date), 1);
|
|
|
|
|
|
int firstWeekDay = KGlobal::locale()->weekStartDay();
|
|
|
int offset = (firstday - firstWeekDay + 7) % 7;
|
|
|
// make sure at least one day of the previous month is visible.
|
|
|
// adjust this <1 if more days should be forced visible:
|
|
|
if ( offset < 1 ) offset += 7;
|
|
|
pCellDate = calendar->addDays( pCellDate, pos - offset );
|
|
|
return pCellDate;
|
|
|
}
|
|
|
|
|
|
void
|
|
|
KDateTable::paintEmptyArea(TQPainter *paint, int, int, int, int)
|
|
|
{
|
|
|
// Erase the unused areas on the right and bottom.
|
|
|
TQRect unusedRight = frameRect();
|
|
|
unusedRight.setLeft(gridSize().width());
|
|
|
|
|
|
TQRect unusedBottom = frameRect();
|
|
|
unusedBottom.setTop(gridSize().height());
|
|
|
|
|
|
paint->eraseRect(unusedRight);
|
|
|
paint->eraseRect(unusedBottom);
|
|
|
}
|
|
|
|
|
|
void
|
|
|
KDateTable::paintCell(TQPainter *painter, int row, int col)
|
|
|
{
|
|
|
const KCalendarSystem * calendar = KGlobal::locale()->calendar();
|
|
|
|
|
|
TQRect rect;
|
|
|
TQString text;
|
|
|
TQPen pen;
|
|
|
int w=cellWidth();
|
|
|
int h=cellHeight();
|
|
|
TQFont font=KGlobalSettings::generalFont();
|
|
|
// -----
|
|
|
|
|
|
if(row == 0)
|
|
|
{ // we are drawing the headline
|
|
|
font.setBold(true);
|
|
|
painter->setFont(font);
|
|
|
bool normalday = true;
|
|
|
int firstWeekDay = KGlobal::locale()->weekStartDay();
|
|
|
int daynum = ( col+firstWeekDay < 8 ) ? col+firstWeekDay :
|
|
|
col+firstWeekDay-7;
|
|
|
if ( daynum == calendar->weekDayOfPray() ||
|
|
|
( daynum == 6 && calendar->calendarName() == "gregorian" ) )
|
|
|
normalday=false;
|
|
|
|
|
|
TQBrush brushInvertTitle(colorGroup().base());
|
|
|
TQColor titleColor(isEnabled()?( KGlobalSettings::activeTitleColor() ):( KGlobalSettings::inactiveTitleColor() ) );
|
|
|
TQColor textColor(isEnabled()?( KGlobalSettings::activeTextColor() ):( KGlobalSettings::inactiveTextColor() ) );
|
|
|
if (!normalday)
|
|
|
{
|
|
|
painter->setPen(textColor);
|
|
|
painter->setBrush(textColor);
|
|
|
painter->drawRect(0, 0, w, h);
|
|
|
painter->setPen(titleColor);
|
|
|
} else {
|
|
|
painter->setPen(titleColor);
|
|
|
painter->setBrush(titleColor);
|
|
|
painter->drawRect(0, 0, w, h);
|
|
|
painter->setPen(textColor);
|
|
|
}
|
|
|
painter->drawText(0, 0, w, h-1, AlignCenter,
|
|
|
calendar->weekDayName(daynum, true), -1, &rect);
|
|
|
painter->setPen(colorGroup().text());
|
|
|
painter->moveTo(0, h-1);
|
|
|
painter->lineTo(w-1, h-1);
|
|
|
// ----- draw the weekday:
|
|
|
} else {
|
|
|
bool paintRect=true;
|
|
|
painter->setFont(font);
|
|
|
int pos=7*(row-1)+col;
|
|
|
|
|
|
TQDate pCellDate = dateFromPos( pos );
|
|
|
// First day of month
|
|
|
text = calendar->dayString(pCellDate, true);
|
|
|
if( calendar->month(pCellDate) != calendar->month(date) )
|
|
|
{ // we are either
|
|
|
// <20> painting a day of the previous month or
|
|
|
// <20> painting a day of the following month
|
|
|
// TODO: don't hardcode gray here! Use a color with less contrast to the background than normal text.
|
|
|
painter->setPen( colorGroup().mid() );
|
|
|
// painter->setPen(gray);
|
|
|
} else { // paint a day of the current month
|
|
|
if ( d->useCustomColors )
|
|
|
{
|
|
|
KDateTablePrivate::DatePaintingMode *mode=d->customPaintingModes[pCellDate.toString()];
|
|
|
if (mode)
|
|
|
{
|
|
|
if (mode->bgMode != NoBgMode)
|
|
|
{
|
|
|
TQBrush oldbrush=painter->brush();
|
|
|
painter->setBrush( mode->bgColor );
|
|
|
switch(mode->bgMode)
|
|
|
{
|
|
|
case(CircleMode) : painter->drawEllipse(0,0,w,h);break;
|
|
|
case(RectangleMode) : painter->drawRect(0,0,w,h);break;
|
|
|
case(NoBgMode) : // Should never be here, but just to get one
|
|
|
// less warning when compiling
|
|
|
default: break;
|
|
|
}
|
|
|
painter->setBrush( oldbrush );
|
|
|
paintRect=false;
|
|
|
}
|
|
|
painter->setPen( mode->fgColor );
|
|
|
} else
|
|
|
painter->setPen(colorGroup().text());
|
|
|
} else //if ( firstWeekDay < 4 ) // <- this doesn' make sense at all!
|
|
|
painter->setPen(colorGroup().text());
|
|
|
}
|
|
|
|
|
|
pen=painter->pen();
|
|
|
int firstWeekDay=KGlobal::locale()->weekStartDay();
|
|
|
int offset=firstday-firstWeekDay;
|
|
|
if(offset<1)
|
|
|
offset+=7;
|
|
|
int d = calendar->day(date);
|
|
|
if( (offset+d) == (pos+1))
|
|
|
{
|
|
|
// draw the currently selected date
|
|
|
if (isEnabled())
|
|
|
{
|
|
|
painter->setPen(colorGroup().highlight());
|
|
|
painter->setBrush(colorGroup().highlight());
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
painter->setPen(colorGroup().text());
|
|
|
painter->setBrush(colorGroup().text());
|
|
|
}
|
|
|
pen=TQPen(colorGroup().highlightedText());
|
|
|
} else {
|
|
|
painter->setBrush(paletteBackgroundColor());
|
|
|
painter->setPen(paletteBackgroundColor());
|
|
|
// painter->setBrush(colorGroup().base());
|
|
|
// painter->setPen(colorGroup().base());
|
|
|
}
|
|
|
|
|
|
if ( pCellDate == TQDate::currentDate() )
|
|
|
{
|
|
|
painter->setPen(colorGroup().text());
|
|
|
}
|
|
|
|
|
|
if ( paintRect ) painter->drawRect(0, 0, w, h);
|
|
|
painter->setPen(pen);
|
|
|
painter->drawText(0, 0, w, h, AlignCenter, text, -1, &rect);
|
|
|
}
|
|
|
if(rect.width()>maxCell.width()) maxCell.setWidth(rect.width());
|
|
|
if(rect.height()>maxCell.height()) maxCell.setHeight(rect.height());
|
|
|
}
|
|
|
|
|
|
void KDateTable::nextMonth()
|
|
|
{
|
|
|
const KCalendarSystem * calendar = KGlobal::locale()->calendar();
|
|
|
setDate(calendar->addMonths( date, 1 ));
|
|
|
}
|
|
|
|
|
|
void KDateTable::previousMonth()
|
|
|
{
|
|
|
const KCalendarSystem * calendar = KGlobal::locale()->calendar();
|
|
|
setDate(calendar->addMonths( date, -1 ));
|
|
|
}
|
|
|
|
|
|
void KDateTable::beginningOfMonth()
|
|
|
{
|
|
|
setDate(TQT_TQDATE_OBJECT(date.addDays(1 - date.day())));
|
|
|
}
|
|
|
|
|
|
void KDateTable::endOfMonth()
|
|
|
{
|
|
|
setDate(TQT_TQDATE_OBJECT(date.addDays(date.daysInMonth() - date.day())));
|
|
|
}
|
|
|
|
|
|
void KDateTable::beginningOfWeek()
|
|
|
{
|
|
|
setDate(TQT_TQDATE_OBJECT(date.addDays(1 - date.dayOfWeek())));
|
|
|
}
|
|
|
|
|
|
void KDateTable::endOfWeek()
|
|
|
{
|
|
|
setDate(TQT_TQDATE_OBJECT(date.addDays(7 - date.dayOfWeek())));
|
|
|
}
|
|
|
|
|
|
void
|
|
|
KDateTable::keyPressEvent( TQKeyEvent *e )
|
|
|
{
|
|
|
switch( e->key() ) {
|
|
|
case Key_Up:
|
|
|
setDate(TQT_TQDATE_OBJECT(date.addDays(-7)));
|
|
|
break;
|
|
|
case Key_Down:
|
|
|
setDate(TQT_TQDATE_OBJECT(date.addDays(7)));
|
|
|
break;
|
|
|
case Key_Left:
|
|
|
setDate(TQT_TQDATE_OBJECT(date.addDays(-1)));
|
|
|
break;
|
|
|
case Key_Right:
|
|
|
setDate(TQT_TQDATE_OBJECT(date.addDays(1)));
|
|
|
break;
|
|
|
case Key_Minus:
|
|
|
setDate(TQT_TQDATE_OBJECT(date.addDays(-1)));
|
|
|
break;
|
|
|
case Key_Plus:
|
|
|
setDate(TQT_TQDATE_OBJECT(date.addDays(1)));
|
|
|
break;
|
|
|
case Key_N:
|
|
|
setDate(TQDate::currentDate());
|
|
|
break;
|
|
|
case Key_Return:
|
|
|
case Key_Enter:
|
|
|
emit tableClicked();
|
|
|
break;
|
|
|
case Key_Control:
|
|
|
case Key_Alt:
|
|
|
case Key_Meta:
|
|
|
case Key_Shift:
|
|
|
// Don't beep for modifiers
|
|
|
break;
|
|
|
default:
|
|
|
if (!e->state()) { // hm
|
|
|
KNotifyClient::beep();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void
|
|
|
KDateTable::viewportResizeEvent(TQResizeEvent * e)
|
|
|
{
|
|
|
TQGridView::viewportResizeEvent(e);
|
|
|
|
|
|
setCellWidth(viewport()->width()/7);
|
|
|
setCellHeight(viewport()->height()/7);
|
|
|
}
|
|
|
|
|
|
void
|
|
|
KDateTable::setFontSize(int size)
|
|
|
{
|
|
|
int count;
|
|
|
TQFontMetrics metrics(fontMetrics());
|
|
|
TQRect rect;
|
|
|
// ----- store rectangles:
|
|
|
fontsize=size;
|
|
|
// ----- find largest day name:
|
|
|
maxCell.setWidth(0);
|
|
|
maxCell.setHeight(0);
|
|
|
for(count=0; count<7; ++count)
|
|
|
{
|
|
|
rect=metrics.boundingRect(KGlobal::locale()->calendar()
|
|
|
->weekDayName(count+1, true));
|
|
|
maxCell.setWidth(QMAX(maxCell.width(), rect.width()));
|
|
|
maxCell.setHeight(QMAX(maxCell.height(), rect.height()));
|
|
|
}
|
|
|
// ----- compare with a real wide number and add some space:
|
|
|
rect=metrics.boundingRect(TQString::fromLatin1("88"));
|
|
|
maxCell.setWidth(QMAX(maxCell.width()+2, rect.width()));
|
|
|
maxCell.setHeight(QMAX(maxCell.height()+4, rect.height()));
|
|
|
}
|
|
|
|
|
|
void
|
|
|
KDateTable::wheelEvent ( TQWheelEvent * e )
|
|
|
{
|
|
|
setDate(TQT_TQDATE_OBJECT(date.addMonths( -(int)(e->delta()/120)) ));
|
|
|
e->accept();
|
|
|
}
|
|
|
|
|
|
void
|
|
|
KDateTable::contentsMousePressEvent(TQMouseEvent *e)
|
|
|
{
|
|
|
|
|
|
if(e->type()!=TQEvent::MouseButtonPress)
|
|
|
{ // the KDatePicker only reacts on mouse press events:
|
|
|
return;
|
|
|
}
|
|
|
if(!isEnabled())
|
|
|
{
|
|
|
KNotifyClient::beep();
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// -----
|
|
|
int row, col, pos, temp;
|
|
|
TQPoint mouseCoord;
|
|
|
// -----
|
|
|
mouseCoord = e->pos();
|
|
|
row=rowAt(mouseCoord.y());
|
|
|
col=columnAt(mouseCoord.x());
|
|
|
if(row<1 || col<0)
|
|
|
{ // the user clicked on the frame of the table
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// Rows and columns are zero indexed. The (row - 1) below is to avoid counting
|
|
|
// the row with the days of the week in the calculation.
|
|
|
|
|
|
// old selected date:
|
|
|
temp = posFromDate( date );
|
|
|
// new position and date
|
|
|
pos = (7 * (row - 1)) + col;
|
|
|
TQDate clickedDate = dateFromPos( pos );
|
|
|
|
|
|
// set the new date. If it is in the previous or next month, the month will
|
|
|
// automatically be changed, no need to do that manually...
|
|
|
setDate( clickedDate );
|
|
|
|
|
|
// call updateCell on the old and new selection. If setDate switched to a different
|
|
|
// month, these cells will be painted twice, but that's no problem.
|
|
|
updateCell( temp/7+1, temp%7 );
|
|
|
updateCell( row, col );
|
|
|
|
|
|
emit tableClicked();
|
|
|
|
|
|
if ( e->button() == Qt::RightButton && d->popupMenuEnabled )
|
|
|
{
|
|
|
KPopupMenu *menu = new KPopupMenu();
|
|
|
menu->insertTitle( KGlobal::locale()->formatDate(clickedDate) );
|
|
|
emit aboutToShowContextMenu( menu, clickedDate );
|
|
|
menu->popup(e->globalPos());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
bool
|
|
|
KDateTable::setDate(const TQDate& date_)
|
|
|
{
|
|
|
bool changed=false;
|
|
|
TQDate temp;
|
|
|
// -----
|
|
|
if(!date_.isValid())
|
|
|
{
|
|
|
kdDebug() << "KDateTable::setDate: refusing to set invalid date." << endl;
|
|
|
return false;
|
|
|
}
|
|
|
if(date!=date_)
|
|
|
{
|
|
|
emit(dateChanged(date, date_));
|
|
|
date=date_;
|
|
|
emit(dateChanged(date));
|
|
|
changed=true;
|
|
|
}
|
|
|
const KCalendarSystem * calendar = KGlobal::locale()->calendar();
|
|
|
|
|
|
calendar->setYMD(temp, calendar->year(date), calendar->month(date), 1);
|
|
|
//temp.setYMD(date.year(), date.month(), 1);
|
|
|
//kdDebug() << "firstDayInWeek: " << temp.toString() << endl;
|
|
|
firstday=temp.dayOfWeek();
|
|
|
numdays=calendar->daysInMonth(date);
|
|
|
|
|
|
temp = calendar->addMonths(temp, -1);
|
|
|
numDaysPrevMonth=calendar->daysInMonth(temp);
|
|
|
if(changed)
|
|
|
{
|
|
|
repaintContents(false);
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
const TQDate&
|
|
|
KDateTable::getDate() const
|
|
|
{
|
|
|
return date;
|
|
|
}
|
|
|
|
|
|
// what are those repaintContents() good for? (pfeiffer)
|
|
|
void KDateTable::focusInEvent( TQFocusEvent *e )
|
|
|
{
|
|
|
// repaintContents(false);
|
|
|
TQGridView::focusInEvent( e );
|
|
|
}
|
|
|
|
|
|
void KDateTable::focusOutEvent( TQFocusEvent *e )
|
|
|
{
|
|
|
// repaintContents(false);
|
|
|
TQGridView::focusOutEvent( e );
|
|
|
}
|
|
|
|
|
|
TQSize
|
|
|
KDateTable::sizeHint() const
|
|
|
{
|
|
|
if(maxCell.height()>0 && maxCell.width()>0)
|
|
|
{
|
|
|
return TQSize(maxCell.width()*numCols()+2*frameWidth(),
|
|
|
(maxCell.height()+2)*numRows()+2*frameWidth());
|
|
|
} else {
|
|
|
kdDebug() << "KDateTable::sizeHint: obscure failure - " << endl;
|
|
|
return TQSize(-1, -1);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void KDateTable::setPopupMenuEnabled( bool enable )
|
|
|
{
|
|
|
d->popupMenuEnabled=enable;
|
|
|
}
|
|
|
|
|
|
bool KDateTable::popupMenuEnabled() const
|
|
|
{
|
|
|
return d->popupMenuEnabled;
|
|
|
}
|
|
|
|
|
|
void KDateTable::setCustomDatePainting(const TQDate &date, const TQColor &fgColor, BackgroundMode bgMode, const TQColor &bgColor)
|
|
|
{
|
|
|
if (!fgColor.isValid())
|
|
|
{
|
|
|
unsetCustomDatePainting( date );
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
KDateTablePrivate::DatePaintingMode *mode=new KDateTablePrivate::DatePaintingMode;
|
|
|
mode->bgMode=bgMode;
|
|
|
mode->fgColor=fgColor;
|
|
|
mode->bgColor=bgColor;
|
|
|
|
|
|
d->customPaintingModes.replace( date.toString(), mode );
|
|
|
d->useCustomColors=true;
|
|
|
update();
|
|
|
}
|
|
|
|
|
|
void KDateTable::unsetCustomDatePainting( const TQDate &date )
|
|
|
{
|
|
|
d->customPaintingModes.remove( date.toString() );
|
|
|
}
|
|
|
|
|
|
KDateInternalWeekSelector::KDateInternalWeekSelector
|
|
|
(TQWidget* parent, const char* name)
|
|
|
: TQLineEdit(parent, name),
|
|
|
val(new TQIntValidator(TQT_TQOBJECT(this))),
|
|
|
result(0)
|
|
|
{
|
|
|
TQFont font;
|
|
|
// -----
|
|
|
font=KGlobalSettings::generalFont();
|
|
|
setFont(font);
|
|
|
setFrameStyle(TQFrame::NoFrame);
|
|
|
setValidator(val);
|
|
|
connect(this, TQT_SIGNAL(returnPressed()), TQT_SLOT(weekEnteredSlot()));
|
|
|
}
|
|
|
|
|
|
void
|
|
|
KDateInternalWeekSelector::weekEnteredSlot()
|
|
|
{
|
|
|
bool ok;
|
|
|
int week;
|
|
|
// ----- check if this is a valid week:
|
|
|
week=text().toInt(&ok);
|
|
|
if(!ok)
|
|
|
{
|
|
|
KNotifyClient::beep();
|
|
|
emit(closeMe(0));
|
|
|
return;
|
|
|
}
|
|
|
result=week;
|
|
|
emit(closeMe(1));
|
|
|
}
|
|
|
|
|
|
int
|
|
|
KDateInternalWeekSelector::getWeek()
|
|
|
{
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
void
|
|
|
KDateInternalWeekSelector::setWeek(int week)
|
|
|
{
|
|
|
TQString temp;
|
|
|
// -----
|
|
|
temp.setNum(week);
|
|
|
setText(temp);
|
|
|
}
|
|
|
|
|
|
void
|
|
|
KDateInternalWeekSelector::setMaxWeek(int max)
|
|
|
{
|
|
|
val->setRange(1, max);
|
|
|
}
|
|
|
|
|
|
// ### CFM To avoid binary incompatibility.
|
|
|
// In future releases, remove this and replace by a QDate
|
|
|
// private member, needed in KDateInternalMonthPicker::paintCell
|
|
|
class KDateInternalMonthPicker::KDateInternalMonthPrivate {
|
|
|
public:
|
|
|
KDateInternalMonthPrivate (int y, int m, int d)
|
|
|
: year(y), month(m), day(d)
|
|
|
{}
|
|
|
int year;
|
|
|
int month;
|
|
|
int day;
|
|
|
};
|
|
|
|
|
|
KDateInternalMonthPicker::~KDateInternalMonthPicker() {
|
|
|
delete d;
|
|
|
}
|
|
|
|
|
|
KDateInternalMonthPicker::KDateInternalMonthPicker
|
|
|
(const TQDate & date, TQWidget* parent, const char* name)
|
|
|
: TQGridView(parent, name),
|
|
|
result(0) // invalid
|
|
|
{
|
|
|
TQRect rect;
|
|
|
TQFont font;
|
|
|
// -----
|
|
|
activeCol = -1;
|
|
|
activeRow = -1;
|
|
|
font=KGlobalSettings::generalFont();
|
|
|
setFont(font);
|
|
|
setHScrollBarMode(AlwaysOff);
|
|
|
setVScrollBarMode(AlwaysOff);
|
|
|
setFrameStyle(TQFrame::NoFrame);
|
|
|
setNumCols(3);
|
|
|
d = new KDateInternalMonthPrivate(date.year(), date.month(), date.day());
|
|
|
// For monthsInYear != 12
|
|
|
setNumRows( (KGlobal::locale()->calendar()->monthsInYear(date) + 2) / 3);
|
|
|
// enable to find drawing failures:
|
|
|
// setTableFlags(Tbl_clipCellPainting);
|
|
|
viewport()->setEraseColor(KGlobalSettings::baseColor()); // for consistency with the datepicker
|
|
|
// ----- find the preferred size
|
|
|
// (this is slow, possibly, but unfortunately it is needed here):
|
|
|
TQFontMetrics metrics(font);
|
|
|
for(int i = 1; ; ++i)
|
|
|
{
|
|
|
TQString str = KGlobal::locale()->calendar()->monthName(i,
|
|
|
KGlobal::locale()->calendar()->year(date), false);
|
|
|
if (str.isNull()) break;
|
|
|
rect=metrics.boundingRect(str);
|
|
|
if(max.width()<rect.width()) max.setWidth(rect.width());
|
|
|
if(max.height()<rect.height()) max.setHeight(rect.height());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
TQSize
|
|
|
KDateInternalMonthPicker::sizeHint() const
|
|
|
{
|
|
|
return TQSize((max.width()+6)*numCols()+2*frameWidth(),
|
|
|
(max.height()+6)*numRows()+2*frameWidth());
|
|
|
}
|
|
|
|
|
|
int
|
|
|
KDateInternalMonthPicker::getResult() const
|
|
|
{
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
void
|
|
|
KDateInternalMonthPicker::setupPainter(TQPainter *p)
|
|
|
{
|
|
|
p->setPen(KGlobalSettings::textColor());
|
|
|
}
|
|
|
|
|
|
void
|
|
|
KDateInternalMonthPicker::viewportResizeEvent(TQResizeEvent*)
|
|
|
{
|
|
|
setCellWidth(width() / numCols());
|
|
|
setCellHeight(height() / numRows());
|
|
|
}
|
|
|
|
|
|
void
|
|
|
KDateInternalMonthPicker::paintCell(TQPainter* painter, int row, int col)
|
|
|
{
|
|
|
int index;
|
|
|
TQString text;
|
|
|
// ----- find the number of the cell:
|
|
|
index=3*row+col+1;
|
|
|
text=KGlobal::locale()->calendar()->monthName(index,
|
|
|
KGlobal::locale()->calendar()->year(TQDate(d->year, d->month,
|
|
|
d->day)), false);
|
|
|
painter->drawText(0, 0, cellWidth(), cellHeight(), AlignCenter, text);
|
|
|
if ( activeCol == col && activeRow == row )
|
|
|
painter->drawRect( 0, 0, cellWidth(), cellHeight() );
|
|
|
}
|
|
|
|
|
|
void
|
|
|
KDateInternalMonthPicker::contentsMousePressEvent(TQMouseEvent *e)
|
|
|
{
|
|
|
if(!isEnabled() || e->button() != Qt::LeftButton)
|
|
|
{
|
|
|
KNotifyClient::beep();
|
|
|
return;
|
|
|
}
|
|
|
// -----
|
|
|
int row, col;
|
|
|
TQPoint mouseCoord;
|
|
|
// -----
|
|
|
mouseCoord = e->pos();
|
|
|
row=rowAt(mouseCoord.y());
|
|
|
col=columnAt(mouseCoord.x());
|
|
|
|
|
|
if(row<0 || col<0)
|
|
|
{ // the user clicked on the frame of the table
|
|
|
activeCol = -1;
|
|
|
activeRow = -1;
|
|
|
} else {
|
|
|
activeCol = col;
|
|
|
activeRow = row;
|
|
|
updateCell( row, col /*, false */ );
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void
|
|
|
KDateInternalMonthPicker::contentsMouseMoveEvent(TQMouseEvent *e)
|
|
|
{
|
|
|
if (e->state() & Qt::LeftButton)
|
|
|
{
|
|
|
int row, col;
|
|
|
TQPoint mouseCoord;
|
|
|
// -----
|
|
|
mouseCoord = e->pos();
|
|
|
row=rowAt(mouseCoord.y());
|
|
|
col=columnAt(mouseCoord.x());
|
|
|
int tmpRow = -1, tmpCol = -1;
|
|
|
if(row<0 || col<0)
|
|
|
{ // the user clicked on the frame of the table
|
|
|
if ( activeCol > -1 )
|
|
|
{
|
|
|
tmpRow = activeRow;
|
|
|
tmpCol = activeCol;
|
|
|
}
|
|
|
activeCol = -1;
|
|
|
activeRow = -1;
|
|
|
} else {
|
|
|
bool differentCell = (activeRow != row || activeCol != col);
|
|
|
if ( activeCol > -1 && differentCell)
|
|
|
{
|
|
|
tmpRow = activeRow;
|
|
|
tmpCol = activeCol;
|
|
|
}
|
|
|
if ( differentCell)
|
|
|
{
|
|
|
activeRow = row;
|
|
|
activeCol = col;
|
|
|
updateCell( row, col /*, false */ ); // mark the new active cell
|
|
|
}
|
|
|
}
|
|
|
if ( tmpRow > -1 ) // repaint the former active cell
|
|
|
updateCell( tmpRow, tmpCol /*, true */ );
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void
|
|
|
KDateInternalMonthPicker::contentsMouseReleaseEvent(TQMouseEvent *e)
|
|
|
{
|
|
|
if(!isEnabled())
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
// -----
|
|
|
int row, col, pos;
|
|
|
TQPoint mouseCoord;
|
|
|
// -----
|
|
|
mouseCoord = e->pos();
|
|
|
row=rowAt(mouseCoord.y());
|
|
|
col=columnAt(mouseCoord.x());
|
|
|
if(row<0 || col<0)
|
|
|
{ // the user clicked on the frame of the table
|
|
|
emit(closeMe(0));
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
pos=3*row+col+1;
|
|
|
result=pos;
|
|
|
emit(closeMe(1));
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
KDateInternalYearSelector::KDateInternalYearSelector
|
|
|
(TQWidget* parent, const char* name)
|
|
|
: TQLineEdit(parent, name),
|
|
|
val(new TQIntValidator(TQT_TQOBJECT(this))),
|
|
|
result(0)
|
|
|
{
|
|
|
TQFont font;
|
|
|
// -----
|
|
|
font=KGlobalSettings::generalFont();
|
|
|
setFont(font);
|
|
|
setFrameStyle(TQFrame::NoFrame);
|
|
|
// we have to respect the limits of TQDate here, I fear:
|
|
|
val->setRange(0, 8000);
|
|
|
setValidator(val);
|
|
|
connect(this, TQT_SIGNAL(returnPressed()), TQT_SLOT(yearEnteredSlot()));
|
|
|
}
|
|
|
|
|
|
void
|
|
|
KDateInternalYearSelector::yearEnteredSlot()
|
|
|
{
|
|
|
bool ok;
|
|
|
int year;
|
|
|
TQDate date;
|
|
|
// ----- check if this is a valid year:
|
|
|
year=text().toInt(&ok);
|
|
|
if(!ok)
|
|
|
{
|
|
|
KNotifyClient::beep();
|
|
|
emit(closeMe(0));
|
|
|
return;
|
|
|
}
|
|
|
//date.setYMD(year, 1, 1);
|
|
|
KGlobal::locale()->calendar()->setYMD(date, year, 1, 1);
|
|
|
if(!date.isValid())
|
|
|
{
|
|
|
KNotifyClient::beep();
|
|
|
emit(closeMe(0));
|
|
|
return;
|
|
|
}
|
|
|
result=year;
|
|
|
emit(closeMe(1));
|
|
|
}
|
|
|
|
|
|
int
|
|
|
KDateInternalYearSelector::getYear()
|
|
|
{
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
void
|
|
|
KDateInternalYearSelector::setYear(int year)
|
|
|
{
|
|
|
TQString temp;
|
|
|
// -----
|
|
|
temp.setNum(year);
|
|
|
setText(temp);
|
|
|
}
|
|
|
|
|
|
class KPopupFrame::KPopupFramePrivate
|
|
|
{
|
|
|
public:
|
|
|
KPopupFramePrivate() : exec(false) {}
|
|
|
|
|
|
bool exec;
|
|
|
};
|
|
|
|
|
|
KPopupFrame::KPopupFrame(TQWidget* parent, const char* name)
|
|
|
: TQFrame(parent, name, (WFlags)WType_Popup),
|
|
|
result(0), // rejected
|
|
|
main(0),
|
|
|
d(new KPopupFramePrivate)
|
|
|
{
|
|
|
setFrameStyle(TQFrame::Box|TQFrame::Raised);
|
|
|
setMidLineWidth(2);
|
|
|
}
|
|
|
|
|
|
KPopupFrame::~KPopupFrame()
|
|
|
{
|
|
|
delete d;
|
|
|
}
|
|
|
|
|
|
void
|
|
|
KPopupFrame::keyPressEvent(TQKeyEvent* e)
|
|
|
{
|
|
|
if(e->key()==Key_Escape)
|
|
|
{
|
|
|
result=0; // rejected
|
|
|
d->exec = false;
|
|
|
tqApp->exit_loop();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void
|
|
|
KPopupFrame::close(int r)
|
|
|
{
|
|
|
result=r;
|
|
|
d->exec = false;
|
|
|
tqApp->exit_loop();
|
|
|
}
|
|
|
|
|
|
void
|
|
|
KPopupFrame::hide()
|
|
|
{
|
|
|
TQFrame::hide();
|
|
|
if (d->exec)
|
|
|
{
|
|
|
d->exec = false;
|
|
|
tqApp->exit_loop();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void
|
|
|
KPopupFrame::setMainWidget(TQWidget* m)
|
|
|
{
|
|
|
main=m;
|
|
|
if(main)
|
|
|
{
|
|
|
resize(main->width()+2*frameWidth(), main->height()+2*frameWidth());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void
|
|
|
KPopupFrame::resizeEvent(TQResizeEvent*)
|
|
|
{
|
|
|
if(main)
|
|
|
{
|
|
|
main->setGeometry(frameWidth(), frameWidth(),
|
|
|
width()-2*frameWidth(), height()-2*frameWidth());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void
|
|
|
KPopupFrame::popup(const TQPoint &pos)
|
|
|
{
|
|
|
// Make sure the whole popup is visible.
|
|
|
TQRect d = KGlobalSettings::desktopGeometry(pos);
|
|
|
|
|
|
int x = pos.x();
|
|
|
int y = pos.y();
|
|
|
int w = width();
|
|
|
int h = height();
|
|
|
if (x+w > d.x()+d.width())
|
|
|
x = d.width() - w;
|
|
|
if (y+h > d.y()+d.height())
|
|
|
y = d.height() - h;
|
|
|
if (x < d.x())
|
|
|
x = 0;
|
|
|
if (y < d.y())
|
|
|
y = 0;
|
|
|
|
|
|
// Pop the thingy up.
|
|
|
move(x, y);
|
|
|
show();
|
|
|
}
|
|
|
|
|
|
int
|
|
|
KPopupFrame::exec(TQPoint pos)
|
|
|
{
|
|
|
popup(pos);
|
|
|
repaint();
|
|
|
d->exec = true;
|
|
|
const TQGuardedPtr<TQObject> that = TQT_TQOBJECT(this);
|
|
|
tqApp->enter_loop();
|
|
|
if ( !that )
|
|
|
return TQDialog::Rejected;
|
|
|
hide();
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
int
|
|
|
KPopupFrame::exec(int x, int y)
|
|
|
{
|
|
|
return exec(TQPoint(x, y));
|
|
|
}
|
|
|
|
|
|
void KPopupFrame::virtual_hook( int, void* )
|
|
|
{ /*BASE::virtual_hook( id, data );*/ }
|
|
|
|
|
|
void KDateTable::virtual_hook( int, void* )
|
|
|
{ /*BASE::virtual_hook( id, data );*/ }
|
|
|
|
|
|
#include "kdatetbl.moc"
|