00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
static const char *todowidget_id =
00031
"$Id: todoWidget.cc,v 1.8 2003/10/13 13:58:19 kainhofe Exp $";
00032
00033
00034
#include "options.h"
00035
00036
#include <qptrlist.h>
00037
#include <klistview.h>
00038
#include <qpushbutton.h>
00039
#include <qlayout.h>
00040
#include <qlabel.h>
00041
#include <qtextview.h>
00042
#include <qcombobox.h>
00043
#include <qwhatsthis.h>
00044
#include <qtextcodec.h>
00045
00046
#include <kmessagebox.h>
00047
00048
#include "kpilotConfig.h"
00049
#include "todoEditor.h"
00050
#include "pilotLocalDatabase.h"
00051
#include "todoWidget.moc"
00052
00053
00054
00055
00056
00057
00058
00059
#define BUFFERSIZE (0xffff)
00060
00061
00062
00063 TodoCheckListItem::TodoCheckListItem(QListView*parent,
const QString&text,
00064 recordid_t pilotid,
void*r):PilotCheckListItem(parent, text, pilotid, r)
00065 {
00066
00067 }
00068
00069
void TodoCheckListItem::stateChange(
bool state)
00070 {
00071 TodoListView*par=dynamic_cast<TodoListView*>(listView());
00072
if (par) par->itemWasChecked(
this, state);
00073 }
00074
00075
00076
00077 TodoWidget::TodoWidget(QWidget * parent,
00078
const QString & path) :
00079 PilotComponent(parent, "component_todo", path),
00080 fTodoInfo(0),
00081 fTodoDB(0),
00082 fPendingTodos(0)
00083 {
00084 FUNCTIONSETUP;
00085
00086 setupWidget();
00087 fTodoList.setAutoDelete(
true);
00088
00089
00090 (
void) todowidget_id;
00091 }
00092
00093 TodoWidget::~TodoWidget()
00094 {
00095 FUNCTIONSETUP;
00096 KPILOT_DELETE( fTodoDB );
00097 }
00098
00099
int TodoWidget::getAllTodos(
PilotDatabase * todoDB)
00100 {
00101 FUNCTIONSETUP;
00102
00103
int currentRecord = 0;
00104 PilotRecord *pilotRec;
00105 PilotTodoEntry *todo;
00106
bool showSecrets = KPilotConfig::getConfig().getShowSecrets();
00107
00108
00109
#ifdef DEBUG
00110
DEBUGKPILOT << fname <<
": Reading ToDoDB..." << endl;
00111
#endif
00112
00113
while ((pilotRec = todoDB->
readRecordByIndex(currentRecord)) != 0L)
00114 {
00115
if (!(pilotRec->isDeleted()) &&
00116 (!(pilotRec->isSecret()) || showSecrets))
00117 {
00118 todo =
new PilotTodoEntry(fTodoAppInfo, pilotRec);
00119
if (todo == 0L)
00120 {
00121 kdWarning() << k_funcinfo
00122 <<
": Couldn't allocate record "
00123 << currentRecord++
00124 << endl;
00125
break;
00126 }
00127 fTodoList.append(todo);
00128 }
00129 KPILOT_DELETE( pilotRec );
00130
00131 currentRecord++;
00132 }
00133
00134
#ifdef DEBUG
00135
DEBUGKPILOT << fname
00136 <<
": Total " << currentRecord <<
" records" << endl;
00137
#endif
00138
00139
return currentRecord;
00140 }
00141
00142
void TodoWidget::showComponent()
00143 {
00144 FUNCTIONSETUP;
00145
if ( fPendingTodos>0 )
return;
00146
00147
#ifdef DEBUG
00148
DEBUGKPILOT << fname
00149 <<
": Reading from directory " << dbPath() << endl;
00150
#endif
00151
00152 fTodoDB =
new PilotLocalDatabase(dbPath(), CSL1(
"ToDoDB"));
00153
unsigned char buffer[BUFFERSIZE];
00154
int appLen;
00155
00156 fTodoList.clear();
00157
00158
if (fTodoDB->isDBOpen())
00159 {
00160 appLen = fTodoDB->readAppBlock(buffer, BUFFERSIZE);
00161 unpack_ToDoAppInfo(&fTodoAppInfo, buffer, appLen);
00162
00163 populateCategories(fCatList, &fTodoAppInfo.category);
00164 getAllTodos(fTodoDB);
00165
00166 }
00167
else
00168 {
00169 populateCategories(fCatList, 0L);
00170 kdWarning() << k_funcinfo
00171 <<
": Could not open local TodoDB" << endl;
00172 }
00173
00174 KPILOT_DELETE( fTodoDB );
00175
00176 updateWidget();
00177 }
00178
00179
bool TodoWidget::preHotSync(QString &s)
00180 {
00181 FUNCTIONSETUP;
00182
00183
if (fPendingTodos)
00184 {
00185
#ifdef DEBUG
00186
DEBUGKPILOT << fname
00187 <<
": fPendingTodo="
00188 << fPendingTodos
00189 << endl;
00190
#endif
00191
00192
#if KDE_VERSION<220
00193
s = i18n(
"There are still %1 todo editing windows open.")
00194 .arg(QString::number(fPendingTodos));
00195
#else
00196
s = i18n(
"There is still an todo editing window open.",
00197
"There are still %n todo editing windows open.",
00198 fPendingTodos);
00199
#endif
00200
return false;
00201 }
00202
00203
return true;
00204 }
00205
00206
void TodoWidget::postHotSync()
00207 {
00208 FUNCTIONSETUP;
00209
00210 fTodoList.clear();
00211 showComponent();
00212 }
00213
00214
void TodoWidget::hideComponent()
00215 {
00216 FUNCTIONSETUP;
00217
if ( fPendingTodos==0 )
00218 {
00219 fTodoList.clear();
00220 fListBox->clear();
00221 KPILOT_DELETE( fTodoDB );
00222 }
00223 }
00224
00225
void TodoWidget::setupWidget()
00226 {
00227 FUNCTIONSETUP;
00228
00229 QLabel *label;
00230 QGridLayout *grid =
new QGridLayout(
this, 6, 4, SPACING);
00231
00232 fCatList =
new QComboBox(
this);
00233 grid->addWidget(fCatList, 0, 1);
00234 connect(fCatList, SIGNAL(activated(
int)),
00235
this, SLOT(slotSetCategory(
int)));
00236 QWhatsThis::add(fCatList,
00237 i18n(
"<qt>Select the category of todos to display here.</qt>"));
00238
00239 label =
new QLabel(i18n(
"Category:"),
this);
00240 label->setBuddy(fCatList);
00241 grid->addWidget(label, 0, 0);
00242
00243 fListBox =
new TodoListView(
this);
00244 fListBox->addColumn( i18n(
"Todo Item" ) );
00245 fListBox->setAllColumnsShowFocus( TRUE );
00246 fListBox->setResizeMode( KListView::LastColumn );
00247 fListBox->setFullWidth( TRUE );
00248 fListBox->setItemsMovable( FALSE );
00249 fListBox->setItemsRenameable (TRUE);
00250 grid->addMultiCellWidget(fListBox, 1, 1, 0, 1);
00251 connect(fListBox, SIGNAL(selectionChanged(QListViewItem*)),
00252
this, SLOT(slotShowTodo(QListViewItem*)));
00253 connect(fListBox, SIGNAL(doubleClicked(QListViewItem*)),
00254
this, SLOT(slotEditRecord(QListViewItem*)));
00255 connect(fListBox, SIGNAL(returnPressed(QListViewItem*)),
00256
this, SLOT(slotEditRecord(QListViewItem*)));
00257 connect(fListBox, SIGNAL(itemChecked(QCheckListItem*,
bool)),
00258
this, SLOT(slotItemChecked(QCheckListItem*,
bool)));
00259 connect(fListBox, SIGNAL(itemRenamed(QListViewItem*,
const QString &,
int)),
00260
this, SLOT(slotItemRenamed(QListViewItem*,
const QString &,
int)));
00261 QWhatsThis::add(fListBox,
00262 i18n(
"<qt>This list displays all the todos "
00263
"in the selected category. Click on "
00264
"one to display it to the right.</qt>"));
00265
00266 label =
new QLabel(i18n(
"Todo info:"),
this);
00267 grid->addWidget(label, 0, 2);
00268
00269
00270 fTodoInfo =
new QTextView(
this);
00271 grid->addMultiCellWidget(fTodoInfo, 1, 4, 2, 2);
00272
00273 QPushButton *button;
00274
00275 fEditButton =
new QPushButton(i18n(
"Edit Record..."),
this);
00276 grid->addWidget(fEditButton, 2, 0);
00277 connect(fEditButton, SIGNAL(clicked()),
this, SLOT(slotEditRecord()));
00278 QWhatsThis::add(fEditButton,
00279 i18n(
"<qt>You can edit a todo when it is selected.</qt>"));
00280
00281 button =
new QPushButton(i18n(
"New Record..."),
this);
00282 grid->addWidget(button, 2, 1);
00283 connect(button, SIGNAL(clicked()),
this, SLOT(slotCreateNewRecord()));
00284 QWhatsThis::add(button, i18n(
"<qt>Add a new todo to the todo list.</qt>"));
00285
00286 fDeleteButton =
new QPushButton(i18n(
"Delete Record"),
this);
00287 grid->addWidget(fDeleteButton, 3, 0);
00288 connect(fDeleteButton, SIGNAL(clicked()),
00289
this, SLOT(slotDeleteRecord()));
00290 QWhatsThis::add(fDeleteButton,
00291 i18n(
"<qt>Delete the selected todo from the todo list.</qt>"));
00292 }
00293
00294
void TodoWidget::updateWidget()
00295 {
00296 FUNCTIONSETUP;
00297
if (!shown)
return;
00298
00299
int listIndex = 0;
00300
00301
int currentCatID = findSelectedCategory(fCatList,
00302 &(fTodoAppInfo.category));
00303
00304 fListBox->clear();
00305 fTodoList.first();
00306
00307
#ifdef DEBUG
00308
DEBUGKPILOT << fname <<
": Adding records..." << endl;
00309
#endif
00310
00311 PilotTodoEntry*todo;
00312
while (fTodoList.current())
00313 {
00314 todo=fTodoList.current();
00315
if ((currentCatID == -1) ||
00316 (todo->getCat() == currentCatID))
00317 {
00318 QString title = todo->getDescription();
00319
00320 TodoCheckListItem*item=
new TodoCheckListItem(fListBox, title,
00321 listIndex, todo);
00322 item->setOn(todo->getComplete());
00323 }
00324 listIndex++;
00325 fTodoList.next();
00326 }
00327
00328
#ifdef DEBUG
00329
DEBUGKPILOT << fname <<
": " << listIndex <<
" records" << endl;
00330
#endif
00331
00332 slotUpdateButtons();
00333 }
00334
00335
00336
00337
void TodoWidget::slotUpdateButtons()
00338 {
00339 FUNCTIONSETUP;
00340
00341
bool enabled = (fListBox->currentItem() != 0L);
00342
00343 fEditButton->setEnabled(enabled);
00344 fDeleteButton->setEnabled(enabled);
00345 }
00346
00347
void TodoWidget::slotSetCategory(
int)
00348 {
00349 FUNCTIONSETUP;
00350
00351 updateWidget();
00352 }
00353
00354
void TodoWidget::slotEditRecord()
00355 {
00356 slotEditRecord(fListBox->currentItem());
00357 }
00358
void TodoWidget::slotEditRecord(QListViewItem*item)
00359 {
00360 FUNCTIONSETUP;
00361
if (!shown)
return;
00362
00363 TodoCheckListItem*p = static_cast<TodoCheckListItem*>(item);
00364
if (!p)
return;
00365 PilotTodoEntry *selectedRecord = (PilotTodoEntry *) p->rec();
00366
00367
if (selectedRecord->id() == 0)
00368 {
00369 KMessageBox::error(0L,
00370 i18n(
"Cannot edit new records until "
00371
"HotSynced with Pilot."),
00372 i18n(
"HotSync Required"));
00373
return;
00374 }
00375
00376 TodoEditor *editor =
new TodoEditor(selectedRecord,
00377 &fTodoAppInfo,
this);
00378
00379 connect(editor, SIGNAL(recordChangeComplete(PilotTodoEntry *)),
00380
this, SLOT(slotUpdateRecord(PilotTodoEntry *)));
00381 connect(editor, SIGNAL(cancelClicked()),
00382
this, SLOT(slotEditCancelled()));
00383 editor->show();
00384
00385 fPendingTodos++;
00386 }
00387
00388
void TodoWidget::slotCreateNewRecord()
00389 {
00390 FUNCTIONSETUP;
00391
if (!shown)
return;
00392
00393
00394
00395
00396
00397
00398
PilotDatabase *myDB =
new PilotLocalDatabase(dbPath(), CSL1(
"ToDoDB"));
00399
00400
if (!myDB || !myDB->
isDBOpen())
00401 {
00402
#ifdef DEBUG
00403
DEBUGKPILOT << fname
00404 <<
": Tried to open "
00405 << dbPath()
00406 <<
"/ToDoDB"
00407 <<
" and got pointer @"
00408 << (
int) myDB
00409 <<
" with status "
00410 << ( myDB ? myDB->
isDBOpen() : false )
00411 << endl;
00412
#endif
00413
00414 KMessageBox::sorry(
this,
00415 i18n(
"You can't add todos to the todo list "
00416
"until you have done a HotSync at least once "
00417
"to retrieve the database layout from your Pilot."),
00418 i18n(
"Can't Add New Todo"));
00419
00420
if (myDB)
00421 KPILOT_DELETE( myDB );
00422
00423
return;
00424 }
00425
00426 TodoEditor *editor =
new TodoEditor(0L,
00427 &fTodoAppInfo,
this);
00428
00429 connect(editor, SIGNAL(recordChangeComplete(PilotTodoEntry *)),
00430
this, SLOT(slotAddRecord(PilotTodoEntry *)));
00431 connect(editor, SIGNAL(cancelClicked()),
00432
this, SLOT(slotEditCancelled()));
00433 editor->show();
00434
00435 fPendingTodos++;
00436 }
00437
00438
void TodoWidget::slotAddRecord(PilotTodoEntry * todo)
00439 {
00440 FUNCTIONSETUP;
00441
if ( !shown && fPendingTodos==0 )
return;
00442
00443
int currentCatID = findSelectedCategory(fCatList,
00444 &(fTodoAppInfo.category),
true);
00445
00446
00447 todo->setCat(currentCatID);
00448 fTodoList.append(todo);
00449 writeTodo(todo);
00450
00451 updateWidget();
00452
00453
00454
00455
00456
00457
00458
00459
00460 fPendingTodos--;
00461
if ( !shown && fPendingTodos==0 ) hideComponent();
00462 }
00463
00464
void TodoWidget::slotUpdateRecord(PilotTodoEntry * todo)
00465 {
00466 FUNCTIONSETUP;
00467
if ( !shown && fPendingTodos==0 )
return;
00468
00469 writeTodo(todo);
00470 TodoCheckListItem* currentRecord = static_cast<TodoCheckListItem*>(fListBox->currentItem());
00471
00472
00473 updateWidget();
00474 fListBox->setCurrentItem(currentRecord);
00475
00476 emit(recordChanged(todo));
00477
00478 fPendingTodos--;
00479
if ( !shown && fPendingTodos==0 ) hideComponent();
00480 }
00481
00482
void TodoWidget::slotEditCancelled()
00483 {
00484 FUNCTIONSETUP;
00485
00486 fPendingTodos--;
00487
if ( !shown && fPendingTodos==0 ) hideComponent();
00488 }
00489
00490
void TodoWidget::slotDeleteRecord()
00491 {
00492 FUNCTIONSETUP;
00493
if (!shown)
return;
00494
00495 TodoCheckListItem* p = static_cast<TodoCheckListItem*>(fListBox->currentItem());
00496
if (p == 0L)
return;
00497
00498 PilotTodoEntry *selectedRecord = (PilotTodoEntry *) p->rec();
00499
00500
if (selectedRecord->id() == 0)
00501 {
00502 KMessageBox::error(
this,
00503 i18n(
"New records cannot be deleted until "
00504
"HotSynced with pilot."),
00505 i18n(
"HotSync Required"));
00506
return;
00507 }
00508
00509
if (KMessageBox::questionYesNo(
this,
00510 i18n(
"Delete currently selected record?"),
00511 i18n(
"Delete Record?")) == KMessageBox::No)
00512
return;
00513
00514 selectedRecord->makeDeleted();
00515 writeTodo(selectedRecord);
00516 emit(recordChanged(selectedRecord));
00517 showComponent();
00518 }
00519
00520
00521
00522
void TodoWidget::slotShowTodo(QListViewItem*item)
00523 {
00524 FUNCTIONSETUP;
00525
if (!shown)
return;
00526
00527 TodoCheckListItem *p = dynamic_cast<TodoCheckListItem*>(item);
00528
if (!p)
return;
00529 PilotTodoEntry *todo = (PilotTodoEntry *) p->rec();
00530
00531
#ifdef DEBUG
00532
DEBUGKPILOT << fname <<
": Showing "<< todo->getDescription()<<endl;
00533
#endif
00534
00535 QString text(CSL1(
"<qt>"));
00536 text += todo->getTextRepresentation(
true);
00537 text += CSL1(
"</qt>\n");
00538 fTodoInfo->setText(text);
00539
00540 slotUpdateButtons();
00541 }
00542
00543
00544
00545
void TodoWidget::writeTodo(PilotTodoEntry * which,
00546
PilotDatabase * todoDB)
00547 {
00548 FUNCTIONSETUP;
00549
00550
00551
00552
00553
00554
00555
PilotDatabase *myDB = todoDB;
00556
bool usemyDB =
false;
00557
00558
if (myDB == 0L || !myDB->
isDBOpen())
00559 {
00560 myDB =
new PilotLocalDatabase(dbPath(), CSL1(
"ToDoDB"));
00561 usemyDB =
true;
00562 }
00563
00564
00565
00566
00567
if (!myDB->
isDBOpen())
00568 {
00569
#ifdef DEBUG
00570
DEBUGKPILOT << fname <<
": Todo database is not open" <<
00571 endl;
00572
#endif
00573
return;
00574 }
00575
00576
00577
00578 PilotRecord *pilotRec = which->pack();
00579
00580 myDB->
writeRecord(pilotRec);
00581 markDBDirty(
"ToDoDB");
00582 KPILOT_DELETE(pilotRec);
00583
00584
00585
00586
00587
00588
if (usemyDB)
00589 {
00590 KPILOT_DELETE(myDB);
00591 }
00592 }
00593
00594
void TodoWidget::slotItemChecked(QCheckListItem*item,
bool on)
00595 {
00596 TodoCheckListItem*p = static_cast<TodoCheckListItem*>(item);
00597
if (!p)
return;
00598 PilotTodoEntry *selectedRecord = (PilotTodoEntry *) p->rec();
00599
if (!selectedRecord)
return;
00600 selectedRecord->setComplete(on);
00601 slotShowTodo(item);
00602 }
00603
00604
void TodoWidget::slotItemRenamed(QListViewItem*item,
const QString &txt,
int nr)
00605 {
00606 TodoCheckListItem*p = static_cast<TodoCheckListItem*>(item);
00607
if (!p)
return;
00608 PilotTodoEntry *selectedRecord = (PilotTodoEntry *) p->rec();
00609
if (!selectedRecord)
return;
00610
if (nr==0)
00611 {
00612 selectedRecord->setDescription(txt);
00613 slotShowTodo(item);
00614 }
00615 }