summaryrefslogtreecommitdiff
path: root/core/pim
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
downloadopie-15318cad33835e4e2dc620d033e43cd930676cdd.zip
opie-15318cad33835e4e2dc620d033e43cd930676cdd.tar.gz
opie-15318cad33835e4e2dc620d033e43cd930676cdd.tar.bz2
Initial revision
Diffstat (limited to 'core/pim') (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
-rw-r--r--core/pim/datebook/.cvsignore12
-rw-r--r--core/pim/datebook/Makefile.in385
-rw-r--r--core/pim/datebook/datebook.cpp854
-rw-r--r--core/pim/datebook/datebook.h111
-rw-r--r--core/pim/datebook/datebook.pro36
-rw-r--r--core/pim/datebook/datebookday.cpp553
-rw-r--r--core/pim/datebook/datebookday.h138
-rw-r--r--core/pim/datebook/datebookdayheader.ui424
-rw-r--r--core/pim/datebook/datebookdayheaderimpl.cpp181
-rw-r--r--core/pim/datebook/datebookdayheaderimpl.h57
-rw-r--r--core/pim/datebook/datebooksettings.cpp135
-rw-r--r--core/pim/datebook/datebooksettings.h48
-rw-r--r--core/pim/datebook/datebooksettingsbase.ui232
-rw-r--r--core/pim/datebook/datebookweek.cpp687
-rw-r--r--core/pim/datebook/datebookweek.h152
-rw-r--r--core/pim/datebook/datebookweekheader.ui167
-rw-r--r--core/pim/datebook/datebookweekheaderimpl.cpp126
-rw-r--r--core/pim/datebook/datebookweekheaderimpl.h62
-rw-r--r--core/pim/datebook/dateentry.ui1095
-rw-r--r--core/pim/datebook/dateentryimpl.cpp474
-rw-r--r--core/pim/datebook/dateentryimpl.h71
-rw-r--r--core/pim/datebook/main.cpp38
-rw-r--r--core/pim/datebook/qpe-datebook.control9
-rw-r--r--core/pim/datebook/repeatentry.cpp595
-rw-r--r--core/pim/datebook/repeatentry.h98
-rw-r--r--core/pim/datebook/repeatentrybase.ui713
-rw-r--r--core/pim/todo/.cvsignore4
-rw-r--r--core/pim/todo/Makefile.in201
-rw-r--r--core/pim/todo/main.cpp36
-rw-r--r--core/pim/todo/mainwindow.cpp466
-rw-r--r--core/pim/todo/mainwindow.h73
-rw-r--r--core/pim/todo/qpe-todo.control9
-rw-r--r--core/pim/todo/todo.pro19
-rw-r--r--core/pim/todo/todoentry.ui266
-rw-r--r--core/pim/todo/todoentryimpl.cpp142
-rw-r--r--core/pim/todo/todoentryimpl.h61
-rw-r--r--core/pim/todo/todotable.cpp859
-rw-r--r--core/pim/todo/todotable.h207
57 files changed, 13558 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.
diff --git a/core/pim/datebook/.cvsignore b/core/pim/datebook/.cvsignore
new file mode 100644
index 0000000..4ba477d
--- a/dev/null
+++ b/core/pim/datebook/.cvsignore
@@ -0,0 +1,12 @@
1moc_*
2Makefile
3dateentry.h
4datebookdayheader.h
5dateentry.cpp
6datebookdayheader.cpp
7datebookweekheader.cpp
8datebookweekheader.h
9datebooksettingsbase.h
10datebooksettingsbase.cpp
11repeatentrybase.cpp
12repeatentrybase.h
diff --git a/core/pim/datebook/Makefile.in b/core/pim/datebook/Makefile.in
new file mode 100644
index 0000000..bdc69dc
--- a/dev/null
+++ b/core/pim/datebook/Makefile.in
@@ -0,0 +1,385 @@
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= datebook
22TARGET1 = lib$(TARGET).so.$(VER_MAJ)
23
24####### Files
25
26 HEADERS =datebookday.h \
27 datebook.h \
28 dateentryimpl.h \
29 datebookdayheaderimpl.h \
30 datebooksettings.h \
31 datebookweek.h \
32 datebookweekheaderimpl.h \
33 repeatentry.h
34 SOURCES =main.cpp \
35 datebookday.cpp \
36 datebook.cpp \
37 dateentryimpl.cpp \
38 datebookdayheaderimpl.cpp \
39 datebooksettings.cpp \
40 datebookweek.cpp \
41 datebookweekheaderimpl.cpp \
42 repeatentry.cpp
43 OBJECTS =main.o \
44 datebookday.o \
45 datebook.o \
46 dateentryimpl.o \
47 datebookdayheaderimpl.o \
48 datebooksettings.o \
49 datebookweek.o \
50 datebookweekheaderimpl.o \
51 repeatentry.o \
52 dateentry.o \
53 datebookdayheader.o \
54 datebooksettingsbase.o \
55 datebookweekheader.o \
56 repeatentrybase.o
57INTERFACES = dateentry.ui \
58 datebookdayheader.ui \
59 datebooksettingsbase.ui \
60 datebookweekheader.ui \
61 repeatentrybase.ui
62UICDECLS = dateentry.h \
63 datebookdayheader.h \
64 datebooksettingsbase.h \
65 datebookweekheader.h \
66 repeatentrybase.h
67UICIMPLS = dateentry.cpp \
68 datebookdayheader.cpp \
69 datebooksettingsbase.cpp \
70 datebookweekheader.cpp \
71 repeatentrybase.cpp
72 SRCMOC =moc_datebookday.cpp \
73 moc_datebook.cpp \
74 moc_dateentryimpl.cpp \
75 moc_datebookdayheaderimpl.cpp \
76 moc_datebookweek.cpp \
77 moc_datebookweekheaderimpl.cpp \
78 moc_repeatentry.cpp \
79 moc_dateentry.cpp \
80 moc_datebookdayheader.cpp \
81 moc_datebooksettingsbase.cpp \
82 moc_datebookweekheader.cpp \
83 moc_repeatentrybase.cpp
84 OBJMOC =moc_datebookday.o \
85 moc_datebook.o \
86 moc_dateentryimpl.o \
87 moc_datebookdayheaderimpl.o \
88 moc_datebookweek.o \
89 moc_datebookweekheaderimpl.o \
90 moc_repeatentry.o \
91 moc_dateentry.o \
92 moc_datebookdayheader.o \
93 moc_datebooksettingsbase.o \
94 moc_datebookweekheader.o \
95 moc_repeatentrybase.o
96
97
98####### Implicit rules
99
100.SUFFIXES: .cpp .cxx .cc .C .c
101
102.cpp.o:
103 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
104
105.cxx.o:
106 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
107
108.cc.o:
109 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
110
111.C.o:
112 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
113
114.c.o:
115 $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
116
117####### Build rules
118
119
120all: $(DESTDIR)$(TARGET)
121
122$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
123 $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
124
125moc: $(SRCMOC)
126
127tmake:
128 tmake datebook.pro
129
130clean:
131 -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
132 -rm -f *~ core
133 -rm -f allmoc.cpp
134
135####### Extension Modules
136
137listpromodules:
138 @echo
139
140listallmodules:
141 @echo
142
143listaddonpromodules:
144 @echo
145
146listaddonentmodules:
147 @echo
148
149
150REQUIRES=
151
152####### Sub-libraries
153
154
155###### Combined headers
156
157
158
159####### Compile
160
161main.o: main.cpp \
162 datebook.h \
163 $(QPEDIR)/include/qpe/datebookdb.h \
164 $(QPEDIR)/include/qpe/event.h \
165 $(QPEDIR)/include/qpe/palmtoprecord.h \
166 $(QPEDIR)/include/qpe/qpeapplication.h
167
168datebookday.o: datebookday.cpp \
169 datebookday.h \
170 $(QPEDIR)/include/qpe/event.h \
171 $(QPEDIR)/include/qpe/palmtoprecord.h \
172 datebookdayheaderimpl.h \
173 datebookdayheader.h \
174 $(QPEDIR)/include/qpe/datebookdb.h \
175 $(QPEDIR)/include/qpe/resource.h \
176 $(QPEDIR)/include/qpe/qpeapplication.h \
177 $(QPEDIR)/include/qpe/timestring.h \
178 $(QPEDIR)/include/qpe/qpedebug.h
179
180datebook.o: datebook.cpp \
181 datebook.h \
182 $(QPEDIR)/include/qpe/datebookdb.h \
183 $(QPEDIR)/include/qpe/event.h \
184 $(QPEDIR)/include/qpe/palmtoprecord.h \
185 datebookday.h \
186 datebooksettings.h \
187 datebooksettingsbase.h \
188 datebookweek.h \
189 dateentryimpl.h \
190 dateentry.h \
191 $(QPEDIR)/include/qpe/datebookmonth.h \
192 $(QPEDIR)/include/qpe/qpeapplication.h \
193 $(QPEDIR)/include/qpe/config.h \
194 $(QPEDIR)/include/qpe/qpedebug.h \
195 $(QPEDIR)/include/qpe/finddialog.h \
196 $(QPEDIR)/include/qpe/ir.h \
197 $(QPEDIR)/include/qpe/qpemenubar.h \
198 $(QPEDIR)/include/qpe/qpemessagebox.h \
199 $(QPEDIR)/include/qpe/resource.h \
200 $(QPEDIR)/include/qpe/sound.h \
201 $(QPEDIR)/include/qpe/timestring.h \
202 $(QPEDIR)/include/qpe/qpetoolbar.h \
203 $(QPEDIR)/include/qpe/tzselect.h \
204 $(QPEDIR)/include/qpe/xmlreader.h
205
206dateentryimpl.o: dateentryimpl.cpp \
207 dateentryimpl.h \
208 dateentry.h \
209 $(QPEDIR)/include/qpe/event.h \
210 $(QPEDIR)/include/qpe/palmtoprecord.h \
211 repeatentry.h \
212 repeatentrybase.h \
213 $(QPEDIR)/include/qpe/qpeapplication.h \
214 $(QPEDIR)/include/qpe/categoryselect.h \
215 $(QPEDIR)/include/qpe/datebookmonth.h \
216 $(QPEDIR)/include/qpe/global.h \
217 $(QPEDIR)/include/qpe/timeconversion.h \
218 $(QPEDIR)/include/qpe/timestring.h \
219 $(QPEDIR)/include/qpe/tzselect.h
220
221datebookdayheaderimpl.o: datebookdayheaderimpl.cpp \
222 datebookdayheaderimpl.h \
223 datebookdayheader.h \
224 $(QPEDIR)/include/qpe/datebookmonth.h \
225 $(QPEDIR)/include/qpe/event.h \
226 $(QPEDIR)/include/qpe/palmtoprecord.h \
227 $(QPEDIR)/include/qpe/timestring.h
228
229datebooksettings.o: datebooksettings.cpp \
230 datebooksettings.h \
231 datebooksettingsbase.h \
232 $(QPEDIR)/include/qpe/qpeapplication.h
233
234datebookweek.o: datebookweek.cpp \
235 datebookweek.h \
236 $(QPEDIR)/include/qpe/event.h \
237 $(QPEDIR)/include/qpe/palmtoprecord.h \
238 datebookweekheaderimpl.h \
239 datebookweekheader.h \
240 $(QPEDIR)/include/qpe/calendar.h \
241 $(QPEDIR)/include/qpe/datebookdb.h \
242 $(QPEDIR)/include/qpe/qpeapplication.h \
243 $(QPEDIR)/include/qpe/timestring.h
244
245datebookweekheaderimpl.o: datebookweekheaderimpl.cpp \
246 datebookweekheaderimpl.h \
247 datebookweekheader.h
248
249repeatentry.o: repeatentry.cpp \
250 repeatentry.h \
251 repeatentrybase.h \
252 $(QPEDIR)/include/qpe/event.h \
253 $(QPEDIR)/include/qpe/palmtoprecord.h \
254 $(QPEDIR)/include/qpe/datebookmonth.h \
255 $(QPEDIR)/include/qpe/qpeapplication.h \
256 $(QPEDIR)/include/qpe/timestring.h
257
258dateentry.h: dateentry.ui
259 $(UIC) dateentry.ui -o $(INTERFACE_DECL_PATH)/dateentry.h
260
261dateentry.cpp: dateentry.ui
262 $(UIC) dateentry.ui -i dateentry.h -o dateentry.cpp
263
264datebookdayheader.h: datebookdayheader.ui
265 $(UIC) datebookdayheader.ui -o $(INTERFACE_DECL_PATH)/datebookdayheader.h
266
267datebookdayheader.cpp: datebookdayheader.ui
268 $(UIC) datebookdayheader.ui -i datebookdayheader.h -o datebookdayheader.cpp
269
270datebooksettingsbase.h: datebooksettingsbase.ui
271 $(UIC) datebooksettingsbase.ui -o $(INTERFACE_DECL_PATH)/datebooksettingsbase.h
272
273datebooksettingsbase.cpp: datebooksettingsbase.ui
274 $(UIC) datebooksettingsbase.ui -i datebooksettingsbase.h -o datebooksettingsbase.cpp
275
276datebookweekheader.h: datebookweekheader.ui
277 $(UIC) datebookweekheader.ui -o $(INTERFACE_DECL_PATH)/datebookweekheader.h
278
279datebookweekheader.cpp: datebookweekheader.ui
280 $(UIC) datebookweekheader.ui -i datebookweekheader.h -o datebookweekheader.cpp
281
282repeatentrybase.h: repeatentrybase.ui
283 $(UIC) repeatentrybase.ui -o $(INTERFACE_DECL_PATH)/repeatentrybase.h
284
285repeatentrybase.cpp: repeatentrybase.ui
286 $(UIC) repeatentrybase.ui -i repeatentrybase.h -o repeatentrybase.cpp
287
288dateentry.o: dateentry.cpp
289
290datebookdayheader.o: datebookdayheader.cpp
291
292datebooksettingsbase.o: datebooksettingsbase.cpp
293
294datebookweekheader.o: datebookweekheader.cpp
295
296repeatentrybase.o: repeatentrybase.cpp
297
298moc_datebookday.o: moc_datebookday.cpp \
299 datebookday.h \
300 $(QPEDIR)/include/qpe/event.h \
301 $(QPEDIR)/include/qpe/palmtoprecord.h
302
303moc_datebook.o: moc_datebook.cpp \
304 datebook.h \
305 $(QPEDIR)/include/qpe/datebookdb.h \
306 $(QPEDIR)/include/qpe/event.h \
307 $(QPEDIR)/include/qpe/palmtoprecord.h
308
309moc_dateentryimpl.o: moc_dateentryimpl.cpp \
310 dateentryimpl.h \
311 dateentry.h \
312 $(QPEDIR)/include/qpe/event.h \
313 $(QPEDIR)/include/qpe/palmtoprecord.h
314
315moc_datebookdayheaderimpl.o: moc_datebookdayheaderimpl.cpp \
316 datebookdayheaderimpl.h \
317 datebookdayheader.h
318
319moc_datebookweek.o: moc_datebookweek.cpp \
320 datebookweek.h \
321 $(QPEDIR)/include/qpe/event.h \
322 $(QPEDIR)/include/qpe/palmtoprecord.h
323
324moc_datebookweekheaderimpl.o: moc_datebookweekheaderimpl.cpp \
325 datebookweekheaderimpl.h \
326 datebookweekheader.h
327
328moc_repeatentry.o: moc_repeatentry.cpp \
329 repeatentry.h \
330 repeatentrybase.h \
331 $(QPEDIR)/include/qpe/event.h \
332 $(QPEDIR)/include/qpe/palmtoprecord.h
333
334moc_dateentry.o: moc_dateentry.cpp \
335 dateentry.h
336
337moc_datebookdayheader.o: moc_datebookdayheader.cpp \
338 datebookdayheader.h
339
340moc_datebooksettingsbase.o: moc_datebooksettingsbase.cpp \
341 datebooksettingsbase.h
342
343moc_datebookweekheader.o: moc_datebookweekheader.cpp \
344 datebookweekheader.h
345
346moc_repeatentrybase.o: moc_repeatentrybase.cpp \
347 repeatentrybase.h
348
349moc_datebookday.cpp: datebookday.h
350 $(MOC) datebookday.h -o moc_datebookday.cpp
351
352moc_datebook.cpp: datebook.h
353 $(MOC) datebook.h -o moc_datebook.cpp
354
355moc_dateentryimpl.cpp: dateentryimpl.h
356 $(MOC) dateentryimpl.h -o moc_dateentryimpl.cpp
357
358moc_datebookdayheaderimpl.cpp: datebookdayheaderimpl.h
359 $(MOC) datebookdayheaderimpl.h -o moc_datebookdayheaderimpl.cpp
360
361moc_datebookweek.cpp: datebookweek.h
362 $(MOC) datebookweek.h -o moc_datebookweek.cpp
363
364moc_datebookweekheaderimpl.cpp: datebookweekheaderimpl.h
365 $(MOC) datebookweekheaderimpl.h -o moc_datebookweekheaderimpl.cpp
366
367moc_repeatentry.cpp: repeatentry.h
368 $(MOC) repeatentry.h -o moc_repeatentry.cpp
369
370moc_dateentry.cpp: dateentry.h
371 $(MOC) dateentry.h -o moc_dateentry.cpp
372
373moc_datebookdayheader.cpp: datebookdayheader.h
374 $(MOC) datebookdayheader.h -o moc_datebookdayheader.cpp
375
376moc_datebooksettingsbase.cpp: datebooksettingsbase.h
377 $(MOC) datebooksettingsbase.h -o moc_datebooksettingsbase.cpp
378
379moc_datebookweekheader.cpp: datebookweekheader.h
380 $(MOC) datebookweekheader.h -o moc_datebookweekheader.cpp
381
382moc_repeatentrybase.cpp: repeatentrybase.h
383 $(MOC) repeatentrybase.h -o moc_repeatentrybase.cpp
384
385
diff --git a/core/pim/datebook/datebook.cpp b/core/pim/datebook/datebook.cpp
new file mode 100644
index 0000000..6ec6cc2
--- a/dev/null
+++ b/core/pim/datebook/datebook.cpp
@@ -0,0 +1,854 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia 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** $Id$
20**
21**********************************************************************/
22
23#include "datebook.h"
24#include "datebookday.h"
25#include "datebooksettings.h"
26#include "datebookweek.h"
27#include "dateentryimpl.h"
28
29#include <qpe/datebookmonth.h>
30#include <qpe/qpeapplication.h>
31#include <qpe/config.h>
32#include <qpe/qpedebug.h>
33#include <qpe/event.h>
34#include <qpe/finddialog.h>
35#include <qpe/ir.h>
36#include <qpe/qpemenubar.h>
37#include <qpe/qpemessagebox.h>
38#include <qpe/resource.h>
39#include <qpe/sound.h>
40#include <qpe/timestring.h>
41#include <qpe/qpetoolbar.h>
42#include <qpe/tzselect.h>
43#include <qpe/xmlreader.h>
44
45#include <qaction.h>
46#include <qcopchannel_qws.h>
47#include <qdatetime.h>
48#include <qdialog.h>
49#include <qfile.h>
50#include <qlabel.h>
51#include <qlayout.h>
52#include <qmessagebox.h>
53#include <qpopupmenu.h>
54#include <qpushbutton.h>
55#include <qtextcodec.h>
56#include <qtextstream.h>
57#include <qtl.h>
58#include <qwidgetstack.h>
59#include <qwindowsystem_qws.h>
60
61#include <sys/stat.h>
62#include <sys/types.h>
63#include <fcntl.h>
64#include <unistd.h>
65
66#include <stdlib.h>
67
68#define DAY 1
69#define WEEK 2
70#define MONTH 3
71
72
73DateBook::DateBook( QWidget *parent, const char *, WFlags f )
74 : QMainWindow( parent, "datebook", f ),
75 aPreset( FALSE ),
76 presetTime( -1 ),
77 startTime( 8 ), // an acceptable default
78 syncing(FALSE),
79 inSearch(FALSE)
80{
81 QTime t;
82 t.start();
83 db = new DateBookDB;
84 qDebug("loading db t=%d", t.elapsed() );
85 loadSettings();
86 setCaption( tr("Calendar") );
87 setIcon( Resource::loadPixmap( "datebook_icon" ) );
88
89 setToolBarsMovable( FALSE );
90
91 QPEToolBar *bar = new QPEToolBar( this );
92 bar->setHorizontalStretchable( TRUE );
93
94 QPEMenuBar *mb = new QPEMenuBar( bar );
95 mb->setMargin( 0 );
96
97 QPEToolBar *sub_bar = new QPEToolBar(this);
98
99 QPopupMenu *view = new QPopupMenu( this );
100 QPopupMenu *settings = new QPopupMenu( this );
101
102 mb->insertItem( tr( "View" ), view );
103 mb->insertItem( tr( "Settings" ), settings );
104
105 QActionGroup *g = new QActionGroup( this );
106 g->setExclusive( TRUE );
107
108 QAction *a = new QAction( tr( "New" ), Resource::loadPixmap( "new" ),
109 QString::null, 0, this, 0 );
110 connect( a, SIGNAL( activated() ), this, SLOT( fileNew() ) );
111 a->addTo( sub_bar );
112
113 a = new QAction( tr( "Day" ), Resource::loadPixmap( "day" ), QString::null, 0, g, 0 );
114 connect( a, SIGNAL( activated() ), this, SLOT( viewDay() ) );
115 a->addTo( sub_bar );
116 a->addTo( view );
117 a->setToggleAction( TRUE );
118 a->setOn( TRUE );
119 dayAction = a;
120 a = new QAction( tr( "Week" ), Resource::loadPixmap( "week" ), QString::null, 0, g, 0 );
121 connect( a, SIGNAL( activated() ), this, SLOT( viewWeek() ) );
122 a->addTo( sub_bar );
123 a->addTo( view );
124 a->setToggleAction( TRUE );
125 weekAction = a;
126 a = new QAction( tr( "Month" ), Resource::loadPixmap( "month" ), QString::null, 0, g, 0 );
127 connect( a, SIGNAL( activated() ), this, SLOT( viewMonth() ) );
128 a->addTo( sub_bar );
129 a->addTo( view );
130 a->setToggleAction( TRUE );
131 monthAction = a;
132
133 a = new QAction( tr( "Find" ), Resource::loadPixmap( "mag" ), QString::null, 0, g, 0 );
134 connect( a, SIGNAL(activated()), this, SLOT(slotFind()) );
135 a->addTo( sub_bar );
136
137 a = new QAction( tr( "Today" ), QString::null, 0, 0 );
138 connect( a, SIGNAL( activated() ), this, SLOT( slotToday() ) );
139 a->addTo( view );
140
141 a = new QAction( tr( "Alarm and Start Time..." ), QString::null, 0, 0 );
142 connect( a, SIGNAL( activated() ), this, SLOT( slotSettings() ) );
143 a->addTo( settings );
144
145 views = new QWidgetStack( this );
146 setCentralWidget( views );
147
148 dayView = 0;
149 weekView = 0;
150 monthView = 0;
151
152 viewDay();
153 connect( qApp, SIGNAL(clockChanged(bool)),
154 this, SLOT(changeClock(bool)) );
155 connect( qApp, SIGNAL(weekChanged(bool)),
156 this, SLOT(changeWeek(bool)) );
157
158#if defined(Q_WS_QWS) && !defined(QT_NO_COP)
159 connect( qApp, SIGNAL(appMessage(const QCString&, const QByteArray&)),
160 this, SLOT(appMessage(const QCString&, const QByteArray&)) );
161#endif
162
163 // listen on QPE/System
164#if defined(Q_WS_QWS)
165#if !defined(QT_NO_COP)
166 QCopChannel *channel = new QCopChannel( "QPE/System", this );
167 connect( channel, SIGNAL(received(const QCString&, const QByteArray&)),
168 this, SLOT(receive(const QCString&, const QByteArray&)) );
169#endif
170#endif
171
172 qDebug("done t=%d", t.elapsed() );
173
174}
175
176void DateBook::receive( const QCString &msg, const QByteArray &data )
177{
178 QDataStream stream( data, IO_ReadOnly );
179 if ( msg == "timeChange(QString)" ) {
180 // update active view!
181 if ( dayAction->isOn() )
182 viewDay();
183 else if ( weekAction->isOn() )
184 viewWeek();
185 else if ( monthAction->isOn() )
186 viewMonth();
187 }
188}
189
190DateBook::~DateBook()
191{
192}
193
194void DateBook::slotSettings()
195{
196 DateBookSettings frmSettings( ampm, this );
197 frmSettings.setStartTime( startTime );
198 frmSettings.setAlarmPreset( aPreset, presetTime );
199#if defined (Q_WS_QWS) || defined(_WS_QWS_)
200 frmSettings.showMaximized();
201#endif
202
203 if ( frmSettings.exec() ) {
204 aPreset = frmSettings.alarmPreset();
205 presetTime = frmSettings.presetTime();
206 startTime = frmSettings.startTime();
207 if ( dayView )
208 dayView->setStartViewTime( startTime );
209 if ( weekView )
210 weekView->setStartViewTime( startTime );
211 saveSettings();
212
213 // make the change obvious
214 if ( views->visibleWidget() ) {
215 if ( views->visibleWidget() == dayView )
216 dayView->redraw();
217 else if ( views->visibleWidget() == weekView )
218 weekView->redraw();
219 }
220 }
221}
222
223void DateBook::fileNew()
224{
225 slotNewEventFromKey("");
226}
227
228QString DateBook::checkEvent(const Event &e)
229{
230 /* check if overlaps with itself */
231 bool checkFailed = FALSE;
232
233 /* check the next 12 repeats. should catch most problems */
234 QDate current_date = e.start().date();
235 Event previous = e;
236 for(int i = 0; i < 12; i++)
237 {
238 QDateTime next;
239 if (!nextOccurance(previous, current_date.addDays(1), next)) {
240 break; // no more repeats
241 }
242 if(next < previous.end()) {
243 checkFailed = TRUE;
244 break;
245 }
246 current_date = next.date();
247 }
248
249 if(checkFailed)
250 return tr("Event duration is potentially longer\n"
251 "than interval between repeats.");
252
253 return QString::null;
254}
255
256QDate DateBook::currentDate()
257{
258 QDate d = QDate::currentDate();
259
260 if ( dayView && views->visibleWidget() == dayView ) {
261 d = dayView->date();
262 } else if ( weekView && views->visibleWidget() == weekView ) {
263 d = weekView->date();
264 } else if ( monthView && views->visibleWidget() == monthView ) {
265 d = monthView->selectedDate();
266 }
267
268 return d;
269}
270
271void DateBook::viewDay()
272{
273 initDay();
274 dayAction->setOn( TRUE );
275 QDate d = currentDate();
276 dayView->setDate( d );
277 views->raiseWidget( dayView );
278 dayView->redraw();
279}
280
281void DateBook::viewWeek()
282{
283 initWeek();
284 weekAction->setOn( TRUE );
285 QDate d = currentDate();
286 weekView->setDate( d );
287 views->raiseWidget( weekView );
288 weekView->redraw();
289}
290
291void DateBook::viewMonth()
292{
293 initMonth();
294 monthAction->setOn( TRUE );
295 QDate d = currentDate();
296 monthView->setDate( d.year(), d.month(), d.day() );
297 views->raiseWidget( monthView );
298 monthView->redraw();
299}
300
301void DateBook::editEvent( const Event &e )
302{
303 if (syncing) {
304 QMessageBox::warning( this, tr("Calendar"),
305 tr( "Can not edit data, currently syncing") );
306 return;
307 }
308
309 // workaround added for text input.
310 QDialog editDlg( this, 0, TRUE );
311 DateEntry *entry;
312 editDlg.setCaption( tr("Edit Event") );
313 QVBoxLayout *vb = new QVBoxLayout( &editDlg );
314 QScrollView *sv = new QScrollView( &editDlg, "scrollview" );
315 sv->setResizePolicy( QScrollView::AutoOneFit );
316 // KLUDGE!!!
317 sv->setHScrollBarMode( QScrollView::AlwaysOff );
318 vb->addWidget( sv );
319 entry = new DateEntry( onMonday, e, ampm, &editDlg, "editor" );
320 entry->timezone->setEnabled( FALSE );
321 sv->addChild( entry );
322
323#if defined(Q_WS_QWS) || defined(_WS_QWS_)
324 editDlg.showMaximized();
325#endif
326 while (editDlg.exec() ) {
327 Event newEv = entry->event();
328 QString error = checkEvent(newEv);
329 if (!error.isNull()) {
330 if (QMessageBox::warning(this, "error box",
331 error, "Fix it", "Continue", 0, 0, 1) == 0)
332 continue;
333 }
334 db->editEvent(e, newEv);
335 emit newEvent();
336 break;
337 }
338}
339
340void DateBook::removeEvent( const Event &e )
341{
342 if (syncing) {
343 QMessageBox::warning( this, tr("Calendar"),
344 tr( "Can not edit data, currently syncing") );
345 return;
346 }
347
348 QString strName = e.description();
349
350 if ( !QPEMessageBox::confirmDelete( this, tr( "Calendar" ),strName ) )
351 return;
352
353 db->removeEvent( e );
354 if ( views->visibleWidget() == dayView && dayView )
355 dayView->redraw();
356}
357
358void DateBook::addEvent( const Event &e )
359{
360 QDate d = e.start().date();
361 initDay();
362 dayView->setDate( d );
363}
364
365void DateBook::showDay( int year, int month, int day )
366{
367 initDay();
368 dayView->setDate( year, month, day );
369 views->raiseWidget( dayView );
370 dayAction->setOn( TRUE );
371}
372
373void DateBook::initDay()
374{
375 if ( !dayView ) {
376 dayView = new DateBookDay( ampm, onMonday, db, views, "day view" );
377 views->addWidget( dayView, DAY );
378 dayView->setStartViewTime( startTime );
379 connect( this, SIGNAL( newEvent() ),
380 dayView, SLOT( redraw() ) );
381 connect( dayView, SIGNAL( newEvent() ),
382 this, SLOT( fileNew() ) );
383 connect( dayView, SIGNAL( removeEvent( const Event & ) ),
384 this, SLOT( removeEvent( const Event & ) ) );
385 connect( dayView, SIGNAL( editEvent( const Event & ) ),
386 this, SLOT( editEvent( const Event & ) ) );
387 connect( dayView, SIGNAL( beamEvent( const Event & ) ),
388 this, SLOT( beamEvent( const Event & ) ) );
389 connect( dayView, SIGNAL(sigNewEvent(const QString &)),
390 this, SLOT(slotNewEventFromKey(const QString &)) );
391 }
392}
393
394void DateBook::initWeek()
395{
396 if ( !weekView ) {
397 weekView = new DateBookWeek( ampm, onMonday, db, views, "week view" );
398 weekView->setStartViewTime( startTime );
399 views->addWidget( weekView, WEEK );
400 connect( weekView, SIGNAL( showDate( int, int, int ) ),
401 this, SLOT( showDay( int, int, int ) ) );
402 connect( this, SIGNAL( newEvent() ),
403 weekView, SLOT( redraw() ) );
404 }
405 //But also get it right: the year that we display can be different
406 //from the year of the current date. So, first find the year
407 //number of the current week.
408
409 int yearNumber, totWeeks;
410 calcWeek( currentDate(), totWeeks, yearNumber, onMonday );
411
412 QDate d = QDate( yearNumber, 12, 31 );
413 calcWeek( d, totWeeks, yearNumber, onMonday );
414
415 while ( totWeeks == 1 ) {
416 d = d.addDays( -1 );
417 calcWeek( d, totWeeks, yearNumber, onMonday );
418 }
419 if ( totWeeks != weekView->totalWeeks() )
420 weekView->setTotalWeeks( totWeeks );
421}
422
423void DateBook::initMonth()
424{
425 if ( !monthView ) {
426 monthView = new DateBookMonth( views, "month view", FALSE, db );
427 views->addWidget( monthView, MONTH );
428 connect( monthView, SIGNAL( dateClicked( int, int, int ) ),
429 this, SLOT( showDay( int, int, int ) ) );
430 connect( this, SIGNAL( newEvent() ),
431 monthView, SLOT( redraw() ) );
432 qApp->processEvents();
433 }
434}
435
436void DateBook::loadSettings()
437{
438 {
439 Config config( "qpe" );
440 config.setGroup("Time");
441 ampm = config.readBoolEntry( "AMPM", TRUE );
442 onMonday = config.readBoolEntry( "MONDAY" );
443 }
444
445 {
446 Config config("DateBook");
447 config.setGroup("Main");
448 startTime = config.readNumEntry("startviewtime", 8);
449 aPreset = config.readBoolEntry("alarmpreset");
450 presetTime = config.readNumEntry("presettime");
451 }
452}
453
454void DateBook::saveSettings()
455{
456 Config config( "qpe" );
457 Config configDB( "DateBook" );
458 configDB.setGroup( "Main" );
459 configDB.writeEntry("startviewtime",startTime);
460 configDB.writeEntry("alarmpreset",aPreset);
461 configDB.writeEntry("presettime",presetTime);
462}
463
464void DateBook::appMessage(const QCString& msg, const QByteArray& data)
465{
466 bool needShow = FALSE;
467 if ( msg == "alarm(QDateTime,int)" ) {
468 QDataStream ds(data,IO_ReadOnly);
469 QDateTime when; int warn;
470 ds >> when >> warn;
471
472 // check to make it's okay to continue,
473 // this is the case that the time was set ahead, and
474 // we are forced given a stale alarm...
475 QDateTime current = QDateTime::currentDateTime();
476 if ( current.time().hour() != when.time().hour()
477 && current.time().minute() != when.time().minute() )
478 return;
479
480 QValueList<EffectiveEvent> list = db->getEffectiveEvents(when.addSecs(warn*60));
481 if ( list.count() > 0 ) {
482 QString msg;
483 bool bSound = FALSE;
484 int stopTimer = 0;
485 bool found = FALSE;
486 for ( QValueList<EffectiveEvent>::ConstIterator it=list.begin();
487 it!=list.end(); ++it ) {
488 if ( (*it).event().hasAlarm() ) {
489 found = TRUE;
490 msg += "<CENTER><B>" + (*it).description() + "</B>"
491 + "<BR>" + (*it).location() + "<BR>"
492 + TimeString::dateString((*it).event().start(),ampm)
493 + (warn
494 ? tr(" (in " + QString::number(warn)
495 + tr(" minutes)"))
496 : QString(""))
497 + "<BR>"
498 + (*it).notes() + "</CENTER>";
499 if ( (*it).event().alarmSound() != Event::Silent ) {
500 bSound = TRUE;
501 }
502 }
503 }
504 if ( found ) {
505 if ( bSound ) {
506 Sound::soundAlarm();
507 stopTimer = startTimer( 5000 );
508 }
509
510 QDialog dlg( this, 0, TRUE );
511 QVBoxLayout *vb = new QVBoxLayout( &dlg );
512 QScrollView *view = new QScrollView( &dlg, "scrollView");
513 view->setResizePolicy( QScrollView::AutoOneFit );
514 vb->addWidget( view );
515 QLabel *lblMsg = new QLabel( msg, &dlg );
516 view->addChild( lblMsg );
517 QPushButton *cmdOk = new QPushButton( tr("OK"), &dlg );
518 connect( cmdOk, SIGNAL(clicked()), &dlg, SLOT(accept()) );
519 vb->addWidget( cmdOk );
520
521#if defined(Q_WS_QWS) || defined(_WS_QWS_)
522 dlg.showMaximized();
523#endif
524 needShow = dlg.exec();
525
526 if ( bSound )
527 killTimer( stopTimer );
528 }
529 }
530 } else if ( msg == "nextView()" ) {
531 QWidget* cur = views->visibleWidget();
532 if ( cur ) {
533 if ( cur == dayView )
534 viewWeek();
535 else if ( cur == weekView )
536 viewMonth();
537 else if ( cur == monthView )
538 viewDay();
539 needShow = TRUE;
540 }
541 }
542 if ( needShow ) {
543#if defined(Q_WS_QWS) || defined(_WS_QWS_)
544 showMaximized();
545#else
546 show();
547#endif
548 raise();
549 QPEApplication::setKeepRunning();
550 setActiveWindow();
551 }
552}
553
554void DateBook::reload()
555{
556 db->reload();
557 if ( dayAction->isOn() )
558 viewDay();
559 else if ( weekAction->isOn() )
560 viewWeek();
561 else if ( monthAction->isOn() )
562 viewMonth();
563 syncing = FALSE;
564}
565
566void DateBook::flush()
567{
568 syncing = TRUE;
569 db->save();
570}
571
572void DateBook::timerEvent( QTimerEvent *e )
573{
574 static int stop = 0;
575 if ( stop < 10 ) {
576 Sound::soundAlarm();
577 stop++;
578 } else {
579 stop = 0;
580 killTimer( e->timerId() );
581 }
582}
583
584void DateBook::changeClock( bool newClock )
585{
586 ampm = newClock;
587 // repaint the affected objects...
588 if (dayView) dayView->redraw();
589 if (weekView) weekView->redraw();
590}
591
592void DateBook::changeWeek( bool m )
593{
594 /* no need to redraw, each widget catches. Do need to
595 store though for widgets we haven't made yet */
596 onMonday = m;
597}
598
599void DateBook::slotToday()
600{
601 // we need to view today
602 QDate dt = QDate::currentDate();
603 showDay( dt.year(), dt.month(), dt.day() );
604}
605
606void DateBook::closeEvent( QCloseEvent *e )
607{
608 if(syncing) {
609 /* no need to save, did that at flush */
610 e->accept();
611 return;
612 }
613
614 // save settings will generate it's own error messages, no
615 // need to do checking ourselves.
616 saveSettings();
617 if ( db->save() )
618 e->accept();
619 else {
620 if ( QMessageBox::critical( this, tr( "Out of space" ),
621 tr("Calendar was unable to save\n"
622 "your changes.\n"
623 "Free up some space and try again.\n"
624 "\nQuit anyway?"),
625 QMessageBox::Yes|QMessageBox::Escape,
626 QMessageBox::No|QMessageBox::Default )
627 != QMessageBox::No )
628 e->accept();
629 else
630 e->ignore();
631 }
632}
633
634// Entering directly from the "keyboard"
635void DateBook::slotNewEventFromKey( const QString &str )
636{
637 if (syncing) {
638 QMessageBox::warning( this, tr("Calendar"),
639 tr( "Can not edit data, currently syncing") );
640 return;
641 }
642
643 // We get to here from a key pressed in the Day View
644 // So we can assume some things. We want the string
645 // passed in to be part of the description.
646 QDateTime start, end;
647 if ( views->visibleWidget() == dayView ) {
648 dayView->selectedDates( start, end );
649 } else if ( views->visibleWidget() == monthView ) {
650 QDate d = monthView->selectedDate();
651 start = end = d;
652 start.setTime( QTime( 10, 0 ) );
653 end.setTime( QTime( 12, 0 ) );
654 } else if ( views->visibleWidget() == weekView ) {
655 QDate d = weekView->date();
656 start = end = d;
657 start.setTime( QTime( 10, 0 ) );
658 end.setTime( QTime( 12, 0 ) );
659 }
660
661 // argh! This really needs to be encapsulated in a class
662 // or function.
663 QDialog newDlg( this, 0, TRUE );
664 newDlg.setCaption( DateEntryBase::tr("New Event") );
665 DateEntry *e;
666 QVBoxLayout *vb = new QVBoxLayout( &newDlg );
667 QScrollView *sv = new QScrollView( &newDlg );
668 sv->setResizePolicy( QScrollView::AutoOneFit );
669 sv->setFrameStyle( QFrame::NoFrame );
670 sv->setHScrollBarMode( QScrollView::AlwaysOff );
671 vb->addWidget( sv );
672
673 Event ev;
674 ev.setDescription( str );
675 // When the new gui comes in, change this...
676 ev.setLocation( tr("(Unknown)") );
677 ev.setStart( start );
678 ev.setEnd( end );
679
680 e = new DateEntry( onMonday, ev, ampm, &newDlg );
681 e->setAlarmEnabled( aPreset, presetTime, Event::Loud );
682 sv->addChild( e );
683#if defined(Q_WS_QWS) || defined(_WS_QWS_)
684 newDlg.showMaximized();
685#endif
686 while (newDlg.exec()) {
687 ev = e->event();
688 ev.assignUid();
689 QString error = checkEvent( ev );
690 if ( !error.isNull() ) {
691 if ( QMessageBox::warning( this, tr("Error!"),
692 error, tr("Fix it"), tr("Continue"), 0, 0, 1 ) == 0 )
693 continue;
694 }
695 db->addEvent( ev );
696 emit newEvent();
697 break;
698 }
699}
700
701void DateBook::setDocument( const QString &filename )
702{
703 if ( filename.find(".vcs") != int(filename.length()) - 4 ) return;
704
705 QValueList<Event> tl = Event::readVCalendar( filename );
706 for( QValueList<Event>::Iterator it = tl.begin(); it != tl.end(); ++it ) {
707 db->addEvent( *it );
708 }
709}
710
711static const char * beamfile = "/tmp/obex/event.vcs";
712
713void DateBook::beamEvent( const Event &e )
714{
715 qDebug("trying to beamn");
716 unlink( beamfile ); // delete if exists
717 mkdir("/tmp/obex/", 0755);
718 Event::writeVCalendar( beamfile, e );
719 Ir *ir = new Ir( this );
720 connect( ir, SIGNAL( done( Ir * ) ), this, SLOT( beamDone( Ir * ) ) );
721 QString description = e.description();
722 ir->send( beamfile, description, "text/x-vCalendar" );
723}
724
725void DateBook::beamDone( Ir *ir )
726{
727 delete ir;
728 unlink( beamfile );
729}
730
731void DateBook::slotFind()
732{
733 // move it to the day view...
734 viewDay();
735 FindDialog frmFind( "Calendar", this );
736 frmFind.setUseDate( true );
737 frmFind.setDate( currentDate() );
738 QObject::connect( &frmFind,
739 SIGNAL(signalFindClicked(const QString&, const QDate&,
740 bool, bool, int)),
741 this,
742 SLOT(slotDoFind(const QString&, const QDate&,
743 bool, bool, int)) );
744 QObject::connect( this,
745 SIGNAL(signalNotFound()),
746 &frmFind,
747 SLOT(slotNotFound()) );
748 QObject::connect( this,
749 SIGNAL(signalWrapAround()),
750 &frmFind,
751 SLOT(slotWrapAround()) );
752 frmFind.exec();
753 inSearch = false;
754}
755
756bool catComp( QArray<int> cats, int category )
757{
758 bool returnMe;
759 int i,
760 count;
761
762 count = int(cats.count());
763 returnMe = false;
764 if ( (category == -1 && count == 0) || category == -2 )
765 returnMe = true;
766 else {
767 for ( i = 0; i < count; i++ ) {
768 if ( category == cats[i] ) {
769 returnMe = true;
770 break;
771 }
772 }
773 }
774 return returnMe;
775}
776
777
778void DateBook::slotDoFind( const QString& txt, const QDate &dt,
779 bool caseSensitive, bool /*backwards*/,
780 int category )
781{
782 QDateTime dtEnd( QDate(3001, 1, 1), QTime(0, 0, 0) ),
783 next;
784
785 QRegExp r( txt );
786 r.setCaseSensitive( caseSensitive );
787
788
789 static Event rev,
790 nonrev;
791 if ( !inSearch ) {
792 rev.setStart( QDateTime(QDate(1960, 1, 1), QTime(0, 0, 0)) );
793 nonrev.setStart( rev.start() );
794 inSearch = true;
795 }
796 static QDate searchDate = dt;
797 static bool wrapAround = true;
798 bool candidtate;
799 candidtate = false;
800
801 QValueList<Event> repeats = db->getRawRepeats();
802
803 // find the candidate for the first repeat that matches...
804 QValueListConstIterator<Event> it;
805 QDate start = dt;
806 for ( it = repeats.begin(); it != repeats.end(); ++it ) {
807 if ( catComp( (*it).categories(), category ) ) {
808 while ( nextOccurance( *it, start, next ) ) {
809 if ( next < dtEnd ) {
810 if ( (*it).match( r ) && !(next <= rev.start()) ) {
811 rev = *it;
812 dtEnd = next;
813 rev.setStart( next );
814 candidtate = true;
815 wrapAround = true;
816 start = dt;
817 break;
818 } else
819 start = next.date().addDays( 1 );
820 }
821 }
822 }
823 }
824
825 // now the for first non repeat...
826 QValueList<Event> nonRepeats = db->getNonRepeatingEvents( dt, dtEnd.date() );
827 qHeapSort( nonRepeats.begin(), nonRepeats.end() );
828 for ( it = nonRepeats.begin(); it != nonRepeats.end(); ++it ) {
829 if ( catComp( (*it).categories(), category ) ) {
830 if ( (*it).start() < dtEnd ) {
831 if ( (*it).match( r ) && !(*it <= nonrev) ) {
832 nonrev = *it;
833 dtEnd = nonrev.start();
834 candidtate = true;
835 wrapAround = true;
836 break;
837 }
838 }
839 }
840 }
841 if ( candidtate ) {
842 dayView->setStartViewTime( dtEnd.time().hour() );
843 dayView->setDate( dtEnd.date().year(), dtEnd.date().month(),
844 dtEnd.date().day() );
845 } else {
846 if ( wrapAround ) {
847 emit signalWrapAround();
848 rev.setStart( QDateTime(QDate(1960, 1, 1), QTime(0, 0, 0)) );
849 nonrev.setStart( rev.start() );
850 } else
851 emit signalNotFound();
852 wrapAround = !wrapAround;
853 }
854}
diff --git a/core/pim/datebook/datebook.h b/core/pim/datebook/datebook.h
new file mode 100644
index 0000000..44627bb
--- a/dev/null
+++ b/core/pim/datebook/datebook.h
@@ -0,0 +1,111 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia 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 DATEBOOK_H
21#define DATEBOOK_H
22
23#include <qpe/datebookdb.h>
24
25#include <qmainwindow.h>
26
27class QAction;
28class QWidgetStack;
29class DateBookDay;
30class DateBookWeek;
31class DateBookMonth;
32class Event;
33class QDate;
34class Ir;
35
36class DateBook : public QMainWindow
37{
38 Q_OBJECT
39
40public:
41 DateBook( QWidget *parent = 0, const char *name = 0, WFlags f = 0 );
42 ~DateBook();
43
44signals:
45 void newEvent();
46 void signalNotFound();
47 void signalWrapAround();
48
49protected:
50 QDate currentDate();
51 void timerEvent( QTimerEvent *e );
52 void closeEvent( QCloseEvent *e );
53
54public slots:
55 void flush();
56 void reload();
57
58private slots:
59 void fileNew();
60 void slotSettings();
61 void slotToday();// view today
62 void changeClock( bool newClock );
63 void changeWeek( bool newDay );
64 void appMessage(const QCString& msg, const QByteArray& data);
65 // handle key events in the day view...
66 void slotNewEventFromKey( const QString &str );
67 void slotFind();
68 void slotDoFind( const QString &, const QDate &, bool, bool, int );
69
70 void viewDay();
71 void viewWeek();
72 void viewMonth();
73
74 void showDay( int y, int m, int d );
75
76 void editEvent( const Event &e );
77 void removeEvent( const Event &e );
78
79 void receive( const QCString &msg, const QByteArray &data );
80 void setDocument( const QString & );
81 void beamEvent( const Event &e );
82 void beamDone( Ir *ir );
83
84private:
85 void addEvent( const Event &e );
86 void initDay();
87 void initWeek();
88 void initMonth();
89 void loadSettings();
90 void saveSettings();
91
92private:
93 DateBookDB *db;
94 QWidgetStack *views;
95 DateBookDay *dayView;
96 DateBookWeek *weekView;
97 DateBookMonth *monthView;
98 QAction *dayAction, *weekAction, *monthAction;
99 bool aPreset; // have everything set to alarm?
100 int presetTime; // the standard time for the alarm
101 int startTime;
102 bool ampm;
103 bool onMonday;
104
105 bool syncing;
106 bool inSearch;
107
108 QString checkEvent(const Event &);
109};
110
111#endif
diff --git a/core/pim/datebook/datebook.pro b/core/pim/datebook/datebook.pro
new file mode 100644
index 0000000..17c02ec
--- a/dev/null
+++ b/core/pim/datebook/datebook.pro
@@ -0,0 +1,36 @@
1 TEMPLATE= app
2 CONFIG += qt warn_on release
3 DESTDIR = $(QPEDIR)/bin
4
5 HEADERS= datebookday.h \
6 datebook.h \
7 dateentryimpl.h \
8 datebookdayheaderimpl.h \
9 datebooksettings.h \
10 datebookweek.h \
11 datebookweekheaderimpl.h \
12 repeatentry.h
13
14 SOURCES= main.cpp \
15 datebookday.cpp \
16 datebook.cpp \
17 dateentryimpl.cpp \
18 datebookdayheaderimpl.cpp \
19 datebooksettings.cpp \
20 datebookweek.cpp \
21 datebookweekheaderimpl.cpp \
22 repeatentry.cpp
23
24 INTERFACES= dateentry.ui \
25 datebookdayheader.ui \
26 datebooksettingsbase.ui \
27 datebookweekheader.ui \
28 repeatentrybase.ui
29
30INCLUDEPATH += $(QPEDIR)/include
31 DEPENDPATH+= $(QPEDIR)/include
32LIBS += -lqpe
33
34 TARGET = datebook
35
36TRANSLATIONS = ../i18n/de/datebook.ts
diff --git a/core/pim/datebook/datebookday.cpp b/core/pim/datebook/datebookday.cpp
new file mode 100644
index 0000000..d5daab2
--- a/dev/null
+++ b/core/pim/datebook/datebookday.cpp
@@ -0,0 +1,553 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia 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 "datebookday.h"
22#include "datebookdayheaderimpl.h"
23
24#include <qpe/datebookdb.h>
25#include <qpe/resource.h>
26#include <qpe/event.h>
27#include <qpe/qpeapplication.h>
28#include <qpe/timestring.h>
29#include <qpe/qpedebug.h>
30
31#include <qheader.h>
32#include <qdatetime.h>
33#include <qpainter.h>
34#include <qsimplerichtext.h>
35#include <qpopupmenu.h>
36#include <qtextcodec.h>
37#include <qpalette.h>
38
39DateBookDayView::DateBookDayView( bool whichClock, QWidget *parent,
40 const char *name )
41 : QTable( 24, 1, parent, name ),
42 ampm( whichClock )
43{
44 enableClipper(TRUE);
45 setTopMargin( 0 );
46 horizontalHeader()->hide();
47 setLeftMargin(38);
48 setColumnStretchable( 0, TRUE );
49 setHScrollBarMode( QScrollView::AlwaysOff );
50 verticalHeader()->setPalette(white);
51 verticalHeader()->setResizeEnabled(FALSE);
52 setSelectionMode( Single );
53
54 // get rid of being able to edit things...
55 QTableItem *tmp;
56 int row;
57 for ( row = 0; row < numRows(); row++ ) {
58 tmp = new QTableItem( this, QTableItem::Never, QString::null);
59 setItem( row, 0, tmp );
60 }
61 initHeader();
62 QObject::connect( qApp, SIGNAL(clockChanged(bool)),
63 this, SLOT(slotChangeClock(bool)) );
64}
65
66void DateBookDayView::initHeader()
67{
68 QString strTmp;
69 for ( int i = 0; i < 24; ++i ) {
70 if ( ampm ) {
71 if ( i == 0 )
72 strTmp = QString::number(12) + ":00";
73 else if ( i == 12 )
74 strTmp = QString::number(12) + tr(":00p");
75 else if ( i > 12 )
76 strTmp = QString::number( i - 12 ) + tr(":00p");
77 else
78 strTmp = QString::number(i) + ":00";
79 } else {
80 if ( i < 10 )
81 strTmp = "0" + QString::number(i) + ":00";
82 else
83 strTmp = QString::number(i) + ":00";
84 }
85 strTmp = strTmp.rightJustify( 6, ' ' );
86 verticalHeader()->setLabel( i, strTmp );
87 setRowStretchable( i, FALSE );
88 }
89}
90
91void DateBookDayView::slotChangeClock( bool newClock )
92{
93 ampm = newClock;
94 initHeader();
95}
96
97bool DateBookDayView::whichClock() const
98{
99 return ampm;
100}
101
102void DateBookDayView::moveUp()
103{
104 scrollBy(0, -20);
105}
106
107void DateBookDayView::moveDown()
108{
109 scrollBy(0, 20);
110}
111
112void DateBookDayView::paintCell( QPainter *p, int, int, const QRect &cr, bool )
113{
114 int w = cr.width();
115 int h = cr.height();
116 p->fillRect( 0, 0, w, h, colorGroup().brush( QColorGroup::Base ) );
117 if ( showGrid() ) {
118 // Draw our lines
119 int x2 = w - 1;
120 int y2 = h - 1;
121 QPen pen( p->pen() );
122 p->setPen( colorGroup().mid() );
123 p->drawLine( x2, 0, x2, y2 );
124 p->drawLine( 0, y2, x2, y2 );
125 p->setPen( pen );
126 }
127}
128
129void DateBookDayView::paintFocus( QPainter *, const QRect & )
130{
131}
132
133
134void DateBookDayView::resizeEvent( QResizeEvent *e )
135{
136 QTable::resizeEvent( e );
137 columnWidthChanged( 0 );
138 emit sigColWidthChanged();
139}
140
141void DateBookDayView::keyPressEvent( QKeyEvent *e )
142{
143 QString txt = e->text();
144 if ( !txt.isNull() && txt[0] > ' ' && e->key() < 0x1000 ) {
145 // we this is some sort of thing we know about...
146 e->accept();
147 emit sigCapturedKey( txt );
148 } else {
149 // I don't know what this key is, do you?
150 e->ignore();
151 }
152}
153
154
155//===========================================================================
156
157DateBookDay::DateBookDay( bool ampm, bool startOnMonday,
158 DateBookDB *newDb, QWidget *parent,
159 const char *name )
160 : QVBox( parent, name ),
161 currDate( QDate::currentDate() ),
162 db( newDb ),
163 startTime( 0 )
164{
165 widgetList.setAutoDelete( true );
166 header = new DateBookDayHeader( startOnMonday, this, "day header" );
167 header->setDate( currDate.year(), currDate.month(), currDate.day() );
168 view = new DateBookDayView( ampm, this, "day view" );
169 connect( header, SIGNAL( dateChanged( int, int, int ) ),
170 this, SLOT( dateChanged( int, int, int ) ) );
171 connect( view, SIGNAL( sigColWidthChanged() ),
172 this, SLOT( slotColWidthChanged() ) );
173 connect( qApp, SIGNAL(weekChanged(bool)),
174 this, SLOT(slotWeekChanged(bool)) );
175 connect( view, SIGNAL(sigCapturedKey(const QString &)),
176 this, SIGNAL(sigNewEvent(const QString&)) );
177}
178
179void DateBookDay::selectedDates( QDateTime &start, QDateTime &end )
180{
181 start.setDate( currDate );
182 end.setDate( currDate );
183
184 int sh=99,eh=-1;
185
186 int n = dayView()->numSelections();
187
188 for (int i=0; i<n; i++) {
189 QTableSelection sel = dayView()->selection( i );
190 sh = QMIN(sh,sel.topRow());
191 eh = QMAX(sh,sel.bottomRow()+1);
192 }
193 if (sh > 23 || eh < 1) {
194 sh=8;
195 eh=9;
196 }
197
198 start.setTime( QTime( sh, 0, 0 ) );
199 end.setTime( QTime( eh, 0, 0 ) );
200}
201
202void DateBookDay::setDate( int y, int m, int d )
203{
204 header->setDate( y, m, d );
205}
206
207void DateBookDay::setDate( QDate d)
208{
209 header->setDate( d.year(), d.month(), d.day() );
210}
211
212void DateBookDay::dateChanged( int y, int m, int d )
213{
214 QDate date( y, m, d );
215 if ( currDate == date )
216 return;
217 currDate.setYMD( y, m, d );
218 relayoutPage();
219 dayView()->clearSelection();
220 QTableSelection ts;
221 ts.init( startTime, 0 );
222 ts.expandTo( startTime, 0 );
223 dayView()->addSelection( ts );
224}
225
226void DateBookDay::redraw()
227{
228 if ( isUpdatesEnabled() )
229 relayoutPage();
230}
231
232void DateBookDay::getEvents()
233{
234 widgetList.clear();
235
236 QValueList<EffectiveEvent> eventList = db->getEffectiveEvents( currDate,
237 currDate );
238 QValueListIterator<EffectiveEvent> it;
239 for ( it = eventList.begin(); it != eventList.end(); ++it ) {
240 DateBookDayWidget* w = new DateBookDayWidget( *it, this );
241 connect( w, SIGNAL( deleteMe( const Event & ) ),
242 this, SIGNAL( removeEvent( const Event & ) ) );
243 connect( w, SIGNAL( editMe( const Event & ) ),
244 this, SIGNAL( editEvent( const Event & ) ) );
245 connect( w, SIGNAL( beamMe( const Event & ) ),
246 this, SIGNAL( beamEvent( const Event & ) ) );
247 widgetList.append( w );
248 }
249}
250
251static int place( const DateBookDayWidget *item, bool *used, int maxn )
252{
253 int place = 0;
254 int start = item->event().start().hour();
255 QTime e = item->event().end();
256 int end = e.hour();
257 if ( e.minute() < 5 )
258 end--;
259 if ( end < start )
260 end = start;
261 while ( place < maxn ) {
262 bool free = TRUE;
263 int s = start;
264 while( s <= end ) {
265 if ( used[10*s+place] ) {
266 free = FALSE;
267 break;
268 }
269 s++;
270 }
271 if ( free ) break;
272 place++;
273 }
274 if ( place == maxn ) {
275 return -1;
276 }
277 while( start <= end ) {
278 used[10*start+place] = TRUE;
279 start++;
280 }
281 return place;
282}
283
284
285void DateBookDay::relayoutPage( bool fromResize )
286{
287 setUpdatesEnabled( FALSE );
288 if ( !fromResize )
289 getEvents(); // no need we already have them!
290
291 int wCount = widgetList.count();
292 int wid = view->columnWidth(0)-1;
293 int n = 1;
294
295 if ( wCount < 20 ) {
296 for ( int i = 0; i < wCount; ) {
297 DateBookDayWidget *w = widgetList.at(i);
298 int x = 0;
299 int xp = 0;
300 QRect geom = w->geometry();
301 geom.setX( x );
302 geom.setWidth( wid );
303 while ( xp < n && intersects( w, geom ) ) {
304 x += wid;
305 xp++;
306 geom.moveBy( wid, 0 );
307 }
308 if ( xp >= n ) {
309 n++;
310 wid = ( view->columnWidth(0)-1 ) / n;
311 i = 0;
312 } else {
313 w->setGeometry( geom );
314 i++;
315 }
316 }
317 view->setContentsPos( 0, startTime * view->rowHeight(0) );
318 } else {
319
320
321 int hours[24];
322 memset( hours, 0, 24*sizeof( int ) );
323 bool overFlow = FALSE;
324 for ( int i = 0; i < wCount; i++ ) {
325 DateBookDayWidget *w = widgetList.at(i);
326 int start = w->event().start().hour();
327 QTime e = w->event().end();
328 int end = e.hour();
329 if ( e.minute() < 5 )
330 end--;
331 if ( end < start )
332 end = start;
333 while( start <= end ) {
334 hours[start]++;
335 if ( hours[start] >= 10 )
336 overFlow = TRUE;
337 ++start;
338 }
339 if ( overFlow )
340 break;
341 }
342 for ( int i = 0; i < 24; i++ ) {
343 n = QMAX( n, hours[i] );
344 }
345 wid = ( view->columnWidth(0)-1 ) / n;
346
347 bool used[24*10];
348 memset( used, FALSE, 24*10*sizeof( bool ) );
349
350 for ( int i = 0; i < wCount; i++ ) {
351 DateBookDayWidget *w = widgetList.at(i);
352 int xp = place( w, used, n );
353 if ( xp != -1 ) {
354 QRect geom = w->geometry();
355 geom.setX( xp*wid );
356 geom.setWidth( wid );
357 w->setGeometry( geom );
358 }
359 }
360 view->setContentsPos( 0, startTime * view->rowHeight(0) );
361 }
362 setUpdatesEnabled( TRUE );
363 return;
364}
365
366DateBookDayWidget *DateBookDay::intersects( const DateBookDayWidget *item, const QRect &geom )
367{
368 int i = 0;
369 DateBookDayWidget *w = widgetList.at(i);
370 int wCount = widgetList.count();
371 while ( i < wCount && w != item ) {
372 if ( w->geometry().intersects( geom ) ) {
373 return w;
374 }
375 w = widgetList.at(++i);
376 }
377
378 return 0;
379}
380
381
382QDate DateBookDay::date() const
383{
384 return currDate;
385}
386
387void DateBookDay::setStartViewTime( int startHere )
388{
389 startTime = startHere;
390 dayView()->clearSelection();
391 QTableSelection ts;
392 ts.init( startTime, 0 );
393 ts.expandTo( startTime, 0 );
394 dayView()->addSelection( ts );
395}
396
397int DateBookDay::startViewTime() const
398{
399 return startTime;
400}
401
402void DateBookDay::slotWeekChanged( bool bStartOnMonday )
403{
404 header->setStartOfWeek( bStartOnMonday );
405 // redraw();
406}
407
408void DateBookDay::keyPressEvent(QKeyEvent *e)
409{
410 switch(e->key()) {
411 case Key_Up:
412 view->moveUp();
413 break;
414 case Key_Down:
415 view->moveDown();
416 break;
417 case Key_Left:
418 setDate(QDate(currDate).addDays(-1));
419 break;
420 case Key_Right:
421 setDate(QDate(currDate).addDays(1));
422 break;
423 default:
424 e->ignore();
425 }
426}
427
428//===========================================================================
429
430DateBookDayWidget::DateBookDayWidget( const EffectiveEvent &e,
431 DateBookDay *db )
432 : QWidget( db->dayView()->viewport() ), ev( e ), dateBook( db )
433{
434 bool whichClock = db->dayView()->whichClock();
435
436 // why would someone use "<"? Oh well, fix it up...
437 // I wonder what other things may be messed up...
438 QString strDesc = ev.description();
439 int where = strDesc.find( "<" );
440 while ( where != -1 ) {
441 strDesc.remove( where, 1 );
442 strDesc.insert( where, "&#60;" );
443 where = strDesc.find( "<", where );
444 }
445
446 QString strCat;
447 // ### Fix later...
448// QString strCat = ev.category();
449// where = strCat.find( "<" );
450// while ( where != -1 ) {
451 // strCat.remove( where, 1 );
452 // strCat.insert( where, "&#60;" );
453 // where = strCat.find( "<", where );
454// }
455
456 QString strNote = ev.notes();
457 where = strNote.find( "<" );
458 while ( where != -1 ) {
459 strNote.remove( where, 1 );
460 strNote.insert( where, "&#60;" );
461 where = strNote.find( "<", where );
462 }
463
464 text = "<b>" + strDesc + "</b><br>" + "<i>"
465 + strCat + "</i>"
466 + "<br><b>" + tr("Start") + "</b>: ";
467
468
469 if ( e.startDate() != ev.date() ) {
470 // multi-day event. Show start date
471 text += TimeString::longDateString( e.startDate() );
472 } else {
473 // Show start time.
474 text += TimeString::timeString( ev.start(), whichClock, FALSE );
475 }
476
477 text += "<br><b>" + tr("End") + "</b>: ";
478 if ( e.endDate() != ev.date() ) {
479 // multi-day event. Show end date
480 text += TimeString::longDateString( e.endDate() );
481 } else {
482 // Show end time.
483 text += TimeString::timeString( ev.end(), whichClock, FALSE );
484 }
485 text += "<br><br>" + strNote;
486 setBackgroundMode( PaletteBase );
487
488 QTime s = ev.start();
489 QTime e = ev.end();
490 int y = s.hour()*60+s.minute();
491 int h = e.hour()*60+e.minute()-y;
492 int rh = dateBook->dayView()->rowHeight(0);
493 y = y*rh/60;
494 h = h*rh/60;
495 if ( h < 3 )
496 h = 3;
497 geom.setY( y );
498 geom.setHeight( h );
499}
500
501DateBookDayWidget::~DateBookDayWidget()
502{
503}
504
505void DateBookDayWidget::paintEvent( QPaintEvent *e )
506{
507 QPainter p( this );
508 p.setPen( QColor(100, 100, 100) );
509 p.setBrush( QColor( 255, 240, 230 ) ); // based on priority?
510 p.drawRect(rect());
511
512 int y = 0;
513 int d = 0;
514
515 if ( ev.event().hasAlarm() ) {
516 p.drawPixmap( width() - 16, 0, Resource::loadPixmap( "bell" ) );
517 y = 20;
518 d = 20;
519 }
520
521 if ( ev.event().hasRepeat() ) {
522 p.drawPixmap( width() - 16, y, Resource::loadPixmap( "repeat" ) );
523 d = 20;
524 }
525
526 QSimpleRichText rt( text, font() );
527 rt.setWidth( geom.width() - d - 6 );
528 rt.draw( &p, 3, 0, e->region(), colorGroup() );
529}
530
531void DateBookDayWidget::mousePressEvent( QMouseEvent *e )
532{
533 QPopupMenu m;
534 m.insertItem( tr( "Edit" ), 1 );
535 m.insertItem( tr( "Delete" ), 2 );
536 m.insertItem( tr( "Beam" ), 3 );
537 int r = m.exec( e->globalPos() );
538 if ( r == 1 ) {
539 emit editMe( ev.event() );
540 } else if ( r == 2 ) {
541 emit deleteMe( ev.event() );
542 } else if ( r == 3 ) {
543 emit beamMe( ev.event() );
544 }
545}
546
547void DateBookDayWidget::setGeometry( const QRect &r )
548{
549 geom = r;
550 setFixedSize( r.width()+1, r.height()+1 );
551 dateBook->dayView()->moveChild( this, r.x(), r.y()-1 );
552 show();
553}
diff --git a/core/pim/datebook/datebookday.h b/core/pim/datebook/datebookday.h
new file mode 100644
index 0000000..531fded
--- a/dev/null
+++ b/core/pim/datebook/datebookday.h
@@ -0,0 +1,138 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia 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 DATEBOOKDAY_H
21#define DATEBOOKDAY_H
22
23#include <qpe/event.h>
24
25#include <qdatetime.h>
26#include <qtable.h>
27#include <qvbox.h>
28#include <qlist.h>
29
30class DateBookDayHeader;
31class DateBookDB;
32class QDateTime;
33class QMouseEvent;
34class QPaintEvent;
35class QResizeEvent;
36
37class DateBookDayView : public QTable
38{
39 Q_OBJECT
40public:
41 DateBookDayView( bool hourClock, QWidget *parent, const char *name );
42 bool whichClock() const;
43
44public slots:
45 void moveUp();
46 void moveDown();
47
48signals:
49 void sigColWidthChanged();
50 void sigCapturedKey( const QString &txt );
51protected slots:
52 void slotChangeClock( bool );
53protected:
54 virtual void paintCell( QPainter *p, int row, int col, const QRect &cr, bool selected );
55 virtual void paintFocus( QPainter *p, const QRect &cr );
56 virtual void resizeEvent( QResizeEvent *e );
57 void keyPressEvent( QKeyEvent *e );
58 void initHeader();
59private:
60 bool ampm;
61};
62
63class DateBookDay;
64class DateBookDayWidget : public QWidget
65{
66 Q_OBJECT
67
68public:
69 DateBookDayWidget( const EffectiveEvent &e, DateBookDay *db );
70 ~DateBookDayWidget();
71
72 const QRect &geometry() { return geom; }
73 void setGeometry( const QRect &r );
74
75 const EffectiveEvent &event() const { return ev; }
76
77signals:
78 void deleteMe( const Event &e );
79 void editMe( const Event &e );
80 void beamMe( const Event &e );
81
82protected:
83 void paintEvent( QPaintEvent *e );
84 void mousePressEvent( QMouseEvent *e );
85
86private:
87 const EffectiveEvent ev;
88 DateBookDay *dateBook;
89 QString text;
90 QRect geom;
91};
92
93class DateBookDay : public QVBox
94{
95 Q_OBJECT
96
97public:
98 DateBookDay( bool ampm, bool startOnMonday, DateBookDB *newDb,
99 QWidget *parent, const char *name );
100 void selectedDates( QDateTime &start, QDateTime &end );
101 QDate date() const;
102 DateBookDayView *dayView() const { return view; }
103 void setStartViewTime( int startHere );
104 int startViewTime() const;
105
106public slots:
107 void setDate( int y, int m, int d );
108 void setDate( QDate );
109 void redraw();
110 void slotWeekChanged( bool bStartOnMonday );
111
112signals:
113 void removeEvent( const Event& );
114 void editEvent( const Event& );
115 void beamEvent( const Event& );
116 void newEvent();
117 void sigNewEvent( const QString & );
118
119protected slots:
120 void keyPressEvent(QKeyEvent *);
121
122private slots:
123 void dateChanged( int y, int m, int d );
124 void slotColWidthChanged() { relayoutPage(); };
125
126private:
127 void getEvents();
128 void relayoutPage( bool fromResize = false );
129 DateBookDayWidget *intersects( const DateBookDayWidget *item, const QRect &geom );
130 QDate currDate;
131 DateBookDayView *view;
132 DateBookDayHeader *header;
133 DateBookDB *db;
134 QList<DateBookDayWidget> widgetList;
135 int startTime;
136};
137
138#endif
diff --git a/core/pim/datebook/datebookdayheader.ui b/core/pim/datebook/datebookdayheader.ui
new file mode 100644
index 0000000..8bc284f
--- a/dev/null
+++ b/core/pim/datebook/datebookdayheader.ui
@@ -0,0 +1,424 @@
1<!DOCTYPE UI><UI>
2<class>DateBookDayHeaderBase</class>
3<comment>/**********************************************************************
4** Copyright (C) 2001 Trolltech AS. All rights reserved.
5**
6** This file is part of Qtopia 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>QWidget</class>
26 <property stdset="1">
27 <name>name</name>
28 <cstring>DateBookDayHeaderBase</cstring>
29 </property>
30 <property stdset="1">
31 <name>geometry</name>
32 <rect>
33 <x>0</x>
34 <y>0</y>
35 <width>249</width>
36 <height>26</height>
37 </rect>
38 </property>
39 <property stdset="1">
40 <name>caption</name>
41 <string>Form1</string>
42 </property>
43 <property>
44 <name>layoutMargin</name>
45 </property>
46 <property>
47 <name>layoutSpacing</name>
48 </property>
49 <hbox>
50 <property stdset="1">
51 <name>margin</name>
52 <number>0</number>
53 </property>
54 <property stdset="1">
55 <name>spacing</name>
56 <number>0</number>
57 </property>
58 <widget>
59 <class>QToolButton</class>
60 <property stdset="1">
61 <name>name</name>
62 <cstring>back</cstring>
63 </property>
64 <property stdset="1">
65 <name>text</name>
66 <string></string>
67 </property>
68 <property stdset="1">
69 <name>pixmap</name>
70 <pixmap>image0</pixmap>
71 </property>
72 <property stdset="1">
73 <name>toggleButton</name>
74 <bool>false</bool>
75 </property>
76 <property stdset="1">
77 <name>autoRepeat</name>
78 <bool>true</bool>
79 </property>
80 <property stdset="1">
81 <name>autoRaise</name>
82 <bool>true</bool>
83 </property>
84 <property stdset="1">
85 <name>toggleButton</name>
86 <bool>false</bool>
87 </property>
88 <property>
89 <name>toolTip</name>
90 <string></string>
91 </property>
92 </widget>
93 <widget>
94 <class>QToolButton</class>
95 <property stdset="1">
96 <name>name</name>
97 <cstring>date</cstring>
98 </property>
99 <property stdset="1">
100 <name>sizePolicy</name>
101 <sizepolicy>
102 <hsizetype>7</hsizetype>
103 <vsizetype>1</vsizetype>
104 </sizepolicy>
105 </property>
106 <property stdset="1">
107 <name>font</name>
108 <font>
109 <bold>1</bold>
110 </font>
111 </property>
112 <property stdset="1">
113 <name>text</name>
114 <string></string>
115 </property>
116 <property stdset="1">
117 <name>pixmap</name>
118 <pixmap></pixmap>
119 </property>
120 <property stdset="1">
121 <name>autoRepeat</name>
122 <bool>false</bool>
123 </property>
124 <property stdset="1">
125 <name>autoRaise</name>
126 <bool>false</bool>
127 </property>
128 </widget>
129 <widget>
130 <class>QButtonGroup</class>
131 <property stdset="1">
132 <name>name</name>
133 <cstring>grpDays</cstring>
134 </property>
135 <property stdset="1">
136 <name>frameShape</name>
137 <enum>NoFrame</enum>
138 </property>
139 <property stdset="1">
140 <name>frameShadow</name>
141 <enum>Plain</enum>
142 </property>
143 <property stdset="1">
144 <name>title</name>
145 <string></string>
146 </property>
147 <property stdset="1">
148 <name>exclusive</name>
149 <bool>true</bool>
150 </property>
151 <property>
152 <name>layoutMargin</name>
153 </property>
154 <property>
155 <name>layoutSpacing</name>
156 </property>
157 <hbox>
158 <property stdset="1">
159 <name>margin</name>
160 <number>0</number>
161 </property>
162 <property stdset="1">
163 <name>spacing</name>
164 <number>1</number>
165 </property>
166 <widget>
167 <class>QToolButton</class>
168 <property stdset="1">
169 <name>name</name>
170 <cstring>cmdDay1</cstring>
171 </property>
172 <property stdset="1">
173 <name>text</name>
174 <string>M</string>
175 </property>
176 <property stdset="1">
177 <name>toggleButton</name>
178 <bool>true</bool>
179 </property>
180 <property stdset="1">
181 <name>autoRaise</name>
182 <bool>true</bool>
183 </property>
184 <property stdset="1">
185 <name>toggleButton</name>
186 <bool>true</bool>
187 </property>
188 <property>
189 <name>toolTip</name>
190 <string></string>
191 </property>
192 </widget>
193 <widget>
194 <class>QToolButton</class>
195 <property stdset="1">
196 <name>name</name>
197 <cstring>cmdDay2</cstring>
198 </property>
199 <property stdset="1">
200 <name>text</name>
201 <string>T</string>
202 </property>
203 <property stdset="1">
204 <name>toggleButton</name>
205 <bool>true</bool>
206 </property>
207 <property stdset="1">
208 <name>autoRaise</name>
209 <bool>true</bool>
210 </property>
211 <property stdset="1">
212 <name>toggleButton</name>
213 <bool>true</bool>
214 </property>
215 <property>
216 <name>toolTip</name>
217 <string></string>
218 </property>
219 </widget>
220 <widget>
221 <class>QToolButton</class>
222 <property stdset="1">
223 <name>name</name>
224 <cstring>cmdDay3</cstring>
225 </property>
226 <property stdset="1">
227 <name>text</name>
228 <string>W</string>
229 </property>
230 <property stdset="1">
231 <name>toggleButton</name>
232 <bool>true</bool>
233 </property>
234 <property stdset="1">
235 <name>autoRaise</name>
236 <bool>true</bool>
237 </property>
238 <property stdset="1">
239 <name>toggleButton</name>
240 <bool>true</bool>
241 </property>
242 <property>
243 <name>toolTip</name>
244 <string></string>
245 </property>
246 </widget>
247 <widget>
248 <class>QToolButton</class>
249 <property stdset="1">
250 <name>name</name>
251 <cstring>cmdDay4</cstring>
252 </property>
253 <property stdset="1">
254 <name>text</name>
255 <string>T</string>
256 </property>
257 <property stdset="1">
258 <name>pixmap</name>
259 <pixmap></pixmap>
260 </property>
261 <property stdset="1">
262 <name>toggleButton</name>
263 <bool>true</bool>
264 </property>
265 <property stdset="1">
266 <name>autoRepeat</name>
267 <bool>false</bool>
268 </property>
269 <property stdset="1">
270 <name>autoRaise</name>
271 <bool>true</bool>
272 </property>
273 <property stdset="1">
274 <name>toggleButton</name>
275 <bool>true</bool>
276 </property>
277 <property>
278 <name>toolTip</name>
279 <string></string>
280 </property>
281 </widget>
282 <widget>
283 <class>QToolButton</class>
284 <property stdset="1">
285 <name>name</name>
286 <cstring>cmdDay5</cstring>
287 </property>
288 <property stdset="1">
289 <name>text</name>
290 <string>F</string>
291 </property>
292 <property stdset="1">
293 <name>toggleButton</name>
294 <bool>true</bool>
295 </property>
296 <property stdset="1">
297 <name>autoRaise</name>
298 <bool>true</bool>
299 </property>
300 <property stdset="1">
301 <name>toggleButton</name>
302 <bool>true</bool>
303 </property>
304 <property>
305 <name>toolTip</name>
306 <string></string>
307 </property>
308 </widget>
309 <widget>
310 <class>QToolButton</class>
311 <property stdset="1">
312 <name>name</name>
313 <cstring>cmdDay6</cstring>
314 </property>
315 <property stdset="1">
316 <name>text</name>
317 <string>S</string>
318 </property>
319 <property stdset="1">
320 <name>toggleButton</name>
321 <bool>true</bool>
322 </property>
323 <property stdset="1">
324 <name>autoRaise</name>
325 <bool>true</bool>
326 </property>
327 <property stdset="1">
328 <name>toggleButton</name>
329 <bool>true</bool>
330 </property>
331 <property>
332 <name>toolTip</name>
333 <string></string>
334 </property>
335 </widget>
336 <widget>
337 <class>QToolButton</class>
338 <property stdset="1">
339 <name>name</name>
340 <cstring>cmdDay7</cstring>
341 </property>
342 <property stdset="1">
343 <name>text</name>
344 <string>S</string>
345 </property>
346 <property stdset="1">
347 <name>toggleButton</name>
348 <bool>true</bool>
349 </property>
350 <property stdset="1">
351 <name>autoRaise</name>
352 <bool>true</bool>
353 </property>
354 <property stdset="1">
355 <name>toggleButton</name>
356 <bool>true</bool>
357 </property>
358 <property>
359 <name>toolTip</name>
360 <string></string>
361 </property>
362 </widget>
363 </hbox>
364 </widget>
365 <widget>
366 <class>QToolButton</class>
367 <property stdset="1">
368 <name>name</name>
369 <cstring>forward</cstring>
370 </property>
371 <property stdset="1">
372 <name>text</name>
373 <string></string>
374 </property>
375 <property stdset="1">
376 <name>pixmap</name>
377 <pixmap>image1</pixmap>
378 </property>
379 <property stdset="1">
380 <name>autoRepeat</name>
381 <bool>true</bool>
382 </property>
383 <property stdset="1">
384 <name>autoRaise</name>
385 <bool>true</bool>
386 </property>
387 </widget>
388 </hbox>
389</widget>
390<images>
391 <image>
392 <name>image0</name>
393 <data format="XPM.GZ" length="582">789c6dcfcd4e843010c0f13b4fd1d01b31bb6cb325211b1f41e3d1c4789876a60bcbd7aeae07637c773b6d5985d870e0f7ef50605b88e7a707516cb3f72b5c5b2b6c036fa2c08f61f87c79bdffcaf2dd5ef0558b5d7e97e51b61c5e33412df4b7f2fcbb09896a94ab557817063cd744cad74a915734aac35308740d018d9332d5ab0c8ec1229f2c2448d156a661b489ee1ab4e4cf2a08a790e24020abb0dd355442eec8e914e45526215790c749e8e89891069125de466b1fe14295705ccaa5863e2d05cc01894925b2a7e8217dd8a631eb169fd509af10fd1a9ebfbdf32008d9d0c07cd274f70ee162773ba2cdfee935c977ffe6b2edf87ec07796f81cd</data>
394 </image>
395 <image>
396 <name>image1</name>
397 <data format="XPM.GZ" length="627">789c7dcfc94ec3301006e07b9ec28a6f114a13cbb1a8108f00e28884387819676993340b07847877329ea8697a60ec83bfdf232f8784bdbfbdb0e4104db39e6bcb6ca54796b8afb6fdfef87cfe89e25cb2650ac1f2f8218a5366d96bdf01aef9b2e65928a4458a0c07b25c29890352e63293e19c53a0968f52230159e8c22981744495133552097554a1f982b4ce6aeb9013d215165c81ec894e109b4070ca85378f2b35f18c04050214b20d04d010762ba457003eecd6442f88f34a45f4817ea147762b35d1acf4c47457d784737d9f18ebee1363614bf852c6f812b6c460f90abb6e93ba694ed7c49fdbaeee2f76b83da71ba772e0db5d9ccf4b07dfdd5e858edd9b2948fff9d796fc3e457f660e8d47</data>
398 </image>
399</images>
400<connections>
401 <connection>
402 <sender>forward</sender>
403 <signal>clicked()</signal>
404 <receiver>DateBookDayHeaderBase</receiver>
405 <slot>goForward()</slot>
406 </connection>
407 <connection>
408 <sender>back</sender>
409 <signal>clicked()</signal>
410 <receiver>DateBookDayHeaderBase</receiver>
411 <slot>goBack()</slot>
412 </connection>
413 <connection>
414 <sender>grpDays</sender>
415 <signal>clicked(int)</signal>
416 <receiver>DateBookDayHeaderBase</receiver>
417 <slot>setDay( int )</slot>
418 </connection>
419 <slot access="public">goBack()</slot>
420 <slot access="public">goForward()</slot>
421 <slot access="public">setDate( int, int, int )</slot>
422 <slot access="public">setDay( int )</slot>
423</connections>
424</UI>
diff --git a/core/pim/datebook/datebookdayheaderimpl.cpp b/core/pim/datebook/datebookdayheaderimpl.cpp
new file mode 100644
index 0000000..fbcb3d2
--- a/dev/null
+++ b/core/pim/datebook/datebookdayheaderimpl.cpp
@@ -0,0 +1,181 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia 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#include "datebookdayheaderimpl.h"
21
22#include <qpe/datebookmonth.h>
23#include <qpe/timestring.h>
24
25#include <qbuttongroup.h>
26#include <qpopupmenu.h>
27#include <qstringlist.h>
28#include <qtimer.h>
29#include <qtoolbutton.h>
30
31/*
32 * Constructs a DateBookDayHeader which is a child of 'parent', with the
33 * name 'name' and widget flags set to 'f'
34 *
35 * The dialog will by default be modeless, unless you set 'modal' to
36 * TRUE to construct a modal dialog.
37 */
38DateBookDayHeader::DateBookDayHeader( bool useMonday,
39 QWidget* parent, const char* name )
40 : DateBookDayHeaderBase( parent, name ),
41 bUseMonday( useMonday )
42{
43 connect(date,SIGNAL(pressed()),this,SLOT(pickDate()));
44
45 setupNames();
46
47 setBackgroundMode( PaletteButton );
48 grpDays->setBackgroundMode( PaletteButton );
49}
50
51/*
52 * Destroys the object and frees any allocated resources
53 */
54DateBookDayHeader::~DateBookDayHeader()
55{
56 // no need to delete child widgets, Qt does it all for us
57}
58
59void DateBookDayHeader::setStartOfWeek( bool onMonday )
60{
61 bUseMonday = onMonday;
62 setupNames();
63 setDate( currDate.year(), currDate.month(), currDate.day() );
64}
65
66void DateBookDayHeader::setupNames()
67{
68 if ( bUseMonday ) {
69 cmdDay1->setText( DateBookDayHeaderBase::tr("Monday").left(1) );
70 cmdDay2->setText( DateBookDayHeaderBase::tr("Tuesday").left(1) );
71 cmdDay3->setText( DateBookDayHeaderBase::tr("Wednesday").left(1) );
72 cmdDay4->setText( DateBookDayHeaderBase::tr("Thursday").left(1) );
73 cmdDay5->setText( DateBookDayHeaderBase::tr("Friday").left(1) );
74 cmdDay6->setText( DateBookDayHeaderBase::tr("Saturday").left(1) );
75 cmdDay7->setText( DateBookDayHeaderBase::tr("Sunday").left(1) );
76 } else {
77 cmdDay1->setText( DateBookDayHeaderBase::tr("Sunday").left(1) );
78 cmdDay2->setText( DateBookDayHeaderBase::tr("Monday").left(1) );
79 cmdDay3->setText( DateBookDayHeaderBase::tr("Tuesday").left(1) );
80 cmdDay4->setText( DateBookDayHeaderBase::tr("Wednesday").left(1) );
81 cmdDay5->setText( DateBookDayHeaderBase::tr("Thursday").left(1) );
82 cmdDay6->setText( DateBookDayHeaderBase::tr("Friday").left(1) );
83 cmdDay7->setText( DateBookDayHeaderBase::tr("Saturday").left(1) );
84 }
85}
86
87
88void DateBookDayHeader::pickDate()
89{
90 static QPopupMenu *m1 = 0;
91 static DateBookMonth *picker = 0;
92 if ( !m1 ) {
93 m1 = new QPopupMenu( this );
94 picker = new DateBookMonth( m1, 0, TRUE );
95 m1->insertItem( picker );
96 connect( picker, SIGNAL( dateClicked( int, int, int ) ),
97 this, SLOT( setDate( int, int, int ) ) );
98 connect( m1, SIGNAL( aboutToHide() ),
99 this, SLOT( gotHide() ) );
100 }
101 picker->setDate( currDate.year(), currDate.month(), currDate.day() );
102 m1->popup(mapToGlobal(date->pos()+QPoint(0,date->height())));
103 picker->setFocus();
104}
105
106void DateBookDayHeader::gotHide()
107{
108 // we have to redo the button...
109 date->setDown( false );
110}
111
112/*
113 * public slot
114 */
115void DateBookDayHeader::goBack()
116{
117 currDate = currDate.addDays( -1 );
118 setDate( currDate.year(), currDate.month(), currDate.day() );
119}
120/*
121 * public slot
122 */
123void DateBookDayHeader::goForward()
124{
125 currDate = currDate.addDays( 1 );
126 setDate( currDate.year(), currDate.month(), currDate.day() );
127}
128
129
130/*
131 * public slot
132 */
133void DateBookDayHeader::setDate( int y, int m, int d )
134{
135 currDate.setYMD( y, m, d );
136 date->setText( TimeString::shortDate( currDate ) );
137
138 int iDayOfWeek = currDate.dayOfWeek();
139 // cleverly adjust the day depending on how we start the week
140 if ( bUseMonday )
141 iDayOfWeek--;
142 else {
143 if ( iDayOfWeek == 7 ) // Sunday
144 iDayOfWeek = 0;
145 }
146 grpDays->setButton( iDayOfWeek );
147 emit dateChanged( y, m, d );
148}
149
150/*
151 * public slot
152 */
153void DateBookDayHeader::setDay( int day )
154{
155 int realDay;
156 int dayOfWeek = currDate.dayOfWeek();
157
158 // a little adjustment is needed...
159 if ( bUseMonday )
160 realDay = day + 1 ;
161 else if ( !bUseMonday && day == 0 ) // sunday
162 realDay = 7;
163 else
164 realDay = day;
165 // special cases first...
166 if ( realDay == 7 && !bUseMonday ) {
167 while ( currDate.dayOfWeek() != realDay )
168 currDate = currDate.addDays( -1 );
169 } else if ( !bUseMonday && dayOfWeek == 7 && dayOfWeek > realDay ) {
170 while ( currDate.dayOfWeek() != realDay )
171 currDate = currDate.addDays( 1 );
172 } else if ( dayOfWeek < realDay ) {
173 while ( currDate.dayOfWeek() < realDay )
174 currDate = currDate.addDays( 1 );
175 } else if ( dayOfWeek > realDay ) {
176 while ( currDate.dayOfWeek() > realDay )
177 currDate = currDate.addDays( -1 );
178 }
179 // update the date...
180 setDate( currDate.year(), currDate.month(), currDate.day() );
181}
diff --git a/core/pim/datebook/datebookdayheaderimpl.h b/core/pim/datebook/datebookdayheaderimpl.h
new file mode 100644
index 0000000..43f3a93
--- a/dev/null
+++ b/core/pim/datebook/datebookdayheaderimpl.h
@@ -0,0 +1,57 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia 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 DATEBOOKDAYHEADER_H
21#define DATEBOOKDAYHEADER_H
22#include "datebookdayheader.h"
23
24#include <qdatetime.h>
25
26class DateBookDayHeader : public DateBookDayHeaderBase
27{
28 Q_OBJECT
29
30public:
31 DateBookDayHeader( bool bUseMonday, QWidget* parent = 0,
32 const char* name = 0 );
33 ~DateBookDayHeader();
34 void setStartOfWeek( bool onMonday );
35
36public slots:
37 void goBack();
38 void goForward();
39 void setDate( int, int, int );
40 void setDay( int );
41 void gotHide();
42
43signals:
44 void dateChanged( int y, int m, int d );
45
46private slots:
47 void pickDate();
48
49
50private:
51 QDate currDate;
52 bool bUseMonday;
53 void setupNames();
54
55};
56
57#endif // DATEBOOKDAYHEADER_H
diff --git a/core/pim/datebook/datebooksettings.cpp b/core/pim/datebook/datebooksettings.cpp
new file mode 100644
index 0000000..c5d8ac1
--- a/dev/null
+++ b/core/pim/datebook/datebooksettings.cpp
@@ -0,0 +1,135 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia 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 "datebooksettings.h"
22
23#include <qpe/qpeapplication.h>
24
25#include <qspinbox.h>
26#include <qcheckbox.h>
27#include <qcombobox.h>
28
29DateBookSettings::DateBookSettings( bool whichClock, QWidget *parent,
30 const char *name, bool modal, WFlags fl )
31 : DateBookSettingsBase( parent, name, modal, fl ),
32 ampm( whichClock )
33{
34 init();
35 QObject::connect( qApp, SIGNAL( clockChanged( bool ) ),
36 this, SLOT( slotChangeClock( bool ) ) );
37}
38
39DateBookSettings::~DateBookSettings()
40{
41}
42
43void DateBookSettings::setStartTime( int newStartViewTime )
44{
45 if ( ampm ) {
46 if ( newStartViewTime >= 12 ) {
47 newStartViewTime %= 12;
48 if ( newStartViewTime == 0 )
49 newStartViewTime = 12;
50 spinStart->setSuffix( tr(":00 PM") );
51 }
52 else if ( newStartViewTime == 0 ) {
53 newStartViewTime = 12;
54 spinStart->setSuffix( tr(":00 AM") );
55 }
56 oldtime = newStartViewTime;
57 }
58 spinStart->setValue( newStartViewTime );
59}
60
61int DateBookSettings::startTime() const
62{
63 int returnMe = spinStart->value();
64 if ( ampm ) {
65 if ( returnMe != 12 && spinStart->suffix().contains(tr("PM"), FALSE) )
66 returnMe += 12;
67 else if (returnMe == 12 && spinStart->suffix().contains(tr("AM"), TRUE))
68 returnMe = 0;
69 }
70 return returnMe;
71}
72
73
74void DateBookSettings::setAlarmPreset( bool bAlarm, int presetTime )
75{
76 chkAlarmPreset->setChecked( bAlarm );
77 if ( presetTime >=5 )
78 spinPreset->setValue( presetTime );
79}
80
81bool DateBookSettings::alarmPreset() const
82{
83 return chkAlarmPreset->isChecked();
84}
85
86int DateBookSettings::presetTime() const
87{
88 return spinPreset->value();
89}
90
91
92void DateBookSettings::slot12Hour( int i )
93{
94 if ( ampm ) {
95 if ( spinStart->suffix().contains( tr("AM"), FALSE ) ) {
96 if ( oldtime == 12 && i == 11 || oldtime == 11 && i == 12 )
97 spinStart->setSuffix( tr(":00 PM") );
98 } else {
99 if ( oldtime == 12 && i == 11 || oldtime == 11 && i == 12 )
100 spinStart->setSuffix( tr(":00 AM") );
101 }
102 oldtime = i;
103 }
104}
105
106void DateBookSettings::init()
107{
108 if ( ampm ) {
109 spinStart->setMinValue( 1 );
110 spinStart->setMaxValue( 12 );
111 spinStart->setValue( 12 );
112 spinStart->setSuffix( tr(":00 AM") );
113 oldtime = 12;
114 } else {
115 spinStart->setMinValue( 0 );
116 spinStart->setMaxValue( 23 );
117 spinStart->setSuffix( tr(":00") );
118 }
119}
120
121void DateBookSettings::slotChangeClock( bool whichClock )
122{
123 int saveMe;
124 saveMe = spinStart->value();
125 if ( ampm && spinStart->suffix().contains( tr("AM"), FALSE ) ) {
126 if ( saveMe == 12 )
127 saveMe = 0;
128 } else if ( ampm && spinStart->suffix().contains( tr("PM"), FALSE ) ) {
129 if ( saveMe != 12 )
130 saveMe += 12;
131 }
132 ampm = whichClock;
133 init();
134 setStartTime( saveMe );
135}
diff --git a/core/pim/datebook/datebooksettings.h b/core/pim/datebook/datebooksettings.h
new file mode 100644
index 0000000..ee9f39c
--- a/dev/null
+++ b/core/pim/datebook/datebooksettings.h
@@ -0,0 +1,48 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia 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 DATEBOOKSETTINGS_H
22#define DATEBOOKSETTINGS_H
23#include "datebooksettingsbase.h"
24
25class DateBookSettings : public DateBookSettingsBase
26{
27public:
28 DateBookSettings( bool whichClock, QWidget *parent = 0,
29 const char *name = 0, bool modal = TRUE, WFlags = 0 );
30 ~DateBookSettings();
31 void setStartTime( int newStartViewTime );
32 int startTime() const;
33 void setAlarmPreset( bool bAlarm, int presetTime );
34 bool alarmPreset() const;
35 int presetTime() const;
36 void setAlarmType( int alarmType );
37 int alarmType() const;
38
39private slots:
40 void slot12Hour( int );
41 void slotChangeClock( bool );
42
43private:
44 void init();
45 bool ampm;
46 int oldtime;
47};
48#endif
diff --git a/core/pim/datebook/datebooksettingsbase.ui b/core/pim/datebook/datebooksettingsbase.ui
new file mode 100644
index 0000000..0f40773
--- a/dev/null
+++ b/core/pim/datebook/datebooksettingsbase.ui
@@ -0,0 +1,232 @@
1<!DOCTYPE UI><UI>
2<class>DateBookSettingsBase</class>
3<comment>**********************************************************************
4** Copyright (C) 2000 Trolltech AS. All rights reserved.
5**
6** This file is part of Qtopia 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>DateBookSettingsBase</cstring>
29 </property>
30 <property stdset="1">
31 <name>geometry</name>
32 <rect>
33 <x>0</x>
34 <y>0</y>
35 <width>232</width>
36 <height>290</height>
37 </rect>
38 </property>
39 <property stdset="1">
40 <name>caption</name>
41 <string>Preferences</string>
42 </property>
43 <property>
44 <name>layoutMargin</name>
45 </property>
46 <property>
47 <name>layoutSpacing</name>
48 </property>
49 <vbox>
50 <property stdset="1">
51 <name>margin</name>
52 <number>5</number>
53 </property>
54 <property stdset="1">
55 <name>spacing</name>
56 <number>1</number>
57 </property>
58 <widget>
59 <class>QGroupBox</class>
60 <property stdset="1">
61 <name>name</name>
62 <cstring>fraStart</cstring>
63 </property>
64 <property stdset="1">
65 <name>frameShape</name>
66 <enum>Box</enum>
67 </property>
68 <property stdset="1">
69 <name>frameShadow</name>
70 <enum>Sunken</enum>
71 </property>
72 <property stdset="1">
73 <name>title</name>
74 <string>Start viewing events</string>
75 </property>
76 <vbox>
77 <property stdset="1">
78 <name>margin</name>
79 <number>11</number>
80 </property>
81 <property stdset="1">
82 <name>spacing</name>
83 <number>6</number>
84 </property>
85 <widget>
86 <class>QLayoutWidget</class>
87 <property stdset="1">
88 <name>name</name>
89 <cstring>Layout1</cstring>
90 </property>
91 <hbox>
92 <property stdset="1">
93 <name>margin</name>
94 <number>0</number>
95 </property>
96 <property stdset="1">
97 <name>spacing</name>
98 <number>6</number>
99 </property>
100 <widget>
101 <class>QLabel</class>
102 <property stdset="1">
103 <name>name</name>
104 <cstring>lblStartTime</cstring>
105 </property>
106 <property stdset="1">
107 <name>text</name>
108 <string>Start Time:</string>
109 </property>
110 </widget>
111 <widget>
112 <class>QSpinBox</class>
113 <property stdset="1">
114 <name>name</name>
115 <cstring>spinStart</cstring>
116 </property>
117 <property stdset="1">
118 <name>suffix</name>
119 <string>:00</string>
120 </property>
121 <property stdset="1">
122 <name>wrapping</name>
123 <bool>true</bool>
124 </property>
125 <property stdset="1">
126 <name>maxValue</name>
127 <number>23</number>
128 </property>
129 </widget>
130 </hbox>
131 </widget>
132 </vbox>
133 </widget>
134 <widget>
135 <class>QGroupBox</class>
136 <property stdset="1">
137 <name>name</name>
138 <cstring>fraAlarm</cstring>
139 </property>
140 <property stdset="1">
141 <name>title</name>
142 <string>Alarm Settings</string>
143 </property>
144 <vbox>
145 <property stdset="1">
146 <name>margin</name>
147 <number>11</number>
148 </property>
149 <property stdset="1">
150 <name>spacing</name>
151 <number>6</number>
152 </property>
153 <widget>
154 <class>QLayoutWidget</class>
155 <property stdset="1">
156 <name>name</name>
157 <cstring>Layout6</cstring>
158 </property>
159 <hbox>
160 <property stdset="1">
161 <name>margin</name>
162 <number>0</number>
163 </property>
164 <property stdset="1">
165 <name>spacing</name>
166 <number>6</number>
167 </property>
168 <widget>
169 <class>QCheckBox</class>
170 <property stdset="1">
171 <name>name</name>
172 <cstring>chkAlarmPreset</cstring>
173 </property>
174 <property stdset="1">
175 <name>text</name>
176 <string>Alarm Preset</string>
177 </property>
178 </widget>
179 <widget>
180 <class>QSpinBox</class>
181 <property stdset="1">
182 <name>name</name>
183 <cstring>spinPreset</cstring>
184 </property>
185 <property stdset="1">
186 <name>enabled</name>
187 <bool>false</bool>
188 </property>
189 <property stdset="1">
190 <name>suffix</name>
191 <string> minutes</string>
192 </property>
193 <property stdset="1">
194 <name>maxValue</name>
195 <number>180</number>
196 </property>
197 <property stdset="1">
198 <name>minValue</name>
199 <number>0</number>
200 </property>
201 <property stdset="1">
202 <name>lineStep</name>
203 <number>5</number>
204 </property>
205 <property stdset="1">
206 <name>value</name>
207 <number>5</number>
208 </property>
209 </widget>
210 </hbox>
211 </widget>
212 </vbox>
213 </widget>
214 </vbox>
215</widget>
216<connections>
217 <connection>
218 <sender>chkAlarmPreset</sender>
219 <signal>toggled(bool)</signal>
220 <receiver>spinPreset</receiver>
221 <slot>setEnabled(bool)</slot>
222 </connection>
223 <connection>
224 <sender>spinStart</sender>
225 <signal>valueChanged(int)</signal>
226 <receiver>DateBookSettingsBase</receiver>
227 <slot>slot12Hour( int )</slot>
228 </connection>
229 <slot access="public">slotChangeClock( bool )</slot>
230 <slot access="public">slot12Hour( int )</slot>
231</connections>
232</UI>
diff --git a/core/pim/datebook/datebookweek.cpp b/core/pim/datebook/datebookweek.cpp
new file mode 100644
index 0000000..e9fcc39
--- a/dev/null
+++ b/core/pim/datebook/datebookweek.cpp
@@ -0,0 +1,687 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia 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#include "datebookweek.h"
21#include "datebookweekheaderimpl.h"
22
23#include <qpe/calendar.h>
24#include <qpe/datebookdb.h>
25#include <qpe/event.h>
26#include <qpe/qpeapplication.h>
27#include <qpe/timestring.h>
28
29#include <qdatetime.h>
30#include <qheader.h>
31#include <qlabel.h>
32#include <qlayout.h>
33#include <qpainter.h>
34#include <qpopupmenu.h>
35#include <qtimer.h>
36#include <qspinbox.h>
37#include <qstyle.h>
38
39//-----------------------------------------------------------------
40
41
42DateBookWeekItem::DateBookWeekItem( const EffectiveEvent e )
43 : ev( e )
44{
45 // with the current implementation change the color for all day events
46 if ( ev.event().type() == Event::AllDay && !ev.event().hasAlarm() ) {
47 c = Qt::green;
48 } else {
49 c = ev.event().hasAlarm() ? Qt::red : Qt::blue;
50 }
51}
52
53void DateBookWeekItem::setGeometry( int x, int y, int w, int h )
54{
55 r.setRect( x, y, w, h );
56}
57
58
59//------------------=---------------------------------------------
60
61DateBookWeekView::DateBookWeekView( bool ap, bool startOnMonday,
62 QWidget *parent, const char *name )
63 : QScrollView( parent, name ), ampm( ap ), bOnMonday( startOnMonday ),
64 showingEvent( false )
65{
66 items.setAutoDelete( true );
67
68 viewport()->setBackgroundMode( PaletteBase );
69
70 header = new QHeader( this );
71 header->addLabel( "" );
72
73 header->setMovingEnabled( false );
74 header->setResizeEnabled( false );
75 header->setClickEnabled( false, 0 );
76 initNames();
77
78
79 connect( header, SIGNAL(clicked(int)), this, SIGNAL(showDay(int)) );
80
81 QObject::connect(qApp, SIGNAL(clockChanged(bool)),
82 this, SLOT(slotChangeClock(bool)));
83
84 QFontMetrics fm( font() );
85 rowHeight = fm.height()+2;
86
87 resizeContents( width(), 24*rowHeight );
88}
89
90void DateBookWeekView::initNames()
91{
92 static bool bFirst = true;
93 if ( bFirst ) {
94 if ( bOnMonday ) {
95 header->addLabel( tr("M", "Monday" ) );
96 header->addLabel( tr("T", "Tuesday") );
97 header->addLabel( tr("W", "Wednesday" ) );
98 header->addLabel( tr("T", "Thursday" ) );
99 header->addLabel( tr("F", "Friday" ) );
100 header->addLabel( tr("S", "Saturday" ) );
101 header->addLabel( tr("S", "Sunday" ) );
102 } else {
103 header->addLabel( tr("S", "Sunday" ) );
104 header->addLabel( tr("M", "Monday") );
105 header->addLabel( tr("T", "Tuesday") );
106 header->addLabel( tr("W", "Wednesday" ) );
107 header->addLabel( tr("T", "Thursday" ) );
108 header->addLabel( tr("F", "Friday" ) );
109 header->addLabel( tr("S", "Saturday" ) );
110 }
111 bFirst = false;
112 } else {
113 // we are change things...
114 if ( bOnMonday ) {
115 header->setLabel( 1, tr("M", "Monday") );
116 header->setLabel( 2, tr("T", "Tuesday") );
117 header->setLabel( 3, tr("W", "Wednesday" ) );
118 header->setLabel( 4, tr("T", "Thursday" ) );
119 header->setLabel( 5, tr("F", "Friday" ) );
120 header->setLabel( 6, tr("S", "Saturday" ) );
121 header->setLabel( 7, tr("S", "Sunday" ) );
122 } else {
123 header->setLabel( 1, tr("S", "Sunday" ) );
124 header->setLabel( 2, tr("M", "Monday") );
125 header->setLabel( 3, tr("T", "Tuesday") );
126 header->setLabel( 4, tr("W", "Wednesday" ) );
127 header->setLabel( 5, tr("T", "Thursday" ) );
128 header->setLabel( 6, tr("F", "Friday" ) );
129 header->setLabel( 7, tr("S", "Saturday" ) );
130 }
131 }
132}
133
134
135
136void DateBookWeekView::showEvents( QValueList<EffectiveEvent> &ev )
137{
138 items.clear();
139 QValueListIterator<EffectiveEvent> it;
140 for ( it = ev.begin(); it != ev.end(); ++it ) {
141 DateBookWeekItem *i = new DateBookWeekItem( *it );
142 positionItem( i );
143 items.append( i );
144 }
145 viewport()->update();
146}
147
148void DateBookWeekView::moveToHour( int h )
149{
150 int offset = h*rowHeight;
151 setContentsPos( 0, offset );
152}
153
154void DateBookWeekView::keyPressEvent( QKeyEvent *e )
155{
156 e->ignore();
157}
158
159void DateBookWeekView::slotChangeClock( bool c )
160{
161 ampm = c;
162 viewport()->update();
163}
164
165static inline int db_round30min( int m )
166{
167 if ( m < 15 )
168 m = 0;
169 else if ( m < 45 )
170 m = 1;
171 else
172 m = 2;
173
174 return m;
175}
176
177void DateBookWeekView::alterDay( int day )
178{
179 if ( !bOnMonday ) {
180 day--;
181 }
182 emit showDay( day );
183}
184
185void DateBookWeekView::positionItem( DateBookWeekItem *i )
186{
187 const int Width = 8;
188 const EffectiveEvent ev = i->event();
189
190 // 30 minute intervals
191 int y = ev.start().hour() * 2;
192 y += db_round30min( ev.start().minute() );
193 if ( y > 47 )
194 y = 47;
195 y = y * rowHeight / 2;
196
197 int h;
198 if ( ev.event().type() == Event::AllDay ) {
199 h = 48;
200 y = 0;
201 } else {
202 h = ( ev.end().hour() - ev.start().hour() ) * 2;
203 h += db_round30min( ev.end().minute() - ev.start().minute() );
204 if ( h < 1 ) h = 1;
205 }
206 h = h * rowHeight / 2;
207
208 int dow = ev.date().dayOfWeek();
209 if ( !bOnMonday ) {
210 if ( dow == 7 )
211 dow = 1;
212 else
213 dow++;
214 }
215 int x = header->sectionPos( dow ) - 1;
216 int xlim = header->sectionPos( dow ) + header->sectionSize( dow );
217 DateBookWeekItem *isect = 0;
218 do {
219 i->setGeometry( x, y, Width, h );
220 isect = intersects( i );
221 x += Width - 1;
222 } while ( isect && x < xlim );
223}
224
225DateBookWeekItem *DateBookWeekView::intersects( const DateBookWeekItem *item )
226{
227 QRect geom = item->geometry();
228
229 // We allow the edges to overlap
230 geom.moveBy( 1, 1 );
231 geom.setSize( geom.size()-QSize(2,2) );
232
233 QListIterator<DateBookWeekItem> it(items);
234 for ( ; it.current(); ++it ) {
235 DateBookWeekItem *i = it.current();
236 if ( i != item ) {
237 if ( i->geometry().intersects( geom ) ) {
238 return i;
239 }
240 }
241 }
242
243 return 0;
244}
245
246void DateBookWeekView::contentsMousePressEvent( QMouseEvent *e )
247{
248 QListIterator<DateBookWeekItem> it(items);
249 for ( ; it.current(); ++it ) {
250 DateBookWeekItem *i = it.current();
251 if ( i->geometry().contains( e->pos() ) ) {
252 showingEvent = true;
253 emit signalShowEvent( i->event() );
254 break;
255 }
256 }
257}
258
259void DateBookWeekView::contentsMouseReleaseEvent( QMouseEvent *e )
260{
261 if ( showingEvent ) {
262 showingEvent = false;
263 emit signalHideEvent();
264 } else {
265 int d = header->sectionAt( e->pos().x() );
266 if ( d > 0 ) {
267 // if ( !bOnMonday )
268 // d--;
269 emit showDay( d );
270 }
271 }
272}
273
274void DateBookWeekView::drawContents( QPainter *p, int cx, int cy, int cw, int ch )
275{
276 QRect ur( cx, cy, cw, ch );
277 p->setPen( lightGray );
278 for ( int i = 1; i <= 7; i++ )
279 p->drawLine( header->sectionPos(i)-2, cy, header->sectionPos(i)-2, cy+ch );
280
281 p->setPen( black );
282 for ( int t = 0; t < 24; t++ ) {
283 int y = t*rowHeight;
284 if ( QRect( 1, y, 20, rowHeight ).intersects( ur ) ) {
285 QString s;
286 if ( ampm ) {
287 if ( t == 0 )
288 s = QString::number( 12 );
289 else if ( t == 12 )
290 s = QString::number(12) + tr( "p" );
291 else if ( t > 12 ) {
292 if ( t - 12 < 10 )
293 s = " ";
294 else
295 s = "";
296 s += QString::number( t - 12 ) + tr("p");
297 } else {
298 if ( 12 - t < 3 )
299 s = "";
300 else
301 s = " ";
302 s += QString::number( t );
303 }
304 } else {
305 s = QString::number( t );
306 if ( s.length() == 1 )
307 s.prepend( "0" );
308 }
309 p->drawText( 1, y+p->fontMetrics().ascent()+1, s );
310 }
311 }
312
313 QListIterator<DateBookWeekItem> it(items);
314 for ( ; it.current(); ++it ) {
315 DateBookWeekItem *i = it.current();
316 if ( i->geometry().intersects( ur ) ) {
317 p->setBrush( i->color() );
318 p->drawRect( i->geometry() );
319 }
320 }
321}
322
323void DateBookWeekView::resizeEvent( QResizeEvent *e )
324{
325 const int hourWidth = 20;
326 QScrollView::resizeEvent( e );
327 int avail = width()-qApp->style().scrollBarExtent().width()-1;
328 header->setGeometry( 0, 0, avail, header->sizeHint().height() );
329 setMargins( 0, header->height(), 0, 0 );
330 header->resizeSection( 0, hourWidth );
331 int sw = (avail - hourWidth) / 7;
332 for ( int i = 1; i < 7; i++ )
333 header->resizeSection( i, sw );
334 header->resizeSection( 7, avail - hourWidth - sw*6 );
335}
336
337void DateBookWeekView::setStartOfWeek( bool bStartOnMonday )
338{
339 bOnMonday = bStartOnMonday;
340 initNames();
341}
342
343//-------------------------------------------------------------------
344
345DateBookWeek::DateBookWeek( bool ap, bool startOnMonday, DateBookDB *newDB,
346 QWidget *parent, const char *name )
347 : QWidget( parent, name ),
348 db( newDB ),
349 startTime( 0 ),
350 ampm( ap ),
351 bStartOnMonday( startOnMonday )
352{
353 setFocusPolicy(StrongFocus);
354 QVBoxLayout *vb = new QVBoxLayout( this );
355 header = new DateBookWeekHeader( bStartOnMonday, this );
356 view = new DateBookWeekView( ampm, startOnMonday, this );
357 vb->addWidget( header );
358 vb->addWidget( view );
359
360 lblDesc = new QLabel( this, "event label" );
361 lblDesc->setFrameStyle( QFrame::Plain | QFrame::Box );
362 lblDesc->setBackgroundColor( yellow );
363 lblDesc->hide();
364
365 tHide = new QTimer( this );
366
367 connect( view, SIGNAL( showDay( int ) ),
368 this, SLOT( showDay( int ) ) );
369 connect( view, SIGNAL(signalShowEvent(const EffectiveEvent&)),
370 this, SLOT(slotShowEvent(const EffectiveEvent&)) );
371 connect( view, SIGNAL(signalHideEvent()),
372 this, SLOT(slotHideEvent()) );
373 connect( header, SIGNAL( dateChanged( int, int ) ),
374 this, SLOT( dateChanged( int, int ) ) );
375 connect( tHide, SIGNAL( timeout() ),
376 lblDesc, SLOT( hide() ) );
377 connect( header->spinYear, SIGNAL(valueChanged(int)),
378 this, SLOT(slotYearChanged(int)) );
379 connect( qApp, SIGNAL(weekChanged(bool)),
380 this, SLOT(slotWeekChanged(bool)) );
381 connect( qApp, SIGNAL(clockChanged(bool)),
382 this, SLOT(slotClockChanged(bool)));
383 setDate(QDate::currentDate());
384
385}
386
387void DateBookWeek::keyPressEvent(QKeyEvent *e)
388{
389 switch(e->key()) {
390 case Key_Up:
391 view->scrollBy(0, -20);
392 break;
393 case Key_Down:
394 view->scrollBy(0, 20);
395 break;
396 case Key_Left:
397 setDate(date().addDays(-7));
398 break;
399 case Key_Right:
400 setDate(date().addDays(7));
401 break;
402 default:
403 e->ignore();
404 }
405}
406
407void DateBookWeek::showDay( int day )
408{
409 QDate d;
410 d = dateFromWeek( _week, year, bStartOnMonday );
411 day--;
412 d = d.addDays( day );
413 emit showDate( d.year(), d.month(), d.day() );
414}
415
416void DateBookWeek::setDate( int y, int m, int d )
417{
418 QDate date;
419 date.setYMD( y, m, d );
420 setDate(QDate(y, m, d));
421}
422
423void DateBookWeek::setDate(QDate date)
424{
425 dow = date.dayOfWeek();
426 int w, y;
427 calcWeek( date, w, y, bStartOnMonday );
428 header->setDate( y, w );
429}
430
431void DateBookWeek::dateChanged( int y, int w )
432{
433 year = y;
434 _week = w;
435 getEvents();
436}
437
438QDate DateBookWeek::date() const
439{
440 QDate d;
441 d = dateFromWeek( _week - 1, year, bStartOnMonday );
442 if ( bStartOnMonday )
443 d = d.addDays( 7 + dow - 1 );
444 else {
445 if ( dow == 7 )
446 d = d.addDays( dow );
447 else
448 d = d.addDays( 7 + dow );
449 }
450 return d;
451}
452
453void DateBookWeek::getEvents()
454{
455 QDate startWeek = weekDate();
456
457 QDate endWeek = startWeek.addDays( 6 );
458 QValueList<EffectiveEvent> eventList = db->getEffectiveEvents(startWeek,
459 endWeek);
460 view->showEvents( eventList );
461 view->moveToHour( startTime );
462}
463
464void DateBookWeek::slotShowEvent( const EffectiveEvent &ev )
465{
466 if ( tHide->isActive() )
467 tHide->stop();
468
469 // why would someone use "<"? Oh well, fix it up...
470 // I wonder what other things may be messed up...
471 QString strDesc = ev.description();
472 int where = strDesc.find( "<" );
473 while ( where != -1 ) {
474 strDesc.remove( where, 1 );
475 strDesc.insert( where, "&#60;" );
476 where = strDesc.find( "<", where );
477 }
478
479 QString strCat;
480 // ### FIX later...
481// QString strCat = ev.category();
482// where = strCat.find( "<" );
483// while ( where != -1 ) {
484 // strCat.remove( where, 1 );
485 // strCat.insert( where, "&#60;" );
486 // where = strCat.find( "<", where );
487// }
488
489 QString strNote = ev.notes();
490 where = strNote.find( "<" );
491 while ( where != -1 ) {
492 strNote.remove( where, 1 );
493 strNote.insert( where, "&#60;" );
494 where = strNote.find( "<", where );
495 }
496
497 QString str = "<b>" + strDesc + "</b><br>" + "<i>"
498 + strCat + "</i>"
499 + "<br>" + TimeString::longDateString( ev.date() )
500 + "<br><b>" + QObject::tr("Start") + "</b>: ";
501
502 if ( ev.startDate() != ev.date() ) {
503 // multi-day event. Show start date
504 str += TimeString::longDateString( ev.startDate() );
505 } else {
506 // Show start time.
507 str += TimeString::timeString(ev.start(), ampm, FALSE );
508 }
509
510 str += "<br><b>" + QObject::tr("End") + "</b>: ";
511 if ( ev.endDate() != ev.date() ) {
512 // multi-day event. Show end date
513 str += TimeString::longDateString( ev.endDate() );
514 } else {
515 // Show end time.
516 str += TimeString::timeString( ev.end(), ampm, FALSE );
517 }
518 str += "<br><br>" + strNote;
519
520 lblDesc->setText( str );
521 lblDesc->resize( lblDesc->sizeHint() );
522 // move the label so it is "centerd" horizontally...
523 lblDesc->move( QMAX(0,(width() - lblDesc->width()) / 2), 0 );
524 lblDesc->show();
525}
526
527void DateBookWeek::slotHideEvent()
528{
529 tHide->start( 2000, true );
530}
531
532void DateBookWeek::setStartViewTime( int startHere )
533{
534 startTime = startHere;
535 view->moveToHour( startTime );
536}
537
538int DateBookWeek::startViewTime() const
539{
540 return startTime;
541}
542
543void DateBookWeek::redraw()
544{
545 getEvents();
546}
547
548void DateBookWeek::slotYearChanged( int y )
549{
550 int totWeek;
551 QDate d( y, 12, 31 );
552 int throwAway;
553 calcWeek( d, totWeek, throwAway, bStartOnMonday );
554 while ( totWeek == 1 ) {
555 d = d.addDays( -1 );
556 calcWeek( d, totWeek, throwAway, bStartOnMonday );
557 }
558 if ( totWeek != totalWeeks() )
559 setTotalWeeks( totWeek );
560}
561
562
563void DateBookWeek::setTotalWeeks( int numWeeks )
564{
565 header->spinWeek->setMaxValue( numWeeks );
566}
567
568int DateBookWeek::totalWeeks() const
569{
570 return header->spinWeek->maxValue();
571}
572
573void DateBookWeek::slotWeekChanged( bool onMonday )
574{
575 bStartOnMonday = onMonday;
576 view->setStartOfWeek( bStartOnMonday );
577 header->setStartOfWeek( bStartOnMonday );
578 redraw();
579}
580
581void DateBookWeek::slotClockChanged( bool ap )
582{
583 ampm = ap;
584}
585
586// return the date at the beginning of the week...
587QDate DateBookWeek::weekDate() const
588{
589 return dateFromWeek( _week, year, bStartOnMonday );
590}
591
592// this used to only be needed by datebook.cpp, but now we need it inside
593// week view since
594// we need to be able to figure out our total number of weeks on the fly...
595// this is probably the best place to put it..
596
597// For Weeks that start on Monday... (EASY!)
598// At the moment we will use ISO 8601 method for computing
599// the week. Granted, other countries use other methods,
600// bet we aren't doing any Locale stuff at the moment. So,
601// this should pass. This Algorithim is public domain and
602// available at:
603// http://personal.ecu.edu/mccartyr/ISOwdALG.txt
604// the week number is return, and the year number is returned in year
605// for Instance 2001/12/31 is actually the first week in 2002.
606// There is a more mathematical definition, but I will implement it when
607// we are pass our deadline.
608
609// For Weeks that start on Sunday... (ahh... home rolled)
610// okay, if Jan 1 is on Friday or Saturday,
611// it will go to the pervious
612// week...
613
614bool calcWeek( const QDate &d, int &week, int &year,
615 bool startOnMonday = false )
616{
617 int weekNumber;
618 int yearNumber;
619
620 // remove a pesky warning, (Optimizations on g++)
621 weekNumber = -1;
622 int jan1WeekDay = QDate(d.year(), 1, 1).dayOfWeek();
623 int dayOfWeek = d.dayOfWeek();
624
625 if ( !d.isValid() )
626 return false;
627
628 if ( startOnMonday ) {
629 // find the Jan1Weekday;
630 if ( d.dayOfYear() <= ( 8 - jan1WeekDay) && jan1WeekDay > 4 ) {
631 yearNumber = d.year() - 1;
632 if ( jan1WeekDay == 5 || ( jan1WeekDay == 6 && QDate::leapYear(yearNumber) ) )
633 weekNumber = 53;
634 else
635 weekNumber = 52;
636 } else
637 yearNumber = d.year();
638 if ( yearNumber == d.year() ) {
639 int totalDays = 365;
640 if ( QDate::leapYear(yearNumber) )
641 totalDays++;
642 if ( ((totalDays - d.dayOfYear()) < (4 - dayOfWeek) )
643 || (jan1WeekDay == 7) && (totalDays - d.dayOfYear()) < 3) {
644 yearNumber++;
645 weekNumber = 1;
646 }
647 }
648 if ( yearNumber == d.year() ) {
649 int j = d.dayOfYear() + (7 - dayOfWeek) + ( jan1WeekDay - 1 );
650 weekNumber = j / 7;
651 if ( jan1WeekDay > 4 )
652 weekNumber--;
653 }
654 } else {
655 // it's better to keep these cases separate...
656 if ( d.dayOfYear() <= (7 - jan1WeekDay) && jan1WeekDay > 4
657 && jan1WeekDay != 7 ) {
658 yearNumber = d.year() - 1;
659 if ( jan1WeekDay == 6
660 || (jan1WeekDay == 7 && QDate::leapYear(yearNumber) ) ) {
661 weekNumber = 53;
662 }else
663 weekNumber = 52;
664 } else
665 yearNumber = d.year();
666 if ( yearNumber == d.year() ) {
667 int totalDays = 365;
668 if ( QDate::leapYear( yearNumber ) )
669 totalDays++;
670 if ( ((totalDays - d.dayOfYear()) < (4 - dayOfWeek % 7)) ) {
671 yearNumber++;
672 weekNumber = 1;
673 }
674 }
675 if ( yearNumber == d.year() ) {
676 int j = d.dayOfYear() + (7 - dayOfWeek % 7) + ( jan1WeekDay - 1 );
677 weekNumber = j / 7;
678 if ( jan1WeekDay > 4 ) {
679 weekNumber--;
680 }
681 }
682 }
683 year = yearNumber;
684 week = weekNumber;
685 return true;
686}
687
diff --git a/core/pim/datebook/datebookweek.h b/core/pim/datebook/datebookweek.h
new file mode 100644
index 0000000..6e675f1
--- a/dev/null
+++ b/core/pim/datebook/datebookweek.h
@@ -0,0 +1,152 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia 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 DATEBOOKWEEK
21#define DATEBOOKWEEK
22
23#include <qpe/event.h>
24
25#include <qlist.h>
26#include <qscrollview.h>
27#include <qstring.h>
28#include <qvaluelist.h>
29
30class DateBookDB;
31class DateBookWeekHeader;
32class QDate;
33class QLabel;
34class QResizeEvent;
35class QSpinBox;
36class QTimer;
37class QHeader;
38
39class DateBookWeekItem
40{
41public:
42 DateBookWeekItem( const EffectiveEvent e );
43
44 void setGeometry( int x, int y, int w, int h );
45 QRect geometry() const { return r; }
46
47 const QColor &color() const { return c; }
48 const EffectiveEvent event() const { return ev; }
49
50private:
51 const EffectiveEvent ev;
52 QRect r;
53 QColor c;
54};
55
56class DateBookWeekView : public QScrollView
57{
58 Q_OBJECT
59public:
60 DateBookWeekView( bool ampm, bool weekOnMonday, QWidget *parent = 0,
61 const char *name = 0 );
62
63 bool whichClock() const;
64 void showEvents( QValueList<EffectiveEvent> &ev );
65 void moveToHour( int h );
66 void setStartOfWeek( bool bOnMonday );
67
68signals:
69 void showDay( int d );
70 void signalShowEvent( const EffectiveEvent & );
71 void signalHideEvent();
72
73protected slots:
74 void keyPressEvent(QKeyEvent *);
75
76private slots:
77 void slotChangeClock( bool );
78 void alterDay( int );
79
80private:
81 void positionItem( DateBookWeekItem *i );
82 DateBookWeekItem *intersects( const DateBookWeekItem * );
83 void drawContents( QPainter *p, int cx, int cy, int cw, int ch );
84 void contentsMousePressEvent( QMouseEvent * );
85 void contentsMouseReleaseEvent( QMouseEvent * );
86 void resizeEvent( QResizeEvent * );
87 void initNames();
88
89private:
90 bool ampm;
91 bool bOnMonday;
92 QHeader *header;
93 QList<DateBookWeekItem> items;
94 int rowHeight;
95 bool showingEvent;
96};
97
98class DateBookWeek : public QWidget
99{
100 Q_OBJECT
101
102public:
103 DateBookWeek( bool ampm, bool weekOnMonday, DateBookDB *newDB,
104 QWidget *parent = 0, const char *name = 0 );
105 void setDate( int y, int m, int d );
106 void setDate( QDate d );
107 QDate date() const;
108 DateBookWeekView *weekView() const { return view; }
109 void setStartViewTime( int startHere );
110 int startViewTime() const;
111 int week() const { return _week; };
112 void setTotalWeeks( int totalWeeks );
113 int totalWeeks() const;
114 QDate weekDate() const;
115
116public slots:
117 void redraw();
118 void slotWeekChanged( bool bStartOnMonday );
119 void slotClockChanged( bool a );
120
121signals:
122 void showDate( int y, int m, int d );
123
124protected slots:
125 void keyPressEvent(QKeyEvent *);
126
127private slots:
128 void showDay( int day );
129 void dateChanged( int y, int w );
130 void slotShowEvent( const EffectiveEvent & );
131 void slotHideEvent();
132 void slotYearChanged( int );
133
134private:
135 void getEvents();
136 int year;
137 int _week;
138 int dow;
139 DateBookWeekHeader *header;
140 DateBookWeekView *view;
141 DateBookDB *db;
142 QLabel *lblDesc;
143 QTimer *tHide;
144 int startTime;
145 bool ampm;
146 bool bStartOnMonday;
147};
148
149
150bool calcWeek( const QDate &d, int &week, int &year,
151 bool startOnMonday = false );
152#endif
diff --git a/core/pim/datebook/datebookweekheader.ui b/core/pim/datebook/datebookweekheader.ui
new file mode 100644
index 0000000..dd6a5b1
--- a/dev/null
+++ b/core/pim/datebook/datebookweekheader.ui
@@ -0,0 +1,167 @@
1<!DOCTYPE UI><UI>
2<class>DateBookWeekHeaderBase</class>
3<comment>*********************************************************************
4** Copyright (C) 2000 Trolltech AS. All rights reserved.
5**
6** This file is part of Qtopia 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*********************************************************************</comment>
22<widget>
23 <class>QWidget</class>
24 <property stdset="1">
25 <name>name</name>
26 <cstring>DateBookWeekHeaderBase</cstring>
27 </property>
28 <property stdset="1">
29 <name>geometry</name>
30 <rect>
31 <x>0</x>
32 <y>0</y>
33 <width>281</width>
34 <height>30</height>
35 </rect>
36 </property>
37 <property stdset="1">
38 <name>caption</name>
39 <string>Form1</string>
40 </property>
41 <property>
42 <name>layoutMargin</name>
43 </property>
44 <property>
45 <name>layoutSpacing</name>
46 </property>
47 <hbox>
48 <property stdset="1">
49 <name>margin</name>
50 <number>0</number>
51 </property>
52 <property stdset="1">
53 <name>spacing</name>
54 <number>6</number>
55 </property>
56 <widget>
57 <class>QSpinBox</class>
58 <property stdset="1">
59 <name>name</name>
60 <cstring>spinYear</cstring>
61 </property>
62 <property stdset="1">
63 <name>sizePolicy</name>
64 <sizepolicy>
65 <hsizetype>0</hsizetype>
66 <vsizetype>0</vsizetype>
67 </sizepolicy>
68 </property>
69 <property stdset="1">
70 <name>prefix</name>
71 <string>Y: </string>
72 </property>
73 <property stdset="1">
74 <name>maxValue</name>
75 <number>2037</number>
76 </property>
77 <property stdset="1">
78 <name>minValue</name>
79 <number>1970</number>
80 </property>
81 <property stdset="1">
82 <name>value</name>
83 <number>2002</number>
84 </property>
85 </widget>
86 <widget>
87 <class>QSpinBox</class>
88 <property stdset="1">
89 <name>name</name>
90 <cstring>spinWeek</cstring>
91 </property>
92 <property stdset="1">
93 <name>sizePolicy</name>
94 <sizepolicy>
95 <hsizetype>0</hsizetype>
96 <vsizetype>0</vsizetype>
97 </sizepolicy>
98 </property>
99 <property stdset="1">
100 <name>prefix</name>
101 <string>W: </string>
102 </property>
103 <property stdset="1">
104 <name>maxValue</name>
105 <number>52</number>
106 </property>
107 <property stdset="1">
108 <name>minValue</name>
109 <number>1</number>
110 </property>
111 <property stdset="1">
112 <name>value</name>
113 <number>1</number>
114 </property>
115 </widget>
116 <widget>
117 <class>QLabel</class>
118 <property stdset="1">
119 <name>name</name>
120 <cstring>labelDate</cstring>
121 </property>
122 <property stdset="1">
123 <name>sizePolicy</name>
124 <sizepolicy>
125 <hsizetype>3</hsizetype>
126 <vsizetype>1</vsizetype>
127 </sizepolicy>
128 </property>
129 <property stdset="1">
130 <name>font</name>
131 <font>
132 <bold>1</bold>
133 </font>
134 </property>
135 <property stdset="1">
136 <name>text</name>
137 <string>00. Jan-00. Jan</string>
138 </property>
139 <property stdset="1">
140 <name>alignment</name>
141 <set>AlignCenter</set>
142 </property>
143 <property>
144 <name>hAlign</name>
145 </property>
146 </widget>
147 </hbox>
148</widget>
149<connections>
150 <connection>
151 <sender>spinYear</sender>
152 <signal>valueChanged(int)</signal>
153 <receiver>DateBookWeekHeaderBase</receiver>
154 <slot>yearChanged( int )</slot>
155 </connection>
156 <connection>
157 <sender>spinWeek</sender>
158 <signal>valueChanged(int)</signal>
159 <receiver>DateBookWeekHeaderBase</receiver>
160 <slot>weekChanged( int )</slot>
161 </connection>
162 <slot access="public">yearChanged( int )</slot>
163 <slot access="public">nextWeek()</slot>
164 <slot access="public">prevWeek()</slot>
165 <slot access="public">weekChanged( int )</slot>
166</connections>
167</UI>
diff --git a/core/pim/datebook/datebookweekheaderimpl.cpp b/core/pim/datebook/datebookweekheaderimpl.cpp
new file mode 100644
index 0000000..e7c7208
--- a/dev/null
+++ b/core/pim/datebook/datebookweekheaderimpl.cpp
@@ -0,0 +1,126 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia 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#include "datebookweekheaderimpl.h"
21#include <qlabel.h>
22#include <qspinbox.h>
23#include <qdatetime.h>
24
25/*
26 * Constructs a DateBookWeekHeader which is a child of 'parent', with the
27 * name 'name' and widget flags set to 'f'
28 */
29DateBookWeekHeader::DateBookWeekHeader( bool startOnMonday, QWidget* parent,
30 const char* name, WFlags fl )
31 : DateBookWeekHeaderBase( parent, name, fl ),
32 bStartOnMonday( startOnMonday )
33{
34 setBackgroundMode( PaletteButton );
35 labelDate->setBackgroundMode( PaletteButton );
36}
37
38/*
39 * Destroys the object and frees any allocated resources
40 */
41DateBookWeekHeader::~DateBookWeekHeader()
42{
43 // no need to delete child widgets, Qt does it all for us
44}
45
46/*
47 * public slot
48 */
49void DateBookWeekHeader::yearChanged( int y )
50{
51 setDate( y, week );
52}
53/*
54 * public slot
55 */
56void DateBookWeekHeader::nextWeek()
57{
58 if ( week < 52 )
59 week++;
60 setDate( year, week );
61}
62/*
63 * public slot
64 */
65void DateBookWeekHeader::prevWeek()
66{
67 if ( week > 1 )
68 week--;
69 setDate( year, week );
70}
71/*
72 * public slot
73 */
74void DateBookWeekHeader::weekChanged( int w )
75{
76 setDate( year, w );
77}
78
79void DateBookWeekHeader::setDate( int y, int w )
80{
81 year = y;
82 week = w;
83 spinYear->setValue( y );
84 spinWeek->setValue( w );
85
86 QDate d = dateFromWeek( week, year, bStartOnMonday );
87
88 QString s = QString::number( d.day() ) + ". " + d.monthName( d.month() )
89 + "-";
90 d = d.addDays( 6 );
91 s += QString::number( d.day() ) + ". " + d.monthName( d.month() );
92 labelDate->setText( s );
93
94 emit dateChanged( y, w );
95}
96
97void DateBookWeekHeader::setStartOfWeek( bool onMonday )
98{
99 bStartOnMonday = onMonday;
100 setDate( year, week );
101}
102
103// dateFromWeek
104// compute the date from the week in the year
105
106QDate dateFromWeek( int week, int year, bool startOnMonday )
107{
108 QDate d;
109 d.setYMD( year, 1, 1 );
110 int dayOfWeek = d.dayOfWeek();
111 if ( startOnMonday ) {
112 if ( dayOfWeek <= 4 ) {
113 d = d.addDays( ( week - 1 ) * 7 - dayOfWeek + 1 );
114 } else {
115 d = d.addDays( (week) * 7 - dayOfWeek + 1 );
116 }
117 } else {
118 if ( dayOfWeek <= 4 || dayOfWeek == 7) {
119 d = d.addDays( ( week - 1 ) * 7 - dayOfWeek % 7 );
120 } else {
121 d = d.addDays( ( week ) * 7 - dayOfWeek % 7 );
122 }
123 }
124 return d;
125}
126
diff --git a/core/pim/datebook/datebookweekheaderimpl.h b/core/pim/datebook/datebookweekheaderimpl.h
new file mode 100644
index 0000000..2abef46
--- a/dev/null
+++ b/core/pim/datebook/datebookweekheaderimpl.h
@@ -0,0 +1,62 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia 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 DATEBOOKDAYHEADER_H
21#define DATEBOOKDAYHEADER_H
22#include <qdatetime.h>
23#include "datebookweekheader.h"
24
25
26class DateBookWeekHeader : public DateBookWeekHeaderBase
27{
28 Q_OBJECT
29
30public:
31 DateBookWeekHeader( bool startOnMonday, QWidget* parent = 0,
32 const char* name = 0, WFlags fl = 0 );
33 ~DateBookWeekHeader();
34
35 void setDate( int y, int w );
36 void setStartOfWeek( bool onMonday );
37
38signals:
39 void dateChanged( int y, int w );
40
41public slots:
42 void yearChanged( int );
43 void nextWeek();
44 void prevWeek();
45 void weekChanged( int );
46
47protected slots:
48 void keyPressEvent(QKeyEvent *e)
49 {
50 e->ignore();
51 }
52
53private:
54 int year,
55 week;
56 bool bStartOnMonday;
57
58};
59
60QDate dateFromWeek( int week, int year, bool startOnMonday );
61
62#endif // DATEBOOKDAYHEADER_H
diff --git a/core/pim/datebook/dateentry.ui b/core/pim/datebook/dateentry.ui
new file mode 100644
index 0000000..0c363a4
--- a/dev/null
+++ b/core/pim/datebook/dateentry.ui
@@ -0,0 +1,1095 @@
1<!DOCTYPE UI><UI>
2<class>DateEntryBase</class>
3<comment>*********************************************************************
4** Copyright (C) 2000 Trolltech AS. All rights reserved.
5**
6** This file is part of Qtopia 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>QWidget</class>
26 <property stdset="1">
27 <name>name</name>
28 <cstring>DateEntryBase</cstring>
29 </property>
30 <property stdset="1">
31 <name>geometry</name>
32 <rect>
33 <x>0</x>
34 <y>0</y>
35 <width>242</width>
36 <height>339</height>
37 </rect>
38 </property>
39 <property stdset="1">
40 <name>caption</name>
41 <string>New Event</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>0</number>
53 </property>
54 <property stdset="1">
55 <name>spacing</name>
56 <number>0</number>
57 </property>
58 <widget row="1" column="0" >
59 <class>QLabel</class>
60 <property stdset="1">
61 <name>name</name>
62 <cstring>TextLabel2</cstring>
63 </property>
64 <property stdset="1">
65 <name>frameShape</name>
66 <enum>MShape</enum>
67 </property>
68 <property stdset="1">
69 <name>frameShadow</name>
70 <enum>MShadow</enum>
71 </property>
72 <property stdset="1">
73 <name>text</name>
74 <string>Location</string>
75 </property>
76 </widget>
77 <widget row="2" column="0" >
78 <class>QLabel</class>
79 <property stdset="1">
80 <name>name</name>
81 <cstring>TextLabel2_2</cstring>
82 </property>
83 <property stdset="1">
84 <name>text</name>
85 <string>Category</string>
86 </property>
87 <property>
88 <name>buddy</name>
89 <cstring>comboPriority</cstring>
90 </property>
91 </widget>
92 <widget row="0" column="1" rowspan="1" colspan="3" >
93 <class>QComboBox</class>
94 <item>
95 <property>
96 <name>text</name>
97 <string>(None)</string>
98 </property>
99 </item>
100 <item>
101 <property>
102 <name>text</name>
103 <string>Meeting</string>
104 </property>
105 </item>
106 <item>
107 <property>
108 <name>text</name>
109 <string>Lunch</string>
110 </property>
111 </item>
112 <item>
113 <property>
114 <name>text</name>
115 <string>Dinner</string>
116 </property>
117 </item>
118 <item>
119 <property>
120 <name>text</name>
121 <string>Travel</string>
122 </property>
123 </item>
124 <property stdset="1">
125 <name>name</name>
126 <cstring>comboDescription</cstring>
127 </property>
128 <property stdset="1">
129 <name>sizePolicy</name>
130 <sizepolicy>
131 <hsizetype>7</hsizetype>
132 <vsizetype>0</vsizetype>
133 </sizepolicy>
134 </property>
135 <property stdset="1">
136 <name>editable</name>
137 <bool>true</bool>
138 </property>
139 <property stdset="1">
140 <name>currentItem</name>
141 <number>0</number>
142 </property>
143 <property stdset="1">
144 <name>duplicatesEnabled</name>
145 <bool>false</bool>
146 </property>
147 </widget>
148 <widget row="0" column="0" >
149 <class>QLabel</class>
150 <property stdset="1">
151 <name>name</name>
152 <cstring>TextLabel1</cstring>
153 </property>
154 <property stdset="1">
155 <name>text</name>
156 <string>Description:</string>
157 </property>
158 </widget>
159 <widget row="1" column="1" rowspan="1" colspan="3" >
160 <class>QComboBox</class>
161 <item>
162 <property>
163 <name>text</name>
164 <string>(Unknown)</string>
165 </property>
166 </item>
167 <item>
168 <property>
169 <name>text</name>
170 <string>Office</string>
171 </property>
172 </item>
173 <item>
174 <property>
175 <name>text</name>
176 <string>Home</string>
177 </property>
178 </item>
179 <property stdset="1">
180 <name>name</name>
181 <cstring>comboLocation</cstring>
182 </property>
183 <property stdset="1">
184 <name>sizePolicy</name>
185 <sizepolicy>
186 <hsizetype>7</hsizetype>
187 <vsizetype>0</vsizetype>
188 </sizepolicy>
189 </property>
190 <property stdset="1">
191 <name>editable</name>
192 <bool>true</bool>
193 </property>
194 <property stdset="1">
195 <name>currentItem</name>
196 <number>0</number>
197 </property>
198 <property stdset="1">
199 <name>duplicatesEnabled</name>
200 <bool>false</bool>
201 </property>
202 </widget>
203 <widget row="2" column="1" rowspan="1" colspan="3" >
204 <class>CategorySelect</class>
205 <property stdset="1">
206 <name>name</name>
207 <cstring>comboCategory</cstring>
208 </property>
209 </widget>
210 <widget row="3" column="0" >
211 <class>QLabel</class>
212 <property stdset="1">
213 <name>name</name>
214 <cstring>TextLabel3</cstring>
215 </property>
216 <property stdset="1">
217 <name>text</name>
218 <string>Start</string>
219 </property>
220 </widget>
221 <widget row="3" column="1" >
222 <class>QPushButton</class>
223 <property stdset="1">
224 <name>name</name>
225 <cstring>buttonStart</cstring>
226 </property>
227 <property stdset="1">
228 <name>text</name>
229 <string>Jan 02 00</string>
230 </property>
231 </widget>
232 <widget row="3" column="2" rowspan="1" colspan="2" >
233 <class>QComboBox</class>
234 <item>
235 <property>
236 <name>text</name>
237 <string>00:00</string>
238 </property>
239 </item>
240 <item>
241 <property>
242 <name>text</name>
243 <string>00:30</string>
244 </property>
245 </item>
246 <item>
247 <property>
248 <name>text</name>
249 <string>01:00</string>
250 </property>
251 </item>
252 <item>
253 <property>
254 <name>text</name>
255 <string>01:30</string>
256 </property>
257 </item>
258 <item>
259 <property>
260 <name>text</name>
261 <string>02:00</string>
262 </property>
263 </item>
264 <item>
265 <property>
266 <name>text</name>
267 <string>02:30</string>
268 </property>
269 </item>
270 <item>
271 <property>
272 <name>text</name>
273 <string>03:00</string>
274 </property>
275 </item>
276 <item>
277 <property>
278 <name>text</name>
279 <string>03:30</string>
280 </property>
281 </item>
282 <item>
283 <property>
284 <name>text</name>
285 <string>04:00</string>
286 </property>
287 </item>
288 <item>
289 <property>
290 <name>text</name>
291 <string>04:30</string>
292 </property>
293 </item>
294 <item>
295 <property>
296 <name>text</name>
297 <string>05:00</string>
298 </property>
299 </item>
300 <item>
301 <property>
302 <name>text</name>
303 <string>05:30</string>
304 </property>
305 </item>
306 <item>
307 <property>
308 <name>text</name>
309 <string>06:00</string>
310 </property>
311 </item>
312 <item>
313 <property>
314 <name>text</name>
315 <string>06:30</string>
316 </property>
317 </item>
318 <item>
319 <property>
320 <name>text</name>
321 <string>07:00</string>
322 </property>
323 </item>
324 <item>
325 <property>
326 <name>text</name>
327 <string>07:30</string>
328 </property>
329 </item>
330 <item>
331 <property>
332 <name>text</name>
333 <string>08:00</string>
334 </property>
335 </item>
336 <item>
337 <property>
338 <name>text</name>
339 <string>08:30</string>
340 </property>
341 </item>
342 <item>
343 <property>
344 <name>text</name>
345 <string>09:00</string>
346 </property>
347 </item>
348 <item>
349 <property>
350 <name>text</name>
351 <string>09:30</string>
352 </property>
353 </item>
354 <item>
355 <property>
356 <name>text</name>
357 <string>10:00</string>
358 </property>
359 </item>
360 <item>
361 <property>
362 <name>text</name>
363 <string>10:30</string>
364 </property>
365 </item>
366 <item>
367 <property>
368 <name>text</name>
369 <string>11:00</string>
370 </property>
371 </item>
372 <item>
373 <property>
374 <name>text</name>
375 <string>11:30</string>
376 </property>
377 </item>
378 <item>
379 <property>
380 <name>text</name>
381 <string>12:00</string>
382 </property>
383 </item>
384 <item>
385 <property>
386 <name>text</name>
387 <string>12:30</string>
388 </property>
389 </item>
390 <item>
391 <property>
392 <name>text</name>
393 <string>13:00</string>
394 </property>
395 </item>
396 <item>
397 <property>
398 <name>text</name>
399 <string>13:30</string>
400 </property>
401 </item>
402 <item>
403 <property>
404 <name>text</name>
405 <string>14:00</string>
406 </property>
407 </item>
408 <item>
409 <property>
410 <name>text</name>
411 <string>14:30</string>
412 </property>
413 </item>
414 <item>
415 <property>
416 <name>text</name>
417 <string>15:00</string>
418 </property>
419 </item>
420 <item>
421 <property>
422 <name>text</name>
423 <string>15:30</string>
424 </property>
425 </item>
426 <item>
427 <property>
428 <name>text</name>
429 <string>16:00</string>
430 </property>
431 </item>
432 <item>
433 <property>
434 <name>text</name>
435 <string>16:30</string>
436 </property>
437 </item>
438 <item>
439 <property>
440 <name>text</name>
441 <string>17:00</string>
442 </property>
443 </item>
444 <item>
445 <property>
446 <name>text</name>
447 <string>17:30</string>
448 </property>
449 </item>
450 <item>
451 <property>
452 <name>text</name>
453 <string>18:00</string>
454 </property>
455 </item>
456 <item>
457 <property>
458 <name>text</name>
459 <string>18:30</string>
460 </property>
461 </item>
462 <item>
463 <property>
464 <name>text</name>
465 <string>19:00</string>
466 </property>
467 </item>
468 <item>
469 <property>
470 <name>text</name>
471 <string>19:30</string>
472 </property>
473 </item>
474 <item>
475 <property>
476 <name>text</name>
477 <string>20:00</string>
478 </property>
479 </item>
480 <item>
481 <property>
482 <name>text</name>
483 <string>20:30</string>
484 </property>
485 </item>
486 <item>
487 <property>
488 <name>text</name>
489 <string>21:00</string>
490 </property>
491 </item>
492 <item>
493 <property>
494 <name>text</name>
495 <string>21:30</string>
496 </property>
497 </item>
498 <item>
499 <property>
500 <name>text</name>
501 <string>22:00</string>
502 </property>
503 </item>
504 <item>
505 <property>
506 <name>text</name>
507 <string>22:30</string>
508 </property>
509 </item>
510 <item>
511 <property>
512 <name>text</name>
513 <string>23:00</string>
514 </property>
515 </item>
516 <item>
517 <property>
518 <name>text</name>
519 <string>23:30</string>
520 </property>
521 </item>
522 <property stdset="1">
523 <name>name</name>
524 <cstring>comboStart</cstring>
525 </property>
526 <property stdset="1">
527 <name>editable</name>
528 <bool>true</bool>
529 </property>
530 <property stdset="1">
531 <name>duplicatesEnabled</name>
532 <bool>false</bool>
533 </property>
534 </widget>
535 <widget row="4" column="1" >
536 <class>QPushButton</class>
537 <property stdset="1">
538 <name>name</name>
539 <cstring>buttonEnd</cstring>
540 </property>
541 <property stdset="1">
542 <name>text</name>
543 <string>Jan 02 00</string>
544 </property>
545 </widget>
546 <widget row="4" column="2" rowspan="1" colspan="2" >
547 <class>QComboBox</class>
548 <item>
549 <property>
550 <name>text</name>
551 <string>00:00</string>
552 </property>
553 </item>
554 <item>
555 <property>
556 <name>text</name>
557 <string>00:30</string>
558 </property>
559 </item>
560 <item>
561 <property>
562 <name>text</name>
563 <string>01:00</string>
564 </property>
565 </item>
566 <item>
567 <property>
568 <name>text</name>
569 <string>01:30</string>
570 </property>
571 </item>
572 <item>
573 <property>
574 <name>text</name>
575 <string>02:00</string>
576 </property>
577 </item>
578 <item>
579 <property>
580 <name>text</name>
581 <string>02:30</string>
582 </property>
583 </item>
584 <item>
585 <property>
586 <name>text</name>
587 <string>03:00</string>
588 </property>
589 </item>
590 <item>
591 <property>
592 <name>text</name>
593 <string>03:30</string>
594 </property>
595 </item>
596 <item>
597 <property>
598 <name>text</name>
599 <string>04:00</string>
600 </property>
601 </item>
602 <item>
603 <property>
604 <name>text</name>
605 <string>04:30</string>
606 </property>
607 </item>
608 <item>
609 <property>
610 <name>text</name>
611 <string>05:00</string>
612 </property>
613 </item>
614 <item>
615 <property>
616 <name>text</name>
617 <string>05:30</string>
618 </property>
619 </item>
620 <item>
621 <property>
622 <name>text</name>
623 <string>06:00</string>
624 </property>
625 </item>
626 <item>
627 <property>
628 <name>text</name>
629 <string>06:30</string>
630 </property>
631 </item>
632 <item>
633 <property>
634 <name>text</name>
635 <string>07:00</string>
636 </property>
637 </item>
638 <item>
639 <property>
640 <name>text</name>
641 <string>07:30</string>
642 </property>
643 </item>
644 <item>
645 <property>
646 <name>text</name>
647 <string>08:00</string>
648 </property>
649 </item>
650 <item>
651 <property>
652 <name>text</name>
653 <string>08:30</string>
654 </property>
655 </item>
656 <item>
657 <property>
658 <name>text</name>
659 <string>09:00</string>
660 </property>
661 </item>
662 <item>
663 <property>
664 <name>text</name>
665 <string>09:30</string>
666 </property>
667 </item>
668 <item>
669 <property>
670 <name>text</name>
671 <string>10:00</string>
672 </property>
673 </item>
674 <item>
675 <property>
676 <name>text</name>
677 <string>10:30</string>
678 </property>
679 </item>
680 <item>
681 <property>
682 <name>text</name>
683 <string>11:00</string>
684 </property>
685 </item>
686 <item>
687 <property>
688 <name>text</name>
689 <string>11:30</string>
690 </property>
691 </item>
692 <item>
693 <property>
694 <name>text</name>
695 <string>12:00</string>
696 </property>
697 </item>
698 <item>
699 <property>
700 <name>text</name>
701 <string>12:30</string>
702 </property>
703 </item>
704 <item>
705 <property>
706 <name>text</name>
707 <string>13:00</string>
708 </property>
709 </item>
710 <item>
711 <property>
712 <name>text</name>
713 <string>13:30</string>
714 </property>
715 </item>
716 <item>
717 <property>
718 <name>text</name>
719 <string>14:00</string>
720 </property>
721 </item>
722 <item>
723 <property>
724 <name>text</name>
725 <string>14:30</string>
726 </property>
727 </item>
728 <item>
729 <property>
730 <name>text</name>
731 <string>15:00</string>
732 </property>
733 </item>
734 <item>
735 <property>
736 <name>text</name>
737 <string>15:30</string>
738 </property>
739 </item>
740 <item>
741 <property>
742 <name>text</name>
743 <string>16:00</string>
744 </property>
745 </item>
746 <item>
747 <property>
748 <name>text</name>
749 <string>16:30</string>
750 </property>
751 </item>
752 <item>
753 <property>
754 <name>text</name>
755 <string>17:00</string>
756 </property>
757 </item>
758 <item>
759 <property>
760 <name>text</name>
761 <string>17:30</string>
762 </property>
763 </item>
764 <item>
765 <property>
766 <name>text</name>
767 <string>18:00</string>
768 </property>
769 </item>
770 <item>
771 <property>
772 <name>text</name>
773 <string>18:30</string>
774 </property>
775 </item>
776 <item>
777 <property>
778 <name>text</name>
779 <string>19:00</string>
780 </property>
781 </item>
782 <item>
783 <property>
784 <name>text</name>
785 <string>19:30</string>
786 </property>
787 </item>
788 <item>
789 <property>
790 <name>text</name>
791 <string>20:00</string>
792 </property>
793 </item>
794 <item>
795 <property>
796 <name>text</name>
797 <string>20:30</string>
798 </property>
799 </item>
800 <item>
801 <property>
802 <name>text</name>
803 <string>21:00</string>
804 </property>
805 </item>
806 <item>
807 <property>
808 <name>text</name>
809 <string>21:30</string>
810 </property>
811 </item>
812 <item>
813 <property>
814 <name>text</name>
815 <string>22:00</string>
816 </property>
817 </item>
818 <item>
819 <property>
820 <name>text</name>
821 <string>22:30</string>
822 </property>
823 </item>
824 <item>
825 <property>
826 <name>text</name>
827 <string>23:00</string>
828 </property>
829 </item>
830 <item>
831 <property>
832 <name>text</name>
833 <string>23:30</string>
834 </property>
835 </item>
836 <property stdset="1">
837 <name>name</name>
838 <cstring>comboEnd</cstring>
839 </property>
840 <property stdset="1">
841 <name>editable</name>
842 <bool>true</bool>
843 </property>
844 <property stdset="1">
845 <name>duplicatesEnabled</name>
846 <bool>false</bool>
847 </property>
848 </widget>
849 <widget row="4" column="0" >
850 <class>QLabel</class>
851 <property stdset="1">
852 <name>name</name>
853 <cstring>TextLabel3_2</cstring>
854 </property>
855 <property stdset="1">
856 <name>text</name>
857 <string>End</string>
858 </property>
859 </widget>
860 <widget row="5" column="0" >
861 <class>QCheckBox</class>
862 <property stdset="1">
863 <name>name</name>
864 <cstring>checkAllDay</cstring>
865 </property>
866 <property stdset="1">
867 <name>text</name>
868 <string>All day</string>
869 </property>
870 </widget>
871 <widget row="6" column="0" >
872 <class>QLabel</class>
873 <property stdset="1">
874 <name>name</name>
875 <cstring>TextLabel3_2_2</cstring>
876 </property>
877 <property stdset="1">
878 <name>text</name>
879 <string>Time zone:</string>
880 </property>
881 </widget>
882 <widget row="6" column="1" rowspan="1" colspan="3" >
883 <class>TimeZoneSelector</class>
884 <property stdset="1">
885 <name>name</name>
886 <cstring>timezone</cstring>
887 </property>
888 </widget>
889 <widget row="7" column="0" >
890 <class>QCheckBox</class>
891 <property stdset="1">
892 <name>name</name>
893 <cstring>checkAlarm</cstring>
894 </property>
895 <property stdset="1">
896 <name>enabled</name>
897 <bool>true</bool>
898 </property>
899 <property stdset="1">
900 <name>autoMask</name>
901 <bool>false</bool>
902 </property>
903 <property stdset="1">
904 <name>text</name>
905 <string>&amp;Alarm</string>
906 </property>
907 <property stdset="1">
908 <name>checked</name>
909 <bool>false</bool>
910 </property>
911 </widget>
912 <widget row="7" column="1" rowspan="1" colspan="2" >
913 <class>QSpinBox</class>
914 <property stdset="1">
915 <name>name</name>
916 <cstring>spinAlarm</cstring>
917 </property>
918 <property stdset="1">
919 <name>enabled</name>
920 <bool>false</bool>
921 </property>
922 <property stdset="1">
923 <name>suffix</name>
924 <string> minutes</string>
925 </property>
926 <property stdset="1">
927 <name>maxValue</name>
928 <number>180</number>
929 </property>
930 <property stdset="1">
931 <name>minValue</name>
932 <number>0</number>
933 </property>
934 <property stdset="1">
935 <name>lineStep</name>
936 <number>5</number>
937 </property>
938 <property stdset="1">
939 <name>value</name>
940 <number>5</number>
941 </property>
942 </widget>
943 <widget row="7" column="3" >
944 <class>QComboBox</class>
945 <item>
946 <property>
947 <name>text</name>
948 <string>Silent</string>
949 </property>
950 </item>
951 <item>
952 <property>
953 <name>text</name>
954 <string>Loud</string>
955 </property>
956 </item>
957 <property stdset="1">
958 <name>name</name>
959 <cstring>comboSound</cstring>
960 </property>
961 <property stdset="1">
962 <name>enabled</name>
963 <bool>false</bool>
964 </property>
965 </widget>
966 <widget row="8" column="0" >
967 <class>QLabel</class>
968 <property stdset="1">
969 <name>name</name>
970 <cstring>lblRepeat</cstring>
971 </property>
972 <property stdset="1">
973 <name>text</name>
974 <string>Repeat</string>
975 </property>
976 </widget>
977 <widget row="8" column="1" rowspan="1" colspan="3" >
978 <class>QToolButton</class>
979 <property stdset="1">
980 <name>name</name>
981 <cstring>cmdRepeat</cstring>
982 </property>
983 <property stdset="1">
984 <name>focusPolicy</name>
985 <enum>TabFocus</enum>
986 </property>
987 <property stdset="1">
988 <name>text</name>
989 <string>No Repeat...</string>
990 </property>
991 </widget>
992 <widget row="9" column="0" rowspan="1" colspan="4" >
993 <class>QMultiLineEdit</class>
994 <property stdset="1">
995 <name>name</name>
996 <cstring>editNote</cstring>
997 </property>
998 </widget>
999 </grid>
1000</widget>
1001<customwidgets>
1002 <customwidget>
1003 <class>TimeZoneSelector</class>
1004 <header location="global">qpe/tzselect.h</header>
1005 <sizehint>
1006 <width>21</width>
1007 <height>10</height>
1008 </sizehint>
1009 <container>0</container>
1010 <sizepolicy>
1011 <hordata>7</hordata>
1012 <verdata>1</verdata>
1013 </sizepolicy>
1014 <pixmap>image0</pixmap>
1015 </customwidget>
1016 <customwidget>
1017 <class>CategorySelect</class>
1018 <header location="global">qpe/categoryselect.h</header>
1019 <sizehint>
1020 <width>-1</width>
1021 <height>-1</height>
1022 </sizehint>
1023 <container>0</container>
1024 <sizepolicy>
1025 <hordata>7</hordata>
1026 <verdata>1</verdata>
1027 </sizepolicy>
1028 <pixmap>image1</pixmap>
1029 </customwidget>
1030</customwidgets>
1031<images>
1032 <image>
1033 <name>image0</name>
1034 <data format="XPM.GZ" length="45">789cd3d7528808f055d0d2e72a2e492cc94c5648ce482c52d04a29cdcdad8c8eb5ade6523250004143a55a6b2e0026630c4f</data>
1035 </image>
1036 <image>
1037 <name>image1</name>
1038 <data format="XPM.GZ" length="646">789c6dd2c10ac2300c00d07bbf2234b7229d1be245fc04c5a3201e4615f430059d0711ff5ddb2e6bb236ec90eed134cb5a19d8ef36602af5ecdbfeeac05dda0798d3abebde87e3faa374d3807fa0d633a52d38d8de6f679fe33fc776e196f53cd010188256a3600a292882096246517815ca99884606e18044a3a40d91824820924265a7923a2e8bcd05f33db1173e002913175f2a6be6d3294871a2d95fa00e8a94ee017b69d339d90df1e77c57ea072ede6758</data>
1039 </image>
1040</images>
1041<connections>
1042 <connection>
1043 <sender>checkAlarm</sender>
1044 <signal>toggled(bool)</signal>
1045 <receiver>spinAlarm</receiver>
1046 <slot>setEnabled(bool)</slot>
1047 </connection>
1048 <connection>
1049 <sender>comboEnd</sender>
1050 <signal>activated(const QString&amp;)</signal>
1051 <receiver>DateEntryBase</receiver>
1052 <slot>endTimeChanged( const QString &amp; )</slot>
1053 </connection>
1054 <connection>
1055 <sender>cmdRepeat</sender>
1056 <signal>clicked()</signal>
1057 <receiver>DateEntryBase</receiver>
1058 <slot>slotRepeat()</slot>
1059 </connection>
1060 <connection>
1061 <sender>comboStart</sender>
1062 <signal>activated(int)</signal>
1063 <receiver>DateEntryBase</receiver>
1064 <slot>startTimeChanged( int )</slot>
1065 </connection>
1066 <connection>
1067 <sender>checkAllDay</sender>
1068 <signal>toggled(bool)</signal>
1069 <receiver>comboEnd</receiver>
1070 <slot>setDisabled(bool)</slot>
1071 </connection>
1072 <connection>
1073 <sender>checkAlarm</sender>
1074 <signal>toggled(bool)</signal>
1075 <receiver>comboSound</receiver>
1076 <slot>setEnabled(bool)</slot>
1077 </connection>
1078 <connection>
1079 <sender>checkAllDay</sender>
1080 <signal>toggled(bool)</signal>
1081 <receiver>comboStart</receiver>
1082 <slot>setDisabled(bool)</slot>
1083 </connection>
1084 <slot access="public">endDateChanged( const QString &amp; )</slot>
1085 <slot access="public">endDateChanged( int, int, int )</slot>
1086 <slot access="public">endTimeChanged( const QString &amp; )</slot>
1087 <slot access="public">slotRepeat()</slot>
1088 <slot access="public">slotWait( int )</slot>
1089 <slot access="public">startDateChanged( const QString &amp; )</slot>
1090 <slot access="public">startDateChanged(int, int, int)</slot>
1091 <slot access="public">startTimeChanged( int )</slot>
1092 <slot access="public">typeChanged( const QString &amp; )</slot>
1093 <slot access="public">tzexecute(void)</slot>
1094</connections>
1095</UI>
diff --git a/core/pim/datebook/dateentryimpl.cpp b/core/pim/datebook/dateentryimpl.cpp
new file mode 100644
index 0000000..1122f79
--- a/dev/null
+++ b/core/pim/datebook/dateentryimpl.cpp
@@ -0,0 +1,474 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia 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 "dateentryimpl.h"
22#include "repeatentry.h"
23
24#include <qpe/qpeapplication.h>
25#include <qpe/categoryselect.h>
26#include <qpe/datebookmonth.h>
27#include <qpe/global.h>
28#include <qpe/timeconversion.h>
29#include <qpe/timestring.h>
30#include <qpe/tzselect.h>
31
32#include <qcheckbox.h>
33#include <qcombobox.h>
34#include <qlayout.h>
35#include <qlineedit.h>
36#include <qmultilineedit.h>
37#include <qpopupmenu.h>
38#include <qscrollview.h>
39#include <qspinbox.h>
40#include <qtoolbutton.h>
41
42#include <stdlib.h>
43
44/*
45 * Constructs a DateEntry which is a child of 'parent', with the
46 * name 'name' and widget flags set to 'f'
47 *
48 * The dialog will by default be modeless, unless you set 'modal' to
49 * TRUE to construct a modal dialog.
50 */
51
52DateEntry::DateEntry( bool startOnMonday, const QDateTime &start,
53 const QDateTime &end, bool whichClock, QWidget* parent,
54 const char* name )
55 : DateEntryBase( parent, name ),
56 ampm( whichClock ),
57 startWeekOnMonday( startOnMonday )
58{
59 init();
60 setDates(start,end);
61}
62
63static void addOrPick( QComboBox* combo, const QString& t )
64{
65 for (int i=0; i<combo->count(); i++) {
66 if ( combo->text(i) == t ) {
67 combo->setCurrentItem(i);
68 return;
69 }
70 }
71 combo->setEditText(t);
72}
73
74DateEntry::DateEntry( bool startOnMonday, const Event &event, bool whichClock,
75 QWidget* parent, const char* name )
76 : DateEntryBase( parent, name ),
77 ampm( whichClock ),
78 startWeekOnMonday( startOnMonday )
79{
80 init();
81 setDates(event.start(),event.end());
82 comboCategory->setCategories( event.categories(), "Calendar", tr("Calendar") );
83 if(!event.description().isEmpty())
84 addOrPick( comboDescription, event.description() );
85 if(!event.location().isEmpty())
86 addOrPick( comboLocation, event.location() );
87 checkAlarm->setChecked( event.hasAlarm() );
88 checkAllDay->setChecked( event.type() == Event::AllDay );
89 if(!event.notes().isEmpty())
90 editNote->setText(event.notes());
91 spinAlarm->setValue(event.alarmTime());
92 if ( event.alarmSound() != Event::Silent )
93 comboSound->setCurrentItem( 1 );
94 if ( event.hasRepeat() ) {
95 rp = event.repeatPattern();
96 cmdRepeat->setText( tr("Repeat...") );
97 }
98 setRepeatLabel();
99}
100
101void DateEntry::setDates( const QDateTime& s, const QDateTime& e )
102{
103 int shour,
104 ehour;
105 QString strStart,
106 strEnd;
107 startDate = s.date();
108 endDate = e.date();
109 startTime = s.time();
110 endTime = e.time();
111 startDateChanged( s.date().year(), s.date().month(), s.date().day() );
112 if ( ampm ) {
113 shour = s.time().hour();
114 ehour = e.time().hour();
115 if ( shour >= 12 ) {
116 if ( shour > 12 )
117 shour -= 12;
118 strStart.sprintf( "%d:%02d PM", shour, s.time().minute() );
119 } else {
120 if ( shour == 0 )
121 shour = 12;
122 strStart.sprintf( "%d:%02d AM", shour, s.time().minute() );
123 }
124 if ( ehour == 24 && e.time().minute() == 0 ) {
125 strEnd = "11:59 PM"; // or "midnight"
126 } else if ( ehour >= 12 ) {
127 if ( ehour > 12 )
128 ehour -= 12;
129 strEnd.sprintf( "%d:%02d PM", ehour, e.time().minute() );
130 } else {
131 if ( ehour == 0 )
132 ehour = 12;
133 strEnd.sprintf( "%d:%02d AM", ehour, e.time().minute() );
134 }
135 } else {
136 strStart.sprintf( "%02d:%02d", s.time().hour(), s.time().minute() );
137 strEnd.sprintf( "%02d:%02d", e.time().hour(), e.time().minute() );
138 }
139 addOrPick(comboStart, strStart );
140 endDateChanged( e.date().year(), e.date().month(), e.date().day() );
141 addOrPick(comboEnd, strEnd );
142}
143
144void DateEntry::init()
145{
146 comboDescription->setInsertionPolicy(QComboBox::AtCurrent);
147 comboLocation->setInsertionPolicy(QComboBox::AtCurrent);
148
149 initCombos();
150 QPopupMenu *m1 = new QPopupMenu( this );
151 startPicker = new DateBookMonth( m1, 0, TRUE );
152 m1->insertItem( startPicker );
153 buttonStart->setPopup( m1 );
154 connect( startPicker, SIGNAL( dateClicked( int, int, int ) ),
155 this, SLOT( startDateChanged( int, int, int ) ) );
156
157 //Let start button change both start and end dates
158 connect( startPicker, SIGNAL( dateClicked( int, int, int ) ),
159 this, SLOT( endDateChanged( int, int, int ) ) );
160 connect( qApp, SIGNAL( clockChanged( bool ) ),
161 this, SLOT( slotChangeClock( bool ) ) );
162 connect( qApp, SIGNAL(weekChanged(bool)),
163 this, SLOT(slotChangeStartOfWeek(bool)) );
164
165 QPopupMenu *m2 = new QPopupMenu( this );
166 endPicker = new DateBookMonth( m2, 0, TRUE );
167 m2->insertItem( endPicker );
168 buttonEnd->setPopup( m2 );
169 connect( endPicker, SIGNAL( dateClicked( int, int, int ) ),
170 this, SLOT( endDateChanged( int, int, int ) ) );
171}
172
173/*
174 * Destroys the object and frees any allocated resources
175 */
176DateEntry::~DateEntry()
177{
178 // no need to delete child widgets, Qt does it all for us
179}
180
181/*
182 * public slot
183 */
184void DateEntry::endDateChanged( int y, int m, int d )
185{
186 endDate.setYMD( y, m, d );
187 if ( endDate < startDate ) {
188 endDate = startDate;
189 }
190
191 buttonEnd->setText( TimeString::shortDate( endDate ) );
192
193 endPicker->setDate( endDate.year(), endDate.month(), endDate.day() );
194}
195
196static QTime parseTime( const QString& s, bool ampm )
197{
198 QTime tmpTime;
199 QStringList l = QStringList::split( ':', s );
200 int hour = l[0].toInt();
201 if ( ampm ) {
202 int i=0;
203 while (i<int(l[1].length()) && l[1][i]>='0' && l[1][i]<='9')
204 i++;
205 QString digits = l[1].left(i);
206 if ( l[1].contains( "PM", FALSE ) ) {
207 if ( hour != 12 )
208 hour += 12;
209 } else {
210 if ( hour == 12 )
211 hour = 0;
212 }
213 l[1] = digits;
214 }
215 int minute = l[1].toInt();
216 if ( minute > 59 )
217 minute = 59;
218 else if ( minute < 0 )
219 minute = 0;
220 if ( hour > 23 ) {
221 hour = 23;
222 minute = 59;
223 } else if ( hour < 0 )
224 hour = 0;
225 tmpTime.setHMS( hour, minute, 0 );
226 return tmpTime;
227}
228
229/*
230 * public slot
231 */
232void DateEntry::endTimeChanged( const QString &s )
233{
234 QTime tmpTime = parseTime(s,ampm);
235 if ( endDate > startDate || tmpTime >= startTime ) {
236 endTime = tmpTime;
237 } else {
238 endTime = startTime;
239 comboEnd->setCurrentItem( comboStart->currentItem() );
240 }
241}
242
243/*
244 * public slot
245 */
246void DateEntry::startDateChanged( int y, int m, int d )
247{
248 QDate prev = startDate;
249 startDate.setYMD( y, m, d );
250 if ( rp.type == Event::Weekly &&
251 startDate.dayOfWeek() != prev.dayOfWeek() ) {
252 // if we change the start of a weekly repeating event
253 // set the repeating day appropriately
254 char mask = 1 << (prev.dayOfWeek()-1);
255 rp.days &= (~mask);
256 rp.days |= 1 << (startDate.dayOfWeek()-1);
257 }
258
259 buttonStart->setText( TimeString::shortDate( startDate ) );
260
261 // our pickers must be reset...
262 startPicker->setDate( y, m, d );
263 endPicker->setDate( y, m, d );
264}
265
266/*
267 * public slot
268 */
269void DateEntry::startTimeChanged( int index )
270{
271 startTime = parseTime(comboStart->text(index),ampm);
272 changeEndCombo( index );
273}
274/*
275 * public slot
276 */
277void DateEntry::typeChanged( const QString &s )
278{
279 bool b = s != "All Day";
280 buttonStart->setEnabled( b );
281 comboStart->setEnabled( b );
282 comboEnd->setEnabled( b );
283}
284/*
285 * public slot
286 */
287void DateEntry::changeEndCombo( int change )
288{
289 if ( change + 2 < comboEnd->count() )
290 change += 2;
291 comboEnd->setCurrentItem( change );
292 endTimeChanged( comboEnd->currentText() );
293}
294
295void DateEntry::slotRepeat()
296{
297 // Work around for compiler Bug..
298 RepeatEntry *e;
299
300 // it is better in my opinion to just grab this from the mother,
301 // since, this dialog doesn't need to keep track of it...
302 if ( rp.type != Event::NoRepeat )
303 e = new RepeatEntry( startWeekOnMonday, rp, startDate, this);
304 else
305 e = new RepeatEntry( startWeekOnMonday, startDate, this );
306
307#if defined(Q_WS_QWS) || defined(_WS_QWS_)
308 e->showMaximized();
309#endif
310 if ( e->exec() ) {
311 rp = e->repeatPattern();
312 setRepeatLabel();
313 }
314}
315
316void DateEntry::slotChangeStartOfWeek( bool onMonday )
317{
318 startWeekOnMonday = onMonday;
319}
320
321Event DateEntry::event()
322{
323 Event ev;
324 Event::SoundTypeChoice st;
325 ev.setDescription( comboDescription->currentText() );
326 ev.setLocation( comboLocation->currentText() );
327 ev.setCategories( comboCategory->currentCategories() );
328 ev.setType( checkAllDay->isChecked() ? Event::AllDay : Event::Normal );
329 if ( startDate > endDate ) {
330 QDate tmp = endDate;
331 endDate = startDate;
332 startDate = tmp;
333 }
334 startTime = parseTime( comboStart->currentText(), ampm );
335 endTime = parseTime( comboEnd->currentText(), ampm );
336 if ( startTime > endTime && endDate == startDate ) {
337 QTime tmp = endTime;
338 endTime = startTime;
339 startTime = tmp;
340 }
341 // don't set the time if theres no need too
342 if ( ev.type() == Event::AllDay ) {
343 startTime.setHMS( 0, 0, 0 );
344 endTime.setHMS( 23, 59, 59 );
345 }
346
347 // adjust start and end times based on timezone
348 QDateTime start( startDate, startTime );
349 QDateTime end( endDate, endTime );
350 time_t start_utc, end_utc;
351
352// qDebug( "tz: %s", timezone->currentZone().latin1() );
353
354 // get real timezone
355 QString realTZ;
356 realTZ = QString::fromLocal8Bit( getenv("TZ") );
357
358 // set timezone
359 if ( setenv( "TZ", timezone->currentZone(), true ) != 0 )
360 qWarning( "There was a problem setting the timezone." );
361
362 // convert to UTC based on selected TZ (calling tzset internally)
363 start_utc = TimeConversion::toUTC( start );
364 end_utc = TimeConversion::toUTC( end );
365
366 // done playing around... put it all back
367 unsetenv( "TZ" );
368 if ( !realTZ.isNull() )
369 if ( setenv( "TZ", realTZ, true ) != 0 )
370 qWarning( "There was a problem setting the timezone." );
371
372 // convert UTC to local time (calling tzset internally)
373 ev.setStart( TimeConversion::fromUTC( start_utc ) );
374 ev.setEnd( TimeConversion::fromUTC( end_utc ) );
375
376 // we only have one type of sound at the moment... LOUD!!!
377 if ( comboSound->currentItem() != 0 )
378 st = Event::Loud;
379 else
380 st = Event::Silent;
381 ev.setAlarm( checkAlarm->isChecked(), spinAlarm->value(), st );
382 if ( rp.type != Event::NoRepeat )
383 ev.setRepeat( TRUE, rp );
384 ev.setNotes( editNote->text() );
385 return ev;
386}
387
388void DateEntry::setRepeatLabel()
389{
390
391 switch( rp.type ) {
392 case Event::Daily:
393 cmdRepeat->setText( tr("Daily...") );
394 break;
395 case Event::Weekly:
396 cmdRepeat->setText( tr("Weekly...") );
397 break;
398 case Event::MonthlyDay:
399 case Event::MonthlyDate:
400 cmdRepeat->setText( tr("Monthly...") );
401 break;
402 case Event::Yearly:
403 cmdRepeat->setText( tr("Yearly...") );
404 break;
405 default:
406 cmdRepeat->setText( tr("No Repeat...") );
407 }
408}
409
410void DateEntry::setAlarmEnabled( bool alarmPreset, int presetTime, Event::SoundTypeChoice sound )
411{
412 checkAlarm->setChecked( alarmPreset );
413 spinAlarm->setValue( presetTime );
414 if ( sound != Event::Silent )
415 comboSound->setCurrentItem( 1 );
416 else
417 comboSound->setCurrentItem( 0 );
418}
419
420void DateEntry::initCombos()
421{
422 comboStart->clear();
423 comboEnd->clear();
424 if ( ampm ) {
425 for ( int i = 0; i < 24; i++ ) {
426 if ( i == 0 ) {
427 comboStart->insertItem( "12:00 AM" );
428 comboStart->insertItem( "12:30 AM" );
429 comboEnd->insertItem( "12:00 AM" );
430 comboEnd->insertItem( "12:30 AM" );
431 } else if ( i == 12 ) {
432 comboStart->insertItem( "12:00 PM" );
433 comboStart->insertItem( "12:30 PM" );
434 comboEnd->insertItem( "12:00 PM" );
435 comboEnd->insertItem( "12:30 PM" );
436 } else if ( i > 12 ) {
437 comboStart->insertItem( QString::number( i - 12 ) + ":00 PM" );
438 comboStart->insertItem( QString::number( i - 12 ) + ":30 PM" );
439 comboEnd->insertItem( QString::number( i - 12 ) + ":00 PM" );
440 comboEnd->insertItem( QString::number( i - 12 ) + ":30 PM" );
441 } else {
442 comboStart->insertItem( QString::number( i) + ":00 AM" );
443 comboStart->insertItem( QString::number( i ) + ":30 AM" );
444 comboEnd->insertItem( QString::number( i ) + ":00 AM" );
445 comboEnd->insertItem( QString::number( i ) + ":30 AM" );
446 }
447 }
448 } else {
449 for ( int i = 0; i < 24; i++ ) {
450 if ( i < 10 ) {
451 comboStart->insertItem( QString("0")
452 + QString::number(i) + ":00" );
453 comboStart->insertItem( QString("0")
454 + QString::number(i) + ":30" );
455 comboEnd->insertItem( QString("0")
456 + QString::number(i) + ":00" );
457 comboEnd->insertItem( QString("0")
458 + QString::number(i) + ":30" );
459 } else {
460 comboStart->insertItem( QString::number(i) + ":00" );
461 comboStart->insertItem( QString::number(i) + ":30" );
462 comboEnd->insertItem( QString::number(i) + ":00" );
463 comboEnd->insertItem( QString::number(i) + ":30" );
464 }
465 }
466 }
467}
468
469void DateEntry::slotChangeClock( bool whichClock )
470{
471 ampm = whichClock;
472 initCombos();
473 setDates( QDateTime( startDate, startTime ), QDateTime( endDate, endTime ) );
474}
diff --git a/core/pim/datebook/dateentryimpl.h b/core/pim/datebook/dateentryimpl.h
new file mode 100644
index 0000000..785af7a
--- a/dev/null
+++ b/core/pim/datebook/dateentryimpl.h
@@ -0,0 +1,71 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia 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 DATEENTRY_H
21#define DATEENTRY_H
22
23#include "dateentry.h"
24
25#include <qpe/event.h>
26
27#include <qdatetime.h>
28
29class DateBookMonth;
30
31class DateEntry : public DateEntryBase
32{
33 Q_OBJECT
34
35public:
36 DateEntry( bool startOnMonday, const QDateTime &start,
37 const QDateTime &end, bool whichClock = FALSE,
38 QWidget* parent = 0, const char* name = 0 );
39 DateEntry( bool startOnMonday, const Event &event, bool whichCLock = FALSE,
40 QWidget* parent = 0, const char* name = 0 );
41 ~DateEntry();
42
43 Event event();
44 void setAlarmEnabled( bool alarmPreset, int presetTime, Event::SoundTypeChoice );
45
46public slots:
47 void endDateChanged( int, int, int );
48 void endTimeChanged( const QString & );
49 void startDateChanged(int, int, int);
50 void startTimeChanged( int index );
51 void typeChanged( const QString & );
52 void changeEndCombo( int change );
53 void slotRepeat();
54 void slotChangeClock( bool );
55 void slotChangeStartOfWeek( bool );
56
57private:
58 void init();
59 void initCombos();
60 void setDates( const QDateTime& s, const QDateTime& e );
61 void setRepeatLabel();
62
63 DateBookMonth *startPicker, *endPicker;
64 QDate startDate, endDate;
65 QTime startTime, endTime;
66 Event::RepeatPattern rp;
67 bool ampm;
68 bool startWeekOnMonday;
69};
70
71#endif // DATEENTRY_H
diff --git a/core/pim/datebook/main.cpp b/core/pim/datebook/main.cpp
new file mode 100644
index 0000000..caa5fb6
--- a/dev/null
+++ b/core/pim/datebook/main.cpp
@@ -0,0 +1,38 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia 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 "datebook.h"
22#include <qpe/qpeapplication.h>
23
24
25int main( int argc, char **argv )
26{
27 QPEApplication a( argc, argv );
28
29 DateBook e;
30 QObject::connect( &a, SIGNAL( flush() ), &e, SLOT( flush() ) );
31 QObject::connect( &a, SIGNAL( reload() ), &e, SLOT( reload() ) );
32
33
34 e.setCaption( DateBook::tr("Calendar") );
35 a.showMainWidget(&e);
36
37 return a.exec();
38}
diff --git a/core/pim/datebook/qpe-datebook.control b/core/pim/datebook/qpe-datebook.control
new file mode 100644
index 0000000..c6ab81a
--- a/dev/null
+++ b/core/pim/datebook/qpe-datebook.control
@@ -0,0 +1,9 @@
1Files: bin/datebook apps/Applications/datebook.desktop
2Priority: optional
3Section: qpe/applications
4Maintainer: Warwick Allison <warwick@trolltech.com>
5Architecture: arm
6Version: $QPE_VERSION-3
7Depends: qpe-base ($QPE_VERSION)
8Description: A datebook/appointment manager
9 A datebook/appointment manager for the Qtopia environment.
diff --git a/core/pim/datebook/repeatentry.cpp b/core/pim/datebook/repeatentry.cpp
new file mode 100644
index 0000000..5637c4d
--- a/dev/null
+++ b/core/pim/datebook/repeatentry.cpp
@@ -0,0 +1,595 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia 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 "repeatentry.h"
22
23#include <qpe/datebookmonth.h>
24#include <qpe/qpeapplication.h>
25#include <qpe/timestring.h>
26
27#include <qbuttongroup.h>
28#include <qlabel.h>
29#include <qpopupmenu.h>
30#include <qspinbox.h>
31#include <qtoolbutton.h>
32
33#include <time.h>
34
35// Global Templates for use in setting up the repeat label...
36const QString strDayTemplate = QObject::tr("Every");
37const QString strYearTemplate = QObject::tr("%1 %2 every ");
38const QString strMonthDateTemplate = QObject::tr("The %1 every ");
39const QString strMonthDayTemplate = QObject::tr("The %1 %1 of every");
40const QString strWeekTemplate = QObject::tr("Every ");
41const QString dayLabel[] = { QObject::tr("Monday"),
42 QObject::tr("Tuesday"),
43 QObject::tr("Wednesday"),
44 QObject::tr("Thursday"),
45 QObject::tr("Friday"),
46 QObject::tr("Saturday"),
47 QObject::tr("Sunday") };
48
49
50 static QString numberPlacing( int x );// return the proper word format for
51 // x (1st, 2nd, etc)
52static int week( const QDate &dt ); // what week in the month is dt?
53
54RepeatEntry::RepeatEntry( bool startOnMonday,
55 const QDate &newStart, QWidget *parent,
56 const char *name, bool modal, WFlags fl )
57 : RepeatEntryBase( parent, name, modal, fl ),
58 start( newStart ),
59 currInterval( NONE ),
60 startWeekOnMonday( startOnMonday )
61{
62 init();
63 fraType->setButton( currInterval );
64 chkNoEnd->setChecked( TRUE );
65 setupNone();
66}
67
68RepeatEntry::RepeatEntry( bool startOnMonday, const Event::RepeatPattern &rp,
69 const QDate &startDate,
70 QWidget *parent, const char *name, bool modal,
71 WFlags fl )
72 : RepeatEntryBase( parent, name, modal, fl ),
73 start( startDate ),
74 end( rp.endDate() ),
75 startWeekOnMonday( startOnMonday )
76{
77 // do some stuff with the repeat pattern
78 init();
79 switch ( rp.type ) {
80 default:
81 case Event::NoRepeat:
82 currInterval = NONE;
83 setupNone();
84 break;
85 case Event::Daily:
86 currInterval = DAY;
87 setupDaily();
88 break;
89 case Event::Weekly:
90 currInterval = WEEK;
91 setupWeekly();
92 int day, buttons;
93 for ( day = 0x01, buttons = 0; buttons < 7;
94 day = day << 1, buttons++ ) {
95 if ( rp.days & day ) {
96 if ( startWeekOnMonday )
97 fraExtra->setButton( buttons );
98 else {
99 if ( buttons == 7 )
100 fraExtra->setButton( 0 );
101 else
102 fraExtra->setButton( buttons + 1 );
103 }
104 }
105 }
106 slotWeekLabel();
107 break;
108 case Event::MonthlyDay:
109 currInterval = MONTH;
110 setupMonthly();
111 fraExtra->setButton( 0 );
112 slotMonthLabel( 0 );
113 break;
114 case Event::MonthlyDate:
115 currInterval = MONTH;
116 setupMonthly();
117 fraExtra->setButton( 1 );
118 slotMonthLabel( 1 );
119 break;
120 case Event::Yearly:
121 currInterval = YEAR;
122 setupYearly();
123 break;
124 }
125 fraType->setButton( currInterval );
126 spinFreq->setValue( rp.frequency );
127 if ( !rp.hasEndDate ) {
128 cmdEnd->setText( RepeatEntryBase::tr("No End Date") );
129 chkNoEnd->setChecked( TRUE );
130 } else
131 cmdEnd->setText( TimeString::shortDate( end ) );
132}
133
134RepeatEntry::~RepeatEntry()
135{
136}
137
138Event::RepeatPattern RepeatEntry::repeatPattern()
139{
140 QListIterator<QToolButton> it( listRTypeButtons );
141 QListIterator<QToolButton> itExtra( listExtra );
142 Event::RepeatPattern rpTmp;
143 int i;
144 for ( i = 0; *it; ++it, i++ ) {
145 if ( (*it)->isOn() ) {
146 switch ( i ) {
147 case NONE:
148 rpTmp.type = Event::NoRepeat;
149 break;
150 case DAY:
151 rpTmp.type = Event::Daily;
152 break;
153 case WEEK:
154 rpTmp.type = Event::Weekly;
155 rpTmp.days = 0;
156 int day;
157 for ( day = 1; *itExtra; ++itExtra, day = day << 1 ) {
158 if ( (*itExtra)->isOn() ) {
159 if ( startWeekOnMonday )
160 rpTmp.days |= day;
161 else {
162 if ( day == 1 )
163 rpTmp.days |= Event::SUN;
164 else
165 rpTmp.days |= day >> 1;
166 }
167 }
168 }
169 break;
170 case MONTH:
171 if ( cmdExtra1->isOn() )
172 rpTmp.type = Event::MonthlyDay;
173 else if ( cmdExtra2->isOn() )
174 rpTmp.type = Event::MonthlyDate;
175 // figure out the montly day...
176 rpTmp.position = week( start );
177 break;
178 case YEAR:
179 rpTmp.type = Event::Yearly;
180 break;
181 }
182 break; // no need to keep looking!
183 }
184 }
185 rpTmp.frequency = spinFreq->value();
186 rpTmp.hasEndDate = !chkNoEnd->isChecked();
187 if ( rpTmp.hasEndDate ) {
188 rpTmp.setEndDate( end );
189 }
190 // timestamp it...
191 rpTmp.createTime = time( NULL );
192 return rpTmp;
193}
194
195void RepeatEntry::slotSetRType( int rtype )
196{
197 // now call the right function based on the type...
198 currInterval = static_cast<repeatButtons>(rtype);
199 switch ( currInterval ) {
200 case NONE:
201 setupNone();
202 break;
203 case DAY:
204 setupDaily();
205 break;
206 case WEEK:
207 setupWeekly();
208 slotWeekLabel();
209 break;
210 case MONTH:
211 setupMonthly();
212 cmdExtra2->setOn( TRUE );
213 slotMonthLabel( 1 );
214 break;
215 case YEAR:
216 setupYearly();
217 break;
218 }
219}
220
221void RepeatEntry::setupNone()
222{
223 lblRepeat->setText( tr("No Repeat") );
224 lblVar1->hide();
225 lblVar2->hide();
226 hideExtras();
227 cmdEnd->hide();
228 lblFreq->hide();
229 lblEvery->hide();
230 lblFreq->hide();
231 spinFreq->hide();
232 lblEnd->hide();
233 lblWeekVar->hide();
234}
235
236void RepeatEntry::setupDaily()
237{
238 hideExtras();
239 lblWeekVar->hide();
240 spinFreq->setValue( 1 );
241 lblFreq->setText( tr("day(s)") );
242 lblVar2->show();
243 showRepeatStuff();
244 lblRepeat->setText( strDayTemplate );
245 setupRepeatLabel( 1 );
246}
247
248void RepeatEntry::setupWeekly()
249{
250 // reshow the buttons...
251 fraExtra->setTitle( RepeatEntryBase::tr("Repeat On") );
252 fraExtra->setExclusive( FALSE );
253 fraExtra->show();
254 if ( startWeekOnMonday ) {
255 cmdExtra1->setText( RepeatEntryBase::tr("Mon") );
256 cmdExtra2->setText( RepeatEntryBase::tr("Tue") );
257 cmdExtra3->setText( RepeatEntryBase::tr("Wed") );
258 cmdExtra4->setText( RepeatEntryBase::tr("Thu") );
259 cmdExtra5->setText( RepeatEntryBase::tr("Fri") );
260 cmdExtra6->setText( RepeatEntryBase::tr("Sat") );
261 cmdExtra7->setText( RepeatEntryBase::tr("Sun") );
262 } else {
263 cmdExtra1->setText( RepeatEntryBase::tr("Sun") );
264 cmdExtra2->setText( RepeatEntryBase::tr("Mon") );
265 cmdExtra3->setText( RepeatEntryBase::tr("Tue") );
266 cmdExtra4->setText( RepeatEntryBase::tr("Wed") );
267 cmdExtra5->setText( RepeatEntryBase::tr("Thu") );
268 cmdExtra6->setText( RepeatEntryBase::tr("Fri") );
269 cmdExtra7->setText( RepeatEntryBase::tr("Sat") );
270 }
271 // I hope clustering these improve performance....
272 cmdExtra1->setOn( FALSE );
273 cmdExtra2->setOn( FALSE );
274 cmdExtra3->setOn( FALSE );
275 cmdExtra4->setOn( FALSE );
276 cmdExtra5->setOn( FALSE );
277 cmdExtra6->setOn( FALSE );
278 cmdExtra7->setOn( FALSE );
279
280 cmdExtra1->show();
281 cmdExtra2->show();
282 cmdExtra3->show();
283 cmdExtra4->show();
284 cmdExtra5->show();
285 cmdExtra6->show();
286 cmdExtra7->show();
287
288 lblWeekVar->show();
289 spinFreq->setValue( 1 );
290 // might as well set the day too...
291 if ( startWeekOnMonday ) {
292 fraExtra->setButton( start.dayOfWeek() - 1 );
293 } else {
294 fraExtra->setButton( start.dayOfWeek() % 7 );
295 }
296 lblFreq->setText( tr("week(s)") );
297 lblVar2->show();
298 showRepeatStuff();
299 setupRepeatLabel( 1 );
300}
301
302void RepeatEntry::setupMonthly()
303{
304 hideExtras();
305 lblWeekVar->hide();
306 fraExtra->setTitle( tr("Repeat By") );
307 fraExtra->setExclusive( TRUE );
308 fraExtra->show();
309 cmdExtra1->setText( tr("Day") );
310 cmdExtra1->show();
311 cmdExtra2->setText( tr("Date") );
312 cmdExtra2->show();
313 spinFreq->setValue( 1 );
314 lblFreq->setText( tr("month(s)") );
315 lblVar2->show();
316 showRepeatStuff();
317 setupRepeatLabel( 1 );
318}
319
320void RepeatEntry::setupYearly()
321{
322 hideExtras();
323 lblWeekVar->hide();
324 spinFreq->setValue( 1 );
325 lblFreq->setText( tr("year(s)") );
326 lblFreq->show();
327 lblFreq->show();
328 showRepeatStuff();
329 lblVar2->show();
330 QString strEvery = strYearTemplate.arg( start.monthName(start.month()) ).arg( numberPlacing(start.day()) );
331 lblRepeat->setText( strEvery );
332 setupRepeatLabel( 1 );
333
334}
335
336void RepeatEntry::init()
337{
338 QPopupMenu *m1 = new QPopupMenu( this );
339 repeatPicker = new DateBookMonth( m1, 0, TRUE );
340 m1->insertItem( repeatPicker );
341 cmdEnd->setPopup( m1 );
342 cmdEnd->setPopupDelay( 0 );
343
344 QObject::connect( repeatPicker, SIGNAL(dateClicked(int, int, int)),
345 this, SLOT(endDateChanged(int, int, int)) );
346 QObject::connect( qApp, SIGNAL(weekChanged(bool)),
347 this, SLOT(slotChangeStartOfWeek(bool)) );
348
349 listRTypeButtons.setAutoDelete( TRUE );
350 listRTypeButtons.append( cmdNone );
351 listRTypeButtons.append( cmdDay );
352 listRTypeButtons.append( cmdWeek );
353 listRTypeButtons.append( cmdMonth );
354 listRTypeButtons.append( cmdYear );
355
356 listExtra.setAutoDelete( TRUE );
357 listExtra.append( cmdExtra1 );
358 listExtra.append( cmdExtra2 );
359 listExtra.append( cmdExtra3 );
360 listExtra.append( cmdExtra4 );
361 listExtra.append( cmdExtra5 );
362 listExtra.append( cmdExtra6 );
363 listExtra.append( cmdExtra7 );
364}
365
366void RepeatEntry::slotNoEnd( bool unused )
367{
368 // if the item was toggled, then go ahead and set it to the maximum date
369 if ( unused ) {
370 end.setYMD( 3000, 12, 31 );
371 cmdEnd->setText( RepeatEntryBase::tr("No End Date") );
372 } else {
373 end = start;
374 cmdEnd->setText( TimeString::shortDate(end) );
375 }
376}
377
378void RepeatEntry::endDateChanged( int y, int m, int d )
379{
380 end.setYMD( y, m, d );
381 if ( end < start )
382 end = start;
383 cmdEnd->setText( TimeString::shortDate( end ) );
384 repeatPicker->setDate( end.year(), end.month(), end.day() );
385}
386
387void RepeatEntry::setupRepeatLabel( const QString &s )
388{
389 lblVar1->setText( s );
390}
391
392void RepeatEntry::setupRepeatLabel( int x )
393{
394 // change the spelling based on the value of x
395 QString strVar2;
396
397 if ( x > 1 )
398 lblVar1->show();
399 else
400 lblVar1->hide();
401
402 switch ( currInterval ) {
403 case NONE:
404 break;
405 case DAY:
406 if ( x > 1 )
407 strVar2 = tr( "days" );
408 else
409 strVar2 = tr( "day" );
410 break;
411 case WEEK:
412 if ( x > 1 )
413 strVar2 = tr( "weeks" );
414 else
415 strVar2 = tr( "week" );
416 break;
417 case MONTH:
418 if ( x > 1 )
419 strVar2 = RepeatEntryBase::tr( "months" );
420 else
421 strVar2 = tr( "month" );
422 break;
423 case YEAR:
424 if ( x > 1 )
425 strVar2 = RepeatEntryBase::tr( "years" );
426 else
427 strVar2 = tr( "year" );
428 break;
429 }
430 if ( !strVar2.isNull() )
431 lblVar2->setText( strVar2 );
432}
433
434void RepeatEntry::showRepeatStuff()
435{
436 cmdEnd->show();
437 chkNoEnd->show();
438 lblFreq->show();
439 lblEvery->show();
440 lblFreq->show();
441 spinFreq->show();
442 lblEnd->show();
443 lblRepeat->setText( RepeatEntryBase::tr("Every") );
444}
445
446void RepeatEntry::slotWeekLabel()
447{
448 QString str;
449 QListIterator<QToolButton> it( listExtra );
450 unsigned int i;
451 unsigned int keepMe;
452 bool bNeedCarriage = FALSE;
453 // don't do something we'll regret!!!
454 if ( currInterval != WEEK )
455 return;
456
457 if ( startWeekOnMonday )
458 keepMe = start.dayOfWeek() - 1;
459 else
460 keepMe = start.dayOfWeek() % 7;
461
462 QStringList list;
463 for ( i = 0; *it; ++it, i++ ) {
464 // a crazy check, if you are repeating weekly, the current day
465 // must be selected!!!
466 if ( i == keepMe && !( (*it)->isOn() ) )
467 (*it)->setOn( TRUE );
468 if ( (*it)->isOn() ) {
469 if ( startWeekOnMonday )
470 list.append( dayLabel[i] );
471 else {
472 if ( i == 0 )
473 list.append( dayLabel[6] );
474 else
475 list.append( dayLabel[i - 1] );
476 }
477 }
478 }
479 QStringList::Iterator itStr;
480 for ( i = 0, itStr = list.begin(); itStr != list.end(); ++itStr, i++ ) {
481 if ( i == 3 )
482 bNeedCarriage = TRUE;
483 else
484 bNeedCarriage = FALSE;
485 if ( str.isNull() )
486 str = *itStr;
487 else if ( i == list.count() - 1 ) {
488 if ( i < 2 )
489 str += tr(" and ") + *itStr;
490 else {
491 if ( bNeedCarriage )
492 str += tr( ",\nand " ) + *itStr;
493 else
494 str += tr( ", and " ) + *itStr;
495 }
496 } else {
497 if ( bNeedCarriage )
498 str += ",\n" + *itStr;
499 else
500 str += ", " + *itStr;
501 }
502 }
503 str = str.prepend( "on " );
504 lblWeekVar->setText( str );
505}
506
507void RepeatEntry::slotMonthLabel( int type )
508{
509 QString str;
510 if ( currInterval != MONTH || type > 1 )
511 return;
512 if ( type == 1 )
513 str = strMonthDateTemplate.arg( numberPlacing(start.day()) );
514 else
515 str = strMonthDayTemplate.arg( numberPlacing(week(start)))
516 .arg( dayLabel[start.dayOfWeek() - 1] );
517 lblRepeat->setText( str );
518}
519
520void RepeatEntry::slotChangeStartOfWeek( bool onMonday )
521{
522 startWeekOnMonday = onMonday;
523 // we need to make this unintrusive as possible...
524 int saveSpin = spinFreq->value();
525 char days = 0;
526 int day;
527 QListIterator<QToolButton> itExtra( listExtra );
528 for ( day = 1; *itExtra; ++itExtra, day = day << 1 ) {
529 if ( (*itExtra)->isOn() ) {
530 if ( !startWeekOnMonday )
531 days |= day;
532 else {
533 if ( day == 1 )
534 days |= Event::SUN;
535 else
536 days |= day >> 1;
537 }
538 }
539 }
540 setupWeekly();
541 spinFreq->setValue( saveSpin );
542 int buttons;
543 for ( day = 0x01, buttons = 0; buttons < 7;
544 day = day << 1, buttons++ ) {
545 if ( days & day ) {
546 if ( startWeekOnMonday )
547 fraExtra->setButton( buttons );
548 else {
549 if ( buttons == 7 )
550 fraExtra->setButton( 0 );
551 else
552 fraExtra->setButton( buttons + 1 );
553 }
554 }
555 }
556 slotWeekLabel();
557}
558
559static int week( const QDate &start )
560{
561 // figure out the week...
562 int stop = start.day(),
563 sentinel = start.dayOfWeek(),
564 dayOfWeek = QDate( start.year(), start.month(), 1 ).dayOfWeek(),
565 week = 1,
566 i;
567 for ( i = 1; i < stop; i++ ) {
568 if ( dayOfWeek++ == sentinel )
569 week++;
570 if ( dayOfWeek > 7 )
571 dayOfWeek = 0;
572 }
573 return week;
574}
575
576static QString numberPlacing( int x )
577{
578 // I hope this works in other languages besides english...
579 QString str = QString::number( x );
580 switch ( x % 10 ) {
581 case 1:
582 str += QWidget::tr( "st" );
583 break;
584 case 2:
585 str += QWidget::tr( "nd" );
586 break;
587 case 3:
588 str += QWidget::tr( "rd" );
589 break;
590 default:
591 str += QWidget::tr( "th" );
592 break;
593 }
594 return str;
595}
diff --git a/core/pim/datebook/repeatentry.h b/core/pim/datebook/repeatentry.h
new file mode 100644
index 0000000..949fecd
--- a/dev/null
+++ b/core/pim/datebook/repeatentry.h
@@ -0,0 +1,98 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia 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 REPEATENTRY_H
22#define REPEATENTRY_H
23
24#include "repeatentrybase.h"
25
26#include <qpe/event.h>
27
28#include <qcheckbox.h>
29#include <qbuttongroup.h>
30#include <qdatetime.h>
31#include <qlist.h>
32#include <qtoolbutton.h>
33
34class DateBookMonth;
35
36class RepeatEntry : public RepeatEntryBase
37{
38 Q_OBJECT
39public:
40 RepeatEntry( bool startOnMonday,
41 const QDate &start, QWidget *parent = 0, const char *name = 0,
42 bool modal = TRUE, WFlags fl = 0 );
43 RepeatEntry( bool startOnMonday,
44 const Event::RepeatPattern &rp, const QDate &start,
45 QWidget *parent = 0, const char *name = 0, bool modal = TRUE,
46 WFlags fl = 0 );
47 ~RepeatEntry();
48
49 Event::RepeatPattern repeatPattern();
50 QDate endDate() { return end; };
51
52public slots:
53 void slotSetRType( int );
54 void endDateChanged( int, int, int );
55 void slotNoEnd( bool unused );
56
57private slots:
58 void setupRepeatLabel( const QString& );
59 void setupRepeatLabel( int );
60 void slotWeekLabel();
61 void slotMonthLabel( int );
62 void slotChangeStartOfWeek( bool onMonday );
63
64private:
65 void setupNone();
66 void setupDaily();
67 void setupWeekly();
68 void setupMonthly();
69 void setupYearly();
70
71 enum repeatButtons { NONE, DAY, WEEK, MONTH, YEAR };
72 void init();
73 inline void hideExtras();
74 void showRepeatStuff();
75
76 QList<QToolButton> listRTypeButtons;
77 QList<QToolButton> listExtra;
78 QDate start; // only used in one spot...
79 QDate end;
80 repeatButtons currInterval;
81 bool startWeekOnMonday;
82 DateBookMonth *repeatPicker;
83};
84
85inline void RepeatEntry::hideExtras()
86{
87 // hide the extra buttons...
88 fraExtra->hide();
89 chkNoEnd->hide();
90 QListIterator<QToolButton> it( listExtra );
91 for ( ; *it; ++it ) {
92 (*it)->hide();
93 (*it)->setOn( FALSE );
94 }
95
96}
97
98#endif
diff --git a/core/pim/datebook/repeatentrybase.ui b/core/pim/datebook/repeatentrybase.ui
new file mode 100644
index 0000000..9621d74
--- a/dev/null
+++ b/core/pim/datebook/repeatentrybase.ui
@@ -0,0 +1,713 @@
1<!DOCTYPE UI><UI>
2<class>RepeatEntryBase</class>
3<comment>*********************************************************************
4** Copyright (C) 2000 Trolltech AS. All rights reserved.
5**
6** This file is part of Qtopia 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>RepeatEntryBase</cstring>
29 </property>
30 <property stdset="1">
31 <name>geometry</name>
32 <rect>
33 <x>0</x>
34 <y>0</y>
35 <width>250</width>
36 <height>309</height>
37 </rect>
38 </property>
39 <property stdset="1">
40 <name>caption</name>
41 <string>Repeating Event </string>
42 </property>
43 <property>
44 <name>layoutMargin</name>
45 </property>
46 <property>
47 <name>layoutSpacing</name>
48 </property>
49 <vbox>
50 <property stdset="1">
51 <name>margin</name>
52 <number>5</number>
53 </property>
54 <property stdset="1">
55 <name>spacing</name>
56 <number>1</number>
57 </property>
58 <widget>
59 <class>QButtonGroup</class>
60 <property stdset="1">
61 <name>name</name>
62 <cstring>fraType</cstring>
63 </property>
64 <property stdset="1">
65 <name>frameShape</name>
66 <enum>NoFrame</enum>
67 </property>
68 <property stdset="1">
69 <name>frameShadow</name>
70 <enum>Sunken</enum>
71 </property>
72 <property stdset="1">
73 <name>title</name>
74 <string></string>
75 </property>
76 <property stdset="1">
77 <name>exclusive</name>
78 <bool>true</bool>
79 </property>
80 <property>
81 <name>layoutMargin</name>
82 </property>
83 <property>
84 <name>layoutSpacing</name>
85 </property>
86 <hbox>
87 <property stdset="1">
88 <name>margin</name>
89 <number>5</number>
90 </property>
91 <property stdset="1">
92 <name>spacing</name>
93 <number>1</number>
94 </property>
95 <widget>
96 <class>QToolButton</class>
97 <property stdset="1">
98 <name>name</name>
99 <cstring>cmdNone</cstring>
100 </property>
101 <property stdset="1">
102 <name>text</name>
103 <string>None</string>
104 </property>
105 <property stdset="1">
106 <name>toggleButton</name>
107 <bool>true</bool>
108 </property>
109 <property stdset="1">
110 <name>toggleButton</name>
111 <bool>true</bool>
112 </property>
113 </widget>
114 <widget>
115 <class>QToolButton</class>
116 <property stdset="1">
117 <name>name</name>
118 <cstring>cmdDay</cstring>
119 </property>
120 <property stdset="1">
121 <name>text</name>
122 <string>Day</string>
123 </property>
124 <property stdset="1">
125 <name>toggleButton</name>
126 <bool>true</bool>
127 </property>
128 <property stdset="1">
129 <name>toggleButton</name>
130 <bool>true</bool>
131 </property>
132 </widget>
133 <widget>
134 <class>QToolButton</class>
135 <property stdset="1">
136 <name>name</name>
137 <cstring>cmdWeek</cstring>
138 </property>
139 <property stdset="1">
140 <name>sizePolicy</name>
141 <sizepolicy>
142 <hsizetype>1</hsizetype>
143 <vsizetype>0</vsizetype>
144 </sizepolicy>
145 </property>
146 <property stdset="1">
147 <name>text</name>
148 <string>Week</string>
149 </property>
150 <property stdset="1">
151 <name>toggleButton</name>
152 <bool>true</bool>
153 </property>
154 <property stdset="1">
155 <name>toggleButton</name>
156 <bool>true</bool>
157 </property>
158 </widget>
159 <widget>
160 <class>QToolButton</class>
161 <property stdset="1">
162 <name>name</name>
163 <cstring>cmdMonth</cstring>
164 </property>
165 <property stdset="1">
166 <name>sizePolicy</name>
167 <sizepolicy>
168 <hsizetype>1</hsizetype>
169 <vsizetype>0</vsizetype>
170 </sizepolicy>
171 </property>
172 <property stdset="1">
173 <name>text</name>
174 <string>Month</string>
175 </property>
176 <property stdset="1">
177 <name>toggleButton</name>
178 <bool>true</bool>
179 </property>
180 <property stdset="1">
181 <name>toggleButton</name>
182 <bool>true</bool>
183 </property>
184 </widget>
185 <widget>
186 <class>QToolButton</class>
187 <property stdset="1">
188 <name>name</name>
189 <cstring>cmdYear</cstring>
190 </property>
191 <property stdset="1">
192 <name>text</name>
193 <string>Year</string>
194 </property>
195 <property stdset="1">
196 <name>toggleButton</name>
197 <bool>true</bool>
198 </property>
199 <property stdset="1">
200 <name>toggleButton</name>
201 <bool>true</bool>
202 </property>
203 </widget>
204 </hbox>
205 </widget>
206 <widget>
207 <class>QLayoutWidget</class>
208 <property stdset="1">
209 <name>name</name>
210 <cstring>Layout4</cstring>
211 </property>
212 <hbox>
213 <property stdset="1">
214 <name>margin</name>
215 <number>0</number>
216 </property>
217 <property stdset="1">
218 <name>spacing</name>
219 <number>6</number>
220 </property>
221 <widget>
222 <class>QLabel</class>
223 <property stdset="1">
224 <name>name</name>
225 <cstring>lblEvery</cstring>
226 </property>
227 <property stdset="1">
228 <name>text</name>
229 <string>Every:</string>
230 </property>
231 </widget>
232 <widget>
233 <class>QSpinBox</class>
234 <property stdset="1">
235 <name>name</name>
236 <cstring>spinFreq</cstring>
237 </property>
238 <property stdset="1">
239 <name>minValue</name>
240 <number>1</number>
241 </property>
242 </widget>
243 <widget>
244 <class>QLabel</class>
245 <property stdset="1">
246 <name>name</name>
247 <cstring>lblFreq</cstring>
248 </property>
249 <property stdset="1">
250 <name>sizePolicy</name>
251 <sizepolicy>
252 <hsizetype>1</hsizetype>
253 <vsizetype>1</vsizetype>
254 </sizepolicy>
255 </property>
256 <property stdset="1">
257 <name>text</name>
258 <string>Frequency</string>
259 </property>
260 </widget>
261 </hbox>
262 </widget>
263 <widget>
264 <class>QLayoutWidget</class>
265 <property stdset="1">
266 <name>name</name>
267 <cstring>Layout8</cstring>
268 </property>
269 <hbox>
270 <property stdset="1">
271 <name>margin</name>
272 <number>0</number>
273 </property>
274 <property stdset="1">
275 <name>spacing</name>
276 <number>6</number>
277 </property>
278 <widget>
279 <class>QLabel</class>
280 <property stdset="1">
281 <name>name</name>
282 <cstring>lblEnd</cstring>
283 </property>
284 <property stdset="1">
285 <name>sizePolicy</name>
286 <sizepolicy>
287 <hsizetype>1</hsizetype>
288 <vsizetype>0</vsizetype>
289 </sizepolicy>
290 </property>
291 <property stdset="1">
292 <name>text</name>
293 <string>End On:</string>
294 </property>
295 </widget>
296 <widget>
297 <class>QToolButton</class>
298 <property stdset="1">
299 <name>name</name>
300 <cstring>cmdEnd</cstring>
301 </property>
302 <property stdset="1">
303 <name>text</name>
304 <string>No End Date</string>
305 </property>
306 </widget>
307 <widget>
308 <class>QCheckBox</class>
309 <property stdset="1">
310 <name>name</name>
311 <cstring>chkNoEnd</cstring>
312 </property>
313 <property stdset="1">
314 <name>text</name>
315 <string>No End Date</string>
316 </property>
317 </widget>
318 </hbox>
319 </widget>
320 <widget>
321 <class>QButtonGroup</class>
322 <property stdset="1">
323 <name>name</name>
324 <cstring>fraExtra</cstring>
325 </property>
326 <property stdset="1">
327 <name>sizePolicy</name>
328 <sizepolicy>
329 <hsizetype>7</hsizetype>
330 <vsizetype>7</vsizetype>
331 </sizepolicy>
332 </property>
333 <property stdset="1">
334 <name>frameShape</name>
335 <enum>Box</enum>
336 </property>
337 <property stdset="1">
338 <name>title</name>
339 <string>Repeat On</string>
340 </property>
341 <property>
342 <name>layoutMargin</name>
343 </property>
344 <property>
345 <name>layoutSpacing</name>
346 </property>
347 <hbox>
348 <property stdset="1">
349 <name>margin</name>
350 <number>5</number>
351 </property>
352 <property stdset="1">
353 <name>spacing</name>
354 <number>1</number>
355 </property>
356 <widget>
357 <class>QToolButton</class>
358 <property stdset="1">
359 <name>name</name>
360 <cstring>cmdExtra1</cstring>
361 </property>
362 <property stdset="1">
363 <name>text</name>
364 <string>Mon</string>
365 </property>
366 <property stdset="1">
367 <name>toggleButton</name>
368 <bool>true</bool>
369 </property>
370 <property stdset="1">
371 <name>toggleButton</name>
372 <bool>true</bool>
373 </property>
374 </widget>
375 <widget>
376 <class>QToolButton</class>
377 <property stdset="1">
378 <name>name</name>
379 <cstring>cmdExtra2</cstring>
380 </property>
381 <property stdset="1">
382 <name>text</name>
383 <string>Tue</string>
384 </property>
385 <property stdset="1">
386 <name>toggleButton</name>
387 <bool>true</bool>
388 </property>
389 <property stdset="1">
390 <name>toggleButton</name>
391 <bool>true</bool>
392 </property>
393 </widget>
394 <widget>
395 <class>QToolButton</class>
396 <property stdset="1">
397 <name>name</name>
398 <cstring>cmdExtra3</cstring>
399 </property>
400 <property stdset="1">
401 <name>text</name>
402 <string>Wed</string>
403 </property>
404 <property stdset="1">
405 <name>toggleButton</name>
406 <bool>true</bool>
407 </property>
408 <property stdset="1">
409 <name>toggleButton</name>
410 <bool>true</bool>
411 </property>
412 </widget>
413 <widget>
414 <class>QToolButton</class>
415 <property stdset="1">
416 <name>name</name>
417 <cstring>cmdExtra4</cstring>
418 </property>
419 <property stdset="1">
420 <name>text</name>
421 <string>Thu</string>
422 </property>
423 <property stdset="1">
424 <name>toggleButton</name>
425 <bool>true</bool>
426 </property>
427 <property stdset="1">
428 <name>toggleButton</name>
429 <bool>true</bool>
430 </property>
431 </widget>
432 <widget>
433 <class>QToolButton</class>
434 <property stdset="1">
435 <name>name</name>
436 <cstring>cmdExtra5</cstring>
437 </property>
438 <property stdset="1">
439 <name>text</name>
440 <string>Fri</string>
441 </property>
442 <property stdset="1">
443 <name>toggleButton</name>
444 <bool>true</bool>
445 </property>
446 <property stdset="1">
447 <name>toggleButton</name>
448 <bool>true</bool>
449 </property>
450 </widget>
451 <widget>
452 <class>QToolButton</class>
453 <property stdset="1">
454 <name>name</name>
455 <cstring>cmdExtra6</cstring>
456 </property>
457 <property stdset="1">
458 <name>text</name>
459 <string>Sat</string>
460 </property>
461 <property stdset="1">
462 <name>toggleButton</name>
463 <bool>true</bool>
464 </property>
465 <property stdset="1">
466 <name>toggleButton</name>
467 <bool>true</bool>
468 </property>
469 </widget>
470 <widget>
471 <class>QToolButton</class>
472 <property stdset="1">
473 <name>name</name>
474 <cstring>cmdExtra7</cstring>
475 </property>
476 <property stdset="1">
477 <name>text</name>
478 <string>Sun</string>
479 </property>
480 <property stdset="1">
481 <name>toggleButton</name>
482 <bool>true</bool>
483 </property>
484 <property stdset="1">
485 <name>toggleButton</name>
486 <bool>true</bool>
487 </property>
488 </widget>
489 </hbox>
490 </widget>
491 <widget>
492 <class>QFrame</class>
493 <property stdset="1">
494 <name>name</name>
495 <cstring>Frame3</cstring>
496 </property>
497 <property stdset="1">
498 <name>sizePolicy</name>
499 <sizepolicy>
500 <hsizetype>7</hsizetype>
501 <vsizetype>7</vsizetype>
502 </sizepolicy>
503 </property>
504 <property stdset="1">
505 <name>frameShape</name>
506 <enum>Box</enum>
507 </property>
508 <property stdset="1">
509 <name>frameShadow</name>
510 <enum>Sunken</enum>
511 </property>
512 <property>
513 <name>layoutMargin</name>
514 </property>
515 <property>
516 <name>layoutSpacing</name>
517 </property>
518 <vbox>
519 <property stdset="1">
520 <name>margin</name>
521 <number>5</number>
522 </property>
523 <property stdset="1">
524 <name>spacing</name>
525 <number>1</number>
526 </property>
527 <widget>
528 <class>QLayoutWidget</class>
529 <property stdset="1">
530 <name>name</name>
531 <cstring>Layout6</cstring>
532 </property>
533 <property>
534 <name>layoutSpacing</name>
535 </property>
536 <hbox>
537 <property stdset="1">
538 <name>margin</name>
539 <number>0</number>
540 </property>
541 <property stdset="1">
542 <name>spacing</name>
543 <number>0</number>
544 </property>
545 <widget>
546 <class>QLabel</class>
547 <property stdset="1">
548 <name>name</name>
549 <cstring>lblRepeat</cstring>
550 </property>
551 <property stdset="1">
552 <name>sizePolicy</name>
553 <sizepolicy>
554 <hsizetype>1</hsizetype>
555 <vsizetype>3</vsizetype>
556 </sizepolicy>
557 </property>
558 <property stdset="1">
559 <name>text</name>
560 <string>Every</string>
561 </property>
562 <property stdset="1">
563 <name>alignment</name>
564 <set>AlignTop|AlignLeft</set>
565 </property>
566 <property>
567 <name>hAlign</name>
568 </property>
569 <property>
570 <name>vAlign</name>
571 </property>
572 </widget>
573 <widget>
574 <class>QLabel</class>
575 <property stdset="1">
576 <name>name</name>
577 <cstring>lblVar1</cstring>
578 </property>
579 <property stdset="1">
580 <name>sizePolicy</name>
581 <sizepolicy>
582 <hsizetype>1</hsizetype>
583 <vsizetype>1</vsizetype>
584 </sizepolicy>
585 </property>
586 <property stdset="1">
587 <name>text</name>
588 <string>Var1</string>
589 </property>
590 <property stdset="1">
591 <name>alignment</name>
592 <set>AlignTop|AlignLeft</set>
593 </property>
594 <property>
595 <name>hAlign</name>
596 </property>
597 <property>
598 <name>vAlign</name>
599 </property>
600 </widget>
601 <widget>
602 <class>QLabel</class>
603 <property stdset="1">
604 <name>name</name>
605 <cstring>lblVar2</cstring>
606 </property>
607 <property stdset="1">
608 <name>sizePolicy</name>
609 <sizepolicy>
610 <hsizetype>4</hsizetype>
611 <vsizetype>1</vsizetype>
612 </sizepolicy>
613 </property>
614 <property stdset="1">
615 <name>text</name>
616 <string>Var 2</string>
617 </property>
618 <property stdset="1">
619 <name>alignment</name>
620 <set>AlignTop|AlignRight</set>
621 </property>
622 <property>
623 <name>hAlign</name>
624 </property>
625 <property>
626 <name>vAlign</name>
627 </property>
628 </widget>
629 </hbox>
630 </widget>
631 <widget>
632 <class>QLabel</class>
633 <property stdset="1">
634 <name>name</name>
635 <cstring>lblWeekVar</cstring>
636 </property>
637 <property stdset="1">
638 <name>sizePolicy</name>
639 <sizepolicy>
640 <hsizetype>1</hsizetype>
641 <vsizetype>7</vsizetype>
642 </sizepolicy>
643 </property>
644 <property stdset="1">
645 <name>text</name>
646 <string>WeekVar</string>
647 </property>
648 <property stdset="1">
649 <name>alignment</name>
650 <set>AlignTop|AlignHCenter</set>
651 </property>
652 <property>
653 <name>hAlign</name>
654 </property>
655 <property>
656 <name>vAlign</name>
657 </property>
658 </widget>
659 </vbox>
660 </widget>
661 </vbox>
662</widget>
663<connections>
664 <connection>
665 <sender>chkNoEnd</sender>
666 <signal>toggled(bool)</signal>
667 <receiver>cmdEnd</receiver>
668 <slot>setDisabled(bool)</slot>
669 </connection>
670 <connection>
671 <sender>chkNoEnd</sender>
672 <signal>toggled(bool)</signal>
673 <receiver>RepeatEntryBase</receiver>
674 <slot>slotNoEnd(bool)</slot>
675 </connection>
676 <connection>
677 <sender>spinFreq</sender>
678 <signal>valueChanged(int)</signal>
679 <receiver>lblVar1</receiver>
680 <slot>setNum(int)</slot>
681 </connection>
682 <connection>
683 <sender>spinFreq</sender>
684 <signal>valueChanged(int)</signal>
685 <receiver>RepeatEntryBase</receiver>
686 <slot>setupRepeatLabel( int )</slot>
687 </connection>
688 <connection>
689 <sender>fraType</sender>
690 <signal>clicked(int)</signal>
691 <receiver>RepeatEntryBase</receiver>
692 <slot>slotSetRType( int )</slot>
693 </connection>
694 <connection>
695 <sender>fraExtra</sender>
696 <signal>clicked(int)</signal>
697 <receiver>RepeatEntryBase</receiver>
698 <slot>slotMonthLabel( int )</slot>
699 </connection>
700 <connection>
701 <sender>fraExtra</sender>
702 <signal>clicked(int)</signal>
703 <receiver>RepeatEntryBase</receiver>
704 <slot>slotWeekLabel()</slot>
705 </connection>
706 <slot access="public">setupRepeatLabel( const QString &amp; )</slot>
707 <slot access="public">setupRepeatLabel( int )</slot>
708 <slot access="public">slotMonthLabel( int )</slot>
709 <slot access="public">slotNoEnd(bool)</slot>
710 <slot access="public">slotSetRType( int )</slot>
711 <slot access="public">slotWeekLabel()</slot>
712</connections>
713</UI>
diff --git a/core/pim/todo/.cvsignore b/core/pim/todo/.cvsignore
new file mode 100644
index 0000000..5ed04d8
--- a/dev/null
+++ b/core/pim/todo/.cvsignore
@@ -0,0 +1,4 @@
1moc_*
2Makefile
3todoentry.h
4todoentry.cpp
diff --git a/core/pim/todo/Makefile.in b/core/pim/todo/Makefile.in
new file mode 100644
index 0000000..f3c5f0e
--- a/dev/null
+++ b/core/pim/todo/Makefile.in
@@ -0,0 +1,201 @@
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= todolist
22TARGET1 = lib$(TARGET).so.$(VER_MAJ)
23
24####### Files
25
26 HEADERS =mainwindow.h \
27 todotable.h \
28 todoentryimpl.h
29 SOURCES =main.cpp \
30 mainwindow.cpp \
31 todotable.cpp \
32 todoentryimpl.cpp
33 OBJECTS =main.o \
34 mainwindow.o \
35 todotable.o \
36 todoentryimpl.o \
37 todoentry.o
38INTERFACES = todoentry.ui
39UICDECLS = todoentry.h
40UICIMPLS = todoentry.cpp
41 SRCMOC =moc_mainwindow.cpp \
42 moc_todotable.cpp \
43 moc_todoentryimpl.cpp \
44 moc_todoentry.cpp
45 OBJMOC =moc_mainwindow.o \
46 moc_todotable.o \
47 moc_todoentryimpl.o \
48 moc_todoentry.o
49
50
51####### Implicit rules
52
53.SUFFIXES: .cpp .cxx .cc .C .c
54
55.cpp.o:
56 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
57
58.cxx.o:
59 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
60
61.cc.o:
62 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
63
64.C.o:
65 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
66
67.c.o:
68 $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
69
70####### Build rules
71
72
73all: $(DESTDIR)$(TARGET)
74
75$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
76 $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
77
78moc: $(SRCMOC)
79
80tmake:
81 tmake todo.pro
82
83clean:
84 -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
85 -rm -f *~ core
86 -rm -f allmoc.cpp
87
88####### Extension Modules
89
90listpromodules:
91 @echo
92
93listallmodules:
94 @echo
95
96listaddonpromodules:
97 @echo
98
99listaddonentmodules:
100 @echo
101
102
103REQUIRES=
104
105####### Sub-libraries
106
107
108###### Combined headers
109
110
111
112####### Compile
113
114main.o: main.cpp \
115 mainwindow.h \
116 $(QPEDIR)/include/qpe/qpeapplication.h
117
118mainwindow.o: mainwindow.cpp \
119 mainwindow.h \
120 todoentryimpl.h \
121 todoentry.h \
122 $(QPEDIR)/include/qpe/task.h \
123 $(QPEDIR)/include/qpe/palmtoprecord.h \
124 $(QPEDIR)/include/qpe/stringutil.h \
125 todotable.h \
126 $(QPEDIR)/include/qpe/categories.h \
127 $(QPEDIR)/include/qpe/qpeapplication.h \
128 $(QPEDIR)/include/qpe/config.h \
129 $(QPEDIR)/include/qpe/finddialog.h \
130 $(QPEDIR)/include/qpe/global.h \
131 $(QPEDIR)/include/qpe/ir.h \
132 $(QPEDIR)/include/qpe/qpemenubar.h \
133 $(QPEDIR)/include/qpe/qpemessagebox.h \
134 $(QPEDIR)/include/qpe/resource.h \
135 $(QPEDIR)/include/qpe/qpetoolbar.h
136
137todotable.o: todotable.cpp \
138 todotable.h \
139 $(QPEDIR)/include/qpe/categories.h \
140 $(QPEDIR)/include/qpe/task.h \
141 $(QPEDIR)/include/qpe/palmtoprecord.h \
142 $(QPEDIR)/include/qpe/stringutil.h \
143 $(QPEDIR)/include/qpe/categoryselect.h \
144 $(QPEDIR)/include/qpe/xmlreader.h
145
146todoentryimpl.o: todoentryimpl.cpp \
147 todoentryimpl.h \
148 todoentry.h \
149 $(QPEDIR)/include/qpe/task.h \
150 $(QPEDIR)/include/qpe/palmtoprecord.h \
151 $(QPEDIR)/include/qpe/stringutil.h \
152 $(QPEDIR)/include/qpe/categoryselect.h \
153 $(QPEDIR)/include/qpe/datebookmonth.h \
154 $(QPEDIR)/include/qpe/event.h \
155 $(QPEDIR)/include/qpe/global.h \
156 $(QPEDIR)/include/qpe/imageedit.h \
157 $(QPEDIR)/include/qpe/timestring.h
158
159todoentry.h: todoentry.ui
160 $(UIC) todoentry.ui -o $(INTERFACE_DECL_PATH)/todoentry.h
161
162todoentry.cpp: todoentry.ui
163 $(UIC) todoentry.ui -i todoentry.h -o todoentry.cpp
164
165todoentry.o: todoentry.cpp \
166 todoentry.h \
167 todoentry.ui
168
169moc_mainwindow.o: moc_mainwindow.cpp \
170 mainwindow.h
171
172moc_todotable.o: moc_todotable.cpp \
173 todotable.h \
174 $(QPEDIR)/include/qpe/categories.h \
175 $(QPEDIR)/include/qpe/task.h \
176 $(QPEDIR)/include/qpe/palmtoprecord.h \
177 $(QPEDIR)/include/qpe/stringutil.h
178
179moc_todoentryimpl.o: moc_todoentryimpl.cpp \
180 todoentryimpl.h \
181 todoentry.h \
182 $(QPEDIR)/include/qpe/task.h \
183 $(QPEDIR)/include/qpe/palmtoprecord.h \
184 $(QPEDIR)/include/qpe/stringutil.h
185
186moc_todoentry.o: moc_todoentry.cpp \
187 todoentry.h
188
189moc_mainwindow.cpp: mainwindow.h
190 $(MOC) mainwindow.h -o moc_mainwindow.cpp
191
192moc_todotable.cpp: todotable.h
193 $(MOC) todotable.h -o moc_todotable.cpp
194
195moc_todoentryimpl.cpp: todoentryimpl.h
196 $(MOC) todoentryimpl.h -o moc_todoentryimpl.cpp
197
198moc_todoentry.cpp: todoentry.h
199 $(MOC) todoentry.h -o moc_todoentry.cpp
200
201
diff --git a/core/pim/todo/main.cpp b/core/pim/todo/main.cpp
new file mode 100644
index 0000000..4e1c8a1
--- a/dev/null
+++ b/core/pim/todo/main.cpp
@@ -0,0 +1,36 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia 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 "mainwindow.h"
22
23#include <qpe/qpeapplication.h>
24
25int main( int argc, char **argv )
26{
27 QPEApplication a( argc, argv );
28
29 TodoWindow mw;
30 QObject::connect( &a, SIGNAL( flush() ), &mw, SLOT( flush() ) );
31 QObject::connect( &a, SIGNAL( reload() ), &mw, SLOT( reload() ) );
32
33 a.showMainWidget(&mw);
34
35 return a.exec();
36}
diff --git a/core/pim/todo/mainwindow.cpp b/core/pim/todo/mainwindow.cpp
new file mode 100644
index 0000000..fb85a09
--- a/dev/null
+++ b/core/pim/todo/mainwindow.cpp
@@ -0,0 +1,466 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia 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 "mainwindow.h"
22#include "todoentryimpl.h"
23#include "todotable.h"
24
25#include <qpe/qpeapplication.h>
26#include <qpe/config.h>
27#include <qpe/finddialog.h>
28#include <qpe/global.h>
29#include <qpe/ir.h>
30#include <qpe/qpemenubar.h>
31#include <qpe/qpemessagebox.h>
32#include <qpe/resource.h>
33#include <qpe/task.h>
34#include <qpe/qpetoolbar.h>
35
36#include <qaction.h>
37#include <qarray.h>
38#include <qdatastream.h>
39#include <qdatetime.h>
40#include <qfile.h>
41#include <qmessagebox.h>
42#include <qpopupmenu.h>
43
44#include <sys/stat.h>
45#include <sys/types.h>
46#include <fcntl.h>
47#include <unistd.h>
48
49#include <stdlib.h>
50
51static QString todolistXMLFilename()
52{
53 return Global::applicationFileName("todolist","todolist.xml");
54}
55
56static QString categoriesXMLFilename()
57{
58 return Global::applicationFileName("todolist","categories.xml");
59}
60
61TodoWindow::TodoWindow( QWidget *parent, const char *name, WFlags f = 0 ) :
62 QMainWindow( parent, name, f ), syncing(FALSE)
63{
64// QTime t;
65// t.start();
66
67 setCaption( tr("Todo") );
68 QString str;
69 table = new TodoTable( this );
70 table->setColumnWidth( 2, 10 );
71 table->setPaintingEnabled( FALSE );
72 table->setUpdatesEnabled( FALSE );
73 table->viewport()->setUpdatesEnabled( FALSE );
74
75 {
76 str = todolistXMLFilename();
77 if ( str.isNull() )
78 QMessageBox::critical( this,
79 tr("Out of Space"),
80 tr("Unable to create startup files\n"
81 "Free up some space\n"
82 "before you enter any data") );
83 else
84 table->load( str );
85 }
86
87 // repeat for categories...
88 str = categoriesXMLFilename();
89 if ( str.isNull() )
90 QMessageBox::critical( this,
91 tr( "Out of Space" ),
92 tr( "Unable to create startup files\n"
93 "Free up some space\n"
94 "before you enter any data") );
95
96 setCentralWidget( table );
97 setToolBarsMovable( FALSE );
98
99// qDebug("after load: t=%d", t.elapsed() );
100
101 Config config( "todo" );
102 config.setGroup( "View" );
103 bool complete = config.readBoolEntry( "ShowComplete", true );
104 table->setShowCompleted( complete );
105 QString category = config.readEntry( "Category", QString::null );
106 table->setShowCategory( category );
107
108 QPEToolBar *bar = new QPEToolBar( this );
109 bar->setHorizontalStretchable( TRUE );
110
111 QPEMenuBar *mb = new QPEMenuBar( bar );
112
113 catMenu = new QPopupMenu( this );
114 QPopupMenu *edit = new QPopupMenu( this );
115 contextMenu = new QPopupMenu( this );
116
117 bar = new QPEToolBar( this );
118
119 QAction *a = new QAction( tr( "New Task" ), Resource::loadPixmap( "new" ),
120 QString::null, 0, this, 0 );
121 connect( a, SIGNAL( activated() ),
122 this, SLOT( slotNew() ) );
123 a->addTo( bar );
124 a->addTo( edit );
125 a = new QAction( tr( "Edit" ), Resource::loadIconSet( "edit" ),
126 QString::null, 0, this, 0 );
127 connect( a, SIGNAL( activated() ),
128 this, SLOT( slotEdit() ) );
129 a->addTo( bar );
130 a->addTo( edit );
131 a->addTo( contextMenu );
132 a->setEnabled( FALSE );
133 editAction = a;
134 a = new QAction( tr( "Delete" ), Resource::loadIconSet( "trash" ),
135 QString::null, 0, this, 0 );
136 connect( a, SIGNAL( activated() ),
137 this, SLOT( slotDelete() ) );
138 a->addTo( bar );
139 a->addTo( edit );
140 a->addTo( contextMenu );
141 a->setEnabled( FALSE );
142 deleteAction = a;
143
144 if ( Ir::supported() ) {
145 a = new QAction( tr( "Beam" ), Resource::loadPixmap( "beam" ),
146 QString::null, 0, this, 0 );
147 connect( a, SIGNAL( activated() ),
148 this, SLOT( slotBeam() ) );
149 a->addTo( edit );
150 a->addTo( bar );
151 }
152
153 a = new QAction( tr( "Find" ), Resource::loadIconSet( "mag" ),
154 QString::null, 0, this, 0 );
155 connect( a, SIGNAL( activated() ),
156 this, SLOT( slotFind() ) );
157 a->addTo( bar );
158 a->addTo( edit );
159 if ( table->numRows() )
160 a->setEnabled( TRUE );
161 else
162 a->setEnabled( FALSE );
163
164 //a->setEnabled( FALSE );
165 findAction = a;
166// qDebug("mainwindow #2: t=%d", t.elapsed() );
167
168 completedAction = new QAction( QString::null, tr("Completed tasks"), 0, this, 0, TRUE );
169
170 catMenu->setCheckable( true );
171 populateCategories();
172
173 mb->insertItem( tr( "Task" ), edit );
174 mb->insertItem( tr( "View" ), catMenu );
175
176 resize( 200, 300 );
177 if ( table->numRows() > 0 )
178 currentEntryChanged( 0, 0 );
179 connect( table, SIGNAL( signalEdit() ),
180 this, SLOT( slotEdit() ) );
181 connect( table, SIGNAL(signalShowMenu(const QPoint &)),
182 this, SLOT( slotShowPopup(const QPoint &)) );
183
184// qDebug("mainwindow #3: t=%d", t.elapsed() );
185 table->updateVisible();
186 table->setUpdatesEnabled( TRUE );
187 table->setPaintingEnabled( TRUE );
188 table->viewport()->setUpdatesEnabled( TRUE );
189
190 connect( completedAction, SIGNAL( toggled(bool) ), this, SLOT( showCompleted(bool) ) );
191 connect( catMenu, SIGNAL(activated(int)), this, SLOT(setCategory(int)) );
192 connect( table, SIGNAL( currentChanged( int, int ) ),
193 this, SLOT( currentEntryChanged( int, int ) ) );
194
195// qDebug("done: t=%d", t.elapsed() );
196}
197
198void TodoWindow::slotNew()
199{
200 if(syncing) {
201 QMessageBox::warning(this, tr("Todo"),
202 tr("Can not edit data, currently syncing"));
203 return;
204 }
205
206 int id;
207 id = -1;
208 QArray<int> ids;
209 ids = table->currentEntry().categories();
210 if ( ids.count() )
211 id = ids[0];
212 NewTaskDialog e( id, this, 0, TRUE );
213
214 Task todo;
215
216#if defined(Q_WS_QWS) || defined(_WS_QWS_)
217 e.showMaximized();
218#endif
219 int ret = e.exec();
220
221 if ( ret == QDialog::Accepted ) {
222 table->setPaintingEnabled( false );
223 todo = e.todoEntry();
224 todo.assignUid();
225 table->addEntry( todo );
226 table->setPaintingEnabled( true );
227 findAction->setEnabled( TRUE );
228 }
229 // I'm afraid we must call this every time now, otherwise
230 // spend expensive time comparing all these strings...
231 populateCategories();
232}
233
234TodoWindow::~TodoWindow()
235{
236}
237
238void TodoWindow::slotDelete()
239{
240 if(syncing) {
241 QMessageBox::warning(this, tr("Todo"),
242 tr("Can not edit data, currently syncing"));
243 return;
244 }
245
246 if ( table->currentRow() == -1 )
247 return;
248
249 QString strName = table->text( table->currentRow(), 2 ).left( 30 );
250
251 if ( !QPEMessageBox::confirmDelete( this, tr( "Todo" ), strName ) )
252 return;
253
254
255
256 table->setPaintingEnabled( false );
257 table->removeCurrentEntry();
258 table->setPaintingEnabled( true );
259
260 if ( table->numRows() == 0 ) {
261 currentEntryChanged( -1, 0 );
262 findAction->setEnabled( FALSE );
263 }
264}
265
266void TodoWindow::slotEdit()
267{
268 if(syncing) {
269 QMessageBox::warning(this, tr("Todo"),
270 tr("Can not edit data, currently syncing"));
271 return;
272 }
273
274 Task todo = table->currentEntry();
275
276 NewTaskDialog e( todo, this, 0, TRUE );
277 e.setCaption( tr( "Edit Task" ) );
278
279#if defined(Q_WS_QWS) || defined(_WS_QWS_)
280 e.showMaximized();
281#endif
282 int ret = e.exec();
283
284 if ( ret == QDialog::Accepted ) {
285 table->setPaintingEnabled( false );
286 todo = e.todoEntry();
287 table->replaceCurrentEntry( todo );
288 table->setPaintingEnabled( true );
289 }
290 populateCategories();
291
292}
293
294void TodoWindow::slotShowPopup( const QPoint &p )
295{
296 contextMenu->popup( p );
297}
298
299void TodoWindow::showCompleted( bool s )
300{
301 if ( !table->isUpdatesEnabled() )
302 return;
303 table->setPaintingEnabled( false );
304 table->setShowCompleted( s );
305 table->setPaintingEnabled( true );
306}
307
308void TodoWindow::currentEntryChanged( int r, int )
309{
310 if ( r != -1 && table->rowHeight( r ) > 0 ) {
311 editAction->setEnabled( TRUE );
312 deleteAction->setEnabled( TRUE );
313 } else {
314 editAction->setEnabled( FALSE );
315 deleteAction->setEnabled( FALSE );
316 }
317}
318
319void TodoWindow::setCategory( int c )
320{
321 if ( c <= 0 ) return;
322 if ( !table->isUpdatesEnabled() )
323 return;
324 table->setPaintingEnabled( false );
325 for ( unsigned int i = 1; i < catMenu->count(); i++ )
326 catMenu->setItemChecked( i, c == (int)i );
327 if ( c == 1 ) {
328 table->setShowCategory( QString::null );
329 setCaption( tr("Todo") + " - " + tr( "All" ) );
330 } else if ( c == (int)catMenu->count() - 1 ) {
331 table->setShowCategory( tr( "Unfiled" ) );
332 setCaption( tr("Todo") + " - " + tr( "Unfiled" ) );
333 } else {
334 QString cat = table->categories()[c - 2];
335 table->setShowCategory( cat );
336 setCaption( tr("Todo") + " - " + cat );
337 }
338 table->setPaintingEnabled( true );
339}
340
341void TodoWindow::populateCategories()
342{
343 catMenu->clear();
344
345 completedAction->addTo( catMenu );
346 completedAction->setOn( table->showCompleted() );
347
348 int id,
349 rememberId;
350 id = 1;
351 catMenu->insertItem( tr( "All" ), id++ );
352// catMenu->insertSeparator();
353 QStringList categories = table->categories();
354 categories.append( tr( "Unfiled" ) );
355 for ( QStringList::Iterator it = categories.begin();
356 it != categories.end(); ++it ) {
357 catMenu->insertItem( *it, id );
358 if ( *it == table->showCategory() )
359 rememberId = id;
360 ++id;
361 }
362 if ( table->showCategory().isEmpty() )
363 setCategory( 1 );
364 else
365 setCategory( rememberId );
366}
367
368void TodoWindow::reload()
369{
370 table->clear();
371 table->load( todolistXMLFilename() );
372 syncing = FALSE;
373}
374
375void TodoWindow::flush()
376{
377 syncing = TRUE;
378 table->save( todolistXMLFilename() );
379}
380
381void TodoWindow::closeEvent( QCloseEvent *e )
382{
383 if(syncing) {
384 /* no need to save if in the middle of syncing */
385 e->accept();
386 return;
387 }
388
389 if ( table->save( todolistXMLFilename() ) ) {
390 e->accept();
391 // repeat for categories...
392 // if writing configs fail, it will emit an
393 // error, but I feel that it is "ok" for us to exit
394 // espically since we aren't told if the write succeeded...
395 Config config( "todo" );
396 config.setGroup( "View" );
397 config.writeEntry( "ShowComplete", table->showCompleted() );
398 config.writeEntry( "Category", table->showCategory() );
399 } else {
400 if ( QMessageBox::critical( this, tr("Out of space"),
401 tr("Todo was unable\n"
402 "to save your changes.\n"
403 "Free up some space\n"
404 "and try again.\n"
405 "\nQuit Anyway?"),
406 QMessageBox::Yes|QMessageBox::Escape,
407 QMessageBox::No|QMessageBox::Default)
408 != QMessageBox::No )
409 e->accept();
410 else
411 e->ignore();
412 }
413}
414
415void TodoWindow::slotFind()
416{
417 // put everything back to view all for searching...
418 if ( !catMenu->isItemChecked( 0 ) )
419 setCategory( 0 );
420
421 FindDialog dlg( "Todo List", this );
422 QObject::connect( &dlg,
423 SIGNAL(signalFindClicked(const QString &,
424 bool, bool, int)),
425 table,
426 SLOT(slotDoFind(const QString&, bool, bool, int)) );
427 QObject::connect( table, SIGNAL(signalNotFound()), &dlg,
428 SLOT(slotNotFound()) );
429 QObject::connect( table, SIGNAL(signalWrapAround()), &dlg,
430 SLOT(slotWrapAround()) );
431 dlg.exec();
432 if ( table->numSelections() )
433 table->clearSelection();
434 table->clearFindRow();
435}
436
437
438void TodoWindow::setDocument( const QString &filename )
439{
440 if ( filename.find(".vcs") != int(filename.length()) - 4 ) return;
441
442 QValueList<Task> tl = Task::readVCalendar( filename );
443 for( QValueList<Task>::Iterator it = tl.begin(); it != tl.end(); ++it ) {
444 table->addEntry( *it );
445 }
446}
447
448static const char * beamfile = "/tmp/obex/todo.vcs";
449
450void TodoWindow::slotBeam()
451{
452 unlink( beamfile ); // delete if exists
453 Task c = table->currentEntry();
454 mkdir("/tmp/obex/", 0755);
455 Task::writeVCalendar( beamfile, c );
456 Ir *ir = new Ir( this );
457 connect( ir, SIGNAL( done( Ir * ) ), this, SLOT( beamDone( Ir * ) ) );
458 QString description = c.description();
459 ir->send( beamfile, description, "text/x-vCalendar" );
460}
461
462void TodoWindow::beamDone( Ir *ir )
463{
464 delete ir;
465 unlink( beamfile );
466}
diff --git a/core/pim/todo/mainwindow.h b/core/pim/todo/mainwindow.h
new file mode 100644
index 0000000..f4fcd1b
--- a/dev/null
+++ b/core/pim/todo/mainwindow.h
@@ -0,0 +1,73 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia 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 MAINWINDOW_H
22#define MAINWINDOW_H
23
24#include <qmainwindow.h>
25
26class TodoTable;
27class QAction;
28class QPopupMenu;
29class Ir;
30
31class TodoWindow : public QMainWindow
32{
33 Q_OBJECT
34
35public:
36 TodoWindow( QWidget *parent = 0, const char *name = 0, WFlags f = 0 );
37 ~TodoWindow();
38
39public slots:
40 void flush();
41 void reload();
42
43protected slots:
44 void slotNew();
45 void slotDelete();
46 void slotEdit();
47 void slotShowPopup( const QPoint & );
48 void showCompleted( bool );
49 void currentEntryChanged( int r, int c );
50 void setCategory( int );
51 void slotFind();
52 void setDocument( const QString & );
53 void slotBeam();
54 void beamDone( Ir * );
55
56protected:
57 void closeEvent( QCloseEvent *e );
58
59private:
60 void populateCategories();
61
62private:
63 TodoTable *table;
64 QAction *editAction,
65 *deleteAction,
66 *findAction,
67 * completedAction;
68 QPopupMenu *contextMenu, *catMenu;
69
70 bool syncing;
71};
72
73#endif
diff --git a/core/pim/todo/qpe-todo.control b/core/pim/todo/qpe-todo.control
new file mode 100644
index 0000000..80195a0
--- a/dev/null
+++ b/core/pim/todo/qpe-todo.control
@@ -0,0 +1,9 @@
1Files: bin/todolist apps/Applications/todo.desktop
2Priority: optional
3Section: qpe/applications
4Maintainer: Warwick Allison <warwick@trolltech.com>
5Architecture: arm
6Version: $QPE_VERSION-3
7Depends: qpe-base ($QPE_VERSION)
8Description: TODO-list manager
9 A Todo-list manager for the Qtopia environment.
diff --git a/core/pim/todo/todo.pro b/core/pim/todo/todo.pro
new file mode 100644
index 0000000..e28ea1c
--- a/dev/null
+++ b/core/pim/todo/todo.pro
@@ -0,0 +1,19 @@
1 TEMPLATE= app
2 CONFIG = qt warn_on release
3 DESTDIR = $(QPEDIR)/bin
4 HEADERS= mainwindow.h \
5 todotable.h \
6 todoentryimpl.h
7 SOURCES= main.cpp \
8 mainwindow.cpp \
9 todotable.cpp \
10 todoentryimpl.cpp
11
12 INTERFACES= todoentry.ui
13
14 TARGET = todolist
15INCLUDEPATH += $(QPEDIR)/include
16 DEPENDPATH+= $(QPEDIR)/include
17LIBS += -lqpe
18
19TRANSLATIONS = ../i18n/de/todolist.ts
diff --git a/core/pim/todo/todoentry.ui b/core/pim/todo/todoentry.ui
new file mode 100644
index 0000000..c735e76
--- a/dev/null
+++ b/core/pim/todo/todoentry.ui
@@ -0,0 +1,266 @@
1<!DOCTYPE UI><UI>
2<class>NewTaskDialogBase</class>
3<comment>*********************************************************************
4** Copyright (C) 2000 Trolltech AS. All rights reserved.
5**
6** This file is part of Qtopia 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*********************************************************************</comment>
22<widget>
23 <class>QDialog</class>
24 <property stdset="1">
25 <name>name</name>
26 <cstring>NewTaskDialogBase</cstring>
27 </property>
28 <property stdset="1">
29 <name>geometry</name>
30 <rect>
31 <x>0</x>
32 <y>0</y>
33 <width>249</width>
34 <height>321</height>
35 </rect>
36 </property>
37 <property stdset="1">
38 <name>caption</name>
39 <string>New Task</string>
40 </property>
41 <property>
42 <name>layoutMargin</name>
43 </property>
44 <property>
45 <name>layoutSpacing</name>
46 </property>
47 <vbox>
48 <property stdset="1">
49 <name>margin</name>
50 <number>0</number>
51 </property>
52 <property stdset="1">
53 <name>spacing</name>
54 <number>0</number>
55 </property>
56 <widget>
57 <class>QLayoutWidget</class>
58 <property stdset="1">
59 <name>name</name>
60 <cstring>Layout4</cstring>
61 </property>
62 <hbox>
63 <property stdset="1">
64 <name>margin</name>
65 <number>0</number>
66 </property>
67 <property stdset="1">
68 <name>spacing</name>
69 <number>6</number>
70 </property>
71 <widget>
72 <class>QLabel</class>
73 <property stdset="1">
74 <name>name</name>
75 <cstring>TextLabel2</cstring>
76 </property>
77 <property stdset="1">
78 <name>text</name>
79 <string>Priority:</string>
80 </property>
81 </widget>
82 <widget>
83 <class>QComboBox</class>
84 <item>
85 <property>
86 <name>text</name>
87 <string>1 - Very High</string>
88 </property>
89 </item>
90 <item>
91 <property>
92 <name>text</name>
93 <string>2 - High</string>
94 </property>
95 </item>
96 <item>
97 <property>
98 <name>text</name>
99 <string>3 - Normal</string>
100 </property>
101 </item>
102 <item>
103 <property>
104 <name>text</name>
105 <string>4 - Low</string>
106 </property>
107 </item>
108 <item>
109 <property>
110 <name>text</name>
111 <string>5 - Very Low</string>
112 </property>
113 </item>
114 <property stdset="1">
115 <name>name</name>
116 <cstring>comboPriority</cstring>
117 </property>
118 <property stdset="1">
119 <name>sizePolicy</name>
120 <sizepolicy>
121 <hsizetype>7</hsizetype>
122 <vsizetype>0</vsizetype>
123 </sizepolicy>
124 </property>
125 <property stdset="1">
126 <name>currentItem</name>
127 <number>2</number>
128 </property>
129 </widget>
130 </hbox>
131 </widget>
132 <widget>
133 <class>QLayoutWidget</class>
134 <property stdset="1">
135 <name>name</name>
136 <cstring>Layout3</cstring>
137 </property>
138 <hbox>
139 <property stdset="1">
140 <name>margin</name>
141 <number>0</number>
142 </property>
143 <property stdset="1">
144 <name>spacing</name>
145 <number>6</number>
146 </property>
147 <widget>
148 <class>QLabel</class>
149 <property stdset="1">
150 <name>name</name>
151 <cstring>TextLabel3</cstring>
152 </property>
153 <property stdset="1">
154 <name>frameShape</name>
155 <enum>NoFrame</enum>
156 </property>
157 <property stdset="1">
158 <name>text</name>
159 <string>Category:</string>
160 </property>
161 </widget>
162 <widget>
163 <class>CategorySelect</class>
164 <property stdset="1">
165 <name>name</name>
166 <cstring>comboCategory</cstring>
167 </property>
168 </widget>
169 </hbox>
170 </widget>
171 <widget>
172 <class>QLayoutWidget</class>
173 <property stdset="1">
174 <name>name</name>
175 <cstring>Layout4</cstring>
176 </property>
177 <hbox>
178 <property stdset="1">
179 <name>margin</name>
180 <number>0</number>
181 </property>
182 <property stdset="1">
183 <name>spacing</name>
184 <number>6</number>
185 </property>
186 <widget>
187 <class>QCheckBox</class>
188 <property stdset="1">
189 <name>name</name>
190 <cstring>checkCompleted</cstring>
191 </property>
192 <property stdset="1">
193 <name>text</name>
194 <string>&amp;Completed</string>
195 </property>
196 </widget>
197 <widget>
198 <class>QCheckBox</class>
199 <property stdset="1">
200 <name>name</name>
201 <cstring>checkDate</cstring>
202 </property>
203 <property stdset="1">
204 <name>text</name>
205 <string>D&amp;ue</string>
206 </property>
207 </widget>
208 <widget>
209 <class>QPushButton</class>
210 <property stdset="1">
211 <name>name</name>
212 <cstring>buttonDate</cstring>
213 </property>
214 <property stdset="1">
215 <name>enabled</name>
216 <bool>false</bool>
217 </property>
218 <property stdset="1">
219 <name>text</name>
220 <string>1 Jan 2001</string>
221 </property>
222 </widget>
223 </hbox>
224 </widget>
225 <widget>
226 <class>QMultiLineEdit</class>
227 <property stdset="1">
228 <name>name</name>
229 <cstring>txtTodo</cstring>
230 </property>
231 </widget>
232 </vbox>
233</widget>
234<customwidgets>
235 <customwidget>
236 <class>CategorySelect</class>
237 <header location="global">qpe/categoryselect.h</header>
238 <sizehint>
239 <width>-1</width>
240 <height>-1</height>
241 </sizehint>
242 <container>0</container>
243 <sizepolicy>
244 <hordata>7</hordata>
245 <verdata>1</verdata>
246 </sizepolicy>
247 <pixmap>image0</pixmap>
248 </customwidget>
249</customwidgets>
250<images>
251 <image>
252 <name>image0</name>
253 <data format="XPM.GZ" length="646">789c6dd2c10ac2300c00d07bbf2234b7229d1be245fc04c5a3201e4615f430059d0711ff5ddb2e6bb236ec90eed134cb5a19d8ef36602af5ecdbfeeac05dda0798d3abebde87e3faa374d3807fa0d633a52d38d8de6f679fe33fc776e196f53cd010188256a3600a292882096246517815ca99884606e18044a3a40d91824820924265a7923a2e8bcd05f33db1173e002913175f2a6be6d3294871a2d95fa00e8a94ee017b69d339d90df1e77c57ea072ede6758</data>
254 </image>
255</images>
256<connections>
257 <connection>
258 <sender>checkDate</sender>
259 <signal>toggled(bool)</signal>
260 <receiver>buttonDate</receiver>
261 <slot>setEnabled(bool)</slot>
262 </connection>
263 <slot access="protected">dateChanged( const QString &amp; )</slot>
264 <slot access="protected">dateChanged( int, int, int )</slot>
265</connections>
266</UI>
diff --git a/core/pim/todo/todoentryimpl.cpp b/core/pim/todo/todoentryimpl.cpp
new file mode 100644
index 0000000..79206de
--- a/dev/null
+++ b/core/pim/todo/todoentryimpl.cpp
@@ -0,0 +1,142 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia 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 "todoentryimpl.h"
22
23#include <qpe/categoryselect.h>
24#include <qpe/datebookmonth.h>
25#include <qpe/global.h>
26#include <qpe/imageedit.h>
27#include <qpe/task.h>
28#include <qpe/timestring.h>
29
30#include <qmessagebox.h>
31#include <qpopupmenu.h>
32#include <qtoolbutton.h>
33#include <qcombobox.h>
34#include <qcheckbox.h>
35#include <qlineedit.h>
36#include <qmultilineedit.h>
37#include <qlabel.h>
38#include <qtimer.h>
39#include <qapplication.h>
40
41
42NewTaskDialog::NewTaskDialog( const Task& task, QWidget *parent,
43 const char *name, bool modal, WFlags fl )
44 : NewTaskDialogBase( parent, name, modal, fl ),
45 todo( task )
46{
47 todo.setCategories( task.categories() );
48 if ( todo.hasDueDate() )
49 date = todo.dueDate();
50 else
51 date = QDate::currentDate();
52
53 init();
54 comboPriority->setCurrentItem( task.priority() - 1 );
55
56 checkCompleted->setChecked( task.isCompleted() );
57 checkDate->setChecked( task.hasDueDate() );
58 buttonDate->setText( TimeString::longDateString( date ) );
59
60 txtTodo->setText( task.description() );
61}
62
63/*
64 * Constructs a NewTaskDialog which is a child of 'parent', with the
65 * name 'name' and widget flags set to 'f'
66 *
67 * The dialog will by default be modeless, unless you set 'modal' to
68 * TRUE to construct a modal dialog.
69 */
70NewTaskDialog::NewTaskDialog( int id, QWidget* parent, const char* name, bool modal,
71 WFlags fl )
72 : NewTaskDialogBase( parent, name, modal, fl ),
73 date( QDate::currentDate() )
74{
75 if ( id != -1 ) {
76 QArray<int> ids( 1 );
77 ids[0] = id;
78 todo.setCategories( ids );
79 }
80 init();
81}
82
83void NewTaskDialog::init()
84{
85 QPopupMenu *m1 = new QPopupMenu( this );
86 picker = new DateBookMonth( m1, 0, TRUE );
87 m1->insertItem( picker );
88 buttonDate->setPopup( m1 );
89 comboCategory->setCategories( todo.categories(), "Todo List", tr("Todo List") );
90
91 connect( picker, SIGNAL( dateClicked( int, int, int ) ),
92 this, SLOT( dateChanged( int, int, int ) ) );
93
94 buttonDate->setText( TimeString::longDateString( date ) );
95 picker->setDate( date.year(), date.month(), date.day() );
96}
97
98/*
99 * Destroys the object and frees any allocated resources
100 */
101NewTaskDialog::~NewTaskDialog()
102{
103 // no need to delete child widgets, Qt does it all for us
104}
105void NewTaskDialog::dateChanged( int y, int m, int d )
106{
107 date = QDate( y, m, d );
108 buttonDate->setText( TimeString::longDateString( date ) );
109}
110
111/*!
112*/
113
114Task NewTaskDialog::todoEntry()
115{
116 todo.setDueDate( date, checkDate->isChecked() );
117 if ( comboCategory->currentCategory() != -1 ) {
118 todo.setCategories( comboCategory->currentCategories() );
119 }
120 todo.setPriority( comboPriority->currentItem() + 1 );
121 todo.setCompleted( checkCompleted->isChecked() );
122
123 todo.setDescription( txtTodo->text() );
124
125 return todo;
126}
127
128
129/*!
130
131*/
132
133void NewTaskDialog::accept()
134{
135 QString strText = txtTodo->text();
136 if ( !strText || strText == "") {
137 // hmm... just decline it then, the user obviously didn't care about it
138 QDialog::reject();
139 return;
140 }
141 QDialog::accept();
142}
diff --git a/core/pim/todo/todoentryimpl.h b/core/pim/todo/todoentryimpl.h
new file mode 100644
index 0000000..932d66e
--- a/dev/null
+++ b/core/pim/todo/todoentryimpl.h
@@ -0,0 +1,61 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia 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 NEWTASKDIALOG_H
22#define NEWTASKDIALOG_H
23
24#include "todoentry.h"
25
26#include <qpe/task.h>
27
28#include <qdatetime.h>
29#include <qpalette.h>
30
31class QLabel;
32class QTimer;
33class DateBookMonth;
34
35class NewTaskDialog : public NewTaskDialogBase
36{
37 Q_OBJECT
38
39public:
40 NewTaskDialog( const Task &task, QWidget *parent = 0, const char* name = 0,
41 bool modal = FALSE, WFlags fl = 0 );
42 NewTaskDialog( int id, QWidget* parent = 0, const char* name = 0,
43 bool modal = FALSE, WFlags fl = 0 );
44 ~NewTaskDialog();
45
46 Task todoEntry();
47
48protected slots:
49 void dateChanged( int y, int m, int d );
50
51protected:
52 virtual void accept();
53
54private:
55 void init();
56 Task todo;
57 QDate date;
58 DateBookMonth *picker;
59};
60
61#endif // NEWTASKDIALOG_H
diff --git a/core/pim/todo/todotable.cpp b/core/pim/todo/todotable.cpp
new file mode 100644
index 0000000..77d3389
--- a/dev/null
+++ b/core/pim/todo/todotable.cpp
@@ -0,0 +1,859 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia 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 "todotable.h"
22
23#include <qpe/categoryselect.h>
24#include <qpe/xmlreader.h>
25
26#include <qasciidict.h>
27#include <qcombobox.h>
28#include <qfile.h>
29#include <qpainter.h>
30#include <qtextcodec.h>
31#include <qtimer.h>
32#include <qdatetime.h>
33
34#include <qcursor.h>
35#include <qregexp.h>
36
37#include <errno.h>
38#include <stdlib.h>
39
40
41
42static bool taskCompare( const Task &task, const QRegExp &r, int category );
43
44static QString journalFileName();
45
46CheckItem::CheckItem( QTable *t, const QString &key )
47 : QTableItem( t, Never, "" ), checked( FALSE ), sortKey( key )
48{
49}
50
51QString CheckItem::key() const
52{
53 return sortKey;
54}
55
56void CheckItem::setChecked( bool b )
57{
58 checked = b;
59 table()->updateCell( row(), col() );
60}
61
62void CheckItem::toggle()
63{
64 TodoTable *parent = static_cast<TodoTable*>(table());
65 Task newTodo = parent->currentEntry();
66 checked = !checked;
67 newTodo.setCompleted( checked );
68 table()->updateCell( row(), col() );
69 parent->replaceCurrentEntry( newTodo, true );
70}
71
72bool CheckItem::isChecked() const
73{
74 return checked;
75}
76
77static const int BoxSize = 10;
78
79void CheckItem::paint( QPainter *p, const QColorGroup &cg, const QRect &cr,
80 bool )
81{
82 p->fillRect( 0, 0, cr.width(), cr.height(), cg.brush( QColorGroup::Base ) );
83
84 int marg = ( cr.width() - BoxSize ) / 2;
85 int x = 0;
86 int y = ( cr.height() - BoxSize ) / 2;
87 p->setPen( QPen( cg.text() ) );
88 p->drawRect( x + marg, y, BoxSize, BoxSize );
89 p->drawRect( x + marg+1, y+1, BoxSize-2, BoxSize-2 );
90 p->setPen( darkGreen );
91 x += 1;
92 y += 1;
93 if ( checked ) {
94 QPointArray a( 7*2 );
95 int i, xx, yy;
96 xx = x+1+marg;
97 yy = y+2;
98 for ( i=0; i<3; i++ ) {
99 a.setPoint( 2*i, xx, yy );
100 a.setPoint( 2*i+1, xx, yy+2 );
101 xx++; yy++;
102 }
103 yy -= 2;
104 for ( i=3; i<7; i++ ) {
105 a.setPoint( 2*i, xx, yy );
106 a.setPoint( 2*i+1, xx, yy+2 );
107 xx++; yy--;
108 }
109 p->drawLineSegments( a );
110 }
111}
112
113
114ComboItem::ComboItem( QTable *t, EditType et )
115 : QTableItem( t, et, "3" ), cb( 0 )
116{
117 setReplaceable( FALSE );
118}
119
120QWidget *ComboItem::createEditor() const
121{
122 QString txt = text();
123 ( (ComboItem*)this )->cb = new QComboBox( table()->viewport() );
124 cb->insertItem( "1" );
125 cb->insertItem( "2" );
126 cb->insertItem( "3" );
127 cb->insertItem( "4" );
128 cb->insertItem( "5" );
129 cb->setCurrentItem( txt.toInt() - 1 );
130 return cb;
131}
132
133void ComboItem::setContentFromEditor( QWidget *w )
134{
135 TodoTable *parent = static_cast<TodoTable*>(table());
136 Task newTodo = parent->currentEntry();
137
138 if ( w->inherits( "QComboBox" ) )
139 setText( ( (QComboBox*)w )->currentText() );
140 else
141 QTableItem::setContentFromEditor( w );
142 newTodo.setPriority( text().toInt() );
143 parent->replaceCurrentEntry( newTodo, true );
144}
145
146void ComboItem::setText( const QString &s )
147{
148 if ( cb )
149 cb->setCurrentItem( s.toInt() - 1 );
150 QTableItem::setText( s );
151}
152
153QString ComboItem::text() const
154{
155 if ( cb )
156 return cb->currentText();
157 return QTableItem::text();
158}
159
160
161
162TodoTable::TodoTable( QWidget *parent, const char *name )
163// #ifdef QT_QTABLE_NOHEADER_CONSTRUCTOR
164// : QTable( 0, 3, parent, name, TRUE ),
165// #else
166 : QTable( 0, 3, parent, name ),
167// #endif
168 showComp( true ),
169 enablePainting( true ),
170 mCat( 0 ),
171 currFindRow( -2 )
172{
173 mCat.load( categoryFileName() );
174 setSorting( TRUE );
175 setSelectionMode( NoSelection );
176 setColumnStretchable( 2, TRUE );
177 setColumnWidth( 0, 20 );
178 setColumnWidth( 1, 35 );
179 setLeftMargin( 0 );
180 verticalHeader()->hide();
181 horizontalHeader()->setLabel( 0, tr( "C." ) );
182 horizontalHeader()->setLabel( 1, tr( "Prior." ) );
183 horizontalHeader()->setLabel( 2, tr( "Description" ) );
184 connect( this, SIGNAL( clicked( int, int, int, const QPoint & ) ),
185 this, SLOT( slotClicked( int, int, int, const QPoint & ) ) );
186 connect( this, SIGNAL( pressed( int, int, int, const QPoint & ) ),
187 this, SLOT( slotPressed( int, int, int, const QPoint & ) ) );
188 connect( this, SIGNAL( valueChanged( int, int ) ),
189 this, SLOT( slotCheckPriority( int, int ) ) );
190 connect( this, SIGNAL( currentChanged( int, int ) ),
191 this, SLOT( slotCurrentChanged( int, int ) ) );
192
193 menuTimer = new QTimer( this );
194 connect( menuTimer, SIGNAL(timeout()), this, SLOT(slotShowMenu()) );
195}
196
197void TodoTable::addEntry( const Task &todo )
198{
199 int row = numRows();
200 setNumRows( row + 1 );
201 updateJournal( todo, ACTION_ADD );
202 insertIntoTable( new Task(todo), row );
203 setCurrentCell(row, currentColumn());
204 updateVisible();
205}
206
207void TodoTable::slotClicked( int row, int col, int, const QPoint &pos )
208{
209 if ( !cellGeometry( row, col ).contains(pos) )
210 return;
211 // let's switch on the column number...
212 switch ( col )
213 {
214 case 0: {
215 CheckItem *i = static_cast<CheckItem*>(item( row, col ));
216 if ( i ) {
217 int x = pos.x() - columnPos( col );
218 int y = pos.y() - rowPos( row );
219 int w = columnWidth( col );
220 int h = rowHeight( row );
221 if ( i && x >= ( w - BoxSize ) / 2 && x <= ( w - BoxSize ) / 2 + BoxSize &&
222 y >= ( h - BoxSize ) / 2 && y <= ( h - BoxSize ) / 2 + BoxSize ) {
223 i->toggle();
224 }
225 emit signalDoneChanged( i->isChecked() );
226 }
227 }
228 break;
229 case 1:
230 break;
231 case 2:
232 // may as well edit it...
233 menuTimer->stop();
234// emit signalEdit();
235 break;
236 }
237}
238
239void TodoTable::slotPressed( int row, int col, int, const QPoint &pos )
240{
241 if ( col == 2 && cellGeometry( row, col ).contains(pos) )
242 menuTimer->start( 750, TRUE );
243}
244
245void TodoTable::slotShowMenu()
246{
247 emit signalShowMenu( QCursor::pos() );
248}
249
250void TodoTable::slotCurrentChanged( int, int )
251{
252 menuTimer->stop();
253}
254
255void TodoTable::internalAddEntries( QList<Task> &list )
256{
257 setNumRows( list.count() );
258 int row = 0;
259 Task *it;
260 for ( it = list.first(); it; it = list.next() )
261 insertIntoTable( it, row++ );
262}
263
264
265Task TodoTable::currentEntry() const
266{
267 QTableItem *i = item( currentRow(), 0 );
268 if ( !i || rowHeight( currentRow() ) <= 0 )
269 return Task();
270 Task *todo = todoList[(CheckItem*)i];
271 todo->setCompleted( ( (CheckItem*)item( currentRow(), 0 ) )->isChecked() );
272 todo->setPriority( ( (ComboItem*)item( currentRow(), 1 ) )->text().toInt() );
273 return *todo;
274}
275
276void TodoTable::replaceCurrentEntry( const Task &todo, bool fromTableItem )
277{
278 int row = currentRow();
279 updateJournal( todo, ACTION_REPLACE, row );
280
281 if ( !fromTableItem ) {
282 journalFreeReplaceEntry( todo, row );
283 updateVisible();
284 }
285}
286
287void TodoTable::removeCurrentEntry()
288{
289 Task *oldTodo;
290 int row = currentRow();
291 CheckItem *chk;
292
293 chk = static_cast<CheckItem*>(item(row, 0 ));
294 if ( !chk )
295 return;
296 oldTodo = todoList[chk];
297 todoList.remove( chk );
298 oldTodo->setCompleted( chk->isChecked() );
299 oldTodo->setPriority( static_cast<ComboItem*>(item(row, 1))->text().toInt() );
300 realignTable( row );
301 updateVisible();
302 updateJournal( *oldTodo, ACTION_REMOVE, row );
303 delete oldTodo;
304}
305
306
307bool TodoTable::save( const QString &fn )
308{
309 QString strNewFile = fn + ".new";
310 QFile f( strNewFile );
311 if ( !f.open( IO_WriteOnly|IO_Raw ) )
312 return false;
313
314 QString buf("<!DOCTYPE Tasks>\n<Tasks>\n");
315 QCString str;
316 int total_written;
317
318 for ( QMap<CheckItem*, Task *>::Iterator it = todoList.begin();
319 it != todoList.end(); ++it ) {
320 if ( !item( it.key()->row(), 0 ) )
321 continue;
322 Task *todo = *it;
323 // sync item with table
324 todo->setCompleted( ((CheckItem*)item(it.key()->row(), 0))->isChecked() );
325 todo->setPriority( ((ComboItem*)item( it.key()->row(), 1))->text().toInt() );
326 buf += "<Task";
327 todo->save( buf );
328 buf += " />\n";
329 str = buf.utf8();
330 total_written = f.writeBlock( str.data(), str.length() );
331 if ( total_written != int(str.length()) ) {
332 f.close();
333 QFile::remove( strNewFile );
334 return false;
335 }
336 buf = "";
337 }
338
339 buf += "</Tasks>\n";
340 str = buf.utf8();
341 total_written = f.writeBlock( str.data(), str.length() );
342 if ( total_written != int(str.length()) ) {
343 f.close();
344 QFile::remove( strNewFile );
345 return false;
346 }
347 f.close();
348
349 // now do the rename
350 if ( ::rename( strNewFile, fn ) < 0 )
351 qWarning( "problem renaming file %s to %s errno %d",
352 strNewFile.latin1(), fn.latin1(), errno );
353
354 // remove the journal
355 QFile::remove( journalFileName() );
356 return true;
357}
358
359void TodoTable::load( const QString &fn )
360{
361 loadFile( fn, false );
362 if ( QFile::exists(journalFileName()) ) {
363 loadFile( journalFileName(), true );
364 save( fn );
365 }
366// QTable::sortColumn(2,TRUE,TRUE);
367// QTable::sortColumn(1,TRUE,TRUE);
368 QTable::sortColumn(0,TRUE,TRUE);
369 setCurrentCell( 0, 2 );
370}
371
372void TodoTable::updateVisible()
373{
374 if ( !isUpdatesEnabled() )
375 return;
376
377// qDebug("--> updateVisible!");
378
379 int visible = 0;
380 int id = mCat.id( "Todo List", showCat );
381 for ( int row = 0; row < numRows(); row++ ) {
382 CheckItem *ci = (CheckItem *)item( row, 0 );
383 Task *t = todoList[ci];
384 QArray<int> vlCats = t->categories();
385 bool hide = false;
386 if ( !showComp && ci->isChecked() )
387 hide = true;
388 if ( !showCat.isEmpty() ) {
389 if ( showCat == tr( "Unfiled" ) ) {
390 if ( vlCats.count() > 0 )
391 hide = true;
392 } else {
393 // do some comparing, we have to reverse our idea here...
394 if ( !hide ) {
395 hide = true;
396 for ( uint it = 0; it < vlCats.count(); ++it ) {
397 if ( vlCats[it] == id ) {
398 hide = false;
399 break;
400 }
401 }
402 }
403 }
404 }
405 if ( hide ) {
406 if ( currentRow() == row )
407 setCurrentCell( -1, 0 );
408 if ( rowHeight( row ) > 0 )
409 hideRow( row );
410 } else {
411 if ( rowHeight( row ) == 0 ) {
412 showRow( row );
413 adjustRow( row );
414 }
415 visible++;
416 }
417 }
418 if ( !visible )
419 setCurrentCell( -1, 0 );
420}
421
422void TodoTable::viewportPaintEvent( QPaintEvent *pe )
423{
424 if ( enablePainting )
425 QTable::viewportPaintEvent( pe );
426}
427
428void TodoTable::setPaintingEnabled( bool e )
429{
430 if ( e != enablePainting ) {
431 if ( !enablePainting ) {
432 enablePainting = true;
433 rowHeightChanged( 0 );
434 viewport()->update();
435 } else {
436 enablePainting = false;
437 }
438 }
439}
440
441void TodoTable::clear()
442{
443 for ( QMap<CheckItem*, Task *>::Iterator it = todoList.begin();
444 it != todoList.end(); ++it ) {
445 Task *todo = *it;
446 delete todo;
447 }
448 todoList.clear();
449 for ( int r = 0; r < numRows(); ++r ) {
450 for ( int c = 0; c < numCols(); ++c ) {
451 if ( cellWidget( r, c ) )
452 clearCellWidget( r, c );
453 clearCell( r, c );
454 }
455 }
456 setNumRows( 0 );
457}
458
459void TodoTable::sortColumn( int col, bool /*ascending*/, bool /*wholeRows*/ )
460{
461 // The default for wholeRows is false, however
462 // for this todo table we want to exchange complete
463 // rows when sorting. Also, we always want ascending, since
464 // the values have a logical order.
465 QTable::sortColumn( col, TRUE, TRUE );
466 updateVisible();
467}
468
469void TodoTable::slotCheckPriority(int row, int col )
470{
471 // kludgey work around to make forward along the updated priority...
472 if ( col == 1 ) {
473 // let everyone know!!
474 ComboItem* i = static_cast<ComboItem*>( item( row, col ) );
475 emit signalPriorityChanged( i->text().toInt() );
476 }
477}
478
479
480void TodoTable::updateJournal( const Task &todo, journal_action action, int row )
481{
482 QFile f( journalFileName() );
483 if ( !f.open(IO_WriteOnly|IO_Append) )
484 return;
485 QString buf;
486 QCString str;
487 buf = "<Task";
488 todo.save( buf );
489 buf += " Action=\"" + QString::number( int(action) ) + "\"";
490 buf += " Row=\"" + QString::number( row ) + "\"";
491 buf += "/>\n";
492 str = buf.utf8();
493 f.writeBlock( str.data(), str.length() );
494 f.close();
495}
496
497void TodoTable::rowHeightChanged( int row )
498{
499 if ( enablePainting )
500 QTable::rowHeightChanged( row );
501}
502
503void TodoTable::loadFile( const QString &strFile, bool fromJournal )
504{
505 QFile f( strFile );
506 if ( !f.open(IO_ReadOnly) )
507 return;
508
509 int action, row;
510 action = 0; row = 0;
511
512 enum Attribute {
513 FCompleted = 0,
514 FHasDate,
515 FPriority,
516 FCategories,
517 FDescription,
518 FDateYear,
519 FDateMonth,
520 FDateDay,
521 FUid,
522 FAction,
523 FRow
524 };
525
526 QAsciiDict<int> dict( 31 );
527 QList<Task> list;
528 dict.setAutoDelete( TRUE );
529 dict.insert( "Completed", new int(FCompleted) );
530 dict.insert( "HasDate", new int(FHasDate) );
531 dict.insert( "Priority", new int(FPriority) );
532 dict.insert( "Categories", new int(FCategories) );
533 dict.insert( "Description", new int(FDescription) );
534 dict.insert( "DateYear", new int(FDateYear) );
535 dict.insert( "DateMonth", new int(FDateMonth) );
536 dict.insert( "DateDay", new int(FDateDay) );
537 dict.insert( "Uid", new int(FUid) );
538 dict.insert( "Action", new int(FAction) );
539 dict.insert( "Row", new int(FRow) );
540
541 QByteArray ba = f.readAll();
542 f.close();
543 char* dt = ba.data();
544 int len = ba.size();
545 bool hasDueDate = FALSE;
546
547 action = ACTION_ADD;
548 int i = 0;
549 char *point;
550 while ( ( point = strstr( dt+i, "<Task " ) ) != NULL ) {
551 // new Task
552 i = point - dt;
553 Task *todo = new Task;
554 int dtY = 0, dtM = 0, dtD = 0;
555
556 i += 5;
557
558 while( 1 ) {
559 while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') )
560 ++i;
561 if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') )
562 break;
563 // we have another attribute, read it.
564 int j = i;
565 while ( j < len && dt[j] != '=' )
566 ++j;
567 char *attr = dt+i;
568 dt[j] = '\0';
569 i = ++j; // skip =
570 while ( i < len && dt[i] != '"' )
571 ++i;
572 j = ++i;
573 bool haveUtf = FALSE;
574 bool haveEnt = FALSE;
575 while ( j < len && dt[j] != '"' ) {
576 if ( ((unsigned char)dt[j]) > 0x7f )
577 haveUtf = TRUE;
578 if ( dt[j] == '&' )
579 haveEnt = TRUE;
580 ++j;
581 }
582 if ( i == j ) {
583 // empty value
584 i = j + 1;
585 continue;
586 }
587 QCString value( dt+i, j-i+1 );
588 i = j + 1;
589 int *lookup = dict[ attr ];
590 if ( !lookup ) {
591 todo->setCustomField(attr, value);
592 continue;
593 }
594 switch( *lookup ) {
595 case FCompleted:
596 todo->setCompleted( value.toInt() );
597 break;
598 case FHasDate:
599 // leave...
600 hasDueDate = value.toInt();
601 break;
602 case FPriority:
603 todo->setPriority( value.toInt() );
604 break;
605 case FCategories: {
606 //QString str = Qtopia::plainString( value );
607 todo->setCategories( Qtopia::Record::idsFromString( value ) );
608 break;
609 }
610 case FDescription:
611 {
612 QString str = (haveUtf ? QString::fromUtf8( value )
613 : QString::fromLatin1( value ) );
614 if ( haveEnt )
615 str = Qtopia::plainString( str );
616 todo->setDescription( str );
617 break;
618 }
619 case FDateYear:
620 dtY = value.toInt();
621 break;
622 case FDateMonth:
623 dtM = value.toInt();
624 break;
625 case FDateDay:
626 dtD = value.toInt();
627 break;
628 case FUid:
629 todo->setUid( value.toInt() );
630 break;
631 case FAction:
632 action = value.toInt();
633 break;
634 case FRow:
635 row = value.toInt();
636 break;
637 default:
638 qDebug( "huh??? missing enum? -- attr.: %s", attr );
639 break;
640 }
641 }
642
643 if ( dtY != 0 && dtM != 0 && dtD != 0 )
644 todo->setDueDate( QDate( dtY, dtM, dtD), hasDueDate );
645 else
646 todo->setHasDueDate( hasDueDate );
647
648// if ( categoryList.find( todo.category() ) == categoryList.end() )
649// categoryList.append( todo.category() );
650
651
652 // sadly we can't delay adding of items from the journal to get
653 // the proper effect, but then, the journal should _never_ be
654 // that huge
655
656 switch( action ) {
657 case ACTION_ADD:
658 if ( fromJournal ) {
659 int myrows = numRows();
660 setNumRows( myrows + 1 );
661 insertIntoTable( todo, myrows );
662 delete todo;
663 } else
664 list.append( todo );
665 break;
666 case ACTION_REMOVE:
667 journalFreeRemoveEntry( row );
668 break;
669 case ACTION_REPLACE:
670 journalFreeReplaceEntry( *todo, row );
671 delete todo;
672 break;
673 default:
674 break;
675 }
676 }
677// qDebug("parsing done=%d", t.elapsed() );
678 if ( list.count() > 0 ) {
679 internalAddEntries( list );
680 list.clear();
681 }
682// qDebug("loading done: t=%d", t.elapsed() );
683}
684
685void TodoTable::journalFreeReplaceEntry( const Task &todo, int row )
686{
687 QString strTodo;
688 strTodo = todo.description().left(40).simplifyWhiteSpace();
689 if ( row == -1 ) {
690 QMapIterator<CheckItem*, Task *> it;
691 for ( it = todoList.begin(); it != todoList.end(); ++it ) {
692 if ( *(*it) == todo ) {
693 row = it.key()->row();
694 it.key()->setChecked( todo.isCompleted() );
695 static_cast<ComboItem*>(item(row, 1))->setText( QString::number(todo.priority()) );
696 item( row, 2 )->setText( strTodo );
697 *(*it) = todo;
698 }
699 }
700 } else {
701 Task *t = todoList[static_cast<CheckItem*>(item(row, 0))];
702 todoList.remove( static_cast<CheckItem*>(item(row, 0)) );
703 delete t;
704 static_cast<CheckItem*>(item(row, 0))->setChecked( todo.isCompleted() );
705 static_cast<ComboItem*>(item(row, 1))->setText( QString::number(todo.priority()) );
706 item( row, 2 )->setText( strTodo );
707 todoList.insert( static_cast<CheckItem*>(item(row,0)), new Task(todo) );
708 }
709}
710
711void TodoTable::journalFreeRemoveEntry( int row )
712{
713 CheckItem *chk;
714 chk = static_cast<CheckItem*>(item(row, 0 ));
715 if ( !chk )
716 return;
717 todoList.remove( chk );
718
719 realignTable( row );
720}
721
722void TodoTable::keyPressEvent( QKeyEvent *e )
723{
724 if ( e->key() == Key_Space || e->key() == Key_Return ) {
725 switch ( currentColumn() ) {
726 case 0: {
727 CheckItem *i = static_cast<CheckItem*>(item(currentRow(),
728 currentColumn()));
729 if ( i )
730 i->toggle();
731 break;
732 }
733 case 1:
734 break;
735 case 2:
736 emit signalEdit();
737 default:
738 break;
739 }
740 } else {
741 QTable::keyPressEvent( e );
742 }
743}
744
745QStringList TodoTable::categories()
746{
747 // This is called seldom, so calling a load in here
748 // should be fine.
749 mCat.load( categoryFileName() );
750 QStringList categoryList = mCat.labels( "Todo List" );
751 return categoryList;
752}
753
754void TodoTable::slotDoFind( const QString &findString, bool caseSensitive,
755 bool backwards, int category )
756{
757 // we have to iterate through the table, this gives the illusion that
758 // sorting is actually being used.
759 if ( currFindRow < -1 )
760 currFindRow = currentRow() - 1;
761 clearSelection( TRUE );
762 int rows,
763 row;
764 CheckItem *chk;
765 QRegExp r( findString );
766
767 r.setCaseSensitive( caseSensitive );
768 rows = numRows();
769 static bool wrapAround = true;
770
771 if ( !backwards ) {
772 for ( row = currFindRow + 1; row < rows; row++ ) {
773 chk = static_cast<CheckItem*>( item(row, 0) );
774 if ( taskCompare(*(todoList[chk]), r, category) )
775 break;
776 }
777 } else {
778 for ( row = currFindRow - 1; row > -1; row-- ) {
779 chk = static_cast<CheckItem*>( item(row, 0) );
780 if ( taskCompare(*(todoList[chk]), r, category) )
781 break;
782 }
783 }
784 if ( row >= rows || row < 0 ) {
785 if ( row < 0 )
786 currFindRow = rows;
787 else
788 currFindRow = -1;
789 if ( wrapAround )
790 emit signalWrapAround();
791 else
792 emit signalNotFound();
793 wrapAround = !wrapAround;
794 } else {
795 currFindRow = row;
796 QTableSelection foundSelection;
797 foundSelection.init( currFindRow, 0 );
798 foundSelection.expandTo( currFindRow, numCols() - 1 );
799 addSelection( foundSelection );
800 setCurrentCell( currFindRow, numCols() - 1 );
801 // we should always be able to wrap around and find this again,
802 // so don't give confusing not found message...
803 wrapAround = true;
804 }
805}
806
807int TodoTable::showCategoryId() const
808{
809 int id;
810 id = -1;
811 // if allcategories are selected, you get unfiled...
812 if ( showCat != tr( "Unfiled" ) && showCat != tr( "All" ) )
813 id = mCat.id( "Todo List", showCat );
814 return id;
815}
816
817static bool taskCompare( const Task &task, const QRegExp &r, int category )
818{
819 bool returnMe;
820 QArray<int> cats;
821 cats = task.categories();
822
823 returnMe = false;
824 if ( (category == -1 && cats.count() == 0) || category == -2 )
825 returnMe = task.match( r );
826 else {
827 int i;
828 for ( i = 0; i < int(cats.count()); i++ ) {
829 if ( cats[i] == category ) {
830 returnMe = task.match( r );
831 break;
832 }
833 }
834 }
835 return returnMe;
836}
837
838static QString journalFileName()
839{
840 QString str;
841 str = getenv( "HOME" );
842 str += "/.todojournal";
843 return str;
844}
845
846// int TodoTable::rowHeight( int ) const
847// {
848// return 18;
849// }
850
851// int TodoTable::rowPos( int row ) const
852// {
853// return 18*row;
854// }
855
856// int TodoTable::rowAt( int pos ) const
857// {
858// return QMIN( pos/18, numRows()-1 );
859// }
diff --git a/core/pim/todo/todotable.h b/core/pim/todo/todotable.h
new file mode 100644
index 0000000..4f3a064
--- a/dev/null
+++ b/core/pim/todo/todotable.h
@@ -0,0 +1,207 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia 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 TODOTABLE_H
22#define TODOTABLE_H
23
24#include <qpe/categories.h>
25#include <qpe/stringutil.h>
26#include <qpe/task.h>
27
28#include <qtable.h>
29#include <qmap.h>
30#include <qguardedptr.h>
31
32class Node;
33class QComboBox;
34class QTimer;
35
36class CheckItem : public QTableItem
37{
38public:
39 CheckItem( QTable *t, const QString &sortkey );
40
41 void setChecked( bool b );
42 void toggle();
43 bool isChecked() const;
44 void setKey( const QString &key ) { sortKey = key; }
45 QString key() const;
46
47 void paint( QPainter *p, const QColorGroup &cg, const QRect &cr, bool selected );
48
49private:
50 bool checked;
51 QString sortKey;
52};
53
54class ComboItem : public QTableItem
55{
56public:
57 ComboItem( QTable *t, EditType et );
58 QWidget *createEditor() const;
59 void setContentFromEditor( QWidget *w );
60 void setText( const QString &s );
61 int alignment() const { return Qt::AlignCenter; }
62
63 QString text() const;
64
65private:
66 QGuardedPtr<QComboBox> cb;
67
68};
69
70class TodoTextItem : public QTableItem
71{
72public:
73 TodoTextItem( QTable *t, const QString & str )
74 :QTableItem( t, QTableItem::Never, str ) {}
75
76 QString key () const { return Qtopia::buildSortKey( text() ); }
77};
78
79
80
81enum journal_action { ACTION_ADD, ACTION_REMOVE, ACTION_REPLACE };
82
83class TodoTable : public QTable
84{
85 Q_OBJECT
86
87public:
88 TodoTable( QWidget *parent = 0, const char * name = 0 );
89 void addEntry( const Task &todo );
90 void clearFindRow() { currFindRow = -2; }
91
92 Task currentEntry() const;
93 void replaceCurrentEntry( const Task &todo, bool fromTableItem = false );
94
95 QStringList categories();
96
97 void setShowCompleted( bool sc ) { showComp = sc; updateVisible(); }
98 bool showCompleted() const { return showComp; }
99
100 void setShowCategory( const QString &c ) { showCat = c; updateVisible(); }
101 const QString &showCategory() const { return showCat; }
102 int showCategoryId() const;
103
104 bool save( const QString &fn );
105 void load( const QString &fn );
106 void clear();
107 void removeCurrentEntry();
108
109 void setPaintingEnabled( bool e );
110
111 virtual void sortColumn( int col, bool ascending, bool /*wholeRows*/ );
112
113// int rowHeight( int ) const;
114// int rowPos( int row ) const;
115// virtual int rowAt( int pos ) const;
116
117signals:
118 void signalEdit();
119 void signalDoneChanged( bool b );
120 void signalPriorityChanged( int i );
121 void signalShowMenu( const QPoint & );
122 void signalNotFound();
123 void signalWrapAround();
124
125protected:
126 void keyPressEvent( QKeyEvent *e );
127
128private:
129 void updateVisible();
130 void viewportPaintEvent( QPaintEvent * );
131 void internalAddEntries( QList<Task> &list);
132 inline void insertIntoTable( Task *todo, int row );
133 void updateJournal( const Task &todo, journal_action action, int row = -1);
134 void mergeJournal();
135 void journalFreeReplaceEntry( const Task &todo, int row );
136 void journalFreeRemoveEntry( int row );
137 inline void realignTable( int row );
138 void loadFile( const QString &strFile, bool fromJournal = false );
139
140private slots:
141 void slotClicked( int row, int col, int button, const QPoint &pos );
142 void slotPressed( int row, int col, int button, const QPoint &pos );
143 void slotCheckPriority(int row, int col );
144 void slotCurrentChanged(int row, int col );
145 void slotDoFind( const QString &findString, bool caseSensetive,
146 bool backwards, int category );
147 void slotShowMenu();
148 void rowHeightChanged( int row );
149
150private:
151 friend class TodoWindow;
152
153 QMap<CheckItem*, Task *> todoList;
154 QStringList categoryList;
155 bool showComp;
156 QString showCat;
157 QTimer *menuTimer;
158 bool enablePainting;
159 Categories mCat;
160 int currFindRow;
161};
162
163
164inline void TodoTable::insertIntoTable( Task *todo, int row )
165{
166 QString sortKey = (char) ((todo->isCompleted() ? 'a' : 'A')
167 + todo->priority() )
168 + Qtopia::buildSortKey( todo->description() );
169 CheckItem *chk = new CheckItem( this, sortKey );
170 chk->setChecked( todo->isCompleted() );
171 ComboItem *cmb = new ComboItem( this, QTableItem::WhenCurrent );
172 cmb->setText( QString::number( todo->priority() ) );
173 QTableItem *ti = new TodoTextItem( this, todo->description().left(40).simplifyWhiteSpace() );
174 ti->setReplaceable( false );
175
176 setItem( row, 0, chk );
177 setItem( row, 1, cmb );
178 setItem( row, 2, ti );
179
180 todoList.insert( chk, todo );
181}
182
183inline void TodoTable::realignTable( int row )
184{
185 QTableItem *ti1,
186 *ti2,
187 *ti3;
188 int totalRows = numRows();
189 for ( int curr = row; curr < totalRows - 1; curr++ ) {
190 // this is bad, we must take the item out and then
191 // set it. In the end, it behaves no worse (time wise)
192 // then the old way of saving the entries to file, clearing
193 // the table re-reading in the file and resetting the table
194 ti1 = item( curr + 1, 0 );
195 ti2 = item( curr + 1, 1 );
196 ti3 = item( curr + 1, 2 );
197 takeItem( ti1 );
198 takeItem( ti2 );
199 takeItem( ti3 );
200 setItem( curr, 0, ti1 );
201 setItem( curr, 1, ti2 );
202 setItem( curr, 2, ti3 );
203 }
204 setNumRows( totalRows - 1 );
205}
206
207#endif