summaryrefslogtreecommitdiffstats
path: root/kpilot/addressWidget.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kpilot/addressWidget.cpp')
-rw-r--r--kpilot/addressWidget.cpp733
1 files changed, 733 insertions, 0 deletions
diff --git a/kpilot/addressWidget.cpp b/kpilot/addressWidget.cpp
new file mode 100644
index 0000000..f8bd65d
--- /dev/null
+++ b/kpilot/addressWidget.cpp
@@ -0,0 +1,733 @@
+/* KPilot
+**
+** Copyright (C) 1998-2001 by Dan Pilone
+** Copyright (C) 2003 Reinhold Kainhofer <reinhold@kainhofer.com>
+** Copyright (C) 2004 by Adriaan de Groot
+**
+** This file defines the addressWidget, that part of KPilot that
+** displays address records from the Pilot.
+*/
+
+/*
+** 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
+*/
+
+
+#ifndef _KPILOT_OPTIONS_H
+#include "options.h"
+#endif
+
+#include <iostream>
+#include <cstring>
+#include <cstdlib>
+
+#include <tqptrlist.h>
+#include <tqlistbox.h>
+#include <tqfile.h>
+#include <tqpushbutton.h>
+#include <tqtextstream.h>
+#include <tqlayout.h>
+#include <tqlabel.h>
+#include <tqmultilineedit.h>
+#include <tqcombobox.h>
+#include <tqwhatsthis.h>
+#include <tqtextview.h>
+#include <tqtextcodec.h>
+#include <tqregexp.h>
+
+#include <tdeapplication.h>
+#include <tdemessagebox.h>
+#include <kdebug.h>
+#include <tdefiledialog.h>
+
+#include "kpilotConfig.h"
+#include "listItems.h"
+#include "addressEditor.h"
+#include "pilotLocalDatabase.h"
+
+#include "addressWidget.moc"
+
+
+AddressWidget::AddressWidget(TQWidget * parent,
+ const TQString & path) :
+ PilotComponent(parent, "component_address", path),
+ fAddrInfo(0L),
+ fAddressAppInfo(0L),
+ fPendingAddresses(0)
+{
+ FUNCTIONSETUP;
+
+ setupWidget();
+ fAddressList.setAutoDelete(true);
+}
+
+AddressWidget::~AddressWidget()
+{
+ FUNCTIONSETUP;
+}
+
+int AddressWidget::getAllAddresses(PilotDatabase * addressDB)
+{
+ FUNCTIONSETUP;
+
+ int currentRecord = 0;
+ PilotRecord *pilotRec;
+ PilotAddress *address;
+
+
+#ifdef DEBUG
+ DEBUGKPILOT << fname << ": Reading AddressDB..." << endl;
+#endif
+
+ while ((pilotRec = addressDB->readRecordByIndex(currentRecord)) != 0L)
+ {
+ if (!(pilotRec->isDeleted()) &&
+ (!(pilotRec->isSecret()) || KPilotSettings::showSecrets()))
+ {
+ address = new PilotAddress(pilotRec);
+ if (address == 0L)
+ {
+ WARNINGKPILOT << "Couldn't allocate record "
+ << currentRecord++
+ << endl;
+ break;
+ }
+ fAddressList.append(address);
+ }
+ delete pilotRec;
+
+ currentRecord++;
+ }
+
+#ifdef DEBUG
+ DEBUGKPILOT << fname
+ << ": Total " << currentRecord << " records" << endl;
+#endif
+
+ return currentRecord;
+}
+
+void AddressWidget::showComponent()
+{
+ FUNCTIONSETUP;
+ if ( fPendingAddresses>0 ) return;
+
+#ifdef DEBUG
+ DEBUGKPILOT << fname
+ << ": Reading from directory " << dbPath() << endl;
+#endif
+
+ PilotDatabase *addressDB =
+ new PilotLocalDatabase(dbPath(), CSL1("AddressDB"));
+
+ fAddressList.clear();
+
+ if (addressDB->isOpen())
+ {
+ KPILOT_DELETE(fAddressAppInfo);
+ fAddressAppInfo = new PilotAddressInfo(addressDB);
+ populateCategories(fCatList, fAddressAppInfo->categoryInfo());
+ getAllAddresses(addressDB);
+
+ }
+ else
+ {
+ populateCategories(fCatList, 0L);
+ WARNINGKPILOT << "Could not open local AddressDB" << endl;
+ }
+
+ KPILOT_DELETE( addressDB );
+
+ updateWidget();
+}
+
+void AddressWidget::hideComponent()
+{
+ FUNCTIONSETUP;
+ if (fPendingAddresses==0 )
+ {
+ fAddressList.clear();
+ fListBox->clear();
+
+ updateWidget();
+ }
+}
+
+/* virtual */ bool AddressWidget::preHotSync(TQString &s)
+{
+ FUNCTIONSETUP;
+
+ if ( fPendingAddresses )
+ {
+#ifdef DEBUG
+ DEBUGKPILOT << fname
+ << ": fPendingAddress="
+ << fPendingAddresses
+ << endl;
+#endif
+
+#if TDE_VERSION<220
+ s = i18n("There are still %1 address editing windows open.")
+ .arg(TQString::number(fPendingAddresses));
+#else
+ s = i18n("There is still an address editing window open.",
+ "There are still %n address editing windows open.",
+ fPendingAddresses);
+#endif
+ return false;
+ }
+
+ return true;
+}
+
+void AddressWidget::postHotSync()
+{
+ FUNCTIONSETUP;
+
+ if ( shown )
+ {
+ fAddressList.clear();
+ showComponent();
+ }
+}
+
+
+void AddressWidget::setupWidget()
+{
+ FUNCTIONSETUP;
+
+ TQLabel *label;
+ TQGridLayout *grid = new TQGridLayout(this, 6, 4, SPACING);
+
+ fCatList = new TQComboBox(this);
+ grid->addWidget(fCatList, 0, 1);
+ connect(fCatList, TQT_SIGNAL(activated(int)),
+ this, TQT_SLOT(slotSetCategory(int)));
+ TQWhatsThis::add(fCatList,
+ i18n("<qt>Select the category of addresses to display here.</qt>"));
+
+ 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(slotShowAddress(int)));
+ connect(fListBox, TQT_SIGNAL(selected(int)),
+ this, TQT_SLOT(slotEditRecord()));
+ TQWhatsThis::add(fListBox,
+ i18n("<qt>This list displays all the addresses "
+ "in the selected category. Click on "
+ "one to display it to the right.</qt>"));
+
+ label = new TQLabel(i18n("Address info:"), this);
+ grid->addWidget(label, 0, 2);
+
+ // address info text view
+ fAddrInfo = new TQTextView(this);
+ grid->addMultiCellWidget(fAddrInfo, 1, 4, 2, 2);
+
+ TQPushButton *button;
+ TQString wt;
+
+ fEditButton = new TQPushButton(i18n("Edit Record..."), this);
+ grid->addWidget(fEditButton, 2, 0);
+ connect(fEditButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotEditRecord()));
+ wt = KPilotSettings::internalEditors() ?
+ i18n("<qt>You can edit an address when it is selected.</qt>") :
+ i18n("<qt><i>Editing is disabled by the 'internal editors' setting.</i></qt>");
+ TQWhatsThis::add(fEditButton,wt);
+
+ button = new TQPushButton(i18n("New Record..."), this);
+ grid->addWidget(button, 2, 1);
+ connect(button, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotCreateNewRecord()));
+ wt = KPilotSettings::internalEditors() ?
+ i18n("<qt>Add a new address to the address book.</qt>") :
+ i18n("<qt><i>Adding is disabled by the 'internal editors' setting.</i></qt>") ;
+ TQWhatsThis::add(button, wt);
+ button->setEnabled(KPilotSettings::internalEditors());
+
+
+ fDeleteButton = new TQPushButton(i18n("Delete Record"), this);
+ grid->addWidget(fDeleteButton, 3, 0);
+ connect(fDeleteButton, TQT_SIGNAL(clicked()),
+ this, TQT_SLOT(slotDeleteRecord()));
+ wt = KPilotSettings::internalEditors() ?
+ i18n("<qt>Delete the selected address from the address book.</qt>") :
+ i18n("<qt><i>Deleting is disabled by the 'internal editors' setting.</i></qt>") ;
+
+ button = new TQPushButton(i18n("Export addresses to file","Export..."), this);
+ grid->addWidget(button, 3,1);
+ connect(button, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotExport()));
+ TQWhatsThis::add(button,
+ i18n("<qt>Export all addresses in the selected category to CSV format.</qt>") );
+
+ TQWhatsThis::add(fDeleteButton,wt);
+}
+
+void AddressWidget::updateWidget()
+{
+ FUNCTIONSETUP;
+
+ if( !fAddressAppInfo )
+ return;
+ int addressDisplayMode = KPilotSettings::addressDisplayMode();
+
+ int listIndex = 0;
+
+#ifdef DEBUG
+ DEBUGKPILOT << fname
+ << ": Display Mode=" << addressDisplayMode << endl;
+#endif
+
+ int currentCatID = findSelectedCategory(fCatList,
+ fAddressAppInfo->categoryInfo());
+
+ fListBox->clear();
+ fAddressList.first();
+
+#ifdef DEBUG
+ DEBUGKPILOT << fname << ": Adding records..." << endl;
+#endif
+
+ while (fAddressList.current())
+ {
+ if ((currentCatID == -1) ||
+ (fAddressList.current()->category() == currentCatID))
+ {
+ TQString title = createTitle(fAddressList.current(),
+ addressDisplayMode);
+
+ if (!title.isEmpty())
+ {
+ title.remove(TQRegExp(CSL1("\n.*")));
+ PilotListItem *p = new PilotListItem(title,
+ listIndex,
+ fAddressList.current());
+
+ fListBox->insertItem(p);
+ }
+ }
+ listIndex++;
+ fAddressList.next();
+ }
+
+ fListBox->sort();
+#ifdef DEBUG
+ DEBUGKPILOT << fname << ": " << listIndex << " records" << endl;
+#endif
+
+ slotUpdateButtons();
+}
+
+
+
+TQString AddressWidget::createTitle(PilotAddress * address, int displayMode)
+{
+ // FUNCTIONSETUP;
+
+ TQString title;
+
+ switch (displayMode)
+ {
+ case 1:
+ if (!address->getField(entryCompany).isEmpty())
+ {
+ title.append(address->getField(entryCompany));
+ }
+ if (!address->getField(entryLastname).isEmpty())
+ {
+ if (!title.isEmpty())
+ {
+ title.append( CSL1(", "));
+ }
+
+ title.append(address->getField(entryLastname));
+ }
+ break;
+ case 0:
+ default:
+ if (!address->getField(entryLastname).isEmpty())
+ {
+ title.append(address->getField(entryLastname));
+ }
+
+ if (!address->getField(entryFirstname).isEmpty())
+ {
+ if (!title.isEmpty())
+ {
+ title.append( CSL1(", "));
+ }
+ title.append(address->getField(entryFirstname));
+ }
+ break;
+ }
+
+ if (title.isEmpty()) // One last try
+ {
+ if (!fAddressList.current()->getField(entryCompany).isEmpty())
+ {
+ title.append(fAddressList.current()->
+ getField(entryCompany));
+ }
+ if (title.isEmpty())
+ {
+ title = i18n("[unknown]");
+ }
+ }
+
+ return title;
+}
+
+
+/* slot */ void AddressWidget::slotUpdateButtons()
+{
+ FUNCTIONSETUP;
+
+ bool enabled = (fListBox->currentItem() != -1);
+
+ enabled &= KPilotSettings::internalEditors();
+ fEditButton->setEnabled(enabled);
+ fDeleteButton->setEnabled(enabled);
+}
+
+void AddressWidget::slotSetCategory(int)
+{
+ FUNCTIONSETUP;
+
+ updateWidget();
+}
+
+void AddressWidget::slotEditRecord()
+{
+ FUNCTIONSETUP;
+ if ( !shown ) return;
+
+ int item = fListBox->currentItem();
+
+ if (item == -1)
+ return;
+
+ PilotListItem *p = (PilotListItem *) fListBox->item(item);
+ PilotAddress *selectedRecord = (PilotAddress *) p->rec();
+
+ if (selectedRecord->id() == 0)
+ {
+ KMessageBox::error(0L,
+ i18n("Cannot edit new records until "
+ "HotSynced with Pilot."),
+ i18n("HotSync Required"));
+ return;
+ }
+
+ AddressEditor *editor = new AddressEditor(selectedRecord,
+ fAddressAppInfo, this);
+
+ connect(editor, TQT_SIGNAL(recordChangeComplete(PilotAddress *)),
+ this, TQT_SLOT(slotUpdateRecord(PilotAddress *)));
+ connect(editor, TQT_SIGNAL(cancelClicked()),
+ this, TQT_SLOT(slotEditCancelled()));
+ editor->show();
+
+ fPendingAddresses++;
+}
+
+void AddressWidget::slotCreateNewRecord()
+{
+ FUNCTIONSETUP;
+ if ( !shown ) return;
+
+ // Response to bug 18072: Don't even try to
+ // add records to an empty or unopened database,
+ // since we don't have the DBInfo stuff to deal with it.
+ //
+ //
+ PilotDatabase *myDB = new PilotLocalDatabase(dbPath(), CSL1("AddressDB"));
+
+ if (!myDB || !myDB->isOpen())
+ {
+#ifdef DEBUG
+ DEBUGKPILOT << fname
+ << ": Tried to open "
+ << dbPath()
+ << "/AddressDB"
+ << " and got pointer @"
+ << (long) myDB
+ << " with status "
+ << ( myDB ? myDB->isOpen() : false )
+ << endl;
+#endif
+
+ KMessageBox::sorry(this,
+ i18n("You cannot add addresses to the address book "
+ "until you have done a HotSync at least once "
+ "to retrieve the database layout from your Pilot."),
+ i18n("Cannot Add New Address"));
+
+ if (myDB)
+ KPILOT_DELETE( myDB );
+
+ return;
+ }
+
+ AddressEditor *editor = new AddressEditor(0L,
+ fAddressAppInfo, this);
+
+ connect(editor, TQT_SIGNAL(recordChangeComplete(PilotAddress *)),
+ this, TQT_SLOT(slotAddRecord(PilotAddress *)));
+ connect(editor, TQT_SIGNAL(cancelClicked()),
+ this, TQT_SLOT(slotEditCancelled()));
+ editor->show();
+
+ fPendingAddresses++;
+}
+
+void AddressWidget::slotAddRecord(PilotAddress * address)
+{
+ FUNCTIONSETUP;
+ if ( !shown && fPendingAddresses==0 ) return;
+
+ int currentCatID = findSelectedCategory(fCatList,
+ fAddressAppInfo->categoryInfo(), true);
+
+
+ address->PilotRecordBase::setCategory(currentCatID);
+ fAddressList.append(address);
+ writeAddress(address);
+ // TODO: Just add the new record to the lists
+ updateWidget();
+
+ // k holds the item number of the address just added.
+ //
+ //
+ int k = fListBox->count() - 1;
+
+ fListBox->setCurrentItem(k); // Show the newest one
+ fListBox->setBottomItem(k);
+
+ fPendingAddresses--;
+ if ( !shown && fPendingAddresses==0 ) hideComponent();
+}
+
+void AddressWidget::slotUpdateRecord(PilotAddress * address)
+{
+ FUNCTIONSETUP;
+ if ( !shown && fPendingAddresses==0 ) return;
+
+ writeAddress(address);
+ int currentRecord = fListBox->currentItem();
+
+ // TODO: Just change the record
+ updateWidget();
+ fListBox->setCurrentItem(currentRecord);
+
+ emit(recordChanged(address));
+
+ fPendingAddresses--;
+ if ( !shown && fPendingAddresses==0 ) hideComponent();
+}
+
+void AddressWidget::slotEditCancelled()
+{
+ FUNCTIONSETUP;
+
+ fPendingAddresses--;
+ if ( !shown && fPendingAddresses==0 ) hideComponent();
+}
+
+void AddressWidget::slotDeleteRecord()
+{
+ FUNCTIONSETUP;
+ if ( !shown ) return;
+
+ int item = fListBox->currentItem();
+
+ if (item == -1)
+ return;
+
+ PilotListItem *p = (PilotListItem *) fListBox->item(item);
+ PilotAddress *selectedRecord = (PilotAddress *) p->rec();
+
+ if (selectedRecord->id() == 0)
+ {
+ KMessageBox::error(this,
+ i18n("New records cannot be deleted until "
+ "HotSynced with pilot."),
+ i18n("HotSync Required"));
+ return;
+ }
+
+ if (KMessageBox::questionYesNo(this,
+ i18n("Delete currently selected record?"),
+ i18n("Delete Record?"), KStdGuiItem::del(), KStdGuiItem::cancel()) == KMessageBox::No)
+ return;
+
+ selectedRecord->setDeleted( true );
+ writeAddress(selectedRecord);
+ emit(recordChanged(selectedRecord));
+ showComponent();
+}
+
+
+
+void AddressWidget::slotShowAddress(int which)
+{
+ FUNCTIONSETUP;
+ if (!shown) return;
+
+ PilotListItem *p = (PilotListItem *) fListBox->item(which);
+ PilotAddress *addr = (PilotAddress *) p->rec();
+
+#ifdef DEBUG
+ DEBUGKPILOT << fname
+ << ": Showing "
+ << addr->getField(entryLastname)
+ << " "
+ << addr->getField(entryFirstname)
+ << endl;
+#endif
+
+ TQString text(CSL1("<qt>"));
+ text += addr->getTextRepresentation(fAddressAppInfo,TQt::RichText);
+ text += CSL1("</qt>\n");
+ fAddrInfo->setText(text);
+
+ slotUpdateButtons();
+}
+
+
+
+void AddressWidget::writeAddress(PilotAddress * which,
+ PilotDatabase * addressDB)
+{
+ FUNCTIONSETUP;
+
+ // Open a database (myDB) only if needed,
+ // i.e. only if the passed-in addressDB
+ // isn't valid.
+ //
+ //
+ PilotDatabase *myDB = addressDB;
+ bool usemyDB = false;
+
+ if (myDB == 0L || !myDB->isOpen())
+ {
+ myDB = new PilotLocalDatabase(dbPath(), CSL1("AddressDB"));
+ usemyDB = true;
+ }
+
+ // Still no valid address database...
+ //
+ //
+ if (!myDB->isOpen())
+ {
+#ifdef DEBUG
+ DEBUGKPILOT << fname << ": Address database is not open" <<
+ endl;
+#endif
+ return;
+ }
+
+
+ // Do the actual work.
+ PilotRecord *pilotRec = which->pack();
+
+ myDB->writeRecord(pilotRec);
+ markDBDirty(CSL1("AddressDB"));
+ delete pilotRec;
+
+ // Clean up in the case that we allocated our own DB.
+ //
+ //
+ if (usemyDB)
+ {
+ KPILOT_DELETE( myDB );
+ }
+}
+
+#define plu_quiet 1
+#include "pilot-addresses.c"
+
+void AddressWidget::slotExport()
+{
+ FUNCTIONSETUP;
+ if( !fAddressAppInfo ) return;
+ int currentCatID = findSelectedCategory(fCatList,
+ fAddressAppInfo->categoryInfo());
+
+ TQString prompt = (currentCatID==-1) ?
+ i18n("Export All Addresses") :
+ i18n("Export Address Category %1").arg(fAddressAppInfo->categoryName(currentCatID)) ;
+
+
+ TQString saveFile = KFileDialog::getSaveFileName(
+ TQString(),
+ CSL1("*.csv|Comma Separated Values"),
+ this,
+ prompt
+ );
+ if (saveFile.isEmpty())
+ {
+#ifdef DEBUG
+ DEBUGKPILOT << fname << ": No save file selected." << endl;
+#endif
+ return;
+ }
+ if (TQFile::exists(saveFile) &&
+ KMessageBox::warningContinueCancel(this,
+ i18n("The file <i>%1</i> exists. Overwrite?").arg(saveFile),
+ i18n("Overwrite File?"),
+ i18n("Overwrite"))!=KMessageBox::Continue)
+ {
+#ifdef DEBUG
+ DEBUGKPILOT << fname << ": Overwrite file canceled." << endl;
+#endif
+ return;
+ }
+
+ FILE *f = fopen(TQFile::encodeName(saveFile),"w");
+ if (!f)
+ {
+ KMessageBox::sorry(this,
+ i18n("The file <i>%1</i> could not be opened for writing.").arg(saveFile));
+ return;
+ }
+ fAddressList.first();
+
+#ifdef DEBUG
+ DEBUGKPILOT << fname << ": Adding records..." << endl;
+#endif
+
+ while (fAddressList.current())
+ {
+ const PilotAddress *a = fAddressList.current();
+ if ((currentCatID == -1) ||
+ (a->category() == currentCatID))
+ {
+ write_record_CSV(f, fAddressAppInfo->info(), a->address(),
+ a->attributes(), a->category(), 0);
+ }
+ fAddressList.next();
+ }
+
+ fclose(f);
+}
+