kpilot Library API Documentation

todoWidget.cc

00001 /* todoWidget.cc KPilot 00002 ** 00003 ** Copyright (C) 2003 by Dan Pilone 00004 ** Written 2003 by Reinhold Kainhofer 00005 ** 00006 ** This file defines the todoWidget, that part of KPilot that 00007 ** displays todo records from the Pilot. 00008 */ 00009 00010 /* 00011 ** This program is free software; you can redistribute it and/or modify 00012 ** it under the terms of the GNU General Public License as published by 00013 ** the Free Software Foundation; either version 2 of the License, or 00014 ** (at your option) any later version. 00015 ** 00016 ** This program is distributed in the hope that it will be useful, 00017 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 ** GNU General Public License for more details. 00020 ** 00021 ** You should have received a copy of the GNU General Public License 00022 ** along with this program in a file called COPYING; if not, write to 00023 ** the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, 00024 ** MA 02111-1307, USA. 00025 */ 00026 00027 /* 00028 ** Bug reports and questions can be sent to kde-pim@kde.org 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 // This is the size of several (automatic) buffers, 00055 // used to retrieve data from the database. 00056 // I have no idea if 0xffff is some magic number or not. 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 /* NOTREACHED */ 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 /* virtual */ 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 // todo info text view 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 /* slot */ 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 // Response to bug 18072: Don't even try to 00394 // add records to an empty or unopened database, 00395 // since we don't have the DBInfo stuff to deal with it. 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 // TODO: Just add the new record to the lists 00451 updateWidget(); 00452 00453 // k holds the item number of the todo just added. 00454 // 00455 // int k = fListBox->count() - 1; 00456 // 00457 // fListBox->setCurrentItem(k); // Show the newest one 00458 // fListBox->setBottomItem(k); 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 // TODO: Just change the record 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 // Open a database (myDB) only if needed, 00551 // i.e. only if the passed-in todoDB 00552 // isn't valid. 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 // Still no valid todo database... 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 // Do the actual work. 00578 PilotRecord *pilotRec = which->pack(); 00579 00580 myDB->writeRecord(pilotRec); 00581 markDBDirty("ToDoDB"); 00582 KPILOT_DELETE(pilotRec); 00583 00584 00585 // Clean up in the case that we allocated our own DB. 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 }
KDE Logo
This file is part of the documentation for kpilot Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Jul 28 23:57:49 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003