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