summaryrefslogtreecommitdiff
path: root/libopie2/opiepim
authorzecke <zecke>2002-11-30 11:28:47 (UTC)
committer zecke <zecke>2002-11-30 11:28:47 (UTC)
commit9b8b30fa6cbdf1424b29cde21fae112e8bf96e6d (patch) (side-by-side diff)
tree896dd858dc2ec2f0b7e1b265cae66ccceecc82da /libopie2/opiepim
parent599c58c6ab2ab936890cbbfa4e6299493c141f8a (diff)
downloadopie-9b8b30fa6cbdf1424b29cde21fae112e8bf96e6d.zip
opie-9b8b30fa6cbdf1424b29cde21fae112e8bf96e6d.tar.gz
opie-9b8b30fa6cbdf1424b29cde21fae112e8bf96e6d.tar.bz2
More infrastructure
ORecur has now the nextOccurence function exceptions We've now Notifers like Alarms and DatebookEntries we may add to execute applications... AppName replaced with service cause it is a service Add rtti to OPimRecord as a static function This is used inside the BackEnd classes to static_cast... added removeAllCompleted to the todobackends... add a common Opie PIM mainwindow which takes care of some simple scripting enchangements.. much more
Diffstat (limited to 'libopie2/opiepim') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opiepim/backend/otodoaccessbackend.h1
-rw-r--r--libopie2/opiepim/backend/otodoaccessvcal.cpp6
-rw-r--r--libopie2/opiepim/backend/otodoaccessvcal.h2
-rw-r--r--libopie2/opiepim/backend/otodoaccessxml.cpp27
-rw-r--r--libopie2/opiepim/backend/otodoaccessxml.h1
-rw-r--r--libopie2/opiepim/core/opimaccesstemplate.h10
-rw-r--r--libopie2/opiepim/core/opimmaintainer.cpp6
-rw-r--r--libopie2/opiepim/core/opimmaintainer.h16
-rw-r--r--libopie2/opiepim/core/opimnotify.cpp227
-rw-r--r--libopie2/opiepim/core/opimnotify.h142
-rw-r--r--libopie2/opiepim/core/opimnotifymanager.cpp69
-rw-r--r--libopie2/opiepim/core/opimnotifymanager.h51
-rw-r--r--libopie2/opiepim/core/opimrecord.cpp3
-rw-r--r--libopie2/opiepim/core/opimrecord.h10
-rw-r--r--libopie2/opiepim/core/opimresolver.h56
-rw-r--r--libopie2/opiepim/core/opimxref.cpp4
-rw-r--r--libopie2/opiepim/core/opimxref.h2
-rw-r--r--libopie2/opiepim/core/opimxrefmanager.cpp4
-rw-r--r--libopie2/opiepim/core/opimxrefmanager.h2
-rw-r--r--libopie2/opiepim/core/opimxrefpartner.cpp4
-rw-r--r--libopie2/opiepim/core/opimxrefpartner.h6
-rw-r--r--libopie2/opiepim/core/orecur.cpp315
-rw-r--r--libopie2/opiepim/core/orecur.h29
-rw-r--r--libopie2/opiepim/core/otodoaccess.cpp7
-rw-r--r--libopie2/opiepim/core/otodoaccess.h17
-rw-r--r--libopie2/opiepim/ocontact.cpp4
-rw-r--r--libopie2/opiepim/ocontact.h3
-rw-r--r--libopie2/opiepim/otodo.cpp72
-rw-r--r--libopie2/opiepim/otodo.h59
-rw-r--r--libopie2/opiepim/ui/opimmainwindow.cpp71
-rw-r--r--libopie2/opiepim/ui/opimmainwindow.h79
31 files changed, 1207 insertions, 98 deletions
diff --git a/libopie2/opiepim/backend/otodoaccessbackend.h b/libopie2/opiepim/backend/otodoaccessbackend.h
index 3bad6b7..7944a2c 100644
--- a/libopie2/opiepim/backend/otodoaccessbackend.h
+++ b/libopie2/opiepim/backend/otodoaccessbackend.h
@@ -1,20 +1,21 @@
#ifndef OPIE_TODO_ACCESS_BACKEND_H
#define OPIE_TODO_ACCESS_BACKEND_H
#include "otodo.h"
#include "opimaccessbackend.h"
class OTodoAccessBackend : public OPimAccessBackend<OTodo> {
public:
OTodoAccessBackend();
~OTodoAccessBackend();
virtual QArray<int> effectiveToDos( const QDate& start,
const QDate& end,
bool includeNoDates ) = 0;
virtual QArray<int> overDue() = 0;
virtual QArray<int> sorted( bool asc, int sortOrder, int sortFilter,
int cat ) = 0;
+ virtual void removeAllCompleted() = 0;
};
#endif
diff --git a/libopie2/opiepim/backend/otodoaccessvcal.cpp b/libopie2/opiepim/backend/otodoaccessvcal.cpp
index ac70ea0..e96cc3c 100644
--- a/libopie2/opiepim/backend/otodoaccessvcal.cpp
+++ b/libopie2/opiepim/backend/otodoaccessvcal.cpp
@@ -1,192 +1,198 @@
#include <qfile.h>
#include <qtopia/private/vobject_p.h>
#include <qtopia/timeconversion.h>
#include <qtopia/private/qfiledirect_p.h>
#include "otodoaccessvcal.h"
namespace {
static OTodo eventByVObj( VObject *obj ){
OTodo event;
VObject *ob;
QCString name;
// no uid, attendees, ... and no fun
// description
if( ( ob = isAPropertyOf( obj, VCDescriptionProp )) != 0 ){
name = vObjectStringZValue( ob );
event.setDescription( name );
}
// summary
if ( ( ob = isAPropertyOf( obj, VCSummaryProp ) ) != 0 ) {
name = vObjectStringZValue( ob );
event.setSummary( name );
}
// completed
if( ( ob = isAPropertyOf( obj, VCStatusProp )) != 0 ){
name = vObjectStringZValue( ob );
if( name == "COMPLETED" ){
event.setCompleted( true );
}else{
event.setCompleted( false );
}
}else
event.setCompleted( false );
// priority
if ((ob = isAPropertyOf(obj, VCPriorityProp))) {
name = vObjectStringZValue( ob );
bool ok;
event.setPriority(name.toInt(&ok) );
}
//due date
if((ob = isAPropertyOf(obj, VCDueProp)) ){
event.setHasDueDate( true );
name = vObjectStringZValue( ob );
event.setDueDate( TimeConversion::fromISO8601( name).date() );
}
// categories
if((ob = isAPropertyOf( obj, VCCategoriesProp )) != 0 ){
name = vObjectStringZValue( ob );
qWarning("Categories:%s", name.data() );
}
event.setUid( 1 );
return event;
};
static VObject *vobjByEvent( const OTodo &event ) {
VObject *task = newVObject( VCTodoProp );
if( task == 0 )
return 0l;
if( event.hasDueDate() )
addPropValue( task, VCDueProp,
TimeConversion::toISO8601( event.dueDate() ) );
if( event.isCompleted() )
addPropValue( task, VCStatusProp, "COMPLETED");
QString string = QString::number(event.priority() );
addPropValue( task, VCPriorityProp, string.local8Bit() );
addPropValue( task, VCCategoriesProp,
event.idsToString( event.categories() ).local8Bit() );
addPropValue( task, VCDescriptionProp,
event.description().local8Bit() );
addPropValue( task, VCSummaryProp,
event.summary().local8Bit() );
return task;
};
}
OTodoAccessVCal::OTodoAccessVCal( const QString& path )
: m_dirty(false), m_file( path )
{
}
OTodoAccessVCal::~OTodoAccessVCal() {
}
bool OTodoAccessVCal::load() {
m_map.clear();
m_dirty = false;
VObject* vcal = 0l;
vcal = Parse_MIME_FromFileName( QFile::encodeName(m_file).data() );
if (!vcal )
return false;
// Iterate over the list
VObjectIterator it;
VObject* vobj;
initPropIterator(&it, vcal);
while( moreIteration( &it ) ) {
vobj = ::nextVObject( &it );
QCString name = ::vObjectName( vobj );
if( name == VCTodoProp ){
OTodo to = eventByVObj( vobj );
m_map.insert( to.uid(), to );
}
}
// Should I do a delete vcal?
return true;
}
bool OTodoAccessVCal::reload() {
return load();
}
bool OTodoAccessVCal::save() {
if (!m_dirty )
return true;
QFileDirect file( m_file );
if (!file.open(IO_WriteOnly ) )
return false;
VObject *obj;
obj = newVObject( VCCalProp );
addPropValue( obj, VCVersionProp, "1.0" );
VObject *vo;
for(QMap<int, OTodo>::ConstIterator it=m_map.begin(); it !=m_map.end(); ++it ){
vo = vobjByEvent( it.data() );
addVObjectProp(obj, vo );
}
writeVObject( file.directHandle(), obj );
cleanVObject( obj );
cleanStrTbl();
m_dirty = false;
return true;
}
void OTodoAccessVCal::clear() {
m_map.clear();
m_dirty = true;
}
bool OTodoAccessVCal::add( const OTodo& to ) {
m_map.insert( to.uid(), to );
m_dirty = true;
return true;
}
bool OTodoAccessVCal::remove( int uid ) {
m_map.remove( uid );
m_dirty = true;
return true;
}
+void OTodoAccessVCal::removeAllCompleted() {
+ for ( QMap<int, OTodo>::Iterator it = m_map.begin(); it != m_map.end(); ++it ) {
+ if ( (*it).isCompleted() )
+ m_map.remove( it );
+ }
+}
bool OTodoAccessVCal::replace( const OTodo& to ) {
m_map.replace( to.uid(), to );
m_dirty = true;
return true;
}
OTodo OTodoAccessVCal::find(int uid )const {
return m_map[uid];
}
QArray<int> OTodoAccessVCal::sorted( bool, int, int, int ) {
QArray<int> ar(0);
return ar;
}
QArray<int> OTodoAccessVCal::allRecords()const {
QArray<int> ar( m_map.count() );
QMap<int, OTodo>::ConstIterator it;
int i = 0;
for ( it = m_map.begin(); it != m_map.end(); ++it ) {
ar[i] = it.key();
i++;
}
return ar;
}
QArray<int> OTodoAccessVCal::queryByExample( const OTodo&, int ) {
QArray<int> ar(0);
return ar;
}
QArray<int> OTodoAccessVCal::effectiveToDos( const QDate& ,
const QDate& ,
bool ) {
QArray<int> ar(0);
return ar;
}
QArray<int> OTodoAccessVCal::overDue() {
QArray<int> ar(0);
return ar;
}
diff --git a/libopie2/opiepim/backend/otodoaccessvcal.h b/libopie2/opiepim/backend/otodoaccessvcal.h
index 4499a7e..452f602 100644
--- a/libopie2/opiepim/backend/otodoaccessvcal.h
+++ b/libopie2/opiepim/backend/otodoaccessvcal.h
@@ -1,35 +1,37 @@
#ifndef OPIE_OTODO_ACCESS_VCAL_H
#define OPIE_OTODO_ACCESS_VCAL_H
#include "otodoaccessbackend.h"
class OTodoAccessVCal : public OTodoAccessBackend {
public:
OTodoAccessVCal(const QString& );
~OTodoAccessVCal();
bool load();
bool reload();
bool save();
QArray<int> allRecords()const;
QArray<int> queryByExample( const OTodo& t, int sort );
QArray<int> effectiveToDos( const QDate& start,
const QDate& end,
bool includeNoDates );
QArray<int> overDue();
QArray<int> sorted( bool asc, int sortOrder, int sortFilter,
int cat );
OTodo find(int uid)const;
void clear();
bool add( const OTodo& );
bool remove( int uid );
bool replace( const OTodo& );
+ void removeAllCompleted();
+
private:
bool m_dirty : 1;
QString m_file;
QMap<int, OTodo> m_map;
};
#endif
diff --git a/libopie2/opiepim/backend/otodoaccessxml.cpp b/libopie2/opiepim/backend/otodoaccessxml.cpp
index c1682c6..b2dfe80 100644
--- a/libopie2/opiepim/backend/otodoaccessxml.cpp
+++ b/libopie2/opiepim/backend/otodoaccessxml.cpp
@@ -1,618 +1,619 @@
#include <qfile.h>
#include <qvector.h>
#include <qpe/global.h>
#include <qpe/stringutil.h>
#include <qpe/timeconversion.h>
#include <opie/xmltree.h>
#include "otodoaccessxml.h"
OTodoAccessXML::OTodoAccessXML( const QString& appName,
const QString& fileName )
: OTodoAccessBackend(), m_app( appName ), m_opened( false ), m_changed( false )
{
if (!fileName.isEmpty() )
m_file = fileName;
else
m_file = Global::applicationFileName( "todolist", "todolist.xml" );
}
OTodoAccessXML::~OTodoAccessXML() {
}
bool OTodoAccessXML::load() {
m_opened = true;
m_changed = false;
/* initialize dict */
/*
* UPDATE dict if you change anything!!!
*/
- QAsciiDict<int> dict(15);
+ QAsciiDict<int> dict(21);
dict.setAutoDelete( TRUE );
dict.insert("Categories" , new int(OTodo::Category) );
dict.insert("Uid" , new int(OTodo::Uid) );
dict.insert("HasDate" , new int(OTodo::HasDate) );
dict.insert("Completed" , new int(OTodo::Completed) );
dict.insert("Description" , new int(OTodo::Description) );
dict.insert("Summary" , new int(OTodo::Summary) );
dict.insert("Priority" , new int(OTodo::Priority) );
dict.insert("DateDay" , new int(OTodo::DateDay) );
dict.insert("DateMonth" , new int(OTodo::DateMonth) );
dict.insert("DateYear" , new int(OTodo::DateYear) );
dict.insert("Progress" , new int(OTodo::Progress) );
dict.insert("Completed", new int(OTodo::Completed) );
dict.insert("CrossReference", new int(OTodo::CrossReference) );
- dict.insert("HasAlarmDateTime",new int(OTodo::HasAlarmDateTime) );
- dict.insert("AlarmDateTime", new int(OTodo::AlarmDateTime) );
+ dict.insert("State", new int(OTodo::State) );
+ dict.insert("Recurrence", new int(OTodo::Recurrence) );
+ dict.insert("Alarms", new int(OTodo::Alarms) );
+ dict.insert("Reminders", new int(OTodo::Reminders) );
+ dict.insert("Notifiers", new int(OTodo::Notifiers) );
+ dict.insert("Maintainer", new int(OTodo::Maintainer) );
// here the custom XML parser from TT it's GPL
- // but we want to push that to TT.....
+ // but we want to push OpiePIM... to TT.....
QFile f(m_file );
if (!f.open(IO_ReadOnly) )
return false;
QByteArray ba = f.readAll();
f.close();
char* dt = ba.data();
int len = ba.size();
int i = 0;
char *point;
const char* collectionString = "<Task ";
while ( dt+i != 0 && ( point = strstr( dt+i, collectionString ) ) != 0l ) {
i = point -dt;
i+= strlen(collectionString);
OTodo ev;
m_year = m_month = m_day = 0;
while ( TRUE ) {
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;
QCString attr( dt+i, j-i+1);
i = ++j; // skip =
// find the start of quotes
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;
QString str = (haveUtf ? QString::fromUtf8( value )
: QString::fromLatin1( value ) );
if ( haveEnt )
str = Qtopia::plainString( str );
/*
* add key + value
*/
todo( &dict, ev, attr, str );
}
/*
* now add it
*/
if (m_events.contains( ev.uid() ) || ev.uid() == 0) {
ev.setUid( 1 );
m_changed = true;
}
if ( ev.hasDueDate() ) {
ev.setDueDate( QDate(m_year, m_month, m_day) );
}
m_events.insert(ev.uid(), ev );
m_year = m_month = m_day = -1;
}
qWarning("counts %d records loaded!", m_events.count() );
return true;
}
bool OTodoAccessXML::reload() {
return load();
}
bool OTodoAccessXML::save() {
// qWarning("saving");
if (!m_opened || !m_changed ) {
// qWarning("not saving");
return true;
}
QString strNewFile = m_file + ".new";
QFile f( strNewFile );
if (!f.open( IO_WriteOnly|IO_Raw ) )
return false;
int written;
QString out;
out = "<!DOCTYPE Tasks>\n<Tasks>\n";
// for all todos
QMap<int, OTodo>::Iterator it;
for (it = m_events.begin(); it != m_events.end(); ++it ) {
out+= "<Task " + toString( (*it) ) + " />\n";
QCString cstr = out.utf8();
written = f.writeBlock( cstr.data(), cstr.length() );
/* less written then we wanted */
if ( written != (int)cstr.length() ) {
f.close();
QFile::remove( strNewFile );
return false;
}
out = QString::null;
}
out += "</Tasks>";
QCString cstr = out.utf8();
written = f.writeBlock( cstr.data(), cstr.length() );
if ( written != (int)cstr.length() ) {
f.close();
QFile::remove( strNewFile );
return false;
}
/* flush before renaming */
f.close();
if( ::rename( strNewFile.latin1(), m_file.latin1() ) < 0 ) {
// qWarning("error renaming");
QFile::remove( strNewFile );
}
m_changed = false;
return true;
}
QArray<int> OTodoAccessXML::allRecords()const {
QArray<int> ids( m_events.count() );
QMap<int, OTodo>::ConstIterator it;
int i = 0;
for ( it = m_events.begin(); it != m_events.end(); ++it ) {
ids[i] = it.key();
i++;
}
return ids;
}
QArray<int> OTodoAccessXML::queryByExample( const OTodo&, int ) {
QArray<int> ids(0);
return ids;
}
OTodo OTodoAccessXML::find( int uid )const {
OTodo todo;
todo.setUid( 0 ); // isEmpty()
QMap<int, OTodo>::ConstIterator it = m_events.find( uid );
if ( it != m_events.end() )
todo = it.data();
return todo;
}
void OTodoAccessXML::clear() {
if (m_opened )
m_changed = true;
m_events.clear();
}
bool OTodoAccessXML::add( const OTodo& todo ) {
// qWarning("add");
m_changed = true;
m_events.insert( todo.uid(), todo );
return true;
}
bool OTodoAccessXML::remove( int uid ) {
m_changed = true;
m_events.remove( uid );
return true;
}
bool OTodoAccessXML::replace( const OTodo& todo) {
m_changed = true;
m_events.replace( todo.uid(), todo );
return true;
}
QArray<int> OTodoAccessXML::effectiveToDos( const QDate& start,
const QDate& end,
bool includeNoDates ) {
QArray<int> ids( m_events.count() );
QMap<int, OTodo>::Iterator it;
int i = 0;
for ( it = m_events.begin(); it != m_events.end(); ++it ) {
if ( !it.data().hasDueDate() ) {
if ( includeNoDates ) {
ids[i] = it.key();
i++;
}
}else if ( it.data().dueDate() >= start &&
it.data().dueDate() <= end ) {
ids[i] = it.key();
i++;
}
}
ids.resize( i );
return ids;
}
QArray<int> OTodoAccessXML::overDue() {
QArray<int> ids( m_events.count() );
int i = 0;
QMap<int, OTodo>::Iterator it;
for ( it = m_events.begin(); it != m_events.end(); ++it ) {
if ( it.data().isOverdue() ) {
ids[i] = it.key();
i++;
}
}
ids.resize( i );
return ids;
}
/* private */
void OTodoAccessXML::todo( QAsciiDict<int>* dict, OTodo& ev,
const QCString& attr, const QString& val) {
// qWarning("parse to do from XMLElement" );
int *find=0;
find = (*dict)[ attr.data() ];
if (!find ) {
// qWarning("Unknown option" + it.key() );
ev.setCustomField( attr, val );
return;
}
switch( *find ) {
case OTodo::Uid:
ev.setUid( val.toInt() );
break;
case OTodo::Category:
ev.setCategories( ev.idsFromString( val ) );
break;
case OTodo::HasDate:
ev.setHasDueDate( val.toInt() );
break;
case OTodo::Completed:
ev.setCompleted( val.toInt() );
break;
case OTodo::Description:
ev.setDescription( val );
break;
case OTodo::Summary:
ev.setSummary( val );
break;
case OTodo::Priority:
ev.setPriority( val.toInt() );
break;
case OTodo::DateDay:
m_day = val.toInt();
break;
case OTodo::DateMonth:
m_month = val.toInt();
break;
case OTodo::DateYear:
m_year = val.toInt();
break;
case OTodo::Progress:
ev.setProgress( val.toInt() );
break;
case OTodo::CrossReference:
{
/*
* A cross refernce looks like
* appname,id;appname,id
* we need to split it up
*/
QStringList refs = QStringList::split(';', val );
QStringList::Iterator strIt;
for (strIt = refs.begin(); strIt != refs.end(); ++strIt ) {
int pos = (*strIt).find(',');
if ( pos > -1 )
; // ev.addRelation( (*strIt).left(pos), (*strIt).mid(pos+1).toInt() );
}
break;
}
- case OTodo::HasAlarmDateTime:
- ev.setHasAlarmDateTime( val.toInt() );
- break;
- case OTodo::AlarmDateTime: {
- /* this sounds better ;) zecke */
- ev.setAlarmDateTime( TimeConversion::fromISO8601( val.local8Bit() ) );
- break;
- }
default:
break;
}
}
QString OTodoAccessXML::toString( const OTodo& ev )const {
QString str;
str += "Completed=\"" + QString::number( ev.isCompleted() ) + "\" ";
str += "HasDate=\"" + QString::number( ev.hasDueDate() ) + "\" ";
str += "Priority=\"" + QString::number( ev.priority() ) + "\" ";
str += "Progress=\"" + QString::number(ev.progress() ) + "\" ";
str += "Categories=\"" + toString( ev.categories() ) + "\" ";
str += "Description=\"" + Qtopia::escapeString( ev.description() ) + "\" ";
str += "Summary=\"" + Qtopia::escapeString( ev.summary() ) + "\" ";
if ( ev.hasDueDate() ) {
str += "DateYear=\"" + QString::number( ev.dueDate().year() ) + "\" ";
str += "DateMonth=\"" + QString::number( ev.dueDate().month() ) + "\" ";
str += "DateDay=\"" + QString::number( ev.dueDate().day() ) + "\" ";
}
// qWarning( "Uid %d", ev.uid() );
str += "Uid=\"" + QString::number( ev.uid() ) + "\" ";
// append the extra options
/* FIXME Qtopia::Record this is currently not
* possible you can set custom fields
* but don' iterate over the list
* I may do #define private protected
* for this case - cough --zecke
*/
/*
QMap<QString, QString> extras = ev.extras();
QMap<QString, QString>::Iterator extIt;
for (extIt = extras.begin(); extIt != extras.end(); ++extIt )
str += extIt.key() + "=\"" + extIt.data() + "\" ";
*/
// cross refernce
- str += "AlarmDateTime=\"" + TimeConversion::toISO8601( ev.alarmDateTime() ) + "\" ";
return str;
}
QString OTodoAccessXML::toString( const QArray<int>& ints ) const {
return Qtopia::Record::idsToString( ints );
}
/* internal class for sorting
*
* Inspired by todoxmlio.cpp from TT
*/
struct OTodoXMLContainer {
OTodo todo;
};
namespace {
inline QString string( const OTodo& todo) {
return todo.summary().isEmpty() ?
todo.description().left(20 ) :
todo.summary();
}
inline int completed( const OTodo& todo1, const OTodo& todo2) {
int ret = 0;
if ( todo1.isCompleted() ) ret++;
if ( todo2.isCompleted() ) ret--;
return ret;
}
inline int priority( const OTodo& t1, const OTodo& t2) {
return ( t1.priority() - t2.priority() );
}
inline int description( const OTodo& t1, const OTodo& t2) {
return QString::compare( string(t1), string(t2) );
}
inline int deadline( const OTodo& t1, const OTodo& t2) {
int ret = 0;
if ( t1.hasDueDate() &&
t2.hasDueDate() )
ret = t2.dueDate().daysTo( t1.dueDate() );
else if ( t1.hasDueDate() )
ret = -1;
else if ( t2.hasDueDate() )
ret = 1;
else
ret = 0;
return ret;
}
};
/*
* Returns:
* 0 if item1 == item2
*
* non-zero if item1 != item2
*
* This function returns int rather than bool so that reimplementations
* can return one of three values and use it to sort by:
*
* 0 if item1 == item2
*
* > 0 (positive integer) if item1 > item2
*
* < 0 (negative integer) if item1 < item2
*
*/
class OTodoXMLVector : public QVector<OTodoXMLContainer> {
public:
OTodoXMLVector(int size, bool asc, int sort)
: QVector<OTodoXMLContainer>( size )
{
setAutoDelete( true );
m_asc = asc;
m_sort = sort;
}
/* return the summary/description */
QString string( const OTodo& todo) {
return todo.summary().isEmpty() ?
todo.description().left(20 ) :
todo.summary();
}
/**
* we take the sortorder( switch on it )
*
*/
int compareItems( Item d1, Item d2 ) {
bool seComp, sePrio, seDesc, seDeadline;
seComp = sePrio = seDeadline = seDesc = false;
int ret =0;
OTodoXMLContainer* con1 = (OTodoXMLContainer*)d1;
OTodoXMLContainer* con2 = (OTodoXMLContainer*)d2;
/* same item */
if ( con1->todo.uid() == con2->todo.uid() )
return 0;
switch ( m_sort ) {
/* completed */
case 0: {
ret = completed( con1->todo, con2->todo );
seComp = TRUE;
break;
}
/* priority */
case 1: {
ret = priority( con1->todo, con2->todo );
sePrio = TRUE;
break;
}
/* description */
case 2: {
ret = description( con1->todo, con2->todo );
seDesc = TRUE;
break;
}
/* deadline */
case 3: {
ret = deadline( con1->todo, con2->todo );
seDeadline = TRUE;
break;
}
default:
ret = 0;
break;
};
/*
* FIXME do better sorting if the first sort criteria
* ret equals 0 start with complete and so on...
*/
/* twist it we're not ascending*/
if (!m_asc)
ret = ret * -1;
if ( ret )
return ret;
// default did not gave difference let's try it other way around
/*
* General try if already checked if not test
* and return
* 1.Completed
* 2.Priority
* 3.Description
* 4.DueDate
*/
if (!seComp ) {
if ( (ret = completed( con1->todo, con2->todo ) ) ) {
if (!m_asc ) ret *= -1;
return ret;
}
}
if (!sePrio ) {
if ( (ret = priority( con1->todo, con2->todo ) ) ) {
if (!m_asc ) ret *= -1;
return ret;
}
}
if (!seDesc ) {
if ( (ret = description(con1->todo, con2->todo ) ) ) {
if (!m_asc) ret *= -1;
return ret;
}
}
if (!seDeadline) {
if ( (ret = deadline( con1->todo, con2->todo ) ) ) {
if (!m_asc) ret *= -1;
return ret;
}
}
return 0;
}
private:
bool m_asc;
int m_sort;
};
QArray<int> OTodoAccessXML::sorted( bool asc, int sortOrder,
int sortFilter, int cat ) {
qWarning("sorted! %d cat", cat);
OTodoXMLVector vector(m_events.count(), asc,sortOrder );
QMap<int, OTodo>::Iterator it;
int item = 0;
bool bCat = sortFilter & 1 ? true : false;
bool bOnly = sortFilter & 2 ? true : false;
bool comp = sortFilter & 4 ? true : false;
for ( it = m_events.begin(); it != m_events.end(); ++it ) {
/* show category */
if ( bCat && cat != 0)
if (!(*it).categories().contains( cat ) ) {
qWarning("category mis match");
continue;
}
/* isOverdue but we should not show overdue - why?*/
/* if ( (*it).isOverdue() && !bOnly ) {
qWarning("item is overdue but !bOnly");
continue;
}
*/
if ( !(*it).isOverdue() && bOnly ) {
qWarning("item is not overdue but bOnly checked");
continue;
}
if ((*it).isCompleted() && comp ) {
qWarning("completed continue!");
continue;
}
OTodoXMLContainer* con = new OTodoXMLContainer();
con->todo = (*it);
vector.insert(item, con );
item++;
}
qWarning("XXX %d Items added", item);
vector.resize( item );
/* sort it now */
vector.sort();
/* now get the uids */
QArray<int> array( vector.count() );
for (uint i= 0; i < vector.count(); i++ ) {
array[i] = ( vector.at(i) )->todo.uid();
}
qWarning("array count = %d %d", array.count(), vector.count() );
return array;
};
+void OTodoAccessXML::removeAllCompleted() {
+ for ( QMap<int, OTodo>::Iterator it = m_events.begin(); it != m_events.end(); ++it ) {
+ if ( (*it).isCompleted() )
+ m_events.remove( it );
+ }
+}
diff --git a/libopie2/opiepim/backend/otodoaccessxml.h b/libopie2/opiepim/backend/otodoaccessxml.h
index dc41c32..93609fe 100644
--- a/libopie2/opiepim/backend/otodoaccessxml.h
+++ b/libopie2/opiepim/backend/otodoaccessxml.h
@@ -1,56 +1,57 @@
#ifndef OPIE_TODO_ACCESS_XML_H
#define OPIE_TODO_ACCESS_XML_H
#include <qasciidict.h>
#include <qmap.h>
#include "otodoaccessbackend.h"
namespace Opie {
class XMLElement;
};
class OTodoAccessXML : public OTodoAccessBackend {
public:
/**
* fileName if Empty we will use the default path
*/
OTodoAccessXML( const QString& appName,
const QString& fileName = QString::null );
~OTodoAccessXML();
bool load();
bool reload();
bool save();
QArray<int> allRecords()const;
QArray<int> queryByExample( const OTodo&, int querysettings );
OTodo find( int uid )const;
void clear();
bool add( const OTodo& );
bool remove( int uid );
+ void removeAllCompleted();
bool replace( const OTodo& );
/* our functions */
QArray<int> effectiveToDos( const QDate& start,
const QDate& end,
bool includeNoDates );
QArray<int> overDue();
QArray<int> sorted( bool asc, int sortOrder,
int sortFilter, int cat );
private:
void todo( QAsciiDict<int>*, OTodo&,const QCString&,const QString& );
QString toString( const OTodo& )const;
QString toString( const QArray<int>& ints ) const;
QMap<int, OTodo> m_events;
QString m_file;
QString m_app;
bool m_opened : 1;
bool m_changed : 1;
class OTodoAccessXMLPrivate;
OTodoAccessXMLPrivate* d;
int m_year, m_month, m_day;
};
#endif
diff --git a/libopie2/opiepim/core/opimaccesstemplate.h b/libopie2/opiepim/core/opimaccesstemplate.h
index 6de68b1..8cf81c8 100644
--- a/libopie2/opiepim/core/opimaccesstemplate.h
+++ b/libopie2/opiepim/core/opimaccesstemplate.h
@@ -1,259 +1,269 @@
#ifndef OPIE_PIM_ACCESS_TEMPLATE_H
#define OPIE_PIM_ACCESS_TEMPLATE_H
#include <qarray.h>
#include <opie/opimrecord.h>
#include <opie/opimaccessbackend.h>
#include <opie/orecordlist.h>
#include "opimcache.h"
#include "otemplatebase.h"
/**
* Thats the frontend to our OPIE PIM
* Library. Either you want to use it's
* interface or you want to implement
* your own Access lib
* Just create a OPimRecord and inherit from
* the plugins
*/
template <class T = OPimRecord >
class OPimAccessTemplate : public OTemplateBase<T> {
public:
typedef ORecordList<T> List;
typedef OPimAccessBackend<T> BackEnd;
typedef OPimCache<T> Cache;
/**
* c'tor BackEnd
*/
OPimAccessTemplate( BackEnd* end);
virtual ~OPimAccessTemplate();
/**
* load from the backend
*/
virtual bool load();
/** Reload database.
* You should execute this function if the external database
* was changed.
* This function will load the external database and afterwards
* rejoin the local changes. Therefore the local database will be set consistent.
*/
virtual bool reload();
/** Save contacts database.
* Save is more a "commit". After calling this function, all changes are public available.
* @return true if successful
*/
virtual bool save();
/**
* if the resource was changed externally
* You should use the signal handling instead of polling possible changes !
* zecke: Do you implement a signal for otodoaccess ?
*/
bool wasChangedExternally()const;
/**
* return a List of records
* you can iterate over them
*/
virtual List allRecords()const;
/**
* queryByExample.
* @see otodoaccess, ocontactaccess
*/
virtual List queryByExample( const T& t, int querySettings );
/**
* find the OPimRecord uid
*/
virtual T find( int uid )const;
/**
* read ahead cache find method ;)
*/
virtual T find( int uid, const QArray<int>&,
uint current, typename OTemplateBase<T>::CacheDirection dir = OTemplateBase<T>::Forward )const;
/* invalidate cache here */
/**
* clears the backend and invalidates the backend
*/
virtual void clear() ;
/**
* add T to the backend
* @param t The item to add.
* @return <i>true</i> if added successfully.
*/
virtual bool add( const T& t ) ;
+ bool add( const OPimRecord& );
/* only the uid matters */
/**
* remove T from the backend
* @param t The item to remove
* @return <i>true</i> if successful.
*/
virtual bool remove( const T& t );
/**
* remove the OPimRecord with uid
* @param uid The ID of the item to remove
* @return <i>true</i> if successful.
*/
virtual bool remove( int uid );
/**
* replace T from backend
* @param t The item to replace
* @return <i>true</i> if successful.
*/
virtual bool replace( const T& t) ;
void setReadAhead( uint count );
/**
* @internal
*/
void cache( const T& )const;
void setSaneCacheSize( int );
protected:
/**
* invalidate the cache
*/
void invalidateCache();
void setBackEnd( BackEnd* end );
/**
* returns the backend
*/
BackEnd* backEnd();
BackEnd* m_backEnd;
Cache m_cache;
};
template <class T>
OPimAccessTemplate<T>::OPimAccessTemplate( BackEnd* end )
: OTemplateBase<T>(), m_backEnd( end )
{
if (end )
end->setFrontend( this );
}
template <class T>
OPimAccessTemplate<T>::~OPimAccessTemplate() {
qWarning("~OPimAccessTemplate<T>");
delete m_backEnd;
}
template <class T>
bool OPimAccessTemplate<T>::load() {
invalidateCache();
return m_backEnd->load();
}
template <class T>
bool OPimAccessTemplate<T>::reload() {
invalidateCache(); // zecke: I think this should be added (se)
return m_backEnd->reload();
}
template <class T>
bool OPimAccessTemplate<T>::save() {
return m_backEnd->save();
}
template <class T>
typename OPimAccessTemplate<T>::List OPimAccessTemplate<T>::allRecords()const {
QArray<int> ints = m_backEnd->allRecords();
List lis(ints, this );
return lis;
}
template <class T>
typename OPimAccessTemplate<T>::List
OPimAccessTemplate<T>::queryByExample( const T& t, int sortOrder ) {
QArray<int> ints = m_backEnd->queryByExample( t, sortOrder );
List lis(ints, this );
return lis;
}
template <class T>
T OPimAccessTemplate<T>::find( int uid ) const{
T t = m_backEnd->find( uid );
cache( t );
return t;
}
template <class T>
T OPimAccessTemplate<T>::find( int uid, const QArray<int>& ar,
uint current, typename OTemplateBase<T>::CacheDirection dir )const {
/*
* better do T.isEmpty()
* after a find this way we would
* avoid two finds in QCache...
*/
// qWarning("find it now %d", uid );
if (m_cache.contains( uid ) ) {
return m_cache.find( uid );
}
T t = m_backEnd->find( uid, ar, current, dir );
cache( t );
return t;
}
template <class T>
void OPimAccessTemplate<T>::clear() {
invalidateCache();
m_backEnd->clear();
}
template <class T>
bool OPimAccessTemplate<T>::add( const T& t ) {
cache( t );
return m_backEnd->add( t );
}
template <class T>
+bool OPimAccessTemplate<T>::add( const OPimRecord& rec) {
+ /* same type */
+ if ( rec.rtti() == T::rtti() ) {
+ const T &t = static_cast<const T&>(rec);
+ return add(t);
+ }
+ return false;
+}
+template <class T>
bool OPimAccessTemplate<T>::remove( const T& t ) {
return remove( t.uid() );
}
template <class T>
bool OPimAccessTemplate<T>::remove( int uid ) {
m_cache.remove( uid );
return m_backEnd->remove( uid );
}
template <class T>
bool OPimAccessTemplate<T>::replace( const T& t ) {
m_cache.replace( t );
return m_backEnd->replace( t );
}
template <class T>
void OPimAccessTemplate<T>::invalidateCache() {
m_cache.invalidate();
}
template <class T>
typename OPimAccessTemplate<T>::BackEnd* OPimAccessTemplate<T>::backEnd() {
return m_backEnd;
}
template <class T>
bool OPimAccessTemplate<T>::wasChangedExternally()const {
return false;
}
template <class T>
void OPimAccessTemplate<T>::setBackEnd( BackEnd* end ) {
m_backEnd = end;
if (m_backEnd )
m_backEnd->setFrontend( this );
}
template <class T>
void OPimAccessTemplate<T>::cache( const T& t ) const{
/* hacky we need to work around the const*/
((OPimAccessTemplate<T>*)this)->m_cache.add( t );
}
template <class T>
void OPimAccessTemplate<T>::setSaneCacheSize( int size ) {
m_cache.setSize( size );
}
template <class T>
void OPimAccessTemplate<T>::setReadAhead( uint count ) {
m_backEnd->setReadAhead( count );
}
#endif
diff --git a/libopie2/opiepim/core/opimmaintainer.cpp b/libopie2/opiepim/core/opimmaintainer.cpp
index e34f035..92cb25a 100644
--- a/libopie2/opiepim/core/opimmaintainer.cpp
+++ b/libopie2/opiepim/core/opimmaintainer.cpp
@@ -1,37 +1,37 @@
#include "opimmaintainer.h"
-OPimMaintainer::OPimMaintainer( enum Mode mode, int uid )
+OPimMaintainer::OPimMaintainer( int mode, int uid )
: m_mode(mode), m_uid(uid )
{}
OPimMaintainer::~OPimMaintainer() {
}
OPimMaintainer::OPimMaintainer( const OPimMaintainer& main ) {
*this = main;
}
OPimMaintainer &OPimMaintainer::operator=( const OPimMaintainer& main ) {
m_mode = main.m_mode;
m_uid = main.m_uid;
return *this;
}
bool OPimMaintainer::operator==( const OPimMaintainer& main ) {
if (m_mode != main.m_mode ) return false;
if (m_uid != main.m_uid ) return false;
return true;
}
bool OPimMaintainer::operator!=( const OPimMaintainer& main ) {
return !(*this == main );
}
-OPimMaintainer::Mode OPimMaintainer::mode()const {
+int OPimMaintainer::mode()const {
return m_mode;
}
int OPimMaintainer::uid()const {
return m_uid;
}
-void OPimMaintainer::setMode( enum Mode mo) {
+void OPimMaintainer::setMode( int mo) {
m_mode = mo;
}
void OPimMaintainer::setUid( int uid ) {
m_uid = uid;
}
diff --git a/libopie2/opiepim/core/opimmaintainer.h b/libopie2/opiepim/core/opimmaintainer.h
index 310e15a..793d066 100644
--- a/libopie2/opiepim/core/opimmaintainer.h
+++ b/libopie2/opiepim/core/opimmaintainer.h
@@ -1,36 +1,40 @@
#ifndef OPIE_PIM_MAINTAINER_H
#define OPIE_PIM_MAINTAINER_H
#include <qstring.h>
/**
* Who maintains what?
*/
class OPimMaintainer {
public:
enum Mode { Undefined = -1,
- Responsible = 0,
+ Nothing = 0,
+ Responsible,
DoneBy,
- Coordinating };
- OPimMaintainer( enum Mode mode = Undefined, int uid = 0);
+ Coordinating,
+ };
+ OPimMaintainer( int mode = Undefined, int uid = 0);
OPimMaintainer( const OPimMaintainer& );
~OPimMaintainer();
OPimMaintainer &operator=( const OPimMaintainer& );
bool operator==( const OPimMaintainer& );
bool operator!=( const OPimMaintainer& );
- Mode mode()const;
+ int mode()const;
int uid()const;
- void setMode( enum Mode );
+ void setMode( int mode );
void setUid( int uid );
private:
- Mode m_mode;
+ int m_mode;
int m_uid;
+ class Private;
+ Private *d;
};
#endif
diff --git a/libopie2/opiepim/core/opimnotify.cpp b/libopie2/opiepim/core/opimnotify.cpp
new file mode 100644
index 0000000..af5514b
--- a/dev/null
+++ b/libopie2/opiepim/core/opimnotify.cpp
@@ -0,0 +1,227 @@
+#include <qshared.h>
+
+#include "opimnotify.h"
+
+struct OPimNotify::Data : public QShared {
+ Data() : QShared(),dur(-1),parent(0) {
+
+ }
+ QDateTime start;
+ int dur;
+ QString application;
+ int parent;
+};
+
+OPimNotify::OPimNotify( const QDateTime& start, int duration, int parent ) {
+ data = new Data;
+ data->start = start;
+ data->dur = duration;
+ data->parent = parent;
+}
+OPimNotify::OPimNotify( const OPimNotify& noti)
+ : data( noti.data )
+{
+ data->ref();
+}
+OPimNotify::~OPimNotify() {
+ if ( data->deref() ) {
+ delete data;
+ data = 0l;
+ }
+}
+
+OPimNotify &OPimNotify::operator=( const OPimNotify& noti) {
+ noti.data->ref();
+ deref();
+ data = noti.data;
+
+ return *this;
+}
+bool OPimNotify::operator==( const OPimNotify& noti ) {
+ if ( data == noti.data ) return true;
+ if ( data->dur != noti.data->dur ) return false;
+ if ( data->parent != noti.data->parent ) return false;
+ if ( data->application != noti.data->application ) return false;
+ if ( data->start != noti.data->start ) return false;
+
+ return true;
+}
+QDateTime OPimNotify::dateTime()const {
+ return data->start;
+}
+QString OPimNotify::service()const {
+ return data->application;
+}
+int OPimNotify::parent()const {
+ return data->parent;
+}
+int OPimNotify::duration()const {
+ return data->dur;
+}
+QDateTime OPimNotify::endTime()const {
+ return QDateTime( data->start.date(), data->start.time().addSecs( data->dur) );
+}
+void OPimNotify::setDateTime( const QDateTime& time ) {
+ copyIntern();
+ data->start = time;
+}
+void OPimNotify::setDuration( int dur ) {
+ copyIntern();
+ data->dur = dur;
+}
+void OPimNotify::setParent( int uid ) {
+ copyIntern();
+ data->parent = uid;
+}
+void OPimNotify::setService( const QString& str ) {
+ copyIntern();
+ data->application = str;
+}
+void OPimNotify::copyIntern() {
+ if ( data->count != 1 ) {
+ data->deref();
+ Data* dat = new Data;
+ dat->start = data->start;
+ dat->dur = data->dur;
+ dat->application = data->application;
+ dat->parent = data->parent;
+ data = dat;
+ }
+}
+void OPimNotify::deref() {
+ if ( data->deref() ) {
+ delete data;
+ data = 0;
+ }
+}
+
+/***********************************************************/
+struct OPimAlarm::Data : public QShared {
+ Data() : QShared() {
+ sound = 1;
+ }
+ int sound;
+ QString file;
+};
+OPimAlarm::OPimAlarm( int sound, const QDateTime& start, int duration, int parent )
+ : OPimNotify( start, duration, parent )
+{
+ data = new Data;
+ data->sound = sound;
+}
+OPimAlarm::OPimAlarm( const OPimAlarm& al)
+ : OPimNotify(al), data( al.data )
+{
+ data->ref();
+}
+OPimAlarm::~OPimAlarm() {
+ if ( data->deref() ) {
+ delete data;
+ data = 0l;
+ }
+}
+OPimAlarm &OPimAlarm::operator=( const OPimAlarm& al)
+{
+ OPimNotify::operator=( al );
+ deref();
+ al.data->ref();
+
+ data = al.data;
+
+
+ return *this;
+}
+bool OPimAlarm::operator==( const OPimAlarm& al) {
+ if ( data->sound != al.data->sound ) return false;
+ else if ( data->sound == Custom && data->file != al.data->file )
+ return false;
+
+ return OPimNotify::operator==( al );
+}
+QString OPimAlarm::type()const {
+ return QString::fromLatin1("OPimAlarm");
+}
+int OPimAlarm::sound()const {
+ return data->sound;
+}
+QString OPimAlarm::file()const {
+ return data->file;
+}
+void OPimAlarm::setSound( int snd) {
+ copyIntern();
+ data->sound = snd;
+}
+void OPimAlarm::setFile( const QString& sound ) {
+ copyIntern();
+ data->file = sound;
+}
+void OPimAlarm::deref() {
+ if ( data->deref() ) {
+ delete data;
+ data = 0l;
+ }
+}
+void OPimAlarm::copyIntern() {
+ if ( data->count != 1 ) {
+ data->deref();
+ Data *newDat = new Data;
+ newDat->sound = data->sound;
+ newDat->file = data->file;
+ data = newDat;
+ }
+}
+/************************/
+struct OPimReminder::Data : public QShared {
+ Data() : QShared(), record( 0) {
+ }
+ int record;
+
+};
+OPimReminder::OPimReminder( int uid, const QDateTime& start, int dur, int parent )
+ : OPimNotify( start, dur, parent )
+{
+ data = new Data;
+ data->record = uid;
+}
+OPimReminder::OPimReminder( const OPimReminder& rem )
+ : OPimNotify( rem ), data( rem.data )
+{
+ data->ref();
+}
+OPimReminder& OPimReminder::operator=( const OPimReminder& rem) {
+ OPimNotify::operator=(rem );
+
+ deref();
+ rem.data->ref();
+ data = rem.data;
+
+ return *this;
+}
+bool OPimReminder::operator==( const OPimReminder& rem) {
+ if ( data->record != rem.data->record ) return false;
+
+ return OPimNotify::operator==( rem );
+}
+QString OPimReminder::type()const {
+ return QString::fromLatin1("OPimReminder");
+}
+int OPimReminder::recordUid()const {
+ return data->record;
+}
+void OPimReminder::setRecordUid( int uid ) {
+ copyIntern();
+ data->record = uid;
+}
+void OPimReminder::deref() {
+ if ( data->deref() ) {
+ delete data;
+ data = 0l;
+ }
+}
+void OPimReminder::copyIntern() {
+ if ( data->count != 1 ) {
+ Data* da = new Data;
+ da->record = data->record;
+ data = da;
+ }
+}
diff --git a/libopie2/opiepim/core/opimnotify.h b/libopie2/opiepim/core/opimnotify.h
new file mode 100644
index 0000000..3501948
--- a/dev/null
+++ b/libopie2/opiepim/core/opimnotify.h
@@ -0,0 +1,142 @@
+#ifndef OPIE_PIM_NOTIFY_H
+#define OPIE_PIM_NOTIFY_H
+
+#include <qdatetime.h>
+#include <qvaluelist.h>
+
+/**
+ * This is the base class of Notifiers. Possible
+ * notifiers would be Alarms, Reminders
+ * What they share is that they have
+ * A DateTime, Type, Duration
+ * This is what this base class takes care of
+ * on top of that it's shared
+ */
+/*
+ * TALK to eilers: have a class OPimDuration which sets the Duration
+ * given on the Due/Start Date? -zecke
+ * discuss: do we need a uid for the notify? -zecke
+ */
+class OPimNotify {
+public:
+ typedef QValueList<OPimNotify> ValueList;
+ OPimNotify( const QDateTime& start = QDateTime(), int duration = 0, int parent = 0 );
+ OPimNotify( const OPimNotify& );
+ virtual ~OPimNotify();
+
+ OPimNotify &operator=(const OPimNotify& );
+ bool operator==( const OPimNotify& );
+
+ virtual QString type()const = 0;
+
+ /** start date */
+ QDateTime dateTime()const;
+ QString service()const;
+
+ /**
+ * RETURN the parent uid
+ */
+ int parent()const;
+
+ /**
+ * in Seconds
+ */
+ int duration()const;
+
+ /**
+ * Start Time + Duration
+ */
+ QDateTime endTime()const;
+
+ void setDateTime( const QDateTime& );
+ void setDuration( int dur );
+ void setParent(int uid );
+ void setService( const QString& );
+
+
+private:
+ inline void copyIntern();
+ void deref();
+ struct Data;
+ Data* data;
+
+ /* d-pointer */
+ class NotifyPrivate;
+ NotifyPrivate* d;
+
+};
+/**
+ * An alarm is a sound/mail/buzzer played/send
+ * at a given time to inform about
+ * an Event
+ */
+class OPimAlarm : public OPimNotify {
+public:
+ enum Sound{Loud=0, Silent, Custom };
+ OPimAlarm( int sound = Silent, const QDateTime& start = QDateTime(), int duration = 0, int parent = 0 );
+ OPimAlarm( const OPimAlarm& );
+ ~OPimAlarm();
+
+ OPimAlarm &operator=( const OPimAlarm& );
+ bool operator==( const OPimAlarm& );
+ QString type()const;
+
+ int sound()const;
+ QString file()const;
+
+ void setSound( int );
+ /* only when sound is custom... */
+ void setFile( const QString& sound );
+
+private:
+ void deref();
+ void copyIntern();
+ struct Data;
+ Data * data;
+
+ class Private;
+ Private* d;
+
+};
+
+/**
+ * A Reminder will be put into the
+ * datebook
+ */
+class OPimReminder : public OPimNotify {
+public:
+
+ /**
+ * c'tor of a reminder
+ * @param uid The uid of the Record inside the Datebook
+ * @param start the StartDate invalid for all day...
+ * @param duration The duration of the event ( -1 for all day )
+ * @param parent The 'parent' record of this reminder
+ */
+ OPimReminder( int uid = 0, const QDateTime& start = QDateTime(),
+ int duration = 0, int parent = 0 );
+ OPimReminder( const OPimReminder& );
+ OPimReminder &operator=(const OPimReminder& );
+
+ QString type()const;
+
+ bool operator==( const OPimReminder& );
+
+ /**
+ * the uid of the alarm
+ * inside the 'datebook' application
+ */
+ int recordUid()const;
+ void setRecordUid( int uid );
+
+private:
+ void deref();
+ void copyIntern();
+
+ struct Data;
+ Data* data;
+ class Private;
+ Private *d;
+};
+
+#endif
diff --git a/libopie2/opiepim/core/opimnotifymanager.cpp b/libopie2/opiepim/core/opimnotifymanager.cpp
new file mode 100644
index 0000000..be4a1c2
--- a/dev/null
+++ b/libopie2/opiepim/core/opimnotifymanager.cpp
@@ -0,0 +1,69 @@
+#include "opimnotifymanager.h"
+
+OPimNotifyManager::OPimNotifyManager( const Reminders& rem, const Alarms& al)
+ : m_rem( rem ), m_al( al )
+{}
+OPimNotifyManager::~OPimNotifyManager() {
+}
+/* use static_cast and type instead of dynamic... */
+void OPimNotifyManager::add( const OPimNotify& noti) {
+ if ( noti.type() == QString::fromLatin1("OPimReminder") ) {
+ const OPimReminder& rem = static_cast<const OPimReminder&>(noti);
+ m_rem.append( rem );
+ }else if ( noti.type() == QString::fromLatin1("OPimAlarm") ) {
+ const OPimAlarm& al = static_cast<const OPimAlarm&>(noti);
+ m_al.append( al );
+ }
+}
+void OPimNotifyManager::remove( const OPimNotify& noti) {
+ if ( noti.type() == QString::fromLatin1("OPimReminder") ) {
+ const OPimReminder& rem = static_cast<const OPimReminder&>(noti);
+ m_rem.remove( rem );
+ }else if ( noti.type() == QString::fromLatin1("OPimAlarm") ) {
+ const OPimAlarm& al = static_cast<const OPimAlarm&>(noti);
+ m_al.remove( al );
+ }
+}
+void OPimNotifyManager::replace( const OPimNotify& noti) {
+ if ( noti.type() == QString::fromLatin1("OPimReminder") ) {
+ const OPimReminder& rem = static_cast<const OPimReminder&>(noti);
+ m_rem.remove( rem );
+ m_rem.append( rem );
+ }else if ( noti.type() == QString::fromLatin1("OPimAlarm") ) {
+ const OPimAlarm& al = static_cast<const OPimAlarm&>(noti);
+ m_al.remove( al );
+ m_al.append( al );
+ }
+}
+OPimNotifyManager::Reminders OPimNotifyManager::reminders()const {
+ return m_rem;
+}
+OPimNotifyManager::Alarms OPimNotifyManager::alarms()const {
+ return m_al;
+}
+void OPimNotifyManager::setAlarms( const Alarms& al) {
+ m_al = al;
+}
+void OPimNotifyManager::setReminders( const Reminders& rem) {
+ m_rem = rem;
+}
+/* FIXME!!! */
+/**
+ * The idea is to check if the provider for our service
+ * is online
+ * if it is we will use QCOP
+ * if not the Factory to get the backend...
+ * Qtopia1.6 services would be kewl to have here....
+ */
+void OPimNotifyManager::registerNotify( const OPimNotify& ) {
+
+}
+/* FIXME!!! */
+/**
+ * same as above...
+ * Also implement Url model
+ * have a MainWindow....
+ */
+void OPimNotifyManager::deregister( const OPimNotify& ) {
+
+}
diff --git a/libopie2/opiepim/core/opimnotifymanager.h b/libopie2/opiepim/core/opimnotifymanager.h
new file mode 100644
index 0000000..0eebc9b
--- a/dev/null
+++ b/libopie2/opiepim/core/opimnotifymanager.h
@@ -0,0 +1,51 @@
+#ifndef OPIE_PIM_NOTIFY_MANAGER_H
+#define OPIE_PIM_NOTIFY_MANAGER_H
+
+#include <qvaluelist.h>
+
+#include <opie/opimnotify.h>
+
+/**
+ * The notify manager keeps track of the Notifiers....
+ */
+class OPimNotifyManager {
+public:
+ typedef QValueList<OPimReminder> Reminders;
+ typedef QValueList<OPimAlarm> Alarms;
+ OPimNotifyManager( const Reminders& rems = Reminders(), const Alarms& alarms = Alarms() );
+ ~OPimNotifyManager();
+
+ /* we will cast it for you ;) */
+ void add( const OPimNotify& );
+ void remove( const OPimNotify& );
+ /* replaces all with this one! */
+ void replace( const OPimNotify& );
+
+ Reminders reminders()const;
+ Alarms alarms()const;
+
+ void setAlarms( const Alarms& );
+ void setReminders( const Reminders& );
+
+ /* register is a Ansi C keyword... */
+ /**
+ * This function will register the Notify to the Alarm Server
+ * or datebook depending on the type of the notify
+ */
+ void registerNotify( const OPimNotify& );
+
+ /**
+ * this will do the opposite..
+ */
+ void deregister( const OPimNotify& );
+
+private:
+ Reminders m_rem;
+ Alarms m_al;
+
+ class Private;
+ Private *d;
+
+};
+
+#endif
diff --git a/libopie2/opiepim/core/opimrecord.cpp b/libopie2/opiepim/core/opimrecord.cpp
index 0e3be9d..49b5bf9 100644
--- a/libopie2/opiepim/core/opimrecord.cpp
+++ b/libopie2/opiepim/core/opimrecord.cpp
@@ -1,81 +1,84 @@
#include <qpe/categories.h>
#include <qpe/categoryselect.h>
#include "opimrecord.h"
Qtopia::UidGen OPimRecord::m_uidGen( Qtopia::UidGen::Qtopia );
OPimRecord::OPimRecord( int uid )
: Qtopia::Record() {
setUid( uid );
}
OPimRecord::~OPimRecord() {
}
OPimRecord::OPimRecord( const OPimRecord& rec )
: Qtopia::Record( rec )
{
(*this) = rec;
}
OPimRecord &OPimRecord::operator=( const OPimRecord& rec) {
Qtopia::Record::operator=( rec );
m_xrefman = rec.m_xrefman;
return *this;
}
/*
* category names
*/
QStringList OPimRecord::categoryNames()const {
QStringList list;
QArray<int> cats = categories();
Categories catDB;
catDB.load( categoryFileName() );
for (uint i = 0; i < cats.count(); i++ ) {
list << catDB.label("Todo List", cats[i] );
}
return list;
}
void OPimRecord::setCategoryNames( const QStringList& ) {
}
void OPimRecord::addCategoryName( const QString& ) {
Categories catDB;
catDB.load( categoryFileName() );
}
bool OPimRecord::isEmpty()const {
return ( uid() == 0 );
}
/*QString OPimRecord::crossToString()const {
QString str;
QMap<QString, QArray<int> >::ConstIterator it;
for (it = m_relations.begin(); it != m_relations.end(); ++it ) {
QArray<int> id = it.data();
for ( uint i = 0; i < id.size(); ++i ) {
str += it.key() + "," + QString::number( i ) + ";";
}
}
str = str.remove( str.length()-1, 1); // strip the ;
//qWarning("IDS " + str );
return str;
}*/
/* if uid = 1 assign a new one */
void OPimRecord::setUid( int uid ) {
if ( uid == 1)
uid = uidGen().generate();
Qtopia::Record::setUid( uid );
};
Qtopia::UidGen &OPimRecord::uidGen() {
return m_uidGen;
}
OPimXRefManager &OPimRecord::xrefmanager() {
return m_xrefman;
}
+int OPimRecord::rtti(){
+ return 0;
+}
diff --git a/libopie2/opiepim/core/opimrecord.h b/libopie2/opiepim/core/opimrecord.h
index 1642a5e..ec99a13 100644
--- a/libopie2/opiepim/core/opimrecord.h
+++ b/libopie2/opiepim/core/opimrecord.h
@@ -1,116 +1,122 @@
#ifndef OPIE_PIM_RECORD_H
#define OPIE_PIM_RECORD_H
#include <qmap.h>
#include <qstring.h>
#include <qstringlist.h>
#include <qpe/palmtoprecord.h>
#include <opie/opimxrefmanager.h>
/**
* This is the base class for
* all PIM Records
*
*/
class OPimRecord : public Qtopia::Record {
public:
/**
* c'tor
* uid of 0 isEmpty
* uid of 1 will be assigned a new one
*/
OPimRecord(int uid = 0);
~OPimRecord();
/**
* copy c'tor
*/
OPimRecord( const OPimRecord& rec );
/**
* copy operator
*/
OPimRecord &operator=( const OPimRecord& );
/**
* category names resolved
*/
QStringList categoryNames()const;
/**
* set category names they will be resolved
*/
void setCategoryNames( const QStringList& );
/**
* addCategoryName adds a name
* to the internal category list
*/
void addCategoryName( const QString& );
/**
* if a Record isEmpty
* it's empty if it's 0
*/
virtual bool isEmpty()const;
/**
* toRichText summary
*/
virtual QString toRichText()const = 0;
/**
* a small one line summary
*/
virtual QString toShortText()const = 0;
/**
* the name of the Record
*/
virtual QString type()const = 0;
/**
* converts the internal structure to a map
*/
virtual QMap<int, QString> toMap()const = 0;
/**
* key value representation of extra items
*/
virtual QMap<QString, QString> toExtraMap()const = 0;
/**
* the name for a recordField
*/
virtual QString recordField(int)const = 0;
/**
* returns a reference of the
* Cross Reference Manager
- * Partner One is THIS PIM RECORD!
- * Two is the Partner where we link to
+ * Partner 'One' is THIS PIM RECORD!
+ * 'Two' is the Partner where we link to
*/
OPimXRefManager& xrefmanager();
/**
* set the uid
*/
virtual void setUid( int uid );
+ /*
+ * used inside the Templates for casting
+ * REIMPLEMENT in your ....
+ */
+ static int rtti();
+
protected:
Qtopia::UidGen &uidGen();
// QString crossToString()const;
private:
class OPimRecordPrivate;
OPimRecordPrivate *d;
OPimXRefManager m_xrefman;
static Qtopia::UidGen m_uidGen;
};
#endif
diff --git a/libopie2/opiepim/core/opimresolver.h b/libopie2/opiepim/core/opimresolver.h
new file mode 100644
index 0000000..86ae3eb
--- a/dev/null
+++ b/libopie2/opiepim/core/opimresolver.h
@@ -0,0 +1,56 @@
+#ifndef OPIE_PIM_RESOLVER
+#define OPIE_PIM_RESOLVER
+
+#include <qstring.h>
+#include <qvaluelist.h>
+
+/**
+ * OPimResolver is a MetaClass to access
+ * available backends read only.
+ * It will be used to resolve uids + app names
+ * to full informations
+ * to traverse through a list of alarms, reminders
+ * to get access to built in PIM functionality
+ * and to more stuff
+ * THE PERFORMANCE will depend on THE BACKEND
+ * USING XML is a waste of memory!!!!!
+ */
+class OPimResolver : public QObject {
+public:
+ enum BuiltIn { TodoList = 0,
+ DateBook,
+ AddressBook
+ };
+ static OPimResolver* self();
+
+
+ /*
+ * return a record for a uid
+ * and an app
+ */
+ OPimRecord &record( const QString& service, int uid );
+
+ /**
+ * return the QCopChannel for service
+ * When we will use Qtopia Services it will be used here
+ */
+ QString qcopChannel( enum BuiltIn& )const;
+ QString qcopChannel( const QString& service );
+
+ /**
+ * return a list of available services
+ */
+ QStringList services()const;
+
+ /**
+ * add a record to a service... ;)
+ */
+ bool add( const QString& service, const OPimRecord& );
+
+private:
+ OPimResolver();
+ OPimRecord *m_last;
+
+}:
+
+#endif
diff --git a/libopie2/opiepim/core/opimxref.cpp b/libopie2/opiepim/core/opimxref.cpp
index 5cae871..8eefbd8 100644
--- a/libopie2/opiepim/core/opimxref.cpp
+++ b/libopie2/opiepim/core/opimxref.cpp
@@ -1,47 +1,47 @@
#include "opimxref.h"
OPimXRef::OPimXRef( const OPimXRefPartner& one, const OPimXRefPartner& two )
: m_partners(2)
{
m_partners[0] = one;
m_partners[1] = two;
}
OPimXRef::OPimXRef()
: m_partners(2)
{
}
OPimXRef::OPimXRef( const OPimXRef& ref) {
*this = ref;
}
OPimXRef::~OPimXRef() {
}
OPimXRef &OPimXRef::operator=( const OPimXRef& ref) {
m_partners = ref.m_partners;
m_partners.detach();
return* this;
}
bool OPimXRef::operator==( const OPimXRef& oper ) {
if ( m_partners == oper.m_partners ) return true;
return false;
}
OPimXRefPartner OPimXRef::partner( enum Partners par) const{
return m_partners[par];
}
void OPimXRef::setPartner( enum Partners par, const OPimXRefPartner& part) {
m_partners[par] = part;
}
bool OPimXRef::containsString( const QString& string ) const{
- if ( m_partners[One].appName() == string ||
- m_partners[Two].appName() == string ) return true;
+ if ( m_partners[One].service() == string ||
+ m_partners[Two].service() == string ) return true;
return false;
}
bool OPimXRef::containsUid( int uid ) const{
if ( m_partners[One].uid() == uid ||
m_partners[Two].uid() == uid ) return true;
return false;
}
diff --git a/libopie2/opiepim/core/opimxref.h b/libopie2/opiepim/core/opimxref.h
index 354739a..6852651 100644
--- a/libopie2/opiepim/core/opimxref.h
+++ b/libopie2/opiepim/core/opimxref.h
@@ -1,39 +1,39 @@
#ifndef OPIM_XREF_H
#define OPIM_XREF_H
#include <qarray.h>
#include <qvaluelist.h>
#include <opie/opimxrefpartner.h>
/**
* this is a Cross Referecne between
* two Cross Reference Partners
*/
class OPimXRef {
public:
typedef QValueList<OPimXRef> ValueList;
enum Partners { One, Two };
OPimXRef( const OPimXRefPartner& ONE, const OPimXRefPartner& );
OPimXRef();
OPimXRef( const OPimXRef& );
~OPimXRef();
OPimXRef &operator=( const OPimXRef& );
bool operator==( const OPimXRef& );
OPimXRefPartner partner( enum Partners )const;
void setPartner( enum Partners, const OPimXRefPartner& );
- bool containsString( const QString& appName)const;
+ bool containsString( const QString& service)const;
bool containsUid( int uid )const;
private:
QArray<OPimXRefPartner> m_partners;
class Private;
Private *d;
};
#endif
diff --git a/libopie2/opiepim/core/opimxrefmanager.cpp b/libopie2/opiepim/core/opimxrefmanager.cpp
index 965f542..58bfd24 100644
--- a/libopie2/opiepim/core/opimxrefmanager.cpp
+++ b/libopie2/opiepim/core/opimxrefmanager.cpp
@@ -1,71 +1,71 @@
#include "opimxrefmanager.h"
OPimXRefManager::OPimXRefManager() {
}
OPimXRefManager::OPimXRefManager( const OPimXRefManager& ref) {
m_list = ref.m_list;
}
OPimXRefManager::~OPimXRefManager() {
}
OPimXRefManager &OPimXRefManager::operator=( const OPimXRefManager& ref) {
m_list = ref.m_list;
return *this;
}
bool OPimXRefManager::operator==( const OPimXRefManager& /*ref*/) {
// if ( m_list == ref.m_list ) return true;
return false;
}
void OPimXRefManager::add( const OPimXRef& ref) {
m_list.append( ref );
}
void OPimXRefManager::remove( const OPimXRef& ref) {
m_list.remove( ref );
}
void OPimXRefManager::replace( const OPimXRef& ref) {
m_list.remove( ref );
m_list.append( ref );
}
void OPimXRefManager::clear() {
m_list.clear();
}
QStringList OPimXRefManager::apps()const {
OPimXRef::ValueList::ConstIterator it;
QStringList list;
QString str;
for ( it = m_list.begin(); it != m_list.end(); ++it ) {
- str = (*it).partner( OPimXRef::One ).appName();
+ str = (*it).partner( OPimXRef::One ).service();
if ( !list.contains( str ) ) list << str;
- str = (*it).partner( OPimXRef::Two ).appName();
+ str = (*it).partner( OPimXRef::Two ).service();
if ( !list.contains( str ) ) list << str;
}
return list;
}
OPimXRef::ValueList OPimXRefManager::list()const {
return m_list;
}
OPimXRef::ValueList OPimXRefManager::list( const QString& appName )const{
OPimXRef::ValueList list;
OPimXRef::ValueList::ConstIterator it;
for ( it = m_list.begin(); it != m_list.end(); ++it ) {
if ( (*it).containsString( appName ) )
list.append( (*it) );
}
return list;
}
OPimXRef::ValueList OPimXRefManager::list( int uid )const {
OPimXRef::ValueList list;
OPimXRef::ValueList::ConstIterator it;
for ( it = m_list.begin(); it != m_list.end(); ++it ) {
if ( (*it).containsUid( uid ) )
list.append( (*it) );
}
return list;
}
diff --git a/libopie2/opiepim/core/opimxrefmanager.h b/libopie2/opiepim/core/opimxrefmanager.h
index 9b003a3..39e5eef 100644
--- a/libopie2/opiepim/core/opimxrefmanager.h
+++ b/libopie2/opiepim/core/opimxrefmanager.h
@@ -1,41 +1,41 @@
#ifndef OPIM_XREF_MANAGER_H
#define OPIM_XREF_MANAGER_H
#include <qstringlist.h>
#include <opie/opimxref.h>
/**
* This is a simple manager for
* OPimXRefs.
* It allows addition, removing, replacing
* clearing and 'querying' the XRef...
*/
class OPimXRefManager {
public:
OPimXRefManager();
OPimXRefManager( const OPimXRefManager& );
~OPimXRefManager();
OPimXRefManager& operator=( const OPimXRefManager& );
bool operator==( const OPimXRefManager& );
void add( const OPimXRef& );
void remove( const OPimXRef& );
void replace( const OPimXRef& );
void clear();
/**
* apps participating
*/
QStringList apps()const;
OPimXRef::ValueList list()const;
- OPimXRef::ValueList list( const QString& appName )const;
+ OPimXRef::ValueList list( const QString& service )const;
OPimXRef::ValueList list( int uid )const;
private:
OPimXRef::ValueList m_list;
};
#endif
diff --git a/libopie2/opiepim/core/opimxrefpartner.cpp b/libopie2/opiepim/core/opimxrefpartner.cpp
index 028f4e6..6ef3efb 100644
--- a/libopie2/opiepim/core/opimxrefpartner.cpp
+++ b/libopie2/opiepim/core/opimxrefpartner.cpp
@@ -1,43 +1,43 @@
#include "opimxrefpartner.h"
OPimXRefPartner::OPimXRefPartner( const QString& appName,
int uid, int field )
: m_app(appName), m_uid(uid), m_field( field ) {
}
OPimXRefPartner::OPimXRefPartner( const OPimXRefPartner& ref ) {
*this = ref;
}
OPimXRefPartner::~OPimXRefPartner() {
}
OPimXRefPartner &OPimXRefPartner::operator=( const OPimXRefPartner& par ) {
m_app = par.m_app;
m_uid = par.m_uid;
m_field = par.m_field;
return *this;
}
bool OPimXRefPartner::operator==( const OPimXRefPartner& par ) {
if ( m_app != par.m_app ) return false;
if ( m_uid != par.m_uid ) return false;
if ( m_field != par.m_field ) return false;
return true;
}
-QString OPimXRefPartner::appName()const {
+QString OPimXRefPartner::service()const {
return m_app;
}
int OPimXRefPartner::uid()const {
return m_uid;
}
int OPimXRefPartner::field()const {
return m_field;
}
-void OPimXRefPartner::setAppName( const QString& appName ) {
+void OPimXRefPartner::setService( const QString& appName ) {
m_app = appName;
}
void OPimXRefPartner::setUid( int uid ) {
m_uid = uid;
}
void OPimXRefPartner::setField( int field ) {
m_field = field;
}
diff --git a/libopie2/opiepim/core/opimxrefpartner.h b/libopie2/opiepim/core/opimxrefpartner.h
index 808b9ab..d76e384 100644
--- a/libopie2/opiepim/core/opimxrefpartner.h
+++ b/libopie2/opiepim/core/opimxrefpartner.h
@@ -1,40 +1,40 @@
#ifndef OPIM_XREF_PARTNER_H
#define OPIM_XREF_PARTNER_H
#include <qstring.h>
/**
* This class represents one partner
* of a Cross Reference.
* In Opie one application
* can link one uid
* with one tableId( fieldId ) to another.
*/
class OPimXRefPartner {
public:
- OPimXRefPartner( const QString& appName = QString::null,
+ OPimXRefPartner( const QString& service = QString::null,
int uid = 0, int field = -1 );
OPimXRefPartner( const OPimXRefPartner& );
OPimXRefPartner& operator=( const OPimXRefPartner& );
~OPimXRefPartner();
bool operator==(const OPimXRefPartner& );
- QString appName()const;
+ QString service()const;
int uid()const;
int field()const;
- void setAppName( const QString& appName );
+ void setService( const QString& service );
void setUid( int uid );
void setField( int field );
private:
QString m_app;
int m_uid;
int m_field;
class Private;
Private* d;
};
#endif
diff --git a/libopie2/opiepim/core/orecur.cpp b/libopie2/opiepim/core/orecur.cpp
index 257d4fd..daf3506 100644
--- a/libopie2/opiepim/core/orecur.cpp
+++ b/libopie2/opiepim/core/orecur.cpp
@@ -1,136 +1,451 @@
#include <qshared.h>
#include <qtopia/timeconversion.h>
#include "orecur.h"
struct ORecur::Data : public QShared {
Data() : QShared() {
type = ORecur::NoRepeat;
freq = -1;
days = 0;
pos = 0;
create = -1;
hasEnd = FALSE;
end = 0;
}
char days; // Q_UINT8 for 8 seven days;)
ORecur::RepeatType type;
int freq;
int pos;
bool hasEnd : 1;
time_t end;
time_t create;
int rep;
+ QString app;
+ ExceptionList list;
+ QDate start;
};
ORecur::ORecur() {
data = new Data;
}
ORecur::ORecur( const ORecur& rec)
: data( rec.data )
{
data->ref();
}
ORecur::~ORecur() {
if ( data->deref() ) {
delete data;
data = 0l;
}
}
void ORecur::deref() {
if ( data->deref() ) {
delete data;
data = 0l;
}
}
bool ORecur::operator==( const ORecur& )const {
return false;
}
ORecur &ORecur::operator=( const ORecur& re) {
re.data->ref();
deref();
data = re.data;
return *this;
}
+bool ORecur::doesRecur()const {
+ return !( type() == NoRepeat );
+}
+/*
+ * we try to be smart here
+ *
+ */
+bool ORecur::doesRecur( const QDate& date ) {
+ /* the day before the recurrance */
+ QDate da = date.addDays(-1);
+
+ QDate recur;
+ if (!nextOcurrence( da, recur ) )
+ return false;
+
+ return (recur == date);
+}
+// FIXME unuglify!
+// GPL from Datebookdb.cpp
+// FIXME exception list!
+bool ORecur::nextOcurrence( const QDate& from, QDate& next ) {
+
+ // easy checks, first are we too far in the future or too far in the past?
+ QDate tmpDate;
+ int freq = frequency();
+ int diff, diff2, a;
+ int iday, imonth, iyear;
+ int dayOfWeek = 0;
+ int firstOfWeek = 0;
+ int weekOfMonth;
+
+
+ if (hasEndDate() && endDate() < from)
+ return FALSE;
+
+ if (start() >= from) {
+ next = start();
+ return TRUE;
+ }
+
+ switch ( type() ) {
+ case Weekly:
+ /* weekly is just daily by 7 */
+ /* first convert the repeatPattern.Days() mask to the next
+ day of week valid after from */
+ dayOfWeek = from.dayOfWeek();
+ dayOfWeek--; /* we want 0-6, doco for above specs 1-7 */
+
+ /* this is done in case freq > 1 and from in week not
+ for this round */
+ // firstOfWeek = 0; this is already done at decl.
+ while(!((1 << firstOfWeek) & days() ))
+ firstOfWeek++;
+
+ /* there is at least one 'day', or there would be no event */
+ while(!((1 << (dayOfWeek % 7)) & days() ))
+ dayOfWeek++;
+
+ dayOfWeek = dayOfWeek % 7; /* the actual day of week */
+ dayOfWeek -= start().dayOfWeek() -1;
+
+ firstOfWeek = firstOfWeek % 7; /* the actual first of week */
+ firstOfWeek -= start().dayOfWeek() -1;
+
+ // dayOfWeek may be negitive now
+ // day of week is number of days to add to start day
+
+ freq *= 7;
+ // FALL-THROUGH !!!!!
+ case Daily:
+ // the add is for the possible fall through from weekly */
+ if(start().addDays(dayOfWeek) > from) {
+ /* first week exception */
+ next = QDate(start().addDays(dayOfWeek) );
+ if ((next > endDate())
+ && hasEndDate() )
+ return FALSE;
+ return TRUE;
+ }
+ /* if from is middle of a non-week */
+
+ diff = start().addDays(dayOfWeek).daysTo(from) % freq;
+ diff2 = start().addDays(firstOfWeek).daysTo(from) % freq;
+
+ if(diff != 0)
+ diff = freq - diff;
+ if(diff2 != 0)
+ diff2 = freq - diff2;
+ diff = QMIN(diff, diff2);
+
+ next = QDate(from.addDays(diff));
+ if ( (next > endDate())
+ && hasEndDate() )
+ return FALSE;
+ return TRUE;
+ case MonthlyDay:
+ iday = from.day();
+ iyear = from.year();
+ imonth = from.month();
+ /* find equivelent day of month for this month */
+ dayOfWeek = start().dayOfWeek();
+ weekOfMonth = (start().day() - 1) / 7;
+
+ /* work out when the next valid month is */
+ a = from.year() - start().year();
+ a *= 12;
+ a = a + (imonth - start().month());
+ /* a is e.start()monthsFrom(from); */
+ if(a % freq) {
+ a = freq - (a % freq);
+ imonth = from.month() + a;
+ if (imonth > 12) {
+ imonth--;
+ iyear += imonth / 12;
+ imonth = imonth % 12;
+ imonth++;
+ }
+ }
+ /* imonth is now the first month after or on
+ from that matches the frequency given */
+
+ /* find for this month */
+ tmpDate = QDate( iyear, imonth, 1 );
+
+ iday = 1;
+ iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7;
+ iday += 7 * weekOfMonth;
+ while (iday > tmpDate.daysInMonth()) {
+ imonth += freq;
+ if (imonth > 12) {
+ imonth--;
+ iyear += imonth / 12;
+ imonth = imonth % 12;
+ imonth++;
+ }
+ tmpDate = QDate( iyear, imonth, 1 );
+ /* these loops could go for a while, check end case now */
+ if ((tmpDate > endDate()) && hasEndDate() )
+ return FALSE;
+ iday = 1;
+ iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7;
+ iday += 7 * weekOfMonth;
+ }
+ tmpDate = QDate(iyear, imonth, iday);
+
+ if (tmpDate >= from) {
+ next = tmpDate;
+ if ((next > endDate() ) && hasEndDate() )
+ return FALSE;
+ return TRUE;
+ }
+
+ /* need to find the next iteration */
+ do {
+ imonth += freq;
+ if (imonth > 12) {
+ imonth--;
+ iyear += imonth / 12;
+ imonth = imonth % 12;
+ imonth++;
+ }
+ tmpDate = QDate( iyear, imonth, 1 );
+ /* these loops could go for a while, check end case now */
+ if ((tmpDate > endDate()) && hasEndDate() )
+ return FALSE;
+ iday = 1;
+ iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7;
+ iday += 7 * weekOfMonth;
+ } while (iday > tmpDate.daysInMonth());
+ tmpDate = QDate(iyear, imonth, iday);
+
+ next = tmpDate;
+ if ((next > endDate()) && hasEndDate() )
+ return FALSE;
+ return TRUE;
+ case MonthlyDate:
+ iday = start().day();
+ iyear = from.year();
+ imonth = from.month();
+
+ a = from.year() - start().year();
+ a *= 12;
+ a = a + (imonth - start().month());
+ /* a is e.start()monthsFrom(from); */
+ if(a % freq) {
+ a = freq - (a % freq);
+ imonth = from.month() + a;
+ if (imonth > 12) {
+ imonth--;
+ iyear += imonth / 12;
+ imonth = imonth % 12;
+ imonth++;
+ }
+ }
+ /* imonth is now the first month after or on
+ from that matches the frequencey given */
+
+ /* this could go for a while, worse case, 4*12 iterations, probably */
+ while(!QDate::isValid(iyear, imonth, iday) ) {
+ imonth += freq;
+ if (imonth > 12) {
+ imonth--;
+ iyear += imonth / 12;
+ imonth = imonth % 12;
+ imonth++;
+ }
+ /* these loops could go for a while, check end case now */
+ if ((QDate(iyear, imonth, 1) > endDate()) && hasEndDate() )
+ return FALSE;
+ }
+
+ if(QDate(iyear, imonth, iday) >= from) {
+ /* done */
+ next = QDate(iyear, imonth, iday);
+ if ((next > endDate()) && hasEndDate() )
+ return FALSE;
+ return TRUE;
+ }
+
+ /* ok, need to cycle */
+ imonth += freq;
+ imonth--;
+ iyear += imonth / 12;
+ imonth = imonth % 12;
+ imonth++;
+
+ while(!QDate::isValid(iyear, imonth, iday) ) {
+ imonth += freq;
+ imonth--;
+ iyear += imonth / 12;
+ imonth = imonth % 12;
+ imonth++;
+ if ((QDate(iyear, imonth, 1) > endDate()) && hasEndDate() )
+ return FALSE;
+ }
+
+ next = QDate(iyear, imonth, iday);
+ if ((next > endDate()) && hasEndDate() )
+ return FALSE;
+ return TRUE;
+ case Yearly:
+ iday = start().day();
+ imonth = start().month();
+ iyear = from.year(); // after all, we want to start in this year
+
+ diff = 1;
+ if(imonth == 2 && iday > 28) {
+ /* leap year, and it counts, calculate actual frequency */
+ if(freq % 4)
+ if (freq % 2)
+ freq = freq * 4;
+ else
+ freq = freq * 2;
+ /* else divides by 4 already, leave freq alone */
+ diff = 4;
+ }
+
+ a = from.year() - start().year();
+ if(a % freq) {
+ a = freq - (a % freq);
+ iyear = iyear + a;
+ }
+
+ /* under the assumption we won't hit one of the special not-leap years twice */
+ if(!QDate::isValid(iyear, imonth, iday)) {
+ /* must have been skipping by leap years and hit one that wasn't, (e.g. 2100) */
+ iyear += freq;
+ }
+
+ if(QDate(iyear, imonth, iday) >= from) {
+ next = QDate(iyear, imonth, iday);
+
+ if ((next > endDate()) && hasEndDate() )
+ return FALSE;
+ return TRUE;
+ }
+ /* iyear == from.year(), need to advance again */
+ iyear += freq;
+ /* under the assumption we won't hit one of the special not-leap years twice */
+ if(!QDate::isValid(iyear, imonth, iday)) {
+ /* must have been skipping by leap years and hit one that wasn't, (e.g. 2100) */
+ iyear += freq;
+ }
+
+ next = QDate(iyear, imonth, iday);
+ if ((next > endDate()) && hasEndDate() )
+ return FALSE;
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
ORecur::RepeatType ORecur::type()const{
return data->type;
}
int ORecur::frequency()const {
return data->freq;
}
int ORecur::position()const {
return data->pos;
}
char ORecur::days() const{
return data->days;
}
bool ORecur::hasEndDate()const {
return data->hasEnd;
}
QDate ORecur::endDate()const {
return TimeConversion::fromUTC( data->end ).date();
}
+QDate ORecur::start()const{
+ return data->start;
+}
time_t ORecur::endDateUTC()const {
return data->end;
}
time_t ORecur::createTime()const {
return data->create;
}
int ORecur::repetition()const {
return data->rep;
}
+QString ORecur::service()const {
+ return data->app;
+}
+ORecur::ExceptionList& ORecur::exceptions() {
+ return data->list;
+}
void ORecur::setType( const RepeatType& z) {
checkOrModify();
data->type = z;
}
void ORecur::setFrequency( int freq ) {
checkOrModify();
data->freq = freq;
}
void ORecur::setPosition( int pos ) {
checkOrModify();
data->pos = pos;
}
void ORecur::setDays( char c ) {
checkOrModify();
data->days = c;
}
void ORecur::setEndDate( const QDate& dt) {
checkOrModify();
data->end = TimeConversion::toUTC( dt );
}
void ORecur::setEndDateUTC( time_t t) {
checkOrModify();
data->end = t;
}
void ORecur::setCreateTime( time_t t) {
checkOrModify();
data->create = t;
}
void ORecur::setHasEndDate( bool b) {
checkOrModify();
data->hasEnd = b;
}
void ORecur::setRepitition( int rep ) {
checkOrModify();
data->rep = rep;
}
+void ORecur::setService( const QString& app ) {
+ checkOrModify();
+ data->app = app;
+}
+void ORecur::setStart( const QDate& dt ) {
+ checkOrModify();
+ data->start = dt;
+}
void ORecur::checkOrModify() {
if ( data->count != 1 ) {
data->deref();
Data* d2 = new Data;
d2->days = data->days;
d2->type = data->type;
d2->freq = data->freq;
d2->pos = data->pos;
d2->hasEnd = data->hasEnd;
d2->end = data->end;
d2->create = data->create;
d2->rep = data->rep;
+ d2->app = data->app;
+ d2->list = data->list;
+ d2->start = data->start;
data = d2;
}
}
diff --git a/libopie2/opiepim/core/orecur.h b/libopie2/opiepim/core/orecur.h
index d24d72d..8713d97 100644
--- a/libopie2/opiepim/core/orecur.h
+++ b/libopie2/opiepim/core/orecur.h
@@ -1,56 +1,83 @@
/*
* GPL from TT
*/
#ifndef OPIE_RECUR_H
#define OPIE_RECUR_H
#include <sys/types.h>
#include <qdatetime.h>
-
+#include <qvaluelist.h>
class ORecur {
public:
+ typedef QValueList<QDate> ExceptionList;
enum RepeatType{ NoRepeat = -1, Daily, Weekly, MonthlyDay,
MonthlyDate, Yearly };
enum Days { MON = 0x01, TUE = 0x02, WED = 0x04, THU = 0x08,
FRI = 0x10, SAT = 0x20, SUN = 0x40 };
ORecur();
ORecur( const ORecur& );
~ORecur();
ORecur &operator=( const ORecur& );
bool operator==(const ORecur& )const;
+
+ bool doesRecur()const;
+ /* if it recurrs on that day */
+ bool doesRecur( const QDate& );
RepeatType type()const;
int frequency()const;
int position()const;
char days()const;
bool hasEndDate()const;
+ QDate start()const;
QDate endDate()const;
time_t endDateUTC()const;
time_t createTime()const;
+
+ /**
+ * FromWhereToStart is not included!!!
+ */
+ bool nextOcurrence( const QDate& FromWhereToStart, QDate &recurDate );
+ /**
+ * The module this ORecur belongs to
+ */
+ QString service()const;
+
+ /*
+ * reference to the exception list
+ */
+ ExceptionList &exceptions();
+
+ /**
+ * the current repetition
+ */
int repetition()const;
void setType( const RepeatType& );
void setFrequency( int freq );
void setPosition( int pos );
void setDays( char c);
void setEndDate( const QDate& dt );
+ void setStart( const QDate& dt );
void setEndDateUTC( time_t );
void setCreateTime( time_t );
void setHasEndDate( bool b );
void setRepitition(int );
+
+ void setService( const QString& ser );
private:
void deref();
inline void checkOrModify();
class Data;
Data* data;
class ORecurPrivate;
ORecurPrivate *d;
};
#endif
diff --git a/libopie2/opiepim/core/otodoaccess.cpp b/libopie2/opiepim/core/otodoaccess.cpp
index c258de6..d860411 100644
--- a/libopie2/opiepim/core/otodoaccess.cpp
+++ b/libopie2/opiepim/core/otodoaccess.cpp
@@ -1,81 +1,86 @@
#include <qdatetime.h>
#include <qpe/alarmserver.h>
// #include "otodoaccesssql.h"
#include "otodoaccess.h"
#include "obackendfactory.h"
OTodoAccess::OTodoAccess( OTodoAccessBackend* end )
: QObject(), OPimAccessTemplate<OTodo>( end ), m_todoBackEnd( end )
{
// if (end == 0l )
// m_todoBackEnd = new OTodoAccessBackendSQL( QString::null);
// Zecke: Du musst hier noch für das XML-Backend einen Appnamen übergeben !
if (end == 0l )
m_todoBackEnd = OBackendFactory<OTodoAccessBackend>::Default ("todo", QString::null);
setBackEnd( m_todoBackEnd );
}
OTodoAccess::~OTodoAccess() {
// qWarning("~OTodoAccess");
}
void OTodoAccess::mergeWith( const QValueList<OTodo>& list ) {
QValueList<OTodo>::ConstIterator it;
for ( it = list.begin(); it != list.end(); ++it ) {
replace( (*it) );
}
}
OTodoAccess::List OTodoAccess::effectiveToDos( const QDate& start,
const QDate& end,
bool includeNoDates ) {
QArray<int> ints = m_todoBackEnd->effectiveToDos( start, end, includeNoDates );
List lis( ints, this );
return lis;
}
OTodoAccess::List OTodoAccess::effectiveToDos( const QDate& start,
bool includeNoDates ) {
return effectiveToDos( start, QDate::currentDate(),
includeNoDates );
}
OTodoAccess::List OTodoAccess::overDue() {
List lis( m_todoBackEnd->overDue(), this );
return lis;
}
void OTodoAccess::addAlarm( const OTodo& event) {
- if (!event.hasAlarmDateTime() )
+/* FIXME use the new notifier architecture
+ if (!event.hasAlarmDateTime() )
return;
QDateTime now = QDateTime::currentDateTime();
QDateTime schedule = event.alarmDateTime();
if ( schedule > now ){
AlarmServer::addAlarm( schedule,
"QPE/Application/todolist",
"alarm(QDateTime,int)", event.uid() );
}
+*/
}
void OTodoAccess::delAlarm( int uid) {
QDateTime schedule; // Create null DateTime
// I hope this will remove all scheduled alarms
// with the given uid !?
// If not: I have to rethink how to remove already
// scheduled events... (se)
// it should be fine -zecke
// qWarning("Removing alarm for event with uid %d", uid );
AlarmServer::deleteAlarm( schedule ,
"QPE/Application/todolist",
"alarm(QDateTime,int)", uid );
}
/* sort order */
OTodoAccess::List OTodoAccess::sorted( bool ascending, int sort,int filter, int cat ) {
QArray<int> ints = m_todoBackEnd->sorted( ascending, sort,
filter, cat );
OTodoAccess::List list( ints, this );
return list;
}
+void OTodoAccess::removeAllCompleted() {
+ m_todoBackEnd->removeAllCompleted();
+}
diff --git a/libopie2/opiepim/core/otodoaccess.h b/libopie2/opiepim/core/otodoaccess.h
index 390ab0e..c079155 100644
--- a/libopie2/opiepim/core/otodoaccess.h
+++ b/libopie2/opiepim/core/otodoaccess.h
@@ -1,93 +1,98 @@
#ifndef OPIE_TODO_ACCESS_H
#define OPIE_TODO_ACCESS_H
#include <qobject.h>
#include <qvaluelist.h>
#include "otodo.h"
#include "otodoaccessbackend.h"
#include "opimaccesstemplate.h"
/**
* OTodoAccess
* the class to get access to
* the todolist
*/
class OTodoAccess : public QObject, public OPimAccessTemplate<OTodo> {
Q_OBJECT
public:
enum SortOrder { Completed = 0,
Priority,
Description,
Deadline };
enum SortFilter{ Category =1,
OnlyOverDue= 2,
DoNotShowCompleted =4 };
/**
* if you use 0l
* the default resource will be
* picked up
*/
OTodoAccess( OTodoAccessBackend* = 0l);
~OTodoAccess();
/* our functions here */
/**
* include todos from start to end
* includeNoDates whether or not to include
* events with no dates
*/
List effectiveToDos( const QDate& start,
const QDate& end,
bool includeNoDates = true );
/**
* start
* end date taken from the currentDate()
*/
List effectiveToDos( const QDate& start,
bool includeNoDates = true );
/**
* return overdue OTodos
*/
List overDue();
/**
*
*/
List sorted( bool ascending, int sortOrder, int sortFilter, int cat );
/**
* merge a list of OTodos into
* the resource
*/
void mergeWith( const QValueList<OTodo>& );
/**
+ * delete all already completed items
+ */
+ void removeAllCompleted();
+
+signals:
+ /**
+ * if the OTodoAccess was changed
+ */
+ void signalChanged( const OTodoAccess* );
+private:
+ /**
* add an Alarm to the AlarmServer
*/
void addAlarm( const OTodo& );
/**
* delete an alarm with the uid from
* the alarm server
*/
void delAlarm( int uid );
-signals:
- /**
- * if the OTodoAccess was changed
- */
- void signalChanged( const OTodoAccess* );
-private:
int m_cat;
OTodoAccessBackend* m_todoBackEnd;
class OTodoAccessPrivate;
OTodoAccessPrivate* d;
};
#endif
diff --git a/libopie2/opiepim/ocontact.cpp b/libopie2/opiepim/ocontact.cpp
index 917eb0a..efa2777 100644
--- a/libopie2/opiepim/ocontact.cpp
+++ b/libopie2/opiepim/ocontact.cpp
@@ -586,518 +586,520 @@ QString OContact::toRichText() const
+ Qtopia::escapeString(str) + "<br>";
if ( categoryNames().count() ){
text += "<b>" + QObject::tr( "Category:") + "</b> ";
text += categoryNames().join(", ");
text += "<br>";
}
// notes last
if ( (value = notes()) ) {
QRegExp reg("\n");
//QString tmp = Qtopia::escapeString(value);
QString tmp = QStyleSheet::convertFromPlainText(value);
//tmp.replace( reg, "<br>" );
text += "<br>" + tmp + "<br>";
}
return text;
}
/*!
\internal
*/
void OContact::insert( int key, const QString &v )
{
QString value = v.stripWhiteSpace();
if ( value.isEmpty() )
mMap.remove( key );
else
mMap.insert( key, value );
}
/*!
\internal
*/
void OContact::replace( int key, const QString & v )
{
QString value = v.stripWhiteSpace();
if ( value.isEmpty() )
mMap.remove( key );
else
mMap.replace( key, value );
}
/*!
\internal
*/
QString OContact::find( int key ) const
{
return mMap[key];
}
/*!
\internal
*/
QString OContact::displayAddress( const QString &street,
const QString &city,
const QString &state,
const QString &zip,
const QString &country ) const
{
QString s = street;
if ( !street.isEmpty() )
s+= "\n";
s += city;
if ( !city.isEmpty() && !state.isEmpty() )
s += ", ";
s += state;
if ( !state.isEmpty() && !zip.isEmpty() )
s += " ";
s += zip;
if ( !country.isEmpty() && !s.isEmpty() )
s += "\n";
s += country;
return s;
}
/*!
\internal
*/
QString OContact::displayBusinessAddress() const
{
return displayAddress( businessStreet(), businessCity(),
businessState(), businessZip(),
businessCountry() );
}
/*!
\internal
*/
QString OContact::displayHomeAddress() const
{
return displayAddress( homeStreet(), homeCity(),
homeState(), homeZip(),
homeCountry() );
}
/*!
Returns the full name of the contact
*/
QString OContact::fullName() const
{
QString title = find( Qtopia::Title );
QString firstName = find( Qtopia::FirstName );
QString middleName = find( Qtopia::MiddleName );
QString lastName = find( Qtopia::LastName );
QString suffix = find( Qtopia::Suffix );
QString name = title;
if ( !firstName.isEmpty() ) {
if ( !name.isEmpty() )
name += " ";
name += firstName;
}
if ( !middleName.isEmpty() ) {
if ( !name.isEmpty() )
name += " ";
name += middleName;
}
if ( !lastName.isEmpty() ) {
if ( !name.isEmpty() )
name += " ";
name += lastName;
}
if ( !suffix.isEmpty() ) {
if ( !name.isEmpty() )
name += " ";
name += suffix;
}
return name.simplifyWhiteSpace();
}
/*!
Returns a list of the names of the children of the contact.
*/
QStringList OContact::childrenList() const
{
return QStringList::split( " ", find( Qtopia::Children ) );
}
/*! \fn void OContact::insertEmail( const QString &email )
Insert \a email into the email list. Ensures \a email can only be added
once. If there is no default email address set, it sets it to the \a email.
*/
/*! \fn void OContact::removeEmail( const QString &email )
Removes the \a email from the email list. If the default email was \a email,
then the default email address is assigned to the first email in the
email list
*/
/*! \fn void OContact::clearEmails()
Clears the email list.
*/
/*! \fn void OContact::insertEmails( const QStringList &emailList )
Appends the \a emailList to the exiting email list
*/
/*!
Returns a list of email addresses belonging to the contact, including
the default email address.
*/
QStringList OContact::emailList() const
{
QString emailStr = emails();
QStringList r;
if ( !emailStr.isEmpty() ) {
qDebug(" emailstr ");
QStringList l = QStringList::split( emailSeparator(), emailStr );
for ( QStringList::ConstIterator it = l.begin();it != l.end();++it )
r += (*it).simplifyWhiteSpace();
}
return r;
}
/*!
\overload
Generates the string for the contact to be filed as from the first,
middle and last name of the contact.
*/
void OContact::setFileAs()
{
QString lastName, firstName, middleName, fileas;
lastName = find( Qtopia::LastName );
firstName = find( Qtopia::FirstName );
middleName = find( Qtopia::MiddleName );
if ( !lastName.isEmpty() && !firstName.isEmpty()
&& !middleName.isEmpty() )
fileas = lastName + ", " + firstName + " " + middleName;
else if ( !lastName.isEmpty() && !firstName.isEmpty() )
fileas = lastName + ", " + firstName;
else if ( !lastName.isEmpty() || !firstName.isEmpty() ||
!middleName.isEmpty() )
fileas = firstName + ( firstName.isEmpty() ? "" : " " )
+ middleName + ( middleName.isEmpty() ? "" : " " )
+ lastName;
replace( Qtopia::FileAs, fileas );
}
/*!
\internal
Appends the contact information to \a buf.
*/
void OContact::save( QString &buf ) const
{
static const QStringList SLFIELDS = fields();
// I'm expecting "<Contact " in front of this...
for ( QMap<int, QString>::ConstIterator it = mMap.begin();
it != mMap.end(); ++it ) {
const QString &value = it.data();
int key = it.key();
if ( !value.isEmpty() ) {
if ( key == Qtopia::AddressCategory || key == Qtopia::AddressUid)
continue;
key -= Qtopia::AddressCategory+1;
buf += SLFIELDS[key];
buf += "=\"" + Qtopia::escapeString(value) + "\" ";
}
}
buf += customToXml();
if ( categories().count() > 0 )
buf += "Categories=\"" + idsToString( categories() ) + "\" ";
buf += "Uid=\"" + QString::number( uid() ) + "\" ";
// You need to close this yourself
}
/*!
\internal
Returns the list of fields belonging to a contact
Never change order of this list ! It has to be regarding
enum AddressBookFields !!
*/
QStringList OContact::fields()
{
QStringList list;
list.append( "Title" ); // Not Used!
list.append( "FirstName" );
list.append( "MiddleName" );
list.append( "LastName" );
list.append( "Suffix" );
list.append( "FileAs" );
list.append( "JobTitle" );
list.append( "Department" );
list.append( "Company" );
list.append( "BusinessPhone" );
list.append( "BusinessFax" );
list.append( "BusinessMobile" );
list.append( "DefaultEmail" );
list.append( "Emails" );
list.append( "HomePhone" );
list.append( "HomeFax" );
list.append( "HomeMobile" );
list.append( "BusinessStreet" );
list.append( "BusinessCity" );
list.append( "BusinessState" );
list.append( "BusinessZip" );
list.append( "BusinessCountry" );
list.append( "BusinessPager" );
list.append( "BusinessWebPage" );
list.append( "Office" );
list.append( "Profession" );
list.append( "Assistant" );
list.append( "Manager" );
list.append( "HomeStreet" );
list.append( "HomeCity" );
list.append( "HomeState" );
list.append( "HomeZip" );
list.append( "HomeCountry" );
list.append( "HomeWebPage" );
list.append( "Spouse" );
list.append( "Gender" );
list.append( "Birthday" );
list.append( "Anniversary" );
list.append( "Nickname" );
list.append( "Children" );
list.append( "Notes" );
list.append( "Groups" );
return list;
}
/*!
Sets the list of email address for contact to those contained in \a str.
Email address should be separated by ';'s.
*/
void OContact::setEmails( const QString &str )
{
replace( Qtopia::Emails, str );
if ( str.isEmpty() )
setDefaultEmail( QString::null );
}
/*!
Sets the list of children for the contact to those contained in \a str.
*/
void OContact::setChildren( const QString &str )
{
replace( Qtopia::Children, str );
}
/*!
Returns TRUE if the contact matches the regular expression \a regexp.
Otherwise returns FALSE.
*/
bool OContact::match( const QString &regexp ) const
{
return match(QRegExp(regexp));
}
/*!
\overload
Returns TRUE if the contact matches the regular expression \a regexp.
Otherwise returns FALSE.
*/
bool OContact::match( const QRegExp &r ) const
{
bool match;
match = false;
QMap<int, QString>::ConstIterator it;
for ( it = mMap.begin(); it != mMap.end(); ++it ) {
if ( (*it).find( r ) > -1 ) {
match = true;
break;
}
}
return match;
}
QString OContact::toShortText() const
{
return ( fullName() );
}
QString OContact::type() const
{
return QString::fromLatin1( "OContact" );
}
// Definition is missing ! (se)
QMap<QString,QString> OContact::toExtraMap() const
{
qWarning ("Function not implemented: OContact::toExtraMap()");
QMap <QString,QString> useless;
return useless;
}
class QString OContact::recordField( int pos ) const
{
QStringList SLFIELDS = fields(); // ?? why this ? (se)
return SLFIELDS[pos];
}
// In future releases, we should store birthday and anniversary
// internally as QDate instead of QString !
// QString is always too complicate to interprete (DD.MM.YY, DD/MM/YY, MM/DD/YY, etc..)(se)
/*! \fn void OContact::setBirthday( const QDate& date )
Sets the birthday for the contact to \a date. If date is null
the current stored date will be removed.
*/
void OContact::setBirthday( const QDate &v )
{
if ( v.isNull() ){
qWarning( "Remove Birthday");
replace( Qtopia::Birthday, QString::null );
return;
}
if ( v.isValid() )
replace( Qtopia::Birthday, TimeConversion::toString( v ) );
}
/*! \fn void OContact::setAnniversary( const QDate &date )
Sets the anniversary of the contact to \a date. If date is
null, the current stored date will be removed.
*/
void OContact::setAnniversary( const QDate &v )
{
if ( v.isNull() ){
qWarning( "Remove Anniversary");
replace( Qtopia::Anniversary, QString::null );
return;
}
if ( v.isValid() )
replace( Qtopia::Anniversary, TimeConversion::toString( v ) );
}
/*! \fn QDate OContact::birthday() const
Returns the birthday of the contact.
*/
QDate OContact::birthday() const
{
QString str = find( Qtopia::Birthday );
qWarning ("Birthday %s", str.latin1() );
if ( !str.isEmpty() )
return TimeConversion::fromString ( str );
else
return QDate();
}
/*! \fn QDate OContact::anniversary() const
Returns the anniversary of the contact.
*/
QDate OContact::anniversary() const
{
QDate empty;
QString str = find( Qtopia::Anniversary );
qWarning ("Anniversary %s", str.latin1() );
if ( !str.isEmpty() )
return TimeConversion::fromString ( str );
else
return empty;
}
void OContact::insertEmail( const QString &v )
{
//qDebug("insertEmail %s", v.latin1());
QString e = v.simplifyWhiteSpace();
QString def = defaultEmail();
// if no default, set it as the default email and don't insert
if ( def.isEmpty() ) {
setDefaultEmail( e ); // will insert into the list for us
return;
}
// otherwise, insert assuming doesn't already exist
QString emailsStr = find( Qtopia::Emails );
if ( emailsStr.contains( e ))
return;
if ( !emailsStr.isEmpty() )
emailsStr += emailSeparator();
emailsStr += e;
replace( Qtopia::Emails, emailsStr );
}
void OContact::removeEmail( const QString &v )
{
QString e = v.simplifyWhiteSpace();
QString def = defaultEmail();
QString emailsStr = find( Qtopia::Emails );
QStringList emails = emailList();
// otherwise, must first contain it
if ( !emailsStr.contains( e ) )
return;
// remove it
//qDebug(" removing email from list %s", e.latin1());
emails.remove( e );
// reset the string
emailsStr = emails.join(emailSeparator()); // Sharp's brain dead separator
replace( Qtopia::Emails, emailsStr );
// if default, then replace the default email with the first one
if ( def == e ) {
//qDebug("removeEmail is default; setting new default");
if ( !emails.count() )
clearEmails();
else // setDefaultEmail will remove e from the list
setDefaultEmail( emails.first() );
}
}
void OContact::clearEmails()
{
mMap.remove( Qtopia::DefaultEmail );
mMap.remove( Qtopia::Emails );
}
void OContact::setDefaultEmail( const QString &v )
{
QString e = v.simplifyWhiteSpace();
//qDebug("OContact::setDefaultEmail %s", e.latin1());
replace( Qtopia::DefaultEmail, e );
if ( !e.isEmpty() )
insertEmail( e );
}
void OContact::insertEmails( const QStringList &v )
{
for ( QStringList::ConstIterator it = v.begin(); it != v.end(); ++it )
insertEmail( *it );
}
-
+int OContact::rtti() {
+ return 2;
+}
void OContact::setUid( int i )
{
OPimRecord::setUid(i);
replace( Qtopia::AddressUid , QString::number(i));
}
diff --git a/libopie2/opiepim/ocontact.h b/libopie2/opiepim/ocontact.h
index d97af1c..65ba43e 100644
--- a/libopie2/opiepim/ocontact.h
+++ b/libopie2/opiepim/ocontact.h
@@ -1,238 +1,239 @@
/**********************************************************************
** Copyright (C) 2000-2002 Trolltech AS. All rights reserved.
** Copyright (C) 2002 by Stefan Eilers (eilers.stefan@epost.de)
**
** This file is part of the 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 __OCONTACT_H__
#define __OCONTACT_H__
#include <opie/opimrecord.h>
#include <qpe/recordfields.h>
#include <qdatetime.h>
#include <qstringlist.h>
#if defined(QPC_TEMPLATEDLL)
// MOC_SKIP_BEGIN
QPC_TEMPLATEEXTERN template class QPC_EXPORT QMap<int, QString>;
// MOC_SKIP_END
#endif
class ContactPrivate;
class QPC_EXPORT OContact : public OPimRecord
{
friend class DataSet;
public:
OContact();
OContact( const QMap<int, QString> &fromMap );
virtual ~OContact();
enum journal_action { ACTION_ADD, ACTION_REMOVE, ACTION_REPLACE };
- /*
+ /*
* do we need to inline them
* if yes do we need to inline them this way?
* -zecke
*/
void setTitle( const QString &v ) { replace( Qtopia::Title, v ); }
void setFirstName( const QString &v ) { replace( Qtopia::FirstName, v ); }
void setMiddleName( const QString &v ) { replace( Qtopia::MiddleName, v ); }
void setLastName( const QString &v ) { replace( Qtopia::LastName, v ); }
void setSuffix( const QString &v ) { replace( Qtopia::Suffix, v ); }
void setFileAs( const QString &v ) { replace( Qtopia::FileAs, v ); }
void setFileAs();
// default email address
void setDefaultEmail( const QString &v );
// inserts email to list and ensure's doesn't already exist
void insertEmail( const QString &v );
void removeEmail( const QString &v );
void clearEmails();
void insertEmails( const QStringList &v );
// home
void setHomeStreet( const QString &v ) { replace( Qtopia::HomeStreet, v ); }
void setHomeCity( const QString &v ) { replace( Qtopia::HomeCity, v ); }
void setHomeState( const QString &v ) { replace( Qtopia::HomeState, v ); }
void setHomeZip( const QString &v ) { replace( Qtopia::HomeZip, v ); }
void setHomeCountry( const QString &v ) { replace( Qtopia::HomeCountry, v ); }
void setHomePhone( const QString &v ) { replace( Qtopia::HomePhone, v ); }
void setHomeFax( const QString &v ) { replace( Qtopia::HomeFax, v ); }
void setHomeMobile( const QString &v ) { replace( Qtopia::HomeMobile, v ); }
void setHomeWebpage( const QString &v ) { replace( Qtopia::HomeWebPage, v ); }
// business
void setCompany( const QString &v ) { replace( Qtopia::Company, v ); }
void setBusinessStreet( const QString &v ) { replace( Qtopia::BusinessStreet, v ); }
void setBusinessCity( const QString &v ) { replace( Qtopia::BusinessCity, v ); }
void setBusinessState( const QString &v ) { replace( Qtopia::BusinessState, v ); }
void setBusinessZip( const QString &v ) { replace( Qtopia::BusinessZip, v ); }
void setBusinessCountry( const QString &v ) { replace( Qtopia::BusinessCountry, v ); }
void setBusinessWebpage( const QString &v ) { replace( Qtopia::BusinessWebPage, v ); }
void setJobTitle( const QString &v ) { replace( Qtopia::JobTitle, v ); }
void setDepartment( const QString &v ) { replace( Qtopia::Department, v ); }
void setOffice( const QString &v ) { replace( Qtopia::Office, v ); }
void setBusinessPhone( const QString &v ) { replace( Qtopia::BusinessPhone, v ); }
void setBusinessFax( const QString &v ) { replace( Qtopia::BusinessFax, v ); }
void setBusinessMobile( const QString &v ) { replace( Qtopia::BusinessMobile, v ); }
void setBusinessPager( const QString &v ) { replace( Qtopia::BusinessPager, v ); }
void setProfession( const QString &v ) { replace( Qtopia::Profession, v ); }
void setAssistant( const QString &v ) { replace( Qtopia::Assistant, v ); }
void setManager( const QString &v ) { replace( Qtopia::Manager, v ); }
// personal
void setSpouse( const QString &v ) { replace( Qtopia::Spouse, v ); }
void setGender( const QString &v ) { replace( Qtopia::Gender, v ); }
void setBirthday( const QDate &v );
void setAnniversary( const QDate &v );
void setNickname( const QString &v ) { replace( Qtopia::Nickname, v ); }
void setChildren( const QString &v );
// other
void setNotes( const QString &v ) { replace( Qtopia::Notes, v); }
bool match( const QString &regexp ) const;
bool match( const QRegExp &regexp ) const;
// // custom
// void setCustomField( const QString &key, const QString &v )
// { replace(Custom- + key, v ); }
// name
QString fullName() const;
QString title() const { return find( Qtopia::Title ); }
QString firstName() const { return find( Qtopia::FirstName ); }
QString middleName() const { return find( Qtopia::MiddleName ); }
QString lastName() const { return find( Qtopia::LastName ); }
QString suffix() const { return find( Qtopia::Suffix ); }
QString fileAs() const { return find( Qtopia::FileAs ); }
// email
QString defaultEmail() const { return find( Qtopia::DefaultEmail ); }
QStringList emailList() const;
// home
/*
* OPimAddress address(enum Location)const;
* would be some how nicer...
* -zecke
*/
QString homeStreet() const { return find( Qtopia::HomeStreet ); }
QString homeCity() const { return find( Qtopia::HomeCity ); }
QString homeState() const { return find( Qtopia::HomeState ); }
QString homeZip() const { return find( Qtopia::HomeZip ); }
QString homeCountry() const { return find( Qtopia::HomeCountry ); }
QString homePhone() const { return find( Qtopia::HomePhone ); }
QString homeFax() const { return find( Qtopia::HomeFax ); }
QString homeMobile() const { return find( Qtopia::HomeMobile ); }
QString homeWebpage() const { return find( Qtopia::HomeWebPage ); }
/** Multi line string containing all non-empty address info in the form
* Street
* City, State Zip
* Country
*/
QString displayHomeAddress() const;
// business
QString company() const { return find( Qtopia::Company ); }
QString businessStreet() const { return find( Qtopia::BusinessStreet ); }
QString businessCity() const { return find( Qtopia::BusinessCity ); }
QString businessState() const { return find( Qtopia::BusinessState ); }
QString businessZip() const { return find( Qtopia::BusinessZip ); }
QString businessCountry() const { return find( Qtopia::BusinessCountry ); }
QString businessWebpage() const { return find( Qtopia::BusinessWebPage ); }
QString jobTitle() const { return find( Qtopia::JobTitle ); }
QString department() const { return find( Qtopia::Department ); }
QString office() const { return find( Qtopia::Office ); }
QString businessPhone() const { return find( Qtopia::BusinessPhone ); }
QString businessFax() const { return find( Qtopia::BusinessFax ); }
QString businessMobile() const { return find( Qtopia::BusinessMobile ); }
QString businessPager() const { return find( Qtopia::BusinessPager ); }
QString profession() const { return find( Qtopia::Profession ); }
QString assistant() const { return find( Qtopia::Assistant ); }
QString manager() const { return find( Qtopia::Manager ); }
/** Multi line string containing all non-empty address info in the form
* Street
* City, State Zip
* Country
*/
QString displayBusinessAddress() const;
//personal
QString spouse() const { return find( Qtopia::Spouse ); }
QString gender() const { return find( Qtopia::Gender ); }
QDate birthday() const;
QDate anniversary() const;
QString nickname() const { return find( Qtopia::Nickname ); }
QString children() const { return find( Qtopia::Children ); }
QStringList childrenList() const;
// other
QString notes() const { return find( Qtopia::Notes ); }
QString groups() const { return find( Qtopia::Groups ); }
QStringList groupList() const;
// // custom
// const QString &customField( const QString &key )
// { return find( Custom- + key ); }
QString toRichText() const;
QMap<int, QString> toMap() const;
QString field( int key ) const { return find( key ); }
void setUid( int i );
QString toShortText()const;
QString OContact::type()const;
QMap<QString,QString> OContact::toExtraMap() const;
class QString OContact::recordField(int) const;
// Why private ? (eilers,se)
QString emailSeparator() const { return " "; }
// the emails should be seperated by a comma
void setEmails( const QString &v );
QString emails() const { return find( Qtopia::Emails ); }
+ static int rtti();
private:
// The XML-Backend needs some access to the private functions
friend class OContactAccessBackend_XML;
void insert( int key, const QString &value );
void replace( int key, const QString &value );
QString find( int key ) const;
static QStringList fields();
void save( QString &buf ) const;
QString displayAddress( const QString &street,
const QString &city,
const QString &state,
const QString &zip,
const QString &country ) const;
QMap<int, QString> mMap;
ContactPrivate *d;
};
#endif
diff --git a/libopie2/opiepim/otodo.cpp b/libopie2/opiepim/otodo.cpp
index 6fcf9f6..ece624a 100644
--- a/libopie2/opiepim/otodo.cpp
+++ b/libopie2/opiepim/otodo.cpp
@@ -1,423 +1,421 @@
#include <qobject.h>
#include <qshared.h>
#include <qpe/palmtopuidgen.h>
#include <qpe/stringutil.h>
#include <qpe/palmtoprecord.h>
#include <qpe/stringutil.h>
#include <qpe/categories.h>
#include <qpe/categoryselect.h>
#include "opimstate.h"
#include "orecur.h"
#include "opimmaintainer.h"
+#include "opimnotifymanager.h"
#include "otodo.h"
struct OTodo::OTodoData : public QShared {
OTodoData() : QShared() {
};
QDate date;
bool isCompleted:1;
bool hasDate:1;
int priority;
QString desc;
QString sum;
QMap<QString, QString> extra;
ushort prog;
- bool hasAlarmDateTime :1;
- QDateTime alarmDateTime;
OPimState state;
ORecur recur;
OPimMaintainer maintainer;
+ QDate start;
+ QDate completed;
+ OPimNotifyManager notifiers;
};
OTodo::OTodo(const OTodo &event )
: OPimRecord( event ), data( event.data )
{
data->ref();
// qWarning("ref up");
}
OTodo::~OTodo() {
// qWarning("~OTodo " );
if ( data->deref() ) {
// qWarning("OTodo::dereffing");
delete data;
data = 0l;
}
}
OTodo::OTodo(bool completed, int priority,
const QArray<int> &category,
const QString& summary,
const QString &description,
ushort progress,
bool hasDate, QDate date, int uid )
: OPimRecord( uid )
{
// qWarning("OTodoData " + summary);
setCategories( category );
data = new OTodoData;
data->date = date;
data->isCompleted = completed;
data->hasDate = hasDate;
data->priority = priority;
data->sum = summary;
data->prog = progress;
data->desc = Qtopia::simplifyMultiLineSpace(description );
- data->hasAlarmDateTime = false;
-
}
OTodo::OTodo(bool completed, int priority,
const QStringList &category,
const QString& summary,
const QString &description,
ushort progress,
bool hasDate, QDate date, int uid )
: OPimRecord( uid )
{
// qWarning("OTodoData" + summary);
setCategories( idsFromString( category.join(";") ) );
data = new OTodoData;
data->date = date;
data->isCompleted = completed;
data->hasDate = hasDate;
data->priority = priority;
data->sum = summary;
data->prog = progress;
data->desc = Qtopia::simplifyMultiLineSpace(description );
- data->hasAlarmDateTime = false;
-
}
bool OTodo::match( const QRegExp &regExp )const
{
if( QString::number( data->priority ).find( regExp ) != -1 ){
return true;
}else if( data->hasDate && data->date.toString().find( regExp) != -1 ){
return true;
}else if(data->desc.find( regExp ) != -1 ){
return true;
}else if(data->sum.find( regExp ) != -1 ) {
return true;
}
return false;
}
bool OTodo::isCompleted() const
{
return data->isCompleted;
}
bool OTodo::hasDueDate() const
{
return data->hasDate;
}
-bool OTodo::hasAlarmDateTime() const
-{
- return data->hasAlarmDateTime;
+bool OTodo::hasStartDate()const {
+ return data->start.isValid();
+}
+bool OTodo::hasCompletedDate()const {
+ return data->completed.isValid();
}
int OTodo::priority()const
{
return data->priority;
}
QString OTodo::summary() const
{
return data->sum;
}
ushort OTodo::progress() const
{
return data->prog;
}
QDate OTodo::dueDate()const
{
return data->date;
}
-
-QDateTime OTodo::alarmDateTime() const
-{
- return data->alarmDateTime;
+QDate OTodo::startDate()const {
+ return data->start;
+}
+QDate OTodo::completedDate()const {
+ return data->completed;
}
-
QString OTodo::description()const
{
return data->desc;
}
OPimState OTodo::state()const {
return data->state;
}
ORecur OTodo::recurrence()const {
return data->recur;
}
OPimMaintainer OTodo::maintainer()const {
return data->maintainer;
}
void OTodo::setCompleted( bool completed )
{
changeOrModify();
data->isCompleted = completed;
}
void OTodo::setHasDueDate( bool hasDate )
{
changeOrModify();
data->hasDate = hasDate;
}
-void OTodo::setHasAlarmDateTime( bool hasAlarmDateTime )
-{
- changeOrModify();
- data->hasAlarmDateTime = hasAlarmDateTime;
-}
void OTodo::setDescription(const QString &desc )
{
// qWarning( "desc " + desc );
changeOrModify();
data->desc = Qtopia::simplifyMultiLineSpace(desc );
}
void OTodo::setSummary( const QString& sum )
{
changeOrModify();
data->sum = sum;
}
void OTodo::setPriority(int prio )
{
changeOrModify();
data->priority = prio;
}
-void OTodo::setDueDate( QDate date )
+void OTodo::setDueDate( const QDate& date )
{
changeOrModify();
data->date = date;
}
-void OTodo::setAlarmDateTime( const QDateTime& alarm )
-{
+void OTodo::setStartDate( const QDate& date ) {
changeOrModify();
- data->alarmDateTime = alarm;
+ data->start = date;
+}
+void OTodo::setCompletedDate( const QDate& date ) {
+ changeOrModify();
+ data->completed = date;
}
void OTodo::setState( const OPimState& state ) {
changeOrModify();
data->state = state;
}
void OTodo::setRecurrence( const ORecur& rec) {
changeOrModify();
data->recur = rec;
}
void OTodo::setMaintainer( const OPimMaintainer& pim ) {
changeOrModify();
data->maintainer = pim;
}
bool OTodo::isOverdue( )
{
if( data->hasDate && !data->isCompleted)
return QDate::currentDate() > data->date;
return false;
}
void OTodo::setProgress(ushort progress )
{
changeOrModify();
data->prog = progress;
}
QString OTodo::toShortText() const {
return summary();
}
/*!
Returns a richt text string
*/
QString OTodo::toRichText() const
{
QString text;
QStringList catlist;
// Description of the todo
if ( !summary().isEmpty() ) {
text += "<b>" + QObject::tr( "Summary:") + "</b><br>";
text += Qtopia::escapeString(summary() ).replace(QRegExp( "[\n]"), "<br>" ) + "<br>";
}
if( !description().isEmpty() ){
text += "<b>" + QObject::tr( "Description:" ) + "</b><br>";
text += Qtopia::escapeString(description() ).replace(QRegExp( "[\n]"), "<br>" ) ;
}
text += "<br><br><br>";
text += "<b>" + QObject::tr( "Priority:") +" </b>"
+ QString::number( priority() ) + " <br>";
text += "<b>" + QObject::tr( "Progress:") + " </b>"
+ QString::number( progress() ) + " %<br>";
if (hasDueDate() ){
text += "<b>" + QObject::tr( "Deadline:") + " </b>";
text += dueDate().toString();
text += "<br>";
}
- if (hasAlarmDateTime() ){
- text += "<b>" + QObject::tr( "Alarmed Notification:") + " </b>";
- text += alarmDateTime().toString();
- text += "<br>";
- }
text += "<b>" + QObject::tr( "Category:") + "</b> ";
text += categoryNames().join(", ");
text += "<br>";
return text;
}
+OPimNotifyManager& OTodo::notifiers() {
+ return data->notifiers;
+}
bool OTodo::operator<( const OTodo &toDoEvent )const{
if( !hasDueDate() && !toDoEvent.hasDueDate() ) return true;
if( !hasDueDate() && toDoEvent.hasDueDate() ) return false;
if( hasDueDate() && toDoEvent.hasDueDate() ){
if( dueDate() == toDoEvent.dueDate() ){ // let's the priority decide
return priority() < toDoEvent.priority();
}else{
return dueDate() < toDoEvent.dueDate();
}
}
return false;
}
bool OTodo::operator<=(const OTodo &toDoEvent )const
{
if( !hasDueDate() && !toDoEvent.hasDueDate() ) return true;
if( !hasDueDate() && toDoEvent.hasDueDate() ) return true;
if( hasDueDate() && toDoEvent.hasDueDate() ){
if( dueDate() == toDoEvent.dueDate() ){ // let's the priority decide
return priority() <= toDoEvent.priority();
}else{
return dueDate() <= toDoEvent.dueDate();
}
}
return true;
}
bool OTodo::operator>(const OTodo &toDoEvent )const
{
if( !hasDueDate() && !toDoEvent.hasDueDate() ) return false;
if( !hasDueDate() && toDoEvent.hasDueDate() ) return false;
if( hasDueDate() && toDoEvent.hasDueDate() ){
if( dueDate() == toDoEvent.dueDate() ){ // let's the priority decide
return priority() > toDoEvent.priority();
}else{
return dueDate() > toDoEvent.dueDate();
}
}
return false;
}
bool OTodo::operator>=(const OTodo &toDoEvent )const
{
if( !hasDueDate() && !toDoEvent.hasDueDate() ) return true;
if( !hasDueDate() && toDoEvent.hasDueDate() ) return false;
if( hasDueDate() && toDoEvent.hasDueDate() ){
if( dueDate() == toDoEvent.dueDate() ){ // let's the priority decide
return priority() > toDoEvent.priority();
}else{
return dueDate() > toDoEvent.dueDate();
}
}
return true;
}
bool OTodo::operator==(const OTodo &toDoEvent )const
{
if ( data->priority != toDoEvent.data->priority ) return false;
if ( data->priority != toDoEvent.data->prog ) return false;
if ( data->isCompleted != toDoEvent.data->isCompleted ) return false;
if ( data->hasDate != toDoEvent.data->hasDate ) return false;
if ( data->date != toDoEvent.data->date ) return false;
if ( data->sum != toDoEvent.data->sum ) return false;
if ( data->desc != toDoEvent.data->desc ) return false;
- if ( data->hasAlarmDateTime != toDoEvent.data->hasAlarmDateTime )
- return false;
- if ( data->alarmDateTime != toDoEvent.data->alarmDateTime )
- return false;
if ( data->maintainer != toDoEvent.data->maintainer )
return false;
return OPimRecord::operator==( toDoEvent );
}
void OTodo::deref() {
// qWarning("deref in ToDoEvent");
if ( data->deref() ) {
// qWarning("deleting");
delete data;
data= 0;
}
}
OTodo &OTodo::operator=(const OTodo &item )
{
OPimRecord::operator=( item );
//qWarning("operator= ref ");
item.data->ref();
deref();
data = item.data;
return *this;
}
QMap<int, QString> OTodo::toMap() const {
QMap<int, QString> map;
map.insert( Uid, QString::number( uid() ) );
map.insert( Category, idsToString( categories() ) );
map.insert( HasDate, QString::number( data->hasDate ) );
map.insert( Completed, QString::number( data->isCompleted ) );
map.insert( Description, data->desc );
map.insert( Summary, data->sum );
map.insert( Priority, QString::number( data->priority ) );
map.insert( DateDay, QString::number( data->date.day() ) );
map.insert( DateMonth, QString::number( data->date.month() ) );
map.insert( DateYear, QString::number( data->date.year() ) );
map.insert( Progress, QString::number( data->prog ) );
// map.insert( CrossReference, crossToString() );
- map.insert( HasAlarmDateTime, QString::number( data->hasAlarmDateTime ) );
- map.insert( AlarmDateTime, data->alarmDateTime.toString() );
-
+ /* FIXME!!! map.insert( State, );
+ map.insert( Recurrence, );
+ map.insert( Reminders, );
+ map.
+ */
return map;
}
QMap<QString, QString> OTodo::toExtraMap()const {
return data->extra;
}
/**
* change or modify looks at the ref count and either
* creates a new QShared Object or it can modify it
* right in place
*/
void OTodo::changeOrModify() {
if ( data->count != 1 ) {
qWarning("changeOrModify");
data->deref();
OTodoData* d2 = new OTodoData();
copy(data, d2 );
data = d2;
}
}
// WATCHOUT
/*
* if you add something to the Data struct
* be sure to copy it here
*/
void OTodo::copy( OTodoData* src, OTodoData* dest ) {
dest->date = src->date;
dest->isCompleted = src->isCompleted;
dest->hasDate = src->hasDate;
dest->priority = src->priority;
dest->desc = src->desc;
dest->sum = src->sum;
dest->extra = src->extra;
dest->prog = src->prog;
- dest->hasAlarmDateTime = src->hasAlarmDateTime;
- dest->alarmDateTime = src->alarmDateTime;
dest->state = src->state;
dest->recur = src->recur;
dest->maintainer = src->maintainer;
+ dest->start = src->start;
+ dest->completed = src->completed;
+ dest->notifiers = src->notifiers;
}
QString OTodo::type() const {
return QString::fromLatin1("OTodo");
}
QString OTodo::recordField(int /*id*/ )const {
return QString::null;
}
+int OTodo::rtti(){
+ return 1;
+}
diff --git a/libopie2/opiepim/otodo.h b/libopie2/opiepim/otodo.h
index 70b0253..2f66f55 100644
--- a/libopie2/opiepim/otodo.h
+++ b/libopie2/opiepim/otodo.h
@@ -1,246 +1,273 @@
#ifndef OPIE_TODO_EVENT_H
#define OPIE_TODO_EVENT_H
#include <qarray.h>
#include <qmap.h>
#include <qregexp.h>
#include <qstringlist.h>
#include <qdatetime.h>
#include <qvaluelist.h>
#include <qpe/recordfields.h>
#include <qpe/palmtopuidgen.h>
#include <opie/opimrecord.h>
class OPimState;
class ORecur;
class OPimMaintainer;
+class OPimNotifyManager;
class OTodo : public OPimRecord {
public:
typedef QValueList<OTodo> ValueList;
enum RecordFields {
Uid = Qtopia::UID_ID,
Category = Qtopia::CATEGORY_ID,
HasDate,
Completed,
Description,
Summary,
Priority,
DateDay,
DateMonth,
DateYear,
Progress,
CrossReference,
- HasAlarmDateTime,
- AlarmDateTime,
State,
- Recurrance,
+ Recurrence,
Alarms,
Reminders,
- Notifiers
+ Notifiers,
+ Maintainer,
+ StartDate,
+ CompletedDate
};
public:
// priorities from Very low to very high
enum TaskPriority { VeryHigh=1, High, Normal, Low, VeryLow };
/* Constructs a new ToDoEvent
@param completed Is the TodoEvent completed
@param priority What is the priority of this ToDoEvent
@param category Which category does it belong( uid )
@param summary A small summary of the todo
@param description What is this ToDoEvent about
@param hasDate Does this Event got a deadline
@param date what is the deadline?
@param uid what is the UUID of this Event
**/
OTodo( bool completed = false, int priority = Normal,
const QStringList &category = QStringList(),
const QString &summary = QString::null ,
const QString &description = QString::null,
ushort progress = 0,
bool hasDate = false, QDate date = QDate::currentDate(),
int uid = 0 /*empty*/ );
OTodo( bool completed, int priority,
const QArray<int>& category,
const QString& summary = QString::null,
const QString& description = QString::null,
ushort progress = 0,
bool hasDate = false, QDate date = QDate::currentDate(),
int uid = 0 /* empty */ );
- /* Copy c'tor
-
- **/
+ /** Copy c'tor
+ *
+ */
OTodo(const OTodo & );
/**
*destructor
*/
~OTodo();
/**
* Is this event completed?
*/
bool isCompleted() const;
/**
* Does this Event have a deadline
*/
bool hasDueDate() const;
+ bool hasStartDate()const;
+ bool hasCompletedDate()const;
/**
* Does this Event has an alarm time ?
*/
bool hasAlarmDateTime() const;
/**
* What is the priority?
*/
int priority()const ;
/**
* progress as ushort 0, 20, 40, 60, 80 or 100%
*/
ushort progress() const;
/**
* The due Date
*/
QDate dueDate()const;
/**
- * Alarm Date and Time
+ * When did it start?
+ */
+ QDate startDate()const;
+
+ /**
+ * When was it completed?
*/
- QDateTime alarmDateTime()const;
+ QDate completedDate()const;
/**
* What is the state of this OTodo?
*/
OPimState state()const;
/**
* the recurrance of this
*/
ORecur recurrence()const;
/**
* the Maintainer of this OTodo
*/
OPimMaintainer maintainer()const;
/**
* The description of the todo
*/
QString description()const;
/**
* A small summary of the todo
*/
QString summary() const;
/**
* @reimplemented
* Return this todoevent in a RichText formatted QString
*/
QString toRichText() const;
+ /*
+ * check if the sharing is still fine!! -zecke
+ */
+ /**
+ * return a reference to our notifiers...
+ */
+ OPimNotifyManager &notifiers();
+
/**
- * reimplementation
+ * reimplementations
*/
QString type()const;
QString toShortText()const;
QMap<QString, QString> toExtraMap()const;
QString recordField(int id )const;
/**
* toMap puts all data into the map. int relates
* to ToDoEvent RecordFields enum
*/
QMap<int, QString> toMap()const;
/**
* Set if this Todo is completed
*/
void setCompleted(bool completed );
/**
* set if this todo got an end data
*/
void setHasDueDate( bool hasDate );
-
- /**
- * set if this todo has an alarm time and date
- */
- void setHasAlarmDateTime ( bool hasAlarm );
+ // FIXME we do not have these for start, completed
+ // cause we'll use the isNull() of QDate for figuring
+ // out if it's has a date...
+ // decide what to do here? -zecke
/**
* Set the priority of the Todo
*/
void setPriority(int priority );
/**
* Set the progress.
*/
void setProgress( ushort progress );
/**
* set the end date
*/
- void setDueDate( QDate date );
+ void setDueDate( const QDate& date );
+ /**
+ * set the start date
+ */
+ void setStartDate( const QDate& date );
+
+ /**
+ * set the completed date
+ */
+ void setCompletedDate( const QDate& date );
void setRecurrence( const ORecur& );
/**
* set the alarm time
*/
void setAlarmDateTime ( const QDateTime& alarm );
void setDescription(const QString& );
void setSummary(const QString& );
/**
* set the state of a Todo
* @param state State what the todo should take
*/
void setState( const OPimState& state);
/**
* set the Maintainer Mode
*/
void setMaintainer( const OPimMaintainer& );
bool isOverdue();
bool match( const QRegExp &r )const;
bool operator<(const OTodo &toDoEvent )const;
bool operator<=(const OTodo &toDoEvent )const;
bool operator!=(const OTodo &toDoEvent )const;
bool operator>(const OTodo &toDoEvent )const;
bool operator>=(const OTodo &toDoEvent)const;
bool operator==(const OTodo &toDoEvent )const;
OTodo &operator=(const OTodo &toDoEvent );
+ static int rtti();
+
private:
class OTodoPrivate;
struct OTodoData;
void deref();
inline void changeOrModify();
void copy( OTodoData* src, OTodoData* dest );
OTodoPrivate *d;
OTodoData *data;
};
inline bool OTodo::operator!=(const OTodo &toDoEvent )const {
return !(*this == toDoEvent);
}
#endif
diff --git a/libopie2/opiepim/ui/opimmainwindow.cpp b/libopie2/opiepim/ui/opimmainwindow.cpp
new file mode 100644
index 0000000..92be2fd
--- a/dev/null
+++ b/libopie2/opiepim/ui/opimmainwindow.cpp
@@ -0,0 +1,71 @@
+#include <qapplication.h>
+#include <qcopchannel_qws.h>
+
+#include <qpe/qcopenvelope_qws.h>
+
+#include "opimmainwindow.h"
+
+OPimMainWindow::OPimMainWindow( const QString& service, QWidget* parent,
+ const char* name, WFlags flag )
+ : QMainWindow( parent, name, flag ), m_service( service ), m_fallBack(0l) {
+
+ /*
+ * let's generate our QCopChannel
+ */
+ m_str = QString("QPE/"+m_service).local8Bit();
+ m_channel= new QCopChannel(m_str, this );
+ connect(m_channel, SIGNAL(received(const QCString&, const QByteArray& ) ),
+ this, SLOT( appMessage( const QCString&, const QByteArray& ) ) );
+
+ /* connect flush and reload */
+ connect(qApp, SIGNAL(flush() ),
+ this, SLOT(flush() ) );
+ connect(qApp, SIGNAL(reload() ),
+ this, SLOT(reload() ) );
+}
+OPimMainWindow::~OPimMainWindow() {
+ delete m_channel;
+}
+QCopChannel* OPimMainWindow::channel() {
+ return m_channel;
+}
+void OPimMainWindow::appMessage( const QCString& cmd, const QByteArray& array ) {
+ /*
+ * create demands to create
+ * a new record...
+ */
+ QDataStream stream(array, IO_ReadOnly);
+ if ( cmd == "create()" ) {
+ int uid = create();
+ QCopEnvelope e(m_str, "created(int)" );
+ e << uid;
+ }else if ( cmd == "remove(int)" ) {
+ int uid;
+ stream >> uid;
+ bool rem = remove( uid );
+ QCopEnvelope e(m_str, "removed(bool)" );
+ e << rem;
+ }else if ( cmd == "beam(int,int)" ) {
+ int uid, trans;
+ stream >> uid;
+ stream >> trans;
+ beam( uid, trans );
+ }else if ( cmd == "show(int)" ) {
+ int uid;
+ stream >> uid;
+ show( uid );
+ }else if ( cmd == "edit(int)" ) {
+ int uid;
+ stream >> uid;
+ edit( uid );
+ }else if ( cmd == "add(int,QByteArray)" ) {
+ int rtti;
+ QByteArray array;
+ stream >> rtti;
+ stream >> array;
+ m_fallBack = record(rtti, array );
+ if (!m_fallBack) return;
+ add( *m_fallBack );
+ delete m_fallBack;
+ }
+}
diff --git a/libopie2/opiepim/ui/opimmainwindow.h b/libopie2/opiepim/ui/opimmainwindow.h
new file mode 100644
index 0000000..94100bd
--- a/dev/null
+++ b/libopie2/opiepim/ui/opimmainwindow.h
@@ -0,0 +1,79 @@
+#ifndef OPIE_PIM_MAINWINDOW_H
+#define OPIE_PIM_MAINWINDOW_H
+
+#include <qmainwindow.h>
+
+#include <opie/opimrecord.h>
+
+/**
+ * This is a common Opie PIM MainWindow
+ * it takes care of the QCOP internals
+ * and implements some functions
+ * for the URL scripting schema
+ */
+/*
+ * due Qt and Templates with signal and slots
+ * do not work that good :(
+ * (Ok how to moc a template ;) )
+ * We will have the mainwindow which calls a struct which
+ * is normally reimplemented as a template ;)
+ */
+
+class QCopChannel;
+class OPimMainWindow : public QMainWindow {
+ Q_OBJECT
+public:
+ enum TransPort { BlueTooth=0,
+ IrDa };
+
+ OPimMainWindow( const QString& service, QWidget *parent = 0, const char* name = 0,
+ WFlags f = WType_TopLevel);
+ virtual ~OPimMainWindow();
+
+
+protected slots:
+ /* for syncing */
+ virtual void flush() = 0;
+ virtual void reload() = 0;
+
+ /** create a new Records and return the uid */
+ virtual int create() = 0;
+ /** remove a record with UID == uid */
+ virtual bool remove( int uid ) = 0;
+ /** beam the record with UID = uid */
+ virtual void beam( int uid , int transport = IrDa) = 0;
+
+ /** show the record with UID == uid */
+ virtual void show( int uid ) = 0;
+ /** edit the record */
+ virtual void edit( int uid ) = 0;
+
+ /** make a copy of it! */
+ virtual void add( const OPimRecord& ) = 0;
+
+ /* I would love to do this as a template
+ * but can't think of a right way
+ * because I need signal and slots -zecke
+ */
+ /*
+ * the only pointer in the whole PIM API :(
+ */
+ virtual OPimRecord* record( int rtti, const QByteArray& ) = 0;
+ QCopChannel* channel();
+
+private slots:
+ void appMessage( const QCString&, const QByteArray& );
+
+
+private:
+ class Private;
+ Private* d;
+
+ QCopChannel* m_channel;
+ QString m_service;
+ QCString m_str;
+ OPimRecord* m_fallBack;
+};
+
+
+#endif