summaryrefslogtreecommitdiff
path: root/core/pim/addressbook
authorkergoth <kergoth>2002-01-25 22:14:26 (UTC)
committer kergoth <kergoth>2002-01-25 22:14:26 (UTC)
commit15318cad33835e4e2dc620d033e43cd930676cdd (patch) (unidiff)
treec2fa0399a2c47fda8e2cd0092c73a809d17f68eb /core/pim/addressbook
downloadopie-15318cad33835e4e2dc620d033e43cd930676cdd.zip
opie-15318cad33835e4e2dc620d033e43cd930676cdd.tar.gz
opie-15318cad33835e4e2dc620d033e43cd930676cdd.tar.bz2
Initial revision
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 @@
1moc_*
2Makefile
3abeditorbase.h
4abaddress.h
5abcompanybase.h
6abnamebase.h
7abeditorbase.cpp
8abaddress.cpp
9abcompanybase.cpp
10abnamebase.cpp
11abeditorpage2base.ui
12abeditorpage2base.h
13abeditorpage2base.cpp
14addresssettingsbase.h
15addresssettingsbase.cpp
16
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 @@
1#############################################################################
2
3####### Compiler, tools and options
4
5 CXX =$(SYSCONF_CXX) $(QT_CXX_MT)
6 CXXFLAGS=$(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
7 CC =$(SYSCONF_CC) $(QT_C_MT)
8 CFLAGS =$(SYSCONF_CFLAGS)
9 INCPATH =-I$(QPEDIR)/include
10 LFLAGS =$(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
11 LIBS =$(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
12 MOC =$(SYSCONF_MOC)
13 UIC =$(SYSCONF_UIC)
14
15####### Target
16
17DESTDIR = $(QPEDIR)/bin/
18VER_MAJ = 1
19VER_MIN = 0
20VER_PATCH = 0
21 TARGET= addressbook
22TARGET1 = lib$(TARGET).so.$(VER_MAJ)
23
24####### Files
25
26 HEADERS =addressbook.h \
27 abeditor.h \
28 ablabel.h \
29 abtable.h \
30 addresssettings.h
31 SOURCES =main.cpp \
32 addressbook.cpp \
33 abeditor.cpp \
34 ablabel.cpp \
35 abtable.cpp \
36 addresssettings.cpp
37 OBJECTS =main.o \
38 addressbook.o \
39 abeditor.o \
40 ablabel.o \
41 abtable.o \
42 addresssettings.o \
43 addresssettingsbase.o
44INTERFACES = addresssettingsbase.ui
45UICDECLS = addresssettingsbase.h
46UICIMPLS = addresssettingsbase.cpp
47 SRCMOC =moc_addressbook.cpp \
48 moc_abeditor.cpp \
49 moc_ablabel.cpp \
50 moc_abtable.cpp \
51 moc_addresssettings.cpp \
52 moc_addresssettingsbase.cpp
53 OBJMOC =moc_addressbook.o \
54 moc_abeditor.o \
55 moc_ablabel.o \
56 moc_abtable.o \
57 moc_addresssettings.o \
58 moc_addresssettingsbase.o
59
60
61####### Implicit rules
62
63.SUFFIXES: .cpp .cxx .cc .C .c
64
65.cpp.o:
66 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
67
68.cxx.o:
69 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
70
71.cc.o:
72 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
73
74.C.o:
75 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
76
77.c.o:
78 $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
79
80####### Build rules
81
82
83all: $(DESTDIR)$(TARGET)
84
85$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
86 $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
87
88moc: $(SRCMOC)
89
90tmake:
91 tmake p4addressbook.pro
92
93clean:
94 -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
95 -rm -f *~ core
96 -rm -f allmoc.cpp
97
98####### Extension Modules
99
100listpromodules:
101 @echo
102
103listallmodules:
104 @echo
105
106listaddonpromodules:
107 @echo
108
109listaddonentmodules:
110 @echo
111
112
113REQUIRES=
114
115####### Sub-libraries
116
117
118###### Combined headers
119
120
121
122####### Compile
123
124main.o: main.cpp \
125 addressbook.h \
126 $(QPEDIR)/include/qpe/qpeapplication.h \
127 $(QPEDIR)/include/qpe/qcopenvelope_qws.h
128
129addressbook.o: addressbook.cpp \
130 abeditor.h \
131 $(QPEDIR)/include/qpe/contact.h \
132 $(QPEDIR)/include/qpe/palmtoprecord.h \
133 $(QPEDIR)/include/qpe/recordfields.h \
134 ablabel.h \
135 abtable.h \
136 $(QPEDIR)/include/qpe/categories.h \
137 addresssettings.h \
138 addresssettingsbase.h \
139 addressbook.h \
140 $(QPEDIR)/include/qpe/qpeapplication.h \
141 $(QPEDIR)/include/qpe/config.h \
142 $(QPEDIR)/include/qpe/finddialog.h \
143 $(QPEDIR)/include/qpe/global.h \
144 $(QPEDIR)/include/qpe/resource.h \
145 $(QPEDIR)/include/qpe/ir.h \
146 $(QPEDIR)/include/qpe/qpemessagebox.h \
147 $(QPEDIR)/include/qpe/qcopenvelope_qws.h \
148 $(QPEDIR)/include/qpe/qpemenubar.h \
149 $(QPEDIR)/include/qpe/qpetoolbar.h
150
151abeditor.o: abeditor.cpp \
152 abeditor.h \
153 $(QPEDIR)/include/qpe/contact.h \
154 $(QPEDIR)/include/qpe/palmtoprecord.h \
155 $(QPEDIR)/include/qpe/recordfields.h \
156 addresspicker.h \
157 $(QPEDIR)/include/qpe/categoryselect.h \
158 $(QPEDIR)/include/qpe/qpeapplication.h \
159 $(QPEDIR)/include/qpe/qpedialog.h
160
161ablabel.o: ablabel.cpp \
162 ablabel.h \
163 $(QPEDIR)/include/qpe/contact.h \
164 $(QPEDIR)/include/qpe/palmtoprecord.h \
165 $(QPEDIR)/include/qpe/recordfields.h \
166 $(QPEDIR)/include/qpe/stringutil.h
167
168abtable.o: abtable.cpp \
169 $(QPEDIR)/include/qpe/categoryselect.h \
170 $(QPEDIR)/include/qpe/config.h \
171 $(QPEDIR)/include/qpe/stringutil.h \
172 $(QPEDIR)/include/qpe/qcopenvelope_qws.h \
173 abtable.h \
174 $(QPEDIR)/include/qpe/categories.h \
175 $(QPEDIR)/include/qpe/contact.h \
176 $(QPEDIR)/include/qpe/palmtoprecord.h \
177 $(QPEDIR)/include/qpe/recordfields.h
178
179addresssettings.o: addresssettings.cpp \
180 addresssettings.h \
181 addresssettingsbase.h \
182 $(QPEDIR)/include/qpe/config.h \
183 $(QPEDIR)/include/qpe/contact.h \
184 $(QPEDIR)/include/qpe/palmtoprecord.h \
185 $(QPEDIR)/include/qpe/recordfields.h
186
187addresssettingsbase.h: addresssettingsbase.ui
188 $(UIC) addresssettingsbase.ui -o $(INTERFACE_DECL_PATH)/addresssettingsbase.h
189
190addresssettingsbase.cpp: addresssettingsbase.ui
191 $(UIC) addresssettingsbase.ui -i addresssettingsbase.h -o addresssettingsbase.cpp
192
193addresssettingsbase.o: addresssettingsbase.cpp \
194 addresssettingsbase.h \
195 addresssettingsbase.ui
196
197moc_addressbook.o: moc_addressbook.cpp \
198 addressbook.h
199
200moc_abeditor.o: moc_abeditor.cpp \
201 abeditor.h \
202 $(QPEDIR)/include/qpe/contact.h \
203 $(QPEDIR)/include/qpe/palmtoprecord.h \
204 $(QPEDIR)/include/qpe/recordfields.h
205
206moc_ablabel.o: moc_ablabel.cpp \
207 ablabel.h \
208 $(QPEDIR)/include/qpe/contact.h \
209 $(QPEDIR)/include/qpe/palmtoprecord.h \
210 $(QPEDIR)/include/qpe/recordfields.h
211
212moc_abtable.o: moc_abtable.cpp \
213 abtable.h \
214 $(QPEDIR)/include/qpe/categories.h \
215 $(QPEDIR)/include/qpe/contact.h \
216 $(QPEDIR)/include/qpe/palmtoprecord.h \
217 $(QPEDIR)/include/qpe/recordfields.h
218
219moc_addresssettings.o: moc_addresssettings.cpp \
220 addresssettings.h \
221 addresssettingsbase.h
222
223moc_addresssettingsbase.o: moc_addresssettingsbase.cpp \
224 addresssettingsbase.h
225
226moc_addressbook.cpp: addressbook.h
227 $(MOC) addressbook.h -o moc_addressbook.cpp
228
229moc_abeditor.cpp: abeditor.h
230 $(MOC) abeditor.h -o moc_abeditor.cpp
231
232moc_ablabel.cpp: ablabel.h
233 $(MOC) ablabel.h -o moc_ablabel.cpp
234
235moc_abtable.cpp: abtable.h
236 $(MOC) abtable.h -o moc_abtable.cpp
237
238moc_addresssettings.cpp: addresssettings.h
239 $(MOC) addresssettings.h -o moc_addresssettings.cpp
240
241moc_addresssettingsbase.cpp: addresssettingsbase.h
242 $(MOC) addresssettingsbase.h -o moc_addresssettingsbase.cpp
243
244
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qt Palmtop Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "abeditor.h"
22#include "addresspicker.h"
23
24#include <qpe/categoryselect.h>
25#include <qpe/qpeapplication.h>
26#include <qpe/qpedialog.h>
27
28#include <qcombobox.h>
29#include <qlabel.h>
30#include <qlayout.h>
31#include <qlineedit.h>
32#include <qmultilineedit.h>
33#include <qscrollview.h>
34#include <qtoolbutton.h>
35#include <qpushbutton.h>
36#include <qmainwindow.h>
37
38
39static inline bool containsAlphaNum( const QString &str );
40static inline bool constainsWhiteSpace( const QString &str );
41
42
43// helper functions, convert our comma delimited list to proper
44// file format...
45void parseEmailFrom( const QString &txt, QString &strDefaultEmail,
46 QString &strAll );
47
48// helper convert from file format to comma delimited...
49void parseEmailTo( const QString &strDefaultEmail,
50 const QString &strOtherEmail, QString &strBack );
51
52
53
54AbEditor::AbEditor( const Contact &entry, const QValueList<int> *newOrdered,
55 QStringList *slNewOrdered,
56 QWidget *parent = 0, const char *name = 0, WFlags fl = 0 )
57 : QDialog( parent, name, TRUE, fl ),
58 orderedValues( newOrdered ),
59 slOrdered( slNewOrdered )
60{
61 init();
62 initMap();
63 setEntry( entry );
64}
65
66AbEditor::~AbEditor()
67{
68}
69
70void AbEditor::init()
71{
72 middleEdit = 0;
73 QVBoxLayout *vb = new QVBoxLayout( this );
74 svPage = new QScrollView( this );
75 svPage->setHScrollBarMode( QScrollView::AlwaysOff );
76 vb->addWidget( svPage );
77 svPage->setResizePolicy( QScrollView::AutoOneFit );
78 svPage->setFrameStyle( QFrame::NoFrame );
79
80 QWidget *container = new QWidget( svPage->viewport() );
81 svPage->addChild( container );
82
83 QGridLayout *gl = new QGridLayout( container, 20, 2, 4, 2 );
84
85 QLabel *l = new QLabel( tr("First Name"), container );
86 gl->addWidget( l, 0, 0 );
87 firstEdit = new QLineEdit( container );
88 gl->addWidget( firstEdit, 0, 1 );
89
90 l = new QLabel( tr("Last Name"), container );
91 gl->addWidget( l, 1, 0 );
92 lastEdit = new QLineEdit( container );
93 gl->addWidget( lastEdit, 1, 1 );
94
95 l = new QLabel( tr("Categories"), container );
96 gl->addWidget( l, 2, 0 );
97
98 cmbCat = new CategorySelect( container );
99 gl->addWidget( cmbCat, 2, 1 );
100
101 int i;
102 bool foundGender,
103 foundNotes;
104 foundGender = foundNotes = false;
105 QStringList::ConstIterator it = slOrdered->begin();
106 for ( i = 0; it != slOrdered->end(); i++, ++it ) {
107 if ( !foundGender && *it == tr("Gender") ) {
108 foundGender = true;
109 } else if ( !foundNotes && *it == tr("Notes") ) {
110 foundNotes = true;
111 } else {
112 l = new QLabel( *it, container );
113 listName.append( l );
114 gl->addWidget( l, i + 3, 0 );
115 QLineEdit *e = new QLineEdit( container );
116 listValue.append( e );
117 gl->addWidget( e, i + 3, 1 );
118 if ( *it == tr( "Middle Name" ) )
119 middleEdit = e;
120 }
121 }
122 l = new QLabel( tr("Gender"), container );
123 gl->addWidget( l, slOrdered->count() + 3, 0 );
124 genderCombo = new QComboBox( container );
125 genderCombo->insertItem( "", 0 );
126 genderCombo->insertItem( tr( "Male" ), 1 );
127 genderCombo->insertItem( tr( "Female" ), 2 );
128 gl->addWidget( genderCombo, slOrdered->count() + 3, 1 );
129
130 dlgNote = new QDialog( this, "Note Dialog", TRUE );
131 dlgNote->setCaption( tr("Enter Note") );
132 QVBoxLayout *vbNote = new QVBoxLayout( dlgNote );
133 // lblNote = new QLabel( dlgNote );
134 // lblNote->setMinimumSize( lblNote->sizeHint() + QSize( 0, 4 ) );
135 // vbNote->addWidget( lblNote );
136 txtNote = new QMultiLineEdit( dlgNote );
137 vbNote->addWidget( txtNote );
138
139 QHBoxLayout *hb = new QHBoxLayout( vb );
140 hb->addStretch( 2 );
141 QPushButton *pb = new QPushButton( tr("Notes..."), this );
142 hb->addWidget( pb );
143 connect( pb, SIGNAL(clicked()), this, SLOT(slotNote()) );
144
145 new QPEDialogListener(this);
146}
147
148void AbEditor::initMap()
149{
150 /*
151 // since the fields and the XML fields exist, create a map
152 // between them...
153 Config cfg1( "AddressBook" );
154 Config cfg2( "AddressBook" );
155 QString strCfg1,
156 strCfg2;
157 int i;
158
159 // This stuff better exist...
160 cfg1.setGroup( "AddressFields" );
161 cfg2.setGroup( "XMLFields" );
162 i = 0;
163 strCfg1 = cfg1.readEntry( "Field" + QString::number(i), QString::null );
164 strCfg2 = cfg2.readEntry( "XMLField" + QString::number(i++),
165 QString::null );
166 while ( !strCfg1.isNull() && !strCfg2.isNull() ) {
167 mapField.insert( strCfg1, strCfg2 );
168 strCfg1 = cfg1.readEntry( "Field" + QString::number(i),
169 QString::null );
170 strCfg2 = cfg2.readEntry( "XMLField" + QString::number(i++),
171 QString::null );
172 }
173 */
174}
175
176void AbEditor::loadFields()
177{
178 QStringList::ConstIterator it;
179 QListIterator<QLabel> lit( listName );
180 for ( it = slOrdered->begin(); *lit; ++lit, ++it ) {
181 (*lit)->setText( *it );
182 }
183}
184
185void AbEditor::setEntry( const Contact &entry )
186{
187 ent = entry;
188 QListIterator<QLineEdit> it( listValue );
189 firstEdit->setText( ent.firstName() );
190 lastEdit->setText( ent.lastName() );
191 cmbCat->setCategories( ent.categories(), "Contacts", tr("Contacts") );
192
193 // ### Fix...
194 QValueList<int>::ConstIterator itVl;
195 for ( itVl = orderedValues->begin(); *it && itVl != orderedValues->end();
196 ++itVl, ++it ) {
197 switch( *itVl ) {
198 case Qtopia::Title:
199 (*it)->setText(ent.title());
200 break;
201 case Qtopia::MiddleName:
202 (*it)->setText( ent.middleName() );
203 break;
204 case Qtopia::Suffix:
205 (*it)->setText( ent.suffix() );
206 break;
207
208 // email
209 case Qtopia::DefaultEmail:
210 case Qtopia::Emails:
211 {
212 QString strDefEmail = ent.defaultEmail();
213 QString strAllEmail = ent.emails();
214 QString strFinal;
215 parseEmailTo( strDefEmail, strAllEmail, strFinal );
216 (*it)->setText( strFinal );
217 // make sure we see the "default"
218 (*it)->home( false );
219 break;
220 }
221
222 // home
223 case Qtopia::HomeStreet:
224 (*it)->setText(ent.homeStreet() );
225 break;
226 case Qtopia::HomeCity:
227 (*it)->setText( ent.homeCity() );
228 break;
229 case Qtopia::HomeState:
230 (*it)->setText( ent.homeState() );
231 break;
232 case Qtopia::HomeZip:
233 (*it)->setText( ent.homeZip() );
234 break;
235 case Qtopia::HomeCountry:
236 (*it)->setText( ent.homeCountry() );
237 break;
238 case Qtopia::HomePhone:
239 (*it)->setText( ent.homePhone() );
240 break;
241 case Qtopia::HomeFax:
242 (*it)->setText( ent.homeFax() );
243 break;
244 case Qtopia::HomeMobile:
245 (*it)->setText( ent.homeMobile() );
246 break;
247 case Qtopia::HomeWebPage:
248 (*it)->setText( ent.homeWebpage() );
249 break;
250
251 // business
252 case Qtopia::Company:
253 (*it)->setText( ent.company() );
254 break;
255 case Qtopia::BusinessStreet:
256 (*it)->setText( ent.businessStreet() );
257 break;
258 case Qtopia::BusinessCity:
259 (*it)->setText( ent.businessCity() );
260 break;
261 case Qtopia::BusinessState:
262 (*it)->setText( ent.businessState() );
263 break;
264 case Qtopia::BusinessZip:
265 (*it)->setText( ent.businessZip() );
266 break;
267 case Qtopia::BusinessCountry:
268 (*it)->setText( ent.businessCountry() );
269 break;
270 case Qtopia::BusinessWebPage:
271 (*it)->setText( ent.businessWebpage() );
272 break;
273 case Qtopia::JobTitle:
274 (*it)->setText( ent.jobTitle() );
275 break;
276 case Qtopia::Department:
277 (*it)->setText( ent.department() );
278 break;
279 case Qtopia::Office:
280 (*it)->setText( ent.office() );
281 break;
282 case Qtopia::BusinessPhone:
283 (*it)->setText( ent.businessPhone() );
284 break;
285 case Qtopia::BusinessFax:
286 (*it)->setText( ent.businessFax() );
287 break;
288 case Qtopia::BusinessMobile:
289 (*it)->setText( ent.businessMobile() );
290 break;
291 case Qtopia::BusinessPager:
292 (*it)->setText( ent.businessPager() );
293 break;
294 case Qtopia::Profession:
295 (*it)->setText( ent.profession() );
296 break;
297 case Qtopia::Assistant:
298 (*it)->setText( ent.assistant() );
299 break;
300 case Qtopia::Manager:
301 (*it)->setText( ent.manager() );
302 break;
303
304 // personal
305 case Qtopia::Spouse:
306 (*it)->setText( ent.spouse() );
307 break;
308 case Qtopia::Children:
309 (*it)->setText( ent.children() );
310 break;
311 case Qtopia::Birthday:
312 (*it)->setText( ent.birthday() );
313 break;
314 case Qtopia::Anniversary:
315 (*it)->setText( ent.anniversary() );
316 break;
317 case Qtopia::Nickname:
318 (*it)->setText( ent.nickname() );
319 break;
320
321 }
322 }
323
324 QString gender = ent.gender();
325 genderCombo->setCurrentItem( gender.toInt() );
326
327 txtNote->setText( ent.notes() );
328}
329
330void AbEditor::accept()
331{
332 if ( isEmpty() )
333 reject();
334 else {
335 saveEntry();
336 QDialog::accept();
337 }
338}
339
340bool AbEditor::isEmpty()
341{
342 // analyze all the fields and make sure there is _something_ there
343 // that warrants saving...
344 QString t = firstEdit->text();
345 if ( !t.isEmpty() && containsAlphaNum( t ) )
346 return false;
347
348 t = lastEdit->text();
349 if ( !t.isEmpty() && containsAlphaNum( t ) )
350 return false;
351
352 QListIterator<QLineEdit> it( listValue );
353 for ( ; it.current(); ++it ) {
354 t = it.current()->text();
355 if ( !t.isEmpty() && containsAlphaNum( t ) )
356 return false;
357 }
358
359 t = txtNote->text();
360 if ( !t.isEmpty() && containsAlphaNum( t ) )
361 return false;
362
363 return true;
364}
365
366void AbEditor::saveEntry()
367{
368 QString strDefaultEmail, strOtherEmail;
369
370 // determine if there has been a change in names
371 if ( ent.firstName() != firstEdit->text() ||
372 ent.lastName() != lastEdit->text()
373 || (middleEdit && ent.middleName() != middleEdit->text()) ) {
374 // set the names
375 ent.setFirstName( firstEdit->text() );
376 ent.setLastName( lastEdit->text() );
377 if ( middleEdit )
378 ent.setMiddleName( middleEdit->text() );
379 ent.setFileAs();
380 }
381
382 ent.setCategories( cmbCat->currentCategories() );
383
384 QListIterator<QLineEdit> it( listValue );
385 int i;
386 QValueList<int>::ConstIterator<int> vlIt;
387 for ( i = 0, vlIt = orderedValues->begin();
388 it.current(); ++it, ++vlIt, i++ ) {
389 switch( *vlIt ) {
390 case Qtopia::Title:
391 ent.setTitle( it.current()->text() );
392 break;
393 case Qtopia::MiddleName:
394 ent.setMiddleName( it.current()->text() );
395 break;
396 case Qtopia::Suffix:
397 ent.setSuffix( it.current()->text() );
398 break;
399 // case Qtopia::Category:
400 // {
401 // // QStringList slCat = QStringList::split( ";", value );
402 // // QValueList<int> cat;
403 // // for ( QStringList::ConstIterator it = slCat.begin();
404 // // it != slCat.end(); ++it )
405 // // cat.append( (*it).toInt() );
406 // // ent.setCategories( cat );
407 // }
408 // break;
409
410 // email
411 case Qtopia::DefaultEmail:
412 case Qtopia::Emails:
413 parseEmailFrom( it.current()->text(), strDefaultEmail,
414 strOtherEmail );
415 ent.setDefaultEmail( strDefaultEmail );
416 ent.setEmails( strOtherEmail );
417 break;
418
419 // home
420 case Qtopia::HomeStreet:
421 ent.setHomeStreet( it.current()->text() );
422 break;
423 case Qtopia::HomeCity:
424 ent.setHomeCity( it.current()->text() );
425 break;
426 case Qtopia::HomeState:
427 ent.setHomeState( it.current()->text() );
428 break;
429 case Qtopia::HomeZip:
430 ent.setHomeZip( it.current()->text() );
431 break;
432 case Qtopia::HomeCountry:
433 ent.setHomeCountry( it.current()->text() );
434 break;
435 case Qtopia::HomePhone:
436 ent.setHomePhone( it.current()->text() );
437 break;
438 case Qtopia::HomeFax:
439 ent.setHomeFax( it.current()->text() );
440 break;
441 case Qtopia::HomeMobile:
442 ent.setHomeMobile( it.current()->text() );
443 break;
444 case Qtopia::HomeWebPage:
445 ent.setHomeWebpage( it.current()->text() );
446 break;
447
448 // business
449 case Qtopia::Company:
450 ent.setCompany( it.current()->text() );
451 break;
452 case Qtopia::BusinessStreet:
453 ent.setBusinessStreet( it.current()->text() );
454 break;
455 case Qtopia::BusinessCity:
456 ent.setBusinessCity( it.current()->text() );
457 break;
458 case Qtopia::BusinessState:
459 ent.setBusinessState( it.current()->text() );
460 break;
461 case Qtopia::BusinessZip:
462 ent.setBusinessZip( it.current()->text() );
463 break;
464 case Qtopia::BusinessCountry:
465 ent.setBusinessCountry( it.current()->text() );
466 break;
467 case Qtopia::BusinessWebPage:
468 ent.setBusinessWebpage( it.current()->text() );
469 break;
470 case Qtopia::JobTitle:
471 ent.setJobTitle( it.current()->text() );
472 break;
473 case Qtopia::Department:
474 ent.setDepartment( it.current()->text() );
475 break;
476 case Qtopia::Office:
477 ent.setOffice( it.current()->text() );
478 break;
479 case Qtopia::BusinessPhone:
480 ent.setBusinessPhone( it.current()->text() );
481 break;
482 case Qtopia::BusinessFax:
483 ent.setBusinessFax( it.current()->text() );
484 break;
485 case Qtopia::BusinessMobile:
486 ent.setBusinessMobile( it.current()->text() );
487 break;
488 case Qtopia::BusinessPager:
489 ent.setBusinessPager( it.current()->text() );
490 break;
491 case Qtopia::Profession:
492 ent.setProfession( it.current()->text() );
493 break;
494 case Qtopia::Assistant:
495 ent.setAssistant( it.current()->text() );
496 break;
497 case Qtopia::Manager:
498 ent.setManager( it.current()->text() );
499 break;
500
501 // personal
502 case Qtopia::Spouse:
503 ent.setSpouse( it.current()->text() );
504 break;
505 case Qtopia::Children:
506 ent.setChildren( it.current()->text() );
507 break;
508 case Qtopia::Birthday:
509 ent.setBirthday( it.current()->text() );
510 break;
511 case Qtopia::Anniversary:
512 ent.setAnniversary( it.current()->text() );
513 break;
514 case Qtopia::Nickname:
515 ent.setNickname( it.current()->text() );
516 break;
517 default:
518 break;
519
520 }
521 }
522
523 int gender = genderCombo->currentItem();
524 ent.setGender( QString::number( gender ) );
525
526 QString str = txtNote->text();
527 if ( !str.isNull() )
528 ent.setNotes( str );
529}
530
531void AbEditor::slotNote()
532{
533 dlgNote->showMaximized();
534 if ( !dlgNote->exec() ) {
535 // reset the note...
536 txtNote->setText( ent.notes() );
537 }
538}
539
540void AbEditor::setNameFocus()
541{
542 firstEdit->setFocus();
543}
544
545void parseEmailFrom( const QString &txt, QString &strDefaultEmail,
546 QString &strAll )
547{
548 int where,
549 start;
550 if ( txt.isEmpty() )
551 return;
552 // find the first
553 where = txt.find( ',' );
554 if ( where < 0 ) {
555 strDefaultEmail = txt;
556 strAll = txt;
557 } else {
558 strDefaultEmail = txt.left( where ).stripWhiteSpace();
559 strAll = strDefaultEmail;
560 while ( where > -1 ) {
561 strAll.append(" ");
562 start = where;
563 where = txt.find( ',', where + 1 );
564 if ( where > - 1 )
565 strAll.append( txt.mid(start + 1, where - start - 1).stripWhiteSpace() );
566 else // grab until the end...
567 strAll.append( txt.right(txt.length() - start - 1).stripWhiteSpace() );
568 }
569 }
570}
571
572void parseEmailTo( const QString &strDefaultEmail,
573 const QString &strOtherEmail, QString &strBack )
574{
575 // create a comma dilimeted set of emails...
576 // use the power of short circuiting...
577 bool foundDefault = false;
578 QString strTmp;
579 int start = 0;
580 int where;
581 // start at the beginng.
582 strBack = strDefaultEmail;
583 where = 0;
584 while ( where > -1 ) {
585 start = where;
586 where = strOtherEmail.find( ' ', where + 1 );
587 if ( where > 0 ) {
588 strTmp = strOtherEmail.mid( start, where - start ).stripWhiteSpace();
589 } else
590 strTmp = strOtherEmail.right( strOtherEmail.length() - start ).stripWhiteSpace();
591 if ( foundDefault || strTmp != strDefaultEmail ) {
592 strBack.append( ", " );
593 strBack.append( strTmp );
594 } else
595 foundDefault = true;
596 }
597}
598
599
600static inline bool containsAlphaNum( const QString &str )
601{
602 int i,
603 count = str.length();
604 for ( i = 0; i < count; i++ )
605 if ( !str[i].isSpace() )
606 return TRUE;
607 return FALSE;
608}
609
610static inline bool constainsWhiteSpace( const QString &str )
611{
612 int i,
613 count = str.length();
614 for (i = 0; i < count; i++ )
615 if ( str[i].isSpace() )
616 return TRUE;
617 return FALSE;
618}
619
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qt Palmtop Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef ABEDITOR_H
21#define ABEDITOR_H
22
23#include <qpe/contact.h>
24
25#include <qdialog.h>
26#include <qlist.h>
27#include <qmap.h>
28#include <qstringlist.h>
29
30class QScrollView;
31class QMultiLineEdit;
32class QLineEdit;
33class QLabel;
34class QComboBox;
35class CategorySelect;
36
37class AbEditor : public QDialog
38{
39 Q_OBJECT
40public:
41 AbEditor( const Contact &entry, const QValueList<int> *newOrdedValues,
42 QStringList *slNewOrdered,
43 QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );
44 ~AbEditor();
45 void loadFields();
46 void setNameFocus();
47 Contact entry() const { return ent; }
48
49public slots:
50 void slotNote();
51 void setEntry( const Contact &entry );
52
53protected slots:
54 void accept();
55
56private:
57 void init();
58 void initMap();
59 void saveEntry();
60 bool isEmpty();
61
62private:
63 QDialog *dlgNote;
64 QLabel *lblNote;
65 QMultiLineEdit *txtNote;
66 Contact ent;
67 QScrollView *svPage;
68 QLineEdit *firstEdit;
69 QLineEdit *lastEdit;
70 QLineEdit *middleEdit;
71 QComboBox *genderCombo;
72 QList<QLineEdit> listValue;
73 QList<QLabel> listName;
74 const QValueList<int> *orderedValues;
75 QStringList *slOrdered;
76 CategorySelect *cmbCat;
77};
78
79#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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qt Palmtop Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "ablabel.h"
22
23#include <qpe/stringutil.h>
24
25#include <qregexp.h>
26#include <qstylesheet.h>
27
28AbLabel::AbLabel( QWidget *parent, const char *name )
29 : QTextView( parent, name )
30{
31}
32
33AbLabel::~AbLabel()
34{
35}
36
37void AbLabel::init( const Contact &entry )
38{
39 ent = entry;
40}
41
42void AbLabel::sync()
43{
44 QString text = ent.toRichText();
45 setText( text );
46}
47
48void AbLabel::keyPressEvent( QKeyEvent *e )
49{
50 if ( e->key() == Qt::Key_F33 ) {
51 emit okPressed();
52 }
53}
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qt Palmtop Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef ABLABEL_H
21#define ABLABEL_H
22
23#include <qpe/contact.h>
24#include <qtextview.h>
25
26class AbLabel : public QTextView
27{
28 Q_OBJECT
29
30public:
31 AbLabel( QWidget *parent, const char *name = 0 );
32 ~AbLabel();
33
34public slots:
35 void init( const Contact &entry );
36 void sync();
37
38signals:
39 void okPressed();
40
41protected:
42 void keyPressEvent( QKeyEvent * );
43
44private:
45 Contact ent;
46
47};
48
49#endif // ABLABEL_H
50
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qt Palmtop Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include <qpe/categoryselect.h>
22#include <qpe/config.h>
23#include <qpe/stringutil.h>
24#include <qpe/qcopenvelope_qws.h>
25
26#include <qasciidict.h>
27#include <qdatetime.h>
28#include <qfile.h>
29
30#include "abtable.h"
31
32#include <errno.h>
33#include <fcntl.h>
34#include <unistd.h>
35#include <stdlib.h>
36
37#include <ctype.h> //toupper() for key hack
38
39static bool contactCompare( const Contact &cnt, const QRegExp &r, int category );
40
41//### qtmail/addresslist.cpp hardcodes this filename as well
42static QString journalFileName()
43{
44 QString str = getenv("HOME");
45 str +="/.abjournal";
46 return str;
47}
48
49
50
51/*!
52 \class AbTableItem abtable.h
53
54 \brief QTableItem based class for showing a field of an entry
55*/
56
57AbTableItem::AbTableItem( QTable *t, EditType et, const QString &s,
58 const QString &secondSortKey)
59 : QTableItem( t, et, s )
60{
61 // sortKey = s.lower() + QChar( '\0' ) + secondSortKey.lower();
62 sortKey = Qtopia::buildSortKey( s, secondSortKey );
63}
64
65int AbTableItem::alignment() const
66{
67 return AlignLeft|AlignVCenter;
68}
69
70QString AbTableItem::key() const
71{
72 return sortKey;
73}
74
75// A way to reset the item, without out doing a delete or a new...
76void AbTableItem::setItem( const QString &txt, const QString &secondKey )
77{
78 setText( txt );
79 sortKey = Qtopia::buildSortKey( txt, secondKey );
80
81 // sortKey = txt.lower() + QChar( '\0' ) + secondKey.lower();
82}
83
84/*!
85 \class AbPickItem abtable.h
86
87 \brief QTableItem based class for showing slection of an entry
88*/
89
90AbPickItem::AbPickItem( QTable *t ) :
91 QTableItem(t, WhenCurrent, "?")
92{
93}
94
95QWidget *AbPickItem::createEditor() const
96{
97 QComboBox* combo = new QComboBox( table()->viewport() );
98 ( (AbPickItem*)this )->cb = combo;
99 AbTable* t = static_cast<AbTable*>(table());
100 QStringList c = t->choiceNames();
101 int cur = 0;
102 for (QStringList::ConstIterator it = c.begin(); it!=c.end(); ++it) {
103 if ( *it == text() )
104 cur = combo->count();
105 combo->insertItem(*it);
106 }
107 combo->setCurrentItem(cur);
108 return combo;
109}
110
111void AbPickItem::setContentFromEditor( QWidget *w )
112{
113 if ( w->inherits("QComboBox") )
114 setText( ( (QComboBox*)w )->currentText() );
115 else
116 QTableItem::setContentFromEditor( w );
117}
118
119/*!
120 \class AbTable abtable.h
121
122 \brief QTable based class for showing a list of entries
123*/
124
125AbTable::AbTable( const QValueList<int> *order, QWidget *parent, const char *name )
126// #ifdef QT_QTABLE_NOHEADER_CONSTRUCTOR
127// : QTable( 0, 0, parent, name, TRUE ),
128// #else
129 : QTable( parent, name ),
130// #endif
131 lastSortCol( -1 ),
132 asc( TRUE ),
133 intFields( order ),
134 currFindRow( -2 ),
135 mCat( 0 )
136{
137 mCat.load( categoryFileName() );
138 setSelectionMode( NoSelection );
139 init();
140 setSorting( TRUE );
141 connect( this, SIGNAL(clicked(int,int,int,const QPoint &)),
142 this, SLOT(itemClicked(int,int)) );
143}
144
145AbTable::~AbTable()
146{
147}
148
149void AbTable::init()
150{
151 setNumRows( 0 );
152 setNumCols( 2 );
153
154 horizontalHeader()->setLabel( 0, tr( "Full Name" ));
155 horizontalHeader()->setLabel( 1, tr( "Contact" ));
156 setLeftMargin( 0 );
157 verticalHeader()->hide();
158}
159
160void AbTable::columnClicked( int col )
161{
162 if ( !sorting() )
163 return;
164
165 if ( lastSortCol == -1 )
166 lastSortCol = col;
167
168 if ( col == lastSortCol ) {
169 asc = !asc;
170 } else {
171 lastSortCol = col;
172 asc = TRUE;
173 }
174 resort();
175}
176
177void AbTable::resort()
178{
179 if ( sorting() ) {
180 if ( lastSortCol == -1 )
181 lastSortCol = 0;
182 sortColumn( lastSortCol, asc, TRUE );
183 updateVisible();
184 }
185}
186
187Contact AbTable::currentEntry()
188{
189 Contact cnt;
190 AbTableItem *abItem;
191 abItem = static_cast<AbTableItem*>(item( currentRow(), 0 ));
192 if ( abItem ) {
193 cnt = contactList[abItem];
194 }
195 return cnt;
196}
197
198void AbTable::replaceCurrentEntry( const Contact &newContact )
199{
200 int row = currentRow();
201 updateJournal( newContact, Contact::ACTION_REPLACE, row );
202 updateVisible();
203
204 journalFreeReplace( newContact, row );
205}
206
207void AbTable::deleteCurrentEntry()
208{
209 int row = currentRow();
210 AbTableItem *abItem;
211 abItem = static_cast<AbTableItem*>(item( row, 0 ));
212 Contact oldContact;
213 oldContact = contactList[abItem];
214 updateJournal( oldContact, Contact::ACTION_REMOVE, row );
215
216 // a little wasteful, but it ensure's there is only one place
217 // where we delete.
218 journalFreeRemove( row );
219 updateVisible();
220
221 if ( numRows() == 0 )
222 emit empty( TRUE );
223}
224
225void AbTable::clear()
226{
227 contactList.clear();
228 for ( int r = 0; r < numRows(); ++r ) {
229 for ( int c = 0; c < numCols(); ++c ) {
230 if ( cellWidget( r, c ) )
231 clearCellWidget( r, c );
232 clearCell( r, c );
233 }
234 }
235 setNumRows( 0 );
236}
237
238void AbTable::refresh()
239{
240 int rows = numRows();
241 QString value;
242 AbTableItem *abi;
243 for ( int r = 0; r < rows; ++r ) {
244 abi = static_cast<AbTableItem*>( item(r, 0) );
245 value = findContactContact( contactList[abi] );
246 static_cast<AbTableItem*>( item(r, 1) )->setItem( value, abi->text() );
247 }
248 resort();
249}
250
251void AbTable::keyPressEvent( QKeyEvent *e )
252{
253 char key = toupper( e->ascii() );
254
255 if ( key >= 'A' && key <= 'Z' )
256 moveTo( key );
257
258 switch( e->key() ) {
259 case Qt::Key_Space:
260 case Qt::Key_Return:
261 case Qt::Key_Enter:
262 emit details();
263 break;
264 default:
265 QTable::keyPressEvent( e );
266 }
267}
268
269void AbTable::moveTo( char c )
270{
271
272 int rows = numRows();
273 QString value;
274 AbTableItem *abi;
275 int r;
276 if ( asc ) {
277 r = 0;
278 while ( r < rows-1) {
279 abi = static_cast<AbTableItem*>( item(r, 0) );
280 QChar first = abi->key()[0];
281 //### is there a bug in QChar to char comparison???
282 if ( first.row() || first.cell() >= c )
283 break;
284 r++;
285 }
286 } else {
287 //### should probably disable reverse sorting instead
288 r = rows - 1;
289 while ( r > 0 ) {
290 abi = static_cast<AbTableItem*>( item(r, 0) );
291 QChar first = abi->key()[0];
292 //### is there a bug in QChar to char comparison???
293 if ( first.row() || first.cell() >= c )
294 break;
295 r--;
296 }
297 }
298 setCurrentCell( r, currentColumn() );
299}
300
301
302QString AbTable::findContactName( const Contact &entry )
303{
304 // We use the fileAs, then company, defaultEmail
305 QString str;
306 str = entry.fileAs();
307 if ( str.isEmpty() ) {
308 str = entry.company();
309 if ( str.isEmpty() ) {
310 str = entry.defaultEmail();
311 }
312 }
313 return str;
314}
315
316QString AbTable::findContactContact( const Contact &entry )
317{
318 QString value;
319 value = "";
320 for ( QValueList<int>::ConstIterator it = intFields->begin();
321 it != intFields->end(); ++it ) {
322 switch ( *it ) {
323 default:
324 break;
325 case Qtopia::Title:
326 value = entry.title();
327 break;
328 case Qtopia::Suffix:
329 value = entry.suffix();
330 break;
331 case Qtopia::FileAs:
332 value = entry.fileAs();
333 break;
334 case Qtopia::DefaultEmail:
335 value = entry.defaultEmail();
336 case Qtopia::Emails:
337 value = entry.emails();
338 break;
339 case Qtopia::HomeStreet:
340 value = entry.homeStreet();
341 break;
342 case Qtopia::HomeCity:
343 value = entry.homeCity();
344 break;
345 case Qtopia::HomeState:
346 value = entry.homeState();
347 break;
348 case Qtopia::HomeZip:
349 value = entry.homeZip();
350 break;
351 case Qtopia::HomeCountry:
352 value = entry.homeCountry();
353 break;
354 case Qtopia::HomePhone:
355 value = entry.homePhone();
356 break;
357 case Qtopia::HomeFax:
358 value = entry.homeFax();
359 break;
360 case Qtopia::HomeMobile:
361 value = entry.homeMobile();
362 break;
363 case Qtopia::HomeWebPage:
364 value = entry.homeWebpage();
365 break;
366 case Qtopia::Company:
367 value = entry.company();
368 break;
369 case Qtopia::BusinessCity:
370 value = entry.businessCity();
371 break;
372 case Qtopia::BusinessStreet:
373 value = entry.businessStreet();
374 break;
375 case Qtopia::BusinessZip:
376 value = entry.businessZip();
377 break;
378 case Qtopia::BusinessCountry:
379 value = entry.businessCountry();
380 break;
381 case Qtopia::BusinessWebPage:
382 value = entry.businessWebpage();
383 break;
384 case Qtopia::JobTitle:
385 value = entry.jobTitle();
386 break;
387 case Qtopia::Department:
388 value = entry.department();
389 break;
390 case Qtopia::Office:
391 value = entry.office();
392 break;
393 case Qtopia::BusinessPhone:
394 value = entry.businessPhone();
395 break;
396 case Qtopia::BusinessFax:
397 value = entry.businessFax();
398 break;
399 case Qtopia::BusinessMobile:
400 value = entry.businessMobile();
401 break;
402 case Qtopia::BusinessPager:
403 value = entry.businessPager();
404 break;
405 case Qtopia::Profession:
406 value = entry.profession();
407 break;
408 case Qtopia::Assistant:
409 value = entry.assistant();
410 break;
411 case Qtopia::Manager:
412 value = entry.manager();
413 break;
414 case Qtopia::Spouse:
415 value = entry.spouse();
416 break;
417 case Qtopia::Gender:
418 value = entry.gender();
419 break;
420 case Qtopia::Birthday:
421 value = entry.birthday();
422 break;
423 case Qtopia::Anniversary:
424 value = entry.anniversary();
425 break;
426 case Qtopia::Nickname:
427 value = entry.nickname();
428 break;
429 case Qtopia::Children:
430 value = entry.children();
431 break;
432 case Qtopia::Notes:
433 value = entry.notes();
434 break;
435 }
436 if ( !value.isEmpty() )
437 break;
438 }
439 return value;
440}
441
442void AbTable::addEntry( const Contact &newCnt )
443{
444 int row = numRows();
445 setNumRows( row + 1 );
446 updateJournal( newCnt, Contact::ACTION_ADD );
447 insertIntoTable( newCnt, row );
448 setCurrentCell( row, 0 );
449 updateVisible();
450}
451
452void AbTable::updateJournal( const Contact &cnt,
453 Contact::journal_action action, int row )
454{
455 QFile f( journalFileName() );
456 if ( !f.open(IO_WriteOnly|IO_Append) )
457 return;
458 QString buf;
459 QCString str;
460 buf = "<Contact ";
461 cnt.save( buf );
462 buf += " action=\"" + QString::number( (int)action ) + "\" ";
463 if ( action == Contact::ACTION_REMOVE || action == Contact::ACTION_REPLACE)
464 buf += " actionrow=\"" + QString::number(row) + "\" ";
465 buf += "/>\n";
466 QCString cstr = buf.utf8();
467 f.writeBlock( cstr.data(), cstr.length() );
468 QCopEnvelope( "QPE/PIM", "addressbookUpdated()" );
469}
470
471bool AbTable::save( const QString &fn )
472{
473// QTime t;
474// t.start();
475
476 QString strNewFile = fn + ".new";
477 QFile f( strNewFile );
478 if ( !f.open( IO_WriteOnly|IO_Raw ) )
479 return false;
480
481 int total_written;
482 QString out;
483 out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n"
484 " <Groups>\n"
485 " </Groups>\n"
486 " <Contacts>\n";
487 QMapIterator<AbTableItem*, Contact> it;
488 for ( it = contactList.begin(); it != contactList.end(); ++it ) {
489 out += "<Contact ";
490 it.data().save( out );
491 out += "/>\n";
492 QCString cstr = out.utf8();
493 total_written = f.writeBlock( cstr.data(), cstr.length() );
494 if ( total_written != int(cstr.length()) ) {
495 f.close();
496 QFile::remove( strNewFile );
497 return false;
498 }
499 out = "";
500 }
501 out += " </Contacts>\n</AddressBook>\n";
502
503 QCString cstr = out.utf8();
504 total_written = f.writeBlock( cstr.data(), cstr.length() );
505 if ( total_written != int(cstr.length()) ) {
506 f.close();
507 QFile::remove( strNewFile );
508 return false;
509 }
510 f.close();
511
512// qDebug("saving: %d", t.elapsed() );
513
514 // move the file over, I'm just going to use the system call
515 // because, I don't feel like using QDir.
516 if ( ::rename( strNewFile.latin1(), fn.latin1() ) < 0 ) {
517 qWarning( "problem renaming file %s to %s, errno: %d",
518 strNewFile.latin1(), fn.latin1(), errno );
519 // remove the tmp file...
520 QFile::remove( strNewFile );
521 }
522 // remove the journal...
523 QFile::remove( journalFileName() );
524 return true;
525}
526
527void AbTable::load( const QString &fn )
528{
529 setSorting( false );
530 loadFile( fn, false );
531 // merge in the journal
532 if ( QFile::exists( journalFileName() ) ) {
533 loadFile( journalFileName(), true );
534 save( fn );
535 }
536 setSorting( true );
537 resort();
538}
539
540void AbTable::loadFile( const QString &strFile, bool journalFile )
541{
542// QTime t;
543// t.start();
544 QFile f( strFile );
545 if ( !f.open(IO_ReadOnly) )
546 return;
547 QList<Contact> list;
548 list.setAutoDelete( TRUE );
549 QByteArray ba = f.readAll();
550 f.close();
551 char *uc = ba.data();//(QChar *)data.unicode();
552 int len = ba.size();//data.length();
553 bool foundAction = false;
554 Contact::journal_action action;
555 bool foundKey = false;
556 int journalKey = 0;
557
558 const int JOURNALACTION = Qtopia::Notes + 1;
559 const int JOURNALROW = JOURNALACTION + 1;
560
561 // **********************************
562 // CHANGE THE SIZE OF THE DICT IF YOU ADD ANY MORE FIELDS!!!!
563 // **********************************
564 QAsciiDict<int> dict( 47 );
565 dict.setAutoDelete( TRUE );
566 dict.insert( "Uid", new int(Qtopia::AddressUid) );
567 dict.insert( "Title", new int(Qtopia::Title) );
568 dict.insert( "FirstName", new int(Qtopia::FirstName) );
569 dict.insert( "MiddleName", new int(Qtopia::MiddleName) );
570 dict.insert( "LastName", new int(Qtopia::LastName) );
571 dict.insert( "Suffix", new int(Qtopia::Suffix) );
572 dict.insert( "FileAs", new int(Qtopia::FileAs) );
573 dict.insert( "Categories", new int(Qtopia::AddressCategory) );
574 dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) );
575 dict.insert( "Emails", new int(Qtopia::Emails) );
576 dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) );
577 dict.insert( "HomeCity", new int(Qtopia::HomeCity) );
578 dict.insert( "HomeState", new int(Qtopia::HomeState) );
579 dict.insert( "HomeZip", new int(Qtopia::HomeZip) );
580 dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) );
581 dict.insert( "HomePhone", new int(Qtopia::HomePhone) );
582 dict.insert( "HomeFax", new int(Qtopia::HomeFax) );
583 dict.insert( "HomeMobile", new int(Qtopia::HomeMobile) );
584 dict.insert( "HomeWebPage", new int(Qtopia::HomeWebPage) );
585 dict.insert( "Company", new int(Qtopia::Company) );
586 dict.insert( "BusinessStreet", new int(Qtopia::BusinessStreet) );
587 dict.insert( "BusinessCity", new int(Qtopia::BusinessCity) );
588 dict.insert( "BusinessState", new int(Qtopia::BusinessState) );
589 dict.insert( "BusinessZip", new int(Qtopia::BusinessZip) );
590 dict.insert( "BusinessCountry", new int(Qtopia::BusinessCountry) );
591 dict.insert( "BusinessWebPage", new int(Qtopia::BusinessWebPage) );
592 dict.insert( "JobTitle", new int(Qtopia::JobTitle) );
593 dict.insert( "Department", new int(Qtopia::Department) );
594 dict.insert( "Office", new int(Qtopia::Office) );
595 dict.insert( "BusinessPhone", new int(Qtopia::BusinessPhone) );
596 dict.insert( "BusinessFax", new int(Qtopia::BusinessFax) );
597 dict.insert( "BusinessMobile", new int(Qtopia::BusinessMobile) );
598 dict.insert( "BusinessPager", new int(Qtopia::BusinessPager) );
599 dict.insert( "Profession", new int(Qtopia::Profession) );
600 dict.insert( "Assistant", new int(Qtopia::Assistant) );
601 dict.insert( "Manager", new int(Qtopia::Manager) );
602 dict.insert( "Spouse", new int(Qtopia::Spouse) );
603 dict.insert( "Children", new int(Qtopia::Children) );
604 dict.insert( "Gender", new int(Qtopia::Gender) );
605 dict.insert( "Birthday", new int(Qtopia::Birthday) );
606 dict.insert( "Anniversary", new int(Qtopia::Anniversary) );
607 dict.insert( "Nickname", new int(Qtopia::Nickname) );
608 dict.insert( "Notes", new int(Qtopia::Notes) );
609 dict.insert( "action", new int(JOURNALACTION) );
610 dict.insert( "actionrow", new int(JOURNALROW) );
611
612 int i = 0;
613 int num = 0;
614 char *point;
615 while ( (point = strstr( uc+i, "<Contact " ) ) != NULL ) {
616 i = point - uc;
617 // if we are reading the standard file, we just need to
618 // insert info, so just say we'll do an insert...
619 action = Contact::ACTION_ADD;
620 // new Contact
621 Contact *cnt = new Contact;
622 i += 9;
623 while ( 1 ) {
624 while ( i < len && (uc[i] == ' ' || uc[i] == '\n' || uc[i] == '\r') )
625 i++;
626 if ( i >= len-2 || (uc[i] == '/' && uc[i+1] == '>') )
627 break;
628 // we have another attribute read it.
629 int j = i;
630 while ( j < len && uc[j] != '=' )
631 j++;
632 char *attr = uc+i;
633 uc[j] = '\0';
634 //qDebug("attr=%s", attr.latin1() );
635 i = ++j; // skip =
636 while ( i < len && uc[i] != '"' )
637 i++;
638 j = ++i;
639 bool haveEnt = FALSE;
640 bool haveUtf = FALSE;
641 while ( j < len && uc[j] != '"' ) {
642 if ( uc[j] == '&' )
643 haveEnt = TRUE;
644 if ( ((unsigned char)uc[j]) > 0x7f )
645 haveUtf = TRUE;
646 j++;
647 }
648
649 if ( j == i ) {
650 // empty value
651 i = j + 1;
652 continue;
653 }
654
655 QString value = haveUtf ? QString::fromUtf8( uc+i, j-i )
656 : QString::fromLatin1( uc+i, j-i );
657 if ( haveEnt )
658 value = Qtopia::plainString( value );
659 i = j + 1;
660
661 int *find = dict[ attr ];
662 if ( !find ) {
663 cnt->setCustomField(attr, value);
664 continue;
665 }
666#if 1
667 switch( *find ) {
668 case Qtopia::AddressUid:
669 cnt->setUid( value.toInt() );
670 break;
671 case Qtopia::AddressCategory:
672 cnt->setCategories( Qtopia::Record::idsFromString( value ));
673 break;
674 case JOURNALACTION:
675 action = Contact::journal_action(value.toInt());
676 break;
677 case JOURNALROW:
678 journalKey = value.toInt();
679 break;
680
681 default:
682 cnt->insert( *find, value );
683 break;
684 }
685#endif
686 }
687
688 // sadly we can't delay adding of items from the journal to get
689 // the proper effect, but then, the journal should _never_ be
690 // that huge, and recovering from a crash is not necessarily
691 // a *fast* thing.
692 switch ( action ) {
693 case Contact::ACTION_ADD:
694 if ( journalFile ) {
695 int myrows = numRows();
696 setNumRows( myrows + 1 );
697 insertIntoTable( *cnt, myrows );
698 delete cnt;
699 }
700 else
701 list.append( cnt );
702 break;
703 case Contact::ACTION_REMOVE:
704 // yup, we don't use the entry to remove the object...
705 journalFreeRemove( journalKey );
706 delete cnt;
707 break;
708 case Contact::ACTION_REPLACE:
709 journalFreeReplace( *cnt, journalKey );
710 delete cnt;
711 break;
712 default:
713 break;
714 }
715 num++;
716 foundAction = false;
717 foundKey = false;
718 // if ( num % 100 == 0 ) {
719 // qDebug("loading file, num=%d, t=%d", num, t.elapsed() );
720 // }
721 }
722 if ( list.count() > 0 ) {
723 internalAddEntries( list );
724 }
725// qDebug("done loading %d, t=%d", num, t.elapsed() );
726
727}
728
729void AbTable::realignTable( int row )
730{
731 QTableItem *ti1,
732 *ti2;
733 int totalRows = numRows();
734 for ( int curr = row; curr < totalRows - 1; curr++ ) {
735 // the same info from the todo list still applies, but I
736 // don't think it is _too_ bad.
737 ti1 = item( curr + 1, 0 );
738 ti2 = item( curr + 1, 1 );
739 takeItem( ti1 );
740 takeItem( ti2 );
741 setItem( curr, 0, ti1 );
742 setItem( curr, 1, ti2 );
743 }
744 setNumRows( totalRows - 1 );
745 resort();
746}
747
748void AbTable::insertIntoTable( const Contact &cnt, int row )
749{
750 QString strName,
751 strContact;
752
753 strName = findContactName( cnt );
754 strContact = findContactContact( cnt );
755
756 AbTableItem *ati;
757 ati = new AbTableItem( this, QTableItem::Never, strName, strContact);
758 contactList.insert( ati, cnt );
759 setItem( row, 0, ati );
760 ati = new AbTableItem( this, QTableItem::Never, strContact, strName);
761 setItem( row, 1, ati );
762
763 //### cannot do this; table only has two columns at this point
764 // setItem( row, 2, new AbPickItem( this ) );
765
766 // resort at some point?
767}
768
769void AbTable::internalAddEntries( QList<Contact> &list )
770{
771 setUpdatesEnabled( FALSE );
772 setNumRows( list.count() );
773 int row = 0;
774 Contact *it;
775 for ( it = list.first(); it; it = list.next() )
776 insertIntoTable( *it, row++ );
777 resort();
778 setUpdatesEnabled( TRUE );
779}
780
781
782void AbTable::journalFreeReplace( const Contact &cnt, int row )
783{
784 QString strName,
785 strContact;
786 AbTableItem *ati;
787
788 strName = findContactName( cnt );
789 strContact = findContactContact( cnt );
790 ati = static_cast<AbTableItem*>(item(row, 0));
791 contactList.remove( ati );
792 ati->setItem( strName, strContact );
793 contactList.insert( ati, cnt );
794
795 ati = static_cast<AbTableItem*>(item(row, 1));
796 ati->setItem( strContact, strName );
797}
798
799void AbTable::journalFreeRemove( int row )
800{
801 AbTableItem *ati;
802 ati = static_cast<AbTableItem*>(item(row, 0));
803 if ( !ati )
804 return;
805 contactList.remove( ati );
806 realignTable( row );
807}
808
809#if QT_VERSION <= 230
810#ifndef SINGLE_APP
811void QTable::paintEmptyArea( QPainter *p, int cx, int cy, int cw, int ch )
812{
813 // Region of the rect we should draw
814 QRegion reg( QRect( cx, cy, cw, ch ) );
815 // Subtract the table from it
816 reg = reg.subtract( QRect( QPoint( 0, 0 ), tableSize() ) );
817 // And draw the rectangles (transformed as needed)
818 QArray<QRect> r = reg.rects();
819 for (unsigned int i=0; i<r.count(); i++)
820 p->fillRect( r[i], colorGroup().brush( QColorGroup::Base ) );
821}
822#endif
823#endif
824
825
826// int AbTable::rowHeight( int ) const
827// {
828// return 18;
829// }
830
831// int AbTable::rowPos( int row ) const
832// {
833// return 18*row;
834// }
835
836// int AbTable::rowAt( int pos ) const
837// {
838// return QMIN( pos/18, numRows()-1 );
839// }
840
841void AbTable::slotDoFind( const QString &findString, bool caseSensitive,
842 bool backwards, int category )
843{
844 if ( currFindRow < -1 )
845 currFindRow = currentRow() - 1;
846 clearSelection( TRUE );
847 int rows,
848 row;
849 AbTableItem *ati;
850 QRegExp r( findString );
851 r.setCaseSensitive( caseSensitive );
852 rows = numRows();
853 static bool wrapAround = true;
854
855 if ( !backwards ) {
856 for ( row = currFindRow + 1; row < rows; row++ ) {
857 ati = static_cast<AbTableItem*>( item(row, 0) );
858 if ( contactCompare( contactList[ati], r, category ) )
859 break;
860
861 }
862 } else {
863 for ( row = currFindRow - 1; row > -1; row-- ) {
864 ati = static_cast<AbTableItem*>( item(row, 0) );
865 if ( contactCompare( contactList[ati], r, category ) )
866 break;
867 }
868 }
869 if ( row >= rows || row < 0 ) {
870 if ( row < 0 )
871 currFindRow = rows;
872 else
873 currFindRow = -1;
874
875 if ( wrapAround )
876 emit signalWrapAround();
877 else
878 emit signalNotFound();
879
880 wrapAround = !wrapAround;
881 } else {
882 currFindRow = row;
883 QTableSelection foundSelection;
884 foundSelection.init( currFindRow, 0 );
885 foundSelection.expandTo( currFindRow, numCols() - 1 );
886 addSelection( foundSelection );
887 setCurrentCell( currFindRow, numCols() - 1 );
888 wrapAround = true;
889 }
890}
891
892static bool contactCompare( const Contact &cnt, const QRegExp &r, int category )
893{
894 bool returnMe;
895 QArray<int> cats;
896 cats = cnt.categories();
897
898 returnMe = false;
899 if ( (category == -1 && cats.count() == 0) || category == -2 )
900 returnMe = cnt.match( r );
901 else {
902 int i;
903 for ( i = 0; i < int(cats.count()); i++ ) {
904 if ( cats[i] == category ) {
905 returnMe = cnt.match( r );
906 break;
907 }
908 }
909 }
910 return returnMe;
911}
912
913void AbTable::fitColumns()
914{
915 int contentsWidth = visibleWidth();
916 int n = numCols();
917 int pw = n == 3 ? columnWidth(2) : 0;
918 setColumnWidth( 0, contentsWidth - contentsWidth / 2 );
919 setColumnWidth( 1, contentsWidth / 2 - pw );
920}
921
922void AbTable::show()
923{
924 fitColumns();
925 QTable::show();
926}
927
928void AbTable::setChoiceNames( const QStringList& list)
929{
930 choicenames = list;
931 if ( choicenames.isEmpty() ) {
932 // hide pick column
933 setNumCols( 2 );
934 } else {
935 // show pick column
936 setNumCols( 3 );
937 setColumnWidth( 2, fontMetrics().width(tr( "Pick" ))+8 );
938 horizontalHeader()->setLabel( 2, tr( "Pick" ));
939 }
940 fitColumns();
941}
942
943void AbTable::itemClicked(int,int col)
944{
945 if ( col == 2 ) {
946 return;
947 } else {
948 emit details();
949 }
950}
951
952QStringList AbTable::choiceNames() const
953{
954 return choicenames;
955}
956
957void AbTable::setChoiceSelection(int /*index*/, const QStringList& /*list*/)
958{
959 /* ######
960
961 QString selname = choicenames.at(index);
962 for (each row) {
963 Contact *c = contactForRow(row);
964 if ( list.contains(c->email) ) {
965 list.remove(c->email);
966 setText(row, 2, selname);
967 }
968 }
969 for (remaining list items) {
970 Contact *c = new contact(item);
971 setText(newrow, 2, selname);
972 }
973
974 */
975}
976
977QStringList AbTable::choiceSelection(int /*index*/) const
978{
979 QStringList r;
980 /* ######
981
982 QString selname = choicenames.at(index);
983 for (each row) {
984 Contact *c = contactForRow(row);
985 if ( text(row,2) == selname ) {
986 r.append(c->email);
987 }
988 }
989
990 */
991 return r;
992}
993
994void AbTable::setShowCategory( const QString &c )
995{
996 showCat = c;
997 updateVisible();
998}
999
1000QString AbTable::showCategory() const
1001{
1002 return showCat;
1003}
1004
1005
1006QStringList AbTable::categories()
1007{
1008 mCat.load( categoryFileName() );
1009 QStringList categoryList = mCat.labels( "Contacts" );
1010 return categoryList;
1011}
1012
1013void AbTable::updateVisible()
1014{
1015 int visible,
1016 totalRows,
1017 id,
1018 totalCats,
1019 it,
1020 row;
1021 bool hide;
1022 AbTableItem *ati;
1023 Contact *cnt;
1024 visible = 0;
1025
1026 setPaintingEnabled( FALSE );
1027
1028 totalRows = numRows();
1029 id = mCat.id( "Contacts", showCat );
1030 QArray<int> cats;
1031 for ( row = 0; row < totalRows; row++ ) {
1032 ati = static_cast<AbTableItem*>( item(row, 0) );
1033 cnt = &contactList[ati];
1034 cats = cnt->categories();
1035 hide = false;
1036 if ( !showCat.isEmpty() ) {
1037 if ( showCat == tr( "Unfiled" ) ) {
1038 if ( cats.count() > 0 )
1039 hide = true;
1040 } else {
1041 // do some comparing
1042 if ( !hide ) {
1043 hide = true;
1044 totalCats = int(cats.count());
1045 for ( it = 0; it < totalCats; it++ ) {
1046 if ( cats[it] == id ) {
1047 hide = false;
1048 break;
1049 }
1050 }
1051 }
1052 }
1053 }
1054 if ( hide ) {
1055 if ( currentRow() == row )
1056 setCurrentCell( -1, 0 );
1057 if ( rowHeight(row) > 0 )
1058 hideRow( row );
1059 } else {
1060 if ( rowHeight(row) == 0 ) {
1061 showRow( row );
1062 adjustRow( row );
1063 }
1064 visible++;
1065 }
1066 }
1067 if ( !visible )
1068 setCurrentCell( -1, 0 );
1069
1070 setPaintingEnabled( TRUE );
1071}
1072
1073
1074void AbTable::setPaintingEnabled( bool e )
1075{
1076 if ( e != enablePainting ) {
1077 if ( !enablePainting ) {
1078 enablePainting = true;
1079 rowHeightChanged( 0 );
1080 viewport()->update();
1081 } else {
1082 enablePainting = false;
1083 }
1084 }
1085}
1086
1087void AbTable::rowHeightChanged( int row )
1088{
1089 if ( enablePainting )
1090 QTable::rowHeightChanged( row );
1091}
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qt Palmtop Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#ifndef ABTABLE_H
22#define ABTABLE_H
23
24#include <qpe/categories.h>
25#include <qpe/contact.h>
26
27#include <qmap.h>
28#include <qtable.h>
29#include <qstringlist.h>
30#include <qcombobox.h>
31
32class AbTableItem : public QTableItem
33{
34public:
35 AbTableItem( QTable *t, EditType et, const QString &s,
36 const QString &secondSortKey);
37 QString entryKey() const;
38 void setEntryKey( const QString & k );
39 virtual int alignment() const;
40 virtual QString key() const;
41 void setItem( const QString &txt, const QString &secondKey );
42
43private:
44 QString sortKey;
45};
46
47class AbPickItem : public QTableItem
48{
49public:
50 AbPickItem( QTable *t );
51
52 QWidget *createEditor() const;
53 void setContentFromEditor( QWidget *w );
54
55private:
56 QGuardedPtr<QComboBox> cb;
57};
58
59class AbTable : public QTable
60{
61 Q_OBJECT
62
63public:
64 AbTable( const QValueList<int> *ordered, QWidget *parent, const char *name=0 );
65 ~AbTable();
66 // NEW
67 void addEntry( const Contact &newContact );
68 Contact currentEntry();
69 void replaceCurrentEntry( const Contact &newContact );
70
71 void init();
72
73 void deleteCurrentEntry();
74 void clear();
75 void clearFindRow() { currFindRow = -2; }
76 void loadFields();
77 void refresh();
78 bool save( const QString &fn );
79 void load( const QString &fn );
80
81 // addresspicker mode
82 void setChoiceNames( const QStringList& list);
83 QStringList choiceNames() const;
84 void setChoiceSelection(int index, const QStringList& list);
85 QStringList choiceSelection(int index) const;
86 void setShowCategory( const QString &c );
87 QString showCategory() const;
88 QStringList categories();
89
90 void show();
91 void setPaintingEnabled( bool e );
92
93public slots:
94 void slotDoFind( const QString &str, bool caseSensitive, bool backwards,
95 int category );
96signals:
97 void empty( bool );
98 void details();
99 void signalNotFound();
100 void signalWrapAround();
101
102protected:
103 virtual void keyPressEvent( QKeyEvent *e );
104
105// int rowHeight( int ) const;
106// int rowPos( int row ) const;
107// virtual int rowAt( int pos ) const;
108
109
110protected slots:
111 void moveTo( char );
112 virtual void columnClicked( int col );
113 void itemClicked(int,int col);
114 void rowHeightChanged( int row );
115
116private:
117 void loadFile( const QString &strFile, bool journalFile );
118 void fitColumns();
119 void resort();
120 void updateJournal( const Contact &contact, Contact::journal_action action,
121 int row = -1 );
122 void insertIntoTable( const Contact &contact, int row );
123 void internalAddEntries( QList<Contact> &list );
124 QString findContactName( const Contact &entry );
125 QString findContactContact( const Contact &entry );
126 void journalFreeReplace( const Contact &cnt, int row );
127 void journalFreeRemove( int row );
128 void realignTable( int );
129 void updateVisible();
130 int lastSortCol;
131 bool asc;
132 QMap<AbTableItem*, Contact> contactList;
133 const QValueList<int> *intFields;
134 int currFindRow;
135 QString showCat;
136 QStringList choicenames;
137 bool enablePainting;
138 Categories mCat;
139};
140#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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qt Palmtop Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "abeditor.h"
22#include "ablabel.h"
23#include "abtable.h"
24#include "addresssettings.h"
25#include "addressbook.h"
26
27#include <qpe/qpeapplication.h>
28#include <qpe/config.h>
29#include <qpe/contact.h>
30#include <qpe/finddialog.h>
31#include <qpe/global.h>
32#include <qpe/resource.h>
33#include <qpe/ir.h>
34#include <qpe/qpemessagebox.h>
35#include <qpe/qcopenvelope_qws.h>
36
37#include <qaction.h>
38#include <qdialog.h>
39#include <qdir.h>
40#include <qfile.h>
41#include <qimage.h>
42#include <qlayout.h>
43#include <qpe/qpemenubar.h>
44#include <qmessagebox.h>
45#include <qpixmap.h>
46#include <qpopupmenu.h>
47#include <qpe/qpetoolbar.h>
48#include <qstringlist.h>
49#include <qtoolbutton.h>
50#include <qwhatsthis.h>
51
52#include <stdlib.h>
53#include <sys/stat.h>
54#include <sys/types.h>
55#include <fcntl.h>
56#include <unistd.h>
57
58#include <qdatetime.h>
59
60static QString addressbookOldXMLFilename()
61{
62 QString filename = QPEApplication::documentDir() + "addressbook.xml";
63 return filename;
64}
65
66static QString addressbookXMLFilename()
67{
68 QString filename = Global::applicationFileName("addressbook",
69 "addressbook.xml");
70 return filename;
71}
72
73static QString addressbookPersonalVCardName()
74{
75 QString filename = Global::applicationFileName("addressbook",
76 "businesscard.vcf");
77 return filename;
78}
79
80
81AddressbookWindow::AddressbookWindow( QWidget *parent, const char *name,
82 WFlags f )
83 : QMainWindow( parent, name, f ),
84 abEditor(0),
85 bAbEditFirstTime(TRUE),
86 syncing(FALSE)
87{
88 initFields();
89
90 setCaption( tr("Contacts") );
91 setIcon( Resource::loadPixmap( "AddressBook" ) );
92
93 setToolBarsMovable( FALSE );
94
95 // Create Toolbars
96
97 QPEToolBar *bar = new QPEToolBar( this );
98 bar->setHorizontalStretchable( TRUE );
99
100 QPEMenuBar *mbList = new QPEMenuBar( bar );
101 mbList->setMargin( 0 );
102
103 QPopupMenu *edit = new QPopupMenu( this );
104 mbList->insertItem( tr( "Contact" ), edit );
105
106 listTools = new QPEToolBar( this, "list operations" );
107
108
109 QAction *a = new QAction( tr( "New" ), Resource::loadPixmap( "new" ), QString::null,
110 0, this, 0 );
111 actionNew = a;
112 connect( a, SIGNAL( activated() ), this, SLOT( slotListNew() ) );
113 a->addTo( edit );
114 a->addTo( listTools );
115
116 a = new QAction( tr( "Edit" ), Resource::loadPixmap( "edit" ), QString::null,
117 0, this, 0 );
118 actionEdit = a;
119 connect( a, SIGNAL( activated() ), this, SLOT( slotViewEdit() ) );
120 a->addTo( edit );
121 a->addTo( listTools );
122
123 a = new QAction( tr( "Delete" ), Resource::loadPixmap( "trash" ), QString::null,
124 0, this, 0 );
125 actionTrash = a;
126 connect( a, SIGNAL( activated() ), this, SLOT( slotListDelete() ) );
127 a->addTo( edit );
128 a->addTo( listTools );
129
130 a = new QAction( tr( "Find" ), Resource::loadPixmap( "mag" ),
131 QString::null, 0, this, 0 );
132 actionFind = a;
133 connect( a, SIGNAL(activated()), this, SLOT(slotFind()) );
134 a->addTo( edit );
135 a->addTo( listTools );
136
137
138 a = new QAction( tr( "Write Mail To" ), Resource::loadPixmap( "qtmail/reply" ),
139 QString::null, 0, this, 0 );
140 a->setEnabled( FALSE );
141 actionMail = a;
142 connect( a, SIGNAL( activated() ), this, SLOT( writeMail() ) );
143 a->addTo( edit );
144 a->addTo( listTools );
145
146
147
148 if ( Ir::supported() ) {
149 a = new QAction( tr ("Beam Entry" ), Resource::loadPixmap( "beam" ), QString::null,
150 0, this, 0 );
151 actionBeam = a;
152 connect( a, SIGNAL( activated() ), this, SLOT( slotBeam() ) );
153 a->addTo( edit );
154 a->addTo( listTools );
155 }
156
157 edit->insertSeparator();
158
159 a = new QAction( tr("My Personal Details"), QString::null, 0, 0, 0, TRUE );
160 actionPersonal = a;
161 connect( a, SIGNAL( activated() ), this, SLOT( slotPersonalView() ) );
162 a->addTo( edit );
163
164
165 a = new QAction( tr( "Arrange Edit Fields"), QString::null, 0, 0 );
166 connect( a, SIGNAL( activated() ), this, SLOT( slotSettings() ) );
167 a->addTo( edit );
168
169 // Create Views
170
171 // This is safe to call without checking to see if it exists...
172 // not to mention it also does the necessary stuff for the
173 // journaling...
174 QString str = addressbookXMLFilename();
175 if ( str.isNull() ) {
176 QMessageBox::warning( this, tr("Out of Space"),
177 tr("There is not enough space to create\n"
178 "neccessary startup files.\n"
179 "\nFree up some space before\nentering data!")
180 );
181 }
182
183 abList = new AbTable( &orderedFields, this, "table" );
184 abList->setHScrollBarMode( QScrollView::AlwaysOff );
185 connect( abList, SIGNAL( empty( bool ) ),
186 this, SLOT( listIsEmpty( bool ) ) );
187 connect( abList, SIGNAL( details() ),
188 this, SLOT( slotListView() ) );
189 connect( abList, SIGNAL(currentChanged(int,int)),
190 this, SLOT(slotUpdateToolbar()) );
191
192 mView = 0;
193
194 abList->load( addressbookXMLFilename() );
195 if ( QFile::exists(addressbookOldXMLFilename()) ) {
196 abList->load( addressbookOldXMLFilename() );
197 QFile::remove(addressbookOldXMLFilename());
198 }
199
200 catMenu = new QPopupMenu( this );
201 catMenu->setCheckable( TRUE );
202 connect( catMenu, SIGNAL(activated(int)), this, SLOT(slotSetCategory(int)) );
203 populateCategories();
204
205 mbList->insertItem( tr("View"), catMenu );
206 setCentralWidget( abList );
207
208 // qDebug("adressbook contrsuction: t=%d", t.elapsed() );
209}
210
211void AddressbookWindow::setDocument( const QString &filename )
212{
213 if ( filename.find(".vcf") != int(filename.length()) - 4 ) return;
214
215 QValueList<Contact> cl = Contact::readVCard( filename );
216 for( QValueList<Contact>::Iterator it = cl.begin(); it != cl.end(); ++it ) {
217 // QString msg = tr("You received a vCard for\n%1.\nDo You want to add it to your\naddressbook?")
218 // .arg( (*it).fullName() );
219 // if ( QMessageBox::information( this, tr("received contact"), msg, QMessageBox::Ok, QMessageBox::Cancel ) ==
220 // QMessageBox::Ok ) {
221 abList->addEntry( *it );
222 // }
223 }
224
225}
226
227void AddressbookWindow::resizeEvent( QResizeEvent *e )
228{
229 QMainWindow::resizeEvent( e );
230
231 if ( centralWidget() == abList )
232 showList();
233 else if ( centralWidget() == mView )
234 showView();
235}
236
237AddressbookWindow::~AddressbookWindow()
238{
239}
240
241void AddressbookWindow::slotUpdateToolbar()
242{
243 Contact ce = abList->currentEntry();
244 actionMail->setEnabled( !ce.defaultEmail().isEmpty() );
245}
246
247void AddressbookWindow::showList()
248{
249 if ( mView ) mView->hide();
250 setCentralWidget( abList );
251 abList->show();
252 // update our focues... (or use a stack widget!);
253 abList->setFocus();
254}
255
256void AddressbookWindow::showView()
257{
258 if ( abList->numRows() > 0 ) {
259 abList->hide();
260 setCentralWidget( abView() );
261 mView->show();
262 mView->setFocus();
263 }
264}
265
266void AddressbookWindow::slotListNew()
267{
268 Contact cnt;
269 if( !syncing ) {
270 if ( abEditor )
271 abEditor->setEntry( cnt );
272 abView()->init( cnt );
273 editEntry( NewEntry );
274 } else {
275 QMessageBox::warning(this, tr("Contacts"),
276 tr("Can not edit data, currently syncing"));
277 }
278}
279
280void AddressbookWindow::slotListView()
281{
282 abView()->init( abList->currentEntry() );
283 mView->sync();
284 showView();
285}
286
287void AddressbookWindow::slotListDelete()
288{
289 if(!syncing) {
290 Contact tmpEntry = abList->currentEntry();
291
292 // get a name, do the best we can...
293 QString strName = tmpEntry.fullName();
294 if ( strName.isEmpty() ) {
295 strName = tmpEntry.company();
296 if ( strName.isEmpty() )
297 strName = "No Name";
298 }
299
300
301 if ( QPEMessageBox::confirmDelete( this, tr( "Contacts" ),
302 strName ) ) {
303 abList->deleteCurrentEntry();
304 showList();
305 }
306 } else {
307 QMessageBox::warning( this, tr("Contacts"),
308 tr("Can not edit data, currently syncing") );
309 }
310}
311
312void AddressbookWindow::slotViewBack()
313{
314 showList();
315}
316
317void AddressbookWindow::slotViewEdit()
318{
319 if(!syncing) {
320 if (actionPersonal->isOn()) {
321 editPersonal();
322 } else {
323 if ( !bAbEditFirstTime )
324 abEditor->setEntry( abList->currentEntry() );
325 editEntry( EditEntry );
326 }
327 } else {
328 QMessageBox::warning( this, tr("Contacts"),
329 tr("Can not edit data, currently syncing") );
330 }
331}
332
333
334
335void AddressbookWindow::writeMail()
336{
337 Contact c = abList->currentEntry();
338 QString name = c.fileAs();
339 QString email = c.defaultEmail();
340 QCopEnvelope e("QPE/Application/qtmail", "writeMail(QString,QString)");
341 e << name << email;
342}
343
344
345
346
347static const char * beamfile = "/tmp/obex/contact.vcf";
348
349void AddressbookWindow::slotBeam()
350{
351 QString filename;
352 Contact c;
353 if ( actionPersonal->isOn() ) {
354 filename = addressbookPersonalVCardName();
355 if (!QFile::exists(filename))
356 return; // can't beam a non-existent file
357 c = Contact::readVCard( filename )[0];
358 } else {
359 unlink( beamfile ); // delete if exists
360 c = abList->currentEntry();
361 mkdir("/tmp/obex/", 0755);
362 Contact::writeVCard( beamfile, c );
363 filename = beamfile;
364 }
365 Ir *ir = new Ir( this );
366 connect( ir, SIGNAL( done( Ir * ) ), this, SLOT( beamDone( Ir * ) ) );
367 QString description = c.fullName();
368 ir->send( filename, description, "text/x-vCard" );
369}
370
371void AddressbookWindow::beamDone( Ir *ir )
372{
373 delete ir;
374 unlink( beamfile );
375}
376
377
378static void parseName( const QString& name, QString *first, QString *middle,
379 QString * last )
380{
381
382 int comma = name.find ( "," );
383 QString rest;
384 if ( comma > 0 ) {
385 *last = name.left( comma );
386 comma++;
387 while ( comma < int(name.length()) && name[comma] == ' ' )
388 comma++;
389 rest = name.mid( comma );
390 } else {
391 int space = name.findRev( ' ' );
392 *last = name.mid( space+1 );
393 rest = name.left( space );
394 }
395 int space = rest.find( ' ' );
396 if ( space <= 0 ) {
397 *first = rest;
398 } else {
399 *first = rest.left( space );
400 *middle = rest.mid( space+1 );
401 }
402
403}
404
405
406void AddressbookWindow::appMessage(const QCString &msg, const QByteArray &data)
407{
408 if (msg == "editPersonal()") {
409 editPersonal();
410 } else if (msg == "editPersonalAndClose()") {
411 editPersonal();
412 close();
413 } else if ( msg == "addContact(QString,QString)" ) {
414 QDataStream stream(data,IO_ReadOnly);
415 QString name, email;
416 stream >> name >> email;
417
418 Contact cnt;
419 QString fn, mn, ln;
420 parseName( name, &fn, &mn, &ln );
421 //qDebug( " %s - %s - %s", fn.latin1(), mn.latin1(), ln.latin1() );
422 cnt.setFirstName( fn );
423 cnt.setMiddleName( mn );
424 cnt.setLastName( ln );
425 cnt.setEmails( email );
426 cnt.setDefaultEmail( email );
427 cnt.setFileAs();
428
429 if ( bAbEditFirstTime ) {
430 abEditor = new AbEditor( cnt, &orderedFields, &slOrderedFields,
431 this, "editor" );
432 bAbEditFirstTime = FALSE;
433 } else {
434 abEditor->setEntry( cnt );
435 }
436 abView()->init( cnt );
437 editEntry( NewEntry );
438
439
440
441 }
442#if 0
443 else if (msg == "pickAddresses(QCString,QCString,QStringList,...)" ) {
444 QDataStream stream(data,IO_ReadOnly);
445 QCString ch,m;
446 QStringList types;
447 stream >> ch >> m >> types;
448 AddressPicker picker(abList,this,0,TRUE);
449 picker.showMaximized();
450 picker.setChoiceNames(types);
451 int i=0;
452 for (QStringList::ConstIterator it = types.begin(); it!=types.end(); ++it) {
453 QStringList sel;
454 stream >> sel;
455 picker.setSelection(i++,sel);
456 }
457 picker.showMaximized();
458 picker.exec();
459
460 // ###### note: contacts may have been added - save here!
461
462 setCentralWidget(abList);
463 QCopEnvelope e(ch,m);
464 i=0;
465 for (QStringList::ConstIterator it = types.begin(); it!=types.end(); ++it) {
466 QStringList sel = picker.selection(i++);
467 e << sel;
468 }
469 }
470#endif
471
472}
473
474void AddressbookWindow::editPersonal()
475{
476 QString filename = addressbookPersonalVCardName();
477 Contact me;
478 if (QFile::exists(filename))
479 me = Contact::readVCard( filename )[0];
480 if (bAbEditFirstTime) {
481 abEditor = new AbEditor( me, &orderedFields, &slOrderedFields,
482 this, "editor" );
483 // don't create a new editor every time
484 bAbEditFirstTime = FALSE;
485 } else
486 abEditor->setEntry( me );
487
488 abEditor->setCaption(tr("Edit My Personal Details"));
489 abEditor->showMaximized();
490
491 // fix the foxus...
492 abEditor->setNameFocus();
493 if ( abEditor->exec() ) {
494 setFocus();
495 Contact new_personal = abEditor->entry();
496 QString fname = addressbookPersonalVCardName();
497 Contact::writeVCard( fname, new_personal );
498 abView()->init(new_personal);
499 abView()->sync();
500 }
501 abEditor->setCaption( tr("Edit Address") );
502}
503
504void AddressbookWindow::slotPersonalView()
505{
506 if (!actionPersonal->isOn()) {
507 // we just turned it off
508 setCaption( tr("Contacts") );
509 actionNew->setEnabled(TRUE);
510 actionTrash->setEnabled(TRUE);
511 actionFind->setEnabled(TRUE);
512 slotUpdateToolbar(); // maybe some of the above could be moved there
513 showList();
514 return;
515 }
516
517 // XXX need to disable some QActions.
518 actionNew->setEnabled(FALSE);
519 actionTrash->setEnabled(FALSE);
520 actionFind->setEnabled(FALSE);
521 actionMail->setEnabled(FALSE);
522
523 setCaption( tr("Contacts - My Personal Details") );
524 QString filename = addressbookPersonalVCardName();
525 Contact me;
526 if (QFile::exists(filename))
527 me = Contact::readVCard( filename )[0];
528
529 abView()->init( me );
530 abView()->sync();
531 abList->hide();
532 setCentralWidget( abView() );
533 mView->show();
534 mView->setFocus();
535}
536
537void AddressbookWindow::editEntry( EntryMode entryMode )
538{
539 Contact entry;
540 if ( bAbEditFirstTime ) {
541 abEditor = new AbEditor( entry, &orderedFields, &slOrderedFields,
542 this, "editor" );
543 bAbEditFirstTime = FALSE;
544 if ( entryMode == EditEntry )
545 abEditor->setEntry( abList->currentEntry() );
546 }
547 // other things may chane the caption.
548 abEditor->setCaption( tr("Edit Address") );
549
550#if defined(Q_WS_QWS) || defined(_WS_QWS_)
551 abEditor->showMaximized();
552#endif
553 // fix the foxus...
554 abEditor->setNameFocus();
555 if ( abEditor->exec() ) {
556 setFocus();
557 if ( entryMode == NewEntry ) {
558 Contact insertEntry = abEditor->entry();
559 insertEntry.assignUid();
560 abList->addEntry( insertEntry );
561 } else {
562 Contact replaceEntry = abEditor->entry();
563 if ( !replaceEntry.isValidUid() )
564 replaceEntry.assignUid();
565 abList->replaceCurrentEntry( replaceEntry );
566 }
567 }
568 populateCategories();
569 showList();
570}
571
572void AddressbookWindow::listIsEmpty( bool empty )
573{
574 if ( !empty ) {
575 deleteButton->setEnabled( TRUE );
576 }
577}
578
579void AddressbookWindow::reload()
580{
581 syncing = FALSE;
582 abList->clear();
583 abList->load( addressbookXMLFilename() );
584}
585
586void AddressbookWindow::flush()
587{
588 syncing = TRUE;
589 abList->save( addressbookXMLFilename() );
590}
591
592
593void AddressbookWindow::closeEvent( QCloseEvent *e )
594{
595 if ( centralWidget() == mView ) {
596 if (actionPersonal->isOn()) {
597 // pretend we clicked it off
598 actionPersonal->setOn(FALSE);
599 slotPersonalView();
600 } else {
601 showList();
602 }
603 e->ignore();
604 return;
605 }
606
607 if(syncing) {
608 /* shouldn't we save, I hear you say? well its already been set
609 so that an edit can not occur during a sync, and we flushed
610 at the start of the sync, so there is no need to save
611 Saving however itself would cause problems. */
612 e->accept();
613 return;
614 }
615//################## shouldn't always save
616 if ( save() )
617 e->accept();
618 else
619 e->ignore();
620}
621
622/*
623 Returns TRUE if it is OK to exit
624 */
625
626bool AddressbookWindow::save()
627{
628 QString str = addressbookXMLFilename();
629 if ( str.isNull() ) {
630 if ( QMessageBox::critical( 0, tr("Out of space"),
631 tr("Unable to save information.\n"
632 "Free up some space\n"
633 "and try again.\n"
634 "\nQuit anyway?"),
635 QMessageBox::Yes|QMessageBox::Escape,
636 QMessageBox::No|QMessageBox::Default )
637 != QMessageBox::No )
638 return TRUE;
639 else
640 return FALSE;
641 } else {
642 if ( !abList->save( str ) ) {
643 if ( QMessageBox::critical( 0, tr( "Out of space" ),
644 tr("Unable to save information.\n"
645 "Free up some space\n"
646 "and try again.\n"
647 "\nQuit anyway?"),
648 QMessageBox::Yes|QMessageBox::Escape,
649 QMessageBox::No|QMessageBox::Default )
650 != QMessageBox::No )
651 return TRUE;
652 else
653 return FALSE;
654 }
655 }
656 return TRUE;
657}
658
659void AddressbookWindow::slotSettings()
660{
661 AddressSettings frmSettings( this );
662#if defined(Q_WS_QWS) || defined(_WS_QWS_)
663 frmSettings.showMaximized();
664#endif
665
666 if ( frmSettings.exec() ) {
667 allFields.clear();
668 orderedFields.clear();
669 slOrderedFields.clear();
670 initFields();
671 if ( abEditor )
672 abEditor->loadFields();
673 abList->refresh();
674 }
675}
676
677
678void AddressbookWindow::initFields()
679{
680 // we really don't need the things from the configuration, anymore
681 // only thing that is important are the important categories. So,
682 // Call the contact functions that correspond to these old functions...
683
684 QStringList xmlFields = Contact::fields();
685 QStringList visibleFields = Contact::trfields();
686 xmlFields.remove( "Title" );
687 visibleFields.remove( tr("Name Title") );
688 visibleFields.remove( tr("Notes") );
689
690 int i,
691 version;
692 Config cfg( "AddressBook" );
693 QString zn;
694
695 // ### Write a function to keep this from happening again...
696 QStringList::ConstIterator it;
697 for ( i = 0, it = xmlFields.begin(); it != xmlFields.end(); ++it, i++ ) {
698 allFields.append( i + 3 );
699 }
700
701 cfg.setGroup( "Version" );
702 version = cfg.readNumEntry( "version" );
703 i = 0;
704 if ( version >= ADDRESSVERSION ) {
705
706 cfg.setGroup( "ImportantCategory" );
707
708 zn = cfg.readEntry( "Category" + QString::number(i), QString::null );
709 while ( !zn.isNull() ) {
710 if ( zn.contains( tr("Work") ) || zn.contains( tr("Mb") ) ) {
711 slOrderedFields.clear();
712 break;
713 }
714 slOrderedFields.append( zn );
715 zn = cfg.readEntry( "Category" + QString::number(++i), QString::null );
716 }
717 } else {
718 QString str;
719 str = getenv("HOME");
720 str += "/Settings/AddressBook.conf";
721 QFile::remove( str );
722 }
723 if ( slOrderedFields.count() > 0 ) {
724 for( QStringList::ConstIterator it = slOrderedFields.begin();
725 it != slOrderedFields.end(); ++it ) {
726 QValueList<int>::ConstIterator itVl;
727 QStringList::ConstIterator itVis;
728 itVl = allFields.begin();
729 for ( itVis = visibleFields.begin();
730 itVis != visibleFields.end() && itVl != allFields.end();
731 ++itVis, ++itVl ) {
732 if ( *it == *itVis && itVl != allFields.end() ) {
733 orderedFields.append( *itVl );
734 }
735 }
736 }
737 } else {
738 QValueList<int>::ConstIterator it;
739 for ( it = allFields.begin(); it != allFields.end(); ++it )
740 orderedFields.append( *it );
741
742 slOrderedFields = visibleFields;
743 orderedFields.remove( Qtopia::AddressUid );
744 orderedFields.remove( Qtopia::Title );
745 orderedFields.remove( Qtopia::Groups );
746 orderedFields.remove( Qtopia::AddressCategory );
747 orderedFields.remove( Qtopia::FirstName );
748 orderedFields.remove( Qtopia::LastName );
749 orderedFields.remove( Qtopia::DefaultEmail );
750 orderedFields.remove( Qtopia::FileAs );
751 orderedFields.remove( Qtopia::Notes );
752 orderedFields.remove( Qtopia::Gender );
753 slOrderedFields.remove( tr("Name Title") );
754 slOrderedFields.remove( tr("First Name") );
755 slOrderedFields.remove( tr("Last Name") );
756 slOrderedFields.remove( tr("File As") );
757 slOrderedFields.remove( tr("Default Email") );
758 slOrderedFields.remove( tr("Notes") );
759 slOrderedFields.remove( tr("Gender") );
760
761 }
762}
763
764
765AbLabel *AddressbookWindow::abView()
766{
767 if ( !mView ) {
768 mView = new AbLabel( this, "viewer" );
769 mView->init( Contact() );
770 connect( mView, SIGNAL( okPressed() ), this, SLOT( slotListView() ) );
771 }
772 return mView;
773}
774
775void AddressbookWindow::slotFind()
776{
777 if ( centralWidget() == abView() )
778 showList();
779 FindDialog frmFind( "Contacts", this );
780 QObject::connect( &frmFind, SIGNAL(signalFindClicked(const QString &, bool, bool, int)), abList, SLOT(slotDoFind( const QString&,bool,bool,int)));
781 QObject::connect( abList, SIGNAL(signalNotFound()), &frmFind, SLOT(slotNotFound()) );
782 QObject::connect( abList, SIGNAL(signalWrapAround()), &frmFind, SLOT(slotWrapAround()) );
783 frmFind.exec();
784 if ( abList->numSelections() )
785 abList->clearSelection();
786 abList->clearFindRow();
787}
788
789void AddressbookWindow::slotSetCategory( int c )
790{
791 if ( c <= 0 )
792 return;
793 for ( unsigned int i = 1; i < catMenu->count(); i++ )
794 catMenu->setItemChecked( i, c == (int)i );
795 if ( c == 1 ) {
796 abList->setShowCategory( QString::null );
797 setCaption( tr("Contacts") + " - " + tr ( "All" ) );
798 } else if ( c == (int)catMenu->count() ) {
799 abList->setShowCategory( tr( "Unfiled" ) );
800 setCaption( tr("Contacts") + " - " + tr( "Unfiled" ) );
801 } else {
802 QString cat = abList->categories()[c - 2];
803 abList->setShowCategory( cat );
804 setCaption( tr("Contacts") + " - " + cat );
805 }
806}
807
808void AddressbookWindow::populateCategories()
809{
810 catMenu->clear();
811
812 int id,
813 rememberId;
814 id = 1;
815 catMenu->insertItem( tr( "All" ), id++ );
816 QStringList categories = abList->categories();
817 categories.append( tr( "Unfiled" ) );
818 for ( QStringList::Iterator it = categories.begin();
819 it != categories.end(); ++it ) {
820 catMenu->insertItem( *it, id );
821 if ( *it == abList->showCategory() )
822 rememberId = id;
823 ++id;
824 }
825 if ( abList->showCategory().isEmpty() )
826 slotSetCategory( 1 );
827 else
828 slotSetCategory( rememberId );
829}
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 @@
1<!DOCTYPE CW><CW>
2<customwidgets>
3 <customwidget>
4 <class>AbLineEdit</class>
5 <header location="local">ablineedit.h</header>
6 <sizehint>
7 <width>-1</width>
8 <height>-1</height>
9 </sizehint>
10 <pixmap>
11 <data format="XPM.GZ" length="646">789c6dd2c10ac2300c00d07bbf2234b7229d1be245fc04c5a3201e4615f430059d0711ff5ddb2e6bb236ec90eed134cb5a19d8ef36602af5ecdbfeeac05dda0798d3abebde87e3faa374d3807fa0d633a52d38d8de6f679fe33fc776e196f53cd010188256a3600a292882096246517815ca99884606e18044a3a40d91824820924265a7923a2e8bcd05f33db1173e002913175f2a6be6d3294871a2d95fa00e8a94ee017b69d339d90df1e77c57ea072ede6758</data>
12 </pixmap>
13 </customwidget>
14 <customwidget>
15 <class>AbMultiLineEdit</class>
16 <header location="local">abmultilineedit.h</header>
17 <sizehint>
18 <width>-1</width>
19 <height>-1</height>
20 </sizehint>
21 <pixmap>
22 <data format="XPM.GZ" length="646">789c6dd2c10ac2300c00d07bbf2234b7229d1be245fc04c5a3201e4615f430059d0711ff5ddb2e6bb236ec90eed134cb5a19d8ef36602af5ecdbfeeac05dda0798d3abebde87e3faa374d3807fa0d633a52d38d8de6f679fe33fc776e196f53cd010188256a3600a292882096246517815ca99884606e18044a3a40d91824820924265a7923a2e8bcd05f33db1173e002913175f2a6be6d3294871a2d95fa00e8a94ee017b69d339d90df1e77c57ea072ede6758</data>
23 </pixmap>
24 </customwidget>
25</customwidgets>
26</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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qt Palmtop Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef Addressbook_H
21#define Addressbook_H
22
23#include <qmainwindow.h>
24
25class AbEditor;
26class AbLabel;
27class AbTable;
28class QPEToolBar;
29class QPopupMenu;
30class QToolButton;
31class QDialog;
32class Ir;
33class QAction;
34
35class AddressbookWindow: public QMainWindow
36{
37 Q_OBJECT
38public:
39 AddressbookWindow( QWidget *parent = 0, const char *name = 0, WFlags f = 0 );
40 ~AddressbookWindow();
41
42protected:
43 void resizeEvent( QResizeEvent * e );
44 void showList();
45 void showView();
46 enum EntryMode { NewEntry=0, EditEntry };
47 void editPersonal();
48 void editEntry( EntryMode );
49 void closeEvent( QCloseEvent *e );
50 bool save();
51
52public slots:
53 void flush();
54 void reload();
55 void appMessage(const QCString &, const QByteArray &);
56 void setDocument( const QString & );
57
58private slots:
59 void slotListNew();
60 void slotListView();
61 void slotListDelete();
62 void slotViewBack();
63 void slotViewEdit();
64 void slotPersonalView();
65 void listIsEmpty( bool );
66 void slotSettings();
67 void writeMail();
68 void slotBeam();
69 void beamDone( Ir * );
70 void slotFind();
71 void slotSetCategory( int );
72 void slotUpdateToolbar();
73
74private:
75 void initFields();// inititialize our fields...
76 AbLabel *abView();
77 void populateCategories();
78
79 QPopupMenu *catMenu;
80 QPEToolBar *listTools;
81 QToolButton *deleteButton;
82 QValueList<int> allFields,
83 orderedFields;
84 QStringList slOrderedFields;
85 enum Panes { paneList=0, paneView, paneEdit };
86 AbEditor *abEditor;
87 AbLabel *mView;
88 AbTable *abList;
89
90 QAction *actionNew, *actionEdit, *actionTrash, *actionFind, *actionBeam,
91 *actionPersonal, *actionMail;
92
93 bool bAbEditFirstTime;
94 int viewMargin;
95
96 bool syncing;
97};
98
99#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 @@
1 TEMPLATE= app
2 CONFIG = qt warn_on release
3 DESTDIR = $(QPEDIR)/bin
4 HEADERS= addressbook.h \
5 abeditor.h \
6 ablabel.h \
7 abtable.h \
8 addresssettings.h
9 SOURCES= main.cpp \
10 addressbook.cpp \
11 abeditor.cpp \
12 ablabel.cpp \
13 abtable.cpp \
14 addresssettings.cpp
15 INTERFACES= addresssettingsbase.ui
16
17 TARGET = addressbook
18INCLUDEPATH += $(QPEDIR)/include
19 DEPENDPATH+= $(QPEDIR)/include
20LIBS += -lqpe
21
22TRANSLATIONS = ../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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qt Palmtop Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "addresspicker.h"
22#include "abtable.h"
23
24#include <qlayout.h>
25
26/*!
27 \a tab is reparented for use in the picker. Take it back out if you want
28 to regain ownership.
29*/
30AddressPicker::AddressPicker(AbTable* tab, QWidget* parent, const char* name, bool modal) :
31 QDialog(parent,name,modal)
32{
33 QVBoxLayout* vb = new QVBoxLayout(this);
34 tab->reparent(this,QPoint(0,0));
35 table = tab;
36 vb->addWidget(table);
37}
38
39void AddressPicker::setChoiceNames(const QStringList& list)
40{
41 table->setChoiceNames(list);
42}
43
44void AddressPicker::setSelection(int index, const QStringList& list)
45{
46 table->setChoiceSelection(index,list);
47}
48
49QStringList AddressPicker::selection(int index) const
50{
51 return table->choiceSelection(index);
52}
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qt Palmtop Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#ifndef AddressPicker_H
21#define AddressPicker_H
22
23#include <qdialog.h>
24
25class AbTable;
26
27class AddressPicker : public QDialog {
28public:
29 AddressPicker(AbTable* table, QWidget* parent, const char* name=0, bool modal=FALSE);
30
31 void setChoiceNames(const QStringList&);
32 void setSelection(int index, const QStringList&);
33 QStringList selection(int index) const;
34
35private:
36 AbTable* table;
37};
38
39#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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qt Palmtop Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21
22#include "addresssettings.h"
23
24#include <qpe/config.h>
25#include <qpe/contact.h>
26
27#include <qfile.h>
28#include <qlistbox.h>
29
30#include <stdlib.h>
31
32AddressSettings::AddressSettings( QWidget *parent, const char *name )
33 : AddressSettingsBase( parent, name, TRUE )
34{
35 init();
36}
37
38AddressSettings::~AddressSettings()
39{
40}
41
42void AddressSettings::init()
43{
44 QStringList slFields = Contact::trfields();
45 // Make this match what is in initFields
46 slFields.remove( tr("Name Title") );
47 slFields.remove( tr("First Name") );
48 slFields.remove( tr("Last Name") );
49 slFields.remove( tr("File As") );
50 slFields.remove( tr("Default Email") );
51 slFields.remove( tr("Notes") );
52 slFields.remove( tr("Gender") );
53
54
55 for( QStringList::Iterator it = slFields.begin();
56 it != slFields.end(); ++it ) {
57 fieldListBox->insertItem( *it );
58 }
59
60 Config cfg( "AddressBook" );
61
62 cfg.setGroup( "Version" );
63 int version;
64 version = cfg.readNumEntry( "version" );
65 if ( version >= ADDRESSVERSION ) {
66 int i = 0;
67 int p = 0;
68 cfg.setGroup( "ImportantCategory" );
69 QString zn = cfg.readEntry( "Category" + QString::number(i),
70 QString::null );
71 while ( !zn.isNull() ) {
72 for ( int m = i; m < (int)fieldListBox->count(); m++ ) {
73 if ( fieldListBox->text( m ) == zn ) {
74 if ( m != p ) {
75 fieldListBox->removeItem( m );
76 fieldListBox->insertItem( zn, p );
77 }
78 p++;
79 break;
80 }
81 }
82 zn = cfg.readEntry( "Category" + QString::number(++i),
83 QString::null );
84 }
85
86 fieldListBox->setCurrentItem( 0 );
87 } else {
88 QString str;
89 str = getenv("HOME");
90
91 str += "/Settings/AddressBook.conf";
92 QFile::remove( str );
93 }
94}
95
96void AddressSettings::itemUp()
97{
98 int i = fieldListBox->currentItem();
99 if ( i > 0 ) {
100 QString item = fieldListBox->currentText();
101 fieldListBox->removeItem( i );
102 fieldListBox->insertItem( item, i-1 );
103 fieldListBox->setCurrentItem( i-1 );
104 }
105}
106
107void AddressSettings::itemDown()
108{
109 int i = fieldListBox->currentItem();
110 if ( i < (int)fieldListBox->count() - 1 ) {
111 QString item = fieldListBox->currentText();
112 fieldListBox->removeItem( i );
113 fieldListBox->insertItem( item, i+1 );
114 fieldListBox->setCurrentItem( i+1 );
115 }
116}
117
118void AddressSettings::accept()
119{
120 save();
121 QDialog::accept();
122}
123
124
125void AddressSettings::save()
126{
127 Config cfg( "AddressBook" );
128 cfg.setGroup( "Version" );
129 // *** To change the version change it here...
130 cfg.writeEntry( "version", QString::number(ADDRESSVERSION) );
131 cfg.setGroup( "ImportantCategory" );
132
133 for ( int i = 0; i < (int)fieldListBox->count(); i++ ) {
134 cfg.writeEntry( "Category"+QString::number(i), fieldListBox->text(i) );
135 }
136}
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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qt Palmtop Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#ifndef _ADDRESSSETTINGS_H_
22#define _ADDRESSSETTINGS_H_
23
24#include <qlist.h>
25#include <qstringlist.h>
26#include "addresssettingsbase.h"
27
28const int ADDRESSVERSION = 3;
29
30class AddressSettings : public AddressSettingsBase
31{
32 Q_OBJECT
33public:
34 AddressSettings( QWidget *parent = 0, const char *name = 0 );
35 ~AddressSettings();
36
37protected:
38 void accept();
39 virtual void itemUp();
40 virtual void itemDown();
41
42private:
43 void init();
44 void save();
45};
46
47#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 @@
1<!DOCTYPE UI><UI>
2<class>AddressSettingsBase</class>
3<comment>/**********************************************************************
4** Copyright (C) 2001 Trolltech AS. All rights reserved.
5**
6** This file is part of Qt Palmtop Environment.
7**
8** This file may be distributed and/or modified under the terms of the
9** GNU General Public License version 2 as published by the Free Software
10** Foundation and appearing in the file LICENSE.GPL included in the
11** packaging of this file.
12**
13** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
14** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
15**
16** See http://www.trolltech.com/gpl/ for GPL licensing information.
17**
18** Contact info@trolltech.com if any conditions of this licensing are
19** not clear to you.
20**
21** $Id$
22**
23**********************************************************************/</comment>
24<widget>
25 <class>QDialog</class>
26 <property stdset="1">
27 <name>name</name>
28 <cstring>AddressSettingsBase</cstring>
29 </property>
30 <property stdset="1">
31 <name>geometry</name>
32 <rect>
33 <x>0</x>
34 <y>0</y>
35 <width>244</width>
36 <height>207</height>
37 </rect>
38 </property>
39 <property stdset="1">
40 <name>caption</name>
41 <string>Arrange Edit Fields</string>
42 </property>
43 <property>
44 <name>layoutMargin</name>
45 </property>
46 <property>
47 <name>layoutSpacing</name>
48 </property>
49 <grid>
50 <property stdset="1">
51 <name>margin</name>
52 <number>6</number>
53 </property>
54 <property stdset="1">
55 <name>spacing</name>
56 <number>6</number>
57 </property>
58 <widget row="1" column="0" rowspan="3" colspan="1" >
59 <class>QListBox</class>
60 <property stdset="1">
61 <name>name</name>
62 <cstring>fieldListBox</cstring>
63 </property>
64 </widget>
65 <widget row="0" column="0" rowspan="1" colspan="2" >
66 <class>QLabel</class>
67 <property stdset="1">
68 <name>name</name>
69 <cstring>lblExplain</cstring>
70 </property>
71 <property stdset="1">
72 <name>sizePolicy</name>
73 <sizepolicy>
74 <hsizetype>1</hsizetype>
75 <vsizetype>1</vsizetype>
76 </sizepolicy>
77 </property>
78 <property stdset="1">
79 <name>frameShape</name>
80 <enum>MShape</enum>
81 </property>
82 <property stdset="1">
83 <name>frameShadow</name>
84 <enum>MShadow</enum>
85 </property>
86 <property stdset="1">
87 <name>text</name>
88 <string>Select the field order:</string>
89 </property>
90 <property stdset="1">
91 <name>alignment</name>
92 <set>AlignTop|AlignLeft</set>
93 </property>
94 <property>
95 <name>hAlign</name>
96 </property>
97 <property>
98 <name>vAlign</name>
99 </property>
100 </widget>
101 <widget row="1" column="1" >
102 <class>QPushButton</class>
103 <property stdset="1">
104 <name>name</name>
105 <cstring>upButton</cstring>
106 </property>
107 <property stdset="1">
108 <name>text</name>
109 <string>Up</string>
110 </property>
111 <property stdset="1">
112 <name>autoRepeat</name>
113 <bool>true</bool>
114 </property>
115 </widget>
116 <widget row="2" column="1" >
117 <class>QPushButton</class>
118 <property stdset="1">
119 <name>name</name>
120 <cstring>downButton</cstring>
121 </property>
122 <property stdset="1">
123 <name>text</name>
124 <string>Down</string>
125 </property>
126 <property stdset="1">
127 <name>autoRepeat</name>
128 <bool>true</bool>
129 </property>
130 </widget>
131 <spacer row="3" column="1" >
132 <property>
133 <name>name</name>
134 <cstring>Spacer2</cstring>
135 </property>
136 <property stdset="1">
137 <name>orientation</name>
138 <enum>Vertical</enum>
139 </property>
140 <property stdset="1">
141 <name>sizeType</name>
142 <enum>Expanding</enum>
143 </property>
144 <property>
145 <name>sizeHint</name>
146 <size>
147 <width>20</width>
148 <height>20</height>
149 </size>
150 </property>
151 </spacer>
152 </grid>
153</widget>
154<connections>
155 <connection>
156 <sender>upButton</sender>
157 <signal>clicked()</signal>
158 <receiver>AddressSettingsBase</receiver>
159 <slot>itemUp()</slot>
160 </connection>
161 <connection>
162 <sender>downButton</sender>
163 <signal>clicked()</signal>
164 <receiver>AddressSettingsBase</receiver>
165 <slot>itemDown()</slot>
166 </connection>
167 <slot access="protected">itemUp()</slot>
168 <slot access="protected">itemDown()</slot>
169</connections>
170</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 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qt Palmtop Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "addressbook.h"
22
23#include <qpe/qpeapplication.h>
24#include <qpe/qcopenvelope_qws.h>
25#include <qstring.h>
26
27int main( int argc, char ** argv )
28{
29 QPEApplication a( argc, argv );
30
31 AddressbookWindow mw;
32 QObject::connect( &a, SIGNAL( flush() ), &mw, SLOT( flush() ) );
33 QObject::connect( &a, SIGNAL( reload() ), &mw, SLOT( reload() ) );
34 QObject::connect( &a, SIGNAL( appMessage(const QCString &, const QByteArray &) ),
35 &mw, SLOT( appMessage(const QCString &, const QByteArray &) ) );
36
37 mw.setCaption( AddressbookWindow::tr("Contacts") );
38 a.showMainDocumentWidget(&mw);
39
40 return a.exec();
41}
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 @@
1Files: bin/addressbook apps/Applications/addressbook.desktop
2Priority: optional
3Section: qpe/applications
4Maintainer: Warwick Allison <warwick@trolltech.com>
5Architecture: arm
6Version: $QPE_VERSION-3
7Depends: qpe-base ($QPE_VERSION)
8Description: Contacts
9 A simple addressbook for the Qtopia environment.