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

mainwindow.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 <unistd.h>
00032 
00033 #include <opie2/odebug.h>
00034 #include <opie2/opimrecurrence.h>
00035 #include <opie2/opimnotifymanager.h>
00036 #include <opie2/otodoaccessvcal.h>
00037 #include <opie2/oapplicationfactory.h>
00038 
00039 #include <qpe/applnk.h>
00040 #include <qpe/config.h>
00041 #include <qpe/ir.h>
00042 #include <qpe/qpemessagebox.h>
00043 #include <qpe/alarmserver.h>
00044 #include <qpe/qpeapplication.h>
00045 
00046 #include <qaction.h>
00047 #include <qlayout.h>
00048 #include <qmenubar.h>
00049 #include <qmessagebox.h>
00050 #include <qpushbutton.h>
00051 #include <qstringlist.h>
00052 #include <qtimer.h>
00053 #include <qwhatsthis.h>
00054 
00055 #include "quickeditimpl.h"
00056 #include "todotemplatemanager.h"
00057 #include "templatedialogimpl.h"
00058 #include "tableview.h"
00059 
00060 #include "textviewshow.h"
00061 #include "todoeditor.h"
00062 #include "newtaskdlg.h"
00063 #include "mainwindow.h"
00064 
00065 using Opie::Core::OApplicationFactory;
00066 OPIE_EXPORT_APP( OApplicationFactory<Todo::MainWindow> )
00067 
00068 using namespace Opie;
00069 using namespace Todo;
00070 
00071 MainWindow::MainWindow( QWidget* parent,
00072                         const char* name, WFlags )
00073     : Opie::OPimMainWindow( "Todolist", "Todo List", tr( "Task" ), "todo",
00074                             parent, name, WType_TopLevel | WStyle_ContextHelp )
00075 {
00076     setCaption( tr( "Todo List" ) );
00077     if (!name)
00078         setName("todo window");
00079 
00080     m_syncing = false;
00081     m_showing = false;
00082     m_counter = 0;
00083     m_tempManager = new TemplateManager();
00084     m_tempManager->load();
00085 
00086     initConfig();
00087     initUI();
00088     initViews();
00089     initActions();
00090     initEditor();
00091     initShow();
00092 
00093     raiseCurrentView();
00094     QTimer::singleShot( 0, this, SLOT(initStuff()) );
00095 }
00096 void MainWindow::initStuff() {
00097     m_todoMgr.load();
00098     setViewCategory( m_curCat );
00099     setCategory( m_curCat );
00100 }
00101 void MainWindow::initActions() {
00102     // Insert Task menu items
00103     QActionGroup *items = new QActionGroup( this, QString::null, false );
00104 
00105     m_deleteCompleteAction = new QAction( QString::null, QWidget::tr( "Delete completed" ),
00106                                           0, items, 0 );
00107     connect( m_deleteCompleteAction, SIGNAL(activated()), this, SLOT(slotDeleteCompleted()) );
00108 
00109     insertItemMenuItems( items );
00110 
00111     // Insert View menu items
00112     items = new QActionGroup( this, QString::null, false );
00113 
00114     m_completedAction = new QAction( QString::null, QWidget::tr("Show completed tasks"),
00115                                      0, items, 0, true );
00116     m_completedAction->setOn( showCompleted() );
00117     connect( m_completedAction, SIGNAL(toggled(bool)), this, SLOT(slotShowCompleted(bool)) );
00118 
00119     QAction *a = new QAction( QString::null, QWidget::tr("Show only over-due tasks"),
00120                               0, items, 0, true );
00121     a->setOn( showOverDue() );
00122     connect( a, SIGNAL(toggled(bool)), this, SLOT(slotShowDue(bool)) );
00123 
00124     m_showDeadLineAction = new QAction( QString::null, QWidget::tr("Show task deadlines"),
00125                                         0, items, 0, true );
00126     m_showDeadLineAction->setOn( showDeadline() );
00127     connect( m_showDeadLineAction, SIGNAL(toggled(bool)), this, SLOT(slotShowDeadLine(bool)) );
00128 
00129     m_showQuickTaskAction = new QAction( QString::null, QWidget::tr("Show quick task bar"),
00130                                          0, items, 0, true );
00131     m_showQuickTaskAction->setOn( showQuickTask() );
00132     connect( m_showQuickTaskAction, SIGNAL(toggled(bool)), this, SLOT(slotShowQuickTask(bool)) );
00133 
00134     insertViewMenuItems( items );
00135 }
00136 /* m_curCat from Config */
00137 void MainWindow::initConfig() {
00138     Config config( "todo" );
00139     config.setGroup( "View" );
00140     m_completed =  config.readBoolEntry( "ShowComplete", true );
00141     m_curCat = config.readEntry( "Category", QString::null );
00142     m_deadline =  config.readBoolEntry( "ShowDeadLine", true);
00143     m_overdue = config.readBoolEntry("ShowOverDue", false );
00144     m_quicktask = config.readBoolEntry("ShowQuickTask", true);
00145 }
00146 void MainWindow::initUI() {
00147     // Create main widget stack
00148     m_stack = new Opie::Ui::OWidgetStack(this,  "main stack");
00149     setCentralWidget( m_stack );
00150     connect( this, SIGNAL(categorySelected(const QString&)),
00151             this, SLOT(setCategory(const QString&)) );
00152 
00153     // Create quick task toolbar
00154     m_curQuick = new QuickEditImpl( this, m_quicktask );
00155     addToolBar( (QToolBar *)m_curQuick->widget(), QWidget::tr( "QuickEdit" ),
00156                 QMainWindow::Top, true );
00157     m_curQuick->signal()->connect( this, SLOT(slotQuickEntered()) );
00158 }
00159 void MainWindow::initViews() {
00160 
00161     TableView* tableView = new TableView( this, m_stack );
00162     QWhatsThis::add( tableView, QWidget::tr( "This is a listing of all current tasks.\n\nThe list displays the following information:\n1. Completed - A green checkmark indicates task is completed.  Click here to complete a task.\n2. Priority - a graphical representation of task priority.  Double-click here to modify.\n3. Description - description of task.  Click here to select the task.\n4. Deadline - shows when task is due.  This column can be shown or hidden by selecting Options->'Show task deadlines' from the menu above." ) );
00163     m_stack->addWidget( tableView,  m_counter++ );
00164     m_views.append( tableView );
00165     m_curView = tableView;
00166     connectBase( tableView );
00167     /* add QString type + QString configname to
00168      * the View menu
00169      * and subdirs for multiple views
00170      */
00171 }
00172 void MainWindow::initEditor() {
00173     m_curEdit = new Editor();
00174 }
00175 void MainWindow::initShow() {
00176     m_curShow = new TextViewShow(this, this);
00177     m_stack->addWidget( m_curShow->widget() , m_counter++ );
00178 }
00179 MainWindow::~MainWindow() {
00180     delete templateManager();
00181 }
00182 void MainWindow::connectBase( ViewBase* ) {
00183     // once templates and signals mix we'll use it again
00184 }
00185 QPopupMenu* MainWindow::contextMenu( int , bool /*recur*/ ) {
00186     return itemContextMenu();
00187 }
00188 OPimTodoAccess::List MainWindow::list()const {
00189     return m_todoMgr.list();
00190 }
00191 OPimTodoAccess::List MainWindow::sorted( bool asc, int sortOrder ) {
00192     int cat = 0;
00193     if ( m_curCat != tr( "All" ) )
00194         cat = currentCatId();
00195     if ( m_curCat == tr( "Unfiled" ) )
00196         cat = -1;
00197 
00198     int filter = OPimTodoAccess::FilterCategory;
00199 
00200     if (!m_completed )
00201         filter |= OPimTodoAccess::DoNotShowCompleted;
00202     if (m_overdue)
00203         filter |= OPimTodoAccess::OnlyOverDue;
00204 
00205     return m_todoMgr.sorted( asc, sortOrder, filter, cat );
00206 }
00207 OPimTodoAccess::List MainWindow::sorted( bool asc, int sortOrder, int addFilter) {
00208     int cat = 0;
00209     if ( m_curCat != tr( "All" ) )
00210         cat = currentCatId();
00211 
00212     if ( m_curCat == tr( "Unfiled" ) )
00213         cat = -1;
00214 
00215     return m_todoMgr.sorted(asc, sortOrder, addFilter,  cat );
00216 }
00217 OPimTodo MainWindow::event( int uid ) {
00218     return m_todoMgr.event( uid );
00219 }
00220 bool MainWindow::isSyncing()const {
00221     return m_syncing;
00222 }
00223 TemplateManager* MainWindow::templateManager() {
00224     return m_tempManager;
00225 }
00226 Editor* MainWindow::currentEditor() {
00227     return m_curEdit;
00228 }
00229 TodoShow* MainWindow::currentShow() {
00230     return m_curShow;
00231 }
00232 void MainWindow::slotReload() {
00233     m_syncing = false;
00234     m_todoMgr.reload();
00235     currentView()->updateView( );
00236     raiseCurrentView();
00237 }
00238 void MainWindow::closeEvent( QCloseEvent* e ) {
00239     if (m_stack->visibleWidget() == currentShow()->widget() ) {
00240         m_showing = false;
00241         raiseCurrentView();
00242         e->ignore();
00243         return;
00244     }
00245     /*
00246      * we should have flushed and now we're still saving
00247      * so there is no need to flush
00248      */
00249     if (m_syncing ) {
00250         e->accept();
00251         return;
00252     }
00253     bool quit = false;
00254     if ( m_todoMgr.saveAll() ){
00255         quit = true;
00256     }else {
00257         if ( QMessageBox::critical( this, QWidget::tr("Out of space"),
00258                                     QWidget::tr("Todo was unable\n"
00259                                        "to save your changes.\n"
00260                                        "Free up some space\n"
00261                                        "and try again.\n"
00262                                        "\nQuit Anyway?"),
00263                                     QMessageBox::Yes|QMessageBox::Escape,
00264                                     QMessageBox::No|QMessageBox::Default)
00265              != QMessageBox::No ) {
00266             e->accept();
00267             quit = true;
00268         }else
00269             e->ignore();
00270 
00271     }
00272 
00273     if (quit ) {
00274         Config config( "todo" );
00275         config.setGroup( "View" );
00276         config.writeEntry( "ShowComplete", showCompleted() );
00277         config.writeEntry( "Category", currentCategory() );
00278         config.writeEntry( "ShowDeadLine", showDeadline());
00279         config.writeEntry( "ShowOverDue", showOverDue() );
00280         config.writeEntry( "ShowQuickTask", showQuickTask() );
00281         /* save templates */
00282         templateManager()->save();
00283         e->accept();
00284         QTimer::singleShot(0, qApp, SLOT(closeAllWindows()) );
00285     }
00286 }
00287 void MainWindow::slotItemNew() {
00288     NewTaskDlg dlg( templateManager()->templates(), this );
00289     if ( QPEApplication::execDialog( &dlg ) == QDialog::Accepted ) {
00290         QString tempName = dlg.tempSelected();
00291         if ( tempName.isNull() )
00292             // Create new, blank task
00293             create();
00294         else {
00295             // Create new task from the template selected
00296             OPimTodo event = templateManager()->templateEvent( tempName );
00297             event = currentEditor()->edit( this, event );
00298             if ( currentEditor()->accepted() ) {
00299                 event.setUid( 1 );
00300                 handleAlarms( OPimTodo(), event );
00301                 m_todoMgr.add( event );
00302                 currentView()->addEvent( event );
00303 
00304                 reloadCategories();
00305             }
00306             raiseCurrentView();
00307         }
00308     }
00309 }
00310 void MainWindow::slotItemEdit() {
00311     slotEdit( currentView()->current() );
00312 }
00313 void MainWindow::slotItemDuplicate() {
00314     if(m_syncing) {
00315         QMessageBox::warning(this, QWidget::tr("Todo"),
00316                                                          QWidget::tr("Data can not be edited, currently syncing"));
00317         return;
00318     }
00319     OPimTodo ev = m_todoMgr.event( currentView()->current() );
00320     /* let's generate a new uid */
00321     ev.setUid(1);
00322     m_todoMgr.add( ev );
00323 
00324     currentView()->addEvent( ev );
00325     raiseCurrentView();
00326 }
00327 void MainWindow::slotItemDelete() {
00328     if (!currentView()->current() )
00329         return;
00330 
00331     if(m_syncing) {
00332         QMessageBox::warning(this, QWidget::tr("Todo"),
00333                                                          QWidget::tr("Data can not be edited, currently syncing"));
00334         return;
00335     }
00336     QString strName = currentView()->currentRepresentation();
00337     if (!QPEMessageBox::confirmDelete(this, QWidget::tr("Todo"), strName ) )
00338         return;
00339 
00340     handleAlarms( m_todoMgr.event( currentView()->current() ), OPimTodo() );
00341     m_todoMgr.remove( currentView()->current() );
00342     currentView()->removeEvent( currentView()->current() );
00343     raiseCurrentView();
00344 }
00345 
00346 static const char *beamfile = "/tmp/opie-todo.vcs";
00347 void MainWindow::slotItemBeam() {
00348     beam( currentView()->current() );
00349 }
00350 void MainWindow::slotItemFind() {
00351 }
00352 void MainWindow::slotConfigure() {
00353     TemplateDialogImpl dlg( this, m_tempManager );
00354     if ( QPEApplication::execDialog( &dlg ) != QDialog::Accepted )
00355         m_tempManager->load();
00356 }
00357 void MainWindow::slotDelete(int uid ) {
00358     if( uid == 0 ) return;
00359     if(m_syncing) {
00360         QMessageBox::warning(this, QWidget::tr("Todo"),
00361                                                          QWidget::tr("Data can not be edited, currently syncing"));
00362         return;
00363     }
00364     OPimTodo to = m_todoMgr.event(uid);
00365     if (!QPEMessageBox::confirmDelete(this, QWidget::tr("Todo"), to.toShortText() ) )
00366         return;
00367 
00368     handleAlarms(to, OPimTodo() );
00369     m_todoMgr.remove( to.uid() );
00370     currentView()->removeEvent( to.uid() );
00371     raiseCurrentView();
00372 }
00373 void MainWindow::slotDeleteAll() {
00374     if(m_syncing) {
00375         QMessageBox::warning(this, QWidget::tr("Todo"),
00376                              QWidget::tr("Data can not be edited, currently syncing"));
00377         return;
00378     }
00379 
00380 
00381     if ( !QPEMessageBox::confirmDelete( this, QWidget::tr( "Todo" ), QWidget::tr("all tasks?") ) )
00382         return;
00383 
00384     m_todoMgr.removeAll();
00385     currentView()->clear();
00386 
00387     raiseCurrentView();
00388 }
00389 void MainWindow::slotDeleteCompleted() {
00390     if(m_syncing) {
00391         QMessageBox::warning(this, QWidget::tr("Todo"),
00392                              QWidget::tr("Data can not be edited, currently syncing"));
00393         return;
00394     }
00395 
00396     if ( !QPEMessageBox::confirmDelete( this, QWidget::tr( "Todo" ), QWidget::tr("all completed tasks?") ) )
00397         return;
00398 
00399 
00400     m_todoMgr.removeCompleted();
00401     currentView()->updateView( );
00402 }
00403 /*
00404  * set the category
00405  */
00406 void MainWindow::setCategory( const QString &category ) {
00407     m_curCat = category;
00408     if ( m_curCat == tr( "All" ) )
00409         m_curCat = QString::null;
00410 
00411     currentView()->setShowCategory( m_curCat );
00412     raiseCurrentView();
00413 }
00414 void MainWindow::slotShowDeadLine( bool dead) {
00415     m_deadline = dead;
00416     currentView()->setShowDeadline( dead );
00417 }
00418 void MainWindow::slotShowCompleted( bool show) {
00419     m_completed = show;
00420     currentView()->setShowCompleted( m_completed );
00421 }
00422 void MainWindow::slotShowQuickTask( bool show ) {
00423     m_quicktask = show;
00424     if ( m_quicktask )
00425         m_curQuick->widget()->show();
00426     else
00427         m_curQuick->widget()->hide();
00428 }
00429 bool MainWindow::showOverDue()const {
00430     return m_overdue;
00431 }
00432 void MainWindow::setDocument( const QString& fi) {
00433     DocLnk doc(fi);
00434     if (doc.isValid() )
00435         receiveFile(doc.file() );
00436     else
00437         receiveFile(fi );
00438 }
00439 void MainWindow::beamDone( Ir* ir) {
00440     delete ir;
00441     ::unlink( beamfile );
00442 }
00443 void MainWindow::receiveFile( const QString& filename ) {
00444     OPimTodoAccessVCal* cal = new OPimTodoAccessVCal(filename );
00445 
00446     OPimTodoAccess acc( cal );
00447     acc.load();
00448     OPimTodoAccess::List list = acc.allRecords();
00449 
00450     if (list.count()){
00451 
00452         QString message = QWidget::tr("<P>%1 new tasks arrived.<p>Would you like to add them to your Todolist?").arg(list.count() );
00453 
00454         if ( QMessageBox::information(this, QWidget::tr("New Tasks"),
00455                                       message, QMessageBox::Ok,
00456                                       QMessageBox::Cancel ) == QMessageBox::Ok ) {
00457             OPimTodoAccess::List::Iterator it;
00458             for ( it = list.begin(); it != list.end(); ++it )
00459                 m_todoMgr.add( (*it) );
00460 
00461             currentView()->updateView();
00462         }
00463     }
00464 }
00465 
00466 void MainWindow::slotFlush() {
00467     m_syncing = true;
00468     m_todoMgr.save();
00469 }
00470 void MainWindow::slotShowDetails() {
00471     slotShow( currentView()->current() );
00472 }
00473 bool MainWindow::showCompleted()const {
00474     return m_completed;
00475 }
00476 bool MainWindow::showDeadline()const {
00477     return m_deadline;
00478 }
00479 bool MainWindow::showQuickTask()const {
00480     return m_quicktask;
00481 }
00482 QString MainWindow::currentCategory()const {
00483     return m_curCat;
00484 }
00485 int MainWindow::currentCatId() {
00486     return m_todoMgr.catId( m_curCat );
00487 }
00488 ViewBase* MainWindow::currentView() {
00489     return m_curView;
00490 }
00491 void MainWindow::raiseCurrentView() {
00492     // due QPE/Application/todolist show(int)
00493     // we might not have the populateCategories slot called once
00494     // we would show the otodo but then imediately switch to the currentView
00495     // if we're initially showing we shouldn't raise the table
00496     // in returnFromView we fix up m_showing
00497     if (m_showing ) return;
00498 
00499     m_stack->raiseWidget( m_curView->widget() );
00500 }
00501 void MainWindow::slotShowDue(bool ov) {
00502     m_overdue = ov;
00503     currentView()->showOverDue( ov );
00504     raiseCurrentView();
00505 }
00506 void MainWindow::slotShow( int uid ) {
00507     if ( uid == 0 ) return;
00508 
00509 
00510     currentShow()->slotShow( event( uid ) );
00511     m_stack->raiseWidget( currentShow()->widget() );
00512 }
00513 void MainWindow::slotShowNext() {
00514     int l = currentView()->next();
00515     if (l!=0)
00516         slotShow(l);
00517 }
00518 void MainWindow::slotShowPrev() {
00519     int l = currentView()->prev();
00520     if (l!=0)
00521         slotShow(l);
00522 }
00523 void MainWindow::slotEdit( int uid ) {
00524     if (uid == 0 ) return;
00525     if(m_syncing) {
00526         QMessageBox::warning(this, QWidget::tr("Todo"),
00527                              QWidget::tr("Data can't be edited, currently syncing"));
00528         return;
00529     }
00530 
00531     OPimTodo old_todo = m_todoMgr.event( uid );
00532 
00533     OPimTodo todo = currentEditor()->edit(this, old_todo );
00534 
00535     /* if completed */
00536     if ( currentEditor()->accepted() ) {
00537         handleAlarms( old_todo, todo );
00538         m_todoMgr.update( todo.uid(), todo );
00539         currentView()->replaceEvent( todo );
00540         /* a Category might have changed */
00541         reloadCategories();
00542     }
00543 
00544     raiseCurrentView();
00545 }
00546 /*
00547 void MainWindow::slotUpdate1( int uid, const SmallTodo& ev) {
00548     m_todoMgr.update( uid, ev );
00549 }
00550 */
00551 void MainWindow::updateTodo(  const OPimTodo& ev) {
00552     m_todoMgr.update( ev.uid() , ev );
00553 }
00554 /* The view changed it's configuration
00555  * update the view menu
00556  */
00557 void MainWindow::slotUpdate3( QWidget* ) {
00558 
00559 }
00560 void MainWindow::updateList() {
00561     m_todoMgr.updateList();
00562 }
00563 void MainWindow::setReadAhead( uint count ) {
00564     if (m_todoMgr.todoDB() )
00565         m_todoMgr.todoDB()->setReadAhead( count );
00566 }
00567 void MainWindow::slotQuickEntered() {
00568     OPimTodo todo = quickEditor()->todo();
00569     if (todo.isEmpty() )
00570         return;
00571 
00572     m_todoMgr.add( todo );
00573     currentView()->addEvent( todo );
00574     raiseCurrentView();
00575 }
00576 QuickEditBase* MainWindow::quickEditor() {
00577     return m_curQuick;
00578 }
00579 void MainWindow::slotComplete( int uid ) {
00580     slotComplete( event(uid) );
00581 }
00582 void MainWindow::slotComplete( const OPimTodo& todo ) {
00583     OPimTodo to = todo;
00584     to.setCompleted( !to.isCompleted() );
00585     to.setCompletedDate( QDate::currentDate() );
00586 
00587     /*
00588      * if the item does recur
00589      * we need to spin it off
00590      * and update the items duedate to the next
00591      * possible recurrance of this item...
00592      * the spinned off one will loose the
00593      * recurrence.
00594      * We calculate the difference between the old due date and the
00595      * new one and add this diff to start, completed and alarm dates
00596      * -zecke
00597      */
00598     if ( to.hasRecurrence() && to.isCompleted() ) {
00599         OPimTodo to2( to );
00600 
00601         /* the spinned off one won't recur anymore */
00602         to.setRecurrence( OPimRecurrence() );
00603 
00604         OPimRecurrence rec = to2.recurrence();
00605         rec.setStart( to.dueDate() );
00606         to2.setRecurrence( rec );
00607         /*
00608          * if there is a next occurence
00609          * from the duedate of the last recurrance
00610          */
00611         QDate date;
00612         if ( to2.recurrence().nextOcurrence( to2.dueDate().addDays(1), date ) ) {
00613             int dayDiff = to.dueDate().daysTo( date );
00614             QDate inval;
00615             /* generate a new uid for the old record */
00616             to.setUid( 1 );
00617 
00618             /* add the old one cause it has a new UID here cause it was spin off */
00619             m_todoMgr.add( to );
00620 
00621             /*
00622              * update the due date
00623              * start date
00624              * and complete date
00625              */
00626             to2.setDueDate( date );
00627             rec.setStart( date );
00628             to2.setRecurrence( rec );  // could be Monday, TuesDay, Thursday every week
00629 
00630             /* move start date */
00631             if (to2.hasStartDate() )
00632                 to2.setStartDate( to2.startDate().addDays( dayDiff ) );
00633 
00634             /* now the alarms */
00635             if (to2.hasNotifiers() ) {
00636                 OPimNotifyManager::Alarms _als = to2.notifiers().alarms();
00637                 OPimNotifyManager::Alarms als;
00638 
00639                 /* for every alarm move the day */
00640                 for ( OPimNotifyManager::Alarms::Iterator it = _als.begin(); it != _als.end(); ++it ) {
00641                     OPimAlarm al = (*it);
00642                     al.setDateTime( al.dateTime().addDays( dayDiff ) );
00643                     als.append( al );
00644                 }
00645                 to2.notifiers().setAlarms( als );
00646                 handleAlarms( OPimTodo(), todo );
00647             }
00648             to2.setCompletedDate( inval );
00649             to2.setCompleted( false );
00650 
00651             updateTodo( to2 );
00652         }else
00653             updateTodo( to );
00654     }else
00655         updateTodo( to );
00656 
00657     currentView()->updateView();
00658     raiseCurrentView();
00659 }
00660 void MainWindow::flush() {
00661     slotFlush();
00662 }
00663 void MainWindow::reload() {
00664     slotReload();
00665 }
00666 int MainWindow::create() {
00667     int uid = 0;
00668     if(m_syncing) {
00669         QMessageBox::warning(this, QWidget::tr("Todo"),
00670                              QWidget::tr("Data can not be edited, currently syncing"));
00671         return uid;
00672     }
00673     m_todoMgr.load();
00674 
00675 
00676     OPimTodo todo = currentEditor()->newTodo( currentCatId(),
00677                                            this );
00678 
00679     if ( currentEditor()->accepted() ) {
00680         //todo.assignUid();
00681         uid = todo.uid();
00682         handleAlarms( OPimTodo(), todo );
00683         m_todoMgr.add( todo );
00684         currentView()->addEvent( todo );
00685 
00686 
00687         // I'm afraid we must call this every time now, otherwise
00688         // spend expensive time comparing all these strings...
00689         // but only call if we changed something -zecke
00690         reloadCategories();
00691     }
00692     raiseCurrentView( );
00693 
00694     return uid;
00695 }
00696 /* delete it silently... */
00697 bool MainWindow::remove( int uid ) {
00698     if (m_syncing) return false;
00699 
00700     /* argh need to get the whole OEvent... to disable alarms -zecke */
00701     handleAlarms( OPimTodo(), m_todoMgr.event( uid ) );
00702 
00703     return m_todoMgr.remove( uid );
00704 }
00705 void MainWindow::beam( int uid) {
00706     if( uid == 0 ) return;
00707 
00708     ::unlink( beamfile );
00709     m_todoMgr.load();
00710 
00711     OPimTodo todo = event( uid );
00712     OPimTodoAccessVCal* cal = new OPimTodoAccessVCal(QString::fromLatin1(beamfile) );
00713     OPimTodoAccess acc( cal );
00714     acc.load();
00715     acc.add( todo );
00716     acc.save();
00717     Ir* ir = new Ir(this );
00718     connect(ir, SIGNAL(done(Ir*) ),
00719             this, SLOT(beamDone(Ir*) ) );
00720     ir->send(beamfile, todo.summary(), "text/x-vCalendar" );
00721 }
00722 void MainWindow::show( int uid ) {
00723     m_todoMgr.load(); // might not be loaded yet
00724     m_showing = true;
00725     slotShow( uid );
00726     raise();
00727     QPEApplication::setKeepRunning();
00728 }
00729 void MainWindow::edit( int uid ) {
00730     m_todoMgr.load();
00731     slotEdit( uid );
00732 }
00733 void MainWindow::add( const OPimRecord& rec) {
00734     OPimTodo test;
00735     if ( rec.rtti() != test.rtti() ) return;
00736     m_todoMgr.load(); // might not be loaded
00737 
00738     const OPimTodo& todo = static_cast<const OPimTodo&>(rec);
00739 
00740     m_todoMgr.add(todo );
00741     currentView()->addEvent( todo );
00742 
00743 
00744     // I'm afraid we must call this every time now, otherwise
00745     // spend expensive time comparing all these strings...
00746     // but only call if we changed something -zecke
00747     reloadCategories();
00748 }
00749 void MainWindow::slotReturnFromView() {
00750     m_showing = false;
00751     raiseCurrentView();
00752 }
00753 
00754 namespace {
00755     OPimNotifyManager::Alarms findNonMatching( const OPimNotifyManager::Alarms& oldAls,
00756                                                const OPimNotifyManager::Alarms& newAls ) {
00757         OPimNotifyManager::Alarms nonMatching;
00758         OPimNotifyManager::Alarms::ConstIterator oldIt = oldAls.begin();
00759         OPimNotifyManager::Alarms::ConstIterator newIt;
00760         for ( ; oldIt != oldAls.end(); ++oldIt ) {
00761             bool found = false;
00762             QDateTime oldDt = (*oldIt).dateTime();
00763             for (newIt= newAls.begin(); newIt != newAls.end(); ++newIt ) {
00764                 if ( oldDt == (*newIt).dateTime() ) {
00765                     found = true;
00766                     break;
00767                     }
00768             }
00769             if (!found)
00770                 nonMatching.append( (*oldIt) );
00771         }
00772         return nonMatching;
00773     }
00774     void addAlarms( const OPimNotifyManager::Alarms& als, int uid ) {
00775         OPimNotifyManager::Alarms::ConstIterator it;
00776         for ( it = als.begin(); it != als.end(); ++it ) {
00777             AlarmServer::addAlarm( (*it).dateTime(), "QPE/Application/todolist", "alarm(QDateTime,int)", uid );
00778         }
00779 
00780     }
00781     void removeAlarms( const OPimNotifyManager::Alarms& als, int uid ) {
00782         OPimNotifyManager::Alarms::ConstIterator it;
00783         for ( it = als.begin(); it != als.end(); ++it ) {
00784             AlarmServer::deleteAlarm( (*it).dateTime(), "QPE/Application/todolist", "alarm(QDateTime,int)", uid );
00785         }
00786     }
00787 }
00788 
00789 void MainWindow::handleAlarms( const OPimTodo& oldTodo, const OPimTodo& newTodo) {
00790     /*
00791      * if oldTodo is not empty and has notifiers we need to find the deleted ones
00792      */
00793     if(!oldTodo.isEmpty() && oldTodo.hasNotifiers() ) {
00794         OPimNotifyManager::Alarms removed;
00795         OPimNotifyManager::Alarms oldAls = oldTodo.notifiers().alarms();
00796         if (!newTodo.hasNotifiers() )
00797             removed = oldAls;
00798         else
00799             removed = findNonMatching( oldAls, newTodo.notifiers().alarms() );
00800 
00801         removeAlarms( removed, oldTodo.uid() );
00802     }
00803     if ( newTodo.hasNotifiers() ) {
00804         OPimNotifyManager::Alarms added;
00805         if ( oldTodo.isEmpty() || !oldTodo.hasNotifiers() )
00806             added = newTodo.notifiers().alarms();
00807         else
00808             added = findNonMatching( newTodo.notifiers().alarms(), oldTodo.notifiers().alarms() );
00809 
00810         addAlarms( added, newTodo.uid() );
00811     }
00812 }
00813 /* we might have not loaded the db */
00814 void MainWindow::doAlarm( const QDateTime& dt, int uid ) {
00815     m_todoMgr.load();
00816 
00817     OPimTodo todo = m_todoMgr.event( uid );
00818     if (!todo.hasNotifiers() ) return;
00819 
00820     /*
00821      * let's find the right alarm and find out if silent
00822      * then show a richtext widget
00823      */
00824     bool loud = false;
00825     OPimNotifyManager::Alarms als = todo.notifiers().alarms();
00826     OPimNotifyManager::Alarms::Iterator it;
00827     for ( it = als.begin(); it != als.end(); ++it ) {
00828         if ( (*it).dateTime() == dt ) {
00829             loud = ( (*it).sound() == OPimAlarm::Loud );
00830             break;
00831         }
00832     }
00833     if (loud)
00834         startAlarm();
00835 
00836     QDialog dlg(this, 0, true );
00837     QVBoxLayout* lay = new QVBoxLayout( &dlg );
00838     QTextView* view = new QTextView( &dlg );
00839     lay->addWidget( view );
00840     QPushButton* btnOk = new QPushButton( tr("Ok"), &dlg );
00841     connect( btnOk, SIGNAL(clicked() ), &dlg, SLOT(accept() ) );
00842     lay->addWidget( btnOk );
00843 
00844     QString text = tr("<h1>Alarm at %1</h1><br>").arg( TimeString::dateString( dt ) );
00845     text += todo.toRichText();
00846     view->setText( text );
00847 
00848     bool needToStay = QPEApplication::execDialog( &dlg );
00849 
00850     if (loud)
00851         killAlarm();
00852 
00853     if (needToStay) {
00854 //        showMaximized();
00855 //        raise();
00856         QPEApplication::setKeepRunning();
00857 //        setActiveWindow();
00858     }
00859 
00860 }
00861 

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