Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

datebookday.cpp

Go to the documentation of this file.
00001 /*
00002                              This file is part of the Opie Project
00003 
00004                              Copyright (C) Opie Team <opie-devel@handhelds.org>
00005               =.
00006             .=l.
00007            .>+-=
00008  _;:,     .>    :=|.         This program is free software; you can
00009 .> <`_,   >  .   <=          redistribute it and/or  modify it under
00010 :`=1 )Y*s>-.--   :           the terms of the GNU Library General Public
00011 .="- .-=="i,     .._         License as published by the Free Software
00012  - .   .-<_>     .<>         Foundation; either version 2 of the License,
00013      ._= =}       :          or (at your option) any later version.
00014     .%`+i>       _;_.
00015     .i_,=:_.      -<s.       This program is distributed in the hope that
00016      +  .  -:.       =       it will be useful,  but WITHOUT ANY WARRANTY;
00017     : ..    .:,     . . .    without even the implied warranty of
00018     =_        +     =;=|`    MERCHANTABILITY or FITNESS FOR A
00019   _.=:.       :    :=>`:     PARTICULAR PURPOSE. See the GNU
00020 ..}^=.=       =       ;      Library General Public License for more
00021 ++=   -.     .`     .:       details.
00022 :     =  ...= . :.=-
00023  -.   .:....=;==+<;          You should have received a copy of the GNU
00024   -_. . .   )=.  =           Library General Public License along with
00025     --        :-=`           this library; see the file COPYING.LIB.
00026                              If not, write to the Free Software Foundation,
00027                              Inc., 59 Temple Place - Suite 330,
00028                              Boston, MA 02111-1307, USA.
00029 */
00030 
00031 #include "datebookday.h"
00032 #include "datebooktypes.h"
00033 #include "datebookdayheaderimpl.h"
00034 #include "datebookdayallday.h"
00035 
00036 #include <opie2/oholidayplugin.h>
00037 #include <opie2/oresource.h>
00038 
00039 #include <qpe/applnk.h>
00040 #include <qpe/ir.h>
00041 #include <qpe/qpeapplication.h>
00042 
00043 #include <qsimplerichtext.h>
00044 #include <qpopupmenu.h>
00045 
00046 
00047 #include <qtimer.h>
00048 
00049 DateBookDayView::DateBookDayView( bool whichClock, QWidget *parent, const char *name )
00050     : QTable( 24, 1, parent, name ), ampm( whichClock ), currDate( QDate::currentDate() )
00051 {
00052     enableClipper(TRUE);
00053     setTopMargin( 0 );
00054     horizontalHeader()->hide();
00055     setLeftMargin(38);
00056     setColumnStretchable( 0, TRUE );
00057     setHScrollBarMode( QScrollView::AlwaysOff );
00058     verticalHeader()->setPalette(white);
00059     verticalHeader()->setResizeEnabled(FALSE);
00060     setSelectionMode( Single );
00061 
00062     // get rid of being able to edit things...
00063     QTableItem *tmp;
00064     int row;
00065     for ( row = 0; row < numRows(); row++ ) {
00066         tmp = new QTableItem( this, QTableItem::Never, QString::null);
00067         setItem( row, 0, tmp );
00068         //setRowHeight( row, 40);
00069     }
00070 
00071     initHeader();
00072     QObject::connect( qApp, SIGNAL(clockChanged(bool)), this, SLOT(slotChangeClock(bool)) );
00073 }
00074 
00075 void DateBookDayView::initHeader()
00076 {
00077     QString strTmp;
00078     int preferredWidth = 0;
00079     for ( int i = 0; i < 24; ++i ) {
00080         if ( ampm ) {
00081             if ( i == 0 )
00082             strTmp = QString::number(12) + ":00";
00083             else if ( i == 12 )
00084             strTmp = QString::number(12) + tr(":00p");
00085             else if ( i > 12 )
00086             strTmp = QString::number( i - 12 ) + tr(":00p");
00087             else
00088             strTmp = QString::number(i) + ":00";
00089         } else {
00090             if ( i < 10 )
00091             strTmp = "0" + QString::number(i) + ":00";
00092             else
00093             strTmp = QString::number(i) + ":00";
00094         }
00095         strTmp = strTmp.rightJustify( 6, ' ' );
00096         verticalHeader()->setLabel( i, strTmp );
00097 
00098         // Compute correct width for current Font (Add some space right)
00099         int actWidth = QFontMetrics( QFont::defaultFont() ).width( strTmp + QString("  ") );
00100         if ( preferredWidth < actWidth )
00101             preferredWidth = actWidth;
00102         setRowStretchable( i, FALSE );
00103     }
00104 
00105     // It seems as if the header has a bug. It does not resize
00106     // correct horizontally if it is used vertical..
00107     // Thus, we do it manually..
00108     setLeftMargin( preferredWidth );
00109 }
00110 
00111 void DateBookDayView::slotDateChanged( int y, int m, int d )
00112 {
00113     currDate.setYMD(y,m,d);
00114 }
00115 
00116 void DateBookDayView::slotChangeClock( bool newClock )
00117 {
00118     ampm = newClock;
00119     initHeader();
00120 }
00121 
00122 bool DateBookDayView::whichClock() const
00123 {
00124     return ampm;
00125 }
00126 
00127 void DateBookDayView::moveUp()
00128 {
00129     scrollBy(0, -20);
00130 }
00131 
00132 void DateBookDayView::moveDown()
00133 {
00134     scrollBy(0, 20);
00135 }
00136 
00137 void DateBookDayView::paintCell( QPainter *p, int, int, const QRect &cr, bool )
00138 {
00139     int w = cr.width();
00140     int h = cr.height();
00141     p->fillRect( 0, 0, w, h, colorGroup().brush( QColorGroup::Base ) );
00142     if ( showGrid() ) {
00143         // Draw our lines
00144         int x2 = w - 1;
00145         int y2 = h - 1;
00146         QPen pen( p->pen() );
00147         p->setPen( colorGroup().dark() );
00148         p->drawLine( x2, 0, x2, y2 );
00149         p->drawLine( 0, y2, x2, y2 );
00150 
00151         p->setPen( colorGroup().midlight() );
00152         p->drawLine( 0, y2 - h/2, x2, y2 - h/2);
00153 
00154         p->setPen( pen );
00155     }
00156 }
00157 
00158 void DateBookDayView::paintFocus( QPainter *, const QRect & )
00159 {
00160 }
00161 
00162 void DateBookDayView::resizeEvent( QResizeEvent *e )
00163 {
00164     QTable::resizeEvent( e );
00165     columnWidthChanged( 0 );
00166     emit sigColWidthChanged();
00167 }
00168 
00169 void DateBookDayView::keyPressEvent( QKeyEvent *e )
00170 {
00171     QString txt = e->text();
00172     if ( !txt.isNull() && txt[0] > ' ' && e->key() < 0x1000 ) {
00173         // we this is some sort of thing we know about...
00174         e->accept();
00175         emit sigCapturedKey( txt );
00176     } else {
00177         // I don't know what this key is, do you?
00178         e->ignore();
00179     }
00180 }
00181 
00182 void DateBookDayView::setRowStyle( int style )
00183 {
00184     if (style<0) style = 0;
00185 
00186     for (int i=0; i<numRows(); i++)
00187         setRowHeight(i, style*10+20);
00188 }
00189 
00190 void DateBookDayView::contentsMouseReleaseEvent( QMouseEvent* /* e */ )
00191 {
00192     int sh=99,eh=-1;
00193 
00194     for(int i=0;i<this->numSelections();i++) {
00195         QTableSelection sel = this->selection( i );
00196         sh = QMIN(sh,sel.topRow());
00197         eh = QMAX(sh,sel.bottomRow()+1);
00198     }
00199     if (sh > 23 || eh < 1) {
00200         sh=8;
00201         eh=9;
00202     }
00203 
00204     quickLineEdit=new DateBookDayViewQuickLineEdit(QDateTime(currDate,QTime(sh,0,0,0)),QDateTime(currDate,QTime(eh,0,0,0)),this->viewport(),"quickedit");
00205     quickLineEdit->setGeometry(0,0,this->columnWidth(0)-1,this->rowHeight(0));
00206     this->moveChild(quickLineEdit,0,sh*this->rowHeight(0));
00207     quickLineEdit->setFocus();
00208     quickLineEdit->show();
00209 }
00210 
00211 //===========================================================================
00212 
00213 DateBookDayViewQuickLineEdit::DateBookDayViewQuickLineEdit(const QDateTime &start, const QDateTime &end,QWidget * parent, const char *name) : QLineEdit(parent,name)
00214 {
00215     active=1;
00216     quickEvent.setStart(start);
00217     quickEvent.setEnd(end);
00218     connect(this,SIGNAL(returnPressed()),this,SLOT(slotReturnPressed()));
00219 }
00220 
00221 void DateBookDayViewQuickLineEdit::slotReturnPressed()
00222 {
00223     if(active && (!this->text().isEmpty())) {   // Fix to avoid having this event beeing added multiple times.
00224         quickEvent.setDescription(this->text());
00225         connect(this,SIGNAL(insertEvent(const Event&)),this->topLevelWidget(),SLOT(insertEvent(const Event&)));
00226         emit(insertEvent(quickEvent));
00227         active=0;
00228     }
00229         /* we need to return to this object.. */
00230     QTimer::singleShot(500, this, SLOT(finallyCallClose())  );  // Close and also delete this widget
00231 }
00232 void DateBookDayViewQuickLineEdit::finallyCallClose() {
00233     close(true); // also deletes this widget...
00234 }
00235 
00236 void DateBookDayViewQuickLineEdit::focusOutEvent ( QFocusEvent* /* e */)
00237 {
00238     slotReturnPressed(); // Reuse code to add event and close this widget.
00239 }
00240 
00241 //===========================================================================
00242 
00243 DateBookDay::DateBookDay( bool ampm, bool startOnMonday, DateBookDBHoliday *newDb, DateBookHoliday*newHdb, QWidget *parent, const char *name )
00244     : QVBox( parent, name ), currDate( QDate::currentDate() ), db( newDb ), startTime( 0 )
00245 {
00246     widgetList.setAutoDelete( true );
00247     _holiday_db = newHdb;
00248     header = new DateBookDayHeader( startOnMonday, this, "day header" );
00249     header->setDate( currDate.year(), currDate.month(), currDate.day() );
00250 
00251     m_allDays = new DatebookdayAllday(newDb, this, "all day event list" );
00252     m_allDays->hide();
00253 
00254     view = new DateBookDayView( ampm, this, "day view" );
00255 
00256     connect( header, SIGNAL( dateChanged(int,int,int) ), this, SLOT( dateChanged(int,int,int) ) );
00257     connect( header, SIGNAL( dateChanged(int,int,int) ), view, SLOT( slotDateChanged(int,int,int) ) );
00258     connect( view, SIGNAL( sigColWidthChanged() ), this, SLOT( slotColWidthChanged() ) );
00259     connect( qApp, SIGNAL(weekChanged(bool)), this, SLOT(slotWeekChanged(bool)) );
00260     connect( view, SIGNAL(sigCapturedKey(const QString&)), this, SIGNAL(sigNewEvent(const QString&)) );
00261 
00262     QTimer *timer = new QTimer( this );
00263 
00264     connect( timer, SIGNAL(timeout()), this, SLOT(updateView()) );  //connect timer for updating timeMarker & daywidgetcolors
00265     timer->start( 1000*60*5, FALSE ); //update every 5min
00266 
00267     selectedWidget = 0;
00268 
00269     timeMarker =  new DateBookDayTimeMarker( this );
00270     timeMarker->setTime( QTime::currentTime() );
00271     rowStyle = -1; // initialize with bogus values
00272         jumpToCurTime = false;
00273 }
00274 
00275 void DateBookDay::setJumpToCurTime( bool bJump )
00276 {
00277     jumpToCurTime = bJump;
00278 }
00279 
00280 void DateBookDay::setRowStyle( int style )
00281 {
00282     if (rowStyle != style) view->setRowStyle( style );
00283     rowStyle = style;
00284 }
00285 
00286 void DateBookDay::updateView( void )
00287 {
00288     timeMarker->setTime( QTime::currentTime() );
00289     //need to find a way to update all DateBookDayWidgets
00290 }
00291 
00292 void DateBookDay::setSelectedWidget( DateBookDayWidget *w )
00293 {
00294     selectedWidget = w;
00295 }
00296 
00297 DateBookDayWidget * DateBookDay::getSelectedWidget( void )
00298 {
00299     return selectedWidget;
00300 }
00301 
00302 void DateBookDay::selectedDates( QDateTime &start, QDateTime &end )
00303 {
00304     start.setDate( currDate );
00305     end.setDate( currDate );
00306 
00307     int sh=99,eh=-1;
00308 
00309     int n = dayView()->numSelections();
00310 
00311     for (int i=0; i<n; i++) {
00312         QTableSelection sel = dayView()->selection( i );
00313         sh = QMIN(sh,sel.topRow());
00314         eh = QMAX(sh,sel.bottomRow()+1);
00315     }
00316 
00317     if (sh > 23 || eh < 1) {
00318         sh=8;
00319         eh=9;
00320     }
00321 
00322     start.setTime( QTime( sh, 0, 0 ) );
00323     end.setTime( QTime( eh, 0, 0 ) );
00324 }
00325 
00326 void DateBookDay::setDate( int y, int m, int d )
00327 {
00328     header->setDate( y, m, d );
00329     selectedWidget = 0;
00330 }
00331 
00332 void DateBookDay::setDate( QDate d)
00333 {
00334     header->setDate( d.year(), d.month(), d.day() );
00335     selectedWidget = 0;
00336 }
00337 
00338 void DateBookDay::dateChanged( int y, int m, int d )
00339 {
00340     QDate date( y, m, d );
00341     if ( currDate == date )
00342         return;
00343     currDate.setYMD( y, m, d );
00344     relayoutPage();
00345     dayView()->clearSelection();
00346     QTableSelection ts;
00347 
00348     if (jumpToCurTime && this->date() == QDate::currentDate())
00349     {
00350         ts.init( QTime::currentTime().hour(), 0);
00351         ts.expandTo( QTime::currentTime().hour(), 0);
00352     } else {
00353         ts.init( startTime, 0 );
00354         ts.expandTo( startTime, 0 );
00355     }
00356 
00357     dayView()->addSelection( ts );
00358     selectedWidget = 0;
00359 }
00360 
00361 void DateBookDay::redraw()
00362 {
00363     if ( isUpdatesEnabled() )
00364         relayoutPage();
00365 }
00366 
00367 void DateBookDay::getEvents()
00368 {
00369     widgetList.clear();
00370 
00371         /* clear the AllDay List */
00372         m_allDays->hide(); // just in case
00373         m_allDays->removeAllEvents();
00374 
00375     QStringList hdays = _holiday_db->holidaylist(currDate);
00376     QStringList::Iterator sit;
00377     QObject* object = 0;
00378 
00379     /* this way we make sure that holiday dummy events are always
00380        on top of the widgetlist. */
00381     for (sit=hdays.begin();sit!=hdays.end();++sit) {
00382         m_allDays->addHoliday(*sit);
00383     }
00384     QValueList<EffectiveEvent> eventList = db->getEffectiveEventsNoHoliday( currDate, currDate );
00385     QValueListIterator<EffectiveEvent> it;
00386 
00387     for ( it = eventList.begin(); it != eventList.end(); ++it ) {
00388         EffectiveEvent ev=*it;
00389         if(!((ev.end().hour()==0) && (ev.end().minute()==0) && (ev.startDate()!=ev.date()))) {  // Skip events ending at 00:00 starting at another day.
00390                     if (ev.event().type() == Event::AllDay ) {
00391                         object = m_allDays->addEvent( ev );
00392                         if (!object)
00393                             continue;
00394                     }else {
00395             DateBookDayWidget* w = new DateBookDayWidget( *it, this );
00396                         widgetList.append( w );
00397                         object = w;
00398                     }
00399 
00400                     connect( object, SIGNAL( deleteMe(const Event&) ), this, SIGNAL( removeEvent(const Event&) ) );
00401                     connect( object, SIGNAL( duplicateMe(const Event&) ), this, SIGNAL( duplicateEvent(const Event&) ) );
00402                     connect( object, SIGNAL( editMe(const Event&) ), this, SIGNAL( editEvent(const Event&) ) );
00403                     connect( object, SIGNAL( beamMe(const Event&) ), this, SIGNAL( beamEvent(const Event&) ) );
00404 
00405         }
00406     }
00407 }
00408 
00409 static int place( const DateBookDayWidget *item, bool *used, int maxn )
00410 {
00411     int place = 0;
00412     int start = item->event().start().hour();
00413     QTime e = item->event().end();
00414     int end = e.hour();
00415     if ( e.minute() < 5 )
00416         end--;
00417     if ( end < start )
00418         end = start;
00419     while ( place < maxn ) {
00420         bool free = TRUE;
00421         int s = start;
00422         while( s <= end ) {
00423             if ( used[10*s+place] ) {
00424                 free = FALSE;
00425                 break;
00426             }
00427             s++;
00428         }
00429         if ( free )
00430             break;
00431         place++;
00432     }
00433     if ( place == maxn ) {
00434         return -1;
00435     }
00436     while( start <= end ) {
00437         used[10*start+place] = TRUE;
00438         start++;
00439     }
00440     return place;
00441 }
00442 
00443 
00444 void DateBookDay::relayoutPage( bool fromResize )
00445 {
00446     setUpdatesEnabled( FALSE );
00447     if ( !fromResize ) {
00448         getEvents();    // no need we already have them!
00449 
00450                 if (m_allDays->items() > 0 )
00451                     m_allDays->show();
00452                 /*
00453                  * else if ( m_allDays->items() ==  0 ) already hide in getEvents
00454                  */
00455         }
00456 
00457     widgetList.sort();
00458     //sorts the widgetList by the heights of the widget so that the tallest widgets are at the beginning
00459     //this is needed for the simple algo below to work correctly, otherwise some widgets would be drawn outside the view
00460 
00461     int wCount = widgetList.count();
00462     int wid = view->columnWidth(0)-1;
00463     int wd;
00464     int n = 1;
00465 
00466     QArray<int> anzIntersect(wCount); //this stores the number of maximal intersections of each widget
00467 
00468     for (int i = 0; i<wCount; anzIntersect[i] = 1, i++);
00469 
00470     if ( wCount < 20 ) {
00471 
00472         QArray<QRect> geometries(wCount);
00473         for (int i = 0; i < wCount; geometries[i] = widgetList.at(i)->geometry(), i++); //stores geometry for each widget in vector
00474 
00475         for ( int i = 0; i < wCount; i++) {
00476             QValueList<int> intersectedWidgets;
00477 
00478             //find all widgets intersecting with widgetList.at(i)
00479             for ( int j = 0; j < wCount; j++) {
00480                 if (i != j)
00481                     if (geometries[j].intersects(geometries[i]))
00482                         intersectedWidgets.append(j);
00483             }
00484 
00485             //for each of these intersecting widgets find out how many widgets are they intersecting with
00486             for ( uint j = 0; j < intersectedWidgets.count(); j++)
00487             {
00488                 QArray<int> inter(wCount);
00489                 inter[j]=1;
00490 
00491                 if (intersectedWidgets[j] != -1)
00492                     for ( uint k = j; k < intersectedWidgets.count(); k++) {
00493                         if (j != k && intersectedWidgets[k] != -1)
00494                             if (geometries[intersectedWidgets[k]].intersects(geometries[intersectedWidgets[j]])) {
00495                                 inter[j]++;
00496                                 intersectedWidgets[k] = -1;
00497                             }
00498                         if (inter[j] > anzIntersect[i]) anzIntersect[i] = inter[j] + 1;
00499                     }
00500                 }
00501             if (anzIntersect[i] == 1 && intersectedWidgets.count()) anzIntersect[i]++;
00502         }
00503 
00504 
00505         for ( int i = 0; i < wCount; i++) {
00506             DateBookDayWidget *w = widgetList.at(i);
00507             QRect geom = w->geometry();
00508             geom.setX( 0 );
00509             wd = (view->columnWidth(0)-1) / anzIntersect[i] - (anzIntersect[i]>1?2:0);
00510             geom.setWidth( wd );
00511             while ( intersects( w, geom ) ) {
00512                 geom.moveBy( wd + 2 + 1, 0 );
00513             }
00514             w->setGeometry( geom );
00515         }
00516 
00517         if (jumpToCurTime && this->date() == QDate::currentDate()) {
00518             view->setContentsPos( 0, QTime::currentTime().hour() * view->rowHeight(0) ); //set listview to current hour
00519         } else {
00520             view->setContentsPos( 0, startTime * view->rowHeight(0) );
00521         }
00522     } else {
00523         int hours[24];
00524         memset( hours, 0, 24*sizeof( int ) );
00525         bool overFlow = FALSE;
00526         for ( int i = 0; i < wCount; i++ ) {
00527             DateBookDayWidget *w = widgetList.at(i);
00528             int start = w->event().start().hour();
00529             QTime e = w->event().end();
00530             int end = e.hour();
00531             if ( e.minute() < 5 )
00532                 end--;
00533             if ( end < start )
00534                 end = start;
00535             while( start <= end ) {
00536                 hours[start]++;
00537                 if ( hours[start] >= 10 )
00538                     overFlow = TRUE;
00539                 ++start;
00540             }
00541             if ( overFlow )
00542                 break;
00543         }
00544         for ( int i = 0; i < 24; i++ ) {
00545             n = QMAX( n, hours[i] );
00546         }
00547         wid = ( view->columnWidth(0)-1 ) / n;
00548 
00549         bool used[24*10];
00550         memset( used, FALSE, 24*10*sizeof( bool ) );
00551 
00552         for ( int i = 0; i < wCount; i++ ) {
00553             DateBookDayWidget *w = widgetList.at(i);
00554             int xp = place( w, used, n );
00555             if ( xp != -1 ) {
00556                 QRect geom = w->geometry();
00557                 geom.setX( xp*(wid+2) );
00558                 geom.setWidth( wid );
00559                 w->setGeometry( geom );
00560             }
00561         }
00562 
00563         if (jumpToCurTime && this->date() == QDate::currentDate()) {
00564             view->setContentsPos( 0, QTime::currentTime().hour() * view->rowHeight(0) ); //set listview to current hour
00565         } else {
00566             view->setContentsPos( 0, startTime * view->rowHeight(0) );
00567         }
00568     }
00569 
00570     timeMarker->setTime( QTime::currentTime() );    //display timeMarker
00571     timeMarker->raise();                //on top of all widgets
00572     if (this->date() == QDate::currentDate()) {     //only show timeMarker on current day
00573         timeMarker->show();
00574     } else {
00575         timeMarker->hide();
00576     }
00577     setUpdatesEnabled( TRUE );
00578     return;
00579 }
00580 
00581 DateBookDayWidget *DateBookDay::intersects( const DateBookDayWidget *item, const QRect &geom )
00582 {
00583     int i = 0;
00584     DateBookDayWidget *w = widgetList.at(i);
00585     int wCount = widgetList.count();
00586     while ( i < wCount && w != item ) {
00587         if ( w->geometry().intersects( geom ) ) {
00588             return w;
00589         }
00590         w = widgetList.at(++i);
00591     }
00592 
00593     return 0;
00594 }
00595 
00596 
00597 QDate DateBookDay::date() const
00598 {
00599     return currDate;
00600 }
00601 
00602 void DateBookDay::setStartViewTime( int startHere )
00603 {
00604     startTime = startHere;
00605     dayView()->clearSelection();
00606     QTableSelection ts;
00607 
00608     if (jumpToCurTime && this->date() == QDate::currentDate()) {    //this should probably be in datebook.cpp where it's called?
00609         ts.init( QTime::currentTime().hour(), 0);
00610         ts.expandTo( QTime::currentTime().hour(), 0);
00611     } else {
00612         ts.init( startTime, 0 );
00613         ts.expandTo( startTime, 0 );
00614     }
00615 
00616     dayView()->addSelection( ts );
00617 }
00618 
00619 int DateBookDay::startViewTime() const
00620 {
00621     return startTime;
00622 }
00623 
00624 void DateBookDay::slotWeekChanged( bool bStartOnMonday )
00625 {
00626     header->setStartOfWeek( bStartOnMonday );
00627 //  redraw();
00628 }
00629 
00630 void DateBookDay::keyPressEvent(QKeyEvent *e)
00631 {
00632     switch(e->key()) {
00633         case Key_Up:
00634             view->moveUp();
00635             break;
00636         case Key_Down:
00637             view->moveDown();
00638             break;
00639         case Key_Left:
00640             setDate(QDate(currDate).addDays(-1));
00641             break;
00642         case Key_Right:
00643             setDate(QDate(currDate).addDays(1));
00644             break;
00645         default:
00646             e->ignore();
00647     }
00648 }
00649 
00650 //===========================================================================
00651 
00652 DateBookDayWidget::DateBookDayWidget( const EffectiveEvent &e, DateBookDay *db )
00653     : QWidget( db->dayView()->viewport() ), ev( e ), dateBook( db )
00654 {
00655     // why would someone use "<"?  Oh well, fix it up...
00656     // I wonder what other things may be messed up...
00657     QString strDesc = ev.description();
00658     int where = strDesc.find( "<" );
00659     while ( where != -1 ) {
00660         strDesc.remove( where, 1 );
00661         strDesc.insert( where, "&#60;" );
00662         where = strDesc.find( "<", where );
00663     }
00664 
00665     QString strCat;
00666 // ### Fix later...
00667 //     QString strCat = ev.category();
00668 //     where = strCat.find( "<" );
00669 //     while ( where != -1 ) {
00670 //  strCat.remove( where, 1 );
00671 //  strCat.insert( where, "&#60;" );
00672 //  where = strCat.find( "<", where );
00673 //     }
00674 
00675     QString strNote = ev.notes();
00676     where = strNote.find( "<" );
00677     while ( where != -1 ) {
00678         strNote.remove( where, 1 );
00679         strNote.insert( where, "&#60;" );
00680         where = strNote.find( "<", where );
00681     }
00682 
00683     text = "<b>" + strDesc + "</b><br>" + "<i>";
00684     if ( !strCat.isEmpty() )  {
00685         text += strCat + "</i><br>";
00686     }
00687     if (ev.event().type() == Event::Normal ) {
00688         setEventText( text );
00689     } else {
00690         setAllDayText( text );
00691     }
00692 
00693     text += "<br><br>" + strNote;
00694 
00695     setBackgroundMode( PaletteBase );
00696 
00697     QTime start = ev.start();
00698     QTime end = ev.end();
00699     int y = start.hour()*60+start.minute();
00700     int h = end.hour()*60+end.minute()-y;
00701     int rh = dateBook->dayView()->rowHeight(0);
00702     y = y*rh/60;
00703     h = h*rh/60;
00704 
00705     if ( h < 12 ) h = 12;   // Make sure the widget is no smaller than 12 pixels high, so that it's possible to read atleast the first line.
00706     if ( y > ((24*rh)-12) ) y=(24*rh)-12;   // Make sure the widget fits inside the dayview.
00707     geom.setY( y );
00708     geom.setHeight( h );
00709     geom.setX( 0 );
00710     geom.setWidth(dateBook->dayView()->columnWidth(0)-1);
00711 
00712 }
00713 
00714 void DateBookDayWidget::setAllDayText( QString &text ) {
00715     text += "<b>" + tr("This is an all day event.") + "</b>";
00716 }
00717 
00718 void DateBookDayWidget::setEventText( QString& text ) {
00719     bool whichClock = dateBook->dayView()->whichClock();
00720     if ( ev.startDate() != ev.endDate() ) {
00721         text += "<b>" + tr("Start") + "</b>: ";
00722         text += TimeString::timeString( ev.event().start().time(), whichClock, FALSE );
00723         text += " - " + TimeString::longDateString( ev.startDate() ) + "<br>";
00724         text += "<b>" + tr("End") + "</b>: ";
00725         text += TimeString::timeString( ev.event().end().time(), whichClock, FALSE );
00726         text += " - " + TimeString::longDateString( ev.endDate() );
00727     } else {
00728         text += "<b>" + tr("Time") + "</b>: ";
00729         text += TimeString::timeString( ev.start(), whichClock, FALSE );
00730         text += "<b>" + tr(" - ") + "</b>";
00731         text += TimeString::timeString( ev.end(), whichClock, FALSE );
00732     }
00733 }
00734 
00735 DateBookDayWidget::~DateBookDayWidget()
00736 {
00737 }
00738 
00739 void DateBookDayWidget::paintEvent( QPaintEvent *e )
00740 {
00741     QPainter p( this );
00742 
00743     if (dateBook->getSelectedWidget() == this) {
00744         p.setBrush( QColor( 155, 240, 230 ) ); // selected item
00745     } else {
00746         if (dateBook->date() == QDate::currentDate()) {
00747             QTime curTime = QTime::currentTime();
00748             if (ev.end() < curTime) {
00749                 p.setBrush( QColor( 180, 180, 180 ) ); // grey, inactive
00750             } else {
00751                 //change color in dependence of the time till the event starts
00752                 int duration = curTime.secsTo(ev.start());
00753                 if (duration < 0) duration = 0;
00754                 int colChange = duration*160/86400; //86400: secs per day, 160: max color shift
00755                 p.setBrush( QColor( 200-colChange, 200-colChange, 255 ) ); //blue
00756             }
00757         } else {
00758             p.setBrush( QColor( 220, 220, 220 ) ); //light grey, inactive (not current date)
00759             //perhaps make a distinction between future/past dates
00760         }
00761     }
00762 
00763     p.setPen( QColor(100, 100, 100) );
00764     p.drawRect(rect());
00765 
00766  //   p.drawRect(0,0, 5, height());
00767 
00768     int y = 0;
00769     int d = 0;
00770 
00771     if ( ev.event().hasAlarm() ) {
00772         p.drawPixmap( width() - AppLnk::smallIconSize(), 0,
00773                       Opie::Core::OResource::loadPixmap( "bell", Opie::Core::OResource::SmallIcon ) );
00774         y = AppLnk::smallIconSize() + 2;
00775         d = 20;
00776     }
00777 
00778     if ( ev.event().hasRepeat() ) {
00779         p.drawPixmap( width() - AppLnk::smallIconSize(), y,
00780                       Opie::Core::OResource::loadPixmap( "repeat", Opie::Core::OResource::SmallIcon ) );
00781         d = 20;
00782         y += AppLnk::smallIconSize() + 2;
00783     }
00784 
00785     QSimpleRichText rt( text, font() );
00786     rt.setWidth( geom.width() - d - 6 );
00787     rt.draw( &p, 7, 0, e->region(), colorGroup() );
00788 }
00789 
00790 /*
00791  * we need to find the real start date for a uid
00792  * we need to check from one day to another...
00793  */
00794 QDate DateBookDay::findRealStart( int uid, const QDate& isIncluded ,  DateBookDB* db) {
00795     QDate dt( isIncluded );
00796     QDate fnd = dt;
00797 
00798     bool doAgain = true;
00799     do{
00800         dt = dt.addDays( -1 );
00801         QValueList<EffectiveEvent> events = db->getEffectiveEvents( dt, dt );
00802         for (QValueList<EffectiveEvent>::Iterator it = events.begin(); it != events.end(); ++it ) {
00803             EffectiveEvent ev = (*it);
00804             if ( uid == ev.event().uid() && ev.start() != QTime(0, 0, 0 ) )
00805                 return ev.date();
00806         }
00807     }while (doAgain );
00808 
00809     return fnd;
00810 }
00811 
00812 void DateBookDayWidget::mousePressEvent( QMouseEvent *e )
00813 {
00814     DateBookDayWidget *item;
00815 
00816     item = dateBook->getSelectedWidget();
00817     if (item)
00818         item->update();
00819 
00820     dateBook->setSelectedWidget(this);
00821     update();
00822     dateBook->repaint();
00823 
00824         Event eve = ev.event();
00825 
00826     QPopupMenu m;
00827     m.insertItem( tr( "Edit" ), 1 );
00828     m.insertItem( tr( "Duplicate" ), 4 );
00829     m.insertItem( tr( "Delete" ), 2 );
00830     if(Ir::supported()) m.insertItem( tr( "Beam" ), 3 );
00831         if(Ir::supported() && ev.event().doRepeat() ) m.insertItem( tr( "Beam this occurence"), 5 );
00832     int r = m.exec( e->globalPos() );
00833     if ( r == 1 ) {
00834         emit editMe( eve );
00835     } else if ( r == 2 ) {
00836         emit deleteMe( eve );
00837     } else if ( r == 3 ) {
00838         emit beamMe( eve );
00839     } else if ( r == 4 ) {
00840         emit duplicateMe( eve );
00841     } else if ( r == 5 ) {
00842             // create an Event and beam it...
00843             /*
00844              * Start with the easy stuff. If start and  end date is the same we can just use
00845              * the values of effective events
00846              * If it is a multi day event we need to find the real start and end date...
00847              */
00848             if ( ev.event().start().date() == ev.event().end().date() ) {
00849                 Event event( ev.event() );
00850 
00851                 QDateTime dt( ev.date(), ev.start() );
00852                 event.setStart( dt );
00853 
00854                 dt.setTime( ev.end() );
00855                 event.setEnd( dt );
00856                 emit beamMe( event );
00857             }else {
00858                 /*
00859                  * at least the the Times are right now
00860                  */
00861                 QDateTime start( ev.event().start() );
00862                 QDateTime end  ( ev.event().end  () );
00863 
00864 
00865                 /*
00866                  * ok we know the start date or we need to find it
00867                  */
00868                 if ( ev.start() != QTime( 0, 0, 0 ) ) {
00869                     start.setDate( ev.date() );
00870                 }else {
00871                     QDate dt = DateBookDay::findRealStart( ev.event().uid(), ev.date(), dateBook->db );
00872                     start.setDate( dt );
00873                 }
00874 
00875 
00876                 /*
00877                  * ok we know now the end date...
00878                  * else
00879                  *   get to know the offset btw the real start and real end
00880                  *   and then add it to the new start date...
00881                  */
00882                 if ( ev.end() != QTime(23, 59, 59 ) ) {
00883                     end.setDate( ev.date() );
00884                 }else{
00885                     int days = ev.event().start().date().daysTo( ev.event().end().date() );
00886                     end.setDate( start.date().addDays( days ) );
00887                 }
00888 
00889 
00890 
00891                 Event event( ev.event() );
00892                 event.setStart( start );
00893                 event.setEnd  ( end   );
00894 
00895 
00896                 emit beamMe( event );
00897             }
00898         }
00899 }
00900 
00901 void DateBookDayWidget::setGeometry( const QRect &r )
00902 {
00903     geom = r;
00904     setFixedSize( r.width()+1, r.height()+1 );
00905     dateBook->dayView()->moveChild( this, r.x(), r.y()-1 );
00906     show();
00907 }
00908 
00909 
00910 //---------------------------------------------------------------------------------------------
00911 //---------------------------------------------------------------------------------------------
00912 
00913 
00914 DateBookDayTimeMarker::DateBookDayTimeMarker( DateBookDay *db )
00915     : QWidget( db->dayView()->viewport() ), dateBook( db )
00916 {
00917     setBackgroundMode( PaletteBase );
00918 }
00919 
00920 DateBookDayTimeMarker::~DateBookDayTimeMarker()
00921 {
00922 }
00923 
00924 void DateBookDayTimeMarker::paintEvent( QPaintEvent */*e*/ )
00925 {
00926     QPainter p( this );
00927     p.setBrush( QColor( 255, 0, 0 ) );
00928 
00929     QPen pen;
00930     pen.setStyle(NoPen);
00931 
00932     p.setPen( pen );
00933     p.drawRect(rect());
00934 }
00935 
00936 void DateBookDayTimeMarker::setTime( const QTime &t )
00937 {
00938     int y = t.hour()*60+t.minute();
00939     int rh = dateBook->dayView()->rowHeight(0);
00940     y = y*rh/60;
00941 
00942     geom.setX( 0 );
00943 
00944     int x = dateBook->dayView()->columnWidth(0)-1;
00945     geom.setWidth( x );
00946 
00947     geom.setY( y );
00948     geom.setHeight( 1 );
00949 
00950     setGeometry( geom );
00951 
00952     time = t;
00953 }
00954 
00955 void DateBookDayTimeMarker::setGeometry( const QRect &r )
00956 {
00957     geom = r;
00958     setFixedSize( r.width()+1, r.height()+1 );
00959     dateBook->dayView()->moveChild( this, r.x(), r.y()-1 );
00960     show();
00961 }

Generated on Sat Nov 5 16:15:47 2005 for OPIE by  doxygen 1.4.2