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