[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-pim
Subject:    Re: Grouping + importing
From:       Rik Hemsley <rik () rikkus ! demon ! co ! uk>
Date:       1999-07-20 16:20:38
[Download RAW message or body]


On 21-Jul-99 Don Sanders wrote:
> Currently the ABEE uses a ContactEntry class which is basically a QDict. The
> ABEB uses a ContactEntryList is basically a list of QDict.

Yes, this is also the approach I am using internally in the example
(called 'v2'). As you say, using a QDict to hold an entire addressbook is
plain daft. I'm only using a QDict as a fake backend. You give a key and you
get a value. I decided that keys should be unique ids rather than names or
whatever. The plan would be to change the QDict to an interface to a backend
which acts like a database, giving you data when you pass it a key. This could
actually be done even with something simple like gdbm as a start. /me leafs
through the gdbm docs.

> There is also the issue of whether/how the ABEB view should be updated when
> another client modifies teh address book 'database' the enduser could be
> required to manually refresh the view, (The outlook express ABEB seems to
> take
> this approach), alternatively CORBA could provide a nice network transparent
> soln to this.

I have been thinking about this whilst working on Empath. Empath will update
the display when new mail has arrived, without the user checking. A similar
approach can be applied with the addressbook UI.

> So as far an "OO model" goes I have these concerns:
> A) I think a QDict like interface with methods like
> ContactEntry::insert( QString field, QString value )
> ContactEntryList::defaultFields( QStringList fields )
> is the most natural for AB clients like the GUI stuff I have been doing.

It is the _easiest_ API but it doesn't fulfil the requirements.
You need to be able to store more than just QString as values. You can't use
QCString as a NUL will terminate the data, and QByteArray has gone. Therefore
I derived a 'CharBuf' from QShared and pass around (a typedef to)
KSharedPtr<CharBuf> called CharPtr. This allows you to read and write raw data
and has the advantage of reference counting.

defaultFields(QStringList) is a useful idea, and it is already in the original
API.

FieldList fields(const QString & fieldName)
and
FieldList fields(const QRegExp & expression)
are your friends here.

There's also stuff like:

FieldList fieldsWithValueType(ValueType)
and
FieldList fieldsWithValueType(const QString &)

for a similar purpose. Note that you can use one of the standard value types
by passing a ValueType enum or ask for an extension type by using the string
parameter.

These aren't in v2 yet, but I'll add them later.

> I'm not convinced that your second objective
> 2) Easy access to all parts of addressbook entities
> has been achieved, rather I think
> 2*) Easy access to all parts of vCardd address book entities
> has been achieved.
> 
> I think your API is an excellent vCard API but I am not convinced it is the
> most natural AB API. (Note basically this just means a QDict to vCard mapping
> is required, this has to be done at some point regardless, the question is
> when, I thinking a ContactEntry -> vCard Entity mapping needs to be written,
> I'm willing to do this but I need to compile your stuff first and will
> probably ask for help/clarification on some fields)

Are you saying 'it's a good API for vCard' or 'it is a vCard API' ? It's not
a vCard API. vCard is completely separate. v2 doesn't know anything about vCard.
You can see this where the import function is used - you only give a string to
identify the kind of format you think the data is in. The plugin is looked
for and loaded then handles the rest. Only the plugin knows about vCard (and
gets all its functionality from libvcard).

If you're saying that the API looks like a vCard API, I have to plead guilty.
It's similar, yes, but then the vCard model is a good one. I've simply replaced
it with an extensible format.

vCard:
Set of value types that are well defined. You may add extra information but
you cannot specify the type of that data and therefore cannot parse it.

v2:
Set of value types that are well defined. You may add extra information and
you _can_ specify the type of that data to facilitate parsing (and therefore
searching / sorting). 

I've basically just provided what you talk about above - a name to value map,
but I've added an API that allows easy access (for the programmer) to the
common fields. I hope this doesn't look like it's intended to nail down a set
of field names and value types. You can use it as a name-value map if you
so wish. The extra parts of the API are simply for convenience.

I've tried to make the standard fields so that they're completely general.
It's extremely difficult to do this for the whole planet. After a lot of
thought I decided that it would be better to associate people with a location,
rather than store a location within a person's record. In a similar vein,
I've provided for associating a 'Comms' object with any entity. This means
you can associate a 'Comms' object with a group (say a company) and have
a contact telephone number and address for the company. You can add extra
'Comms' objects to a person through their xValues. This means if you have
two 'work' contacts (here and overseas) and three 'home' contacts (home,
on the move and at the mistress) you can add them as extras. There's only
one 'Comms' object defined for a person by default.

> B) Have you given any though to dealing with large/remote address books, I'm
> thinking of dealing with this later. I think a whole new API and modified GUI
> is need to handle this
> (eg. server give me records x to y when sorted by field abc)

I think the API shouldn't be written to reflect the back end, but obviously
there will need to be parts to handle this kind of thing.
For example,
QStringList KAB::addressBooks();
returns 'Local', 'LDAP server at work', 'SomeOtherKabAcrossTheInternet'.

The GUI could then provide for selecting which addressbooks should be used
and call something like:
QStringList iWillUse;
iWillUse << "Local" << "LDAP server at work";
KAB::useAddressBooks(iWillUse);

This should be easy to do. Configuring new servers could be done through
the GUI or via a kcm module.

> I thinking the best way to handle addressbooks is to assumme that they have
> been broken up into sensible size folders/groups and load all entries in a
> folder at once, (so that an arbitrary set of fields can be displayed).
> Perhaps
> this could be optimized by providing a method that returns all subfolders in
> a
> folder so that a explorer like tree control for navigation could be provided.

Really ? I don't know if assuming that you have a small group to read is
necessarily a good plan. Loading everything into memory at once can't be
a smart move. Certainly a group browser would be very useful. I think the
back end should handle all storage and only communicate one entity at a time.
This way, kab will search by loading each record in turn and looking at it.
It's not the fastest method but should be acceptable and won't eat your swap :)

> C) Dynamic updating
> Does you model deal with this? I can see several different solns, require the
> user to manually update, chunky updates where the entire AB folder is
> reloaded
> whenever the AB is modified, or finer updating incrementally handling
> insertions/deletions and only refreshing/resorting modified entries.

Yes, I think as I said above this should be ok. kab can use a timer to check
if the database has been updated and when it has, tell the GUI.

> Other issues:
> Import abilities through a plugin interface sounds damn cool.

It is :) You can't imagine how happy I was when I wrote the code and it just
worked first time !

> You are using namespaces. I'm using egcs 1.03 at the moment and will have to
> upgrade before I can compile your code.

Yes, sorry about that. It would restrict what I'm doing if I didn't.

> My UI doesn't support all vCard info. For instance your sample vCard contains
> the line
> EMAIL;TYPE=INTERNET: rik@kde.org
> 
> currently my UI just has email, email-2 and email-3 fields. The draw back
> here
> is that if someone edits the sample vCard in my editor they will lose the
> TYPE
> inforamtion, and I can't handle more than 3 email fields. Also the entire TZ
> field will be lost as the GUI doesn't currently support it. (Perhaps I could
> automatically put this in the Custom fields tab).


Well, I don't support all vCard info either, not directly anyway. Certainly
I can add extra 'Comms' object to a person when they have more than one email
address, and I also (through the 'Member' entity) provide for associating
one email address with the person as a group member, and a separate one for
home. The vCard plugin does some nasty stuff to try and find either the one
and only email address given, or the one marked as preferred. This is then
used in the Person's Comms object.

I just drop the TZ field in the plugin, but I could simply do:
XValueList l = person->xValues();
XValue * x = new XValue;
x->setName("TimeZone");
x->setValue(timezoneString);
l.add(x);
person->setXValues(l);

(Apologies for the crap API for that. Will be fixed)

> Okay I hoped that made sense. By all accounts you have implemented an
> excellent vCard API but I think more discussion needs to take place regarding
> the AB API.

Certainly you made sense. I'm concerned you think that I've written a vCard API
though. This is supposed to be a general AB API with support for import filters
and an object model that matches the real world as closely as possible without
being locale dependent.

By all means discuss further ! I will not claim that I've provided the perfect
API by any means. This is draft #0.000001 and I've put out a Request For
Comments ;)

Cheers,
Rik


--
KDE - Colour outside the lines  : http://www.kde.org
[[without]] - software for KDE  : http://without.netpedia.net

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic