/* ============================================================ * * 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 * Copyright (C) 2006-2007 by Gilles Caulier * * 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 #include #include #include #include // KDE includes. #include #include #include #include // 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::tqcurrentDate(); 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::tqsizeHint() 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 = tqcolorGroup(); 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 = KGlobal::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, KGlobal::locale()->calendar()->weekDayName(i, true) .remove(2,1)); #else p.drawText(rsmall, TQt::AlignVCenter|TQt::AlignHCenter, KGlobal::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") .tqarg(KGlobal::locale()->calendar()->monthName(d->month, false)) .tqarg(KGlobal::locale()->calendar()->year(TQDate(d->year,d->month,1)))); #else p.drawText(r, TQt::AlignCenter, TQString("%1 %2") .tqarg(KGlobal::locale()->monthName(d->month)) .tqarg(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 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(), TQT_SIGNAL(signalNewItems(const ImageInfoList&)), this, TQT_SLOT(slotAddItems(const ImageInfoList&))); connect(AlbumLister::instance(), TQT_SIGNAL(signalDeleteItem(ImageInfo*)), this, TQT_SLOT(slotDeleteItem(ImageInfo*))); } else { TQDate date = TQDate::tqcurrentDate(); setYearMonth(date.year(), date.month()); AlbumLister::instance()->setDayFilter(TQValueList()); 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