/*************************************************************************** kmymoneycalendar.cpp - description ------------------- begin : Wed Jul 2 2003 copyright : (C) 2000-2003 by Michael Edwardes email : mte@users.sourceforge.net Javier Campos Morales Felix Rodriguez John C Thomas Baumgart Kevin Tambascio ***************************************************************************/ /*************************************************************************** * Contains code from KDatePicker in tdelibs-3.1.2. * Original license message: * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ****************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifdef HAVE_CONFIG_H #include #endif // ---------------------------------------------------------------------------- // TQt Includes #include #include #include #include #include #include #include #include #include #include #include // ---------------------------------------------------------------------------- // TDE Includes #include #include #include #include #include #include #include #include #include // for maximum re-use #include #if KDE_IS_VERSION(3,2,0) #include #endif // ---------------------------------------------------------------------------- // Project Includes #include "kmymoneycalendar.h" #include "kmymoneydatetbl.h" class kMyMoneyCalendar::kMyMoneyCalendarPrivate { public: kMyMoneyCalendarPrivate() : closeButton(0L), selectWeek(0L), userButton1(0), userButton2(0) {} TQToolButton *closeButton; TQToolButton *selectWeek; TQPushButton *userButton1; TQPushButton *userButton2; }; kMyMoneyCalendar::kMyMoneyCalendar(TQWidget *parent, const char *name ) : TQFrame(parent,name), table(0), d(new kMyMoneyCalendarPrivate) { } kMyMoneyCalendar::~kMyMoneyCalendar() { delete d; } void kMyMoneyCalendar::init( const TQDate &dt ) { styleControl = new TQPushButton(i18n("Select Style"), this); yearForward = new TQToolButton(this); yearBackward = new TQToolButton(this); monthForward = new TQToolButton(this); monthBackward = new TQToolButton(this); selectMonth = new TQToolButton(this); selectYear = new TQToolButton(this); line = new KLineEdit(this); val = new KDateValidator(this); fontsize = 10; d->selectWeek = new TQToolButton( this ); // TDEIconLoader *kiconloader = TDEGlobal::iconLoader(); TDEPopupMenu* tdepopupmenuNew = new TDEPopupMenu(this); tdepopupmenuNew->insertItem(i18n("Week"), this, TQ_SLOT(slotSetStyleWeekly())); tdepopupmenuNew->insertItem(i18n("Month"), this, TQ_SLOT(slotSetStyleMonthly())); /* tdepopupmenuNew->insertItem(i18n("3 Months"), this, TQ_SLOT(slotSetStyleQuarterly())); */ styleControl->setPopup(tdepopupmenuNew); TQToolTip::add(styleControl, i18n("Choose Style")); TQToolTip::add(yearForward, i18n("Next year")); TQToolTip::add(yearBackward, i18n("Previous year")); TQToolTip::add(monthForward, i18n("Next month")); TQToolTip::add(monthBackward, i18n("Previous month")); TQToolTip::add(d->selectWeek, i18n("Select a week")); TQToolTip::add(selectMonth, i18n("Select a month")); TQToolTip::add(selectYear, i18n("Select a year")); // ----- setFontSize(10); line->setValidator(val); line->installEventFilter( this ); yearForward->setPixmap(BarIcon(TQString::fromLatin1("2rightarrow"))); yearBackward->setPixmap(BarIcon(TQString::fromLatin1("2leftarrow"))); monthForward->setPixmap(BarIcon(TQString::fromLatin1("1rightarrow"))); monthBackward->setPixmap(BarIcon(TQString::fromLatin1("1leftarrow"))); setDate(dt); // set button texts connect(table, TQ_SIGNAL(dateChanged(TQDate)), TQ_SLOT(dateChangedSlot(TQDate))); connect(table, TQ_SIGNAL(tableClicked()), TQ_SLOT(tableClickedSlot())); connect(monthForward, TQ_SIGNAL(clicked()), TQ_SLOT(monthForwardClicked())); connect(monthBackward, TQ_SIGNAL(clicked()), TQ_SLOT(monthBackwardClicked())); connect(yearForward, TQ_SIGNAL(clicked()), TQ_SLOT(yearForwardClicked())); connect(yearBackward, TQ_SIGNAL(clicked()), TQ_SLOT(yearBackwardClicked())); connect(d->selectWeek, TQ_SIGNAL(clicked()), TQ_SLOT(selectWeekClicked())); connect(selectMonth, TQ_SIGNAL(clicked()), TQ_SLOT(selectMonthClicked())); connect(selectYear, TQ_SIGNAL(clicked()), TQ_SLOT(selectYearClicked())); connect(line, TQ_SIGNAL(returnPressed()), TQ_SLOT(lineEnterPressed())); if (table) table->setFocus(); } bool kMyMoneyCalendar::eventFilter(TQObject *o, TQEvent *e ) { if ( e->type() == TQEvent::KeyPress ) { TQKeyEvent *k = (TQKeyEvent *)e; if ( (k->key() == TQt::Key_Prior) || (k->key() == TQt::Key_Next) || (k->key() == TQt::Key_Up) || (k->key() == TQt::Key_Down) ) { TQApplication::sendEvent( table, e ); table->setFocus(); return TRUE; // eat event } } return TQFrame::eventFilter( o, e ); } void kMyMoneyCalendar::resizeEvent(TQResizeEvent*) { TQWidget *buttons[] = { styleControl, d->userButton1, d->userButton2, yearBackward, monthBackward, selectMonth, selectYear, monthForward, yearForward, d->closeButton }; const int NoOfButtons=sizeof(buttons)/sizeof(buttons[0]); TQSize sizes[NoOfButtons]; int buttonHeight=0; int count; int w; int x=0; // ----- calculate button row height: for(count=0; countsizeHint(); buttonHeight=TQMAX(buttonHeight, sizes[count].height()); } else sizes[count] = TQSize(0,0); // closeButton } // ----- calculate size of the month button: for(count=0; countsetGeometry(x, 0, sizes[0].width(), buttonHeight); x += sizes[0].width(); for (count=1; count<=noUserButtons; ++count) { if (buttons[count]) { buttons[count]->setGeometry(x, 0, sizes[count].width(), buttonHeight); x += sizes[count].width(); } } x = width(); for(count=(1+noUserButtons); countsetGeometry(x, 0, w, buttonHeight); x+=w; } // ----- place the line edit for direct input: sizes[0]=line->sizeHint(); int week_width=d->selectWeek->fontMetrics().width(i18n("Week XX"))+((d->closeButton != 0L) ? 50 : 20); line->setGeometry(0, height()-sizes[0].height(), width()-week_width, sizes[0].height()); d->selectWeek->setGeometry(width()-week_width, height()-sizes[0].height(), week_width, sizes[0].height()); // ----- adjust the table: table->setGeometry(0, buttonHeight, width(), height()-buttonHeight-sizes[0].height()); table->setFocus(); } void kMyMoneyCalendar::dateChangedSlot(TQDate date) { kdDebug() << "kMyMoneyCalendar::dateChangedSlot: date changed (" << date.year() << "/" << date.month() << "/" << date.day() << ")." << endl; line->setText(TDEGlobal::locale()->formatDate(date, true)); d->selectWeek->setText(i18n("Week %1").arg(weekOfYear(date))); selectMonth->setText(MONTH_NAME(date.month(), date.year(), false)); selectYear->setText(date.toString("yyyy")); emit(dateChanged(date)); } void kMyMoneyCalendar::tableClickedSlot() { kdDebug() << "kMyMoneyCalendar::tableClickedSlot: table clicked." << endl; emit(dateSelected(table->getDate())); emit(tableClicked()); } const TQDate& kMyMoneyCalendar::getDate() const { return table->getDate(); } const TQDate & kMyMoneyCalendar::date() const { return table->getDate(); } bool kMyMoneyCalendar::setDate(const TQDate& date) { if (!table) return true; // hack if(date.isValid()) { TQString temp; // ----- table->setDate(date); d->selectWeek->setText(i18n("Week %1").arg(weekOfYear(date))); selectMonth->setText(MONTH_NAME(date.month(), date.year(), false)); temp.setNum(date.year()); selectYear->setText(temp); line->setText(TDEGlobal::locale()->formatDate(date, true)); return true; } else { kdDebug() << "kMyMoneyCalendar::setDate: refusing to set invalid date." << endl; return false; } } void kMyMoneyCalendar::monthForwardClicked() { setDate( table->getDate().addMonths(1) ); } void kMyMoneyCalendar::monthBackwardClicked() { setDate( table->getDate().addMonths(-1) ); } void kMyMoneyCalendar::yearForwardClicked() { setDate( table->getDate().addYears(1) ); } void kMyMoneyCalendar::yearBackwardClicked() { setDate( table->getDate().addYears(-1) ); } void kMyMoneyCalendar::selectWeekClicked() { #if TDE_VERSION >= 310 && TDE_VERSION <= 314 int week; TDEPopupFrame* popup = new TDEPopupFrame(this); KDateInternalWeekSelector* picker = new KDateInternalWeekSelector(/*fontsize, */popup); // ----- picker->resize(picker->sizeHint()); popup->setMainWidget(picker); connect(picker, TQ_SIGNAL(closeMe(int)), popup, TQ_SLOT(close(int))); picker->setFocus(); if(popup->exec(d->selectWeek->mapToGlobal(TQPoint(0, d->selectWeek->height())))) { TQDate date; int year; // ----- week=picker->getWeek(); date=table->getDate(); year=date.year(); // ----- find the first selectable day in this week (hacky solution :) date.setYMD(year, 1, 1); while (weekOfYear(date)>50) date=date.addDays(1); while (weekOfYear(date)= 310 && TDE_VERSION <= 314 int month; TDEPopupFrame* popup = new TDEPopupFrame(this); KDateInternalMonthPicker* picker = new KDateInternalMonthPicker(/*fontsize, */popup); // ----- picker->resize(picker->sizeHint()); popup->setMainWidget(picker); picker->setFocus(); connect(picker, TQ_SIGNAL(closeMe(int)), popup, TQ_SLOT(close(int))); if(popup->exec(selectMonth->mapToGlobal(TQPoint(0, selectMonth->height())))) { TQDate date; int day; // ----- month=picker->getResult(); date=table->getDate(); day=date.day(); // ----- construct a valid date in this month: date.setYMD(date.year(), month, 1); date.setYMD(date.year(), month, TQMIN(day, date.daysInMonth())); // ----- set this month setDate(date); } else { KNotifyClient::beep(); } delete popup; #endif } void kMyMoneyCalendar::selectYearClicked() { #if TDE_VERSION >= 310 && TDE_VERSION <= 314 int year; TDEPopupFrame* popup = new TDEPopupFrame(this); KDateInternalYearSelector* picker = new KDateInternalYearSelector(fontsize, popup); // ----- picker->resize(picker->sizeHint()); popup->setMainWidget(picker); connect(picker, TQ_SIGNAL(closeMe(int)), popup, TQ_SLOT(close(int))); picker->setFocus(); if(popup->exec(selectYear->mapToGlobal(TQPoint(0, selectMonth->height())))) { TQDate date; int day; // ----- year=picker->getYear(); date=table->getDate(); day=date.day(); // ----- construct a valid date in this month: date.setYMD(year, date.month(), 1); date.setYMD(year, date.month(), TQMIN(day, date.daysInMonth())); // ----- set this month setDate(date); } else { KNotifyClient::beep(); } delete popup; #endif } void kMyMoneyCalendar::setEnabled(bool enable) { TQWidget *widgets[]= { styleControl, yearForward, yearBackward, monthForward, monthBackward, selectMonth, selectYear, line, table, d->selectWeek, d->userButton1, d->userButton2 }; const int Size=sizeof(widgets)/sizeof(widgets[0]); int count; // ----- for(count=0; countsetEnabled(enable); } } void kMyMoneyCalendar::lineEnterPressed() { TQDate temp; // ----- if(val->date(line->text(), temp)==TQValidator::Acceptable) { kdDebug() << "kMyMoneyCalendar::lineEnterPressed: valid date entered." << endl; emit(dateEntered(temp)); setDate(temp); } else { KNotifyClient::beep(); kdDebug() << "kMyMoneyCalendar::lineEnterPressed: invalid date entered." << endl; } } TQSize kMyMoneyCalendar::sizeHint() const { TQSize tableSize=table->sizeHint(); TQWidget *buttons[]={ styleControl, yearBackward, monthBackward, selectMonth, selectYear, monthForward, yearForward, d->closeButton, d->userButton1, d->userButton2 }; const int NoOfButtons=sizeof(buttons)/sizeof(buttons[0]); TQSize sizes[NoOfButtons]; int cx=0, cy=0, count; // ----- store the size hints: for(count=0; countsizeHint(); else sizes[count] = TQSize(0,0); if(buttons[count]==selectMonth) { TQSize metricBound = style().sizeFromContents(TQStyle::CT_ToolButton, selectMonth, maxMonthRect); cx+=TQMAX(metricBound.width(), maxMonthRect.width()+2*TQApplication::style().pixelMetric(TQStyle::PM_ButtonMargin)); } else { cx+=sizes[count].width(); } cy=TQMAX(sizes[count].height(), cy); } // ----- calculate width hint: cx=TQMAX(cx, tableSize.width()); // line edit ignored // ----- calculate height hint: cy+=tableSize.height()+line->sizeHint().height(); return TQSize(cx, cy); } void kMyMoneyCalendar::setFontSize(int s) { if (table) { TQWidget *buttons[]= { // styleControl // yearBackward, // monthBackward, selectMonth, selectYear, // monthForward, // yearForward }; const int NoOfButtons=sizeof(buttons)/sizeof(buttons[0]); int count; TQFont font; TQRect r; // ----- fontsize=s; for(count=0; countfont(); font.setPointSize(s); buttons[count]->setFont(font); } TQFontMetrics metrics(selectMonth->fontMetrics()); for(int i=1; i <= 12; ++i) { // maxMonthRect is used by sizeHint() r=metrics.boundingRect(MONTH_NAME(i, 2000, false)); maxMonthRect.setWidth(TQMAX(r.width(), maxMonthRect.width())); maxMonthRect.setHeight(TQMAX(r.height(), maxMonthRect.height())); } table->setFontSize(s); } } void kMyMoneyCalendar::setCloseButton( bool enable ) { if ( enable == (d->closeButton != 0L) ) return; if ( enable ) { d->closeButton = new TQToolButton( this ); TQToolTip::add(d->closeButton, i18n("Close")); d->closeButton->setPixmap( SmallIcon("remove") ); connect( d->closeButton, TQ_SIGNAL( clicked() ), topLevelWidget(), TQ_SLOT( close() ) ); } else { delete d->closeButton; d->closeButton = 0L; } updateGeometry(); } bool kMyMoneyCalendar::hasCloseButton() const { return (d->closeButton != 0L); } int kMyMoneyCalendar::weekOfYear(TQDate date) { // Calculate ISO 8601 week number (taken from glibc/Gnumeric) int year, week, wday, jan1wday, nextjan1wday; TQDate jan1date, nextjan1date; year=date.year(); wday=date.dayOfWeek(); jan1date=TQDate(year,1,1); jan1wday=jan1date.dayOfWeek(); week = (date.dayOfYear()-1 + jan1wday-1)/7 + ((jan1wday-1) == 0 ? 1 : 0); /* Does date belong to last week of previous year? */ if ((week == 0) && (jan1wday > 4 /*THURSDAY*/)) { TQDate tmpdate=TQDate(year-1,12,31); return weekOfYear(tmpdate); } if ((jan1wday <= 4 /*THURSDAY*/) && (jan1wday > 1 /*MONDAY*/)) week++; if (week == 53) { nextjan1date=TQDate(year+1, 1, 1); nextjan1wday = nextjan1date.dayOfWeek(); if (nextjan1wday <= 4 /*THURSDAY*/) week = 1; } return week; } void kMyMoneyCalendar::virtual_hook( int /*id*/, void* /*data*/ ) { /*BASE::virtual_hook( id, data );*/ } void kMyMoneyCalendar::slotSetStyleWeekly() { setType(kMyMoneyDateTbl::WEEKLY); } void kMyMoneyCalendar::slotSetStyleMonthly() { setType(kMyMoneyDateTbl::MONTHLY); } void kMyMoneyCalendar::slotSetStyleQuarterly() { setType(kMyMoneyDateTbl::QUARTERLY); } void kMyMoneyCalendar::setUserButton1(bool enable, TQPushButton* pb) { if ( enable == (d->userButton1 != 0L) ) return; if ( enable ) { d->userButton1 = pb; } else { delete d->userButton1; d->userButton1 = 0L; } updateGeometry(); } void kMyMoneyCalendar::setUserButton2(bool enable, TQPushButton* pb) { if ( enable == (d->userButton2 != 0L) ) return; if ( enable ) { d->userButton2 = pb; } else { delete d->userButton2; d->userButton2 = 0L; } updateGeometry(); } #include "kmymoneycalendar.moc"