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