/* This file is part of the KDE project Copyright (C) 1997 Tim D. Gilman (tdgilman@best.org) (C) 1998-2001 Mirko Boehm (mirko@kde.org) (C) 2004-2006 Dag Andersen <danders@get2net.dk> 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. */ #include "kptdatetable.h" #include "kptmap.h" #include <tdeapplication.h> #include <knotifyclient.h> #include <kcalendarsystem.h> #include <tqdatetime.h> #include <tqstring.h> #include <tqpen.h> #include <tqpainter.h> #include <tqdialog.h> #include <assert.h> #include <tqlayout.h> #include <tqvaluelist.h> #include <tdeglobalsettings.h> #include <kdebug.h> namespace KPlato { DateValidator::DateValidator(TQWidget* parent, const char* name) : TQValidator(TQT_TQOBJECT(parent), name) { } TQValidator::State DateValidator::validate(TQString& text, int&) const { TQDate temp; // ----- everything is tested in date(): return date(text, temp); } TQValidator::State DateValidator::date(const TQString& text, TQDate& d) const { TQDate tmp = TDEGlobal::locale()->readDate(text); if (!tmp.isNull()) { d = tmp; return Acceptable; } else return Valid; } void DateValidator::fixup( TQString& ) const { } DateTable::DateTable(TQWidget *parent, TQDate date_, const char* name, WFlags f) : TQGridView(parent, name, f), m_enabled(true) { //kdDebug()<<k_funcinfo<<endl; m_dateStartCol = 1; m_selectedDates.clear(); m_selectedWeekdays.clear(); TQPair<int, int> p(0,0); m_weeks.fill(p, 7); setFontSize(10); if(!date_.isValid()) { kdError() <<k_funcinfo<<"Given date is invalid, using current date." << endl; date_=TQDate::currentDate(); } setFocusPolicy( TQ_StrongFocus ); setNumCols(7+m_dateStartCol); // 7 days a week + maybe 1 for weeknumbers setNumRows(7); // 6 weeks max + headline setHScrollBarMode(AlwaysOff); setVScrollBarMode(AlwaysOff); viewport()->setEraseColor(TDEGlobalSettings::baseColor()); setDate(date_); // this initializes firstday, numdays, numDaysPrevMonth colorBackgroundHoliday = TQColor(0, 245, 255, TQColor::Hsv); //colorBackgroundHoliday = colorBackgroundHoliday.light(); colorBackgroundWorkday = TQColor(208, 230, 240, TQColor::Hsv);; //colorBackgroundWorkday = colorBackgroundWorkday.light(); colorTextHoliday = black; colorTextWorkday = black; colorLine = black; backgroundSelectColor = TDEGlobalSettings::highlightColor(); penSelectColor=TDEGlobalSettings::baseColor(); } void DateTable::paintWeekday(TQPainter *painter, int col) { TQRect rect; int w=cellWidth(); int h=cellHeight(); TQFont font = TDEGlobalSettings::generalFont(); font.setBold(true); if (!m_enabled) font.setItalic(true); painter->setFont(font); int day = weekday(col); //kdDebug()<<k_funcinfo<<" col="<<col<<" day="<<day<<" name="<<daystr<<endl; painter->setBrush(TDEGlobalSettings::baseColor()); painter->setPen(TDEGlobalSettings::baseColor()); painter->drawRect(0, 0, w, h); painter->setPen(TDEGlobalSettings::textColor()); if (m_markedWeekdays.state(day) == Map::Working) { painter->setPen(colorBackgroundWorkday); painter->setBrush(colorBackgroundWorkday); painter->drawRect(0, 0, w, h); painter->setPen(colorTextWorkday); } else if (m_markedWeekdays.state(day) == Map::NonWorking) { painter->setPen(colorBackgroundHoliday); painter->setBrush(colorBackgroundHoliday); painter->drawRect(0, 0, w, h); painter->setPen(colorTextHoliday); } if (m_selectedWeekdays.contains(day)) { painter->setPen(backgroundSelectColor); painter->setBrush(backgroundSelectColor); painter->drawRect(2, 2, w-4, h-4); painter->setPen(penSelectColor); } painter->drawText(0, 0, w, h-1, AlignCenter, TDEGlobal::locale()->calendar()->weekDayName(day, true), -1, &rect); painter->setPen(colorLine); painter->moveTo(0, h-1); painter->lineTo(w-1, h-1); if(rect.width()>maxCell.width()) maxCell.setWidth(rect.width()); if(rect.height()>maxCell.height()) maxCell.setHeight(rect.height()); //kdDebug()<<k_funcinfo<<"headline: row,col=("<<row<<","<<col<<")"<<" day="<<daystr<<endl; } void DateTable::paintWeekNumber(TQPainter *painter, int row) { TQRect rect; int w=cellWidth(); int h=cellHeight(); TQFont font=TDEGlobalSettings::generalFont(); font.setBold(true); if (!m_enabled) font.setItalic(true); painter->setFont(font); painter->setBrush(TDEGlobalSettings::baseColor()); painter->setPen(TDEGlobalSettings::baseColor()); painter->drawRect(0, 0, w, h); painter->setPen(TDEGlobalSettings::textColor()); painter->drawText(0, 0, w, h-1, AlignCenter, TQString("%1").arg(m_weeks[row].first), -1, &rect); painter->setPen(colorLine); painter->moveTo(w-1, 0); painter->lineTo(w-1, h-1); if(rect.width()>maxCell.width()) maxCell.setWidth(rect.width()); if(rect.height()>maxCell.height()) maxCell.setHeight(rect.height()); } void DateTable::paintDay(TQPainter *painter, int row, int col) { //kdDebug()<<k_funcinfo<<"row,col=("<<row<<","<<col<<")"<<" num col="<<numCols()<<endl; TQRect rect; int w=cellWidth(); int h=cellHeight(); TQFont font=TDEGlobalSettings::generalFont(); font.setPointSize(fontsize); if (!m_enabled) font.setItalic(true); painter->setFont(font); TQDate d = getDate(position(row, col)); painter->setBrush(TDEGlobalSettings::baseColor()); painter->setPen(TDEGlobalSettings::baseColor()); painter->drawRect(0, 0, w, h); // First paint the dates background if (m_markedDates.state(d) == Map::NonWorking) { //kdDebug()<<k_funcinfo<<"Marked date: "<<d<<" row,col=("<<row<<","<<col<<")=NonWorking"<<endl; painter->setPen(colorBackgroundHoliday); painter->setBrush(colorBackgroundHoliday); painter->drawRect(0, 0, w, h); } else if (m_markedDates.state(d) == Map::Working) { //kdDebug()<<k_funcinfo<<"Marked date: "<<d<<" row,col=("<<row<<","<<col<<")=Working"<<endl; painter->setPen(colorBackgroundWorkday); painter->setBrush(colorBackgroundWorkday); painter->drawRect(0, 0, w, h); } if(m_selectedDates.contains(d)) { //kdDebug()<<k_funcinfo<<"Selected: "<<d<<" row,col=("<<row<<","<<col<<")"<<endl; painter->setPen(backgroundSelectColor); painter->setBrush(backgroundSelectColor); painter->drawRect(2, 2, w-4, h-4); } // If weeks or weekdays are selected/marked we draw lines around the date TQPen pen = painter->pen(); if (m_markedWeekdays.state(weekday(col)) == Map::Working) { //kdDebug()<<k_funcinfo<<"Marked weekday: row,dayCol=("<<row<<","<<dayCol<<")=Working"<<endl; pen.setColor(colorBackgroundWorkday); painter->setPen(pen); painter->moveTo(0, 0); painter->lineTo(0, h-1); painter->moveTo(w-1, 0); painter->lineTo(w-1, h-1); } // then paint square if current date if (d == TQDate::currentDate()) { painter->setPen(colorLine); painter->drawRect(1, 1, w-2, h-2); } // and now the day number d.month() == date.month() ? painter->setPen(TDEGlobalSettings::textColor()) : painter->setPen(gray); painter->drawText(0, 0, w, h, AlignCenter, TQString().setNum(d.day()), -1, &rect); if(rect.width()>maxCell.width()) maxCell.setWidth(rect.width()); if(rect.height()>maxCell.height()) maxCell.setHeight(rect.height()); } void DateTable::paintCell(TQPainter *painter, int row, int col) { //kdDebug()<<k_funcinfo<<"row,col=("<<row<<","<<col<<")"<<"enabled="<<m_enabled<<endl; if (row == 0 && col == 0) { painter->save(); int w=cellWidth(); int h=cellHeight(); painter->setPen(colorLine); painter->setBrush(TDEGlobalSettings::baseColor()); painter->moveTo(w-1, 0); painter->lineTo(w-1, h-1); painter->lineTo(0, h-1); painter->restore(); return; } painter->save(); if(row==0) { // we are drawing the weekdays paintWeekday(painter, col); } else if (col == 0) { // draw week numbers paintWeekNumber(painter, row); } else { // draw the day paintDay(painter, row, col); } painter->restore(); } //FIXME void DateTable::keyPressEvent( TQKeyEvent *e ) { if (!m_enabled) return; if ( e->key() == TQt::Key_Prior ) { setDate(date.addMonths(-1)); return; } if ( e->key() == TQt::Key_Next ) { setDate(date.addMonths(1)); return; } if ( e->key() == TQt::Key_Up ) { if ( date.day() > 7 ) { setDate(date.addDays(-7)); return; } } if ( e->key() == TQt::Key_Down ) { if ( date.day() <= date.daysInMonth()-7 ) { setDate(date.addDays(7)); return; } } if ( e->key() == TQt::Key_Left ) { if ( date.day() > 1 ) { setDate(date.addDays(-1)); return; } } if ( e->key() == TQt::Key_Right ) { if ( date.day() < date.daysInMonth() ) { setDate(date.addDays(1)); return; } } if ( e->key() == TQt::Key_Minus ) { setDate(date.addDays(-1)); return; } if ( e->key() == TQt::Key_Plus ) { setDate(date.addDays(1)); return; } if ( e->key() == TQt::Key_N ) { setDate(TQDate::currentDate()); return; } if ( e->key() == TQt::Key_Control ) { return; } if ( e->key() == TQt::Key_Shift ) { return; } KNotifyClient::beep(); } void DateTable::viewportResizeEvent(TQResizeEvent * e) { TQGridView::viewportResizeEvent(e); setCellWidth(viewport()->width()/numCols()); setCellHeight(viewport()->height()/numRows()); } void DateTable::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(TDEGlobal::locale()->calendar()->weekDayName(count+1, true)); maxCell.setWidth(TQMAX(maxCell.width(), rect.width())); maxCell.setHeight(TQMAX(maxCell.height(), rect.height())); } // ----- compare with a real wide number and add some space: rect=metrics.boundingRect(TQString::fromLatin1("88")); maxCell.setWidth(TQMAX(maxCell.width()+2, rect.width())); maxCell.setHeight(TQMAX(maxCell.height()+4, rect.height())); } //FIXME void DateTable::wheelEvent ( TQWheelEvent * e ) { setDate(date.addMonths( -(int)(e->delta()/120)) ); e->accept(); } void DateTable::contentsMousePressEvent(TQMouseEvent *e) { if (!m_enabled) return; //kdDebug()<<k_funcinfo<<endl; if(e->type()!=TQEvent::MouseButtonPress) { return; } TQPoint mouseCoord = e->pos(); int row=rowAt(mouseCoord.y()); int col=columnAt(mouseCoord.x()); if (row == 0 && col == 0) { // user clicked on (unused) upper left square updateSelectedCells(); m_selectedWeekdays.clear(); m_selectedDates.clear(); repaintContents(false); emit selectionCleared(); return; } if (col == 0) { // user clicked on week numbers updateSelectedCells(); m_selectedWeekdays.clear(); m_selectedDates.clear(); updateSelectedCells(); repaintContents(false); return; } if (row==0 && col>0) { // the user clicked on weekdays updateSelectedCells(); m_selectedDates.clear(); int day = weekday(col); if (e->state() & ShiftButton) { // select all days between this and the furthest away selected day, // check first downside - then upside, clear all others bool select = false; for(int i=m_dateStartCol; i < col; ++i) { //kdDebug()<<"Down["<<i<<"]: col="<<col<<" day="<<day<<" column(i)="<<column(i)<<endl; if (m_selectedWeekdays.contains(weekday(i))) { select = true; // we have hit a selected day; select the rest } else if (select) { m_selectedWeekdays.toggle(weekday(i)); // select } } bool selected = select; select = false; for(int i=7; i > col; --i) { //kdDebug()<<"Up["<<i<<"]: col="<<col<<" day="<<day<<" column(i)="<<column(i)<<endl; if (m_selectedWeekdays.contains(weekday(i))) { if (selected) m_selectedWeekdays.toggle(weekday(i)); // deselect else select = true; } else if (select) { m_selectedWeekdays.toggle(weekday(i)); // select } } if (!m_selectedWeekdays.contains(day)) { m_selectedWeekdays.toggle(day); // always select } } else if (e->state() & ControlButton) { // toggle select this date m_selectedWeekdays.toggle(day); } else { // toggle select this, clear all others m_selectedWeekdays.toggleClear(day); } updateSelectedCells(); repaintContents(false); if (m_enabled) { //kdDebug()<<k_funcinfo<<"emit weekdaySelected("<<day<<")"<<endl; emit weekdaySelected(day); // day= 1..7 } return; } if (contentsMousePressEvent_internal(e)) { // Date hit, m_selectedWeekdays.clear(); if (e->state() & ShiftButton) { // find first&last date TQDate first; TQDate last; DateMap::ConstIterator it; for (it = m_selectedDates.constBegin(); it != m_selectedDates.constEnd(); ++it) { //kdDebug()<<k_funcinfo<<it.key()<<endl; TQDate d = TQDate::fromString(it.key(), Qt::ISODate); if (!d.isValid()) continue; if (!first.isValid() || first > d) first = d; if (!last.isValid() || last < d) last = d; } // select between anchor and pressed date inclusive m_selectedDates.clear(); if (first.isValid() && last.isValid()) { TQDate anchor = first < date ? first : last; int i = anchor > date ? -1 : 1; while (anchor != date) { //kdDebug()<<k_funcinfo<<anchor.toString(Qt::ISODate)<<endl; m_selectedDates.toggle(anchor); anchor = anchor.addDays(i); } } m_selectedDates.toggle(date); } else if (e->state() & ControlButton) { // toggle select this date m_selectedDates.toggle(date); //kdDebug()<<k_funcinfo<<"toggle date: "<<date.toString()<<" state="<<m_selectedDates.state(date)<<endl; } else { // Select this, clear all others m_selectedDates.clear(); m_selectedDates.toggleClear(date); //kdDebug()<<k_funcinfo<<"toggleClear date: "<<date.toString()<<" state="<<m_selectedDates.state(date)<<endl; } } repaintContents(false); } bool DateTable::contentsMousePressEvent_internal(TQMouseEvent *e) { TQPoint mouseCoord = e->pos(); int row=rowAt(mouseCoord.y()); int col=columnAt(mouseCoord.x()); if(row<1 || col<0) { // the user clicked on the frame of the table return false; } //kdDebug()<<k_funcinfo<<"pos["<<row<<","<<col<<"]="<<position(row,col)<<" firstday="<<firstday<<endl; selectDate(getDate(position(row, col))); return true; } bool DateTable::selectDate(const TQDate& date_) { //kdDebug()<<k_funcinfo<<"date="<<date_.toString()<<endl; bool changed=false; TQDate temp; // ----- if(!date_.isValid()) { return false; } if(date!=date_) { date=date_; changed=true; } temp.setYMD(date.year(), date.month(), 1); firstday=column(TDEGlobal::locale()->calendar()->dayOfWeek(temp)); if(firstday==1) firstday=8; // Reserve row 1 for previous month numdays=date.daysInMonth(); if(date.month()==1) { // set to december of previous year temp.setYMD(date.year()-1, 12, 1); setWeekNumbers(TQDate(date.year()-1, 12, 31)); } else { // set to previous month temp.setYMD(date.year(), date.month()-1, 1); TQDate d(date.year(), date.month()-1,1); setWeekNumbers(d.addDays(d.daysInMonth()-1)); } numDaysPrevMonth=temp.daysInMonth(); if(changed) { repaintContents(false); } if (m_enabled) emit(dateChanged(date)); return true; } bool DateTable::setDate(const TQDate& date_, bool repaint) { //kdDebug()<<k_funcinfo<<"date="<<date_.toString()<<endl; bool changed=false; TQDate temp; // ----- if(!date_.isValid()) { //kdDebug() << "DateTable::setDate: refusing to set invalid date." << endl; return false; } if(date!=date_) { date=date_; changed=true; } //m_selectedDates.clear(); temp.setYMD(date.year(), date.month(), 1); firstday=column(TDEGlobal::locale()->calendar()->dayOfWeek(temp)); if(firstday==1) firstday=8; //kdDebug()<<k_funcinfo<<"date="<<temp<<"day="<<(TDEGlobal::locale()->calendar()->dayOfWeek(temp))<<" firstday="<<firstday<<endl; numdays=date.daysInMonth(); if(date.month()==1) { // set to december of previous year temp.setYMD(date.year()-1, 12, 1); setWeekNumbers(TQDate(date.year()-1, 12, 31)); } else { // set to previous month temp.setYMD(date.year(), date.month()-1, 1); TQDate d(date.year(), date.month()-1,1); setWeekNumbers(d.addDays(d.daysInMonth()-1)); } /* if (m_selectedWeekdays.isEmpty() && !m_selectedDates.isEmpty() && !m_selectedDates.contains(date)) { //kdDebug()<<k_funcinfo<<"date inserted"<<endl; m_selectedDates.insert(date); }*/ numDaysPrevMonth=temp.daysInMonth(); if(changed && repaint) { repaintContents(false); } if (m_enabled) emit(dateChanged(date)); return true; } const TQDate& DateTable::getDate() const { return date; } void DateTable::focusInEvent( TQFocusEvent *e ) { TQGridView::focusInEvent( e ); } void DateTable::focusOutEvent( TQFocusEvent *e ) { TQGridView::focusOutEvent( e ); } TQSize DateTable::sizeHint() const { if(maxCell.height()>0 && maxCell.width()>0) { return TQSize(maxCell.width()*numCols()+2*frameWidth(), (maxCell.height()+2)*numRows()+2*frameWidth()); } else { //kdDebug() << "DateTable::sizeHint: obscure failure - " << endl; return TQSize(-1, -1); } } void DateTable::setWeekNumbers(TQDate date) { if (!date.isValid()) { kdError()<<k_funcinfo<<"Invalid date"<<endl; } TQDate d(date); for (int i = 1; i < 7; ++i) { m_weeks[i].first = d.weekNumber(&(m_weeks[i].second)); //kdDebug()<<k_funcinfo<<"date="<<d.toString()<<" week=("<<m_weeks[i].first<<","<<m_weeks[i].second<<")"<<endl; d = d.addDays(7); } } void DateTable::updateCells() { //kdDebug()<<k_funcinfo<<endl; for (int row=0; row < numRows(); ++row) { for (int col=0; col < numCols(); ++col) { updateCell(row, col); } } } void DateTable::updateSelectedCells() { //kdDebug()<<k_funcinfo<<endl; TQDate dt(date.year(), date.month(), 1); dt = dt.addDays(-firstday); for (int pos=0; pos < 42; ++pos) { if (m_selectedDates.contains(dt.addDays(pos)) || m_selectedWeekdays.contains(pos%7+1)) { updateCell(pos/7+1, pos%7+1); //kdDebug()<<k_funcinfo<<" update cell ("<<pos/7+1<<","<<pos%7+1<<") date="<<dt.addDays(pos).toString()<<endl; } } } void DateTable::updateMarkedCells() { TQDate dt(date.year(), date.month(), 1); dt = dt.addDays(-firstday); for (int pos=0; pos < 42; ++pos) { if (m_markedDates.contains(dt.addDays(pos)) || m_markedWeekdays.contains(pos%7+1)) { updateCell(pos/7+1, pos%7+1); //kdDebug()<<k_funcinfo<<" update cell ("<<pos/7+1<<","<<pos%7+1<<") date="<<dt.addDays(pos).toString()<<endl; } } } void DateTable::setMarkedWeekdays(const IntMap days) { updateMarkedCells(); m_markedWeekdays.clear(); m_markedWeekdays = days; updateMarkedCells(); repaintContents(false); } bool DateTable::weekdayMarked(int day) { return m_markedWeekdays.contains(day); } bool DateTable::dateMarked(TQDate date) { return m_markedDates[date.toString()]; } TQDate DateTable::getDate(int pos) const { return TQDate(date.year(), date.month(), 1).addDays(pos-firstday); } int DateTable::weekday(int col) const { int day = col - m_dateStartCol + TDEGlobal::locale()->weekStartDay(); if (day > 7) day %= 7; //kdDebug()<<k_funcinfo<<"col="<<col<<" day="<<day<<" StartCol="<<m_dateStartCol<<" weekStartDay="<<TDEGlobal::locale()->weekStartDay()<<endl; return day; } int DateTable::column(int weekday) const { int col = weekday - TDEGlobal::locale()->weekStartDay(); if (col < 0) col += 7; //kdDebug()<<k_funcinfo<<"col="<<col<<" day="<<col<<" StartCol="<<m_dateStartCol<<" weekStartDay="<<TDEGlobal::locale()->weekStartDay()<<endl; return col + m_dateStartCol; } void DateTable::clear() { clearSelection(); m_markedDates.clear(); m_markedWeekdays.clear(); repaintContents(false); } void DateTable::clearSelection() { m_selectedDates.clear(); m_selectedWeekdays.clear(); repaintContents(false); } void DateTable::setEnabled(bool yes) { if (m_enabled == yes) return; m_enabled=yes; updateCells(); } void DateTable::markSelected(int state) { if (!m_selectedDates.isEmpty()) { DateMap::iterator it; for(it = m_selectedDates.begin(); it != m_selectedDates.end(); ++it) { m_markedDates.insert(it.key(), state); //kdDebug()<<k_funcinfo<<"marked date: "<<it.key()<<"="<<state<<endl; } } else if (!m_selectedWeekdays.isEmpty()) { IntMap::iterator it; for(it = m_selectedWeekdays.begin(); it != m_selectedWeekdays.end(); ++it) { m_markedWeekdays.insert(it.key(), state); //kdDebug()<<k_funcinfo<<"marked weekday: "<<it.key()<<"="<<state<<endl; } } updateSelectedCells(); repaintContents(false); } DateInternalWeekSelector::DateInternalWeekSelector (int fontsize, TQWidget* parent, const char* name) : TQLineEdit(parent, name), val(new TQIntValidator(TQT_TQOBJECT(this))), result(0) { TQFont font; // ----- font=TDEGlobalSettings::generalFont(); font.setPointSize(fontsize); setFont(font); setFrameStyle(TQFrame::NoFrame); val->setRange(1, 53); setValidator(val); connect(this, TQT_SIGNAL(returnPressed()), TQT_SLOT(weekEnteredSlot())); } void DateInternalWeekSelector::weekEnteredSlot() { bool ok; int week; // ----- check if this is a valid week: week=text().toInt(&ok); if(!ok) { KNotifyClient::beep(); return; } result=week; emit(closeMe(1)); } int DateInternalWeekSelector::getWeek() const { return result; } void DateInternalWeekSelector::setWeek(int week) { TQString temp; // ----- temp.setNum(week); setText(temp); } DateInternalMonthPicker::DateInternalMonthPicker (int fontsize, TQWidget* parent, const char* name) : TQGridView(parent, name), result(0) // invalid { TQRect rect; TQFont font; // ----- activeCol = -1; activeRow = -1; font=TDEGlobalSettings::generalFont(); font.setPointSize(fontsize); setFont(font); setHScrollBarMode(AlwaysOff); setVScrollBarMode(AlwaysOff); setFrameStyle(TQFrame::NoFrame); setNumRows(4); setNumCols(3); // enable to find drawing failures: // setTableFlags(Tbl_clipCellPainting); viewport()->setEraseColor(TDEGlobalSettings::baseColor()); // for consistency with the datepicker // ----- find the preferred size // (this is slow, possibly, but unfortunatly it is needed here): TQFontMetrics metrics(font); for(int i=1; i <= 12; ++i) { rect=metrics.boundingRect(TDEGlobal::locale()->calendar()->monthName(i, false)); if(max.width()<rect.width()) max.setWidth(rect.width()); if(max.height()<rect.height()) max.setHeight(rect.height()); } } TQSize DateInternalMonthPicker::sizeHint() const { return TQSize((max.width()+6)*numCols()+2*frameWidth(), (max.height()+6)*numRows()+2*frameWidth()); } int DateInternalMonthPicker::getResult() const { return result; } void DateInternalMonthPicker::setupPainter(TQPainter *p) { p->setPen(TDEGlobalSettings::textColor()); } void DateInternalMonthPicker::viewportResizeEvent(TQResizeEvent*) { setCellWidth(width()/3); setCellHeight(height()/4); } void DateInternalMonthPicker::paintCell(TQPainter* painter, int row, int col) { int index; TQString text; // ----- find the number of the cell: index=3*row+col+1; text=TDEGlobal::locale()->calendar()->monthName(index, false); painter->drawText(0, 0, cellWidth(), cellHeight(), AlignCenter, text); if ( activeCol == col && activeRow == row ) painter->drawRect( 0, 0, cellWidth(), cellHeight() ); } void DateInternalMonthPicker::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 DateInternalMonthPicker::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 DateInternalMonthPicker::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)); } pos=3*row+col+1; result=pos; emit(closeMe(1)); } DateInternalYearSelector::DateInternalYearSelector (int fontsize, TQWidget* parent, const char* name) : TQLineEdit(parent, name), val(new TQIntValidator(TQT_TQOBJECT(this))), result(0) { TQFont font; // ----- font=TDEGlobalSettings::generalFont(); font.setPointSize(fontsize); 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 DateInternalYearSelector::yearEnteredSlot() { bool ok; int year; TQDate date; // ----- check if this is a valid year: year=text().toInt(&ok); if(!ok) { KNotifyClient::beep(); return; } date.setYMD(year, 1, 1); if(!date.isValid()) { KNotifyClient::beep(); return; } result=year; emit(closeMe(1)); } int DateInternalYearSelector::getYear() const { return result; } void DateInternalYearSelector::setYear(int year) { TQString temp; // ----- temp.setNum(year); setText(temp); } PopupFrame::PopupFrame(TQWidget* parent, const char* name) : TQFrame(parent, name, WType_Popup), result(0), // rejected main(0) { setFrameStyle(TQFrame::Box|TQFrame::Raised); setMidLineWidth(2); } void PopupFrame::keyPressEvent(TQKeyEvent* e) { if(e->key()==Key_Escape) { result=0; // rejected tqApp->exit_loop(); } } void PopupFrame::close(int r) { result=r; tqApp->exit_loop(); } void PopupFrame::setMainWidget(TQWidget* m) { main=m; if(main!=0) { resize(main->width()+2*frameWidth(), main->height()+2*frameWidth()); } } void PopupFrame::resizeEvent(TQResizeEvent*) { if(main!=0) { main->setGeometry(frameWidth(), frameWidth(), width()-2*frameWidth(), height()-2*frameWidth()); } } void PopupFrame::popup(const TQPoint &pos) { // Make sure the whole popup is visible. TQRect d = TQApplication::desktop()->screenGeometry(TQApplication::desktop()->screenNumber(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 PopupFrame::exec(TQPoint pos) { popup(pos); repaint(); tqApp->enter_loop(); hide(); return result; } int PopupFrame::exec(int x, int y) { return exec(TQPoint(x, y)); } void PopupFrame::virtual_hook( int, void* ) { /*BASE::virtual_hook( id, data );*/ } void DateTable::virtual_hook( int, void* ) { /*BASE::virtual_hook( id, data );*/ } } //KPlato namespace #include "kptdatetable.moc"