author | kergoth <kergoth> | 2002-01-25 22:14:26 (UTC) |
---|---|---|
committer | kergoth <kergoth> | 2002-01-25 22:14:26 (UTC) |
commit | 15318cad33835e4e2dc620d033e43cd930676cdd (patch) (side-by-side diff) | |
tree | c2fa0399a2c47fda8e2cd0092c73a809d17f68eb /core/pim/addressbook | |
download | opie-15318cad33835e4e2dc620d033e43cd930676cdd.zip opie-15318cad33835e4e2dc620d033e43cd930676cdd.tar.gz opie-15318cad33835e4e2dc620d033e43cd930676cdd.tar.bz2 |
Initial revision
-rw-r--r-- | core/pim/addressbook/.cvsignore | 16 | ||||
-rw-r--r-- | core/pim/addressbook/Makefile.in | 244 | ||||
-rw-r--r-- | core/pim/addressbook/abeditor.cpp | 619 | ||||
-rw-r--r-- | core/pim/addressbook/abeditor.h | 79 | ||||
-rw-r--r-- | core/pim/addressbook/ablabel.cpp | 53 | ||||
-rw-r--r-- | core/pim/addressbook/ablabel.h | 50 | ||||
-rw-r--r-- | core/pim/addressbook/abtable.cpp | 1091 | ||||
-rw-r--r-- | core/pim/addressbook/abtable.h | 140 | ||||
-rw-r--r-- | core/pim/addressbook/addressbook.cpp | 829 | ||||
-rw-r--r-- | core/pim/addressbook/addressbook.cw | 26 | ||||
-rw-r--r-- | core/pim/addressbook/addressbook.h | 99 | ||||
-rw-r--r-- | core/pim/addressbook/addressbook.pro | 22 | ||||
-rw-r--r-- | core/pim/addressbook/addresspicker.cpp | 52 | ||||
-rw-r--r-- | core/pim/addressbook/addresspicker.h | 39 | ||||
-rw-r--r-- | core/pim/addressbook/addresssettings.cpp | 136 | ||||
-rw-r--r-- | core/pim/addressbook/addresssettings.h | 47 | ||||
-rw-r--r-- | core/pim/addressbook/addresssettingsbase.ui | 170 | ||||
-rw-r--r-- | core/pim/addressbook/main.cpp | 41 | ||||
-rw-r--r-- | core/pim/addressbook/qpe-addressbook.control | 9 |
19 files changed, 3762 insertions, 0 deletions
diff --git a/core/pim/addressbook/.cvsignore b/core/pim/addressbook/.cvsignore new file mode 100644 index 0000000..28d87f2 --- a/dev/null +++ b/core/pim/addressbook/.cvsignore @@ -0,0 +1,16 @@ +moc_* +Makefile +abeditorbase.h +abaddress.h +abcompanybase.h +abnamebase.h +abeditorbase.cpp +abaddress.cpp +abcompanybase.cpp +abnamebase.cpp +abeditorpage2base.ui +abeditorpage2base.h +abeditorpage2base.cpp +addresssettingsbase.h +addresssettingsbase.cpp + diff --git a/core/pim/addressbook/Makefile.in b/core/pim/addressbook/Makefile.in new file mode 100644 index 0000000..93c73c3 --- a/dev/null +++ b/core/pim/addressbook/Makefile.in @@ -0,0 +1,244 @@ +############################################################################# + +####### Compiler, tools and options + +CXX = $(SYSCONF_CXX) $(QT_CXX_MT) +CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS) +CC = $(SYSCONF_CC) $(QT_C_MT) +CFLAGS = $(SYSCONF_CFLAGS) +INCPATH = -I$(QPEDIR)/include +LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT) +LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP) +MOC = $(SYSCONF_MOC) +UIC = $(SYSCONF_UIC) + +####### Target + +DESTDIR = $(QPEDIR)/bin/ +VER_MAJ = 1 +VER_MIN = 0 +VER_PATCH = 0 +TARGET = addressbook +TARGET1 = lib$(TARGET).so.$(VER_MAJ) + +####### Files + +HEADERS = addressbook.h \ + abeditor.h \ + ablabel.h \ + abtable.h \ + addresssettings.h +SOURCES = main.cpp \ + addressbook.cpp \ + abeditor.cpp \ + ablabel.cpp \ + abtable.cpp \ + addresssettings.cpp +OBJECTS = main.o \ + addressbook.o \ + abeditor.o \ + ablabel.o \ + abtable.o \ + addresssettings.o \ + addresssettingsbase.o +INTERFACES = addresssettingsbase.ui +UICDECLS = addresssettingsbase.h +UICIMPLS = addresssettingsbase.cpp +SRCMOC = moc_addressbook.cpp \ + moc_abeditor.cpp \ + moc_ablabel.cpp \ + moc_abtable.cpp \ + moc_addresssettings.cpp \ + moc_addresssettingsbase.cpp +OBJMOC = moc_addressbook.o \ + moc_abeditor.o \ + moc_ablabel.o \ + moc_abtable.o \ + moc_addresssettings.o \ + moc_addresssettingsbase.o + + +####### Implicit rules + +.SUFFIXES: .cpp .cxx .cc .C .c + +.cpp.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.cxx.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.cc.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.C.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.c.o: + $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $< + +####### Build rules + + +all: $(DESTDIR)$(TARGET) + +$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS) + $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS) + +moc: $(SRCMOC) + +tmake: + tmake p4addressbook.pro + +clean: + -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS) + -rm -f *~ core + -rm -f allmoc.cpp + +####### Extension Modules + +listpromodules: + @echo + +listallmodules: + @echo + +listaddonpromodules: + @echo + +listaddonentmodules: + @echo + + +REQUIRES= + +####### Sub-libraries + + +###### Combined headers + + + +####### Compile + +main.o: main.cpp \ + addressbook.h \ + $(QPEDIR)/include/qpe/qpeapplication.h \ + $(QPEDIR)/include/qpe/qcopenvelope_qws.h + +addressbook.o: addressbook.cpp \ + abeditor.h \ + $(QPEDIR)/include/qpe/contact.h \ + $(QPEDIR)/include/qpe/palmtoprecord.h \ + $(QPEDIR)/include/qpe/recordfields.h \ + ablabel.h \ + abtable.h \ + $(QPEDIR)/include/qpe/categories.h \ + addresssettings.h \ + addresssettingsbase.h \ + addressbook.h \ + $(QPEDIR)/include/qpe/qpeapplication.h \ + $(QPEDIR)/include/qpe/config.h \ + $(QPEDIR)/include/qpe/finddialog.h \ + $(QPEDIR)/include/qpe/global.h \ + $(QPEDIR)/include/qpe/resource.h \ + $(QPEDIR)/include/qpe/ir.h \ + $(QPEDIR)/include/qpe/qpemessagebox.h \ + $(QPEDIR)/include/qpe/qcopenvelope_qws.h \ + $(QPEDIR)/include/qpe/qpemenubar.h \ + $(QPEDIR)/include/qpe/qpetoolbar.h + +abeditor.o: abeditor.cpp \ + abeditor.h \ + $(QPEDIR)/include/qpe/contact.h \ + $(QPEDIR)/include/qpe/palmtoprecord.h \ + $(QPEDIR)/include/qpe/recordfields.h \ + addresspicker.h \ + $(QPEDIR)/include/qpe/categoryselect.h \ + $(QPEDIR)/include/qpe/qpeapplication.h \ + $(QPEDIR)/include/qpe/qpedialog.h + +ablabel.o: ablabel.cpp \ + ablabel.h \ + $(QPEDIR)/include/qpe/contact.h \ + $(QPEDIR)/include/qpe/palmtoprecord.h \ + $(QPEDIR)/include/qpe/recordfields.h \ + $(QPEDIR)/include/qpe/stringutil.h + +abtable.o: abtable.cpp \ + $(QPEDIR)/include/qpe/categoryselect.h \ + $(QPEDIR)/include/qpe/config.h \ + $(QPEDIR)/include/qpe/stringutil.h \ + $(QPEDIR)/include/qpe/qcopenvelope_qws.h \ + abtable.h \ + $(QPEDIR)/include/qpe/categories.h \ + $(QPEDIR)/include/qpe/contact.h \ + $(QPEDIR)/include/qpe/palmtoprecord.h \ + $(QPEDIR)/include/qpe/recordfields.h + +addresssettings.o: addresssettings.cpp \ + addresssettings.h \ + addresssettingsbase.h \ + $(QPEDIR)/include/qpe/config.h \ + $(QPEDIR)/include/qpe/contact.h \ + $(QPEDIR)/include/qpe/palmtoprecord.h \ + $(QPEDIR)/include/qpe/recordfields.h + +addresssettingsbase.h: addresssettingsbase.ui + $(UIC) addresssettingsbase.ui -o $(INTERFACE_DECL_PATH)/addresssettingsbase.h + +addresssettingsbase.cpp: addresssettingsbase.ui + $(UIC) addresssettingsbase.ui -i addresssettingsbase.h -o addresssettingsbase.cpp + +addresssettingsbase.o: addresssettingsbase.cpp \ + addresssettingsbase.h \ + addresssettingsbase.ui + +moc_addressbook.o: moc_addressbook.cpp \ + addressbook.h + +moc_abeditor.o: moc_abeditor.cpp \ + abeditor.h \ + $(QPEDIR)/include/qpe/contact.h \ + $(QPEDIR)/include/qpe/palmtoprecord.h \ + $(QPEDIR)/include/qpe/recordfields.h + +moc_ablabel.o: moc_ablabel.cpp \ + ablabel.h \ + $(QPEDIR)/include/qpe/contact.h \ + $(QPEDIR)/include/qpe/palmtoprecord.h \ + $(QPEDIR)/include/qpe/recordfields.h + +moc_abtable.o: moc_abtable.cpp \ + abtable.h \ + $(QPEDIR)/include/qpe/categories.h \ + $(QPEDIR)/include/qpe/contact.h \ + $(QPEDIR)/include/qpe/palmtoprecord.h \ + $(QPEDIR)/include/qpe/recordfields.h + +moc_addresssettings.o: moc_addresssettings.cpp \ + addresssettings.h \ + addresssettingsbase.h + +moc_addresssettingsbase.o: moc_addresssettingsbase.cpp \ + addresssettingsbase.h + +moc_addressbook.cpp: addressbook.h + $(MOC) addressbook.h -o moc_addressbook.cpp + +moc_abeditor.cpp: abeditor.h + $(MOC) abeditor.h -o moc_abeditor.cpp + +moc_ablabel.cpp: ablabel.h + $(MOC) ablabel.h -o moc_ablabel.cpp + +moc_abtable.cpp: abtable.h + $(MOC) abtable.h -o moc_abtable.cpp + +moc_addresssettings.cpp: addresssettings.h + $(MOC) addresssettings.h -o moc_addresssettings.cpp + +moc_addresssettingsbase.cpp: addresssettingsbase.h + $(MOC) addresssettingsbase.h -o moc_addresssettingsbase.cpp + + diff --git a/core/pim/addressbook/abeditor.cpp b/core/pim/addressbook/abeditor.cpp new file mode 100644 index 0000000..6354db9 --- a/dev/null +++ b/core/pim/addressbook/abeditor.cpp @@ -0,0 +1,619 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qt Palmtop Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#include "abeditor.h" +#include "addresspicker.h" + +#include <qpe/categoryselect.h> +#include <qpe/qpeapplication.h> +#include <qpe/qpedialog.h> + +#include <qcombobox.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qlineedit.h> +#include <qmultilineedit.h> +#include <qscrollview.h> +#include <qtoolbutton.h> +#include <qpushbutton.h> +#include <qmainwindow.h> + + +static inline bool containsAlphaNum( const QString &str ); +static inline bool constainsWhiteSpace( const QString &str ); + + +// helper functions, convert our comma delimited list to proper +// file format... +void parseEmailFrom( const QString &txt, QString &strDefaultEmail, + QString &strAll ); + +// helper convert from file format to comma delimited... +void parseEmailTo( const QString &strDefaultEmail, + const QString &strOtherEmail, QString &strBack ); + + + +AbEditor::AbEditor( const Contact &entry, const QValueList<int> *newOrdered, + QStringList *slNewOrdered, + QWidget *parent = 0, const char *name = 0, WFlags fl = 0 ) + : QDialog( parent, name, TRUE, fl ), + orderedValues( newOrdered ), + slOrdered( slNewOrdered ) +{ + init(); + initMap(); + setEntry( entry ); +} + +AbEditor::~AbEditor() +{ +} + +void AbEditor::init() +{ + middleEdit = 0; + QVBoxLayout *vb = new QVBoxLayout( this ); + svPage = new QScrollView( this ); + svPage->setHScrollBarMode( QScrollView::AlwaysOff ); + vb->addWidget( svPage ); + svPage->setResizePolicy( QScrollView::AutoOneFit ); + svPage->setFrameStyle( QFrame::NoFrame ); + + QWidget *container = new QWidget( svPage->viewport() ); + svPage->addChild( container ); + + QGridLayout *gl = new QGridLayout( container, 20, 2, 4, 2 ); + + QLabel *l = new QLabel( tr("First Name"), container ); + gl->addWidget( l, 0, 0 ); + firstEdit = new QLineEdit( container ); + gl->addWidget( firstEdit, 0, 1 ); + + l = new QLabel( tr("Last Name"), container ); + gl->addWidget( l, 1, 0 ); + lastEdit = new QLineEdit( container ); + gl->addWidget( lastEdit, 1, 1 ); + + l = new QLabel( tr("Categories"), container ); + gl->addWidget( l, 2, 0 ); + + cmbCat = new CategorySelect( container ); + gl->addWidget( cmbCat, 2, 1 ); + + int i; + bool foundGender, + foundNotes; + foundGender = foundNotes = false; + QStringList::ConstIterator it = slOrdered->begin(); + for ( i = 0; it != slOrdered->end(); i++, ++it ) { + if ( !foundGender && *it == tr("Gender") ) { + foundGender = true; + } else if ( !foundNotes && *it == tr("Notes") ) { + foundNotes = true; + } else { + l = new QLabel( *it, container ); + listName.append( l ); + gl->addWidget( l, i + 3, 0 ); + QLineEdit *e = new QLineEdit( container ); + listValue.append( e ); + gl->addWidget( e, i + 3, 1 ); + if ( *it == tr( "Middle Name" ) ) + middleEdit = e; + } + } + l = new QLabel( tr("Gender"), container ); + gl->addWidget( l, slOrdered->count() + 3, 0 ); + genderCombo = new QComboBox( container ); + genderCombo->insertItem( "", 0 ); + genderCombo->insertItem( tr( "Male" ), 1 ); + genderCombo->insertItem( tr( "Female" ), 2 ); + gl->addWidget( genderCombo, slOrdered->count() + 3, 1 ); + + dlgNote = new QDialog( this, "Note Dialog", TRUE ); + dlgNote->setCaption( tr("Enter Note") ); + QVBoxLayout *vbNote = new QVBoxLayout( dlgNote ); + // lblNote = new QLabel( dlgNote ); + // lblNote->setMinimumSize( lblNote->sizeHint() + QSize( 0, 4 ) ); + // vbNote->addWidget( lblNote ); + txtNote = new QMultiLineEdit( dlgNote ); + vbNote->addWidget( txtNote ); + + QHBoxLayout *hb = new QHBoxLayout( vb ); + hb->addStretch( 2 ); + QPushButton *pb = new QPushButton( tr("Notes..."), this ); + hb->addWidget( pb ); + connect( pb, SIGNAL(clicked()), this, SLOT(slotNote()) ); + + new QPEDialogListener(this); +} + +void AbEditor::initMap() +{ + /* + // since the fields and the XML fields exist, create a map + // between them... + Config cfg1( "AddressBook" ); + Config cfg2( "AddressBook" ); + QString strCfg1, + strCfg2; + int i; + + // This stuff better exist... + cfg1.setGroup( "AddressFields" ); + cfg2.setGroup( "XMLFields" ); + i = 0; + strCfg1 = cfg1.readEntry( "Field" + QString::number(i), QString::null ); + strCfg2 = cfg2.readEntry( "XMLField" + QString::number(i++), + QString::null ); + while ( !strCfg1.isNull() && !strCfg2.isNull() ) { + mapField.insert( strCfg1, strCfg2 ); + strCfg1 = cfg1.readEntry( "Field" + QString::number(i), + QString::null ); + strCfg2 = cfg2.readEntry( "XMLField" + QString::number(i++), + QString::null ); + } + */ +} + +void AbEditor::loadFields() +{ + QStringList::ConstIterator it; + QListIterator<QLabel> lit( listName ); + for ( it = slOrdered->begin(); *lit; ++lit, ++it ) { + (*lit)->setText( *it ); + } +} + +void AbEditor::setEntry( const Contact &entry ) +{ + ent = entry; + QListIterator<QLineEdit> it( listValue ); + firstEdit->setText( ent.firstName() ); + lastEdit->setText( ent.lastName() ); + cmbCat->setCategories( ent.categories(), "Contacts", tr("Contacts") ); + + // ### Fix... + QValueList<int>::ConstIterator itVl; + for ( itVl = orderedValues->begin(); *it && itVl != orderedValues->end(); + ++itVl, ++it ) { + switch( *itVl ) { + case Qtopia::Title: + (*it)->setText(ent.title()); + break; + case Qtopia::MiddleName: + (*it)->setText( ent.middleName() ); + break; + case Qtopia::Suffix: + (*it)->setText( ent.suffix() ); + break; + + // email + case Qtopia::DefaultEmail: + case Qtopia::Emails: + { + QString strDefEmail = ent.defaultEmail(); + QString strAllEmail = ent.emails(); + QString strFinal; + parseEmailTo( strDefEmail, strAllEmail, strFinal ); + (*it)->setText( strFinal ); + // make sure we see the "default" + (*it)->home( false ); + break; + } + + // home + case Qtopia::HomeStreet: + (*it)->setText(ent.homeStreet() ); + break; + case Qtopia::HomeCity: + (*it)->setText( ent.homeCity() ); + break; + case Qtopia::HomeState: + (*it)->setText( ent.homeState() ); + break; + case Qtopia::HomeZip: + (*it)->setText( ent.homeZip() ); + break; + case Qtopia::HomeCountry: + (*it)->setText( ent.homeCountry() ); + break; + case Qtopia::HomePhone: + (*it)->setText( ent.homePhone() ); + break; + case Qtopia::HomeFax: + (*it)->setText( ent.homeFax() ); + break; + case Qtopia::HomeMobile: + (*it)->setText( ent.homeMobile() ); + break; + case Qtopia::HomeWebPage: + (*it)->setText( ent.homeWebpage() ); + break; + + // business + case Qtopia::Company: + (*it)->setText( ent.company() ); + break; + case Qtopia::BusinessStreet: + (*it)->setText( ent.businessStreet() ); + break; + case Qtopia::BusinessCity: + (*it)->setText( ent.businessCity() ); + break; + case Qtopia::BusinessState: + (*it)->setText( ent.businessState() ); + break; + case Qtopia::BusinessZip: + (*it)->setText( ent.businessZip() ); + break; + case Qtopia::BusinessCountry: + (*it)->setText( ent.businessCountry() ); + break; + case Qtopia::BusinessWebPage: + (*it)->setText( ent.businessWebpage() ); + break; + case Qtopia::JobTitle: + (*it)->setText( ent.jobTitle() ); + break; + case Qtopia::Department: + (*it)->setText( ent.department() ); + break; + case Qtopia::Office: + (*it)->setText( ent.office() ); + break; + case Qtopia::BusinessPhone: + (*it)->setText( ent.businessPhone() ); + break; + case Qtopia::BusinessFax: + (*it)->setText( ent.businessFax() ); + break; + case Qtopia::BusinessMobile: + (*it)->setText( ent.businessMobile() ); + break; + case Qtopia::BusinessPager: + (*it)->setText( ent.businessPager() ); + break; + case Qtopia::Profession: + (*it)->setText( ent.profession() ); + break; + case Qtopia::Assistant: + (*it)->setText( ent.assistant() ); + break; + case Qtopia::Manager: + (*it)->setText( ent.manager() ); + break; + + // personal + case Qtopia::Spouse: + (*it)->setText( ent.spouse() ); + break; + case Qtopia::Children: + (*it)->setText( ent.children() ); + break; + case Qtopia::Birthday: + (*it)->setText( ent.birthday() ); + break; + case Qtopia::Anniversary: + (*it)->setText( ent.anniversary() ); + break; + case Qtopia::Nickname: + (*it)->setText( ent.nickname() ); + break; + + } + } + + QString gender = ent.gender(); + genderCombo->setCurrentItem( gender.toInt() ); + + txtNote->setText( ent.notes() ); +} + +void AbEditor::accept() +{ + if ( isEmpty() ) + reject(); + else { + saveEntry(); + QDialog::accept(); + } +} + +bool AbEditor::isEmpty() +{ + // analyze all the fields and make sure there is _something_ there + // that warrants saving... + QString t = firstEdit->text(); + if ( !t.isEmpty() && containsAlphaNum( t ) ) + return false; + + t = lastEdit->text(); + if ( !t.isEmpty() && containsAlphaNum( t ) ) + return false; + + QListIterator<QLineEdit> it( listValue ); + for ( ; it.current(); ++it ) { + t = it.current()->text(); + if ( !t.isEmpty() && containsAlphaNum( t ) ) + return false; + } + + t = txtNote->text(); + if ( !t.isEmpty() && containsAlphaNum( t ) ) + return false; + + return true; +} + +void AbEditor::saveEntry() +{ + QString strDefaultEmail, strOtherEmail; + + // determine if there has been a change in names + if ( ent.firstName() != firstEdit->text() || + ent.lastName() != lastEdit->text() + || (middleEdit && ent.middleName() != middleEdit->text()) ) { + // set the names + ent.setFirstName( firstEdit->text() ); + ent.setLastName( lastEdit->text() ); + if ( middleEdit ) + ent.setMiddleName( middleEdit->text() ); + ent.setFileAs(); + } + + ent.setCategories( cmbCat->currentCategories() ); + + QListIterator<QLineEdit> it( listValue ); + int i; + QValueList<int>::ConstIterator<int> vlIt; + for ( i = 0, vlIt = orderedValues->begin(); + it.current(); ++it, ++vlIt, i++ ) { + switch( *vlIt ) { + case Qtopia::Title: + ent.setTitle( it.current()->text() ); + break; + case Qtopia::MiddleName: + ent.setMiddleName( it.current()->text() ); + break; + case Qtopia::Suffix: + ent.setSuffix( it.current()->text() ); + break; +// case Qtopia::Category: +// { +// // QStringList slCat = QStringList::split( ";", value ); +// // QValueList<int> cat; +// // for ( QStringList::ConstIterator it = slCat.begin(); +// // it != slCat.end(); ++it ) +// // cat.append( (*it).toInt() ); +// // ent.setCategories( cat ); +// } +// break; + + // email + case Qtopia::DefaultEmail: + case Qtopia::Emails: + parseEmailFrom( it.current()->text(), strDefaultEmail, + strOtherEmail ); + ent.setDefaultEmail( strDefaultEmail ); + ent.setEmails( strOtherEmail ); + break; + + // home + case Qtopia::HomeStreet: + ent.setHomeStreet( it.current()->text() ); + break; + case Qtopia::HomeCity: + ent.setHomeCity( it.current()->text() ); + break; + case Qtopia::HomeState: + ent.setHomeState( it.current()->text() ); + break; + case Qtopia::HomeZip: + ent.setHomeZip( it.current()->text() ); + break; + case Qtopia::HomeCountry: + ent.setHomeCountry( it.current()->text() ); + break; + case Qtopia::HomePhone: + ent.setHomePhone( it.current()->text() ); + break; + case Qtopia::HomeFax: + ent.setHomeFax( it.current()->text() ); + break; + case Qtopia::HomeMobile: + ent.setHomeMobile( it.current()->text() ); + break; + case Qtopia::HomeWebPage: + ent.setHomeWebpage( it.current()->text() ); + break; + + // business + case Qtopia::Company: + ent.setCompany( it.current()->text() ); + break; + case Qtopia::BusinessStreet: + ent.setBusinessStreet( it.current()->text() ); + break; + case Qtopia::BusinessCity: + ent.setBusinessCity( it.current()->text() ); + break; + case Qtopia::BusinessState: + ent.setBusinessState( it.current()->text() ); + break; + case Qtopia::BusinessZip: + ent.setBusinessZip( it.current()->text() ); + break; + case Qtopia::BusinessCountry: + ent.setBusinessCountry( it.current()->text() ); + break; + case Qtopia::BusinessWebPage: + ent.setBusinessWebpage( it.current()->text() ); + break; + case Qtopia::JobTitle: + ent.setJobTitle( it.current()->text() ); + break; + case Qtopia::Department: + ent.setDepartment( it.current()->text() ); + break; + case Qtopia::Office: + ent.setOffice( it.current()->text() ); + break; + case Qtopia::BusinessPhone: + ent.setBusinessPhone( it.current()->text() ); + break; + case Qtopia::BusinessFax: + ent.setBusinessFax( it.current()->text() ); + break; + case Qtopia::BusinessMobile: + ent.setBusinessMobile( it.current()->text() ); + break; + case Qtopia::BusinessPager: + ent.setBusinessPager( it.current()->text() ); + break; + case Qtopia::Profession: + ent.setProfession( it.current()->text() ); + break; + case Qtopia::Assistant: + ent.setAssistant( it.current()->text() ); + break; + case Qtopia::Manager: + ent.setManager( it.current()->text() ); + break; + + // personal + case Qtopia::Spouse: + ent.setSpouse( it.current()->text() ); + break; + case Qtopia::Children: + ent.setChildren( it.current()->text() ); + break; + case Qtopia::Birthday: + ent.setBirthday( it.current()->text() ); + break; + case Qtopia::Anniversary: + ent.setAnniversary( it.current()->text() ); + break; + case Qtopia::Nickname: + ent.setNickname( it.current()->text() ); + break; + default: + break; + + } + } + + int gender = genderCombo->currentItem(); + ent.setGender( QString::number( gender ) ); + + QString str = txtNote->text(); + if ( !str.isNull() ) + ent.setNotes( str ); +} + +void AbEditor::slotNote() +{ + dlgNote->showMaximized(); + if ( !dlgNote->exec() ) { + // reset the note... + txtNote->setText( ent.notes() ); + } +} + +void AbEditor::setNameFocus() +{ + firstEdit->setFocus(); +} + +void parseEmailFrom( const QString &txt, QString &strDefaultEmail, + QString &strAll ) +{ + int where, + start; + if ( txt.isEmpty() ) + return; + // find the first + where = txt.find( ',' ); + if ( where < 0 ) { + strDefaultEmail = txt; + strAll = txt; + } else { + strDefaultEmail = txt.left( where ).stripWhiteSpace(); + strAll = strDefaultEmail; + while ( where > -1 ) { + strAll.append(" "); + start = where; + where = txt.find( ',', where + 1 ); + if ( where > - 1 ) + strAll.append( txt.mid(start + 1, where - start - 1).stripWhiteSpace() ); + else // grab until the end... + strAll.append( txt.right(txt.length() - start - 1).stripWhiteSpace() ); + } + } +} + +void parseEmailTo( const QString &strDefaultEmail, + const QString &strOtherEmail, QString &strBack ) +{ + // create a comma dilimeted set of emails... + // use the power of short circuiting... + bool foundDefault = false; + QString strTmp; + int start = 0; + int where; + // start at the beginng. + strBack = strDefaultEmail; + where = 0; + while ( where > -1 ) { + start = where; + where = strOtherEmail.find( ' ', where + 1 ); + if ( where > 0 ) { + strTmp = strOtherEmail.mid( start, where - start ).stripWhiteSpace(); + } else + strTmp = strOtherEmail.right( strOtherEmail.length() - start ).stripWhiteSpace(); + if ( foundDefault || strTmp != strDefaultEmail ) { + strBack.append( ", " ); + strBack.append( strTmp ); + } else + foundDefault = true; + } +} + + +static inline bool containsAlphaNum( const QString &str ) +{ + int i, + count = str.length(); + for ( i = 0; i < count; i++ ) + if ( !str[i].isSpace() ) + return TRUE; + return FALSE; +} + +static inline bool constainsWhiteSpace( const QString &str ) +{ + int i, + count = str.length(); + for (i = 0; i < count; i++ ) + if ( str[i].isSpace() ) + return TRUE; + return FALSE; +} + diff --git a/core/pim/addressbook/abeditor.h b/core/pim/addressbook/abeditor.h new file mode 100644 index 0000000..9ce6704 --- a/dev/null +++ b/core/pim/addressbook/abeditor.h @@ -0,0 +1,79 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qt Palmtop Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef ABEDITOR_H +#define ABEDITOR_H + +#include <qpe/contact.h> + +#include <qdialog.h> +#include <qlist.h> +#include <qmap.h> +#include <qstringlist.h> + +class QScrollView; +class QMultiLineEdit; +class QLineEdit; +class QLabel; +class QComboBox; +class CategorySelect; + +class AbEditor : public QDialog +{ + Q_OBJECT +public: + AbEditor( const Contact &entry, const QValueList<int> *newOrdedValues, + QStringList *slNewOrdered, + QWidget* parent = 0, const char* name = 0, WFlags fl = 0 ); + ~AbEditor(); + void loadFields(); + void setNameFocus(); + Contact entry() const { return ent; } + +public slots: + void slotNote(); + void setEntry( const Contact &entry ); + +protected slots: + void accept(); + +private: + void init(); + void initMap(); + void saveEntry(); + bool isEmpty(); + +private: + QDialog *dlgNote; + QLabel *lblNote; + QMultiLineEdit *txtNote; + Contact ent; + QScrollView *svPage; + QLineEdit *firstEdit; + QLineEdit *lastEdit; + QLineEdit *middleEdit; + QComboBox *genderCombo; + QList<QLineEdit> listValue; + QList<QLabel> listName; + const QValueList<int> *orderedValues; + QStringList *slOrdered; + CategorySelect *cmbCat; +}; + +#endif diff --git a/core/pim/addressbook/ablabel.cpp b/core/pim/addressbook/ablabel.cpp new file mode 100644 index 0000000..3bf3e12 --- a/dev/null +++ b/core/pim/addressbook/ablabel.cpp @@ -0,0 +1,53 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qt Palmtop Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#include "ablabel.h" + +#include <qpe/stringutil.h> + +#include <qregexp.h> +#include <qstylesheet.h> + +AbLabel::AbLabel( QWidget *parent, const char *name ) + : QTextView( parent, name ) +{ +} + +AbLabel::~AbLabel() +{ +} + +void AbLabel::init( const Contact &entry ) +{ + ent = entry; +} + +void AbLabel::sync() +{ + QString text = ent.toRichText(); + setText( text ); +} + +void AbLabel::keyPressEvent( QKeyEvent *e ) +{ + if ( e->key() == Qt::Key_F33 ) { + emit okPressed(); + } +} diff --git a/core/pim/addressbook/ablabel.h b/core/pim/addressbook/ablabel.h new file mode 100644 index 0000000..cfbd999 --- a/dev/null +++ b/core/pim/addressbook/ablabel.h @@ -0,0 +1,50 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qt Palmtop Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef ABLABEL_H +#define ABLABEL_H + +#include <qpe/contact.h> +#include <qtextview.h> + +class AbLabel : public QTextView +{ + Q_OBJECT + +public: + AbLabel( QWidget *parent, const char *name = 0 ); + ~AbLabel(); + +public slots: + void init( const Contact &entry ); + void sync(); + +signals: + void okPressed(); + +protected: + void keyPressEvent( QKeyEvent * ); + +private: + Contact ent; + +}; + +#endif // ABLABEL_H + diff --git a/core/pim/addressbook/abtable.cpp b/core/pim/addressbook/abtable.cpp new file mode 100644 index 0000000..0911edf --- a/dev/null +++ b/core/pim/addressbook/abtable.cpp @@ -0,0 +1,1091 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qt Palmtop Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#include <qpe/categoryselect.h> +#include <qpe/config.h> +#include <qpe/stringutil.h> +#include <qpe/qcopenvelope_qws.h> + +#include <qasciidict.h> +#include <qdatetime.h> +#include <qfile.h> + +#include "abtable.h" + +#include <errno.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdlib.h> + +#include <ctype.h> //toupper() for key hack + +static bool contactCompare( const Contact &cnt, const QRegExp &r, int category ); + +//### qtmail/addresslist.cpp hardcodes this filename as well +static QString journalFileName() +{ + QString str = getenv("HOME"); + str +="/.abjournal"; + return str; +} + + + +/*! + \class AbTableItem abtable.h + + \brief QTableItem based class for showing a field of an entry +*/ + +AbTableItem::AbTableItem( QTable *t, EditType et, const QString &s, + const QString &secondSortKey) + : QTableItem( t, et, s ) +{ + // sortKey = s.lower() + QChar( '\0' ) + secondSortKey.lower(); + sortKey = Qtopia::buildSortKey( s, secondSortKey ); +} + +int AbTableItem::alignment() const +{ + return AlignLeft|AlignVCenter; +} + +QString AbTableItem::key() const +{ + return sortKey; +} + +// A way to reset the item, without out doing a delete or a new... +void AbTableItem::setItem( const QString &txt, const QString &secondKey ) +{ + setText( txt ); + sortKey = Qtopia::buildSortKey( txt, secondKey ); + + // sortKey = txt.lower() + QChar( '\0' ) + secondKey.lower(); +} + +/*! + \class AbPickItem abtable.h + + \brief QTableItem based class for showing slection of an entry +*/ + +AbPickItem::AbPickItem( QTable *t ) : + QTableItem(t, WhenCurrent, "?") +{ +} + +QWidget *AbPickItem::createEditor() const +{ + QComboBox* combo = new QComboBox( table()->viewport() ); + ( (AbPickItem*)this )->cb = combo; + AbTable* t = static_cast<AbTable*>(table()); + QStringList c = t->choiceNames(); + int cur = 0; + for (QStringList::ConstIterator it = c.begin(); it!=c.end(); ++it) { + if ( *it == text() ) + cur = combo->count(); + combo->insertItem(*it); + } + combo->setCurrentItem(cur); + return combo; +} + +void AbPickItem::setContentFromEditor( QWidget *w ) +{ + if ( w->inherits("QComboBox") ) + setText( ( (QComboBox*)w )->currentText() ); + else + QTableItem::setContentFromEditor( w ); +} + +/*! + \class AbTable abtable.h + + \brief QTable based class for showing a list of entries +*/ + +AbTable::AbTable( const QValueList<int> *order, QWidget *parent, const char *name ) +// #ifdef QT_QTABLE_NOHEADER_CONSTRUCTOR +// : QTable( 0, 0, parent, name, TRUE ), +// #else + : QTable( parent, name ), +// #endif + lastSortCol( -1 ), + asc( TRUE ), + intFields( order ), + currFindRow( -2 ), + mCat( 0 ) +{ + mCat.load( categoryFileName() ); + setSelectionMode( NoSelection ); + init(); + setSorting( TRUE ); + connect( this, SIGNAL(clicked(int,int,int,const QPoint &)), + this, SLOT(itemClicked(int,int)) ); +} + +AbTable::~AbTable() +{ +} + +void AbTable::init() +{ + setNumRows( 0 ); + setNumCols( 2 ); + + horizontalHeader()->setLabel( 0, tr( "Full Name" )); + horizontalHeader()->setLabel( 1, tr( "Contact" )); + setLeftMargin( 0 ); + verticalHeader()->hide(); +} + +void AbTable::columnClicked( int col ) +{ + if ( !sorting() ) + return; + + if ( lastSortCol == -1 ) + lastSortCol = col; + + if ( col == lastSortCol ) { + asc = !asc; + } else { + lastSortCol = col; + asc = TRUE; + } + resort(); +} + +void AbTable::resort() +{ + if ( sorting() ) { + if ( lastSortCol == -1 ) + lastSortCol = 0; + sortColumn( lastSortCol, asc, TRUE ); + updateVisible(); + } +} + +Contact AbTable::currentEntry() +{ + Contact cnt; + AbTableItem *abItem; + abItem = static_cast<AbTableItem*>(item( currentRow(), 0 )); + if ( abItem ) { + cnt = contactList[abItem]; + } + return cnt; +} + +void AbTable::replaceCurrentEntry( const Contact &newContact ) +{ + int row = currentRow(); + updateJournal( newContact, Contact::ACTION_REPLACE, row ); + updateVisible(); + + journalFreeReplace( newContact, row ); +} + +void AbTable::deleteCurrentEntry() +{ + int row = currentRow(); + AbTableItem *abItem; + abItem = static_cast<AbTableItem*>(item( row, 0 )); + Contact oldContact; + oldContact = contactList[abItem]; + updateJournal( oldContact, Contact::ACTION_REMOVE, row ); + + // a little wasteful, but it ensure's there is only one place + // where we delete. + journalFreeRemove( row ); + updateVisible(); + + if ( numRows() == 0 ) + emit empty( TRUE ); +} + +void AbTable::clear() +{ + contactList.clear(); + for ( int r = 0; r < numRows(); ++r ) { + for ( int c = 0; c < numCols(); ++c ) { + if ( cellWidget( r, c ) ) + clearCellWidget( r, c ); + clearCell( r, c ); + } + } + setNumRows( 0 ); +} + +void AbTable::refresh() +{ + int rows = numRows(); + QString value; + AbTableItem *abi; + for ( int r = 0; r < rows; ++r ) { + abi = static_cast<AbTableItem*>( item(r, 0) ); + value = findContactContact( contactList[abi] ); + static_cast<AbTableItem*>( item(r, 1) )->setItem( value, abi->text() ); + } + resort(); +} + +void AbTable::keyPressEvent( QKeyEvent *e ) +{ + char key = toupper( e->ascii() ); + + if ( key >= 'A' && key <= 'Z' ) + moveTo( key ); + + switch( e->key() ) { + case Qt::Key_Space: + case Qt::Key_Return: + case Qt::Key_Enter: + emit details(); + break; + default: + QTable::keyPressEvent( e ); + } +} + +void AbTable::moveTo( char c ) +{ + + int rows = numRows(); + QString value; + AbTableItem *abi; + int r; + if ( asc ) { + r = 0; + while ( r < rows-1) { + abi = static_cast<AbTableItem*>( item(r, 0) ); + QChar first = abi->key()[0]; + //### is there a bug in QChar to char comparison??? + if ( first.row() || first.cell() >= c ) + break; + r++; + } + } else { + //### should probably disable reverse sorting instead + r = rows - 1; + while ( r > 0 ) { + abi = static_cast<AbTableItem*>( item(r, 0) ); + QChar first = abi->key()[0]; + //### is there a bug in QChar to char comparison??? + if ( first.row() || first.cell() >= c ) + break; + r--; + } + } + setCurrentCell( r, currentColumn() ); +} + + +QString AbTable::findContactName( const Contact &entry ) +{ + // We use the fileAs, then company, defaultEmail + QString str; + str = entry.fileAs(); + if ( str.isEmpty() ) { + str = entry.company(); + if ( str.isEmpty() ) { + str = entry.defaultEmail(); + } + } + return str; +} + +QString AbTable::findContactContact( const Contact &entry ) +{ + QString value; + value = ""; + for ( QValueList<int>::ConstIterator it = intFields->begin(); + it != intFields->end(); ++it ) { + switch ( *it ) { + default: + break; + case Qtopia::Title: + value = entry.title(); + break; + case Qtopia::Suffix: + value = entry.suffix(); + break; + case Qtopia::FileAs: + value = entry.fileAs(); + break; + case Qtopia::DefaultEmail: + value = entry.defaultEmail(); + case Qtopia::Emails: + value = entry.emails(); + break; + case Qtopia::HomeStreet: + value = entry.homeStreet(); + break; + case Qtopia::HomeCity: + value = entry.homeCity(); + break; + case Qtopia::HomeState: + value = entry.homeState(); + break; + case Qtopia::HomeZip: + value = entry.homeZip(); + break; + case Qtopia::HomeCountry: + value = entry.homeCountry(); + break; + case Qtopia::HomePhone: + value = entry.homePhone(); + break; + case Qtopia::HomeFax: + value = entry.homeFax(); + break; + case Qtopia::HomeMobile: + value = entry.homeMobile(); + break; + case Qtopia::HomeWebPage: + value = entry.homeWebpage(); + break; + case Qtopia::Company: + value = entry.company(); + break; + case Qtopia::BusinessCity: + value = entry.businessCity(); + break; + case Qtopia::BusinessStreet: + value = entry.businessStreet(); + break; + case Qtopia::BusinessZip: + value = entry.businessZip(); + break; + case Qtopia::BusinessCountry: + value = entry.businessCountry(); + break; + case Qtopia::BusinessWebPage: + value = entry.businessWebpage(); + break; + case Qtopia::JobTitle: + value = entry.jobTitle(); + break; + case Qtopia::Department: + value = entry.department(); + break; + case Qtopia::Office: + value = entry.office(); + break; + case Qtopia::BusinessPhone: + value = entry.businessPhone(); + break; + case Qtopia::BusinessFax: + value = entry.businessFax(); + break; + case Qtopia::BusinessMobile: + value = entry.businessMobile(); + break; + case Qtopia::BusinessPager: + value = entry.businessPager(); + break; + case Qtopia::Profession: + value = entry.profession(); + break; + case Qtopia::Assistant: + value = entry.assistant(); + break; + case Qtopia::Manager: + value = entry.manager(); + break; + case Qtopia::Spouse: + value = entry.spouse(); + break; + case Qtopia::Gender: + value = entry.gender(); + break; + case Qtopia::Birthday: + value = entry.birthday(); + break; + case Qtopia::Anniversary: + value = entry.anniversary(); + break; + case Qtopia::Nickname: + value = entry.nickname(); + break; + case Qtopia::Children: + value = entry.children(); + break; + case Qtopia::Notes: + value = entry.notes(); + break; + } + if ( !value.isEmpty() ) + break; + } + return value; +} + +void AbTable::addEntry( const Contact &newCnt ) +{ + int row = numRows(); + setNumRows( row + 1 ); + updateJournal( newCnt, Contact::ACTION_ADD ); + insertIntoTable( newCnt, row ); + setCurrentCell( row, 0 ); + updateVisible(); +} + +void AbTable::updateJournal( const Contact &cnt, + Contact::journal_action action, int row ) +{ + QFile f( journalFileName() ); + if ( !f.open(IO_WriteOnly|IO_Append) ) + return; + QString buf; + QCString str; + buf = "<Contact "; + cnt.save( buf ); + buf += " action=\"" + QString::number( (int)action ) + "\" "; + if ( action == Contact::ACTION_REMOVE || action == Contact::ACTION_REPLACE) + buf += " actionrow=\"" + QString::number(row) + "\" "; + buf += "/>\n"; + QCString cstr = buf.utf8(); + f.writeBlock( cstr.data(), cstr.length() ); + QCopEnvelope( "QPE/PIM", "addressbookUpdated()" ); +} + +bool AbTable::save( const QString &fn ) +{ +// QTime t; +// t.start(); + + QString strNewFile = fn + ".new"; + QFile f( strNewFile ); + if ( !f.open( IO_WriteOnly|IO_Raw ) ) + return false; + + int total_written; + QString out; + out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n" + " <Groups>\n" + " </Groups>\n" + " <Contacts>\n"; + QMapIterator<AbTableItem*, Contact> it; + for ( it = contactList.begin(); it != contactList.end(); ++it ) { + out += "<Contact "; + it.data().save( out ); + out += "/>\n"; + QCString cstr = out.utf8(); + total_written = f.writeBlock( cstr.data(), cstr.length() ); + if ( total_written != int(cstr.length()) ) { + f.close(); + QFile::remove( strNewFile ); + return false; + } + out = ""; + } + out += " </Contacts>\n</AddressBook>\n"; + + QCString cstr = out.utf8(); + total_written = f.writeBlock( cstr.data(), cstr.length() ); + if ( total_written != int(cstr.length()) ) { + f.close(); + QFile::remove( strNewFile ); + return false; + } + f.close(); + +// qDebug("saving: %d", t.elapsed() ); + + // move the file over, I'm just going to use the system call + // because, I don't feel like using QDir. + if ( ::rename( strNewFile.latin1(), fn.latin1() ) < 0 ) { + qWarning( "problem renaming file %s to %s, errno: %d", + strNewFile.latin1(), fn.latin1(), errno ); + // remove the tmp file... + QFile::remove( strNewFile ); + } + // remove the journal... + QFile::remove( journalFileName() ); + return true; +} + +void AbTable::load( const QString &fn ) +{ + setSorting( false ); + loadFile( fn, false ); + // merge in the journal + if ( QFile::exists( journalFileName() ) ) { + loadFile( journalFileName(), true ); + save( fn ); + } + setSorting( true ); + resort(); +} + +void AbTable::loadFile( const QString &strFile, bool journalFile ) +{ +// QTime t; +// t.start(); + QFile f( strFile ); + if ( !f.open(IO_ReadOnly) ) + return; + QList<Contact> list; + list.setAutoDelete( TRUE ); + QByteArray ba = f.readAll(); + f.close(); + char *uc = ba.data();//(QChar *)data.unicode(); + int len = ba.size();//data.length(); + bool foundAction = false; + Contact::journal_action action; + bool foundKey = false; + int journalKey = 0; + + const int JOURNALACTION = Qtopia::Notes + 1; + const int JOURNALROW = JOURNALACTION + 1; + + // ********************************** + // CHANGE THE SIZE OF THE DICT IF YOU ADD ANY MORE FIELDS!!!! + // ********************************** + QAsciiDict<int> dict( 47 ); + dict.setAutoDelete( TRUE ); + dict.insert( "Uid", new int(Qtopia::AddressUid) ); + dict.insert( "Title", new int(Qtopia::Title) ); + dict.insert( "FirstName", new int(Qtopia::FirstName) ); + dict.insert( "MiddleName", new int(Qtopia::MiddleName) ); + dict.insert( "LastName", new int(Qtopia::LastName) ); + dict.insert( "Suffix", new int(Qtopia::Suffix) ); + dict.insert( "FileAs", new int(Qtopia::FileAs) ); + dict.insert( "Categories", new int(Qtopia::AddressCategory) ); + dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) ); + dict.insert( "Emails", new int(Qtopia::Emails) ); + dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) ); + dict.insert( "HomeCity", new int(Qtopia::HomeCity) ); + dict.insert( "HomeState", new int(Qtopia::HomeState) ); + dict.insert( "HomeZip", new int(Qtopia::HomeZip) ); + dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) ); + dict.insert( "HomePhone", new int(Qtopia::HomePhone) ); + dict.insert( "HomeFax", new int(Qtopia::HomeFax) ); + dict.insert( "HomeMobile", new int(Qtopia::HomeMobile) ); + dict.insert( "HomeWebPage", new int(Qtopia::HomeWebPage) ); + dict.insert( "Company", new int(Qtopia::Company) ); + dict.insert( "BusinessStreet", new int(Qtopia::BusinessStreet) ); + dict.insert( "BusinessCity", new int(Qtopia::BusinessCity) ); + dict.insert( "BusinessState", new int(Qtopia::BusinessState) ); + dict.insert( "BusinessZip", new int(Qtopia::BusinessZip) ); + dict.insert( "BusinessCountry", new int(Qtopia::BusinessCountry) ); + dict.insert( "BusinessWebPage", new int(Qtopia::BusinessWebPage) ); + dict.insert( "JobTitle", new int(Qtopia::JobTitle) ); + dict.insert( "Department", new int(Qtopia::Department) ); + dict.insert( "Office", new int(Qtopia::Office) ); + dict.insert( "BusinessPhone", new int(Qtopia::BusinessPhone) ); + dict.insert( "BusinessFax", new int(Qtopia::BusinessFax) ); + dict.insert( "BusinessMobile", new int(Qtopia::BusinessMobile) ); + dict.insert( "BusinessPager", new int(Qtopia::BusinessPager) ); + dict.insert( "Profession", new int(Qtopia::Profession) ); + dict.insert( "Assistant", new int(Qtopia::Assistant) ); + dict.insert( "Manager", new int(Qtopia::Manager) ); + dict.insert( "Spouse", new int(Qtopia::Spouse) ); + dict.insert( "Children", new int(Qtopia::Children) ); + dict.insert( "Gender", new int(Qtopia::Gender) ); + dict.insert( "Birthday", new int(Qtopia::Birthday) ); + dict.insert( "Anniversary", new int(Qtopia::Anniversary) ); + dict.insert( "Nickname", new int(Qtopia::Nickname) ); + dict.insert( "Notes", new int(Qtopia::Notes) ); + dict.insert( "action", new int(JOURNALACTION) ); + dict.insert( "actionrow", new int(JOURNALROW) ); + + int i = 0; + int num = 0; + char *point; + while ( (point = strstr( uc+i, "<Contact " ) ) != NULL ) { + i = point - uc; + // if we are reading the standard file, we just need to + // insert info, so just say we'll do an insert... + action = Contact::ACTION_ADD; + // new Contact + Contact *cnt = new Contact; + i += 9; + while ( 1 ) { + while ( i < len && (uc[i] == ' ' || uc[i] == '\n' || uc[i] == '\r') ) + i++; + if ( i >= len-2 || (uc[i] == '/' && uc[i+1] == '>') ) + break; + // we have another attribute read it. + int j = i; + while ( j < len && uc[j] != '=' ) + j++; + char *attr = uc+i; + uc[j] = '\0'; + //qDebug("attr=%s", attr.latin1() ); + i = ++j; // skip = + while ( i < len && uc[i] != '"' ) + i++; + j = ++i; + bool haveEnt = FALSE; + bool haveUtf = FALSE; + while ( j < len && uc[j] != '"' ) { + if ( uc[j] == '&' ) + haveEnt = TRUE; + if ( ((unsigned char)uc[j]) > 0x7f ) + haveUtf = TRUE; + j++; + } + + if ( j == i ) { + // empty value + i = j + 1; + continue; + } + + QString value = haveUtf ? QString::fromUtf8( uc+i, j-i ) + : QString::fromLatin1( uc+i, j-i ); + if ( haveEnt ) + value = Qtopia::plainString( value ); + i = j + 1; + + int *find = dict[ attr ]; + if ( !find ) { + cnt->setCustomField(attr, value); + continue; + } +#if 1 + switch( *find ) { + case Qtopia::AddressUid: + cnt->setUid( value.toInt() ); + break; + case Qtopia::AddressCategory: + cnt->setCategories( Qtopia::Record::idsFromString( value )); + break; + case JOURNALACTION: + action = Contact::journal_action(value.toInt()); + break; + case JOURNALROW: + journalKey = value.toInt(); + break; + + default: + cnt->insert( *find, value ); + break; + } +#endif + } + + // sadly we can't delay adding of items from the journal to get + // the proper effect, but then, the journal should _never_ be + // that huge, and recovering from a crash is not necessarily + // a *fast* thing. + switch ( action ) { + case Contact::ACTION_ADD: + if ( journalFile ) { + int myrows = numRows(); + setNumRows( myrows + 1 ); + insertIntoTable( *cnt, myrows ); + delete cnt; + } + else + list.append( cnt ); + break; + case Contact::ACTION_REMOVE: + // yup, we don't use the entry to remove the object... + journalFreeRemove( journalKey ); + delete cnt; + break; + case Contact::ACTION_REPLACE: + journalFreeReplace( *cnt, journalKey ); + delete cnt; + break; + default: + break; + } + num++; + foundAction = false; + foundKey = false; +// if ( num % 100 == 0 ) { +// qDebug("loading file, num=%d, t=%d", num, t.elapsed() ); +// } + } + if ( list.count() > 0 ) { + internalAddEntries( list ); + } +// qDebug("done loading %d, t=%d", num, t.elapsed() ); + +} + +void AbTable::realignTable( int row ) +{ + QTableItem *ti1, + *ti2; + int totalRows = numRows(); + for ( int curr = row; curr < totalRows - 1; curr++ ) { + // the same info from the todo list still applies, but I + // don't think it is _too_ bad. + ti1 = item( curr + 1, 0 ); + ti2 = item( curr + 1, 1 ); + takeItem( ti1 ); + takeItem( ti2 ); + setItem( curr, 0, ti1 ); + setItem( curr, 1, ti2 ); + } + setNumRows( totalRows - 1 ); + resort(); +} + +void AbTable::insertIntoTable( const Contact &cnt, int row ) +{ + QString strName, + strContact; + + strName = findContactName( cnt ); + strContact = findContactContact( cnt ); + + AbTableItem *ati; + ati = new AbTableItem( this, QTableItem::Never, strName, strContact); + contactList.insert( ati, cnt ); + setItem( row, 0, ati ); + ati = new AbTableItem( this, QTableItem::Never, strContact, strName); + setItem( row, 1, ati ); + + //### cannot do this; table only has two columns at this point + // setItem( row, 2, new AbPickItem( this ) ); + + // resort at some point? +} + +void AbTable::internalAddEntries( QList<Contact> &list ) +{ + setUpdatesEnabled( FALSE ); + setNumRows( list.count() ); + int row = 0; + Contact *it; + for ( it = list.first(); it; it = list.next() ) + insertIntoTable( *it, row++ ); + resort(); + setUpdatesEnabled( TRUE ); +} + + +void AbTable::journalFreeReplace( const Contact &cnt, int row ) +{ + QString strName, + strContact; + AbTableItem *ati; + + strName = findContactName( cnt ); + strContact = findContactContact( cnt ); + ati = static_cast<AbTableItem*>(item(row, 0)); + contactList.remove( ati ); + ati->setItem( strName, strContact ); + contactList.insert( ati, cnt ); + + ati = static_cast<AbTableItem*>(item(row, 1)); + ati->setItem( strContact, strName ); +} + +void AbTable::journalFreeRemove( int row ) +{ + AbTableItem *ati; + ati = static_cast<AbTableItem*>(item(row, 0)); + if ( !ati ) + return; + contactList.remove( ati ); + realignTable( row ); +} + +#if QT_VERSION <= 230 +#ifndef SINGLE_APP +void QTable::paintEmptyArea( QPainter *p, int cx, int cy, int cw, int ch ) +{ + // Region of the rect we should draw + QRegion reg( QRect( cx, cy, cw, ch ) ); + // Subtract the table from it + reg = reg.subtract( QRect( QPoint( 0, 0 ), tableSize() ) ); + // And draw the rectangles (transformed as needed) + QArray<QRect> r = reg.rects(); + for (unsigned int i=0; i<r.count(); i++) + p->fillRect( r[i], colorGroup().brush( QColorGroup::Base ) ); +} +#endif +#endif + + +// int AbTable::rowHeight( int ) const +// { +// return 18; +// } + +// int AbTable::rowPos( int row ) const +// { +// return 18*row; +// } + +// int AbTable::rowAt( int pos ) const +// { +// return QMIN( pos/18, numRows()-1 ); +// } + +void AbTable::slotDoFind( const QString &findString, bool caseSensitive, + bool backwards, int category ) +{ + if ( currFindRow < -1 ) + currFindRow = currentRow() - 1; + clearSelection( TRUE ); + int rows, + row; + AbTableItem *ati; + QRegExp r( findString ); + r.setCaseSensitive( caseSensitive ); + rows = numRows(); + static bool wrapAround = true; + + if ( !backwards ) { + for ( row = currFindRow + 1; row < rows; row++ ) { + ati = static_cast<AbTableItem*>( item(row, 0) ); + if ( contactCompare( contactList[ati], r, category ) ) + break; + + } + } else { + for ( row = currFindRow - 1; row > -1; row-- ) { + ati = static_cast<AbTableItem*>( item(row, 0) ); + if ( contactCompare( contactList[ati], r, category ) ) + break; + } + } + if ( row >= rows || row < 0 ) { + if ( row < 0 ) + currFindRow = rows; + else + currFindRow = -1; + + if ( wrapAround ) + emit signalWrapAround(); + else + emit signalNotFound(); + + wrapAround = !wrapAround; + } else { + currFindRow = row; + QTableSelection foundSelection; + foundSelection.init( currFindRow, 0 ); + foundSelection.expandTo( currFindRow, numCols() - 1 ); + addSelection( foundSelection ); + setCurrentCell( currFindRow, numCols() - 1 ); + wrapAround = true; + } +} + +static bool contactCompare( const Contact &cnt, const QRegExp &r, int category ) +{ + bool returnMe; + QArray<int> cats; + cats = cnt.categories(); + + returnMe = false; + if ( (category == -1 && cats.count() == 0) || category == -2 ) + returnMe = cnt.match( r ); + else { + int i; + for ( i = 0; i < int(cats.count()); i++ ) { + if ( cats[i] == category ) { + returnMe = cnt.match( r ); + break; + } + } + } + return returnMe; +} + +void AbTable::fitColumns() +{ + int contentsWidth = visibleWidth(); + int n = numCols(); + int pw = n == 3 ? columnWidth(2) : 0; + setColumnWidth( 0, contentsWidth - contentsWidth / 2 ); + setColumnWidth( 1, contentsWidth / 2 - pw ); +} + +void AbTable::show() +{ + fitColumns(); + QTable::show(); +} + +void AbTable::setChoiceNames( const QStringList& list) +{ + choicenames = list; + if ( choicenames.isEmpty() ) { + // hide pick column + setNumCols( 2 ); + } else { + // show pick column + setNumCols( 3 ); + setColumnWidth( 2, fontMetrics().width(tr( "Pick" ))+8 ); + horizontalHeader()->setLabel( 2, tr( "Pick" )); + } + fitColumns(); +} + +void AbTable::itemClicked(int,int col) +{ + if ( col == 2 ) { + return; + } else { + emit details(); + } +} + +QStringList AbTable::choiceNames() const +{ + return choicenames; +} + +void AbTable::setChoiceSelection(int /*index*/, const QStringList& /*list*/) +{ + /* ###### + + QString selname = choicenames.at(index); + for (each row) { + Contact *c = contactForRow(row); + if ( list.contains(c->email) ) { + list.remove(c->email); + setText(row, 2, selname); + } + } + for (remaining list items) { + Contact *c = new contact(item); + setText(newrow, 2, selname); + } + + */ +} + +QStringList AbTable::choiceSelection(int /*index*/) const +{ + QStringList r; + /* ###### + + QString selname = choicenames.at(index); + for (each row) { + Contact *c = contactForRow(row); + if ( text(row,2) == selname ) { + r.append(c->email); + } + } + + */ + return r; +} + +void AbTable::setShowCategory( const QString &c ) +{ + showCat = c; + updateVisible(); +} + +QString AbTable::showCategory() const +{ + return showCat; +} + + +QStringList AbTable::categories() +{ + mCat.load( categoryFileName() ); + QStringList categoryList = mCat.labels( "Contacts" ); + return categoryList; +} + +void AbTable::updateVisible() +{ + int visible, + totalRows, + id, + totalCats, + it, + row; + bool hide; + AbTableItem *ati; + Contact *cnt; + visible = 0; + + setPaintingEnabled( FALSE ); + + totalRows = numRows(); + id = mCat.id( "Contacts", showCat ); + QArray<int> cats; + for ( row = 0; row < totalRows; row++ ) { + ati = static_cast<AbTableItem*>( item(row, 0) ); + cnt = &contactList[ati]; + cats = cnt->categories(); + hide = false; + if ( !showCat.isEmpty() ) { + if ( showCat == tr( "Unfiled" ) ) { + if ( cats.count() > 0 ) + hide = true; + } else { + // do some comparing + if ( !hide ) { + hide = true; + totalCats = int(cats.count()); + for ( it = 0; it < totalCats; it++ ) { + if ( cats[it] == id ) { + hide = false; + break; + } + } + } + } + } + if ( hide ) { + if ( currentRow() == row ) + setCurrentCell( -1, 0 ); + if ( rowHeight(row) > 0 ) + hideRow( row ); + } else { + if ( rowHeight(row) == 0 ) { + showRow( row ); + adjustRow( row ); + } + visible++; + } + } + if ( !visible ) + setCurrentCell( -1, 0 ); + + setPaintingEnabled( TRUE ); +} + + +void AbTable::setPaintingEnabled( bool e ) +{ + if ( e != enablePainting ) { + if ( !enablePainting ) { + enablePainting = true; + rowHeightChanged( 0 ); + viewport()->update(); + } else { + enablePainting = false; + } + } +} + +void AbTable::rowHeightChanged( int row ) +{ + if ( enablePainting ) + QTable::rowHeightChanged( row ); +} diff --git a/core/pim/addressbook/abtable.h b/core/pim/addressbook/abtable.h new file mode 100644 index 0000000..9b96997 --- a/dev/null +++ b/core/pim/addressbook/abtable.h @@ -0,0 +1,140 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qt Palmtop Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#ifndef ABTABLE_H +#define ABTABLE_H + +#include <qpe/categories.h> +#include <qpe/contact.h> + +#include <qmap.h> +#include <qtable.h> +#include <qstringlist.h> +#include <qcombobox.h> + +class AbTableItem : public QTableItem +{ +public: + AbTableItem( QTable *t, EditType et, const QString &s, + const QString &secondSortKey); + QString entryKey() const; + void setEntryKey( const QString & k ); + virtual int alignment() const; + virtual QString key() const; + void setItem( const QString &txt, const QString &secondKey ); + +private: + QString sortKey; +}; + +class AbPickItem : public QTableItem +{ +public: + AbPickItem( QTable *t ); + + QWidget *createEditor() const; + void setContentFromEditor( QWidget *w ); + +private: + QGuardedPtr<QComboBox> cb; +}; + +class AbTable : public QTable +{ + Q_OBJECT + +public: + AbTable( const QValueList<int> *ordered, QWidget *parent, const char *name=0 ); + ~AbTable(); + // NEW + void addEntry( const Contact &newContact ); + Contact currentEntry(); + void replaceCurrentEntry( const Contact &newContact ); + + void init(); + + void deleteCurrentEntry(); + void clear(); + void clearFindRow() { currFindRow = -2; } + void loadFields(); + void refresh(); + bool save( const QString &fn ); + void load( const QString &fn ); + + // addresspicker mode + void setChoiceNames( const QStringList& list); + QStringList choiceNames() const; + void setChoiceSelection(int index, const QStringList& list); + QStringList choiceSelection(int index) const; + void setShowCategory( const QString &c ); + QString showCategory() const; + QStringList categories(); + + void show(); + void setPaintingEnabled( bool e ); + +public slots: + void slotDoFind( const QString &str, bool caseSensitive, bool backwards, + int category ); +signals: + void empty( bool ); + void details(); + void signalNotFound(); + void signalWrapAround(); + +protected: + virtual void keyPressEvent( QKeyEvent *e ); + +// int rowHeight( int ) const; +// int rowPos( int row ) const; +// virtual int rowAt( int pos ) const; + + +protected slots: + void moveTo( char ); + virtual void columnClicked( int col ); + void itemClicked(int,int col); + void rowHeightChanged( int row ); + +private: + void loadFile( const QString &strFile, bool journalFile ); + void fitColumns(); + void resort(); + void updateJournal( const Contact &contact, Contact::journal_action action, + int row = -1 ); + void insertIntoTable( const Contact &contact, int row ); + void internalAddEntries( QList<Contact> &list ); + QString findContactName( const Contact &entry ); + QString findContactContact( const Contact &entry ); + void journalFreeReplace( const Contact &cnt, int row ); + void journalFreeRemove( int row ); + void realignTable( int ); + void updateVisible(); + int lastSortCol; + bool asc; + QMap<AbTableItem*, Contact> contactList; + const QValueList<int> *intFields; + int currFindRow; + QString showCat; + QStringList choicenames; + bool enablePainting; + Categories mCat; +}; +#endif // ABTABLE_H diff --git a/core/pim/addressbook/addressbook.cpp b/core/pim/addressbook/addressbook.cpp new file mode 100644 index 0000000..b694e4f --- a/dev/null +++ b/core/pim/addressbook/addressbook.cpp @@ -0,0 +1,829 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qt Palmtop Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#include "abeditor.h" +#include "ablabel.h" +#include "abtable.h" +#include "addresssettings.h" +#include "addressbook.h" + +#include <qpe/qpeapplication.h> +#include <qpe/config.h> +#include <qpe/contact.h> +#include <qpe/finddialog.h> +#include <qpe/global.h> +#include <qpe/resource.h> +#include <qpe/ir.h> +#include <qpe/qpemessagebox.h> +#include <qpe/qcopenvelope_qws.h> + +#include <qaction.h> +#include <qdialog.h> +#include <qdir.h> +#include <qfile.h> +#include <qimage.h> +#include <qlayout.h> +#include <qpe/qpemenubar.h> +#include <qmessagebox.h> +#include <qpixmap.h> +#include <qpopupmenu.h> +#include <qpe/qpetoolbar.h> +#include <qstringlist.h> +#include <qtoolbutton.h> +#include <qwhatsthis.h> + +#include <stdlib.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <fcntl.h> +#include <unistd.h> + +#include <qdatetime.h> + +static QString addressbookOldXMLFilename() +{ + QString filename = QPEApplication::documentDir() + "addressbook.xml"; + return filename; +} + +static QString addressbookXMLFilename() +{ + QString filename = Global::applicationFileName("addressbook", + "addressbook.xml"); + return filename; +} + +static QString addressbookPersonalVCardName() +{ + QString filename = Global::applicationFileName("addressbook", + "businesscard.vcf"); + return filename; +} + + +AddressbookWindow::AddressbookWindow( QWidget *parent, const char *name, + WFlags f ) + : QMainWindow( parent, name, f ), + abEditor(0), + bAbEditFirstTime(TRUE), + syncing(FALSE) +{ + initFields(); + + setCaption( tr("Contacts") ); + setIcon( Resource::loadPixmap( "AddressBook" ) ); + + setToolBarsMovable( FALSE ); + + // Create Toolbars + + QPEToolBar *bar = new QPEToolBar( this ); + bar->setHorizontalStretchable( TRUE ); + + QPEMenuBar *mbList = new QPEMenuBar( bar ); + mbList->setMargin( 0 ); + + QPopupMenu *edit = new QPopupMenu( this ); + mbList->insertItem( tr( "Contact" ), edit ); + + listTools = new QPEToolBar( this, "list operations" ); + + + QAction *a = new QAction( tr( "New" ), Resource::loadPixmap( "new" ), QString::null, + 0, this, 0 ); + actionNew = a; + connect( a, SIGNAL( activated() ), this, SLOT( slotListNew() ) ); + a->addTo( edit ); + a->addTo( listTools ); + + a = new QAction( tr( "Edit" ), Resource::loadPixmap( "edit" ), QString::null, + 0, this, 0 ); + actionEdit = a; + connect( a, SIGNAL( activated() ), this, SLOT( slotViewEdit() ) ); + a->addTo( edit ); + a->addTo( listTools ); + + a = new QAction( tr( "Delete" ), Resource::loadPixmap( "trash" ), QString::null, + 0, this, 0 ); + actionTrash = a; + connect( a, SIGNAL( activated() ), this, SLOT( slotListDelete() ) ); + a->addTo( edit ); + a->addTo( listTools ); + + a = new QAction( tr( "Find" ), Resource::loadPixmap( "mag" ), + QString::null, 0, this, 0 ); + actionFind = a; + connect( a, SIGNAL(activated()), this, SLOT(slotFind()) ); + a->addTo( edit ); + a->addTo( listTools ); + + + a = new QAction( tr( "Write Mail To" ), Resource::loadPixmap( "qtmail/reply" ), + QString::null, 0, this, 0 ); + a->setEnabled( FALSE ); + actionMail = a; + connect( a, SIGNAL( activated() ), this, SLOT( writeMail() ) ); + a->addTo( edit ); + a->addTo( listTools ); + + + + if ( Ir::supported() ) { + a = new QAction( tr ("Beam Entry" ), Resource::loadPixmap( "beam" ), QString::null, + 0, this, 0 ); + actionBeam = a; + connect( a, SIGNAL( activated() ), this, SLOT( slotBeam() ) ); + a->addTo( edit ); + a->addTo( listTools ); + } + + edit->insertSeparator(); + + a = new QAction( tr("My Personal Details"), QString::null, 0, 0, 0, TRUE ); + actionPersonal = a; + connect( a, SIGNAL( activated() ), this, SLOT( slotPersonalView() ) ); + a->addTo( edit ); + + + a = new QAction( tr( "Arrange Edit Fields"), QString::null, 0, 0 ); + connect( a, SIGNAL( activated() ), this, SLOT( slotSettings() ) ); + a->addTo( edit ); + + // Create Views + + // This is safe to call without checking to see if it exists... + // not to mention it also does the necessary stuff for the + // journaling... + QString str = addressbookXMLFilename(); + if ( str.isNull() ) { + QMessageBox::warning( this, tr("Out of Space"), + tr("There is not enough space to create\n" + "neccessary startup files.\n" + "\nFree up some space before\nentering data!") + ); + } + + abList = new AbTable( &orderedFields, this, "table" ); + abList->setHScrollBarMode( QScrollView::AlwaysOff ); + connect( abList, SIGNAL( empty( bool ) ), + this, SLOT( listIsEmpty( bool ) ) ); + connect( abList, SIGNAL( details() ), + this, SLOT( slotListView() ) ); + connect( abList, SIGNAL(currentChanged(int,int)), + this, SLOT(slotUpdateToolbar()) ); + + mView = 0; + + abList->load( addressbookXMLFilename() ); + if ( QFile::exists(addressbookOldXMLFilename()) ) { + abList->load( addressbookOldXMLFilename() ); + QFile::remove(addressbookOldXMLFilename()); + } + + catMenu = new QPopupMenu( this ); + catMenu->setCheckable( TRUE ); + connect( catMenu, SIGNAL(activated(int)), this, SLOT(slotSetCategory(int)) ); + populateCategories(); + + mbList->insertItem( tr("View"), catMenu ); + setCentralWidget( abList ); + + // qDebug("adressbook contrsuction: t=%d", t.elapsed() ); +} + +void AddressbookWindow::setDocument( const QString &filename ) +{ + if ( filename.find(".vcf") != int(filename.length()) - 4 ) return; + + QValueList<Contact> cl = Contact::readVCard( filename ); + for( QValueList<Contact>::Iterator it = cl.begin(); it != cl.end(); ++it ) { +// QString msg = tr("You received a vCard for\n%1.\nDo You want to add it to your\naddressbook?") +// .arg( (*it).fullName() ); +// if ( QMessageBox::information( this, tr("received contact"), msg, QMessageBox::Ok, QMessageBox::Cancel ) == +// QMessageBox::Ok ) { + abList->addEntry( *it ); +// } + } + +} + +void AddressbookWindow::resizeEvent( QResizeEvent *e ) +{ + QMainWindow::resizeEvent( e ); + + if ( centralWidget() == abList ) + showList(); + else if ( centralWidget() == mView ) + showView(); +} + +AddressbookWindow::~AddressbookWindow() +{ +} + +void AddressbookWindow::slotUpdateToolbar() +{ + Contact ce = abList->currentEntry(); + actionMail->setEnabled( !ce.defaultEmail().isEmpty() ); +} + +void AddressbookWindow::showList() +{ + if ( mView ) mView->hide(); + setCentralWidget( abList ); + abList->show(); + // update our focues... (or use a stack widget!); + abList->setFocus(); +} + +void AddressbookWindow::showView() +{ + if ( abList->numRows() > 0 ) { + abList->hide(); + setCentralWidget( abView() ); + mView->show(); + mView->setFocus(); + } +} + +void AddressbookWindow::slotListNew() +{ + Contact cnt; + if( !syncing ) { + if ( abEditor ) + abEditor->setEntry( cnt ); + abView()->init( cnt ); + editEntry( NewEntry ); + } else { + QMessageBox::warning(this, tr("Contacts"), + tr("Can not edit data, currently syncing")); + } +} + +void AddressbookWindow::slotListView() +{ + abView()->init( abList->currentEntry() ); + mView->sync(); + showView(); +} + +void AddressbookWindow::slotListDelete() +{ + if(!syncing) { + Contact tmpEntry = abList->currentEntry(); + + // get a name, do the best we can... + QString strName = tmpEntry.fullName(); + if ( strName.isEmpty() ) { + strName = tmpEntry.company(); + if ( strName.isEmpty() ) + strName = "No Name"; + } + + + if ( QPEMessageBox::confirmDelete( this, tr( "Contacts" ), + strName ) ) { + abList->deleteCurrentEntry(); + showList(); + } + } else { + QMessageBox::warning( this, tr("Contacts"), + tr("Can not edit data, currently syncing") ); + } +} + +void AddressbookWindow::slotViewBack() +{ + showList(); +} + +void AddressbookWindow::slotViewEdit() +{ + if(!syncing) { + if (actionPersonal->isOn()) { + editPersonal(); + } else { + if ( !bAbEditFirstTime ) + abEditor->setEntry( abList->currentEntry() ); + editEntry( EditEntry ); + } + } else { + QMessageBox::warning( this, tr("Contacts"), + tr("Can not edit data, currently syncing") ); + } +} + + + +void AddressbookWindow::writeMail() +{ + Contact c = abList->currentEntry(); + QString name = c.fileAs(); + QString email = c.defaultEmail(); + QCopEnvelope e("QPE/Application/qtmail", "writeMail(QString,QString)"); + e << name << email; +} + + + + +static const char * beamfile = "/tmp/obex/contact.vcf"; + +void AddressbookWindow::slotBeam() +{ + QString filename; + Contact c; + if ( actionPersonal->isOn() ) { + filename = addressbookPersonalVCardName(); + if (!QFile::exists(filename)) + return; // can't beam a non-existent file + c = Contact::readVCard( filename )[0]; + } else { + unlink( beamfile ); // delete if exists + c = abList->currentEntry(); + mkdir("/tmp/obex/", 0755); + Contact::writeVCard( beamfile, c ); + filename = beamfile; + } + Ir *ir = new Ir( this ); + connect( ir, SIGNAL( done( Ir * ) ), this, SLOT( beamDone( Ir * ) ) ); + QString description = c.fullName(); + ir->send( filename, description, "text/x-vCard" ); +} + +void AddressbookWindow::beamDone( Ir *ir ) +{ + delete ir; + unlink( beamfile ); +} + + +static void parseName( const QString& name, QString *first, QString *middle, + QString * last ) +{ + + int comma = name.find ( "," ); + QString rest; + if ( comma > 0 ) { + *last = name.left( comma ); + comma++; + while ( comma < int(name.length()) && name[comma] == ' ' ) + comma++; + rest = name.mid( comma ); + } else { + int space = name.findRev( ' ' ); + *last = name.mid( space+1 ); + rest = name.left( space ); + } + int space = rest.find( ' ' ); + if ( space <= 0 ) { + *first = rest; + } else { + *first = rest.left( space ); + *middle = rest.mid( space+1 ); + } + +} + + +void AddressbookWindow::appMessage(const QCString &msg, const QByteArray &data) +{ + if (msg == "editPersonal()") { + editPersonal(); + } else if (msg == "editPersonalAndClose()") { + editPersonal(); + close(); + } else if ( msg == "addContact(QString,QString)" ) { + QDataStream stream(data,IO_ReadOnly); + QString name, email; + stream >> name >> email; + + Contact cnt; + QString fn, mn, ln; + parseName( name, &fn, &mn, &ln ); + // qDebug( " %s - %s - %s", fn.latin1(), mn.latin1(), ln.latin1() ); + cnt.setFirstName( fn ); + cnt.setMiddleName( mn ); + cnt.setLastName( ln ); + cnt.setEmails( email ); + cnt.setDefaultEmail( email ); + cnt.setFileAs(); + + if ( bAbEditFirstTime ) { + abEditor = new AbEditor( cnt, &orderedFields, &slOrderedFields, + this, "editor" ); + bAbEditFirstTime = FALSE; + } else { + abEditor->setEntry( cnt ); + } + abView()->init( cnt ); + editEntry( NewEntry ); + + + + } +#if 0 + else if (msg == "pickAddresses(QCString,QCString,QStringList,...)" ) { + QDataStream stream(data,IO_ReadOnly); + QCString ch,m; + QStringList types; + stream >> ch >> m >> types; + AddressPicker picker(abList,this,0,TRUE); + picker.showMaximized(); + picker.setChoiceNames(types); + int i=0; + for (QStringList::ConstIterator it = types.begin(); it!=types.end(); ++it) { + QStringList sel; + stream >> sel; + picker.setSelection(i++,sel); + } + picker.showMaximized(); + picker.exec(); + + // ###### note: contacts may have been added - save here! + + setCentralWidget(abList); + QCopEnvelope e(ch,m); + i=0; + for (QStringList::ConstIterator it = types.begin(); it!=types.end(); ++it) { + QStringList sel = picker.selection(i++); + e << sel; + } + } +#endif + +} + +void AddressbookWindow::editPersonal() +{ + QString filename = addressbookPersonalVCardName(); + Contact me; + if (QFile::exists(filename)) + me = Contact::readVCard( filename )[0]; + if (bAbEditFirstTime) { + abEditor = new AbEditor( me, &orderedFields, &slOrderedFields, + this, "editor" ); + // don't create a new editor every time + bAbEditFirstTime = FALSE; + } else + abEditor->setEntry( me ); + + abEditor->setCaption(tr("Edit My Personal Details")); + abEditor->showMaximized(); + + // fix the foxus... + abEditor->setNameFocus(); + if ( abEditor->exec() ) { + setFocus(); + Contact new_personal = abEditor->entry(); + QString fname = addressbookPersonalVCardName(); + Contact::writeVCard( fname, new_personal ); + abView()->init(new_personal); + abView()->sync(); + } + abEditor->setCaption( tr("Edit Address") ); +} + +void AddressbookWindow::slotPersonalView() +{ + if (!actionPersonal->isOn()) { + // we just turned it off + setCaption( tr("Contacts") ); + actionNew->setEnabled(TRUE); + actionTrash->setEnabled(TRUE); + actionFind->setEnabled(TRUE); + slotUpdateToolbar(); // maybe some of the above could be moved there + showList(); + return; + } + + // XXX need to disable some QActions. + actionNew->setEnabled(FALSE); + actionTrash->setEnabled(FALSE); + actionFind->setEnabled(FALSE); + actionMail->setEnabled(FALSE); + + setCaption( tr("Contacts - My Personal Details") ); + QString filename = addressbookPersonalVCardName(); + Contact me; + if (QFile::exists(filename)) + me = Contact::readVCard( filename )[0]; + + abView()->init( me ); + abView()->sync(); + abList->hide(); + setCentralWidget( abView() ); + mView->show(); + mView->setFocus(); +} + +void AddressbookWindow::editEntry( EntryMode entryMode ) +{ + Contact entry; + if ( bAbEditFirstTime ) { + abEditor = new AbEditor( entry, &orderedFields, &slOrderedFields, + this, "editor" ); + bAbEditFirstTime = FALSE; + if ( entryMode == EditEntry ) + abEditor->setEntry( abList->currentEntry() ); + } + // other things may chane the caption. + abEditor->setCaption( tr("Edit Address") ); + +#if defined(Q_WS_QWS) || defined(_WS_QWS_) + abEditor->showMaximized(); +#endif + // fix the foxus... + abEditor->setNameFocus(); + if ( abEditor->exec() ) { + setFocus(); + if ( entryMode == NewEntry ) { + Contact insertEntry = abEditor->entry(); + insertEntry.assignUid(); + abList->addEntry( insertEntry ); + } else { + Contact replaceEntry = abEditor->entry(); + if ( !replaceEntry.isValidUid() ) + replaceEntry.assignUid(); + abList->replaceCurrentEntry( replaceEntry ); + } + } + populateCategories(); + showList(); +} + +void AddressbookWindow::listIsEmpty( bool empty ) +{ + if ( !empty ) { + deleteButton->setEnabled( TRUE ); + } +} + +void AddressbookWindow::reload() +{ + syncing = FALSE; + abList->clear(); + abList->load( addressbookXMLFilename() ); +} + +void AddressbookWindow::flush() +{ + syncing = TRUE; + abList->save( addressbookXMLFilename() ); +} + + +void AddressbookWindow::closeEvent( QCloseEvent *e ) +{ + if ( centralWidget() == mView ) { + if (actionPersonal->isOn()) { + // pretend we clicked it off + actionPersonal->setOn(FALSE); + slotPersonalView(); + } else { + showList(); + } + e->ignore(); + return; + } + + if(syncing) { + /* shouldn't we save, I hear you say? well its already been set + so that an edit can not occur during a sync, and we flushed + at the start of the sync, so there is no need to save + Saving however itself would cause problems. */ + e->accept(); + return; + } +//################## shouldn't always save + if ( save() ) + e->accept(); + else + e->ignore(); +} + +/* + Returns TRUE if it is OK to exit + */ + +bool AddressbookWindow::save() +{ + QString str = addressbookXMLFilename(); + if ( str.isNull() ) { + if ( QMessageBox::critical( 0, tr("Out of space"), + tr("Unable to save information.\n" + "Free up some space\n" + "and try again.\n" + "\nQuit anyway?"), + QMessageBox::Yes|QMessageBox::Escape, + QMessageBox::No|QMessageBox::Default ) + != QMessageBox::No ) + return TRUE; + else + return FALSE; + } else { + if ( !abList->save( str ) ) { + if ( QMessageBox::critical( 0, tr( "Out of space" ), + tr("Unable to save information.\n" + "Free up some space\n" + "and try again.\n" + "\nQuit anyway?"), + QMessageBox::Yes|QMessageBox::Escape, + QMessageBox::No|QMessageBox::Default ) + != QMessageBox::No ) + return TRUE; + else + return FALSE; + } + } + return TRUE; +} + +void AddressbookWindow::slotSettings() +{ + AddressSettings frmSettings( this ); +#if defined(Q_WS_QWS) || defined(_WS_QWS_) + frmSettings.showMaximized(); +#endif + + if ( frmSettings.exec() ) { + allFields.clear(); + orderedFields.clear(); + slOrderedFields.clear(); + initFields(); + if ( abEditor ) + abEditor->loadFields(); + abList->refresh(); + } +} + + +void AddressbookWindow::initFields() +{ + // we really don't need the things from the configuration, anymore + // only thing that is important are the important categories. So, + // Call the contact functions that correspond to these old functions... + + QStringList xmlFields = Contact::fields(); + QStringList visibleFields = Contact::trfields(); + xmlFields.remove( "Title" ); + visibleFields.remove( tr("Name Title") ); + visibleFields.remove( tr("Notes") ); + + int i, + version; + Config cfg( "AddressBook" ); + QString zn; + + // ### Write a function to keep this from happening again... + QStringList::ConstIterator it; + for ( i = 0, it = xmlFields.begin(); it != xmlFields.end(); ++it, i++ ) { + allFields.append( i + 3 ); + } + + cfg.setGroup( "Version" ); + version = cfg.readNumEntry( "version" ); + i = 0; + if ( version >= ADDRESSVERSION ) { + + cfg.setGroup( "ImportantCategory" ); + + zn = cfg.readEntry( "Category" + QString::number(i), QString::null ); + while ( !zn.isNull() ) { + if ( zn.contains( tr("Work") ) || zn.contains( tr("Mb") ) ) { + slOrderedFields.clear(); + break; + } + slOrderedFields.append( zn ); + zn = cfg.readEntry( "Category" + QString::number(++i), QString::null ); + } + } else { + QString str; + str = getenv("HOME"); + str += "/Settings/AddressBook.conf"; + QFile::remove( str ); + } + if ( slOrderedFields.count() > 0 ) { + for( QStringList::ConstIterator it = slOrderedFields.begin(); + it != slOrderedFields.end(); ++it ) { + QValueList<int>::ConstIterator itVl; + QStringList::ConstIterator itVis; + itVl = allFields.begin(); + for ( itVis = visibleFields.begin(); + itVis != visibleFields.end() && itVl != allFields.end(); + ++itVis, ++itVl ) { + if ( *it == *itVis && itVl != allFields.end() ) { + orderedFields.append( *itVl ); + } + } + } + } else { + QValueList<int>::ConstIterator it; + for ( it = allFields.begin(); it != allFields.end(); ++it ) + orderedFields.append( *it ); + + slOrderedFields = visibleFields; + orderedFields.remove( Qtopia::AddressUid ); + orderedFields.remove( Qtopia::Title ); + orderedFields.remove( Qtopia::Groups ); + orderedFields.remove( Qtopia::AddressCategory ); + orderedFields.remove( Qtopia::FirstName ); + orderedFields.remove( Qtopia::LastName ); + orderedFields.remove( Qtopia::DefaultEmail ); + orderedFields.remove( Qtopia::FileAs ); + orderedFields.remove( Qtopia::Notes ); + orderedFields.remove( Qtopia::Gender ); + slOrderedFields.remove( tr("Name Title") ); + slOrderedFields.remove( tr("First Name") ); + slOrderedFields.remove( tr("Last Name") ); + slOrderedFields.remove( tr("File As") ); + slOrderedFields.remove( tr("Default Email") ); + slOrderedFields.remove( tr("Notes") ); + slOrderedFields.remove( tr("Gender") ); + + } +} + + +AbLabel *AddressbookWindow::abView() +{ + if ( !mView ) { + mView = new AbLabel( this, "viewer" ); + mView->init( Contact() ); + connect( mView, SIGNAL( okPressed() ), this, SLOT( slotListView() ) ); + } + return mView; +} + +void AddressbookWindow::slotFind() +{ + if ( centralWidget() == abView() ) + showList(); + FindDialog frmFind( "Contacts", this ); + QObject::connect( &frmFind, SIGNAL(signalFindClicked(const QString &, bool, bool, int)), abList, SLOT(slotDoFind( const QString&,bool,bool,int))); + QObject::connect( abList, SIGNAL(signalNotFound()), &frmFind, SLOT(slotNotFound()) ); + QObject::connect( abList, SIGNAL(signalWrapAround()), &frmFind, SLOT(slotWrapAround()) ); + frmFind.exec(); + if ( abList->numSelections() ) + abList->clearSelection(); + abList->clearFindRow(); +} + +void AddressbookWindow::slotSetCategory( int c ) +{ + if ( c <= 0 ) + return; + for ( unsigned int i = 1; i < catMenu->count(); i++ ) + catMenu->setItemChecked( i, c == (int)i ); + if ( c == 1 ) { + abList->setShowCategory( QString::null ); + setCaption( tr("Contacts") + " - " + tr ( "All" ) ); + } else if ( c == (int)catMenu->count() ) { + abList->setShowCategory( tr( "Unfiled" ) ); + setCaption( tr("Contacts") + " - " + tr( "Unfiled" ) ); + } else { + QString cat = abList->categories()[c - 2]; + abList->setShowCategory( cat ); + setCaption( tr("Contacts") + " - " + cat ); + } +} + +void AddressbookWindow::populateCategories() +{ + catMenu->clear(); + + int id, + rememberId; + id = 1; + catMenu->insertItem( tr( "All" ), id++ ); + QStringList categories = abList->categories(); + categories.append( tr( "Unfiled" ) ); + for ( QStringList::Iterator it = categories.begin(); + it != categories.end(); ++it ) { + catMenu->insertItem( *it, id ); + if ( *it == abList->showCategory() ) + rememberId = id; + ++id; + } + if ( abList->showCategory().isEmpty() ) + slotSetCategory( 1 ); + else + slotSetCategory( rememberId ); +} diff --git a/core/pim/addressbook/addressbook.cw b/core/pim/addressbook/addressbook.cw new file mode 100644 index 0000000..452df36 --- a/dev/null +++ b/core/pim/addressbook/addressbook.cw @@ -0,0 +1,26 @@ +<!DOCTYPE CW><CW> +<customwidgets> + <customwidget> + <class>AbLineEdit</class> + <header location="local">ablineedit.h</header> + <sizehint> + <width>-1</width> + <height>-1</height> + </sizehint> + <pixmap> + <data format="XPM.GZ" length="646">789c6dd2c10ac2300c00d07bbf2234b7229d1be245fc04c5a3201e4615f430059d0711ff5ddb2e6bb236ec90eed134cb5a19d8ef36602af5ecdbfeeac05dda0798d3abebde87e3faa374d3807fa0d633a52d38d8de6f679fe33fc776e196f53cd010188256a3600a292882096246517815ca99884606e18044a3a40d91824820924265a7923a2e8bcd05f33db1173e002913175f2a6be6d3294871a2d95fa00e8a94ee017b69d339d90df1e77c57ea072ede6758</data> + </pixmap> + </customwidget> + <customwidget> + <class>AbMultiLineEdit</class> + <header location="local">abmultilineedit.h</header> + <sizehint> + <width>-1</width> + <height>-1</height> + </sizehint> + <pixmap> + <data format="XPM.GZ" length="646">789c6dd2c10ac2300c00d07bbf2234b7229d1be245fc04c5a3201e4615f430059d0711ff5ddb2e6bb236ec90eed134cb5a19d8ef36602af5ecdbfeeac05dda0798d3abebde87e3faa374d3807fa0d633a52d38d8de6f679fe33fc776e196f53cd010188256a3600a292882096246517815ca99884606e18044a3a40d91824820924265a7923a2e8bcd05f33db1173e002913175f2a6be6d3294871a2d95fa00e8a94ee017b69d339d90df1e77c57ea072ede6758</data> + </pixmap> + </customwidget> +</customwidgets> +</CW> diff --git a/core/pim/addressbook/addressbook.h b/core/pim/addressbook/addressbook.h new file mode 100644 index 0000000..9694465 --- a/dev/null +++ b/core/pim/addressbook/addressbook.h @@ -0,0 +1,99 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qt Palmtop Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef Addressbook_H +#define Addressbook_H + +#include <qmainwindow.h> + +class AbEditor; +class AbLabel; +class AbTable; +class QPEToolBar; +class QPopupMenu; +class QToolButton; +class QDialog; +class Ir; +class QAction; + +class AddressbookWindow: public QMainWindow +{ + Q_OBJECT +public: + AddressbookWindow( QWidget *parent = 0, const char *name = 0, WFlags f = 0 ); + ~AddressbookWindow(); + +protected: + void resizeEvent( QResizeEvent * e ); + void showList(); + void showView(); + enum EntryMode { NewEntry=0, EditEntry }; + void editPersonal(); + void editEntry( EntryMode ); + void closeEvent( QCloseEvent *e ); + bool save(); + +public slots: + void flush(); + void reload(); + void appMessage(const QCString &, const QByteArray &); + void setDocument( const QString & ); + +private slots: + void slotListNew(); + void slotListView(); + void slotListDelete(); + void slotViewBack(); + void slotViewEdit(); + void slotPersonalView(); + void listIsEmpty( bool ); + void slotSettings(); + void writeMail(); + void slotBeam(); + void beamDone( Ir * ); + void slotFind(); + void slotSetCategory( int ); + void slotUpdateToolbar(); + +private: + void initFields(); // inititialize our fields... + AbLabel *abView(); + void populateCategories(); + + QPopupMenu *catMenu; + QPEToolBar *listTools; + QToolButton *deleteButton; + QValueList<int> allFields, + orderedFields; + QStringList slOrderedFields; + enum Panes { paneList=0, paneView, paneEdit }; + AbEditor *abEditor; + AbLabel *mView; + AbTable *abList; + + QAction *actionNew, *actionEdit, *actionTrash, *actionFind, *actionBeam, + *actionPersonal, *actionMail; + + bool bAbEditFirstTime; + int viewMargin; + + bool syncing; +}; + +#endif diff --git a/core/pim/addressbook/addressbook.pro b/core/pim/addressbook/addressbook.pro new file mode 100644 index 0000000..8d3401d --- a/dev/null +++ b/core/pim/addressbook/addressbook.pro @@ -0,0 +1,22 @@ +TEMPLATE = app +CONFIG = qt warn_on release +DESTDIR = $(QPEDIR)/bin +HEADERS = addressbook.h \ + abeditor.h \ + ablabel.h \ + abtable.h \ + addresssettings.h +SOURCES = main.cpp \ + addressbook.cpp \ + abeditor.cpp \ + ablabel.cpp \ + abtable.cpp \ + addresssettings.cpp +INTERFACES = addresssettingsbase.ui + +TARGET = addressbook +INCLUDEPATH += $(QPEDIR)/include +DEPENDPATH += $(QPEDIR)/include +LIBS += -lqpe + +TRANSLATIONS = ../i18n/de/addressbook.ts diff --git a/core/pim/addressbook/addresspicker.cpp b/core/pim/addressbook/addresspicker.cpp new file mode 100644 index 0000000..79c4d43 --- a/dev/null +++ b/core/pim/addressbook/addresspicker.cpp @@ -0,0 +1,52 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qt Palmtop Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#include "addresspicker.h" +#include "abtable.h" + +#include <qlayout.h> + +/*! + \a tab is reparented for use in the picker. Take it back out if you want + to regain ownership. +*/ +AddressPicker::AddressPicker(AbTable* tab, QWidget* parent, const char* name, bool modal) : + QDialog(parent,name,modal) +{ + QVBoxLayout* vb = new QVBoxLayout(this); + tab->reparent(this,QPoint(0,0)); + table = tab; + vb->addWidget(table); +} + +void AddressPicker::setChoiceNames(const QStringList& list) +{ + table->setChoiceNames(list); +} + +void AddressPicker::setSelection(int index, const QStringList& list) +{ + table->setChoiceSelection(index,list); +} + +QStringList AddressPicker::selection(int index) const +{ + return table->choiceSelection(index); +} diff --git a/core/pim/addressbook/addresspicker.h b/core/pim/addressbook/addresspicker.h new file mode 100644 index 0000000..8a57479 --- a/dev/null +++ b/core/pim/addressbook/addresspicker.h @@ -0,0 +1,39 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qt Palmtop Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef AddressPicker_H +#define AddressPicker_H + +#include <qdialog.h> + +class AbTable; + +class AddressPicker : public QDialog { +public: + AddressPicker(AbTable* table, QWidget* parent, const char* name=0, bool modal=FALSE); + + void setChoiceNames(const QStringList&); + void setSelection(int index, const QStringList&); + QStringList selection(int index) const; + +private: + AbTable* table; +}; + +#endif diff --git a/core/pim/addressbook/addresssettings.cpp b/core/pim/addressbook/addresssettings.cpp new file mode 100644 index 0000000..e7c2210 --- a/dev/null +++ b/core/pim/addressbook/addresssettings.cpp @@ -0,0 +1,136 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qt Palmtop Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + + +#include "addresssettings.h" + +#include <qpe/config.h> +#include <qpe/contact.h> + +#include <qfile.h> +#include <qlistbox.h> + +#include <stdlib.h> + +AddressSettings::AddressSettings( QWidget *parent, const char *name ) + : AddressSettingsBase( parent, name, TRUE ) +{ + init(); +} + +AddressSettings::~AddressSettings() +{ +} + +void AddressSettings::init() +{ + QStringList slFields = Contact::trfields(); + // Make this match what is in initFields + slFields.remove( tr("Name Title") ); + slFields.remove( tr("First Name") ); + slFields.remove( tr("Last Name") ); + slFields.remove( tr("File As") ); + slFields.remove( tr("Default Email") ); + slFields.remove( tr("Notes") ); + slFields.remove( tr("Gender") ); + + + for( QStringList::Iterator it = slFields.begin(); + it != slFields.end(); ++it ) { + fieldListBox->insertItem( *it ); + } + + Config cfg( "AddressBook" ); + + cfg.setGroup( "Version" ); + int version; + version = cfg.readNumEntry( "version" ); + if ( version >= ADDRESSVERSION ) { + int i = 0; + int p = 0; + cfg.setGroup( "ImportantCategory" ); + QString zn = cfg.readEntry( "Category" + QString::number(i), + QString::null ); + while ( !zn.isNull() ) { + for ( int m = i; m < (int)fieldListBox->count(); m++ ) { + if ( fieldListBox->text( m ) == zn ) { + if ( m != p ) { + fieldListBox->removeItem( m ); + fieldListBox->insertItem( zn, p ); + } + p++; + break; + } + } + zn = cfg.readEntry( "Category" + QString::number(++i), + QString::null ); + } + + fieldListBox->setCurrentItem( 0 ); + } else { + QString str; + str = getenv("HOME"); + + str += "/Settings/AddressBook.conf"; + QFile::remove( str ); + } +} + +void AddressSettings::itemUp() +{ + int i = fieldListBox->currentItem(); + if ( i > 0 ) { + QString item = fieldListBox->currentText(); + fieldListBox->removeItem( i ); + fieldListBox->insertItem( item, i-1 ); + fieldListBox->setCurrentItem( i-1 ); + } +} + +void AddressSettings::itemDown() +{ + int i = fieldListBox->currentItem(); + if ( i < (int)fieldListBox->count() - 1 ) { + QString item = fieldListBox->currentText(); + fieldListBox->removeItem( i ); + fieldListBox->insertItem( item, i+1 ); + fieldListBox->setCurrentItem( i+1 ); + } +} + +void AddressSettings::accept() +{ + save(); + QDialog::accept(); +} + + +void AddressSettings::save() +{ + Config cfg( "AddressBook" ); + cfg.setGroup( "Version" ); + // *** To change the version change it here... + cfg.writeEntry( "version", QString::number(ADDRESSVERSION) ); + cfg.setGroup( "ImportantCategory" ); + + for ( int i = 0; i < (int)fieldListBox->count(); i++ ) { + cfg.writeEntry( "Category"+QString::number(i), fieldListBox->text(i) ); + } +} diff --git a/core/pim/addressbook/addresssettings.h b/core/pim/addressbook/addresssettings.h new file mode 100644 index 0000000..0fdfa77 --- a/dev/null +++ b/core/pim/addressbook/addresssettings.h @@ -0,0 +1,47 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qt Palmtop Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#ifndef _ADDRESSSETTINGS_H_ +#define _ADDRESSSETTINGS_H_ + +#include <qlist.h> +#include <qstringlist.h> +#include "addresssettingsbase.h" + +const int ADDRESSVERSION = 3; + +class AddressSettings : public AddressSettingsBase +{ + Q_OBJECT +public: + AddressSettings( QWidget *parent = 0, const char *name = 0 ); + ~AddressSettings(); + +protected: + void accept(); + virtual void itemUp(); + virtual void itemDown(); + +private: + void init(); + void save(); +}; + +#endif // _ADDRESSSETTINGS_H_ diff --git a/core/pim/addressbook/addresssettingsbase.ui b/core/pim/addressbook/addresssettingsbase.ui new file mode 100644 index 0000000..bd3b85b --- a/dev/null +++ b/core/pim/addressbook/addresssettingsbase.ui @@ -0,0 +1,170 @@ +<!DOCTYPE UI><UI> +<class>AddressSettingsBase</class> +<comment>/********************************************************************** +** Copyright (C) 2001 Trolltech AS. All rights reserved. +** +** This file is part of Qt Palmtop Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +** $Id$ +** +**********************************************************************/</comment> +<widget> + <class>QDialog</class> + <property stdset="1"> + <name>name</name> + <cstring>AddressSettingsBase</cstring> + </property> + <property stdset="1"> + <name>geometry</name> + <rect> + <x>0</x> + <y>0</y> + <width>244</width> + <height>207</height> + </rect> + </property> + <property stdset="1"> + <name>caption</name> + <string>Arrange Edit Fields</string> + </property> + <property> + <name>layoutMargin</name> + </property> + <property> + <name>layoutSpacing</name> + </property> + <grid> + <property stdset="1"> + <name>margin</name> + <number>6</number> + </property> + <property stdset="1"> + <name>spacing</name> + <number>6</number> + </property> + <widget row="1" column="0" rowspan="3" colspan="1" > + <class>QListBox</class> + <property stdset="1"> + <name>name</name> + <cstring>fieldListBox</cstring> + </property> + </widget> + <widget row="0" column="0" rowspan="1" colspan="2" > + <class>QLabel</class> + <property stdset="1"> + <name>name</name> + <cstring>lblExplain</cstring> + </property> + <property stdset="1"> + <name>sizePolicy</name> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>1</vsizetype> + </sizepolicy> + </property> + <property stdset="1"> + <name>frameShape</name> + <enum>MShape</enum> + </property> + <property stdset="1"> + <name>frameShadow</name> + <enum>MShadow</enum> + </property> + <property stdset="1"> + <name>text</name> + <string>Select the field order:</string> + </property> + <property stdset="1"> + <name>alignment</name> + <set>AlignTop|AlignLeft</set> + </property> + <property> + <name>hAlign</name> + </property> + <property> + <name>vAlign</name> + </property> + </widget> + <widget row="1" column="1" > + <class>QPushButton</class> + <property stdset="1"> + <name>name</name> + <cstring>upButton</cstring> + </property> + <property stdset="1"> + <name>text</name> + <string>Up</string> + </property> + <property stdset="1"> + <name>autoRepeat</name> + <bool>true</bool> + </property> + </widget> + <widget row="2" column="1" > + <class>QPushButton</class> + <property stdset="1"> + <name>name</name> + <cstring>downButton</cstring> + </property> + <property stdset="1"> + <name>text</name> + <string>Down</string> + </property> + <property stdset="1"> + <name>autoRepeat</name> + <bool>true</bool> + </property> + </widget> + <spacer row="3" column="1" > + <property> + <name>name</name> + <cstring>Spacer2</cstring> + </property> + <property stdset="1"> + <name>orientation</name> + <enum>Vertical</enum> + </property> + <property stdset="1"> + <name>sizeType</name> + <enum>Expanding</enum> + </property> + <property> + <name>sizeHint</name> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </grid> +</widget> +<connections> + <connection> + <sender>upButton</sender> + <signal>clicked()</signal> + <receiver>AddressSettingsBase</receiver> + <slot>itemUp()</slot> + </connection> + <connection> + <sender>downButton</sender> + <signal>clicked()</signal> + <receiver>AddressSettingsBase</receiver> + <slot>itemDown()</slot> + </connection> + <slot access="protected">itemUp()</slot> + <slot access="protected">itemDown()</slot> +</connections> +</UI> diff --git a/core/pim/addressbook/main.cpp b/core/pim/addressbook/main.cpp new file mode 100644 index 0000000..2ea1819 --- a/dev/null +++ b/core/pim/addressbook/main.cpp @@ -0,0 +1,41 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qt Palmtop Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#include "addressbook.h" + +#include <qpe/qpeapplication.h> +#include <qpe/qcopenvelope_qws.h> +#include <qstring.h> + +int main( int argc, char ** argv ) +{ + QPEApplication a( argc, argv ); + + AddressbookWindow mw; + QObject::connect( &a, SIGNAL( flush() ), &mw, SLOT( flush() ) ); + QObject::connect( &a, SIGNAL( reload() ), &mw, SLOT( reload() ) ); + QObject::connect( &a, SIGNAL( appMessage(const QCString &, const QByteArray &) ), + &mw, SLOT( appMessage(const QCString &, const QByteArray &) ) ); + + mw.setCaption( AddressbookWindow::tr("Contacts") ); + a.showMainDocumentWidget(&mw); + + return a.exec(); +} diff --git a/core/pim/addressbook/qpe-addressbook.control b/core/pim/addressbook/qpe-addressbook.control new file mode 100644 index 0000000..cca98f3 --- a/dev/null +++ b/core/pim/addressbook/qpe-addressbook.control @@ -0,0 +1,9 @@ +Files: bin/addressbook apps/Applications/addressbook.desktop +Priority: optional +Section: qpe/applications +Maintainer: Warwick Allison <warwick@trolltech.com> +Architecture: arm +Version: $QPE_VERSION-3 +Depends: qpe-base ($QPE_VERSION) +Description: Contacts + A simple addressbook for the Qtopia environment. |