summaryrefslogtreecommitdiff
path: root/core/pim/addressbook
Side-by-side diff
Diffstat (limited to 'core/pim/addressbook') (more/less context) (ignore whitespace changes)
-rw-r--r--core/pim/addressbook/.cvsignore16
-rw-r--r--core/pim/addressbook/Makefile.in244
-rw-r--r--core/pim/addressbook/abeditor.cpp619
-rw-r--r--core/pim/addressbook/abeditor.h79
-rw-r--r--core/pim/addressbook/ablabel.cpp53
-rw-r--r--core/pim/addressbook/ablabel.h50
-rw-r--r--core/pim/addressbook/abtable.cpp1091
-rw-r--r--core/pim/addressbook/abtable.h140
-rw-r--r--core/pim/addressbook/addressbook.cpp829
-rw-r--r--core/pim/addressbook/addressbook.cw26
-rw-r--r--core/pim/addressbook/addressbook.h99
-rw-r--r--core/pim/addressbook/addressbook.pro22
-rw-r--r--core/pim/addressbook/addresspicker.cpp52
-rw-r--r--core/pim/addressbook/addresspicker.h39
-rw-r--r--core/pim/addressbook/addresssettings.cpp136
-rw-r--r--core/pim/addressbook/addresssettings.h47
-rw-r--r--core/pim/addressbook/addresssettingsbase.ui170
-rw-r--r--core/pim/addressbook/main.cpp41
-rw-r--r--core/pim/addressbook/qpe-addressbook.control9
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.