summaryrefslogtreecommitdiff
path: root/core/pim/todo/mainwindow.cpp
Unidiff
Diffstat (limited to 'core/pim/todo/mainwindow.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--core/pim/todo/mainwindow.cpp466
1 files changed, 466 insertions, 0 deletions
diff --git a/core/pim/todo/mainwindow.cpp b/core/pim/todo/mainwindow.cpp
new file mode 100644
index 0000000..fb85a09
--- a/dev/null
+++ b/core/pim/todo/mainwindow.cpp
@@ -0,0 +1,466 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "mainwindow.h"
22#include "todoentryimpl.h"
23#include "todotable.h"
24
25#include <qpe/qpeapplication.h>
26#include <qpe/config.h>
27#include <qpe/finddialog.h>
28#include <qpe/global.h>
29#include <qpe/ir.h>
30#include <qpe/qpemenubar.h>
31#include <qpe/qpemessagebox.h>
32#include <qpe/resource.h>
33#include <qpe/task.h>
34#include <qpe/qpetoolbar.h>
35
36#include <qaction.h>
37#include <qarray.h>
38#include <qdatastream.h>
39#include <qdatetime.h>
40#include <qfile.h>
41#include <qmessagebox.h>
42#include <qpopupmenu.h>
43
44#include <sys/stat.h>
45#include <sys/types.h>
46#include <fcntl.h>
47#include <unistd.h>
48
49#include <stdlib.h>
50
51static QString todolistXMLFilename()
52{
53 return Global::applicationFileName("todolist","todolist.xml");
54}
55
56static QString categoriesXMLFilename()
57{
58 return Global::applicationFileName("todolist","categories.xml");
59}
60
61TodoWindow::TodoWindow( QWidget *parent, const char *name, WFlags f = 0 ) :
62 QMainWindow( parent, name, f ), syncing(FALSE)
63{
64// QTime t;
65// t.start();
66
67 setCaption( tr("Todo") );
68 QString str;
69 table = new TodoTable( this );
70 table->setColumnWidth( 2, 10 );
71 table->setPaintingEnabled( FALSE );
72 table->setUpdatesEnabled( FALSE );
73 table->viewport()->setUpdatesEnabled( FALSE );
74
75 {
76 str = todolistXMLFilename();
77 if ( str.isNull() )
78 QMessageBox::critical( this,
79 tr("Out of Space"),
80 tr("Unable to create startup files\n"
81 "Free up some space\n"
82 "before you enter any data") );
83 else
84 table->load( str );
85 }
86
87 // repeat for categories...
88 str = categoriesXMLFilename();
89 if ( str.isNull() )
90 QMessageBox::critical( this,
91 tr( "Out of Space" ),
92 tr( "Unable to create startup files\n"
93 "Free up some space\n"
94 "before you enter any data") );
95
96 setCentralWidget( table );
97 setToolBarsMovable( FALSE );
98
99// qDebug("after load: t=%d", t.elapsed() );
100
101 Config config( "todo" );
102 config.setGroup( "View" );
103 bool complete = config.readBoolEntry( "ShowComplete", true );
104 table->setShowCompleted( complete );
105 QString category = config.readEntry( "Category", QString::null );
106 table->setShowCategory( category );
107
108 QPEToolBar *bar = new QPEToolBar( this );
109 bar->setHorizontalStretchable( TRUE );
110
111 QPEMenuBar *mb = new QPEMenuBar( bar );
112
113 catMenu = new QPopupMenu( this );
114 QPopupMenu *edit = new QPopupMenu( this );
115 contextMenu = new QPopupMenu( this );
116
117 bar = new QPEToolBar( this );
118
119 QAction *a = new QAction( tr( "New Task" ), Resource::loadPixmap( "new" ),
120 QString::null, 0, this, 0 );
121 connect( a, SIGNAL( activated() ),
122 this, SLOT( slotNew() ) );
123 a->addTo( bar );
124 a->addTo( edit );
125 a = new QAction( tr( "Edit" ), Resource::loadIconSet( "edit" ),
126 QString::null, 0, this, 0 );
127 connect( a, SIGNAL( activated() ),
128 this, SLOT( slotEdit() ) );
129 a->addTo( bar );
130 a->addTo( edit );
131 a->addTo( contextMenu );
132 a->setEnabled( FALSE );
133 editAction = a;
134 a = new QAction( tr( "Delete" ), Resource::loadIconSet( "trash" ),
135 QString::null, 0, this, 0 );
136 connect( a, SIGNAL( activated() ),
137 this, SLOT( slotDelete() ) );
138 a->addTo( bar );
139 a->addTo( edit );
140 a->addTo( contextMenu );
141 a->setEnabled( FALSE );
142 deleteAction = a;
143
144 if ( Ir::supported() ) {
145 a = new QAction( tr( "Beam" ), Resource::loadPixmap( "beam" ),
146 QString::null, 0, this, 0 );
147 connect( a, SIGNAL( activated() ),
148 this, SLOT( slotBeam() ) );
149 a->addTo( edit );
150 a->addTo( bar );
151 }
152
153 a = new QAction( tr( "Find" ), Resource::loadIconSet( "mag" ),
154 QString::null, 0, this, 0 );
155 connect( a, SIGNAL( activated() ),
156 this, SLOT( slotFind() ) );
157 a->addTo( bar );
158 a->addTo( edit );
159 if ( table->numRows() )
160 a->setEnabled( TRUE );
161 else
162 a->setEnabled( FALSE );
163
164 //a->setEnabled( FALSE );
165 findAction = a;
166// qDebug("mainwindow #2: t=%d", t.elapsed() );
167
168 completedAction = new QAction( QString::null, tr("Completed tasks"), 0, this, 0, TRUE );
169
170 catMenu->setCheckable( true );
171 populateCategories();
172
173 mb->insertItem( tr( "Task" ), edit );
174 mb->insertItem( tr( "View" ), catMenu );
175
176 resize( 200, 300 );
177 if ( table->numRows() > 0 )
178 currentEntryChanged( 0, 0 );
179 connect( table, SIGNAL( signalEdit() ),
180 this, SLOT( slotEdit() ) );
181 connect( table, SIGNAL(signalShowMenu(const QPoint &)),
182 this, SLOT( slotShowPopup(const QPoint &)) );
183
184// qDebug("mainwindow #3: t=%d", t.elapsed() );
185 table->updateVisible();
186 table->setUpdatesEnabled( TRUE );
187 table->setPaintingEnabled( TRUE );
188 table->viewport()->setUpdatesEnabled( TRUE );
189
190 connect( completedAction, SIGNAL( toggled(bool) ), this, SLOT( showCompleted(bool) ) );
191 connect( catMenu, SIGNAL(activated(int)), this, SLOT(setCategory(int)) );
192 connect( table, SIGNAL( currentChanged( int, int ) ),
193 this, SLOT( currentEntryChanged( int, int ) ) );
194
195// qDebug("done: t=%d", t.elapsed() );
196}
197
198void TodoWindow::slotNew()
199{
200 if(syncing) {
201 QMessageBox::warning(this, tr("Todo"),
202 tr("Can not edit data, currently syncing"));
203 return;
204 }
205
206 int id;
207 id = -1;
208 QArray<int> ids;
209 ids = table->currentEntry().categories();
210 if ( ids.count() )
211 id = ids[0];
212 NewTaskDialog e( id, this, 0, TRUE );
213
214 Task todo;
215
216#if defined(Q_WS_QWS) || defined(_WS_QWS_)
217 e.showMaximized();
218#endif
219 int ret = e.exec();
220
221 if ( ret == QDialog::Accepted ) {
222 table->setPaintingEnabled( false );
223 todo = e.todoEntry();
224 todo.assignUid();
225 table->addEntry( todo );
226 table->setPaintingEnabled( true );
227 findAction->setEnabled( TRUE );
228 }
229 // I'm afraid we must call this every time now, otherwise
230 // spend expensive time comparing all these strings...
231 populateCategories();
232}
233
234TodoWindow::~TodoWindow()
235{
236}
237
238void TodoWindow::slotDelete()
239{
240 if(syncing) {
241 QMessageBox::warning(this, tr("Todo"),
242 tr("Can not edit data, currently syncing"));
243 return;
244 }
245
246 if ( table->currentRow() == -1 )
247 return;
248
249 QString strName = table->text( table->currentRow(), 2 ).left( 30 );
250
251 if ( !QPEMessageBox::confirmDelete( this, tr( "Todo" ), strName ) )
252 return;
253
254
255
256 table->setPaintingEnabled( false );
257 table->removeCurrentEntry();
258 table->setPaintingEnabled( true );
259
260 if ( table->numRows() == 0 ) {
261 currentEntryChanged( -1, 0 );
262 findAction->setEnabled( FALSE );
263 }
264}
265
266void TodoWindow::slotEdit()
267{
268 if(syncing) {
269 QMessageBox::warning(this, tr("Todo"),
270 tr("Can not edit data, currently syncing"));
271 return;
272 }
273
274 Task todo = table->currentEntry();
275
276 NewTaskDialog e( todo, this, 0, TRUE );
277 e.setCaption( tr( "Edit Task" ) );
278
279#if defined(Q_WS_QWS) || defined(_WS_QWS_)
280 e.showMaximized();
281#endif
282 int ret = e.exec();
283
284 if ( ret == QDialog::Accepted ) {
285 table->setPaintingEnabled( false );
286 todo = e.todoEntry();
287 table->replaceCurrentEntry( todo );
288 table->setPaintingEnabled( true );
289 }
290 populateCategories();
291
292}
293
294void TodoWindow::slotShowPopup( const QPoint &p )
295{
296 contextMenu->popup( p );
297}
298
299void TodoWindow::showCompleted( bool s )
300{
301 if ( !table->isUpdatesEnabled() )
302 return;
303 table->setPaintingEnabled( false );
304 table->setShowCompleted( s );
305 table->setPaintingEnabled( true );
306}
307
308void TodoWindow::currentEntryChanged( int r, int )
309{
310 if ( r != -1 && table->rowHeight( r ) > 0 ) {
311 editAction->setEnabled( TRUE );
312 deleteAction->setEnabled( TRUE );
313 } else {
314 editAction->setEnabled( FALSE );
315 deleteAction->setEnabled( FALSE );
316 }
317}
318
319void TodoWindow::setCategory( int c )
320{
321 if ( c <= 0 ) return;
322 if ( !table->isUpdatesEnabled() )
323 return;
324 table->setPaintingEnabled( false );
325 for ( unsigned int i = 1; i < catMenu->count(); i++ )
326 catMenu->setItemChecked( i, c == (int)i );
327 if ( c == 1 ) {
328 table->setShowCategory( QString::null );
329 setCaption( tr("Todo") + " - " + tr( "All" ) );
330 } else if ( c == (int)catMenu->count() - 1 ) {
331 table->setShowCategory( tr( "Unfiled" ) );
332 setCaption( tr("Todo") + " - " + tr( "Unfiled" ) );
333 } else {
334 QString cat = table->categories()[c - 2];
335 table->setShowCategory( cat );
336 setCaption( tr("Todo") + " - " + cat );
337 }
338 table->setPaintingEnabled( true );
339}
340
341void TodoWindow::populateCategories()
342{
343 catMenu->clear();
344
345 completedAction->addTo( catMenu );
346 completedAction->setOn( table->showCompleted() );
347
348 int id,
349 rememberId;
350 id = 1;
351 catMenu->insertItem( tr( "All" ), id++ );
352// catMenu->insertSeparator();
353 QStringList categories = table->categories();
354 categories.append( tr( "Unfiled" ) );
355 for ( QStringList::Iterator it = categories.begin();
356 it != categories.end(); ++it ) {
357 catMenu->insertItem( *it, id );
358 if ( *it == table->showCategory() )
359 rememberId = id;
360 ++id;
361 }
362 if ( table->showCategory().isEmpty() )
363 setCategory( 1 );
364 else
365 setCategory( rememberId );
366}
367
368void TodoWindow::reload()
369{
370 table->clear();
371 table->load( todolistXMLFilename() );
372 syncing = FALSE;
373}
374
375void TodoWindow::flush()
376{
377 syncing = TRUE;
378 table->save( todolistXMLFilename() );
379}
380
381void TodoWindow::closeEvent( QCloseEvent *e )
382{
383 if(syncing) {
384 /* no need to save if in the middle of syncing */
385 e->accept();
386 return;
387 }
388
389 if ( table->save( todolistXMLFilename() ) ) {
390 e->accept();
391 // repeat for categories...
392 // if writing configs fail, it will emit an
393 // error, but I feel that it is "ok" for us to exit
394 // espically since we aren't told if the write succeeded...
395 Config config( "todo" );
396 config.setGroup( "View" );
397 config.writeEntry( "ShowComplete", table->showCompleted() );
398 config.writeEntry( "Category", table->showCategory() );
399 } else {
400 if ( QMessageBox::critical( this, tr("Out of space"),
401 tr("Todo was unable\n"
402 "to save your changes.\n"
403 "Free up some space\n"
404 "and try again.\n"
405 "\nQuit Anyway?"),
406 QMessageBox::Yes|QMessageBox::Escape,
407 QMessageBox::No|QMessageBox::Default)
408 != QMessageBox::No )
409 e->accept();
410 else
411 e->ignore();
412 }
413}
414
415void TodoWindow::slotFind()
416{
417 // put everything back to view all for searching...
418 if ( !catMenu->isItemChecked( 0 ) )
419 setCategory( 0 );
420
421 FindDialog dlg( "Todo List", this );
422 QObject::connect( &dlg,
423 SIGNAL(signalFindClicked(const QString &,
424 bool, bool, int)),
425 table,
426 SLOT(slotDoFind(const QString&, bool, bool, int)) );
427 QObject::connect( table, SIGNAL(signalNotFound()), &dlg,
428 SLOT(slotNotFound()) );
429 QObject::connect( table, SIGNAL(signalWrapAround()), &dlg,
430 SLOT(slotWrapAround()) );
431 dlg.exec();
432 if ( table->numSelections() )
433 table->clearSelection();
434 table->clearFindRow();
435}
436
437
438void TodoWindow::setDocument( const QString &filename )
439{
440 if ( filename.find(".vcs") != int(filename.length()) - 4 ) return;
441
442 QValueList<Task> tl = Task::readVCalendar( filename );
443 for( QValueList<Task>::Iterator it = tl.begin(); it != tl.end(); ++it ) {
444 table->addEntry( *it );
445 }
446}
447
448static const char * beamfile = "/tmp/obex/todo.vcs";
449
450void TodoWindow::slotBeam()
451{
452 unlink( beamfile ); // delete if exists
453 Task c = table->currentEntry();
454 mkdir("/tmp/obex/", 0755);
455 Task::writeVCalendar( beamfile, c );
456 Ir *ir = new Ir( this );
457 connect( ir, SIGNAL( done( Ir * ) ), this, SLOT( beamDone( Ir * ) ) );
458 QString description = c.description();
459 ir->send( beamfile, description, "text/x-vCalendar" );
460}
461
462void TodoWindow::beamDone( Ir *ir )
463{
464 delete ir;
465 unlink( beamfile );
466}