-rw-r--r-- | core/pim/datebook/datebook.cpp | 7 | ||||
-rw-r--r-- | core/pim/datebook/datebook.h | 3 | ||||
-rw-r--r-- | core/pim/datebook/datebookday.cpp | 863 | ||||
-rw-r--r-- | core/pim/datebook/datebookday.h | 25 |
4 files changed, 469 insertions, 429 deletions
diff --git a/core/pim/datebook/datebook.cpp b/core/pim/datebook/datebook.cpp index 4fbcb10..6dd8918 100644 --- a/core/pim/datebook/datebook.cpp +++ b/core/pim/datebook/datebook.cpp @@ -2,768 +2,775 @@ ** Copyright (C) 2000 Trolltech AS. All rights reserved. ** ** This file is part of 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. ** ** $Id$ ** **********************************************************************/ #define QTOPIA_INTERNAL_FD #include "datebook.h" #include "datebookday.h" #include "datebooksettings.h" #include "datebookweek.h" #include "datebookweeklst.h" #include "dateentryimpl.h" #include <qpe/datebookmonth.h> #include <qpe/qpeapplication.h> #include <qpe/config.h> #include <qpe/qpedebug.h> #include <qpe/event.h> #include <qpe/finddialog.h> #include <qpe/ir.h> #include <qpe/qpemenubar.h> #include <qpe/qpemessagebox.h> #include <qpe/resource.h> #include <qpe/sound.h> #include <qpe/timestring.h> #include <qpe/qpetoolbar.h> #include <qpe/tzselect.h> #include <qpe/xmlreader.h> #include <qaction.h> #include <qcopchannel_qws.h> #include <qdatetime.h> #include <qdialog.h> #include <qfile.h> #include <qlabel.h> #include <qlayout.h> #include <qmessagebox.h> #include <qpopupmenu.h> #include <qpushbutton.h> #include <qregexp.h> #include <qtextcodec.h> #include <qtextstream.h> #include <qtimer.h> #include <qtl.h> #include <qwidgetstack.h> #include <qwindowsystem_qws.h> #include <sys/stat.h> #include <sys/types.h> #include <fcntl.h> #include <unistd.h> #include <stdlib.h> DateBook::DateBook( QWidget *parent, const char *, WFlags f ) : QMainWindow( parent, "datebook", f ), aPreset( FALSE ), presetTime( -1 ), startTime( 8 ), // an acceptable default rowStyle( 0 ), bJumpToCurTime(FALSE), syncing(FALSE), inSearch(FALSE), alarmCounter(0) { bool needEvilHack= false; // if we need an Evil Hack QTime t; t.start(); db = new DateBookDBHack; qDebug("loading db t=%d", t.elapsed() ); loadSettings(); setCaption( tr("Calendar") ); setIcon( Resource::loadPixmap( "datebook_icon" ) ); setToolBarsMovable( FALSE ); views = new QWidgetStack( this ); setCentralWidget( views ); dayView = 0; weekView = 0; weekLstView = 0; monthView = 0; QPEToolBar *bar = new QPEToolBar( this ); bar->setHorizontalStretchable( TRUE ); QPEMenuBar *mb = new QPEMenuBar( bar ); mb->setMargin( 0 ); QPEToolBar *sub_bar = new QPEToolBar(this); QPopupMenu *view = new QPopupMenu( this ); QPopupMenu *settings = new QPopupMenu( this ); mb->insertItem( tr( "View" ), view ); mb->insertItem( tr( "Settings" ), settings ); QActionGroup *g = new QActionGroup( this ); g->setExclusive( TRUE ); QAction *a = new QAction( tr( "New" ), Resource::loadPixmap( "new" ), QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( fileNew() ) ); a->addTo( sub_bar ); a = new QAction( tr( "Today" ), Resource::loadPixmap( "datebook/to_day" ), QString::null, 0, g, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( slotToday() ) ); a->addTo( sub_bar ); a->addTo( view ); a = new QAction( tr( "Day" ), Resource::loadPixmap( "day" ), QString::null, 0, g, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( viewDay() ) ); a->addTo( sub_bar ); a->addTo( view ); a->setToggleAction( TRUE ); a->setOn( TRUE ); dayAction = a; a = new QAction( tr( "Week" ), Resource::loadPixmap( "week" ), QString::null, 0, g, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( viewWeek() ) ); a->addTo( sub_bar ); a->addTo( view ); a->setToggleAction( TRUE ); weekAction = a; a = new QAction( tr( "WeekLst" ), Resource::loadPixmap( "datebook/weeklst" ), QString::null, 0, g, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( viewWeekLst() ) ); a->addTo( sub_bar ); a->addTo( view ); a->setToggleAction( TRUE ); weekLstAction = a; a = new QAction( tr( "Month" ), Resource::loadPixmap( "month" ), QString::null, 0, g, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( viewMonth() ) ); a->addTo( sub_bar ); a->addTo( view ); a->setToggleAction( TRUE ); monthAction = a; a = new QAction( tr( "Find" ), Resource::loadPixmap( "mag" ), QString::null, 0, g, 0 ); connect( a, SIGNAL(activated()), this, SLOT(slotFind()) ); a->addTo( sub_bar ); a = new QAction( tr( "Edit..." ), QString::null, 0, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( slotSettings() ) ); a->addTo( settings ); if(defaultView==DAY) viewDay(); if(defaultView==WEEK) needEvilHack=true; // viewWeek(); if(defaultView==WEEKLST) viewWeekLst(); if(defaultView==MONTH) viewMonth(); connect( qApp, SIGNAL(clockChanged(bool)), this, SLOT(changeClock(bool)) ); connect( qApp, SIGNAL(weekChanged(bool)), this, SLOT(changeWeek(bool)) ); #if defined(Q_WS_QWS) && !defined(QT_NO_COP) connect( qApp, SIGNAL(appMessage(const QCString&, const QByteArray&)), this, SLOT(appMessage(const QCString&, const QByteArray&)) ); #endif // listen on QPE/System #if defined(Q_WS_QWS) #if !defined(QT_NO_COP) QCopChannel *channel = new QCopChannel( "QPE/System", this ); connect( channel, SIGNAL(received(const QCString&, const QByteArray&)), this, SLOT(receive(const QCString&, const QByteArray&)) ); channel = new QCopChannel( "QPE/Datebook", this ); connect( channel, SIGNAL(received(const QCString&, const QByteArray&)), this, SLOT(receive(const QCString&, const QByteArray&)) ); qDebug("olle\n"); #endif #endif qDebug("done t=%d", t.elapsed() ); /* * Here is a problem description: * When Weekview is the default view * a DateBookWeekView get's created * redraw() get's called. So what? * Remember that we're still in the c'tor * and no final layout has happened? Ok * now all Events get arranged. Their x * position get's determined by a QHeader * position. But the QHeader isn't layouted or * at the right position. redraw() is a slot * so we'll call it then via a singleShot * from view() */ if( needEvilHack ){ QTimer::singleShot( 500, this, SLOT(viewWeek()) ); } } void DateBook::receive( const QCString &msg, const QByteArray &data ) { QDataStream stream( data, IO_ReadOnly ); if ( msg == "timeChange(QString)" ) { // update active view! if ( dayAction->isOn() ) viewDay(); else if ( weekAction->isOn() ) viewWeek(); else if ( monthAction->isOn() ) viewMonth(); } else if (msg == "editEvent(int)") { int uid; stream >> uid; Event e=db->eventByUID(uid); editEvent(e); } } DateBook::~DateBook() { } void DateBook::slotSettings() { DateBookSettings frmSettings( ampm, this ); frmSettings.setStartTime( startTime ); frmSettings.setAlarmPreset( aPreset, presetTime ); frmSettings.setJumpToCurTime( bJumpToCurTime ); frmSettings.setRowStyle( rowStyle ); frmSettings.comboDefaultView->setCurrentItem(defaultView-1); frmSettings.comboWeekListView->setCurrentItem(weeklistviewconfig); #if defined (Q_WS_QWS) || defined(_WS_QWS_) frmSettings.showMaximized(); #endif if ( frmSettings.exec() ) { aPreset = frmSettings.alarmPreset(); presetTime = frmSettings.presetTime(); startTime = frmSettings.startTime(); bJumpToCurTime = frmSettings.jumpToCurTime(); rowStyle = frmSettings.rowStyle(); defaultView=frmSettings.comboDefaultView->currentItem()+1; weeklistviewconfig=frmSettings.comboWeekListView->currentItem(); if ( dayView ) { dayView->setStartViewTime( startTime ); dayView->setJumpToCurTime( bJumpToCurTime ); dayView->setRowStyle( rowStyle ); } if ( weekView ) { weekView->setStartViewTime( startTime ); } saveSettings(); // make the change obvious if ( views->visibleWidget() ) { if ( views->visibleWidget() == dayView ) dayView->redraw(); else if ( views->visibleWidget() == weekView ) weekView->redraw(); else if ( views->visibleWidget() == weekLstView ) weekLstView->redraw(); } } } void DateBook::fileNew() { slotNewEventFromKey(""); } QString DateBook::checkEvent(const Event &e) { /* check if overlaps with itself */ bool checkFailed = FALSE; /* check the next 12 repeats. should catch most problems */ QDate current_date = e.start().date(); Event previous = e; for(int i = 0; i < 12; i++) { QDateTime next; if (!nextOccurance(previous, current_date.addDays(1), next)) { break; // no more repeats } if(next < previous.end()) { checkFailed = TRUE; break; } current_date = next.date(); } if(checkFailed) return tr("Event duration is potentially longer\n" "than interval between repeats."); return QString::null; } QDate DateBook::currentDate() { QDate d = QDate::currentDate(); if ( dayView && views->visibleWidget() == dayView ) { d = dayView->date(); } else if ( weekView && views->visibleWidget() == weekView ) { d = weekView->date(); } else if ( weekLstView && views->visibleWidget() == weekLstView ) { d = weekLstView->date(); } else if ( monthView && views->visibleWidget() == monthView ) { d = monthView->selectedDate(); } return d; } void DateBook::view(int v, const QDate &d) { if (v==DAY) { initDay(); dayAction->setOn( TRUE ); dayView->setDate( d ); views->raiseWidget( dayView ); dayView->redraw(); } else if (v==WEEK) { initWeek(); weekAction->setOn( TRUE ); weekView->setDate( d ); views->raiseWidget( weekView ); weekView->redraw(); } else if (v==WEEKLST) { initWeekLst(); weekLstAction->setOn( TRUE ); weekLstView->setDate(d); views->raiseWidget( weekLstView ); weekLstView->redraw(); } else if (v==MONTH) { initMonth(); monthAction->setOn( TRUE ); monthView->setDate( d.year(), d.month(), d.day() ); views->raiseWidget( monthView ); monthView->redraw(); } } void DateBook::viewDefault(const QDate &d) { /* Config config("DateBook"); config.setGroup("Main"); int current=config.readNumEntry("defaultview", DAY); view(current,d); */ view(defaultView,d); } void DateBook::viewDay() { view(DAY,currentDate()); } void DateBook::viewWeek() { view(WEEK,currentDate()); } void DateBook::viewWeekLst() { view(WEEKLST,currentDate()); } void DateBook::viewMonth() { view(MONTH,currentDate()); } +void DateBook::insertEvent( const Event &e ) +{ + qWarning("Adding Event!"); + db->addEvent(e); + emit newEvent(); +} + void DateBook::duplicateEvent( const Event &e ) { qWarning("Hmmm..."); // Alot of code duplication, as this is almost like editEvent(); if (syncing) { QMessageBox::warning( this, tr("Calendar"), tr( "Can not edit data, currently syncing") ); return; } Event dupevent(e); // Make a duplicate. // workaround added for text input. QDialog editDlg( this, 0, TRUE ); DateEntry *entry; editDlg.setCaption( tr("Duplicate Event") ); QVBoxLayout *vb = new QVBoxLayout( &editDlg ); QScrollView *sv = new QScrollView( &editDlg, "scrollview" ); sv->setResizePolicy( QScrollView::AutoOneFit ); // KLUDGE!!! sv->setHScrollBarMode( QScrollView::AlwaysOff ); vb->addWidget( sv ); entry = new DateEntry( onMonday, dupevent, ampm, &editDlg, "editor" ); entry->timezone->setEnabled( FALSE ); sv->addChild( entry ); #if defined(Q_WS_QWS) || defined(_WS_QWS_) editDlg.showMaximized(); #endif while (editDlg.exec() ) { Event newEv = entry->event(); QString error = checkEvent(newEv); if (!error.isNull()) { if (QMessageBox::warning(this, "error box", error, "Fix it", "Continue", 0, 0, 1) == 0) continue; } db->addEvent(newEv); emit newEvent(); break; } } void DateBook::editEvent( const Event &e ) { if (syncing) { QMessageBox::warning( this, tr("Calendar"), tr( "Can not edit data, currently syncing") ); return; } // workaround added for text input. QDialog editDlg( this, 0, TRUE ); DateEntry *entry; editDlg.setCaption( tr("Edit Event") ); QVBoxLayout *vb = new QVBoxLayout( &editDlg ); QScrollView *sv = new QScrollView( &editDlg, "scrollview" ); sv->setResizePolicy( QScrollView::AutoOneFit ); // KLUDGE!!! sv->setHScrollBarMode( QScrollView::AlwaysOff ); vb->addWidget( sv ); entry = new DateEntry( onMonday, e, ampm, &editDlg, "editor" ); entry->timezone->setEnabled( FALSE ); sv->addChild( entry ); #if defined(Q_WS_QWS) || defined(_WS_QWS_) editDlg.showMaximized(); #endif while (editDlg.exec() ) { Event newEv = entry->event(); if(newEv.description().isEmpty() && newEv.notes().isEmpty() ) break; newEv.setUid(e.uid()); // FIXME: Hack not to clear uid QString error = checkEvent(newEv); if (!error.isNull()) { if (QMessageBox::warning(this, "error box", error, "Fix it", "Continue", 0, 0, 1) == 0) continue; } db->editEvent(e, newEv); emit newEvent(); break; } } void DateBook::removeEvent( const Event &e ) { if (syncing) { QMessageBox::warning( this, tr("Calendar"), tr( "Can not edit data, currently syncing") ); return; } QString strName = e.description(); if ( !QPEMessageBox::confirmDelete( this, tr( "Calendar" ),strName ) ) return; db->removeEvent( e ); if ( views->visibleWidget() == dayView && dayView ) dayView->redraw(); } void DateBook::addEvent( const Event &e ) { QDate d = e.start().date(); initDay(); dayView->setDate( d ); } void DateBook::showDay( int year, int month, int day ) { QDate d(year, month, day); view(DAY,d); } void DateBook::initDay() { if ( !dayView ) { dayView = new DateBookDay( ampm, onMonday, db, views, "day view" ); views->addWidget( dayView, DAY ); dayView->setStartViewTime( startTime ); dayView->setJumpToCurTime( bJumpToCurTime ); dayView->setRowStyle( rowStyle ); connect( this, SIGNAL( newEvent() ), dayView, SLOT( redraw() ) ); connect( dayView, SIGNAL( newEvent() ), this, SLOT( fileNew() ) ); connect( dayView, SIGNAL( removeEvent( const Event & ) ), this, SLOT( removeEvent( const Event & ) ) ); connect( dayView, SIGNAL( editEvent( const Event & ) ), this, SLOT( editEvent( const Event & ) ) ); connect( dayView, SIGNAL( duplicateEvent( const Event & ) ), this, SLOT( duplicateEvent( const Event & ) ) ); connect( dayView, SIGNAL( beamEvent( const Event & ) ), this, SLOT( beamEvent( const Event & ) ) ); connect( dayView, SIGNAL(sigNewEvent(const QString &)), this, SLOT(slotNewEventFromKey(const QString &)) ); } } void DateBook::initWeek() { if ( !weekView ) { weekView = new DateBookWeek( ampm, onMonday, db, views, "week view" ); weekView->setStartViewTime( startTime ); views->addWidget( weekView, WEEK ); connect( weekView, SIGNAL( showDate( int, int, int ) ), this, SLOT( showDay( int, int, int ) ) ); connect( this, SIGNAL( newEvent() ), weekView, SLOT( redraw() ) ); } //But also get it right: the year that we display can be different //from the year of the current date. So, first find the year //number of the current week. int yearNumber, totWeeks; calcWeek( currentDate(), totWeeks, yearNumber, onMonday ); QDate d = QDate( yearNumber, 12, 31 ); calcWeek( d, totWeeks, yearNumber, onMonday ); while ( totWeeks == 1 ) { d = d.addDays( -1 ); calcWeek( d, totWeeks, yearNumber, onMonday ); } if ( totWeeks != weekView->totalWeeks() ) weekView->setTotalWeeks( totWeeks ); } void DateBook::initWeekLst() { if ( !weekLstView ) { weekLstView = new DateBookWeekLst( ampm, onMonday, db, views, "weeklst view" ); views->addWidget( weekLstView, WEEKLST ); //weekLstView->setStartViewTime( startTime ); connect( weekLstView, SIGNAL( showDate( int, int, int ) ), this, SLOT( showDay( int, int, int ) ) ); connect( weekLstView, SIGNAL( addEvent( const QDateTime &, const QDateTime &, const QString & , const QString &) ), this, SLOT( slotNewEntry( const QDateTime &, const QDateTime &, const QString & , const QString &) ) ); connect( this, SIGNAL( newEvent() ), weekLstView, SLOT( redraw() ) ); connect( weekLstView, SIGNAL( editEvent( const Event & ) ), this, SLOT( editEvent( const Event & ) ) ); } } void DateBook::initMonth() { if ( !monthView ) { monthView = new DateBookMonth( views, "month view", FALSE, db ); views->addWidget( monthView, MONTH ); connect( monthView, SIGNAL( dateClicked( int, int, int ) ), this, SLOT( showDay( int, int, int ) ) ); connect( this, SIGNAL( newEvent() ), monthView, SLOT( redraw() ) ); qApp->processEvents(); } } void DateBook::loadSettings() { Config qpeconfig( "qpe" ); qpeconfig.setGroup("Time"); ampm = qpeconfig.readBoolEntry( "AMPM", TRUE ); onMonday = qpeconfig.readBoolEntry( "MONDAY" ); Config config("DateBook"); config.setGroup("Main"); startTime = config.readNumEntry("startviewtime", 8); aPreset = config.readBoolEntry("alarmpreset"); presetTime = config.readNumEntry("presettime"); bJumpToCurTime = config.readBoolEntry("jumptocurtime"); rowStyle = config.readNumEntry("rowstyle"); defaultView = config.readNumEntry("defaultview",DAY); weeklistviewconfig = config.readNumEntry("weeklistviewconfig",NORMAL); } void DateBook::saveSettings() { Config config( "qpe" ); Config configDB( "DateBook" ); configDB.setGroup( "Main" ); configDB.writeEntry("startviewtime",startTime); configDB.writeEntry("alarmpreset",aPreset); configDB.writeEntry("presettime",presetTime); configDB.writeEntry("jumptocurtime", bJumpToCurTime); configDB.writeEntry("rowstyle", rowStyle); configDB.writeEntry("defaultview",defaultView); configDB.writeEntry("weeklistviewconfig",weeklistviewconfig); } void DateBook::appMessage(const QCString& msg, const QByteArray& data) { bool needShow = FALSE; if ( msg == "alarm(QDateTime,int)" ) { QDataStream ds(data,IO_ReadOnly); QDateTime when; int warn; ds >> when >> warn; // check to make it's okay to continue, // this is the case that the time was set ahead, and // we are forced given a stale alarm... QDateTime current = QDateTime::currentDateTime(); if ( current.time().hour() != when.time().hour() && current.time().minute() != when.time().minute() ) return; QValueList<EffectiveEvent> list = db->getEffectiveEvents(when.addSecs(warn*60)); if ( list.count() > 0 ) { QString msg; bool bSound = FALSE; int stopTimer = 0; bool found = FALSE; for ( QValueList<EffectiveEvent>::ConstIterator it=list.begin(); it!=list.end(); ++it ) { if ( (*it).event().hasAlarm() ) { found = TRUE; msg += "<CENTER><B>" + (*it).description() + "</B>" + "<BR>" + (*it).location() + "<BR>" + TimeString::dateString((*it).event().start(),ampm) + (warn ? tr(" (in " + QString::number(warn) + tr(" minutes)")) : QString("")) + "<BR>" + (*it).notes() + "</CENTER>"; if ( (*it).event().alarmSound() != Event::Silent ) { bSound = TRUE; } } } if ( found ) { if ( bSound ) { Sound::soundAlarm(); alarmCounter = 0; stopTimer = startTimer( 5000 ); } QDialog dlg( this, 0, TRUE ); QVBoxLayout *vb = new QVBoxLayout( &dlg ); QScrollView *view = new QScrollView( &dlg, "scrollView"); view->setResizePolicy( QScrollView::AutoOneFit ); vb->addWidget( view ); QLabel *lblMsg = new QLabel( msg, &dlg ); view->addChild( lblMsg ); QPushButton *cmdOk = new QPushButton( tr("OK"), &dlg ); connect( cmdOk, SIGNAL(clicked()), &dlg, SLOT(accept()) ); vb->addWidget( cmdOk ); #if defined(Q_WS_QWS) || defined(_WS_QWS_) dlg.showMaximized(); #endif needShow = dlg.exec(); if ( bSound ) killTimer( stopTimer ); } } } else if ( msg == "nextView()" ) { if ( !qApp-> activeWindow ( )) { needShow = TRUE; } else { QWidget* cur = views->visibleWidget(); if ( cur ) { if ( cur == dayView ) viewWeek(); else if ( cur == weekView ) viewWeekLst(); else if ( cur == weekLstView ) viewMonth(); else if ( cur == monthView ) viewDay(); needShow = TRUE; } } } if ( needShow ) { #if defined(Q_WS_QWS) || defined(_WS_QWS_) showMaximized(); #else show(); #endif raise(); QPEApplication::setKeepRunning(); setActiveWindow(); } } void DateBook::reload() { db->reload(); if ( dayAction->isOn() ) viewDay(); else if ( weekAction->isOn() ) viewWeek(); else if ( monthAction->isOn() ) viewMonth(); syncing = FALSE; } void DateBook::flush() { syncing = TRUE; db->save(); } void DateBook::timerEvent( QTimerEvent *e ) { if ( alarmCounter < 10 ) { alarmCounter++; Sound::soundAlarm(); } else { killTimer( e->timerId() ); } } void DateBook::changeClock( bool newClock ) { ampm = newClock; // repaint the affected objects... if (dayView) dayView->redraw(); if (weekView) weekView->redraw(); if (weekLstView) weekLstView->redraw(); } void DateBook::changeWeek( bool m ) { /* no need to redraw, each widget catches. Do need to store though for widgets we haven't made yet */ onMonday = m; } void DateBook::slotToday() { // we need to view today using default view view(defaultView,QDate::currentDate()); } void DateBook::closeEvent( QCloseEvent *e ) { if(syncing) { /* no need to save, did that at flush */ e->accept(); return; } // save settings will generate it's own error messages, no // need to do checking ourselves. saveSettings(); diff --git a/core/pim/datebook/datebook.h b/core/pim/datebook/datebook.h index 5216770..3f57d4a 100644 --- a/core/pim/datebook/datebook.h +++ b/core/pim/datebook/datebook.h @@ -1,135 +1,136 @@ /********************************************************************** ** Copyright (C) 2000 Trolltech AS. All rights reserved. ** ** This file is part of 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. ** **********************************************************************/ #ifndef DATEBOOK_H #define DATEBOOK_H #include <qpe/datebookdb.h> #include <qmainwindow.h> enum { DAY=1,WEEK,WEEKLST,MONTH }; // defaultView values enum { NONE=0,NORMAL,EXTENDED }; // WeekLstView's modes. class QAction; class QWidgetStack; class DateBookDay; class DateBookWeek; class DateBookWeekLst; class DateBookMonth; class Event; class QDate; class Ir; class DateBookDBHack : public DateBookDB { public: Event eventByUID(int id); }; class DateBook : public QMainWindow { Q_OBJECT public: DateBook( QWidget *parent = 0, const char *name = 0, WFlags f = 0 ); ~DateBook(); signals: void newEvent(); void signalNotFound(); void signalWrapAround(); protected: QDate currentDate(); void timerEvent( QTimerEvent *e ); void closeEvent( QCloseEvent *e ); void view(int v, const QDate &d); public slots: void flush(); void reload(); private slots: void fileNew(); void slotNewEntry(const QDateTime &start, const QDateTime &end, const QString &str, const QString &location=0); void slotSettings(); void slotToday(); // view today void changeClock( bool newClock ); void changeWeek( bool newDay ); void appMessage(const QCString& msg, const QByteArray& data); // handle key events in the day view... void slotNewEventFromKey( const QString &str ); void slotFind(); void slotDoFind( const QString &, const QDate &, bool, bool, int ); void viewDefault(const QDate &d); void viewDay(); void viewWeek(); void viewWeekLst(); void viewMonth(); void showDay( int y, int m, int d ); - void editEvent( const Event &e ); + void insertEvent( const Event &e ); + void editEvent( const Event &e ); void duplicateEvent( const Event &e ); void removeEvent( const Event &e ); void receive( const QCString &msg, const QByteArray &data ); void setDocument( const QString & ); void beamEvent( const Event &e ); void beamDone( Ir *ir ); private: void addEvent( const Event &e ); void initDay(); void initWeek(); void initWeekLst(); void initMonth(); void loadSettings(); void saveSettings(); private: DateBookDBHack *db; QWidgetStack *views; DateBookDay *dayView; DateBookWeek *weekView; DateBookMonth *monthView; DateBookWeekLst *weekLstView; QAction *dayAction, *weekAction, *weekLstAction, *monthAction; int weeklistviewconfig; bool aPreset; // have everything set to alarm? int presetTime; // the standard time for the alarm int startTime; int rowStyle; int defaultView; bool bJumpToCurTime; //should jump to current time in dayview? bool ampm; bool onMonday; bool syncing; bool inSearch; int alarmCounter; QString checkEvent(const Event &); }; #endif diff --git a/core/pim/datebook/datebookday.cpp b/core/pim/datebook/datebookday.cpp index db4c2fd..0a40ea9 100644 --- a/core/pim/datebook/datebookday.cpp +++ b/core/pim/datebook/datebookday.cpp @@ -1,802 +1,811 @@ /********************************************************************** ** Copyright (C) 2000 Trolltech AS. All rights reserved. ** ** This file is part of 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 <qmessagebox.h> #include "datebookday.h" #include "datebookdayheaderimpl.h" #include <qpe/datebookdb.h> #include <qpe/resource.h> #include <qpe/event.h> #include <qpe/qpeapplication.h> #include <qpe/timestring.h> #include <qpe/qpedebug.h> #include <qpe/ir.h> #include <qheader.h> #include <qdatetime.h> #include <qpainter.h> #include <qsimplerichtext.h> #include <qpopupmenu.h> #include <qtextcodec.h> #include <qpalette.h> +#include <qlineedit.h> + #include <qtimer.h> -DateBookDayView::DateBookDayView( bool whichClock, QWidget *parent, - const char *name ) - : QTable( 24, 1, parent, name ), - ampm( whichClock ) -{ - enableClipper(TRUE); - setTopMargin( 0 ); - horizontalHeader()->hide(); - setLeftMargin(38); - setColumnStretchable( 0, TRUE ); - setHScrollBarMode( QScrollView::AlwaysOff ); - verticalHeader()->setPalette(white); - verticalHeader()->setResizeEnabled(FALSE); - setSelectionMode( Single ); - - // get rid of being able to edit things... - QTableItem *tmp; - int row; - for ( row = 0; row < numRows(); row++ ) { - tmp = new QTableItem( this, QTableItem::Never, QString::null); - setItem( row, 0, tmp ); - //setRowHeight( row, 40); - } - initHeader(); - QObject::connect( qApp, SIGNAL(clockChanged(bool)), - this, SLOT(slotChangeClock(bool)) ); +DateBookDayView::DateBookDayView( bool whichClock, QWidget *parent, const char *name ) + : QTable( 24, 1, parent, name ), ampm( whichClock ), currDate( QDate::currentDate() ) +{ + enableClipper(TRUE); + setTopMargin( 0 ); + horizontalHeader()->hide(); + setLeftMargin(38); + setColumnStretchable( 0, TRUE ); + setHScrollBarMode( QScrollView::AlwaysOff ); + verticalHeader()->setPalette(white); + verticalHeader()->setResizeEnabled(FALSE); + setSelectionMode( Single ); + + // get rid of being able to edit things... + QTableItem *tmp; + int row; + for ( row = 0; row < numRows(); row++ ) { + tmp = new QTableItem( this, QTableItem::Never, QString::null); + setItem( row, 0, tmp ); + //setRowHeight( row, 40); + } + + initHeader(); + QObject::connect( qApp, SIGNAL(clockChanged(bool)), this, SLOT(slotChangeClock(bool)) ); } void DateBookDayView::initHeader() { - QString strTmp; - for ( int i = 0; i < 24; ++i ) { - if ( ampm ) { - if ( i == 0 ) - strTmp = QString::number(12) + ":00"; - else if ( i == 12 ) - strTmp = QString::number(12) + tr(":00p"); - else if ( i > 12 ) - strTmp = QString::number( i - 12 ) + tr(":00p"); - else - strTmp = QString::number(i) + ":00"; - } else { - if ( i < 10 ) - strTmp = "0" + QString::number(i) + ":00"; - else - strTmp = QString::number(i) + ":00"; + QString strTmp; + for ( int i = 0; i < 24; ++i ) { + if ( ampm ) { + if ( i == 0 ) + strTmp = QString::number(12) + ":00"; + else if ( i == 12 ) + strTmp = QString::number(12) + tr(":00p"); + else if ( i > 12 ) + strTmp = QString::number( i - 12 ) + tr(":00p"); + else + strTmp = QString::number(i) + ":00"; + } else { + if ( i < 10 ) + strTmp = "0" + QString::number(i) + ":00"; + else + strTmp = QString::number(i) + ":00"; + } + strTmp = strTmp.rightJustify( 6, ' ' ); + verticalHeader()->setLabel( i, strTmp ); + setRowStretchable( i, FALSE ); } - strTmp = strTmp.rightJustify( 6, ' ' ); - verticalHeader()->setLabel( i, strTmp ); - setRowStretchable( i, FALSE ); - } +} + +void DateBookDayView::slotDateChanged( int y, int m, int d ) +{ + currDate.setYMD(y,m,d); } void DateBookDayView::slotChangeClock( bool newClock ) { - ampm = newClock; - initHeader(); + ampm = newClock; + initHeader(); } bool DateBookDayView::whichClock() const { - return ampm; + return ampm; } void DateBookDayView::moveUp() { - scrollBy(0, -20); + scrollBy(0, -20); } void DateBookDayView::moveDown() { - scrollBy(0, 20); + scrollBy(0, 20); } void DateBookDayView::paintCell( QPainter *p, int, int, const QRect &cr, bool ) { - int w = cr.width(); - int h = cr.height(); - p->fillRect( 0, 0, w, h, colorGroup().brush( QColorGroup::Base ) ); - if ( showGrid() ) { - // Draw our lines - int x2 = w - 1; - int y2 = h - 1; - QPen pen( p->pen() ); - p->setPen( colorGroup().dark() ); - p->drawLine( x2, 0, x2, y2 ); - p->drawLine( 0, y2, x2, y2 ); - - p->setPen( colorGroup().midlight() ); - p->drawLine( 0, y2 - h/2, x2, y2 - h/2); - - p->setPen( pen ); + int w = cr.width(); + int h = cr.height(); + p->fillRect( 0, 0, w, h, colorGroup().brush( QColorGroup::Base ) ); + if ( showGrid() ) { + // Draw our lines + int x2 = w - 1; + int y2 = h - 1; + QPen pen( p->pen() ); + p->setPen( colorGroup().dark() ); + p->drawLine( x2, 0, x2, y2 ); + p->drawLine( 0, y2, x2, y2 ); + + p->setPen( colorGroup().midlight() ); + p->drawLine( 0, y2 - h/2, x2, y2 - h/2); + + p->setPen( pen ); } } void DateBookDayView::paintFocus( QPainter *, const QRect & ) { } - void DateBookDayView::resizeEvent( QResizeEvent *e ) { - QTable::resizeEvent( e ); - columnWidthChanged( 0 ); - emit sigColWidthChanged(); + QTable::resizeEvent( e ); + columnWidthChanged( 0 ); + emit sigColWidthChanged(); } void DateBookDayView::keyPressEvent( QKeyEvent *e ) { - QString txt = e->text(); - if ( !txt.isNull() && txt[0] > ' ' && e->key() < 0x1000 ) { - // we this is some sort of thing we know about... - e->accept(); - emit sigCapturedKey( txt ); + QString txt = e->text(); + if ( !txt.isNull() && txt[0] > ' ' && e->key() < 0x1000 ) { + // we this is some sort of thing we know about... + e->accept(); + emit sigCapturedKey( txt ); } else { - // I don't know what this key is, do you? - e->ignore(); - } + // I don't know what this key is, do you? + e->ignore(); + } } void DateBookDayView::setRowStyle( int style ) { if (style<0) style = 0; for (int i=0; i<numRows(); i++) setRowHeight(i, style*10+20); } +void DateBookDayView::contentsMouseReleaseEvent( QMouseEvent *e ) +{ + int y=e->y(); + int diff=y%(this->rowHeight(0)); + int hour=y/this->rowHeight(0); + quickLineEdit=new DateBookDayViewQuickLineEdit(QDateTime(currDate,QTime(hour,0,0,0)),QDateTime(currDate,QTime(hour,59,0,0)),this->viewport(),"quickedit"); + quickLineEdit->setGeometry(0,0,this->columnWidth(0)-1,this->rowHeight(0)); + this->moveChild(quickLineEdit,0,y-diff); + quickLineEdit->setFocus(); + quickLineEdit->show(); +} + //=========================================================================== -DateBookDay::DateBookDay( bool ampm, bool startOnMonday, - DateBookDB *newDb, QWidget *parent, - const char *name ) - : QVBox( parent, name ), - currDate( QDate::currentDate() ), - db( newDb ), - startTime( 0 ) +DateBookDayViewQuickLineEdit::DateBookDayViewQuickLineEdit(const QDateTime &start, const QDateTime &end,QWidget * parent, const char *name=0) : QLineEdit(parent,name) { - widgetList.setAutoDelete( true ); - header = new DateBookDayHeader( startOnMonday, this, "day header" ); - header->setDate( currDate.year(), currDate.month(), currDate.day() ); - view = new DateBookDayView( ampm, this, "day view" ); + active=1; + quickEvent.setStart(start); + quickEvent.setEnd(end); + connect(this,SIGNAL(returnPressed()),this,SLOT(slotReturnPressed())); +} - connect( header, SIGNAL( dateChanged( int, int, int ) ), - this, SLOT( dateChanged( int, int, int ) ) ); - connect( view, SIGNAL( sigColWidthChanged() ), - this, SLOT( slotColWidthChanged() ) ); - connect( qApp, SIGNAL(weekChanged(bool)), - this, SLOT(slotWeekChanged(bool)) ); - connect( view, SIGNAL(sigCapturedKey(const QString &)), - this, SIGNAL(sigNewEvent(const QString&)) ); +void DateBookDayViewQuickLineEdit::slotReturnPressed() +{ + if(active && (!this->text().isEmpty())) { // Fix to avoid having this event beeing added multiple times. + quickEvent.setDescription(this->text()); + connect(this,SIGNAL(insertEvent(const Event &)),this->topLevelWidget(),SLOT(insertEvent(const Event &))); + emit(insertEvent(quickEvent)); + active=0; + } + this->close(true); // Close and also delete this widget +} - QTimer *timer = new QTimer( this ); +void DateBookDayViewQuickLineEdit::focusOutEvent ( QFocusEvent * e ) +{ + slotReturnPressed(); // Reuse code to add event and close this widget. +} - connect( timer, SIGNAL(timeout()), - this, SLOT(updateView()) ); //connect timer for updating timeMarker & daywidgetcolors - timer->start( 1000*60*5, FALSE ); //update every 5min +//=========================================================================== - selectedWidget = 0; +DateBookDay::DateBookDay( bool ampm, bool startOnMonday, DateBookDB *newDb, QWidget *parent, const char *name ) + : QVBox( parent, name ), currDate( QDate::currentDate() ), db( newDb ), startTime( 0 ) +{ + widgetList.setAutoDelete( true ); + header = new DateBookDayHeader( startOnMonday, this, "day header" ); + header->setDate( currDate.year(), currDate.month(), currDate.day() ); + view = new DateBookDayView( ampm, this, "day view" ); + + connect( header, SIGNAL( dateChanged( int, int, int ) ), this, SLOT( dateChanged( int, int, int ) ) ); + connect( header, SIGNAL( dateChanged( int, int, int ) ), view, SLOT( slotDateChanged( int, int, int ) ) ); + connect( view, SIGNAL( sigColWidthChanged() ), this, SLOT( slotColWidthChanged() ) ); + connect( qApp, SIGNAL(weekChanged(bool)), this, SLOT(slotWeekChanged(bool)) ); + connect( view, SIGNAL(sigCapturedKey(const QString &)), this, SIGNAL(sigNewEvent(const QString&)) ); + + QTimer *timer = new QTimer( this ); + + connect( timer, SIGNAL(timeout()), this, SLOT(updateView()) ); //connect timer for updating timeMarker & daywidgetcolors + timer->start( 1000*60*5, FALSE ); //update every 5min - timeMarker = new DateBookDayTimeMarker( this ); - timeMarker->setTime( QTime::currentTime() ); - rowStyle = -1; // initialize with bogus values + selectedWidget = 0; + + timeMarker = new DateBookDayTimeMarker( this ); + timeMarker->setTime( QTime::currentTime() ); + rowStyle = -1; // initialize with bogus values } void DateBookDay::setJumpToCurTime( bool bJump ) { jumpToCurTime = bJump; } void DateBookDay::setRowStyle( int style ) { if (rowStyle != style) view->setRowStyle( style ); rowStyle = style; } void DateBookDay::updateView( void ) { timeMarker->setTime( QTime::currentTime() ); //need to find a way to update all DateBookDayWidgets } void DateBookDay::setSelectedWidget( DateBookDayWidget *w ) { selectedWidget = w; } DateBookDayWidget * DateBookDay::getSelectedWidget( void ) { return selectedWidget; } void DateBookDay::selectedDates( QDateTime &start, QDateTime &end ) { - start.setDate( currDate ); - end.setDate( currDate ); + start.setDate( currDate ); + end.setDate( currDate ); - int sh=99,eh=-1; + int sh=99,eh=-1; - int n = dayView()->numSelections(); + int n = dayView()->numSelections(); - for (int i=0; i<n; i++) { - QTableSelection sel = dayView()->selection( i ); - sh = QMIN(sh,sel.topRow()); - eh = QMAX(sh,sel.bottomRow()+1); - } - if (sh > 23 || eh < 1) { - sh=8; - eh=9; - } + for (int i=0; i<n; i++) { + QTableSelection sel = dayView()->selection( i ); + sh = QMIN(sh,sel.topRow()); + eh = QMAX(sh,sel.bottomRow()+1); + } + + if (sh > 23 || eh < 1) { + sh=8; + eh=9; + } - start.setTime( QTime( sh, 0, 0 ) ); - end.setTime( QTime( eh, 0, 0 ) ); + start.setTime( QTime( sh, 0, 0 ) ); + end.setTime( QTime( eh, 0, 0 ) ); } void DateBookDay::setDate( int y, int m, int d ) { - header->setDate( y, m, d ); - - selectedWidget = 0; + header->setDate( y, m, d ); + selectedWidget = 0; } void DateBookDay::setDate( QDate d) { - header->setDate( d.year(), d.month(), d.day() ); - - selectedWidget = 0; + header->setDate( d.year(), d.month(), d.day() ); + selectedWidget = 0; } void DateBookDay::dateChanged( int y, int m, int d ) { - QDate date( y, m, d ); - if ( currDate == date ) - return; - currDate.setYMD( y, m, d ); - relayoutPage(); - dayView()->clearSelection(); - QTableSelection ts; - - if (jumpToCurTime && this->date() == QDate::currentDate()) - { - ts.init( QTime::currentTime().hour(), 0); - ts.expandTo( QTime::currentTime().hour(), 0); - } else - { - ts.init( startTime, 0 ); - ts.expandTo( startTime, 0 ); - } - - dayView()->addSelection( ts ); + QDate date( y, m, d ); + if ( currDate == date ) + return; + currDate.setYMD( y, m, d ); + relayoutPage(); + dayView()->clearSelection(); + QTableSelection ts; - selectedWidget = 0; + if (jumpToCurTime && this->date() == QDate::currentDate()) + { + ts.init( QTime::currentTime().hour(), 0); + ts.expandTo( QTime::currentTime().hour(), 0); + } else { + ts.init( startTime, 0 ); + ts.expandTo( startTime, 0 ); + } + dayView()->addSelection( ts ); + selectedWidget = 0; } void DateBookDay::redraw() { - if ( isUpdatesEnabled() ) - relayoutPage(); + if ( isUpdatesEnabled() ) + relayoutPage(); } void DateBookDay::getEvents() { widgetList.clear(); QValueList<EffectiveEvent> eventList = db->getEffectiveEvents( currDate, currDate ); QValueListIterator<EffectiveEvent> it; for ( it = eventList.begin(); it != eventList.end(); ++it ) { EffectiveEvent ev=*it; if(!((ev.end().hour()==0) && (ev.end().minute()==0) && (ev.startDate()!=ev.date()))) { // Skip events ending at 00:00 starting at another day. DateBookDayWidget* w = new DateBookDayWidget( *it, this ); - connect( w, SIGNAL( deleteMe( const Event & ) ), - this, SIGNAL( removeEvent( const Event & ) ) ); - connect( w, SIGNAL( duplicateMe( const Event & ) ), - this, SIGNAL( duplicateEvent( const Event & ) ) ); - connect( w, SIGNAL( editMe( const Event & ) ), - this, SIGNAL( editEvent( const Event & ) ) ); - connect( w, SIGNAL( beamMe( const Event & ) ), - this, SIGNAL( beamEvent( const Event & ) ) ); + connect( w, SIGNAL( deleteMe( const Event & ) ), this, SIGNAL( removeEvent( const Event & ) ) ); + connect( w, SIGNAL( duplicateMe( const Event & ) ), this, SIGNAL( duplicateEvent( const Event & ) ) ); + connect( w, SIGNAL( editMe( const Event & ) ), this, SIGNAL( editEvent( const Event & ) ) ); + connect( w, SIGNAL( beamMe( const Event & ) ), this, SIGNAL( beamEvent( const Event & ) ) ); widgetList.append( w ); } - } - + } } static int place( const DateBookDayWidget *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++; + 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 ( free ) break; - place++; - } - if ( place == maxn ) { - return -1; - } - while( start <= end ) { - used[10*start+place] = TRUE; - start++; - } - return place; + if ( place == maxn ) { + return -1; + } + while( start <= end ) { + used[10*start+place] = TRUE; + start++; + } + return place; } void DateBookDay::relayoutPage( bool fromResize ) { - setUpdatesEnabled( FALSE ); - if ( !fromResize ) - getEvents(); // no need we already have them! - - widgetList.sort(); - //sorts the widgetList by the heights of the widget so that the tallest widgets are at the beginning - //this is needed for the simple algo below to work correctly, otherwise some widgets would be drawn outside the view - - int wCount = widgetList.count(); - int wid = view->columnWidth(0)-1; - int wd; - int n = 1; - - QArray<int> anzIntersect(wCount); //this stores the number of maximal intersections of each widget - - for (int i = 0; i<wCount; anzIntersect[i] = 1, i++); - - if ( wCount < 20 ) { - - QArray<QRect> geometries(wCount); - for (int i = 0; i < wCount; geometries[i] = widgetList.at(i)->geometry(), i++); //stores geometry for each widget in vector - - for ( int i = 0; i < wCount; i++) - { - QValueList<int> intersectedWidgets; - - //find all widgets intersecting with widgetList.at(i) - for ( int j = 0; j < wCount; j++) - if (i != j) - if (geometries[j].intersects(geometries[i])) - intersectedWidgets.append(j); - - //for each of these intersecting widgets find out how many widgets are they intersecting with - for ( uint j = 0; j < intersectedWidgets.count(); j++) - { - QArray<int> inter(wCount); - inter[j]=1; - - if (intersectedWidgets[j] != -1) - for ( uint k = j; k < intersectedWidgets.count(); k++) - if (j != k && intersectedWidgets[k] != -1) - if (geometries[intersectedWidgets[k]].intersects(geometries[intersectedWidgets[j]])) - { - inter[j]++; - intersectedWidgets[k] = -1; - } - if (inter[j] > anzIntersect[i]) anzIntersect[i] = inter[j] + 1; + setUpdatesEnabled( FALSE ); + if ( !fromResize ) + getEvents(); // no need we already have them! + + widgetList.sort(); + //sorts the widgetList by the heights of the widget so that the tallest widgets are at the beginning + //this is needed for the simple algo below to work correctly, otherwise some widgets would be drawn outside the view + + int wCount = widgetList.count(); + int wid = view->columnWidth(0)-1; + int wd; + int n = 1; + + QArray<int> anzIntersect(wCount); //this stores the number of maximal intersections of each widget + + for (int i = 0; i<wCount; anzIntersect[i] = 1, i++); + + if ( wCount < 20 ) { + + QArray<QRect> geometries(wCount); + for (int i = 0; i < wCount; geometries[i] = widgetList.at(i)->geometry(), i++); //stores geometry for each widget in vector + + for ( int i = 0; i < wCount; i++) { + QValueList<int> intersectedWidgets; + + //find all widgets intersecting with widgetList.at(i) + for ( int j = 0; j < wCount; j++) { + if (i != j) + if (geometries[j].intersects(geometries[i])) + intersectedWidgets.append(j); + } + + //for each of these intersecting widgets find out how many widgets are they intersecting with + for ( uint j = 0; j < intersectedWidgets.count(); j++) + { + QArray<int> inter(wCount); + inter[j]=1; + + if (intersectedWidgets[j] != -1) + for ( uint k = j; k < intersectedWidgets.count(); k++) { + if (j != k && intersectedWidgets[k] != -1) + if (geometries[intersectedWidgets[k]].intersects(geometries[intersectedWidgets[j]])) { + inter[j]++; + intersectedWidgets[k] = -1; + } + if (inter[j] > anzIntersect[i]) anzIntersect[i] = inter[j] + 1; + } + } + if (anzIntersect[i] == 1 && intersectedWidgets.count()) anzIntersect[i]++; } - if (anzIntersect[i] == 1 && intersectedWidgets.count()) anzIntersect[i]++; - } - - - for ( int i = 0; i < wCount; i++) { - DateBookDayWidget *w = widgetList.at(i); - QRect geom = w->geometry(); - - geom.setX( 0 ); - - wd = (view->columnWidth(0)-1) / anzIntersect[i] - (anzIntersect[i]>1?2:0); - geom.setWidth( wd ); - - while ( intersects( w, geom ) ) { - geom.moveBy( wd + 2 + 1, 0 ); - } - w->setGeometry( geom ); - } - - if (jumpToCurTime && this->date() == QDate::currentDate()) - view->setContentsPos( 0, QTime::currentTime().hour() * view->rowHeight(0) ); //set listview to current hour - else - view->setContentsPos( 0, startTime * view->rowHeight(0) ); - - - } else { + for ( int i = 0; i < wCount; i++) { + DateBookDayWidget *w = widgetList.at(i); + QRect geom = w->geometry(); + geom.setX( 0 ); + wd = (view->columnWidth(0)-1) / anzIntersect[i] - (anzIntersect[i]>1?2:0); + geom.setWidth( wd ); + while ( intersects( w, geom ) ) { + geom.moveBy( wd + 2 + 1, 0 ); + } + w->setGeometry( geom ); + } + if (jumpToCurTime && this->date() == QDate::currentDate()) { + view->setContentsPos( 0, QTime::currentTime().hour() * view->rowHeight(0) ); //set listview to current hour + } else { + view->setContentsPos( 0, startTime * view->rowHeight(0) ); + } + } else { + int hours[24]; + memset( hours, 0, 24*sizeof( int ) ); + bool overFlow = FALSE; + for ( int i = 0; i < wCount; i++ ) { + DateBookDayWidget *w = widgetList.at(i); + int start = w->event().start().hour(); + QTime e = w->event().end(); + int end = e.hour(); + if ( e.minute() < 5 ) + end--; + if ( end < start ) + end = start; + while( start <= end ) { + hours[start]++; + if ( hours[start] >= 10 ) + overFlow = TRUE; + ++start; + } + if ( overFlow ) + break; + } + for ( int i = 0; i < 24; i++ ) { + n = QMAX( n, hours[i] ); + } + wid = ( view->columnWidth(0)-1 ) / n; + + bool used[24*10]; + memset( used, FALSE, 24*10*sizeof( bool ) ); + + for ( int i = 0; i < wCount; i++ ) { + DateBookDayWidget *w = widgetList.at(i); + int xp = place( w, used, n ); + if ( xp != -1 ) { + QRect geom = w->geometry(); + geom.setX( xp*(wid+2) ); + geom.setWidth( wid ); + w->setGeometry( geom ); + } + } - int hours[24]; - memset( hours, 0, 24*sizeof( int ) ); - bool overFlow = FALSE; - for ( int i = 0; i < wCount; i++ ) { - DateBookDayWidget *w = widgetList.at(i); - int start = w->event().start().hour(); - QTime e = w->event().end(); - int end = e.hour(); - if ( e.minute() < 5 ) - end--; - if ( end < start ) - end = start; - while( start <= end ) { - hours[start]++; - if ( hours[start] >= 10 ) - overFlow = TRUE; - ++start; - } - if ( overFlow ) - break; - } - for ( int i = 0; i < 24; i++ ) { - n = QMAX( n, hours[i] ); - } - wid = ( view->columnWidth(0)-1 ) / n; - - bool used[24*10]; - memset( used, FALSE, 24*10*sizeof( bool ) ); - - for ( int i = 0; i < wCount; i++ ) { - DateBookDayWidget *w = widgetList.at(i); - int xp = place( w, used, n ); - if ( xp != -1 ) { - QRect geom = w->geometry(); - geom.setX( xp*(wid+2) ); - geom.setWidth( wid ); - w->setGeometry( geom ); - } + if (jumpToCurTime && this->date() == QDate::currentDate()) { + view->setContentsPos( 0, QTime::currentTime().hour() * view->rowHeight(0) ); //set listview to current hour + } else { + view->setContentsPos( 0, startTime * view->rowHeight(0) ); + } } - if (jumpToCurTime && this->date() == QDate::currentDate()) - view->setContentsPos( 0, QTime::currentTime().hour() * view->rowHeight(0) ); //set listview to current hour - else - view->setContentsPos( 0, startTime * view->rowHeight(0) ); - } - - timeMarker->setTime( QTime::currentTime() ); //display timeMarker - timeMarker->raise(); //on top of all widgets - if (this->date() == QDate::currentDate()) //only show timeMarker on current day - timeMarker->show(); else timeMarker->hide(); + timeMarker->setTime( QTime::currentTime() ); //display timeMarker + timeMarker->raise(); //on top of all widgets + if (this->date() == QDate::currentDate()) //only show timeMarker on current day + timeMarker->show(); else timeMarker->hide(); - setUpdatesEnabled( TRUE ); - return; + setUpdatesEnabled( TRUE ); + return; } DateBookDayWidget *DateBookDay::intersects( const DateBookDayWidget *item, const QRect &geom ) { - int i = 0; - DateBookDayWidget *w = widgetList.at(i); - int wCount = widgetList.count(); - while ( i < wCount && w != item ) { - if ( w->geometry().intersects( geom ) ) { - return w; + int i = 0; + DateBookDayWidget *w = widgetList.at(i); + int wCount = widgetList.count(); + while ( i < wCount && w != item ) { + if ( w->geometry().intersects( geom ) ) { + return w; + } + w = widgetList.at(++i); } - w = widgetList.at(++i); - } - return 0; + return 0; } QDate DateBookDay::date() const { - return currDate; + return currDate; } void DateBookDay::setStartViewTime( int startHere ) { - startTime = startHere; - dayView()->clearSelection(); - QTableSelection ts; - - if (jumpToCurTime && this->date() == QDate::currentDate()) //this should probably be in datebook.cpp where it's called? - { - ts.init( QTime::currentTime().hour(), 0); - ts.expandTo( QTime::currentTime().hour(), 0); - } else - { - ts.init( startTime, 0 ); - ts.expandTo( startTime, 0 ); - } + startTime = startHere; + dayView()->clearSelection(); + QTableSelection ts; + + if (jumpToCurTime && this->date() == QDate::currentDate()) { //this should probably be in datebook.cpp where it's called? + ts.init( QTime::currentTime().hour(), 0); + ts.expandTo( QTime::currentTime().hour(), 0); + } else { + ts.init( startTime, 0 ); + ts.expandTo( startTime, 0 ); + } - dayView()->addSelection( ts ); + dayView()->addSelection( ts ); } int DateBookDay::startViewTime() const { - return startTime; + return startTime; } void DateBookDay::slotWeekChanged( bool bStartOnMonday ) { - header->setStartOfWeek( bStartOnMonday ); - // redraw(); + header->setStartOfWeek( bStartOnMonday ); +// redraw(); } void DateBookDay::keyPressEvent(QKeyEvent *e) { - switch(e->key()) { - case Key_Up: - view->moveUp(); - break; - case Key_Down: - view->moveDown(); - break; - case Key_Left: - setDate(QDate(currDate).addDays(-1)); - break; - case Key_Right: - setDate(QDate(currDate).addDays(1)); - break; - default: - e->ignore(); - } + switch(e->key()) { + case Key_Up: + view->moveUp(); + break; + case Key_Down: + view->moveDown(); + break; + case Key_Left: + setDate(QDate(currDate).addDays(-1)); + break; + case Key_Right: + setDate(QDate(currDate).addDays(1)); + break; + default: + e->ignore(); + } } //=========================================================================== -DateBookDayWidget::DateBookDayWidget( const EffectiveEvent &e, - DateBookDay *db ) - : QWidget( db->dayView()->viewport() ), ev( e ), dateBook( db ) +DateBookDayWidget::DateBookDayWidget( const EffectiveEvent &e, DateBookDay *db ) + : QWidget( db->dayView()->viewport() ), ev( e ), dateBook( db ) { - - // why would someone use "<"? Oh well, fix it up... // I wonder what other things may be messed up... - QString strDesc = ev.description(); - int where = strDesc.find( "<" ); - while ( where != -1 ) { - strDesc.remove( where, 1 ); - strDesc.insert( where, "<" ); - where = strDesc.find( "<", where ); - } + QString strDesc = ev.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; +// ### 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.notes(); where = strNote.find( "<" ); while ( where != -1 ) { strNote.remove( where, 1 ); strNote.insert( where, "<" ); where = strNote.find( "<", where ); } text = "<b>" + strDesc + "</b><br>" + "<i>"; if ( !strCat.isEmpty() ) { text += strCat + "</i><br>"; } - if (ev.event().type() == Event::Normal ) + if (ev.event().type() == Event::Normal ) { setEventText( text ); - else + } else { setAllDayText( text ); + } - text += "<br><br>" + strNote; + text += "<br><br>" + strNote; - setBackgroundMode( PaletteBase ); + setBackgroundMode( PaletteBase ); QTime start = ev.start(); QTime end = ev.end(); int y = start.hour()*60+start.minute(); int h = end.hour()*60+end.minute()-y; int rh = dateBook->dayView()->rowHeight(0); y = y*rh/60; h = h*rh/60; 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. if ( y > ((24*rh)-12) ) y=(24*rh)-12; // Make sure the widget fits inside the dayview. geom.setY( y ); geom.setHeight( h ); geom.setX( 0 ); geom.setWidth(dateBook->dayView()->columnWidth(0)-1); } + void DateBookDayWidget::setAllDayText( QString &text ) { - text += "<b>" + tr("This is an all day event.") + "</b>"; + text += "<b>" + tr("This is an all day event.") + "</b>"; } + void DateBookDayWidget::setEventText( QString& text ) { bool whichClock = dateBook->dayView()->whichClock(); if ( ev.startDate() != ev.endDate() ) { text += "<b>" + tr("Start") + "</b>: "; text += TimeString::timeString( ev.event().start().time(), whichClock, FALSE ); text += " - " + TimeString::longDateString( ev.startDate() ) + "<br>"; text += "<b>" + tr("End") + "</b>: "; text += TimeString::timeString( ev.event().end().time(), whichClock, FALSE ); text += " - " + TimeString::longDateString( ev.endDate() ); } else { text += "<b>" + tr("Time") + "</b>: "; text += TimeString::timeString( ev.start(), whichClock, FALSE ); text += "<b>" + tr(" - ") + "</b>"; text += TimeString::timeString( ev.end(), whichClock, FALSE ); } } DateBookDayWidget::~DateBookDayWidget() { } void DateBookDayWidget::paintEvent( QPaintEvent *e ) { - QPainter p( this ); + QPainter p( this ); - if (dateBook->getSelectedWidget() == this) - { - p.setBrush( QColor( 155, 240, 230 ) ); // selected item - } else - { - if (dateBook->date() == QDate::currentDate()) - { - QTime curTime = QTime::currentTime(); - - if (ev.end() < curTime) - { - p.setBrush( QColor( 180, 180, 180 ) ); // grey, inactive - } else - { - //change color in dependence of the time till the event starts - int duration = curTime.secsTo(ev.start()); - if (duration < 0) duration = 0; - int colChange = duration*160/86400; //86400: secs per day, 160: max color shift - - p.setBrush( QColor( 200-colChange, 200-colChange, 255 ) ); //blue - } - } else - { - p.setBrush( QColor( 220, 220, 220 ) ); //light grey, inactive (not current date) - //perhaps make a distinction between future/past dates - } - } + if (dateBook->getSelectedWidget() == this) { + p.setBrush( QColor( 155, 240, 230 ) ); // selected item + } else { + if (dateBook->date() == QDate::currentDate()) { + QTime curTime = QTime::currentTime(); + if (ev.end() < curTime) { + p.setBrush( QColor( 180, 180, 180 ) ); // grey, inactive + } else { + //change color in dependence of the time till the event starts + int duration = curTime.secsTo(ev.start()); + if (duration < 0) duration = 0; + int colChange = duration*160/86400; //86400: secs per day, 160: max color shift + p.setBrush( QColor( 200-colChange, 200-colChange, 255 ) ); //blue + } + } else { + p.setBrush( QColor( 220, 220, 220 ) ); //light grey, inactive (not current date) + //perhaps make a distinction between future/past dates + } + } - p.setPen( QColor(100, 100, 100) ); - p.drawRect(rect()); + p.setPen( QColor(100, 100, 100) ); + p.drawRect(rect()); // p.drawRect(0,0, 5, height()); - int y = 0; - int d = 0; + int y = 0; + int d = 0; - if ( ev.event().hasAlarm() ) { - p.drawPixmap( width() - 16, 0, Resource::loadPixmap( "bell" ) ); - y = 20; - d = 20; - } + if ( ev.event().hasAlarm() ) { + p.drawPixmap( width() - 16, 0, Resource::loadPixmap( "bell" ) ); + y = 20; + d = 20; + } - if ( ev.event().hasRepeat() ) { - p.drawPixmap( width() - 16, y, Resource::loadPixmap( "repeat" ) ); - d = 20; - y += 20; - } + if ( ev.event().hasRepeat() ) { + p.drawPixmap( width() - 16, y, Resource::loadPixmap( "repeat" ) ); + d = 20; + y += 20; + } - QSimpleRichText rt( text, font() ); - rt.setWidth( geom.width() - d - 6 ); - rt.draw( &p, 7, 0, e->region(), colorGroup() ); + QSimpleRichText rt( text, font() ); + rt.setWidth( geom.width() - d - 6 ); + rt.draw( &p, 7, 0, e->region(), colorGroup() ); } void DateBookDayWidget::mousePressEvent( QMouseEvent *e ) { DateBookDayWidget *item; item = dateBook->getSelectedWidget(); - if (item) item->update(); + if (item) + item->update(); dateBook->setSelectedWidget(this); update(); dateBook->repaint(); QPopupMenu m; m.insertItem( tr( "Edit" ), 1 ); m.insertItem( tr( "Duplicate" ), 4 ); m.insertItem( tr( "Delete" ), 2 ); if(Ir::supported()) m.insertItem( tr( "Beam" ), 3 ); int r = m.exec( e->globalPos() ); if ( r == 1 ) { emit editMe( ev.event() ); } else if ( r == 2 ) { emit deleteMe( ev.event() ); } else if ( r == 3 ) { emit beamMe( ev.event() ); } else if ( r == 4 ) { emit duplicateMe( ev.event() ); } } void DateBookDayWidget::setGeometry( const QRect &r ) { - geom = r; - setFixedSize( r.width()+1, r.height()+1 ); - dateBook->dayView()->moveChild( this, r.x(), r.y()-1 ); - show(); + geom = r; + setFixedSize( r.width()+1, r.height()+1 ); + dateBook->dayView()->moveChild( this, r.x(), r.y()-1 ); + show(); } //--------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------- DateBookDayTimeMarker::DateBookDayTimeMarker( DateBookDay *db ) - : QWidget( db->dayView()->viewport() ), dateBook( db ) + : QWidget( db->dayView()->viewport() ), dateBook( db ) { setBackgroundMode( PaletteBase ); } DateBookDayTimeMarker::~DateBookDayTimeMarker() { } void DateBookDayTimeMarker::paintEvent( QPaintEvent */*e*/ ) { QPainter p( this ); p.setBrush( QColor( 255, 0, 0 ) ); QPen pen; pen.setStyle(NoPen); p.setPen( pen ); p.drawRect(rect()); } void DateBookDayTimeMarker::setTime( const QTime &t ) { int y = t.hour()*60+t.minute(); int rh = dateBook->dayView()->rowHeight(0); y = y*rh/60; geom.setX( 0 ); int x = dateBook->dayView()->columnWidth(0)-1; geom.setWidth( x ); geom.setY( y ); geom.setHeight( 1 ); setGeometry( geom ); time = t; } void DateBookDayTimeMarker::setGeometry( const QRect &r ) { - geom = r; - setFixedSize( r.width()+1, r.height()+1 ); - dateBook->dayView()->moveChild( this, r.x(), r.y()-1 ); - show(); + geom = r; + setFixedSize( r.width()+1, r.height()+1 ); + dateBook->dayView()->moveChild( this, r.x(), r.y()-1 ); + show(); } diff --git a/core/pim/datebook/datebookday.h b/core/pim/datebook/datebookday.h index 2faf24e..961f60f 100644 --- a/core/pim/datebook/datebookday.h +++ b/core/pim/datebook/datebookday.h @@ -1,207 +1,230 @@ /********************************************************************** ** Copyright (C) 2000 Trolltech AS. All rights reserved. ** ** This file is part of 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. ** **********************************************************************/ #ifndef DATEBOOKDAY_H #define DATEBOOKDAY_H #include <qpe/event.h> #include <qdatetime.h> #include <qtable.h> #include <qvbox.h> #include <qlist.h> +#include "datebook.h" +#include <qlineedit.h> + class DateBookDayHeader; class DateBookDB; class QDateTime; class QMouseEvent; class QPaintEvent; class QResizeEvent; +class DateBookDayViewQuickLineEdit : public QLineEdit +{ + Q_OBJECT +public: + DateBookDayViewQuickLineEdit(const QDateTime &start, const QDateTime &end,QWidget * parent, const char *name=0); +protected: + Event quickEvent; + int active; + void focusOutEvent( QFocusEvent *e ); +protected slots: + void slotReturnPressed(void); +signals: + void insertEvent(const Event &e); +}; + + class DateBookDayView : public QTable { Q_OBJECT public: DateBookDayView( bool hourClock, QWidget *parent, const char *name ); bool whichClock() const; void setRowStyle( int style ); public slots: void moveUp(); void moveDown(); + void slotDateChanged( int year, int month, int day ); signals: void sigColWidthChanged(); void sigCapturedKey( const QString &txt ); protected slots: - void slotChangeClock( bool ); + void slotChangeClock( bool ); protected: virtual void paintCell( QPainter *p, int row, int col, const QRect &cr, bool selected ); virtual void paintFocus( QPainter *p, const QRect &cr ); virtual void resizeEvent( QResizeEvent *e ); void keyPressEvent( QKeyEvent *e ); + void contentsMouseReleaseEvent( QMouseEvent *e ); void initHeader(); private: bool ampm; + QDate currDate; + DateBookDayViewQuickLineEdit *quickLineEdit; }; class DateBookDay; class DateBookDayWidget : public QWidget { Q_OBJECT public: DateBookDayWidget( const EffectiveEvent &e, DateBookDay *db ); ~DateBookDayWidget(); const QRect &geometry() { return geom; } void setGeometry( const QRect &r ); const EffectiveEvent &event() const { return ev; } signals: void deleteMe( const Event &e ); void duplicateMe( const Event &e ); void editMe( const Event &e ); void beamMe( const Event &e ); protected: void paintEvent( QPaintEvent *e ); void mousePressEvent( QMouseEvent *e ); private: /** * Sets the text for an all day Event * All day events have no time associated */ void setAllDayText( QString& text ); /** * Sets the EventText * it got a start and an end Time */ void setEventText( QString& text ); const EffectiveEvent ev; DateBookDay *dateBook; QString text; QRect geom; }; //Marker for current time in the dayview class DateBookDayTimeMarker : public QWidget { Q_OBJECT public: DateBookDayTimeMarker( DateBookDay *db ); ~DateBookDayTimeMarker(); const QRect &geometry() { return geom; } void setGeometry( const QRect &r ); void setTime( const QTime &t ); signals: protected: void paintEvent( QPaintEvent *e ); private: QRect geom; QTime time; DateBookDay *dateBook; }; //reimplemented the compareItems function so that it sorts DayWidgets by geometry heights class WidgetListClass : public QList<DateBookDayWidget> { private: int compareItems( QCollection::Item s1, QCollection::Item s2 ) { //hmm, don't punish me for that ;) if (reinterpret_cast<DateBookDayWidget*>(s1)->geometry().height() > reinterpret_cast<DateBookDayWidget*>(s2)->geometry().height()) { return -1; } else { return 1; } } }; class DateBookDay : public QVBox { Q_OBJECT public: DateBookDay( bool ampm, bool startOnMonday, DateBookDB *newDb, QWidget *parent, const char *name ); void selectedDates( QDateTime &start, QDateTime &end ); QDate date() const; DateBookDayView *dayView() const { return view; } void setStartViewTime( int startHere ); int startViewTime() const; void setSelectedWidget( DateBookDayWidget * ); DateBookDayWidget * getSelectedWidget( void ); void setJumpToCurTime( bool bJump ); void setRowStyle( int style ); public slots: void setDate( int y, int m, int d ); void setDate( QDate ); void redraw(); void slotWeekChanged( bool bStartOnMonday ); void updateView(); //updates TimeMarker and DayWidget-colors signals: void removeEvent( const Event& ); void editEvent( const Event& ); void duplicateEvent( const Event& ); void beamEvent( const Event& ); void newEvent(); void sigNewEvent( const QString & ); protected slots: void keyPressEvent(QKeyEvent *); private slots: void dateChanged( int y, int m, int d ); void slotColWidthChanged() { relayoutPage(); }; private: void getEvents(); void relayoutPage( bool fromResize = false ); DateBookDayWidget *intersects( const DateBookDayWidget *item, const QRect &geom ); QDate currDate; DateBookDayView *view; DateBookDayHeader *header; DateBookDB *db; WidgetListClass widgetList; //reimplemented QList for sorting widgets by height int startTime; bool jumpToCurTime; //should we jump to current time in dayview? int rowStyle; DateBookDayWidget *selectedWidget; //actual selected widget (obviously) DateBookDayTimeMarker *timeMarker; //marker for current time }; #endif |