summaryrefslogtreecommitdiff
authorzecke <zecke>2002-04-14 15:14:03 (UTC)
committer zecke <zecke>2002-04-14 15:14:03 (UTC)
commita0fe593db4e700989cc19e28b67a58f87823afeb (patch) (unidiff)
tree1a369409be81aa0feb15899b56adda6ec12b2591
parent16dd1d47d51e6307be8d89d36571115cb7c8788c (diff)
downloadopie-a0fe593db4e700989cc19e28b67a58f87823afeb.zip
opie-a0fe593db4e700989cc19e28b67a58f87823afeb.tar.gz
opie-a0fe593db4e700989cc19e28b67a58f87823afeb.tar.bz2
-menu restructure ( closer to the Zaurus)
-first Part of restoring journal I need to rewrite the whole crap later qt journaled on a row basis which doesn't work anymore cause of flexible sorting -something I forgot ;)
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--core/pim/todo/mainwindow.cpp106
-rw-r--r--core/pim/todo/mainwindow.h14
-rw-r--r--core/pim/todo/todotable.cpp148
-rw-r--r--core/pim/todo/todotable.h7
4 files changed, 238 insertions, 37 deletions
diff --git a/core/pim/todo/mainwindow.cpp b/core/pim/todo/mainwindow.cpp
index b5cace9..883d78c 100644
--- a/core/pim/todo/mainwindow.cpp
+++ b/core/pim/todo/mainwindow.cpp
@@ -1,503 +1,571 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved. 2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3 Copyright (C) 2002 zecke 3 Copyright (C) 2002 zecke
4 Copyright (C) 2002 Stefan Eilers 4 Copyright (C) 2002 Stefan Eilers
5** 5**
6** This file is part of Qtopia Environment. 6** This file is part of Qtopia Environment.
7** 7**
8** This file may be distributed and/or modified under the terms of the 8** This file may be distributed and/or modified under the terms of the
9** GNU General Public License version 2 as published by the Free Software 9** GNU General Public License version 2 as published by the Free Software
10** Foundation and appearing in the file LICENSE.GPL included in the 10** Foundation and appearing in the file LICENSE.GPL included in the
11** packaging of this file. 11** packaging of this file.
12** 12**
13** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 13** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
14** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 14** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
15** 15**
16** See http://www.trolltech.com/gpl/ for GPL licensing information. 16** See http://www.trolltech.com/gpl/ for GPL licensing information.
17** 17**
18** Contact info@trolltech.com if any conditions of this licensing are 18** Contact info@trolltech.com if any conditions of this licensing are
19** not clear to you. 19** not clear to you.
20** 20**
21**********************************************************************/ 21**********************************************************************/
22 22
23#define QTOPIA_INTERNAL_FD 23#define QTOPIA_INTERNAL_FD
24 24
25#include "mainwindow.h" 25#include "mainwindow.h"
26#include "todoentryimpl.h" 26#include "todoentryimpl.h"
27#include "todotable.h" 27#include "todotable.h"
28 28
29#include <opie/tododb.h> 29#include <opie/tododb.h>
30#include <opie/todovcalresource.h> 30#include <opie/todovcalresource.h>
31#include <opie/ofontmenu.h> 31#include <opie/ofontmenu.h>
32 32
33#include <qpe/qpeapplication.h> 33#include <qpe/qpeapplication.h>
34#include <qpe/config.h> 34#include <qpe/config.h>
35#include <qpe/finddialog.h> 35#include <qpe/finddialog.h>
36#include <qpe/global.h> 36#include <qpe/global.h>
37#include <qpe/ir.h> 37#include <qpe/ir.h>
38#include <qpe/qpemenubar.h> 38#include <qpe/qpemenubar.h>
39#include <qpe/qpemessagebox.h> 39#include <qpe/qpemessagebox.h>
40#include <qpe/resource.h> 40#include <qpe/resource.h>
41//#include <qpe/task.h> 41//#include <qpe/task.h>
42#include <qpe/qpetoolbar.h> 42#include <qpe/qpetoolbar.h>
43 43
44#include <qaction.h> 44#include <qaction.h>
45#include <qarray.h> 45#include <qarray.h>
46#include <qdatastream.h> 46#include <qdatastream.h>
47#include <qdatetime.h> 47#include <qdatetime.h>
48#include <qfile.h> 48#include <qfile.h>
49#include <qmessagebox.h> 49#include <qmessagebox.h>
50#include <qpopupmenu.h> 50#include <qpopupmenu.h>
51 51
52#include <sys/stat.h> 52#include <sys/stat.h>
53#include <sys/types.h> 53#include <sys/types.h>
54#include <fcntl.h> 54#include <fcntl.h>
55#include <unistd.h> 55#include <unistd.h>
56 56
57#include <stdlib.h> 57#include <stdlib.h>
58 58
59static QString todolistXMLFilename() 59static QString todolistXMLFilename()
60{ 60{
61 return Global::applicationFileName("todolist","todolist.xml"); 61 return Global::applicationFileName("todolist","todolist.xml");
62} 62}
63 63
64static QString categoriesXMLFilename() 64static QString categoriesXMLFilename()
65{ 65{
66 return Global::applicationFileName("todolist","categories.xml"); 66 return Global::applicationFileName("todolist","categories.xml");
67} 67}
68 68
69TodoWindow::TodoWindow( QWidget *parent, const char *name, WFlags f = 0 ) : 69TodoWindow::TodoWindow( QWidget *parent, const char *name, WFlags f = 0 ) :
70 QMainWindow( parent, name, f ), syncing(FALSE) 70 QMainWindow( parent, name, f ), syncing(FALSE)
71{ 71{
72// QTime t; 72// QTime t;
73// t.start(); 73// t.start();
74 74
75 setCaption( tr("Todo") ); 75 setCaption( tr("Todo") );
76 QString str; 76 QString str;
77 table = new TodoTable( this ); 77 table = new TodoTable( this );
78 table->setColumnWidth( 2, 10 ); 78 table->setColumnWidth( 2, 10 );
79 table->setPaintingEnabled( FALSE ); 79 table->setPaintingEnabled( FALSE );
80 table->setUpdatesEnabled( FALSE ); 80 table->setUpdatesEnabled( FALSE );
81 table->viewport()->setUpdatesEnabled( FALSE ); 81 table->viewport()->setUpdatesEnabled( FALSE );
82 82
83 { 83 {
84 str = todolistXMLFilename(); 84 str = todolistXMLFilename();
85 if ( str.isNull() ) 85 if ( str.isNull() )
86 QMessageBox::critical( this, 86 QMessageBox::critical( this,
87 tr("Out of Space"), 87 tr("Out of Space"),
88 tr("Unable to create startup files\n" 88 tr("Unable to create startup files\n"
89 "Free up some space\n" 89 "Free up some space\n"
90 "before you enter any data") ); 90 "before you enter any data") );
91 else 91 else
92 table->load( str ); 92 table->load( str );
93 } 93 }
94 94
95 // repeat for categories... 95 // repeat for categories...
96 str = categoriesXMLFilename(); 96 str = categoriesXMLFilename();
97 if ( str.isNull() ) 97 if ( str.isNull() )
98 QMessageBox::critical( this, 98 QMessageBox::critical( this,
99 tr( "Out of Space" ), 99 tr( "Out of Space" ),
100 tr( "Unable to create startup files\n" 100 tr( "Unable to create startup files\n"
101 "Free up some space\n" 101 "Free up some space\n"
102 "before you enter any data") ); 102 "before you enter any data") );
103 103
104 setCentralWidget( table ); 104 setCentralWidget( table );
105 setToolBarsMovable( FALSE ); 105 setToolBarsMovable( FALSE );
106 106
107// qDebug("after load: t=%d", t.elapsed() ); 107// qDebug("after load: t=%d", t.elapsed() );
108 108
109 Config config( "todo" ); 109 Config config( "todo" );
110 config.setGroup( "View" ); 110 config.setGroup( "View" );
111 bool complete = config.readBoolEntry( "ShowComplete", true ); 111 bool complete = config.readBoolEntry( "ShowComplete", true );
112 table->setShowCompleted( complete ); 112 table->setShowCompleted( complete );
113 113
114 bool showdeadline = config.readBoolEntry("ShowDeadLine", true); 114 bool showdeadline = config.readBoolEntry("ShowDeadLine", true);
115 table->setShowDeadline (showdeadline); 115 table->setShowDeadline (showdeadline);
116 116
117 QString category = config.readEntry( "Category", QString::null ); 117 QString category = config.readEntry( "Category", QString::null );
118 table->setShowCategory( category ); 118 table->setShowCategory( category );
119 119
120 QPEToolBar *bar = new QPEToolBar( this ); 120 QPEToolBar *bar = new QPEToolBar( this );
121 bar->setHorizontalStretchable( TRUE ); 121 bar->setHorizontalStretchable( TRUE );
122 122
123 QPEMenuBar *mb = new QPEMenuBar( bar ); 123 QPEMenuBar *mb = new QPEMenuBar( bar );
124 124
125 catMenu = new QPopupMenu( this ); 125 catMenu = new QPopupMenu( this );
126 QPopupMenu *edit = new QPopupMenu( this ); 126 QPopupMenu *edit = new QPopupMenu( this );
127 QPopupMenu *options = new QPopupMenu(this );
128
127 contextMenu = new QPopupMenu( this ); 129 contextMenu = new QPopupMenu( this );
128 130
129 bar = new QPEToolBar( this ); 131 bar = new QPEToolBar( this );
130 132
131 QAction *a = new QAction( tr( "New Task" ), Resource::loadPixmap( "new" ), 133 QAction *a = new QAction( tr( "New Task" ), Resource::loadPixmap( "new" ),
132 QString::null, 0, this, 0 ); 134 QString::null, 0, this, 0 );
133 connect( a, SIGNAL( activated() ), 135 connect( a, SIGNAL( activated() ),
134 this, SLOT( slotNew() ) ); 136 this, SLOT( slotNew() ) );
135 a->addTo( bar ); 137 a->addTo( bar );
136 a->addTo( edit ); 138 a->addTo( edit );
137 139
138 a = new QAction( tr( "Edit" ), Resource::loadIconSet( "edit" ), 140 a = new QAction( tr( "Edit Task" ), Resource::loadIconSet( "edit" ),
139 QString::null, 0, this, 0 ); 141 QString::null, 0, this, 0 );
140 connect( a, SIGNAL( activated() ), 142 connect( a, SIGNAL( activated() ),
141 this, SLOT( slotEdit() ) ); 143 this, SLOT( slotEdit() ) );
142 a->addTo( bar ); 144 a->addTo( bar );
143 a->addTo( edit ); 145 a->addTo( edit );
144 a->addTo( contextMenu ); 146 a->addTo( contextMenu );
145 a->setEnabled( FALSE ); 147 a->setEnabled( FALSE );
146 editAction = a; 148 editAction = a;
149 edit->insertSeparator();
147 150
148 a = new QAction( tr( "Delete" ), Resource::loadIconSet( "trash" ), 151 a = new QAction( tr( "Delete..." ), Resource::loadIconSet( "trash" ),
149 QString::null, 0, this, 0 ); 152 QString::null, 0, this, 0 );
150 connect( a, SIGNAL( activated() ), 153 connect( a, SIGNAL( activated() ),
151 this, SLOT( slotDelete() ) ); 154 this, SLOT( slotDelete() ) );
152 a->addTo( bar ); 155 a->addTo( bar );
153 a->addTo( edit ); 156 a->addTo( edit );
154 a->addTo( contextMenu ); 157 a->addTo( contextMenu );
155 a->setEnabled( FALSE ); 158 a->setEnabled( FALSE );
156 deleteAction = a; 159 deleteAction = a;
157 160
161 // delete All in category is missing....
162 // set All Done
163 // set All Done in category
164
165 a = new QAction( QString::null, tr( "Delete all..."), 0, this, 0 );
166 connect(a, SIGNAL( activated() ),
167 this, SLOT( slotDeleteAll() ) );
168 a->addTo(edit );
169 a->setEnabled( FALSE );
170 deleteAllAction = a;
171
172 edit->insertSeparator();
173 a = new QAction( QString::null, tr("Duplicate" ), 0, this, 0 );
174 connect(a, SIGNAL( activated() ),
175 this, SLOT( slotDuplicate() ) );
176 a->addTo(edit );
177 a->setEnabled( FALSE );
178 duplicateAction = a;
179
180 edit->insertSeparator();
158 if ( Ir::supported() ) { 181 if ( Ir::supported() ) {
159 a = new QAction( tr( "Beam" ), Resource::loadPixmap( "beam" ), 182 a = new QAction( tr( "Beam" ), Resource::loadPixmap( "beam" ),
160 QString::null, 0, this, 0 ); 183 QString::null, 0, this, 0 );
161 connect( a, SIGNAL( activated() ), 184 connect( a, SIGNAL( activated() ),
162 this, SLOT( slotBeam() ) ); 185 this, SLOT( slotBeam() ) );
163 a->addTo( edit ); 186 a->addTo( edit );
164 a->addTo( bar ); 187 a->addTo( bar );
165 } 188 }
166 189
167 a = new QAction( tr( "Find" ), Resource::loadIconSet( "mag" ), 190 a = new QAction( tr( "Find" ), Resource::loadIconSet( "mag" ),
168 QString::null, 0, this, 0 ); 191 QString::null, 0, this, 0 );
169 connect( a, SIGNAL( activated() ), 192 connect( a, SIGNAL( activated() ),
170 this, SLOT( slotFind() ) ); 193 this, SLOT( slotFind() ) );
171 a->addTo( bar ); 194 a->addTo( bar );
172 a->addTo( edit ); 195 a->addTo( options );
196 options->insertSeparator();
197
173 if ( table->numRows() ) 198 if ( table->numRows() )
174 a->setEnabled( TRUE ); 199 a->setEnabled( TRUE );
175 else 200 else
176 a->setEnabled( FALSE ); 201 a->setEnabled( FALSE );
177 202
178 //a->setEnabled( FALSE ); 203 //a->setEnabled( FALSE );
179 findAction = a; 204 findAction = a;
180// qDebug("mainwindow #2: t=%d", t.elapsed() ); 205// qDebug("mainwindow #2: t=%d", t.elapsed() );
181 206
182 completedAction = new QAction( QString::null, tr("Completed tasks"), 0, this, 0, TRUE ); 207 completedAction = new QAction( QString::null, tr("Completed tasks"), 0, this, 0, TRUE );
183 208
184 showdeadlineAction = new QAction( QString::null, tr( "Show Deadline" ), 0, this, 0, TRUE ); 209 showdeadlineAction = new QAction( QString::null, tr( "Show Deadline" ), 0, this, 0, TRUE );
185 210
186 catMenu->setCheckable( true ); 211 catMenu->setCheckable( true );
187 populateCategories(); 212 populateCategories();
188 213
189 mb->insertItem( tr( "Data" ), edit ); 214
190 mb->insertItem( tr( "View" ), catMenu ); 215 completedAction->addTo( options );
216 completedAction->setOn( table->showCompleted() );
217 showdeadlineAction->addTo( options );
218 showdeadlineAction->setOn( table->showDeadline() );
219 options->insertSeparator( );
220 QList<QWidget> list;
221 list.append(table );
222 OFontMenu *menu = new OFontMenu(this, "menu",list );
223 menu->forceSize( table->horizontalHeader(), 10 );
224 //catMenu->insertItem(tr("Fonts"), menu );
225 list.clear();
226 options->insertItem( tr("Fonts"), menu );
227
191 228
229 mb->insertItem( tr( "Data" ), edit );
230 mb->insertItem( tr( "Category" ), catMenu );
231 mb->insertItem( tr( "Options"), options );
192 resize( 200, 300 ); 232 resize( 200, 300 );
193 if ( table->numRows() > 0 ) 233 if ( table->numRows() > 0 )
194 currentEntryChanged( 0, 0 ); 234 currentEntryChanged( 0, 0 );
195 connect( table, SIGNAL( signalEdit() ), 235 connect( table, SIGNAL( signalEdit() ),
196 this, SLOT( slotEdit() ) ); 236 this, SLOT( slotEdit() ) );
197 connect( table, SIGNAL(signalShowMenu(const QPoint &)), 237 connect( table, SIGNAL(signalShowMenu(const QPoint &)),
198 this, SLOT( slotShowPopup(const QPoint &)) ); 238 this, SLOT( slotShowPopup(const QPoint &)) );
199 239
200// qDebug("mainwindow #3: t=%d", t.elapsed() ); 240// qDebug("mainwindow #3: t=%d", t.elapsed() );
201 table->updateVisible(); 241 table->updateVisible();
202 table->setUpdatesEnabled( TRUE ); 242 table->setUpdatesEnabled( TRUE );
203 table->setPaintingEnabled( TRUE ); 243 table->setPaintingEnabled( TRUE );
204 table->viewport()->setUpdatesEnabled( TRUE ); 244 table->viewport()->setUpdatesEnabled( TRUE );
205 245
206 connect( completedAction, SIGNAL( toggled(bool) ), this, SLOT( showCompleted(bool) ) ); 246 connect( completedAction, SIGNAL( toggled(bool) ), this, SLOT( showCompleted(bool) ) );
207 connect( showdeadlineAction, SIGNAL( toggled(bool) ), this, SLOT( showDeadline(bool) ) ); 247 connect( showdeadlineAction, SIGNAL( toggled(bool) ), this, SLOT( showDeadline(bool) ) );
208 connect( catMenu, SIGNAL(activated(int)), this, SLOT(setCategory(int)) ); 248 connect( catMenu, SIGNAL(activated(int)), this, SLOT(setCategory(int)) );
209 connect( table, SIGNAL( currentChanged( int, int ) ), 249 connect( table, SIGNAL( currentChanged( int, int ) ),
210 this, SLOT( currentEntryChanged( int, int ) ) ); 250 this, SLOT( currentEntryChanged( int, int ) ) );
211 251
212// qDebug("done: t=%d", t.elapsed() ); 252// qDebug("done: t=%d", t.elapsed() );
213} 253}
214 254
215void TodoWindow::slotNew() 255void TodoWindow::slotNew()
216{ 256{
217 if(syncing) { 257 if(syncing) {
218 QMessageBox::warning(this, tr("Todo"), 258 QMessageBox::warning(this, tr("Todo"),
219 tr("Can not edit data, currently syncing")); 259 tr("Can not edit data, currently syncing"));
220 return; 260 return;
221 } 261 }
222 262
223 int id; 263 int id;
224 id = -1; 264 id = -1;
225 QArray<int> ids; 265 QArray<int> ids;
226 ids = table->currentEntry().categories(); 266 ids = table->currentEntry().categories();
227 if ( ids.count() ) 267 if ( ids.count() )
228 id = ids[0]; 268 id = ids[0];
229 NewTaskDialog e( id, this, 0, TRUE ); 269 NewTaskDialog e( id, this, 0, TRUE );
230 270
231 ToDoEvent todo; 271 ToDoEvent todo;
232 272
233#if defined(Q_WS_QWS) || defined(_WS_QWS_) 273#if defined(Q_WS_QWS) || defined(_WS_QWS_)
234 e.showMaximized(); 274 e.showMaximized();
235#endif 275#endif
236 int ret = e.exec(); 276 int ret = e.exec();
237 qWarning("finished" ); 277 qWarning("finished" );
238 if ( ret == QDialog::Accepted ) { 278 if ( ret == QDialog::Accepted ) {
239 table->setPaintingEnabled( false ); 279 table->setPaintingEnabled( false );
240 todo = e.todoEntry(); 280 todo = e.todoEntry();
241 //todo.assignUid(); 281 //todo.assignUid();
242 table->addEntry( todo ); 282 table->addEntry( todo );
243 table->setPaintingEnabled( true ); 283 table->setPaintingEnabled( true );
244 findAction->setEnabled( TRUE ); 284 findAction->setEnabled( TRUE );
245 } 285 }
246 // I'm afraid we must call this every time now, otherwise 286 // I'm afraid we must call this every time now, otherwise
247 // spend expensive time comparing all these strings... 287 // spend expensive time comparing all these strings...
248 populateCategories(); 288 populateCategories();
249} 289}
250 290
251TodoWindow::~TodoWindow() 291TodoWindow::~TodoWindow()
252{ 292{
253} 293}
254 294
255void TodoWindow::slotDelete() 295void TodoWindow::slotDelete()
256{ 296{
257 if(syncing) { 297 if(syncing) {
258 QMessageBox::warning(this, tr("Todo"), 298 QMessageBox::warning(this, tr("Todo"),
259 tr("Can not edit data, currently syncing")); 299 tr("Can not edit data, currently syncing"));
260 return; 300 return;
261 } 301 }
262 302
263 if ( table->currentRow() == -1 ) 303 if ( table->currentRow() == -1 )
264 return; 304 return;
265 305
266 QString strName = table->text( table->currentRow(), 2 ).left( 30 ); 306 QString strName = table->text( table->currentRow(), 2 ).left( 30 );
267 307
268 if ( !QPEMessageBox::confirmDelete( this, tr( "Todo" ), strName ) ) 308 if ( !QPEMessageBox::confirmDelete( this, tr( "Todo" ), strName ) )
269 return; 309 return;
270 310
271 311
272 312
273 table->setPaintingEnabled( false ); 313 table->setPaintingEnabled( false );
274 table->removeCurrentEntry(); 314 table->removeCurrentEntry();
275 table->setPaintingEnabled( true ); 315 table->setPaintingEnabled( true );
276 316
277 if ( table->numRows() == 0 ) { 317 if ( table->numRows() == 0 ) {
278 currentEntryChanged( -1, 0 ); 318 currentEntryChanged( -1, 0 );
279 findAction->setEnabled( FALSE ); 319 findAction->setEnabled( FALSE );
280 } 320 }
281} 321}
322void TodoWindow::slotDeleteAll()
323{
324 if(syncing) {
325 QMessageBox::warning(this, tr("Todo"),
326 tr("Can not edit data, currently syncing"));
327 return;
328 }
329
330 //QString strName = table->text( table->currentRow(), 2 ).left( 30 );
331
332 if ( !QPEMessageBox::confirmDelete( this, tr( "Todo" ), tr("Should I delete all tasks?") ) )
333 return;
334
335
336
337 table->setPaintingEnabled( false );
338 table->removeAllEntries();
339 table->setPaintingEnabled( true );
340
341 if ( table->numRows() == 0 ) {
342 currentEntryChanged( -1, 0 );
343 findAction->setEnabled( FALSE );
344 }
345}
282 346
283void TodoWindow::slotEdit() 347void TodoWindow::slotEdit()
284{ 348{
285 if(syncing) { 349 if(syncing) {
286 QMessageBox::warning(this, tr("Todo"), 350 QMessageBox::warning(this, tr("Todo"),
287 tr("Can not edit data, currently syncing")); 351 tr("Can not edit data, currently syncing"));
288 return; 352 return;
289 } 353 }
290 354
291 ToDoEvent todo = table->currentEntry(); 355 ToDoEvent todo = table->currentEntry();
292 356
293 NewTaskDialog e( todo, this, 0, TRUE ); 357 NewTaskDialog e( todo, this, 0, TRUE );
294 e.setCaption( tr( "Edit Task" ) ); 358 e.setCaption( tr( "Edit Task" ) );
295 359
296#if defined(Q_WS_QWS) || defined(_WS_QWS_) 360#if defined(Q_WS_QWS) || defined(_WS_QWS_)
297 e.showMaximized(); 361 e.showMaximized();
298#endif 362#endif
299 int ret = e.exec(); 363 int ret = e.exec();
300 364
301 if ( ret == QDialog::Accepted ) { 365 if ( ret == QDialog::Accepted ) {
302 table->setPaintingEnabled( false ); 366 table->setPaintingEnabled( false );
303 todo = e.todoEntry(); 367 todo = e.todoEntry();
304 table->replaceCurrentEntry( todo ); 368 table->replaceCurrentEntry( todo );
305 table->setPaintingEnabled( true ); 369 table->setPaintingEnabled( true );
306 } 370 }
307 populateCategories(); 371 populateCategories();
308 372
309} 373}
310 374void TodoWindow::slotDuplicate()
375{
376 if(syncing) {
377 QMessageBox::warning(this, tr("Todo"),
378 tr("Can not edit data, currently syncing"));
379 return;
380 }
381 ToDoEvent ev = table->currentEntry();
382 ToDoEvent ev2 = ToDoEvent( ev );
383 table->setPaintingEnabled( false );
384 table->addEntry( ev2 );
385 table->setPaintingEnabled( true );
386}
311void TodoWindow::slotShowPopup( const QPoint &p ) 387void TodoWindow::slotShowPopup( const QPoint &p )
312{ 388{
313 contextMenu->popup( p ); 389 contextMenu->popup( p );
314} 390}
315 391
316void TodoWindow::showCompleted( bool s ) 392void TodoWindow::showCompleted( bool s )
317{ 393{
318 if ( !table->isUpdatesEnabled() ) 394 if ( !table->isUpdatesEnabled() )
319 return; 395 return;
320 table->setPaintingEnabled( false ); 396 table->setPaintingEnabled( false );
321 table->setShowCompleted( s ); 397 table->setShowCompleted( s );
322 table->setPaintingEnabled( true ); 398 table->setPaintingEnabled( true );
323} 399}
324 400
325void TodoWindow::currentEntryChanged( int r, int ) 401void TodoWindow::currentEntryChanged( int r, int )
326{ 402{
327 if ( r != -1 && table->rowHeight( r ) > 0 ) { 403 if ( r != -1 && table->rowHeight( r ) > 0 ) {
328 editAction->setEnabled( TRUE ); 404 editAction->setEnabled( TRUE );
329 deleteAction->setEnabled( TRUE ); 405 deleteAction->setEnabled( TRUE );
406 duplicateAction->setEnabled( TRUE );
407 deleteAllAction->setEnabled( TRUE );
330 } else { 408 } else {
331 editAction->setEnabled( FALSE ); 409 editAction->setEnabled( FALSE );
332 deleteAction->setEnabled( FALSE ); 410 deleteAction->setEnabled( FALSE );
411 duplicateAction->setEnabled( FALSE );
412 deleteAllAction->setEnabled( FALSE );
333 } 413 }
334} 414}
335 415
336void TodoWindow::setCategory( int c ) 416void TodoWindow::setCategory( int c )
337{ 417{
338 if ( c <= 0 ) return; 418 if ( c <= 0 ) return;
339 if ( !table->isUpdatesEnabled() ) 419 if ( !table->isUpdatesEnabled() )
340 return; 420 return;
341 table->setPaintingEnabled( false ); 421 table->setPaintingEnabled( false );
342 for ( unsigned int i = 1; i < catMenu->count(); i++ ) 422 for ( unsigned int i = 1; i < catMenu->count(); i++ )
343 catMenu->setItemChecked( i, c == (int)i ); 423 catMenu->setItemChecked( i, c == (int)i );
344 if ( c == 1 ) { 424 if ( c == 1 ) {
345 table->setShowCategory( QString::null ); 425 table->setShowCategory( QString::null );
346 setCaption( tr("Todo") + " - " + tr( "All Categories" ) ); 426 setCaption( tr("Todo") + " - " + tr( "All Categories" ) );
347 } else if ( c == (int)catMenu->count() - 1 ) { 427 } else if ( c == (int)catMenu->count() - 1 ) {
348 table->setShowCategory( tr( "Unfiled" ) ); 428 table->setShowCategory( tr( "Unfiled" ) );
349 setCaption( tr("Todo") + " - " + tr( "Unfiled" ) ); 429 setCaption( tr("Todo") + " - " + tr( "Unfiled" ) );
350 } else { 430 } else {
351 QString cat = table->categories()[c - 2]; 431 QString cat = table->categories()[c - 2];
352 table->setShowCategory( cat ); 432 table->setShowCategory( cat );
353 setCaption( tr("Todo") + " - " + cat ); 433 setCaption( tr("Todo") + " - " + cat );
354 } 434 }
355 table->setPaintingEnabled( true ); 435 table->setPaintingEnabled( true );
356} 436}
357 437
358void TodoWindow::populateCategories() 438void TodoWindow::populateCategories()
359{ 439{
360 catMenu->clear(); 440 catMenu->clear();
361
362 QList<QWidget> list;
363 list.append(table );
364 OFontMenu *menu = new OFontMenu(this, "menu",list );
365 menu->forceSize( table->horizontalHeader(), 10 );
366 catMenu->insertItem(tr("Fonts"), menu );
367
368 completedAction->addTo( catMenu );
369 completedAction->setOn( table->showCompleted() );
370 showdeadlineAction->addTo( catMenu );
371 showdeadlineAction->setOn( table->showDeadline() );
372 catMenu->insertSeparator();
373 int id, rememberId; 441 int id, rememberId;
374 id = 1; 442 id = 1;
375 catMenu->insertItem( tr( "All Categories" ), id++ ); 443 catMenu->insertItem( tr( "All Categories" ), id++ );
376// catMenu->insertSeparator(); 444 catMenu->insertSeparator();
377 QStringList categories = table->categories(); 445 QStringList categories = table->categories();
378 categories.append( tr( "Unfiled" ) ); 446 categories.append( tr( "Unfiled" ) );
379 for ( QStringList::Iterator it = categories.begin(); 447 for ( QStringList::Iterator it = categories.begin();
380 it != categories.end(); ++it ) { 448 it != categories.end(); ++it ) {
381 catMenu->insertItem( *it, id ); 449 catMenu->insertItem( *it, id );
382 if ( *it == table->showCategory() ) 450 if ( *it == table->showCategory() )
383 rememberId = id; 451 rememberId = id;
384 ++id; 452 ++id;
385 } 453 }
386 if ( table->showCategory().isEmpty() ) 454 if ( table->showCategory().isEmpty() )
387 setCategory( 1 ); 455 setCategory( 1 );
388 else 456 else
389 setCategory( rememberId ); 457 setCategory( rememberId );
390} 458}
391 459
392void TodoWindow::reload() 460void TodoWindow::reload()
393{ 461{
394 table->clear(); 462 table->clear();
395 table->load( todolistXMLFilename() ); 463 table->load( todolistXMLFilename() );
396 syncing = FALSE; 464 syncing = FALSE;
397} 465}
398 466
399void TodoWindow::flush() 467void TodoWindow::flush()
400{ 468{
401 syncing = TRUE; 469 syncing = TRUE;
402 table->save( todolistXMLFilename() ); 470 table->save( todolistXMLFilename() );
403} 471}
404 472
405void TodoWindow::closeEvent( QCloseEvent *e ) 473void TodoWindow::closeEvent( QCloseEvent *e )
406{ 474{
407 if(syncing) { 475 if(syncing) {
408 /* no need to save if in the middle of syncing */ 476 /* no need to save if in the middle of syncing */
409 e->accept(); 477 e->accept();
410 return; 478 return;
411 } 479 }
412 480
413 if ( table->save( todolistXMLFilename() ) ) { 481 if ( table->save( todolistXMLFilename() ) ) {
414 e->accept(); 482 e->accept();
415 // repeat for categories... 483 // repeat for categories...
416 // if writing configs fail, it will emit an 484 // if writing configs fail, it will emit an
417 // error, but I feel that it is "ok" for us to exit 485 // error, but I feel that it is "ok" for us to exit
418 // espically since we aren't told if the write succeeded... 486 // espically since we aren't told if the write succeeded...
419 Config config( "todo" ); 487 Config config( "todo" );
420 config.setGroup( "View" ); 488 config.setGroup( "View" );
421 config.writeEntry( "ShowComplete", table->showCompleted() ); 489 config.writeEntry( "ShowComplete", table->showCompleted() );
422 config.writeEntry( "Category", table->showCategory() ); 490 config.writeEntry( "Category", table->showCategory() );
423 /* added 20.01.2k2 by se */ 491 /* added 20.01.2k2 by se */
424 config.writeEntry( "ShowDeadLine", table->showDeadline()); 492 config.writeEntry( "ShowDeadLine", table->showDeadline());
425 } else { 493 } else {
426 if ( QMessageBox::critical( this, tr("Out of space"), 494 if ( QMessageBox::critical( this, tr("Out of space"),
427 tr("Todo was unable\n" 495 tr("Todo was unable\n"
428 "to save your changes.\n" 496 "to save your changes.\n"
429 "Free up some space\n" 497 "Free up some space\n"
430 "and try again.\n" 498 "and try again.\n"
431 "\nQuit Anyway?"), 499 "\nQuit Anyway?"),
432 QMessageBox::Yes|QMessageBox::Escape, 500 QMessageBox::Yes|QMessageBox::Escape,
433 QMessageBox::No|QMessageBox::Default) 501 QMessageBox::No|QMessageBox::Default)
434 != QMessageBox::No ) 502 != QMessageBox::No )
435 e->accept(); 503 e->accept();
436 else 504 else
437 e->ignore(); 505 e->ignore();
438 } 506 }
439} 507}
440 508
441void TodoWindow::slotFind() 509void TodoWindow::slotFind()
442{ 510{
443 // put everything back to view all for searching... 511 // put everything back to view all for searching...
444 if ( !catMenu->isItemChecked( 0 ) ) 512 if ( !catMenu->isItemChecked( 0 ) )
445 setCategory( 0 ); 513 setCategory( 0 );
446 514
447 FindDialog dlg( "Todo List", this ); 515 FindDialog dlg( "Todo List", this );
448 QObject::connect( &dlg, 516 QObject::connect( &dlg,
449 SIGNAL(signalFindClicked(const QString &, 517 SIGNAL(signalFindClicked(const QString &,
450 bool, bool, int)), 518 bool, bool, int)),
451 table, 519 table,
452 SLOT(slotDoFind(const QString&, bool, bool, int)) ); 520 SLOT(slotDoFind(const QString&, bool, bool, int)) );
453 QObject::connect( table, SIGNAL(signalNotFound()), &dlg, 521 QObject::connect( table, SIGNAL(signalNotFound()), &dlg,
454 SLOT(slotNotFound()) ); 522 SLOT(slotNotFound()) );
455 QObject::connect( table, SIGNAL(signalWrapAround()), &dlg, 523 QObject::connect( table, SIGNAL(signalWrapAround()), &dlg,
456 SLOT(slotWrapAround()) ); 524 SLOT(slotWrapAround()) );
457 dlg.exec(); 525 dlg.exec();
458 if ( table->numSelections() ) 526 if ( table->numSelections() )
459 table->clearSelection(); 527 table->clearSelection();
460 table->clearFindRow(); 528 table->clearFindRow();
461} 529}
462 530
463 531
464void TodoWindow::setDocument( const QString &filename ) 532void TodoWindow::setDocument( const QString &filename )
465{ 533{
466 if ( filename.find(".vcs") != int(filename.length()) - 4 ) return; 534 if ( filename.find(".vcs") != int(filename.length()) - 4 ) return;
467 535
468 ToDoDB todoDB(filename, new ToDoVCalResource() ); 536 ToDoDB todoDB(filename, new ToDoVCalResource() );
469 QValueList<ToDoEvent> tl = todoDB.rawToDos(); 537 QValueList<ToDoEvent> tl = todoDB.rawToDos();
470 for( QValueList<ToDoEvent>::Iterator it = tl.begin(); it != tl.end(); ++it ) { 538 for( QValueList<ToDoEvent>::Iterator it = tl.begin(); it != tl.end(); ++it ) {
471 table->addEntry( *it ); 539 table->addEntry( *it );
472 } 540 }
473} 541}
474 542
475static const char * beamfile = "/tmp/obex/todo.vcs"; 543static const char * beamfile = "/tmp/obex/todo.vcs";
476 544
477void TodoWindow::slotBeam() 545void TodoWindow::slotBeam()
478{ 546{
479 unlink( beamfile ); // delete if exists 547 unlink( beamfile ); // delete if exists
480 ToDoEvent c = table->currentEntry(); 548 ToDoEvent c = table->currentEntry();
481 mkdir("/tmp/obex/", 0755); 549 mkdir("/tmp/obex/", 0755);
482 ToDoDB todoDB( beamfile, new ToDoVCalResource() ); 550 ToDoDB todoDB( beamfile, new ToDoVCalResource() );
483 todoDB.addEvent( c ); 551 todoDB.addEvent( c );
484 todoDB.save(); 552 todoDB.save();
485 Ir *ir = new Ir( this ); 553 Ir *ir = new Ir( this );
486 connect( ir, SIGNAL( done( Ir * ) ), this, SLOT( beamDone( Ir * ) ) ); 554 connect( ir, SIGNAL( done( Ir * ) ), this, SLOT( beamDone( Ir * ) ) );
487 QString description = c.description(); 555 QString description = c.description();
488 ir->send( beamfile, description, "text/x-vCalendar" ); 556 ir->send( beamfile, description, "text/x-vCalendar" );
489} 557}
490 558
491void TodoWindow::beamDone( Ir *ir ) 559void TodoWindow::beamDone( Ir *ir )
492{ 560{
493 delete ir; 561 delete ir;
494 unlink( beamfile ); 562 unlink( beamfile );
495} 563}
496 564
497/* added 20.01.2k2 by se */ 565/* added 20.01.2k2 by se */
498void TodoWindow::showDeadline( bool s ) 566void TodoWindow::showDeadline( bool s )
499{ 567{
500 table->setPaintingEnabled( false ); 568 table->setPaintingEnabled( false );
501 table->setShowDeadline( s ); 569 table->setShowDeadline( s );
502 table->setPaintingEnabled( true ); 570 table->setPaintingEnabled( true );
503} 571}
diff --git a/core/pim/todo/mainwindow.h b/core/pim/todo/mainwindow.h
index 9be7c66..b9172e1 100644
--- a/core/pim/todo/mainwindow.h
+++ b/core/pim/todo/mainwindow.h
@@ -1,82 +1,86 @@
1/********************************************************************** 1/**********************************************************************
2 Copyright (C) 2002 Holger 'zecke' Freyther <freyther@kde.org> 2 Copyright (C) 2002 Holger 'zecke' Freyther <freyther@kde.org>
3** Copyright (C) 2000 Trolltech AS. All rights reserved. 3** Copyright (C) 2000 Trolltech AS. All rights reserved.
4** 4**
5** This file is part of Qtopia and Opi Environment. 5** This file is part of Qtopia and Opi Environment.
6** 6**
7** This file may be distributed and/or modified under the terms of the 7** This file may be distributed and/or modified under the terms of the
8** GNU General Public License version 2 as published by the Free Software 8** GNU General Public License version 2 as published by the Free Software
9** Foundation and appearing in the file LICENSE.GPL included in the 9** Foundation and appearing in the file LICENSE.GPL included in the
10** packaging of this file. 10** packaging of this file.
11** 11**
12** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 12** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
13** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 13** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
14** 14**
15** See http://www.trolltech.com/gpl/ for GPL licensing information. 15** See http://www.trolltech.com/gpl/ for GPL licensing information.
16** 16**
17** Contact info@trolltech.com if any conditions of this licensing are 17** Contact info@trolltech.com if any conditions of this licensing are
18** not clear to you. 18** not clear to you.
19** 19**
20**********************************************************************/ 20**********************************************************************/
21 21
22#ifndef MAINWINDOW_H 22#ifndef MAINWINDOW_H
23#define MAINWINDOW_H 23#define MAINWINDOW_H
24 24
25#include <qmainwindow.h> 25#include <qmainwindow.h>
26 26
27class TodoTable; 27class TodoTable;
28class QAction; 28class QAction;
29class QPopupMenu; 29class QPopupMenu;
30class Ir; 30class Ir;
31class OFontMenu; 31class OFontMenu;
32 32
33class TodoWindow : public QMainWindow 33class TodoWindow : public QMainWindow
34{ 34{
35 Q_OBJECT 35 Q_OBJECT
36 36
37public: 37public:
38 TodoWindow( QWidget *parent = 0, const char *name = 0, WFlags f = 0 ); 38 TodoWindow( QWidget *parent = 0, const char *name = 0, WFlags f = 0 );
39 ~TodoWindow(); 39 ~TodoWindow();
40 40
41public slots: 41public slots:
42 void flush(); 42 void flush();
43 void reload(); 43 void reload();
44 44
45protected slots: 45protected slots:
46 void slotNew(); 46 void slotNew();
47 void slotDelete(); 47 void slotDelete();
48 void slotEdit(); 48 void slotEdit();
49 void slotShowPopup( const QPoint & ); 49 void slotShowPopup( const QPoint & );
50 void showCompleted( bool ); 50 void showCompleted( bool );
51 51
52 /* added 20.01.2k2 by se */ 52 /* added 20.01.2k2 by se */
53 void showDeadline( bool ); 53 void showDeadline( bool );
54 54
55 void currentEntryChanged( int r, int c ); 55 void currentEntryChanged( int r, int c );
56 void setCategory( int ); 56 void setCategory( int );
57 void slotFind(); 57 void slotFind();
58 void setDocument( const QString & ); 58 void setDocument( const QString & );
59 void slotBeam(); 59 void slotBeam();
60 void beamDone( Ir * ); 60 void beamDone( Ir * );
61 61 void slotDeleteAll();
62 void slotDuplicate();
63
62protected: 64protected:
63 void closeEvent( QCloseEvent *e ); 65 void closeEvent( QCloseEvent *e );
64 66
65private: 67private:
66 void populateCategories(); 68 void populateCategories();
67 69
68private: 70private:
69 TodoTable *table; 71 TodoTable *table;
70 QAction *editAction, 72 QAction *editAction,
71 *deleteAction, 73 *deleteAction,
72 *findAction, 74 *findAction,
73 * completedAction, 75 *completedAction,
74 *showdeadlineAction ; 76 *showdeadlineAction,
77 *deleteAllAction,
78 *duplicateAction;
75 QPopupMenu *contextMenu, *catMenu; 79 QPopupMenu *contextMenu, *catMenu;
76 80
77 bool syncing; 81 bool syncing;
78}; 82};
79 83
80#endif 84#endif
81 85
82 86
diff --git a/core/pim/todo/todotable.cpp b/core/pim/todo/todotable.cpp
index 2acd03c..401d2c8 100644
--- a/core/pim/todo/todotable.cpp
+++ b/core/pim/todo/todotable.cpp
@@ -1,761 +1,885 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved. 2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of Qtopia Environment. 4** This file is part of Qtopia Environment.
5** 5**
6** This file may be distributed and/or modified under the terms of the 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 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 8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file. 9** packaging of this file.
10** 10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 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. 12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13** 13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information. 14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15** 15**
16** Contact info@trolltech.com if any conditions of this licensing are 16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you. 17** not clear to you.
18** 18**
19**********************************************************************/ 19**********************************************************************/
20/* Show Deadline was added by Stefan Eilers (se, eilers.stefan@epost.de) 20/* Show Deadline was added by Stefan Eilers (se, eilers.stefan@epost.de)
21 */ 21 */
22#include "todotable.h" 22#include "todotable.h"
23 23
24#include <opie/tododb.h> 24#include <opie/tododb.h>
25#include <opie/xmltree.h>
26
25#include <qpe/categoryselect.h> 27#include <qpe/categoryselect.h>
26#include <qpe/xmlreader.h> 28#include <qpe/xmlreader.h>
27 29
28#include <qasciidict.h> 30#include <qasciidict.h>
29#include <qcombobox.h> 31#include <qcombobox.h>
30#include <qfile.h> 32#include <qfile.h>
31#include <qpainter.h> 33#include <qpainter.h>
32#include <qtextcodec.h> 34#include <qtextcodec.h>
33#include <qtimer.h> 35#include <qtimer.h>
34#include <qdatetime.h> 36#include <qdatetime.h>
37#include <qtextstream.h>
35 38
36#include <qcursor.h> 39#include <qcursor.h>
37#include <qregexp.h> 40#include <qregexp.h>
38 41
39#include <errno.h> 42#include <errno.h>
40#include <stdlib.h> 43#include <stdlib.h>
41 44
42#include <stdio.h> 45#include <stdio.h>
46#include <iostream>
43 47
48namespace {
44 49
45 50 static bool taskCompare( const ToDoEvent &task, const QRegExp &r, int category );
46static bool taskCompare( const ToDoEvent &task, const QRegExp &r, int category ); 51 static QString journalFileName();
47 52 static ToDoEvent xmlToEvent( XMLElement *ev );
48static QString journalFileName(); 53}
49
50CheckItem::CheckItem( QTable *t, const QString &key ) 54CheckItem::CheckItem( QTable *t, const QString &key )
51 : QTableItem( t, Never, "" ), checked( FALSE ), sortKey( key ) 55 : QTableItem( t, Never, "" ), checked( FALSE ), sortKey( key )
52{ 56{
53} 57}
54 58
55QString CheckItem::key() const 59QString CheckItem::key() const
56{ 60{
57 return sortKey; 61 return sortKey;
58} 62}
59 63
60void CheckItem::setChecked( bool b ) 64void CheckItem::setChecked( bool b )
61{ 65{
62 checked = b; 66 checked = b;
63 table()->updateCell( row(), col() ); 67 table()->updateCell( row(), col() );
64} 68}
65 69
66void CheckItem::toggle() 70void CheckItem::toggle()
67{ 71{
68 TodoTable *parent = static_cast<TodoTable*>(table()); 72 TodoTable *parent = static_cast<TodoTable*>(table());
69 ToDoEvent newTodo = parent->currentEntry(); 73 ToDoEvent newTodo = parent->currentEntry();
70 checked = !checked; 74 checked = !checked;
71 newTodo.setCompleted( checked ); 75 newTodo.setCompleted( checked );
72 table()->updateCell( row(), col() ); 76 table()->updateCell( row(), col() );
73 parent->replaceCurrentEntry( newTodo, true ); 77 parent->replaceCurrentEntry( newTodo, true );
74} 78}
75 79
76bool CheckItem::isChecked() const 80bool CheckItem::isChecked() const
77{ 81{
78 return checked; 82 return checked;
79} 83}
80 84
81static const int BoxSize = 10; 85static const int BoxSize = 10;
82 86
83void CheckItem::paint( QPainter *p, const QColorGroup &cg, const QRect &cr, 87void CheckItem::paint( QPainter *p, const QColorGroup &cg, const QRect &cr,
84 bool ) 88 bool )
85{ 89{
86 p->fillRect( 0, 0, cr.width(), cr.height(), cg.brush( QColorGroup::Base ) ); 90 p->fillRect( 0, 0, cr.width(), cr.height(), cg.brush( QColorGroup::Base ) );
87 91
88 int marg = ( cr.width() - BoxSize ) / 2; 92 int marg = ( cr.width() - BoxSize ) / 2;
89 int x = 0; 93 int x = 0;
90 int y = ( cr.height() - BoxSize ) / 2; 94 int y = ( cr.height() - BoxSize ) / 2;
91 p->setPen( QPen( cg.text() ) ); 95 p->setPen( QPen( cg.text() ) );
92 p->drawRect( x + marg, y, BoxSize, BoxSize ); 96 p->drawRect( x + marg, y, BoxSize, BoxSize );
93 p->drawRect( x + marg+1, y+1, BoxSize-2, BoxSize-2 ); 97 p->drawRect( x + marg+1, y+1, BoxSize-2, BoxSize-2 );
94 p->setPen( darkGreen ); 98 p->setPen( darkGreen );
95 x += 1; 99 x += 1;
96 y += 1; 100 y += 1;
97 if ( checked ) { 101 if ( checked ) {
98 QPointArray a( 7*2 ); 102 QPointArray a( 7*2 );
99 int i, xx, yy; 103 int i, xx, yy;
100 xx = x+1+marg; 104 xx = x+1+marg;
101 yy = y+2; 105 yy = y+2;
102 for ( i=0; i<3; i++ ) { 106 for ( i=0; i<3; i++ ) {
103 a.setPoint( 2*i, xx, yy ); 107 a.setPoint( 2*i, xx, yy );
104 a.setPoint( 2*i+1, xx, yy+2 ); 108 a.setPoint( 2*i+1, xx, yy+2 );
105 xx++; yy++; 109 xx++; yy++;
106 } 110 }
107 yy -= 2; 111 yy -= 2;
108 for ( i=3; i<7; i++ ) { 112 for ( i=3; i<7; i++ ) {
109 a.setPoint( 2*i, xx, yy ); 113 a.setPoint( 2*i, xx, yy );
110 a.setPoint( 2*i+1, xx, yy+2 ); 114 a.setPoint( 2*i+1, xx, yy+2 );
111 xx++; yy--; 115 xx++; yy--;
112 } 116 }
113 p->drawLineSegments( a ); 117 p->drawLineSegments( a );
114 } 118 }
115} 119}
116 120
117 121
118ComboItem::ComboItem( QTable *t, EditType et ) 122ComboItem::ComboItem( QTable *t, EditType et )
119 : QTableItem( t, et, "3" ), cb( 0 ) 123 : QTableItem( t, et, "3" ), cb( 0 )
120{ 124{
121 setReplaceable( FALSE ); 125 setReplaceable( FALSE );
122} 126}
123 127
124QWidget *ComboItem::createEditor() const 128QWidget *ComboItem::createEditor() const
125{ 129{
126 QString txt = text(); 130 QString txt = text();
127 ( (ComboItem*)this )->cb = new QComboBox( table()->viewport() ); 131 ( (ComboItem*)this )->cb = new QComboBox( table()->viewport() );
128 cb->insertItem( "1" ); 132 cb->insertItem( "1" );
129 cb->insertItem( "2" ); 133 cb->insertItem( "2" );
130 cb->insertItem( "3" ); 134 cb->insertItem( "3" );
131 cb->insertItem( "4" ); 135 cb->insertItem( "4" );
132 cb->insertItem( "5" ); 136 cb->insertItem( "5" );
133 cb->setCurrentItem( txt.toInt() - 1 ); 137 cb->setCurrentItem( txt.toInt() - 1 );
134 return cb; 138 return cb;
135} 139}
136 140
137void ComboItem::setContentFromEditor( QWidget *w ) 141void ComboItem::setContentFromEditor( QWidget *w )
138{ 142{
139 TodoTable *parent = static_cast<TodoTable*>(table()); 143 TodoTable *parent = static_cast<TodoTable*>(table());
140 ToDoEvent newTodo = parent->currentEntry(); 144 ToDoEvent newTodo = parent->currentEntry();
141 145
142 if ( w->inherits( "QComboBox" ) ) 146 if ( w->inherits( "QComboBox" ) )
143 setText( ( (QComboBox*)w )->currentText() ); 147 setText( ( (QComboBox*)w )->currentText() );
144 else 148 else
145 QTableItem::setContentFromEditor( w ); 149 QTableItem::setContentFromEditor( w );
146 newTodo.setPriority( text().toInt() ); 150 newTodo.setPriority( text().toInt() );
147 parent->replaceCurrentEntry( newTodo, true ); 151 parent->replaceCurrentEntry( newTodo, true );
148} 152}
149 153
150void ComboItem::setText( const QString &s ) 154void ComboItem::setText( const QString &s )
151{ 155{
152 if ( cb ) 156 if ( cb )
153 cb->setCurrentItem( s.toInt() - 1 ); 157 cb->setCurrentItem( s.toInt() - 1 );
154 QTableItem::setText( s ); 158 QTableItem::setText( s );
155} 159}
156 160
157QString ComboItem::text() const 161QString ComboItem::text() const
158{ 162{
159 if ( cb ) 163 if ( cb )
160 return cb->currentText(); 164 return cb->currentText();
161 return QTableItem::text(); 165 return QTableItem::text();
162} 166}
163DueTextItem::DueTextItem( QTable *t, ToDoEvent *ev ) 167DueTextItem::DueTextItem( QTable *t, ToDoEvent *ev )
164 : QTableItem(t, Never, QString::null ) 168 : QTableItem(t, Never, QString::null )
165{ 169{
166 setToDoEvent( ev ); 170 setToDoEvent( ev );
167} 171}
168QString DueTextItem::key() const 172QString DueTextItem::key() const
169{ 173{
170 QString key; 174 QString key;
171 if( m_hasDate ){ 175 if( m_hasDate ){
172 if(m_off == 0 ){ 176 if(m_off == 0 ){
173 key.append("b"); 177 key.append("b");
174 }else if( m_off > 0 ){ 178 }else if( m_off > 0 ){
175 key.append("c"); 179 key.append("c");
176 }else if( m_off < 0 ){ 180 }else if( m_off < 0 ){
177 key.append("a"); 181 key.append("a");
178 } 182 }
179 key.append(QString::number(m_off ) ); 183 key.append(QString::number(m_off ) );
180 }else{ 184 }else{
181 key.append("d"); 185 key.append("d");
182 } 186 }
183 return key; 187 return key;
184} 188}
185void DueTextItem::setToDoEvent( const ToDoEvent *ev ) 189void DueTextItem::setToDoEvent( const ToDoEvent *ev )
186{ 190{
187 m_hasDate = ev->hasDate(); 191 m_hasDate = ev->hasDate();
188 m_completed = ev->isCompleted(); 192 m_completed = ev->isCompleted();
189 if( ev->hasDate() ){ 193 if( ev->hasDate() ){
190 QDate today = QDate::currentDate(); 194 QDate today = QDate::currentDate();
191 m_off = today.daysTo(ev->date() ); 195 m_off = today.daysTo(ev->date() );
192 setText( QString::number(m_off) + " day(s) " ); 196 setText( QString::number(m_off) + " day(s) " );
193 }else{ 197 }else{
194 setText("n.d." ); 198 setText("n.d." );
195 m_off = 0; 199 m_off = 0;
196 } 200 }
197} 201}
198void DueTextItem::paint( QPainter *p, const QColorGroup &cg, const QRect &cr, bool selected ) 202void DueTextItem::paint( QPainter *p, const QColorGroup &cg, const QRect &cr, bool selected )
199{ 203{
200 QColorGroup cg2(cg); 204 QColorGroup cg2(cg);
201 QColor text = cg.text(); 205 QColor text = cg.text();
202 if( m_hasDate && !m_completed ){ 206 if( m_hasDate && !m_completed ){
203 if( m_off < 0 ){ 207 if( m_off < 0 ){
204 cg2.setColor(QColorGroup::Text, QColor(red ) ); 208 cg2.setColor(QColorGroup::Text, QColor(red ) );
205 }else if( m_off == 0 ){ 209 }else if( m_off == 0 ){
206 cg2.setColor(QColorGroup::Text, QColor(yellow) ); // orange isn't predefined 210 cg2.setColor(QColorGroup::Text, QColor(yellow) ); // orange isn't predefined
207 }else if( m_off > 0){ 211 }else if( m_off > 0){
208 cg2.setColor(QColorGroup::Text, QColor(green ) ); 212 cg2.setColor(QColorGroup::Text, QColor(green ) );
209 } 213 }
210 } 214 }
211 QTableItem::paint(p, cg2, cr, selected ); 215 QTableItem::paint(p, cg2, cr, selected );
212 cg2.setColor(QColorGroup::Text, text ); 216 cg2.setColor(QColorGroup::Text, text );
213} 217}
214TodoTable::TodoTable( QWidget *parent, const char *name ) 218TodoTable::TodoTable( QWidget *parent, const char *name )
215// #ifdef QT_QTABLE_NOHEADER_CONSTRUCTOR 219// #ifdef QT_QTABLE_NOHEADER_CONSTRUCTOR
216// : QTable( 0, 3, parent, name, TRUE ), 220// : QTable( 0, 3, parent, name, TRUE ),
217// #else 221// #else
218 : QTable( 0, 4, parent, name ), 222 : QTable( 0, 4, parent, name ),
219// #endif 223// #endif
220 showComp( true ), 224 showComp( true ),
221 enablePainting( true ), 225 enablePainting( true ),
222 mCat( 0 ), 226 mCat( 0 ),
223 currFindRow( -2 ), 227 currFindRow( -2 ),
224 showDeadl( true) 228 showDeadl( true)
225{ 229{
226 mCat.load( categoryFileName() ); 230 mCat.load( categoryFileName() );
227 setSorting( TRUE ); 231 setSorting( TRUE );
228 setSelectionMode( NoSelection ); 232 setSelectionMode( NoSelection );
229 setColumnStretchable( 2, TRUE ); 233 setColumnStretchable( 2, TRUE );
230 setColumnWidth( 0, 20 ); 234 setColumnWidth( 0, 20 );
231 setColumnWidth( 1, 35 ); 235 setColumnWidth( 1, 35 );
232 236
233 setLeftMargin( 0 ); 237 setLeftMargin( 0 );
234 verticalHeader()->hide(); 238 verticalHeader()->hide();
235 horizontalHeader()->setLabel( 0, tr( "C." ) ); 239 horizontalHeader()->setLabel( 0, tr( "C." ) );
236 horizontalHeader()->setLabel( 1, tr( "Prior." ) ); 240 horizontalHeader()->setLabel( 1, tr( "Prior." ) );
237 horizontalHeader()->setLabel( 2, tr( "Description" ) ); 241 horizontalHeader()->setLabel( 2, tr( "Description" ) );
238 242
239 setColumnStretchable( 3, FALSE ); 243 setColumnStretchable( 3, FALSE );
240 setColumnWidth( 3, 20 ); 244 setColumnWidth( 3, 20 );
241 horizontalHeader()->setLabel( 3, tr( "Deadline" ) ); 245 horizontalHeader()->setLabel( 3, tr( "Deadline" ) );
242 246
243 if (showDeadl){ 247 if (showDeadl){
244 showColumn (3); 248 showColumn (3);
245 }else{ 249 }else{
246 hideColumn (3); 250 hideColumn (3);
247 } 251 }
248 252
249 connect( this, SIGNAL( clicked( int, int, int, const QPoint & ) ), 253 connect( this, SIGNAL( clicked( int, int, int, const QPoint & ) ),
250 this, SLOT( slotClicked( int, int, int, const QPoint & ) ) ); 254 this, SLOT( slotClicked( int, int, int, const QPoint & ) ) );
251 connect( this, SIGNAL( pressed( int, int, int, const QPoint & ) ), 255 connect( this, SIGNAL( pressed( int, int, int, const QPoint & ) ),
252 this, SLOT( slotPressed( int, int, int, const QPoint & ) ) ); 256 this, SLOT( slotPressed( int, int, int, const QPoint & ) ) );
253 connect( this, SIGNAL( valueChanged( int, int ) ), 257 connect( this, SIGNAL( valueChanged( int, int ) ),
254 this, SLOT( slotCheckPriority( int, int ) ) ); 258 this, SLOT( slotCheckPriority( int, int ) ) );
255 connect( this, SIGNAL( currentChanged( int, int ) ), 259 connect( this, SIGNAL( currentChanged( int, int ) ),
256 this, SLOT( slotCurrentChanged( int, int ) ) ); 260 this, SLOT( slotCurrentChanged( int, int ) ) );
257 261
258 menuTimer = new QTimer( this ); 262 menuTimer = new QTimer( this );
259 connect( menuTimer, SIGNAL(timeout()), this, SLOT(slotShowMenu()) ); 263 connect( menuTimer, SIGNAL(timeout()), this, SLOT(slotShowMenu()) );
260} 264}
261 265
262void TodoTable::addEntry( const ToDoEvent &todo ) 266void TodoTable::addEntry( const ToDoEvent &todo )
263{ 267{
264 int row = numRows(); 268 int row = numRows();
265 setNumRows( row + 1 ); 269 setNumRows( row + 1 );
266 updateJournal( todo, ACTION_ADD ); 270 updateJournal( todo, ACTION_ADD );
267 insertIntoTable( new ToDoEvent(todo), row ); 271 insertIntoTable( new ToDoEvent(todo), row );
268 setCurrentCell(row, currentColumn()); 272 setCurrentCell(row, currentColumn());
269 updateVisible(); 273 updateVisible();
270} 274}
271 275
272void TodoTable::slotClicked( int row, int col, int, const QPoint &pos ) 276void TodoTable::slotClicked( int row, int col, int, const QPoint &pos )
273{ 277{
274 if ( !cellGeometry( row, col ).contains(pos) ) 278 if ( !cellGeometry( row, col ).contains(pos) )
275 return; 279 return;
276 // let's switch on the column number... 280 // let's switch on the column number...
277 switch ( col ) 281 switch ( col )
278 { 282 {
279 case 0: { 283 case 0: {
280 CheckItem *i = static_cast<CheckItem*>(item( row, col )); 284 CheckItem *i = static_cast<CheckItem*>(item( row, col ));
281 if ( i ) { 285 if ( i ) {
282 int x = pos.x() - columnPos( col ); 286 int x = pos.x() - columnPos( col );
283 int y = pos.y() - rowPos( row ); 287 int y = pos.y() - rowPos( row );
284 int w = columnWidth( col ); 288 int w = columnWidth( col );
285 int h = rowHeight( row ); 289 int h = rowHeight( row );
286 if ( i && x >= ( w - BoxSize ) / 2 && x <= ( w - BoxSize ) / 2 + BoxSize && 290 if ( i && x >= ( w - BoxSize ) / 2 && x <= ( w - BoxSize ) / 2 + BoxSize &&
287 y >= ( h - BoxSize ) / 2 && y <= ( h - BoxSize ) / 2 + BoxSize ) { 291 y >= ( h - BoxSize ) / 2 && y <= ( h - BoxSize ) / 2 + BoxSize ) {
288 i->toggle(); 292 i->toggle();
289 } 293 }
290 emit signalDoneChanged( i->isChecked() ); 294 emit signalDoneChanged( i->isChecked() );
291 } 295 }
292 } 296 }
293 break; 297 break;
294 case 1: 298 case 1:
295 break; 299 break;
296 case 2: 300 case 2:
297 // may as well edit it... 301 // may as well edit it...
298 // menuTimer->stop(); 302 // menuTimer->stop();
299// emit signalEdit(); 303// emit signalEdit();
300 // fall through 304 // fall through
301 case 3: 305 case 3:
302 // may as well edit it... 306 // may as well edit it...
303 menuTimer->stop(); 307 menuTimer->stop();
304 // emit signalEdit(); 308 // emit signalEdit();
305 break; 309 break;
306 } 310 }
307} 311}
308 312
309void TodoTable::slotPressed( int row, int col, int, const QPoint &pos ) 313void TodoTable::slotPressed( int row, int col, int, const QPoint &pos )
310{ 314{
311 if ( col == 2 && cellGeometry( row, col ).contains(pos) ) 315 if ( col == 2 && cellGeometry( row, col ).contains(pos) )
312 menuTimer->start( 750, TRUE ); 316 menuTimer->start( 750, TRUE );
313} 317}
314 318
315void TodoTable::slotShowMenu() 319void TodoTable::slotShowMenu()
316{ 320{
317 emit signalShowMenu( QCursor::pos() ); 321 emit signalShowMenu( QCursor::pos() );
318} 322}
319 323
320void TodoTable::slotCurrentChanged( int, int ) 324void TodoTable::slotCurrentChanged( int, int )
321{ 325{
322 menuTimer->stop(); 326 menuTimer->stop();
323} 327}
324 328
325void TodoTable::internalAddEntries( QList<ToDoEvent> &list ) 329void TodoTable::internalAddEntries( QList<ToDoEvent> &list )
326{ 330{
327 setNumRows( list.count() ); 331 setNumRows( list.count() );
328 int row = 0; 332 int row = 0;
329 ToDoEvent *it; 333 ToDoEvent *it;
330 for ( it = list.first(); it; it = list.next() ) 334 for ( it = list.first(); it; it = list.next() )
331 insertIntoTable( it, row++ ); 335 insertIntoTable( it, row++ );
332} 336}
333 337
334 338
335ToDoEvent TodoTable::currentEntry() const 339ToDoEvent TodoTable::currentEntry() const
336{ 340{
337 printf ("in currentEntry\n"); 341 printf ("in currentEntry\n");
338 342
339 QTableItem *i = item( currentRow(), 0 ); 343 QTableItem *i = item( currentRow(), 0 );
340 if ( !i || rowHeight( currentRow() ) <= 0 ) 344 if ( !i || rowHeight( currentRow() ) <= 0 )
341 return ToDoEvent(); 345 return ToDoEvent();
342 ToDoEvent *todo = todoList[(CheckItem*)i]; 346 ToDoEvent *todo = todoList[(CheckItem*)i];
343 todo->setCompleted( ( (CheckItem*)item( currentRow(), 0 ) )->isChecked() ); 347 todo->setCompleted( ( (CheckItem*)item( currentRow(), 0 ) )->isChecked() );
344 todo->setPriority( ( (ComboItem*)item( currentRow(), 1 ) )->text().toInt() ); 348 todo->setPriority( ( (ComboItem*)item( currentRow(), 1 ) )->text().toInt() );
345 return *todo; 349 return *todo;
346} 350}
347 351
348void TodoTable::replaceCurrentEntry( const ToDoEvent &todo, bool fromTableItem ) 352void TodoTable::replaceCurrentEntry( const ToDoEvent &todo, bool fromTableItem )
349{ 353{
350 int row = currentRow(); 354 int row = currentRow();
351 updateJournal( todo, ACTION_REPLACE, row ); 355 updateJournal( todo, ACTION_REPLACE, row );
352 356
353 if ( !fromTableItem ) { 357 if ( !fromTableItem ) {
354 journalFreeReplaceEntry( todo, row ); 358 journalFreeReplaceEntry( todo, row );
355 updateVisible(); 359 updateVisible();
356 } 360 }
357} 361}
358 362
359void TodoTable::removeCurrentEntry() 363void TodoTable::removeCurrentEntry()
360{ 364{
361 ToDoEvent *oldTodo; 365 ToDoEvent *oldTodo;
362 int row = currentRow(); 366 int row = currentRow();
363 CheckItem *chk; 367 CheckItem *chk;
364 368
365 chk = static_cast<CheckItem*>(item(row, 0 )); 369 chk = static_cast<CheckItem*>(item(row, 0 ));
366 if ( !chk ) 370 if ( !chk )
367 return; 371 return;
368 oldTodo = todoList[chk]; 372 oldTodo = todoList[chk];
369 todoList.remove( chk ); 373 todoList.remove( chk );
370 oldTodo->setCompleted( chk->isChecked() ); 374 oldTodo->setCompleted( chk->isChecked() );
371 oldTodo->setPriority( static_cast<ComboItem*>(item(row, 1))->text().toInt() ); 375 oldTodo->setPriority( static_cast<ComboItem*>(item(row, 1))->text().toInt() );
372 realignTable( row ); 376 realignTable( row );
373 updateVisible(); 377 updateVisible();
374 updateJournal( *oldTodo, ACTION_REMOVE, row ); 378 updateJournal( *oldTodo, ACTION_REMOVE, row );
375 delete oldTodo; 379 delete oldTodo;
376} 380}
377 381
378 382
379bool TodoTable::save( const QString &fn ) 383bool TodoTable::save( const QString &fn )
380{ 384{
381 QString strNewFile = fn + ".new"; 385 QString strNewFile = fn + ".new";
382 QFile::remove( strNewFile ); // just to be sure 386 QFile::remove( strNewFile ); // just to be sure
383 ToDoDB todoDB( strNewFile ); 387 ToDoDB todoDB( strNewFile );
384 for ( QMap<CheckItem*, ToDoEvent *>::Iterator it = todoList.begin(); 388 for ( QMap<CheckItem*, ToDoEvent *>::Iterator it = todoList.begin();
385 it != todoList.end(); ++it ) { 389 it != todoList.end(); ++it ) {
386 if ( !item( it.key()->row(), 0 ) ) 390 if ( !item( it.key()->row(), 0 ) )
387 continue; 391 continue;
388 ToDoEvent *todo = *it; 392 ToDoEvent *todo = *it;
389 // sync item with table 393 // sync item with table
390 todo->setCompleted( ((CheckItem*)item(it.key()->row(), 0))->isChecked() ); 394 todo->setCompleted( ((CheckItem*)item(it.key()->row(), 0))->isChecked() );
391 todo->setPriority( ((ComboItem*)item( it.key()->row(), 1))->text().toInt() ); 395 todo->setPriority( ((ComboItem*)item( it.key()->row(), 1))->text().toInt() );
392 todoDB.addEvent( *todo ); 396 todoDB.addEvent( *todo );
393 } 397 }
394 if(!todoDB.save() ){ 398 if(!todoDB.save() ){
395 QFile::remove( strNewFile ); 399 QFile::remove( strNewFile );
396 return false; 400 return false;
397 }; 401 };
398 // now do the rename 402 // now do the rename
399 if ( ::rename( strNewFile, fn ) < 0 ) 403 if ( ::rename( strNewFile, fn ) < 0 )
400 qWarning( "problem renaming file %s to %s errno %d", 404 qWarning( "problem renaming file %s to %s errno %d",
401 strNewFile.latin1(), fn.latin1(), errno ); 405 strNewFile.latin1(), fn.latin1(), errno );
402 406
403 // remove the journal 407 // remove the journal
404 QFile::remove( journalFileName() ); 408 QFile::remove( journalFileName() );
405 return true; 409 return true;
406} 410}
407 411
408void TodoTable::load( const QString &fn ) 412void TodoTable::load( const QString &fn )
409{ 413{
410 loadFile( fn, false ); 414 loadFile( fn, false );
411 if ( QFile::exists(journalFileName()) ) { 415 if ( QFile::exists(journalFileName()) ) {
412 loadFile( journalFileName(), true ); 416 applyJournal( );
413 save( fn ); 417 save( fn );
414 } 418 }
415// QTable::sortColumn(2,TRUE,TRUE); 419// QTable::sortColumn(2,TRUE,TRUE);
416// QTable::sortColumn(1,TRUE,TRUE); 420// QTable::sortColumn(1,TRUE,TRUE);
417 QTable::sortColumn(0,TRUE,TRUE); 421 QTable::sortColumn(0,TRUE,TRUE);
418 setCurrentCell( 0, 2 ); 422 setCurrentCell( 0, 2 );
419 setSorting(true ); 423 setSorting(true );
420} 424}
421
422void TodoTable::updateVisible() 425void TodoTable::updateVisible()
423{ 426{
424 if ( !isUpdatesEnabled() ) 427 if ( !isUpdatesEnabled() )
425 return; 428 return;
426 429
427 if (showDeadl){ 430 if (showDeadl){
428 showColumn (3); 431 showColumn (3);
429 adjustColumn(3); 432 adjustColumn(3);
430 }else{ 433 }else{
431 hideColumn (3); 434 hideColumn (3);
432 adjustColumn(2); 435 adjustColumn(2);
433 } 436 }
434 437
435 int visible = 0; 438 int visible = 0;
436 int id = mCat.id( "Todo List", showCat ); 439 int id = mCat.id( "Todo List", showCat );
437 for ( int row = 0; row < numRows(); row++ ) { 440 for ( int row = 0; row < numRows(); row++ ) {
438 CheckItem *ci = (CheckItem *)item( row, 0 ); 441 CheckItem *ci = (CheckItem *)item( row, 0 );
439 ToDoEvent *t = todoList[ci]; 442 ToDoEvent *t = todoList[ci];
440 QArray<int> vlCats = t->categories(); 443 QArray<int> vlCats = t->categories();
441 bool hide = false; 444 bool hide = false;
442 if ( !showComp && ci->isChecked() ) 445 if ( !showComp && ci->isChecked() )
443 hide = true; 446 hide = true;
444 if ( !showCat.isEmpty() ) { 447 if ( !showCat.isEmpty() ) {
445 if ( showCat == tr( "Unfiled" ) ) { 448 if ( showCat == tr( "Unfiled" ) ) {
446 if ( vlCats.count() > 0 ) 449 if ( vlCats.count() > 0 )
447 hide = true; 450 hide = true;
448 } else { 451 } else {
449 // do some comparing, we have to reverse our idea here... which idea - zecke 452 // do some comparing, we have to reverse our idea here... which idea? - zecke
450 if ( !hide ) { 453 if ( !hide ) {
451 hide = true; 454 hide = true;
452 for ( uint it = 0; it < vlCats.count(); ++it ) { 455 for ( uint it = 0; it < vlCats.count(); ++it ) {
453 if ( vlCats[it] == id ) { 456 if ( vlCats[it] == id ) {
454 hide = false; 457 hide = false;
455 break; 458 break;
456 } 459 }
457 } 460 }
458 } 461 }
459 } 462 }
460 } 463 }
461 if ( hide ) { 464 if ( hide ) {
462 if ( currentRow() == row ) 465 if ( currentRow() == row )
463 setCurrentCell( -1, 0 ); 466 setCurrentCell( -1, 0 );
464 if ( rowHeight( row ) > 0 ) 467 if ( rowHeight( row ) > 0 )
465 hideRow( row ); 468 hideRow( row );
466 } else { 469 } else {
467 if ( rowHeight( row ) == 0 ) { 470 if ( rowHeight( row ) == 0 ) {
468 showRow( row ); 471 showRow( row );
469 adjustRow( row ); 472 adjustRow( row );
470 } 473 }
471 visible++; 474 visible++;
472 } 475 }
473 } 476 }
474 if ( !visible ) 477 if ( !visible )
475 setCurrentCell( -1, 0 ); 478 setCurrentCell( -1, 0 );
476} 479}
477 480
478void TodoTable::viewportPaintEvent( QPaintEvent *pe ) 481void TodoTable::viewportPaintEvent( QPaintEvent *pe )
479{ 482{
480 if ( enablePainting ) 483 if ( enablePainting )
481 QTable::viewportPaintEvent( pe ); 484 QTable::viewportPaintEvent( pe );
482} 485}
483 486
484void TodoTable::setPaintingEnabled( bool e ) 487void TodoTable::setPaintingEnabled( bool e )
485{ 488{
486 if ( e != enablePainting ) { 489 if ( e != enablePainting ) {
487 if ( !enablePainting ) { 490 if ( !enablePainting ) {
488 enablePainting = true; 491 enablePainting = true;
489 rowHeightChanged( 0 ); 492 rowHeightChanged( 0 );
490 viewport()->update(); 493 viewport()->update();
491 } else { 494 } else {
492 enablePainting = false; 495 enablePainting = false;
493 } 496 }
494 } 497 }
495} 498}
496 499
497void TodoTable::clear() 500void TodoTable::clear()
498{ 501{
499 for ( QMap<CheckItem*, ToDoEvent *>::Iterator it = todoList.begin(); 502 for ( QMap<CheckItem*, ToDoEvent *>::Iterator it = todoList.begin();
500 it != todoList.end(); ++it ) { 503 it != todoList.end(); ++it ) {
501 ToDoEvent *todo = *it; 504 ToDoEvent *todo = *it;
505 updateJournal( todo, ACTION_REMOVE, 0 );
502 delete todo; 506 delete todo;
503 } 507 }
504 todoList.clear(); 508 todoList.clear();
505 for ( int r = 0; r < numRows(); ++r ) { 509 for ( int r = 0; r < numRows(); ++r ) {
506 for ( int c = 0; c < numCols(); ++c ) { 510 for ( int c = 0; c < numCols(); ++c ) {
507 if ( cellWidget( r, c ) ) 511 if ( cellWidget( r, c ) )
508 clearCellWidget( r, c ); 512 clearCellWidget( r, c );
509 clearCell( r, c ); 513 clearCell( r, c );
510 } 514 }
511 } 515 }
512 setNumRows( 0 ); 516 setNumRows( 0 );
513} 517}
514 518
515void TodoTable::sortColumn( int col, bool ascending, bool /*wholeRows*/ ) 519void TodoTable::sortColumn( int col, bool ascending, bool /*wholeRows*/ )
516{ 520{
517 // The default for wholeRows is false, however 521 // The default for wholeRows is false, however
518 // for this todo table we want to exchange complete 522 // for this todo table we want to exchange complete
519 // rows when sorting. Also, we always want ascending, since 523 // rows when sorting. Also, we always want ascending, since
520 // the values have a logical order. 524 // the values have a logical order.
521 QTable::sortColumn( col, ascending, TRUE ); 525 QTable::sortColumn( col, ascending, TRUE );
522 updateVisible(); 526 updateVisible();
523} 527}
524 528
525void TodoTable::slotCheckPriority(int row, int col ) 529void TodoTable::slotCheckPriority(int row, int col )
526{ 530{
527 // kludgey work around to make forward along the updated priority... 531 // kludgey work around to make forward along the updated priority...
528 if ( col == 1 ) { 532 if ( col == 1 ) {
529 // let everyone know!! 533 // let everyone know!!
530 ComboItem* i = static_cast<ComboItem*>( item( row, col ) ); 534 ComboItem* i = static_cast<ComboItem*>( item( row, col ) );
531 emit signalPriorityChanged( i->text().toInt() ); 535 emit signalPriorityChanged( i->text().toInt() );
532 } 536 }
533} 537}
534 538
535 539
536void TodoTable::updateJournal( const ToDoEvent &/*todo*/, journal_action action, int row ) 540void TodoTable::updateJournal( const ToDoEvent &todo, journal_action action, int row )
537{ 541{
538 QFile f( journalFileName() ); 542 QFile f( journalFileName() );
539 if ( !f.open(IO_WriteOnly|IO_Append) ) 543 if ( !f.open(IO_WriteOnly|IO_Append) )
540 return; 544 return;
541 QString buf; 545 QString buf;
542 QCString str; 546 QCString str;
543 buf = "<Task"; 547 buf = "<Task";
544 // todo.save( buf ); 548 // todo.save( buf );
545 buf += " Action=\"" + QString::number( int(action) ) + "\""; 549 buf += " Action=\"" + QString::number( int(action) ) + "\"";
546 buf += " Row=\"" + QString::number( row ) + "\""; // better write the id 550 buf += " Uid=\"" + QString::number( todo.uid() ) + "\""; // better write the id
551 buf += " Completed=\""+ QString::number((int)todo.isCompleted() ) + "\"";
552 buf += " HasDate=\""+ QString::number((int)todo.hasDate() ) +"\"";
553 buf += " Priority=\"" + QString::number( todo.priority() ) + "\"";
554 QArray<int> arrat = todo.categories();
555 QString attr;
556 for(uint i=0; i < arrat.count(); i++ ){
557 attr.append(QString::number(arrat[i])+";" );
558 }
559 if(!attr.isEmpty() ) // remove the last ;
560 attr.remove(attr.length()-1, 1 );
561 buf += " Categories=\"" + attr + "\"";
562 buf += " Description=\"" + todo.description() + "\"";
563 if(todo.hasDate() ) {
564 buf += " DateYear=\""+QString::number( todo.date().year() ) + "\"";
565 buf += " DateMonth=\"" + QString::number( todo.date().month() ) + "\"";
566 buf += " DateDay=\"" + QString::number( todo.date().day() ) + "\"";
567 }
547 buf += "/>\n"; 568 buf += "/>\n";
548 str = buf.utf8(); 569 str = buf.utf8();
549 f.writeBlock( str.data(), str.length() ); 570 f.writeBlock( str.data(), str.length() );
550 f.close(); 571 f.close();
551} 572}
552 573
553void TodoTable::rowHeightChanged( int row ) 574void TodoTable::rowHeightChanged( int row )
554{ 575{
555 if ( enablePainting ) 576 if ( enablePainting )
556 QTable::rowHeightChanged( row ); 577 QTable::rowHeightChanged( row );
557} 578}
558 579
559void TodoTable::loadFile( const QString &strFile, bool fromJournal ) 580void TodoTable::loadFile( const QString &strFile, bool fromJournal )
560{ 581{
561 582
562 QList<ToDoEvent> list; 583 QList<ToDoEvent> list;
563 ToDoDB todoDB; 584 ToDoDB todoDB;
564 QValueList<ToDoEvent> vaList = todoDB.rawToDos(); 585 QValueList<ToDoEvent> vaList = todoDB.rawToDos();
565 for(QValueList<ToDoEvent>::ConstIterator it = vaList.begin(); it != vaList.end(); ++it ){ 586 for(QValueList<ToDoEvent>::ConstIterator it = vaList.begin(); it != vaList.end(); ++it ){
566 list.append( new ToDoEvent( (*it) ) ); 587 list.append( new ToDoEvent( (*it) ) );
567 } 588 }
568 vaList.clear(); 589 vaList.clear();
569 // qDebug("parsing done=%d", t.elapsed() ); 590 // qDebug("parsing done=%d", t.elapsed() );
570 if ( list.count() > 0 ) { 591 if ( list.count() > 0 ) {
571 internalAddEntries( list ); 592 internalAddEntries( list );
572 list.clear(); 593 list.clear();
573 } 594 }
574// qDebug("loading done: t=%d", t.elapsed() ); 595// qDebug("loading done: t=%d", t.elapsed() );
575} 596}
576 597
577void TodoTable::journalFreeReplaceEntry( const ToDoEvent &todo, int row ) 598void TodoTable::journalFreeReplaceEntry( const ToDoEvent &todo, int row )
578{ 599{
579 QString strTodo; 600 QString strTodo;
580 strTodo = todo.description().left(40).simplifyWhiteSpace(); 601 strTodo = todo.description().left(40).simplifyWhiteSpace();
581 if ( row == -1 ) { 602 if ( row == -1 ) {
582 QMapIterator<CheckItem*, ToDoEvent *> it; 603 QMapIterator<CheckItem*, ToDoEvent *> it;
583 for ( it = todoList.begin(); it != todoList.end(); ++it ) { 604 for ( it = todoList.begin(); it != todoList.end(); ++it ) {
584 if ( *(*it) == todo ) { 605 if ( *(*it) == todo ) {
585 row = it.key()->row(); 606 row = it.key()->row();
586 it.key()->setChecked( todo.isCompleted() ); 607 it.key()->setChecked( todo.isCompleted() );
587 static_cast<ComboItem*>(item(row, 1))->setText( QString::number(todo.priority()) ); 608 static_cast<ComboItem*>(item(row, 1))->setText( QString::number(todo.priority()) );
588 item( row, 2 )->setText( strTodo ); 609 item( row, 2 )->setText( strTodo );
589 610
590 if (showDeadl){ 611 if (showDeadl){
591 static_cast<DueTextItem*>(item(row,3))->setToDoEvent(&todo ); 612 static_cast<DueTextItem*>(item(row,3))->setToDoEvent(&todo );
592 } 613 }
593 614
594 *(*it) = todo; 615 *(*it) = todo;
595 } 616 }
596 } 617 }
597 } else { 618 } else {
598 ToDoEvent *t = todoList[static_cast<CheckItem*>(item(row, 0))]; 619 ToDoEvent *t = todoList[static_cast<CheckItem*>(item(row, 0))];
599 todoList.remove( static_cast<CheckItem*>(item(row, 0)) ); 620 todoList.remove( static_cast<CheckItem*>(item(row, 0)) );
600 delete t; 621 delete t;
601 static_cast<CheckItem*>(item(row, 0))->setChecked( todo.isCompleted() ); 622 static_cast<CheckItem*>(item(row, 0))->setChecked( todo.isCompleted() );
602 static_cast<ComboItem*>(item(row, 1))->setText( QString::number(todo.priority()) ); 623 static_cast<ComboItem*>(item(row, 1))->setText( QString::number(todo.priority()) );
603 item( row, 2 )->setText( strTodo ); 624 item( row, 2 )->setText( strTodo );
604 625
605 if (showDeadl){ 626 if (showDeadl){
606 static_cast<DueTextItem*>(item(row,3))->setToDoEvent(&todo ); 627 static_cast<DueTextItem*>(item(row,3))->setToDoEvent(&todo );
607 } 628 }
608 629
609 todoList.insert( static_cast<CheckItem*>(item(row,0)), new ToDoEvent(todo) ); 630 todoList.insert( static_cast<CheckItem*>(item(row,0)), new ToDoEvent(todo) );
610 } 631 }
611} 632}
612 633
613void TodoTable::journalFreeRemoveEntry( int row ) 634void TodoTable::journalFreeRemoveEntry( int row )
614{ 635{
615 CheckItem *chk; 636 CheckItem *chk;
616 chk = static_cast<CheckItem*>(item(row, 0 )); 637 chk = static_cast<CheckItem*>(item(row, 0 ));
617 if ( !chk ) 638 if ( !chk )
618 return; 639 return;
619 todoList.remove( chk ); 640 todoList.remove( chk );
620 641
621 realignTable( row ); 642 realignTable( row );
622} 643}
623 644
624void TodoTable::keyPressEvent( QKeyEvent *e ) 645void TodoTable::keyPressEvent( QKeyEvent *e )
625{ 646{
626 if ( e->key() == Key_Space || e->key() == Key_Return ) { 647 if ( e->key() == Key_Space || e->key() == Key_Return ) {
627 switch ( currentColumn() ) { 648 switch ( currentColumn() ) {
628 case 0: { 649 case 0: {
629 CheckItem *i = static_cast<CheckItem*>(item(currentRow(), 650 CheckItem *i = static_cast<CheckItem*>(item(currentRow(),
630 currentColumn())); 651 currentColumn()));
631 if ( i ) 652 if ( i )
632 i->toggle(); 653 i->toggle();
633 break; 654 break;
634 } 655 }
635 case 1: 656 case 1:
636 break; 657 break;
637 case 2: 658 case 2:
638 emit signalEdit(); 659 emit signalEdit();
639 default: 660 default:
640 break; 661 break;
641 } 662 }
642 } else { 663 } else {
643 QTable::keyPressEvent( e ); 664 QTable::keyPressEvent( e );
644 } 665 }
645} 666}
646 667
647QStringList TodoTable::categories() 668QStringList TodoTable::categories()
648{ 669{
649 // This is called seldom, so calling a load in here 670 // This is called seldom, so calling a load in here
650 // should be fine. 671 // should be fine.
651 mCat.load( categoryFileName() ); 672 mCat.load( categoryFileName() );
652 QStringList categoryList = mCat.labels( "Todo List" ); 673 QStringList categoryList = mCat.labels( "Todo List" );
653 return categoryList; 674 return categoryList;
654} 675}
655 676
656void TodoTable::slotDoFind( const QString &findString, bool caseSensitive, 677void TodoTable::slotDoFind( const QString &findString, bool caseSensitive,
657 bool backwards, int category ) 678 bool backwards, int category )
658{ 679{
659 // we have to iterate through the table, this gives the illusion that 680 // we have to iterate through the table, this gives the illusion that
660 // sorting is actually being used. 681 // sorting is actually being used.
661 if ( currFindRow < -1 ) 682 if ( currFindRow < -1 )
662 currFindRow = currentRow() - 1; 683 currFindRow = currentRow() - 1;
663 clearSelection( TRUE ); 684 clearSelection( TRUE );
664 int rows, 685 int rows,
665 row; 686 row;
666 CheckItem *chk; 687 CheckItem *chk;
667 QRegExp r( findString ); 688 QRegExp r( findString );
668 689
669 r.setCaseSensitive( caseSensitive ); 690 r.setCaseSensitive( caseSensitive );
670 rows = numRows(); 691 rows = numRows();
671 static bool wrapAround = true; 692 static bool wrapAround = true;
672 693
673 if ( !backwards ) { 694 if ( !backwards ) {
674 for ( row = currFindRow + 1; row < rows; row++ ) { 695 for ( row = currFindRow + 1; row < rows; row++ ) {
675 chk = static_cast<CheckItem*>( item(row, 0) ); 696 chk = static_cast<CheckItem*>( item(row, 0) );
676 if ( taskCompare(*(todoList[chk]), r, category) ) 697 if ( taskCompare(*(todoList[chk]), r, category) )
677 break; 698 break;
678 } 699 }
679 } else { 700 } else {
680 for ( row = currFindRow - 1; row > -1; row-- ) { 701 for ( row = currFindRow - 1; row > -1; row-- ) {
681 chk = static_cast<CheckItem*>( item(row, 0) ); 702 chk = static_cast<CheckItem*>( item(row, 0) );
682 if ( taskCompare(*(todoList[chk]), r, category) ) 703 if ( taskCompare(*(todoList[chk]), r, category) )
683 break; 704 break;
684 } 705 }
685 } 706 }
686 if ( row >= rows || row < 0 ) { 707 if ( row >= rows || row < 0 ) {
687 if ( row < 0 ) 708 if ( row < 0 )
688 currFindRow = rows; 709 currFindRow = rows;
689 else 710 else
690 currFindRow = -1; 711 currFindRow = -1;
691 if ( wrapAround ) 712 if ( wrapAround )
692 emit signalWrapAround(); 713 emit signalWrapAround();
693 else 714 else
694 emit signalNotFound(); 715 emit signalNotFound();
695 wrapAround = !wrapAround; 716 wrapAround = !wrapAround;
696 } else { 717 } else {
697 currFindRow = row; 718 currFindRow = row;
698 QTableSelection foundSelection; 719 QTableSelection foundSelection;
699 foundSelection.init( currFindRow, 0 ); 720 foundSelection.init( currFindRow, 0 );
700 foundSelection.expandTo( currFindRow, numCols() - 1 ); 721 foundSelection.expandTo( currFindRow, numCols() - 1 );
701 addSelection( foundSelection ); 722 addSelection( foundSelection );
702 setCurrentCell( currFindRow, numCols() - 1 ); 723 setCurrentCell( currFindRow, numCols() - 1 );
703 // we should always be able to wrap around and find this again, 724 // we should always be able to wrap around and find this again,
704 // so don't give confusing not found message... 725 // so don't give confusing not found message...
705 wrapAround = true; 726 wrapAround = true;
706 } 727 }
707} 728}
708 729
709int TodoTable::showCategoryId() const 730int TodoTable::showCategoryId() const
710{ 731{
711 int id; 732 int id;
712 id = -1; 733 id = -1;
713 // if allcategories are selected, you get unfiled... 734 // if allcategories are selected, you get unfiled...
714 if ( showCat != tr( "Unfiled" ) && showCat != tr( "All" ) ) 735 if ( showCat != tr( "Unfiled" ) && showCat != tr( "All" ) )
715 id = mCat.id( "Todo List", showCat ); 736 id = mCat.id( "Todo List", showCat );
716 return id; 737 return id;
717} 738}
718 739void TodoTable::applyJournal()
740{
741 // we need to hack
742 QFile file( journalFileName() );
743 if( file.open(IO_ReadOnly ) ) {
744 QByteArray ar = file.readAll();
745 file.close();
746 QFile file2( journalFileName() + "_new" );
747 if( file2.open(IO_WriteOnly ) ){
748 QTextStream str(&file2 );
749 str << QString::fromLatin1("<Tasks>") << endl;
750 str << ar.data();
751 str << QString::fromLatin1("</Tasks>") << endl;
752 file2.close();
753 }
754 XMLElement *root = XMLElement::load(journalFileName()+ "_new");
755 XMLElement *el = root->firstChild();
756 el = el->firstChild();
757 while( el ){
758 qWarning("journal: %s %s", el->attribute("Uid" ).latin1(), el->tagName().latin1() );
759 doApply( el );
760 el = el->nextChild();
761 }
762 QFile::remove(journalFileName()+ "_new" );
763 }
764}
765// check Action and decide
766void TodoTable::doApply(XMLElement *el )
767{
768 QString dummy;
769 bool ok;
770 int action;
771 dummy = el->attribute("Action" );
772 action = dummy.toInt(&ok );
773 ToDoEvent ev = xmlToEvent( el );
774 if( ok ){
775 switch( action ){
776 case ACTION_ADD:
777 addEntry( ev );
778 break;
779 case ACTION_REMOVE:{ // find an entry with the same uid and remove it then
780 break;
781 }
782 case ACTION_REPLACE:
783 break;
784 }
785 }
786}
787namespace {
719static bool taskCompare( const ToDoEvent &task, const QRegExp &r, int category ) 788static bool taskCompare( const ToDoEvent &task, const QRegExp &r, int category )
720{ 789{
721 bool returnMe; 790 bool returnMe;
722 QArray<int> cats; 791 QArray<int> cats;
723 cats = task.categories(); 792 cats = task.categories();
724 793
725 returnMe = false; 794 returnMe = false;
726 if ( (category == -1 && cats.count() == 0) || category == -2 ) 795 if ( (category == -1 && cats.count() == 0) || category == -2 )
727 returnMe = task.match( r ); 796 returnMe = task.match( r );
728 else { 797 else {
729 int i; 798 int i;
730 for ( i = 0; i < int(cats.count()); i++ ) { 799 for ( i = 0; i < int(cats.count()); i++ ) {
731 if ( cats[i] == category ) { 800 if ( cats[i] == category ) {
732 returnMe = task.match( r ); 801 returnMe = task.match( r );
733 break; 802 break;
734 } 803 }
735 } 804 }
736 } 805 }
737 return returnMe; 806 return returnMe;
738} 807}
739 808
740static QString journalFileName() 809static QString journalFileName()
741{ 810{
742 QString str; 811 QString str;
743 str = getenv( "HOME" ); 812 str = getenv( "HOME" );
744 str += "/.todojournal"; 813 str += "/.opie_todojournal";
745 return str; 814 return str;
746} 815}
816static ToDoEvent xmlToEvent( XMLElement *element )
817{
818 QString dummy;
819 ToDoEvent event;
820 bool ok;
821 int dumInt;
822 // completed
823 dummy = element->attribute("Completed" );
824 dumInt = dummy.toInt(&ok );
825 if(ok ) event.setCompleted( dumInt == 0 ? false : true );
826 // hasDate
827 dummy = element->attribute("HasDate" );
828 dumInt = dummy.toInt(&ok );
829 if(ok ) event.setHasDate( dumInt == 0 ? false: true );
830 // set the date
831 bool hasDa = dumInt;
832 if ( hasDa ) { //parse the date
833 int year, day, month = 0;
834 year = day = month;
835 // year
836 dummy = element->attribute("DateYear" );
837 dumInt = dummy.toInt(&ok );
838 if( ok ) year = dumInt;
839 // month
840 dummy = element->attribute("DateMonth" );
841 dumInt = dummy.toInt(&ok );
842 if(ok ) month = dumInt;
843 dummy = element->attribute("DateDay" );
844 dumInt = dummy.toInt(&ok );
845 if(ok ) day = dumInt;
846 // set the date
847 QDate date( year, month, day );
848 event.setDate( date);
849 }
850 dummy = element->attribute("Priority" );
851 dumInt = dummy.toInt(&ok );
852 if(!ok ) dumInt = ToDoEvent::NORMAL;
853 event.setPriority( dumInt );
854 //description
855 dummy = element->attribute("Description" );
856 event.setDescription( dummy );
857 // category
858 dummy = element->attribute("Categories" );
859 QStringList ids = QStringList::split(";", dummy );
860 event.setCategories( ids );
861
862 //uid
863 dummy = element->attribute("Uid" );
864 dumInt = dummy.toInt(&ok );
865 if(ok ) event.setUid( dumInt );
866
867 return event;
868}
747 869
870}
748// int TodoTable::rowHeight( int ) const 871// int TodoTable::rowHeight( int ) const
749// { 872// {
750// return 18; 873// return 18;
751// } 874// }
752 875
753// int TodoTable::rowPos( int row ) const 876// int TodoTable::rowPos( int row ) const
754// { 877// {
755// return 18*row; 878// return 18*row;
756// } 879// }
757 880
758// int TodoTable::rowAt( int pos ) const 881// int TodoTable::rowAt( int pos ) const
759// { 882// {
760// return QMIN( pos/18, numRows()-1 ); 883// return QMIN( pos/18, numRows()-1 );
761// } 884// }
885
diff --git a/core/pim/todo/todotable.h b/core/pim/todo/todotable.h
index 32df514..6917e04 100644
--- a/core/pim/todo/todotable.h
+++ b/core/pim/todo/todotable.h
@@ -1,233 +1,238 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved. 2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of Qtopia Environment. 4** This file is part of Qtopia Environment.
5** 5**
6** This file may be distributed and/or modified under the terms of the 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 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 8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file. 9** packaging of this file.
10** 10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 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. 12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13** 13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information. 14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15** 15**
16** Contact info@trolltech.com if any conditions of this licensing are 16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you. 17** not clear to you.
18** 18**
19**********************************************************************/ 19**********************************************************************/
20 20
21#ifndef TODOTABLE_H 21#ifndef TODOTABLE_H
22#define TODOTABLE_H 22#define TODOTABLE_H
23 23
24#include <qpe/categories.h> 24#include <qpe/categories.h>
25#include <qpe/stringutil.h> 25#include <qpe/stringutil.h>
26//#include <qpe/task.h> 26//#include <qpe/task.h>
27#include <opie/todoevent.h> 27#include <opie/todoevent.h>
28 28
29#include <qtable.h> 29#include <qtable.h>
30#include <qmap.h> 30#include <qmap.h>
31#include <qguardedptr.h> 31#include <qguardedptr.h>
32 32
33class Node; 33class Node;
34class QComboBox; 34class QComboBox;
35class QTimer; 35class QTimer;
36 36
37class CheckItem : public QTableItem 37class CheckItem : public QTableItem
38{ 38{
39public: 39public:
40 CheckItem( QTable *t, const QString &sortkey ); 40 CheckItem( QTable *t, const QString &sortkey );
41 41
42 void setChecked( bool b ); 42 void setChecked( bool b );
43 void toggle(); 43 void toggle();
44 bool isChecked() const; 44 bool isChecked() const;
45 void setKey( const QString &key ) { sortKey = key; } 45 void setKey( const QString &key ) { sortKey = key; }
46 QString key() const; 46 QString key() const;
47 47
48 void paint( QPainter *p, const QColorGroup &cg, const QRect &cr, bool selected ); 48 void paint( QPainter *p, const QColorGroup &cg, const QRect &cr, bool selected );
49 49
50private: 50private:
51 bool checked; 51 bool checked;
52 QString sortKey; 52 QString sortKey;
53}; 53};
54 54
55class ComboItem : public QTableItem 55class ComboItem : public QTableItem
56{ 56{
57public: 57public:
58 ComboItem( QTable *t, EditType et ); 58 ComboItem( QTable *t, EditType et );
59 QWidget *createEditor() const; 59 QWidget *createEditor() const;
60 void setContentFromEditor( QWidget *w ); 60 void setContentFromEditor( QWidget *w );
61 void setText( const QString &s ); 61 void setText( const QString &s );
62 int alignment() const { return Qt::AlignCenter; } 62 int alignment() const { return Qt::AlignCenter; }
63 63
64 QString text() const; 64 QString text() const;
65 65
66private: 66private:
67 QGuardedPtr<QComboBox> cb; 67 QGuardedPtr<QComboBox> cb;
68 68
69}; 69};
70 70
71class TodoTextItem : public QTableItem 71class TodoTextItem : public QTableItem
72{ 72{
73public: 73public:
74 TodoTextItem( QTable *t, const QString & str ) 74 TodoTextItem( QTable *t, const QString & str )
75 :QTableItem( t, QTableItem::Never, str ) {} 75 :QTableItem( t, QTableItem::Never, str ) {}
76 76
77 QString key () const { return Qtopia::buildSortKey( text() ); } 77 QString key () const { return Qtopia::buildSortKey( text() ); }
78}; 78};
79 79
80class DueTextItem : public QTableItem 80class DueTextItem : public QTableItem
81{ 81{
82 public: 82 public:
83 DueTextItem( QTable *t, ToDoEvent *ev ); 83 DueTextItem( QTable *t, ToDoEvent *ev );
84 QString key() const; 84 QString key() const;
85 void setToDoEvent( const ToDoEvent *ev ); 85 void setToDoEvent( const ToDoEvent *ev );
86 void paint( QPainter *p, const QColorGroup &cg, const QRect &cr, bool selected ); 86 void paint( QPainter *p, const QColorGroup &cg, const QRect &cr, bool selected );
87 private: 87 private:
88 int m_off; 88 int m_off;
89 bool m_hasDate:1; 89 bool m_hasDate:1;
90 bool m_completed:1; 90 bool m_completed:1;
91 91
92}; 92};
93 93
94 94
95enum journal_action { ACTION_ADD, ACTION_REMOVE, ACTION_REPLACE }; 95enum journal_action { ACTION_ADD=0, ACTION_REMOVE, ACTION_REPLACE };
96 96
97class XMLElement;
97class TodoTable : public QTable 98class TodoTable : public QTable
98{ 99{
99 Q_OBJECT 100 Q_OBJECT
100 101
101public: 102public:
102 TodoTable( QWidget *parent = 0, const char * name = 0 ); 103 TodoTable( QWidget *parent = 0, const char * name = 0 );
103 void addEntry( const ToDoEvent &todo ); 104 void addEntry( const ToDoEvent &todo );
104 void clearFindRow() { currFindRow = -2; } 105 void clearFindRow() { currFindRow = -2; }
105 106
106 ToDoEvent currentEntry() const; 107 ToDoEvent currentEntry() const;
107 void replaceCurrentEntry( const ToDoEvent &todo, bool fromTableItem = false ); 108 void replaceCurrentEntry( const ToDoEvent &todo, bool fromTableItem = false );
108 109
109 QStringList categories(); 110 QStringList categories();
110 111
111 void setShowCompleted( bool sc ) { showComp = sc; updateVisible(); } 112 void setShowCompleted( bool sc ) { showComp = sc; updateVisible(); }
112 bool showCompleted() const { return showComp; } 113 bool showCompleted() const { return showComp; }
113 114
114 void setShowDeadline (bool sd) {showDeadl = sd; updateVisible();} 115 void setShowDeadline (bool sd) {showDeadl = sd; updateVisible();}
115 bool showDeadline() const { return showDeadl;} 116 bool showDeadline() const { return showDeadl;}
116 117
117 void setShowCategory( const QString &c ) { showCat = c; updateVisible(); } 118 void setShowCategory( const QString &c ) { showCat = c; updateVisible(); }
118 const QString &showCategory() const { return showCat; } 119 const QString &showCategory() const { return showCat; }
119 int showCategoryId() const; 120 int showCategoryId() const;
120 121
121 bool save( const QString &fn ); 122 bool save( const QString &fn );
122 void load( const QString &fn ); 123 void load( const QString &fn );
124 void applyJournal( );
123 void clear(); 125 void clear();
124 void removeCurrentEntry(); 126 void removeCurrentEntry();
127 void removeAllEntries() { clear(); };
128 //void removeAllEntriesInCategory(const QString &category );
125 129
126 void setPaintingEnabled( bool e ); 130 void setPaintingEnabled( bool e );
127 131
128 virtual void sortColumn( int col, bool ascending, bool /*wholeRows*/ ); 132 virtual void sortColumn( int col, bool ascending, bool /*wholeRows*/ );
129 133
130// int rowHeight( int ) const; 134// int rowHeight( int ) const;
131// int rowPos( int row ) const; 135// int rowPos( int row ) const;
132// virtual int rowAt( int pos ) const; 136// virtual int rowAt( int pos ) const;
133 137
134signals: 138signals:
135 void signalEdit(); 139 void signalEdit();
136 void signalDoneChanged( bool b ); 140 void signalDoneChanged( bool b );
137 void signalPriorityChanged( int i ); 141 void signalPriorityChanged( int i );
138 void signalShowMenu( const QPoint & ); 142 void signalShowMenu( const QPoint & );
139 void signalNotFound(); 143 void signalNotFound();
140 void signalWrapAround(); 144 void signalWrapAround();
141 145
142protected: 146protected:
143 void keyPressEvent( QKeyEvent *e ); 147 void keyPressEvent( QKeyEvent *e );
144 148
145private: 149private:
146 void updateVisible(); 150 void updateVisible();
147 void viewportPaintEvent( QPaintEvent * ); 151 void viewportPaintEvent( QPaintEvent * );
148 void internalAddEntries( QList<ToDoEvent> &list); 152 void internalAddEntries( QList<ToDoEvent> &list);
149 inline void insertIntoTable( ToDoEvent *todo, int row ); 153 inline void insertIntoTable( ToDoEvent *todo, int row );
150 void updateJournal( const ToDoEvent &todo, journal_action action, int row = -1); 154 void updateJournal( const ToDoEvent &todo, journal_action action, int row = -1);
151 void mergeJournal(); 155 void mergeJournal();
152 void journalFreeReplaceEntry( const ToDoEvent &todo, int row ); 156 void journalFreeReplaceEntry( const ToDoEvent &todo, int row );
153 void journalFreeRemoveEntry( int row ); 157 void journalFreeRemoveEntry( int row );
154 inline void realignTable( int row ); 158 inline void realignTable( int row );
155 void loadFile( const QString &strFile, bool fromJournal = false ); 159 void loadFile( const QString &strFile, bool fromJournal = false );
160 void doApply(XMLElement *el );
156 161
157private slots: 162private slots:
158 void slotClicked( int row, int col, int button, const QPoint &pos ); 163 void slotClicked( int row, int col, int button, const QPoint &pos );
159 void slotPressed( int row, int col, int button, const QPoint &pos ); 164 void slotPressed( int row, int col, int button, const QPoint &pos );
160 void slotCheckPriority(int row, int col ); 165 void slotCheckPriority(int row, int col );
161 void slotCurrentChanged(int row, int col ); 166 void slotCurrentChanged(int row, int col );
162 void slotDoFind( const QString &findString, bool caseSensetive, 167 void slotDoFind( const QString &findString, bool caseSensetive,
163 bool backwards, int category ); 168 bool backwards, int category );
164 void slotShowMenu(); 169 void slotShowMenu();
165 void rowHeightChanged( int row ); 170 void rowHeightChanged( int row );
166 171
167private: 172private:
168 friend class TodoWindow; 173 friend class TodoWindow;
169 174
170 QMap<CheckItem*, ToDoEvent *> todoList; 175 QMap<CheckItem*, ToDoEvent *> todoList;
171 QStringList categoryList; 176 QStringList categoryList;
172 bool showComp; 177 bool showComp;
173 QString showCat; 178 QString showCat;
174 QTimer *menuTimer; 179 QTimer *menuTimer;
175 bool enablePainting; 180 bool enablePainting;
176 Categories mCat; 181 Categories mCat;
177 int currFindRow; 182 int currFindRow;
178 bool showDeadl:1; 183 bool showDeadl:1;
179}; 184};
180 185
181 186
182inline void TodoTable::insertIntoTable( ToDoEvent *todo, int row ) 187inline void TodoTable::insertIntoTable( ToDoEvent *todo, int row )
183{ 188{
184 QString sortKey = (char) ((todo->isCompleted() ? 'a' : 'A') 189 QString sortKey = (char) ((todo->isCompleted() ? 'a' : 'A')
185 + todo->priority() ) 190 + todo->priority() )
186 + Qtopia::buildSortKey( todo->description() ); 191 + Qtopia::buildSortKey( todo->description() );
187 CheckItem *chk = new CheckItem( this, sortKey ); 192 CheckItem *chk = new CheckItem( this, sortKey );
188 chk->setChecked( todo->isCompleted() ); 193 chk->setChecked( todo->isCompleted() );
189 ComboItem *cmb = new ComboItem( this, QTableItem::WhenCurrent ); 194 ComboItem *cmb = new ComboItem( this, QTableItem::WhenCurrent );
190 cmb->setText( QString::number( todo->priority() ) ); 195 cmb->setText( QString::number( todo->priority() ) );
191 QTableItem *ti = new TodoTextItem( this, todo->description().left(40).simplifyWhiteSpace() ); 196 QTableItem *ti = new TodoTextItem( this, todo->description().left(40).simplifyWhiteSpace() );
192 ti->setReplaceable( false ); 197 ti->setReplaceable( false );
193 198
194 DueTextItem *due = new DueTextItem(this, todo ); 199 DueTextItem *due = new DueTextItem(this, todo );
195 setItem( row, 3, due); 200 setItem( row, 3, due);
196 201
197 setItem( row, 0, chk ); 202 setItem( row, 0, chk );
198 setItem( row, 1, cmb ); 203 setItem( row, 1, cmb );
199 setItem( row, 2, ti ); 204 setItem( row, 2, ti );
200 205
201 206
202 todoList.insert( chk, todo ); 207 todoList.insert( chk, todo );
203} 208}
204 209
205inline void TodoTable::realignTable( int row ) 210inline void TodoTable::realignTable( int row )
206{ 211{
207 QTableItem *ti1, 212 QTableItem *ti1,
208 *ti2, 213 *ti2,
209 *ti3, 214 *ti3,
210 *ti4; 215 *ti4;
211 int totalRows = numRows(); 216 int totalRows = numRows();
212 for ( int curr = row; curr < totalRows - 1; curr++ ) { 217 for ( int curr = row; curr < totalRows - 1; curr++ ) {
213 // this is bad, we must take the item out and then 218 // this is bad, we must take the item out and then
214 // set it. In the end, it behaves no worse (time wise) 219 // set it. In the end, it behaves no worse (time wise)
215 // then the old way of saving the entries to file, clearing 220 // then the old way of saving the entries to file, clearing
216 // the table re-reading in the file and resetting the table 221 // the table re-reading in the file and resetting the table
217 ti1 = item( curr + 1, 0 ); 222 ti1 = item( curr + 1, 0 );
218 ti2 = item( curr + 1, 1 ); 223 ti2 = item( curr + 1, 1 );
219 ti3 = item( curr + 1, 2 ); 224 ti3 = item( curr + 1, 2 );
220 ti4 = item( curr + 1, 3 ); 225 ti4 = item( curr + 1, 3 );
221 takeItem( ti1 ); 226 takeItem( ti1 );
222 takeItem( ti2 ); 227 takeItem( ti2 );
223 takeItem( ti3 ); 228 takeItem( ti3 );
224 takeItem( ti4 ); 229 takeItem( ti4 );
225 setItem( curr, 0, ti1 ); 230 setItem( curr, 0, ti1 );
226 setItem( curr, 1, ti2 ); 231 setItem( curr, 1, ti2 );
227 setItem( curr, 2, ti3 ); 232 setItem( curr, 2, ti3 );
228 setItem( curr, 3, ti4 ); 233 setItem( curr, 3, ti4 );
229 } 234 }
230 setNumRows( totalRows - 1 ); 235 setNumRows( totalRows - 1 );
231} 236}
232 237
233#endif 238#endif