summaryrefslogtreecommitdiffstats
path: root/src/digikam/monthwidget.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/digikam/monthwidget.cpp')
-rw-r--r--src/digikam/monthwidget.cpp423
1 files changed, 423 insertions, 0 deletions
diff --git a/src/digikam/monthwidget.cpp b/src/digikam/monthwidget.cpp
new file mode 100644
index 00000000..665318fd
--- /dev/null
+++ b/src/digikam/monthwidget.cpp
@@ -0,0 +1,423 @@
+/* ============================================================
+ *
+ * This file is a part of digiKam project
+ * http://www.digikam.org
+ *
+ * Date : 2005-05-02
+ * Description : a widget to perform month selection.
+ *
+ * Copyright (C) 2005 by Renchi Raju <renchi@pooh.tam.uiuc.edu>
+ * Copyright (C) 2006-2007 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ *
+ * 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, or (at your option)
+ * any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * ============================================================ */
+
+// TQt includes.
+
+#include <tqdatetime.h>
+#include <tqfontmetrics.h>
+#include <tqpainter.h>
+#include <tqpixmap.h>
+#include <tqpalette.h>
+
+// KDE includes.
+
+#include <tdelocale.h>
+#include <tdeglobal.h>
+#include <kcalendarsystem.h>
+#include <tdeversion.h>
+
+// Local includes.
+
+#include "imageinfo.h"
+#include "albumlister.h"
+#include "monthwidget.h"
+#include "monthwidget.moc"
+
+namespace Digikam
+{
+
+class MonthWidgetPriv
+{
+public:
+
+ struct Month
+ {
+ bool active;
+ bool selected;
+
+ int day;
+ int numImages;
+ };
+
+ MonthWidgetPriv()
+ {
+ active = true;
+ }
+
+ bool active;
+
+ int year;
+ int month;
+ int width;
+ int height;
+ int currw;
+ int currh;
+
+ struct Month days[42];
+};
+
+MonthWidget::MonthWidget(TQWidget* parent)
+ : TQFrame(parent, 0, TQt::WNoAutoErase)
+{
+ d = new MonthWidgetPriv;
+ init();
+
+ TQDate date = TQDate::currentDate();
+ setYearMonth(date.year(), date.month());
+
+ setActive(false);
+}
+
+MonthWidget::~MonthWidget()
+{
+ delete d;
+}
+
+void MonthWidget::init()
+{
+ TQFont fn(font());
+ fn.setBold(true);
+ fn.setPointSize(fn.pointSize()+1);
+ TQFontMetrics fm(fn);
+ TQRect r(fm.boundingRect("XX"));
+ r.setWidth(r.width() + 2);
+ r.setHeight(r.height() + 4);
+ d->width = r.width();
+ d->height = r.height();
+
+ setMinimumWidth(d->width * 8);
+ setMinimumHeight(d->height * 9);
+}
+
+void MonthWidget::setYearMonth(int year, int month)
+{
+ d->year = year;
+ d->month = month;
+
+ for (int i=0; i<42; i++)
+ {
+ d->days[i].active = false;
+ d->days[i].selected = false;
+ d->days[i].day = -1;
+ d->days[i].numImages = 0;
+ }
+
+ TQDate date(year, month, 1);
+ int s = date.dayOfWeek();
+
+ for (int i=s; i<(s+date.daysInMonth()); i++)
+ {
+ d->days[i-1].day = i-s+1;
+ }
+
+ update();
+}
+
+TQSize MonthWidget::sizeHint() const
+{
+ return TQSize(d->width * 8, d->height * 9);
+}
+
+void MonthWidget::resizeEvent(TQResizeEvent *e)
+{
+ TQWidget::resizeEvent(e);
+
+ d->currw = contentsRect().width()/8;
+ d->currh = contentsRect().height()/9;
+}
+
+void MonthWidget::drawContents(TQPainter *)
+{
+ TQRect cr(contentsRect());
+
+ TQPixmap pix(cr.width(), cr.height());
+
+ TQColorGroup cg = colorGroup();
+
+ TQFont fnBold(font());
+ TQFont fnOrig(font());
+ fnBold.setBold(true);
+ fnOrig.setBold(false);
+
+ TQPainter p(&pix);
+ p.fillRect(0, 0, cr.width(), cr.height(), cg.background());
+
+ TQRect r(0, 0, d->currw, d->currh);
+ TQRect rsmall;
+
+ int sx, sy;
+ int index = 0;
+ bool weekvisible;
+ for (int j=3; j<9; j++)
+ {
+ sy = d->currh * j;
+ weekvisible = false;
+
+ for (int i=1; i<8; i++)
+ {
+ sx = d->currw * i;
+ r.moveTopLeft(TQPoint(sx,sy));
+ rsmall = TQRect(r.x()+1, r.y()+1, r.width()-2, r.height()-2);
+ if (d->days[index].day != -1)
+ {
+ if (d->days[index].selected)
+ {
+ p.fillRect(r, cg.highlight());
+ p.setPen(cg.highlightedText());
+
+ if (d->days[index].active)
+ {
+ p.setFont(fnBold);
+ }
+ else
+ {
+ p.setFont(fnOrig);
+ }
+ }
+ else
+ {
+ if (d->days[index].active)
+ {
+ p.setPen(cg.text());
+ p.setFont(fnBold);
+ }
+ else
+ {
+ p.setPen(cg.mid());
+ p.setFont(fnOrig);
+ }
+ }
+
+ p.drawText(rsmall, TQt::AlignVCenter|TQt::AlignHCenter,
+ TQString::number(d->days[index].day));
+
+ if(!weekvisible)
+ {
+ int weeknr = TDEGlobal::locale()->calendar()->weekNumber(TQDate(d->year,
+ d->month, d->days[index].day));
+ p.setPen(d->active ? TQt::black : TQt::gray);
+ p.setFont(fnBold);
+ p.fillRect(1, sy, d->currw-1, d->currh-1, TQColor(210,210,210));
+ p.drawText(1, sy, d->currw-1, d->currh-1, TQt::AlignVCenter|TQt::AlignHCenter,
+ TQString::number(weeknr));
+ weekvisible = true;
+ }
+
+ }
+
+ index++;
+ }
+ }
+
+ p.setPen(d->active ? TQt::black : TQt::gray);
+
+ p.setFont(fnBold);
+
+ sy = 2*d->currh;
+ for (int i=1; i<8; i++)
+ {
+ sx = d->currw * i;
+ r.moveTopLeft(TQPoint(sx+1,sy+1));
+ rsmall = r;
+ rsmall.setWidth(r.width() - 2);
+ rsmall.setHeight(r.height() - 2);
+#if KDE_IS_VERSION(3,2,0)
+ p.drawText(rsmall, TQt::AlignVCenter|TQt::AlignHCenter,
+ TDEGlobal::locale()->calendar()->weekDayName(i, true)
+ .remove(2,1));
+#else
+ p.drawText(rsmall, TQt::AlignVCenter|TQt::AlignHCenter,
+ TDEGlobal::locale()->weekDayName(i, true).remove(2,1));
+#endif
+ index++;
+ }
+
+ r = TQRect(0, 0, cr.width(), 2*d->currh);
+
+ fnBold.setPointSize(fnBold.pointSize()+2);
+ p.setFont(fnBold);
+
+#if KDE_IS_VERSION(3,2,0)
+ p.drawText(r, TQt::AlignCenter,
+ TQString("%1 %2")
+ .arg(TDEGlobal::locale()->calendar()->monthName(d->month, false))
+ .arg(TDEGlobal::locale()->calendar()->year(TQDate(d->year,d->month,1))));
+#else
+ p.drawText(r, TQt::AlignCenter,
+ TQString("%1 %2")
+ .arg(TDEGlobal::locale()->monthName(d->month))
+ .arg(TQString::number(d->year)));
+#endif
+
+ p.end();
+
+ bitBlt(this, cr.x(), cr.y(), &pix);
+}
+
+void MonthWidget::mousePressEvent(TQMouseEvent *e)
+{
+ int firstSelected = 0, lastSelected = 0;
+ if (e->state() != TQt::ControlButton)
+ {
+ for (int i=0; i<42; i++)
+ {
+ if (d->days[i].selected)
+ {
+ if (firstSelected==0)
+ firstSelected = i;
+ lastSelected =i;
+ }
+ d->days[i].selected = false;
+ }
+ }
+
+ TQRect r1(0, d->currh*3, d->currw, d->currh*6);
+ TQRect r2(d->currw, d->currh*3, d->currw*7, d->currh*6);
+ TQRect r3(d->currw, d->currh*2, d->currw*7, d->currh);
+
+ // Click on a weekday
+ if( r3.contains(e->pos()))
+ {
+ int j = (e->pos().x() - d->currw)/d->currw;
+ for (int i=0; i<6; i++)
+ {
+ d->days[i*7+j].selected = !d->days[i*7+j].selected;
+ }
+ }
+ // Click on a week
+ else if (r1.contains(e->pos()))
+ {
+ int j = (e->pos().y() - 3*d->currh)/d->currh;
+ for (int i=0; i<7; i++)
+ {
+ d->days[j*7+i].selected = !d->days[j*7+i].selected;
+ }
+ }
+ // Click on a day.
+ else if (r2.contains(e->pos()))
+ {
+ int i, j;
+ i = (e->pos().x() - d->currw)/d->currw;
+ j = (e->pos().y() - 3*d->currh)/d->currh;
+ if (e->state() == TQt::ShiftButton)
+ {
+ int endSelection = j*7+i;
+ if (endSelection > firstSelected)
+ for (int i2=firstSelected ; i2 <= endSelection; i2++)
+ d->days[i2].selected = true;
+ else if (endSelection < firstSelected)
+ for (int i2=lastSelected ; i2 >= endSelection; i2--)
+ d->days[i2].selected = true;
+ }
+ else
+ d->days[j*7+i].selected = !d->days[j*7+i].selected;
+ }
+
+ TQValueList<TQDateTime> filterDays;
+ for (int i=0; i<42; i++)
+ {
+ if (d->days[i].selected && d->days[i].day != -1)
+ filterDays.append(TQDateTime(TQDate(d->year, d->month, d->days[i].day), TQTime()));
+ }
+
+ AlbumLister::instance()->setDayFilter(filterDays);
+
+ update();
+}
+
+void MonthWidget::setActive(bool val)
+{
+ if (d->active == val)
+ return;
+
+ d->active = val;
+
+ if (d->active)
+ {
+ connect(AlbumLister::instance(), TQ_SIGNAL(signalNewItems(const ImageInfoList&)),
+ this, TQ_SLOT(slotAddItems(const ImageInfoList&)));
+
+ connect(AlbumLister::instance(), TQ_SIGNAL(signalDeleteItem(ImageInfo*)),
+ this, TQ_SLOT(slotDeleteItem(ImageInfo*)));
+ }
+ else
+ {
+ TQDate date = TQDate::currentDate();
+ setYearMonth(date.year(), date.month());
+ AlbumLister::instance()->setDayFilter(TQValueList<TQDateTime>());
+
+ disconnect(AlbumLister::instance());
+ }
+}
+
+void MonthWidget::slotAddItems(const ImageInfoList& items)
+{
+ if (!d->active)
+ return;
+
+ ImageInfo* item;
+ for (ImageInfoListIterator it(items); (item = it.current()); ++it)
+ {
+ TQDateTime dt = item->dateTime();
+
+ for (int i=0; i<42; i++)
+ {
+ if (d->days[i].day == dt.date().day())
+ {
+ d->days[i].active = true;
+ d->days[i].numImages++;
+ break;
+ }
+ }
+ }
+
+ update();
+}
+
+void MonthWidget::slotDeleteItem(ImageInfo* item)
+{
+ if (!d->active || !item)
+ return;
+
+ TQDateTime dt = item->dateTime();
+
+ for (int i=0; i<42; i++)
+ {
+ if (d->days[i].day == dt.date().day())
+ {
+ d->days[i].numImages--;
+ if (d->days[i].numImages <= 0)
+ {
+ d->days[i].active = false;
+ d->days[i].numImages = 0;
+ }
+
+ break;
+ }
+ }
+
+ update();
+}
+
+} // namespace Digikam