summaryrefslogtreecommitdiffstats
path: root/kmymoney2/widgets/kmymoneydatetbl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kmymoney2/widgets/kmymoneydatetbl.cpp')
-rw-r--r--kmymoney2/widgets/kmymoneydatetbl.cpp698
1 files changed, 698 insertions, 0 deletions
diff --git a/kmymoney2/widgets/kmymoneydatetbl.cpp b/kmymoney2/widgets/kmymoneydatetbl.cpp
new file mode 100644
index 0000000..e48e01e
--- /dev/null
+++ b/kmymoney2/widgets/kmymoneydatetbl.cpp
@@ -0,0 +1,698 @@
+/***************************************************************************
+ kmymoneydatetbl.cpp - description
+ -------------------
+ begin : Thu Jul 3 2003
+ copyright : (C) 2000-2003 by Michael Edwardes
+ Javier Campos Morales <[email protected]>
+ Felix Rodriguez <[email protected]>
+ Thomas Baumgart <[email protected]>
+ Kevin Tambascio <[email protected]>
+ ***************************************************************************/
+
+ /****************************************************************************
+ Contains code from the KDateTable class ala kdelibs-3.1.2. Original license:
+
+ This file is part of the KDE libraries
+ Copyright (C) 1997 Tim D. Gilman ([email protected])
+ (C) 1998-2001 Mirko Boehm ([email protected])
+ 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. *
+ * *
+ ***************************************************************************/
+
+// ----------------------------------------------------------------------------
+// QT Includes
+#include <qglobal.h>
+#include <qdatetime.h>
+#include <qstring.h>
+#include <qpen.h>
+#include <qpainter.h>
+#include <qdialog.h>
+
+// ----------------------------------------------------------------------------
+// KDE Includes
+#include "kdecompat.h"
+#include <kdatetbl.h> // Use the classes available for maximum re-use
+#include <kglobal.h>
+#include <kglobalsettings.h>
+#include <kapplication.h>
+#include <klocale.h>
+#include <kdebug.h>
+#include <knotifyclient.h>
+#if KDE_IS_VERSION(3,2,0)
+#include <kcalendarsystem.h>
+#endif
+
+// ----------------------------------------------------------------------------
+// Project Includes
+#include "kmymoneydatetbl.h"
+
+kMyMoneyDateTbl::kMyMoneyDateTbl(QWidget *parent, QDate date_, const char* name, WFlags f)
+ : QGridView(parent, name, f)
+{
+ // call this first to make sure that member variables are initialized
+ setType(MONTHLY);
+
+ setFontSize(10);
+
+ if(!date_.isValid())
+ {
+ kdDebug() << "kMyMoneyDateTbl ctor: WARNING: Given date is invalid, using current date." << endl;
+ date_=QDate::currentDate();
+ }
+ setFocusPolicy( QWidget::StrongFocus );
+
+
+ viewport()->setEraseColor(KGlobalSettings::baseColor());
+
+ setDate(date_); // this initializes firstday, numdays, numDaysPrevMonth
+
+ // So we can emit hoverDate
+// QApplication::setGlobalMouseTracking(true);
+ viewport()->setMouseTracking(true);
+}
+
+void
+kMyMoneyDateTbl::paintCell(QPainter *painter, int row, int col)
+{
+ QRect rect;
+ QString text;
+ QPen pen;
+ int w=cellWidth();
+ int h=cellHeight();
+ QBrush brushBlue(KGlobalSettings::activeTitleColor());
+ QBrush brushLightblue(KGlobalSettings::baseColor());
+ QFont font=KGlobalSettings::generalFont();
+
+ // -----
+ font.setPointSize(fontsize);
+
+#if KDE_VERSION < 310
+ int firstWeekDay = KGlobal::locale()->weekStartsMonday() ? 1 : 0;
+#else
+ int firstWeekDay = KGlobal::locale()->weekStartDay();
+#endif
+
+ if (row==0)
+ { // we are drawing the headline
+ if (m_type == MONTHLY)
+ {
+ font.setBold(true);
+ painter->setFont(font);
+ bool normalday = true;
+ QString daystr;
+ if ( col+firstWeekDay < 8 )
+ daystr = WEEK_DAY_NAME(col+firstWeekDay, true);
+ else
+ daystr = WEEK_DAY_NAME(col+firstWeekDay-7, true);
+
+ if ( daystr==i18n("Sunday", "Sun") || daystr==i18n("Saturday", "Sat") )
+ normalday=false;
+
+ if (!normalday)
+ {
+ painter->setPen(KGlobalSettings::baseColor());
+ painter->setBrush(brushLightblue);
+ painter->drawRect(0, 0, w, h);
+ painter->setPen(KGlobalSettings::activeTitleColor());
+ } else {
+ painter->setPen(KGlobalSettings::activeTitleColor());
+ painter->setBrush(brushBlue);
+ painter->drawRect(0, 0, w, h);
+ painter->setPen(KGlobalSettings::activeTextColor());
+ }
+ painter->drawText(0, 0, w, h-1, AlignCenter,
+ daystr, -1, &rect);
+ painter->setPen(KGlobalSettings::textColor());
+ 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());
+ }
+ else if (m_type == WEEKLY)
+ {
+ painter->setPen(KGlobalSettings::activeTitleColor());
+ painter->setBrush(brushBlue);
+ painter->drawRect(0, 0, w, h);
+ painter->setPen(KGlobalSettings::activeTextColor());
+
+ int year=date.year();
+ QString headerText;
+#if QT_VERSION > 0x030005
+ // FIXME: Shouldn't that be i18n()'ed as well
+ QString weekStr = QString::number(date.weekNumber(&year));
+ QString yearStr = QString::number(year);
+ headerText = i18n("Week %1 for year %2.")
+ .arg(weekStr)
+ .arg(yearStr);
+#else
+ // FIXME: include code to display the same as for KDE >= 3.0.5
+ QString weekStr = QString::number(weekNumber(date, &year));
+ QString yearStr = QString::number(year);
+ headerText = i18n("Week %1 for year %2.")
+ .arg(weekStr)
+ .arg(yearStr);
+#endif
+
+ painter->drawText(0, 0, w, h-1, AlignCenter, headerText, -1, &rect);
+
+ maxCell.setWidth(width());
+
+ if(rect.height()>maxCell.height())
+ maxCell.setHeight(rect.height());
+ }
+ else if (m_type == QUARTERLY)
+ {
+ int athird = width()/3;
+
+ painter->setPen(KGlobalSettings::activeTitleColor());
+ painter->setBrush(brushBlue);
+ painter->setPen(/*KGlobalSettings::activeTextColor()*/black);
+
+ if (col == 0)
+ {
+ painter->drawRect(0, 0, athird, h);
+ painter->drawText(0, 0, athird, h-1, AlignCenter, "Month 1", -1, &rect);
+
+ painter->drawRect(athird, 0, athird, h);
+ painter->drawText(athird, 0, athird, h-1, AlignCenter, "Month 2", -1, &rect);
+
+ painter->drawRect(athird*2, 0, athird, h);
+ painter->drawText(athird*2, 0, athird, h-1, AlignCenter, "Month 3", -1, &rect);
+ }
+ }
+ }
+ else
+ {
+ int pos;
+
+ QDate drawDate(date);
+
+ if (m_type == MONTHLY)
+ {
+ pos=7*(row-1)+col;
+ if ( firstWeekDay < 4 )
+ pos += firstWeekDay;
+ else
+ pos += firstWeekDay - 7;
+
+ if (pos<firstday || (firstday+numdays<=pos))
+ { // we are either
+ // painting a day of the previous month or
+ // painting a day of the following month
+
+ if (pos<firstday)
+ { // previous month
+ drawDate = drawDate.addMonths(-1);
+ text.setNum(numDaysPrevMonth+pos-firstday+1);
+ drawDate.setYMD(drawDate.year(), drawDate.month(), text.toInt());
+ } else { // following month
+ drawDate = drawDate.addMonths(1);
+ text.setNum(pos-firstday-numdays+1);
+ drawDate.setYMD(drawDate.year(), drawDate.month(), text.toInt());
+ }
+ } else { // paint a day of the current month
+ text.setNum(pos-firstday+1);
+ drawDate.setYMD(drawDate.year(), drawDate.month(), text.toInt());
+ }
+ }
+ else if (m_type == WEEKLY)
+ {
+ // TODO: Handle other start weekdays than Monday
+ text = QDate::shortDayName(row);
+ text += " ";
+
+ int dayOfWeek = date.dayOfWeek();
+ int diff;
+
+ if (row < dayOfWeek)
+ {
+ diff = -(dayOfWeek - row);
+ }
+ else
+ {
+ diff = row - dayOfWeek;
+ }
+
+ drawDate = date.addDays(diff);
+ }
+ else if (m_type == QUARTERLY)
+ {
+ }
+
+ drawCellContents(painter, row, col, drawDate);
+ }
+}
+
+void
+kMyMoneyDateTbl::keyPressEvent( QKeyEvent *e )
+{
+ if ( e->key() == Qt::Key_Prior ) {
+ setDate(date.addMonths(-1));
+ return;
+ }
+ if ( e->key() == Qt::Key_Next ) {
+ setDate(date.addMonths(1));
+ return;
+ }
+
+ if ( e->key() == Qt::Key_Up ) {
+ if ( date.day() > 7 ) {
+ setDate(date.addDays(-7));
+ return;
+ }
+ }
+ if ( e->key() == Qt::Key_Down ) {
+ if ( date.day() <= date.daysInMonth()-7 ) {
+ setDate(date.addDays(7));
+ return;
+ }
+ }
+ if ( e->key() == Qt::Key_Left ) {
+ if ( date.day() > 1 ) {
+ setDate(date.addDays(-1));
+ return;
+ }
+ }
+ if ( e->key() == Qt::Key_Right ) {
+ if ( date.day() < date.daysInMonth() ) {
+ setDate(date.addDays(1));
+ return;
+ }
+ }
+
+ if ( e->key() == Qt::Key_Minus ) {
+ setDate(date.addDays(-1));
+ return;
+ }
+ if ( e->key() == Qt::Key_Plus ) {
+ setDate(date.addDays(1));
+ return;
+ }
+ if ( e->key() == Qt::Key_N ) {
+ setDate(QDate::currentDate());
+ return;
+ }
+
+ KNotifyClient::beep();
+}
+
+void
+kMyMoneyDateTbl::viewportResizeEvent(QResizeEvent * e)
+{
+ if (e)
+ QGridView::viewportResizeEvent(e);
+
+ setCellWidth(viewport()->width()/m_colCount);
+ setCellHeight(viewport()->height()/m_rowCount);
+}
+
+void
+kMyMoneyDateTbl::setFontSize(int size)
+{
+ int count;
+ QFontMetrics metrics(fontMetrics());
+ QRect rect;
+
+ // ----- store rectangles:
+ fontsize=size;
+
+ // ----- find largest day name:
+ maxCell.setWidth(0);
+ maxCell.setHeight(0);
+
+ for(count=0; count<m_colCount; ++count)
+ {
+ rect=metrics.boundingRect(WEEK_DAY_NAME(count+1, true));
+ maxCell.setWidth(QMAX(maxCell.width(), rect.width()));
+ maxCell.setHeight(QMAX(maxCell.height(), rect.height()));
+ }
+
+ if (m_type == WEEKLY)
+ {
+ // Re-size to width
+ maxCell.setWidth(width());
+ }
+
+ // ----- compare with a real wide number and add some space:
+ rect=metrics.boundingRect(QString::fromLatin1("88"));
+ maxCell.setWidth(QMAX(maxCell.width()+2, rect.width()));
+ maxCell.setHeight(QMAX(maxCell.height()+4, rect.height()));
+}
+
+void
+kMyMoneyDateTbl::wheelEvent ( QWheelEvent * e )
+{
+ setDate(date.addMonths( -(int)(e->delta()/120)) );
+ e->accept();
+}
+
+void
+kMyMoneyDateTbl::contentsMouseReleaseEvent(QMouseEvent *e)
+{
+ if (e->type()!=QEvent::MouseButtonRelease)
+ { // the KDatePicker only reacts on mouse press events:
+ return;
+ }
+
+ if(!isEnabled())
+ {
+ KNotifyClient::beep();
+ return;
+ }
+
+#if KDE_VERSION < 310
+ int dayoff = KGlobal::locale()->weekStartsMonday() ? 1 : 0;
+#else
+ int dayoff = KGlobal::locale()->weekStartDay();
+#endif
+
+ // -----
+ int row, col, pos, temp;
+ QPoint 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;
+ }
+
+ if (m_type == MONTHLY)
+ {
+ // 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. We however want pos
+ // to be "1 indexed", hence the "+ 1" at the end of the sum.
+ pos = (7 * (row - 1)) + col + 1;
+
+ // This gets pretty nasty below. firstday is a locale independant index for
+ // the first day of the week. dayoff is the day of the week that the week
+ // starts with for the selected locale. Monday = 1 .. Sunday = 7
+ // Strangely, in some cases dayoff is in fact set to 8, hence all of the
+ // "dayoff % 7" sections below.
+
+ if (pos + dayoff % 7 <= firstday)
+ { // this day is in the previous month
+ setDate(date.addDays(-1 * (date.day() + firstday - pos - dayoff % 7)));
+ return;
+ }
+
+ if (firstday + numdays < pos + dayoff % 7)
+ { // this date is in the next month
+ setDate(date.addDays(pos - firstday - date.day() + dayoff % 7));
+ return;
+ }
+ temp = firstday + date.day() - dayoff % 7 - 1;
+
+ setDate(QDate(date.year(), date.month(), pos - firstday + dayoff % 7));
+
+ updateCell(temp/7+1, temp%7); // Update the previously selected cell
+ }
+ else if (m_type == WEEKLY)
+ {
+ int dayOfWeek = date.dayOfWeek();
+ int diff;
+
+ if (row < dayOfWeek)
+ {
+ diff = -(dayOfWeek - row);
+ }
+ else
+ {
+ diff = row - dayOfWeek;
+ }
+
+ setDate(date.addDays(diff));
+ updateCell(dayOfWeek, 0);
+ }
+ else if (m_type == QUARTERLY)
+ {
+ }
+
+ updateCell(row, col); // Update the selected cell
+
+ emit(tableClicked());
+}
+
+bool
+kMyMoneyDateTbl::setDate(const QDate& date_)
+{
+ bool changed=false;
+ QDate temp;
+ // -----
+ if(!date_.isValid())
+ {
+ kdDebug() << "kMyMoneyDateTbl::setDate: refusing to set invalid date." << endl;
+ return false;
+ }
+
+ if(date!=date_)
+ {
+ date=date_;
+ changed=true;
+ }
+
+ temp.setYMD(date.year(), date.month(), 1);
+ firstday=temp.dayOfWeek();
+
+ if (firstday==1)
+ firstday=8;
+
+ numdays=date.daysInMonth();
+
+ if (date.month()==1)
+ { // set to december of previous year
+ temp.setYMD(date.year()-1, 12, 1);
+ } else { // set to previous month
+ temp.setYMD(date.year(), date.month()-1, 1);
+ }
+
+ numDaysPrevMonth=temp.daysInMonth();
+
+ if (changed)
+ {
+ repaintContents(false);
+ }
+
+ emit(dateChanged(date));
+ return true;
+}
+
+const QDate&
+kMyMoneyDateTbl::getDate() const
+{
+ return date;
+}
+
+// what are those repaintContents() good for? (pfeiffer)
+void kMyMoneyDateTbl::focusInEvent( QFocusEvent *e )
+{
+// repaintContents(false);
+ QGridView::focusInEvent( e );
+}
+
+void kMyMoneyDateTbl::focusOutEvent( QFocusEvent *e )
+{
+// repaintContents(false);
+ QGridView::focusOutEvent( e );
+}
+
+QSize
+kMyMoneyDateTbl::sizeHint() const
+{
+ if (maxCell.height()>0 && maxCell.width()>0)
+ {
+ return QSize(maxCell.width()*numCols()+2*frameWidth(),
+ (maxCell.height()+2)*numRows()+2*frameWidth());
+ } else {
+ kdDebug() << "kMyMoneyDateTbl::sizeHint: obscure failure - " << endl;
+ return QSize(-1, -1);
+ }
+}
+
+
+void kMyMoneyDateTbl::setType(calendarType type)
+{
+ if (type == WEEKLY)
+ {
+ m_rowCount = 8;
+ m_colCount = 1;
+ m_type = WEEKLY;
+ }
+ else if (type == QUARTERLY)
+ {
+ m_rowCount = 7;
+ m_colCount = 21;
+ m_type = QUARTERLY;
+ }
+ else // default to monthly
+ {
+ m_rowCount = m_colCount = 7;
+ m_type = MONTHLY;
+ }
+
+ setNumRows(m_rowCount);
+ setNumCols(m_colCount);
+ setHScrollBarMode(AlwaysOff);
+ setVScrollBarMode(AlwaysOff);
+
+ viewportResizeEvent(NULL);
+}
+
+void kMyMoneyDateTbl::contentsMouseMoveEvent(QMouseEvent* e)
+{
+ int row, col, pos;
+ QPoint mouseCoord;
+
+ mouseCoord = e->pos();
+ row = rowAt(mouseCoord.y());
+ col = columnAt(mouseCoord.x());
+ if (row<1 || col<0)
+ {
+ return;
+ }
+
+#if KDE_VERSION < 310
+ int firstWeekDay = KGlobal::locale()->weekStartsMonday() ? 1 : 0;
+#else
+ int firstWeekDay = KGlobal::locale()->weekStartDay();
+#endif
+
+ QDate drawDate(date);
+ QString text;
+
+ if (m_type == MONTHLY)
+ {
+ pos=7*(row-1)+col;
+ if ( firstWeekDay < 4 )
+ pos += firstWeekDay;
+ else
+ pos += firstWeekDay - 7;
+
+ if (pos<firstday || (firstday+numdays<=pos))
+ { // we are either
+ // painting a day of the previous month or
+ // painting a day of the following month
+
+ if (pos<firstday)
+ { // previous month
+ drawDate = drawDate.addMonths(-1);
+ text.setNum(numDaysPrevMonth+pos-firstday+1);
+ drawDate.setYMD(drawDate.year(), drawDate.month(), text.toInt());
+ } else { // following month
+ drawDate = drawDate.addMonths(1);
+ text.setNum(pos-firstday-numdays+1);
+ drawDate.setYMD(drawDate.year(), drawDate.month(), text.toInt());
+ }
+ } else { // paint a day of the current month
+ text.setNum(pos-firstday+1);
+ drawDate.setYMD(drawDate.year(), drawDate.month(), text.toInt());
+ }
+ }
+ else if (m_type == WEEKLY)
+ {
+ // TODO: Handle other start weekdays than Monday
+ text = QDate::shortDayName(row);
+ text += " ";
+
+ int dayOfWeek = date.dayOfWeek();
+ int diff;
+
+ if (row < dayOfWeek)
+ {
+ diff = -(dayOfWeek - row);
+ }
+ else
+ {
+ diff = row - dayOfWeek;
+ }
+
+ drawDate = date.addDays(diff);
+ }
+ else if (m_type == QUARTERLY)
+ {
+ }
+
+ if (m_drawDateOrig != drawDate)
+ {
+ m_drawDateOrig = drawDate;
+ emit hoverDate(drawDate);
+ }
+
+ QGridView::contentsMouseMoveEvent(e);
+}
+
+#if QT_VERSION <= 0x030005
+// The following code is borrowed from QT 3.2 QDate::weekNumber()
+// and slightly modified
+int kMyMoneyDateTbl::weekNumber(const QDate& date, int *yearNumber) const
+{
+ if ( !date.isValid() )
+ return 0;
+
+ int dow = date.dayOfWeek();
+ int doy = date.dayOfYear();
+ int currYear = date.year();
+ int jan1WeekDay = QDate( currYear, 1, 1 ).dayOfWeek();
+ int yearNum;
+ int weekNum;
+
+ if ( doy <= (8 - jan1WeekDay) && jan1WeekDay > 4 ) {
+ yearNum = currYear - 1;
+ weekNum = 52;
+ if ( jan1WeekDay == 5 ||
+ (jan1WeekDay == 6 && QDate::leapYear(yearNum)) )
+ weekNum++;
+ } else {
+ int totalDays = 365;
+ if ( QDate::leapYear(currYear) )
+ totalDays++;
+
+ if ( (totalDays - doy < 4 - dow)
+ || (jan1WeekDay == 7 && totalDays - doy < 3) ) {
+ yearNum = currYear + 1;
+ weekNum = 1;
+ } else {
+ int j = doy + ( 7 - dow ) + ( jan1WeekDay - 1 );
+ yearNum = currYear;
+ weekNum = j / 7;
+ if ( jan1WeekDay > 4 )
+ weekNum--;
+ }
+ }
+ if ( yearNumber )
+ *yearNumber = yearNum;
+ return weekNum;
+
+}
+#endif
+
+#include "kmymoneydatetbl.moc"