summaryrefslogtreecommitdiffabout
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--bin/kdepim/WhatsNew.txt22
-rw-r--r--kmicromail/libetpan/maildir/maildir.c25
-rw-r--r--kmicromail/libetpan/mh/mailmh.c12
-rw-r--r--korganizer/calendarview.cpp4
-rw-r--r--korganizer/kotodoview.cpp1
-rw-r--r--korganizer/kotodoviewitem.cpp2
-rw-r--r--libkcal/sharpformat.cpp7
-rw-r--r--version2
8 files changed, 60 insertions, 15 deletions
diff --git a/bin/kdepim/WhatsNew.txt b/bin/kdepim/WhatsNew.txt
index 4905631..eb7cf13 100644
--- a/bin/kdepim/WhatsNew.txt
+++ b/bin/kdepim/WhatsNew.txt
@@ -1,194 +1,216 @@
Info about the changes in new versions of KDE-Pim/Pi
+********** VERSION 1.9.14 ************
+
+Fixed some problems with the dialog sizes when switching
+portrait/landscape mode on 640x480 PDA display.
+
+Fixed some other small bugs.
+
+Fixed an ugly bug in KOpieMail:
+KOpieMail was not able to write files (mails) to MSDOS file system,
+like on an usual preformatted SD card. That should work now.
+To save your mail data on the Sd card do the following:
+Create a dir on the SD card:
+mkdir /mnt/card/localmail
+Go to your home dir:
+cd
+Go to kopiemail data storage dir:
+cd kdepim/apps/kopiemail
+Create a symlink to the SD card:
+ls -s /mnt/card/localmail
+Now KOpieMail will store all mails on the SD card.
+
+
********** VERSION 1.9.13 ************
Fixed nasty PwM/Pi file reading bug, when
the used hash algo of file is different then the global
hash algo.
Added KA/Pi support for opie mailit mailapplication.
Fixed some bugs in OM/Pi.
Now character conversion tables are available for the Zaurus
to make OM/Pi working properly.
To get the character conversion in OM/Pi working, please download
at the sourceforge project site the package
sr-character-conversion_SharpROM_arm.ipk.zip
(or oz-character-conversion_OZ-gcc3xx_arm.ipk.zip for OZ roms)
from the section "general files for KDE/Pim"
Instructions how to install this package are in a ReadMe in this file.
Fixed the orientation change problem in KA/Pi when switching
portrait/landscape mode.
French translation available for KA/Pi and OM/Pi.
Fixed some problems with categories in KO/Pi in DTM sync.
Added selection dialog for export to phone in KA/Pi.
If in KO/Pi is an attendee selected to add to a meeting and this
attendee is already in the list of attendees, this person is not added
again.
Some menu cleanup in KA/Pi.
********** VERSION 1.9.12 ************
Fix for the bug in KO/Pi What's Next view of version 1.9.11.
Bugfix: Licence file is now shown again.
OM/Pi now supports Unicode (utf8 charset).
Fixed some bugs in OM/Pi.
KA/Pi has more German translation.
********** VERSION 1.9.11 ************
Fixed several problems in PWM/Pi, like
asking the user, if unsaved changed are pending
when closing the app.
And PwM/Pi handles now different texts for the
fields Description, Username, Password, configurable per category.
Fixed a crash in KO/Pi , when importing/loading vcs files
which have an entry with an attendee with state:
NEEDS ACTION
Fixed some problems in the German translation of OM/Pi,
which makes some dialogs not fitting on the screen
of the Z 5500.
Fixed Qtopia crash, when disabling/deinstalling
KO/Pi alarm applet.
Implemented direct KDE<->KA/Pi sync for KA/Pi running
on Linux desktop.
Added feature "remove sync info" to sync menu.
Tweaked the KO/Pi What's next view a bit, added
setting to hide events that are done.
Disabled "beam receive enabled" on startup to
avoid problems if Fastload is enabled.
Please set "beam receive enabled",
if you want to receive data via IR.
Fixed bug in direct KDE<->KO/Pi sync for KO/Pi running
on Linux desktop.
Made in KA/Pi scrolling possible, if details view is selected.
(The keyboard focus is set automatically to the search line)
Fixed a bug in DMT sync, that a new entry in DTM was added
on every sync to Kx/Pi.
Fixed missing writing of KA/Pi categories to DMT entries when syncing.
Fixed a bug in DMT sync with todos created in KO/Pi containing
non-latin1 characters.
Rearranged package contents of Sharp-ipks and made all
packages installable on SD again.
Fixed the writing of addressbook data in DTM sync.
Empty fields in KA/Pi were not removed.
Added better category handling in KA/Pi:
Added item
Edit Categories and
Manage new categories
to the settings menu.
Possible to configure a view to display categories.
Added detailed "KDE Sync Howto" and "Multi Sync Howto" to Help menu.
Fixed displaying of "free" days and time in KO Monthview and Agendaview.
... and many other bugfixes.
********** VERSION 1.9.10 ************
Many internal small bugfixes.
And fix of the "big" bug in KO/Pi,
that after Syncing the appointments had an offset by several hours.
That was a problem with the internal timezone setting,
introduced by the changed timezone configuration settings.
German translation for OM/Pi is now available.
********** VERSION 1.9.9 ************
KDE-Pim/Pi has a new Member!
It is called PWM/Pi (Passwordmanager/platform-independent)
and it is available for the Zaurus.
It is planned, that it will be available later for Windows.
(And for Linux, of course).
It is a port of the Passwordmanager of KDE.
It will need the MicroKDElibs to run.
Made loading of addressbooks in KA/Pi up to 7 times faster!
The bigger your addressbook file, the more starting speed
will you gain. (relatively)
The Qtopia addressbook connector is now platform independend
as well and should work on any platform for importing/exporting
Qtopia and Opie XML files.
Added a +30min feature to the timezone settings to make
KDE-Pim/Pi useable in Australia and other parts on the
world with strange timezones ;-)
German "Umlaute" should now be sorted correctly on the Z in KA/Pi.
It is now possible to disable the
"receive data via infrared" feature, such that syncing with
Outlook is now possible again with Kx/Pi runing.
Please disable it, before syncing Sharp DTM with Outlook.
For your convenience, the "receive data via infrared" feature
is disabled automatically, if you sync Kx/Pi with DTM.
You have to enable it again manually after syncing.
Enabling this feature makes it impossible to start the
Sharp DTM apps. If this feature is enabled, you will only get the
alarm notification from KO/Pi and not from the Sharp calendar.
This is very useful if you sync KO/Pi with Sharp DTM,
because after syncing you usually would get notified about
an alarm by KO/Pi and the Sharp Calendar.
Together with the Linux desktop version of KO/Pi
it is now possible to sync KO/Pi on the Zaurus
with the complete KDE-desktop (3.3 or later)
calendar data easily.
That makes it possible to sync the Z with one
click of a mouse with the KDE-Desktop.
This feature it available for all Zaurus platforms KO/Pi
is running on.
The only thing needed is a running KO/Pi on Linux and
a compiled version of the small
KDE-Pim/Pi<->KDE-Desktop access command line program,
which is in the KDE-Pim/Pi sources available.
The "KDE-desktop" syncing feature for KA/Pi will follow
in the next releases.
Fixed the vcard export bug, which had the version 1.9.8.
Added missing GERMAN translation to KO/Pi.
Hi PsionX, could you add the missing french translation?Thx!
Translation files for KA/Pi are available as well.
GERMAN translation will be available in the next release.
PsionX ( yres, you again ;-) ), could you start translating
KA/Pi? Thx!
You can download the version 1.9.9 at
http://sourceforge.net/project/showfiles.php?group_id=104103&package_id=112604
Note:
To run the mail program OM/Pi you need libopenssl.
diff --git a/kmicromail/libetpan/maildir/maildir.c b/kmicromail/libetpan/maildir/maildir.c
index 0e038b1..1ef0b7a 100644
--- a/kmicromail/libetpan/maildir/maildir.c
+++ b/kmicromail/libetpan/maildir/maildir.c
@@ -1,729 +1,740 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001 - 2003 - DINH Viet Hoa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the libEtPan! project nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* $Id$
*/
#include "maildir.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <dirent.h>
#include <time.h>
#include <sys/stat.h>
#include <sys/mman.h>
#ifdef LIBETPAN_SYSTEM_BASENAME
#include <libgen.h>
#endif
/*
We suppose the maildir mailbox remains on one unique filesystem.
*/
struct maildir * maildir_new(const char * path)
{
struct maildir * md;
md = malloc(sizeof(* md));
if (md == NULL)
goto err;
md->mdir_counter = 0;
md->mdir_mtime_new = (time_t) -1;
md->mdir_mtime_cur = (time_t) -1;
md->mdir_pid = getpid();
gethostname(md->mdir_hostname, sizeof(md->mdir_hostname));
strncpy(md->mdir_path, path, sizeof(md->mdir_path));
md->mdir_path[PATH_MAX - 1] = '\0';
md->mdir_msg_list = carray_new(128);
if (md->mdir_msg_list == NULL)
goto free;
md->mdir_msg_hash = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYNONE);
if (md->mdir_msg_hash == NULL)
goto free_msg_list;
return md;
free_msg_list:
carray_free(md->mdir_msg_list);
free:
free(md);
err:
return NULL;
}
static void maildir_flush(struct maildir * md, int msg_new);
void maildir_free(struct maildir * md)
{
maildir_flush(md, 0);
maildir_flush(md, 1);
chash_free(md->mdir_msg_hash);
carray_free(md->mdir_msg_list);
free(md);
}
#define MAX_TRY_ALLOC 32
static char * maildir_get_new_message_filename(struct maildir * md,
char * tmpfile)
{
char filename[PATH_MAX];
char basename[PATH_MAX];
int k;
time_t now;
-
+ struct stat f_stat;
now = time(NULL);
k = 0;
+
+ fprintf(stderr,"maildir_get_new_message_filename: %s \n", tmpfile);
while (k < MAX_TRY_ALLOC) {
snprintf(basename, sizeof(basename), "%lu.%u_%u.%s",
(unsigned long) now, md->mdir_pid, md->mdir_counter, md->mdir_hostname);
snprintf(filename, sizeof(filename), "%s/tmp/%s",
md->mdir_path, basename);
-
- if (link(tmpfile, filename) == 0) {
+ fprintf(stderr,"filename %s \n", filename);
+ // LR changed following lines
+ if ( stat( filename, &f_stat ) == -1 ) {
+ //if (link(tmpfile, filename) == 0) {
char * dup_filename;
dup_filename = strdup(filename);
if (dup_filename == NULL) {
- unlink(filename);
+ //unlink(filename);
return NULL;
}
-
- unlink(tmpfile);
+ fprintf(stderr,"filename %s %s \n", tmpfile,dup_filename);
+ //unlink(tmpfile);
+ rename (tmpfile,dup_filename );
md->mdir_counter ++;
return dup_filename;
}
md->mdir_counter ++;
k ++;
}
return NULL;
}
static void msg_free(struct maildir_msg * msg)
{
free(msg->msg_uid);
free(msg->msg_filename);
free(msg);
}
/*
msg_new()
filename is given without path
*/
static struct maildir_msg * msg_new(char * filename, int new_msg)
{
struct maildir_msg * msg;
char * p;
int flags;
size_t uid_len;
char * begin_uid;
/* name of file : xxx-xxx_xxx-xxx:2,SRFT */
msg = malloc(sizeof(* msg));
if (msg == NULL)
goto err;
msg->msg_filename = strdup(filename);
if (msg->msg_filename == NULL)
goto free;
begin_uid = filename;
uid_len = strlen(begin_uid);
flags = 0;
p = strstr(filename, ":2,");
if (p != NULL) {
uid_len = p - begin_uid;
p += 3;
/* parse flags */
while (* p != '\0') {
switch (* p) {
case 'S':
flags |= MAILDIR_FLAG_SEEN;
break;
case 'R':
flags |= MAILDIR_FLAG_REPLIED;
break;
case 'F':
flags |= MAILDIR_FLAG_FLAGGED;
break;
case 'T':
flags |= MAILDIR_FLAG_TRASHED;
break;
}
p ++;
}
}
if (new_msg)
flags |= MAILDIR_FLAG_NEW;
msg->msg_flags = flags;
msg->msg_uid = malloc(uid_len + 1);
if (msg->msg_uid == NULL)
goto free_filename;
strncpy(msg->msg_uid, begin_uid, uid_len);
msg->msg_uid[uid_len] = '\0';
return msg;
free_filename:
free(msg->msg_filename);
free:
free(msg);
err:
return NULL;
}
static void maildir_flush(struct maildir * md, int msg_new)
{
unsigned int i;
i = 0;
while (i < carray_count(md->mdir_msg_list)) {
struct maildir_msg * msg;
int delete;
msg = carray_get(md->mdir_msg_list, i);
if (msg_new) {
delete = 0;
if ((msg->msg_flags & MAILDIR_FLAG_NEW) != 0)
delete = 1;
}
else {
delete = 1;
if ((msg->msg_flags & MAILDIR_FLAG_NEW) != 0)
delete = 0;
}
if (delete) {
chashdatum key;
key.data = msg->msg_uid;
key.len = strlen(msg->msg_uid);
chash_delete(md->mdir_msg_hash, &key, NULL);
carray_delete(md->mdir_msg_list, i);
msg_free(msg);
}
else {
i ++;
}
}
}
static int add_message(struct maildir * md,
char * filename, int is_new)
{
struct maildir_msg * msg;
chashdatum key;
chashdatum value;
unsigned int i;
int res;
int r;
+ fprintf(stderr,"add_message filename: %s \n", filename);
msg = msg_new(filename, is_new);
if (msg == NULL) {
res = MAILDIR_ERROR_MEMORY;
goto err;
}
r = carray_add(md->mdir_msg_list, msg, &i);
if (r < 0) {
res = MAILDIR_ERROR_MEMORY;
goto free_msg;
}
key.data = msg->msg_uid;
key.len = strlen(msg->msg_uid);
value.data = msg;
value.len = 0;
r = chash_set(md->mdir_msg_hash, &key, &value, NULL);
if (r < 0) {
res = MAILDIR_ERROR_MEMORY;
goto delete;
}
return MAILDIR_NO_ERROR;
delete:
carray_delete(md->mdir_msg_list, i);
free_msg:
msg_free(msg);
err:
return res;
}
static int add_directory(struct maildir * md, char * path, int is_new)
{
DIR * d;
struct dirent * entry;
int res;
int r;
char filename[PATH_MAX];
d = opendir(path);
if (d == NULL) {
res = MAILDIR_ERROR_DIRECTORY;
goto err;
}
while ((entry = readdir(d)) != NULL) {
struct stat stat_info;
snprintf(filename, sizeof(filename), "%s/%s", path, entry->d_name);
r = stat(filename, &stat_info);
if (r < 0)
continue;
if (S_ISDIR(stat_info.st_mode))
continue;
r = add_message(md, entry->d_name, is_new);
if (r != MAILDIR_NO_ERROR) {
/* ignore errors */
}
}
closedir(d);
return MAILDIR_NO_ERROR;
err:
return res;
}
int maildir_update(struct maildir * md)
{
struct stat stat_info;
char path_new[PATH_MAX];
char path_cur[PATH_MAX];
int r;
int res;
snprintf(path_new, sizeof(path_new), "%s/new", md->mdir_path);
snprintf(path_cur, sizeof(path_cur), "%s/cur", md->mdir_path);
/* did new/ changed ? */
r = stat(path_new, &stat_info);
if (r < 0) {
res = MAILDIR_ERROR_DIRECTORY;
goto free;
}
if (md->mdir_mtime_new != stat_info.st_mtime) {
md->mdir_mtime_new = stat_info.st_mtime;
maildir_flush(md, 1);
/* messages in new */
r = add_directory(md, path_new, 1);
if (r != MAILDIR_NO_ERROR) {
res = r;
goto free;
}
}
/* did cur/ changed ? */
r = stat(path_cur, &stat_info);
if (r < 0) {
res = MAILDIR_ERROR_DIRECTORY;
goto free;
}
if (md->mdir_mtime_cur != stat_info.st_mtime) {
md->mdir_mtime_cur = stat_info.st_mtime;
maildir_flush(md, 0);
/* messages in cur */
r = add_directory(md, path_cur, 0);
if (r != MAILDIR_NO_ERROR) {
res = r;
goto free;
}
}
return MAILDIR_NO_ERROR;
free:
maildir_flush(md, 0);
maildir_flush(md, 1);
md->mdir_mtime_cur = (time_t) -1;
md->mdir_mtime_new = (time_t) -1;
return res;
}
#ifndef LIBETPAN_SYSTEM_BASENAME
static char * libetpan_basename(char * filename)
{
char * next;
char * p;
p = filename;
next = strchr(p, '/');
while (next != NULL) {
p = next;
next = strchr(p + 1, '/');
}
if (p == filename)
return filename;
else
return p + 1;
}
#else
#define libetpan_basename(a) basename(a)
#endif
int maildir_message_add_uid(struct maildir * md,
const char * message, size_t size,
char * uid, size_t max_uid_len)
{
char path_new[PATH_MAX];
char tmpname[PATH_MAX];
int fd;
int r;
char * mapping;
char * delivery_tmp_name;
char * delivery_tmp_basename;
char delivery_new_name[PATH_MAX];
char * delivery_new_basename;
int res;
struct stat stat_info;
+ fprintf(stderr,"maildir_message_add_uid for uid: %s \n", uid);
r = maildir_update(md);
if (r != MAILDIR_NO_ERROR) {
res = r;
goto err;
}
/* write to tmp/ with a classic temporary file */
snprintf(tmpname, sizeof(tmpname), "%s/tmp/etpan-maildir-XXXXXX",
md->mdir_path);
fd = mkstemp(tmpname);
if (fd < 0) {
res = MAILDIR_ERROR_FILE;
goto err;
}
r = ftruncate(fd, size);
if (r < 0) {
res = MAILDIR_ERROR_FILE;
goto close;
}
mapping = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (mapping == MAP_FAILED) {
res = MAILDIR_ERROR_FILE;
goto close;
}
memcpy(mapping, message, size);
msync(mapping, size, MS_SYNC);
munmap(mapping, size);
close(fd);
/* write to tmp/ with maildir standard name */
delivery_tmp_name = maildir_get_new_message_filename(md, tmpname);
if (delivery_tmp_name == NULL) {
res = MAILDIR_ERROR_FILE;
goto unlink;
}
/* write to new/ with maildir standard name */
strncpy(tmpname, delivery_tmp_name, sizeof(tmpname));
tmpname[sizeof(tmpname) - 1] = '\0';
delivery_tmp_basename = libetpan_basename(tmpname);
snprintf(delivery_new_name, sizeof(delivery_new_name), "%s/new/%s",
md->mdir_path, delivery_tmp_basename);
r = link(delivery_tmp_name, delivery_new_name);
if (r < 0) {
res = MAILDIR_ERROR_FILE;
goto unlink_tmp;
}
snprintf(path_new, sizeof(path_new), "%s/new", md->mdir_path);
r = stat(path_new, &stat_info);
if (r < 0) {
unlink(delivery_new_name);
res = MAILDIR_ERROR_FILE;
goto unlink_tmp;
}
md->mdir_mtime_new = stat_info.st_mtime;
delivery_new_basename = libetpan_basename(delivery_new_name);
r = add_message(md, delivery_new_basename, 1);
if (r != MAILDIR_NO_ERROR) {
unlink(delivery_new_name);
res = MAILDIR_ERROR_FILE;
goto unlink_tmp;
}
if (uid != NULL)
strncpy(uid, delivery_new_basename, max_uid_len);
unlink(delivery_tmp_name);
free(delivery_tmp_name);
return MAILDIR_NO_ERROR;
unlink_tmp:
unlink(delivery_tmp_name);
free(delivery_tmp_name);
goto err;
close:
close(fd);
unlink:
unlink(tmpname);
err:
return res;
}
int maildir_message_add(struct maildir * md,
const char * message, size_t size)
{
return maildir_message_add_uid(md, message, size,
NULL, 0);
}
int maildir_message_add_file_uid(struct maildir * md, int fd,
char * uid, size_t max_uid_len)
{
char * message;
struct stat buf;
int r;
+ fprintf(stderr,"maildir_message_add_file_uid: %s \n", uid);
if (fstat(fd, &buf) == -1)
return MAILDIR_ERROR_FILE;
message = mmap(NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (message == MAP_FAILED)
return MAILDIR_ERROR_FILE;
r = maildir_message_add_uid(md, message, buf.st_size, uid, max_uid_len);
munmap(message, buf.st_size);
return r;
}
int maildir_message_add_file(struct maildir * md, int fd)
{
+ fprintf(stderr,"maildir_message_add_file \n");
return maildir_message_add_file_uid(md, fd,
NULL, 0);
}
char * maildir_message_get(struct maildir * md, const char * uid)
{
chashdatum key;
chashdatum value;
char filename[PATH_MAX];
char * dup_filename;
struct maildir_msg * msg;
char * dir;
int r;
+ fprintf(stderr,"maildir_message_get for uid: %s \n", uid);
key.data = (void *) uid;
key.len = strlen(uid);
r = chash_get(md->mdir_msg_hash, &key, &value);
if (r < 0)
return NULL;
msg = value.data;
if ((msg->msg_flags & MAILDIR_FLAG_NEW) != 0)
dir = "new";
else
dir = "cur";
snprintf(filename, sizeof(filename), "%s/%s/%s",
md->mdir_path, dir, msg->msg_filename);
dup_filename = strdup(filename);
if (dup_filename == NULL)
return NULL;
return dup_filename;
}
int maildir_message_remove(struct maildir * md, const char * uid)
{
chashdatum key;
chashdatum value;
char filename[PATH_MAX];
struct maildir_msg * msg;
char * dir;
int r;
int res;
+ fprintf(stderr,"maildir_message_remove for uid: %s \n", uid);
key.data = (void *) uid;
key.len = strlen(uid);
r = chash_get(md->mdir_msg_hash, &key, &value);
if (r < 0) {
res = MAILDIR_ERROR_NOT_FOUND;
goto err;
}
msg = value.data;
if ((msg->msg_flags & MAILDIR_FLAG_NEW) != 0)
dir = "new";
else
dir = "cur";
snprintf(filename, sizeof(filename), "%s/%s/%s",
md->mdir_path, dir, msg->msg_filename);
r = unlink(filename);
if (r < 0) {
res = MAILDIR_ERROR_FILE;
goto err;
}
return MAILDIR_NO_ERROR;
err:
return res;
}
int maildir_message_change_flags(struct maildir * md,
const char * uid, int new_flags)
{
chashdatum key;
chashdatum value;
char filename[PATH_MAX];
struct maildir_msg * msg;
char * dir;
int r;
char new_filename[PATH_MAX];
char flag_str[5];
size_t i;
int res;
-
+ fprintf(stderr,"maildir_message_change_flags for uid: %s \n", uid);
key.data = (void *) uid;
key.len = strlen(uid);
r = chash_get(md->mdir_msg_hash, &key, &value);
if (r < 0) {
res = MAILDIR_ERROR_NOT_FOUND;
goto err;
}
msg = value.data;
if ((msg->msg_flags & MAILDIR_FLAG_NEW) != 0)
dir = "new";
else
dir = "cur";
snprintf(filename, sizeof(filename), "%s/%s/%s",
md->mdir_path, dir, msg->msg_filename);
if ((new_flags & MAILDIR_FLAG_NEW) != 0)
dir = "new";
else
dir = "cur";
i = 0;
if ((new_flags & MAILDIR_FLAG_SEEN) != 0) {
flag_str[i] = 'S';
i ++;
}
if ((new_flags & MAILDIR_FLAG_REPLIED) != 0) {
flag_str[i] = 'R';
i ++;
}
if ((new_flags & MAILDIR_FLAG_FLAGGED) != 0) {
flag_str[i] = 'F';
i ++;
}
if ((new_flags & MAILDIR_FLAG_TRASHED) != 0) {
flag_str[i] = 'T';
i ++;
}
flag_str[i] = 0;
if (flag_str[0] == '\0')
snprintf(new_filename, sizeof(new_filename), "%s/%s/%s",
md->mdir_path, dir, msg->msg_uid);
else
snprintf(new_filename, sizeof(new_filename), "%s/%s/%s:2,%s",
md->mdir_path, dir, msg->msg_uid, flag_str);
if (strcmp(filename, new_filename) == 0)
return MAILDIR_NO_ERROR;
r = link(filename, new_filename);
if (r < 0) {
res = MAILDIR_ERROR_FILE;
goto err;
}
unlink(filename);
return MAILDIR_NO_ERROR;
err:
return res;
}
diff --git a/kmicromail/libetpan/mh/mailmh.c b/kmicromail/libetpan/mh/mailmh.c
index 119f217..5e2b4cc 100644
--- a/kmicromail/libetpan/mh/mailmh.c
+++ b/kmicromail/libetpan/mh/mailmh.c
@@ -418,402 +418,406 @@ int mailmh_folder_update(struct mailmh_folder * folder)
key.len = strlen(ent->d_name);
r = chash_get(folder->fl_subfolders_hash, &key, &data);
if (r < 0) {
subfolder = mailmh_folder_new(folder, ent->d_name);
if (subfolder == NULL) {
res = MAILMH_ERROR_MEMORY;
goto closedir;
}
r = carray_add(folder->fl_subfolders_tab, subfolder, &array_index);
if (r < 0) {
mailmh_folder_free(subfolder);
res = MAILMH_ERROR_MEMORY;
goto closedir;
}
subfolder->fl_array_index = array_index;
key.data = subfolder->fl_filename;
key.len = strlen(subfolder->fl_filename);
data.data = subfolder;
data.len = 0;
r = chash_set(folder->fl_subfolders_hash, &key, &data, NULL);
if (r < 0) {
carray_delete_fast(folder->fl_subfolders_tab, subfolder->fl_array_index);
mailmh_folder_free(subfolder);
res = MAILMH_ERROR_MEMORY;
goto closedir;
}
}
}
}
}
while (ent != NULL);
folder->fl_max_index = max_index;
mh_seq = malloc(strlen(folder->fl_filename) + 2 + sizeof(".mh_sequences"));
if (mh_seq == NULL) {
res = MAILMH_ERROR_MEMORY;
goto closedir;
}
strcpy(mh_seq, folder->fl_filename);
strcat(mh_seq, MAIL_DIR_SEPARATOR_S);
strcat(mh_seq, ".mh_sequences");
if (stat(mh_seq, &buf) == -1) {
int fd;
fd = creat(mh_seq, S_IRUSR | S_IWUSR);
if (fd != -1)
close(fd);
}
free(mh_seq);
closedir(d);
return MAILMH_NO_ERROR;
closedir:
closedir(d);
err:
return res;
}
int mailmh_folder_add_subfolder(struct mailmh_folder * parent,
const char * name)
{
char * foldername;
int r;
struct mailmh_folder * folder;
unsigned int array_index;
chashdatum key;
chashdatum data;
foldername = malloc(strlen(parent->fl_filename) + strlen(name) + 2);
if (foldername == NULL)
return MAILMH_ERROR_MEMORY;
strcpy(foldername, parent->fl_filename);
strcat(foldername, MAIL_DIR_SEPARATOR_S);
strcat(foldername, name);
r = mkdir(foldername, 0700);
free(foldername);
if (r < 0)
return MAILMH_ERROR_FOLDER;
folder = mailmh_folder_new(parent, name);
if (folder == NULL)
return MAILMH_ERROR_MEMORY;
r = carray_add(parent->fl_subfolders_tab, folder, &array_index);
if (r < 0) {
mailmh_folder_free(folder);
return MAILMH_ERROR_MEMORY;
}
folder->fl_array_index = array_index;
key.data = folder->fl_filename;
key.len = strlen(folder->fl_filename);
data.data = folder;
data.len = 0;
r = chash_set(parent->fl_subfolders_hash, &key, &data, NULL);
if (r < 0) {
carray_delete_fast(folder->fl_subfolders_tab, folder->fl_array_index);
mailmh_folder_free(folder);
return MAILMH_ERROR_MEMORY;
}
return MAILMH_NO_ERROR;
}
int mailmh_folder_remove_subfolder(struct mailmh_folder * folder)
{
struct mailmh_folder * parent;
chashdatum key;
chashdatum data;
int r;
parent = folder->fl_parent;
key.data = folder->fl_filename;
key.len = strlen(folder->fl_filename);
r = chash_get(parent->fl_subfolders_hash, &key, &data);
if (r < 0)
return MAILMH_ERROR_FOLDER;
chash_delete(parent->fl_subfolders_hash, &key, NULL);
carray_delete_fast(parent->fl_subfolders_tab, folder->fl_array_index);
mailmh_folder_free(folder);
return MAILMH_NO_ERROR;
}
int mailmh_folder_rename_subfolder(struct mailmh_folder * src_folder,
struct mailmh_folder * dst_folder,
const char * new_name)
{
int r;
struct mailmh_folder * folder;
struct mailmh_folder * parent;
char * new_foldername;
parent = src_folder->fl_parent;
if (parent == NULL)
return MAILMH_ERROR_RENAME;
new_foldername = malloc(strlen(dst_folder->fl_filename) + 2 + strlen(new_name));
if (new_foldername == NULL)
return MAILMH_ERROR_MEMORY;
strcpy(new_foldername, dst_folder->fl_filename);
strcat(new_foldername, MAIL_DIR_SEPARATOR_S);
strcat(new_foldername, new_name);
r = rename(src_folder->fl_filename, new_foldername);
free(new_foldername);
if (r < 0)
return MAILMH_ERROR_RENAME;
r = mailmh_folder_remove_subfolder(src_folder);
if (r != MAILMH_NO_ERROR)
return r;
folder = mailmh_folder_new(dst_folder, new_name);
if (folder == NULL)
return MAILMH_ERROR_MEMORY;
r = carray_add(parent->fl_subfolders_tab, folder, NULL);
if (r < 0) {
mailmh_folder_free(folder);
return MAILMH_ERROR_MEMORY;
}
return MAILMH_NO_ERROR;
}
#define MAX_TRY_ALLOC 32
/* initial file MUST be in the same directory */
static int mailmh_folder_alloc_msg(struct mailmh_folder * folder,
char * filename, uint32_t * result)
{
uint32_t max;
uint32_t k;
char * new_filename;
size_t len;
+ struct stat f_stat;
len = strlen(folder->fl_filename) + 20;
new_filename = malloc(len);
if (new_filename == NULL)
return MAILMH_ERROR_MEMORY;
max = folder->fl_max_index + 1;
+ //fprintf(stderr,"mailmh_folder_alloc_msg filename: %s \n", filename);
k = 0;
while (k < MAX_TRY_ALLOC) {
snprintf(new_filename, len, "%s%c%lu", folder->fl_filename,
MAIL_DIR_SEPARATOR, (unsigned long) (max + k));
-
- if (link(filename, new_filename) == 0) {
+ //fprintf(stderr,"mailmh_folder_alloc_msg new_filename: %s \n", new_filename);
+ if ( stat( new_filename, &f_stat ) == -1 ) {
+ // if (link(filename, new_filename) == 0) {
int r;
-
+ //fprintf(stderr,"filename found \n");
+ //unlink(filename);
+ rename (filename,new_filename );
free(new_filename);
- unlink(filename);
if (k > MAX_TRY_ALLOC / 2) {
r = mailmh_folder_update(folder);
/* ignore errors */
}
* result = max + k;
folder->fl_max_index = max + k;
return MAILMH_NO_ERROR;
}
else if (errno == EXDEV) {
free(filename);
return MAILMH_ERROR_FOLDER;
}
k ++;
}
free(new_filename);
return MAILMH_ERROR_FOLDER;
}
int mailmh_folder_get_message_filename(struct mailmh_folder * folder,
uint32_t index, char ** result)
{
char * filename;
int len;
#if 0
r = mailmh_folder_update(folder);
if (r != MAILMH_NO_ERROR)
return r;
#endif
len = strlen(folder->fl_filename) + 20;
filename = malloc(len);
if (filename == NULL)
return MAILMH_ERROR_MEMORY;
snprintf(filename, len, "%s%c%lu", folder->fl_filename, MAIL_DIR_SEPARATOR,
(unsigned long) index);
* result = filename;
return MAILMH_NO_ERROR;;
}
int mailmh_folder_get_message_fd(struct mailmh_folder * folder,
uint32_t index, int flags, int * result)
{
char * filename;
int fd;
int r;
#if 0
r = mailmh_folder_update(folder);
if (r != MAILMH_NO_ERROR)
return r;
#endif
r = mailmh_folder_get_message_filename(folder, index, &filename);
if (r != MAILMH_NO_ERROR)
return r;
fd = open(filename, flags);
free(filename);
if (fd == -1)
return MAILMH_ERROR_MSG_NOT_FOUND;
* result = fd;
return MAILMH_NO_ERROR;
}
int mailmh_folder_get_message_size(struct mailmh_folder * folder,
uint32_t index, size_t * result)
{
int r;
char * filename;
struct stat buf;
r = mailmh_folder_get_message_filename(folder, index, &filename);
if (r != MAILMH_NO_ERROR)
return r;
r = stat(filename, &buf);
free(filename);
if (r < 0)
return MAILMH_ERROR_FILE;
* result = buf.st_size;
return MAILMH_NO_ERROR;
}
int mailmh_folder_add_message_uid(struct mailmh_folder * folder,
const char * message, size_t size,
uint32_t * pindex)
{
char * tmpname;
int fd;
size_t namesize;
size_t left;
ssize_t res;
struct mailmh_msg_info * msg_info;
uint32_t index;
int error;
int r;
unsigned int array_index;
struct stat buf;
chashdatum key;
chashdatum data;
#if 0
r = mailmh_folder_update(folder);
if (r != MAILMH_NO_ERROR) {
error = r;
goto err;
}
#endif
namesize = strlen(folder->fl_filename) + 20;
tmpname = malloc(namesize);
snprintf(tmpname, namesize, "%s%ctmpXXXXXX",
folder->fl_filename, MAIL_DIR_SEPARATOR);
fd = mkstemp(tmpname);
if (fd < 0) {
error = MAILMH_ERROR_FILE;
goto free;
}
left = size;
while (left > 0) {
res = write(fd, message, left);
if (res == -1) {
close(fd);
error = MAILMH_ERROR_FILE;
goto free;
}
left -= res;
}
close(fd);
r = stat(tmpname, &buf);
if (r < 0) {
error = MAILMH_ERROR_FILE;
goto free;
}
r = mailmh_folder_alloc_msg(folder, tmpname, &index);
if (r != MAILMH_NO_ERROR) {
unlink(tmpname);
error = MAILMH_ERROR_COULD_NOT_ALLOC_MSG;
goto free;
}
free(tmpname);
msg_info = mailmh_msg_info_new(index, size, buf.st_mtime);
if (msg_info == NULL) {
mailmh_folder_remove_message(folder, index);
error = MAILMH_ERROR_MEMORY;
goto err;
}
r = carray_add(folder->fl_msgs_tab, msg_info, &array_index);
if (r < 0) {
mailmh_folder_remove_message(folder, index);
mailmh_msg_info_free(msg_info);
error = MAILMH_ERROR_MEMORY;
goto err;
}
msg_info->msg_array_index = array_index;
#if 0
r = cinthash_add(folder->fl_msgs_hash, index, msg_info);
#endif
key.data = &index;
key.len = sizeof(index);
data.data = msg_info;
data.len = 0;
if (pindex != NULL)
* pindex = index;
r = chash_set(folder->fl_msgs_hash, &key, &data, NULL);
if (r < 0) {
carray_delete_fast(folder->fl_msgs_tab, msg_info->msg_array_index);
mailmh_msg_info_free(msg_info);
diff --git a/korganizer/calendarview.cpp b/korganizer/calendarview.cpp
index 2321087..3908dbb 100644
--- a/korganizer/calendarview.cpp
+++ b/korganizer/calendarview.cpp
@@ -2258,392 +2258,396 @@ void CalendarView::removeCategories()
inc->setCategories( newCatList.join(",") );
inc = incList.next();
}
}
int CalendarView::addCategories()
{
QPtrList<Incidence> incList = mCalendar->rawIncidences();
QStringList catList = KOPrefs::instance()->mCustomCategories;
QStringList catIncList;
Incidence* inc = incList.first();
int i;
int count = 0;
while ( inc ) {
catIncList = inc->categories() ;
for( i = 0; i< catIncList.count(); ++i ) {
if ( !catList.contains (catIncList[i])) {
catList.append( catIncList[i] );
//qDebug("add cat %s ", catIncList[i].latin1());
++count;
}
}
inc = incList.next();
}
catList.sort();
KOPrefs::instance()->mCustomCategories = catList;
return count;
}
void CalendarView::manageCategories()
{
KOCatPrefs* cp = new KOCatPrefs();
cp->show();
int w =cp->sizeHint().width() ;
int h = cp->sizeHint().height() ;
int dw = QApplication::desktop()->width();
int dh = QApplication::desktop()->height();
cp->setGeometry( (dw-w)/2, (dh - h )/2 ,w,h );
if ( !cp->exec() ) {
delete cp;
return;
}
int count = 0;
if ( cp->addCat() ) {
count = addCategories();
if ( count ) {
topLevelWidget()->setCaption(QString::number( count )+ i18n(" Categories added to list! "));
writeSettings();
} else
topLevelWidget()->setCaption(QString::number( 0 )+ i18n(" Categories added to list! "));
} else {
removeCategories();
updateView();
}
delete cp;
}
void CalendarView::beamIncidence(Incidence * Inc)
{
QPtrList<Incidence> delSel ;
delSel.append(Inc);
beamIncidenceList( delSel );
}
void CalendarView::beamCalendar()
{
QPtrList<Incidence> delSel = mCalendar->rawIncidences();
//qDebug("beamCalendar() ");
beamIncidenceList( delSel );
}
void CalendarView::beamFilteredCalendar()
{
QPtrList<Incidence> delSel = mCalendar->incidences();
//qDebug("beamFilteredCalendar() ");
beamIncidenceList( delSel );
}
void CalendarView::beamIncidenceList(QPtrList<Incidence> delSel )
{
if ( beamDialog->exec () == QDialog::Rejected )
return;
#ifdef DESKTOP_VERSION
QString fn = locateLocal( "tmp", "kopibeamfile" );
#else
QString fn = "/tmp/kopibeamfile";
#endif
QString mes;
bool createbup = true;
if ( createbup ) {
QString description = "\n";
CalendarLocal* cal = new CalendarLocal();
if ( beamDialog->beamLocal() )
cal->setLocalTime();
else
cal->setTimeZoneId(KPimGlobalPrefs::instance()->mTimeZoneId);
Incidence *incidence = delSel.first();
bool addText = false;
if ( delSel.count() < 10 )
addText = true;
else {
description.sprintf(i18n(" %d items?"),delSel.count() );
}
while ( incidence ) {
Incidence *in = incidence->clone();
if ( ! in->summary().isEmpty() ) {
in->setDescription("");
} else {
in->setSummary( in->description().left(20));
in->setDescription("");
}
if ( addText )
description += in->summary() + "\n";
cal->addIncidence( in );
incidence = delSel.next();
}
if ( beamDialog->beamVcal() ) {
fn += ".vcs";
FileStorage storage( cal, fn, new VCalFormat );
storage.save();
} else {
fn += ".ics";
FileStorage storage( cal, fn, new ICalFormat( ) );
storage.save();
}
delete cal;
mes = i18n("KO/Pi: Ready for beaming");
topLevelWidget()->setCaption(mes);
KApplication::convert2latin1( fn );
#ifndef DESKTOP_VERSION
Ir *ir = new Ir( this );
connect( ir, SIGNAL( done( Ir * ) ), this, SLOT( beamDone( Ir * ) ) );
ir->send( fn, description, "text/x-vCalendar" );
#endif
}
}
void CalendarView::beamDone( Ir *ir )
{
#ifndef DESKTOP_VERSION
delete ir;
#endif
topLevelWidget()->setCaption( i18n("KO/Pi: Beaming done.") );
topLevelWidget()->raise();
}
void CalendarView::moveIncidence(Incidence * inc )
{
if ( !inc ) return;
// qDebug("showDatePickerForIncidence( ) ");
if ( mDateFrame->isVisible() )
mDateFrame->hide();
else {
int w =mDatePicker->sizeHint().width()+2*mDateFrame->lineWidth() ;
int h = mDatePicker->sizeHint().height()+2*mDateFrame->lineWidth() ;
int dw = QApplication::desktop()->width();
int dh = QApplication::desktop()->height();
mDateFrame->setGeometry( (dw-w)/2, (dh - h )/2 ,w,h );
mDateFrame->show();
}
mDatePickerMode = 2;
mMoveIncidence = inc ;
QDate da;
if ( mMoveIncidence->type() == "Todo" ) {
Todo * to = (Todo *) mMoveIncidence;
if ( to->hasDueDate() )
da = to->dtDue().date();
else
da = QDate::currentDate();
} else {
da = mMoveIncidence->dtStart().date();
}
mDatePicker->setDate( da );
}
void CalendarView::showDatePicker( )
{
//qDebug("CalendarView::showDatePicker( ) ");
if ( mDateFrame->isVisible() )
mDateFrame->hide();
else {
int w =mDatePicker->sizeHint().width() ;
int h = mDatePicker->sizeHint().height() ;
int dw = QApplication::desktop()->width();
int dh = QApplication::desktop()->height();
mDateFrame->setGeometry( (dw-w)/2, (dh - h )/2 ,w,h );
mDateFrame->show();
}
mDatePickerMode = 1;
mDatePicker->setDate( mNavigator->selectedDates().first() );
}
void CalendarView::showEventEditor()
{
#ifdef DESKTOP_VERSION
mEventEditor->show();
#else
+ if ( mEventEditor->width() != QApplication::desktop()->width() )
+ mEventEditor->hide();
mEventEditor->showMaximized();
#endif
}
void CalendarView::showTodoEditor()
{
#ifdef DESKTOP_VERSION
mTodoEditor->show();
#else
+ if ( mTodoEditor->width() != QApplication::desktop()->width() )
+ mTodoEditor->hide();
mTodoEditor->showMaximized();
#endif
}
void CalendarView::cloneIncidence()
{
Incidence *incidence = currentSelection();
if ( !incidence ) incidence = mTodoList->selectedIncidences().first();
if ( incidence ) {
cloneIncidence(incidence);
}
}
void CalendarView::moveIncidence()
{
Incidence *incidence = currentSelection();
if ( !incidence ) incidence = mTodoList->selectedIncidences().first();
if ( incidence ) {
moveIncidence(incidence);
}
}
void CalendarView::beamIncidence()
{
Incidence *incidence = currentSelection();
if ( !incidence ) incidence = mTodoList->selectedIncidences().first();
if ( incidence ) {
beamIncidence(incidence);
}
}
void CalendarView::toggleCancelIncidence()
{
Incidence *incidence = currentSelection();
if ( !incidence ) incidence = mTodoList->selectedIncidences().first();
if ( incidence ) {
cancelIncidence(incidence);
}
}
void CalendarView::cancelIncidence(Incidence * inc )
{
inc->setCancelled( ! inc->cancelled() );
changeIncidenceDisplay( inc,KOGlobals::EVENTEDITED );
updateView();
}
void CalendarView::cloneIncidence(Incidence * orgInc )
{
Incidence * newInc = orgInc->clone();
newInc->recreate();
if ( newInc->type() == "Todo" ) {
Todo* t = (Todo*) newInc;
mTodoEditor->editTodo( t );
showTodoEditor();
if ( mTodoEditor->exec() ) {
mCalendar->addTodo( t );
updateView();
} else {
delete t;
}
}
else {
Event* e = (Event*) newInc;
mEventEditor->editEvent( e );
showEventEditor();
if ( mEventEditor->exec() ) {
mCalendar->addEvent( e );
updateView();
} else {
delete e;
}
}
}
void CalendarView::newEvent()
{
// TODO: Replace this code by a common eventDurationHint of KOBaseView.
KOAgendaView *aView = mViewManager->agendaView();
if (aView) {
if (aView->selectionStart().isValid()) {
if (aView->selectedIsAllDay()) {
newEvent(aView->selectionStart(),aView->selectionEnd(),true);
} else {
newEvent(aView->selectionStart(),aView->selectionEnd());
}
return;
}
}
QDate date = mNavigator->selectedDates().first();
QDateTime current = QDateTime::currentDateTime();
if ( date <= current.date() ) {
int hour = current.time().hour() +1;
newEvent( QDateTime( current.date(), QTime( hour, 0, 0 ) ),
QDateTime( current.date(), QTime( hour+ KOPrefs::instance()->mDefaultDuration, 0, 0 ) ) );
} else
newEvent( QDateTime( date, QTime( KOPrefs::instance()->mStartTime, 0, 0 ) ),
QDateTime( date, QTime( KOPrefs::instance()->mStartTime +
KOPrefs::instance()->mDefaultDuration, 0, 0 ) ) );
}
void CalendarView::newEvent(QDateTime fh)
{
newEvent(fh,
QDateTime(fh.addSecs(3600*KOPrefs::instance()->mDefaultDuration)));
}
void CalendarView::newEvent(QDate dt)
{
newEvent(QDateTime(dt, QTime(0,0,0)),
QDateTime(dt, QTime(0,0,0)), true);
}
void CalendarView::newEvent(QDateTime fromHint, QDateTime toHint, bool allDay)
{
mEventEditor->newEvent(fromHint,toHint,allDay);
if ( mFilterView->filtersEnabled() ) {
CalFilter *filter = mFilterView->selectedFilter();
if (filter && filter->showCategories()) {
mEventEditor->setCategories(filter->categoryList().join(",") );
}
if ( filter )
mEventEditor->setSecrecy( filter->getSecrecy() );
}
showEventEditor();
}
void CalendarView::todoAdded(Todo * t)
{
changeTodoDisplay ( t ,KOGlobals::EVENTADDED);
updateTodoViews();
}
void CalendarView::todoChanged(Todo * t)
{
emit todoModified( t, 4 );
// updateTodoViews();
}
void CalendarView::todoToBeDeleted(Todo *)
{
//qDebug("todoToBeDeleted(Todo *) ");
updateTodoViews();
}
void CalendarView::todoDeleted()
{
//qDebug(" todoDeleted()");
updateTodoViews();
}
void CalendarView::newTodo()
{
mTodoEditor->newTodo(QDateTime::currentDateTime().addDays(7),0,true);
if ( mFilterView->filtersEnabled() ) {
CalFilter *filter = mFilterView->selectedFilter();
if (filter && filter->showCategories()) {
mTodoEditor->setCategories(filter->categoryList().join(",") );
}
if ( filter )
mTodoEditor->setSecrecy( filter->getSecrecy() );
}
showTodoEditor();
}
void CalendarView::newSubTodo()
{
Todo *todo = selectedTodo();
if ( todo ) newSubTodo( todo );
}
void CalendarView::newSubTodo(Todo *parentEvent)
{
mTodoEditor->newTodo(QDateTime::currentDateTime().addDays(7),parentEvent,true);
showTodoEditor();
}
void CalendarView::newFloatingEvent()
{
DateList tmpList = mNavigator->selectedDates();
QDate date = tmpList.first();
newEvent( QDateTime( date, QTime( 12, 0, 0 ) ),
QDateTime( date, QTime( 12, 0, 0 ) ), true );
}
void CalendarView::editEvent( Event *event )
{
if ( !event ) return;
diff --git a/korganizer/kotodoview.cpp b/korganizer/kotodoview.cpp
index a12acd1..9cafc60 100644
--- a/korganizer/kotodoview.cpp
+++ b/korganizer/kotodoview.cpp
@@ -185,384 +185,385 @@ void KOTodoListView::contentsDropEvent(QDropEvent *e)
}
}
#endif
}
void KOTodoListView::contentsMousePressEvent(QMouseEvent* e)
{
QListView::contentsMousePressEvent(e);
#ifndef KORG_NODND
QPoint p(contentsToViewport(e->pos()));
QListViewItem *i = itemAt(p);
if (i) {
// if the user clicked into the root decoration of the item, don't
// try to start a drag!
if (p.x() > header()->sectionPos(header()->mapToIndex(0)) +
treeStepSize() * (i->depth() + (rootIsDecorated() ? 1 : 0)) +
itemMargin() ||
p.x() < header()->sectionPos(header()->mapToIndex(0))) {
if (e->button()==Qt::LeftButton) {
mPressPos = e->pos();
mMousePressed = true;
}
}
}
#endif
}
void KOTodoListView::contentsMouseMoveEvent(QMouseEvent* e)
{
#ifndef KORG_NODND
// kdDebug() << "KOTodoListView::contentsMouseMoveEvent()" << endl;
QListView::contentsMouseMoveEvent(e);
if (mMousePressed && (mPressPos - e->pos()).manhattanLength() >
QApplication::startDragDistance()) {
mMousePressed = false;
QListViewItem *item = itemAt(contentsToViewport(mPressPos));
if (item) {
// kdDebug() << "Start Drag for item " << item->text(0) << endl;
DndFactory factory( mCalendar );
ICalDrag *vd = factory.createDragTodo(
((KOTodoViewItem *)item)->todo(),viewport());
if (vd->drag()) {
kdDebug() << "KOTodoListView::contentsMouseMoveEvent(): Delete drag source" << endl;
}
/*
QString source = fullPath(item);
if ( QFile::exists(source) ) {
QUriDrag* ud = new QUriDrag(viewport());
ud->setFilenames( source );
if ( ud->drag() )
QMessageBox::information( this, "Drag source",
QString("Delete ")+source, "Not implemented" );
*/
}
}
#endif
}
void KOTodoListView::keyPressEvent ( QKeyEvent * e )
{
QListViewItem* cn;
if ( e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter ) {
cn = currentItem();
if ( cn ) {
KOTodoViewItem* ci = (KOTodoViewItem*)( cn );
if ( ci ){
if ( e->state() == ShiftButton )
ci->setOn( false );
else
ci->setOn( true );
cn = cn->nextSibling();
if ( cn ) {
setCurrentItem ( cn );
ensureItemVisible ( cn );
}
}
}
return;
}
// qDebug("KOTodoListView::keyPressEvent ");
if ( e->state() == Qt::ControlButton || e->state() == Qt::ShiftButton || mName != "todolistsmall" ) {
switch ( e->key() ) {
case Qt::Key_Down:
case Qt::Key_Up:
QListView::keyPressEvent ( e );
break;
case Qt::Key_Left:
case Qt::Key_Right:
QListView::keyPressEvent ( e );
e->accept();
return;
break;
default:
e->ignore();
break;
}
return;
}
e->ignore();
}
void KOTodoListView::contentsMouseReleaseEvent(QMouseEvent *e)
{
QListView::contentsMouseReleaseEvent(e);
mMousePressed = false;
}
void KOTodoListView::contentsMouseDoubleClickEvent(QMouseEvent *e)
{
if (!e) return;
QPoint vp = contentsToViewport(e->pos());
QListViewItem *item = itemAt(vp);
emit double_Clicked(item);
if (!item) return;
emit doubleClicked(item,vp,0);
}
/////////////////////////////////////////////////////////////////////////////
KOQuickTodo::KOQuickTodo(QWidget *parent) :
QLineEdit(parent)
{
setText(i18n("Click to add a new Todo"));
}
void KOQuickTodo::focusInEvent(QFocusEvent *ev)
{
if ( text()==i18n("Click to add a new Todo") )
setText("");
QLineEdit::focusInEvent(ev);
}
void KOQuickTodo::focusOutEvent(QFocusEvent *ev)
{
setText(i18n("Click to add a new Todo"));
QLineEdit::focusOutEvent(ev);
}
/////////////////////////////////////////////////////////////////////////////
KOTodoView::KOTodoView(Calendar *calendar,QWidget* parent,const char* name) :
KOrg::BaseView(calendar,parent,name)
{
QBoxLayout *topLayout = new QVBoxLayout(this);
mName = QString ( name );
mBlockUpdate = false;
mQuickAdd = new KOQuickTodo(this);
topLayout->addWidget(mQuickAdd);
if ( !KOPrefs::instance()->mEnableQuickTodo ) mQuickAdd->hide();
mTodoListView = new KOTodoListView(calendar,this, name );
topLayout->addWidget(mTodoListView);
//mTodoListView->header()->setMaximumHeight(30);
mTodoListView->setRootIsDecorated(true);
mTodoListView->setAllColumnsShowFocus(true);
mTodoListView->setShowSortIndicator(true);
mTodoListView->addColumn(i18n("Todo"));
mTodoListView->addColumn(i18n("Prio"));
mTodoListView->setColumnAlignment(1,AlignHCenter);
mTodoListView->addColumn(i18n("Complete"));
mTodoListView->setColumnAlignment(2,AlignHCenter);
mTodoListView->addColumn(i18n("Due Date"));
mTodoListView->setColumnAlignment(3,AlignLeft);
mTodoListView->addColumn(i18n("Due Time"));
mTodoListView->setColumnAlignment(4,AlignHCenter);
mTodoListView->addColumn(i18n("Cancelled"));
mTodoListView->addColumn(i18n("Categories"));
#if 0
mTodoListView->addColumn(i18n("Sort Id"));
mTodoListView->setColumnAlignment(4,AlignHCenter);
#endif
mTodoListView->setMinimumHeight( 60 );
mTodoListView->setItemsRenameable( true );
mTodoListView->setRenameable( 0 );
mTodoListView->setColumnWidth( 0, 120 );
mTodoListView->setColumnWidthMode(0, QListView::Manual);
mTodoListView->setColumnWidthMode(1, QListView::Manual);
mTodoListView->setColumnWidthMode(2, QListView::Manual);
mTodoListView->setColumnWidthMode(3, QListView::Manual);
mTodoListView->setColumnWidthMode(4, QListView::Manual);
mTodoListView->setColumnWidthMode(5, QListView::Manual);
+ mTodoListView->setColumnWidthMode(6, QListView::Manual);
mTodoListView->setColumnAlignment( 2, AlignCenter );
#if 0
mTodoListView->setColumnWidthMode(6, QListView::Manual);
#endif
mPriorityPopupMenu = new QPopupMenu(this);
for (int i = 1; i <= 5; i++) {
QString label = QString ("%1").arg (i);
mPriority[mPriorityPopupMenu->insertItem (label)] = i;
}
connect (mPriorityPopupMenu, SIGNAL(activated (int)), SLOT (setNewPriority(int)));
mPercentageCompletedPopupMenu = new QPopupMenu(this);
for (int i = 0; i <= 100; i+=20) {
QString label = QString ("%1 %").arg (i);
mPercentage[mPercentageCompletedPopupMenu->insertItem (label)] = i;
}
connect (mPercentageCompletedPopupMenu, SIGNAL (activated (int)), SLOT (setNewPercentage (int)));
mItemPopupMenu = new QPopupMenu(this);
mItemPopupMenu->insertItem(i18n("Show..."), this,
SLOT (showTodo()));
mItemPopupMenu->insertItem(i18n("Edit..."), this,
SLOT (editTodo()));
mItemPopupMenu->insertItem( i18n("Delete"), this,
SLOT (deleteTodo()));
mItemPopupMenu->insertItem( i18n("Clone..."), this,
SLOT (cloneTodo()));
mItemPopupMenu->insertItem( i18n("Move..."), this,
SLOT (moveTodo()));
mItemPopupMenu->insertItem( i18n("Beam..."), this,
SLOT (beamTodo()));
mItemPopupMenu->insertItem( i18n("Toggle Cancel"), this,
SLOT (cancelTodo()));
mItemPopupMenu->insertSeparator();
mItemPopupMenu->insertItem( i18n("New Todo..."), this,
SLOT (newTodo()));
mItemPopupMenu->insertItem(i18n("New Sub-Todo..."), this,
SLOT (newSubTodo()));
mItemPopupMenu->insertItem(i18n("Unparent Todo"), this,
SLOT (unparentTodo()),0,21);
mItemPopupMenu->insertItem(i18n("Reparent Todo"), this,
SLOT (reparentTodo()),0,22);
mItemPopupMenu->insertSeparator();
mItemPopupMenu->insertItem(i18n("Delete completed To-Dos","Purge Completed"),
this, SLOT( purgeCompleted() ) );
mItemPopupMenu->insertItem(i18n("toggle completed To-Dos","Show Completed"),
this, SLOT( toggleCompleted() ),0, 33 );
mItemPopupMenu->insertItem(i18n("toggle quick todo","Show Quick Todo"),
this, SLOT( toggleQuickTodo() ),0, 34 );
mPopupMenu = new QPopupMenu(this);
mPopupMenu->insertItem(SmallIconSet("todo"), i18n("New Todo..."), this,
SLOT (newTodo()),0,1);
mPopupMenu->insertItem(i18n("delete completed To-Dos","Purge Completed"),
this, SLOT(purgeCompleted()),0,2);
mPopupMenu->insertItem(i18n("Show Completed"),
this, SLOT( toggleCompleted() ),0,3 );
mPopupMenu->insertItem(i18n("toggle quick todo","Show Quick Todo"),
this, SLOT( toggleQuickTodo() ),0,4 );
mDocPrefs = new DocPrefs( name );
mPopupMenu->setCheckable( true );
mItemPopupMenu->setCheckable( true );
// Double clicking conflicts with opening/closing the subtree
connect( mTodoListView, SIGNAL( doubleClicked( QListViewItem *) ),
SLOT( editItem( QListViewItem *) ) );
/*
connect( mTodoListView, SIGNAL( rightButtonClicked ( QListViewItem *,
const QPoint &,int ) ),
SLOT( popupMenu( QListViewItem *, const QPoint & ,int) ) );
*/
connect( mTodoListView, SIGNAL( contextRequest ( QListViewItem *,
const QPoint &,int ) ),
SLOT( popupMenu( QListViewItem *, const QPoint & ,int) ) );
connect( mTodoListView, SIGNAL( clicked( QListViewItem * ) ),
SLOT( itemClicked( QListViewItem * ) ) );
connect( mTodoListView, SIGNAL( double_Clicked( QListViewItem * ) ),
SLOT( itemDoubleClicked( QListViewItem * ) ) );
connect( mTodoListView, SIGNAL( todoDropped( Todo * ) ),
SLOT( updateView() ) );
connect( mTodoListView, SIGNAL( expanded( QListViewItem * ) ),
SLOT( itemStateChanged( QListViewItem * ) ) );
connect( mTodoListView, SIGNAL( collapsed( QListViewItem * ) ),
SLOT( itemStateChanged( QListViewItem * ) ) );
#if 0
connect(mTodoListView,SIGNAL(selectionChanged(QListViewItem *)),
SLOT(selectionChanged(QListViewItem *)));
connect(mTodoListView,SIGNAL(clicked(QListViewItem *)),
SLOT(selectionChanged(QListViewItem *)));
connect(mTodoListView,SIGNAL(pressed(QListViewItem *)),
SLOT(selectionChanged(QListViewItem *)));
#endif
connect( mTodoListView, SIGNAL(selectionChanged() ),
SLOT( processSelectionChange() ) );
connect( mQuickAdd, SIGNAL( returnPressed () ),
SLOT( addQuickTodo() ) );
// if ( QApplication::desktop()->width() < 480 ) {
// setNarrow();
// mTodoListView->setColumnWidth( 0, 100 );
// }
}
KOTodoView::~KOTodoView()
{
delete mDocPrefs;
}
void KOTodoView::jumpToDate ()
{
// if (mActiveItem) {
// mActiveItem->todo());
// if ( mActiveItem->todo()->hasDueDate() )
// emit mActiveItem->todo()jumpToTime( mTodo->dtDue().date() );
}
void KOTodoView::setNarrow()
{
//mTodoListView->setColumnWidth( 0, 120 );
mTodoListView->setColumnWidth( 1, 35 );
mTodoListView->setColumnWidth( 2, 40 );
mTodoListView->setColumnWidth( 3, 80 );
mTodoListView->setColumnWidth( 4, 40 );
mTodoListView->setColumnWidth( 5, 90 );
}
void KOTodoView::updateView()
{
pendingSubtodo = 0;
if ( mBlockUpdate ) {
//qDebug("blocked ");
return;
}
//qDebug("update ");
// kdDebug() << "KOTodoView::updateView()" << endl;
QFont fo = KOPrefs::instance()->mTodoViewFont;
mTodoListView->clear();
if ( mName == "todolistsmall" ) {
if ( KOPrefs::instance()->mTodoViewUsesSmallFont ) {
int ps = fo.pointSize() -2;
if ( ps > 12 )
ps -= 2;
fo.setPointSize( ps );
}
}
mTodoListView->setFont( fo );
// QFontMetrics fm ( KOPrefs::instance()->mTodoViewFont );
//mTodoListView->header()->setMaximumHeight(fm.height());
QPtrList<Todo> todoList = calendar()->todos();
/*
kdDebug() << "KOTodoView::updateView(): Todo List:" << endl;
Event *t;
for(t = todoList.first(); t; t = todoList.next()) {
kdDebug() << " " << t->getSummary() << endl;
if (t->getRelatedTo()) {
kdDebug() << " (related to " << t->getRelatedTo()->getSummary() << ")" << endl;
}
QPtrList<Event> l = t->getRelations();
Event *c;
for(c=l.first();c;c=l.next()) {
kdDebug() << " - relation: " << c->getSummary() << endl;
}
}
*/
// Put for each Event a KOTodoViewItem in the list view. Don't rely on a
// specific order of events. That means that we have to generate parent items
// recursively for proper hierarchical display of Todos.
mTodoMap.clear();
Todo *todo;
todo = todoList.first();// todo; todo = todoList.next()) {
while ( todo ) {
bool next = true;
// qDebug("todo %s ", todo->summary().latin1());
Incidence *incidence = todo->relatedTo();
while ( incidence ) {
if ( incidence->type() == "Todo") {
//qDebug("related %s ",incidence->summary().latin1() );
if ( !(todoList.contains ( ((Todo* )incidence ) ) )) {
//qDebug("related not found ");
todoList.remove( );
todo = todoList.current();
diff --git a/korganizer/kotodoviewitem.cpp b/korganizer/kotodoviewitem.cpp
index 85647b1..ae0b334 100644
--- a/korganizer/kotodoviewitem.cpp
+++ b/korganizer/kotodoviewitem.cpp
@@ -1,237 +1,237 @@
/*
This file is part of KOrganizer.
Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <klocale.h>
#include <kdebug.h>
#include <qapp.h>
#include <kiconloader.h>
#include "kotodoviewitem.h"
#include "kotodoview.h"
#include "koprefs.h"
KOTodoViewItem::KOTodoViewItem( QListView *parent, Todo *todo, KOTodoView *kotodo)
: QCheckListItem( parent , "", CheckBox ), mTodo( todo ), mTodoView( kotodo )
{
construct();
}
KOTodoViewItem::KOTodoViewItem( KOTodoViewItem *parent, Todo *todo, KOTodoView *kotodo )
: QCheckListItem( parent, "", CheckBox ), mTodo( todo ), mTodoView( kotodo )
{
construct();
}
QString KOTodoViewItem::key(int column,bool) const
{
QMap<int,QString>::ConstIterator it = mKeyMap.find(column);
if (it == mKeyMap.end()) {
- return text(column);
+ return text(column).lower();
} else {
return *it;
}
}
void KOTodoViewItem:: setup()
{
int h = 20;
if ( listView () ) {
QFontMetrics fm ( listView ()->font () );
h = fm.height();
}
setHeight( h );
}
void KOTodoViewItem::setSortKey(int column,const QString &key)
{
mKeyMap.insert(column,key);
}
#if QT_VERSION >= 300
void KOTodoViewItem::paintBranches(QPainter *p,const QColorGroup & cg,int w,
int y,int h)
{
QListViewItem::paintBranches(p,cg,w,y,h);
}
#else
#endif
void KOTodoViewItem::construct()
{
// qDebug("KOTodoViewItem::construct() ");
m_init = true;
QString keyd = "==";
QString keyt = "==";
setOn(mTodo->isCompleted());
setText(0,mTodo->summary());
setText(1,QString::number(mTodo->priority()));
setText(2,i18n("%1 %").arg(QString::number(mTodo->percentComplete())));
if (mTodo->percentComplete()<100) {
if (mTodo->isCompleted()) setSortKey(2,QString::number(999));
else setSortKey(2,QString::number(mTodo->percentComplete()));
}
else {
if (mTodo->isCompleted()) setSortKey(2,QString::number(999));
else setSortKey(2,QString::number(99));
}
if (mTodo->hasDueDate()) {
setText(3, mTodo->dtDueDateStr());
QDate d = mTodo->dtDue().date();
keyd.sprintf("%04d%02d%02d",d.year(),d.month(),d.day());
setSortKey(3,keyd);
if (mTodo->doesFloat()) {
setText(4,"");
}
else {
setText(4,mTodo->dtDueTimeStr());
QTime t = mTodo->dtDue().time();
keyt.sprintf("%02d%02d",t.hour(),t.minute());
setSortKey(4,keyt);
}
} else {
setText(3,"");
setText(4,"");
}
setSortKey(3,keyd);
setSortKey(4,keyt);
if (mTodo->isCompleted()) setSortKey(1,"6" + QString::number(mTodo->priority())+keyd+keyt);
else setSortKey(1,QString::number(mTodo->priority())+keyd+keyt);
setText(5,mTodo->cancelled() ? i18n("Yes") : i18n("No"));
setText(6,mTodo->categoriesStr());
#if 0
// Find sort id in description. It's the text behind the last '#' character
// found in the description. White spaces are removed from beginning and end
// of sort id.
int pos = mTodo->description().findRev('#');
if (pos < 0) {
setText(6,"");
} else {
QString str = mTodo->description().mid(pos+1);
str.stripWhiteSpace();
setText(6,str);
}
#endif
m_known = false;
m_init = false;
setMyPixmap();
}
void KOTodoViewItem::setMyPixmap()
{
int size = 5;
QPixmap pixi = QPixmap( 1, 1 );
// if ( !mTodo->isCompleted() && mTodo->hasDueDate() && mTodo->dtDue() < QDateTime::currentDateTime() ) {
// pixi = SmallIcon("redcross16");
// } else {
QPainter p;
int pixSize = 0;
QPixmap pPix = QPixmap( size, size );
if ( mTodo->description().length() > 0 ) {
pixi.resize(size, pixSize+size);
pPix.fill( Qt::darkGreen );
p.begin( &pixi );
p. drawPixmap ( 0, pixSize, pPix);
p.end();
pixSize += size;
}
if ( mTodo->isAlarmEnabled() ) {
pixi.resize(size, pixSize+size);
pPix.fill( Qt::red );
p.begin( &pixi );
p. drawPixmap ( 0, pixSize, pPix);
p.end();
pixSize += size;
}
// }
if ( pixi.width() > 1 ) {
setPixmap ( 0,pixi ) ;
}
}
void KOTodoViewItem::stateChange(bool state)
{
// qDebug("KOTodoViewItem::stateChange ");
// do not change setting on startup
if ( m_init ) return;
kdDebug() << "State changed, modified " << state << endl;
QString keyd = "==";
QString keyt = "==";
if (state) mTodo->setCompleted(state);
else mTodo->setPercentComplete(0);
if (isOn()!=state) {
setOn(state);
}
if (mTodo->hasDueDate()) {
setText(3, mTodo->dtDueDateStr());
QDate d = mTodo->dtDue().date();
keyd.sprintf("%04d%02d%02d",d.year(),d.month(),d.day());
setSortKey(3,keyd);
if (mTodo->doesFloat()) {
setText(4,"");
}
else {
setText(4,mTodo->dtDueTimeStr());
QTime t = mTodo->dtDue().time();
keyt.sprintf("%02d%02d",t.hour(),t.minute());
setSortKey(4,keyt);
}
}
if (mTodo->isCompleted()) setSortKey(1,QString::number(9)+keyd+keyt);
else setSortKey(1,QString::number(mTodo->priority())+keyd+keyt);
setText(2,i18n("%1 %").arg(QString::number(mTodo->percentComplete())));
if (mTodo->percentComplete()<100) {
if (mTodo->isCompleted()) setSortKey(2,QString::number(999));
else setSortKey(2,QString::number(mTodo->percentComplete()));
}
else {
if (mTodo->isCompleted()) setSortKey(2,QString::number(999));
else setSortKey(2,QString::number(99));
}
QListViewItem * myChild = firstChild();
KOTodoViewItem *item;
while( myChild ) {
item = static_cast<KOTodoViewItem*>(myChild);
item->stateChange(state);
myChild = myChild->nextSibling();
}
mTodoView->modified(true);
mTodoView->setTodoModified( mTodo );
setMyPixmap();
}
bool KOTodoViewItem::isAlternate()
{
#ifndef KORG_NOLVALTERNATION
KOTodoListView *lv = static_cast<KOTodoListView *>(listView());
if (lv && lv->alternateBackground().isValid())
{
KOTodoViewItem *above = 0;
diff --git a/libkcal/sharpformat.cpp b/libkcal/sharpformat.cpp
index 24b8349..c2ee2c9 100644
--- a/libkcal/sharpformat.cpp
+++ b/libkcal/sharpformat.cpp
@@ -65,386 +65,389 @@ class SharpParser : public QObject
public:
SharpParser( Calendar *calendar ) : mCalendar( calendar ) {
}
bool startElement( Calendar *existingCalendar, const QStringList & attList, QString qName )
{
int i = 1;
bool skip = true;
int max = attList.count() -2;
while ( i < max ) {
if ( !attList[i].isEmpty() ) {
skip = false;
break;
}
++i ;
}
if ( skip )
return false;
ulong cSum = SharpFormat::getCsum(attList );
if ( qName == "Event" ) {
Event *event;
event = existingCalendar->event( "Sharp_DTM",attList[0] );
if ( event )
event = (Event*)event->clone();
else
event = new Event;
event->setID("Sharp_DTM", attList[0] );
event->setCsum( "Sharp_DTM", QString::number( cSum ));
event->setTempSyncStat(SYNC_TEMPSTATE_NEW_EXTERNAL );
event->setSummary( attList[2] );
event->setLocation( attList[3] );
event->setDescription( attList[4] );
if ( attList[7] == "1" ) {
event->setDtStart( QDateTime(fromString( attList[17]+"T000000", false ).date(),QTime(0,0,0 ) ));
event->setDtEnd( QDateTime(fromString( attList[18]+"T000000", false ).date(),QTime(0,0,0 )));
event->setFloats( true );
} else {
event->setFloats( false );
event->setDtStart( fromString( attList[5] ) );
event->setDtEnd( fromString( attList[6] ));
}
QString rtype = attList[11];
if ( rtype != "255" ) {
// qDebug("recurs ");
QDate startDate = event->dtStart().date();
QString freqStr = attList[12];
int freq = freqStr.toInt();
QString hasEndDateStr = attList[15] ;
bool hasEndDate = hasEndDateStr == "1";
QString endDateStr = attList[16];
QDate endDate = fromString( endDateStr ).date();
QString weekDaysStr = attList[14];
uint weekDaysNum = weekDaysStr.toInt();
QBitArray weekDays( 7 );
int i;
int bb = 1;
for( i = 1; i <= 7; ++i ) {
weekDays.setBit( i - 1, ( bb & weekDaysNum ));
bb = 2 << (i-1);
//qDebug(" %d bit %d ",i-1,weekDays.at(i-1) );
}
// qDebug("next ");
QString posStr = attList[13];
int pos = posStr.toInt();
Recurrence *r = event->recurrence();
if ( rtype == "0" ) {
if ( hasEndDate ) r->setDaily( freq, endDate );
else r->setDaily( freq, -1 );
} else if ( rtype == "1" ) {
if ( hasEndDate ) r->setWeekly( freq, weekDays, endDate );
else r->setWeekly( freq, weekDays, -1 );
} else if ( rtype == "3" ) {
if ( hasEndDate )
r->setMonthly( Recurrence::rMonthlyDay, freq, endDate );
else
r->setMonthly( Recurrence::rMonthlyDay, freq, -1 );
r->addMonthlyDay( startDate.day() );
} else if ( rtype == "2" ) {
if ( hasEndDate )
r->setMonthly( Recurrence::rMonthlyPos, freq, endDate );
else
r->setMonthly( Recurrence::rMonthlyPos, freq, -1 );
QBitArray days( 7 );
days.fill( false );
days.setBit( startDate.dayOfWeek() - 1 );
r->addMonthlyPos( pos, days );
} else if ( rtype == "4" ) {
if ( hasEndDate )
r->setYearly( Recurrence::rYearlyMonth, freq, endDate );
else
r->setYearly( Recurrence::rYearlyMonth, freq, -1 );
r->addYearlyNum( startDate.month() );
}
} else {
event->recurrence()->unsetRecurs();
}
QString categoryList = attList[1] ;
event->setCategories( categoryList );
// strange 0 semms to mean: alarm enabled
if ( attList[8] == "0" ) {
Alarm *alarm;
if ( event->alarms().count() > 0 )
alarm = event->alarms().first();
else {
alarm = new Alarm( event );
event->addAlarm( alarm );
alarm->setType( Alarm::Audio );
}
//alarm->setType( Alarm::Audio );
alarm->setEnabled( true );
int alarmOffset = attList[9].toInt();
alarm->setStartOffset( alarmOffset * -60 );
} else {
Alarm *alarm;
if ( event->alarms().count() > 0 ) {
alarm = event->alarms().first();
alarm->setType( Alarm::Audio );
alarm->setStartOffset( -60*15 );
alarm->setEnabled( false );
}
}
mCalendar->addEvent( event);
} else if ( qName == "Todo" ) {
Todo *todo;
todo = existingCalendar->todo( "Sharp_DTM", attList[0] );
if (todo )
todo = (Todo*)todo->clone();
else
todo = new Todo;
//CARDID,CATEGORY,ETDY,LTDY,FNDY,MARK,PRTY,TITL,MEM1
// 0 1 2 3 4 5 6 7 8
//1,,,,,1,4,Loch zumachen,""
//3,Privat,20040317T000000,20040318T000000,20040319T000000,0,5,Call bbb,"notes123 bbb gggg ""bb "" "
//2,"Familie,Freunde,Holiday",20040318T000000,20040324T000000,20040317T000000,1,2,tod2,notes
todo->setID( "Sharp_DTM", attList[0]);
todo->setCsum( "Sharp_DTM", QString::number( cSum ));
todo->setTempSyncStat( SYNC_TEMPSTATE_NEW_EXTERNAL );
todo->setSummary( attList[7] );
todo->setDescription( attList[8]);
int priority = attList[6].toInt();
if ( priority == 0 ) priority = 3;
todo->setPriority( priority );
QString categoryList = attList[1];
todo->setCategories( categoryList );
QString hasDateStr = attList[3]; // due
if ( !hasDateStr.isEmpty() ) {
if ( hasDateStr.right(6) == "000000" ) {
todo->setDtDue( QDateTime(fromString( hasDateStr, false ).date(), QTime(0,0,0 )) );
todo->setFloats( true );
}
else {
todo->setDtDue( fromString( hasDateStr ) );
todo->setFloats( false );
}
todo->setHasDueDate( true );
}
hasDateStr = attList[2];//start
if ( !hasDateStr.isEmpty() ) {
todo->setDtStart( fromString( hasDateStr ) );
todo->setHasStartDate( true);
} else
todo->setHasStartDate( false );
hasDateStr = attList[4];//completed
if ( !hasDateStr.isEmpty() ) {
todo->setCompleted(fromString( hasDateStr ) );
}
QString completedStr = attList[5];
if ( completedStr == "0" )
todo->setCompleted( true );
- else
- todo->setCompleted( false );
+ else {
+ // do not change percent complete
+ if ( todo->isCompleted() )
+ todo->setCompleted( false );
+ }
mCalendar->addTodo( todo );
} else if ( qName == "Category" ) {
/*
QString id = attributes.value( "id" );
QString name = attributes.value( "name" );
setCategory( id, name );
*/
}
//qDebug("end ");
return true;
}
QDateTime fromString ( QString s, bool useTz = true ) {
QDateTime dt;
int y,m,t,h,min,sec;
y = s.mid(0,4).toInt();
m = s.mid(4,2).toInt();
t = s.mid(6,2).toInt();
h = s.mid(9,2).toInt();
min = s.mid(11,2).toInt();
sec = s.mid(13,2).toInt();
dt = QDateTime(QDate(y,m,t), QTime(h,min,sec));
int offset = KGlobal::locale()->localTimeOffset( dt );
if ( useTz )
dt = dt.addSecs ( offset*60);
return dt;
}
protected:
QDateTime toDateTime( const QString &value )
{
QDateTime dt;
dt.setTime_t( value.toUInt() );
return dt;
}
private:
Calendar *mCalendar;
};
SharpFormat::SharpFormat()
{
}
SharpFormat::~SharpFormat()
{
}
ulong SharpFormat::getCsum( const QStringList & attList)
{
int max = attList.count() -1;
ulong cSum = 0;
int j,k,i;
int add;
for ( i = 1; i < max ; ++i ) {
QString s = attList[i];
if ( ! s.isEmpty() ){
j = s.length();
for ( k = 0; k < j; ++k ) {
int mul = k +1;
add = s[k].unicode ();
if ( k < 16 )
mul = mul * mul;
add = add * mul *i*i*i;
cSum += add;
}
}
}
return cSum;
}
#include <stdlib.h>
#define DEBUGMODE false
//#define DEBUGMODE true
bool SharpFormat::load( Calendar *calendar, Calendar *existngCal )
{
bool debug = DEBUGMODE;
QString text;
QString codec = "utf8";
QLabel status ( i18n("Reading events ..."), 0 );
int w = status.sizeHint().width()+20 ;
if ( w < 200 ) w = 200;
int h = status.sizeHint().height()+20 ;
int dw = QApplication::desktop()->width();
int dh = QApplication::desktop()->height();
status.setCaption(i18n("Reading DTM Data") );
status.setGeometry( (dw-w)/2, (dh - h )/2 ,w,h );
status.show();
status.raise();
qApp->processEvents();
QString fileName;
if ( ! debug ) {
fileName = "/tmp/kopitempout";
QString command ="db2file datebook -r -c "+ codec + " > " + fileName;
system ( command.latin1() );
} else {
fileName = "/tmp/events.txt";
}
QFile file( fileName );
if (!file.open( IO_ReadOnly ) ) {
return false;
}
QTextStream ts( &file );
ts.setCodec( QTextCodec::codecForName("utf8") );
text = ts.read();
file.close();
status.setText( i18n("Processing events ...") );
status.raise();
qApp->processEvents();
fromString2Cal( calendar, existngCal, text, "Event" );
status.setText( i18n("Reading todos ...") );
qApp->processEvents();
if ( ! debug ) {
fileName = "/tmp/kopitempout";
QString command = "db2file todo -r -c " + codec+ " > " + fileName;
system ( command.latin1() );
} else {
fileName = "/tmp/todo.txt";
}
file.setName( fileName );
if (!file.open( IO_ReadOnly ) ) {
return false;
}
ts.setDevice( &file );
text = ts.read();
file.close();
status.setText( i18n("Processing todos ...") );
status.raise();
qApp->processEvents();
fromString2Cal( calendar, existngCal, text, "Todo" );
return true;
}
int SharpFormat::getNumFromRecord( QString answer, Incidence* inc )
{
int retval = -1;
QStringList templist;
QString tempString;
int start = 0;
int len = answer.length();
int end = answer.find ("\n",start)+1;
bool ok = true;
start = end;
int ccc = 0;
while ( start > 0 ) {
templist.clear();
ok = true;
int loopCount = 0;
while ( ok ) {
++loopCount;
if ( loopCount > 25 ) {
qDebug("KO: Error in while loop");
ok = false;
start = 0;
break;
}
if ( ok )
tempString = getPart( answer, ok, start );
if ( start >= len || start == 0 ) {
start = 0;
ok = false;
}
if ( tempString.right(1) =="\n" )
tempString = tempString.left( tempString.length()-1);
templist.append( tempString );
}
++ccc;
if ( ccc == 2 && loopCount < 25 ) {
start = 0;
bool ok;
int newnum = templist[0].toInt( &ok );
if ( ok && newnum > 0) {
retval = newnum;
inc->setID( "Sharp_DTM",templist[0] );
inc->setCsum( "Sharp_DTM", QString::number( getCsum( templist ) ));
inc->setTempSyncStat( SYNC_TEMPSTATE_NEW_ID );
}
if ( ok && newnum == -1 ) {
qDebug("Error writing back %s ", inc->summary().latin1());
}
}
diff --git a/version b/version
index c4fe6e2..0343cbb 100644
--- a/version
+++ b/version
@@ -1 +1 @@
-version = "1.9.13";
+version = "1.9.14";