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 static const char *memowidget_id =
00029 "$Id: memoWidget.cc,v 1.61 2003/10/13 13:58:19 kainhofe Exp $";
00030
00031 #include "options.h"
00032
00033 #include <time.h>
00034
00035 #include <pi-macros.h>
00036 #include <pi-dlp.h>
00037
00038 #include <qdir.h>
00039 #include <qptrlist.h>
00040 #include <qlistbox.h>
00041 #include <qfile.h>
00042 #include <qpushbutton.h>
00043 #include <qlayout.h>
00044 #include <qdom.h>
00045 #include <qtextstream.h>
00046 #include <qwhatsthis.h>
00047 #include <qlabel.h>
00048 #include <qtextcodec.h>
00049
00050 #include <kapplication.h>
00051 #include <kmessagebox.h>
00052 #include <kfiledialog.h>
00053
00054 #include "kpilot.h"
00055 #include "kpilotConfig.h"
00056 #include "listItems.h"
00057 #include "pilotLocalDatabase.h"
00058 #include "pilotMemo.h"
00059
00060 #include "memoWidget.moc"
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 #define PILOT_BUFFER_SIZE (0xffff)
00071
00072
00073
00074 MemoWidget::MemoWidget(QWidget * parent,
00075 const QString & path) :
00076 PilotComponent(parent, "component_memo", path),
00077 fTextWidget(0L),
00078 lastSelectedMemo(-1)
00079 {
00080 FUNCTIONSETUP;
00081
00082 setGeometry(0, 0,
00083 parent->geometry().width(), parent->geometry().height());
00084 setupWidget();
00085 fMemoList.setAutoDelete(true);
00086 slotUpdateButtons();
00087
00088 #if 0
00089 connect(fTextWidget, SIGNAL(textChanged()),
00090 this, SLOT(slotTextChanged()));
00091 #endif
00092
00093
00094 (void) memowidget_id;
00095 }
00096
00097 MemoWidget::~MemoWidget()
00098 {
00099 FUNCTIONSETUP;
00100 saveChangedMemo();
00101 }
00102
00103
00104
00105
00106
00107
00108
00109
00110 void MemoWidget::initializeMemos(PilotDatabase * memoDB)
00111 {
00112 FUNCTIONSETUP;
00113
00114
00115
00116
00117
00118 bool showSecrets = KPilotConfig::getConfig().getShowSecrets();
00119
00120 fMemoList.clear();
00121
00122
00123 int currentRecord = 0;
00124 PilotRecord *pilotRec;
00125 PilotMemo *memo;
00126
00127 while ((pilotRec = memoDB->readRecordByIndex(currentRecord)) != NULL)
00128 {
00129 if (!pilotRec->isDeleted())
00130 {
00131 if ((!pilotRec->isSecret()) || showSecrets)
00132 {
00133 memo = new PilotMemo(pilotRec);
00134 fMemoList.append(memo);
00135
00136 #ifdef DEBUG
00137 DEBUGKPILOT << fname <<
00138 ": Added memo "
00139 << currentRecord << endl;
00140 #endif
00141 }
00142 else
00143 {
00144 #ifdef DEBUG
00145 DEBUGKPILOT << fname <<
00146 ": Skipped secret record " <<
00147 currentRecord << endl;
00148 #endif
00149 }
00150 }
00151 else
00152 {
00153 #ifdef DEBUG
00154 DEBUGKPILOT << fname <<
00155 ": Skipped deleted record " <<
00156 currentRecord << endl;
00157 #endif
00158 }
00159
00160 delete pilotRec;
00161
00162 currentRecord++;
00163 }
00164 }
00165
00166
00167 void MemoWidget::showComponent()
00168 {
00169 FUNCTIONSETUP;
00170 if (!shown) return;
00171
00172
00173
00174
00175
00176 PilotLocalDatabase *memoDB =
00177 new PilotLocalDatabase(dbPath(), CSL1("MemoDB"));
00178 if (memoDB == NULL || !memoDB->isDBOpen())
00179 {
00180 kdWarning() << k_funcinfo <<
00181 ": Can't open local database MemoDB\n";
00182
00183 populateCategories(fCatList, 0L);
00184 updateWidget();
00185 return;
00186 }
00187
00188
00189
00190
00191 int appLen = memoDB->appInfoSize();
00192
00193 #ifdef DEBUG
00194 DEBUGKPILOT << fname << ": Got appInfoLen " << appLen << endl;
00195 #endif
00196
00197 unpack_MemoAppInfo(&fMemoAppInfo,
00198 (unsigned char *) memoDB->appInfo(), appLen);
00199
00200 #ifdef DEBUG
00201 DEBUGKPILOT << fname << ": Unpacked app info." << endl;
00202
00203 for (int i = 0; i < 15; i++)
00204 {
00205 DEBUGKPILOT << fname
00206 << ": Category #"
00207 << i
00208 << " has ID "
00209 << (int) fMemoAppInfo.category.ID[i]
00210 << " and name "
00211 << (fMemoAppInfo.category.name[i][0] ? "*" : "-")
00212 << fMemoAppInfo.category.name[i] << endl;
00213 }
00214 #endif
00215
00216 populateCategories(fCatList, &fMemoAppInfo.category);
00217
00218 #ifdef DEBUG
00219 DEBUGKPILOT << fname << ": Populated categories" << endl;
00220 #endif
00221
00222 initializeMemos(memoDB);
00223
00224 #ifdef DEBUG
00225 DEBUGKPILOT << fname << ": Finished initializing" << endl;
00226 #endif
00227
00228 KPILOT_DELETE( memoDB );
00229
00230 updateWidget();
00231 }
00232
00233 void MemoWidget::hideComponent()
00234 {
00235 FUNCTIONSETUP;
00236 saveChangedMemo();
00237 fCatList->clear();
00238 fTextWidget->clear();
00239 fMemoList.clear();
00240 fListBox->clear();
00241 lastSelectedMemo = -1;
00242 }
00243
00244 void MemoWidget::postHotSync()
00245 {
00246 FUNCTIONSETUP;
00247 fMemoList.clear();
00248 showComponent();
00249 }
00250
00251
00252
00253
00254
00255
00256
00257 void MemoWidget::setupWidget()
00258 {
00259 FUNCTIONSETUP;
00260
00261 QLabel *label = NULL;
00262 QPushButton *button = NULL;
00263 QGridLayout *grid = new QGridLayout(this, 5, 4, SPACING);
00264
00265 fCatList = new QComboBox(this);
00266 grid->addWidget(fCatList, 0, 1);
00267 connect(fCatList, SIGNAL(activated(int)),
00268 this, SLOT(slotSetCategory(int)));
00269 QWhatsThis::add(fCatList,
00270 i18n("Select the category of addresses\n"
00271 "to display here."));
00272
00273 (void) i18n("Memos:");
00274 label = new QLabel(i18n("Category:"), this);
00275 label->setBuddy(fCatList);
00276 grid->addWidget(label, 0, 0);
00277
00278 fListBox = new QListBox(this);
00279 grid->addMultiCellWidget(fListBox, 1, 1, 0, 1);
00280 connect(fListBox, SIGNAL(highlighted(int)),
00281 this, SLOT(slotShowMemo(int)));
00282 connect(fListBox, SIGNAL(selectionChanged()),
00283 this,SLOT(slotUpdateButtons()));
00284 QWhatsThis::add(fListBox,
00285 i18n("This list displays all the memos\n"
00286 "in the selected category. Click on\n"
00287 "one to display it to the right."));
00288
00289 label = new QLabel(i18n("Memo text:"), this);
00290 grid->addWidget(label, 0, 2);
00291
00292 fTextWidget = new KTextEdit(this, "textArea");
00293 fTextWidget->setWordWrap(KTextEdit::WidgetWidth);
00294 fTextWidget->setTextFormat(Qt::PlainText);
00295 grid->addMultiCellWidget(fTextWidget, 1, 4, 2, 2);
00296 QWhatsThis::add(fTextWidget,
00297 i18n("The text of the selected memo appears here."));
00298
00299 button = new QPushButton(i18n("Import Memo..."), this);
00300 grid->addWidget(button, 2, 0);
00301 connect(button, SIGNAL(clicked()), this, SLOT(slotImportMemo()));
00302 QWhatsThis::add(button,
00303 i18n
00304 ("Read a text file and add it to the Pilot's memo database."));
00305
00306 fExportButton = new QPushButton(i18n("Export Memo..."), this);
00307 grid->addWidget(fExportButton, 2, 1);
00308 connect(fExportButton, SIGNAL(clicked()), this,
00309 SLOT(slotExportMemo()));
00310 QWhatsThis::add(fExportButton,
00311 i18n("Write the selected memo to a file."));
00312
00313 fDeleteButton = new QPushButton(i18n("Delete Memo"), this);
00314 grid->addWidget(fDeleteButton, 3, 0);
00315 connect(fDeleteButton, SIGNAL(clicked()), this,
00316 SLOT(slotDeleteMemo()));
00317 QWhatsThis::add(fDeleteButton, i18n("Delete the selected memo."));
00318 }
00319
00320 void MemoWidget::slotUpdateButtons()
00321 {
00322 FUNCTIONSETUP;
00323
00324 bool highlight = false;
00325
00326 if ((fListBox->currentItem() != -1) &&
00327 (fListBox->isSelected(fListBox->currentItem())))
00328 highlight=true;
00329
00330 #ifdef DEBUG
00331 DEBUGKPILOT << fname << ": Selected items " << highlight << endl;
00332 #endif
00333
00334 if (fExportButton)
00335 {
00336 fExportButton->setEnabled(highlight);
00337 }
00338 if (fDeleteButton)
00339 {
00340 fDeleteButton->setEnabled(highlight);
00341 }
00342 }
00343
00344 void MemoWidget::slotSetCategory(int)
00345 {
00346 FUNCTIONSETUP;
00347 updateWidget();
00348 }
00349
00350 void MemoWidget::slotDeleteMemo()
00351 {
00352 FUNCTIONSETUP;
00353 if (!shown) return;
00354
00355 int item = fListBox->currentItem();
00356
00357 if (item == -1)
00358 {
00359 #ifdef DEBUG
00360 DEBUGKPILOT << fname << ": No current item selected\n";
00361 #endif
00362 return;
00363 }
00364
00365 PilotListItem *p = (PilotListItem *) fListBox->item(item);
00366 PilotMemo *selectedMemo = (PilotMemo *) p->rec();
00367
00368 if (selectedMemo->id() == 0x0)
00369 {
00370
00371
00372
00373
00374
00375 kdWarning() << k_funcinfo <<
00376 ": Refusing to delete new memo.\n";
00377
00378 KMessageBox::error(this,
00379 i18n("New memo cannot be deleted until "
00380 "HotSynced with pilot."),
00381 i18n("HotSync Required"));
00382 return;
00383 }
00384
00385
00386 if (KMessageBox::questionYesNo(this,
00387 i18n("Delete currently selected memo?"),
00388 i18n("Delete Memo?")) == KMessageBox::No)
00389 {
00390 #ifdef DEBUG
00391 DEBUGKPILOT << fname <<
00392 ": User decided not to delete memo.\n";
00393 #endif
00394 return;
00395 }
00396
00397 selectedMemo->makeDeleted();
00398 writeMemo(selectedMemo);
00399 fMemoList.remove(selectedMemo);
00400 delete p;
00401 }
00402
00403
00404 void MemoWidget::updateWidget()
00405 {
00406 FUNCTIONSETUP;
00407 if (!shown) return;
00408
00409 if (fCatList->currentItem() == -1)
00410 {
00411 #ifdef DEBUG
00412 DEBUGKPILOT << fname << ": No category selected.\n";
00413 #endif
00414 return;
00415 }
00416
00417 int listIndex = 0;
00418 int currentCatID = findSelectedCategory(fCatList,
00419 &(fMemoAppInfo.category), false);
00420
00421
00422 fListBox->clear();
00423 fMemoList.first();
00424
00425
00426
00427
00428
00429
00430
00431 while (fMemoList.current())
00432 {
00433 if ((fMemoList.current()->getCat() == currentCatID) ||
00434 (currentCatID == -1))
00435 {
00436 PilotListItem *p =
00437 new PilotListItem(fMemoList.current()->
00438 shortTitle(),
00439 listIndex,
00440 fMemoList.current());
00441
00442
00443
00444
00445
00446 fListBox->insertItem(p);
00447
00448 #ifdef DEBUG
00449 DEBUGKPILOT << fname << ": Added memo "
00450 << fMemoList.current()->getTitle() << endl;
00451 #endif
00452 }
00453 else
00454 {
00455 #ifdef DEBUG
00456 DEBUGKPILOT << fname << ": Skipped memo "
00457 << fMemoList.current()->getTitle() << endl;
00458 #endif
00459 }
00460
00461 listIndex++;
00462 fMemoList.next();
00463 }
00464
00465 fTextWidget->clear();
00466
00467 slotUpdateButtons();
00468
00469 lastSelectedMemo=-1;
00470 }
00471
00472 void MemoWidget::slotShowMemo(int which)
00473 {
00474 FUNCTIONSETUP;
00475 if ( which == -1 ) return;
00476 if (!shown) return;
00477
00478 slotUpdateButtons();
00479 if ( !fListBox->isSelected(which) )
00480 {
00481
00482 fTextWidget->blockSignals(true);
00483 fTextWidget->clear();
00484 fTextWidget->blockSignals(false);
00485 return;
00486 }
00487
00488
00489 #ifdef DEBUG
00490 DEBUGKPILOT << fname << ": Displaying memo " << which << endl;
00491 #endif
00492 fTextWidget->blockSignals(true);
00493 PilotListItem *p = (PilotListItem *) fListBox->item(which);
00494 PilotMemo *theMemo = (PilotMemo *) p->rec();
00495 fTextWidget->setText(theMemo->text());
00496 fTextWidget->blockSignals(false);
00497 }
00498
00499 void MemoWidget::writeMemo(PilotMemo * which)
00500 {
00501 FUNCTIONSETUP;
00502 if (!shown) return;
00503
00504 PilotDatabase *memoDB = new PilotLocalDatabase(dbPath(), CSL1("MemoDB"));
00505 PilotRecord *pilotRec = which->pack();
00506
00507 memoDB->writeRecord(pilotRec);
00508 markDBDirty("MemoDB");
00509 KPILOT_DELETE( pilotRec );
00510 KPILOT_DELETE( memoDB );
00511 }
00512
00513 void MemoWidget::saveChangedMemo()
00514 {
00515 FUNCTIONSETUP;
00516 if (!shown) return;
00517
00518 if (-1 == lastSelectedMemo) return;
00519 if (!fTextWidget->isModified()) return;
00520
00521 #ifdef DEBUG
00522 DEBUGKPILOT << fname
00523 << ": Saving changed memo " << lastSelectedMemo << endl;
00524 #endif
00525
00526 PilotListItem *p =
00527 (PilotListItem *) fListBox->item(lastSelectedMemo);
00528 PilotMemo *currentMemo = (PilotMemo *) p->rec();
00529
00530 currentMemo->setText(PilotAppCategory::codec()->
00531 fromUnicode(fTextWidget->text()));
00532 writeMemo(currentMemo);
00533 }
00534
00535 bool MemoWidget::preHotSync(QString &)
00536 {
00537 FUNCTIONSETUP;
00538 saveChangedMemo();
00539 return true;
00540 }
00541
00542 void MemoWidget::slotImportMemo()
00543 {
00544 FUNCTIONSETUP;
00545 if (!shown) return;
00546
00547 int i = 0;
00548 int nextChar;
00549 int currentCatID = findSelectedCategory(fCatList,
00550 &(fMemoAppInfo.category), true);
00551
00552 QString fileName = KFileDialog::getOpenFileName();
00553
00554 if (!fileName.isEmpty())
00555 {
00556 QFile importFile(fileName);
00557
00558 if (importFile.open(IO_ReadOnly) == FALSE)
00559 {
00560
00561 return;
00562 }
00563 char *text = new char[(int) MemoWidget::MAX_MEMO_LEN];
00564
00565 for (i = 0;
00566 (i < (MemoWidget::MAX_MEMO_LEN - 1))
00567 && ((nextChar = importFile.getch()) != -1); i++)
00568 text[i] = nextChar;
00569 text[i] = 0;
00570 PilotMemo *aMemo = new PilotMemo(text, 0, 0, currentCatID);
00571
00572 fMemoList.append(aMemo);
00573 writeMemo(aMemo);
00574 updateWidget();
00575 delete[]text;
00576 }
00577 }
00578
00579 void MemoWidget::slotExportMemo()
00580 {
00581 FUNCTIONSETUP;
00582 if (!shown) return;
00583
00584 int index = fListBox->numRows();
00585 if (index == 0)
00586 return;
00587
00588 QString data;
00589
00590 const QString filter = CSL1("*|Plain text output\n*.xml|XML output");
00591 QString fileName;
00592
00593 KFileDialog kfile( QString::null , filter, fExportButton , "memoSave" , true );
00594 kfile.setOperationMode( KFileDialog::Saving );
00595
00596 if ( kfile.exec() == QDialog::Accepted ) {
00597 fileName = kfile.selectedFile();
00598 }
00599
00600 if (fileName.isEmpty())
00601 return;
00602
00603 QPtrList<PilotListItem> menu_items;
00604
00605 for (int x = 0; x < index; x++){
00606 if (fListBox->item(x)->isSelected()){
00607 menu_items.append((PilotListItem *) fListBox->item(x));
00608 }
00609 }
00610
00611 if (kfile.currentFilter() == CSL1("*.xml") )
00612 {
00613 MemoWidget::saveAsXML( fileName , menu_items );
00614 }
00615 else
00616 {
00617 MemoWidget::saveAsText( fileName , menu_items );
00618 }
00619
00620
00621 return;
00622 }
00623
00624 bool MemoWidget::saveAsText(const QString &fileName,const QPtrList<PilotListItem> &memo_list)
00625 {
00626 QFile f( fileName );
00627 QTextStream stream(&f);
00628
00629 if ( QFile::exists( fileName ) )
00630 {
00631 if( !f.open(IO_ReadWrite | IO_Append) )
00632 {
00633 return false;
00634 }
00635 }
00636 else
00637 {
00638 if( !f.open(IO_WriteOnly) )
00639 {
00640 return false;
00641 }
00642 }
00643
00644 QPtrListIterator<PilotListItem> it(memo_list);
00645 for ( ; it.current(); ++it )
00646 {
00647 PilotListItem *p = it.current();
00648 PilotMemo *theMemo = (PilotMemo *) p->rec();
00649 stream << theMemo->text() << endl;
00650 }
00651
00652
00653 return true;
00654 }
00655
00656 bool MemoWidget::saveAsXML(const QString &fileName,const QPtrList<PilotListItem> &memo_list)
00657 {
00658 QDomDocument doc( CSL1("kpilotmemos") );
00659 QFile f( fileName );
00660 QTextStream stream( &f );
00661 QDomElement memos;
00662 int append = 0;
00663
00664
00665 if ( f.exists() )
00666 {
00667 if ( !f.open(IO_ReadOnly ) ) return false;
00668
00669 if ( doc.setContent( &f ) )
00670 {
00671
00672
00673
00674 memos = doc.documentElement();
00675 if ( memos.tagName()!= CSL1("memos") )
00676 {
00677 return false;
00678 }
00679
00680
00681
00682 else
00683 {
00684 append = 1;
00685 }
00686
00687
00688
00689 }
00690 else
00691 {
00692
00693
00694
00695 return false;
00696 }
00697 }
00698 else
00699 {
00700 if ( !f.open(IO_ReadWrite ) ) return false;
00701
00702
00703
00704 }
00705
00706 f.close();
00707
00708 QString mpilotid;
00709 mpilotid = "1";
00710
00711
00712 if (append == 1)
00713 {
00714 memos = doc.documentElement();
00715 }
00716 else
00717 {
00718 memos = doc.createElement( CSL1("memos") );
00719 doc.appendChild ( memos );
00720 }
00721
00722 QPtrListIterator<PilotListItem> it(memo_list);
00723 for ( ; it.current(); ++it )
00724 {
00725 PilotListItem *p = it.current();
00726 PilotMemo *theMemo = (PilotMemo *) p->rec();
00727
00728
00729 QDomElement memo = doc.createElement( CSL1("memo") );
00730 memo.setAttribute ( CSL1("pilotid") , mpilotid );
00731 memos.appendChild ( memo );
00732
00733
00734
00735
00736
00737
00738
00739
00740 QDomElement title = doc.createElement(CSL1("title" ));
00741 memo.appendChild ( title );
00742
00743 QDomText titletext = doc.createTextNode( theMemo->shortTitle() );
00744 title.appendChild ( titletext );
00745
00746 QDomText body = doc.createTextNode( theMemo->text() );
00747 memo.appendChild ( body );
00748 }
00749 if ( !f.open(IO_WriteOnly ) ) return false;
00750 stream << doc.toString();
00751 return true;
00752 }
00753