diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2011-02-16 20:17:18 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2011-02-16 20:17:18 +0000 |
commit | cb7eddb91455a69cf66fcd717e91a51ca5e2cfef (patch) | |
tree | cf5546e4d7c44370fbe9ca2be937bd254f30ebaa /kpilot/memoWidget.cc | |
download | kpilot-cb7eddb91455a69cf66fcd717e91a51ca5e2cfef.tar.gz kpilot-cb7eddb91455a69cf66fcd717e91a51ca5e2cfef.zip |
Moved kpilot from kdepim to applications, as the core Trinity libraries should not contain hardware-dependent software
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/kpilot@1221127 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kpilot/memoWidget.cc')
-rw-r--r-- | kpilot/memoWidget.cc | 803 |
1 files changed, 803 insertions, 0 deletions
diff --git a/kpilot/memoWidget.cc b/kpilot/memoWidget.cc new file mode 100644 index 0000000..186aeee --- /dev/null +++ b/kpilot/memoWidget.cc @@ -0,0 +1,803 @@ +/* KPilot +** +** Copyright (C) 1998-2001 by Dan Pilone +** Copyright (C) 2001 by David Bishop (XML stuff) +** Copyright (C) 2004 by Adriaan de Groot +** +** This is the memo-viewing widget (internal conduit) used by KPilot. +*/ + +/* +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program in a file called COPYING; if not, write to +** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +** MA 02110-1301, USA. +*/ + +/* +** Bug reports and questions can be sent to kde-pim@kde.org +*/ + +#include "options.h" + +#include <time.h> + +#include <pi-macros.h> +#include <pi-dlp.h> + +#include <tqdir.h> +#include <tqptrlist.h> +#include <tqlistbox.h> +#include <tqfile.h> +#include <tqpushbutton.h> +#include <tqlayout.h> +#include <tqdom.h> +#include <tqtextstream.h> +#include <tqwhatsthis.h> +#include <tqlabel.h> +#include <tqdatetime.h> +#include <tqptrlist.h> + +#include <kapplication.h> +#include <kmessagebox.h> +#include <kfiledialog.h> +#include <kdeversion.h> +#include <ktextedit.h> + +#include "kpilot.h" +#include "kpilotConfig.h" +#include "listItems.h" +#include "pilotLocalDatabase.h" +#include "pilotMemo.h" + +#include "memoWidget.moc" + + +class MemoWidget::Private +{ +public: + Private() : fMemoAppInfo(0L) { } ; + ~Private() { KPILOT_DELETE(fMemoAppInfo); } ; + + PilotMemoInfo *fMemoAppInfo; + TQPtrList<PilotMemo> fMemoList; +} ; + + +MemoWidget::MemoWidget(TQWidget * parent, + const TQString & path) : + PilotComponent(parent, "component_memo", path), + fTextWidget(0L), + d(new Private()), + lastSelectedMemo(-1) +{ + FUNCTIONSETUP; + + setGeometry(0, 0, + parent->tqgeometry().width(), parent->tqgeometry().height()); + setupWidget(); + d->fMemoList.setAutoDelete(true); + slotUpdateButtons(); +} + +MemoWidget::~MemoWidget() +{ + FUNCTIONSETUP; + saveChangedMemo(); + KPILOT_DELETE(d); +} + + +// void MemoWidget::initializeMemos(PilotDatabase *memoDB) +// +// Reads all the memos from the local database and places them +// in the selection screen. +// + +void MemoWidget::initializeMemos(PilotDatabase * memoDB) +{ + FUNCTIONSETUP; + + + // ShowSecrets tells us to also list memos with an attribute of "Secret" + // or "Private" + // + bool showSecrets = KPilotSettings::showSecrets(); + + d->fMemoList.clear(); + + + int currentRecord = 0; + PilotRecord *pilotRec; + PilotMemo *memo; + + while ((pilotRec = memoDB->readRecordByIndex(currentRecord)) != NULL) + { + if (!pilotRec->isDeleted()) + { + if ((!pilotRec->isSecret()) || showSecrets) + { + memo = new PilotMemo(pilotRec); + d->fMemoList.append(memo); + +#ifdef DEBUG + DEBUGKPILOT << fname << + ": Added memo " + << currentRecord << endl; +#endif + } + else + { +#ifdef DEBUG + DEBUGKPILOT << fname << + ": Skipped secret record " << + currentRecord << endl; +#endif + } + } + else + { +#ifdef DEBUG + DEBUGKPILOT << fname << + ": Skipped deleted record " << + currentRecord << endl; +#endif + } + + delete pilotRec; + + currentRecord++; + } +} + + +void MemoWidget::showComponent() +{ + FUNCTIONSETUP; + if (!shown) return; + + // Get the local database - assume the call may fail and return + // NULL, or the database object may be returned but unopened. + // + // + PilotLocalDatabase *memoDB = + new PilotLocalDatabase(dbPath(), CSL1("MemoDB")); + if (memoDB == NULL || !memoDB->isOpen()) + { + WARNINGKPILOT << "Can't open local database MemoDB\n"; + + populateCategories(fCatList, 0L); + updateWidget(); + return; + } + + KPILOT_DELETE(d->fMemoAppInfo); + d->fMemoAppInfo = new PilotMemoInfo(memoDB); + + d->fMemoAppInfo->dump(); + populateCategories(fCatList, d->fMemoAppInfo->categoryInfo()); + initializeMemos(memoDB); + + KPILOT_DELETE( memoDB ); + + updateWidget(); +} + +void MemoWidget::hideComponent() +{ + FUNCTIONSETUP; + saveChangedMemo(); + fCatList->clear(); + fTextWidget->clear(); + d->fMemoList.clear(); + fListBox->clear(); + lastSelectedMemo = -1; +} + +void MemoWidget::postHotSync() +{ + FUNCTIONSETUP; + d->fMemoList.clear(); + showComponent(); +} + + +// void MemoWidget::setupWidget() +// +// Setup all the GUI components by allocating them. +// +// +void MemoWidget::setupWidget() +{ + FUNCTIONSETUP; + + TQLabel *label = NULL; + TQPushButton *button = NULL; + TQGridLayout *grid = new TQGridLayout(this, 5, 4, SPACING); + TQString wt; + + fCatList = new TQComboBox(this); + grid->addWidget(fCatList, 0, 1); + connect(fCatList, TQT_SIGNAL(activated(int)), + this, TQT_SLOT(slotSetCategory(int))); + TQWhatsThis::add(fCatList, + i18n("Select the category of addresses\n" + "to display here.")); + + (void) i18n("Memos:"); + label = new TQLabel(i18n("Category:"), this); + label->setBuddy(fCatList); + grid->addWidget(label, 0, 0); + + fListBox = new TQListBox(this); + grid->addMultiCellWidget(fListBox, 1, 1, 0, 1); + connect(fListBox, TQT_SIGNAL(highlighted(int)), + this, TQT_SLOT(slotShowMemo(int))); + connect(fListBox, TQT_SIGNAL(selectionChanged()), + this,TQT_SLOT(slotUpdateButtons())); + TQWhatsThis::add(fListBox, + i18n("This list displays all the memos\n" + "in the selected category. Click on\n" + "one to display it to the right.")); + + label = new TQLabel(i18n("Memo text:"), this); + grid->addWidget(label, 0, 2); + + fTextWidget = new KTextEdit(this, "textArea"); + fTextWidget->setWordWrap(KTextEdit::WidgetWidth); + fTextWidget->setTextFormat(Qt::PlainText); + grid->addMultiCellWidget(fTextWidget, 1, 4, 2, 2); + TQWhatsThis::add(fTextWidget, + i18n("The text of the selected memo appears here.")); + fTextWidget->setReadOnly(!KPilotSettings::internalEditors()); + + button = new TQPushButton(i18n("Import Memo..."), this); + grid->addWidget(button, 2, 0); + connect(button, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotImportMemo())); + wt = KPilotSettings::internalEditors() ? + i18n ("Read a text file and add it to the Pilot's memo database.") : + i18n("<qt><i>Import is disabled by the 'internal editors' setting.</i></qt>"); + TQWhatsThis::add(button,wt); + + fExportButton = new TQPushButton(i18n("Export Memo..."), this); + grid->addWidget(fExportButton, 2, 1); + connect(fExportButton, TQT_SIGNAL(clicked()), this, + TQT_SLOT(slotExportMemo())); + TQWhatsThis::add(fExportButton, + i18n("Write the selected memo to a file.")); + + fDeleteButton = new TQPushButton(i18n("Delete Memo"), this); + grid->addWidget(fDeleteButton, 3, 1); + connect(fDeleteButton, TQT_SIGNAL(clicked()), this, + TQT_SLOT(slotDeleteMemo())); + wt = KPilotSettings::internalEditors() ? + i18n("Delete the selected memo.") : + i18n("<qt><i>Deleting is disabled by the 'internal editors' setting.</i></qt>") ; + TQWhatsThis::add(fDeleteButton, wt); + + button = new TQPushButton(i18n("Add Memo"), this); + grid->addWidget(button, 3, 0); + connect(button, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotAddMemo())); + TQWhatsThis::add(button,i18n("Add a new memo to the database.")); +} + +void MemoWidget::slotUpdateButtons() +{ + FUNCTIONSETUP; + + bool highlight = false; + + if ((fListBox->currentItem() != -1) && + (fListBox->isSelected(fListBox->currentItem()))) + highlight=true; + +#ifdef DEBUG + DEBUGKPILOT << fname << ": Selected items " << highlight << endl; +#endif + + if (fExportButton) + { + fExportButton->setEnabled(highlight); + } + + // The remaining buttons are relevant only if the + // internal editors are editable. + highlight &= KPilotSettings::internalEditors() ; + if (fDeleteButton) + { + fDeleteButton->setEnabled(highlight); + } +} + +void MemoWidget::slotSetCategory(int) +{ + FUNCTIONSETUP; + updateWidget(); +} + +void MemoWidget::slotDeleteMemo() +{ + FUNCTIONSETUP; + if (!shown) return; + + int item = fListBox->currentItem(); + + if (item == -1) + { +#ifdef DEBUG + DEBUGKPILOT << fname << ": No current item selected\n"; +#endif + return; + } + if (KMessageBox::questionYesNo(this, + i18n("Delete currently selected memo?"), + i18n("Delete Memo?"), KStdGuiItem::del(), KStdGuiItem::cancel()) != KMessageBox::Yes) + { +#ifdef DEBUG + DEBUGKPILOT << fname << + ": User decided not to delete memo.\n"; +#endif + return; + } + + PilotListItem *p = (PilotListItem *) fListBox->item(item); + PilotMemo *selectedMemo = (PilotMemo *) p->rec(); + + if (selectedMemo->id() == 0x0) + { +#ifdef DEBUG + DEBUGKPILOT << fname << ": Searching for record to delete (it's fresh)" << endl; +#endif + PilotLocalDatabase *memoDB = new PilotLocalDatabase(dbPath(), CSL1("MemoDB")); + if (!memoDB || (!memoDB->isOpen())) + { + // Err.. peculiar. + WARNINGKPILOT << "Can't open MemoDB" << endl; + KMessageBox::sorry(this, + i18n("Cannot open MemoDB to delete record."), + i18n("Cannot Delete Memo")); + return; + } + memoDB->resetDBIndex(); +#ifdef DEBUG + DEBUGKPILOT << fname << ": Searching for new record." << endl; +#endif + const PilotRecord *r = 0L; + while ((r = memoDB->findNextNewRecord())) + { +#ifdef DEBUG + DEBUGKPILOT << fname << ": got record " << (void *) r << endl; +#endif + PilotMemo m(r); + if (m.text() == selectedMemo->text()) + { +#ifdef DEBUG + DEBUGKPILOT << fname << ": I think I found the memo." << endl; +#endif + (const_cast<PilotRecord *>(r))->setDeleted(true); + break; + } + } + delete memoDB; + } + else + { + selectedMemo->setDeleted(true); + writeMemo(selectedMemo); + } + d->fMemoList.remove(selectedMemo); + delete p; +} + + +void MemoWidget::updateWidget() +{ + FUNCTIONSETUP; + if (!shown || !d->fMemoAppInfo ) return; + + if (fCatList->currentItem() == -1) + { +#ifdef DEBUG + DEBUGKPILOT << fname << ": No category selected.\n"; +#endif + return; + } + + int listIndex = 0; + int currentCatID = findSelectedCategory(fCatList, + d->fMemoAppInfo->categoryInfo(), false); + + + fListBox->clear(); + d->fMemoList.first(); + + + // Iterate through all the memos and insert each memo + // only if the category of the memo matches the selected category + // (using -1 to mean "All") + // + // + while (d->fMemoList.current()) + { + PilotMemo *curr = d->fMemoList.current(); + if ((curr->category() == currentCatID) || + (currentCatID == -1)) + { + PilotListItem *p = + new PilotListItem(curr->shortTitle(), + listIndex, + curr); + + // List will delete the title of the memo, + // so there's no memory leak here. + // + // + fListBox->insertItem(p); + +#ifdef DEBUG + DEBUGKPILOT << fname << ": Added memo " + << curr->getTitle() << endl; +#endif + } + else + { +#ifdef DEBUG + DEBUGKPILOT << fname << ": Skipped memo " + << curr->getTitle() << endl; +#endif + } + + listIndex++; + d->fMemoList.next(); + } + + fTextWidget->clear(); + + slotUpdateButtons(); + + lastSelectedMemo=-1; +} + +void MemoWidget::showMemo(const PilotMemo *m) +{ + FUNCTIONSETUP; + + int index = fListBox->count(); + for (int x = 0; x < index; x++) + { + PilotMemo *p = (PilotMemo *) ((PilotListItem *)fListBox->item(x))->rec(); +#ifdef DEBUG + DEBUGKPILOT << fname << ": Memo @" << (void *) p <<endl; + DEBUGKPILOT << fname << " :" << fListBox->item(x)->text() << endl; +#endif + if (m==p) + { + fListBox->setSelected(x,true); + slotShowMemo(x); + break; + } + } + +} + +void MemoWidget::slotShowMemo(int which) +{ + FUNCTIONSETUP; + if ( which == -1 ) return; + if (!shown) return; + + slotUpdateButtons(); + if ( !fListBox->isSelected(which) ) + { + // Handle unselecting a memo. This is easy. + fTextWidget->blockSignals(true); + fTextWidget->clear(); + fTextWidget->blockSignals(false); + return; + } + + +#ifdef DEBUG + DEBUGKPILOT << fname << ": Displaying memo " << which << endl; +#endif + fTextWidget->blockSignals(true); + PilotListItem *p = (PilotListItem *) fListBox->item(which); + PilotMemo *theMemo = (PilotMemo *) p->rec(); + fTextWidget->setText(theMemo->text()); + fTextWidget->blockSignals(false); +} + + +void MemoWidget::writeMemo(PilotMemo * which) +{ + FUNCTIONSETUP; + if (!shown) return; + PilotRecord *pilotRec = which->pack(); + PilotDatabase *memoDB = new PilotLocalDatabase(dbPath(), CSL1("MemoDB")); + memoDB->writeRecord(pilotRec); + markDBDirty(CSL1("MemoDB")); + KPILOT_DELETE( memoDB ); + KPILOT_DELETE( pilotRec ); +} + +void MemoWidget::saveChangedMemo() +{ + FUNCTIONSETUP; + if (!shown) return; + + if (-1 == lastSelectedMemo) return; + if (!fTextWidget->isModified()) return; + +#ifdef DEBUG + DEBUGKPILOT << fname + << ": Saving changed memo " << lastSelectedMemo << endl; +#endif + + PilotListItem *p = + (PilotListItem *) fListBox->item(lastSelectedMemo); + PilotMemo *currentMemo = (PilotMemo *) p->rec(); + +// TODO: overload setText in PilotMemo + currentMemo->setText(Pilot::toPilot(fTextWidget->text())); + writeMemo(currentMemo); +} + +/* virtual */ bool MemoWidget::preHotSync(TQString &) +{ + FUNCTIONSETUP; + saveChangedMemo(); + return true; +} + +bool MemoWidget::addMemo(const TQString &s, int category) +{ + FUNCTIONSETUP; + + if (s.length() >= MemoWidget::MAX_MEMO_LEN) + { + return false; + } + if ((category<0) || (category>=(int)Pilot::CATEGORY_COUNT)) + { + category=Pilot::Unfiled; + } + + PilotMemo *aMemo = new PilotMemo(); + aMemo->setCategory(category); + aMemo->setText(s); + + d->fMemoList.append(aMemo); + writeMemo(aMemo); + updateWidget(); +#ifdef DEBUG + DEBUGKPILOT << fname << ": New memo @" << (void *)aMemo << endl; +#endif + showMemo(aMemo); + return true; +} + +void MemoWidget::slotAddMemo() +{ + FUNCTIONSETUP; + int currentCatID = findSelectedCategory(fCatList, + d->fMemoAppInfo->categoryInfo(), true); + addMemo(TQDateTime::tqcurrentDateTime().toString(), currentCatID); +} + +void MemoWidget::slotImportMemo() +{ + FUNCTIONSETUP; + if (!shown || !d->fMemoAppInfo ) return; + + int currentCatID = findSelectedCategory(fCatList, + d->fMemoAppInfo->categoryInfo(), true); + + TQString fileName = KFileDialog::getOpenFileName(); + + if (!fileName.isEmpty()) + { + TQFile importFile(fileName); + + if (importFile.open(IO_ReadOnly) == FALSE) + { + // show error! + return; + } + + if (importFile.size() > MemoWidget::MAX_MEMO_LEN) + { + // Perhaps read first 64k? + return; + } + + TQTextStream stream(&importFile); + TQString memoText = stream.read(); + addMemo(memoText, currentCatID); + } +} + +void MemoWidget::slotExportMemo() +{ + FUNCTIONSETUP; + if (!shown) return; + + int index = fListBox->numRows(); + if (index == 0) + return; + + TQString data; + + const TQString filter = CSL1("*|Plain text output\n*.xml|XML output"); + TQString fileName; + + KFileDialog kfile( TQString::null , filter, fExportButton , "memoSave" , true ); + kfile.setOperationMode( KFileDialog::Saving ); + + if ( kfile.exec() == TQDialog::Accepted ) { + fileName = kfile.selectedFile(); + } + + if (fileName.isEmpty()) + return; + + TQPtrList<PilotListItem> menu_items; + + for (int x = 0; x < index; x++){ + if (fListBox->item(x)->isSelected()){ + menu_items.append((PilotListItem *) fListBox->item(x)); + } + } + + if (kfile.currentFilter() == CSL1("*.xml") ) + { + MemoWidget::saveAsXML( fileName , menu_items ); + } + else + { + MemoWidget::saveAsText( fileName , menu_items ); + } + + + return; +} + +bool MemoWidget::saveAsText(const TQString &fileName,const TQPtrList<PilotListItem> &memo_list) +{ + TQFile f( fileName ); + TQTextStream stream(&f); + + if ( TQFile::exists( fileName ) ) + { + if( !f.open(IO_ReadWrite | IO_Append) ) + { + return false; + } + } + else + { + if( !f.open(IO_WriteOnly) ) + { + return false; + } + } + + TQPtrListIterator<PilotListItem> it(memo_list); + for ( ; it.current(); ++it ) + { + PilotListItem *p = it.current(); + PilotMemo *theMemo = (PilotMemo *) p->rec(); + stream << theMemo->text() << endl; + } + + + return true; +} + +bool MemoWidget::saveAsXML(const TQString &fileName,const TQPtrList<PilotListItem> &memo_list) +{ + TQDomDocument doc( CSL1("kpilotmemos") ); + TQFile f( fileName ); + TQTextStream stream( &f ); + TQDomElement memos; + int append = 0; + + + if ( f.exists() ) + { + if ( !f.open(IO_ReadOnly ) ) return false; + + if ( doc.setContent( &f ) ) + { + // + // + //Only if QDom can read the .xml file and set the doc object to be populated with it's contents + memos = doc.documentElement(); + if ( memos.tagName()!= CSL1("memos") ) + { + return false; + } + // + // + //This is an XML Document but it isn't a valid KPilot-Memo xml document + else + { + append = 1; + } + // + // + //This is a valid KPilot memo, and we will append the current memo to the xml + } + else + { + // + // + //We *couldn't* understand the xml. Return false! + return false; + } + } + else + { + if ( !f.open(IO_ReadWrite ) ) return false; + // + // + //If there's no such file, we are not appending, just opening the file to read/write. + } + + f.close(); + // These are temporary, and should be retrieved from the pilot stuff + TQString mpilotid; + mpilotid = "1"; + // End of temp variables + + if (append == 1) + { + memos = doc.documentElement(); + } + else + { + memos = doc.createElement( CSL1("memos") ); + doc.appendChild ( memos ); + } + + TQPtrListIterator<PilotListItem> it(memo_list); + for ( ; it.current(); ++it ) + { + PilotListItem *p = it.current(); + PilotMemo *theMemo = (PilotMemo *) p->rec(); + + + TQDomElement memo = doc.createElement( CSL1("memo") ); + memo.setAttribute ( CSL1("pilotid") , mpilotid ); + memos.appendChild ( memo ); + + //TQDomElement category = doc.createElement( "category" ); + //head.appendChild ( category ); + // + //TQDomText categorytext = doc.createTextNode( memo->category() ); + //category.appendChild ( categorytext ); + //FIXME + + TQDomElement title = doc.createElement(CSL1("title" )); + memo.appendChild ( title ); + + TQDomText titletext = doc.createTextNode( theMemo->shortTitle() ); + title.appendChild ( titletext ); + + TQDomText body = doc.createTextNode( theMemo->text() ); + memo.appendChild ( body ); + } + if ( !f.open(IO_WriteOnly ) ) return false; + stream << doc.toString(); + return true; +} + |