📄 dayview.cpp
字号:
/************************************************************************ Copyright (C) 2000-2002 Trolltech AS. All rights reserved.**** This file is part of the Qtopia Environment.**** This file may be distributed and/or modified under the terms of the** GNU General Public License version 2 as published by the Free Software** Foundation and appearing in the file LICENSE.GPL included in the** packaging of this file.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.**** See http://www.trolltech.com/gpl/ for GPL licensing information.**** Contact info@trolltech.com if any conditions of this licensing are** not clear to you.************************************************************************/#include "dayview.h"#include "dayviewheaderimpl.h"#include "layoutmanager.h"#include "datebookdb.h"#ifdef Q_WS_QWS#include <qtopia/ir.h>#endif#ifdef QTOPIA_DESKTOP#include <common/iconloader.h>#endif#include <qtopia/resource.h>#include <qtopia/qpeapplication.h>#include <qtopia/timestring.h>#include <qtopia/qpedebug.h>#include <qheader.h>#include <qdatetime.h>#include <qpainter.h>#include <qsimplerichtext.h>#include <qpopupmenu.h>#include <qtextcodec.h>#include <qpalette.h>#include <qabstractlayout.h>#include <qlayout.h>#include <qregexp.h>#include <qstyle.h>#include <qtimer.h>static const int short_time_height = 20;static int day_height = 18;inline QRect expandRect(QRect r){ QRect nr(r.x() - 1, r.y() - 1, r.width() + 1, r.height() + 1); return nr;}class DayItem : public LayoutItem{public: DayItem(const QDate &referenceDate, const Occurrence &ev) : LayoutItem(ev) , hasFocus(FALSE) { // why would someone use "<"? Oh well, fix it up... // I wonder what other things may be messed up... QString strDesc = ev.event().description(); int where = strDesc.find( "<" ); while ( where != -1 ) { strDesc.remove( where, 1 ); strDesc.insert( where, "<" ); where = strDesc.find( "<", where ); } QString strCat; // ### Fix later... // QString strCat = ev.category(); // where = strCat.find( "<" ); // while ( where != -1 ) { // strCat.remove( where, 1 ); // strCat.insert( where, "<" ); // where = strCat.find( "<", where ); // } QString strNote = ev.event().notes(); where = strNote.find( "<" ); while ( where != -1 ) { strNote.remove( where, 1 ); strNote.insert( where, "<" ); where = strNote.find( "<", where ); } headingText = "<b>" + strDesc + "</b><br>"; if (ev.event().timeZone().isValid()) { noteTZ=ev.event().timeZone().id(); // ########### translate with new TZ class, not this mess int i = noteTZ.find('/'); noteTZ = noteTZ.mid( i + 1 ); noteTZ = noteTZ.replace(QRegExp("_"), " "); } noteStart = ev.event().start(); noteEnd = ev.event().end(); noteShowStartDate = referenceDate != ev.date(); noteShowEndDate = referenceDate != ev.endDate(); noteStr = strNote; //setBackgroundMode( PaletteBase ); } ~DayItem() { } void setFocus(bool b) { hasFocus = b; } void drawItem( QPainter *p, int x, int y, const QColorGroup &cg ) { p->save(); QRect r = expandRect(geometry()); x += r.x(); y += r.y(); int w = r.width(); int h = r.height(); p->setBrush(event().color().light(175)); if (hasFocus) { p->setPen( QPen(QColor(0,0,0)) ); p->drawRect( x, y, w, h ); p->drawRect( x + 1, y + 1, w - 2, h - 2 ); } else { p->setPen( QColor(100, 100, 100) ); p->drawRect( x, y, w, h ); } // now for the inner rect; x += 4; w -= 8; y += 2; h -= 4; int d = 0; loadPMs(); if ( event().hasAlarm() ) { p->drawPixmap( x + w - 13, y, pm_alarmbell ); d += 17; } if ( event().hasRepeat() ) { p->drawPixmap( x + w - 13 - d, y, pm_repeat ); d += 17; } else if ( event().isException() ) { p->drawPixmap( x + w - 13 - d, y, pm_repeatE ); d += 17; } QSimpleRichText rt( headingText, p->font() ); QString noteText; if (!noteTZ.isEmpty()) noteText = "<b>"+DayViewContents::tr("Time zone:")+"</b> " + noteTZ + "<br>"; noteText += "<b>" + DayViewContents::tr("Start") + "</b>: "; if ( noteShowStartDate ) { // multi-day event. Show start date noteText += TimeString::localYMD( noteStart.date(), TimeString::Long ); } else { // Show start time. noteText += TimeString::localHM( noteStart.time() ); } noteText += "<br><b>" + DayViewContents::tr("End") + "</b>: "; if ( noteShowEndDate ) { // multi-day event. Show end date noteText += TimeString::localYMD( noteEnd.date(), TimeString::Long ); } else { // Show end time. noteText += TimeString::localHM( noteEnd.time() ); } noteText += "<br><br>" + noteStr; QSimpleRichText rtNotes( noteText, p->font() ); // modified clip region for rt. // better to clip than to draw over our icons. QRect rect(x, y, w - d, h); rt.setWidth( w - d ); rtNotes.setWidth( w ); p->setClipRect(p->xForm(QRect(x,y,w,h))); rtNotes.draw( p, x, y + rt.height(), QRegion(x, y, w, h), cg ); p->setClipRect(p->xForm(rect)); rt.draw( p, x, y, QRegion(rect), cg ); p->restore(); }private: void loadPMs() { if ( pm_repeat.isNull() ) { pm_repeat = Resource::loadIconSet("repeat").pixmap();#ifdef QTOPIA_DESKTOP pm_repeatE = IconLoader::loadPixmap("repeatException"); pm_alarmbell = IconLoader::loadPixmap("smallalarm");#else pm_repeatE = Resource::loadIconSet("repeatException").pixmap(); pm_alarmbell = Resource::loadIconSet("smallalarm").pixmap();#endif } } QPixmap pm_repeat, pm_alarmbell, pm_repeatE; QString headingText; QString noteTZ; QDateTime noteStart; QDateTime noteEnd; bool noteShowStartDate; bool noteShowEndDate; QString noteStr; bool hasFocus;};class DayViewLayout : public LayoutManager{public: DayViewLayout(int w, int h) : LayoutManager(w,h), fItem(0) { } void clear() { fItem = 0; LayoutManager::clear(); } DayItem *focusedItem() const { return fItem; }; void setFocusedItem(DayItem *i) { if (fItem) fItem->setFocus(FALSE); fItem = 0; if (i && items().containsRef(i)) { i->setFocus(TRUE); fItem = i; } } virtual DayItem *firstItem() { if (fItem) fItem->setFocus(FALSE); if (items().size() > 0) { // really should be 'top' item, most to left. fItem = (DayItem *)items().at(0); fItem->setFocus(TRUE); } else fItem = 0; return fItem; } virtual DayItem *nextItem() { if (fItem) fItem->setFocus(FALSE); else return 0; int pos = items().findRef(fItem); pos++; if (pos >= (int)items().count()) { fItem = 0; } else { fItem = (DayItem *)items().at(pos); fItem->setFocus(TRUE); } return fItem; } virtual DayItem *previousItem() { if (fItem) fItem->setFocus(FALSE); else return 0; int pos = items().findRef(fItem); pos--; if (pos < 0 || items().count() < 1) { fItem = 0; } else { fItem = (DayItem *)items().at(pos); fItem->setFocus(TRUE); } return fItem; } virtual DayItem *lastItem() { if (fItem) fItem->setFocus(FALSE); if (items().size() > 0) { // really should be 'top' item, most to left. fItem = (DayItem *)items().at(items().size()-1); fItem->setFocus(TRUE); } else fItem = 0; return fItem; } void addOccurrence(Occurrence &e, const QDate &cDate ) { DayItem *di = new DayItem(cDate, e); initializeGeometry(di); addItem(di); }protected: DayItem *fItem;};class AllDayLayout : public DayViewLayout{public: AllDayLayout(int w, int h) : DayViewLayout(w,h) { } void layoutItems(bool = FALSE) { for ( int i = 0; i < count(); i++) { LayoutItem *w = items().at(i); // one under the other, full width. QRect geom = w->geometry(); geom.setX( i % 2 ? size().width() / 2 : 0 ); geom.setY( day_height * (i / 2) ); int width = size().width() - (size().width() % 2); // round down to even. int day_width = i % 2 == 0 && i == count() - 1 ? size().width() : width / 2; if ( i % 2 ) day_width += size().width() % 2; // round up the second item. geom.setWidth( day_width ); geom.setHeight( day_height ); w->setGeometry(geom); } }};/* // Preserved since we may need to take this algorithm laterstatic int place( const DayViewWidget *item, bool *used, int maxn ){ int place = 0; int start = item->event().start().hour(); QTime e = item->event().end(); int end = e.hour(); if ( e.minute() < 5 ) end--; if ( end < start ) end = start; while ( place < maxn ) { bool free = TRUE; int s = start; while( s <= end ) { if ( used[10*s+place] ) { free = FALSE; break; } s++; } if ( free ) break; place++; } if ( place == maxn ) { return -1; } while( start <= end ) { used[10*start+place] = TRUE; start++; } return place;}*/DayViewContents::DayViewContents( Type t, QWidget *parent, const char *name ) : QScrollView( parent, name, WRepaintNoErase ), typ(t), start_of_day(8), time_height(short_time_height){ setResizePolicy(Manual); startSel = endSel = -1; dragging = FALSE; QFontMetrics fm( font() ); time_width = fm.width( TimeString::hourString(12,TRUE)+" " )+2; time_height = fm.height(); day_height = fm.height() + 5;#ifdef QTOPIA_DESKTOP day_height += 2; // difference in font metrics?#endif setHScrollBarMode(AlwaysOff); if (typ == AllDay) { setMargins(0, 0, 0, 0); setBackgroundMode(PaletteDark); itemList = new AllDayLayout(contentsWidth(), contentsHeight()); } else { itemList = new DayViewLayout(contentsWidth() - time_width, contentsHeight()); } viewport()->setBackgroundColor( white ); visibleTimer = new QTimer( this ); connect( visibleTimer, SIGNAL(timeout()), this, SLOT(makeVisible()) ); TimeString::connectChange(this,SLOT(timeStringChanged()));}DayViewContents::~DayViewContents(){ clearItems(); delete itemList;}void DayViewContents::addOccurrence(Occurrence &ev, const QDate &cDate){ itemList->addOccurrence(ev, cDate); if (typ == AllDay) { resizeContents( itemList->count() > 4 ? width() - style().scrollBarExtent().width() : width(), day_height * ((itemList->count() + 1) / 2 )); itemList->setSize( contentsWidth() - (typ == AllDay ? 0 : time_width) - 1, contentsHeight()); }}void DayViewContents::clearItems(){ itemList->clear(); itemList->setFocusedItem(0);}void DayViewContents::layoutItems(){ itemList->layoutItems(TRUE); updateContents(0, 0, contentsWidth(), contentsHeight());}void DayViewContents::timeStringChanged(){ updateContents(0, 0, contentsWidth(), contentsHeight());}void DayViewContents::clearSelectedTimes(){ int oldSelMin = QMIN(startSel, endSel); int oldSelMax = QMAX(startSel, endSel); startSel = endSel = -1; repaintContents(0, posOfHour(oldSelMin - 1), time_width, posOfHour(oldSelMax + 1), FALSE);}void DayViewContents::startAtTime(int t){ start_of_day = t; if (typ != AllDay) setContentsPos(0, posOfHour(t));}void DayViewContents::selectDate(const QDate &d){ itemList->setDate(d); showStartTime();}void DayViewContents::showStartTime(){ setContentsPos(0, posOfHour(start_of_day));}DayItem *DayViewContents::firstItem( bool show ){ DayItem *orig = itemList->focusedItem(); DayItem *dim = itemList->firstItem(); if (orig != dim && show) moveSelection( orig, dim ); return dim;}DayItem *DayViewContents::lastItem( bool show ){ DayItem *orig = itemList->focusedItem(); DayItem *dim = itemList->lastItem(); if (orig != dim && show ) moveSelection( orig, dim ); return dim;}DayItem *DayViewContents::nextItem( bool show ){ DayItem *orig = itemList->focusedItem(); DayItem *dim = itemList->nextItem(); if (orig != dim && show ) moveSelection( orig, dim ); return dim;}DayItem *DayViewContents::previousItem( bool show ){ DayItem *orig = itemList->focusedItem(); DayItem *dim = itemList->previousItem(); if (orig != dim && show ) moveSelection( orig, dim ); return dim;}DayItem *DayViewContents::currentItem() const{ return itemList->focusedItem();}void DayViewContents::setCurrentItem(DayItem *dim, bool show){ DayItem *orig = itemList->focusedItem(); if (dim && dim != orig) itemList->setFocusedItem(dim); if (show) moveSelection( orig, dim );}void DayViewContents::moveSelection( DayItem *from, DayItem *to ){ if (to) { QRect r = expandRect(to->geometry()); if (typ != AllDay) r.moveBy(time_width, 0); visRect = r; visibleTimer->start(5, TRUE); updateContents(r.x(),r.y(), r.width(), r.height()); } if (from && from != to) { QRect ogr = expandRect(from->geometry()); if (typ != AllDay) ogr.moveBy(time_width, 0); updateContents(ogr.x(),ogr.y(), ogr.width(), ogr.height()); }}void DayViewContents::makeVisible(){ if ( visRect.x() < 0 || visRect.y() < 0 || visRect.width() < 0 || visRect.height() < 0 ) return; int cx = visRect.x() + visRect.width()/2; int cy = visRect.y() + visRect.height()/2; ensureVisible( cx, cy, visRect.width()/2+5, visRect.height()/2+5 );}void DayViewContents::moveUp(){ scrollBy(0, -20);}void DayViewContents::moveDown(){ scrollBy(0, 20);}void DayViewContents::resizeEvent( QResizeEvent * ){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -