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 }