summaryrefslogtreecommitdiff
path: root/core/pim
Side-by-side diff
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 @@
+moc_*
+Makefile
+abeditorbase.h
+abaddress.h
+abcompanybase.h
+abnamebase.h
+abeditorbase.cpp
+abaddress.cpp
+abcompanybase.cpp
+abnamebase.cpp
+abeditorpage2base.ui
+abeditorpage2base.h
+abeditorpage2base.cpp
+addresssettingsbase.h
+addresssettingsbase.cpp
+
diff --git a/core/pim/addressbook/Makefile.in b/core/pim/addressbook/Makefile.in
new file mode 100644
index 0000000..93c73c3
--- a/dev/null
+++ b/core/pim/addressbook/Makefile.in
@@ -0,0 +1,244 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS)
+INCPATH = -I$(QPEDIR)/include
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = $(QPEDIR)/bin/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = addressbook
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = addressbook.h \
+ abeditor.h \
+ ablabel.h \
+ abtable.h \
+ addresssettings.h
+SOURCES = main.cpp \
+ addressbook.cpp \
+ abeditor.cpp \
+ ablabel.cpp \
+ abtable.cpp \
+ addresssettings.cpp
+OBJECTS = main.o \
+ addressbook.o \
+ abeditor.o \
+ ablabel.o \
+ abtable.o \
+ addresssettings.o \
+ addresssettingsbase.o
+INTERFACES = addresssettingsbase.ui
+UICDECLS = addresssettingsbase.h
+UICIMPLS = addresssettingsbase.cpp
+SRCMOC = moc_addressbook.cpp \
+ moc_abeditor.cpp \
+ moc_ablabel.cpp \
+ moc_abtable.cpp \
+ moc_addresssettings.cpp \
+ moc_addresssettingsbase.cpp
+OBJMOC = moc_addressbook.o \
+ moc_abeditor.o \
+ moc_ablabel.o \
+ moc_abtable.o \
+ moc_addresssettings.o \
+ moc_addresssettingsbase.o
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(TARGET)
+
+$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake p4addressbook.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+main.o: main.cpp \
+ addressbook.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ $(QPEDIR)/include/qpe/qcopenvelope_qws.h
+
+addressbook.o: addressbook.cpp \
+ abeditor.h \
+ $(QPEDIR)/include/qpe/contact.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h \
+ $(QPEDIR)/include/qpe/recordfields.h \
+ ablabel.h \
+ abtable.h \
+ $(QPEDIR)/include/qpe/categories.h \
+ addresssettings.h \
+ addresssettingsbase.h \
+ addressbook.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ $(QPEDIR)/include/qpe/config.h \
+ $(QPEDIR)/include/qpe/finddialog.h \
+ $(QPEDIR)/include/qpe/global.h \
+ $(QPEDIR)/include/qpe/resource.h \
+ $(QPEDIR)/include/qpe/ir.h \
+ $(QPEDIR)/include/qpe/qpemessagebox.h \
+ $(QPEDIR)/include/qpe/qcopenvelope_qws.h \
+ $(QPEDIR)/include/qpe/qpemenubar.h \
+ $(QPEDIR)/include/qpe/qpetoolbar.h
+
+abeditor.o: abeditor.cpp \
+ abeditor.h \
+ $(QPEDIR)/include/qpe/contact.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h \
+ $(QPEDIR)/include/qpe/recordfields.h \
+ addresspicker.h \
+ $(QPEDIR)/include/qpe/categoryselect.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ $(QPEDIR)/include/qpe/qpedialog.h
+
+ablabel.o: ablabel.cpp \
+ ablabel.h \
+ $(QPEDIR)/include/qpe/contact.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h \
+ $(QPEDIR)/include/qpe/recordfields.h \
+ $(QPEDIR)/include/qpe/stringutil.h
+
+abtable.o: abtable.cpp \
+ $(QPEDIR)/include/qpe/categoryselect.h \
+ $(QPEDIR)/include/qpe/config.h \
+ $(QPEDIR)/include/qpe/stringutil.h \
+ $(QPEDIR)/include/qpe/qcopenvelope_qws.h \
+ abtable.h \
+ $(QPEDIR)/include/qpe/categories.h \
+ $(QPEDIR)/include/qpe/contact.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h \
+ $(QPEDIR)/include/qpe/recordfields.h
+
+addresssettings.o: addresssettings.cpp \
+ addresssettings.h \
+ addresssettingsbase.h \
+ $(QPEDIR)/include/qpe/config.h \
+ $(QPEDIR)/include/qpe/contact.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h \
+ $(QPEDIR)/include/qpe/recordfields.h
+
+addresssettingsbase.h: addresssettingsbase.ui
+ $(UIC) addresssettingsbase.ui -o $(INTERFACE_DECL_PATH)/addresssettingsbase.h
+
+addresssettingsbase.cpp: addresssettingsbase.ui
+ $(UIC) addresssettingsbase.ui -i addresssettingsbase.h -o addresssettingsbase.cpp
+
+addresssettingsbase.o: addresssettingsbase.cpp \
+ addresssettingsbase.h \
+ addresssettingsbase.ui
+
+moc_addressbook.o: moc_addressbook.cpp \
+ addressbook.h
+
+moc_abeditor.o: moc_abeditor.cpp \
+ abeditor.h \
+ $(QPEDIR)/include/qpe/contact.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h \
+ $(QPEDIR)/include/qpe/recordfields.h
+
+moc_ablabel.o: moc_ablabel.cpp \
+ ablabel.h \
+ $(QPEDIR)/include/qpe/contact.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h \
+ $(QPEDIR)/include/qpe/recordfields.h
+
+moc_abtable.o: moc_abtable.cpp \
+ abtable.h \
+ $(QPEDIR)/include/qpe/categories.h \
+ $(QPEDIR)/include/qpe/contact.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h \
+ $(QPEDIR)/include/qpe/recordfields.h
+
+moc_addresssettings.o: moc_addresssettings.cpp \
+ addresssettings.h \
+ addresssettingsbase.h
+
+moc_addresssettingsbase.o: moc_addresssettingsbase.cpp \
+ addresssettingsbase.h
+
+moc_addressbook.cpp: addressbook.h
+ $(MOC) addressbook.h -o moc_addressbook.cpp
+
+moc_abeditor.cpp: abeditor.h
+ $(MOC) abeditor.h -o moc_abeditor.cpp
+
+moc_ablabel.cpp: ablabel.h
+ $(MOC) ablabel.h -o moc_ablabel.cpp
+
+moc_abtable.cpp: abtable.h
+ $(MOC) abtable.h -o moc_abtable.cpp
+
+moc_addresssettings.cpp: addresssettings.h
+ $(MOC) addresssettings.h -o moc_addresssettings.cpp
+
+moc_addresssettingsbase.cpp: addresssettingsbase.h
+ $(MOC) addresssettingsbase.h -o moc_addresssettingsbase.cpp
+
+
diff --git a/core/pim/addressbook/abeditor.cpp b/core/pim/addressbook/abeditor.cpp
new file mode 100644
index 0000000..6354db9
--- a/dev/null
+++ b/core/pim/addressbook/abeditor.cpp
@@ -0,0 +1,619 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qt Palmtop Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "abeditor.h"
+#include "addresspicker.h"
+
+#include <qpe/categoryselect.h>
+#include <qpe/qpeapplication.h>
+#include <qpe/qpedialog.h>
+
+#include <qcombobox.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qlineedit.h>
+#include <qmultilineedit.h>
+#include <qscrollview.h>
+#include <qtoolbutton.h>
+#include <qpushbutton.h>
+#include <qmainwindow.h>
+
+
+static inline bool containsAlphaNum( const QString &str );
+static inline bool constainsWhiteSpace( const QString &str );
+
+
+// helper functions, convert our comma delimited list to proper
+// file format...
+void parseEmailFrom( const QString &txt, QString &strDefaultEmail,
+ QString &strAll );
+
+// helper convert from file format to comma delimited...
+void parseEmailTo( const QString &strDefaultEmail,
+ const QString &strOtherEmail, QString &strBack );
+
+
+
+AbEditor::AbEditor( const Contact &entry, const QValueList<int> *newOrdered,
+ QStringList *slNewOrdered,
+ QWidget *parent = 0, const char *name = 0, WFlags fl = 0 )
+ : QDialog( parent, name, TRUE, fl ),
+ orderedValues( newOrdered ),
+ slOrdered( slNewOrdered )
+{
+ init();
+ initMap();
+ setEntry( entry );
+}
+
+AbEditor::~AbEditor()
+{
+}
+
+void AbEditor::init()
+{
+ middleEdit = 0;
+ QVBoxLayout *vb = new QVBoxLayout( this );
+ svPage = new QScrollView( this );
+ svPage->setHScrollBarMode( QScrollView::AlwaysOff );
+ vb->addWidget( svPage );
+ svPage->setResizePolicy( QScrollView::AutoOneFit );
+ svPage->setFrameStyle( QFrame::NoFrame );
+
+ QWidget *container = new QWidget( svPage->viewport() );
+ svPage->addChild( container );
+
+ QGridLayout *gl = new QGridLayout( container, 20, 2, 4, 2 );
+
+ QLabel *l = new QLabel( tr("First Name"), container );
+ gl->addWidget( l, 0, 0 );
+ firstEdit = new QLineEdit( container );
+ gl->addWidget( firstEdit, 0, 1 );
+
+ l = new QLabel( tr("Last Name"), container );
+ gl->addWidget( l, 1, 0 );
+ lastEdit = new QLineEdit( container );
+ gl->addWidget( lastEdit, 1, 1 );
+
+ l = new QLabel( tr("Categories"), container );
+ gl->addWidget( l, 2, 0 );
+
+ cmbCat = new CategorySelect( container );
+ gl->addWidget( cmbCat, 2, 1 );
+
+ int i;
+ bool foundGender,
+ foundNotes;
+ foundGender = foundNotes = false;
+ QStringList::ConstIterator it = slOrdered->begin();
+ for ( i = 0; it != slOrdered->end(); i++, ++it ) {
+ if ( !foundGender && *it == tr("Gender") ) {
+ foundGender = true;
+ } else if ( !foundNotes && *it == tr("Notes") ) {
+ foundNotes = true;
+ } else {
+ l = new QLabel( *it, container );
+ listName.append( l );
+ gl->addWidget( l, i + 3, 0 );
+ QLineEdit *e = new QLineEdit( container );
+ listValue.append( e );
+ gl->addWidget( e, i + 3, 1 );
+ if ( *it == tr( "Middle Name" ) )
+ middleEdit = e;
+ }
+ }
+ l = new QLabel( tr("Gender"), container );
+ gl->addWidget( l, slOrdered->count() + 3, 0 );
+ genderCombo = new QComboBox( container );
+ genderCombo->insertItem( "", 0 );
+ genderCombo->insertItem( tr( "Male" ), 1 );
+ genderCombo->insertItem( tr( "Female" ), 2 );
+ gl->addWidget( genderCombo, slOrdered->count() + 3, 1 );
+
+ dlgNote = new QDialog( this, "Note Dialog", TRUE );
+ dlgNote->setCaption( tr("Enter Note") );
+ QVBoxLayout *vbNote = new QVBoxLayout( dlgNote );
+ // lblNote = new QLabel( dlgNote );
+ // lblNote->setMinimumSize( lblNote->sizeHint() + QSize( 0, 4 ) );
+ // vbNote->addWidget( lblNote );
+ txtNote = new QMultiLineEdit( dlgNote );
+ vbNote->addWidget( txtNote );
+
+ QHBoxLayout *hb = new QHBoxLayout( vb );
+ hb->addStretch( 2 );
+ QPushButton *pb = new QPushButton( tr("Notes..."), this );
+ hb->addWidget( pb );
+ connect( pb, SIGNAL(clicked()), this, SLOT(slotNote()) );
+
+ new QPEDialogListener(this);
+}
+
+void AbEditor::initMap()
+{
+ /*
+ // since the fields and the XML fields exist, create a map
+ // between them...
+ Config cfg1( "AddressBook" );
+ Config cfg2( "AddressBook" );
+ QString strCfg1,
+ strCfg2;
+ int i;
+
+ // This stuff better exist...
+ cfg1.setGroup( "AddressFields" );
+ cfg2.setGroup( "XMLFields" );
+ i = 0;
+ strCfg1 = cfg1.readEntry( "Field" + QString::number(i), QString::null );
+ strCfg2 = cfg2.readEntry( "XMLField" + QString::number(i++),
+ QString::null );
+ while ( !strCfg1.isNull() && !strCfg2.isNull() ) {
+ mapField.insert( strCfg1, strCfg2 );
+ strCfg1 = cfg1.readEntry( "Field" + QString::number(i),
+ QString::null );
+ strCfg2 = cfg2.readEntry( "XMLField" + QString::number(i++),
+ QString::null );
+ }
+ */
+}
+
+void AbEditor::loadFields()
+{
+ QStringList::ConstIterator it;
+ QListIterator<QLabel> lit( listName );
+ for ( it = slOrdered->begin(); *lit; ++lit, ++it ) {
+ (*lit)->setText( *it );
+ }
+}
+
+void AbEditor::setEntry( const Contact &entry )
+{
+ ent = entry;
+ QListIterator<QLineEdit> it( listValue );
+ firstEdit->setText( ent.firstName() );
+ lastEdit->setText( ent.lastName() );
+ cmbCat->setCategories( ent.categories(), "Contacts", tr("Contacts") );
+
+ // ### Fix...
+ QValueList<int>::ConstIterator itVl;
+ for ( itVl = orderedValues->begin(); *it && itVl != orderedValues->end();
+ ++itVl, ++it ) {
+ switch( *itVl ) {
+ case Qtopia::Title:
+ (*it)->setText(ent.title());
+ break;
+ case Qtopia::MiddleName:
+ (*it)->setText( ent.middleName() );
+ break;
+ case Qtopia::Suffix:
+ (*it)->setText( ent.suffix() );
+ break;
+
+ // email
+ case Qtopia::DefaultEmail:
+ case Qtopia::Emails:
+ {
+ QString strDefEmail = ent.defaultEmail();
+ QString strAllEmail = ent.emails();
+ QString strFinal;
+ parseEmailTo( strDefEmail, strAllEmail, strFinal );
+ (*it)->setText( strFinal );
+ // make sure we see the "default"
+ (*it)->home( false );
+ break;
+ }
+
+ // home
+ case Qtopia::HomeStreet:
+ (*it)->setText(ent.homeStreet() );
+ break;
+ case Qtopia::HomeCity:
+ (*it)->setText( ent.homeCity() );
+ break;
+ case Qtopia::HomeState:
+ (*it)->setText( ent.homeState() );
+ break;
+ case Qtopia::HomeZip:
+ (*it)->setText( ent.homeZip() );
+ break;
+ case Qtopia::HomeCountry:
+ (*it)->setText( ent.homeCountry() );
+ break;
+ case Qtopia::HomePhone:
+ (*it)->setText( ent.homePhone() );
+ break;
+ case Qtopia::HomeFax:
+ (*it)->setText( ent.homeFax() );
+ break;
+ case Qtopia::HomeMobile:
+ (*it)->setText( ent.homeMobile() );
+ break;
+ case Qtopia::HomeWebPage:
+ (*it)->setText( ent.homeWebpage() );
+ break;
+
+ // business
+ case Qtopia::Company:
+ (*it)->setText( ent.company() );
+ break;
+ case Qtopia::BusinessStreet:
+ (*it)->setText( ent.businessStreet() );
+ break;
+ case Qtopia::BusinessCity:
+ (*it)->setText( ent.businessCity() );
+ break;
+ case Qtopia::BusinessState:
+ (*it)->setText( ent.businessState() );
+ break;
+ case Qtopia::BusinessZip:
+ (*it)->setText( ent.businessZip() );
+ break;
+ case Qtopia::BusinessCountry:
+ (*it)->setText( ent.businessCountry() );
+ break;
+ case Qtopia::BusinessWebPage:
+ (*it)->setText( ent.businessWebpage() );
+ break;
+ case Qtopia::JobTitle:
+ (*it)->setText( ent.jobTitle() );
+ break;
+ case Qtopia::Department:
+ (*it)->setText( ent.department() );
+ break;
+ case Qtopia::Office:
+ (*it)->setText( ent.office() );
+ break;
+ case Qtopia::BusinessPhone:
+ (*it)->setText( ent.businessPhone() );
+ break;
+ case Qtopia::BusinessFax:
+ (*it)->setText( ent.businessFax() );
+ break;
+ case Qtopia::BusinessMobile:
+ (*it)->setText( ent.businessMobile() );
+ break;
+ case Qtopia::BusinessPager:
+ (*it)->setText( ent.businessPager() );
+ break;
+ case Qtopia::Profession:
+ (*it)->setText( ent.profession() );
+ break;
+ case Qtopia::Assistant:
+ (*it)->setText( ent.assistant() );
+ break;
+ case Qtopia::Manager:
+ (*it)->setText( ent.manager() );
+ break;
+
+ // personal
+ case Qtopia::Spouse:
+ (*it)->setText( ent.spouse() );
+ break;
+ case Qtopia::Children:
+ (*it)->setText( ent.children() );
+ break;
+ case Qtopia::Birthday:
+ (*it)->setText( ent.birthday() );
+ break;
+ case Qtopia::Anniversary:
+ (*it)->setText( ent.anniversary() );
+ break;
+ case Qtopia::Nickname:
+ (*it)->setText( ent.nickname() );
+ break;
+
+ }
+ }
+
+ QString gender = ent.gender();
+ genderCombo->setCurrentItem( gender.toInt() );
+
+ txtNote->setText( ent.notes() );
+}
+
+void AbEditor::accept()
+{
+ if ( isEmpty() )
+ reject();
+ else {
+ saveEntry();
+ QDialog::accept();
+ }
+}
+
+bool AbEditor::isEmpty()
+{
+ // analyze all the fields and make sure there is _something_ there
+ // that warrants saving...
+ QString t = firstEdit->text();
+ if ( !t.isEmpty() && containsAlphaNum( t ) )
+ return false;
+
+ t = lastEdit->text();
+ if ( !t.isEmpty() && containsAlphaNum( t ) )
+ return false;
+
+ QListIterator<QLineEdit> it( listValue );
+ for ( ; it.current(); ++it ) {
+ t = it.current()->text();
+ if ( !t.isEmpty() && containsAlphaNum( t ) )
+ return false;
+ }
+
+ t = txtNote->text();
+ if ( !t.isEmpty() && containsAlphaNum( t ) )
+ return false;
+
+ return true;
+}
+
+void AbEditor::saveEntry()
+{
+ QString strDefaultEmail, strOtherEmail;
+
+ // determine if there has been a change in names
+ if ( ent.firstName() != firstEdit->text() ||
+ ent.lastName() != lastEdit->text()
+ || (middleEdit && ent.middleName() != middleEdit->text()) ) {
+ // set the names
+ ent.setFirstName( firstEdit->text() );
+ ent.setLastName( lastEdit->text() );
+ if ( middleEdit )
+ ent.setMiddleName( middleEdit->text() );
+ ent.setFileAs();
+ }
+
+ ent.setCategories( cmbCat->currentCategories() );
+
+ QListIterator<QLineEdit> it( listValue );
+ int i;
+ QValueList<int>::ConstIterator<int> vlIt;
+ for ( i = 0, vlIt = orderedValues->begin();
+ it.current(); ++it, ++vlIt, i++ ) {
+ switch( *vlIt ) {
+ case Qtopia::Title:
+ ent.setTitle( it.current()->text() );
+ break;
+ case Qtopia::MiddleName:
+ ent.setMiddleName( it.current()->text() );
+ break;
+ case Qtopia::Suffix:
+ ent.setSuffix( it.current()->text() );
+ break;
+// case Qtopia::Category:
+// {
+// // QStringList slCat = QStringList::split( ";", value );
+// // QValueList<int> cat;
+// // for ( QStringList::ConstIterator it = slCat.begin();
+// // it != slCat.end(); ++it )
+// // cat.append( (*it).toInt() );
+// // ent.setCategories( cat );
+// }
+// break;
+
+ // email
+ case Qtopia::DefaultEmail:
+ case Qtopia::Emails:
+ parseEmailFrom( it.current()->text(), strDefaultEmail,
+ strOtherEmail );
+ ent.setDefaultEmail( strDefaultEmail );
+ ent.setEmails( strOtherEmail );
+ break;
+
+ // home
+ case Qtopia::HomeStreet:
+ ent.setHomeStreet( it.current()->text() );
+ break;
+ case Qtopia::HomeCity:
+ ent.setHomeCity( it.current()->text() );
+ break;
+ case Qtopia::HomeState:
+ ent.setHomeState( it.current()->text() );
+ break;
+ case Qtopia::HomeZip:
+ ent.setHomeZip( it.current()->text() );
+ break;
+ case Qtopia::HomeCountry:
+ ent.setHomeCountry( it.current()->text() );
+ break;
+ case Qtopia::HomePhone:
+ ent.setHomePhone( it.current()->text() );
+ break;
+ case Qtopia::HomeFax:
+ ent.setHomeFax( it.current()->text() );
+ break;
+ case Qtopia::HomeMobile:
+ ent.setHomeMobile( it.current()->text() );
+ break;
+ case Qtopia::HomeWebPage:
+ ent.setHomeWebpage( it.current()->text() );
+ break;
+
+ // business
+ case Qtopia::Company:
+ ent.setCompany( it.current()->text() );
+ break;
+ case Qtopia::BusinessStreet:
+ ent.setBusinessStreet( it.current()->text() );
+ break;
+ case Qtopia::BusinessCity:
+ ent.setBusinessCity( it.current()->text() );
+ break;
+ case Qtopia::BusinessState:
+ ent.setBusinessState( it.current()->text() );
+ break;
+ case Qtopia::BusinessZip:
+ ent.setBusinessZip( it.current()->text() );
+ break;
+ case Qtopia::BusinessCountry:
+ ent.setBusinessCountry( it.current()->text() );
+ break;
+ case Qtopia::BusinessWebPage:
+ ent.setBusinessWebpage( it.current()->text() );
+ break;
+ case Qtopia::JobTitle:
+ ent.setJobTitle( it.current()->text() );
+ break;
+ case Qtopia::Department:
+ ent.setDepartment( it.current()->text() );
+ break;
+ case Qtopia::Office:
+ ent.setOffice( it.current()->text() );
+ break;
+ case Qtopia::BusinessPhone:
+ ent.setBusinessPhone( it.current()->text() );
+ break;
+ case Qtopia::BusinessFax:
+ ent.setBusinessFax( it.current()->text() );
+ break;
+ case Qtopia::BusinessMobile:
+ ent.setBusinessMobile( it.current()->text() );
+ break;
+ case Qtopia::BusinessPager:
+ ent.setBusinessPager( it.current()->text() );
+ break;
+ case Qtopia::Profession:
+ ent.setProfession( it.current()->text() );
+ break;
+ case Qtopia::Assistant:
+ ent.setAssistant( it.current()->text() );
+ break;
+ case Qtopia::Manager:
+ ent.setManager( it.current()->text() );
+ break;
+
+ // personal
+ case Qtopia::Spouse:
+ ent.setSpouse( it.current()->text() );
+ break;
+ case Qtopia::Children:
+ ent.setChildren( it.current()->text() );
+ break;
+ case Qtopia::Birthday:
+ ent.setBirthday( it.current()->text() );
+ break;
+ case Qtopia::Anniversary:
+ ent.setAnniversary( it.current()->text() );
+ break;
+ case Qtopia::Nickname:
+ ent.setNickname( it.current()->text() );
+ break;
+ default:
+ break;
+
+ }
+ }
+
+ int gender = genderCombo->currentItem();
+ ent.setGender( QString::number( gender ) );
+
+ QString str = txtNote->text();
+ if ( !str.isNull() )
+ ent.setNotes( str );
+}
+
+void AbEditor::slotNote()
+{
+ dlgNote->showMaximized();
+ if ( !dlgNote->exec() ) {
+ // reset the note...
+ txtNote->setText( ent.notes() );
+ }
+}
+
+void AbEditor::setNameFocus()
+{
+ firstEdit->setFocus();
+}
+
+void parseEmailFrom( const QString &txt, QString &strDefaultEmail,
+ QString &strAll )
+{
+ int where,
+ start;
+ if ( txt.isEmpty() )
+ return;
+ // find the first
+ where = txt.find( ',' );
+ if ( where < 0 ) {
+ strDefaultEmail = txt;
+ strAll = txt;
+ } else {
+ strDefaultEmail = txt.left( where ).stripWhiteSpace();
+ strAll = strDefaultEmail;
+ while ( where > -1 ) {
+ strAll.append(" ");
+ start = where;
+ where = txt.find( ',', where + 1 );
+ if ( where > - 1 )
+ strAll.append( txt.mid(start + 1, where - start - 1).stripWhiteSpace() );
+ else // grab until the end...
+ strAll.append( txt.right(txt.length() - start - 1).stripWhiteSpace() );
+ }
+ }
+}
+
+void parseEmailTo( const QString &strDefaultEmail,
+ const QString &strOtherEmail, QString &strBack )
+{
+ // create a comma dilimeted set of emails...
+ // use the power of short circuiting...
+ bool foundDefault = false;
+ QString strTmp;
+ int start = 0;
+ int where;
+ // start at the beginng.
+ strBack = strDefaultEmail;
+ where = 0;
+ while ( where > -1 ) {
+ start = where;
+ where = strOtherEmail.find( ' ', where + 1 );
+ if ( where > 0 ) {
+ strTmp = strOtherEmail.mid( start, where - start ).stripWhiteSpace();
+ } else
+ strTmp = strOtherEmail.right( strOtherEmail.length() - start ).stripWhiteSpace();
+ if ( foundDefault || strTmp != strDefaultEmail ) {
+ strBack.append( ", " );
+ strBack.append( strTmp );
+ } else
+ foundDefault = true;
+ }
+}
+
+
+static inline bool containsAlphaNum( const QString &str )
+{
+ int i,
+ count = str.length();
+ for ( i = 0; i < count; i++ )
+ if ( !str[i].isSpace() )
+ return TRUE;
+ return FALSE;
+}
+
+static inline bool constainsWhiteSpace( const QString &str )
+{
+ int i,
+ count = str.length();
+ for (i = 0; i < count; i++ )
+ if ( str[i].isSpace() )
+ return TRUE;
+ return FALSE;
+}
+
diff --git a/core/pim/addressbook/abeditor.h b/core/pim/addressbook/abeditor.h
new file mode 100644
index 0000000..9ce6704
--- a/dev/null
+++ b/core/pim/addressbook/abeditor.h
@@ -0,0 +1,79 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qt Palmtop Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef ABEDITOR_H
+#define ABEDITOR_H
+
+#include <qpe/contact.h>
+
+#include <qdialog.h>
+#include <qlist.h>
+#include <qmap.h>
+#include <qstringlist.h>
+
+class QScrollView;
+class QMultiLineEdit;
+class QLineEdit;
+class QLabel;
+class QComboBox;
+class CategorySelect;
+
+class AbEditor : public QDialog
+{
+ Q_OBJECT
+public:
+ AbEditor( const Contact &entry, const QValueList<int> *newOrdedValues,
+ QStringList *slNewOrdered,
+ QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );
+ ~AbEditor();
+ void loadFields();
+ void setNameFocus();
+ Contact entry() const { return ent; }
+
+public slots:
+ void slotNote();
+ void setEntry( const Contact &entry );
+
+protected slots:
+ void accept();
+
+private:
+ void init();
+ void initMap();
+ void saveEntry();
+ bool isEmpty();
+
+private:
+ QDialog *dlgNote;
+ QLabel *lblNote;
+ QMultiLineEdit *txtNote;
+ Contact ent;
+ QScrollView *svPage;
+ QLineEdit *firstEdit;
+ QLineEdit *lastEdit;
+ QLineEdit *middleEdit;
+ QComboBox *genderCombo;
+ QList<QLineEdit> listValue;
+ QList<QLabel> listName;
+ const QValueList<int> *orderedValues;
+ QStringList *slOrdered;
+ CategorySelect *cmbCat;
+};
+
+#endif
diff --git a/core/pim/addressbook/ablabel.cpp b/core/pim/addressbook/ablabel.cpp
new file mode 100644
index 0000000..3bf3e12
--- a/dev/null
+++ b/core/pim/addressbook/ablabel.cpp
@@ -0,0 +1,53 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qt Palmtop Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "ablabel.h"
+
+#include <qpe/stringutil.h>
+
+#include <qregexp.h>
+#include <qstylesheet.h>
+
+AbLabel::AbLabel( QWidget *parent, const char *name )
+ : QTextView( parent, name )
+{
+}
+
+AbLabel::~AbLabel()
+{
+}
+
+void AbLabel::init( const Contact &entry )
+{
+ ent = entry;
+}
+
+void AbLabel::sync()
+{
+ QString text = ent.toRichText();
+ setText( text );
+}
+
+void AbLabel::keyPressEvent( QKeyEvent *e )
+{
+ if ( e->key() == Qt::Key_F33 ) {
+ emit okPressed();
+ }
+}
diff --git a/core/pim/addressbook/ablabel.h b/core/pim/addressbook/ablabel.h
new file mode 100644
index 0000000..cfbd999
--- a/dev/null
+++ b/core/pim/addressbook/ablabel.h
@@ -0,0 +1,50 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qt Palmtop Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef ABLABEL_H
+#define ABLABEL_H
+
+#include <qpe/contact.h>
+#include <qtextview.h>
+
+class AbLabel : public QTextView
+{
+ Q_OBJECT
+
+public:
+ AbLabel( QWidget *parent, const char *name = 0 );
+ ~AbLabel();
+
+public slots:
+ void init( const Contact &entry );
+ void sync();
+
+signals:
+ void okPressed();
+
+protected:
+ void keyPressEvent( QKeyEvent * );
+
+private:
+ Contact ent;
+
+};
+
+#endif // ABLABEL_H
+
diff --git a/core/pim/addressbook/abtable.cpp b/core/pim/addressbook/abtable.cpp
new file mode 100644
index 0000000..0911edf
--- a/dev/null
+++ b/core/pim/addressbook/abtable.cpp
@@ -0,0 +1,1091 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qt Palmtop Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include <qpe/categoryselect.h>
+#include <qpe/config.h>
+#include <qpe/stringutil.h>
+#include <qpe/qcopenvelope_qws.h>
+
+#include <qasciidict.h>
+#include <qdatetime.h>
+#include <qfile.h>
+
+#include "abtable.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include <ctype.h> //toupper() for key hack
+
+static bool contactCompare( const Contact &cnt, const QRegExp &r, int category );
+
+//### qtmail/addresslist.cpp hardcodes this filename as well
+static QString journalFileName()
+{
+ QString str = getenv("HOME");
+ str +="/.abjournal";
+ return str;
+}
+
+
+
+/*!
+ \class AbTableItem abtable.h
+
+ \brief QTableItem based class for showing a field of an entry
+*/
+
+AbTableItem::AbTableItem( QTable *t, EditType et, const QString &s,
+ const QString &secondSortKey)
+ : QTableItem( t, et, s )
+{
+ // sortKey = s.lower() + QChar( '\0' ) + secondSortKey.lower();
+ sortKey = Qtopia::buildSortKey( s, secondSortKey );
+}
+
+int AbTableItem::alignment() const
+{
+ return AlignLeft|AlignVCenter;
+}
+
+QString AbTableItem::key() const
+{
+ return sortKey;
+}
+
+// A way to reset the item, without out doing a delete or a new...
+void AbTableItem::setItem( const QString &txt, const QString &secondKey )
+{
+ setText( txt );
+ sortKey = Qtopia::buildSortKey( txt, secondKey );
+
+ // sortKey = txt.lower() + QChar( '\0' ) + secondKey.lower();
+}
+
+/*!
+ \class AbPickItem abtable.h
+
+ \brief QTableItem based class for showing slection of an entry
+*/
+
+AbPickItem::AbPickItem( QTable *t ) :
+ QTableItem(t, WhenCurrent, "?")
+{
+}
+
+QWidget *AbPickItem::createEditor() const
+{
+ QComboBox* combo = new QComboBox( table()->viewport() );
+ ( (AbPickItem*)this )->cb = combo;
+ AbTable* t = static_cast<AbTable*>(table());
+ QStringList c = t->choiceNames();
+ int cur = 0;
+ for (QStringList::ConstIterator it = c.begin(); it!=c.end(); ++it) {
+ if ( *it == text() )
+ cur = combo->count();
+ combo->insertItem(*it);
+ }
+ combo->setCurrentItem(cur);
+ return combo;
+}
+
+void AbPickItem::setContentFromEditor( QWidget *w )
+{
+ if ( w->inherits("QComboBox") )
+ setText( ( (QComboBox*)w )->currentText() );
+ else
+ QTableItem::setContentFromEditor( w );
+}
+
+/*!
+ \class AbTable abtable.h
+
+ \brief QTable based class for showing a list of entries
+*/
+
+AbTable::AbTable( const QValueList<int> *order, QWidget *parent, const char *name )
+// #ifdef QT_QTABLE_NOHEADER_CONSTRUCTOR
+// : QTable( 0, 0, parent, name, TRUE ),
+// #else
+ : QTable( parent, name ),
+// #endif
+ lastSortCol( -1 ),
+ asc( TRUE ),
+ intFields( order ),
+ currFindRow( -2 ),
+ mCat( 0 )
+{
+ mCat.load( categoryFileName() );
+ setSelectionMode( NoSelection );
+ init();
+ setSorting( TRUE );
+ connect( this, SIGNAL(clicked(int,int,int,const QPoint &)),
+ this, SLOT(itemClicked(int,int)) );
+}
+
+AbTable::~AbTable()
+{
+}
+
+void AbTable::init()
+{
+ setNumRows( 0 );
+ setNumCols( 2 );
+
+ horizontalHeader()->setLabel( 0, tr( "Full Name" ));
+ horizontalHeader()->setLabel( 1, tr( "Contact" ));
+ setLeftMargin( 0 );
+ verticalHeader()->hide();
+}
+
+void AbTable::columnClicked( int col )
+{
+ if ( !sorting() )
+ return;
+
+ if ( lastSortCol == -1 )
+ lastSortCol = col;
+
+ if ( col == lastSortCol ) {
+ asc = !asc;
+ } else {
+ lastSortCol = col;
+ asc = TRUE;
+ }
+ resort();
+}
+
+void AbTable::resort()
+{
+ if ( sorting() ) {
+ if ( lastSortCol == -1 )
+ lastSortCol = 0;
+ sortColumn( lastSortCol, asc, TRUE );
+ updateVisible();
+ }
+}
+
+Contact AbTable::currentEntry()
+{
+ Contact cnt;
+ AbTableItem *abItem;
+ abItem = static_cast<AbTableItem*>(item( currentRow(), 0 ));
+ if ( abItem ) {
+ cnt = contactList[abItem];
+ }
+ return cnt;
+}
+
+void AbTable::replaceCurrentEntry( const Contact &newContact )
+{
+ int row = currentRow();
+ updateJournal( newContact, Contact::ACTION_REPLACE, row );
+ updateVisible();
+
+ journalFreeReplace( newContact, row );
+}
+
+void AbTable::deleteCurrentEntry()
+{
+ int row = currentRow();
+ AbTableItem *abItem;
+ abItem = static_cast<AbTableItem*>(item( row, 0 ));
+ Contact oldContact;
+ oldContact = contactList[abItem];
+ updateJournal( oldContact, Contact::ACTION_REMOVE, row );
+
+ // a little wasteful, but it ensure's there is only one place
+ // where we delete.
+ journalFreeRemove( row );
+ updateVisible();
+
+ if ( numRows() == 0 )
+ emit empty( TRUE );
+}
+
+void AbTable::clear()
+{
+ contactList.clear();
+ for ( int r = 0; r < numRows(); ++r ) {
+ for ( int c = 0; c < numCols(); ++c ) {
+ if ( cellWidget( r, c ) )
+ clearCellWidget( r, c );
+ clearCell( r, c );
+ }
+ }
+ setNumRows( 0 );
+}
+
+void AbTable::refresh()
+{
+ int rows = numRows();
+ QString value;
+ AbTableItem *abi;
+ for ( int r = 0; r < rows; ++r ) {
+ abi = static_cast<AbTableItem*>( item(r, 0) );
+ value = findContactContact( contactList[abi] );
+ static_cast<AbTableItem*>( item(r, 1) )->setItem( value, abi->text() );
+ }
+ resort();
+}
+
+void AbTable::keyPressEvent( QKeyEvent *e )
+{
+ char key = toupper( e->ascii() );
+
+ if ( key >= 'A' && key <= 'Z' )
+ moveTo( key );
+
+ switch( e->key() ) {
+ case Qt::Key_Space:
+ case Qt::Key_Return:
+ case Qt::Key_Enter:
+ emit details();
+ break;
+ default:
+ QTable::keyPressEvent( e );
+ }
+}
+
+void AbTable::moveTo( char c )
+{
+
+ int rows = numRows();
+ QString value;
+ AbTableItem *abi;
+ int r;
+ if ( asc ) {
+ r = 0;
+ while ( r < rows-1) {
+ abi = static_cast<AbTableItem*>( item(r, 0) );
+ QChar first = abi->key()[0];
+ //### is there a bug in QChar to char comparison???
+ if ( first.row() || first.cell() >= c )
+ break;
+ r++;
+ }
+ } else {
+ //### should probably disable reverse sorting instead
+ r = rows - 1;
+ while ( r > 0 ) {
+ abi = static_cast<AbTableItem*>( item(r, 0) );
+ QChar first = abi->key()[0];
+ //### is there a bug in QChar to char comparison???
+ if ( first.row() || first.cell() >= c )
+ break;
+ r--;
+ }
+ }
+ setCurrentCell( r, currentColumn() );
+}
+
+
+QString AbTable::findContactName( const Contact &entry )
+{
+ // We use the fileAs, then company, defaultEmail
+ QString str;
+ str = entry.fileAs();
+ if ( str.isEmpty() ) {
+ str = entry.company();
+ if ( str.isEmpty() ) {
+ str = entry.defaultEmail();
+ }
+ }
+ return str;
+}
+
+QString AbTable::findContactContact( const Contact &entry )
+{
+ QString value;
+ value = "";
+ for ( QValueList<int>::ConstIterator it = intFields->begin();
+ it != intFields->end(); ++it ) {
+ switch ( *it ) {
+ default:
+ break;
+ case Qtopia::Title:
+ value = entry.title();
+ break;
+ case Qtopia::Suffix:
+ value = entry.suffix();
+ break;
+ case Qtopia::FileAs:
+ value = entry.fileAs();
+ break;
+ case Qtopia::DefaultEmail:
+ value = entry.defaultEmail();
+ case Qtopia::Emails:
+ value = entry.emails();
+ break;
+ case Qtopia::HomeStreet:
+ value = entry.homeStreet();
+ break;
+ case Qtopia::HomeCity:
+ value = entry.homeCity();
+ break;
+ case Qtopia::HomeState:
+ value = entry.homeState();
+ break;
+ case Qtopia::HomeZip:
+ value = entry.homeZip();
+ break;
+ case Qtopia::HomeCountry:
+ value = entry.homeCountry();
+ break;
+ case Qtopia::HomePhone:
+ value = entry.homePhone();
+ break;
+ case Qtopia::HomeFax:
+ value = entry.homeFax();
+ break;
+ case Qtopia::HomeMobile:
+ value = entry.homeMobile();
+ break;
+ case Qtopia::HomeWebPage:
+ value = entry.homeWebpage();
+ break;
+ case Qtopia::Company:
+ value = entry.company();
+ break;
+ case Qtopia::BusinessCity:
+ value = entry.businessCity();
+ break;
+ case Qtopia::BusinessStreet:
+ value = entry.businessStreet();
+ break;
+ case Qtopia::BusinessZip:
+ value = entry.businessZip();
+ break;
+ case Qtopia::BusinessCountry:
+ value = entry.businessCountry();
+ break;
+ case Qtopia::BusinessWebPage:
+ value = entry.businessWebpage();
+ break;
+ case Qtopia::JobTitle:
+ value = entry.jobTitle();
+ break;
+ case Qtopia::Department:
+ value = entry.department();
+ break;
+ case Qtopia::Office:
+ value = entry.office();
+ break;
+ case Qtopia::BusinessPhone:
+ value = entry.businessPhone();
+ break;
+ case Qtopia::BusinessFax:
+ value = entry.businessFax();
+ break;
+ case Qtopia::BusinessMobile:
+ value = entry.businessMobile();
+ break;
+ case Qtopia::BusinessPager:
+ value = entry.businessPager();
+ break;
+ case Qtopia::Profession:
+ value = entry.profession();
+ break;
+ case Qtopia::Assistant:
+ value = entry.assistant();
+ break;
+ case Qtopia::Manager:
+ value = entry.manager();
+ break;
+ case Qtopia::Spouse:
+ value = entry.spouse();
+ break;
+ case Qtopia::Gender:
+ value = entry.gender();
+ break;
+ case Qtopia::Birthday:
+ value = entry.birthday();
+ break;
+ case Qtopia::Anniversary:
+ value = entry.anniversary();
+ break;
+ case Qtopia::Nickname:
+ value = entry.nickname();
+ break;
+ case Qtopia::Children:
+ value = entry.children();
+ break;
+ case Qtopia::Notes:
+ value = entry.notes();
+ break;
+ }
+ if ( !value.isEmpty() )
+ break;
+ }
+ return value;
+}
+
+void AbTable::addEntry( const Contact &newCnt )
+{
+ int row = numRows();
+ setNumRows( row + 1 );
+ updateJournal( newCnt, Contact::ACTION_ADD );
+ insertIntoTable( newCnt, row );
+ setCurrentCell( row, 0 );
+ updateVisible();
+}
+
+void AbTable::updateJournal( const Contact &cnt,
+ Contact::journal_action action, int row )
+{
+ QFile f( journalFileName() );
+ if ( !f.open(IO_WriteOnly|IO_Append) )
+ return;
+ QString buf;
+ QCString str;
+ buf = "<Contact ";
+ cnt.save( buf );
+ buf += " action=\"" + QString::number( (int)action ) + "\" ";
+ if ( action == Contact::ACTION_REMOVE || action == Contact::ACTION_REPLACE)
+ buf += " actionrow=\"" + QString::number(row) + "\" ";
+ buf += "/>\n";
+ QCString cstr = buf.utf8();
+ f.writeBlock( cstr.data(), cstr.length() );
+ QCopEnvelope( "QPE/PIM", "addressbookUpdated()" );
+}
+
+bool AbTable::save( const QString &fn )
+{
+// QTime t;
+// t.start();
+
+ QString strNewFile = fn + ".new";
+ QFile f( strNewFile );
+ if ( !f.open( IO_WriteOnly|IO_Raw ) )
+ return false;
+
+ int total_written;
+ QString out;
+ out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n"
+ " <Groups>\n"
+ " </Groups>\n"
+ " <Contacts>\n";
+ QMapIterator<AbTableItem*, Contact> it;
+ for ( it = contactList.begin(); it != contactList.end(); ++it ) {
+ out += "<Contact ";
+ it.data().save( out );
+ out += "/>\n";
+ QCString cstr = out.utf8();
+ total_written = f.writeBlock( cstr.data(), cstr.length() );
+ if ( total_written != int(cstr.length()) ) {
+ f.close();
+ QFile::remove( strNewFile );
+ return false;
+ }
+ out = "";
+ }
+ out += " </Contacts>\n</AddressBook>\n";
+
+ QCString cstr = out.utf8();
+ total_written = f.writeBlock( cstr.data(), cstr.length() );
+ if ( total_written != int(cstr.length()) ) {
+ f.close();
+ QFile::remove( strNewFile );
+ return false;
+ }
+ f.close();
+
+// qDebug("saving: %d", t.elapsed() );
+
+ // move the file over, I'm just going to use the system call
+ // because, I don't feel like using QDir.
+ if ( ::rename( strNewFile.latin1(), fn.latin1() ) < 0 ) {
+ qWarning( "problem renaming file %s to %s, errno: %d",
+ strNewFile.latin1(), fn.latin1(), errno );
+ // remove the tmp file...
+ QFile::remove( strNewFile );
+ }
+ // remove the journal...
+ QFile::remove( journalFileName() );
+ return true;
+}
+
+void AbTable::load( const QString &fn )
+{
+ setSorting( false );
+ loadFile( fn, false );
+ // merge in the journal
+ if ( QFile::exists( journalFileName() ) ) {
+ loadFile( journalFileName(), true );
+ save( fn );
+ }
+ setSorting( true );
+ resort();
+}
+
+void AbTable::loadFile( const QString &strFile, bool journalFile )
+{
+// QTime t;
+// t.start();
+ QFile f( strFile );
+ if ( !f.open(IO_ReadOnly) )
+ return;
+ QList<Contact> list;
+ list.setAutoDelete( TRUE );
+ QByteArray ba = f.readAll();
+ f.close();
+ char *uc = ba.data();//(QChar *)data.unicode();
+ int len = ba.size();//data.length();
+ bool foundAction = false;
+ Contact::journal_action action;
+ bool foundKey = false;
+ int journalKey = 0;
+
+ const int JOURNALACTION = Qtopia::Notes + 1;
+ const int JOURNALROW = JOURNALACTION + 1;
+
+ // **********************************
+ // CHANGE THE SIZE OF THE DICT IF YOU ADD ANY MORE FIELDS!!!!
+ // **********************************
+ QAsciiDict<int> dict( 47 );
+ dict.setAutoDelete( TRUE );
+ dict.insert( "Uid", new int(Qtopia::AddressUid) );
+ dict.insert( "Title", new int(Qtopia::Title) );
+ dict.insert( "FirstName", new int(Qtopia::FirstName) );
+ dict.insert( "MiddleName", new int(Qtopia::MiddleName) );
+ dict.insert( "LastName", new int(Qtopia::LastName) );
+ dict.insert( "Suffix", new int(Qtopia::Suffix) );
+ dict.insert( "FileAs", new int(Qtopia::FileAs) );
+ dict.insert( "Categories", new int(Qtopia::AddressCategory) );
+ dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) );
+ dict.insert( "Emails", new int(Qtopia::Emails) );
+ dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) );
+ dict.insert( "HomeCity", new int(Qtopia::HomeCity) );
+ dict.insert( "HomeState", new int(Qtopia::HomeState) );
+ dict.insert( "HomeZip", new int(Qtopia::HomeZip) );
+ dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) );
+ dict.insert( "HomePhone", new int(Qtopia::HomePhone) );
+ dict.insert( "HomeFax", new int(Qtopia::HomeFax) );
+ dict.insert( "HomeMobile", new int(Qtopia::HomeMobile) );
+ dict.insert( "HomeWebPage", new int(Qtopia::HomeWebPage) );
+ dict.insert( "Company", new int(Qtopia::Company) );
+ dict.insert( "BusinessStreet", new int(Qtopia::BusinessStreet) );
+ dict.insert( "BusinessCity", new int(Qtopia::BusinessCity) );
+ dict.insert( "BusinessState", new int(Qtopia::BusinessState) );
+ dict.insert( "BusinessZip", new int(Qtopia::BusinessZip) );
+ dict.insert( "BusinessCountry", new int(Qtopia::BusinessCountry) );
+ dict.insert( "BusinessWebPage", new int(Qtopia::BusinessWebPage) );
+ dict.insert( "JobTitle", new int(Qtopia::JobTitle) );
+ dict.insert( "Department", new int(Qtopia::Department) );
+ dict.insert( "Office", new int(Qtopia::Office) );
+ dict.insert( "BusinessPhone", new int(Qtopia::BusinessPhone) );
+ dict.insert( "BusinessFax", new int(Qtopia::BusinessFax) );
+ dict.insert( "BusinessMobile", new int(Qtopia::BusinessMobile) );
+ dict.insert( "BusinessPager", new int(Qtopia::BusinessPager) );
+ dict.insert( "Profession", new int(Qtopia::Profession) );
+ dict.insert( "Assistant", new int(Qtopia::Assistant) );
+ dict.insert( "Manager", new int(Qtopia::Manager) );
+ dict.insert( "Spouse", new int(Qtopia::Spouse) );
+ dict.insert( "Children", new int(Qtopia::Children) );
+ dict.insert( "Gender", new int(Qtopia::Gender) );
+ dict.insert( "Birthday", new int(Qtopia::Birthday) );
+ dict.insert( "Anniversary", new int(Qtopia::Anniversary) );
+ dict.insert( "Nickname", new int(Qtopia::Nickname) );
+ dict.insert( "Notes", new int(Qtopia::Notes) );
+ dict.insert( "action", new int(JOURNALACTION) );
+ dict.insert( "actionrow", new int(JOURNALROW) );
+
+ int i = 0;
+ int num = 0;
+ char *point;
+ while ( (point = strstr( uc+i, "<Contact " ) ) != NULL ) {
+ i = point - uc;
+ // if we are reading the standard file, we just need to
+ // insert info, so just say we'll do an insert...
+ action = Contact::ACTION_ADD;
+ // new Contact
+ Contact *cnt = new Contact;
+ i += 9;
+ while ( 1 ) {
+ while ( i < len && (uc[i] == ' ' || uc[i] == '\n' || uc[i] == '\r') )
+ i++;
+ if ( i >= len-2 || (uc[i] == '/' && uc[i+1] == '>') )
+ break;
+ // we have another attribute read it.
+ int j = i;
+ while ( j < len && uc[j] != '=' )
+ j++;
+ char *attr = uc+i;
+ uc[j] = '\0';
+ //qDebug("attr=%s", attr.latin1() );
+ i = ++j; // skip =
+ while ( i < len && uc[i] != '"' )
+ i++;
+ j = ++i;
+ bool haveEnt = FALSE;
+ bool haveUtf = FALSE;
+ while ( j < len && uc[j] != '"' ) {
+ if ( uc[j] == '&' )
+ haveEnt = TRUE;
+ if ( ((unsigned char)uc[j]) > 0x7f )
+ haveUtf = TRUE;
+ j++;
+ }
+
+ if ( j == i ) {
+ // empty value
+ i = j + 1;
+ continue;
+ }
+
+ QString value = haveUtf ? QString::fromUtf8( uc+i, j-i )
+ : QString::fromLatin1( uc+i, j-i );
+ if ( haveEnt )
+ value = Qtopia::plainString( value );
+ i = j + 1;
+
+ int *find = dict[ attr ];
+ if ( !find ) {
+ cnt->setCustomField(attr, value);
+ continue;
+ }
+#if 1
+ switch( *find ) {
+ case Qtopia::AddressUid:
+ cnt->setUid( value.toInt() );
+ break;
+ case Qtopia::AddressCategory:
+ cnt->setCategories( Qtopia::Record::idsFromString( value ));
+ break;
+ case JOURNALACTION:
+ action = Contact::journal_action(value.toInt());
+ break;
+ case JOURNALROW:
+ journalKey = value.toInt();
+ break;
+
+ default:
+ cnt->insert( *find, value );
+ break;
+ }
+#endif
+ }
+
+ // sadly we can't delay adding of items from the journal to get
+ // the proper effect, but then, the journal should _never_ be
+ // that huge, and recovering from a crash is not necessarily
+ // a *fast* thing.
+ switch ( action ) {
+ case Contact::ACTION_ADD:
+ if ( journalFile ) {
+ int myrows = numRows();
+ setNumRows( myrows + 1 );
+ insertIntoTable( *cnt, myrows );
+ delete cnt;
+ }
+ else
+ list.append( cnt );
+ break;
+ case Contact::ACTION_REMOVE:
+ // yup, we don't use the entry to remove the object...
+ journalFreeRemove( journalKey );
+ delete cnt;
+ break;
+ case Contact::ACTION_REPLACE:
+ journalFreeReplace( *cnt, journalKey );
+ delete cnt;
+ break;
+ default:
+ break;
+ }
+ num++;
+ foundAction = false;
+ foundKey = false;
+// if ( num % 100 == 0 ) {
+// qDebug("loading file, num=%d, t=%d", num, t.elapsed() );
+// }
+ }
+ if ( list.count() > 0 ) {
+ internalAddEntries( list );
+ }
+// qDebug("done loading %d, t=%d", num, t.elapsed() );
+
+}
+
+void AbTable::realignTable( int row )
+{
+ QTableItem *ti1,
+ *ti2;
+ int totalRows = numRows();
+ for ( int curr = row; curr < totalRows - 1; curr++ ) {
+ // the same info from the todo list still applies, but I
+ // don't think it is _too_ bad.
+ ti1 = item( curr + 1, 0 );
+ ti2 = item( curr + 1, 1 );
+ takeItem( ti1 );
+ takeItem( ti2 );
+ setItem( curr, 0, ti1 );
+ setItem( curr, 1, ti2 );
+ }
+ setNumRows( totalRows - 1 );
+ resort();
+}
+
+void AbTable::insertIntoTable( const Contact &cnt, int row )
+{
+ QString strName,
+ strContact;
+
+ strName = findContactName( cnt );
+ strContact = findContactContact( cnt );
+
+ AbTableItem *ati;
+ ati = new AbTableItem( this, QTableItem::Never, strName, strContact);
+ contactList.insert( ati, cnt );
+ setItem( row, 0, ati );
+ ati = new AbTableItem( this, QTableItem::Never, strContact, strName);
+ setItem( row, 1, ati );
+
+ //### cannot do this; table only has two columns at this point
+ // setItem( row, 2, new AbPickItem( this ) );
+
+ // resort at some point?
+}
+
+void AbTable::internalAddEntries( QList<Contact> &list )
+{
+ setUpdatesEnabled( FALSE );
+ setNumRows( list.count() );
+ int row = 0;
+ Contact *it;
+ for ( it = list.first(); it; it = list.next() )
+ insertIntoTable( *it, row++ );
+ resort();
+ setUpdatesEnabled( TRUE );
+}
+
+
+void AbTable::journalFreeReplace( const Contact &cnt, int row )
+{
+ QString strName,
+ strContact;
+ AbTableItem *ati;
+
+ strName = findContactName( cnt );
+ strContact = findContactContact( cnt );
+ ati = static_cast<AbTableItem*>(item(row, 0));
+ contactList.remove( ati );
+ ati->setItem( strName, strContact );
+ contactList.insert( ati, cnt );
+
+ ati = static_cast<AbTableItem*>(item(row, 1));
+ ati->setItem( strContact, strName );
+}
+
+void AbTable::journalFreeRemove( int row )
+{
+ AbTableItem *ati;
+ ati = static_cast<AbTableItem*>(item(row, 0));
+ if ( !ati )
+ return;
+ contactList.remove( ati );
+ realignTable( row );
+}
+
+#if QT_VERSION <= 230
+#ifndef SINGLE_APP
+void QTable::paintEmptyArea( QPainter *p, int cx, int cy, int cw, int ch )
+{
+ // Region of the rect we should draw
+ QRegion reg( QRect( cx, cy, cw, ch ) );
+ // Subtract the table from it
+ reg = reg.subtract( QRect( QPoint( 0, 0 ), tableSize() ) );
+ // And draw the rectangles (transformed as needed)
+ QArray<QRect> r = reg.rects();
+ for (unsigned int i=0; i<r.count(); i++)
+ p->fillRect( r[i], colorGroup().brush( QColorGroup::Base ) );
+}
+#endif
+#endif
+
+
+// int AbTable::rowHeight( int ) const
+// {
+// return 18;
+// }
+
+// int AbTable::rowPos( int row ) const
+// {
+// return 18*row;
+// }
+
+// int AbTable::rowAt( int pos ) const
+// {
+// return QMIN( pos/18, numRows()-1 );
+// }
+
+void AbTable::slotDoFind( const QString &findString, bool caseSensitive,
+ bool backwards, int category )
+{
+ if ( currFindRow < -1 )
+ currFindRow = currentRow() - 1;
+ clearSelection( TRUE );
+ int rows,
+ row;
+ AbTableItem *ati;
+ QRegExp r( findString );
+ r.setCaseSensitive( caseSensitive );
+ rows = numRows();
+ static bool wrapAround = true;
+
+ if ( !backwards ) {
+ for ( row = currFindRow + 1; row < rows; row++ ) {
+ ati = static_cast<AbTableItem*>( item(row, 0) );
+ if ( contactCompare( contactList[ati], r, category ) )
+ break;
+
+ }
+ } else {
+ for ( row = currFindRow - 1; row > -1; row-- ) {
+ ati = static_cast<AbTableItem*>( item(row, 0) );
+ if ( contactCompare( contactList[ati], r, category ) )
+ break;
+ }
+ }
+ if ( row >= rows || row < 0 ) {
+ if ( row < 0 )
+ currFindRow = rows;
+ else
+ currFindRow = -1;
+
+ if ( wrapAround )
+ emit signalWrapAround();
+ else
+ emit signalNotFound();
+
+ wrapAround = !wrapAround;
+ } else {
+ currFindRow = row;
+ QTableSelection foundSelection;
+ foundSelection.init( currFindRow, 0 );
+ foundSelection.expandTo( currFindRow, numCols() - 1 );
+ addSelection( foundSelection );
+ setCurrentCell( currFindRow, numCols() - 1 );
+ wrapAround = true;
+ }
+}
+
+static bool contactCompare( const Contact &cnt, const QRegExp &r, int category )
+{
+ bool returnMe;
+ QArray<int> cats;
+ cats = cnt.categories();
+
+ returnMe = false;
+ if ( (category == -1 && cats.count() == 0) || category == -2 )
+ returnMe = cnt.match( r );
+ else {
+ int i;
+ for ( i = 0; i < int(cats.count()); i++ ) {
+ if ( cats[i] == category ) {
+ returnMe = cnt.match( r );
+ break;
+ }
+ }
+ }
+ return returnMe;
+}
+
+void AbTable::fitColumns()
+{
+ int contentsWidth = visibleWidth();
+ int n = numCols();
+ int pw = n == 3 ? columnWidth(2) : 0;
+ setColumnWidth( 0, contentsWidth - contentsWidth / 2 );
+ setColumnWidth( 1, contentsWidth / 2 - pw );
+}
+
+void AbTable::show()
+{
+ fitColumns();
+ QTable::show();
+}
+
+void AbTable::setChoiceNames( const QStringList& list)
+{
+ choicenames = list;
+ if ( choicenames.isEmpty() ) {
+ // hide pick column
+ setNumCols( 2 );
+ } else {
+ // show pick column
+ setNumCols( 3 );
+ setColumnWidth( 2, fontMetrics().width(tr( "Pick" ))+8 );
+ horizontalHeader()->setLabel( 2, tr( "Pick" ));
+ }
+ fitColumns();
+}
+
+void AbTable::itemClicked(int,int col)
+{
+ if ( col == 2 ) {
+ return;
+ } else {
+ emit details();
+ }
+}
+
+QStringList AbTable::choiceNames() const
+{
+ return choicenames;
+}
+
+void AbTable::setChoiceSelection(int /*index*/, const QStringList& /*list*/)
+{
+ /* ######
+
+ QString selname = choicenames.at(index);
+ for (each row) {
+ Contact *c = contactForRow(row);
+ if ( list.contains(c->email) ) {
+ list.remove(c->email);
+ setText(row, 2, selname);
+ }
+ }
+ for (remaining list items) {
+ Contact *c = new contact(item);
+ setText(newrow, 2, selname);
+ }
+
+ */
+}
+
+QStringList AbTable::choiceSelection(int /*index*/) const
+{
+ QStringList r;
+ /* ######
+
+ QString selname = choicenames.at(index);
+ for (each row) {
+ Contact *c = contactForRow(row);
+ if ( text(row,2) == selname ) {
+ r.append(c->email);
+ }
+ }
+
+ */
+ return r;
+}
+
+void AbTable::setShowCategory( const QString &c )
+{
+ showCat = c;
+ updateVisible();
+}
+
+QString AbTable::showCategory() const
+{
+ return showCat;
+}
+
+
+QStringList AbTable::categories()
+{
+ mCat.load( categoryFileName() );
+ QStringList categoryList = mCat.labels( "Contacts" );
+ return categoryList;
+}
+
+void AbTable::updateVisible()
+{
+ int visible,
+ totalRows,
+ id,
+ totalCats,
+ it,
+ row;
+ bool hide;
+ AbTableItem *ati;
+ Contact *cnt;
+ visible = 0;
+
+ setPaintingEnabled( FALSE );
+
+ totalRows = numRows();
+ id = mCat.id( "Contacts", showCat );
+ QArray<int> cats;
+ for ( row = 0; row < totalRows; row++ ) {
+ ati = static_cast<AbTableItem*>( item(row, 0) );
+ cnt = &contactList[ati];
+ cats = cnt->categories();
+ hide = false;
+ if ( !showCat.isEmpty() ) {
+ if ( showCat == tr( "Unfiled" ) ) {
+ if ( cats.count() > 0 )
+ hide = true;
+ } else {
+ // do some comparing
+ if ( !hide ) {
+ hide = true;
+ totalCats = int(cats.count());
+ for ( it = 0; it < totalCats; it++ ) {
+ if ( cats[it] == id ) {
+ hide = false;
+ break;
+ }
+ }
+ }
+ }
+ }
+ if ( hide ) {
+ if ( currentRow() == row )
+ setCurrentCell( -1, 0 );
+ if ( rowHeight(row) > 0 )
+ hideRow( row );
+ } else {
+ if ( rowHeight(row) == 0 ) {
+ showRow( row );
+ adjustRow( row );
+ }
+ visible++;
+ }
+ }
+ if ( !visible )
+ setCurrentCell( -1, 0 );
+
+ setPaintingEnabled( TRUE );
+}
+
+
+void AbTable::setPaintingEnabled( bool e )
+{
+ if ( e != enablePainting ) {
+ if ( !enablePainting ) {
+ enablePainting = true;
+ rowHeightChanged( 0 );
+ viewport()->update();
+ } else {
+ enablePainting = false;
+ }
+ }
+}
+
+void AbTable::rowHeightChanged( int row )
+{
+ if ( enablePainting )
+ QTable::rowHeightChanged( row );
+}
diff --git a/core/pim/addressbook/abtable.h b/core/pim/addressbook/abtable.h
new file mode 100644
index 0000000..9b96997
--- a/dev/null
+++ b/core/pim/addressbook/abtable.h
@@ -0,0 +1,140 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qt Palmtop Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef ABTABLE_H
+#define ABTABLE_H
+
+#include <qpe/categories.h>
+#include <qpe/contact.h>
+
+#include <qmap.h>
+#include <qtable.h>
+#include <qstringlist.h>
+#include <qcombobox.h>
+
+class AbTableItem : public QTableItem
+{
+public:
+ AbTableItem( QTable *t, EditType et, const QString &s,
+ const QString &secondSortKey);
+ QString entryKey() const;
+ void setEntryKey( const QString & k );
+ virtual int alignment() const;
+ virtual QString key() const;
+ void setItem( const QString &txt, const QString &secondKey );
+
+private:
+ QString sortKey;
+};
+
+class AbPickItem : public QTableItem
+{
+public:
+ AbPickItem( QTable *t );
+
+ QWidget *createEditor() const;
+ void setContentFromEditor( QWidget *w );
+
+private:
+ QGuardedPtr<QComboBox> cb;
+};
+
+class AbTable : public QTable
+{
+ Q_OBJECT
+
+public:
+ AbTable( const QValueList<int> *ordered, QWidget *parent, const char *name=0 );
+ ~AbTable();
+ // NEW
+ void addEntry( const Contact &newContact );
+ Contact currentEntry();
+ void replaceCurrentEntry( const Contact &newContact );
+
+ void init();
+
+ void deleteCurrentEntry();
+ void clear();
+ void clearFindRow() { currFindRow = -2; }
+ void loadFields();
+ void refresh();
+ bool save( const QString &fn );
+ void load( const QString &fn );
+
+ // addresspicker mode
+ void setChoiceNames( const QStringList& list);
+ QStringList choiceNames() const;
+ void setChoiceSelection(int index, const QStringList& list);
+ QStringList choiceSelection(int index) const;
+ void setShowCategory( const QString &c );
+ QString showCategory() const;
+ QStringList categories();
+
+ void show();
+ void setPaintingEnabled( bool e );
+
+public slots:
+ void slotDoFind( const QString &str, bool caseSensitive, bool backwards,
+ int category );
+signals:
+ void empty( bool );
+ void details();
+ void signalNotFound();
+ void signalWrapAround();
+
+protected:
+ virtual void keyPressEvent( QKeyEvent *e );
+
+// int rowHeight( int ) const;
+// int rowPos( int row ) const;
+// virtual int rowAt( int pos ) const;
+
+
+protected slots:
+ void moveTo( char );
+ virtual void columnClicked( int col );
+ void itemClicked(int,int col);
+ void rowHeightChanged( int row );
+
+private:
+ void loadFile( const QString &strFile, bool journalFile );
+ void fitColumns();
+ void resort();
+ void updateJournal( const Contact &contact, Contact::journal_action action,
+ int row = -1 );
+ void insertIntoTable( const Contact &contact, int row );
+ void internalAddEntries( QList<Contact> &list );
+ QString findContactName( const Contact &entry );
+ QString findContactContact( const Contact &entry );
+ void journalFreeReplace( const Contact &cnt, int row );
+ void journalFreeRemove( int row );
+ void realignTable( int );
+ void updateVisible();
+ int lastSortCol;
+ bool asc;
+ QMap<AbTableItem*, Contact> contactList;
+ const QValueList<int> *intFields;
+ int currFindRow;
+ QString showCat;
+ QStringList choicenames;
+ bool enablePainting;
+ Categories mCat;
+};
+#endif // ABTABLE_H
diff --git a/core/pim/addressbook/addressbook.cpp b/core/pim/addressbook/addressbook.cpp
new file mode 100644
index 0000000..b694e4f
--- a/dev/null
+++ b/core/pim/addressbook/addressbook.cpp
@@ -0,0 +1,829 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qt Palmtop Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "abeditor.h"
+#include "ablabel.h"
+#include "abtable.h"
+#include "addresssettings.h"
+#include "addressbook.h"
+
+#include <qpe/qpeapplication.h>
+#include <qpe/config.h>
+#include <qpe/contact.h>
+#include <qpe/finddialog.h>
+#include <qpe/global.h>
+#include <qpe/resource.h>
+#include <qpe/ir.h>
+#include <qpe/qpemessagebox.h>
+#include <qpe/qcopenvelope_qws.h>
+
+#include <qaction.h>
+#include <qdialog.h>
+#include <qdir.h>
+#include <qfile.h>
+#include <qimage.h>
+#include <qlayout.h>
+#include <qpe/qpemenubar.h>
+#include <qmessagebox.h>
+#include <qpixmap.h>
+#include <qpopupmenu.h>
+#include <qpe/qpetoolbar.h>
+#include <qstringlist.h>
+#include <qtoolbutton.h>
+#include <qwhatsthis.h>
+
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <qdatetime.h>
+
+static QString addressbookOldXMLFilename()
+{
+ QString filename = QPEApplication::documentDir() + "addressbook.xml";
+ return filename;
+}
+
+static QString addressbookXMLFilename()
+{
+ QString filename = Global::applicationFileName("addressbook",
+ "addressbook.xml");
+ return filename;
+}
+
+static QString addressbookPersonalVCardName()
+{
+ QString filename = Global::applicationFileName("addressbook",
+ "businesscard.vcf");
+ return filename;
+}
+
+
+AddressbookWindow::AddressbookWindow( QWidget *parent, const char *name,
+ WFlags f )
+ : QMainWindow( parent, name, f ),
+ abEditor(0),
+ bAbEditFirstTime(TRUE),
+ syncing(FALSE)
+{
+ initFields();
+
+ setCaption( tr("Contacts") );
+ setIcon( Resource::loadPixmap( "AddressBook" ) );
+
+ setToolBarsMovable( FALSE );
+
+ // Create Toolbars
+
+ QPEToolBar *bar = new QPEToolBar( this );
+ bar->setHorizontalStretchable( TRUE );
+
+ QPEMenuBar *mbList = new QPEMenuBar( bar );
+ mbList->setMargin( 0 );
+
+ QPopupMenu *edit = new QPopupMenu( this );
+ mbList->insertItem( tr( "Contact" ), edit );
+
+ listTools = new QPEToolBar( this, "list operations" );
+
+
+ QAction *a = new QAction( tr( "New" ), Resource::loadPixmap( "new" ), QString::null,
+ 0, this, 0 );
+ actionNew = a;
+ connect( a, SIGNAL( activated() ), this, SLOT( slotListNew() ) );
+ a->addTo( edit );
+ a->addTo( listTools );
+
+ a = new QAction( tr( "Edit" ), Resource::loadPixmap( "edit" ), QString::null,
+ 0, this, 0 );
+ actionEdit = a;
+ connect( a, SIGNAL( activated() ), this, SLOT( slotViewEdit() ) );
+ a->addTo( edit );
+ a->addTo( listTools );
+
+ a = new QAction( tr( "Delete" ), Resource::loadPixmap( "trash" ), QString::null,
+ 0, this, 0 );
+ actionTrash = a;
+ connect( a, SIGNAL( activated() ), this, SLOT( slotListDelete() ) );
+ a->addTo( edit );
+ a->addTo( listTools );
+
+ a = new QAction( tr( "Find" ), Resource::loadPixmap( "mag" ),
+ QString::null, 0, this, 0 );
+ actionFind = a;
+ connect( a, SIGNAL(activated()), this, SLOT(slotFind()) );
+ a->addTo( edit );
+ a->addTo( listTools );
+
+
+ a = new QAction( tr( "Write Mail To" ), Resource::loadPixmap( "qtmail/reply" ),
+ QString::null, 0, this, 0 );
+ a->setEnabled( FALSE );
+ actionMail = a;
+ connect( a, SIGNAL( activated() ), this, SLOT( writeMail() ) );
+ a->addTo( edit );
+ a->addTo( listTools );
+
+
+
+ if ( Ir::supported() ) {
+ a = new QAction( tr ("Beam Entry" ), Resource::loadPixmap( "beam" ), QString::null,
+ 0, this, 0 );
+ actionBeam = a;
+ connect( a, SIGNAL( activated() ), this, SLOT( slotBeam() ) );
+ a->addTo( edit );
+ a->addTo( listTools );
+ }
+
+ edit->insertSeparator();
+
+ a = new QAction( tr("My Personal Details"), QString::null, 0, 0, 0, TRUE );
+ actionPersonal = a;
+ connect( a, SIGNAL( activated() ), this, SLOT( slotPersonalView() ) );
+ a->addTo( edit );
+
+
+ a = new QAction( tr( "Arrange Edit Fields"), QString::null, 0, 0 );
+ connect( a, SIGNAL( activated() ), this, SLOT( slotSettings() ) );
+ a->addTo( edit );
+
+ // Create Views
+
+ // This is safe to call without checking to see if it exists...
+ // not to mention it also does the necessary stuff for the
+ // journaling...
+ QString str = addressbookXMLFilename();
+ if ( str.isNull() ) {
+ QMessageBox::warning( this, tr("Out of Space"),
+ tr("There is not enough space to create\n"
+ "neccessary startup files.\n"
+ "\nFree up some space before\nentering data!")
+ );
+ }
+
+ abList = new AbTable( &orderedFields, this, "table" );
+ abList->setHScrollBarMode( QScrollView::AlwaysOff );
+ connect( abList, SIGNAL( empty( bool ) ),
+ this, SLOT( listIsEmpty( bool ) ) );
+ connect( abList, SIGNAL( details() ),
+ this, SLOT( slotListView() ) );
+ connect( abList, SIGNAL(currentChanged(int,int)),
+ this, SLOT(slotUpdateToolbar()) );
+
+ mView = 0;
+
+ abList->load( addressbookXMLFilename() );
+ if ( QFile::exists(addressbookOldXMLFilename()) ) {
+ abList->load( addressbookOldXMLFilename() );
+ QFile::remove(addressbookOldXMLFilename());
+ }
+
+ catMenu = new QPopupMenu( this );
+ catMenu->setCheckable( TRUE );
+ connect( catMenu, SIGNAL(activated(int)), this, SLOT(slotSetCategory(int)) );
+ populateCategories();
+
+ mbList->insertItem( tr("View"), catMenu );
+ setCentralWidget( abList );
+
+ // qDebug("adressbook contrsuction: t=%d", t.elapsed() );
+}
+
+void AddressbookWindow::setDocument( const QString &filename )
+{
+ if ( filename.find(".vcf") != int(filename.length()) - 4 ) return;
+
+ QValueList<Contact> cl = Contact::readVCard( filename );
+ for( QValueList<Contact>::Iterator it = cl.begin(); it != cl.end(); ++it ) {
+// QString msg = tr("You received a vCard for\n%1.\nDo You want to add it to your\naddressbook?")
+// .arg( (*it).fullName() );
+// if ( QMessageBox::information( this, tr("received contact"), msg, QMessageBox::Ok, QMessageBox::Cancel ) ==
+// QMessageBox::Ok ) {
+ abList->addEntry( *it );
+// }
+ }
+
+}
+
+void AddressbookWindow::resizeEvent( QResizeEvent *e )
+{
+ QMainWindow::resizeEvent( e );
+
+ if ( centralWidget() == abList )
+ showList();
+ else if ( centralWidget() == mView )
+ showView();
+}
+
+AddressbookWindow::~AddressbookWindow()
+{
+}
+
+void AddressbookWindow::slotUpdateToolbar()
+{
+ Contact ce = abList->currentEntry();
+ actionMail->setEnabled( !ce.defaultEmail().isEmpty() );
+}
+
+void AddressbookWindow::showList()
+{
+ if ( mView ) mView->hide();
+ setCentralWidget( abList );
+ abList->show();
+ // update our focues... (or use a stack widget!);
+ abList->setFocus();
+}
+
+void AddressbookWindow::showView()
+{
+ if ( abList->numRows() > 0 ) {
+ abList->hide();
+ setCentralWidget( abView() );
+ mView->show();
+ mView->setFocus();
+ }
+}
+
+void AddressbookWindow::slotListNew()
+{
+ Contact cnt;
+ if( !syncing ) {
+ if ( abEditor )
+ abEditor->setEntry( cnt );
+ abView()->init( cnt );
+ editEntry( NewEntry );
+ } else {
+ QMessageBox::warning(this, tr("Contacts"),
+ tr("Can not edit data, currently syncing"));
+ }
+}
+
+void AddressbookWindow::slotListView()
+{
+ abView()->init( abList->currentEntry() );
+ mView->sync();
+ showView();
+}
+
+void AddressbookWindow::slotListDelete()
+{
+ if(!syncing) {
+ Contact tmpEntry = abList->currentEntry();
+
+ // get a name, do the best we can...
+ QString strName = tmpEntry.fullName();
+ if ( strName.isEmpty() ) {
+ strName = tmpEntry.company();
+ if ( strName.isEmpty() )
+ strName = "No Name";
+ }
+
+
+ if ( QPEMessageBox::confirmDelete( this, tr( "Contacts" ),
+ strName ) ) {
+ abList->deleteCurrentEntry();
+ showList();
+ }
+ } else {
+ QMessageBox::warning( this, tr("Contacts"),
+ tr("Can not edit data, currently syncing") );
+ }
+}
+
+void AddressbookWindow::slotViewBack()
+{
+ showList();
+}
+
+void AddressbookWindow::slotViewEdit()
+{
+ if(!syncing) {
+ if (actionPersonal->isOn()) {
+ editPersonal();
+ } else {
+ if ( !bAbEditFirstTime )
+ abEditor->setEntry( abList->currentEntry() );
+ editEntry( EditEntry );
+ }
+ } else {
+ QMessageBox::warning( this, tr("Contacts"),
+ tr("Can not edit data, currently syncing") );
+ }
+}
+
+
+
+void AddressbookWindow::writeMail()
+{
+ Contact c = abList->currentEntry();
+ QString name = c.fileAs();
+ QString email = c.defaultEmail();
+ QCopEnvelope e("QPE/Application/qtmail", "writeMail(QString,QString)");
+ e << name << email;
+}
+
+
+
+
+static const char * beamfile = "/tmp/obex/contact.vcf";
+
+void AddressbookWindow::slotBeam()
+{
+ QString filename;
+ Contact c;
+ if ( actionPersonal->isOn() ) {
+ filename = addressbookPersonalVCardName();
+ if (!QFile::exists(filename))
+ return; // can't beam a non-existent file
+ c = Contact::readVCard( filename )[0];
+ } else {
+ unlink( beamfile ); // delete if exists
+ c = abList->currentEntry();
+ mkdir("/tmp/obex/", 0755);
+ Contact::writeVCard( beamfile, c );
+ filename = beamfile;
+ }
+ Ir *ir = new Ir( this );
+ connect( ir, SIGNAL( done( Ir * ) ), this, SLOT( beamDone( Ir * ) ) );
+ QString description = c.fullName();
+ ir->send( filename, description, "text/x-vCard" );
+}
+
+void AddressbookWindow::beamDone( Ir *ir )
+{
+ delete ir;
+ unlink( beamfile );
+}
+
+
+static void parseName( const QString& name, QString *first, QString *middle,
+ QString * last )
+{
+
+ int comma = name.find ( "," );
+ QString rest;
+ if ( comma > 0 ) {
+ *last = name.left( comma );
+ comma++;
+ while ( comma < int(name.length()) && name[comma] == ' ' )
+ comma++;
+ rest = name.mid( comma );
+ } else {
+ int space = name.findRev( ' ' );
+ *last = name.mid( space+1 );
+ rest = name.left( space );
+ }
+ int space = rest.find( ' ' );
+ if ( space <= 0 ) {
+ *first = rest;
+ } else {
+ *first = rest.left( space );
+ *middle = rest.mid( space+1 );
+ }
+
+}
+
+
+void AddressbookWindow::appMessage(const QCString &msg, const QByteArray &data)
+{
+ if (msg == "editPersonal()") {
+ editPersonal();
+ } else if (msg == "editPersonalAndClose()") {
+ editPersonal();
+ close();
+ } else if ( msg == "addContact(QString,QString)" ) {
+ QDataStream stream(data,IO_ReadOnly);
+ QString name, email;
+ stream >> name >> email;
+
+ Contact cnt;
+ QString fn, mn, ln;
+ parseName( name, &fn, &mn, &ln );
+ // qDebug( " %s - %s - %s", fn.latin1(), mn.latin1(), ln.latin1() );
+ cnt.setFirstName( fn );
+ cnt.setMiddleName( mn );
+ cnt.setLastName( ln );
+ cnt.setEmails( email );
+ cnt.setDefaultEmail( email );
+ cnt.setFileAs();
+
+ if ( bAbEditFirstTime ) {
+ abEditor = new AbEditor( cnt, &orderedFields, &slOrderedFields,
+ this, "editor" );
+ bAbEditFirstTime = FALSE;
+ } else {
+ abEditor->setEntry( cnt );
+ }
+ abView()->init( cnt );
+ editEntry( NewEntry );
+
+
+
+ }
+#if 0
+ else if (msg == "pickAddresses(QCString,QCString,QStringList,...)" ) {
+ QDataStream stream(data,IO_ReadOnly);
+ QCString ch,m;
+ QStringList types;
+ stream >> ch >> m >> types;
+ AddressPicker picker(abList,this,0,TRUE);
+ picker.showMaximized();
+ picker.setChoiceNames(types);
+ int i=0;
+ for (QStringList::ConstIterator it = types.begin(); it!=types.end(); ++it) {
+ QStringList sel;
+ stream >> sel;
+ picker.setSelection(i++,sel);
+ }
+ picker.showMaximized();
+ picker.exec();
+
+ // ###### note: contacts may have been added - save here!
+
+ setCentralWidget(abList);
+ QCopEnvelope e(ch,m);
+ i=0;
+ for (QStringList::ConstIterator it = types.begin(); it!=types.end(); ++it) {
+ QStringList sel = picker.selection(i++);
+ e << sel;
+ }
+ }
+#endif
+
+}
+
+void AddressbookWindow::editPersonal()
+{
+ QString filename = addressbookPersonalVCardName();
+ Contact me;
+ if (QFile::exists(filename))
+ me = Contact::readVCard( filename )[0];
+ if (bAbEditFirstTime) {
+ abEditor = new AbEditor( me, &orderedFields, &slOrderedFields,
+ this, "editor" );
+ // don't create a new editor every time
+ bAbEditFirstTime = FALSE;
+ } else
+ abEditor->setEntry( me );
+
+ abEditor->setCaption(tr("Edit My Personal Details"));
+ abEditor->showMaximized();
+
+ // fix the foxus...
+ abEditor->setNameFocus();
+ if ( abEditor->exec() ) {
+ setFocus();
+ Contact new_personal = abEditor->entry();
+ QString fname = addressbookPersonalVCardName();
+ Contact::writeVCard( fname, new_personal );
+ abView()->init(new_personal);
+ abView()->sync();
+ }
+ abEditor->setCaption( tr("Edit Address") );
+}
+
+void AddressbookWindow::slotPersonalView()
+{
+ if (!actionPersonal->isOn()) {
+ // we just turned it off
+ setCaption( tr("Contacts") );
+ actionNew->setEnabled(TRUE);
+ actionTrash->setEnabled(TRUE);
+ actionFind->setEnabled(TRUE);
+ slotUpdateToolbar(); // maybe some of the above could be moved there
+ showList();
+ return;
+ }
+
+ // XXX need to disable some QActions.
+ actionNew->setEnabled(FALSE);
+ actionTrash->setEnabled(FALSE);
+ actionFind->setEnabled(FALSE);
+ actionMail->setEnabled(FALSE);
+
+ setCaption( tr("Contacts - My Personal Details") );
+ QString filename = addressbookPersonalVCardName();
+ Contact me;
+ if (QFile::exists(filename))
+ me = Contact::readVCard( filename )[0];
+
+ abView()->init( me );
+ abView()->sync();
+ abList->hide();
+ setCentralWidget( abView() );
+ mView->show();
+ mView->setFocus();
+}
+
+void AddressbookWindow::editEntry( EntryMode entryMode )
+{
+ Contact entry;
+ if ( bAbEditFirstTime ) {
+ abEditor = new AbEditor( entry, &orderedFields, &slOrderedFields,
+ this, "editor" );
+ bAbEditFirstTime = FALSE;
+ if ( entryMode == EditEntry )
+ abEditor->setEntry( abList->currentEntry() );
+ }
+ // other things may chane the caption.
+ abEditor->setCaption( tr("Edit Address") );
+
+#if defined(Q_WS_QWS) || defined(_WS_QWS_)
+ abEditor->showMaximized();
+#endif
+ // fix the foxus...
+ abEditor->setNameFocus();
+ if ( abEditor->exec() ) {
+ setFocus();
+ if ( entryMode == NewEntry ) {
+ Contact insertEntry = abEditor->entry();
+ insertEntry.assignUid();
+ abList->addEntry( insertEntry );
+ } else {
+ Contact replaceEntry = abEditor->entry();
+ if ( !replaceEntry.isValidUid() )
+ replaceEntry.assignUid();
+ abList->replaceCurrentEntry( replaceEntry );
+ }
+ }
+ populateCategories();
+ showList();
+}
+
+void AddressbookWindow::listIsEmpty( bool empty )
+{
+ if ( !empty ) {
+ deleteButton->setEnabled( TRUE );
+ }
+}
+
+void AddressbookWindow::reload()
+{
+ syncing = FALSE;
+ abList->clear();
+ abList->load( addressbookXMLFilename() );
+}
+
+void AddressbookWindow::flush()
+{
+ syncing = TRUE;
+ abList->save( addressbookXMLFilename() );
+}
+
+
+void AddressbookWindow::closeEvent( QCloseEvent *e )
+{
+ if ( centralWidget() == mView ) {
+ if (actionPersonal->isOn()) {
+ // pretend we clicked it off
+ actionPersonal->setOn(FALSE);
+ slotPersonalView();
+ } else {
+ showList();
+ }
+ e->ignore();
+ return;
+ }
+
+ if(syncing) {
+ /* shouldn't we save, I hear you say? well its already been set
+ so that an edit can not occur during a sync, and we flushed
+ at the start of the sync, so there is no need to save
+ Saving however itself would cause problems. */
+ e->accept();
+ return;
+ }
+//################## shouldn't always save
+ if ( save() )
+ e->accept();
+ else
+ e->ignore();
+}
+
+/*
+ Returns TRUE if it is OK to exit
+ */
+
+bool AddressbookWindow::save()
+{
+ QString str = addressbookXMLFilename();
+ if ( str.isNull() ) {
+ if ( QMessageBox::critical( 0, tr("Out of space"),
+ tr("Unable to save information.\n"
+ "Free up some space\n"
+ "and try again.\n"
+ "\nQuit anyway?"),
+ QMessageBox::Yes|QMessageBox::Escape,
+ QMessageBox::No|QMessageBox::Default )
+ != QMessageBox::No )
+ return TRUE;
+ else
+ return FALSE;
+ } else {
+ if ( !abList->save( str ) ) {
+ if ( QMessageBox::critical( 0, tr( "Out of space" ),
+ tr("Unable to save information.\n"
+ "Free up some space\n"
+ "and try again.\n"
+ "\nQuit anyway?"),
+ QMessageBox::Yes|QMessageBox::Escape,
+ QMessageBox::No|QMessageBox::Default )
+ != QMessageBox::No )
+ return TRUE;
+ else
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+void AddressbookWindow::slotSettings()
+{
+ AddressSettings frmSettings( this );
+#if defined(Q_WS_QWS) || defined(_WS_QWS_)
+ frmSettings.showMaximized();
+#endif
+
+ if ( frmSettings.exec() ) {
+ allFields.clear();
+ orderedFields.clear();
+ slOrderedFields.clear();
+ initFields();
+ if ( abEditor )
+ abEditor->loadFields();
+ abList->refresh();
+ }
+}
+
+
+void AddressbookWindow::initFields()
+{
+ // we really don't need the things from the configuration, anymore
+ // only thing that is important are the important categories. So,
+ // Call the contact functions that correspond to these old functions...
+
+ QStringList xmlFields = Contact::fields();
+ QStringList visibleFields = Contact::trfields();
+ xmlFields.remove( "Title" );
+ visibleFields.remove( tr("Name Title") );
+ visibleFields.remove( tr("Notes") );
+
+ int i,
+ version;
+ Config cfg( "AddressBook" );
+ QString zn;
+
+ // ### Write a function to keep this from happening again...
+ QStringList::ConstIterator it;
+ for ( i = 0, it = xmlFields.begin(); it != xmlFields.end(); ++it, i++ ) {
+ allFields.append( i + 3 );
+ }
+
+ cfg.setGroup( "Version" );
+ version = cfg.readNumEntry( "version" );
+ i = 0;
+ if ( version >= ADDRESSVERSION ) {
+
+ cfg.setGroup( "ImportantCategory" );
+
+ zn = cfg.readEntry( "Category" + QString::number(i), QString::null );
+ while ( !zn.isNull() ) {
+ if ( zn.contains( tr("Work") ) || zn.contains( tr("Mb") ) ) {
+ slOrderedFields.clear();
+ break;
+ }
+ slOrderedFields.append( zn );
+ zn = cfg.readEntry( "Category" + QString::number(++i), QString::null );
+ }
+ } else {
+ QString str;
+ str = getenv("HOME");
+ str += "/Settings/AddressBook.conf";
+ QFile::remove( str );
+ }
+ if ( slOrderedFields.count() > 0 ) {
+ for( QStringList::ConstIterator it = slOrderedFields.begin();
+ it != slOrderedFields.end(); ++it ) {
+ QValueList<int>::ConstIterator itVl;
+ QStringList::ConstIterator itVis;
+ itVl = allFields.begin();
+ for ( itVis = visibleFields.begin();
+ itVis != visibleFields.end() && itVl != allFields.end();
+ ++itVis, ++itVl ) {
+ if ( *it == *itVis && itVl != allFields.end() ) {
+ orderedFields.append( *itVl );
+ }
+ }
+ }
+ } else {
+ QValueList<int>::ConstIterator it;
+ for ( it = allFields.begin(); it != allFields.end(); ++it )
+ orderedFields.append( *it );
+
+ slOrderedFields = visibleFields;
+ orderedFields.remove( Qtopia::AddressUid );
+ orderedFields.remove( Qtopia::Title );
+ orderedFields.remove( Qtopia::Groups );
+ orderedFields.remove( Qtopia::AddressCategory );
+ orderedFields.remove( Qtopia::FirstName );
+ orderedFields.remove( Qtopia::LastName );
+ orderedFields.remove( Qtopia::DefaultEmail );
+ orderedFields.remove( Qtopia::FileAs );
+ orderedFields.remove( Qtopia::Notes );
+ orderedFields.remove( Qtopia::Gender );
+ slOrderedFields.remove( tr("Name Title") );
+ slOrderedFields.remove( tr("First Name") );
+ slOrderedFields.remove( tr("Last Name") );
+ slOrderedFields.remove( tr("File As") );
+ slOrderedFields.remove( tr("Default Email") );
+ slOrderedFields.remove( tr("Notes") );
+ slOrderedFields.remove( tr("Gender") );
+
+ }
+}
+
+
+AbLabel *AddressbookWindow::abView()
+{
+ if ( !mView ) {
+ mView = new AbLabel( this, "viewer" );
+ mView->init( Contact() );
+ connect( mView, SIGNAL( okPressed() ), this, SLOT( slotListView() ) );
+ }
+ return mView;
+}
+
+void AddressbookWindow::slotFind()
+{
+ if ( centralWidget() == abView() )
+ showList();
+ FindDialog frmFind( "Contacts", this );
+ QObject::connect( &frmFind, SIGNAL(signalFindClicked(const QString &, bool, bool, int)), abList, SLOT(slotDoFind( const QString&,bool,bool,int)));
+ QObject::connect( abList, SIGNAL(signalNotFound()), &frmFind, SLOT(slotNotFound()) );
+ QObject::connect( abList, SIGNAL(signalWrapAround()), &frmFind, SLOT(slotWrapAround()) );
+ frmFind.exec();
+ if ( abList->numSelections() )
+ abList->clearSelection();
+ abList->clearFindRow();
+}
+
+void AddressbookWindow::slotSetCategory( int c )
+{
+ if ( c <= 0 )
+ return;
+ for ( unsigned int i = 1; i < catMenu->count(); i++ )
+ catMenu->setItemChecked( i, c == (int)i );
+ if ( c == 1 ) {
+ abList->setShowCategory( QString::null );
+ setCaption( tr("Contacts") + " - " + tr ( "All" ) );
+ } else if ( c == (int)catMenu->count() ) {
+ abList->setShowCategory( tr( "Unfiled" ) );
+ setCaption( tr("Contacts") + " - " + tr( "Unfiled" ) );
+ } else {
+ QString cat = abList->categories()[c - 2];
+ abList->setShowCategory( cat );
+ setCaption( tr("Contacts") + " - " + cat );
+ }
+}
+
+void AddressbookWindow::populateCategories()
+{
+ catMenu->clear();
+
+ int id,
+ rememberId;
+ id = 1;
+ catMenu->insertItem( tr( "All" ), id++ );
+ QStringList categories = abList->categories();
+ categories.append( tr( "Unfiled" ) );
+ for ( QStringList::Iterator it = categories.begin();
+ it != categories.end(); ++it ) {
+ catMenu->insertItem( *it, id );
+ if ( *it == abList->showCategory() )
+ rememberId = id;
+ ++id;
+ }
+ if ( abList->showCategory().isEmpty() )
+ slotSetCategory( 1 );
+ else
+ slotSetCategory( rememberId );
+}
diff --git a/core/pim/addressbook/addressbook.cw b/core/pim/addressbook/addressbook.cw
new file mode 100644
index 0000000..452df36
--- a/dev/null
+++ b/core/pim/addressbook/addressbook.cw
@@ -0,0 +1,26 @@
+<!DOCTYPE CW><CW>
+<customwidgets>
+ <customwidget>
+ <class>AbLineEdit</class>
+ <header location="local">ablineedit.h</header>
+ <sizehint>
+ <width>-1</width>
+ <height>-1</height>
+ </sizehint>
+ <pixmap>
+ <data format="XPM.GZ" length="646">789c6dd2c10ac2300c00d07bbf2234b7229d1be245fc04c5a3201e4615f430059d0711ff5ddb2e6bb236ec90eed134cb5a19d8ef36602af5ecdbfeeac05dda0798d3abebde87e3faa374d3807fa0d633a52d38d8de6f679fe33fc776e196f53cd010188256a3600a292882096246517815ca99884606e18044a3a40d91824820924265a7923a2e8bcd05f33db1173e002913175f2a6be6d3294871a2d95fa00e8a94ee017b69d339d90df1e77c57ea072ede6758</data>
+ </pixmap>
+ </customwidget>
+ <customwidget>
+ <class>AbMultiLineEdit</class>
+ <header location="local">abmultilineedit.h</header>
+ <sizehint>
+ <width>-1</width>
+ <height>-1</height>
+ </sizehint>
+ <pixmap>
+ <data format="XPM.GZ" length="646">789c6dd2c10ac2300c00d07bbf2234b7229d1be245fc04c5a3201e4615f430059d0711ff5ddb2e6bb236ec90eed134cb5a19d8ef36602af5ecdbfeeac05dda0798d3abebde87e3faa374d3807fa0d633a52d38d8de6f679fe33fc776e196f53cd010188256a3600a292882096246517815ca99884606e18044a3a40d91824820924265a7923a2e8bcd05f33db1173e002913175f2a6be6d3294871a2d95fa00e8a94ee017b69d339d90df1e77c57ea072ede6758</data>
+ </pixmap>
+ </customwidget>
+</customwidgets>
+</CW>
diff --git a/core/pim/addressbook/addressbook.h b/core/pim/addressbook/addressbook.h
new file mode 100644
index 0000000..9694465
--- a/dev/null
+++ b/core/pim/addressbook/addressbook.h
@@ -0,0 +1,99 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qt Palmtop Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef Addressbook_H
+#define Addressbook_H
+
+#include <qmainwindow.h>
+
+class AbEditor;
+class AbLabel;
+class AbTable;
+class QPEToolBar;
+class QPopupMenu;
+class QToolButton;
+class QDialog;
+class Ir;
+class QAction;
+
+class AddressbookWindow: public QMainWindow
+{
+ Q_OBJECT
+public:
+ AddressbookWindow( QWidget *parent = 0, const char *name = 0, WFlags f = 0 );
+ ~AddressbookWindow();
+
+protected:
+ void resizeEvent( QResizeEvent * e );
+ void showList();
+ void showView();
+ enum EntryMode { NewEntry=0, EditEntry };
+ void editPersonal();
+ void editEntry( EntryMode );
+ void closeEvent( QCloseEvent *e );
+ bool save();
+
+public slots:
+ void flush();
+ void reload();
+ void appMessage(const QCString &, const QByteArray &);
+ void setDocument( const QString & );
+
+private slots:
+ void slotListNew();
+ void slotListView();
+ void slotListDelete();
+ void slotViewBack();
+ void slotViewEdit();
+ void slotPersonalView();
+ void listIsEmpty( bool );
+ void slotSettings();
+ void writeMail();
+ void slotBeam();
+ void beamDone( Ir * );
+ void slotFind();
+ void slotSetCategory( int );
+ void slotUpdateToolbar();
+
+private:
+ void initFields(); // inititialize our fields...
+ AbLabel *abView();
+ void populateCategories();
+
+ QPopupMenu *catMenu;
+ QPEToolBar *listTools;
+ QToolButton *deleteButton;
+ QValueList<int> allFields,
+ orderedFields;
+ QStringList slOrderedFields;
+ enum Panes { paneList=0, paneView, paneEdit };
+ AbEditor *abEditor;
+ AbLabel *mView;
+ AbTable *abList;
+
+ QAction *actionNew, *actionEdit, *actionTrash, *actionFind, *actionBeam,
+ *actionPersonal, *actionMail;
+
+ bool bAbEditFirstTime;
+ int viewMargin;
+
+ bool syncing;
+};
+
+#endif
diff --git a/core/pim/addressbook/addressbook.pro b/core/pim/addressbook/addressbook.pro
new file mode 100644
index 0000000..8d3401d
--- a/dev/null
+++ b/core/pim/addressbook/addressbook.pro
@@ -0,0 +1,22 @@
+TEMPLATE = app
+CONFIG = qt warn_on release
+DESTDIR = $(QPEDIR)/bin
+HEADERS = addressbook.h \
+ abeditor.h \
+ ablabel.h \
+ abtable.h \
+ addresssettings.h
+SOURCES = main.cpp \
+ addressbook.cpp \
+ abeditor.cpp \
+ ablabel.cpp \
+ abtable.cpp \
+ addresssettings.cpp
+INTERFACES = addresssettingsbase.ui
+
+TARGET = addressbook
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += $(QPEDIR)/include
+LIBS += -lqpe
+
+TRANSLATIONS = ../i18n/de/addressbook.ts
diff --git a/core/pim/addressbook/addresspicker.cpp b/core/pim/addressbook/addresspicker.cpp
new file mode 100644
index 0000000..79c4d43
--- a/dev/null
+++ b/core/pim/addressbook/addresspicker.cpp
@@ -0,0 +1,52 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qt Palmtop Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "addresspicker.h"
+#include "abtable.h"
+
+#include <qlayout.h>
+
+/*!
+ \a tab is reparented for use in the picker. Take it back out if you want
+ to regain ownership.
+*/
+AddressPicker::AddressPicker(AbTable* tab, QWidget* parent, const char* name, bool modal) :
+ QDialog(parent,name,modal)
+{
+ QVBoxLayout* vb = new QVBoxLayout(this);
+ tab->reparent(this,QPoint(0,0));
+ table = tab;
+ vb->addWidget(table);
+}
+
+void AddressPicker::setChoiceNames(const QStringList& list)
+{
+ table->setChoiceNames(list);
+}
+
+void AddressPicker::setSelection(int index, const QStringList& list)
+{
+ table->setChoiceSelection(index,list);
+}
+
+QStringList AddressPicker::selection(int index) const
+{
+ return table->choiceSelection(index);
+}
diff --git a/core/pim/addressbook/addresspicker.h b/core/pim/addressbook/addresspicker.h
new file mode 100644
index 0000000..8a57479
--- a/dev/null
+++ b/core/pim/addressbook/addresspicker.h
@@ -0,0 +1,39 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qt Palmtop Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef AddressPicker_H
+#define AddressPicker_H
+
+#include <qdialog.h>
+
+class AbTable;
+
+class AddressPicker : public QDialog {
+public:
+ AddressPicker(AbTable* table, QWidget* parent, const char* name=0, bool modal=FALSE);
+
+ void setChoiceNames(const QStringList&);
+ void setSelection(int index, const QStringList&);
+ QStringList selection(int index) const;
+
+private:
+ AbTable* table;
+};
+
+#endif
diff --git a/core/pim/addressbook/addresssettings.cpp b/core/pim/addressbook/addresssettings.cpp
new file mode 100644
index 0000000..e7c2210
--- a/dev/null
+++ b/core/pim/addressbook/addresssettings.cpp
@@ -0,0 +1,136 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qt Palmtop Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+
+#include "addresssettings.h"
+
+#include <qpe/config.h>
+#include <qpe/contact.h>
+
+#include <qfile.h>
+#include <qlistbox.h>
+
+#include <stdlib.h>
+
+AddressSettings::AddressSettings( QWidget *parent, const char *name )
+ : AddressSettingsBase( parent, name, TRUE )
+{
+ init();
+}
+
+AddressSettings::~AddressSettings()
+{
+}
+
+void AddressSettings::init()
+{
+ QStringList slFields = Contact::trfields();
+ // Make this match what is in initFields
+ slFields.remove( tr("Name Title") );
+ slFields.remove( tr("First Name") );
+ slFields.remove( tr("Last Name") );
+ slFields.remove( tr("File As") );
+ slFields.remove( tr("Default Email") );
+ slFields.remove( tr("Notes") );
+ slFields.remove( tr("Gender") );
+
+
+ for( QStringList::Iterator it = slFields.begin();
+ it != slFields.end(); ++it ) {
+ fieldListBox->insertItem( *it );
+ }
+
+ Config cfg( "AddressBook" );
+
+ cfg.setGroup( "Version" );
+ int version;
+ version = cfg.readNumEntry( "version" );
+ if ( version >= ADDRESSVERSION ) {
+ int i = 0;
+ int p = 0;
+ cfg.setGroup( "ImportantCategory" );
+ QString zn = cfg.readEntry( "Category" + QString::number(i),
+ QString::null );
+ while ( !zn.isNull() ) {
+ for ( int m = i; m < (int)fieldListBox->count(); m++ ) {
+ if ( fieldListBox->text( m ) == zn ) {
+ if ( m != p ) {
+ fieldListBox->removeItem( m );
+ fieldListBox->insertItem( zn, p );
+ }
+ p++;
+ break;
+ }
+ }
+ zn = cfg.readEntry( "Category" + QString::number(++i),
+ QString::null );
+ }
+
+ fieldListBox->setCurrentItem( 0 );
+ } else {
+ QString str;
+ str = getenv("HOME");
+
+ str += "/Settings/AddressBook.conf";
+ QFile::remove( str );
+ }
+}
+
+void AddressSettings::itemUp()
+{
+ int i = fieldListBox->currentItem();
+ if ( i > 0 ) {
+ QString item = fieldListBox->currentText();
+ fieldListBox->removeItem( i );
+ fieldListBox->insertItem( item, i-1 );
+ fieldListBox->setCurrentItem( i-1 );
+ }
+}
+
+void AddressSettings::itemDown()
+{
+ int i = fieldListBox->currentItem();
+ if ( i < (int)fieldListBox->count() - 1 ) {
+ QString item = fieldListBox->currentText();
+ fieldListBox->removeItem( i );
+ fieldListBox->insertItem( item, i+1 );
+ fieldListBox->setCurrentItem( i+1 );
+ }
+}
+
+void AddressSettings::accept()
+{
+ save();
+ QDialog::accept();
+}
+
+
+void AddressSettings::save()
+{
+ Config cfg( "AddressBook" );
+ cfg.setGroup( "Version" );
+ // *** To change the version change it here...
+ cfg.writeEntry( "version", QString::number(ADDRESSVERSION) );
+ cfg.setGroup( "ImportantCategory" );
+
+ for ( int i = 0; i < (int)fieldListBox->count(); i++ ) {
+ cfg.writeEntry( "Category"+QString::number(i), fieldListBox->text(i) );
+ }
+}
diff --git a/core/pim/addressbook/addresssettings.h b/core/pim/addressbook/addresssettings.h
new file mode 100644
index 0000000..0fdfa77
--- a/dev/null
+++ b/core/pim/addressbook/addresssettings.h
@@ -0,0 +1,47 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qt Palmtop Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef _ADDRESSSETTINGS_H_
+#define _ADDRESSSETTINGS_H_
+
+#include <qlist.h>
+#include <qstringlist.h>
+#include "addresssettingsbase.h"
+
+const int ADDRESSVERSION = 3;
+
+class AddressSettings : public AddressSettingsBase
+{
+ Q_OBJECT
+public:
+ AddressSettings( QWidget *parent = 0, const char *name = 0 );
+ ~AddressSettings();
+
+protected:
+ void accept();
+ virtual void itemUp();
+ virtual void itemDown();
+
+private:
+ void init();
+ void save();
+};
+
+#endif // _ADDRESSSETTINGS_H_
diff --git a/core/pim/addressbook/addresssettingsbase.ui b/core/pim/addressbook/addresssettingsbase.ui
new file mode 100644
index 0000000..bd3b85b
--- a/dev/null
+++ b/core/pim/addressbook/addresssettingsbase.ui
@@ -0,0 +1,170 @@
+<!DOCTYPE UI><UI>
+<class>AddressSettingsBase</class>
+<comment>/**********************************************************************
+** Copyright (C) 2001 Trolltech AS. All rights reserved.
+**
+** This file is part of Qt Palmtop Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+** $Id$
+**
+**********************************************************************/</comment>
+<widget>
+ <class>QDialog</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>AddressSettingsBase</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>244</width>
+ <height>207</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>Arrange Edit Fields</string>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <grid>
+ <property stdset="1">
+ <name>margin</name>
+ <number>6</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget row="1" column="0" rowspan="3" colspan="1" >
+ <class>QListBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>fieldListBox</cstring>
+ </property>
+ </widget>
+ <widget row="0" column="0" rowspan="1" colspan="2" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>lblExplain</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>1</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>MShape</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>MShadow</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Select the field order:</string>
+ </property>
+ <property stdset="1">
+ <name>alignment</name>
+ <set>AlignTop|AlignLeft</set>
+ </property>
+ <property>
+ <name>hAlign</name>
+ </property>
+ <property>
+ <name>vAlign</name>
+ </property>
+ </widget>
+ <widget row="1" column="1" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>upButton</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Up</string>
+ </property>
+ <property stdset="1">
+ <name>autoRepeat</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget row="2" column="1" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>downButton</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Down</string>
+ </property>
+ <property stdset="1">
+ <name>autoRepeat</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <spacer row="3" column="1" >
+ <property>
+ <name>name</name>
+ <cstring>Spacer2</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Vertical</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>upButton</sender>
+ <signal>clicked()</signal>
+ <receiver>AddressSettingsBase</receiver>
+ <slot>itemUp()</slot>
+ </connection>
+ <connection>
+ <sender>downButton</sender>
+ <signal>clicked()</signal>
+ <receiver>AddressSettingsBase</receiver>
+ <slot>itemDown()</slot>
+ </connection>
+ <slot access="protected">itemUp()</slot>
+ <slot access="protected">itemDown()</slot>
+</connections>
+</UI>
diff --git a/core/pim/addressbook/main.cpp b/core/pim/addressbook/main.cpp
new file mode 100644
index 0000000..2ea1819
--- a/dev/null
+++ b/core/pim/addressbook/main.cpp
@@ -0,0 +1,41 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qt Palmtop Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "addressbook.h"
+
+#include <qpe/qpeapplication.h>
+#include <qpe/qcopenvelope_qws.h>
+#include <qstring.h>
+
+int main( int argc, char ** argv )
+{
+ QPEApplication a( argc, argv );
+
+ AddressbookWindow mw;
+ QObject::connect( &a, SIGNAL( flush() ), &mw, SLOT( flush() ) );
+ QObject::connect( &a, SIGNAL( reload() ), &mw, SLOT( reload() ) );
+ QObject::connect( &a, SIGNAL( appMessage(const QCString &, const QByteArray &) ),
+ &mw, SLOT( appMessage(const QCString &, const QByteArray &) ) );
+
+ mw.setCaption( AddressbookWindow::tr("Contacts") );
+ a.showMainDocumentWidget(&mw);
+
+ return a.exec();
+}
diff --git a/core/pim/addressbook/qpe-addressbook.control b/core/pim/addressbook/qpe-addressbook.control
new file mode 100644
index 0000000..cca98f3
--- a/dev/null
+++ b/core/pim/addressbook/qpe-addressbook.control
@@ -0,0 +1,9 @@
+Files: bin/addressbook apps/Applications/addressbook.desktop
+Priority: optional
+Section: qpe/applications
+Maintainer: Warwick Allison <warwick@trolltech.com>
+Architecture: arm
+Version: $QPE_VERSION-3
+Depends: qpe-base ($QPE_VERSION)
+Description: Contacts
+ A simple addressbook for the Qtopia environment.
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 @@
+moc_*
+Makefile
+dateentry.h
+datebookdayheader.h
+dateentry.cpp
+datebookdayheader.cpp
+datebookweekheader.cpp
+datebookweekheader.h
+datebooksettingsbase.h
+datebooksettingsbase.cpp
+repeatentrybase.cpp
+repeatentrybase.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 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS)
+INCPATH = -I$(QPEDIR)/include
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = $(QPEDIR)/bin/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = datebook
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = datebookday.h \
+ datebook.h \
+ dateentryimpl.h \
+ datebookdayheaderimpl.h \
+ datebooksettings.h \
+ datebookweek.h \
+ datebookweekheaderimpl.h \
+ repeatentry.h
+SOURCES = main.cpp \
+ datebookday.cpp \
+ datebook.cpp \
+ dateentryimpl.cpp \
+ datebookdayheaderimpl.cpp \
+ datebooksettings.cpp \
+ datebookweek.cpp \
+ datebookweekheaderimpl.cpp \
+ repeatentry.cpp
+OBJECTS = main.o \
+ datebookday.o \
+ datebook.o \
+ dateentryimpl.o \
+ datebookdayheaderimpl.o \
+ datebooksettings.o \
+ datebookweek.o \
+ datebookweekheaderimpl.o \
+ repeatentry.o \
+ dateentry.o \
+ datebookdayheader.o \
+ datebooksettingsbase.o \
+ datebookweekheader.o \
+ repeatentrybase.o
+INTERFACES = dateentry.ui \
+ datebookdayheader.ui \
+ datebooksettingsbase.ui \
+ datebookweekheader.ui \
+ repeatentrybase.ui
+UICDECLS = dateentry.h \
+ datebookdayheader.h \
+ datebooksettingsbase.h \
+ datebookweekheader.h \
+ repeatentrybase.h
+UICIMPLS = dateentry.cpp \
+ datebookdayheader.cpp \
+ datebooksettingsbase.cpp \
+ datebookweekheader.cpp \
+ repeatentrybase.cpp
+SRCMOC = moc_datebookday.cpp \
+ moc_datebook.cpp \
+ moc_dateentryimpl.cpp \
+ moc_datebookdayheaderimpl.cpp \
+ moc_datebookweek.cpp \
+ moc_datebookweekheaderimpl.cpp \
+ moc_repeatentry.cpp \
+ moc_dateentry.cpp \
+ moc_datebookdayheader.cpp \
+ moc_datebooksettingsbase.cpp \
+ moc_datebookweekheader.cpp \
+ moc_repeatentrybase.cpp
+OBJMOC = moc_datebookday.o \
+ moc_datebook.o \
+ moc_dateentryimpl.o \
+ moc_datebookdayheaderimpl.o \
+ moc_datebookweek.o \
+ moc_datebookweekheaderimpl.o \
+ moc_repeatentry.o \
+ moc_dateentry.o \
+ moc_datebookdayheader.o \
+ moc_datebooksettingsbase.o \
+ moc_datebookweekheader.o \
+ moc_repeatentrybase.o
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(TARGET)
+
+$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake datebook.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+main.o: main.cpp \
+ datebook.h \
+ $(QPEDIR)/include/qpe/datebookdb.h \
+ $(QPEDIR)/include/qpe/event.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h
+
+datebookday.o: datebookday.cpp \
+ datebookday.h \
+ $(QPEDIR)/include/qpe/event.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h \
+ datebookdayheaderimpl.h \
+ datebookdayheader.h \
+ $(QPEDIR)/include/qpe/datebookdb.h \
+ $(QPEDIR)/include/qpe/resource.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ $(QPEDIR)/include/qpe/timestring.h \
+ $(QPEDIR)/include/qpe/qpedebug.h
+
+datebook.o: datebook.cpp \
+ datebook.h \
+ $(QPEDIR)/include/qpe/datebookdb.h \
+ $(QPEDIR)/include/qpe/event.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h \
+ datebookday.h \
+ datebooksettings.h \
+ datebooksettingsbase.h \
+ datebookweek.h \
+ dateentryimpl.h \
+ dateentry.h \
+ $(QPEDIR)/include/qpe/datebookmonth.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ $(QPEDIR)/include/qpe/config.h \
+ $(QPEDIR)/include/qpe/qpedebug.h \
+ $(QPEDIR)/include/qpe/finddialog.h \
+ $(QPEDIR)/include/qpe/ir.h \
+ $(QPEDIR)/include/qpe/qpemenubar.h \
+ $(QPEDIR)/include/qpe/qpemessagebox.h \
+ $(QPEDIR)/include/qpe/resource.h \
+ $(QPEDIR)/include/qpe/sound.h \
+ $(QPEDIR)/include/qpe/timestring.h \
+ $(QPEDIR)/include/qpe/qpetoolbar.h \
+ $(QPEDIR)/include/qpe/tzselect.h \
+ $(QPEDIR)/include/qpe/xmlreader.h
+
+dateentryimpl.o: dateentryimpl.cpp \
+ dateentryimpl.h \
+ dateentry.h \
+ $(QPEDIR)/include/qpe/event.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h \
+ repeatentry.h \
+ repeatentrybase.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ $(QPEDIR)/include/qpe/categoryselect.h \
+ $(QPEDIR)/include/qpe/datebookmonth.h \
+ $(QPEDIR)/include/qpe/global.h \
+ $(QPEDIR)/include/qpe/timeconversion.h \
+ $(QPEDIR)/include/qpe/timestring.h \
+ $(QPEDIR)/include/qpe/tzselect.h
+
+datebookdayheaderimpl.o: datebookdayheaderimpl.cpp \
+ datebookdayheaderimpl.h \
+ datebookdayheader.h \
+ $(QPEDIR)/include/qpe/datebookmonth.h \
+ $(QPEDIR)/include/qpe/event.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h \
+ $(QPEDIR)/include/qpe/timestring.h
+
+datebooksettings.o: datebooksettings.cpp \
+ datebooksettings.h \
+ datebooksettingsbase.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h
+
+datebookweek.o: datebookweek.cpp \
+ datebookweek.h \
+ $(QPEDIR)/include/qpe/event.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h \
+ datebookweekheaderimpl.h \
+ datebookweekheader.h \
+ $(QPEDIR)/include/qpe/calendar.h \
+ $(QPEDIR)/include/qpe/datebookdb.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ $(QPEDIR)/include/qpe/timestring.h
+
+datebookweekheaderimpl.o: datebookweekheaderimpl.cpp \
+ datebookweekheaderimpl.h \
+ datebookweekheader.h
+
+repeatentry.o: repeatentry.cpp \
+ repeatentry.h \
+ repeatentrybase.h \
+ $(QPEDIR)/include/qpe/event.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h \
+ $(QPEDIR)/include/qpe/datebookmonth.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ $(QPEDIR)/include/qpe/timestring.h
+
+dateentry.h: dateentry.ui
+ $(UIC) dateentry.ui -o $(INTERFACE_DECL_PATH)/dateentry.h
+
+dateentry.cpp: dateentry.ui
+ $(UIC) dateentry.ui -i dateentry.h -o dateentry.cpp
+
+datebookdayheader.h: datebookdayheader.ui
+ $(UIC) datebookdayheader.ui -o $(INTERFACE_DECL_PATH)/datebookdayheader.h
+
+datebookdayheader.cpp: datebookdayheader.ui
+ $(UIC) datebookdayheader.ui -i datebookdayheader.h -o datebookdayheader.cpp
+
+datebooksettingsbase.h: datebooksettingsbase.ui
+ $(UIC) datebooksettingsbase.ui -o $(INTERFACE_DECL_PATH)/datebooksettingsbase.h
+
+datebooksettingsbase.cpp: datebooksettingsbase.ui
+ $(UIC) datebooksettingsbase.ui -i datebooksettingsbase.h -o datebooksettingsbase.cpp
+
+datebookweekheader.h: datebookweekheader.ui
+ $(UIC) datebookweekheader.ui -o $(INTERFACE_DECL_PATH)/datebookweekheader.h
+
+datebookweekheader.cpp: datebookweekheader.ui
+ $(UIC) datebookweekheader.ui -i datebookweekheader.h -o datebookweekheader.cpp
+
+repeatentrybase.h: repeatentrybase.ui
+ $(UIC) repeatentrybase.ui -o $(INTERFACE_DECL_PATH)/repeatentrybase.h
+
+repeatentrybase.cpp: repeatentrybase.ui
+ $(UIC) repeatentrybase.ui -i repeatentrybase.h -o repeatentrybase.cpp
+
+dateentry.o: dateentry.cpp
+
+datebookdayheader.o: datebookdayheader.cpp
+
+datebooksettingsbase.o: datebooksettingsbase.cpp
+
+datebookweekheader.o: datebookweekheader.cpp
+
+repeatentrybase.o: repeatentrybase.cpp
+
+moc_datebookday.o: moc_datebookday.cpp \
+ datebookday.h \
+ $(QPEDIR)/include/qpe/event.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h
+
+moc_datebook.o: moc_datebook.cpp \
+ datebook.h \
+ $(QPEDIR)/include/qpe/datebookdb.h \
+ $(QPEDIR)/include/qpe/event.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h
+
+moc_dateentryimpl.o: moc_dateentryimpl.cpp \
+ dateentryimpl.h \
+ dateentry.h \
+ $(QPEDIR)/include/qpe/event.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h
+
+moc_datebookdayheaderimpl.o: moc_datebookdayheaderimpl.cpp \
+ datebookdayheaderimpl.h \
+ datebookdayheader.h
+
+moc_datebookweek.o: moc_datebookweek.cpp \
+ datebookweek.h \
+ $(QPEDIR)/include/qpe/event.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h
+
+moc_datebookweekheaderimpl.o: moc_datebookweekheaderimpl.cpp \
+ datebookweekheaderimpl.h \
+ datebookweekheader.h
+
+moc_repeatentry.o: moc_repeatentry.cpp \
+ repeatentry.h \
+ repeatentrybase.h \
+ $(QPEDIR)/include/qpe/event.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h
+
+moc_dateentry.o: moc_dateentry.cpp \
+ dateentry.h
+
+moc_datebookdayheader.o: moc_datebookdayheader.cpp \
+ datebookdayheader.h
+
+moc_datebooksettingsbase.o: moc_datebooksettingsbase.cpp \
+ datebooksettingsbase.h
+
+moc_datebookweekheader.o: moc_datebookweekheader.cpp \
+ datebookweekheader.h
+
+moc_repeatentrybase.o: moc_repeatentrybase.cpp \
+ repeatentrybase.h
+
+moc_datebookday.cpp: datebookday.h
+ $(MOC) datebookday.h -o moc_datebookday.cpp
+
+moc_datebook.cpp: datebook.h
+ $(MOC) datebook.h -o moc_datebook.cpp
+
+moc_dateentryimpl.cpp: dateentryimpl.h
+ $(MOC) dateentryimpl.h -o moc_dateentryimpl.cpp
+
+moc_datebookdayheaderimpl.cpp: datebookdayheaderimpl.h
+ $(MOC) datebookdayheaderimpl.h -o moc_datebookdayheaderimpl.cpp
+
+moc_datebookweek.cpp: datebookweek.h
+ $(MOC) datebookweek.h -o moc_datebookweek.cpp
+
+moc_datebookweekheaderimpl.cpp: datebookweekheaderimpl.h
+ $(MOC) datebookweekheaderimpl.h -o moc_datebookweekheaderimpl.cpp
+
+moc_repeatentry.cpp: repeatentry.h
+ $(MOC) repeatentry.h -o moc_repeatentry.cpp
+
+moc_dateentry.cpp: dateentry.h
+ $(MOC) dateentry.h -o moc_dateentry.cpp
+
+moc_datebookdayheader.cpp: datebookdayheader.h
+ $(MOC) datebookdayheader.h -o moc_datebookdayheader.cpp
+
+moc_datebooksettingsbase.cpp: datebooksettingsbase.h
+ $(MOC) datebooksettingsbase.h -o moc_datebooksettingsbase.cpp
+
+moc_datebookweekheader.cpp: datebookweekheader.h
+ $(MOC) datebookweekheader.h -o moc_datebookweekheader.cpp
+
+moc_repeatentrybase.cpp: repeatentrybase.h
+ $(MOC) repeatentrybase.h -o moc_repeatentrybase.cpp
+
+
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 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+** $Id$
+**
+**********************************************************************/
+
+#include "datebook.h"
+#include "datebookday.h"
+#include "datebooksettings.h"
+#include "datebookweek.h"
+#include "dateentryimpl.h"
+
+#include <qpe/datebookmonth.h>
+#include <qpe/qpeapplication.h>
+#include <qpe/config.h>
+#include <qpe/qpedebug.h>
+#include <qpe/event.h>
+#include <qpe/finddialog.h>
+#include <qpe/ir.h>
+#include <qpe/qpemenubar.h>
+#include <qpe/qpemessagebox.h>
+#include <qpe/resource.h>
+#include <qpe/sound.h>
+#include <qpe/timestring.h>
+#include <qpe/qpetoolbar.h>
+#include <qpe/tzselect.h>
+#include <qpe/xmlreader.h>
+
+#include <qaction.h>
+#include <qcopchannel_qws.h>
+#include <qdatetime.h>
+#include <qdialog.h>
+#include <qfile.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qmessagebox.h>
+#include <qpopupmenu.h>
+#include <qpushbutton.h>
+#include <qtextcodec.h>
+#include <qtextstream.h>
+#include <qtl.h>
+#include <qwidgetstack.h>
+#include <qwindowsystem_qws.h>
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <stdlib.h>
+
+#define DAY 1
+#define WEEK 2
+#define MONTH 3
+
+
+DateBook::DateBook( QWidget *parent, const char *, WFlags f )
+ : QMainWindow( parent, "datebook", f ),
+ aPreset( FALSE ),
+ presetTime( -1 ),
+ startTime( 8 ), // an acceptable default
+ syncing(FALSE),
+ inSearch(FALSE)
+{
+ QTime t;
+ t.start();
+ db = new DateBookDB;
+ qDebug("loading db t=%d", t.elapsed() );
+ loadSettings();
+ setCaption( tr("Calendar") );
+ setIcon( Resource::loadPixmap( "datebook_icon" ) );
+
+ setToolBarsMovable( FALSE );
+
+ QPEToolBar *bar = new QPEToolBar( this );
+ bar->setHorizontalStretchable( TRUE );
+
+ QPEMenuBar *mb = new QPEMenuBar( bar );
+ mb->setMargin( 0 );
+
+ QPEToolBar *sub_bar = new QPEToolBar(this);
+
+ QPopupMenu *view = new QPopupMenu( this );
+ QPopupMenu *settings = new QPopupMenu( this );
+
+ mb->insertItem( tr( "View" ), view );
+ mb->insertItem( tr( "Settings" ), settings );
+
+ QActionGroup *g = new QActionGroup( this );
+ g->setExclusive( TRUE );
+
+ QAction *a = new QAction( tr( "New" ), Resource::loadPixmap( "new" ),
+ QString::null, 0, this, 0 );
+ connect( a, SIGNAL( activated() ), this, SLOT( fileNew() ) );
+ a->addTo( sub_bar );
+
+ a = new QAction( tr( "Day" ), Resource::loadPixmap( "day" ), QString::null, 0, g, 0 );
+ connect( a, SIGNAL( activated() ), this, SLOT( viewDay() ) );
+ a->addTo( sub_bar );
+ a->addTo( view );
+ a->setToggleAction( TRUE );
+ a->setOn( TRUE );
+ dayAction = a;
+ a = new QAction( tr( "Week" ), Resource::loadPixmap( "week" ), QString::null, 0, g, 0 );
+ connect( a, SIGNAL( activated() ), this, SLOT( viewWeek() ) );
+ a->addTo( sub_bar );
+ a->addTo( view );
+ a->setToggleAction( TRUE );
+ weekAction = a;
+ a = new QAction( tr( "Month" ), Resource::loadPixmap( "month" ), QString::null, 0, g, 0 );
+ connect( a, SIGNAL( activated() ), this, SLOT( viewMonth() ) );
+ a->addTo( sub_bar );
+ a->addTo( view );
+ a->setToggleAction( TRUE );
+ monthAction = a;
+
+ a = new QAction( tr( "Find" ), Resource::loadPixmap( "mag" ), QString::null, 0, g, 0 );
+ connect( a, SIGNAL(activated()), this, SLOT(slotFind()) );
+ a->addTo( sub_bar );
+
+ a = new QAction( tr( "Today" ), QString::null, 0, 0 );
+ connect( a, SIGNAL( activated() ), this, SLOT( slotToday() ) );
+ a->addTo( view );
+
+ a = new QAction( tr( "Alarm and Start Time..." ), QString::null, 0, 0 );
+ connect( a, SIGNAL( activated() ), this, SLOT( slotSettings() ) );
+ a->addTo( settings );
+
+ views = new QWidgetStack( this );
+ setCentralWidget( views );
+
+ dayView = 0;
+ weekView = 0;
+ monthView = 0;
+
+ viewDay();
+ connect( qApp, SIGNAL(clockChanged(bool)),
+ this, SLOT(changeClock(bool)) );
+ connect( qApp, SIGNAL(weekChanged(bool)),
+ this, SLOT(changeWeek(bool)) );
+
+#if defined(Q_WS_QWS) && !defined(QT_NO_COP)
+ connect( qApp, SIGNAL(appMessage(const QCString&, const QByteArray&)),
+ this, SLOT(appMessage(const QCString&, const QByteArray&)) );
+#endif
+
+ // listen on QPE/System
+#if defined(Q_WS_QWS)
+#if !defined(QT_NO_COP)
+ QCopChannel *channel = new QCopChannel( "QPE/System", this );
+ connect( channel, SIGNAL(received(const QCString&, const QByteArray&)),
+ this, SLOT(receive(const QCString&, const QByteArray&)) );
+#endif
+#endif
+
+ qDebug("done t=%d", t.elapsed() );
+
+}
+
+void DateBook::receive( const QCString &msg, const QByteArray &data )
+{
+ QDataStream stream( data, IO_ReadOnly );
+ if ( msg == "timeChange(QString)" ) {
+ // update active view!
+ if ( dayAction->isOn() )
+ viewDay();
+ else if ( weekAction->isOn() )
+ viewWeek();
+ else if ( monthAction->isOn() )
+ viewMonth();
+ }
+}
+
+DateBook::~DateBook()
+{
+}
+
+void DateBook::slotSettings()
+{
+ DateBookSettings frmSettings( ampm, this );
+ frmSettings.setStartTime( startTime );
+ frmSettings.setAlarmPreset( aPreset, presetTime );
+#if defined (Q_WS_QWS) || defined(_WS_QWS_)
+ frmSettings.showMaximized();
+#endif
+
+ if ( frmSettings.exec() ) {
+ aPreset = frmSettings.alarmPreset();
+ presetTime = frmSettings.presetTime();
+ startTime = frmSettings.startTime();
+ if ( dayView )
+ dayView->setStartViewTime( startTime );
+ if ( weekView )
+ weekView->setStartViewTime( startTime );
+ saveSettings();
+
+ // make the change obvious
+ if ( views->visibleWidget() ) {
+ if ( views->visibleWidget() == dayView )
+ dayView->redraw();
+ else if ( views->visibleWidget() == weekView )
+ weekView->redraw();
+ }
+ }
+}
+
+void DateBook::fileNew()
+{
+ slotNewEventFromKey("");
+}
+
+QString DateBook::checkEvent(const Event &e)
+{
+ /* check if overlaps with itself */
+ bool checkFailed = FALSE;
+
+ /* check the next 12 repeats. should catch most problems */
+ QDate current_date = e.start().date();
+ Event previous = e;
+ for(int i = 0; i < 12; i++)
+ {
+ QDateTime next;
+ if (!nextOccurance(previous, current_date.addDays(1), next)) {
+ break; // no more repeats
+ }
+ if(next < previous.end()) {
+ checkFailed = TRUE;
+ break;
+ }
+ current_date = next.date();
+ }
+
+ if(checkFailed)
+ return tr("Event duration is potentially longer\n"
+ "than interval between repeats.");
+
+ return QString::null;
+}
+
+QDate DateBook::currentDate()
+{
+ QDate d = QDate::currentDate();
+
+ if ( dayView && views->visibleWidget() == dayView ) {
+ d = dayView->date();
+ } else if ( weekView && views->visibleWidget() == weekView ) {
+ d = weekView->date();
+ } else if ( monthView && views->visibleWidget() == monthView ) {
+ d = monthView->selectedDate();
+ }
+
+ return d;
+}
+
+void DateBook::viewDay()
+{
+ initDay();
+ dayAction->setOn( TRUE );
+ QDate d = currentDate();
+ dayView->setDate( d );
+ views->raiseWidget( dayView );
+ dayView->redraw();
+}
+
+void DateBook::viewWeek()
+{
+ initWeek();
+ weekAction->setOn( TRUE );
+ QDate d = currentDate();
+ weekView->setDate( d );
+ views->raiseWidget( weekView );
+ weekView->redraw();
+}
+
+void DateBook::viewMonth()
+{
+ initMonth();
+ monthAction->setOn( TRUE );
+ QDate d = currentDate();
+ monthView->setDate( d.year(), d.month(), d.day() );
+ views->raiseWidget( monthView );
+ monthView->redraw();
+}
+
+void DateBook::editEvent( const Event &e )
+{
+ if (syncing) {
+ QMessageBox::warning( this, tr("Calendar"),
+ tr( "Can not edit data, currently syncing") );
+ return;
+ }
+
+ // workaround added for text input.
+ QDialog editDlg( this, 0, TRUE );
+ DateEntry *entry;
+ editDlg.setCaption( tr("Edit Event") );
+ QVBoxLayout *vb = new QVBoxLayout( &editDlg );
+ QScrollView *sv = new QScrollView( &editDlg, "scrollview" );
+ sv->setResizePolicy( QScrollView::AutoOneFit );
+ // KLUDGE!!!
+ sv->setHScrollBarMode( QScrollView::AlwaysOff );
+ vb->addWidget( sv );
+ entry = new DateEntry( onMonday, e, ampm, &editDlg, "editor" );
+ entry->timezone->setEnabled( FALSE );
+ sv->addChild( entry );
+
+#if defined(Q_WS_QWS) || defined(_WS_QWS_)
+ editDlg.showMaximized();
+#endif
+ while (editDlg.exec() ) {
+ Event newEv = entry->event();
+ QString error = checkEvent(newEv);
+ if (!error.isNull()) {
+ if (QMessageBox::warning(this, "error box",
+ error, "Fix it", "Continue", 0, 0, 1) == 0)
+ continue;
+ }
+ db->editEvent(e, newEv);
+ emit newEvent();
+ break;
+ }
+}
+
+void DateBook::removeEvent( const Event &e )
+{
+ if (syncing) {
+ QMessageBox::warning( this, tr("Calendar"),
+ tr( "Can not edit data, currently syncing") );
+ return;
+ }
+
+ QString strName = e.description();
+
+ if ( !QPEMessageBox::confirmDelete( this, tr( "Calendar" ),strName ) )
+ return;
+
+ db->removeEvent( e );
+ if ( views->visibleWidget() == dayView && dayView )
+ dayView->redraw();
+}
+
+void DateBook::addEvent( const Event &e )
+{
+ QDate d = e.start().date();
+ initDay();
+ dayView->setDate( d );
+}
+
+void DateBook::showDay( int year, int month, int day )
+{
+ initDay();
+ dayView->setDate( year, month, day );
+ views->raiseWidget( dayView );
+ dayAction->setOn( TRUE );
+}
+
+void DateBook::initDay()
+{
+ if ( !dayView ) {
+ dayView = new DateBookDay( ampm, onMonday, db, views, "day view" );
+ views->addWidget( dayView, DAY );
+ dayView->setStartViewTime( startTime );
+ connect( this, SIGNAL( newEvent() ),
+ dayView, SLOT( redraw() ) );
+ connect( dayView, SIGNAL( newEvent() ),
+ this, SLOT( fileNew() ) );
+ connect( dayView, SIGNAL( removeEvent( const Event & ) ),
+ this, SLOT( removeEvent( const Event & ) ) );
+ connect( dayView, SIGNAL( editEvent( const Event & ) ),
+ this, SLOT( editEvent( const Event & ) ) );
+ connect( dayView, SIGNAL( beamEvent( const Event & ) ),
+ this, SLOT( beamEvent( const Event & ) ) );
+ connect( dayView, SIGNAL(sigNewEvent(const QString &)),
+ this, SLOT(slotNewEventFromKey(const QString &)) );
+ }
+}
+
+void DateBook::initWeek()
+{
+ if ( !weekView ) {
+ weekView = new DateBookWeek( ampm, onMonday, db, views, "week view" );
+ weekView->setStartViewTime( startTime );
+ views->addWidget( weekView, WEEK );
+ connect( weekView, SIGNAL( showDate( int, int, int ) ),
+ this, SLOT( showDay( int, int, int ) ) );
+ connect( this, SIGNAL( newEvent() ),
+ weekView, SLOT( redraw() ) );
+ }
+ //But also get it right: the year that we display can be different
+ //from the year of the current date. So, first find the year
+ //number of the current week.
+
+ int yearNumber, totWeeks;
+ calcWeek( currentDate(), totWeeks, yearNumber, onMonday );
+
+ QDate d = QDate( yearNumber, 12, 31 );
+ calcWeek( d, totWeeks, yearNumber, onMonday );
+
+ while ( totWeeks == 1 ) {
+ d = d.addDays( -1 );
+ calcWeek( d, totWeeks, yearNumber, onMonday );
+ }
+ if ( totWeeks != weekView->totalWeeks() )
+ weekView->setTotalWeeks( totWeeks );
+}
+
+void DateBook::initMonth()
+{
+ if ( !monthView ) {
+ monthView = new DateBookMonth( views, "month view", FALSE, db );
+ views->addWidget( monthView, MONTH );
+ connect( monthView, SIGNAL( dateClicked( int, int, int ) ),
+ this, SLOT( showDay( int, int, int ) ) );
+ connect( this, SIGNAL( newEvent() ),
+ monthView, SLOT( redraw() ) );
+ qApp->processEvents();
+ }
+}
+
+void DateBook::loadSettings()
+{
+ {
+ Config config( "qpe" );
+ config.setGroup("Time");
+ ampm = config.readBoolEntry( "AMPM", TRUE );
+ onMonday = config.readBoolEntry( "MONDAY" );
+ }
+
+ {
+ Config config("DateBook");
+ config.setGroup("Main");
+ startTime = config.readNumEntry("startviewtime", 8);
+ aPreset = config.readBoolEntry("alarmpreset");
+ presetTime = config.readNumEntry("presettime");
+ }
+}
+
+void DateBook::saveSettings()
+{
+ Config config( "qpe" );
+ Config configDB( "DateBook" );
+ configDB.setGroup( "Main" );
+ configDB.writeEntry("startviewtime",startTime);
+ configDB.writeEntry("alarmpreset",aPreset);
+ configDB.writeEntry("presettime",presetTime);
+}
+
+void DateBook::appMessage(const QCString& msg, const QByteArray& data)
+{
+ bool needShow = FALSE;
+ if ( msg == "alarm(QDateTime,int)" ) {
+ QDataStream ds(data,IO_ReadOnly);
+ QDateTime when; int warn;
+ ds >> when >> warn;
+
+ // check to make it's okay to continue,
+ // this is the case that the time was set ahead, and
+ // we are forced given a stale alarm...
+ QDateTime current = QDateTime::currentDateTime();
+ if ( current.time().hour() != when.time().hour()
+ && current.time().minute() != when.time().minute() )
+ return;
+
+ QValueList<EffectiveEvent> list = db->getEffectiveEvents(when.addSecs(warn*60));
+ if ( list.count() > 0 ) {
+ QString msg;
+ bool bSound = FALSE;
+ int stopTimer = 0;
+ bool found = FALSE;
+ for ( QValueList<EffectiveEvent>::ConstIterator it=list.begin();
+ it!=list.end(); ++it ) {
+ if ( (*it).event().hasAlarm() ) {
+ found = TRUE;
+ msg += "<CENTER><B>" + (*it).description() + "</B>"
+ + "<BR>" + (*it).location() + "<BR>"
+ + TimeString::dateString((*it).event().start(),ampm)
+ + (warn
+ ? tr(" (in " + QString::number(warn)
+ + tr(" minutes)"))
+ : QString(""))
+ + "<BR>"
+ + (*it).notes() + "</CENTER>";
+ if ( (*it).event().alarmSound() != Event::Silent ) {
+ bSound = TRUE;
+ }
+ }
+ }
+ if ( found ) {
+ if ( bSound ) {
+ Sound::soundAlarm();
+ stopTimer = startTimer( 5000 );
+ }
+
+ QDialog dlg( this, 0, TRUE );
+ QVBoxLayout *vb = new QVBoxLayout( &dlg );
+ QScrollView *view = new QScrollView( &dlg, "scrollView");
+ view->setResizePolicy( QScrollView::AutoOneFit );
+ vb->addWidget( view );
+ QLabel *lblMsg = new QLabel( msg, &dlg );
+ view->addChild( lblMsg );
+ QPushButton *cmdOk = new QPushButton( tr("OK"), &dlg );
+ connect( cmdOk, SIGNAL(clicked()), &dlg, SLOT(accept()) );
+ vb->addWidget( cmdOk );
+
+#if defined(Q_WS_QWS) || defined(_WS_QWS_)
+ dlg.showMaximized();
+#endif
+ needShow = dlg.exec();
+
+ if ( bSound )
+ killTimer( stopTimer );
+ }
+ }
+ } else if ( msg == "nextView()" ) {
+ QWidget* cur = views->visibleWidget();
+ if ( cur ) {
+ if ( cur == dayView )
+ viewWeek();
+ else if ( cur == weekView )
+ viewMonth();
+ else if ( cur == monthView )
+ viewDay();
+ needShow = TRUE;
+ }
+ }
+ if ( needShow ) {
+#if defined(Q_WS_QWS) || defined(_WS_QWS_)
+ showMaximized();
+#else
+ show();
+#endif
+ raise();
+ QPEApplication::setKeepRunning();
+ setActiveWindow();
+ }
+}
+
+void DateBook::reload()
+{
+ db->reload();
+ if ( dayAction->isOn() )
+ viewDay();
+ else if ( weekAction->isOn() )
+ viewWeek();
+ else if ( monthAction->isOn() )
+ viewMonth();
+ syncing = FALSE;
+}
+
+void DateBook::flush()
+{
+ syncing = TRUE;
+ db->save();
+}
+
+void DateBook::timerEvent( QTimerEvent *e )
+{
+ static int stop = 0;
+ if ( stop < 10 ) {
+ Sound::soundAlarm();
+ stop++;
+ } else {
+ stop = 0;
+ killTimer( e->timerId() );
+ }
+}
+
+void DateBook::changeClock( bool newClock )
+{
+ ampm = newClock;
+ // repaint the affected objects...
+ if (dayView) dayView->redraw();
+ if (weekView) weekView->redraw();
+}
+
+void DateBook::changeWeek( bool m )
+{
+ /* no need to redraw, each widget catches. Do need to
+ store though for widgets we haven't made yet */
+ onMonday = m;
+}
+
+void DateBook::slotToday()
+{
+ // we need to view today
+ QDate dt = QDate::currentDate();
+ showDay( dt.year(), dt.month(), dt.day() );
+}
+
+void DateBook::closeEvent( QCloseEvent *e )
+{
+ if(syncing) {
+ /* no need to save, did that at flush */
+ e->accept();
+ return;
+ }
+
+ // save settings will generate it's own error messages, no
+ // need to do checking ourselves.
+ saveSettings();
+ if ( db->save() )
+ e->accept();
+ else {
+ if ( QMessageBox::critical( this, tr( "Out of space" ),
+ tr("Calendar was unable to save\n"
+ "your changes.\n"
+ "Free up some space and try again.\n"
+ "\nQuit anyway?"),
+ QMessageBox::Yes|QMessageBox::Escape,
+ QMessageBox::No|QMessageBox::Default )
+ != QMessageBox::No )
+ e->accept();
+ else
+ e->ignore();
+ }
+}
+
+// Entering directly from the "keyboard"
+void DateBook::slotNewEventFromKey( const QString &str )
+{
+ if (syncing) {
+ QMessageBox::warning( this, tr("Calendar"),
+ tr( "Can not edit data, currently syncing") );
+ return;
+ }
+
+ // We get to here from a key pressed in the Day View
+ // So we can assume some things. We want the string
+ // passed in to be part of the description.
+ QDateTime start, end;
+ if ( views->visibleWidget() == dayView ) {
+ dayView->selectedDates( start, end );
+ } else if ( views->visibleWidget() == monthView ) {
+ QDate d = monthView->selectedDate();
+ start = end = d;
+ start.setTime( QTime( 10, 0 ) );
+ end.setTime( QTime( 12, 0 ) );
+ } else if ( views->visibleWidget() == weekView ) {
+ QDate d = weekView->date();
+ start = end = d;
+ start.setTime( QTime( 10, 0 ) );
+ end.setTime( QTime( 12, 0 ) );
+ }
+
+ // argh! This really needs to be encapsulated in a class
+ // or function.
+ QDialog newDlg( this, 0, TRUE );
+ newDlg.setCaption( DateEntryBase::tr("New Event") );
+ DateEntry *e;
+ QVBoxLayout *vb = new QVBoxLayout( &newDlg );
+ QScrollView *sv = new QScrollView( &newDlg );
+ sv->setResizePolicy( QScrollView::AutoOneFit );
+ sv->setFrameStyle( QFrame::NoFrame );
+ sv->setHScrollBarMode( QScrollView::AlwaysOff );
+ vb->addWidget( sv );
+
+ Event ev;
+ ev.setDescription( str );
+ // When the new gui comes in, change this...
+ ev.setLocation( tr("(Unknown)") );
+ ev.setStart( start );
+ ev.setEnd( end );
+
+ e = new DateEntry( onMonday, ev, ampm, &newDlg );
+ e->setAlarmEnabled( aPreset, presetTime, Event::Loud );
+ sv->addChild( e );
+#if defined(Q_WS_QWS) || defined(_WS_QWS_)
+ newDlg.showMaximized();
+#endif
+ while (newDlg.exec()) {
+ ev = e->event();
+ ev.assignUid();
+ QString error = checkEvent( ev );
+ if ( !error.isNull() ) {
+ if ( QMessageBox::warning( this, tr("Error!"),
+ error, tr("Fix it"), tr("Continue"), 0, 0, 1 ) == 0 )
+ continue;
+ }
+ db->addEvent( ev );
+ emit newEvent();
+ break;
+ }
+}
+
+void DateBook::setDocument( const QString &filename )
+{
+ if ( filename.find(".vcs") != int(filename.length()) - 4 ) return;
+
+ QValueList<Event> tl = Event::readVCalendar( filename );
+ for( QValueList<Event>::Iterator it = tl.begin(); it != tl.end(); ++it ) {
+ db->addEvent( *it );
+ }
+}
+
+static const char * beamfile = "/tmp/obex/event.vcs";
+
+void DateBook::beamEvent( const Event &e )
+{
+ qDebug("trying to beamn");
+ unlink( beamfile ); // delete if exists
+ mkdir("/tmp/obex/", 0755);
+ Event::writeVCalendar( beamfile, e );
+ Ir *ir = new Ir( this );
+ connect( ir, SIGNAL( done( Ir * ) ), this, SLOT( beamDone( Ir * ) ) );
+ QString description = e.description();
+ ir->send( beamfile, description, "text/x-vCalendar" );
+}
+
+void DateBook::beamDone( Ir *ir )
+{
+ delete ir;
+ unlink( beamfile );
+}
+
+void DateBook::slotFind()
+{
+ // move it to the day view...
+ viewDay();
+ FindDialog frmFind( "Calendar", this );
+ frmFind.setUseDate( true );
+ frmFind.setDate( currentDate() );
+ QObject::connect( &frmFind,
+ SIGNAL(signalFindClicked(const QString&, const QDate&,
+ bool, bool, int)),
+ this,
+ SLOT(slotDoFind(const QString&, const QDate&,
+ bool, bool, int)) );
+ QObject::connect( this,
+ SIGNAL(signalNotFound()),
+ &frmFind,
+ SLOT(slotNotFound()) );
+ QObject::connect( this,
+ SIGNAL(signalWrapAround()),
+ &frmFind,
+ SLOT(slotWrapAround()) );
+ frmFind.exec();
+ inSearch = false;
+}
+
+bool catComp( QArray<int> cats, int category )
+{
+ bool returnMe;
+ int i,
+ count;
+
+ count = int(cats.count());
+ returnMe = false;
+ if ( (category == -1 && count == 0) || category == -2 )
+ returnMe = true;
+ else {
+ for ( i = 0; i < count; i++ ) {
+ if ( category == cats[i] ) {
+ returnMe = true;
+ break;
+ }
+ }
+ }
+ return returnMe;
+}
+
+
+void DateBook::slotDoFind( const QString& txt, const QDate &dt,
+ bool caseSensitive, bool /*backwards*/,
+ int category )
+{
+ QDateTime dtEnd( QDate(3001, 1, 1), QTime(0, 0, 0) ),
+ next;
+
+ QRegExp r( txt );
+ r.setCaseSensitive( caseSensitive );
+
+
+ static Event rev,
+ nonrev;
+ if ( !inSearch ) {
+ rev.setStart( QDateTime(QDate(1960, 1, 1), QTime(0, 0, 0)) );
+ nonrev.setStart( rev.start() );
+ inSearch = true;
+ }
+ static QDate searchDate = dt;
+ static bool wrapAround = true;
+ bool candidtate;
+ candidtate = false;
+
+ QValueList<Event> repeats = db->getRawRepeats();
+
+ // find the candidate for the first repeat that matches...
+ QValueListConstIterator<Event> it;
+ QDate start = dt;
+ for ( it = repeats.begin(); it != repeats.end(); ++it ) {
+ if ( catComp( (*it).categories(), category ) ) {
+ while ( nextOccurance( *it, start, next ) ) {
+ if ( next < dtEnd ) {
+ if ( (*it).match( r ) && !(next <= rev.start()) ) {
+ rev = *it;
+ dtEnd = next;
+ rev.setStart( next );
+ candidtate = true;
+ wrapAround = true;
+ start = dt;
+ break;
+ } else
+ start = next.date().addDays( 1 );
+ }
+ }
+ }
+ }
+
+ // now the for first non repeat...
+ QValueList<Event> nonRepeats = db->getNonRepeatingEvents( dt, dtEnd.date() );
+ qHeapSort( nonRepeats.begin(), nonRepeats.end() );
+ for ( it = nonRepeats.begin(); it != nonRepeats.end(); ++it ) {
+ if ( catComp( (*it).categories(), category ) ) {
+ if ( (*it).start() < dtEnd ) {
+ if ( (*it).match( r ) && !(*it <= nonrev) ) {
+ nonrev = *it;
+ dtEnd = nonrev.start();
+ candidtate = true;
+ wrapAround = true;
+ break;
+ }
+ }
+ }
+ }
+ if ( candidtate ) {
+ dayView->setStartViewTime( dtEnd.time().hour() );
+ dayView->setDate( dtEnd.date().year(), dtEnd.date().month(),
+ dtEnd.date().day() );
+ } else {
+ if ( wrapAround ) {
+ emit signalWrapAround();
+ rev.setStart( QDateTime(QDate(1960, 1, 1), QTime(0, 0, 0)) );
+ nonrev.setStart( rev.start() );
+ } else
+ emit signalNotFound();
+ wrapAround = !wrapAround;
+ }
+}
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 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef DATEBOOK_H
+#define DATEBOOK_H
+
+#include <qpe/datebookdb.h>
+
+#include <qmainwindow.h>
+
+class QAction;
+class QWidgetStack;
+class DateBookDay;
+class DateBookWeek;
+class DateBookMonth;
+class Event;
+class QDate;
+class Ir;
+
+class DateBook : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ DateBook( QWidget *parent = 0, const char *name = 0, WFlags f = 0 );
+ ~DateBook();
+
+signals:
+ void newEvent();
+ void signalNotFound();
+ void signalWrapAround();
+
+protected:
+ QDate currentDate();
+ void timerEvent( QTimerEvent *e );
+ void closeEvent( QCloseEvent *e );
+
+public slots:
+ void flush();
+ void reload();
+
+private slots:
+ void fileNew();
+ void slotSettings();
+ void slotToday(); // view today
+ void changeClock( bool newClock );
+ void changeWeek( bool newDay );
+ void appMessage(const QCString& msg, const QByteArray& data);
+ // handle key events in the day view...
+ void slotNewEventFromKey( const QString &str );
+ void slotFind();
+ void slotDoFind( const QString &, const QDate &, bool, bool, int );
+
+ void viewDay();
+ void viewWeek();
+ void viewMonth();
+
+ void showDay( int y, int m, int d );
+
+ void editEvent( const Event &e );
+ void removeEvent( const Event &e );
+
+ void receive( const QCString &msg, const QByteArray &data );
+ void setDocument( const QString & );
+ void beamEvent( const Event &e );
+ void beamDone( Ir *ir );
+
+private:
+ void addEvent( const Event &e );
+ void initDay();
+ void initWeek();
+ void initMonth();
+ void loadSettings();
+ void saveSettings();
+
+private:
+ DateBookDB *db;
+ QWidgetStack *views;
+ DateBookDay *dayView;
+ DateBookWeek *weekView;
+ DateBookMonth *monthView;
+ QAction *dayAction, *weekAction, *monthAction;
+ bool aPreset; // have everything set to alarm?
+ int presetTime; // the standard time for the alarm
+ int startTime;
+ bool ampm;
+ bool onMonday;
+
+ bool syncing;
+ bool inSearch;
+
+ QString checkEvent(const Event &);
+};
+
+#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 @@
+TEMPLATE = app
+CONFIG += qt warn_on release
+DESTDIR = $(QPEDIR)/bin
+
+HEADERS = datebookday.h \
+ datebook.h \
+ dateentryimpl.h \
+ datebookdayheaderimpl.h \
+ datebooksettings.h \
+ datebookweek.h \
+ datebookweekheaderimpl.h \
+ repeatentry.h
+
+SOURCES = main.cpp \
+ datebookday.cpp \
+ datebook.cpp \
+ dateentryimpl.cpp \
+ datebookdayheaderimpl.cpp \
+ datebooksettings.cpp \
+ datebookweek.cpp \
+ datebookweekheaderimpl.cpp \
+ repeatentry.cpp
+
+INTERFACES = dateentry.ui \
+ datebookdayheader.ui \
+ datebooksettingsbase.ui \
+ datebookweekheader.ui \
+ repeatentrybase.ui
+
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += $(QPEDIR)/include
+LIBS += -lqpe
+
+TARGET = datebook
+
+TRANSLATIONS = ../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 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "datebookday.h"
+#include "datebookdayheaderimpl.h"
+
+#include <qpe/datebookdb.h>
+#include <qpe/resource.h>
+#include <qpe/event.h>
+#include <qpe/qpeapplication.h>
+#include <qpe/timestring.h>
+#include <qpe/qpedebug.h>
+
+#include <qheader.h>
+#include <qdatetime.h>
+#include <qpainter.h>
+#include <qsimplerichtext.h>
+#include <qpopupmenu.h>
+#include <qtextcodec.h>
+#include <qpalette.h>
+
+DateBookDayView::DateBookDayView( bool whichClock, QWidget *parent,
+ const char *name )
+ : QTable( 24, 1, parent, name ),
+ ampm( whichClock )
+{
+ enableClipper(TRUE);
+ setTopMargin( 0 );
+ horizontalHeader()->hide();
+ setLeftMargin(38);
+ setColumnStretchable( 0, TRUE );
+ setHScrollBarMode( QScrollView::AlwaysOff );
+ verticalHeader()->setPalette(white);
+ verticalHeader()->setResizeEnabled(FALSE);
+ setSelectionMode( Single );
+
+ // get rid of being able to edit things...
+ QTableItem *tmp;
+ int row;
+ for ( row = 0; row < numRows(); row++ ) {
+ tmp = new QTableItem( this, QTableItem::Never, QString::null);
+ setItem( row, 0, tmp );
+ }
+ initHeader();
+ QObject::connect( qApp, SIGNAL(clockChanged(bool)),
+ this, SLOT(slotChangeClock(bool)) );
+}
+
+void DateBookDayView::initHeader()
+{
+ QString strTmp;
+ for ( int i = 0; i < 24; ++i ) {
+ if ( ampm ) {
+ if ( i == 0 )
+ strTmp = QString::number(12) + ":00";
+ else if ( i == 12 )
+ strTmp = QString::number(12) + tr(":00p");
+ else if ( i > 12 )
+ strTmp = QString::number( i - 12 ) + tr(":00p");
+ else
+ strTmp = QString::number(i) + ":00";
+ } else {
+ if ( i < 10 )
+ strTmp = "0" + QString::number(i) + ":00";
+ else
+ strTmp = QString::number(i) + ":00";
+ }
+ strTmp = strTmp.rightJustify( 6, ' ' );
+ verticalHeader()->setLabel( i, strTmp );
+ setRowStretchable( i, FALSE );
+ }
+}
+
+void DateBookDayView::slotChangeClock( bool newClock )
+{
+ ampm = newClock;
+ initHeader();
+}
+
+bool DateBookDayView::whichClock() const
+{
+ return ampm;
+}
+
+void DateBookDayView::moveUp()
+{
+ scrollBy(0, -20);
+}
+
+void DateBookDayView::moveDown()
+{
+ scrollBy(0, 20);
+}
+
+void DateBookDayView::paintCell( QPainter *p, int, int, const QRect &cr, bool )
+{
+ int w = cr.width();
+ int h = cr.height();
+ p->fillRect( 0, 0, w, h, colorGroup().brush( QColorGroup::Base ) );
+ if ( showGrid() ) {
+ // Draw our lines
+ int x2 = w - 1;
+ int y2 = h - 1;
+ QPen pen( p->pen() );
+ p->setPen( colorGroup().mid() );
+ p->drawLine( x2, 0, x2, y2 );
+ p->drawLine( 0, y2, x2, y2 );
+ p->setPen( pen );
+ }
+}
+
+void DateBookDayView::paintFocus( QPainter *, const QRect & )
+{
+}
+
+
+void DateBookDayView::resizeEvent( QResizeEvent *e )
+{
+ QTable::resizeEvent( e );
+ columnWidthChanged( 0 );
+ emit sigColWidthChanged();
+}
+
+void DateBookDayView::keyPressEvent( QKeyEvent *e )
+{
+ QString txt = e->text();
+ if ( !txt.isNull() && txt[0] > ' ' && e->key() < 0x1000 ) {
+ // we this is some sort of thing we know about...
+ e->accept();
+ emit sigCapturedKey( txt );
+ } else {
+ // I don't know what this key is, do you?
+ e->ignore();
+ }
+}
+
+
+//===========================================================================
+
+DateBookDay::DateBookDay( bool ampm, bool startOnMonday,
+ DateBookDB *newDb, QWidget *parent,
+ const char *name )
+ : QVBox( parent, name ),
+ currDate( QDate::currentDate() ),
+ db( newDb ),
+ startTime( 0 )
+{
+ widgetList.setAutoDelete( true );
+ header = new DateBookDayHeader( startOnMonday, this, "day header" );
+ header->setDate( currDate.year(), currDate.month(), currDate.day() );
+ view = new DateBookDayView( ampm, this, "day view" );
+ connect( header, SIGNAL( dateChanged( int, int, int ) ),
+ this, SLOT( dateChanged( int, int, int ) ) );
+ connect( view, SIGNAL( sigColWidthChanged() ),
+ this, SLOT( slotColWidthChanged() ) );
+ connect( qApp, SIGNAL(weekChanged(bool)),
+ this, SLOT(slotWeekChanged(bool)) );
+ connect( view, SIGNAL(sigCapturedKey(const QString &)),
+ this, SIGNAL(sigNewEvent(const QString&)) );
+}
+
+void DateBookDay::selectedDates( QDateTime &start, QDateTime &end )
+{
+ start.setDate( currDate );
+ end.setDate( currDate );
+
+ int sh=99,eh=-1;
+
+ int n = dayView()->numSelections();
+
+ for (int i=0; i<n; i++) {
+ QTableSelection sel = dayView()->selection( i );
+ sh = QMIN(sh,sel.topRow());
+ eh = QMAX(sh,sel.bottomRow()+1);
+ }
+ if (sh > 23 || eh < 1) {
+ sh=8;
+ eh=9;
+ }
+
+ start.setTime( QTime( sh, 0, 0 ) );
+ end.setTime( QTime( eh, 0, 0 ) );
+}
+
+void DateBookDay::setDate( int y, int m, int d )
+{
+ header->setDate( y, m, d );
+}
+
+void DateBookDay::setDate( QDate d)
+{
+ header->setDate( d.year(), d.month(), d.day() );
+}
+
+void DateBookDay::dateChanged( int y, int m, int d )
+{
+ QDate date( y, m, d );
+ if ( currDate == date )
+ return;
+ currDate.setYMD( y, m, d );
+ relayoutPage();
+ dayView()->clearSelection();
+ QTableSelection ts;
+ ts.init( startTime, 0 );
+ ts.expandTo( startTime, 0 );
+ dayView()->addSelection( ts );
+}
+
+void DateBookDay::redraw()
+{
+ if ( isUpdatesEnabled() )
+ relayoutPage();
+}
+
+void DateBookDay::getEvents()
+{
+ widgetList.clear();
+
+ QValueList<EffectiveEvent> eventList = db->getEffectiveEvents( currDate,
+ currDate );
+ QValueListIterator<EffectiveEvent> it;
+ for ( it = eventList.begin(); it != eventList.end(); ++it ) {
+ DateBookDayWidget* w = new DateBookDayWidget( *it, this );
+ connect( w, SIGNAL( deleteMe( const Event & ) ),
+ this, SIGNAL( removeEvent( const Event & ) ) );
+ connect( w, SIGNAL( editMe( const Event & ) ),
+ this, SIGNAL( editEvent( const Event & ) ) );
+ connect( w, SIGNAL( beamMe( const Event & ) ),
+ this, SIGNAL( beamEvent( const Event & ) ) );
+ widgetList.append( w );
+ }
+}
+
+static int place( const DateBookDayWidget *item, bool *used, int maxn )
+{
+ int place = 0;
+ int start = item->event().start().hour();
+ QTime e = item->event().end();
+ int end = e.hour();
+ if ( e.minute() < 5 )
+ end--;
+ if ( end < start )
+ end = start;
+ while ( place < maxn ) {
+ bool free = TRUE;
+ int s = start;
+ while( s <= end ) {
+ if ( used[10*s+place] ) {
+ free = FALSE;
+ break;
+ }
+ s++;
+ }
+ if ( free ) break;
+ place++;
+ }
+ if ( place == maxn ) {
+ return -1;
+ }
+ while( start <= end ) {
+ used[10*start+place] = TRUE;
+ start++;
+ }
+ return place;
+}
+
+
+void DateBookDay::relayoutPage( bool fromResize )
+{
+ setUpdatesEnabled( FALSE );
+ if ( !fromResize )
+ getEvents(); // no need we already have them!
+
+ int wCount = widgetList.count();
+ int wid = view->columnWidth(0)-1;
+ int n = 1;
+
+ if ( wCount < 20 ) {
+ for ( int i = 0; i < wCount; ) {
+ DateBookDayWidget *w = widgetList.at(i);
+ int x = 0;
+ int xp = 0;
+ QRect geom = w->geometry();
+ geom.setX( x );
+ geom.setWidth( wid );
+ while ( xp < n && intersects( w, geom ) ) {
+ x += wid;
+ xp++;
+ geom.moveBy( wid, 0 );
+ }
+ if ( xp >= n ) {
+ n++;
+ wid = ( view->columnWidth(0)-1 ) / n;
+ i = 0;
+ } else {
+ w->setGeometry( geom );
+ i++;
+ }
+ }
+ view->setContentsPos( 0, startTime * view->rowHeight(0) );
+ } else {
+
+
+ int hours[24];
+ memset( hours, 0, 24*sizeof( int ) );
+ bool overFlow = FALSE;
+ for ( int i = 0; i < wCount; i++ ) {
+ DateBookDayWidget *w = widgetList.at(i);
+ int start = w->event().start().hour();
+ QTime e = w->event().end();
+ int end = e.hour();
+ if ( e.minute() < 5 )
+ end--;
+ if ( end < start )
+ end = start;
+ while( start <= end ) {
+ hours[start]++;
+ if ( hours[start] >= 10 )
+ overFlow = TRUE;
+ ++start;
+ }
+ if ( overFlow )
+ break;
+ }
+ for ( int i = 0; i < 24; i++ ) {
+ n = QMAX( n, hours[i] );
+ }
+ wid = ( view->columnWidth(0)-1 ) / n;
+
+ bool used[24*10];
+ memset( used, FALSE, 24*10*sizeof( bool ) );
+
+ for ( int i = 0; i < wCount; i++ ) {
+ DateBookDayWidget *w = widgetList.at(i);
+ int xp = place( w, used, n );
+ if ( xp != -1 ) {
+ QRect geom = w->geometry();
+ geom.setX( xp*wid );
+ geom.setWidth( wid );
+ w->setGeometry( geom );
+ }
+ }
+ view->setContentsPos( 0, startTime * view->rowHeight(0) );
+ }
+ setUpdatesEnabled( TRUE );
+ return;
+}
+
+DateBookDayWidget *DateBookDay::intersects( const DateBookDayWidget *item, const QRect &geom )
+{
+ int i = 0;
+ DateBookDayWidget *w = widgetList.at(i);
+ int wCount = widgetList.count();
+ while ( i < wCount && w != item ) {
+ if ( w->geometry().intersects( geom ) ) {
+ return w;
+ }
+ w = widgetList.at(++i);
+ }
+
+ return 0;
+}
+
+
+QDate DateBookDay::date() const
+{
+ return currDate;
+}
+
+void DateBookDay::setStartViewTime( int startHere )
+{
+ startTime = startHere;
+ dayView()->clearSelection();
+ QTableSelection ts;
+ ts.init( startTime, 0 );
+ ts.expandTo( startTime, 0 );
+ dayView()->addSelection( ts );
+}
+
+int DateBookDay::startViewTime() const
+{
+ return startTime;
+}
+
+void DateBookDay::slotWeekChanged( bool bStartOnMonday )
+{
+ header->setStartOfWeek( bStartOnMonday );
+ // redraw();
+}
+
+void DateBookDay::keyPressEvent(QKeyEvent *e)
+{
+ switch(e->key()) {
+ case Key_Up:
+ view->moveUp();
+ break;
+ case Key_Down:
+ view->moveDown();
+ break;
+ case Key_Left:
+ setDate(QDate(currDate).addDays(-1));
+ break;
+ case Key_Right:
+ setDate(QDate(currDate).addDays(1));
+ break;
+ default:
+ e->ignore();
+ }
+}
+
+//===========================================================================
+
+DateBookDayWidget::DateBookDayWidget( const EffectiveEvent &e,
+ DateBookDay *db )
+ : QWidget( db->dayView()->viewport() ), ev( e ), dateBook( db )
+{
+ bool whichClock = db->dayView()->whichClock();
+
+ // why would someone use "<"? Oh well, fix it up...
+ // I wonder what other things may be messed up...
+ QString strDesc = ev.description();
+ int where = strDesc.find( "<" );
+ while ( where != -1 ) {
+ strDesc.remove( where, 1 );
+ strDesc.insert( where, "&#60;" );
+ where = strDesc.find( "<", where );
+ }
+
+ QString strCat;
+ // ### Fix later...
+// QString strCat = ev.category();
+// where = strCat.find( "<" );
+// while ( where != -1 ) {
+// strCat.remove( where, 1 );
+// strCat.insert( where, "&#60;" );
+// where = strCat.find( "<", where );
+// }
+
+ QString strNote = ev.notes();
+ where = strNote.find( "<" );
+ while ( where != -1 ) {
+ strNote.remove( where, 1 );
+ strNote.insert( where, "&#60;" );
+ where = strNote.find( "<", where );
+ }
+
+ text = "<b>" + strDesc + "</b><br>" + "<i>"
+ + strCat + "</i>"
+ + "<br><b>" + tr("Start") + "</b>: ";
+
+
+ if ( e.startDate() != ev.date() ) {
+ // multi-day event. Show start date
+ text += TimeString::longDateString( e.startDate() );
+ } else {
+ // Show start time.
+ text += TimeString::timeString( ev.start(), whichClock, FALSE );
+ }
+
+ text += "<br><b>" + tr("End") + "</b>: ";
+ if ( e.endDate() != ev.date() ) {
+ // multi-day event. Show end date
+ text += TimeString::longDateString( e.endDate() );
+ } else {
+ // Show end time.
+ text += TimeString::timeString( ev.end(), whichClock, FALSE );
+ }
+ text += "<br><br>" + strNote;
+ setBackgroundMode( PaletteBase );
+
+ QTime s = ev.start();
+ QTime e = ev.end();
+ int y = s.hour()*60+s.minute();
+ int h = e.hour()*60+e.minute()-y;
+ int rh = dateBook->dayView()->rowHeight(0);
+ y = y*rh/60;
+ h = h*rh/60;
+ if ( h < 3 )
+ h = 3;
+ geom.setY( y );
+ geom.setHeight( h );
+}
+
+DateBookDayWidget::~DateBookDayWidget()
+{
+}
+
+void DateBookDayWidget::paintEvent( QPaintEvent *e )
+{
+ QPainter p( this );
+ p.setPen( QColor(100, 100, 100) );
+ p.setBrush( QColor( 255, 240, 230 ) ); // based on priority?
+ p.drawRect(rect());
+
+ int y = 0;
+ int d = 0;
+
+ if ( ev.event().hasAlarm() ) {
+ p.drawPixmap( width() - 16, 0, Resource::loadPixmap( "bell" ) );
+ y = 20;
+ d = 20;
+ }
+
+ if ( ev.event().hasRepeat() ) {
+ p.drawPixmap( width() - 16, y, Resource::loadPixmap( "repeat" ) );
+ d = 20;
+ }
+
+ QSimpleRichText rt( text, font() );
+ rt.setWidth( geom.width() - d - 6 );
+ rt.draw( &p, 3, 0, e->region(), colorGroup() );
+}
+
+void DateBookDayWidget::mousePressEvent( QMouseEvent *e )
+{
+ QPopupMenu m;
+ m.insertItem( tr( "Edit" ), 1 );
+ m.insertItem( tr( "Delete" ), 2 );
+ m.insertItem( tr( "Beam" ), 3 );
+ int r = m.exec( e->globalPos() );
+ if ( r == 1 ) {
+ emit editMe( ev.event() );
+ } else if ( r == 2 ) {
+ emit deleteMe( ev.event() );
+ } else if ( r == 3 ) {
+ emit beamMe( ev.event() );
+ }
+}
+
+void DateBookDayWidget::setGeometry( const QRect &r )
+{
+ geom = r;
+ setFixedSize( r.width()+1, r.height()+1 );
+ dateBook->dayView()->moveChild( this, r.x(), r.y()-1 );
+ show();
+}
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 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef DATEBOOKDAY_H
+#define DATEBOOKDAY_H
+
+#include <qpe/event.h>
+
+#include <qdatetime.h>
+#include <qtable.h>
+#include <qvbox.h>
+#include <qlist.h>
+
+class DateBookDayHeader;
+class DateBookDB;
+class QDateTime;
+class QMouseEvent;
+class QPaintEvent;
+class QResizeEvent;
+
+class DateBookDayView : public QTable
+{
+ Q_OBJECT
+public:
+ DateBookDayView( bool hourClock, QWidget *parent, const char *name );
+ bool whichClock() const;
+
+public slots:
+ void moveUp();
+ void moveDown();
+
+signals:
+ void sigColWidthChanged();
+ void sigCapturedKey( const QString &txt );
+protected slots:
+ void slotChangeClock( bool );
+protected:
+ virtual void paintCell( QPainter *p, int row, int col, const QRect &cr, bool selected );
+ virtual void paintFocus( QPainter *p, const QRect &cr );
+ virtual void resizeEvent( QResizeEvent *e );
+ void keyPressEvent( QKeyEvent *e );
+ void initHeader();
+private:
+ bool ampm;
+};
+
+class DateBookDay;
+class DateBookDayWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ DateBookDayWidget( const EffectiveEvent &e, DateBookDay *db );
+ ~DateBookDayWidget();
+
+ const QRect &geometry() { return geom; }
+ void setGeometry( const QRect &r );
+
+ const EffectiveEvent &event() const { return ev; }
+
+signals:
+ void deleteMe( const Event &e );
+ void editMe( const Event &e );
+ void beamMe( const Event &e );
+
+protected:
+ void paintEvent( QPaintEvent *e );
+ void mousePressEvent( QMouseEvent *e );
+
+private:
+ const EffectiveEvent ev;
+ DateBookDay *dateBook;
+ QString text;
+ QRect geom;
+};
+
+class DateBookDay : public QVBox
+{
+ Q_OBJECT
+
+public:
+ DateBookDay( bool ampm, bool startOnMonday, DateBookDB *newDb,
+ QWidget *parent, const char *name );
+ void selectedDates( QDateTime &start, QDateTime &end );
+ QDate date() const;
+ DateBookDayView *dayView() const { return view; }
+ void setStartViewTime( int startHere );
+ int startViewTime() const;
+
+public slots:
+ void setDate( int y, int m, int d );
+ void setDate( QDate );
+ void redraw();
+ void slotWeekChanged( bool bStartOnMonday );
+
+signals:
+ void removeEvent( const Event& );
+ void editEvent( const Event& );
+ void beamEvent( const Event& );
+ void newEvent();
+ void sigNewEvent( const QString & );
+
+protected slots:
+ void keyPressEvent(QKeyEvent *);
+
+private slots:
+ void dateChanged( int y, int m, int d );
+ void slotColWidthChanged() { relayoutPage(); };
+
+private:
+ void getEvents();
+ void relayoutPage( bool fromResize = false );
+ DateBookDayWidget *intersects( const DateBookDayWidget *item, const QRect &geom );
+ QDate currDate;
+ DateBookDayView *view;
+ DateBookDayHeader *header;
+ DateBookDB *db;
+ QList<DateBookDayWidget> widgetList;
+ int startTime;
+};
+
+#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 @@
+<!DOCTYPE UI><UI>
+<class>DateBookDayHeaderBase</class>
+<comment>/**********************************************************************
+** Copyright (C) 2001 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+** $Id$
+**
+**********************************************************************/</comment>
+<widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>DateBookDayHeaderBase</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>249</width>
+ <height>26</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>Form1</string>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>0</number>
+ </property>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>back</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string></string>
+ </property>
+ <property stdset="1">
+ <name>pixmap</name>
+ <pixmap>image0</pixmap>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>false</bool>
+ </property>
+ <property stdset="1">
+ <name>autoRepeat</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>autoRaise</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>false</bool>
+ </property>
+ <property>
+ <name>toolTip</name>
+ <string></string>
+ </property>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>date</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>1</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>font</name>
+ <font>
+ <bold>1</bold>
+ </font>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string></string>
+ </property>
+ <property stdset="1">
+ <name>pixmap</name>
+ <pixmap></pixmap>
+ </property>
+ <property stdset="1">
+ <name>autoRepeat</name>
+ <bool>false</bool>
+ </property>
+ <property stdset="1">
+ <name>autoRaise</name>
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget>
+ <class>QButtonGroup</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>grpDays</cstring>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>NoFrame</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>Plain</enum>
+ </property>
+ <property stdset="1">
+ <name>title</name>
+ <string></string>
+ </property>
+ <property stdset="1">
+ <name>exclusive</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>1</number>
+ </property>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdDay1</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>M</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>autoRaise</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>toolTip</name>
+ <string></string>
+ </property>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdDay2</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>T</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>autoRaise</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>toolTip</name>
+ <string></string>
+ </property>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdDay3</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>W</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>autoRaise</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>toolTip</name>
+ <string></string>
+ </property>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdDay4</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>T</string>
+ </property>
+ <property stdset="1">
+ <name>pixmap</name>
+ <pixmap></pixmap>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>autoRepeat</name>
+ <bool>false</bool>
+ </property>
+ <property stdset="1">
+ <name>autoRaise</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>toolTip</name>
+ <string></string>
+ </property>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdDay5</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>F</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>autoRaise</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>toolTip</name>
+ <string></string>
+ </property>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdDay6</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>S</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>autoRaise</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>toolTip</name>
+ <string></string>
+ </property>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdDay7</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>S</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>autoRaise</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>toolTip</name>
+ <string></string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>forward</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string></string>
+ </property>
+ <property stdset="1">
+ <name>pixmap</name>
+ <pixmap>image1</pixmap>
+ </property>
+ <property stdset="1">
+ <name>autoRepeat</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>autoRaise</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ </hbox>
+</widget>
+<images>
+ <image>
+ <name>image0</name>
+ <data format="XPM.GZ" length="582">789c6dcfcd4e843010c0f13b4fd1d01b31bb6cb325211b1f41e3d1c4789876a60bcbd7aeae07637c773b6d5985d870e0f7ef50605b88e7a707516cb3f72b5c5b2b6c036fa2c08f61f87c79bdffcaf2dd5ef0558b5d7e97e51b61c5e33412df4b7f2fcbb09896a94ab557817063cd744cad74a915734aac35308740d018d9332d5ab0c8ec1229f2c2448d156a661b489ee1ab4e4cf2a08a790e24020abb0dd355442eec8e914e45526215790c749e8e89891069125de466b1fe14295705ccaa5863e2d05cc01894925b2a7e8217dd8a631eb169fd509af10fd1a9ebfbdf32008d9d0c07cd274f70ee162773ba2cdfee935c977ffe6b2edf87ec07796f81cd</data>
+ </image>
+ <image>
+ <name>image1</name>
+ <data format="XPM.GZ" length="627">789c7dcfc94ec3301006e07b9ec28a6f114a13cbb1a8108f00e28884387819676993340b07847877329ea8697a60ec83bfdf232f8784bdbfbdb0e4104db39e6bcb6ca54796b8afb6fdfef87cfe89e25cb2650ac1f2f8218a5366d96bdf01aef9b2e65928a4458a0c07b25c29890352e63293e19c53a0968f52230159e8c22981744495133552097554a1f982b4ce6aeb9013d215165c81ec894e109b4070ca85378f2b35f18c04050214b20d04d010762ba457003eecd6442f88f34a45f4817ea147762b35d1acf4c47457d784737d9f18ebee1363614bf852c6f812b6c460f90abb6e93ba694ed7c49fdbaeee2f76b83da71ba772e0db5d9ccf4b07dfdd5e858edd9b2948fff9d796fc3e457f660e8d47</data>
+ </image>
+</images>
+<connections>
+ <connection>
+ <sender>forward</sender>
+ <signal>clicked()</signal>
+ <receiver>DateBookDayHeaderBase</receiver>
+ <slot>goForward()</slot>
+ </connection>
+ <connection>
+ <sender>back</sender>
+ <signal>clicked()</signal>
+ <receiver>DateBookDayHeaderBase</receiver>
+ <slot>goBack()</slot>
+ </connection>
+ <connection>
+ <sender>grpDays</sender>
+ <signal>clicked(int)</signal>
+ <receiver>DateBookDayHeaderBase</receiver>
+ <slot>setDay( int )</slot>
+ </connection>
+ <slot access="public">goBack()</slot>
+ <slot access="public">goForward()</slot>
+ <slot access="public">setDate( int, int, int )</slot>
+ <slot access="public">setDay( int )</slot>
+</connections>
+</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 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "datebookdayheaderimpl.h"
+
+#include <qpe/datebookmonth.h>
+#include <qpe/timestring.h>
+
+#include <qbuttongroup.h>
+#include <qpopupmenu.h>
+#include <qstringlist.h>
+#include <qtimer.h>
+#include <qtoolbutton.h>
+
+/*
+ * Constructs a DateBookDayHeader which is a child of 'parent', with the
+ * name 'name' and widget flags set to 'f'
+ *
+ * The dialog will by default be modeless, unless you set 'modal' to
+ * TRUE to construct a modal dialog.
+ */
+DateBookDayHeader::DateBookDayHeader( bool useMonday,
+ QWidget* parent, const char* name )
+ : DateBookDayHeaderBase( parent, name ),
+ bUseMonday( useMonday )
+{
+ connect(date,SIGNAL(pressed()),this,SLOT(pickDate()));
+
+ setupNames();
+
+ setBackgroundMode( PaletteButton );
+ grpDays->setBackgroundMode( PaletteButton );
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+DateBookDayHeader::~DateBookDayHeader()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+
+void DateBookDayHeader::setStartOfWeek( bool onMonday )
+{
+ bUseMonday = onMonday;
+ setupNames();
+ setDate( currDate.year(), currDate.month(), currDate.day() );
+}
+
+void DateBookDayHeader::setupNames()
+{
+ if ( bUseMonday ) {
+ cmdDay1->setText( DateBookDayHeaderBase::tr("Monday").left(1) );
+ cmdDay2->setText( DateBookDayHeaderBase::tr("Tuesday").left(1) );
+ cmdDay3->setText( DateBookDayHeaderBase::tr("Wednesday").left(1) );
+ cmdDay4->setText( DateBookDayHeaderBase::tr("Thursday").left(1) );
+ cmdDay5->setText( DateBookDayHeaderBase::tr("Friday").left(1) );
+ cmdDay6->setText( DateBookDayHeaderBase::tr("Saturday").left(1) );
+ cmdDay7->setText( DateBookDayHeaderBase::tr("Sunday").left(1) );
+ } else {
+ cmdDay1->setText( DateBookDayHeaderBase::tr("Sunday").left(1) );
+ cmdDay2->setText( DateBookDayHeaderBase::tr("Monday").left(1) );
+ cmdDay3->setText( DateBookDayHeaderBase::tr("Tuesday").left(1) );
+ cmdDay4->setText( DateBookDayHeaderBase::tr("Wednesday").left(1) );
+ cmdDay5->setText( DateBookDayHeaderBase::tr("Thursday").left(1) );
+ cmdDay6->setText( DateBookDayHeaderBase::tr("Friday").left(1) );
+ cmdDay7->setText( DateBookDayHeaderBase::tr("Saturday").left(1) );
+ }
+}
+
+
+void DateBookDayHeader::pickDate()
+{
+ static QPopupMenu *m1 = 0;
+ static DateBookMonth *picker = 0;
+ if ( !m1 ) {
+ m1 = new QPopupMenu( this );
+ picker = new DateBookMonth( m1, 0, TRUE );
+ m1->insertItem( picker );
+ connect( picker, SIGNAL( dateClicked( int, int, int ) ),
+ this, SLOT( setDate( int, int, int ) ) );
+ connect( m1, SIGNAL( aboutToHide() ),
+ this, SLOT( gotHide() ) );
+ }
+ picker->setDate( currDate.year(), currDate.month(), currDate.day() );
+ m1->popup(mapToGlobal(date->pos()+QPoint(0,date->height())));
+ picker->setFocus();
+}
+
+void DateBookDayHeader::gotHide()
+{
+ // we have to redo the button...
+ date->setDown( false );
+}
+
+/*
+ * public slot
+ */
+void DateBookDayHeader::goBack()
+{
+ currDate = currDate.addDays( -1 );
+ setDate( currDate.year(), currDate.month(), currDate.day() );
+}
+/*
+ * public slot
+ */
+void DateBookDayHeader::goForward()
+{
+ currDate = currDate.addDays( 1 );
+ setDate( currDate.year(), currDate.month(), currDate.day() );
+}
+
+
+/*
+ * public slot
+ */
+void DateBookDayHeader::setDate( int y, int m, int d )
+{
+ currDate.setYMD( y, m, d );
+ date->setText( TimeString::shortDate( currDate ) );
+
+ int iDayOfWeek = currDate.dayOfWeek();
+ // cleverly adjust the day depending on how we start the week
+ if ( bUseMonday )
+ iDayOfWeek--;
+ else {
+ if ( iDayOfWeek == 7 ) // Sunday
+ iDayOfWeek = 0;
+ }
+ grpDays->setButton( iDayOfWeek );
+ emit dateChanged( y, m, d );
+}
+
+/*
+ * public slot
+ */
+void DateBookDayHeader::setDay( int day )
+{
+ int realDay;
+ int dayOfWeek = currDate.dayOfWeek();
+
+ // a little adjustment is needed...
+ if ( bUseMonday )
+ realDay = day + 1 ;
+ else if ( !bUseMonday && day == 0 ) // sunday
+ realDay = 7;
+ else
+ realDay = day;
+ // special cases first...
+ if ( realDay == 7 && !bUseMonday ) {
+ while ( currDate.dayOfWeek() != realDay )
+ currDate = currDate.addDays( -1 );
+ } else if ( !bUseMonday && dayOfWeek == 7 && dayOfWeek > realDay ) {
+ while ( currDate.dayOfWeek() != realDay )
+ currDate = currDate.addDays( 1 );
+ } else if ( dayOfWeek < realDay ) {
+ while ( currDate.dayOfWeek() < realDay )
+ currDate = currDate.addDays( 1 );
+ } else if ( dayOfWeek > realDay ) {
+ while ( currDate.dayOfWeek() > realDay )
+ currDate = currDate.addDays( -1 );
+ }
+ // update the date...
+ setDate( currDate.year(), currDate.month(), currDate.day() );
+}
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 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef DATEBOOKDAYHEADER_H
+#define DATEBOOKDAYHEADER_H
+#include "datebookdayheader.h"
+
+#include <qdatetime.h>
+
+class DateBookDayHeader : public DateBookDayHeaderBase
+{
+ Q_OBJECT
+
+public:
+ DateBookDayHeader( bool bUseMonday, QWidget* parent = 0,
+ const char* name = 0 );
+ ~DateBookDayHeader();
+ void setStartOfWeek( bool onMonday );
+
+public slots:
+ void goBack();
+ void goForward();
+ void setDate( int, int, int );
+ void setDay( int );
+ void gotHide();
+
+signals:
+ void dateChanged( int y, int m, int d );
+
+private slots:
+ void pickDate();
+
+
+private:
+ QDate currDate;
+ bool bUseMonday;
+ void setupNames();
+
+};
+
+#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 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "datebooksettings.h"
+
+#include <qpe/qpeapplication.h>
+
+#include <qspinbox.h>
+#include <qcheckbox.h>
+#include <qcombobox.h>
+
+DateBookSettings::DateBookSettings( bool whichClock, QWidget *parent,
+ const char *name, bool modal, WFlags fl )
+ : DateBookSettingsBase( parent, name, modal, fl ),
+ ampm( whichClock )
+{
+ init();
+ QObject::connect( qApp, SIGNAL( clockChanged( bool ) ),
+ this, SLOT( slotChangeClock( bool ) ) );
+}
+
+DateBookSettings::~DateBookSettings()
+{
+}
+
+void DateBookSettings::setStartTime( int newStartViewTime )
+{
+ if ( ampm ) {
+ if ( newStartViewTime >= 12 ) {
+ newStartViewTime %= 12;
+ if ( newStartViewTime == 0 )
+ newStartViewTime = 12;
+ spinStart->setSuffix( tr(":00 PM") );
+ }
+ else if ( newStartViewTime == 0 ) {
+ newStartViewTime = 12;
+ spinStart->setSuffix( tr(":00 AM") );
+ }
+ oldtime = newStartViewTime;
+ }
+ spinStart->setValue( newStartViewTime );
+}
+
+int DateBookSettings::startTime() const
+{
+ int returnMe = spinStart->value();
+ if ( ampm ) {
+ if ( returnMe != 12 && spinStart->suffix().contains(tr("PM"), FALSE) )
+ returnMe += 12;
+ else if (returnMe == 12 && spinStart->suffix().contains(tr("AM"), TRUE))
+ returnMe = 0;
+ }
+ return returnMe;
+}
+
+
+void DateBookSettings::setAlarmPreset( bool bAlarm, int presetTime )
+{
+ chkAlarmPreset->setChecked( bAlarm );
+ if ( presetTime >=5 )
+ spinPreset->setValue( presetTime );
+}
+
+bool DateBookSettings::alarmPreset() const
+{
+ return chkAlarmPreset->isChecked();
+}
+
+int DateBookSettings::presetTime() const
+{
+ return spinPreset->value();
+}
+
+
+void DateBookSettings::slot12Hour( int i )
+{
+ if ( ampm ) {
+ if ( spinStart->suffix().contains( tr("AM"), FALSE ) ) {
+ if ( oldtime == 12 && i == 11 || oldtime == 11 && i == 12 )
+ spinStart->setSuffix( tr(":00 PM") );
+ } else {
+ if ( oldtime == 12 && i == 11 || oldtime == 11 && i == 12 )
+ spinStart->setSuffix( tr(":00 AM") );
+ }
+ oldtime = i;
+ }
+}
+
+void DateBookSettings::init()
+{
+ if ( ampm ) {
+ spinStart->setMinValue( 1 );
+ spinStart->setMaxValue( 12 );
+ spinStart->setValue( 12 );
+ spinStart->setSuffix( tr(":00 AM") );
+ oldtime = 12;
+ } else {
+ spinStart->setMinValue( 0 );
+ spinStart->setMaxValue( 23 );
+ spinStart->setSuffix( tr(":00") );
+ }
+}
+
+void DateBookSettings::slotChangeClock( bool whichClock )
+{
+ int saveMe;
+ saveMe = spinStart->value();
+ if ( ampm && spinStart->suffix().contains( tr("AM"), FALSE ) ) {
+ if ( saveMe == 12 )
+ saveMe = 0;
+ } else if ( ampm && spinStart->suffix().contains( tr("PM"), FALSE ) ) {
+ if ( saveMe != 12 )
+ saveMe += 12;
+ }
+ ampm = whichClock;
+ init();
+ setStartTime( saveMe );
+}
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 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef DATEBOOKSETTINGS_H
+#define DATEBOOKSETTINGS_H
+#include "datebooksettingsbase.h"
+
+class DateBookSettings : public DateBookSettingsBase
+{
+public:
+ DateBookSettings( bool whichClock, QWidget *parent = 0,
+ const char *name = 0, bool modal = TRUE, WFlags = 0 );
+ ~DateBookSettings();
+ void setStartTime( int newStartViewTime );
+ int startTime() const;
+ void setAlarmPreset( bool bAlarm, int presetTime );
+ bool alarmPreset() const;
+ int presetTime() const;
+ void setAlarmType( int alarmType );
+ int alarmType() const;
+
+private slots:
+ void slot12Hour( int );
+ void slotChangeClock( bool );
+
+private:
+ void init();
+ bool ampm;
+ int oldtime;
+};
+#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 @@
+<!DOCTYPE UI><UI>
+<class>DateBookSettingsBase</class>
+<comment>**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+** $Id$
+**
+**********************************************************************</comment>
+<widget>
+ <class>QDialog</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>DateBookSettingsBase</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>232</width>
+ <height>290</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>Preferences</string>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>5</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>1</number>
+ </property>
+ <widget>
+ <class>QGroupBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>fraStart</cstring>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>Box</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>Sunken</enum>
+ </property>
+ <property stdset="1">
+ <name>title</name>
+ <string>Start viewing events</string>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>11</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout1</cstring>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>lblStartTime</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Start Time:</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QSpinBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>spinStart</cstring>
+ </property>
+ <property stdset="1">
+ <name>suffix</name>
+ <string>:00</string>
+ </property>
+ <property stdset="1">
+ <name>wrapping</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>maxValue</name>
+ <number>23</number>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ <widget>
+ <class>QGroupBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>fraAlarm</cstring>
+ </property>
+ <property stdset="1">
+ <name>title</name>
+ <string>Alarm Settings</string>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>11</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout6</cstring>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QCheckBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>chkAlarmPreset</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Alarm Preset</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QSpinBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>spinPreset</cstring>
+ </property>
+ <property stdset="1">
+ <name>enabled</name>
+ <bool>false</bool>
+ </property>
+ <property stdset="1">
+ <name>suffix</name>
+ <string> minutes</string>
+ </property>
+ <property stdset="1">
+ <name>maxValue</name>
+ <number>180</number>
+ </property>
+ <property stdset="1">
+ <name>minValue</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>lineStep</name>
+ <number>5</number>
+ </property>
+ <property stdset="1">
+ <name>value</name>
+ <number>5</number>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ </vbox>
+</widget>
+<connections>
+ <connection>
+ <sender>chkAlarmPreset</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>spinPreset</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>spinStart</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>DateBookSettingsBase</receiver>
+ <slot>slot12Hour( int )</slot>
+ </connection>
+ <slot access="public">slotChangeClock( bool )</slot>
+ <slot access="public">slot12Hour( int )</slot>
+</connections>
+</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 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "datebookweek.h"
+#include "datebookweekheaderimpl.h"
+
+#include <qpe/calendar.h>
+#include <qpe/datebookdb.h>
+#include <qpe/event.h>
+#include <qpe/qpeapplication.h>
+#include <qpe/timestring.h>
+
+#include <qdatetime.h>
+#include <qheader.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qpainter.h>
+#include <qpopupmenu.h>
+#include <qtimer.h>
+#include <qspinbox.h>
+#include <qstyle.h>
+
+//-----------------------------------------------------------------
+
+
+DateBookWeekItem::DateBookWeekItem( const EffectiveEvent e )
+ : ev( e )
+{
+ // with the current implementation change the color for all day events
+ if ( ev.event().type() == Event::AllDay && !ev.event().hasAlarm() ) {
+ c = Qt::green;
+ } else {
+ c = ev.event().hasAlarm() ? Qt::red : Qt::blue;
+ }
+}
+
+void DateBookWeekItem::setGeometry( int x, int y, int w, int h )
+{
+ r.setRect( x, y, w, h );
+}
+
+
+//------------------=---------------------------------------------
+
+DateBookWeekView::DateBookWeekView( bool ap, bool startOnMonday,
+ QWidget *parent, const char *name )
+ : QScrollView( parent, name ), ampm( ap ), bOnMonday( startOnMonday ),
+ showingEvent( false )
+{
+ items.setAutoDelete( true );
+
+ viewport()->setBackgroundMode( PaletteBase );
+
+ header = new QHeader( this );
+ header->addLabel( "" );
+
+ header->setMovingEnabled( false );
+ header->setResizeEnabled( false );
+ header->setClickEnabled( false, 0 );
+ initNames();
+
+
+ connect( header, SIGNAL(clicked(int)), this, SIGNAL(showDay(int)) );
+
+ QObject::connect(qApp, SIGNAL(clockChanged(bool)),
+ this, SLOT(slotChangeClock(bool)));
+
+ QFontMetrics fm( font() );
+ rowHeight = fm.height()+2;
+
+ resizeContents( width(), 24*rowHeight );
+}
+
+void DateBookWeekView::initNames()
+{
+ static bool bFirst = true;
+ if ( bFirst ) {
+ if ( bOnMonday ) {
+ header->addLabel( tr("M", "Monday" ) );
+ header->addLabel( tr("T", "Tuesday") );
+ header->addLabel( tr("W", "Wednesday" ) );
+ header->addLabel( tr("T", "Thursday" ) );
+ header->addLabel( tr("F", "Friday" ) );
+ header->addLabel( tr("S", "Saturday" ) );
+ header->addLabel( tr("S", "Sunday" ) );
+ } else {
+ header->addLabel( tr("S", "Sunday" ) );
+ header->addLabel( tr("M", "Monday") );
+ header->addLabel( tr("T", "Tuesday") );
+ header->addLabel( tr("W", "Wednesday" ) );
+ header->addLabel( tr("T", "Thursday" ) );
+ header->addLabel( tr("F", "Friday" ) );
+ header->addLabel( tr("S", "Saturday" ) );
+ }
+ bFirst = false;
+ } else {
+ // we are change things...
+ if ( bOnMonday ) {
+ header->setLabel( 1, tr("M", "Monday") );
+ header->setLabel( 2, tr("T", "Tuesday") );
+ header->setLabel( 3, tr("W", "Wednesday" ) );
+ header->setLabel( 4, tr("T", "Thursday" ) );
+ header->setLabel( 5, tr("F", "Friday" ) );
+ header->setLabel( 6, tr("S", "Saturday" ) );
+ header->setLabel( 7, tr("S", "Sunday" ) );
+ } else {
+ header->setLabel( 1, tr("S", "Sunday" ) );
+ header->setLabel( 2, tr("M", "Monday") );
+ header->setLabel( 3, tr("T", "Tuesday") );
+ header->setLabel( 4, tr("W", "Wednesday" ) );
+ header->setLabel( 5, tr("T", "Thursday" ) );
+ header->setLabel( 6, tr("F", "Friday" ) );
+ header->setLabel( 7, tr("S", "Saturday" ) );
+ }
+ }
+}
+
+
+
+void DateBookWeekView::showEvents( QValueList<EffectiveEvent> &ev )
+{
+ items.clear();
+ QValueListIterator<EffectiveEvent> it;
+ for ( it = ev.begin(); it != ev.end(); ++it ) {
+ DateBookWeekItem *i = new DateBookWeekItem( *it );
+ positionItem( i );
+ items.append( i );
+ }
+ viewport()->update();
+}
+
+void DateBookWeekView::moveToHour( int h )
+{
+ int offset = h*rowHeight;
+ setContentsPos( 0, offset );
+}
+
+void DateBookWeekView::keyPressEvent( QKeyEvent *e )
+{
+ e->ignore();
+}
+
+void DateBookWeekView::slotChangeClock( bool c )
+{
+ ampm = c;
+ viewport()->update();
+}
+
+static inline int db_round30min( int m )
+{
+ if ( m < 15 )
+ m = 0;
+ else if ( m < 45 )
+ m = 1;
+ else
+ m = 2;
+
+ return m;
+}
+
+void DateBookWeekView::alterDay( int day )
+{
+ if ( !bOnMonday ) {
+ day--;
+ }
+ emit showDay( day );
+}
+
+void DateBookWeekView::positionItem( DateBookWeekItem *i )
+{
+ const int Width = 8;
+ const EffectiveEvent ev = i->event();
+
+ // 30 minute intervals
+ int y = ev.start().hour() * 2;
+ y += db_round30min( ev.start().minute() );
+ if ( y > 47 )
+ y = 47;
+ y = y * rowHeight / 2;
+
+ int h;
+ if ( ev.event().type() == Event::AllDay ) {
+ h = 48;
+ y = 0;
+ } else {
+ h = ( ev.end().hour() - ev.start().hour() ) * 2;
+ h += db_round30min( ev.end().minute() - ev.start().minute() );
+ if ( h < 1 ) h = 1;
+ }
+ h = h * rowHeight / 2;
+
+ int dow = ev.date().dayOfWeek();
+ if ( !bOnMonday ) {
+ if ( dow == 7 )
+ dow = 1;
+ else
+ dow++;
+ }
+ int x = header->sectionPos( dow ) - 1;
+ int xlim = header->sectionPos( dow ) + header->sectionSize( dow );
+ DateBookWeekItem *isect = 0;
+ do {
+ i->setGeometry( x, y, Width, h );
+ isect = intersects( i );
+ x += Width - 1;
+ } while ( isect && x < xlim );
+}
+
+DateBookWeekItem *DateBookWeekView::intersects( const DateBookWeekItem *item )
+{
+ QRect geom = item->geometry();
+
+ // We allow the edges to overlap
+ geom.moveBy( 1, 1 );
+ geom.setSize( geom.size()-QSize(2,2) );
+
+ QListIterator<DateBookWeekItem> it(items);
+ for ( ; it.current(); ++it ) {
+ DateBookWeekItem *i = it.current();
+ if ( i != item ) {
+ if ( i->geometry().intersects( geom ) ) {
+ return i;
+ }
+ }
+ }
+
+ return 0;
+}
+
+void DateBookWeekView::contentsMousePressEvent( QMouseEvent *e )
+{
+ QListIterator<DateBookWeekItem> it(items);
+ for ( ; it.current(); ++it ) {
+ DateBookWeekItem *i = it.current();
+ if ( i->geometry().contains( e->pos() ) ) {
+ showingEvent = true;
+ emit signalShowEvent( i->event() );
+ break;
+ }
+ }
+}
+
+void DateBookWeekView::contentsMouseReleaseEvent( QMouseEvent *e )
+{
+ if ( showingEvent ) {
+ showingEvent = false;
+ emit signalHideEvent();
+ } else {
+ int d = header->sectionAt( e->pos().x() );
+ if ( d > 0 ) {
+// if ( !bOnMonday )
+// d--;
+ emit showDay( d );
+ }
+ }
+}
+
+void DateBookWeekView::drawContents( QPainter *p, int cx, int cy, int cw, int ch )
+{
+ QRect ur( cx, cy, cw, ch );
+ p->setPen( lightGray );
+ for ( int i = 1; i <= 7; i++ )
+ p->drawLine( header->sectionPos(i)-2, cy, header->sectionPos(i)-2, cy+ch );
+
+ p->setPen( black );
+ for ( int t = 0; t < 24; t++ ) {
+ int y = t*rowHeight;
+ if ( QRect( 1, y, 20, rowHeight ).intersects( ur ) ) {
+ QString s;
+ if ( ampm ) {
+ if ( t == 0 )
+ s = QString::number( 12 );
+ else if ( t == 12 )
+ s = QString::number(12) + tr( "p" );
+ else if ( t > 12 ) {
+ if ( t - 12 < 10 )
+ s = " ";
+ else
+ s = "";
+ s += QString::number( t - 12 ) + tr("p");
+ } else {
+ if ( 12 - t < 3 )
+ s = "";
+ else
+ s = " ";
+ s += QString::number( t );
+ }
+ } else {
+ s = QString::number( t );
+ if ( s.length() == 1 )
+ s.prepend( "0" );
+ }
+ p->drawText( 1, y+p->fontMetrics().ascent()+1, s );
+ }
+ }
+
+ QListIterator<DateBookWeekItem> it(items);
+ for ( ; it.current(); ++it ) {
+ DateBookWeekItem *i = it.current();
+ if ( i->geometry().intersects( ur ) ) {
+ p->setBrush( i->color() );
+ p->drawRect( i->geometry() );
+ }
+ }
+}
+
+void DateBookWeekView::resizeEvent( QResizeEvent *e )
+{
+ const int hourWidth = 20;
+ QScrollView::resizeEvent( e );
+ int avail = width()-qApp->style().scrollBarExtent().width()-1;
+ header->setGeometry( 0, 0, avail, header->sizeHint().height() );
+ setMargins( 0, header->height(), 0, 0 );
+ header->resizeSection( 0, hourWidth );
+ int sw = (avail - hourWidth) / 7;
+ for ( int i = 1; i < 7; i++ )
+ header->resizeSection( i, sw );
+ header->resizeSection( 7, avail - hourWidth - sw*6 );
+}
+
+void DateBookWeekView::setStartOfWeek( bool bStartOnMonday )
+{
+ bOnMonday = bStartOnMonday;
+ initNames();
+}
+
+//-------------------------------------------------------------------
+
+DateBookWeek::DateBookWeek( bool ap, bool startOnMonday, DateBookDB *newDB,
+ QWidget *parent, const char *name )
+ : QWidget( parent, name ),
+ db( newDB ),
+ startTime( 0 ),
+ ampm( ap ),
+ bStartOnMonday( startOnMonday )
+{
+ setFocusPolicy(StrongFocus);
+ QVBoxLayout *vb = new QVBoxLayout( this );
+ header = new DateBookWeekHeader( bStartOnMonday, this );
+ view = new DateBookWeekView( ampm, startOnMonday, this );
+ vb->addWidget( header );
+ vb->addWidget( view );
+
+ lblDesc = new QLabel( this, "event label" );
+ lblDesc->setFrameStyle( QFrame::Plain | QFrame::Box );
+ lblDesc->setBackgroundColor( yellow );
+ lblDesc->hide();
+
+ tHide = new QTimer( this );
+
+ connect( view, SIGNAL( showDay( int ) ),
+ this, SLOT( showDay( int ) ) );
+ connect( view, SIGNAL(signalShowEvent(const EffectiveEvent&)),
+ this, SLOT(slotShowEvent(const EffectiveEvent&)) );
+ connect( view, SIGNAL(signalHideEvent()),
+ this, SLOT(slotHideEvent()) );
+ connect( header, SIGNAL( dateChanged( int, int ) ),
+ this, SLOT( dateChanged( int, int ) ) );
+ connect( tHide, SIGNAL( timeout() ),
+ lblDesc, SLOT( hide() ) );
+ connect( header->spinYear, SIGNAL(valueChanged(int)),
+ this, SLOT(slotYearChanged(int)) );
+ connect( qApp, SIGNAL(weekChanged(bool)),
+ this, SLOT(slotWeekChanged(bool)) );
+ connect( qApp, SIGNAL(clockChanged(bool)),
+ this, SLOT(slotClockChanged(bool)));
+ setDate(QDate::currentDate());
+
+}
+
+void DateBookWeek::keyPressEvent(QKeyEvent *e)
+{
+ switch(e->key()) {
+ case Key_Up:
+ view->scrollBy(0, -20);
+ break;
+ case Key_Down:
+ view->scrollBy(0, 20);
+ break;
+ case Key_Left:
+ setDate(date().addDays(-7));
+ break;
+ case Key_Right:
+ setDate(date().addDays(7));
+ break;
+ default:
+ e->ignore();
+ }
+}
+
+void DateBookWeek::showDay( int day )
+{
+ QDate d;
+ d = dateFromWeek( _week, year, bStartOnMonday );
+ day--;
+ d = d.addDays( day );
+ emit showDate( d.year(), d.month(), d.day() );
+}
+
+void DateBookWeek::setDate( int y, int m, int d )
+{
+ QDate date;
+ date.setYMD( y, m, d );
+ setDate(QDate(y, m, d));
+}
+
+void DateBookWeek::setDate(QDate date)
+{
+ dow = date.dayOfWeek();
+ int w, y;
+ calcWeek( date, w, y, bStartOnMonday );
+ header->setDate( y, w );
+}
+
+void DateBookWeek::dateChanged( int y, int w )
+{
+ year = y;
+ _week = w;
+ getEvents();
+}
+
+QDate DateBookWeek::date() const
+{
+ QDate d;
+ d = dateFromWeek( _week - 1, year, bStartOnMonday );
+ if ( bStartOnMonday )
+ d = d.addDays( 7 + dow - 1 );
+ else {
+ if ( dow == 7 )
+ d = d.addDays( dow );
+ else
+ d = d.addDays( 7 + dow );
+ }
+ return d;
+}
+
+void DateBookWeek::getEvents()
+{
+ QDate startWeek = weekDate();
+
+ QDate endWeek = startWeek.addDays( 6 );
+ QValueList<EffectiveEvent> eventList = db->getEffectiveEvents(startWeek,
+ endWeek);
+ view->showEvents( eventList );
+ view->moveToHour( startTime );
+}
+
+void DateBookWeek::slotShowEvent( const EffectiveEvent &ev )
+{
+ if ( tHide->isActive() )
+ tHide->stop();
+
+ // why would someone use "<"? Oh well, fix it up...
+ // I wonder what other things may be messed up...
+ QString strDesc = ev.description();
+ int where = strDesc.find( "<" );
+ while ( where != -1 ) {
+ strDesc.remove( where, 1 );
+ strDesc.insert( where, "&#60;" );
+ where = strDesc.find( "<", where );
+ }
+
+ QString strCat;
+ // ### FIX later...
+// QString strCat = ev.category();
+// where = strCat.find( "<" );
+// while ( where != -1 ) {
+// strCat.remove( where, 1 );
+// strCat.insert( where, "&#60;" );
+// where = strCat.find( "<", where );
+// }
+
+ QString strNote = ev.notes();
+ where = strNote.find( "<" );
+ while ( where != -1 ) {
+ strNote.remove( where, 1 );
+ strNote.insert( where, "&#60;" );
+ where = strNote.find( "<", where );
+ }
+
+ QString str = "<b>" + strDesc + "</b><br>" + "<i>"
+ + strCat + "</i>"
+ + "<br>" + TimeString::longDateString( ev.date() )
+ + "<br><b>" + QObject::tr("Start") + "</b>: ";
+
+ if ( ev.startDate() != ev.date() ) {
+ // multi-day event. Show start date
+ str += TimeString::longDateString( ev.startDate() );
+ } else {
+ // Show start time.
+ str += TimeString::timeString(ev.start(), ampm, FALSE );
+ }
+
+ str += "<br><b>" + QObject::tr("End") + "</b>: ";
+ if ( ev.endDate() != ev.date() ) {
+ // multi-day event. Show end date
+ str += TimeString::longDateString( ev.endDate() );
+ } else {
+ // Show end time.
+ str += TimeString::timeString( ev.end(), ampm, FALSE );
+ }
+ str += "<br><br>" + strNote;
+
+ lblDesc->setText( str );
+ lblDesc->resize( lblDesc->sizeHint() );
+ // move the label so it is "centerd" horizontally...
+ lblDesc->move( QMAX(0,(width() - lblDesc->width()) / 2), 0 );
+ lblDesc->show();
+}
+
+void DateBookWeek::slotHideEvent()
+{
+ tHide->start( 2000, true );
+}
+
+void DateBookWeek::setStartViewTime( int startHere )
+{
+ startTime = startHere;
+ view->moveToHour( startTime );
+}
+
+int DateBookWeek::startViewTime() const
+{
+ return startTime;
+}
+
+void DateBookWeek::redraw()
+{
+ getEvents();
+}
+
+void DateBookWeek::slotYearChanged( int y )
+{
+ int totWeek;
+ QDate d( y, 12, 31 );
+ int throwAway;
+ calcWeek( d, totWeek, throwAway, bStartOnMonday );
+ while ( totWeek == 1 ) {
+ d = d.addDays( -1 );
+ calcWeek( d, totWeek, throwAway, bStartOnMonday );
+ }
+ if ( totWeek != totalWeeks() )
+ setTotalWeeks( totWeek );
+}
+
+
+void DateBookWeek::setTotalWeeks( int numWeeks )
+{
+ header->spinWeek->setMaxValue( numWeeks );
+}
+
+int DateBookWeek::totalWeeks() const
+{
+ return header->spinWeek->maxValue();
+}
+
+void DateBookWeek::slotWeekChanged( bool onMonday )
+{
+ bStartOnMonday = onMonday;
+ view->setStartOfWeek( bStartOnMonday );
+ header->setStartOfWeek( bStartOnMonday );
+ redraw();
+}
+
+void DateBookWeek::slotClockChanged( bool ap )
+{
+ ampm = ap;
+}
+
+// return the date at the beginning of the week...
+QDate DateBookWeek::weekDate() const
+{
+ return dateFromWeek( _week, year, bStartOnMonday );
+}
+
+// this used to only be needed by datebook.cpp, but now we need it inside
+// week view since
+// we need to be able to figure out our total number of weeks on the fly...
+// this is probably the best place to put it..
+
+// For Weeks that start on Monday... (EASY!)
+// At the moment we will use ISO 8601 method for computing
+// the week. Granted, other countries use other methods,
+// bet we aren't doing any Locale stuff at the moment. So,
+// this should pass. This Algorithim is public domain and
+// available at:
+// http://personal.ecu.edu/mccartyr/ISOwdALG.txt
+// the week number is return, and the year number is returned in year
+// for Instance 2001/12/31 is actually the first week in 2002.
+// There is a more mathematical definition, but I will implement it when
+// we are pass our deadline.
+
+// For Weeks that start on Sunday... (ahh... home rolled)
+// okay, if Jan 1 is on Friday or Saturday,
+// it will go to the pervious
+// week...
+
+bool calcWeek( const QDate &d, int &week, int &year,
+ bool startOnMonday = false )
+{
+ int weekNumber;
+ int yearNumber;
+
+ // remove a pesky warning, (Optimizations on g++)
+ weekNumber = -1;
+ int jan1WeekDay = QDate(d.year(), 1, 1).dayOfWeek();
+ int dayOfWeek = d.dayOfWeek();
+
+ if ( !d.isValid() )
+ return false;
+
+ if ( startOnMonday ) {
+ // find the Jan1Weekday;
+ if ( d.dayOfYear() <= ( 8 - jan1WeekDay) && jan1WeekDay > 4 ) {
+ yearNumber = d.year() - 1;
+ if ( jan1WeekDay == 5 || ( jan1WeekDay == 6 && QDate::leapYear(yearNumber) ) )
+ weekNumber = 53;
+ else
+ weekNumber = 52;
+ } else
+ yearNumber = d.year();
+ if ( yearNumber == d.year() ) {
+ int totalDays = 365;
+ if ( QDate::leapYear(yearNumber) )
+ totalDays++;
+ if ( ((totalDays - d.dayOfYear()) < (4 - dayOfWeek) )
+ || (jan1WeekDay == 7) && (totalDays - d.dayOfYear()) < 3) {
+ yearNumber++;
+ weekNumber = 1;
+ }
+ }
+ if ( yearNumber == d.year() ) {
+ int j = d.dayOfYear() + (7 - dayOfWeek) + ( jan1WeekDay - 1 );
+ weekNumber = j / 7;
+ if ( jan1WeekDay > 4 )
+ weekNumber--;
+ }
+ } else {
+ // it's better to keep these cases separate...
+ if ( d.dayOfYear() <= (7 - jan1WeekDay) && jan1WeekDay > 4
+ && jan1WeekDay != 7 ) {
+ yearNumber = d.year() - 1;
+ if ( jan1WeekDay == 6
+ || (jan1WeekDay == 7 && QDate::leapYear(yearNumber) ) ) {
+ weekNumber = 53;
+ }else
+ weekNumber = 52;
+ } else
+ yearNumber = d.year();
+ if ( yearNumber == d.year() ) {
+ int totalDays = 365;
+ if ( QDate::leapYear( yearNumber ) )
+ totalDays++;
+ if ( ((totalDays - d.dayOfYear()) < (4 - dayOfWeek % 7)) ) {
+ yearNumber++;
+ weekNumber = 1;
+ }
+ }
+ if ( yearNumber == d.year() ) {
+ int j = d.dayOfYear() + (7 - dayOfWeek % 7) + ( jan1WeekDay - 1 );
+ weekNumber = j / 7;
+ if ( jan1WeekDay > 4 ) {
+ weekNumber--;
+ }
+ }
+ }
+ year = yearNumber;
+ week = weekNumber;
+ return true;
+}
+
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 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef DATEBOOKWEEK
+#define DATEBOOKWEEK
+
+#include <qpe/event.h>
+
+#include <qlist.h>
+#include <qscrollview.h>
+#include <qstring.h>
+#include <qvaluelist.h>
+
+class DateBookDB;
+class DateBookWeekHeader;
+class QDate;
+class QLabel;
+class QResizeEvent;
+class QSpinBox;
+class QTimer;
+class QHeader;
+
+class DateBookWeekItem
+{
+public:
+ DateBookWeekItem( const EffectiveEvent e );
+
+ void setGeometry( int x, int y, int w, int h );
+ QRect geometry() const { return r; }
+
+ const QColor &color() const { return c; }
+ const EffectiveEvent event() const { return ev; }
+
+private:
+ const EffectiveEvent ev;
+ QRect r;
+ QColor c;
+};
+
+class DateBookWeekView : public QScrollView
+{
+ Q_OBJECT
+public:
+ DateBookWeekView( bool ampm, bool weekOnMonday, QWidget *parent = 0,
+ const char *name = 0 );
+
+ bool whichClock() const;
+ void showEvents( QValueList<EffectiveEvent> &ev );
+ void moveToHour( int h );
+ void setStartOfWeek( bool bOnMonday );
+
+signals:
+ void showDay( int d );
+ void signalShowEvent( const EffectiveEvent & );
+ void signalHideEvent();
+
+protected slots:
+ void keyPressEvent(QKeyEvent *);
+
+private slots:
+ void slotChangeClock( bool );
+ void alterDay( int );
+
+private:
+ void positionItem( DateBookWeekItem *i );
+ DateBookWeekItem *intersects( const DateBookWeekItem * );
+ void drawContents( QPainter *p, int cx, int cy, int cw, int ch );
+ void contentsMousePressEvent( QMouseEvent * );
+ void contentsMouseReleaseEvent( QMouseEvent * );
+ void resizeEvent( QResizeEvent * );
+ void initNames();
+
+private:
+ bool ampm;
+ bool bOnMonday;
+ QHeader *header;
+ QList<DateBookWeekItem> items;
+ int rowHeight;
+ bool showingEvent;
+};
+
+class DateBookWeek : public QWidget
+{
+ Q_OBJECT
+
+public:
+ DateBookWeek( bool ampm, bool weekOnMonday, DateBookDB *newDB,
+ QWidget *parent = 0, const char *name = 0 );
+ void setDate( int y, int m, int d );
+ void setDate( QDate d );
+ QDate date() const;
+ DateBookWeekView *weekView() const { return view; }
+ void setStartViewTime( int startHere );
+ int startViewTime() const;
+ int week() const { return _week; };
+ void setTotalWeeks( int totalWeeks );
+ int totalWeeks() const;
+ QDate weekDate() const;
+
+public slots:
+ void redraw();
+ void slotWeekChanged( bool bStartOnMonday );
+ void slotClockChanged( bool a );
+
+signals:
+ void showDate( int y, int m, int d );
+
+protected slots:
+ void keyPressEvent(QKeyEvent *);
+
+private slots:
+ void showDay( int day );
+ void dateChanged( int y, int w );
+ void slotShowEvent( const EffectiveEvent & );
+ void slotHideEvent();
+ void slotYearChanged( int );
+
+private:
+ void getEvents();
+ int year;
+ int _week;
+ int dow;
+ DateBookWeekHeader *header;
+ DateBookWeekView *view;
+ DateBookDB *db;
+ QLabel *lblDesc;
+ QTimer *tHide;
+ int startTime;
+ bool ampm;
+ bool bStartOnMonday;
+};
+
+
+bool calcWeek( const QDate &d, int &week, int &year,
+ bool startOnMonday = false );
+#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 @@
+<!DOCTYPE UI><UI>
+<class>DateBookWeekHeaderBase</class>
+<comment>*********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+*********************************************************************</comment>
+<widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>DateBookWeekHeaderBase</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>281</width>
+ <height>30</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>Form1</string>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QSpinBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>spinYear</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>prefix</name>
+ <string>Y: </string>
+ </property>
+ <property stdset="1">
+ <name>maxValue</name>
+ <number>2037</number>
+ </property>
+ <property stdset="1">
+ <name>minValue</name>
+ <number>1970</number>
+ </property>
+ <property stdset="1">
+ <name>value</name>
+ <number>2002</number>
+ </property>
+ </widget>
+ <widget>
+ <class>QSpinBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>spinWeek</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>prefix</name>
+ <string>W: </string>
+ </property>
+ <property stdset="1">
+ <name>maxValue</name>
+ <number>52</number>
+ </property>
+ <property stdset="1">
+ <name>minValue</name>
+ <number>1</number>
+ </property>
+ <property stdset="1">
+ <name>value</name>
+ <number>1</number>
+ </property>
+ </widget>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>labelDate</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>1</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>font</name>
+ <font>
+ <bold>1</bold>
+ </font>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>00. Jan-00. Jan</string>
+ </property>
+ <property stdset="1">
+ <name>alignment</name>
+ <set>AlignCenter</set>
+ </property>
+ <property>
+ <name>hAlign</name>
+ </property>
+ </widget>
+ </hbox>
+</widget>
+<connections>
+ <connection>
+ <sender>spinYear</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>DateBookWeekHeaderBase</receiver>
+ <slot>yearChanged( int )</slot>
+ </connection>
+ <connection>
+ <sender>spinWeek</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>DateBookWeekHeaderBase</receiver>
+ <slot>weekChanged( int )</slot>
+ </connection>
+ <slot access="public">yearChanged( int )</slot>
+ <slot access="public">nextWeek()</slot>
+ <slot access="public">prevWeek()</slot>
+ <slot access="public">weekChanged( int )</slot>
+</connections>
+</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 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "datebookweekheaderimpl.h"
+#include <qlabel.h>
+#include <qspinbox.h>
+#include <qdatetime.h>
+
+/*
+ * Constructs a DateBookWeekHeader which is a child of 'parent', with the
+ * name 'name' and widget flags set to 'f'
+ */
+DateBookWeekHeader::DateBookWeekHeader( bool startOnMonday, QWidget* parent,
+ const char* name, WFlags fl )
+ : DateBookWeekHeaderBase( parent, name, fl ),
+ bStartOnMonday( startOnMonday )
+{
+ setBackgroundMode( PaletteButton );
+ labelDate->setBackgroundMode( PaletteButton );
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+DateBookWeekHeader::~DateBookWeekHeader()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+
+/*
+ * public slot
+ */
+void DateBookWeekHeader::yearChanged( int y )
+{
+ setDate( y, week );
+}
+/*
+ * public slot
+ */
+void DateBookWeekHeader::nextWeek()
+{
+ if ( week < 52 )
+ week++;
+ setDate( year, week );
+}
+/*
+ * public slot
+ */
+void DateBookWeekHeader::prevWeek()
+{
+ if ( week > 1 )
+ week--;
+ setDate( year, week );
+}
+/*
+ * public slot
+ */
+void DateBookWeekHeader::weekChanged( int w )
+{
+ setDate( year, w );
+}
+
+void DateBookWeekHeader::setDate( int y, int w )
+{
+ year = y;
+ week = w;
+ spinYear->setValue( y );
+ spinWeek->setValue( w );
+
+ QDate d = dateFromWeek( week, year, bStartOnMonday );
+
+ QString s = QString::number( d.day() ) + ". " + d.monthName( d.month() )
+ + "-";
+ d = d.addDays( 6 );
+ s += QString::number( d.day() ) + ". " + d.monthName( d.month() );
+ labelDate->setText( s );
+
+ emit dateChanged( y, w );
+}
+
+void DateBookWeekHeader::setStartOfWeek( bool onMonday )
+{
+ bStartOnMonday = onMonday;
+ setDate( year, week );
+}
+
+// dateFromWeek
+// compute the date from the week in the year
+
+QDate dateFromWeek( int week, int year, bool startOnMonday )
+{
+ QDate d;
+ d.setYMD( year, 1, 1 );
+ int dayOfWeek = d.dayOfWeek();
+ if ( startOnMonday ) {
+ if ( dayOfWeek <= 4 ) {
+ d = d.addDays( ( week - 1 ) * 7 - dayOfWeek + 1 );
+ } else {
+ d = d.addDays( (week) * 7 - dayOfWeek + 1 );
+ }
+ } else {
+ if ( dayOfWeek <= 4 || dayOfWeek == 7) {
+ d = d.addDays( ( week - 1 ) * 7 - dayOfWeek % 7 );
+ } else {
+ d = d.addDays( ( week ) * 7 - dayOfWeek % 7 );
+ }
+ }
+ return d;
+}
+
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 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef DATEBOOKDAYHEADER_H
+#define DATEBOOKDAYHEADER_H
+#include <qdatetime.h>
+#include "datebookweekheader.h"
+
+
+class DateBookWeekHeader : public DateBookWeekHeaderBase
+{
+ Q_OBJECT
+
+public:
+ DateBookWeekHeader( bool startOnMonday, QWidget* parent = 0,
+ const char* name = 0, WFlags fl = 0 );
+ ~DateBookWeekHeader();
+
+ void setDate( int y, int w );
+ void setStartOfWeek( bool onMonday );
+
+signals:
+ void dateChanged( int y, int w );
+
+public slots:
+ void yearChanged( int );
+ void nextWeek();
+ void prevWeek();
+ void weekChanged( int );
+
+protected slots:
+ void keyPressEvent(QKeyEvent *e)
+ {
+ e->ignore();
+ }
+
+private:
+ int year,
+ week;
+ bool bStartOnMonday;
+
+};
+
+QDate dateFromWeek( int week, int year, bool startOnMonday );
+
+#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 @@
+<!DOCTYPE UI><UI>
+<class>DateEntryBase</class>
+<comment>*********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+** $Id$
+**
+*********************************************************************</comment>
+<widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>DateEntryBase</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>242</width>
+ <height>339</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>New Event</string>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <grid>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>0</number>
+ </property>
+ <widget row="1" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel2</cstring>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>MShape</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>MShadow</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Location</string>
+ </property>
+ </widget>
+ <widget row="2" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel2_2</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Category</string>
+ </property>
+ <property>
+ <name>buddy</name>
+ <cstring>comboPriority</cstring>
+ </property>
+ </widget>
+ <widget row="0" column="1" rowspan="1" colspan="3" >
+ <class>QComboBox</class>
+ <item>
+ <property>
+ <name>text</name>
+ <string>(None)</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>Meeting</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>Lunch</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>Dinner</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>Travel</string>
+ </property>
+ </item>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>comboDescription</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>editable</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>currentItem</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>duplicatesEnabled</name>
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget row="0" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel1</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Description:</string>
+ </property>
+ </widget>
+ <widget row="1" column="1" rowspan="1" colspan="3" >
+ <class>QComboBox</class>
+ <item>
+ <property>
+ <name>text</name>
+ <string>(Unknown)</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>Office</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>Home</string>
+ </property>
+ </item>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>comboLocation</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>editable</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>currentItem</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>duplicatesEnabled</name>
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget row="2" column="1" rowspan="1" colspan="3" >
+ <class>CategorySelect</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>comboCategory</cstring>
+ </property>
+ </widget>
+ <widget row="3" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel3</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Start</string>
+ </property>
+ </widget>
+ <widget row="3" column="1" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>buttonStart</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Jan 02 00</string>
+ </property>
+ </widget>
+ <widget row="3" column="2" rowspan="1" colspan="2" >
+ <class>QComboBox</class>
+ <item>
+ <property>
+ <name>text</name>
+ <string>00:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>00:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>01:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>01:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>02:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>02:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>03:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>03:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>04:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>04:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>05:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>05:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>06:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>06:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>07:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>07:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>08:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>08:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>09:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>09:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>10:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>10:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>11:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>11:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>12:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>12:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>13:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>13:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>14:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>14:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>15:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>15:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>16:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>16:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>17:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>17:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>18:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>18:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>19:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>19:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>20:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>20:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>21:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>21:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>22:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>22:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>23:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>23:30</string>
+ </property>
+ </item>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>comboStart</cstring>
+ </property>
+ <property stdset="1">
+ <name>editable</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>duplicatesEnabled</name>
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget row="4" column="1" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>buttonEnd</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Jan 02 00</string>
+ </property>
+ </widget>
+ <widget row="4" column="2" rowspan="1" colspan="2" >
+ <class>QComboBox</class>
+ <item>
+ <property>
+ <name>text</name>
+ <string>00:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>00:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>01:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>01:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>02:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>02:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>03:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>03:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>04:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>04:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>05:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>05:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>06:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>06:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>07:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>07:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>08:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>08:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>09:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>09:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>10:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>10:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>11:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>11:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>12:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>12:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>13:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>13:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>14:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>14:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>15:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>15:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>16:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>16:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>17:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>17:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>18:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>18:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>19:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>19:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>20:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>20:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>21:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>21:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>22:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>22:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>23:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>23:30</string>
+ </property>
+ </item>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>comboEnd</cstring>
+ </property>
+ <property stdset="1">
+ <name>editable</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>duplicatesEnabled</name>
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget row="4" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel3_2</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>End</string>
+ </property>
+ </widget>
+ <widget row="5" column="0" >
+ <class>QCheckBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>checkAllDay</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>All day</string>
+ </property>
+ </widget>
+ <widget row="6" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel3_2_2</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Time zone:</string>
+ </property>
+ </widget>
+ <widget row="6" column="1" rowspan="1" colspan="3" >
+ <class>TimeZoneSelector</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>timezone</cstring>
+ </property>
+ </widget>
+ <widget row="7" column="0" >
+ <class>QCheckBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>checkAlarm</cstring>
+ </property>
+ <property stdset="1">
+ <name>enabled</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>autoMask</name>
+ <bool>false</bool>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&amp;Alarm</string>
+ </property>
+ <property stdset="1">
+ <name>checked</name>
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget row="7" column="1" rowspan="1" colspan="2" >
+ <class>QSpinBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>spinAlarm</cstring>
+ </property>
+ <property stdset="1">
+ <name>enabled</name>
+ <bool>false</bool>
+ </property>
+ <property stdset="1">
+ <name>suffix</name>
+ <string> minutes</string>
+ </property>
+ <property stdset="1">
+ <name>maxValue</name>
+ <number>180</number>
+ </property>
+ <property stdset="1">
+ <name>minValue</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>lineStep</name>
+ <number>5</number>
+ </property>
+ <property stdset="1">
+ <name>value</name>
+ <number>5</number>
+ </property>
+ </widget>
+ <widget row="7" column="3" >
+ <class>QComboBox</class>
+ <item>
+ <property>
+ <name>text</name>
+ <string>Silent</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>Loud</string>
+ </property>
+ </item>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>comboSound</cstring>
+ </property>
+ <property stdset="1">
+ <name>enabled</name>
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget row="8" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>lblRepeat</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Repeat</string>
+ </property>
+ </widget>
+ <widget row="8" column="1" rowspan="1" colspan="3" >
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdRepeat</cstring>
+ </property>
+ <property stdset="1">
+ <name>focusPolicy</name>
+ <enum>TabFocus</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>No Repeat...</string>
+ </property>
+ </widget>
+ <widget row="9" column="0" rowspan="1" colspan="4" >
+ <class>QMultiLineEdit</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>editNote</cstring>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<customwidgets>
+ <customwidget>
+ <class>TimeZoneSelector</class>
+ <header location="global">qpe/tzselect.h</header>
+ <sizehint>
+ <width>21</width>
+ <height>10</height>
+ </sizehint>
+ <container>0</container>
+ <sizepolicy>
+ <hordata>7</hordata>
+ <verdata>1</verdata>
+ </sizepolicy>
+ <pixmap>image0</pixmap>
+ </customwidget>
+ <customwidget>
+ <class>CategorySelect</class>
+ <header location="global">qpe/categoryselect.h</header>
+ <sizehint>
+ <width>-1</width>
+ <height>-1</height>
+ </sizehint>
+ <container>0</container>
+ <sizepolicy>
+ <hordata>7</hordata>
+ <verdata>1</verdata>
+ </sizepolicy>
+ <pixmap>image1</pixmap>
+ </customwidget>
+</customwidgets>
+<images>
+ <image>
+ <name>image0</name>
+ <data format="XPM.GZ" length="45">789cd3d7528808f055d0d2e72a2e492cc94c5648ce482c52d04a29cdcdad8c8eb5ade6523250004143a55a6b2e0026630c4f</data>
+ </image>
+ <image>
+ <name>image1</name>
+ <data format="XPM.GZ" length="646">789c6dd2c10ac2300c00d07bbf2234b7229d1be245fc04c5a3201e4615f430059d0711ff5ddb2e6bb236ec90eed134cb5a19d8ef36602af5ecdbfeeac05dda0798d3abebde87e3faa374d3807fa0d633a52d38d8de6f679fe33fc776e196f53cd010188256a3600a292882096246517815ca99884606e18044a3a40d91824820924265a7923a2e8bcd05f33db1173e002913175f2a6be6d3294871a2d95fa00e8a94ee017b69d339d90df1e77c57ea072ede6758</data>
+ </image>
+</images>
+<connections>
+ <connection>
+ <sender>checkAlarm</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>spinAlarm</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>comboEnd</sender>
+ <signal>activated(const QString&amp;)</signal>
+ <receiver>DateEntryBase</receiver>
+ <slot>endTimeChanged( const QString &amp; )</slot>
+ </connection>
+ <connection>
+ <sender>cmdRepeat</sender>
+ <signal>clicked()</signal>
+ <receiver>DateEntryBase</receiver>
+ <slot>slotRepeat()</slot>
+ </connection>
+ <connection>
+ <sender>comboStart</sender>
+ <signal>activated(int)</signal>
+ <receiver>DateEntryBase</receiver>
+ <slot>startTimeChanged( int )</slot>
+ </connection>
+ <connection>
+ <sender>checkAllDay</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>comboEnd</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>checkAlarm</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>comboSound</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>checkAllDay</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>comboStart</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <slot access="public">endDateChanged( const QString &amp; )</slot>
+ <slot access="public">endDateChanged( int, int, int )</slot>
+ <slot access="public">endTimeChanged( const QString &amp; )</slot>
+ <slot access="public">slotRepeat()</slot>
+ <slot access="public">slotWait( int )</slot>
+ <slot access="public">startDateChanged( const QString &amp; )</slot>
+ <slot access="public">startDateChanged(int, int, int)</slot>
+ <slot access="public">startTimeChanged( int )</slot>
+ <slot access="public">typeChanged( const QString &amp; )</slot>
+ <slot access="public">tzexecute(void)</slot>
+</connections>
+</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 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "dateentryimpl.h"
+#include "repeatentry.h"
+
+#include <qpe/qpeapplication.h>
+#include <qpe/categoryselect.h>
+#include <qpe/datebookmonth.h>
+#include <qpe/global.h>
+#include <qpe/timeconversion.h>
+#include <qpe/timestring.h>
+#include <qpe/tzselect.h>
+
+#include <qcheckbox.h>
+#include <qcombobox.h>
+#include <qlayout.h>
+#include <qlineedit.h>
+#include <qmultilineedit.h>
+#include <qpopupmenu.h>
+#include <qscrollview.h>
+#include <qspinbox.h>
+#include <qtoolbutton.h>
+
+#include <stdlib.h>
+
+/*
+ * Constructs a DateEntry which is a child of 'parent', with the
+ * name 'name' and widget flags set to 'f'
+ *
+ * The dialog will by default be modeless, unless you set 'modal' to
+ * TRUE to construct a modal dialog.
+ */
+
+DateEntry::DateEntry( bool startOnMonday, const QDateTime &start,
+ const QDateTime &end, bool whichClock, QWidget* parent,
+ const char* name )
+ : DateEntryBase( parent, name ),
+ ampm( whichClock ),
+ startWeekOnMonday( startOnMonday )
+{
+ init();
+ setDates(start,end);
+}
+
+static void addOrPick( QComboBox* combo, const QString& t )
+{
+ for (int i=0; i<combo->count(); i++) {
+ if ( combo->text(i) == t ) {
+ combo->setCurrentItem(i);
+ return;
+ }
+ }
+ combo->setEditText(t);
+}
+
+DateEntry::DateEntry( bool startOnMonday, const Event &event, bool whichClock,
+ QWidget* parent, const char* name )
+ : DateEntryBase( parent, name ),
+ ampm( whichClock ),
+ startWeekOnMonday( startOnMonday )
+{
+ init();
+ setDates(event.start(),event.end());
+ comboCategory->setCategories( event.categories(), "Calendar", tr("Calendar") );
+ if(!event.description().isEmpty())
+ addOrPick( comboDescription, event.description() );
+ if(!event.location().isEmpty())
+ addOrPick( comboLocation, event.location() );
+ checkAlarm->setChecked( event.hasAlarm() );
+ checkAllDay->setChecked( event.type() == Event::AllDay );
+ if(!event.notes().isEmpty())
+ editNote->setText(event.notes());
+ spinAlarm->setValue(event.alarmTime());
+ if ( event.alarmSound() != Event::Silent )
+ comboSound->setCurrentItem( 1 );
+ if ( event.hasRepeat() ) {
+ rp = event.repeatPattern();
+ cmdRepeat->setText( tr("Repeat...") );
+ }
+ setRepeatLabel();
+}
+
+void DateEntry::setDates( const QDateTime& s, const QDateTime& e )
+{
+ int shour,
+ ehour;
+ QString strStart,
+ strEnd;
+ startDate = s.date();
+ endDate = e.date();
+ startTime = s.time();
+ endTime = e.time();
+ startDateChanged( s.date().year(), s.date().month(), s.date().day() );
+ if ( ampm ) {
+ shour = s.time().hour();
+ ehour = e.time().hour();
+ if ( shour >= 12 ) {
+ if ( shour > 12 )
+ shour -= 12;
+ strStart.sprintf( "%d:%02d PM", shour, s.time().minute() );
+ } else {
+ if ( shour == 0 )
+ shour = 12;
+ strStart.sprintf( "%d:%02d AM", shour, s.time().minute() );
+ }
+ if ( ehour == 24 && e.time().minute() == 0 ) {
+ strEnd = "11:59 PM"; // or "midnight"
+ } else if ( ehour >= 12 ) {
+ if ( ehour > 12 )
+ ehour -= 12;
+ strEnd.sprintf( "%d:%02d PM", ehour, e.time().minute() );
+ } else {
+ if ( ehour == 0 )
+ ehour = 12;
+ strEnd.sprintf( "%d:%02d AM", ehour, e.time().minute() );
+ }
+ } else {
+ strStart.sprintf( "%02d:%02d", s.time().hour(), s.time().minute() );
+ strEnd.sprintf( "%02d:%02d", e.time().hour(), e.time().minute() );
+ }
+ addOrPick(comboStart, strStart );
+ endDateChanged( e.date().year(), e.date().month(), e.date().day() );
+ addOrPick(comboEnd, strEnd );
+}
+
+void DateEntry::init()
+{
+ comboDescription->setInsertionPolicy(QComboBox::AtCurrent);
+ comboLocation->setInsertionPolicy(QComboBox::AtCurrent);
+
+ initCombos();
+ QPopupMenu *m1 = new QPopupMenu( this );
+ startPicker = new DateBookMonth( m1, 0, TRUE );
+ m1->insertItem( startPicker );
+ buttonStart->setPopup( m1 );
+ connect( startPicker, SIGNAL( dateClicked( int, int, int ) ),
+ this, SLOT( startDateChanged( int, int, int ) ) );
+
+ //Let start button change both start and end dates
+ connect( startPicker, SIGNAL( dateClicked( int, int, int ) ),
+ this, SLOT( endDateChanged( int, int, int ) ) );
+ connect( qApp, SIGNAL( clockChanged( bool ) ),
+ this, SLOT( slotChangeClock( bool ) ) );
+ connect( qApp, SIGNAL(weekChanged(bool)),
+ this, SLOT(slotChangeStartOfWeek(bool)) );
+
+ QPopupMenu *m2 = new QPopupMenu( this );
+ endPicker = new DateBookMonth( m2, 0, TRUE );
+ m2->insertItem( endPicker );
+ buttonEnd->setPopup( m2 );
+ connect( endPicker, SIGNAL( dateClicked( int, int, int ) ),
+ this, SLOT( endDateChanged( int, int, int ) ) );
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+DateEntry::~DateEntry()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+
+/*
+ * public slot
+ */
+void DateEntry::endDateChanged( int y, int m, int d )
+{
+ endDate.setYMD( y, m, d );
+ if ( endDate < startDate ) {
+ endDate = startDate;
+ }
+
+ buttonEnd->setText( TimeString::shortDate( endDate ) );
+
+ endPicker->setDate( endDate.year(), endDate.month(), endDate.day() );
+}
+
+static QTime parseTime( const QString& s, bool ampm )
+{
+ QTime tmpTime;
+ QStringList l = QStringList::split( ':', s );
+ int hour = l[0].toInt();
+ if ( ampm ) {
+ int i=0;
+ while (i<int(l[1].length()) && l[1][i]>='0' && l[1][i]<='9')
+ i++;
+ QString digits = l[1].left(i);
+ if ( l[1].contains( "PM", FALSE ) ) {
+ if ( hour != 12 )
+ hour += 12;
+ } else {
+ if ( hour == 12 )
+ hour = 0;
+ }
+ l[1] = digits;
+ }
+ int minute = l[1].toInt();
+ if ( minute > 59 )
+ minute = 59;
+ else if ( minute < 0 )
+ minute = 0;
+ if ( hour > 23 ) {
+ hour = 23;
+ minute = 59;
+ } else if ( hour < 0 )
+ hour = 0;
+ tmpTime.setHMS( hour, minute, 0 );
+ return tmpTime;
+}
+
+/*
+ * public slot
+ */
+void DateEntry::endTimeChanged( const QString &s )
+{
+ QTime tmpTime = parseTime(s,ampm);
+ if ( endDate > startDate || tmpTime >= startTime ) {
+ endTime = tmpTime;
+ } else {
+ endTime = startTime;
+ comboEnd->setCurrentItem( comboStart->currentItem() );
+ }
+}
+
+/*
+ * public slot
+ */
+void DateEntry::startDateChanged( int y, int m, int d )
+{
+ QDate prev = startDate;
+ startDate.setYMD( y, m, d );
+ if ( rp.type == Event::Weekly &&
+ startDate.dayOfWeek() != prev.dayOfWeek() ) {
+ // if we change the start of a weekly repeating event
+ // set the repeating day appropriately
+ char mask = 1 << (prev.dayOfWeek()-1);
+ rp.days &= (~mask);
+ rp.days |= 1 << (startDate.dayOfWeek()-1);
+ }
+
+ buttonStart->setText( TimeString::shortDate( startDate ) );
+
+ // our pickers must be reset...
+ startPicker->setDate( y, m, d );
+ endPicker->setDate( y, m, d );
+}
+
+/*
+ * public slot
+ */
+void DateEntry::startTimeChanged( int index )
+{
+ startTime = parseTime(comboStart->text(index),ampm);
+ changeEndCombo( index );
+}
+/*
+ * public slot
+ */
+void DateEntry::typeChanged( const QString &s )
+{
+ bool b = s != "All Day";
+ buttonStart->setEnabled( b );
+ comboStart->setEnabled( b );
+ comboEnd->setEnabled( b );
+}
+/*
+ * public slot
+ */
+void DateEntry::changeEndCombo( int change )
+{
+ if ( change + 2 < comboEnd->count() )
+ change += 2;
+ comboEnd->setCurrentItem( change );
+ endTimeChanged( comboEnd->currentText() );
+}
+
+void DateEntry::slotRepeat()
+{
+ // Work around for compiler Bug..
+ RepeatEntry *e;
+
+ // it is better in my opinion to just grab this from the mother,
+ // since, this dialog doesn't need to keep track of it...
+ if ( rp.type != Event::NoRepeat )
+ e = new RepeatEntry( startWeekOnMonday, rp, startDate, this);
+ else
+ e = new RepeatEntry( startWeekOnMonday, startDate, this );
+
+#if defined(Q_WS_QWS) || defined(_WS_QWS_)
+ e->showMaximized();
+#endif
+ if ( e->exec() ) {
+ rp = e->repeatPattern();
+ setRepeatLabel();
+ }
+}
+
+void DateEntry::slotChangeStartOfWeek( bool onMonday )
+{
+ startWeekOnMonday = onMonday;
+}
+
+Event DateEntry::event()
+{
+ Event ev;
+ Event::SoundTypeChoice st;
+ ev.setDescription( comboDescription->currentText() );
+ ev.setLocation( comboLocation->currentText() );
+ ev.setCategories( comboCategory->currentCategories() );
+ ev.setType( checkAllDay->isChecked() ? Event::AllDay : Event::Normal );
+ if ( startDate > endDate ) {
+ QDate tmp = endDate;
+ endDate = startDate;
+ startDate = tmp;
+ }
+ startTime = parseTime( comboStart->currentText(), ampm );
+ endTime = parseTime( comboEnd->currentText(), ampm );
+ if ( startTime > endTime && endDate == startDate ) {
+ QTime tmp = endTime;
+ endTime = startTime;
+ startTime = tmp;
+ }
+ // don't set the time if theres no need too
+ if ( ev.type() == Event::AllDay ) {
+ startTime.setHMS( 0, 0, 0 );
+ endTime.setHMS( 23, 59, 59 );
+ }
+
+ // adjust start and end times based on timezone
+ QDateTime start( startDate, startTime );
+ QDateTime end( endDate, endTime );
+ time_t start_utc, end_utc;
+
+// qDebug( "tz: %s", timezone->currentZone().latin1() );
+
+ // get real timezone
+ QString realTZ;
+ realTZ = QString::fromLocal8Bit( getenv("TZ") );
+
+ // set timezone
+ if ( setenv( "TZ", timezone->currentZone(), true ) != 0 )
+ qWarning( "There was a problem setting the timezone." );
+
+ // convert to UTC based on selected TZ (calling tzset internally)
+ start_utc = TimeConversion::toUTC( start );
+ end_utc = TimeConversion::toUTC( end );
+
+ // done playing around... put it all back
+ unsetenv( "TZ" );
+ if ( !realTZ.isNull() )
+ if ( setenv( "TZ", realTZ, true ) != 0 )
+ qWarning( "There was a problem setting the timezone." );
+
+ // convert UTC to local time (calling tzset internally)
+ ev.setStart( TimeConversion::fromUTC( start_utc ) );
+ ev.setEnd( TimeConversion::fromUTC( end_utc ) );
+
+ // we only have one type of sound at the moment... LOUD!!!
+ if ( comboSound->currentItem() != 0 )
+ st = Event::Loud;
+ else
+ st = Event::Silent;
+ ev.setAlarm( checkAlarm->isChecked(), spinAlarm->value(), st );
+ if ( rp.type != Event::NoRepeat )
+ ev.setRepeat( TRUE, rp );
+ ev.setNotes( editNote->text() );
+ return ev;
+}
+
+void DateEntry::setRepeatLabel()
+{
+
+ switch( rp.type ) {
+ case Event::Daily:
+ cmdRepeat->setText( tr("Daily...") );
+ break;
+ case Event::Weekly:
+ cmdRepeat->setText( tr("Weekly...") );
+ break;
+ case Event::MonthlyDay:
+ case Event::MonthlyDate:
+ cmdRepeat->setText( tr("Monthly...") );
+ break;
+ case Event::Yearly:
+ cmdRepeat->setText( tr("Yearly...") );
+ break;
+ default:
+ cmdRepeat->setText( tr("No Repeat...") );
+ }
+}
+
+void DateEntry::setAlarmEnabled( bool alarmPreset, int presetTime, Event::SoundTypeChoice sound )
+{
+ checkAlarm->setChecked( alarmPreset );
+ spinAlarm->setValue( presetTime );
+ if ( sound != Event::Silent )
+ comboSound->setCurrentItem( 1 );
+ else
+ comboSound->setCurrentItem( 0 );
+}
+
+void DateEntry::initCombos()
+{
+ comboStart->clear();
+ comboEnd->clear();
+ if ( ampm ) {
+ for ( int i = 0; i < 24; i++ ) {
+ if ( i == 0 ) {
+ comboStart->insertItem( "12:00 AM" );
+ comboStart->insertItem( "12:30 AM" );
+ comboEnd->insertItem( "12:00 AM" );
+ comboEnd->insertItem( "12:30 AM" );
+ } else if ( i == 12 ) {
+ comboStart->insertItem( "12:00 PM" );
+ comboStart->insertItem( "12:30 PM" );
+ comboEnd->insertItem( "12:00 PM" );
+ comboEnd->insertItem( "12:30 PM" );
+ } else if ( i > 12 ) {
+ comboStart->insertItem( QString::number( i - 12 ) + ":00 PM" );
+ comboStart->insertItem( QString::number( i - 12 ) + ":30 PM" );
+ comboEnd->insertItem( QString::number( i - 12 ) + ":00 PM" );
+ comboEnd->insertItem( QString::number( i - 12 ) + ":30 PM" );
+ } else {
+ comboStart->insertItem( QString::number( i) + ":00 AM" );
+ comboStart->insertItem( QString::number( i ) + ":30 AM" );
+ comboEnd->insertItem( QString::number( i ) + ":00 AM" );
+ comboEnd->insertItem( QString::number( i ) + ":30 AM" );
+ }
+ }
+ } else {
+ for ( int i = 0; i < 24; i++ ) {
+ if ( i < 10 ) {
+ comboStart->insertItem( QString("0")
+ + QString::number(i) + ":00" );
+ comboStart->insertItem( QString("0")
+ + QString::number(i) + ":30" );
+ comboEnd->insertItem( QString("0")
+ + QString::number(i) + ":00" );
+ comboEnd->insertItem( QString("0")
+ + QString::number(i) + ":30" );
+ } else {
+ comboStart->insertItem( QString::number(i) + ":00" );
+ comboStart->insertItem( QString::number(i) + ":30" );
+ comboEnd->insertItem( QString::number(i) + ":00" );
+ comboEnd->insertItem( QString::number(i) + ":30" );
+ }
+ }
+ }
+}
+
+void DateEntry::slotChangeClock( bool whichClock )
+{
+ ampm = whichClock;
+ initCombos();
+ setDates( QDateTime( startDate, startTime ), QDateTime( endDate, endTime ) );
+}
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 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef DATEENTRY_H
+#define DATEENTRY_H
+
+#include "dateentry.h"
+
+#include <qpe/event.h>
+
+#include <qdatetime.h>
+
+class DateBookMonth;
+
+class DateEntry : public DateEntryBase
+{
+ Q_OBJECT
+
+public:
+ DateEntry( bool startOnMonday, const QDateTime &start,
+ const QDateTime &end, bool whichClock = FALSE,
+ QWidget* parent = 0, const char* name = 0 );
+ DateEntry( bool startOnMonday, const Event &event, bool whichCLock = FALSE,
+ QWidget* parent = 0, const char* name = 0 );
+ ~DateEntry();
+
+ Event event();
+ void setAlarmEnabled( bool alarmPreset, int presetTime, Event::SoundTypeChoice );
+
+public slots:
+ void endDateChanged( int, int, int );
+ void endTimeChanged( const QString & );
+ void startDateChanged(int, int, int);
+ void startTimeChanged( int index );
+ void typeChanged( const QString & );
+ void changeEndCombo( int change );
+ void slotRepeat();
+ void slotChangeClock( bool );
+ void slotChangeStartOfWeek( bool );
+
+private:
+ void init();
+ void initCombos();
+ void setDates( const QDateTime& s, const QDateTime& e );
+ void setRepeatLabel();
+
+ DateBookMonth *startPicker, *endPicker;
+ QDate startDate, endDate;
+ QTime startTime, endTime;
+ Event::RepeatPattern rp;
+ bool ampm;
+ bool startWeekOnMonday;
+};
+
+#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 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "datebook.h"
+#include <qpe/qpeapplication.h>
+
+
+int main( int argc, char **argv )
+{
+ QPEApplication a( argc, argv );
+
+ DateBook e;
+ QObject::connect( &a, SIGNAL( flush() ), &e, SLOT( flush() ) );
+ QObject::connect( &a, SIGNAL( reload() ), &e, SLOT( reload() ) );
+
+
+ e.setCaption( DateBook::tr("Calendar") );
+ a.showMainWidget(&e);
+
+ return a.exec();
+}
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 @@
+Files: bin/datebook apps/Applications/datebook.desktop
+Priority: optional
+Section: qpe/applications
+Maintainer: Warwick Allison <warwick@trolltech.com>
+Architecture: arm
+Version: $QPE_VERSION-3
+Depends: qpe-base ($QPE_VERSION)
+Description: A datebook/appointment manager
+ 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 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "repeatentry.h"
+
+#include <qpe/datebookmonth.h>
+#include <qpe/qpeapplication.h>
+#include <qpe/timestring.h>
+
+#include <qbuttongroup.h>
+#include <qlabel.h>
+#include <qpopupmenu.h>
+#include <qspinbox.h>
+#include <qtoolbutton.h>
+
+#include <time.h>
+
+// Global Templates for use in setting up the repeat label...
+const QString strDayTemplate = QObject::tr("Every");
+const QString strYearTemplate = QObject::tr("%1 %2 every ");
+const QString strMonthDateTemplate = QObject::tr("The %1 every ");
+const QString strMonthDayTemplate = QObject::tr("The %1 %1 of every");
+const QString strWeekTemplate = QObject::tr("Every ");
+const QString dayLabel[] = { QObject::tr("Monday"),
+ QObject::tr("Tuesday"),
+ QObject::tr("Wednesday"),
+ QObject::tr("Thursday"),
+ QObject::tr("Friday"),
+ QObject::tr("Saturday"),
+ QObject::tr("Sunday") };
+
+
+static QString numberPlacing( int x ); // return the proper word format for
+ // x (1st, 2nd, etc)
+static int week( const QDate &dt ); // what week in the month is dt?
+
+RepeatEntry::RepeatEntry( bool startOnMonday,
+ const QDate &newStart, QWidget *parent,
+ const char *name, bool modal, WFlags fl )
+ : RepeatEntryBase( parent, name, modal, fl ),
+ start( newStart ),
+ currInterval( NONE ),
+ startWeekOnMonday( startOnMonday )
+{
+ init();
+ fraType->setButton( currInterval );
+ chkNoEnd->setChecked( TRUE );
+ setupNone();
+}
+
+RepeatEntry::RepeatEntry( bool startOnMonday, const Event::RepeatPattern &rp,
+ const QDate &startDate,
+ QWidget *parent, const char *name, bool modal,
+ WFlags fl )
+ : RepeatEntryBase( parent, name, modal, fl ),
+ start( startDate ),
+ end( rp.endDate() ),
+ startWeekOnMonday( startOnMonday )
+{
+ // do some stuff with the repeat pattern
+ init();
+ switch ( rp.type ) {
+ default:
+ case Event::NoRepeat:
+ currInterval = NONE;
+ setupNone();
+ break;
+ case Event::Daily:
+ currInterval = DAY;
+ setupDaily();
+ break;
+ case Event::Weekly:
+ currInterval = WEEK;
+ setupWeekly();
+ int day, buttons;
+ for ( day = 0x01, buttons = 0; buttons < 7;
+ day = day << 1, buttons++ ) {
+ if ( rp.days & day ) {
+ if ( startWeekOnMonday )
+ fraExtra->setButton( buttons );
+ else {
+ if ( buttons == 7 )
+ fraExtra->setButton( 0 );
+ else
+ fraExtra->setButton( buttons + 1 );
+ }
+ }
+ }
+ slotWeekLabel();
+ break;
+ case Event::MonthlyDay:
+ currInterval = MONTH;
+ setupMonthly();
+ fraExtra->setButton( 0 );
+ slotMonthLabel( 0 );
+ break;
+ case Event::MonthlyDate:
+ currInterval = MONTH;
+ setupMonthly();
+ fraExtra->setButton( 1 );
+ slotMonthLabel( 1 );
+ break;
+ case Event::Yearly:
+ currInterval = YEAR;
+ setupYearly();
+ break;
+ }
+ fraType->setButton( currInterval );
+ spinFreq->setValue( rp.frequency );
+ if ( !rp.hasEndDate ) {
+ cmdEnd->setText( RepeatEntryBase::tr("No End Date") );
+ chkNoEnd->setChecked( TRUE );
+ } else
+ cmdEnd->setText( TimeString::shortDate( end ) );
+}
+
+RepeatEntry::~RepeatEntry()
+{
+}
+
+Event::RepeatPattern RepeatEntry::repeatPattern()
+{
+ QListIterator<QToolButton> it( listRTypeButtons );
+ QListIterator<QToolButton> itExtra( listExtra );
+ Event::RepeatPattern rpTmp;
+ int i;
+ for ( i = 0; *it; ++it, i++ ) {
+ if ( (*it)->isOn() ) {
+ switch ( i ) {
+ case NONE:
+ rpTmp.type = Event::NoRepeat;
+ break;
+ case DAY:
+ rpTmp.type = Event::Daily;
+ break;
+ case WEEK:
+ rpTmp.type = Event::Weekly;
+ rpTmp.days = 0;
+ int day;
+ for ( day = 1; *itExtra; ++itExtra, day = day << 1 ) {
+ if ( (*itExtra)->isOn() ) {
+ if ( startWeekOnMonday )
+ rpTmp.days |= day;
+ else {
+ if ( day == 1 )
+ rpTmp.days |= Event::SUN;
+ else
+ rpTmp.days |= day >> 1;
+ }
+ }
+ }
+ break;
+ case MONTH:
+ if ( cmdExtra1->isOn() )
+ rpTmp.type = Event::MonthlyDay;
+ else if ( cmdExtra2->isOn() )
+ rpTmp.type = Event::MonthlyDate;
+ // figure out the montly day...
+ rpTmp.position = week( start );
+ break;
+ case YEAR:
+ rpTmp.type = Event::Yearly;
+ break;
+ }
+ break; // no need to keep looking!
+ }
+ }
+ rpTmp.frequency = spinFreq->value();
+ rpTmp.hasEndDate = !chkNoEnd->isChecked();
+ if ( rpTmp.hasEndDate ) {
+ rpTmp.setEndDate( end );
+ }
+ // timestamp it...
+ rpTmp.createTime = time( NULL );
+ return rpTmp;
+}
+
+void RepeatEntry::slotSetRType( int rtype )
+{
+ // now call the right function based on the type...
+ currInterval = static_cast<repeatButtons>(rtype);
+ switch ( currInterval ) {
+ case NONE:
+ setupNone();
+ break;
+ case DAY:
+ setupDaily();
+ break;
+ case WEEK:
+ setupWeekly();
+ slotWeekLabel();
+ break;
+ case MONTH:
+ setupMonthly();
+ cmdExtra2->setOn( TRUE );
+ slotMonthLabel( 1 );
+ break;
+ case YEAR:
+ setupYearly();
+ break;
+ }
+}
+
+void RepeatEntry::setupNone()
+{
+ lblRepeat->setText( tr("No Repeat") );
+ lblVar1->hide();
+ lblVar2->hide();
+ hideExtras();
+ cmdEnd->hide();
+ lblFreq->hide();
+ lblEvery->hide();
+ lblFreq->hide();
+ spinFreq->hide();
+ lblEnd->hide();
+ lblWeekVar->hide();
+}
+
+void RepeatEntry::setupDaily()
+{
+ hideExtras();
+ lblWeekVar->hide();
+ spinFreq->setValue( 1 );
+ lblFreq->setText( tr("day(s)") );
+ lblVar2->show();
+ showRepeatStuff();
+ lblRepeat->setText( strDayTemplate );
+ setupRepeatLabel( 1 );
+}
+
+void RepeatEntry::setupWeekly()
+{
+ // reshow the buttons...
+ fraExtra->setTitle( RepeatEntryBase::tr("Repeat On") );
+ fraExtra->setExclusive( FALSE );
+ fraExtra->show();
+ if ( startWeekOnMonday ) {
+ cmdExtra1->setText( RepeatEntryBase::tr("Mon") );
+ cmdExtra2->setText( RepeatEntryBase::tr("Tue") );
+ cmdExtra3->setText( RepeatEntryBase::tr("Wed") );
+ cmdExtra4->setText( RepeatEntryBase::tr("Thu") );
+ cmdExtra5->setText( RepeatEntryBase::tr("Fri") );
+ cmdExtra6->setText( RepeatEntryBase::tr("Sat") );
+ cmdExtra7->setText( RepeatEntryBase::tr("Sun") );
+ } else {
+ cmdExtra1->setText( RepeatEntryBase::tr("Sun") );
+ cmdExtra2->setText( RepeatEntryBase::tr("Mon") );
+ cmdExtra3->setText( RepeatEntryBase::tr("Tue") );
+ cmdExtra4->setText( RepeatEntryBase::tr("Wed") );
+ cmdExtra5->setText( RepeatEntryBase::tr("Thu") );
+ cmdExtra6->setText( RepeatEntryBase::tr("Fri") );
+ cmdExtra7->setText( RepeatEntryBase::tr("Sat") );
+ }
+ // I hope clustering these improve performance....
+ cmdExtra1->setOn( FALSE );
+ cmdExtra2->setOn( FALSE );
+ cmdExtra3->setOn( FALSE );
+ cmdExtra4->setOn( FALSE );
+ cmdExtra5->setOn( FALSE );
+ cmdExtra6->setOn( FALSE );
+ cmdExtra7->setOn( FALSE );
+
+ cmdExtra1->show();
+ cmdExtra2->show();
+ cmdExtra3->show();
+ cmdExtra4->show();
+ cmdExtra5->show();
+ cmdExtra6->show();
+ cmdExtra7->show();
+
+ lblWeekVar->show();
+ spinFreq->setValue( 1 );
+ // might as well set the day too...
+ if ( startWeekOnMonday ) {
+ fraExtra->setButton( start.dayOfWeek() - 1 );
+ } else {
+ fraExtra->setButton( start.dayOfWeek() % 7 );
+ }
+ lblFreq->setText( tr("week(s)") );
+ lblVar2->show();
+ showRepeatStuff();
+ setupRepeatLabel( 1 );
+}
+
+void RepeatEntry::setupMonthly()
+{
+ hideExtras();
+ lblWeekVar->hide();
+ fraExtra->setTitle( tr("Repeat By") );
+ fraExtra->setExclusive( TRUE );
+ fraExtra->show();
+ cmdExtra1->setText( tr("Day") );
+ cmdExtra1->show();
+ cmdExtra2->setText( tr("Date") );
+ cmdExtra2->show();
+ spinFreq->setValue( 1 );
+ lblFreq->setText( tr("month(s)") );
+ lblVar2->show();
+ showRepeatStuff();
+ setupRepeatLabel( 1 );
+}
+
+void RepeatEntry::setupYearly()
+{
+ hideExtras();
+ lblWeekVar->hide();
+ spinFreq->setValue( 1 );
+ lblFreq->setText( tr("year(s)") );
+ lblFreq->show();
+ lblFreq->show();
+ showRepeatStuff();
+ lblVar2->show();
+ QString strEvery = strYearTemplate.arg( start.monthName(start.month()) ).arg( numberPlacing(start.day()) );
+ lblRepeat->setText( strEvery );
+ setupRepeatLabel( 1 );
+
+}
+
+void RepeatEntry::init()
+{
+ QPopupMenu *m1 = new QPopupMenu( this );
+ repeatPicker = new DateBookMonth( m1, 0, TRUE );
+ m1->insertItem( repeatPicker );
+ cmdEnd->setPopup( m1 );
+ cmdEnd->setPopupDelay( 0 );
+
+ QObject::connect( repeatPicker, SIGNAL(dateClicked(int, int, int)),
+ this, SLOT(endDateChanged(int, int, int)) );
+ QObject::connect( qApp, SIGNAL(weekChanged(bool)),
+ this, SLOT(slotChangeStartOfWeek(bool)) );
+
+ listRTypeButtons.setAutoDelete( TRUE );
+ listRTypeButtons.append( cmdNone );
+ listRTypeButtons.append( cmdDay );
+ listRTypeButtons.append( cmdWeek );
+ listRTypeButtons.append( cmdMonth );
+ listRTypeButtons.append( cmdYear );
+
+ listExtra.setAutoDelete( TRUE );
+ listExtra.append( cmdExtra1 );
+ listExtra.append( cmdExtra2 );
+ listExtra.append( cmdExtra3 );
+ listExtra.append( cmdExtra4 );
+ listExtra.append( cmdExtra5 );
+ listExtra.append( cmdExtra6 );
+ listExtra.append( cmdExtra7 );
+}
+
+void RepeatEntry::slotNoEnd( bool unused )
+{
+ // if the item was toggled, then go ahead and set it to the maximum date
+ if ( unused ) {
+ end.setYMD( 3000, 12, 31 );
+ cmdEnd->setText( RepeatEntryBase::tr("No End Date") );
+ } else {
+ end = start;
+ cmdEnd->setText( TimeString::shortDate(end) );
+ }
+}
+
+void RepeatEntry::endDateChanged( int y, int m, int d )
+{
+ end.setYMD( y, m, d );
+ if ( end < start )
+ end = start;
+ cmdEnd->setText( TimeString::shortDate( end ) );
+ repeatPicker->setDate( end.year(), end.month(), end.day() );
+}
+
+void RepeatEntry::setupRepeatLabel( const QString &s )
+{
+ lblVar1->setText( s );
+}
+
+void RepeatEntry::setupRepeatLabel( int x )
+{
+ // change the spelling based on the value of x
+ QString strVar2;
+
+ if ( x > 1 )
+ lblVar1->show();
+ else
+ lblVar1->hide();
+
+ switch ( currInterval ) {
+ case NONE:
+ break;
+ case DAY:
+ if ( x > 1 )
+ strVar2 = tr( "days" );
+ else
+ strVar2 = tr( "day" );
+ break;
+ case WEEK:
+ if ( x > 1 )
+ strVar2 = tr( "weeks" );
+ else
+ strVar2 = tr( "week" );
+ break;
+ case MONTH:
+ if ( x > 1 )
+ strVar2 = RepeatEntryBase::tr( "months" );
+ else
+ strVar2 = tr( "month" );
+ break;
+ case YEAR:
+ if ( x > 1 )
+ strVar2 = RepeatEntryBase::tr( "years" );
+ else
+ strVar2 = tr( "year" );
+ break;
+ }
+ if ( !strVar2.isNull() )
+ lblVar2->setText( strVar2 );
+}
+
+void RepeatEntry::showRepeatStuff()
+{
+ cmdEnd->show();
+ chkNoEnd->show();
+ lblFreq->show();
+ lblEvery->show();
+ lblFreq->show();
+ spinFreq->show();
+ lblEnd->show();
+ lblRepeat->setText( RepeatEntryBase::tr("Every") );
+}
+
+void RepeatEntry::slotWeekLabel()
+{
+ QString str;
+ QListIterator<QToolButton> it( listExtra );
+ unsigned int i;
+ unsigned int keepMe;
+ bool bNeedCarriage = FALSE;
+ // don't do something we'll regret!!!
+ if ( currInterval != WEEK )
+ return;
+
+ if ( startWeekOnMonday )
+ keepMe = start.dayOfWeek() - 1;
+ else
+ keepMe = start.dayOfWeek() % 7;
+
+ QStringList list;
+ for ( i = 0; *it; ++it, i++ ) {
+ // a crazy check, if you are repeating weekly, the current day
+ // must be selected!!!
+ if ( i == keepMe && !( (*it)->isOn() ) )
+ (*it)->setOn( TRUE );
+ if ( (*it)->isOn() ) {
+ if ( startWeekOnMonday )
+ list.append( dayLabel[i] );
+ else {
+ if ( i == 0 )
+ list.append( dayLabel[6] );
+ else
+ list.append( dayLabel[i - 1] );
+ }
+ }
+ }
+ QStringList::Iterator itStr;
+ for ( i = 0, itStr = list.begin(); itStr != list.end(); ++itStr, i++ ) {
+ if ( i == 3 )
+ bNeedCarriage = TRUE;
+ else
+ bNeedCarriage = FALSE;
+ if ( str.isNull() )
+ str = *itStr;
+ else if ( i == list.count() - 1 ) {
+ if ( i < 2 )
+ str += tr(" and ") + *itStr;
+ else {
+ if ( bNeedCarriage )
+ str += tr( ",\nand " ) + *itStr;
+ else
+ str += tr( ", and " ) + *itStr;
+ }
+ } else {
+ if ( bNeedCarriage )
+ str += ",\n" + *itStr;
+ else
+ str += ", " + *itStr;
+ }
+ }
+ str = str.prepend( "on " );
+ lblWeekVar->setText( str );
+}
+
+void RepeatEntry::slotMonthLabel( int type )
+{
+ QString str;
+ if ( currInterval != MONTH || type > 1 )
+ return;
+ if ( type == 1 )
+ str = strMonthDateTemplate.arg( numberPlacing(start.day()) );
+ else
+ str = strMonthDayTemplate.arg( numberPlacing(week(start)))
+ .arg( dayLabel[start.dayOfWeek() - 1] );
+ lblRepeat->setText( str );
+}
+
+void RepeatEntry::slotChangeStartOfWeek( bool onMonday )
+{
+ startWeekOnMonday = onMonday;
+ // we need to make this unintrusive as possible...
+ int saveSpin = spinFreq->value();
+ char days = 0;
+ int day;
+ QListIterator<QToolButton> itExtra( listExtra );
+ for ( day = 1; *itExtra; ++itExtra, day = day << 1 ) {
+ if ( (*itExtra)->isOn() ) {
+ if ( !startWeekOnMonday )
+ days |= day;
+ else {
+ if ( day == 1 )
+ days |= Event::SUN;
+ else
+ days |= day >> 1;
+ }
+ }
+ }
+ setupWeekly();
+ spinFreq->setValue( saveSpin );
+ int buttons;
+ for ( day = 0x01, buttons = 0; buttons < 7;
+ day = day << 1, buttons++ ) {
+ if ( days & day ) {
+ if ( startWeekOnMonday )
+ fraExtra->setButton( buttons );
+ else {
+ if ( buttons == 7 )
+ fraExtra->setButton( 0 );
+ else
+ fraExtra->setButton( buttons + 1 );
+ }
+ }
+ }
+ slotWeekLabel();
+}
+
+static int week( const QDate &start )
+{
+ // figure out the week...
+ int stop = start.day(),
+ sentinel = start.dayOfWeek(),
+ dayOfWeek = QDate( start.year(), start.month(), 1 ).dayOfWeek(),
+ week = 1,
+ i;
+ for ( i = 1; i < stop; i++ ) {
+ if ( dayOfWeek++ == sentinel )
+ week++;
+ if ( dayOfWeek > 7 )
+ dayOfWeek = 0;
+ }
+ return week;
+}
+
+static QString numberPlacing( int x )
+{
+ // I hope this works in other languages besides english...
+ QString str = QString::number( x );
+ switch ( x % 10 ) {
+ case 1:
+ str += QWidget::tr( "st" );
+ break;
+ case 2:
+ str += QWidget::tr( "nd" );
+ break;
+ case 3:
+ str += QWidget::tr( "rd" );
+ break;
+ default:
+ str += QWidget::tr( "th" );
+ break;
+ }
+ return str;
+}
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 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef REPEATENTRY_H
+#define REPEATENTRY_H
+
+#include "repeatentrybase.h"
+
+#include <qpe/event.h>
+
+#include <qcheckbox.h>
+#include <qbuttongroup.h>
+#include <qdatetime.h>
+#include <qlist.h>
+#include <qtoolbutton.h>
+
+class DateBookMonth;
+
+class RepeatEntry : public RepeatEntryBase
+{
+ Q_OBJECT
+public:
+ RepeatEntry( bool startOnMonday,
+ const QDate &start, QWidget *parent = 0, const char *name = 0,
+ bool modal = TRUE, WFlags fl = 0 );
+ RepeatEntry( bool startOnMonday,
+ const Event::RepeatPattern &rp, const QDate &start,
+ QWidget *parent = 0, const char *name = 0, bool modal = TRUE,
+ WFlags fl = 0 );
+ ~RepeatEntry();
+
+ Event::RepeatPattern repeatPattern();
+ QDate endDate() { return end; };
+
+public slots:
+ void slotSetRType( int );
+ void endDateChanged( int, int, int );
+ void slotNoEnd( bool unused );
+
+private slots:
+ void setupRepeatLabel( const QString& );
+ void setupRepeatLabel( int );
+ void slotWeekLabel();
+ void slotMonthLabel( int );
+ void slotChangeStartOfWeek( bool onMonday );
+
+private:
+ void setupNone();
+ void setupDaily();
+ void setupWeekly();
+ void setupMonthly();
+ void setupYearly();
+
+ enum repeatButtons { NONE, DAY, WEEK, MONTH, YEAR };
+ void init();
+ inline void hideExtras();
+ void showRepeatStuff();
+
+ QList<QToolButton> listRTypeButtons;
+ QList<QToolButton> listExtra;
+ QDate start; // only used in one spot...
+ QDate end;
+ repeatButtons currInterval;
+ bool startWeekOnMonday;
+ DateBookMonth *repeatPicker;
+};
+
+inline void RepeatEntry::hideExtras()
+{
+ // hide the extra buttons...
+ fraExtra->hide();
+ chkNoEnd->hide();
+ QListIterator<QToolButton> it( listExtra );
+ for ( ; *it; ++it ) {
+ (*it)->hide();
+ (*it)->setOn( FALSE );
+ }
+
+}
+
+#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 @@
+<!DOCTYPE UI><UI>
+<class>RepeatEntryBase</class>
+<comment>*********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+** $Id$
+**
+*********************************************************************</comment>
+<widget>
+ <class>QDialog</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>RepeatEntryBase</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>250</width>
+ <height>309</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>Repeating Event </string>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>5</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>1</number>
+ </property>
+ <widget>
+ <class>QButtonGroup</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>fraType</cstring>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>NoFrame</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>Sunken</enum>
+ </property>
+ <property stdset="1">
+ <name>title</name>
+ <string></string>
+ </property>
+ <property stdset="1">
+ <name>exclusive</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>5</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>1</number>
+ </property>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdNone</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>None</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdDay</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Day</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdWeek</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>0</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Week</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdMonth</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>0</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Month</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdYear</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Year</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout4</cstring>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>lblEvery</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Every:</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QSpinBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>spinFreq</cstring>
+ </property>
+ <property stdset="1">
+ <name>minValue</name>
+ <number>1</number>
+ </property>
+ </widget>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>lblFreq</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>1</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Frequency</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout8</cstring>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>lblEnd</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>0</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>End On:</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdEnd</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>No End Date</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QCheckBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>chkNoEnd</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>No End Date</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget>
+ <class>QButtonGroup</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>fraExtra</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>Box</enum>
+ </property>
+ <property stdset="1">
+ <name>title</name>
+ <string>Repeat On</string>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>5</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>1</number>
+ </property>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdExtra1</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Mon</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdExtra2</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Tue</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdExtra3</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Wed</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdExtra4</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Thu</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdExtra5</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Fri</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdExtra6</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Sat</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdExtra7</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Sun</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget>
+ <class>QFrame</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Frame3</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>Box</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>Sunken</enum>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>5</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>1</number>
+ </property>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout6</cstring>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>0</number>
+ </property>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>lblRepeat</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>3</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Every</string>
+ </property>
+ <property stdset="1">
+ <name>alignment</name>
+ <set>AlignTop|AlignLeft</set>
+ </property>
+ <property>
+ <name>hAlign</name>
+ </property>
+ <property>
+ <name>vAlign</name>
+ </property>
+ </widget>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>lblVar1</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>1</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Var1</string>
+ </property>
+ <property stdset="1">
+ <name>alignment</name>
+ <set>AlignTop|AlignLeft</set>
+ </property>
+ <property>
+ <name>hAlign</name>
+ </property>
+ <property>
+ <name>vAlign</name>
+ </property>
+ </widget>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>lblVar2</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>1</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Var 2</string>
+ </property>
+ <property stdset="1">
+ <name>alignment</name>
+ <set>AlignTop|AlignRight</set>
+ </property>
+ <property>
+ <name>hAlign</name>
+ </property>
+ <property>
+ <name>vAlign</name>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>lblWeekVar</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>7</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>WeekVar</string>
+ </property>
+ <property stdset="1">
+ <name>alignment</name>
+ <set>AlignTop|AlignHCenter</set>
+ </property>
+ <property>
+ <name>hAlign</name>
+ </property>
+ <property>
+ <name>vAlign</name>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </vbox>
+</widget>
+<connections>
+ <connection>
+ <sender>chkNoEnd</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdEnd</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>chkNoEnd</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>RepeatEntryBase</receiver>
+ <slot>slotNoEnd(bool)</slot>
+ </connection>
+ <connection>
+ <sender>spinFreq</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>lblVar1</receiver>
+ <slot>setNum(int)</slot>
+ </connection>
+ <connection>
+ <sender>spinFreq</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>RepeatEntryBase</receiver>
+ <slot>setupRepeatLabel( int )</slot>
+ </connection>
+ <connection>
+ <sender>fraType</sender>
+ <signal>clicked(int)</signal>
+ <receiver>RepeatEntryBase</receiver>
+ <slot>slotSetRType( int )</slot>
+ </connection>
+ <connection>
+ <sender>fraExtra</sender>
+ <signal>clicked(int)</signal>
+ <receiver>RepeatEntryBase</receiver>
+ <slot>slotMonthLabel( int )</slot>
+ </connection>
+ <connection>
+ <sender>fraExtra</sender>
+ <signal>clicked(int)</signal>
+ <receiver>RepeatEntryBase</receiver>
+ <slot>slotWeekLabel()</slot>
+ </connection>
+ <slot access="public">setupRepeatLabel( const QString &amp; )</slot>
+ <slot access="public">setupRepeatLabel( int )</slot>
+ <slot access="public">slotMonthLabel( int )</slot>
+ <slot access="public">slotNoEnd(bool)</slot>
+ <slot access="public">slotSetRType( int )</slot>
+ <slot access="public">slotWeekLabel()</slot>
+</connections>
+</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 @@
+moc_*
+Makefile
+todoentry.h
+todoentry.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 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS)
+INCPATH = -I$(QPEDIR)/include
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = $(QPEDIR)/bin/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = todolist
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = mainwindow.h \
+ todotable.h \
+ todoentryimpl.h
+SOURCES = main.cpp \
+ mainwindow.cpp \
+ todotable.cpp \
+ todoentryimpl.cpp
+OBJECTS = main.o \
+ mainwindow.o \
+ todotable.o \
+ todoentryimpl.o \
+ todoentry.o
+INTERFACES = todoentry.ui
+UICDECLS = todoentry.h
+UICIMPLS = todoentry.cpp
+SRCMOC = moc_mainwindow.cpp \
+ moc_todotable.cpp \
+ moc_todoentryimpl.cpp \
+ moc_todoentry.cpp
+OBJMOC = moc_mainwindow.o \
+ moc_todotable.o \
+ moc_todoentryimpl.o \
+ moc_todoentry.o
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(TARGET)
+
+$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake todo.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+main.o: main.cpp \
+ mainwindow.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h
+
+mainwindow.o: mainwindow.cpp \
+ mainwindow.h \
+ todoentryimpl.h \
+ todoentry.h \
+ $(QPEDIR)/include/qpe/task.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h \
+ $(QPEDIR)/include/qpe/stringutil.h \
+ todotable.h \
+ $(QPEDIR)/include/qpe/categories.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ $(QPEDIR)/include/qpe/config.h \
+ $(QPEDIR)/include/qpe/finddialog.h \
+ $(QPEDIR)/include/qpe/global.h \
+ $(QPEDIR)/include/qpe/ir.h \
+ $(QPEDIR)/include/qpe/qpemenubar.h \
+ $(QPEDIR)/include/qpe/qpemessagebox.h \
+ $(QPEDIR)/include/qpe/resource.h \
+ $(QPEDIR)/include/qpe/qpetoolbar.h
+
+todotable.o: todotable.cpp \
+ todotable.h \
+ $(QPEDIR)/include/qpe/categories.h \
+ $(QPEDIR)/include/qpe/task.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h \
+ $(QPEDIR)/include/qpe/stringutil.h \
+ $(QPEDIR)/include/qpe/categoryselect.h \
+ $(QPEDIR)/include/qpe/xmlreader.h
+
+todoentryimpl.o: todoentryimpl.cpp \
+ todoentryimpl.h \
+ todoentry.h \
+ $(QPEDIR)/include/qpe/task.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h \
+ $(QPEDIR)/include/qpe/stringutil.h \
+ $(QPEDIR)/include/qpe/categoryselect.h \
+ $(QPEDIR)/include/qpe/datebookmonth.h \
+ $(QPEDIR)/include/qpe/event.h \
+ $(QPEDIR)/include/qpe/global.h \
+ $(QPEDIR)/include/qpe/imageedit.h \
+ $(QPEDIR)/include/qpe/timestring.h
+
+todoentry.h: todoentry.ui
+ $(UIC) todoentry.ui -o $(INTERFACE_DECL_PATH)/todoentry.h
+
+todoentry.cpp: todoentry.ui
+ $(UIC) todoentry.ui -i todoentry.h -o todoentry.cpp
+
+todoentry.o: todoentry.cpp \
+ todoentry.h \
+ todoentry.ui
+
+moc_mainwindow.o: moc_mainwindow.cpp \
+ mainwindow.h
+
+moc_todotable.o: moc_todotable.cpp \
+ todotable.h \
+ $(QPEDIR)/include/qpe/categories.h \
+ $(QPEDIR)/include/qpe/task.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h \
+ $(QPEDIR)/include/qpe/stringutil.h
+
+moc_todoentryimpl.o: moc_todoentryimpl.cpp \
+ todoentryimpl.h \
+ todoentry.h \
+ $(QPEDIR)/include/qpe/task.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h \
+ $(QPEDIR)/include/qpe/stringutil.h
+
+moc_todoentry.o: moc_todoentry.cpp \
+ todoentry.h
+
+moc_mainwindow.cpp: mainwindow.h
+ $(MOC) mainwindow.h -o moc_mainwindow.cpp
+
+moc_todotable.cpp: todotable.h
+ $(MOC) todotable.h -o moc_todotable.cpp
+
+moc_todoentryimpl.cpp: todoentryimpl.h
+ $(MOC) todoentryimpl.h -o moc_todoentryimpl.cpp
+
+moc_todoentry.cpp: todoentry.h
+ $(MOC) todoentry.h -o moc_todoentry.cpp
+
+
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 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "mainwindow.h"
+
+#include <qpe/qpeapplication.h>
+
+int main( int argc, char **argv )
+{
+ QPEApplication a( argc, argv );
+
+ TodoWindow mw;
+ QObject::connect( &a, SIGNAL( flush() ), &mw, SLOT( flush() ) );
+ QObject::connect( &a, SIGNAL( reload() ), &mw, SLOT( reload() ) );
+
+ a.showMainWidget(&mw);
+
+ return a.exec();
+}
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 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "mainwindow.h"
+#include "todoentryimpl.h"
+#include "todotable.h"
+
+#include <qpe/qpeapplication.h>
+#include <qpe/config.h>
+#include <qpe/finddialog.h>
+#include <qpe/global.h>
+#include <qpe/ir.h>
+#include <qpe/qpemenubar.h>
+#include <qpe/qpemessagebox.h>
+#include <qpe/resource.h>
+#include <qpe/task.h>
+#include <qpe/qpetoolbar.h>
+
+#include <qaction.h>
+#include <qarray.h>
+#include <qdatastream.h>
+#include <qdatetime.h>
+#include <qfile.h>
+#include <qmessagebox.h>
+#include <qpopupmenu.h>
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <stdlib.h>
+
+static QString todolistXMLFilename()
+{
+ return Global::applicationFileName("todolist","todolist.xml");
+}
+
+static QString categoriesXMLFilename()
+{
+ return Global::applicationFileName("todolist","categories.xml");
+}
+
+TodoWindow::TodoWindow( QWidget *parent, const char *name, WFlags f = 0 ) :
+ QMainWindow( parent, name, f ), syncing(FALSE)
+{
+// QTime t;
+// t.start();
+
+ setCaption( tr("Todo") );
+ QString str;
+ table = new TodoTable( this );
+ table->setColumnWidth( 2, 10 );
+ table->setPaintingEnabled( FALSE );
+ table->setUpdatesEnabled( FALSE );
+ table->viewport()->setUpdatesEnabled( FALSE );
+
+ {
+ str = todolistXMLFilename();
+ if ( str.isNull() )
+ QMessageBox::critical( this,
+ tr("Out of Space"),
+ tr("Unable to create startup files\n"
+ "Free up some space\n"
+ "before you enter any data") );
+ else
+ table->load( str );
+ }
+
+ // repeat for categories...
+ str = categoriesXMLFilename();
+ if ( str.isNull() )
+ QMessageBox::critical( this,
+ tr( "Out of Space" ),
+ tr( "Unable to create startup files\n"
+ "Free up some space\n"
+ "before you enter any data") );
+
+ setCentralWidget( table );
+ setToolBarsMovable( FALSE );
+
+// qDebug("after load: t=%d", t.elapsed() );
+
+ Config config( "todo" );
+ config.setGroup( "View" );
+ bool complete = config.readBoolEntry( "ShowComplete", true );
+ table->setShowCompleted( complete );
+ QString category = config.readEntry( "Category", QString::null );
+ table->setShowCategory( category );
+
+ QPEToolBar *bar = new QPEToolBar( this );
+ bar->setHorizontalStretchable( TRUE );
+
+ QPEMenuBar *mb = new QPEMenuBar( bar );
+
+ catMenu = new QPopupMenu( this );
+ QPopupMenu *edit = new QPopupMenu( this );
+ contextMenu = new QPopupMenu( this );
+
+ bar = new QPEToolBar( this );
+
+ QAction *a = new QAction( tr( "New Task" ), Resource::loadPixmap( "new" ),
+ QString::null, 0, this, 0 );
+ connect( a, SIGNAL( activated() ),
+ this, SLOT( slotNew() ) );
+ a->addTo( bar );
+ a->addTo( edit );
+ a = new QAction( tr( "Edit" ), Resource::loadIconSet( "edit" ),
+ QString::null, 0, this, 0 );
+ connect( a, SIGNAL( activated() ),
+ this, SLOT( slotEdit() ) );
+ a->addTo( bar );
+ a->addTo( edit );
+ a->addTo( contextMenu );
+ a->setEnabled( FALSE );
+ editAction = a;
+ a = new QAction( tr( "Delete" ), Resource::loadIconSet( "trash" ),
+ QString::null, 0, this, 0 );
+ connect( a, SIGNAL( activated() ),
+ this, SLOT( slotDelete() ) );
+ a->addTo( bar );
+ a->addTo( edit );
+ a->addTo( contextMenu );
+ a->setEnabled( FALSE );
+ deleteAction = a;
+
+ if ( Ir::supported() ) {
+ a = new QAction( tr( "Beam" ), Resource::loadPixmap( "beam" ),
+ QString::null, 0, this, 0 );
+ connect( a, SIGNAL( activated() ),
+ this, SLOT( slotBeam() ) );
+ a->addTo( edit );
+ a->addTo( bar );
+ }
+
+ a = new QAction( tr( "Find" ), Resource::loadIconSet( "mag" ),
+ QString::null, 0, this, 0 );
+ connect( a, SIGNAL( activated() ),
+ this, SLOT( slotFind() ) );
+ a->addTo( bar );
+ a->addTo( edit );
+ if ( table->numRows() )
+ a->setEnabled( TRUE );
+ else
+ a->setEnabled( FALSE );
+
+ //a->setEnabled( FALSE );
+ findAction = a;
+// qDebug("mainwindow #2: t=%d", t.elapsed() );
+
+ completedAction = new QAction( QString::null, tr("Completed tasks"), 0, this, 0, TRUE );
+
+ catMenu->setCheckable( true );
+ populateCategories();
+
+ mb->insertItem( tr( "Task" ), edit );
+ mb->insertItem( tr( "View" ), catMenu );
+
+ resize( 200, 300 );
+ if ( table->numRows() > 0 )
+ currentEntryChanged( 0, 0 );
+ connect( table, SIGNAL( signalEdit() ),
+ this, SLOT( slotEdit() ) );
+ connect( table, SIGNAL(signalShowMenu(const QPoint &)),
+ this, SLOT( slotShowPopup(const QPoint &)) );
+
+// qDebug("mainwindow #3: t=%d", t.elapsed() );
+ table->updateVisible();
+ table->setUpdatesEnabled( TRUE );
+ table->setPaintingEnabled( TRUE );
+ table->viewport()->setUpdatesEnabled( TRUE );
+
+ connect( completedAction, SIGNAL( toggled(bool) ), this, SLOT( showCompleted(bool) ) );
+ connect( catMenu, SIGNAL(activated(int)), this, SLOT(setCategory(int)) );
+ connect( table, SIGNAL( currentChanged( int, int ) ),
+ this, SLOT( currentEntryChanged( int, int ) ) );
+
+// qDebug("done: t=%d", t.elapsed() );
+}
+
+void TodoWindow::slotNew()
+{
+ if(syncing) {
+ QMessageBox::warning(this, tr("Todo"),
+ tr("Can not edit data, currently syncing"));
+ return;
+ }
+
+ int id;
+ id = -1;
+ QArray<int> ids;
+ ids = table->currentEntry().categories();
+ if ( ids.count() )
+ id = ids[0];
+ NewTaskDialog e( id, this, 0, TRUE );
+
+ Task todo;
+
+#if defined(Q_WS_QWS) || defined(_WS_QWS_)
+ e.showMaximized();
+#endif
+ int ret = e.exec();
+
+ if ( ret == QDialog::Accepted ) {
+ table->setPaintingEnabled( false );
+ todo = e.todoEntry();
+ todo.assignUid();
+ table->addEntry( todo );
+ table->setPaintingEnabled( true );
+ findAction->setEnabled( TRUE );
+ }
+ // I'm afraid we must call this every time now, otherwise
+ // spend expensive time comparing all these strings...
+ populateCategories();
+}
+
+TodoWindow::~TodoWindow()
+{
+}
+
+void TodoWindow::slotDelete()
+{
+ if(syncing) {
+ QMessageBox::warning(this, tr("Todo"),
+ tr("Can not edit data, currently syncing"));
+ return;
+ }
+
+ if ( table->currentRow() == -1 )
+ return;
+
+ QString strName = table->text( table->currentRow(), 2 ).left( 30 );
+
+ if ( !QPEMessageBox::confirmDelete( this, tr( "Todo" ), strName ) )
+ return;
+
+
+
+ table->setPaintingEnabled( false );
+ table->removeCurrentEntry();
+ table->setPaintingEnabled( true );
+
+ if ( table->numRows() == 0 ) {
+ currentEntryChanged( -1, 0 );
+ findAction->setEnabled( FALSE );
+ }
+}
+
+void TodoWindow::slotEdit()
+{
+ if(syncing) {
+ QMessageBox::warning(this, tr("Todo"),
+ tr("Can not edit data, currently syncing"));
+ return;
+ }
+
+ Task todo = table->currentEntry();
+
+ NewTaskDialog e( todo, this, 0, TRUE );
+ e.setCaption( tr( "Edit Task" ) );
+
+#if defined(Q_WS_QWS) || defined(_WS_QWS_)
+ e.showMaximized();
+#endif
+ int ret = e.exec();
+
+ if ( ret == QDialog::Accepted ) {
+ table->setPaintingEnabled( false );
+ todo = e.todoEntry();
+ table->replaceCurrentEntry( todo );
+ table->setPaintingEnabled( true );
+ }
+ populateCategories();
+
+}
+
+void TodoWindow::slotShowPopup( const QPoint &p )
+{
+ contextMenu->popup( p );
+}
+
+void TodoWindow::showCompleted( bool s )
+{
+ if ( !table->isUpdatesEnabled() )
+ return;
+ table->setPaintingEnabled( false );
+ table->setShowCompleted( s );
+ table->setPaintingEnabled( true );
+}
+
+void TodoWindow::currentEntryChanged( int r, int )
+{
+ if ( r != -1 && table->rowHeight( r ) > 0 ) {
+ editAction->setEnabled( TRUE );
+ deleteAction->setEnabled( TRUE );
+ } else {
+ editAction->setEnabled( FALSE );
+ deleteAction->setEnabled( FALSE );
+ }
+}
+
+void TodoWindow::setCategory( int c )
+{
+ if ( c <= 0 ) return;
+ if ( !table->isUpdatesEnabled() )
+ return;
+ table->setPaintingEnabled( false );
+ for ( unsigned int i = 1; i < catMenu->count(); i++ )
+ catMenu->setItemChecked( i, c == (int)i );
+ if ( c == 1 ) {
+ table->setShowCategory( QString::null );
+ setCaption( tr("Todo") + " - " + tr( "All" ) );
+ } else if ( c == (int)catMenu->count() - 1 ) {
+ table->setShowCategory( tr( "Unfiled" ) );
+ setCaption( tr("Todo") + " - " + tr( "Unfiled" ) );
+ } else {
+ QString cat = table->categories()[c - 2];
+ table->setShowCategory( cat );
+ setCaption( tr("Todo") + " - " + cat );
+ }
+ table->setPaintingEnabled( true );
+}
+
+void TodoWindow::populateCategories()
+{
+ catMenu->clear();
+
+ completedAction->addTo( catMenu );
+ completedAction->setOn( table->showCompleted() );
+
+ int id,
+ rememberId;
+ id = 1;
+ catMenu->insertItem( tr( "All" ), id++ );
+// catMenu->insertSeparator();
+ QStringList categories = table->categories();
+ categories.append( tr( "Unfiled" ) );
+ for ( QStringList::Iterator it = categories.begin();
+ it != categories.end(); ++it ) {
+ catMenu->insertItem( *it, id );
+ if ( *it == table->showCategory() )
+ rememberId = id;
+ ++id;
+ }
+ if ( table->showCategory().isEmpty() )
+ setCategory( 1 );
+ else
+ setCategory( rememberId );
+}
+
+void TodoWindow::reload()
+{
+ table->clear();
+ table->load( todolistXMLFilename() );
+ syncing = FALSE;
+}
+
+void TodoWindow::flush()
+{
+ syncing = TRUE;
+ table->save( todolistXMLFilename() );
+}
+
+void TodoWindow::closeEvent( QCloseEvent *e )
+{
+ if(syncing) {
+ /* no need to save if in the middle of syncing */
+ e->accept();
+ return;
+ }
+
+ if ( table->save( todolistXMLFilename() ) ) {
+ e->accept();
+ // repeat for categories...
+ // if writing configs fail, it will emit an
+ // error, but I feel that it is "ok" for us to exit
+ // espically since we aren't told if the write succeeded...
+ Config config( "todo" );
+ config.setGroup( "View" );
+ config.writeEntry( "ShowComplete", table->showCompleted() );
+ config.writeEntry( "Category", table->showCategory() );
+ } else {
+ if ( QMessageBox::critical( this, tr("Out of space"),
+ tr("Todo was unable\n"
+ "to save your changes.\n"
+ "Free up some space\n"
+ "and try again.\n"
+ "\nQuit Anyway?"),
+ QMessageBox::Yes|QMessageBox::Escape,
+ QMessageBox::No|QMessageBox::Default)
+ != QMessageBox::No )
+ e->accept();
+ else
+ e->ignore();
+ }
+}
+
+void TodoWindow::slotFind()
+{
+ // put everything back to view all for searching...
+ if ( !catMenu->isItemChecked( 0 ) )
+ setCategory( 0 );
+
+ FindDialog dlg( "Todo List", this );
+ QObject::connect( &dlg,
+ SIGNAL(signalFindClicked(const QString &,
+ bool, bool, int)),
+ table,
+ SLOT(slotDoFind(const QString&, bool, bool, int)) );
+ QObject::connect( table, SIGNAL(signalNotFound()), &dlg,
+ SLOT(slotNotFound()) );
+ QObject::connect( table, SIGNAL(signalWrapAround()), &dlg,
+ SLOT(slotWrapAround()) );
+ dlg.exec();
+ if ( table->numSelections() )
+ table->clearSelection();
+ table->clearFindRow();
+}
+
+
+void TodoWindow::setDocument( const QString &filename )
+{
+ if ( filename.find(".vcs") != int(filename.length()) - 4 ) return;
+
+ QValueList<Task> tl = Task::readVCalendar( filename );
+ for( QValueList<Task>::Iterator it = tl.begin(); it != tl.end(); ++it ) {
+ table->addEntry( *it );
+ }
+}
+
+static const char * beamfile = "/tmp/obex/todo.vcs";
+
+void TodoWindow::slotBeam()
+{
+ unlink( beamfile ); // delete if exists
+ Task c = table->currentEntry();
+ mkdir("/tmp/obex/", 0755);
+ Task::writeVCalendar( beamfile, c );
+ Ir *ir = new Ir( this );
+ connect( ir, SIGNAL( done( Ir * ) ), this, SLOT( beamDone( Ir * ) ) );
+ QString description = c.description();
+ ir->send( beamfile, description, "text/x-vCalendar" );
+}
+
+void TodoWindow::beamDone( Ir *ir )
+{
+ delete ir;
+ unlink( beamfile );
+}
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 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <qmainwindow.h>
+
+class TodoTable;
+class QAction;
+class QPopupMenu;
+class Ir;
+
+class TodoWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ TodoWindow( QWidget *parent = 0, const char *name = 0, WFlags f = 0 );
+ ~TodoWindow();
+
+public slots:
+ void flush();
+ void reload();
+
+protected slots:
+ void slotNew();
+ void slotDelete();
+ void slotEdit();
+ void slotShowPopup( const QPoint & );
+ void showCompleted( bool );
+ void currentEntryChanged( int r, int c );
+ void setCategory( int );
+ void slotFind();
+ void setDocument( const QString & );
+ void slotBeam();
+ void beamDone( Ir * );
+
+protected:
+ void closeEvent( QCloseEvent *e );
+
+private:
+ void populateCategories();
+
+private:
+ TodoTable *table;
+ QAction *editAction,
+ *deleteAction,
+ *findAction,
+ * completedAction;
+ QPopupMenu *contextMenu, *catMenu;
+
+ bool syncing;
+};
+
+#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 @@
+Files: bin/todolist apps/Applications/todo.desktop
+Priority: optional
+Section: qpe/applications
+Maintainer: Warwick Allison <warwick@trolltech.com>
+Architecture: arm
+Version: $QPE_VERSION-3
+Depends: qpe-base ($QPE_VERSION)
+Description: TODO-list manager
+ 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 @@
+TEMPLATE = app
+CONFIG = qt warn_on release
+DESTDIR = $(QPEDIR)/bin
+HEADERS = mainwindow.h \
+ todotable.h \
+ todoentryimpl.h
+SOURCES = main.cpp \
+ mainwindow.cpp \
+ todotable.cpp \
+ todoentryimpl.cpp
+
+INTERFACES = todoentry.ui
+
+TARGET = todolist
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += $(QPEDIR)/include
+LIBS += -lqpe
+
+TRANSLATIONS = ../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 @@
+<!DOCTYPE UI><UI>
+<class>NewTaskDialogBase</class>
+<comment>*********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+*********************************************************************</comment>
+<widget>
+ <class>QDialog</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>NewTaskDialogBase</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>249</width>
+ <height>321</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>New Task</string>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>0</number>
+ </property>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout4</cstring>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel2</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Priority:</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QComboBox</class>
+ <item>
+ <property>
+ <name>text</name>
+ <string>1 - Very High</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>2 - High</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>3 - Normal</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>4 - Low</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>5 - Very Low</string>
+ </property>
+ </item>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>comboPriority</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>currentItem</name>
+ <number>2</number>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout3</cstring>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel3</cstring>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>NoFrame</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Category:</string>
+ </property>
+ </widget>
+ <widget>
+ <class>CategorySelect</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>comboCategory</cstring>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout4</cstring>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QCheckBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>checkCompleted</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&amp;Completed</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QCheckBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>checkDate</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>D&amp;ue</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>buttonDate</cstring>
+ </property>
+ <property stdset="1">
+ <name>enabled</name>
+ <bool>false</bool>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>1 Jan 2001</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget>
+ <class>QMultiLineEdit</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>txtTodo</cstring>
+ </property>
+ </widget>
+ </vbox>
+</widget>
+<customwidgets>
+ <customwidget>
+ <class>CategorySelect</class>
+ <header location="global">qpe/categoryselect.h</header>
+ <sizehint>
+ <width>-1</width>
+ <height>-1</height>
+ </sizehint>
+ <container>0</container>
+ <sizepolicy>
+ <hordata>7</hordata>
+ <verdata>1</verdata>
+ </sizepolicy>
+ <pixmap>image0</pixmap>
+ </customwidget>
+</customwidgets>
+<images>
+ <image>
+ <name>image0</name>
+ <data format="XPM.GZ" length="646">789c6dd2c10ac2300c00d07bbf2234b7229d1be245fc04c5a3201e4615f430059d0711ff5ddb2e6bb236ec90eed134cb5a19d8ef36602af5ecdbfeeac05dda0798d3abebde87e3faa374d3807fa0d633a52d38d8de6f679fe33fc776e196f53cd010188256a3600a292882096246517815ca99884606e18044a3a40d91824820924265a7923a2e8bcd05f33db1173e002913175f2a6be6d3294871a2d95fa00e8a94ee017b69d339d90df1e77c57ea072ede6758</data>
+ </image>
+</images>
+<connections>
+ <connection>
+ <sender>checkDate</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>buttonDate</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <slot access="protected">dateChanged( const QString &amp; )</slot>
+ <slot access="protected">dateChanged( int, int, int )</slot>
+</connections>
+</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 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "todoentryimpl.h"
+
+#include <qpe/categoryselect.h>
+#include <qpe/datebookmonth.h>
+#include <qpe/global.h>
+#include <qpe/imageedit.h>
+#include <qpe/task.h>
+#include <qpe/timestring.h>
+
+#include <qmessagebox.h>
+#include <qpopupmenu.h>
+#include <qtoolbutton.h>
+#include <qcombobox.h>
+#include <qcheckbox.h>
+#include <qlineedit.h>
+#include <qmultilineedit.h>
+#include <qlabel.h>
+#include <qtimer.h>
+#include <qapplication.h>
+
+
+NewTaskDialog::NewTaskDialog( const Task& task, QWidget *parent,
+ const char *name, bool modal, WFlags fl )
+ : NewTaskDialogBase( parent, name, modal, fl ),
+ todo( task )
+{
+ todo.setCategories( task.categories() );
+ if ( todo.hasDueDate() )
+ date = todo.dueDate();
+ else
+ date = QDate::currentDate();
+
+ init();
+ comboPriority->setCurrentItem( task.priority() - 1 );
+
+ checkCompleted->setChecked( task.isCompleted() );
+ checkDate->setChecked( task.hasDueDate() );
+ buttonDate->setText( TimeString::longDateString( date ) );
+
+ txtTodo->setText( task.description() );
+}
+
+/*
+ * Constructs a NewTaskDialog which is a child of 'parent', with the
+ * name 'name' and widget flags set to 'f'
+ *
+ * The dialog will by default be modeless, unless you set 'modal' to
+ * TRUE to construct a modal dialog.
+ */
+NewTaskDialog::NewTaskDialog( int id, QWidget* parent, const char* name, bool modal,
+ WFlags fl )
+ : NewTaskDialogBase( parent, name, modal, fl ),
+ date( QDate::currentDate() )
+{
+ if ( id != -1 ) {
+ QArray<int> ids( 1 );
+ ids[0] = id;
+ todo.setCategories( ids );
+ }
+ init();
+}
+
+void NewTaskDialog::init()
+{
+ QPopupMenu *m1 = new QPopupMenu( this );
+ picker = new DateBookMonth( m1, 0, TRUE );
+ m1->insertItem( picker );
+ buttonDate->setPopup( m1 );
+ comboCategory->setCategories( todo.categories(), "Todo List", tr("Todo List") );
+
+ connect( picker, SIGNAL( dateClicked( int, int, int ) ),
+ this, SLOT( dateChanged( int, int, int ) ) );
+
+ buttonDate->setText( TimeString::longDateString( date ) );
+ picker->setDate( date.year(), date.month(), date.day() );
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+NewTaskDialog::~NewTaskDialog()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+void NewTaskDialog::dateChanged( int y, int m, int d )
+{
+ date = QDate( y, m, d );
+ buttonDate->setText( TimeString::longDateString( date ) );
+}
+
+/*!
+*/
+
+Task NewTaskDialog::todoEntry()
+{
+ todo.setDueDate( date, checkDate->isChecked() );
+ if ( comboCategory->currentCategory() != -1 ) {
+ todo.setCategories( comboCategory->currentCategories() );
+ }
+ todo.setPriority( comboPriority->currentItem() + 1 );
+ todo.setCompleted( checkCompleted->isChecked() );
+
+ todo.setDescription( txtTodo->text() );
+
+ return todo;
+}
+
+
+/*!
+
+*/
+
+void NewTaskDialog::accept()
+{
+ QString strText = txtTodo->text();
+ if ( !strText || strText == "") {
+ // hmm... just decline it then, the user obviously didn't care about it
+ QDialog::reject();
+ return;
+ }
+ QDialog::accept();
+}
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 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef NEWTASKDIALOG_H
+#define NEWTASKDIALOG_H
+
+#include "todoentry.h"
+
+#include <qpe/task.h>
+
+#include <qdatetime.h>
+#include <qpalette.h>
+
+class QLabel;
+class QTimer;
+class DateBookMonth;
+
+class NewTaskDialog : public NewTaskDialogBase
+{
+ Q_OBJECT
+
+public:
+ NewTaskDialog( const Task &task, QWidget *parent = 0, const char* name = 0,
+ bool modal = FALSE, WFlags fl = 0 );
+ NewTaskDialog( int id, QWidget* parent = 0, const char* name = 0,
+ bool modal = FALSE, WFlags fl = 0 );
+ ~NewTaskDialog();
+
+ Task todoEntry();
+
+protected slots:
+ void dateChanged( int y, int m, int d );
+
+protected:
+ virtual void accept();
+
+private:
+ void init();
+ Task todo;
+ QDate date;
+ DateBookMonth *picker;
+};
+
+#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 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "todotable.h"
+
+#include <qpe/categoryselect.h>
+#include <qpe/xmlreader.h>
+
+#include <qasciidict.h>
+#include <qcombobox.h>
+#include <qfile.h>
+#include <qpainter.h>
+#include <qtextcodec.h>
+#include <qtimer.h>
+#include <qdatetime.h>
+
+#include <qcursor.h>
+#include <qregexp.h>
+
+#include <errno.h>
+#include <stdlib.h>
+
+
+
+static bool taskCompare( const Task &task, const QRegExp &r, int category );
+
+static QString journalFileName();
+
+CheckItem::CheckItem( QTable *t, const QString &key )
+ : QTableItem( t, Never, "" ), checked( FALSE ), sortKey( key )
+{
+}
+
+QString CheckItem::key() const
+{
+ return sortKey;
+}
+
+void CheckItem::setChecked( bool b )
+{
+ checked = b;
+ table()->updateCell( row(), col() );
+}
+
+void CheckItem::toggle()
+{
+ TodoTable *parent = static_cast<TodoTable*>(table());
+ Task newTodo = parent->currentEntry();
+ checked = !checked;
+ newTodo.setCompleted( checked );
+ table()->updateCell( row(), col() );
+ parent->replaceCurrentEntry( newTodo, true );
+}
+
+bool CheckItem::isChecked() const
+{
+ return checked;
+}
+
+static const int BoxSize = 10;
+
+void CheckItem::paint( QPainter *p, const QColorGroup &cg, const QRect &cr,
+ bool )
+{
+ p->fillRect( 0, 0, cr.width(), cr.height(), cg.brush( QColorGroup::Base ) );
+
+ int marg = ( cr.width() - BoxSize ) / 2;
+ int x = 0;
+ int y = ( cr.height() - BoxSize ) / 2;
+ p->setPen( QPen( cg.text() ) );
+ p->drawRect( x + marg, y, BoxSize, BoxSize );
+ p->drawRect( x + marg+1, y+1, BoxSize-2, BoxSize-2 );
+ p->setPen( darkGreen );
+ x += 1;
+ y += 1;
+ if ( checked ) {
+ QPointArray a( 7*2 );
+ int i, xx, yy;
+ xx = x+1+marg;
+ yy = y+2;
+ for ( i=0; i<3; i++ ) {
+ a.setPoint( 2*i, xx, yy );
+ a.setPoint( 2*i+1, xx, yy+2 );
+ xx++; yy++;
+ }
+ yy -= 2;
+ for ( i=3; i<7; i++ ) {
+ a.setPoint( 2*i, xx, yy );
+ a.setPoint( 2*i+1, xx, yy+2 );
+ xx++; yy--;
+ }
+ p->drawLineSegments( a );
+ }
+}
+
+
+ComboItem::ComboItem( QTable *t, EditType et )
+ : QTableItem( t, et, "3" ), cb( 0 )
+{
+ setReplaceable( FALSE );
+}
+
+QWidget *ComboItem::createEditor() const
+{
+ QString txt = text();
+ ( (ComboItem*)this )->cb = new QComboBox( table()->viewport() );
+ cb->insertItem( "1" );
+ cb->insertItem( "2" );
+ cb->insertItem( "3" );
+ cb->insertItem( "4" );
+ cb->insertItem( "5" );
+ cb->setCurrentItem( txt.toInt() - 1 );
+ return cb;
+}
+
+void ComboItem::setContentFromEditor( QWidget *w )
+{
+ TodoTable *parent = static_cast<TodoTable*>(table());
+ Task newTodo = parent->currentEntry();
+
+ if ( w->inherits( "QComboBox" ) )
+ setText( ( (QComboBox*)w )->currentText() );
+ else
+ QTableItem::setContentFromEditor( w );
+ newTodo.setPriority( text().toInt() );
+ parent->replaceCurrentEntry( newTodo, true );
+}
+
+void ComboItem::setText( const QString &s )
+{
+ if ( cb )
+ cb->setCurrentItem( s.toInt() - 1 );
+ QTableItem::setText( s );
+}
+
+QString ComboItem::text() const
+{
+ if ( cb )
+ return cb->currentText();
+ return QTableItem::text();
+}
+
+
+
+TodoTable::TodoTable( QWidget *parent, const char *name )
+// #ifdef QT_QTABLE_NOHEADER_CONSTRUCTOR
+// : QTable( 0, 3, parent, name, TRUE ),
+// #else
+ : QTable( 0, 3, parent, name ),
+// #endif
+ showComp( true ),
+ enablePainting( true ),
+ mCat( 0 ),
+ currFindRow( -2 )
+{
+ mCat.load( categoryFileName() );
+ setSorting( TRUE );
+ setSelectionMode( NoSelection );
+ setColumnStretchable( 2, TRUE );
+ setColumnWidth( 0, 20 );
+ setColumnWidth( 1, 35 );
+ setLeftMargin( 0 );
+ verticalHeader()->hide();
+ horizontalHeader()->setLabel( 0, tr( "C." ) );
+ horizontalHeader()->setLabel( 1, tr( "Prior." ) );
+ horizontalHeader()->setLabel( 2, tr( "Description" ) );
+ connect( this, SIGNAL( clicked( int, int, int, const QPoint & ) ),
+ this, SLOT( slotClicked( int, int, int, const QPoint & ) ) );
+ connect( this, SIGNAL( pressed( int, int, int, const QPoint & ) ),
+ this, SLOT( slotPressed( int, int, int, const QPoint & ) ) );
+ connect( this, SIGNAL( valueChanged( int, int ) ),
+ this, SLOT( slotCheckPriority( int, int ) ) );
+ connect( this, SIGNAL( currentChanged( int, int ) ),
+ this, SLOT( slotCurrentChanged( int, int ) ) );
+
+ menuTimer = new QTimer( this );
+ connect( menuTimer, SIGNAL(timeout()), this, SLOT(slotShowMenu()) );
+}
+
+void TodoTable::addEntry( const Task &todo )
+{
+ int row = numRows();
+ setNumRows( row + 1 );
+ updateJournal( todo, ACTION_ADD );
+ insertIntoTable( new Task(todo), row );
+ setCurrentCell(row, currentColumn());
+ updateVisible();
+}
+
+void TodoTable::slotClicked( int row, int col, int, const QPoint &pos )
+{
+ if ( !cellGeometry( row, col ).contains(pos) )
+ return;
+ // let's switch on the column number...
+ switch ( col )
+ {
+ case 0: {
+ CheckItem *i = static_cast<CheckItem*>(item( row, col ));
+ if ( i ) {
+ int x = pos.x() - columnPos( col );
+ int y = pos.y() - rowPos( row );
+ int w = columnWidth( col );
+ int h = rowHeight( row );
+ if ( i && x >= ( w - BoxSize ) / 2 && x <= ( w - BoxSize ) / 2 + BoxSize &&
+ y >= ( h - BoxSize ) / 2 && y <= ( h - BoxSize ) / 2 + BoxSize ) {
+ i->toggle();
+ }
+ emit signalDoneChanged( i->isChecked() );
+ }
+ }
+ break;
+ case 1:
+ break;
+ case 2:
+ // may as well edit it...
+ menuTimer->stop();
+// emit signalEdit();
+ break;
+ }
+}
+
+void TodoTable::slotPressed( int row, int col, int, const QPoint &pos )
+{
+ if ( col == 2 && cellGeometry( row, col ).contains(pos) )
+ menuTimer->start( 750, TRUE );
+}
+
+void TodoTable::slotShowMenu()
+{
+ emit signalShowMenu( QCursor::pos() );
+}
+
+void TodoTable::slotCurrentChanged( int, int )
+{
+ menuTimer->stop();
+}
+
+void TodoTable::internalAddEntries( QList<Task> &list )
+{
+ setNumRows( list.count() );
+ int row = 0;
+ Task *it;
+ for ( it = list.first(); it; it = list.next() )
+ insertIntoTable( it, row++ );
+}
+
+
+Task TodoTable::currentEntry() const
+{
+ QTableItem *i = item( currentRow(), 0 );
+ if ( !i || rowHeight( currentRow() ) <= 0 )
+ return Task();
+ Task *todo = todoList[(CheckItem*)i];
+ todo->setCompleted( ( (CheckItem*)item( currentRow(), 0 ) )->isChecked() );
+ todo->setPriority( ( (ComboItem*)item( currentRow(), 1 ) )->text().toInt() );
+ return *todo;
+}
+
+void TodoTable::replaceCurrentEntry( const Task &todo, bool fromTableItem )
+{
+ int row = currentRow();
+ updateJournal( todo, ACTION_REPLACE, row );
+
+ if ( !fromTableItem ) {
+ journalFreeReplaceEntry( todo, row );
+ updateVisible();
+ }
+}
+
+void TodoTable::removeCurrentEntry()
+{
+ Task *oldTodo;
+ int row = currentRow();
+ CheckItem *chk;
+
+ chk = static_cast<CheckItem*>(item(row, 0 ));
+ if ( !chk )
+ return;
+ oldTodo = todoList[chk];
+ todoList.remove( chk );
+ oldTodo->setCompleted( chk->isChecked() );
+ oldTodo->setPriority( static_cast<ComboItem*>(item(row, 1))->text().toInt() );
+ realignTable( row );
+ updateVisible();
+ updateJournal( *oldTodo, ACTION_REMOVE, row );
+ delete oldTodo;
+}
+
+
+bool TodoTable::save( const QString &fn )
+{
+ QString strNewFile = fn + ".new";
+ QFile f( strNewFile );
+ if ( !f.open( IO_WriteOnly|IO_Raw ) )
+ return false;
+
+ QString buf("<!DOCTYPE Tasks>\n<Tasks>\n");
+ QCString str;
+ int total_written;
+
+ for ( QMap<CheckItem*, Task *>::Iterator it = todoList.begin();
+ it != todoList.end(); ++it ) {
+ if ( !item( it.key()->row(), 0 ) )
+ continue;
+ Task *todo = *it;
+ // sync item with table
+ todo->setCompleted( ((CheckItem*)item(it.key()->row(), 0))->isChecked() );
+ todo->setPriority( ((ComboItem*)item( it.key()->row(), 1))->text().toInt() );
+ buf += "<Task";
+ todo->save( buf );
+ buf += " />\n";
+ str = buf.utf8();
+ total_written = f.writeBlock( str.data(), str.length() );
+ if ( total_written != int(str.length()) ) {
+ f.close();
+ QFile::remove( strNewFile );
+ return false;
+ }
+ buf = "";
+ }
+
+ buf += "</Tasks>\n";
+ str = buf.utf8();
+ total_written = f.writeBlock( str.data(), str.length() );
+ if ( total_written != int(str.length()) ) {
+ f.close();
+ QFile::remove( strNewFile );
+ return false;
+ }
+ f.close();
+
+ // now do the rename
+ if ( ::rename( strNewFile, fn ) < 0 )
+ qWarning( "problem renaming file %s to %s errno %d",
+ strNewFile.latin1(), fn.latin1(), errno );
+
+ // remove the journal
+ QFile::remove( journalFileName() );
+ return true;
+}
+
+void TodoTable::load( const QString &fn )
+{
+ loadFile( fn, false );
+ if ( QFile::exists(journalFileName()) ) {
+ loadFile( journalFileName(), true );
+ save( fn );
+ }
+// QTable::sortColumn(2,TRUE,TRUE);
+// QTable::sortColumn(1,TRUE,TRUE);
+ QTable::sortColumn(0,TRUE,TRUE);
+ setCurrentCell( 0, 2 );
+}
+
+void TodoTable::updateVisible()
+{
+ if ( !isUpdatesEnabled() )
+ return;
+
+// qDebug("--> updateVisible!");
+
+ int visible = 0;
+ int id = mCat.id( "Todo List", showCat );
+ for ( int row = 0; row < numRows(); row++ ) {
+ CheckItem *ci = (CheckItem *)item( row, 0 );
+ Task *t = todoList[ci];
+ QArray<int> vlCats = t->categories();
+ bool hide = false;
+ if ( !showComp && ci->isChecked() )
+ hide = true;
+ if ( !showCat.isEmpty() ) {
+ if ( showCat == tr( "Unfiled" ) ) {
+ if ( vlCats.count() > 0 )
+ hide = true;
+ } else {
+ // do some comparing, we have to reverse our idea here...
+ if ( !hide ) {
+ hide = true;
+ for ( uint it = 0; it < vlCats.count(); ++it ) {
+ if ( vlCats[it] == id ) {
+ hide = false;
+ break;
+ }
+ }
+ }
+ }
+ }
+ if ( hide ) {
+ if ( currentRow() == row )
+ setCurrentCell( -1, 0 );
+ if ( rowHeight( row ) > 0 )
+ hideRow( row );
+ } else {
+ if ( rowHeight( row ) == 0 ) {
+ showRow( row );
+ adjustRow( row );
+ }
+ visible++;
+ }
+ }
+ if ( !visible )
+ setCurrentCell( -1, 0 );
+}
+
+void TodoTable::viewportPaintEvent( QPaintEvent *pe )
+{
+ if ( enablePainting )
+ QTable::viewportPaintEvent( pe );
+}
+
+void TodoTable::setPaintingEnabled( bool e )
+{
+ if ( e != enablePainting ) {
+ if ( !enablePainting ) {
+ enablePainting = true;
+ rowHeightChanged( 0 );
+ viewport()->update();
+ } else {
+ enablePainting = false;
+ }
+ }
+}
+
+void TodoTable::clear()
+{
+ for ( QMap<CheckItem*, Task *>::Iterator it = todoList.begin();
+ it != todoList.end(); ++it ) {
+ Task *todo = *it;
+ delete todo;
+ }
+ todoList.clear();
+ for ( int r = 0; r < numRows(); ++r ) {
+ for ( int c = 0; c < numCols(); ++c ) {
+ if ( cellWidget( r, c ) )
+ clearCellWidget( r, c );
+ clearCell( r, c );
+ }
+ }
+ setNumRows( 0 );
+}
+
+void TodoTable::sortColumn( int col, bool /*ascending*/, bool /*wholeRows*/ )
+{
+ // The default for wholeRows is false, however
+ // for this todo table we want to exchange complete
+ // rows when sorting. Also, we always want ascending, since
+ // the values have a logical order.
+ QTable::sortColumn( col, TRUE, TRUE );
+ updateVisible();
+}
+
+void TodoTable::slotCheckPriority(int row, int col )
+{
+ // kludgey work around to make forward along the updated priority...
+ if ( col == 1 ) {
+ // let everyone know!!
+ ComboItem* i = static_cast<ComboItem*>( item( row, col ) );
+ emit signalPriorityChanged( i->text().toInt() );
+ }
+}
+
+
+void TodoTable::updateJournal( const Task &todo, journal_action action, int row )
+{
+ QFile f( journalFileName() );
+ if ( !f.open(IO_WriteOnly|IO_Append) )
+ return;
+ QString buf;
+ QCString str;
+ buf = "<Task";
+ todo.save( buf );
+ buf += " Action=\"" + QString::number( int(action) ) + "\"";
+ buf += " Row=\"" + QString::number( row ) + "\"";
+ buf += "/>\n";
+ str = buf.utf8();
+ f.writeBlock( str.data(), str.length() );
+ f.close();
+}
+
+void TodoTable::rowHeightChanged( int row )
+{
+ if ( enablePainting )
+ QTable::rowHeightChanged( row );
+}
+
+void TodoTable::loadFile( const QString &strFile, bool fromJournal )
+{
+ QFile f( strFile );
+ if ( !f.open(IO_ReadOnly) )
+ return;
+
+ int action, row;
+ action = 0; row = 0;
+
+ enum Attribute {
+ FCompleted = 0,
+ FHasDate,
+ FPriority,
+ FCategories,
+ FDescription,
+ FDateYear,
+ FDateMonth,
+ FDateDay,
+ FUid,
+ FAction,
+ FRow
+ };
+
+ QAsciiDict<int> dict( 31 );
+ QList<Task> list;
+ dict.setAutoDelete( TRUE );
+ dict.insert( "Completed", new int(FCompleted) );
+ dict.insert( "HasDate", new int(FHasDate) );
+ dict.insert( "Priority", new int(FPriority) );
+ dict.insert( "Categories", new int(FCategories) );
+ dict.insert( "Description", new int(FDescription) );
+ dict.insert( "DateYear", new int(FDateYear) );
+ dict.insert( "DateMonth", new int(FDateMonth) );
+ dict.insert( "DateDay", new int(FDateDay) );
+ dict.insert( "Uid", new int(FUid) );
+ dict.insert( "Action", new int(FAction) );
+ dict.insert( "Row", new int(FRow) );
+
+ QByteArray ba = f.readAll();
+ f.close();
+ char* dt = ba.data();
+ int len = ba.size();
+ bool hasDueDate = FALSE;
+
+ action = ACTION_ADD;
+ int i = 0;
+ char *point;
+ while ( ( point = strstr( dt+i, "<Task " ) ) != NULL ) {
+ // new Task
+ i = point - dt;
+ Task *todo = new Task;
+ int dtY = 0, dtM = 0, dtD = 0;
+
+ i += 5;
+
+ while( 1 ) {
+ while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') )
+ ++i;
+ if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') )
+ break;
+ // we have another attribute, read it.
+ int j = i;
+ while ( j < len && dt[j] != '=' )
+ ++j;
+ char *attr = dt+i;
+ dt[j] = '\0';
+ i = ++j; // skip =
+ while ( i < len && dt[i] != '"' )
+ ++i;
+ j = ++i;
+ bool haveUtf = FALSE;
+ bool haveEnt = FALSE;
+ while ( j < len && dt[j] != '"' ) {
+ if ( ((unsigned char)dt[j]) > 0x7f )
+ haveUtf = TRUE;
+ if ( dt[j] == '&' )
+ haveEnt = TRUE;
+ ++j;
+ }
+ if ( i == j ) {
+ // empty value
+ i = j + 1;
+ continue;
+ }
+ QCString value( dt+i, j-i+1 );
+ i = j + 1;
+ int *lookup = dict[ attr ];
+ if ( !lookup ) {
+ todo->setCustomField(attr, value);
+ continue;
+ }
+ switch( *lookup ) {
+ case FCompleted:
+ todo->setCompleted( value.toInt() );
+ break;
+ case FHasDate:
+ // leave...
+ hasDueDate = value.toInt();
+ break;
+ case FPriority:
+ todo->setPriority( value.toInt() );
+ break;
+ case FCategories: {
+ //QString str = Qtopia::plainString( value );
+ todo->setCategories( Qtopia::Record::idsFromString( value ) );
+ break;
+ }
+ case FDescription:
+ {
+ QString str = (haveUtf ? QString::fromUtf8( value )
+ : QString::fromLatin1( value ) );
+ if ( haveEnt )
+ str = Qtopia::plainString( str );
+ todo->setDescription( str );
+ break;
+ }
+ case FDateYear:
+ dtY = value.toInt();
+ break;
+ case FDateMonth:
+ dtM = value.toInt();
+ break;
+ case FDateDay:
+ dtD = value.toInt();
+ break;
+ case FUid:
+ todo->setUid( value.toInt() );
+ break;
+ case FAction:
+ action = value.toInt();
+ break;
+ case FRow:
+ row = value.toInt();
+ break;
+ default:
+ qDebug( "huh??? missing enum? -- attr.: %s", attr );
+ break;
+ }
+ }
+
+ if ( dtY != 0 && dtM != 0 && dtD != 0 )
+ todo->setDueDate( QDate( dtY, dtM, dtD), hasDueDate );
+ else
+ todo->setHasDueDate( hasDueDate );
+
+// if ( categoryList.find( todo.category() ) == categoryList.end() )
+// categoryList.append( todo.category() );
+
+
+ // sadly we can't delay adding of items from the journal to get
+ // the proper effect, but then, the journal should _never_ be
+ // that huge
+
+ switch( action ) {
+ case ACTION_ADD:
+ if ( fromJournal ) {
+ int myrows = numRows();
+ setNumRows( myrows + 1 );
+ insertIntoTable( todo, myrows );
+ delete todo;
+ } else
+ list.append( todo );
+ break;
+ case ACTION_REMOVE:
+ journalFreeRemoveEntry( row );
+ break;
+ case ACTION_REPLACE:
+ journalFreeReplaceEntry( *todo, row );
+ delete todo;
+ break;
+ default:
+ break;
+ }
+ }
+// qDebug("parsing done=%d", t.elapsed() );
+ if ( list.count() > 0 ) {
+ internalAddEntries( list );
+ list.clear();
+ }
+// qDebug("loading done: t=%d", t.elapsed() );
+}
+
+void TodoTable::journalFreeReplaceEntry( const Task &todo, int row )
+{
+ QString strTodo;
+ strTodo = todo.description().left(40).simplifyWhiteSpace();
+ if ( row == -1 ) {
+ QMapIterator<CheckItem*, Task *> it;
+ for ( it = todoList.begin(); it != todoList.end(); ++it ) {
+ if ( *(*it) == todo ) {
+ row = it.key()->row();
+ it.key()->setChecked( todo.isCompleted() );
+ static_cast<ComboItem*>(item(row, 1))->setText( QString::number(todo.priority()) );
+ item( row, 2 )->setText( strTodo );
+ *(*it) = todo;
+ }
+ }
+ } else {
+ Task *t = todoList[static_cast<CheckItem*>(item(row, 0))];
+ todoList.remove( static_cast<CheckItem*>(item(row, 0)) );
+ delete t;
+ static_cast<CheckItem*>(item(row, 0))->setChecked( todo.isCompleted() );
+ static_cast<ComboItem*>(item(row, 1))->setText( QString::number(todo.priority()) );
+ item( row, 2 )->setText( strTodo );
+ todoList.insert( static_cast<CheckItem*>(item(row,0)), new Task(todo) );
+ }
+}
+
+void TodoTable::journalFreeRemoveEntry( int row )
+{
+ CheckItem *chk;
+ chk = static_cast<CheckItem*>(item(row, 0 ));
+ if ( !chk )
+ return;
+ todoList.remove( chk );
+
+ realignTable( row );
+}
+
+void TodoTable::keyPressEvent( QKeyEvent *e )
+{
+ if ( e->key() == Key_Space || e->key() == Key_Return ) {
+ switch ( currentColumn() ) {
+ case 0: {
+ CheckItem *i = static_cast<CheckItem*>(item(currentRow(),
+ currentColumn()));
+ if ( i )
+ i->toggle();
+ break;
+ }
+ case 1:
+ break;
+ case 2:
+ emit signalEdit();
+ default:
+ break;
+ }
+ } else {
+ QTable::keyPressEvent( e );
+ }
+}
+
+QStringList TodoTable::categories()
+{
+ // This is called seldom, so calling a load in here
+ // should be fine.
+ mCat.load( categoryFileName() );
+ QStringList categoryList = mCat.labels( "Todo List" );
+ return categoryList;
+}
+
+void TodoTable::slotDoFind( const QString &findString, bool caseSensitive,
+ bool backwards, int category )
+{
+ // we have to iterate through the table, this gives the illusion that
+ // sorting is actually being used.
+ if ( currFindRow < -1 )
+ currFindRow = currentRow() - 1;
+ clearSelection( TRUE );
+ int rows,
+ row;
+ CheckItem *chk;
+ QRegExp r( findString );
+
+ r.setCaseSensitive( caseSensitive );
+ rows = numRows();
+ static bool wrapAround = true;
+
+ if ( !backwards ) {
+ for ( row = currFindRow + 1; row < rows; row++ ) {
+ chk = static_cast<CheckItem*>( item(row, 0) );
+ if ( taskCompare(*(todoList[chk]), r, category) )
+ break;
+ }
+ } else {
+ for ( row = currFindRow - 1; row > -1; row-- ) {
+ chk = static_cast<CheckItem*>( item(row, 0) );
+ if ( taskCompare(*(todoList[chk]), r, category) )
+ break;
+ }
+ }
+ if ( row >= rows || row < 0 ) {
+ if ( row < 0 )
+ currFindRow = rows;
+ else
+ currFindRow = -1;
+ if ( wrapAround )
+ emit signalWrapAround();
+ else
+ emit signalNotFound();
+ wrapAround = !wrapAround;
+ } else {
+ currFindRow = row;
+ QTableSelection foundSelection;
+ foundSelection.init( currFindRow, 0 );
+ foundSelection.expandTo( currFindRow, numCols() - 1 );
+ addSelection( foundSelection );
+ setCurrentCell( currFindRow, numCols() - 1 );
+ // we should always be able to wrap around and find this again,
+ // so don't give confusing not found message...
+ wrapAround = true;
+ }
+}
+
+int TodoTable::showCategoryId() const
+{
+ int id;
+ id = -1;
+ // if allcategories are selected, you get unfiled...
+ if ( showCat != tr( "Unfiled" ) && showCat != tr( "All" ) )
+ id = mCat.id( "Todo List", showCat );
+ return id;
+}
+
+static bool taskCompare( const Task &task, const QRegExp &r, int category )
+{
+ bool returnMe;
+ QArray<int> cats;
+ cats = task.categories();
+
+ returnMe = false;
+ if ( (category == -1 && cats.count() == 0) || category == -2 )
+ returnMe = task.match( r );
+ else {
+ int i;
+ for ( i = 0; i < int(cats.count()); i++ ) {
+ if ( cats[i] == category ) {
+ returnMe = task.match( r );
+ break;
+ }
+ }
+ }
+ return returnMe;
+}
+
+static QString journalFileName()
+{
+ QString str;
+ str = getenv( "HOME" );
+ str += "/.todojournal";
+ return str;
+}
+
+// int TodoTable::rowHeight( int ) const
+// {
+// return 18;
+// }
+
+// int TodoTable::rowPos( int row ) const
+// {
+// return 18*row;
+// }
+
+// int TodoTable::rowAt( int pos ) const
+// {
+// return QMIN( pos/18, numRows()-1 );
+// }
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 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef TODOTABLE_H
+#define TODOTABLE_H
+
+#include <qpe/categories.h>
+#include <qpe/stringutil.h>
+#include <qpe/task.h>
+
+#include <qtable.h>
+#include <qmap.h>
+#include <qguardedptr.h>
+
+class Node;
+class QComboBox;
+class QTimer;
+
+class CheckItem : public QTableItem
+{
+public:
+ CheckItem( QTable *t, const QString &sortkey );
+
+ void setChecked( bool b );
+ void toggle();
+ bool isChecked() const;
+ void setKey( const QString &key ) { sortKey = key; }
+ QString key() const;
+
+ void paint( QPainter *p, const QColorGroup &cg, const QRect &cr, bool selected );
+
+private:
+ bool checked;
+ QString sortKey;
+};
+
+class ComboItem : public QTableItem
+{
+public:
+ ComboItem( QTable *t, EditType et );
+ QWidget *createEditor() const;
+ void setContentFromEditor( QWidget *w );
+ void setText( const QString &s );
+ int alignment() const { return Qt::AlignCenter; }
+
+ QString text() const;
+
+private:
+ QGuardedPtr<QComboBox> cb;
+
+};
+
+class TodoTextItem : public QTableItem
+{
+public:
+ TodoTextItem( QTable *t, const QString & str )
+ :QTableItem( t, QTableItem::Never, str ) {}
+
+ QString key () const { return Qtopia::buildSortKey( text() ); }
+};
+
+
+
+enum journal_action { ACTION_ADD, ACTION_REMOVE, ACTION_REPLACE };
+
+class TodoTable : public QTable
+{
+ Q_OBJECT
+
+public:
+ TodoTable( QWidget *parent = 0, const char * name = 0 );
+ void addEntry( const Task &todo );
+ void clearFindRow() { currFindRow = -2; }
+
+ Task currentEntry() const;
+ void replaceCurrentEntry( const Task &todo, bool fromTableItem = false );
+
+ QStringList categories();
+
+ void setShowCompleted( bool sc ) { showComp = sc; updateVisible(); }
+ bool showCompleted() const { return showComp; }
+
+ void setShowCategory( const QString &c ) { showCat = c; updateVisible(); }
+ const QString &showCategory() const { return showCat; }
+ int showCategoryId() const;
+
+ bool save( const QString &fn );
+ void load( const QString &fn );
+ void clear();
+ void removeCurrentEntry();
+
+ void setPaintingEnabled( bool e );
+
+ virtual void sortColumn( int col, bool ascending, bool /*wholeRows*/ );
+
+// int rowHeight( int ) const;
+// int rowPos( int row ) const;
+// virtual int rowAt( int pos ) const;
+
+signals:
+ void signalEdit();
+ void signalDoneChanged( bool b );
+ void signalPriorityChanged( int i );
+ void signalShowMenu( const QPoint & );
+ void signalNotFound();
+ void signalWrapAround();
+
+protected:
+ void keyPressEvent( QKeyEvent *e );
+
+private:
+ void updateVisible();
+ void viewportPaintEvent( QPaintEvent * );
+ void internalAddEntries( QList<Task> &list);
+ inline void insertIntoTable( Task *todo, int row );
+ void updateJournal( const Task &todo, journal_action action, int row = -1);
+ void mergeJournal();
+ void journalFreeReplaceEntry( const Task &todo, int row );
+ void journalFreeRemoveEntry( int row );
+ inline void realignTable( int row );
+ void loadFile( const QString &strFile, bool fromJournal = false );
+
+private slots:
+ void slotClicked( int row, int col, int button, const QPoint &pos );
+ void slotPressed( int row, int col, int button, const QPoint &pos );
+ void slotCheckPriority(int row, int col );
+ void slotCurrentChanged(int row, int col );
+ void slotDoFind( const QString &findString, bool caseSensetive,
+ bool backwards, int category );
+ void slotShowMenu();
+ void rowHeightChanged( int row );
+
+private:
+ friend class TodoWindow;
+
+ QMap<CheckItem*, Task *> todoList;
+ QStringList categoryList;
+ bool showComp;
+ QString showCat;
+ QTimer *menuTimer;
+ bool enablePainting;
+ Categories mCat;
+ int currFindRow;
+};
+
+
+inline void TodoTable::insertIntoTable( Task *todo, int row )
+{
+ QString sortKey = (char) ((todo->isCompleted() ? 'a' : 'A')
+ + todo->priority() )
+ + Qtopia::buildSortKey( todo->description() );
+ CheckItem *chk = new CheckItem( this, sortKey );
+ chk->setChecked( todo->isCompleted() );
+ ComboItem *cmb = new ComboItem( this, QTableItem::WhenCurrent );
+ cmb->setText( QString::number( todo->priority() ) );
+ QTableItem *ti = new TodoTextItem( this, todo->description().left(40).simplifyWhiteSpace() );
+ ti->setReplaceable( false );
+
+ setItem( row, 0, chk );
+ setItem( row, 1, cmb );
+ setItem( row, 2, ti );
+
+ todoList.insert( chk, todo );
+}
+
+inline void TodoTable::realignTable( int row )
+{
+ QTableItem *ti1,
+ *ti2,
+ *ti3;
+ int totalRows = numRows();
+ for ( int curr = row; curr < totalRows - 1; curr++ ) {
+ // this is bad, we must take the item out and then
+ // set it. In the end, it behaves no worse (time wise)
+ // then the old way of saving the entries to file, clearing
+ // the table re-reading in the file and resetting the table
+ ti1 = item( curr + 1, 0 );
+ ti2 = item( curr + 1, 1 );
+ ti3 = item( curr + 1, 2 );
+ takeItem( ti1 );
+ takeItem( ti2 );
+ takeItem( ti3 );
+ setItem( curr, 0, ti1 );
+ setItem( curr, 1, ti2 );
+ setItem( curr, 2, ti3 );
+ }
+ setNumRows( totalRows - 1 );
+}
+
+#endif