[Commits] [SCM] claws branch, vfolder, created. 3.10.1-105-g56525de
miras at claws-mail.org
miras at claws-mail.org
Sat Jun 21 20:30:27 CEST 2014
The branch vfolder of project "claws" (Claws Mail) has been created
at 56525de819a32955ed283dccafce200a2bc5de0b (commit)
- Log -----------------------------------------------------------------
commit 56525de819a32955ed283dccafce200a2bc5de0b
Author: Michael Rasmussen <mir at datanom.net>
Date: Sat Jun 21 20:19:05 2014 +0200
Add tool tip to virtual folder properties window
diff --git a/src/plugins/vfolder/vfolder_gtk.c b/src/plugins/vfolder/vfolder_gtk.c
index 2f4e488..25b88a2 100644
--- a/src/plugins/vfolder/vfolder_gtk.c
+++ b/src/plugins/vfolder/vfolder_gtk.c
@@ -486,9 +486,9 @@ void vfolder_new_folder_cb(GtkAction* action, gpointer data) {
return;
}
}
- new_folder = input_dialog(_("New folder"),
- _("Input the name of new folder:"),
- _("NewFolder"));
+ new_folder = input_dialog(_("New virtual folder"),
+ _("Input the name of the folder:"),
+ _("Virtual Folder"));
if (!new_folder) return;
AUTORELEASE_STR(new_folder, {g_free(new_folder); return;});
diff --git a/src/plugins/vfolder/vfolder_prop.c b/src/plugins/vfolder/vfolder_prop.c
index 2f08d8b..203a0c0 100644
--- a/src/plugins/vfolder/vfolder_prop.c
+++ b/src/plugins/vfolder/vfolder_prop.c
@@ -300,16 +300,22 @@ gboolean vfolder_edit_item_dialog(VFolderItem* vitem, FolderItem* item) {
MainWindow *mainwin = mainwindow_get_mainwindow();
props_dialog = g_new0(PropsDialog, 1);
props_dialog->filter = gtk_entry_new();
+ CLAWS_SET_TIP(props_dialog->filter, _("Glob filter. '*' or '?' for wildcard"));
props_dialog->frozen = gtk_check_button_new();
+ CLAWS_SET_TIP(props_dialog->frozen, _("Disable automatic update. Manual refresh is not affected"));
props_dialog->source = gtk_entry_new();
+ CLAWS_SET_TIP(props_dialog->source, _("Folder to watch"));
props_dialog->label_btn =
gtk_radio_button_new_with_mnemonic(NULL, HEADERS);
+ CLAWS_SET_TIP(props_dialog->label_btn, _("Only scan message headers"));
props_dialog->message_btn =
gtk_radio_button_new_with_mnemonic_from_widget(
GTK_RADIO_BUTTON(props_dialog->label_btn), BODY);
+ CLAWS_SET_TIP(props_dialog->message_btn, _("Only scan message body"));
props_dialog->both_btn =
gtk_radio_button_new_with_mnemonic_from_widget(
GTK_RADIO_BUTTON(props_dialog->label_btn), BOTH);
+ CLAWS_SET_TIP(props_dialog->both_btn, _("Scan both message headers and message body"));
gtk_widget_set_name(props_dialog->source, "source");
add_current_config(vitem, props_dialog);
commit a64dce323775ee34919c45021ba6549fd14ba19c
Merge: 008682b 82866a2
Author: Michael Rasmussen <mir at datanom.net>
Date: Sat Jun 21 20:00:26 2014 +0200
Merge branch 'master' of ssh+git://git.claws-mail.org/home/git/claws into vfolder
commit 008682b19a6d627434c9580a3161d20c68255e7e
Author: Michael Rasmussen <mir at datanom.net>
Date: Sat Jun 21 19:59:53 2014 +0200
Ready for release in the wild
diff --git a/src/plugins/vfolder/Makefile.am b/src/plugins/vfolder/Makefile.am
index 0808e93..eb51703 100644
--- a/src/plugins/vfolder/Makefile.am
+++ b/src/plugins/vfolder/Makefile.am
@@ -12,13 +12,11 @@ vfolder_la_SOURCES = \
vfolder.c \
vfolder_init.c \
vfolder_gtk.c \
- vfolder_prop.c
-
-nodist_include_HEADERS = \
+ vfolder_prop.c \
vfolder_gtk.h \
vfolder_prop.h
-vfolderincludedir = $(pkgincludedir)/plugins/@PACKAGE@
+vfolderincludedir = $(includedir)/claws-mail/vfolder
vfolderinclude_HEADERS = \
vfolder.h
diff --git a/src/plugins/vfolder/TODO b/src/plugins/vfolder/TODO
index 8b13789..d6fca1e 100644
--- a/src/plugins/vfolder/TODO
+++ b/src/plugins/vfolder/TODO
@@ -1 +1,7 @@
-
+- enable recursive behavior. Since filenames are not unique outside of a
+folder item this will require a lot of code.
+- use claws' built-in quick search. Add button to create a virtual folder
+using the result of search. Since quick search has the ability to make recursive
+searches this whish depends on whether recursive behavior is implemented
+in the VFolder plugin.
+- add 'Create virtual folder' to main context menu.
diff --git a/src/plugins/vfolder/vfolder.c b/src/plugins/vfolder/vfolder.c
index ea56977..c821a28 100644
--- a/src/plugins/vfolder/vfolder.c
+++ b/src/plugins/vfolder/vfolder.c
@@ -6,7 +6,8 @@
/*
* Virtual folder plugin for claws-mail
*
- * Claws Mail is Copyright (C) 1999-2012 by the Claws Mail Team
+ * Claws Mail is Copyright (C) 1999-2014 by Michael Rasmussen and
+ * the Claws Mail Team
*
* 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
@@ -43,6 +44,8 @@
#include "main.h"
#include "localfolder.h"
#include "statusbar.h"
+#include "mainwindow.h"
+#include "folderview.h"
#include "vfolder.h"
#include "vfolder_gtk.h"
@@ -94,6 +97,20 @@ static GHashTable* vfolder_vfolders_new() {
g_str_equal, g_free, vfolder_free_hashtable);
}
+static void vfolder_vfolders_config_save() {
+ GHashTableIter iter;
+ gpointer key, value;
+
+ g_hash_table_iter_init (&iter, vfolders);
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
+ if (value) {
+ VFolderItem* vitem = VFOLDER_ITEM(value);
+ FolderPropsResponse resp = vfolder_folder_item_props_write(vitem);
+ vfolder_item_props_response(resp);
+ }
+ }
+}
+
static void vfolder_msgvault_add_msg(MsgPair* msgpair) {
VFolderItem* vitem = msgpair->vitem;
guint* snum = GUINT_TO_POINTER(msgpair->src);
@@ -147,9 +164,11 @@ static void vfolder_init_read_func(FolderItem* item, gpointer data) {
vfolder_set_msgs_filter(VFOLDER_ITEM(item));
-/* if (! IS_VFOLDER_FROZEN(VFOLDER_ITEM(item))) {
+/*
+ if (! VFOLDER_ITEM(item)->frozen) {
folder_item_scan(VFOLDER_ITEM(item)->source);
- }*/
+ }
+*/
}
static void vfolder_make_rc_dir(void) {
@@ -555,6 +574,8 @@ static gint vfolder_add_msg(Folder* folder, FolderItem* dest, const gchar* file,
}
static gchar* vfolder_fetch_msg(Folder* folder, FolderItem* item, gint num) {
+ if (num < 0) return NULL;
+
gchar* snum = g_strdup_printf("%d", num);
gchar* file = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, VFOLDER_DIR,
G_DIR_SEPARATOR_S, item->path, G_DIR_SEPARATOR_S, snum, NULL);
@@ -608,11 +629,11 @@ static gint vfolder_remove_msg(Folder* folder, FolderItem* item, gint num) {
file = vfolder_fetch_msg(folder, item, num);
if (! is_file_exist(file)) {
/* num relates to source */
- vnum = vfolder_get_virtual_msg_num(VFOLDER_ITEM(item), num);
g_free(file);
+ vnum = vfolder_get_virtual_msg_num(VFOLDER_ITEM(item), num);
file = vfolder_fetch_msg(folder, item, vnum);
}
- cm_return_val_if_fail(file != NULL, -1);
+ if (! file) return -1;
if (claws_unlink(file) < 0) {
FILE_OP_ERROR(file, "unlink");
@@ -658,6 +679,16 @@ static gboolean vfolder_subscribe_uri(Folder* folder, const gchar* uri) {
return FALSE;
}
+static gint vfolder_folder_rename(Folder *folder, FolderItem *item, const gchar *name) {
+ cm_return_val_if_fail(item != NULL, -1);
+
+ if (item->name)
+ g_free(item->name);
+ item->name = g_strdup(name);
+
+ return 0;
+}
+
FolderClass* vfolder_folder_get_class() {
if (vfolder_class.idstr == NULL ) {
vfolder_class.type = F_UNKNOWN;
@@ -673,14 +704,11 @@ FolderClass* vfolder_folder_get_class() {
vfolder_class.create_tree = vfolder_create_tree;
/* FolderItem functions */
-/*
- vfolder_class.rename_folder = NULL;
-*/
vfolder_class.item_new = vfolder_item_new;
vfolder_class.item_destroy = vfolder_item_destroy;
vfolder_class.item_get_path = vfolder_item_get_path;
vfolder_class.create_folder = vfolder_folder_create;
- vfolder_class.rename_folder = NULL;
+ vfolder_class.rename_folder = vfolder_folder_rename;
vfolder_class.remove_folder = vfolder_folder_remove;
vfolder_class.get_num_list = vfolder_get_num_list;
vfolder_class.scan_required = vfolder_scan_required;
@@ -734,7 +762,9 @@ void vfolder_done(void) {
vfolder_gtk_done();
- g_hash_table_destroy(vfolders);
+ vfolder_vfolders_config_save();
+
+ g_hash_table_destroy(vfolders);
if (!claws_is_exiting())
folder_unregister_class(vfolder_folder_get_class());
@@ -1001,3 +1031,41 @@ VFolderItem* vfolder_folder_item_watch(FolderItem* item) {
return match;
}
+
+void vfolder_source_path_change(VFolderItem* vitem, FolderItem* newItem) {
+ VFolderItem* newVitem = NULL;
+ gpointer key, value;
+
+ cm_return_if_fail(vitem != NULL);
+
+ if (g_hash_table_lookup_extended(vfolders, vitem->source_id, &key, &value)) {
+ g_hash_table_steal(vfolders, vitem->source_id);
+ g_free(key);
+ newVitem = VFOLDER_ITEM(value);
+ newVitem->source = newItem;
+ g_free(newVitem->source_id);
+ newVitem->source_id = folder_item_get_identifier(newItem);
+ g_hash_table_replace(vfolders, g_strdup(newVitem->source_id), newVitem);
+ }
+}
+
+void vfolder_source_folder_remove(VFolderItem* vitem) {
+ cm_return_if_fail(vitem != NULL);
+
+ MainWindow* mainwindow = mainwindow_get_mainwindow();
+ FolderView* folderview = mainwindow->folderview;
+ gchar *id1, *id2;
+
+ if (! vitem->frozen) {
+ FolderItem* item = folderview_get_selected_item(folderview);
+ if (item) {
+ id1 = folder_item_get_identifier(item);
+ id2 = folder_item_get_identifier(FOLDER_ITEM(vitem));
+ if (strcmp(id1, id2) == 0)
+ folderview_close_opened(folderview);
+ g_free(id1);
+ g_free(id2);
+ }
+ vfolder_folder_remove(FOLDER_ITEM(vitem)->folder, FOLDER_ITEM(vitem));
+ }
+}
diff --git a/src/plugins/vfolder/vfolder.h b/src/plugins/vfolder/vfolder.h
index 8a2406e..41655d0 100644
--- a/src/plugins/vfolder/vfolder.h
+++ b/src/plugins/vfolder/vfolder.h
@@ -6,7 +6,9 @@
/*
* Virtual folder plugin for claws-mail
- * Claws Mail is Copyright (C) 1999-2012 by the Claws Mail Team
+ *
+ * Claws Mail is Copyright (C) 1999-2014 by Michael Rasmussen and
+ * the Claws Mail Team
*
* 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
@@ -63,7 +65,7 @@ typedef MsgInfoList* (*MSGFILTERFUNC) (MsgInfoList* msgs, VFolderItem* item);
struct _VFolderItem {
FolderItem item;
- gchar* filter; /* Regex used to select messages */
+ gchar* filter; /* Glob used to select messages */
gboolean frozen; /* Automatic update or not */
gboolean updating; /* Is this VFolder currently updating */
gboolean changed;
@@ -101,6 +103,8 @@ void vfolder_scan_source_folder(VFolderItem * vitem);
void vfolder_scan_source_folder_list(GSList* vitems);
void vfolder_scan_source_folder_all();
VFolderItem* vfolder_folder_item_watch(FolderItem* item);
+void vfolder_source_path_change(VFolderItem* vitem, FolderItem* newItem);
+void vfolder_source_folder_remove(VFolderItem* vitem);
G_END_DECLS
diff --git a/src/plugins/vfolder/vfolder_gtk.c b/src/plugins/vfolder/vfolder_gtk.c
index ffaa320..2f4e488 100644
--- a/src/plugins/vfolder/vfolder_gtk.c
+++ b/src/plugins/vfolder/vfolder_gtk.c
@@ -6,7 +6,8 @@
/*
* Virtual folder plugin for claws-mail
*
- * Claws Mail is Copyright (C) 1999-2012 by the Claws Mail Team
+ * Claws Mail is Copyright (C) 1999-2014 by Michael Rasmussen and
+ * the Claws Mail Team
*
* 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
@@ -60,7 +61,6 @@
static guint folder_hook_id;
static guint item_hook_id;
static guint msginfo_hook_id;
-//static GSList* widgets = NULL;
typedef struct {
MsgInfoList* list;
@@ -89,7 +89,7 @@ static GtkActionEntry vfolder_popup_entries[] = {
{"FolderViewPopup/FolderProperties", NULL, NULL, NULL, NULL, G_CALLBACK(vfolder_properties_cb) },
- {"FolderViewPopup/RenameFolder", NULL, NULL, NULL, NULL, NULL /*G_CALLBACK(vfolder_refresh_cb)*/ },
+ {"FolderViewPopup/RenameFolder", NULL, NULL, NULL, NULL, G_CALLBACK(vfolder_rename_cb) },
{"FolderViewPopup/NewFolder", NULL, NULL, NULL, NULL, G_CALLBACK(vfolder_new_folder_cb) },
{"FolderViewPopup/RemoveFolder", NULL, NULL, NULL, NULL, G_CALLBACK(vfolder_remove_folder_cb) },
@@ -112,9 +112,8 @@ static void vfolder_set_sensitivity(GtkUIManager *ui_manager, FolderItem *item)
#define SET_SENS(name, sens) \
cm_menu_set_sensitive_full(ui_manager, "Popup/"name, sens)
- VFolderItem* vitem = VFOLDER_ITEM(item);
- SET_SENS("FolderViewPopup/RefreshFolder", folder_item_parent(item) != NULL && ! vitem->frozen);
- SET_SENS("FolderViewPopup/RefreshAllFolders", folder_item_parent(item) == NULL && ! vitem->frozen);
+ SET_SENS("FolderViewPopup/RefreshFolder", folder_item_parent(item) != NULL);
+ SET_SENS("FolderViewPopup/RefreshAllFolders", folder_item_parent(item) == NULL);
SET_SENS("FolderViewPopup/FolderProperties", folder_item_parent(item) != NULL);
SET_SENS("FolderViewPopup/RenameFolder", folder_item_parent(item) != NULL);
SET_SENS("FolderViewPopup/NewFolder", TRUE);
@@ -144,6 +143,7 @@ static void vfolder_fill_popup_menu_labels(void) {
static gboolean vfolder_folder_update_hook(gpointer source, gpointer data) {
FolderUpdateData* hookdata;
+ VFolderItem* vitem;
g_return_val_if_fail(source != NULL, FALSE);
hookdata = (FolderUpdateData *) source;
@@ -151,39 +151,21 @@ static gboolean vfolder_folder_update_hook(gpointer source, gpointer data) {
if (! hookdata->folder || IS_VFOLDER_FOLDER(hookdata->folder))
return FALSE;
- if (hookdata->update_flags & FOLDER_ADD_FOLDER) {
- /* TODO: check if the added folder is foundation for vfolder */
- debug_print("FOLDER_ADD_FOLDER\n");
- }
-
- if (hookdata->update_flags & FOLDER_REMOVE_FOLDER) {
- /* TODO: check if the removed folder is foundation for vfolder */
- debug_print("FOLDER_REMOVE_FOLDER\n");
- }
-
- if (hookdata->update_flags & FOLDER_TREE_CHANGED) {
- /* TODO: check if the changed folder tree affects any vfolder */
- debug_print("FOLDER_TREE_CHANGED\n");
- }
-
- if (hookdata->update_flags & FOLDER_ADD_FOLDERITEM) {
- /* TODO: check if the added folder item affects any vfolder */
- debug_print("FOLDER_ADD_FOLDERITEM\n");
- }
-
if (hookdata->update_flags & FOLDER_REMOVE_FOLDERITEM) {
/* TODO: check if the removed folder item is foundation for vfolder */
debug_print("FOLDER_REMOVE_FOLDERITEM\n");
- }
-
- if (hookdata->update_flags & FOLDER_RENAME_FOLDERITEM) {
- /* TODO: can renaming a folder item affect any vfolder? */
- debug_print("FOLDER_RENAME_FOLDERITEM\n");
+ vitem = vfolder_folder_item_watch(hookdata->item);
+ if (vitem) {
+ vfolder_source_folder_remove(vitem);
+ }
}
if (hookdata->update_flags & FOLDER_MOVE_FOLDERITEM) {
- /* TODO: check if the moved folder item is foundation for vfolder */
debug_print("FOLDER_MOVE_FOLDERITEM\n");
+ /* item = from item2 = to */
+ vitem = vfolder_folder_item_watch(hookdata->item);
+ if (vitem)
+ vfolder_source_path_change(vitem, hookdata->item2);
}
return FALSE;
@@ -199,35 +181,13 @@ static gboolean vfolder_folder_item_update_hook(gpointer source, gpointer data)
if (! hookdata->item || IS_VFOLDER_FOLDER_ITEM(hookdata->item))
return FALSE;
- if (hookdata->update_flags & F_ITEM_UPDATE_MSGCNT &&
- ~ hookdata->update_flags & (F_ITEM_UPDATE_MSGCNT | F_ITEM_UPDATE_CONTENT)) {
- debug_print("F_ITEM_UPDATE_MSGCNT\n");
-/* vitem = vfolder_folder_item_watch(hookdata->item);
- if (vitem && ! vitem->updating)
- vfolder_scan_source_folder(vitem);*/
- }
-
- if (hookdata->update_flags & F_ITEM_UPDATE_CONTENT /*&&
- ~ hookdata->update_flags & (F_ITEM_UPDATE_MSGCNT | F_ITEM_UPDATE_CONTENT)*/) {
+ if (hookdata->update_flags & F_ITEM_UPDATE_CONTENT) {
debug_print("F_ITEM_UPDATE_CONTENT\n");
vitem = vfolder_folder_item_watch(hookdata->item);
- if (vitem && ! vitem->updating)
+ if (vitem && ! vitem->updating && ! vitem->frozen)
vfolder_scan_source_folder(vitem);
}
- if (hookdata->update_flags & F_ITEM_UPDATE_ADDMSG) {
- debug_print("F_ITEM_UPDATE_ADDMSG\n");
- }
-
- if (hookdata->update_flags & F_ITEM_UPDATE_REMOVEMSG ) {
- debug_print("F_ITEM_UPDATE_REMOVEMSG\n");
- }
-
- if (hookdata->update_flags & F_ITEM_UPDATE_NAME) {
- /* TODO: need update? */
- debug_print("F_ITEM_UPDATE_NAME\n");
- }
-
return FALSE;
}
@@ -246,13 +206,6 @@ static gboolean vfolder_msg_info_update_hook(gpointer source, gpointer data) {
if (IS_VFOLDER_MSGINFO(msginfo))
return FALSE;
- if (MSG_IS_NEW(msginfo->flags)) {
- vitem = vfolder_folder_item_watch(msginfo->folder);
- if (vitem) {
- debug_print("MSG_IS_NEW\n");
- }
- }
-
if (MSG_IS_DELETED(msginfo->flags)) {
vitem = vfolder_folder_item_watch(msginfo->folder);
if (vitem) {
@@ -271,8 +224,8 @@ static gboolean vfolder_msg_info_update_hook(gpointer source, gpointer data) {
g_free(msg);
return FALSE;
}
- vitem = vfolder_folder_item_watch(msginfo->to_folder);
- if (! vitem) {
+ vitem = vfolder_folder_item_watch(msginfo->folder);
+ if (vitem && ! vitem->frozen) {
/*
* if folder we move to is already monitored we need not
* do anything since distination folder will be automatically
@@ -282,14 +235,6 @@ static gboolean vfolder_msg_info_update_hook(gpointer source, gpointer data) {
}
}
- if (MSG_IS_MOVE_DONE(msginfo->flags)) {
- vitem = vfolder_folder_item_watch(msginfo->to_folder);
- if (vitem) {
- return FALSE;
- }
- debug_print("MSG_IS_MOVE\n");
- }
-
if (MSG_IS_COPY(msginfo->flags)) {
debug_print("MSG_IS_COPY\n");
if (IS_VFOLDER_FOLDER_ITEM(msginfo->to_folder)) {
@@ -498,49 +443,49 @@ void vfolder_properties_cb(GtkAction* action, gpointer data) {
g_return_if_fail(item->folder != NULL);
if (vfolder_edit_item_dialog(VFOLDER_ITEM(item), NULL)) {
- /* TODO: update */
- if (debug_get_mode()) {
-// GHashTableIter iter;
-// gpointer key, value;
-
-/* g_hash_table_iter_init(&iter, VFOLDER_ITEM(item)->me_to_claws);
- while (g_hash_table_iter_next(&iter, &key, &value)) {
- gchar* buf = g_new0(gchar, BUFSIZ);
- MsgInfo* msginfo = vfolder_find_msg_from_vfolder_num(
- VFOLDER_ITEM(item), GPOINTER_TO_UINT(key));
- FILE* msg = procmsg_open_message(msginfo);
- while (fread(buf, 1, BUFSIZ - 1, msg) > 0) {
- fprintf(stderr, "%s", buf);
- g_free(buf);
- buf = g_new0(gchar, BUFSIZ);
- }
- fprintf(stderr, "\n");
- if (buf)
- g_free(buf);
- fclose(msg);
- }*/
- }
+ FolderPropsResponse resp = vfolder_folder_item_props_write(VFOLDER_ITEM(item));
+ vfolder_item_props_response(resp);
}
}
+void vfolder_rename_cb(GtkAction* action, gpointer data) {
+ FolderView *folderview = (FolderView *)data;
+ FolderItem *item;
+ gchar *new_name, *old_name;
+
+ item = folderview_get_selected_item(folderview);
+ cm_return_if_fail(item != NULL);
+ cm_return_if_fail(item->path != NULL);
+ cm_return_if_fail(item->folder != NULL);
+
+ old_name = folder_item_get_name(item);
+ new_name = input_dialog(_("Rename folder"),
+ _("Input the new name for folder:"),
+ old_name);
+ g_free(old_name);
+ if (!new_name) return;
+ AUTORELEASE_STR(new_name, {g_free(new_name); return;});
+
+ folder_item_rename(item, new_name);
+}
+
void vfolder_new_folder_cb(GtkAction* action, gpointer data) {
FolderView *folderview = (FolderView *)data;
FolderItem *item, *new_item, *parent;
gchar* new_folder;
gchar* name;
gchar* p;
- gchar* id;
item = folderview_get_selected_item(folderview);
- cm_return_if_fail(item != NULL);
- cm_return_if_fail(item->path != NULL);
- cm_return_if_fail(item->folder != NULL);
+ if (item) {
+ cm_return_if_fail(item->path != NULL);
+ cm_return_if_fail(item->folder != NULL);
- if (item->no_sub) {
- alertpanel_error(N_("Virtual folders cannot contain subfolders"));
- return;
+ if (item->no_sub) {
+ alertpanel_error(N_("Virtual folders cannot contain subfolders"));
+ return;
+ }
}
-
new_folder = input_dialog(_("New folder"),
_("Input the name of new folder:"),
_("NewFolder"));
@@ -577,16 +522,12 @@ void vfolder_new_folder_cb(GtkAction* action, gpointer data) {
return;
}
- id = folder_item_get_identifier(item);
if (vfolder_msgvault_add(VFOLDER_ITEM(new_item))) {
new_item->folder->klass->remove_folder(new_item->folder, new_item);
new_item = NULL;
- g_free(id);
return;
}
- g_free(id);
-
folder_write_list();
}
diff --git a/src/plugins/vfolder/vfolder_gtk.h b/src/plugins/vfolder/vfolder_gtk.h
index 270f337..d6270eb 100644
--- a/src/plugins/vfolder/vfolder_gtk.h
+++ b/src/plugins/vfolder/vfolder_gtk.h
@@ -6,7 +6,9 @@
/*
* Virtual folder plugin for claws-mail
- * Claws Mail is Copyright (C) 1999-2012 by the Claws Mail Team
+ *
+ * Claws Mail is Copyright (C) 1999-2014 by Michael Rasmussen and
+ * the Claws Mail Team
*
* 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
@@ -42,6 +44,7 @@ GtkResponseType vfolder_msg_dialog(GtkMessageType msgtype, GtkButtonsType btntyp
/* Callback functions */
void vfolder_new_folder_cb(GtkAction* action, gpointer data);
+void vfolder_rename_cb(GtkAction* action, gpointer data);
void vfolder_remove_folder_cb(GtkAction* action, gpointer data);
void vfolder_properties_cb(GtkAction* action, gpointer data);
void vfolder_refresh_cb(GtkAction* action, gpointer data);
diff --git a/src/plugins/vfolder/vfolder_init.c b/src/plugins/vfolder/vfolder_init.c
index 568f468..0b06023 100644
--- a/src/plugins/vfolder/vfolder_init.c
+++ b/src/plugins/vfolder/vfolder_init.c
@@ -2,11 +2,11 @@
* $Id: $
*/
/* vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: */
-
/*
* Virtual folder plugin for claws-mail
*
- * Claws Mail is Copyright (C) 1999-2012 by the Claws Mail Team
+ * Claws Mail is Copyright (C) 1999-2014 by Michael Rasmussen and
+ * the Claws Mail Team
*
* 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
diff --git a/src/plugins/vfolder/vfolder_prop.c b/src/plugins/vfolder/vfolder_prop.c
index e7485f2..2f08d8b 100644
--- a/src/plugins/vfolder/vfolder_prop.c
+++ b/src/plugins/vfolder/vfolder_prop.c
@@ -2,11 +2,11 @@
* $Id: $
*/
/* vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: */
-
/*
* Virtual folder plugin for claws-mail
*
- * Claws Mail is Copyright (C) 1999-2012 by the Claws Mail Team
+ * Claws Mail is Copyright (C) 1999-2014 by Michael Rasmussen and
+ * the Claws Mail Team
*
* 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
@@ -129,7 +129,7 @@ static GtkWidget* vfolder_prop_row(GtkWidget* widget,
return row;
}
-static gboolean vfolder_set_search_type(VFolderItem* item, GtkWidget* list) {
+static gboolean vfolder_set_search_type(VFolderItem* item, GtkWidget* list, gboolean* update) {
GSList *btn_list, *btns;
gboolean active = FALSE;
GtkToggleButton* btn = NULL;
@@ -166,6 +166,16 @@ static gboolean vfolder_set_search_type(VFolderItem* item, GtkWidget* list) {
return FALSE;
}
+static gboolean vfolder_change_source(VFolderItem* vitem, const gchar* str) {
+ if (! vitem->source_id && ! str)
+ return FALSE;
+ if (! vitem->source_id && str)
+ return TRUE;
+ if (vitem->source_id && ! str)
+ return TRUE;
+ return (strcmp(vitem->source_id, str)) ? TRUE : FALSE;
+}
+
static gboolean vfolder_search_headers(MsgInfo* msg, GPatternSpec* pattern) {
return ((msg->cc && g_pattern_match_string(pattern, msg->cc)) ||
(msg->from && g_pattern_match_string(pattern, msg->from)) ||
@@ -252,7 +262,7 @@ static gboolean vfolder_create_msgs_list(VFolderItem* item) {
}
void vfolder_set_msgs_filter(VFolderItem* vfolder_item) {
- g_return_if_fail(vfolder_item != NULL);
+ cm_return_if_fail(vfolder_item != NULL);
vfolder_item->msg_filter_func = vfolder_filter_msgs_list;
}
@@ -260,8 +270,7 @@ void vfolder_set_msgs_filter(VFolderItem* vfolder_item) {
gboolean vfolder_create_item_dialog(VFolderItem* vitem, FolderItem* item) {
gboolean created = FALSE;
- g_return_val_if_fail(vitem != NULL, created);
- g_return_val_if_fail(item != NULL, created);
+ cm_return_val_if_fail(vitem != NULL, created);
vitem->msg_filter_func = vfolder_filter_msgs_list;
@@ -284,9 +293,9 @@ gboolean vfolder_edit_item_dialog(VFolderItem* vitem, FolderItem* item) {
gboolean frozen;
gchar* old_filter = NULL;
FolderItem* old_source;
+ gboolean update = TRUE;
- g_return_val_if_fail(vitem != NULL, ok);
- g_return_val_if_fail(item != NULL || vitem->source != NULL, ok);
+ cm_return_val_if_fail(vitem != NULL, ok);
MainWindow *mainwin = mainwindow_get_mainwindow();
props_dialog = g_new0(PropsDialog, 1);
@@ -319,13 +328,15 @@ gboolean vfolder_edit_item_dialog(VFolderItem* vitem, FolderItem* item) {
row = vfolder_prop_row(props_dialog->source, N_("_Source folder"), 130, FALSE);
gtk_box_pack_start(GTK_BOX(vbox), row, FALSE, FALSE, 5);
- if (!item)
- id = folder_item_get_identifier(vitem->source);
- else
- id = folder_item_get_identifier(item);
- gtk_entry_set_text(GTK_ENTRY(props_dialog->source), id);
- gtk_widget_set_sensitive(props_dialog->source, FALSE);
- g_free(id);
+ if (item || vitem->source) {
+ if (!item)
+ id = folder_item_get_identifier(vitem->source);
+ else
+ id = folder_item_get_identifier(item);
+ gtk_entry_set_text(GTK_ENTRY(props_dialog->source), id);
+ gtk_widget_set_sensitive(props_dialog->source, FALSE);
+ g_free(id);
+ }
GtkWidget* frame1 = gtk_frame_new(_("Message filter"));
GtkWidget* vbox1 = gtk_vbox_new(TRUE, 2);
@@ -368,18 +379,26 @@ gboolean vfolder_edit_item_dialog(VFolderItem* vitem, FolderItem* item) {
}
}
else {
- if (!vitem->filter || strcmp(vitem->filter, str) != 0) {
+ if (vitem->filter && strcmp(vitem->filter, str) == 0)
+ update = FALSE;
+ else {
g_free(vitem->filter);
vitem->filter = g_strdup(str);
ok = TRUE;
}
}
}
- if (vfolder_set_search_type(vitem, props_dialog->label_btn))
+
+ if (vfolder_set_search_type(vitem, props_dialog->label_btn, &update)) {
+ update = TRUE;
ok = TRUE;
+ } else {
+ update = FALSE;
+ }
+
str = gtk_entry_get_text(GTK_ENTRY(props_dialog->source));
- if (str) {
+ if (vfolder_change_source(vitem, str)) {
if (item) {
vitem->source = item;
} else {
@@ -426,13 +445,14 @@ gboolean vfolder_edit_item_dialog(VFolderItem* vitem, FolderItem* item) {
vitem->changed = TRUE;
}
} else {
- ok = FALSE;
- goto error;
+ ok = TRUE;
+ update = FALSE;
}
if (vitem->frozen != frozen) {
vitem->frozen = frozen;
ok = TRUE;
+ vitem->changed = TRUE;
}
}
diff --git a/src/plugins/vfolder/vfolder_prop.h b/src/plugins/vfolder/vfolder_prop.h
index 4a3e11f..c1fbe06 100644
--- a/src/plugins/vfolder/vfolder_prop.h
+++ b/src/plugins/vfolder/vfolder_prop.h
@@ -1,12 +1,12 @@
/*
* $Id: $
- */
-
-/* vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: */
-
+* vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·:
+*/
/*
* Virtual folder plugin for claws-mail
- * Claws Mail is Copyright (C) 1999-2012 by the Claws Mail Team
+ *
+ * Claws Mail is Copyright (C) 1999-2014 by Michael Rasmussen and
+ * the Claws Mail Team
*
* 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
commit e86757a0887f5fda93fb757f93dd1297dbd26025
Author: Michael Rasmussen <mir at datanom.net>
Date: Thu Jun 19 02:42:58 2014 +0200
Framework finished
diff --git a/src/plugins/vfolder/Makefile.am b/src/plugins/vfolder/Makefile.am
index 0d79537..0808e93 100644
--- a/src/plugins/vfolder/Makefile.am
+++ b/src/plugins/vfolder/Makefile.am
@@ -35,3 +35,5 @@ vfolder_la_CPPFLAGS = \
-I$(top_srcdir)/src/gtk \
$(GLIB_CFLAGS) \
$(GTK_CFLAGS)
+
+EXTRA_DIST = TODO
diff --git a/src/plugins/vfolder/TODO b/src/plugins/vfolder/TODO
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/src/plugins/vfolder/TODO
@@ -0,0 +1 @@
+
diff --git a/src/plugins/vfolder/vfolder.c b/src/plugins/vfolder/vfolder.c
index 330252c..ea56977 100644
--- a/src/plugins/vfolder/vfolder.c
+++ b/src/plugins/vfolder/vfolder.c
@@ -52,29 +52,87 @@ typedef struct {
LocalFolder folder;
} VFolder;
+typedef struct {
+ gint src;
+ gint dest;
+ VFolderItem* vitem;
+} MsgPair;
+
+struct _MsgVault {
+ GHashTable* src_to_virt;
+ GHashTable* virt_to_src;
+};
+
FolderClass vfolder_class;
GHashTable* vfolders;
static gboolean existing_tree_found = FALSE;
-static void free_vfolder_hashtable(gpointer data) {
- g_return_if_fail(data!= NULL);
+static MsgInfo* vfolder_msgvault_get_msginfo(VFolderItem* vitem, gint num, gboolean vmsginfo) {
+ if (! vitem || ! vitem->msgvault) return NULL;
- GHashTable* vfolder = (GHashTable *) data;
- g_hash_table_destroy(vfolder);
+ if (vmsginfo) {
+ debug_print("src->dest: Look up [%d] from %s\n", num, vitem->source_id);
+ return g_hash_table_lookup(vitem->msgvault->src_to_virt, GINT_TO_POINTER(num));
+ } else {
+ gchar* id = folder_item_get_identifier(FOLDER_ITEM(vitem));
+ debug_print("dest->src: Look up [%d] from %s\n", num, id);
+ g_free(id);
+ return g_hash_table_lookup(vitem->msgvault->virt_to_src, GINT_TO_POINTER(num));
+ }
}
-static GHashTable* vfolders_hashtable_new() {
- return g_hash_table_new_full(g_str_hash,
- g_str_equal, g_free, free_vfolder_hashtable);
+static void vfolder_free_hashtable(gpointer data) {
+ cm_return_if_fail(data!= NULL);
+
+ VFolderItem* vfolder = (VFolderItem *) data;
+ debug_print("%s: Removing virtual folder from folders\n", vfolder->source_id);
+ vfolder_msgvault_free(vfolder->msgvault);
}
-static GHashTable* vfolder_hashtable_new() {
+static GHashTable* vfolder_vfolders_new() {
return g_hash_table_new_full(g_str_hash,
- g_str_equal, g_free, (GDestroyNotify) procmsg_msginfo_free);
+ g_str_equal, g_free, vfolder_free_hashtable);
+}
+
+static void vfolder_msgvault_add_msg(MsgPair* msgpair) {
+ VFolderItem* vitem = msgpair->vitem;
+ guint* snum = GUINT_TO_POINTER(msgpair->src);
+ guint* dnum = GUINT_TO_POINTER(msgpair->dest);
+
+ debug_print("Adding message: src->%d dest->%d\n", GPOINTER_TO_INT(snum), GPOINTER_TO_INT(dnum));
+ if (! vitem->msgvault)
+ vitem->msgvault = vfolder_msgvault_new();
+ g_hash_table_replace(vitem->msgvault->src_to_virt, snum, dnum);
+ g_hash_table_replace(vitem->msgvault->virt_to_src, dnum, snum);
+}
+
+static gboolean vfolder_msgvault_remove_msg(VFolderItem* vitem, gint msgnum) {
+ gboolean ret;
+ MsgVault* msgvault = vitem->msgvault;
+ guint* num = GUINT_TO_POINTER(msgnum);
+ gpointer key;
+
+ if (! msgvault) return FALSE;
+
+ if ((key = g_hash_table_lookup(msgvault->src_to_virt, num)) != NULL) {
+ debug_print("Removing message: src->%d dest->%d\n", msgnum, GPOINTER_TO_INT(key));
+ g_hash_table_remove(msgvault->virt_to_src, key);
+ g_hash_table_remove(msgvault->src_to_virt, num);
+ ret = FALSE;
+ } else if ((key = g_hash_table_lookup(msgvault->virt_to_src, num)) != NULL) {
+ debug_print("Removing message: src->%d dest->%d\n", GPOINTER_TO_INT(key), msgnum);
+ g_hash_table_remove(msgvault->virt_to_src, num);
+ g_hash_table_remove(msgvault->src_to_virt, key);
+ ret = FALSE;
+ } else
+ ret = TRUE;
+
+ return ret;
}
static void vfolder_init_read_func(FolderItem* item, gpointer data) {
- g_return_if_fail(item != NULL);
+ cm_return_if_fail(item != NULL);
+ FolderPropsResponse resp;
if (! IS_VFOLDER_FOLDER_ITEM(item))
return;
@@ -84,7 +142,9 @@ static void vfolder_init_read_func(FolderItem* item, gpointer data) {
if (folder_item_parent(item) == NULL)
return;
- vfolder_folder_item_props_read(VFOLDER_ITEM(item));
+ resp = vfolder_folder_item_props_read(VFOLDER_ITEM(item));
+ vfolder_item_props_response(resp);
+
vfolder_set_msgs_filter(VFOLDER_ITEM(item));
/* if (! IS_VFOLDER_FROZEN(VFOLDER_ITEM(item))) {
@@ -113,12 +173,13 @@ static void vfolder_create_default_mailbox(void) {
root = folder_new(vfolder_folder_get_class(), VFOLDER_DEFAULT_MAILBOX, NULL);
- g_return_if_fail(root != NULL);
+ cm_return_if_fail(root != NULL);
folder_add(root);
}
-static Folder* vfolder_new_folder(const gchar* name, const gchar* path) {
+/* Folder functions */
+static Folder* vfolder_folder_new(const gchar* name, const gchar* path) {
VFolder* folder;
debug_print("VFolder: new_folder\n");
@@ -128,11 +189,12 @@ static Folder* vfolder_new_folder(const gchar* name, const gchar* path) {
folder = g_new0(VFolder, 1);
FOLDER(folder)->klass = &vfolder_class;
folder_init(FOLDER(folder), name);
+ FOLDER(folder)->klass->create_tree(FOLDER(folder));
return FOLDER(folder);
}
-static void vfolder_destroy_folder(Folder* _folder)
+static void vfolder_folder_destroy(Folder* _folder)
{
VFolder* folder = VFOLDER(_folder);
@@ -161,8 +223,9 @@ static gint vfolder_create_tree(Folder* folder) {
}
static gint vfolder_scan_tree(Folder *folder) {
- g_return_val_if_fail(folder != NULL, -1);
+ cm_return_val_if_fail(folder != NULL, -1);
+ folder->inbox = NULL;
folder->outbox = NULL;
folder->draft = NULL;
folder->queue = NULL;
@@ -174,6 +237,427 @@ static gint vfolder_scan_tree(Folder *folder) {
return 0;
}
+/* FolderItem functions */
+static gboolean vfolder_scan_required(Folder* folder, FolderItem* item) {
+ cm_return_val_if_fail(item != NULL, FALSE);
+ FolderItem* src = VFOLDER_ITEM(item)->source;
+
+ debug_print("%s: Check if scan is required\n", item->path);
+ cm_return_val_if_fail(src != NULL, FALSE);
+
+ debug_print("mtime src [%ld] mtime VFolder [%ld]\n", src->mtime, item->mtime);
+ if (src->mtime > item->mtime)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static FolderItem* vfolder_item_new(Folder* folder) {
+ VFolderItem* vitem;
+
+ debug_print("VFolder: item_new\n");
+
+ vitem = g_new0(VFolderItem, 1);
+
+ vitem->filter = NULL;
+ vitem->frozen = FALSE;
+ vitem->updating = FALSE;
+ vitem->changed = TRUE;
+ vitem->source_id = NULL;
+ vitem->search = SEARCH_HEADERS;
+ vitem->source = NULL;
+ vitem->msgvault = vfolder_msgvault_new();
+
+ return FOLDER_ITEM(vitem);
+}
+
+static void vfolder_item_destroy(Folder* folder, FolderItem* item) {
+ VFolderItem* vitem = VFOLDER_ITEM(item);
+
+ cm_return_if_fail(vitem != NULL);
+
+ if (vitem->source_id) {
+ debug_print("%s: Removing virtual folder from message store\n", vitem->source_id);
+ g_hash_table_remove(vfolders, vitem->source_id);
+ g_free(vitem->source_id);
+ vitem->source_id = NULL;
+ }
+
+ g_free(vitem->filter);
+ vitem->filter = NULL;
+ vitem->msgvault = NULL;
+ vitem->source = NULL;
+
+ g_free(item);
+ item = NULL;
+}
+
+static gchar* vfolder_item_get_path(Folder* folder, FolderItem* item) {
+ gchar* result;
+
+ cm_return_val_if_fail(item != NULL, NULL);
+
+ result = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, VFOLDER_DIR,
+ G_DIR_SEPARATOR_S, item->path, NULL);
+ return result;
+}
+
+static gint vfolder_folder_remove(Folder* folder, FolderItem* item) {
+ GDir* dp;
+ const gchar* name;
+ gchar* cwd;
+ gint ret = -1;
+
+ cm_return_val_if_fail(folder != NULL, -1);
+ cm_return_val_if_fail(item != NULL, -1);
+ cm_return_val_if_fail(item->path != NULL, -1);
+ cm_return_val_if_fail(item->stype == F_NORMAL, -1);
+
+ debug_print("VFolder: removing folder item %s\n", item->path);
+
+ gchar* path = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
+ VFOLDER_DIR, G_DIR_SEPARATOR_S, item->path, NULL);
+ remove_numbered_files(path, item->last_num - item->total_msgs + 1, item->last_num);
+
+ folder_item_remove(item);
+
+ cwd = g_get_current_dir();
+
+ if (change_dir(path) < 0 ) {
+ g_free(path);
+ return ret;
+ }
+
+ if( (dp = g_dir_open(".", 0, NULL)) == NULL ) {
+ FILE_OP_ERROR(path, "g_dir_open");
+ change_dir(cwd);
+ g_free(cwd);
+ g_free(path);
+ return ret;
+ }
+
+ while ((name = g_dir_read_name(dp)) != NULL) {
+ debug_print("Removing: %s\n", name);
+ claws_unlink(name);
+ }
+
+ g_dir_close(dp);
+ change_dir(cwd);
+ if (g_rmdir(path) == 0)
+ ret = 0;
+
+ g_free(cwd);
+ g_free(path);
+
+ return ret;
+}
+
+static FolderItem* vfolder_folder_create(Folder* folder,
+ FolderItem* parent,
+ const gchar* name) {
+ gchar* path = NULL;
+ FolderItem* newitem = NULL;
+
+ cm_return_val_if_fail(folder != NULL, NULL);
+ cm_return_val_if_fail(parent != NULL, NULL);
+ cm_return_val_if_fail(name != NULL, NULL);
+
+ if (parent->no_sub)
+ return NULL;
+
+ path = g_strconcat((parent->path != NULL) ? parent->path : "", name, NULL);
+ newitem = folder_item_new(folder, name, path);
+ newitem->no_sub = TRUE;
+
+ folder_item_append(parent, newitem);
+ g_free(path);
+
+ return newitem;
+}
+
+static gint vfolder_get_num_list(Folder* folder, FolderItem* item,
+ MsgNumberList** list, gboolean* old_uids_valid) {
+ gchar* path;
+ DIR* dp;
+ struct dirent* d;
+ gint num, nummsgs = 0;
+
+ cm_return_val_if_fail(item != NULL, -1);
+
+ debug_print("VFolder: scanning '%s'...\n", item->path);
+
+ if (vfolder_scan_required(folder, item))
+ vfolder_scan_source_folder(VFOLDER_ITEM(item));
+ else
+ item->mtime = time(NULL);
+
+ *old_uids_valid = TRUE;
+
+ path = folder_item_get_path(item);
+ cm_return_val_if_fail(path != NULL, -1);
+ if (change_dir(path) < 0 ) {
+ g_free(path);
+ return -1;
+ }
+ g_free(path);
+
+ if( (dp = opendir(".")) == NULL ) {
+ FILE_OP_ERROR(item->path, "opendir");
+ return -1;
+ }
+
+ while ((d = readdir(dp)) != NULL ) {
+ if( (num = to_number(d->d_name)) > 0 ) {
+ debug_print("Adding %d to list\n", num);
+ *list = g_slist_prepend(*list, GINT_TO_POINTER(num));
+ nummsgs++;
+ }
+ }
+ closedir(dp);
+
+ return nummsgs;
+}
+
+/* Message functions */
+static void vfolder_get_last_num(Folder *folder, FolderItem *item) {
+ gchar *path;
+ DIR *dp;
+ struct dirent *d;
+ gint max = 0;
+ gint num;
+
+ cm_return_if_fail(item != NULL);
+
+ debug_print("vfolder_get_last_num(): Scanning %s ...\n", item->path);
+ path = folder_item_get_path(item);
+ cm_return_if_fail(path != NULL);
+
+ if (! is_dir_exist(path)) return;
+
+ if (change_dir(path) < 0) {
+ g_free(path);
+ return;
+ }
+ g_free(path);
+
+ if ((dp = opendir(".")) == NULL) {
+ FILE_OP_ERROR(item->path, "opendir");
+ return;
+ }
+
+ while ((d = readdir(dp)) != NULL) {
+ if ((num = to_number(d->d_name)) > 0 && dirent_is_regular_file(d)) {
+ if( max < num )
+ max = num;
+ }
+ }
+ closedir(dp);
+
+ debug_print("Last number in dir %s = %d\n", item->path, max);
+ item->last_num = max;
+}
+
+static gchar* vfolder_get_new_msg_filename(FolderItem* dest) {
+ gchar* destfile;
+ gchar* destpath;
+
+ destpath = folder_item_get_path(dest);
+ cm_return_val_if_fail(destpath != NULL, NULL);
+
+ if (!is_dir_exist(destpath))
+ make_dir_hier(destpath);
+
+ for( ; ; ) {
+ destfile = g_strdup_printf("%s%c%d", destpath, G_DIR_SEPARATOR,
+ dest->last_num + 1);
+ if (is_file_entry_exist(destfile)) {
+ dest->last_num++;
+ g_free(destfile);
+ } else
+ break;
+ }
+
+ g_free(destpath);
+
+ return destfile;
+}
+
+static gint vfolder_add_msgs(Folder* folder, FolderItem* dest, GSList* file_list,
+ GHashTable* relation) {
+ gchar* destfile;
+ GSList* cur;
+ MsgFileInfo* fileinfo;
+ VFolderItem* vitem;
+
+ cm_return_val_if_fail(dest != NULL, -1);
+ cm_return_val_if_fail(file_list != NULL, -1);
+
+ vitem = VFOLDER_ITEM(dest);
+ if (dest->last_num < 0) {
+ vfolder_get_last_num(folder, dest);
+ if (dest->last_num < 0)
+ dest->last_num = 0;
+ }
+
+ for( cur = file_list; cur != NULL; cur = cur->next ) {
+ fileinfo = (MsgFileInfo *)cur->data;
+
+ destfile = vfolder_get_new_msg_filename(dest);
+ if (! destfile)
+ goto bail;
+
+ if (copy_file(fileinfo->file, destfile, TRUE) < 0) {
+ g_warning("can't copy message %s to %s\n", fileinfo->file, destfile);
+ g_free(destfile);
+ destfile = NULL;
+ goto bail;
+ }
+
+ if( relation != NULL )
+ g_hash_table_insert(relation, fileinfo,
+ GINT_TO_POINTER(dest->last_num + 1) );
+ g_free(destfile);
+
+ MsgPair* pair = g_new0(MsgPair, 1);
+ pair->src = fileinfo->msginfo->msgnum;
+ pair->dest = dest->last_num + 1;
+ pair->vitem = vitem;
+ vfolder_msgvault_add_msg(pair);
+ g_free(pair);
+ dest->last_num++;
+ vitem->changed = TRUE;
+ }
+
+ FolderPropsResponse resp = vfolder_folder_item_props_write(VFOLDER_ITEM(dest));
+ vfolder_item_props_response(resp);
+
+bail:
+
+ return (destfile) ? dest->last_num : -1;
+}
+
+static gint vfolder_add_msg(Folder* folder, FolderItem* dest, const gchar* file,
+ MsgFlags* flags) {
+ gint ret;
+ GSList file_list;
+ MsgFileInfo fileinfo;
+
+ cm_return_val_if_fail(file != NULL, -1);
+
+ fileinfo.msginfo = NULL;
+ fileinfo.file = (gchar *)file;
+ fileinfo.flags = flags;
+ file_list.data = &fileinfo;
+ file_list.next = NULL;
+
+ ret = vfolder_add_msgs(folder, dest, &file_list, NULL);
+ return ret;
+}
+
+static gchar* vfolder_fetch_msg(Folder* folder, FolderItem* item, gint num) {
+ gchar* snum = g_strdup_printf("%d", num);
+ gchar* file = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, VFOLDER_DIR,
+ G_DIR_SEPARATOR_S, item->path, G_DIR_SEPARATOR_S, snum, NULL);
+
+ debug_print("VFolder: fetch_msg: '%s'\n", file);
+
+ g_free(snum);
+
+ return file;
+}
+
+static MsgInfo* vfolder_get_msginfo(Folder* folder, FolderItem* item, gint num) {
+ MsgInfo* msginfo = NULL;
+ gchar* file;
+ MsgFlags flags;
+
+ debug_print("VFolder: get_msginfo: %d\n", num);
+
+ cm_return_val_if_fail(folder != NULL, NULL);
+ cm_return_val_if_fail(item != NULL, NULL);
+ cm_return_val_if_fail(num > 0, NULL);
+
+ file = vfolder_fetch_msg(folder, item, num);
+ if (! g_file_test(file, G_FILE_TEST_EXISTS)) {
+ g_free(file);
+ return NULL;
+ }
+
+ flags.perm_flags = MSG_NEW | MSG_UNREAD;
+ flags.tmp_flags = 0;
+
+ msginfo = procheader_parse_file(file, flags, TRUE, TRUE);
+
+ if (msginfo)
+ msginfo->msgnum = num;
+
+ if (!msginfo->folder)
+ msginfo->folder = item;
+
+ g_free(file);
+
+ return msginfo;
+}
+
+static gint vfolder_remove_msg(Folder* folder, FolderItem* item, gint num) {
+ gchar* file;
+ gint vnum;
+
+ cm_return_val_if_fail(item != NULL, -1);
+
+ file = vfolder_fetch_msg(folder, item, num);
+ if (! is_file_exist(file)) {
+ /* num relates to source */
+ vnum = vfolder_get_virtual_msg_num(VFOLDER_ITEM(item), num);
+ g_free(file);
+ file = vfolder_fetch_msg(folder, item, vnum);
+ }
+ cm_return_val_if_fail(file != NULL, -1);
+
+ if (claws_unlink(file) < 0) {
+ FILE_OP_ERROR(file, "unlink");
+ g_free(file);
+ return -1;
+ }
+
+ vfolder_msgvault_remove_msg(VFOLDER_ITEM(item), num);
+ VFOLDER_ITEM(item)->changed = TRUE;
+
+ FolderPropsResponse resp = vfolder_folder_item_props_write(VFOLDER_ITEM(item));
+ vfolder_item_props_response(resp);
+
+ folder_item_scan(item);
+
+ g_free(file);
+
+ return 0;
+}
+
+static gint vfolder_remove_all_msg(Folder* folder, FolderItem* item) {
+ GSList *msg_list, *list;
+
+ cm_return_val_if_fail(item != NULL, -1);
+
+ msg_list = folder_item_get_msg_list(item);
+ if (msg_list) {
+ for (list = msg_list; list; list = g_slist_next(list)) {
+ MsgInfo* msginfo = (MsgInfo *) list->data;
+ folder_item_remove_msg(item, msginfo->msgnum);
+ }
+ }
+ g_slist_free(msg_list);
+
+ return 0;
+}
+
+static gint vfolder_copy_msg (Folder* folder, FolderItem* dest, MsgInfo* msginfo) {
+ return -1;
+}
+
+static gboolean vfolder_subscribe_uri(Folder* folder, const gchar* uri) {
+ return FALSE;
+}
+
FolderClass* vfolder_folder_get_class() {
if (vfolder_class.idstr == NULL ) {
vfolder_class.type = F_UNKNOWN;
@@ -181,35 +665,33 @@ FolderClass* vfolder_folder_get_class() {
vfolder_class.uistr = "VFolder";
/* Folder functions */
- vfolder_class.new_folder = vfolder_new_folder;
- vfolder_class.destroy_folder = vfolder_destroy_folder;
+ vfolder_class.new_folder = vfolder_folder_new;
+ vfolder_class.destroy_folder = vfolder_folder_destroy;
vfolder_class.set_xml = folder_set_xml;
vfolder_class.get_xml = folder_get_xml;
vfolder_class.scan_tree = vfolder_scan_tree;
vfolder_class.create_tree = vfolder_create_tree;
/* FolderItem functions */
-/* vfolder_class.item_new = vfolder_item_new;
+/*
+ vfolder_class.rename_folder = NULL;
+*/
+ vfolder_class.item_new = vfolder_item_new;
vfolder_class.item_destroy = vfolder_item_destroy;
vfolder_class.item_get_path = vfolder_item_get_path;
- vfolder_class.create_folder = vfolder_create_folder;
+ vfolder_class.create_folder = vfolder_folder_create;
vfolder_class.rename_folder = NULL;
- vfolder_class.remove_folder = vfolder_remove_folder;
+ vfolder_class.remove_folder = vfolder_folder_remove;
vfolder_class.get_num_list = vfolder_get_num_list;
- vfolder_class.scan_required = vfolder_scan_required;*/
- vfolder_class.item_new = NULL;
- vfolder_class.item_destroy = NULL;
- vfolder_class.item_get_path = NULL;
- vfolder_class.create_folder = NULL;
- vfolder_class.rename_folder = NULL;
- vfolder_class.remove_folder = NULL;
- vfolder_class.get_num_list = NULL;
- vfolder_class.scan_required = NULL;
+ vfolder_class.scan_required = vfolder_scan_required;
/* Message functions */
-/* vfolder_class.get_msginfo = vfolder_get_msginfo;
- vfolder_class.fetch_msg = vfolder_fetch_msg;
+/*
vfolder_class.copy_msgs = vfolder_copy_msgs;
+*/
+ vfolder_class.get_msginfo = vfolder_get_msginfo;
+ vfolder_class.fetch_msg = vfolder_fetch_msg;
+ vfolder_class.copy_msgs = NULL;
vfolder_class.copy_msg = vfolder_copy_msg;
vfolder_class.add_msg = vfolder_add_msg;
vfolder_class.add_msgs = vfolder_add_msgs;
@@ -217,18 +699,7 @@ FolderClass* vfolder_folder_get_class() {
vfolder_class.remove_msgs = NULL;
vfolder_class.remove_all_msg = vfolder_remove_all_msg;
vfolder_class.change_flags = NULL;
- vfolder_class.subscribe = vfolder_subscribe_uri;*/
- vfolder_class.get_msginfo = NULL;
- vfolder_class.fetch_msg = NULL;
- vfolder_class.copy_msgs = NULL;
- vfolder_class.copy_msg = NULL;
- vfolder_class.add_msg = NULL;
- vfolder_class.add_msgs = NULL;
- vfolder_class.remove_msg = NULL;
- vfolder_class.remove_msgs = NULL;
- vfolder_class.remove_all_msg = NULL;
- vfolder_class.change_flags = NULL;
- vfolder_class.subscribe = NULL;
+ vfolder_class.subscribe = vfolder_subscribe_uri;
debug_print("VFolder: registered folderclass\n");
}
@@ -249,9 +720,9 @@ gboolean vfolder_init(void) {
return FALSE;
}
- folder_func_to_all_folders((FolderItemFunc)vfolder_init_read_func, NULL);
+ vfolders = vfolder_vfolders_new();
- vfolders = vfolders_hashtable_new();
+ folder_func_to_all_folders((FolderItemFunc)vfolder_init_read_func, NULL);
if (existing_tree_found == FALSE)
vfolder_create_default_mailbox();
@@ -268,3 +739,265 @@ void vfolder_done(void) {
if (!claws_is_exiting())
folder_unregister_class(vfolder_folder_get_class());
}
+
+void vfolder_set_last_num(Folder *folder, FolderItem *item) {
+ gchar *path;
+ DIR *dp;
+ struct dirent *d;
+ gint max = 0;
+ gint num;
+
+ cm_return_if_fail(item != NULL);
+
+ debug_print("vfolder_get_last_num(): Scanning %s ...\n", item->path);
+ path = folder_item_get_path(item);
+ cm_return_if_fail(path != NULL);
+ if( change_dir(path) < 0 ) {
+ g_free(path);
+ return;
+ }
+ g_free(path);
+
+ if( (dp = opendir(".")) == NULL ) {
+ FILE_OP_ERROR(item->path, "opendir");
+ return;
+ }
+
+ while( (d = readdir(dp)) != NULL ) {
+ if( (num = to_number(d->d_name)) > 0 && dirent_is_regular_file(d) ) {
+ if( max < num )
+ max = num;
+ }
+ }
+ closedir(dp);
+
+ debug_print("Last number in dir %s = %d\n", item->path, max);
+ item->last_num = max;
+}
+
+gint vfolder_get_virtual_msg_num(VFolderItem* vitem, gint srcnum) {
+ gpointer val;
+
+ cm_return_val_if_fail(vitem != NULL, -1);
+
+ val = g_hash_table_lookup(vitem->msgvault->src_to_virt, GINT_TO_POINTER(srcnum));
+
+ if (val)
+ return GPOINTER_TO_INT(val);
+ else
+ return -1;
+}
+
+gint vfolder_get_source_msg_num(VFolderItem* vitem, gint virtnum) {
+ gpointer val;
+
+ cm_return_val_if_fail(vitem != NULL, -1);
+
+ val = g_hash_table_lookup(vitem->msgvault->virt_to_src, GINT_TO_POINTER(virtnum));
+
+ if (val)
+ return GPOINTER_TO_INT(val);
+ else
+ return -1;
+}
+
+gboolean vfolder_msgvault_add(VFolderItem* vitem) {
+ cm_return_val_if_fail(vitem != NULL, TRUE);
+ cm_return_val_if_fail(vitem->source_id != NULL, TRUE);
+
+ g_hash_table_replace(vfolders, g_strdup(vitem->source_id), vitem);
+
+ return FALSE;
+}
+
+#define MSGVAULT_GROUP "message vault"
+gboolean vfolder_msgvault_serialize(VFolderItem* vitem, GKeyFile* config) {
+ MsgVault* msgvault;
+ GHashTableIter iter;
+ gpointer key, value;
+
+ cm_return_val_if_fail(vitem != NULL, TRUE);
+ cm_return_val_if_fail(vitem->msgvault != NULL, TRUE);
+ cm_return_val_if_fail(config != NULL, TRUE);
+
+ msgvault = vitem->msgvault;
+ g_hash_table_iter_init (&iter, msgvault->virt_to_src);
+ // Save each key / value pair to file
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ gchar* k = itos(GPOINTER_TO_INT(key));
+ g_key_file_set_integer(config, MSGVAULT_GROUP, g_strdup(k), GPOINTER_TO_INT(value));
+ debug_print("Vault to config: src->%s dest->%d\n", k, GPOINTER_TO_INT(value));
+ }
+
+ return FALSE;
+}
+
+gboolean vfolder_msgvault_restore(VFolderItem* vitem, GKeyFile* config) {
+ MsgVault* msgvault;
+ gchar **keys;
+ gchar **keys_it;
+
+ cm_return_val_if_fail(vitem != NULL, TRUE);
+ cm_return_val_if_fail(config != NULL, TRUE);
+
+ if (!vitem->msgvault)
+ vitem->msgvault = vfolder_msgvault_new();
+ msgvault = vitem->msgvault;
+
+ keys = g_key_file_get_keys (config, MSGVAULT_GROUP, NULL, NULL);
+ keys_it = keys;
+ // Add each key / value pair from file
+ while (keys_it != NULL && (*keys_it) != NULL) {
+ gint value = g_key_file_get_integer(config, MSGVAULT_GROUP, (*keys_it), NULL);
+ gint key = to_number(*keys_it);
+ debug_print("Insert into vault: src->%d dest->%d\n", value, key);
+ g_hash_table_insert(msgvault->virt_to_src, GINT_TO_POINTER(key), GINT_TO_POINTER(value));
+ g_hash_table_insert(msgvault->src_to_virt, GINT_TO_POINTER(value), GINT_TO_POINTER(key));
+ ++keys_it;
+ }
+ if (keys != NULL)
+ g_strfreev (keys);
+
+ return FALSE;
+}
+
+MsgVault* vfolder_msgvault_new() {
+ MsgVault* msgvault = g_new0(MsgVault, 1);
+ msgvault->src_to_virt = g_hash_table_new(g_direct_hash, g_direct_equal);
+ msgvault->virt_to_src = g_hash_table_new(g_direct_hash, g_direct_equal);
+
+ return msgvault;
+}
+
+void vfolder_msgvault_free(MsgVault* data) {
+ cm_return_if_fail(data != NULL);
+
+ debug_print("Removing message vault\n");
+
+ g_hash_table_destroy(data->src_to_virt);
+ g_hash_table_destroy(data->virt_to_src);
+ g_free(data);
+}
+
+void vfolder_scan_source_folder(VFolderItem * vitem) {
+ MsgInfoList *mlist, *cur, *unfiltered = NULL, *filtered;
+ GSList* filelist = NULL, *tmp;
+ GHashTableIter iter;
+ gpointer key, value;
+ MsgInfo* msginfo;
+ FolderItem* item;
+
+ cm_return_if_fail(vitem != NULL);
+
+ if (! vitem->source) return;
+
+ debug_print("%s: Scanning source [%s]\n", FOLDER_ITEM(vitem)->path, vitem->source_id);
+
+ item = folder_find_item_from_identifier(vitem->source_id);
+ if (! item) return;
+
+ vitem->updating = TRUE;
+ folder_item_scan(item);
+
+ folder_item_update_freeze();
+ mlist = folder_item_get_msg_list(item);
+
+ /* find new messages */
+ for (cur = mlist; cur; cur = g_slist_next(cur)) {
+ msginfo = (MsgInfo *) cur->data;
+ MsgInfo* vmsginfo = vfolder_msgvault_get_msginfo(vitem, msginfo->msgnum, TRUE);
+ if (! vmsginfo)
+ unfiltered = g_slist_append(unfiltered, msginfo);
+ else
+ procmsg_msginfo_free(msginfo);
+ }
+ filtered = vitem->msg_filter_func(unfiltered, vitem);
+ if (filtered) {
+ filelist = procmsg_get_message_file_list(filtered);
+ if (filelist) {
+ gint n = folder_item_add_msgs(FOLDER_ITEM(vitem), filelist, FALSE);
+ FOLDER_ITEM(vitem)->last_num = n;
+ procmsg_message_file_list_free(filelist);
+ }
+ g_slist_free(filtered);
+ }
+ procmsg_msg_list_free(unfiltered);
+
+ /* find removed messages */
+ filelist = NULL;
+ g_hash_table_iter_init (&iter, vitem->msgvault->virt_to_src);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ gint num = GPOINTER_TO_INT(value);
+ msginfo = folder_item_get_msginfo(vitem->source, num);
+ if (! msginfo)
+ filelist = g_slist_prepend(filelist, value);
+ else
+ procmsg_msginfo_free(msginfo);
+ }
+
+ for (tmp = filelist; tmp; tmp = g_slist_next(tmp)) {
+ gint num = GPOINTER_TO_INT(tmp->data);
+ folder_item_remove_msg(FOLDER_ITEM(vitem), num);
+ }
+
+ if (filelist)
+ g_slist_free(filelist);
+
+ if (mlist)
+ g_slist_free(mlist);
+
+ folder_item_update_thaw();
+
+ FOLDER_ITEM(vitem)->mtime = time(NULL);
+ vitem->updating = FALSE;
+}
+
+void vfolder_scan_source_folder_list(GSList* vitems) {
+ GSList* cur;
+ VFolderItem* vitem;
+
+ if (! vitems) return;
+
+ for (cur = vitems; cur; cur = g_slist_next(cur)) {
+ vitem = (VFolderItem *) cur->data;
+ vfolder_scan_source_folder(vitem);
+ }
+}
+
+void vfolder_scan_source_folder_all() {
+ GHashTableIter iter;
+ gpointer key, value;
+ VFolderItem* vitem;
+ GSList* vitems = NULL;
+
+ g_hash_table_iter_init (&iter, vfolders);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ vitem = VFOLDER_ITEM(value);
+ vitems = g_slist_prepend(vitems, vitem);
+ }
+
+ vfolder_scan_source_folder_list(vitems);
+ g_slist_free(vitems);
+}
+
+VFolderItem* vfolder_folder_item_watch(FolderItem* item) {
+ GHashTableIter iter;
+ gpointer key, value;
+ VFolderItem* match = NULL;
+
+ cm_return_val_if_fail(item != NULL, FALSE);
+
+ gchar* id = folder_item_get_identifier(item);
+ if (!id) return FALSE;
+
+ g_hash_table_iter_init (&iter, vfolders);
+ while (g_hash_table_iter_next (&iter, &key, &value) && ! match) {
+ VFolderItem* vitem = VFOLDER_ITEM(value);
+ if (g_utf8_collate(id, vitem->source_id) == 0)
+ match = vitem;
+ }
+
+ g_free(id);
+
+ return match;
+}
diff --git a/src/plugins/vfolder/vfolder.h b/src/plugins/vfolder/vfolder.h
index 51f394d..8a2406e 100644
--- a/src/plugins/vfolder/vfolder.h
+++ b/src/plugins/vfolder/vfolder.h
@@ -41,6 +41,22 @@ G_BEGIN_DECLS
#define VFOLDER_DEFAULT_MAILBOX _("Virtual folders")
typedef struct _VFolderItem VFolderItem;
+typedef struct _MsgVault MsgVault;
+
+typedef enum {
+ FOLDER_ITEM_PROPS_OK,
+ FOLDER_ITEM_PROPS_NO_ITEM,
+ FOLDER_ITEM_PROPS_BACKUP_FAIL,
+ FOLDER_ITEM_PROPS_READ_DATA_FAIL,
+ FOLDER_ITEM_PROPS_MAKE_RC_DIR_FAIL,
+ FOLDER_ITEM_PROPS_READ_USING_DEFAULT
+} FolderPropsResponse;
+
+typedef enum {
+ SEARCH_HEADERS = 1, /* from/to/subject */
+ SEARCH_BODY = 2, /* message */
+ SEARCH_BOTH = 4 /* both */
+} SearchType;
typedef MsgInfoList* (*MSGFILTERFUNC) (MsgInfoList* msgs, VFolderItem* item);
@@ -50,9 +66,12 @@ struct _VFolderItem {
gchar* filter; /* Regex used to select messages */
gboolean frozen; /* Automatic update or not */
gboolean updating; /* Is this VFolder currently updating */
+ gboolean changed;
+ SearchType search;
FolderItem* source; /* Source folder for virtual folder */
- GHashTable* msg_store; /* Hashtable containing MsgInfo. Key is msginfo_identifier */
+ gchar* source_id;
+ MsgVault* msgvault; /* Message store */
MSGFILTERFUNC msg_filter_func; /* Active filter function */
};
@@ -70,6 +89,18 @@ gboolean vfolder_init(void);
void vfolder_done(void);
FolderClass* vfolder_folder_get_class(void);
+gint vfolder_get_virtual_msg_num(VFolderItem* vitem, gint srcnum);
+gint vfolder_get_source_msg_num(VFolderItem* vitem, gint virtnum);
+void vfolder_set_last_num(Folder *folder, FolderItem *item);
+gboolean vfolder_msgvault_add(VFolderItem* vitem);
+void vfolder_msgvault_free(MsgVault* data);
+MsgVault* vfolder_msgvault_new();
+gboolean vfolder_msgvault_serialize(VFolderItem* vitem, GKeyFile* config);
+gboolean vfolder_msgvault_restore(VFolderItem* vitem, GKeyFile* config);
+void vfolder_scan_source_folder(VFolderItem * vitem);
+void vfolder_scan_source_folder_list(GSList* vitems);
+void vfolder_scan_source_folder_all();
+VFolderItem* vfolder_folder_item_watch(FolderItem* item);
G_END_DECLS
diff --git a/src/plugins/vfolder/vfolder_gtk.c b/src/plugins/vfolder/vfolder_gtk.c
index eb037c5..ffaa320 100644
--- a/src/plugins/vfolder/vfolder_gtk.c
+++ b/src/plugins/vfolder/vfolder_gtk.c
@@ -60,7 +60,7 @@
static guint folder_hook_id;
static guint item_hook_id;
static guint msginfo_hook_id;
-static GSList* widgets = NULL;
+//static GSList* widgets = NULL;
typedef struct {
MsgInfoList* list;
@@ -84,8 +84,8 @@ static char* vfolder_popup_menu_labels[] = {
};
static GtkActionEntry vfolder_popup_entries[] = {
- {"FolderViewPopup/RefreshFolder", NULL, NULL, NULL, NULL, NULL /*G_CALLBACK(vfolder_refresh_cb)*/ },
- {"FolderViewPopup/RefreshAllFolders", NULL, NULL, NULL, NULL, NULL /*G_CALLBACK(vfolder_refresh_cb)*/ },
+ {"FolderViewPopup/RefreshFolder", NULL, NULL, NULL, NULL, G_CALLBACK(vfolder_refresh_cb) },
+ {"FolderViewPopup/RefreshAllFolders", NULL, NULL, NULL, NULL, G_CALLBACK(vfolder_refresh_all_cb) },
{"FolderViewPopup/FolderProperties", NULL, NULL, NULL, NULL, G_CALLBACK(vfolder_properties_cb) },
@@ -112,9 +112,9 @@ static void vfolder_set_sensitivity(GtkUIManager *ui_manager, FolderItem *item)
#define SET_SENS(name, sens) \
cm_menu_set_sensitive_full(ui_manager, "Popup/"name, sens)
- VFolderItem *ritem = (VFolderItem *)item;
- SET_SENS("FolderViewPopup/RefreshFolder", folder_item_parent(item) != NULL && ! ritem->frozen);
- SET_SENS("FolderViewPopup/RefreshAllFolders", folder_item_parent(item) == NULL && ! ritem->frozen);
+ VFolderItem* vitem = VFOLDER_ITEM(item);
+ SET_SENS("FolderViewPopup/RefreshFolder", folder_item_parent(item) != NULL && ! vitem->frozen);
+ SET_SENS("FolderViewPopup/RefreshAllFolders", folder_item_parent(item) == NULL && ! vitem->frozen);
SET_SENS("FolderViewPopup/FolderProperties", folder_item_parent(item) != NULL);
SET_SENS("FolderViewPopup/RenameFolder", folder_item_parent(item) != NULL);
SET_SENS("FolderViewPopup/NewFolder", TRUE);
@@ -142,325 +142,6 @@ static void vfolder_fill_popup_menu_labels(void) {
}
}
-static void gslist_menu_item_free(GSList** menu_list) {
- GSList* list;
-
- if (! menu_list || ! *menu_list)
- return;
-
- for (list = *menu_list; list; list = g_slist_next(list)) {
- MenuItem* menu = (MenuItem *) list->data;
- g_free(menu);
- }
-
- g_slist_free(*menu_list);
- *menu_list = NULL;
-}
-
-static gboolean get_menu_widgets() {
- MainWindow* mainwindow;
- MenuItem* menuitem = NULL;
- GtkWidget* widget;
-
- mainwindow = mainwindow_get_mainwindow();
- if (mainwindow && mainwindow->ui_manager) {
- widget = gtk_ui_manager_get_widget(
- mainwindow->ui_manager, "/Menus/SummaryViewPopup/Move/");
- if (widget) {
- menuitem = g_new0(MenuItem, 1);
- menuitem->widget = widget;
- menuitem->action = gtk_ui_manager_get_action(
- mainwindow->ui_manager, "/Menus/SummaryViewPopup/Move/");
- widgets = g_slist_prepend(widgets, menuitem);
- }
- else
- return FALSE;
-
- widget = gtk_ui_manager_get_widget(
- mainwindow->ui_manager, "/Menus/SummaryViewPopup/Trash/");
- if (widget) {
- menuitem = g_new0(MenuItem, 1);
- menuitem->widget = widget;
- menuitem->action = gtk_ui_manager_get_action(
- mainwindow->ui_manager, "/Menus/SummaryViewPopup/Trash/");
- widgets = g_slist_prepend(widgets, menuitem);
- }
- else {
- gslist_menu_item_free(&widgets);
- return FALSE;
- }
-
- widget = gtk_ui_manager_get_widget(
- mainwindow->ui_manager, "/Menus/SummaryViewPopup/Delete/");
- if (widget) {
- menuitem = g_new0(MenuItem, 1);
- menuitem->widget = widget;
- menuitem->action = gtk_ui_manager_get_action(
- mainwindow->ui_manager, "/Menus/SummaryViewPopup/Delete/");
- widgets = g_slist_prepend(widgets, menuitem);
- }
- else {
- gslist_menu_item_free(&widgets);
- return FALSE;
- }
-
- widget = gtk_ui_manager_get_widget(
- mainwindow->ui_manager, "/Menu/Message/Move/");
- if (widget) {
- menuitem = g_new0(MenuItem, 1);
- menuitem->widget = widget;
- menuitem->action = gtk_ui_manager_get_action(
- mainwindow->ui_manager, "/Menu/Message/Move/");
- widgets = g_slist_prepend(widgets, menuitem);
- }
- else {
- gslist_menu_item_free(&widgets);
- return FALSE;
- }
-
- widget = gtk_ui_manager_get_widget(
- mainwindow->ui_manager, "/Menu/Message/Trash/");
- if (widget) {
- menuitem = g_new0(MenuItem, 1);
- menuitem->widget = widget;
- menuitem->action = gtk_ui_manager_get_action(
- mainwindow->ui_manager, "/Menu/Message/Trash/");
- widgets = g_slist_prepend(widgets, menuitem);
- }
- else {
- gslist_menu_item_free(&widgets);
- return FALSE;
- }
-
- widget = gtk_ui_manager_get_widget(
- mainwindow->ui_manager, "/Menu/Message/Delete/");
- if (widget) {
- menuitem = g_new0(MenuItem, 1);
- menuitem->widget = widget;
- menuitem->action = gtk_ui_manager_get_action(
- mainwindow->ui_manager, "/Menu/Message/Delete/");
- widgets = g_slist_prepend(widgets, menuitem);
- }
- else {
- gslist_menu_item_free(&widgets);
- return FALSE;
- }
-
- }
- else
- return FALSE;
-
- return TRUE;
-}
-/*
-static gboolean vfolder_widgets_is_visible() {
- gboolean visible = TRUE;
-
- if (widgets && widgets->data) {
- MenuItem* menu = (MenuItem *) widgets->data;
- visible = gtk_widget_get_visible(menu->widget);
- }
-
- return visible;
-}
-
-static gboolean vfolder_hide_widgets(VFolderItem* item) {
- GSList* list;
- MainWindow* mainwindow;
-
-// if (! item->deep_copy) {
- for (list = widgets; list; list = g_slist_next(list)) {
- MenuItem* menu = (MenuItem *) list->data;
- gtk_widget_hide(menu->widget);
- gtk_action_block_activate(menu->action);
- }
-
- mainwindow = mainwindow_get_mainwindow();
- if (mainwindow && mainwindow->toolbar) {
- if (mainwindow->toolbar->trash_btn)
- gtk_widget_hide(mainwindow->toolbar->trash_btn);
- if (mainwindow->toolbar->delete_btn)
- gtk_widget_hide(mainwindow->toolbar->delete_btn);
- }
-// }
- return TRUE;
-}
-*/
-static gboolean vfolder_show_widgets(VFolderItem* item) {
- GSList* list;
- MainWindow* mainwindow;
-
-// if (! item->deep_copy) {
- for (list = widgets; list; list = g_slist_next(list)) {
- MenuItem* menu = (MenuItem *) list->data;
- gtk_widget_show(menu->widget);
- gtk_action_unblock_activate(menu->action);
- }
-
- mainwindow = mainwindow_get_mainwindow();
- if (mainwindow && mainwindow->toolbar) {
- if (mainwindow->toolbar->trash_btn)
- gtk_widget_show(mainwindow->toolbar->trash_btn);
- if (mainwindow->toolbar->delete_btn)
- gtk_widget_show(mainwindow->toolbar->delete_btn);
- }
-// }
- return TRUE;
-}
-/*
-static gchar* vfolder_get_message_file_path(VFolderItem* item, MsgInfo* msg) {
- gchar* path;
- GSList* list = NULL, *cur;
- Folder* folder;
- gboolean old_uid;
- guint last = 0;
-
- if (item->deep_copy) {
- path = procmsg_get_message_file_path(msg);
- }
- else {
- gchar* root = folder_item_get_path(msg->to_folder);
- folder = msg->to_folder->folder;
- guint num = folder->klass->get_num_list(folder, msg->to_folder, &list, &old_uid);
- if (num >= 0) {
- for (cur = list, last = 0; cur; cur = g_slist_next(cur)) {
- guint tmp = GPOINTER_TO_UINT(cur->data);
- if (tmp > last)
- last = tmp;
- }
- }
- g_slist_free(list);
-
- path = g_strdup_printf("%s%s%u", root, G_DIR_SEPARATOR_S, last + 1);
- g_free(root);
- }
- return path;
-}
-*/
-
-/*
-static void vfolder_item_update(AddMsgData* msgdata) {
- MsgInfoList* cur;
- GSList update;
- MsgFileInfo fileinfo;
-
- if (!msgdata->item || !msgdata->list->data)
- return;
-
- for (cur = msgdata->list; cur; cur = g_slist_next(cur)) {
- MsgInfo* msg = (MsgInfo *) cur->data;
- if (MSG_IS_DELETED(msg->flags)) {
- folder_item_remove_msg(FOLDER_ITEM(msgdata->item), msg->msgnum);
- }
- else {
- fileinfo.msginfo = msg;
- fileinfo.flags = &msg->flags;
- fileinfo.file = msgdata->file;
- update.data = &fileinfo;
- update.next = NULL;
- folder_item_scan(msg->folder);
- gint n = folder_item_add_msgs(FOLDER_ITEM(msgdata->item), &update, FALSE);
- gchar* p = strrchr(fileinfo.file, G_DIR_SEPARATOR);
- p += 1;
- guint num = to_number((const gchar *) p);
- vfolder_replace_key_in_bridge(msgdata->item, msg->msgnum, num);
- FOLDER_ITEM(msgdata->item)->last_num = n;
- }
- }
-
- //procmsg_message_file_list_free(list);
- //item->msginfos = folder_item_get_msg_list(FOLDER_ITEM(item));
-}
-*/
-/*
-static void add_msg_data_free(AddMsgData** rec) {
- if (rec && *rec) {
- AddMsgData* data = *rec;
- g_slist_free(data->list);
- g_free(data->file);
- g_free(data);
- *rec = NULL;
- }
-}
-*/
-/*
-static void vfolder_update_affected_folder_items(MsgInfo* msginfo) {
- GList *vfolders, *cur;
- GSList* cur_msg;
- gchar* src;
- AddMsgData* data;
- MsgInfo* msg;
-
- if (! msginfo)
- return;
-
- if (MSG_IS_NEW(msginfo->flags) ||
- MSG_IS_MOVE(msginfo->flags) ||
- MSG_IS_COPY(msginfo->flags) ||
- MSG_IS_DELETED(msginfo->flags)) {
- vfolders = vfolder_get_vfolder_items();
- for (cur = vfolders; cur; cur = g_list_next(cur)) {
- data = g_new0(AddMsgData, 1);
- VFolderItem* vitem = VFOLDER_ITEM(cur->data);
- if (MSG_IS_MOVE(msginfo->flags) || MSG_IS_COPY(msginfo->flags))
- src = folder_item_get_identifier(msginfo->to_folder);
- else
- src = folder_item_get_identifier(msginfo->folder);
- gchar* shadow = folder_item_get_identifier(vitem->source);
- debug_print("cmp %s : %s\n", src, shadow);
- if (src && shadow && strcmp(src, shadow) == 0) {
- if (MSG_IS_DELETED(msginfo->flags)) {
- msg = vfolder_find_msg_from_claws_num(vitem, msginfo->msgnum);
- if (msg)
- data->list = g_slist_append(data->list, msg);
- else {
- add_msg_data_free(&data);
- g_slist_free(add_msg_data);
- add_msg_data = NULL;
- g_free(src);
- g_free(shadow);
- return;
- }
- }
- else {
- data->list = g_slist_append(data->list, msginfo);
- data->item = vitem;
- data->file = vfolder_get_message_file_path(vitem, msginfo);
- add_msg_data = g_slist_prepend(add_msg_data, data);
- }
- if (data->list && MSG_IS_DELETED(msginfo->flags)) {
- GSList* list = vfolder_filter_msgs_list(data->list, vitem);
- if (list && list->data) {
- MsgInfo* msg = (MsgInfo *) list->data;
- MSG_SET_PERM_FLAGS(msg->flags, MSG_DELETED);
- }
- g_slist_free(data->list);
- data->list = list;
- data->item = vitem;
- vfolder_item_update(data);
- add_msg_data_free(&data);
- g_slist_free(add_msg_data);
- add_msg_data = NULL;
- }
- }
- g_free(src);
- g_free(shadow);
- }
- }
- if (add_msg_data) {
- for (cur_msg = add_msg_data; cur_msg; cur_msg = g_slist_next(cur_msg)) {
- data = (AddMsgData *) cur_msg->data;
- GSList* list = vfolder_filter_msgs_list(data->list, data->item);
- g_slist_free(data->list);
- data->list = list;
- vfolder_item_update(data);
- add_msg_data_free(&data);
- }
- g_slist_free(add_msg_data);
- add_msg_data = NULL;
- }
-}
-*/
static gboolean vfolder_folder_update_hook(gpointer source, gpointer data) {
FolderUpdateData* hookdata;
@@ -470,9 +151,9 @@ static gboolean vfolder_folder_update_hook(gpointer source, gpointer data) {
if (! hookdata->folder || IS_VFOLDER_FOLDER(hookdata->folder))
return FALSE;
- if (hookdata->update_flags & FOLDER_REMOVE_FOLDERITEM) {
- /* TODO: check if the removed folder item is foundation for vfolder */
- debug_print("FOLDER_REMOVE_FOLDERITEM\n");
+ if (hookdata->update_flags & FOLDER_ADD_FOLDER) {
+ /* TODO: check if the added folder is foundation for vfolder */
+ debug_print("FOLDER_ADD_FOLDER\n");
}
if (hookdata->update_flags & FOLDER_REMOVE_FOLDER) {
@@ -481,24 +162,36 @@ static gboolean vfolder_folder_update_hook(gpointer source, gpointer data) {
}
if (hookdata->update_flags & FOLDER_TREE_CHANGED) {
- /* TODO: check if the removed folder is foundation for vfolder */
+ /* TODO: check if the changed folder tree affects any vfolder */
debug_print("FOLDER_TREE_CHANGED\n");
}
+ if (hookdata->update_flags & FOLDER_ADD_FOLDERITEM) {
+ /* TODO: check if the added folder item affects any vfolder */
+ debug_print("FOLDER_ADD_FOLDERITEM\n");
+ }
+
+ if (hookdata->update_flags & FOLDER_REMOVE_FOLDERITEM) {
+ /* TODO: check if the removed folder item is foundation for vfolder */
+ debug_print("FOLDER_REMOVE_FOLDERITEM\n");
+ }
+
if (hookdata->update_flags & FOLDER_RENAME_FOLDERITEM) {
- /* TODO: check if the removed folder is foundation for vfolder */
+ /* TODO: can renaming a folder item affect any vfolder? */
debug_print("FOLDER_RENAME_FOLDERITEM\n");
}
+ if (hookdata->update_flags & FOLDER_MOVE_FOLDERITEM) {
+ /* TODO: check if the moved folder item is foundation for vfolder */
+ debug_print("FOLDER_MOVE_FOLDERITEM\n");
+ }
+
return FALSE;
}
static gboolean vfolder_folder_item_update_hook(gpointer source, gpointer data) {
FolderItemUpdateData* hookdata;
-// gint save_state = -1;
- GList *items = NULL, *cur;
-// gboolean r;
-// MainWindow* mainwindow;
+ VFolderItem* vitem;
g_return_val_if_fail(source != NULL, FALSE);
hookdata = (FolderItemUpdateData *) source;
@@ -506,161 +199,112 @@ static gboolean vfolder_folder_item_update_hook(gpointer source, gpointer data)
if (! hookdata->item || IS_VFOLDER_FOLDER_ITEM(hookdata->item))
return FALSE;
- if (hookdata->update_flags & F_ITEM_UPDATE_REMOVEMSG ) {
- debug_print("F_ITEM_UPDATE_REMOVEMSG\n");
- //items = vfolder_get_vfolder_from_source(hookdata->item);
- if (items) {
- for (cur = items; cur; cur = g_list_next(cur)) {
- //vfolder_folder_item_update_msgs(VFOLDER_ITEM(cur->data), F_ITEM_UPDATE_REMOVEMSG);
- }
- g_list_free(items);
- }
+ if (hookdata->update_flags & F_ITEM_UPDATE_MSGCNT &&
+ ~ hookdata->update_flags & (F_ITEM_UPDATE_MSGCNT | F_ITEM_UPDATE_CONTENT)) {
+ debug_print("F_ITEM_UPDATE_MSGCNT\n");
+/* vitem = vfolder_folder_item_watch(hookdata->item);
+ if (vitem && ! vitem->updating)
+ vfolder_scan_source_folder(vitem);*/
}
- else if (hookdata->update_flags & F_ITEM_UPDATE_CONTENT) {
+ if (hookdata->update_flags & F_ITEM_UPDATE_CONTENT /*&&
+ ~ hookdata->update_flags & (F_ITEM_UPDATE_MSGCNT | F_ITEM_UPDATE_CONTENT)*/) {
debug_print("F_ITEM_UPDATE_CONTENT\n");
- //items = vfolder_get_vfolder_from_source(hookdata->item);
- if (items) {
- for (cur = items; cur; cur = g_list_next(cur)) {
- //vfolder_folder_item_update_msgs(VFOLDER_ITEM(cur->data), F_ITEM_UPDATE_CONTENT);
- }
- g_list_free(items);
- }
- //mainwindow = mainwindow_get_mainwindow();
- //summary_execute(mainwindow->summaryview);
+ vitem = vfolder_folder_item_watch(hookdata->item);
+ if (vitem && ! vitem->updating)
+ vfolder_scan_source_folder(vitem);
}
- else if (hookdata->update_flags & F_ITEM_UPDATE_ADDMSG) {
+ if (hookdata->update_flags & F_ITEM_UPDATE_ADDMSG) {
debug_print("F_ITEM_UPDATE_ADDMSG\n");
- //items = vfolder_get_vfolder_from_source(hookdata->item);
- if (items) {
- for (cur = items; cur; cur = g_list_next(cur)) {
- //vfolder_folder_item_update_msgs(VFOLDER_ITEM(cur->data), F_ITEM_UPDATE_ADDMSG);
- }
- g_list_free(items);
- }
}
- else if (hookdata->update_flags & F_ITEM_UPDATE_MSGCNT) {
- debug_print("F_ITEM_UPDATE_MSGCNT\n");
-/* if (IS_VFOLDER_FOLDER_ITEM(item)) {
-
- if (! (VFOLDER_ITEM(item))->deep_copy) {
- if (! (VFOLDER_ITEM(item))->active) {
- r = vfolder_hide_widgets(VFOLDER_ITEM(item));
- if (r)
- VFOLDER_ITEM(item)->active = TRUE;
- }
- else {
- r = vfolder_show_widgets(VFOLDER_ITEM(item));
- if (r)
- VFOLDER_ITEM(item)->active = FALSE;
- }
-
- if (r)
- save_state = 1;
- else
- save_state = 0;
- }
- else
- vfolder_show_widgets(VFOLDER_ITEM(item));
- }
- else {
- if (!vfolder_widgets_is_visible())
- vfolder_show_widgets(VFOLDER_ITEM(item));
- }*/
-/*
- items = vfolder_get_vfolder_from_source(hookdata->item);
- if (items) {
- for (cur = items; cur; cur = g_list_next(cur)) {
- vfolder_folder_item_update_msgs(VFOLDER_ITEM(cur->data), F_ITEM_UPDATE_MSGCNT);
- }
- g_list_free(items);
- }
-*/
+ if (hookdata->update_flags & F_ITEM_UPDATE_REMOVEMSG ) {
+ debug_print("F_ITEM_UPDATE_REMOVEMSG\n");
}
- else if (hookdata->update_flags & F_ITEM_UPDATE_NAME) {
+ if (hookdata->update_flags & F_ITEM_UPDATE_NAME) {
/* TODO: need update? */
debug_print("F_ITEM_UPDATE_NAME\n");
- //items = vfolder_get_vfolder_from_source(hookdata->item);
- if (items) {
- for (cur = items; cur; cur = g_list_next(cur)) {
- //vfolder_folder_item_update_msgs(VFOLDER_ITEM(cur->data), F_ITEM_UPDATE_NAME);
- }
- g_list_free(items);
- }
}
- else {
- /* Unhandled callback */
- debug_print("Unhandled FolderItem callback\n");
- }
-/*
- if (!save_state) {
- MainWindow* mainwindow = mainwindow_get_mainwindow();
- alertpanel_error(_("%s: Could not hide dangerous actions"), hookdata->item->name);
- summary_lock(mainwindow->summaryview);
- }
-*/
return FALSE;
}
-/*
+
static gboolean vfolder_msg_info_update_hook(gpointer source, gpointer data) {
MsgInfoUpdate* hookdata;
- MainWindow* mainwindow;
MsgInfo* msginfo;
+ VFolderItem* vitem;
+
+ cm_return_val_if_fail(source != NULL, FALSE);
- g_return_val_if_fail(source != NULL, FALSE);
hookdata = (MsgInfoUpdate *) source;
msginfo = hookdata->msginfo;
- g_return_val_if_fail(msginfo != NULL, TRUE);
+ cm_return_val_if_fail(msginfo != NULL, FALSE);
if (IS_VFOLDER_MSGINFO(msginfo))
return FALSE;
- debug_print("\n\nPermflag: %u Tmpflag: %u (scanned: %u)\n\n\n",
- (guint32) msginfo->flags.perm_flags, (guint32) msginfo->flags.tmp_flags, 1U << 31);
if (MSG_IS_NEW(msginfo->flags)) {
- debug_print("MSG_IS_NEW\n");
- vfolder_update_affected_folder_items(msginfo);
- mainwindow = mainwindow_get_mainwindow();
- summary_execute(mainwindow->summaryview);
+ vitem = vfolder_folder_item_watch(msginfo->folder);
+ if (vitem) {
+ debug_print("MSG_IS_NEW\n");
+ }
}
if (MSG_IS_DELETED(msginfo->flags)) {
- debug_print("MSG_IS_DELETED\n");
- vfolder_update_affected_folder_items(msginfo);
- mainwindow = mainwindow_get_mainwindow();
- summary_execute(mainwindow->summaryview);
+ vitem = vfolder_folder_item_watch(msginfo->folder);
+ if (vitem) {
+ debug_print("MSG_IS_DELETED\n");
+ folder_item_remove_msg(FOLDER_ITEM(vitem), msginfo->msgnum);
+ }
}
if (MSG_IS_MOVE(msginfo->flags)) {
+ debug_print("MSG_IS_MOVE to VFolder\n");
+ if (IS_VFOLDER_FOLDER_ITEM(msginfo->to_folder)) {
+ vitem = VFOLDER_ITEM(msginfo->to_folder);
+ gchar* msg = g_strconcat(vitem->source_id, ":\n",
+ _("Cannot move to VFolder"), NULL);
+ alertpanel_error(msg);
+ g_free(msg);
+ return FALSE;
+ }
+ vitem = vfolder_folder_item_watch(msginfo->to_folder);
+ if (! vitem) {
+ /*
+ * if folder we move to is already monitored we need not
+ * do anything since distination folder will be automatically
+ * scanned when F_ITEM_UPDATE_MSGCNT is invoked
+ */
+ folder_item_remove_msg(FOLDER_ITEM(vitem), msginfo->msgnum);
+ }
+ }
+
+ if (MSG_IS_MOVE_DONE(msginfo->flags)) {
+ vitem = vfolder_folder_item_watch(msginfo->to_folder);
+ if (vitem) {
+ return FALSE;
+ }
debug_print("MSG_IS_MOVE\n");
- vfolder_update_affected_folder_items(msginfo);
- mainwindow = mainwindow_get_mainwindow();
- summary_execute(mainwindow->summaryview);
}
if (MSG_IS_COPY(msginfo->flags)) {
debug_print("MSG_IS_COPY\n");
- vfolder_update_affected_folder_items(msginfo);
- mainwindow = mainwindow_get_mainwindow();
- summary_execute(mainwindow->summaryview);
+ if (IS_VFOLDER_FOLDER_ITEM(msginfo->to_folder)) {
+ vitem = VFOLDER_ITEM(msginfo->to_folder);
+ gchar* msg = g_strconcat(vitem->source_id, ":\n",
+ _("Cannot copy to VFolder"), NULL);
+ alertpanel_error(msg);
+ g_free(msg);
+ return FALSE;
+ }
}
-// if (MSG_IS_POSTFILTERED(msginfo->flags)) {
-// debug_print("MSG_IS_POSTFILTERED\n");
-// vfolder_update_affected_folder_items(msginfo);
-// mainwindow = mainwindow_get_mainwindow();
-// summary_execute(mainwindow->summaryview);
-// }
-
-
return FALSE;
}
-*/
+
static gchar* vfolder_get_rc_file(VFolderItem* item) {
gchar* (*item_get_path) (Folder* folder, FolderItem* item);
gchar* path;
@@ -675,56 +319,32 @@ static gchar* vfolder_get_rc_file(VFolderItem* item) {
return rc_file;
}
-FolderPropsResponse vfolder_folder_item_props_write(VFolderItem* item) {
+FolderPropsResponse vfolder_folder_item_props_write(VFolderItem* vitem) {
gchar* rc_file;
GKeyFile* config;
- gchar* id;
gchar* data = NULL;
FILE* fp;
gsize len = 0;
FolderPropsResponse resp = FOLDER_ITEM_PROPS_NO_ITEM;
-/* gchar* numstr;
- GHashTableIter iter;
- gpointer key, value;*/
- g_return_val_if_fail(item != NULL, resp);
+ g_return_val_if_fail(vitem != NULL, resp);
- rc_file = vfolder_get_rc_file(item);
- config = g_key_file_new();
+ if (! vitem->changed) return FOLDER_ITEM_PROPS_OK;
- if (item->filter)
- g_key_file_set_string(config, CONFIG_GROUP, "filter", item->filter);
+ debug_print("%s: Writing configuration\n", vitem->source_id);
- g_key_file_set_boolean(config, CONFIG_GROUP, "frozen", item->frozen);
+ rc_file = vfolder_get_rc_file(vitem);
+ config = g_key_file_new();
- if (item->source) {
- id = folder_item_get_identifier(item->source);
- if (id) {
- g_key_file_set_string(config, CONFIG_GROUP, "source", id);
- g_free(id);
- }
- }
+ if (vitem->filter)
+ g_key_file_set_string(config, CONFIG_GROUP, "filter", vitem->filter);
+ if (vitem->source_id)
+ g_key_file_set_string(config, CONFIG_GROUP, "source_id", vitem->source_id);
+ g_key_file_set_boolean(config, CONFIG_GROUP, "frozen", vitem->frozen);
+ g_key_file_set_integer(config, CONFIG_GROUP, "searchtype", vitem->search);
-/* if (item->claws_to_me && item->me_to_claws) {
- numstr = NULL;
- g_hash_table_iter_init(&iter, item->claws_to_me);
- while (g_hash_table_iter_next(&iter, &key, &value)) {
- len++;
- MsgBridge* bridge = value;
- if (numstr) {
- gchar* tmp = g_strdup(numstr);
- g_free(numstr);
- numstr = g_strdup_printf("%s, %u:%u",
- tmp, bridge->my_num, bridge->claws_num);
- g_free(tmp);
- }
- else
- numstr = g_strdup_printf("%u:%u", bridge->my_num, bridge->claws_num);
- }
-
- g_key_file_set_string(config, CONFIG_GROUP, "file_id_list", numstr);
- g_free(numstr);
- }*/
+ if (vitem->msgvault)
+ vfolder_msgvault_serialize(vitem, config);
if (g_file_test(rc_file, G_FILE_TEST_EXISTS)) {
gchar* bakpath = g_strconcat(rc_file, ".bak", NULL);
@@ -735,8 +355,6 @@ FolderPropsResponse vfolder_folder_item_props_write(VFolderItem* item) {
g_free(bakpath);
}
-// g_key_file_set_integer(config, CONFIG_GROUP, "filter-function", item->filter_func);
-
data = g_key_file_to_data(config, &len, NULL);
if (len < 1) {
g_warning("Could not get config data");
@@ -762,6 +380,7 @@ FolderPropsResponse vfolder_folder_item_props_write(VFolderItem* item) {
}
fwrite(data, len, 1, fp);
fclose(fp);
+ vitem->changed = FALSE;
resp = FOLDER_ITEM_PROPS_OK;
}
@@ -774,18 +393,17 @@ error:
return resp;
}
-FolderPropsResponse vfolder_folder_item_props_read(VFolderItem* item) {
+FolderPropsResponse vfolder_folder_item_props_read(VFolderItem* vitem) {
gchar* rc_file;
GKeyFile* config;
GError* error = NULL;
- gchar *id, *msgnums;
- gchar **list, **head;
FolderPropsResponse resp = FOLDER_ITEM_PROPS_NO_ITEM;
- gint lastnum;
- g_return_val_if_fail(item != NULL, resp);
+ g_return_val_if_fail(vitem != NULL, resp);
+
+ if (! vitem->changed) return FOLDER_ITEM_PROPS_OK;
- rc_file = vfolder_get_rc_file(item);
+ rc_file = vfolder_get_rc_file(vitem);
config = g_key_file_new();
if (g_file_test(rc_file, G_FILE_TEST_EXISTS)) {
@@ -796,39 +414,24 @@ FolderPropsResponse vfolder_folder_item_props_read(VFolderItem* item) {
resp = FOLDER_ITEM_PROPS_READ_USING_DEFAULT;
}
else {
- item->filter = g_key_file_get_string(config, CONFIG_GROUP, "filter", NULL);
-// item->search = g_key_file_get_integer(config, CONFIG_GROUP, "searchtype", NULL);
- item->frozen = g_key_file_get_boolean(config, CONFIG_GROUP, "frozen", NULL);
-// item->deep_copy = g_key_file_get_boolean(config, CONFIG_GROUP, "deep_copy", NULL);
-// item->filter_func = g_key_file_get_integer(config, CONFIG_GROUP, "filter_function", NULL);
-
- id = g_key_file_get_string(config, CONFIG_GROUP, "source", NULL);
- if (id) {
- item->source = folder_find_item_from_identifier(id);
- g_free(id);
- }
- msgnums = g_key_file_get_string(config, CONFIG_GROUP, "file_id_list", NULL);
- if (msgnums) {
- list = g_strsplit(msgnums, ",", 0);
- head = list;
- lastnum = -1;
- while (*list) {
- /*gchar* anum = g_strdup(*list++);
- g_strstrip(anum);
- MsgBridge* bridge = vfolder_split_file_id(anum);
- g_free(anum);
- if (lastnum < (gint) bridge->my_num)
- lastnum = bridge->my_num;
- if (bridge->my_num > 0) {
- vfolder_add_message_to_bridge(item, bridge);
- }
- g_free(bridge);*/
- }
- FOLDER_ITEM(item)->last_num = lastnum;
- g_strfreev(head);
- g_free(msgnums);
- }
+ vitem->filter = g_key_file_get_string(config, CONFIG_GROUP, "filter", NULL);
+ vitem->search = g_key_file_get_integer(config, CONFIG_GROUP, "searchtype", NULL);
+ vitem->frozen = g_key_file_get_boolean(config, CONFIG_GROUP, "frozen", NULL);
+ vitem->source_id = g_key_file_get_string(config, CONFIG_GROUP, "source_id", NULL);
+ if (vitem->source_id)
+ vitem->source = folder_find_item_from_identifier(vitem->source_id);
+ vfolder_msgvault_restore(vitem, config);
+
+ FolderItem* item = FOLDER_ITEM(vitem);
+ vfolder_set_last_num(item->folder, item);
+
+ vfolder_msgvault_add(vitem);
+
resp = FOLDER_ITEM_PROPS_OK;
+
+ vitem->changed = FALSE;
+
+ debug_print("%s: Read configuration\n", vitem->source_id);
}
}
@@ -857,21 +460,13 @@ gboolean vfolder_gtk_init(gchar** error) {
return FALSE;
}
-/* msginfo_hook_id = hooks_register_hook(MSGINFO_UPDATE_HOOKLIST,
+ msginfo_hook_id = hooks_register_hook(MSGINFO_UPDATE_HOOKLIST,
vfolder_msg_info_update_hook, NULL);
if (msginfo_hook_id == -1) {
*error = g_strdup(_("Failed to register message info update hook"));
hooks_unregister_hook(FOLDER_UPDATE_HOOKLIST, folder_hook_id);
hooks_unregister_hook(FOLDER_ITEM_UPDATE_HOOKLIST, item_hook_id);
return FALSE;
- }*/
-
- if (! get_menu_widgets()) {
- *error = g_strdup(_("Failed to get menu widgets"));
- hooks_unregister_hook(FOLDER_UPDATE_HOOKLIST, folder_hook_id);
- hooks_unregister_hook(FOLDER_ITEM_UPDATE_HOOKLIST, item_hook_id);
- hooks_unregister_hook(MSGINFO_UPDATE_HOOKLIST, msginfo_hook_id);
- return FALSE;
}
return TRUE;
@@ -879,27 +474,14 @@ gboolean vfolder_gtk_init(gchar** error) {
void vfolder_gtk_done(void) {
MainWindow *mainwin = mainwindow_get_mainwindow();
- FolderView *folderview = NULL;
- FolderItem *fitem = NULL;
hooks_unregister_hook(FOLDER_UPDATE_HOOKLIST, folder_hook_id);
hooks_unregister_hook(FOLDER_ITEM_UPDATE_HOOKLIST, item_hook_id);
- //hooks_unregister_hook(MSGINFO_UPDATE_HOOKLIST, msginfo_hook_id);
+ hooks_unregister_hook(MSGINFO_UPDATE_HOOKLIST, msginfo_hook_id);
if (mainwin == NULL || claws_is_exiting())
return;
- folderview = mainwin->folderview;
- fitem = folderview->summaryview->folder_item;
-
- if (fitem && IS_VFOLDER_FOLDER_ITEM(fitem)) {
- vfolder_show_widgets(VFOLDER_ITEM(fitem));
- gslist_menu_item_free(&widgets);
-
- folderview_unselect(folderview);
- summary_clear_all(folderview->summaryview);
- }
-
folderview_unregister_popup(&vfolder_popup);
}
@@ -915,7 +497,7 @@ void vfolder_properties_cb(GtkAction* action, gpointer data) {
g_return_if_fail(item->path != NULL);
g_return_if_fail(item->folder != NULL);
- if (vfolder_edit_item_dialog(VFOLDER_ITEM(item))) {
+ if (vfolder_edit_item_dialog(VFOLDER_ITEM(item), NULL)) {
/* TODO: update */
if (debug_get_mode()) {
// GHashTableIter iter;
@@ -938,31 +520,21 @@ void vfolder_properties_cb(GtkAction* action, gpointer data) {
fclose(msg);
}*/
}
- vfolder_folder_item_props_write(VFOLDER_ITEM(item));
}
}
void vfolder_new_folder_cb(GtkAction* action, gpointer data) {
FolderView *folderview = (FolderView *)data;
- GtkCMCTree *ctree = NULL;
- FolderItem *item;
- FolderItem *new_item;
- gchar *new_folder;
- gchar *name;
- gchar *p;
-
- if (!folderview->selected) return;
- if (!GTK_IS_CMCTREE(folderview->ctree)) return;
-
- ctree = GTK_CMCTREE(folderview->ctree);
- item = gtk_cmctree_node_get_row_data(ctree, folderview->selected);
- //item = folderview_get_selected_item(folderview);
- if (! item) {
- //item = FOLDER_ITEM(vfolder_get_vfolder_item(NULL));
- }
+ FolderItem *item, *new_item, *parent;
+ gchar* new_folder;
+ gchar* name;
+ gchar* p;
+ gchar* id;
- cm_return_if_fail(item != NULL);
- cm_return_if_fail(item->folder != NULL);
+ item = folderview_get_selected_item(folderview);
+ cm_return_if_fail(item != NULL);
+ cm_return_if_fail(item->path != NULL);
+ cm_return_if_fail(item->folder != NULL);
if (item->no_sub) {
alertpanel_error(N_("Virtual folders cannot contain subfolders"));
@@ -985,49 +557,76 @@ void vfolder_new_folder_cb(GtkAction* action, gpointer data) {
name = trim_string(new_folder, 32);
AUTORELEASE_STR(name, {g_free(name); return;});
+ Folder* folder = folder_find_from_name(VFOLDER_DEFAULT_MAILBOX, vfolder_folder_get_class());
+ parent = FOLDER_ITEM(folder->node->data);
/* find whether the directory already exists */
- if (folder_find_child_item_by_name(item, new_folder)) {
+ if (folder_find_child_item_by_name(parent, new_folder)) {
alertpanel_error(_("The folder '%s' already exists."), name);
return;
}
- new_item = folder_create_folder(item, new_folder);
+ new_item = folder_create_folder(parent, new_folder);
if (!new_item) {
alertpanel_error(_("Can't create the folder '%s'."), name);
return;
}
- if (! vfolder_create_item_dialog(new_item)) {
- //VFolderItem* vitem = VFOLDER_ITEM(new_item);
+ if (! vfolder_create_item_dialog(VFOLDER_ITEM(new_item), item)) {
+ new_item->folder->klass->remove_folder(new_item->folder, new_item);
+ new_item = NULL;
+ return;
+ }
+
+ id = folder_item_get_identifier(item);
+ if (vfolder_msgvault_add(VFOLDER_ITEM(new_item))) {
new_item->folder->klass->remove_folder(new_item->folder, new_item);
new_item = NULL;
+ g_free(id);
return;
}
+ g_free(id);
+
folder_write_list();
}
+void vfolder_refresh_cb(GtkAction* action, gpointer data) {
+ FolderView *folderview = (FolderView *)data;
+ FolderItem *item;
+
+ g_return_if_fail(folderview != NULL);
+
+ item = folderview_get_selected_item(folderview);
+
+ g_return_if_fail(item != NULL);
+ g_return_if_fail(item->path != NULL);
+ g_return_if_fail(item->folder != NULL);
+
+ vfolder_scan_source_folder(VFOLDER_ITEM(item));
+}
+
+void vfolder_refresh_all_cb(GtkAction* action, gpointer data) {
+ vfolder_scan_source_folder_all();
+}
+
void vfolder_remove_folder_cb(GtkAction* action, gpointer data) {
FolderView *folderview = (FolderView *)data;
- GtkCMCTree *ctree = GTK_CMCTREE(folderview->ctree);
+ GtkCMCTree *ctree;
FolderItem *item;
gchar *message, *name;
AlertValue avalue;
- gchar *old_path = NULL;
- gchar *old_id;
-
- /* Silence lame warnings */
- old_id = (old_path) ? NULL : old_path;
item = folderview_get_selected_item(folderview);
g_return_if_fail(item != NULL);
g_return_if_fail(item->path != NULL);
g_return_if_fail(item->folder != NULL);
+ ctree = GTK_CMCTREE(folderview->ctree);
+
name = trim_string(item->name, 32);
AUTORELEASE_STR(name, {g_free(name); return;});
message = g_strdup_printf
- (_("All folders and messages under '%s' will be permanently deleted. "
+ (_("All messages under '%s' will be permanently deleted. "
"Recovery will not be possible.\n\n"
"Do you really want to delete?"), name);
avalue = alertpanel_full(_("Delete folder"), message,
@@ -1036,9 +635,6 @@ void vfolder_remove_folder_cb(GtkAction* action, gpointer data) {
g_free(message);
if (avalue != G_ALERTALTERNATE) return;
- Xstrdup_a(old_path, item->path, return);
- old_id = folder_item_get_identifier(item);
-
if (folderview->opened == folderview->selected ||
gtk_cmctree_is_ancestor(ctree,
folderview->selected,
@@ -1050,11 +646,24 @@ void vfolder_remove_folder_cb(GtkAction* action, gpointer data) {
if (item->folder->klass->remove_folder(item->folder, item) < 0) {
folder_item_scan(item);
alertpanel_error(_("Can't remove the folder '%s'."), name);
- g_free(old_id);
return;
}
folder_write_list();
+}
+
+GtkResponseType vfolder_msg_dialog(GtkMessageType msgtype, GtkButtonsType btntype,
+ const gchar* message) {
+ GtkResponseType ret;
+ GtkWidget* dialog;
+
+ MainWindow* mainwin = mainwindow_get_mainwindow();
+ dialog = gtk_message_dialog_new (GTK_WINDOW(mainwin->window),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ msgtype, btntype, message);
+
+ ret = gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
- g_free(old_id);
+ return ret;
}
diff --git a/src/plugins/vfolder/vfolder_gtk.h b/src/plugins/vfolder/vfolder_gtk.h
index 5b41ee4..270f337 100644
--- a/src/plugins/vfolder/vfolder_gtk.h
+++ b/src/plugins/vfolder/vfolder_gtk.h
@@ -33,24 +33,19 @@ G_BEGIN_DECLS
#include "vfolder.h"
#include <gtk/gtk.h>
-typedef enum {
- FOLDER_ITEM_PROPS_OK,
- FOLDER_ITEM_PROPS_NO_ITEM,
- FOLDER_ITEM_PROPS_BACKUP_FAIL,
- FOLDER_ITEM_PROPS_READ_DATA_FAIL,
- FOLDER_ITEM_PROPS_MAKE_RC_DIR_FAIL,
- FOLDER_ITEM_PROPS_READ_USING_DEFAULT
-} FolderPropsResponse;
-
gboolean vfolder_gtk_init(gchar** error);
void vfolder_gtk_done(void);
FolderPropsResponse vfolder_folder_item_props_read(VFolderItem* item);
FolderPropsResponse vfolder_folder_item_props_write(VFolderItem* item);
+GtkResponseType vfolder_msg_dialog(GtkMessageType msgtype, GtkButtonsType btntype,
+ const gchar* message);
/* Callback functions */
void vfolder_new_folder_cb(GtkAction* action, gpointer data);
void vfolder_remove_folder_cb(GtkAction* action, gpointer data);
void vfolder_properties_cb(GtkAction* action, gpointer data);
+void vfolder_refresh_cb(GtkAction* action, gpointer data);
+void vfolder_refresh_all_cb(GtkAction* action, gpointer data);
G_END_DECLS
diff --git a/src/plugins/vfolder/vfolder_init.c b/src/plugins/vfolder/vfolder_init.c
index b000514..568f468 100644
--- a/src/plugins/vfolder/vfolder_init.c
+++ b/src/plugins/vfolder/vfolder_init.c
@@ -55,23 +55,14 @@ static GtkActionEntry vfolder_main_menu[] = {{
static gint main_menu_id = 0;
gint plugin_init(gchar** error) {
- debug_set_mode(TRUE);
MainWindow *mainwin = mainwindow_get_mainwindow();
-/*
-#ifdef G_OS_UNIX
- bindtextdomain(TEXTDOMAIN, LOCALEDIR);
-#else
- bindtextdomain(TEXTDOMAIN, get_locale_dir());
-#endif
- bind_textdomain_codeset(TEXTDOMAIN, "UTF-8");
-*/
if (!check_plugin_version(MAKE_NUMERIC_VERSION(0,0,1,0),
VERSION_NUMERIC, PLUGIN_NAME, error))
return -1;
gtk_action_group_add_actions(mainwin->action_group, vfolder_main_menu,
- 1, (gpointer)mainwin);
+ 1, (gpointer)mainwin->folderview);
MENUITEM_ADDUI_ID_MANAGER(mainwin->ui_manager, "/Menu/View", "CreateVfolder",
"View/CreateVfolder", GTK_UI_MANAGER_MENUITEM,
main_menu_id)
@@ -92,15 +83,13 @@ gboolean plugin_done(void) {
vfolder_done();
- if (mainwin == NULL)
- return FALSE;
-
- MENUITEM_REMUI_MANAGER(mainwin->ui_manager,mainwin->action_group, "View/CreateVfolder", main_menu_id);
- main_menu_id = 0;
+ if (mainwin) {
+ MENUITEM_REMUI_MANAGER(mainwin->ui_manager,mainwin->action_group, "View/CreateVfolder", main_menu_id);
+ main_menu_id = 0;
+ }
debug_print("vfolder plugin unloaded\n");
- debug_set_mode(FALSE);
return TRUE;
}
diff --git a/src/plugins/vfolder/vfolder_prop.c b/src/plugins/vfolder/vfolder_prop.c
index c7187aa..e7485f2 100644
--- a/src/plugins/vfolder/vfolder_prop.c
+++ b/src/plugins/vfolder/vfolder_prop.c
@@ -52,7 +52,6 @@
typedef struct {
GtkWidget* filter;
GtkWidget* frozen;
- GtkWidget* deep_copy;
GtkWidget* source;
GtkWidget* label_btn;
GtkWidget* message_btn;
@@ -70,7 +69,6 @@ static void add_current_config(VFolderItem* item, PropsDialog* props) {
}
}
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(props->frozen), item->frozen);
-/* gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(props->deep_copy), item->deep_copy);
switch (item->search) {
case SEARCH_BODY:
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(props->message_btn), TRUE);
@@ -78,7 +76,7 @@ static void add_current_config(VFolderItem* item, PropsDialog* props) {
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(props->both_btn), TRUE);
case SEARCH_HEADERS:
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(props->label_btn), TRUE);
- }*/
+ }
}
static gboolean is_source_widget(GtkWidget* widget) {
@@ -144,7 +142,7 @@ static gboolean vfolder_set_search_type(VFolderItem* item, GtkWidget* list) {
if (active) {
const gchar* label = gtk_button_get_label(GTK_BUTTON(btn));
if (label) {
-/* if (strcmp(BOTH, label) == 0) {
+ if (strcmp(BOTH, label) == 0) {
if (item->search != SEARCH_BOTH) {
item->search = SEARCH_BOTH;
return TRUE;
@@ -161,24 +159,12 @@ static gboolean vfolder_set_search_type(VFolderItem* item, GtkWidget* list) {
item->search = SEARCH_HEADERS;
return TRUE;
}
- }*/
+ }
}
}
return FALSE;
}
-/*
-static void vfolder_copy_msginfo_list(gpointer data, gpointer user_data) {
- MsgInfo* msg = (MsgInfo *) data;
- MsgInfo* new_msg;
- VFolderItem* item = (VFolderItem *) user_data;
-
- g_return_if_fail(msg != NULL);
- g_return_if_fail(item != NULL);
-
- new_msg = procmsg_msginfo_copy(msg);
- item->msginfos = g_slist_prepend(item->msginfos, new_msg);
-}
static gboolean vfolder_search_headers(MsgInfo* msg, GPatternSpec* pattern) {
return ((msg->cc && g_pattern_match_string(pattern, msg->cc)) ||
@@ -201,7 +187,7 @@ static gboolean vfolder_search_body(MsgInfo* msg, GPatternSpec* pattern) {
return found;
}
-*/
+
static MsgInfoList* vfolder_filter_msgs_list(MsgInfoList* msgs, VFolderItem* item) {
MsgInfoList *list = NULL, *tmp;
GPatternSpec* pattern;
@@ -214,7 +200,7 @@ static MsgInfoList* vfolder_filter_msgs_list(MsgInfoList* msgs, VFolderItem* ite
for (tmp = msgs; tmp; tmp = g_slist_next(tmp)) {
msg = (MsgInfo *) tmp->data;
-/* switch (item->search) {
+ switch (item->search) {
case SEARCH_HEADERS:
if (vfolder_search_headers(msg, pattern))
list = g_slist_prepend(list, msg);
@@ -231,21 +217,23 @@ static MsgInfoList* vfolder_filter_msgs_list(MsgInfoList* msgs, VFolderItem* ite
if (vfolder_search_body(msg, pattern))
list = g_slist_prepend(list, msg);
break;
- }*/
+ }
}
+ if (list)
+ list = g_slist_reverse(list);
+
g_pattern_spec_free(pattern);
return list;
}
-static gboolean vfolder_create_msgs_list(VFolderItem* item, gboolean copy) {
+static gboolean vfolder_create_msgs_list(VFolderItem* item) {
MsgInfoList *msgs = NULL, *filtered = NULL;
gboolean ok = FALSE;
GSList* filelist = NULL;
if (item->filter && item->msg_filter_func) {
-// item->deep_copy = copy;
ok = TRUE;
msgs = folder_item_get_msg_list(item->source);
filtered = item->msg_filter_func(msgs, item);
@@ -258,7 +246,7 @@ static gboolean vfolder_create_msgs_list(VFolderItem* item, gboolean copy) {
}
g_slist_free(filtered);
}
- g_slist_free(msgs);
+ procmsg_msg_list_free(msgs);
}
return ok;
}
@@ -269,28 +257,21 @@ void vfolder_set_msgs_filter(VFolderItem* vfolder_item) {
vfolder_item->msg_filter_func = vfolder_filter_msgs_list;
}
-gboolean vfolder_create_item_dialog(FolderItem* folder_item) {
+gboolean vfolder_create_item_dialog(VFolderItem* vitem, FolderItem* item) {
gboolean created = FALSE;
- VFolderItem* item = NULL;
- g_return_val_if_fail(folder_item != NULL, created);
- g_return_val_if_fail(IS_VFOLDER_FOLDER_ITEM(folder_item), created);
+ g_return_val_if_fail(vitem != NULL, created);
+ g_return_val_if_fail(item != NULL, created);
- item = VFOLDER_ITEM(folder_item);
- item->msg_filter_func = vfolder_filter_msgs_list;
+ vitem->msg_filter_func = vfolder_filter_msgs_list;
- if (vfolder_edit_item_dialog(item)) {
- /* save properties */
- if (FOLDER_ITEM_PROPS_OK != vfolder_folder_item_props_write(item))
- created = FALSE;
- else
- created = TRUE;
- }
+ if (vfolder_edit_item_dialog(vitem, item))
+ created = TRUE;
return created;
}
-gboolean vfolder_edit_item_dialog(VFolderItem* vfolder_item) {
+gboolean vfolder_edit_item_dialog(VFolderItem* vitem, FolderItem* item) {
gboolean ok = FALSE;
PropsDialog* props_dialog;
GtkWidget* dialog;
@@ -298,19 +279,19 @@ gboolean vfolder_edit_item_dialog(VFolderItem* vfolder_item) {
GtkWidget* row;
GtkWidget* box;
gint response;
- gchar* name;
+ gchar *name, *id;
const gchar* str;
- gboolean frozen, deep_copy;
- FolderItem* source;
+ gboolean frozen;
gchar* old_filter = NULL;
+ FolderItem* old_source;
- g_return_val_if_fail(vfolder_item != NULL, ok);
+ g_return_val_if_fail(vitem != NULL, ok);
+ g_return_val_if_fail(item != NULL || vitem->source != NULL, ok);
MainWindow *mainwin = mainwindow_get_mainwindow();
props_dialog = g_new0(PropsDialog, 1);
props_dialog->filter = gtk_entry_new();
props_dialog->frozen = gtk_check_button_new();
- props_dialog->deep_copy = gtk_check_button_new();
props_dialog->source = gtk_entry_new();
props_dialog->label_btn =
gtk_radio_button_new_with_mnemonic(NULL, HEADERS);
@@ -321,7 +302,7 @@ gboolean vfolder_edit_item_dialog(VFolderItem* vfolder_item) {
gtk_radio_button_new_with_mnemonic_from_widget(
GTK_RADIO_BUTTON(props_dialog->label_btn), BOTH);
gtk_widget_set_name(props_dialog->source, "source");
- add_current_config(vfolder_item, props_dialog);
+ add_current_config(vitem, props_dialog);
dialog = gtk_dialog_new_with_buttons(
N_("Edit VFolder Properties"),
@@ -335,9 +316,17 @@ gboolean vfolder_edit_item_dialog(VFolderItem* vfolder_item) {
GtkWidget* vbox = gtk_vbox_new(FALSE, 5);
- row = vfolder_prop_row(props_dialog->source, N_("_Source folder"), 110, FALSE);
+ row = vfolder_prop_row(props_dialog->source, N_("_Source folder"), 130, FALSE);
gtk_box_pack_start(GTK_BOX(vbox), row, FALSE, FALSE, 5);
+ if (!item)
+ id = folder_item_get_identifier(vitem->source);
+ else
+ id = folder_item_get_identifier(item);
+ gtk_entry_set_text(GTK_ENTRY(props_dialog->source), id);
+ gtk_widget_set_sensitive(props_dialog->source, FALSE);
+ g_free(id);
+
GtkWidget* frame1 = gtk_frame_new(_("Message filter"));
GtkWidget* vbox1 = gtk_vbox_new(TRUE, 2);
gtk_container_add(GTK_CONTAINER(frame1), vbox1);
@@ -356,95 +345,96 @@ gboolean vfolder_edit_item_dialog(VFolderItem* vfolder_item) {
row = vfolder_prop_row(props_dialog->frozen, N_("F_reeze content"), 110, TRUE);
gtk_box_pack_start(GTK_BOX(vbox), row, FALSE, FALSE, 5);
- row = vfolder_prop_row(props_dialog->deep_copy, N_("Co_py messages"), 110, TRUE);
- gtk_box_pack_start(GTK_BOX(vbox), row, FALSE, FALSE, 5);
-
- name = g_strconcat(FOLDER_ITEM(vfolder_item)->name, N_(": settings"), NULL);
+ name = g_strconcat(FOLDER_ITEM(vitem)->name, N_(": settings"), NULL);
GtkWidget* frame = gtk_frame_new(name);
g_free(name);
gtk_container_add(GTK_CONTAINER(frame), vbox);
- gtk_widget_show_all(frame);
gtk_container_add(GTK_CONTAINER(content), frame);
+ gtk_widget_show_all(content);
response = gtk_dialog_run(GTK_DIALOG(dialog));
if (response == GTK_RESPONSE_ACCEPT) {
frozen = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(props_dialog->frozen));
- deep_copy = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(props_dialog->deep_copy));
str = gtk_entry_get_text(GTK_ENTRY(props_dialog->filter));
if (str) {
- old_filter = g_strdup(vfolder_item->filter);
+ old_filter = g_strdup(vitem->filter);
if (strlen(str) == 0) {
- if (vfolder_item->filter) {
- g_free(vfolder_item->filter);
- vfolder_item->filter = NULL;
+ if (vitem->filter) {
+ g_free(vitem->filter);
+ vitem->filter = NULL;
ok = TRUE;
}
}
else {
- if (!vfolder_item->filter || strcmp(vfolder_item->filter, str) != 0) {
- g_free(vfolder_item->filter);
- vfolder_item->filter = g_strdup(str);
+ if (!vitem->filter || strcmp(vitem->filter, str) != 0) {
+ g_free(vitem->filter);
+ vitem->filter = g_strdup(str);
ok = TRUE;
}
}
}
- if (vfolder_set_search_type(vfolder_item, props_dialog->label_btn))
+ if (vfolder_set_search_type(vitem, props_dialog->label_btn))
ok = TRUE;
str = gtk_entry_get_text(GTK_ENTRY(props_dialog->source));
if (str) {
- source = folder_find_item_from_identifier(str);
- if (source && (source->stype != F_NORMAL && source->stype != F_INBOX)) {
- alertpanel_error(_("%s: Not suitable for virtual folders\n"
- "Use only folder type: Normal or Inbox\n"), str);
- g_free(vfolder_item->filter);
- vfolder_item->filter = g_strdup(old_filter);
- ok = FALSE;
- goto error;
+ if (item) {
+ vitem->source = item;
+ } else {
+ /* remove msgvault */
+ vfolder_msgvault_free(vitem->msgvault);
+ vitem->msgvault = vfolder_msgvault_new();
}
if (strlen(str) == 0) {
- if (vfolder_item->source) {
- vfolder_item->source = NULL;
- folder_item_remove_all_msg(FOLDER_ITEM(vfolder_item));
+ if (vitem->source) {
+ vitem->source = NULL;
+ folder_item_remove_all_msg(FOLDER_ITEM(vitem));
ok = TRUE;
}
- }
- else {
- folder_item_remove_all_msg(FOLDER_ITEM(vfolder_item));
- gchar* id = (vfolder_item->source) ?
- folder_item_get_identifier(vfolder_item->source) : NULL;
- if (!id || strcmp(id, str) != 0)
- vfolder_item->source = source;
- if (vfolder_item->source) {
- ok = vfolder_create_msgs_list(vfolder_item, deep_copy);
- if (ok == FALSE) {
- g_free(vfolder_item->filter);
- vfolder_item->filter = g_strdup(old_filter);
- goto error;
- }
+ } else {
+ old_source = NULL;
+ id = (vitem->source) ? folder_item_get_identifier(vitem->source) : NULL;
+ if (!id || strcmp(id, str) != 0) {
+ old_source = vitem->source;
+ vitem->source = folder_get_item_from_identifier(str);
}
- else {
- g_free(vfolder_item->filter);
- vfolder_item->filter = g_strdup(old_filter);
+ g_free(id);
+ if (vitem->source && (vitem->source->stype != F_NORMAL && vitem->source->stype != F_INBOX)) {
+ alertpanel_error(_("%s: Not suitable for virtual folders\n"
+ "Use only folder type: Normal or Inbox\n"), str);
+ g_free(vitem->filter);
+ vitem->filter = g_strdup(old_filter);
+ if (old_source)
+ vitem->source = old_source;
ok = FALSE;
goto error;
}
+ if (vitem->source_id)
+ g_free(vitem->source_id);
+ vitem->source_id = folder_item_get_identifier(vitem->source);
+ if (FOLDER_ITEM(vitem)->total_msgs > 0)
+ folder_item_remove_all_msg(FOLDER_ITEM(vitem));
+ ok = vfolder_create_msgs_list(vitem);
+ if (ok == FALSE) {
+ g_free(vitem->filter);
+ vitem->filter = g_strdup(old_filter);
+ goto error;
+ }
+ vitem->changed = TRUE;
}
+ } else {
+ ok = FALSE;
+ goto error;
}
- if (vfolder_item->frozen != frozen) {
- vfolder_item->frozen = frozen;
+ if (vitem->frozen != frozen) {
+ vitem->frozen = frozen;
ok = TRUE;
}
-/* if (vfolder_item->deep_copy != deep_copy) {
- vfolder_item->deep_copy = deep_copy;
- ok = TRUE;
- }*/
-
}
error:
@@ -454,3 +444,35 @@ error:
return ok;
}
+
+void vfolder_item_props_response(FolderPropsResponse resp) {
+ GtkResponseType ret;
+
+ switch (resp) {
+ case FOLDER_ITEM_PROPS_OK: break;
+ case FOLDER_ITEM_PROPS_BACKUP_FAIL:
+ vfolder_msg_dialog(GTK_MESSAGE_WARNING, GTK_BUTTONS_OK,
+ "Making backup of config failed");
+ break;
+ case FOLDER_ITEM_PROPS_READ_USING_DEFAULT:
+ vfolder_msg_dialog(GTK_MESSAGE_WARNING, GTK_BUTTONS_OK,
+ "Missing config file. Using defaults");
+ break;
+ case FOLDER_ITEM_PROPS_NO_ITEM:
+ ret = vfolder_msg_dialog(GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
+ "Writing config failed\nContinue?");
+ if (ret != GTK_RESPONSE_YES)
+ vfolder_done();
+ break;
+ case FOLDER_ITEM_PROPS_READ_DATA_FAIL:
+ vfolder_msg_dialog(GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
+ "Reading config failed. Unloading plugin");
+ vfolder_done();
+ break;
+ case FOLDER_ITEM_PROPS_MAKE_RC_DIR_FAIL:
+ vfolder_msg_dialog(GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
+ "Creating top folder failed. Unloading plugin");
+ vfolder_done();
+ break;
+ }
+}
diff --git a/src/plugins/vfolder/vfolder_prop.h b/src/plugins/vfolder/vfolder_prop.h
index 04fb493..4a3e11f 100644
--- a/src/plugins/vfolder/vfolder_prop.h
+++ b/src/plugins/vfolder/vfolder_prop.h
@@ -34,9 +34,10 @@ G_BEGIN_DECLS
#include "vfolder.h"
#include <gtk/gtk.h>
-gboolean vfolder_create_item_dialog(FolderItem* folder_item);
-gboolean vfolder_edit_item_dialog(VFolderItem* vfolder_item);
+gboolean vfolder_create_item_dialog(VFolderItem* vitem, FolderItem* item);
+gboolean vfolder_edit_item_dialog(VFolderItem* vitem, FolderItem* item);
void vfolder_set_msgs_filter(VFolderItem* vfolder_item);
+void vfolder_item_props_response(FolderPropsResponse resp);
G_END_DECLS
commit e0b729908766b15202d118b6eb95cf12f050e83a
Merge: 628da7d 8e65767
Author: Michael Rasmussen <mir at datanom.net>
Date: Wed Jun 18 23:43:01 2014 +0200
Merge branch 'master' of ssh+git://git.claws-mail.org/home/git/claws into vfolder
diff --cc configure.ac
index f6c2c5d,1cc5e25..d67ad8f
--- a/configure.ac
+++ b/configure.ac
@@@ -1060,10 -1069,9 +1073,10 @@@ dnl PGP/Mime: pgpcore libgpgm
dnl PGP/Inline: pgpcore libgpgme
dnl S/Mime: pgpcore libgpgme
dnl Python: Python
- dnl RSSyl: libxml2 libcurl
+ dnl RSSyl: expat libcurl
dnl SpamReport: libcurl
dnl vCalendar: libcurl
+dnl VFolder: none
dnl libcurl ********************************************************************
PKG_CHECK_MODULES(CURL, libcurl, HAVE_CURL=yes, HAVE_CURL=no)
commit 628da7de6c4542e64357fc281555f6ac81547430
Merge: 8da1959 c981e7a
Author: Michael Rasmussen <mir at datanom.net>
Date: Sun Jun 15 17:51:35 2014 +0200
Merge branch 'master' of ssh+git://git.claws-mail.org/home/git/claws into vfolder
commit 8da1959fb498002c2de9b0b37ca5d1d68777ada8
Merge: d863d99 eaf1e7a
Author: Michael Rasmussen <mir at datanom.net>
Date: Sat Jun 14 17:53:39 2014 +0200
Merge branch 'master' of ssh+git://git.claws-mail.org/home/git/claws into vfolder
commit d863d9937e2718b51f6d7cac54fc9da01e5fe0d6
Merge: c4ae33d 89b7b7a
Author: Michael Rasmussen <mir at datanom.net>
Date: Thu Jun 12 02:16:58 2014 +0200
Merge branch 'master' of ssh+git://git.claws-mail.org/home/git/claws into vfolder
commit c4ae33dd424ccaf4f23702fe75131902f3b2a5c7
Merge: 113f951 06ce560
Author: Michael Rasmussen <mir at datanom.net>
Date: Tue Jun 10 17:17:26 2014 +0200
Merge branch 'master' of ssh+git://git.claws-mail.org/home/git/claws into vfolder
commit 113f951660dcf06b86ef75a840e4f49508277b39
Author: Michael Rasmussen <mir at datanom.net>
Date: Sun Jun 8 18:53:52 2014 +0200
Initial commit of vfolder
diff --git a/src/plugins/vfolder/Makefile.am b/src/plugins/vfolder/Makefile.am
new file mode 100644
index 0000000..0d79537
--- /dev/null
+++ b/src/plugins/vfolder/Makefile.am
@@ -0,0 +1,37 @@
+# Makefile.am for "src/plugins/vfolder" directory
+# This file is part of Claws Mail package.
+# See COPYING file for license details.
+
+plugindir = $(pkglibdir)/plugins
+
+if BUILD_VFOLDER_PLUGIN
+plugin_LTLIBRARIES = vfolder.la
+endif
+
+vfolder_la_SOURCES = \
+ vfolder.c \
+ vfolder_init.c \
+ vfolder_gtk.c \
+ vfolder_prop.c
+
+nodist_include_HEADERS = \
+ vfolder_gtk.h \
+ vfolder_prop.h
+
+vfolderincludedir = $(pkgincludedir)/plugins/@PACKAGE@
+vfolderinclude_HEADERS = \
+ vfolder.h
+
+vfolder_la_LDFLAGS = \
+ -avoid-version -module \
+ $(GTK_LIBS)
+
+vfolder_la_LIBADD =
+
+vfolder_la_CPPFLAGS = \
+ -I$(top_srcdir)/src \
+ -I$(top_srcdir)/src/common \
+ -I$(top_builddir)/src/common \
+ -I$(top_srcdir)/src/gtk \
+ $(GLIB_CFLAGS) \
+ $(GTK_CFLAGS)
diff --git a/src/plugins/vfolder/vfolder.c b/src/plugins/vfolder/vfolder.c
new file mode 100644
index 0000000..330252c
--- /dev/null
+++ b/src/plugins/vfolder/vfolder.c
@@ -0,0 +1,270 @@
+/*
+ * $Id: $
+ */
+/* vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: */
+
+/*
+ * Virtual folder plugin for claws-mail
+ *
+ * Claws Mail is Copyright (C) 1999-2012 by the Claws Mail Team
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#include "claws-features.h"
+#endif
+
+#include <glib.h>
+#include <glib/gi18n.h>
+
+#include "common/claws.h"
+#include "common/version.h"
+#include "plugin.h"
+#include "defs.h"
+
+#include "procmsg.h"
+#include "procheader.h"
+#include "folder.h"
+#include "alertpanel.h"
+#include "main.h"
+#include "localfolder.h"
+#include "statusbar.h"
+
+#include "vfolder.h"
+#include "vfolder_gtk.h"
+#include "vfolder_prop.h"
+
+typedef struct {
+ LocalFolder folder;
+} VFolder;
+
+FolderClass vfolder_class;
+GHashTable* vfolders;
+static gboolean existing_tree_found = FALSE;
+
+static void free_vfolder_hashtable(gpointer data) {
+ g_return_if_fail(data!= NULL);
+
+ GHashTable* vfolder = (GHashTable *) data;
+ g_hash_table_destroy(vfolder);
+}
+
+static GHashTable* vfolders_hashtable_new() {
+ return g_hash_table_new_full(g_str_hash,
+ g_str_equal, g_free, free_vfolder_hashtable);
+}
+
+static GHashTable* vfolder_hashtable_new() {
+ return g_hash_table_new_full(g_str_hash,
+ g_str_equal, g_free, (GDestroyNotify) procmsg_msginfo_free);
+}
+
+static void vfolder_init_read_func(FolderItem* item, gpointer data) {
+ g_return_if_fail(item != NULL);
+
+ if (! IS_VFOLDER_FOLDER_ITEM(item))
+ return;
+
+ existing_tree_found = TRUE;
+
+ if (folder_item_parent(item) == NULL)
+ return;
+
+ vfolder_folder_item_props_read(VFOLDER_ITEM(item));
+ vfolder_set_msgs_filter(VFOLDER_ITEM(item));
+
+/* if (! IS_VFOLDER_FROZEN(VFOLDER_ITEM(item))) {
+ folder_item_scan(VFOLDER_ITEM(item)->source);
+ }*/
+}
+
+static void vfolder_make_rc_dir(void) {
+ gchar* vfolder_dir = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, VFOLDER_DIR, NULL);
+
+ if (! is_dir_exist(vfolder_dir)) {
+ if (make_dir(vfolder_dir) < 0) {
+ g_warning("couldn't create directory %s\n", vfolder_dir);
+ }
+
+ debug_print("created directorty %s\n", vfolder_dir);
+ }
+
+ g_free(vfolder_dir);
+}
+
+static void vfolder_create_default_mailbox(void) {
+ Folder* root = NULL;
+
+ vfolder_make_rc_dir();
+
+ root = folder_new(vfolder_folder_get_class(), VFOLDER_DEFAULT_MAILBOX, NULL);
+
+ g_return_if_fail(root != NULL);
+
+ folder_add(root);
+}
+
+static Folder* vfolder_new_folder(const gchar* name, const gchar* path) {
+ VFolder* folder;
+
+ debug_print("VFolder: new_folder\n");
+
+ vfolder_make_rc_dir();
+
+ folder = g_new0(VFolder, 1);
+ FOLDER(folder)->klass = &vfolder_class;
+ folder_init(FOLDER(folder), name);
+
+ return FOLDER(folder);
+}
+
+static void vfolder_destroy_folder(Folder* _folder)
+{
+ VFolder* folder = VFOLDER(_folder);
+
+ folder_local_folder_destroy(LOCAL_FOLDER(folder));
+}
+
+static gint vfolder_create_tree(Folder* folder) {
+ FolderItem* rootitem;
+ GNode* rootnode;
+
+ vfolder_make_rc_dir();
+
+ if (!folder->node) {
+ rootitem = folder_item_new(folder, folder->name, NULL);
+ rootitem->folder = folder;
+ rootnode = g_node_new(rootitem);
+ folder->node = rootnode;
+ rootitem->node = rootnode;
+ } else {
+ rootitem = FOLDER_ITEM(folder->node->data);
+ rootnode = folder->node;
+ }
+
+ debug_print("VFolder: created new vfolder tree\n");
+ return 0;
+}
+
+static gint vfolder_scan_tree(Folder *folder) {
+ g_return_val_if_fail(folder != NULL, -1);
+
+ folder->outbox = NULL;
+ folder->draft = NULL;
+ folder->queue = NULL;
+ folder->trash = NULL;
+
+ debug_print("VFolder: scanning tree\n");
+ vfolder_create_tree(folder);
+
+ return 0;
+}
+
+FolderClass* vfolder_folder_get_class() {
+ if (vfolder_class.idstr == NULL ) {
+ vfolder_class.type = F_UNKNOWN;
+ vfolder_class.idstr = "vfolder";
+ vfolder_class.uistr = "VFolder";
+
+ /* Folder functions */
+ vfolder_class.new_folder = vfolder_new_folder;
+ vfolder_class.destroy_folder = vfolder_destroy_folder;
+ vfolder_class.set_xml = folder_set_xml;
+ vfolder_class.get_xml = folder_get_xml;
+ vfolder_class.scan_tree = vfolder_scan_tree;
+ vfolder_class.create_tree = vfolder_create_tree;
+
+ /* FolderItem functions */
+/* vfolder_class.item_new = vfolder_item_new;
+ vfolder_class.item_destroy = vfolder_item_destroy;
+ vfolder_class.item_get_path = vfolder_item_get_path;
+ vfolder_class.create_folder = vfolder_create_folder;
+ vfolder_class.rename_folder = NULL;
+ vfolder_class.remove_folder = vfolder_remove_folder;
+ vfolder_class.get_num_list = vfolder_get_num_list;
+ vfolder_class.scan_required = vfolder_scan_required;*/
+ vfolder_class.item_new = NULL;
+ vfolder_class.item_destroy = NULL;
+ vfolder_class.item_get_path = NULL;
+ vfolder_class.create_folder = NULL;
+ vfolder_class.rename_folder = NULL;
+ vfolder_class.remove_folder = NULL;
+ vfolder_class.get_num_list = NULL;
+ vfolder_class.scan_required = NULL;
+
+ /* Message functions */
+/* vfolder_class.get_msginfo = vfolder_get_msginfo;
+ vfolder_class.fetch_msg = vfolder_fetch_msg;
+ vfolder_class.copy_msgs = vfolder_copy_msgs;
+ vfolder_class.copy_msg = vfolder_copy_msg;
+ vfolder_class.add_msg = vfolder_add_msg;
+ vfolder_class.add_msgs = vfolder_add_msgs;
+ vfolder_class.remove_msg = vfolder_remove_msg;
+ vfolder_class.remove_msgs = NULL;
+ vfolder_class.remove_all_msg = vfolder_remove_all_msg;
+ vfolder_class.change_flags = NULL;
+ vfolder_class.subscribe = vfolder_subscribe_uri;*/
+ vfolder_class.get_msginfo = NULL;
+ vfolder_class.fetch_msg = NULL;
+ vfolder_class.copy_msgs = NULL;
+ vfolder_class.copy_msg = NULL;
+ vfolder_class.add_msg = NULL;
+ vfolder_class.add_msgs = NULL;
+ vfolder_class.remove_msg = NULL;
+ vfolder_class.remove_msgs = NULL;
+ vfolder_class.remove_all_msg = NULL;
+ vfolder_class.change_flags = NULL;
+ vfolder_class.subscribe = NULL;
+
+ debug_print("VFolder: registered folderclass\n");
+ }
+
+ return &vfolder_class;
+}
+
+/* Local functions */
+
+gboolean vfolder_init(void) {
+ gchar* error = g_new0(gchar, 1);
+
+ folder_register_class(vfolder_folder_get_class());
+
+ if (! vfolder_gtk_init(&error)) {
+ alertpanel_error("%s", error);
+ vfolder_done();
+ return FALSE;
+ }
+
+ folder_func_to_all_folders((FolderItemFunc)vfolder_init_read_func, NULL);
+
+ vfolders = vfolders_hashtable_new();
+
+ if (existing_tree_found == FALSE)
+ vfolder_create_default_mailbox();
+
+ return TRUE;
+}
+
+void vfolder_done(void) {
+
+ vfolder_gtk_done();
+
+ g_hash_table_destroy(vfolders);
+
+ if (!claws_is_exiting())
+ folder_unregister_class(vfolder_folder_get_class());
+}
diff --git a/src/plugins/vfolder/vfolder.h b/src/plugins/vfolder/vfolder.h
new file mode 100644
index 0000000..51f394d
--- /dev/null
+++ b/src/plugins/vfolder/vfolder.h
@@ -0,0 +1,76 @@
+/*
+ * $Id: $
+ */
+
+/* vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: */
+
+/*
+ * Virtual folder plugin for claws-mail
+ * Claws Mail is Copyright (C) 1999-2012 by the Claws Mail Team
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef __VFOLDER_H__
+#define __VFOLDER_H__
+
+#include <glib.h>
+#include <glib/gi18n.h>
+
+G_BEGIN_DECLS
+
+#include "folder.h"
+#include "procmsg.h"
+
+/* Name of directory in rcdir where VFolder will store its data. */
+#define VFOLDER_DIR "vfolder"
+
+/* Parent mailbox name */
+#define VFOLDER_DEFAULT_MAILBOX _("Virtual folders")
+
+typedef struct _VFolderItem VFolderItem;
+
+typedef MsgInfoList* (*MSGFILTERFUNC) (MsgInfoList* msgs, VFolderItem* item);
+
+struct _VFolderItem {
+ FolderItem item;
+
+ gchar* filter; /* Regex used to select messages */
+ gboolean frozen; /* Automatic update or not */
+ gboolean updating; /* Is this VFolder currently updating */
+
+ FolderItem* source; /* Source folder for virtual folder */
+ GHashTable* msg_store; /* Hashtable containing MsgInfo. Key is msginfo_identifier */
+ MSGFILTERFUNC msg_filter_func; /* Active filter function */
+};
+
+#define VFOLDER_ITEM(obj) ((VFolderItem *)obj)
+#define VFOLDER(obj) ((VFolder *)obj)
+
+#define IS_VFOLDER_FOLDER(folder) \
+ ((folder) && (folder->klass == vfolder_folder_get_class()))
+#define IS_VFOLDER_FOLDER_ITEM(item) \
+ ((item) && (item->folder->klass == vfolder_folder_get_class()))
+#define IS_VFOLDER_MSGINFO(msginfo) \
+ ((msginfo) && (msginfo->folder) && IS_VFOLDER_FOLDER_ITEM(msginfo->folder))
+
+gboolean vfolder_init(void);
+void vfolder_done(void);
+
+FolderClass* vfolder_folder_get_class(void);
+
+G_END_DECLS
+
+#endif
diff --git a/src/plugins/vfolder/vfolder_gtk.c b/src/plugins/vfolder/vfolder_gtk.c
new file mode 100644
index 0000000..eb037c5
--- /dev/null
+++ b/src/plugins/vfolder/vfolder_gtk.c
@@ -0,0 +1,1060 @@
+/*
+ * $Id: $
+ */
+/* vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: */
+
+/*
+ * Virtual folder plugin for claws-mail
+ *
+ * Claws Mail is Copyright (C) 1999-2012 by the Claws Mail Team
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#include "claws-features.h"
+#endif
+
+#include "menu.h"
+#include <gtk/gtk.h>
+#include <glib.h>
+#include <glib/gi18n.h>
+
+#include "common/claws.h"
+#include "common/version.h"
+#include "plugin.h"
+#include "defs.h"
+
+#include "mainwindow.h"
+#include "inputdialog.h"
+#include "folder.h"
+#include "folderview.h"
+#include "folder_item_prefs.h"
+#include "alertpanel.h"
+#include "hooks.h"
+#include "utils.h"
+#include "summaryview.h"
+
+#include "main.h"
+#include "gtkutils.h"
+
+#include "vfolder_gtk.h"
+#include "vfolder.h"
+#include "vfolder_prop.h"
+
+#define CONFIG_GROUP "VFolder"
+
+static guint folder_hook_id;
+static guint item_hook_id;
+static guint msginfo_hook_id;
+static GSList* widgets = NULL;
+
+typedef struct {
+ MsgInfoList* list;
+ VFolderItem* item;
+ gchar* file;
+} AddMsgData;
+
+typedef struct {
+ GtkWidget* widget;
+ GtkAction* action;
+} MenuItem;
+
+static char* vfolder_popup_menu_labels[] = {
+ N_("_Refresh folder"),
+ N_("Refresh _all folders"),
+ N_("Folder pr_operties..."),
+ N_("Rena_me..."),
+ N_("_Create new folder..."),
+ N_("_Delete folder..."),
+ NULL
+};
+
+static GtkActionEntry vfolder_popup_entries[] = {
+ {"FolderViewPopup/RefreshFolder", NULL, NULL, NULL, NULL, NULL /*G_CALLBACK(vfolder_refresh_cb)*/ },
+ {"FolderViewPopup/RefreshAllFolders", NULL, NULL, NULL, NULL, NULL /*G_CALLBACK(vfolder_refresh_cb)*/ },
+
+ {"FolderViewPopup/FolderProperties", NULL, NULL, NULL, NULL, G_CALLBACK(vfolder_properties_cb) },
+
+ {"FolderViewPopup/RenameFolder", NULL, NULL, NULL, NULL, NULL /*G_CALLBACK(vfolder_refresh_cb)*/ },
+
+ {"FolderViewPopup/NewFolder", NULL, NULL, NULL, NULL, G_CALLBACK(vfolder_new_folder_cb) },
+ {"FolderViewPopup/RemoveFolder", NULL, NULL, NULL, NULL, G_CALLBACK(vfolder_remove_folder_cb) },
+};
+
+static void vfolder_add_menuitems(GtkUIManager *ui_manager, FolderItem *item) {
+ MENUITEM_ADDUI_MANAGER(ui_manager, "/Popup/FolderViewPopup", "RefreshFolder", "FolderViewPopup/RefreshFolder", GTK_UI_MANAGER_MENUITEM)
+ MENUITEM_ADDUI_MANAGER(ui_manager, "/Popup/FolderViewPopup", "RefreshAllFolders", "FolderViewPopup/RefreshAllFolders", GTK_UI_MANAGER_MENUITEM)
+ MENUITEM_ADDUI_MANAGER(ui_manager, "/Popup/FolderViewPopup", "SeparatorVF1", "FolderViewPopup/---", GTK_UI_MANAGER_SEPARATOR)
+ MENUITEM_ADDUI_MANAGER(ui_manager, "/Popup/FolderViewPopup", "FolderProperties", "FolderViewPopup/FolderProperties", GTK_UI_MANAGER_MENUITEM)
+ MENUITEM_ADDUI_MANAGER(ui_manager, "/Popup/FolderViewPopup", "SeparatorVF2", "FolderViewPopup/---", GTK_UI_MANAGER_SEPARATOR)
+ MENUITEM_ADDUI_MANAGER(ui_manager, "/Popup/FolderViewPopup", "RenameFolder", "FolderViewPopup/RenameFolder", GTK_UI_MANAGER_MENUITEM)
+ MENUITEM_ADDUI_MANAGER(ui_manager, "/Popup/FolderViewPopup", "SeparatorVF3", "FolderViewPopup/---", GTK_UI_MANAGER_SEPARATOR)
+ MENUITEM_ADDUI_MANAGER(ui_manager, "/Popup/FolderViewPopup", "NewFolder", "FolderViewPopup/NewFolder", GTK_UI_MANAGER_MENUITEM)
+ MENUITEM_ADDUI_MANAGER(ui_manager, "/Popup/FolderViewPopup", "RemoveFolder", "FolderViewPopup/RemoveFolder", GTK_UI_MANAGER_MENUITEM)
+ MENUITEM_ADDUI_MANAGER(ui_manager, "/Popup/FolderViewPopup", "SeparatorVF4", "FolderViewPopup/---", GTK_UI_MANAGER_SEPARATOR)
+}
+
+static void vfolder_set_sensitivity(GtkUIManager *ui_manager, FolderItem *item) {
+#define SET_SENS(name, sens) \
+ cm_menu_set_sensitive_full(ui_manager, "Popup/"name, sens)
+
+ VFolderItem *ritem = (VFolderItem *)item;
+ SET_SENS("FolderViewPopup/RefreshFolder", folder_item_parent(item) != NULL && ! ritem->frozen);
+ SET_SENS("FolderViewPopup/RefreshAllFolders", folder_item_parent(item) == NULL && ! ritem->frozen);
+ SET_SENS("FolderViewPopup/FolderProperties", folder_item_parent(item) != NULL);
+ SET_SENS("FolderViewPopup/RenameFolder", folder_item_parent(item) != NULL);
+ SET_SENS("FolderViewPopup/NewFolder", TRUE);
+ SET_SENS("FolderViewPopup/RemoveFolder", folder_item_parent(item) != NULL);
+
+#undef SET_SENS
+}
+
+static FolderViewPopup vfolder_popup = {
+ "vfolder",
+ "<vfolder>",
+ vfolder_popup_entries,
+ G_N_ELEMENTS(vfolder_popup_entries),
+ NULL, 0,
+ NULL, 0, 0, NULL,
+ vfolder_add_menuitems,
+ vfolder_set_sensitivity
+};
+
+static void vfolder_fill_popup_menu_labels(void) {
+ gint i;
+
+ for (i = 0; vfolder_popup_menu_labels[i] != NULL; i++) {
+ (vfolder_popup_entries[i]).label = _(vfolder_popup_menu_labels[i]);
+ }
+}
+
+static void gslist_menu_item_free(GSList** menu_list) {
+ GSList* list;
+
+ if (! menu_list || ! *menu_list)
+ return;
+
+ for (list = *menu_list; list; list = g_slist_next(list)) {
+ MenuItem* menu = (MenuItem *) list->data;
+ g_free(menu);
+ }
+
+ g_slist_free(*menu_list);
+ *menu_list = NULL;
+}
+
+static gboolean get_menu_widgets() {
+ MainWindow* mainwindow;
+ MenuItem* menuitem = NULL;
+ GtkWidget* widget;
+
+ mainwindow = mainwindow_get_mainwindow();
+ if (mainwindow && mainwindow->ui_manager) {
+ widget = gtk_ui_manager_get_widget(
+ mainwindow->ui_manager, "/Menus/SummaryViewPopup/Move/");
+ if (widget) {
+ menuitem = g_new0(MenuItem, 1);
+ menuitem->widget = widget;
+ menuitem->action = gtk_ui_manager_get_action(
+ mainwindow->ui_manager, "/Menus/SummaryViewPopup/Move/");
+ widgets = g_slist_prepend(widgets, menuitem);
+ }
+ else
+ return FALSE;
+
+ widget = gtk_ui_manager_get_widget(
+ mainwindow->ui_manager, "/Menus/SummaryViewPopup/Trash/");
+ if (widget) {
+ menuitem = g_new0(MenuItem, 1);
+ menuitem->widget = widget;
+ menuitem->action = gtk_ui_manager_get_action(
+ mainwindow->ui_manager, "/Menus/SummaryViewPopup/Trash/");
+ widgets = g_slist_prepend(widgets, menuitem);
+ }
+ else {
+ gslist_menu_item_free(&widgets);
+ return FALSE;
+ }
+
+ widget = gtk_ui_manager_get_widget(
+ mainwindow->ui_manager, "/Menus/SummaryViewPopup/Delete/");
+ if (widget) {
+ menuitem = g_new0(MenuItem, 1);
+ menuitem->widget = widget;
+ menuitem->action = gtk_ui_manager_get_action(
+ mainwindow->ui_manager, "/Menus/SummaryViewPopup/Delete/");
+ widgets = g_slist_prepend(widgets, menuitem);
+ }
+ else {
+ gslist_menu_item_free(&widgets);
+ return FALSE;
+ }
+
+ widget = gtk_ui_manager_get_widget(
+ mainwindow->ui_manager, "/Menu/Message/Move/");
+ if (widget) {
+ menuitem = g_new0(MenuItem, 1);
+ menuitem->widget = widget;
+ menuitem->action = gtk_ui_manager_get_action(
+ mainwindow->ui_manager, "/Menu/Message/Move/");
+ widgets = g_slist_prepend(widgets, menuitem);
+ }
+ else {
+ gslist_menu_item_free(&widgets);
+ return FALSE;
+ }
+
+ widget = gtk_ui_manager_get_widget(
+ mainwindow->ui_manager, "/Menu/Message/Trash/");
+ if (widget) {
+ menuitem = g_new0(MenuItem, 1);
+ menuitem->widget = widget;
+ menuitem->action = gtk_ui_manager_get_action(
+ mainwindow->ui_manager, "/Menu/Message/Trash/");
+ widgets = g_slist_prepend(widgets, menuitem);
+ }
+ else {
+ gslist_menu_item_free(&widgets);
+ return FALSE;
+ }
+
+ widget = gtk_ui_manager_get_widget(
+ mainwindow->ui_manager, "/Menu/Message/Delete/");
+ if (widget) {
+ menuitem = g_new0(MenuItem, 1);
+ menuitem->widget = widget;
+ menuitem->action = gtk_ui_manager_get_action(
+ mainwindow->ui_manager, "/Menu/Message/Delete/");
+ widgets = g_slist_prepend(widgets, menuitem);
+ }
+ else {
+ gslist_menu_item_free(&widgets);
+ return FALSE;
+ }
+
+ }
+ else
+ return FALSE;
+
+ return TRUE;
+}
+/*
+static gboolean vfolder_widgets_is_visible() {
+ gboolean visible = TRUE;
+
+ if (widgets && widgets->data) {
+ MenuItem* menu = (MenuItem *) widgets->data;
+ visible = gtk_widget_get_visible(menu->widget);
+ }
+
+ return visible;
+}
+
+static gboolean vfolder_hide_widgets(VFolderItem* item) {
+ GSList* list;
+ MainWindow* mainwindow;
+
+// if (! item->deep_copy) {
+ for (list = widgets; list; list = g_slist_next(list)) {
+ MenuItem* menu = (MenuItem *) list->data;
+ gtk_widget_hide(menu->widget);
+ gtk_action_block_activate(menu->action);
+ }
+
+ mainwindow = mainwindow_get_mainwindow();
+ if (mainwindow && mainwindow->toolbar) {
+ if (mainwindow->toolbar->trash_btn)
+ gtk_widget_hide(mainwindow->toolbar->trash_btn);
+ if (mainwindow->toolbar->delete_btn)
+ gtk_widget_hide(mainwindow->toolbar->delete_btn);
+ }
+// }
+ return TRUE;
+}
+*/
+static gboolean vfolder_show_widgets(VFolderItem* item) {
+ GSList* list;
+ MainWindow* mainwindow;
+
+// if (! item->deep_copy) {
+ for (list = widgets; list; list = g_slist_next(list)) {
+ MenuItem* menu = (MenuItem *) list->data;
+ gtk_widget_show(menu->widget);
+ gtk_action_unblock_activate(menu->action);
+ }
+
+ mainwindow = mainwindow_get_mainwindow();
+ if (mainwindow && mainwindow->toolbar) {
+ if (mainwindow->toolbar->trash_btn)
+ gtk_widget_show(mainwindow->toolbar->trash_btn);
+ if (mainwindow->toolbar->delete_btn)
+ gtk_widget_show(mainwindow->toolbar->delete_btn);
+ }
+// }
+ return TRUE;
+}
+/*
+static gchar* vfolder_get_message_file_path(VFolderItem* item, MsgInfo* msg) {
+ gchar* path;
+ GSList* list = NULL, *cur;
+ Folder* folder;
+ gboolean old_uid;
+ guint last = 0;
+
+ if (item->deep_copy) {
+ path = procmsg_get_message_file_path(msg);
+ }
+ else {
+ gchar* root = folder_item_get_path(msg->to_folder);
+ folder = msg->to_folder->folder;
+ guint num = folder->klass->get_num_list(folder, msg->to_folder, &list, &old_uid);
+ if (num >= 0) {
+ for (cur = list, last = 0; cur; cur = g_slist_next(cur)) {
+ guint tmp = GPOINTER_TO_UINT(cur->data);
+ if (tmp > last)
+ last = tmp;
+ }
+ }
+ g_slist_free(list);
+
+ path = g_strdup_printf("%s%s%u", root, G_DIR_SEPARATOR_S, last + 1);
+ g_free(root);
+ }
+ return path;
+}
+*/
+
+/*
+static void vfolder_item_update(AddMsgData* msgdata) {
+ MsgInfoList* cur;
+ GSList update;
+ MsgFileInfo fileinfo;
+
+ if (!msgdata->item || !msgdata->list->data)
+ return;
+
+ for (cur = msgdata->list; cur; cur = g_slist_next(cur)) {
+ MsgInfo* msg = (MsgInfo *) cur->data;
+ if (MSG_IS_DELETED(msg->flags)) {
+ folder_item_remove_msg(FOLDER_ITEM(msgdata->item), msg->msgnum);
+ }
+ else {
+ fileinfo.msginfo = msg;
+ fileinfo.flags = &msg->flags;
+ fileinfo.file = msgdata->file;
+ update.data = &fileinfo;
+ update.next = NULL;
+ folder_item_scan(msg->folder);
+ gint n = folder_item_add_msgs(FOLDER_ITEM(msgdata->item), &update, FALSE);
+ gchar* p = strrchr(fileinfo.file, G_DIR_SEPARATOR);
+ p += 1;
+ guint num = to_number((const gchar *) p);
+ vfolder_replace_key_in_bridge(msgdata->item, msg->msgnum, num);
+ FOLDER_ITEM(msgdata->item)->last_num = n;
+ }
+ }
+
+ //procmsg_message_file_list_free(list);
+ //item->msginfos = folder_item_get_msg_list(FOLDER_ITEM(item));
+}
+*/
+/*
+static void add_msg_data_free(AddMsgData** rec) {
+ if (rec && *rec) {
+ AddMsgData* data = *rec;
+ g_slist_free(data->list);
+ g_free(data->file);
+ g_free(data);
+ *rec = NULL;
+ }
+}
+*/
+/*
+static void vfolder_update_affected_folder_items(MsgInfo* msginfo) {
+ GList *vfolders, *cur;
+ GSList* cur_msg;
+ gchar* src;
+ AddMsgData* data;
+ MsgInfo* msg;
+
+ if (! msginfo)
+ return;
+
+ if (MSG_IS_NEW(msginfo->flags) ||
+ MSG_IS_MOVE(msginfo->flags) ||
+ MSG_IS_COPY(msginfo->flags) ||
+ MSG_IS_DELETED(msginfo->flags)) {
+ vfolders = vfolder_get_vfolder_items();
+ for (cur = vfolders; cur; cur = g_list_next(cur)) {
+ data = g_new0(AddMsgData, 1);
+ VFolderItem* vitem = VFOLDER_ITEM(cur->data);
+ if (MSG_IS_MOVE(msginfo->flags) || MSG_IS_COPY(msginfo->flags))
+ src = folder_item_get_identifier(msginfo->to_folder);
+ else
+ src = folder_item_get_identifier(msginfo->folder);
+ gchar* shadow = folder_item_get_identifier(vitem->source);
+ debug_print("cmp %s : %s\n", src, shadow);
+ if (src && shadow && strcmp(src, shadow) == 0) {
+ if (MSG_IS_DELETED(msginfo->flags)) {
+ msg = vfolder_find_msg_from_claws_num(vitem, msginfo->msgnum);
+ if (msg)
+ data->list = g_slist_append(data->list, msg);
+ else {
+ add_msg_data_free(&data);
+ g_slist_free(add_msg_data);
+ add_msg_data = NULL;
+ g_free(src);
+ g_free(shadow);
+ return;
+ }
+ }
+ else {
+ data->list = g_slist_append(data->list, msginfo);
+ data->item = vitem;
+ data->file = vfolder_get_message_file_path(vitem, msginfo);
+ add_msg_data = g_slist_prepend(add_msg_data, data);
+ }
+ if (data->list && MSG_IS_DELETED(msginfo->flags)) {
+ GSList* list = vfolder_filter_msgs_list(data->list, vitem);
+ if (list && list->data) {
+ MsgInfo* msg = (MsgInfo *) list->data;
+ MSG_SET_PERM_FLAGS(msg->flags, MSG_DELETED);
+ }
+ g_slist_free(data->list);
+ data->list = list;
+ data->item = vitem;
+ vfolder_item_update(data);
+ add_msg_data_free(&data);
+ g_slist_free(add_msg_data);
+ add_msg_data = NULL;
+ }
+ }
+ g_free(src);
+ g_free(shadow);
+ }
+ }
+ if (add_msg_data) {
+ for (cur_msg = add_msg_data; cur_msg; cur_msg = g_slist_next(cur_msg)) {
+ data = (AddMsgData *) cur_msg->data;
+ GSList* list = vfolder_filter_msgs_list(data->list, data->item);
+ g_slist_free(data->list);
+ data->list = list;
+ vfolder_item_update(data);
+ add_msg_data_free(&data);
+ }
+ g_slist_free(add_msg_data);
+ add_msg_data = NULL;
+ }
+}
+*/
+static gboolean vfolder_folder_update_hook(gpointer source, gpointer data) {
+ FolderUpdateData* hookdata;
+
+ g_return_val_if_fail(source != NULL, FALSE);
+ hookdata = (FolderUpdateData *) source;
+
+ if (! hookdata->folder || IS_VFOLDER_FOLDER(hookdata->folder))
+ return FALSE;
+
+ if (hookdata->update_flags & FOLDER_REMOVE_FOLDERITEM) {
+ /* TODO: check if the removed folder item is foundation for vfolder */
+ debug_print("FOLDER_REMOVE_FOLDERITEM\n");
+ }
+
+ if (hookdata->update_flags & FOLDER_REMOVE_FOLDER) {
+ /* TODO: check if the removed folder is foundation for vfolder */
+ debug_print("FOLDER_REMOVE_FOLDER\n");
+ }
+
+ if (hookdata->update_flags & FOLDER_TREE_CHANGED) {
+ /* TODO: check if the removed folder is foundation for vfolder */
+ debug_print("FOLDER_TREE_CHANGED\n");
+ }
+
+ if (hookdata->update_flags & FOLDER_RENAME_FOLDERITEM) {
+ /* TODO: check if the removed folder is foundation for vfolder */
+ debug_print("FOLDER_RENAME_FOLDERITEM\n");
+ }
+
+ return FALSE;
+}
+
+static gboolean vfolder_folder_item_update_hook(gpointer source, gpointer data) {
+ FolderItemUpdateData* hookdata;
+// gint save_state = -1;
+ GList *items = NULL, *cur;
+// gboolean r;
+// MainWindow* mainwindow;
+
+ g_return_val_if_fail(source != NULL, FALSE);
+ hookdata = (FolderItemUpdateData *) source;
+
+ if (! hookdata->item || IS_VFOLDER_FOLDER_ITEM(hookdata->item))
+ return FALSE;
+
+ if (hookdata->update_flags & F_ITEM_UPDATE_REMOVEMSG ) {
+ debug_print("F_ITEM_UPDATE_REMOVEMSG\n");
+ //items = vfolder_get_vfolder_from_source(hookdata->item);
+ if (items) {
+ for (cur = items; cur; cur = g_list_next(cur)) {
+ //vfolder_folder_item_update_msgs(VFOLDER_ITEM(cur->data), F_ITEM_UPDATE_REMOVEMSG);
+ }
+ g_list_free(items);
+ }
+ }
+
+ else if (hookdata->update_flags & F_ITEM_UPDATE_CONTENT) {
+ debug_print("F_ITEM_UPDATE_CONTENT\n");
+ //items = vfolder_get_vfolder_from_source(hookdata->item);
+ if (items) {
+ for (cur = items; cur; cur = g_list_next(cur)) {
+ //vfolder_folder_item_update_msgs(VFOLDER_ITEM(cur->data), F_ITEM_UPDATE_CONTENT);
+ }
+ g_list_free(items);
+ }
+ //mainwindow = mainwindow_get_mainwindow();
+ //summary_execute(mainwindow->summaryview);
+ }
+
+ else if (hookdata->update_flags & F_ITEM_UPDATE_ADDMSG) {
+ debug_print("F_ITEM_UPDATE_ADDMSG\n");
+ //items = vfolder_get_vfolder_from_source(hookdata->item);
+ if (items) {
+ for (cur = items; cur; cur = g_list_next(cur)) {
+ //vfolder_folder_item_update_msgs(VFOLDER_ITEM(cur->data), F_ITEM_UPDATE_ADDMSG);
+ }
+ g_list_free(items);
+ }
+ }
+
+ else if (hookdata->update_flags & F_ITEM_UPDATE_MSGCNT) {
+ debug_print("F_ITEM_UPDATE_MSGCNT\n");
+/* if (IS_VFOLDER_FOLDER_ITEM(item)) {
+
+ if (! (VFOLDER_ITEM(item))->deep_copy) {
+ if (! (VFOLDER_ITEM(item))->active) {
+ r = vfolder_hide_widgets(VFOLDER_ITEM(item));
+ if (r)
+ VFOLDER_ITEM(item)->active = TRUE;
+ }
+ else {
+ r = vfolder_show_widgets(VFOLDER_ITEM(item));
+ if (r)
+ VFOLDER_ITEM(item)->active = FALSE;
+ }
+
+ if (r)
+ save_state = 1;
+ else
+ save_state = 0;
+ }
+ else
+ vfolder_show_widgets(VFOLDER_ITEM(item));
+ }
+ else {
+ if (!vfolder_widgets_is_visible())
+ vfolder_show_widgets(VFOLDER_ITEM(item));
+ }*/
+/*
+ items = vfolder_get_vfolder_from_source(hookdata->item);
+ if (items) {
+ for (cur = items; cur; cur = g_list_next(cur)) {
+ vfolder_folder_item_update_msgs(VFOLDER_ITEM(cur->data), F_ITEM_UPDATE_MSGCNT);
+ }
+ g_list_free(items);
+ }
+*/
+ }
+
+ else if (hookdata->update_flags & F_ITEM_UPDATE_NAME) {
+ /* TODO: need update? */
+ debug_print("F_ITEM_UPDATE_NAME\n");
+ //items = vfolder_get_vfolder_from_source(hookdata->item);
+ if (items) {
+ for (cur = items; cur; cur = g_list_next(cur)) {
+ //vfolder_folder_item_update_msgs(VFOLDER_ITEM(cur->data), F_ITEM_UPDATE_NAME);
+ }
+ g_list_free(items);
+ }
+ }
+
+ else {
+ /* Unhandled callback */
+ debug_print("Unhandled FolderItem callback\n");
+ }
+/*
+ if (!save_state) {
+ MainWindow* mainwindow = mainwindow_get_mainwindow();
+ alertpanel_error(_("%s: Could not hide dangerous actions"), hookdata->item->name);
+ summary_lock(mainwindow->summaryview);
+ }
+*/
+ return FALSE;
+}
+/*
+static gboolean vfolder_msg_info_update_hook(gpointer source, gpointer data) {
+ MsgInfoUpdate* hookdata;
+ MainWindow* mainwindow;
+ MsgInfo* msginfo;
+
+ g_return_val_if_fail(source != NULL, FALSE);
+ hookdata = (MsgInfoUpdate *) source;
+ msginfo = hookdata->msginfo;
+
+ g_return_val_if_fail(msginfo != NULL, TRUE);
+
+ if (IS_VFOLDER_MSGINFO(msginfo))
+ return FALSE;
+
+ debug_print("\n\nPermflag: %u Tmpflag: %u (scanned: %u)\n\n\n",
+ (guint32) msginfo->flags.perm_flags, (guint32) msginfo->flags.tmp_flags, 1U << 31);
+ if (MSG_IS_NEW(msginfo->flags)) {
+ debug_print("MSG_IS_NEW\n");
+ vfolder_update_affected_folder_items(msginfo);
+ mainwindow = mainwindow_get_mainwindow();
+ summary_execute(mainwindow->summaryview);
+ }
+
+ if (MSG_IS_DELETED(msginfo->flags)) {
+ debug_print("MSG_IS_DELETED\n");
+ vfolder_update_affected_folder_items(msginfo);
+ mainwindow = mainwindow_get_mainwindow();
+ summary_execute(mainwindow->summaryview);
+ }
+
+ if (MSG_IS_MOVE(msginfo->flags)) {
+ debug_print("MSG_IS_MOVE\n");
+ vfolder_update_affected_folder_items(msginfo);
+ mainwindow = mainwindow_get_mainwindow();
+ summary_execute(mainwindow->summaryview);
+ }
+
+ if (MSG_IS_COPY(msginfo->flags)) {
+ debug_print("MSG_IS_COPY\n");
+ vfolder_update_affected_folder_items(msginfo);
+ mainwindow = mainwindow_get_mainwindow();
+ summary_execute(mainwindow->summaryview);
+ }
+
+// if (MSG_IS_POSTFILTERED(msginfo->flags)) {
+// debug_print("MSG_IS_POSTFILTERED\n");
+// vfolder_update_affected_folder_items(msginfo);
+// mainwindow = mainwindow_get_mainwindow();
+// summary_execute(mainwindow->summaryview);
+// }
+
+
+ return FALSE;
+}
+*/
+static gchar* vfolder_get_rc_file(VFolderItem* item) {
+ gchar* (*item_get_path) (Folder* folder, FolderItem* item);
+ gchar* path;
+ gchar* rc_file;
+
+ item_get_path = FOLDER_ITEM(item)->folder->klass->item_get_path;
+
+ path = item_get_path(FOLDER_ITEM(item)->folder, FOLDER_ITEM(item));
+ rc_file = g_strconcat(path, G_DIR_SEPARATOR_S, "folderitemrc", NULL);
+ g_free(path);
+
+ return rc_file;
+}
+
+FolderPropsResponse vfolder_folder_item_props_write(VFolderItem* item) {
+ gchar* rc_file;
+ GKeyFile* config;
+ gchar* id;
+ gchar* data = NULL;
+ FILE* fp;
+ gsize len = 0;
+ FolderPropsResponse resp = FOLDER_ITEM_PROPS_NO_ITEM;
+/* gchar* numstr;
+ GHashTableIter iter;
+ gpointer key, value;*/
+
+ g_return_val_if_fail(item != NULL, resp);
+
+ rc_file = vfolder_get_rc_file(item);
+ config = g_key_file_new();
+
+ if (item->filter)
+ g_key_file_set_string(config, CONFIG_GROUP, "filter", item->filter);
+
+ g_key_file_set_boolean(config, CONFIG_GROUP, "frozen", item->frozen);
+
+ if (item->source) {
+ id = folder_item_get_identifier(item->source);
+ if (id) {
+ g_key_file_set_string(config, CONFIG_GROUP, "source", id);
+ g_free(id);
+ }
+ }
+
+/* if (item->claws_to_me && item->me_to_claws) {
+ numstr = NULL;
+ g_hash_table_iter_init(&iter, item->claws_to_me);
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
+ len++;
+ MsgBridge* bridge = value;
+ if (numstr) {
+ gchar* tmp = g_strdup(numstr);
+ g_free(numstr);
+ numstr = g_strdup_printf("%s, %u:%u",
+ tmp, bridge->my_num, bridge->claws_num);
+ g_free(tmp);
+ }
+ else
+ numstr = g_strdup_printf("%u:%u", bridge->my_num, bridge->claws_num);
+ }
+
+ g_key_file_set_string(config, CONFIG_GROUP, "file_id_list", numstr);
+ g_free(numstr);
+ }*/
+
+ if (g_file_test(rc_file, G_FILE_TEST_EXISTS)) {
+ gchar* bakpath = g_strconcat(rc_file, ".bak", NULL);
+ if (g_rename(rc_file, bakpath) < 0) {
+ g_warning("%s: Could not create", bakpath);
+ resp = FOLDER_ITEM_PROPS_BACKUP_FAIL;
+ }
+ g_free(bakpath);
+ }
+
+// g_key_file_set_integer(config, CONFIG_GROUP, "filter-function", item->filter_func);
+
+ data = g_key_file_to_data(config, &len, NULL);
+ if (len < 1) {
+ g_warning("Could not get config data");
+ resp = FOLDER_ITEM_PROPS_READ_DATA_FAIL;
+ }
+ else {
+ fp = g_fopen(rc_file, "w");
+ if (fp == NULL) {
+ gchar* dir_path_end = g_strrstr(rc_file, G_DIR_SEPARATOR_S);
+ gchar* rc_dir = g_strndup(rc_file, dir_path_end - rc_file);
+ debug_print("rc_dir: %s\n", rc_dir);
+ int r = g_mkdir_with_parents(rc_dir, 0700);
+ if (r != 0)
+ resp = FOLDER_ITEM_PROPS_MAKE_RC_DIR_FAIL;
+ g_free(rc_dir);
+ if (resp == FOLDER_ITEM_PROPS_MAKE_RC_DIR_FAIL)
+ goto error;
+ fp = g_fopen(rc_file, "w");
+ if (fp == NULL) {
+ resp = FOLDER_ITEM_PROPS_MAKE_RC_DIR_FAIL;
+ goto error;
+ }
+ }
+ fwrite(data, len, 1, fp);
+ fclose(fp);
+ resp = FOLDER_ITEM_PROPS_OK;
+ }
+
+error:
+ g_free(data);
+
+ g_key_file_free(config);
+ g_free(rc_file);
+
+ return resp;
+}
+
+FolderPropsResponse vfolder_folder_item_props_read(VFolderItem* item) {
+ gchar* rc_file;
+ GKeyFile* config;
+ GError* error = NULL;
+ gchar *id, *msgnums;
+ gchar **list, **head;
+ FolderPropsResponse resp = FOLDER_ITEM_PROPS_NO_ITEM;
+ gint lastnum;
+
+ g_return_val_if_fail(item != NULL, resp);
+
+ rc_file = vfolder_get_rc_file(item);
+ config = g_key_file_new();
+
+ if (g_file_test(rc_file, G_FILE_TEST_EXISTS)) {
+ g_key_file_load_from_file(config, rc_file, G_KEY_FILE_KEEP_COMMENTS, &error);
+ if (error) {
+ g_warning("%s. Using defaults", error->message);
+ g_error_free(error);
+ resp = FOLDER_ITEM_PROPS_READ_USING_DEFAULT;
+ }
+ else {
+ item->filter = g_key_file_get_string(config, CONFIG_GROUP, "filter", NULL);
+// item->search = g_key_file_get_integer(config, CONFIG_GROUP, "searchtype", NULL);
+ item->frozen = g_key_file_get_boolean(config, CONFIG_GROUP, "frozen", NULL);
+// item->deep_copy = g_key_file_get_boolean(config, CONFIG_GROUP, "deep_copy", NULL);
+// item->filter_func = g_key_file_get_integer(config, CONFIG_GROUP, "filter_function", NULL);
+
+ id = g_key_file_get_string(config, CONFIG_GROUP, "source", NULL);
+ if (id) {
+ item->source = folder_find_item_from_identifier(id);
+ g_free(id);
+ }
+ msgnums = g_key_file_get_string(config, CONFIG_GROUP, "file_id_list", NULL);
+ if (msgnums) {
+ list = g_strsplit(msgnums, ",", 0);
+ head = list;
+ lastnum = -1;
+ while (*list) {
+ /*gchar* anum = g_strdup(*list++);
+ g_strstrip(anum);
+ MsgBridge* bridge = vfolder_split_file_id(anum);
+ g_free(anum);
+ if (lastnum < (gint) bridge->my_num)
+ lastnum = bridge->my_num;
+ if (bridge->my_num > 0) {
+ vfolder_add_message_to_bridge(item, bridge);
+ }
+ g_free(bridge);*/
+ }
+ FOLDER_ITEM(item)->last_num = lastnum;
+ g_strfreev(head);
+ g_free(msgnums);
+ }
+ resp = FOLDER_ITEM_PROPS_OK;
+ }
+ }
+
+ g_key_file_free(config);
+ g_free(rc_file);
+
+ return resp;
+}
+
+gboolean vfolder_gtk_init(gchar** error) {
+ vfolder_fill_popup_menu_labels();
+ folderview_register_popup(&vfolder_popup);
+
+ folder_hook_id = hooks_register_hook(FOLDER_UPDATE_HOOKLIST,
+ vfolder_folder_update_hook, NULL);
+ if (folder_hook_id == -1) {
+ *error = g_strdup(_("Failed to register folder update hook"));
+ return FALSE;
+ }
+
+ item_hook_id = hooks_register_hook(FOLDER_ITEM_UPDATE_HOOKLIST,
+ vfolder_folder_item_update_hook, NULL);
+ if (item_hook_id == -1) {
+ *error = g_strdup(_("Failed to register folder item update hook"));
+ hooks_unregister_hook(FOLDER_UPDATE_HOOKLIST, folder_hook_id);
+ return FALSE;
+ }
+
+/* msginfo_hook_id = hooks_register_hook(MSGINFO_UPDATE_HOOKLIST,
+ vfolder_msg_info_update_hook, NULL);
+ if (msginfo_hook_id == -1) {
+ *error = g_strdup(_("Failed to register message info update hook"));
+ hooks_unregister_hook(FOLDER_UPDATE_HOOKLIST, folder_hook_id);
+ hooks_unregister_hook(FOLDER_ITEM_UPDATE_HOOKLIST, item_hook_id);
+ return FALSE;
+ }*/
+
+ if (! get_menu_widgets()) {
+ *error = g_strdup(_("Failed to get menu widgets"));
+ hooks_unregister_hook(FOLDER_UPDATE_HOOKLIST, folder_hook_id);
+ hooks_unregister_hook(FOLDER_ITEM_UPDATE_HOOKLIST, item_hook_id);
+ hooks_unregister_hook(MSGINFO_UPDATE_HOOKLIST, msginfo_hook_id);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void vfolder_gtk_done(void) {
+ MainWindow *mainwin = mainwindow_get_mainwindow();
+ FolderView *folderview = NULL;
+ FolderItem *fitem = NULL;
+
+ hooks_unregister_hook(FOLDER_UPDATE_HOOKLIST, folder_hook_id);
+ hooks_unregister_hook(FOLDER_ITEM_UPDATE_HOOKLIST, item_hook_id);
+ //hooks_unregister_hook(MSGINFO_UPDATE_HOOKLIST, msginfo_hook_id);
+
+ if (mainwin == NULL || claws_is_exiting())
+ return;
+
+ folderview = mainwin->folderview;
+ fitem = folderview->summaryview->folder_item;
+
+ if (fitem && IS_VFOLDER_FOLDER_ITEM(fitem)) {
+ vfolder_show_widgets(VFOLDER_ITEM(fitem));
+ gslist_menu_item_free(&widgets);
+
+ folderview_unselect(folderview);
+ summary_clear_all(folderview->summaryview);
+ }
+
+ folderview_unregister_popup(&vfolder_popup);
+}
+
+void vfolder_properties_cb(GtkAction* action, gpointer data) {
+ FolderView *folderview = (FolderView *)data;
+ FolderItem *item;
+
+ g_return_if_fail(folderview != NULL);
+
+ item = folderview_get_selected_item(folderview);
+
+ g_return_if_fail(item != NULL);
+ g_return_if_fail(item->path != NULL);
+ g_return_if_fail(item->folder != NULL);
+
+ if (vfolder_edit_item_dialog(VFOLDER_ITEM(item))) {
+ /* TODO: update */
+ if (debug_get_mode()) {
+// GHashTableIter iter;
+// gpointer key, value;
+
+/* g_hash_table_iter_init(&iter, VFOLDER_ITEM(item)->me_to_claws);
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
+ gchar* buf = g_new0(gchar, BUFSIZ);
+ MsgInfo* msginfo = vfolder_find_msg_from_vfolder_num(
+ VFOLDER_ITEM(item), GPOINTER_TO_UINT(key));
+ FILE* msg = procmsg_open_message(msginfo);
+ while (fread(buf, 1, BUFSIZ - 1, msg) > 0) {
+ fprintf(stderr, "%s", buf);
+ g_free(buf);
+ buf = g_new0(gchar, BUFSIZ);
+ }
+ fprintf(stderr, "\n");
+ if (buf)
+ g_free(buf);
+ fclose(msg);
+ }*/
+ }
+ vfolder_folder_item_props_write(VFOLDER_ITEM(item));
+ }
+}
+
+void vfolder_new_folder_cb(GtkAction* action, gpointer data) {
+ FolderView *folderview = (FolderView *)data;
+ GtkCMCTree *ctree = NULL;
+ FolderItem *item;
+ FolderItem *new_item;
+ gchar *new_folder;
+ gchar *name;
+ gchar *p;
+
+ if (!folderview->selected) return;
+ if (!GTK_IS_CMCTREE(folderview->ctree)) return;
+
+ ctree = GTK_CMCTREE(folderview->ctree);
+ item = gtk_cmctree_node_get_row_data(ctree, folderview->selected);
+ //item = folderview_get_selected_item(folderview);
+ if (! item) {
+ //item = FOLDER_ITEM(vfolder_get_vfolder_item(NULL));
+ }
+
+ cm_return_if_fail(item != NULL);
+ cm_return_if_fail(item->folder != NULL);
+
+ if (item->no_sub) {
+ alertpanel_error(N_("Virtual folders cannot contain subfolders"));
+ return;
+ }
+
+ new_folder = input_dialog(_("New folder"),
+ _("Input the name of new folder:"),
+ _("NewFolder"));
+ if (!new_folder) return;
+ AUTORELEASE_STR(new_folder, {g_free(new_folder); return;});
+
+ p = strchr(new_folder, G_DIR_SEPARATOR);
+ if (p) {
+ alertpanel_error(_("'%c' can't be included in folder name."),
+ G_DIR_SEPARATOR);
+ return;
+ }
+
+ name = trim_string(new_folder, 32);
+ AUTORELEASE_STR(name, {g_free(name); return;});
+
+ /* find whether the directory already exists */
+ if (folder_find_child_item_by_name(item, new_folder)) {
+ alertpanel_error(_("The folder '%s' already exists."), name);
+ return;
+ }
+
+ new_item = folder_create_folder(item, new_folder);
+ if (!new_item) {
+ alertpanel_error(_("Can't create the folder '%s'."), name);
+ return;
+ }
+
+ if (! vfolder_create_item_dialog(new_item)) {
+ //VFolderItem* vitem = VFOLDER_ITEM(new_item);
+ new_item->folder->klass->remove_folder(new_item->folder, new_item);
+ new_item = NULL;
+ return;
+ }
+
+ folder_write_list();
+}
+
+void vfolder_remove_folder_cb(GtkAction* action, gpointer data) {
+ FolderView *folderview = (FolderView *)data;
+ GtkCMCTree *ctree = GTK_CMCTREE(folderview->ctree);
+ FolderItem *item;
+ gchar *message, *name;
+ AlertValue avalue;
+ gchar *old_path = NULL;
+ gchar *old_id;
+
+ /* Silence lame warnings */
+ old_id = (old_path) ? NULL : old_path;
+
+ item = folderview_get_selected_item(folderview);
+ g_return_if_fail(item != NULL);
+ g_return_if_fail(item->path != NULL);
+ g_return_if_fail(item->folder != NULL);
+
+ name = trim_string(item->name, 32);
+ AUTORELEASE_STR(name, {g_free(name); return;});
+ message = g_strdup_printf
+ (_("All folders and messages under '%s' will be permanently deleted. "
+ "Recovery will not be possible.\n\n"
+ "Do you really want to delete?"), name);
+ avalue = alertpanel_full(_("Delete folder"), message,
+ GTK_STOCK_CANCEL, GTK_STOCK_DELETE, NULL, FALSE,
+ NULL, ALERT_WARNING, G_ALERTDEFAULT);
+ g_free(message);
+ if (avalue != G_ALERTALTERNATE) return;
+
+ Xstrdup_a(old_path, item->path, return);
+ old_id = folder_item_get_identifier(item);
+
+ if (folderview->opened == folderview->selected ||
+ gtk_cmctree_is_ancestor(ctree,
+ folderview->selected,
+ folderview->opened)) {
+ summary_clear_all(folderview->summaryview);
+ folderview->opened = NULL;
+ }
+
+ if (item->folder->klass->remove_folder(item->folder, item) < 0) {
+ folder_item_scan(item);
+ alertpanel_error(_("Can't remove the folder '%s'."), name);
+ g_free(old_id);
+ return;
+ }
+
+ folder_write_list();
+
+ g_free(old_id);
+}
diff --git a/src/plugins/vfolder/vfolder_gtk.h b/src/plugins/vfolder/vfolder_gtk.h
new file mode 100644
index 0000000..5b41ee4
--- /dev/null
+++ b/src/plugins/vfolder/vfolder_gtk.h
@@ -0,0 +1,57 @@
+/*
+ * $Id: $
+ */
+
+/* vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: */
+
+/*
+ * Virtual folder plugin for claws-mail
+ * Claws Mail is Copyright (C) 1999-2012 by the Claws Mail Team
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef __VFOLDER_GTK_H__
+#define __VFOLDER_GTK_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+#include "vfolder.h"
+#include <gtk/gtk.h>
+
+typedef enum {
+ FOLDER_ITEM_PROPS_OK,
+ FOLDER_ITEM_PROPS_NO_ITEM,
+ FOLDER_ITEM_PROPS_BACKUP_FAIL,
+ FOLDER_ITEM_PROPS_READ_DATA_FAIL,
+ FOLDER_ITEM_PROPS_MAKE_RC_DIR_FAIL,
+ FOLDER_ITEM_PROPS_READ_USING_DEFAULT
+} FolderPropsResponse;
+
+gboolean vfolder_gtk_init(gchar** error);
+void vfolder_gtk_done(void);
+FolderPropsResponse vfolder_folder_item_props_read(VFolderItem* item);
+FolderPropsResponse vfolder_folder_item_props_write(VFolderItem* item);
+
+/* Callback functions */
+void vfolder_new_folder_cb(GtkAction* action, gpointer data);
+void vfolder_remove_folder_cb(GtkAction* action, gpointer data);
+void vfolder_properties_cb(GtkAction* action, gpointer data);
+
+G_END_DECLS
+
+#endif
diff --git a/src/plugins/vfolder/vfolder_init.c b/src/plugins/vfolder/vfolder_init.c
new file mode 100644
index 0000000..b000514
--- /dev/null
+++ b/src/plugins/vfolder/vfolder_init.c
@@ -0,0 +1,150 @@
+/*
+ * $Id: $
+ */
+/* vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: */
+
+/*
+ * Virtual folder plugin for claws-mail
+ *
+ * Claws Mail is Copyright (C) 1999-2012 by the Claws Mail Team
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#include "claws-features.h"
+#endif
+
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+
+#include "common/claws.h"
+#include "common/version.h"
+#include "plugin.h"
+
+#include "mimeview.h"
+#include "utils.h"
+#include "alertpanel.h"
+#include "statusbar.h"
+#include "menu.h"
+#include "vfolder.h"
+#include "vfolder_gtk.h"
+
+#define PLUGIN_NAME (_("VFolder"))
+
+static GtkActionEntry vfolder_main_menu[] = {{
+ "View/CreateVfolder",
+ NULL, N_("Create virtual folder..."),
+ "<Control>v", N_("Create a virtual folder"),
+ G_CALLBACK(vfolder_new_folder_cb)
+}};
+
+static gint main_menu_id = 0;
+
+gint plugin_init(gchar** error) {
+ debug_set_mode(TRUE);
+ MainWindow *mainwin = mainwindow_get_mainwindow();
+
+/*
+#ifdef G_OS_UNIX
+ bindtextdomain(TEXTDOMAIN, LOCALEDIR);
+#else
+ bindtextdomain(TEXTDOMAIN, get_locale_dir());
+#endif
+ bind_textdomain_codeset(TEXTDOMAIN, "UTF-8");
+*/
+ if (!check_plugin_version(MAKE_NUMERIC_VERSION(0,0,1,0),
+ VERSION_NUMERIC, PLUGIN_NAME, error))
+ return -1;
+
+ gtk_action_group_add_actions(mainwin->action_group, vfolder_main_menu,
+ 1, (gpointer)mainwin);
+ MENUITEM_ADDUI_ID_MANAGER(mainwin->ui_manager, "/Menu/View", "CreateVfolder",
+ "View/CreateVfolder", GTK_UI_MANAGER_MENUITEM,
+ main_menu_id)
+
+ if (! vfolder_init()) {
+ debug_print("vfolder plugin unloading due to init errors\n");
+ plugin_done();
+ return -1;
+ }
+
+ debug_print("vfolder plugin loaded\n");
+
+ return 0;
+}
+
+gboolean plugin_done(void) {
+ MainWindow *mainwin = mainwindow_get_mainwindow();
+
+ vfolder_done();
+
+ if (mainwin == NULL)
+ return FALSE;
+
+ MENUITEM_REMUI_MANAGER(mainwin->ui_manager,mainwin->action_group, "View/CreateVfolder", main_menu_id);
+ main_menu_id = 0;
+
+ debug_print("vfolder plugin unloaded\n");
+
+ debug_set_mode(FALSE);
+ return TRUE;
+}
+
+const gchar* plugin_licence(void) {
+ return "GPL3+";
+}
+
+const gchar* plugin_version(void) {
+ return VERSION;
+}
+
+const gchar* plugin_type(void) {
+ return "GTK2";
+}
+
+const gchar* plugin_name(void) {
+ return PLUGIN_NAME;
+}
+
+const gchar* plugin_desc(void) {
+ return _("This plugin adds virtual folder support to Claws Mail.\n"
+ "\n"
+ "1) Select one or more mail folder(s) to use as the basic mail pool\n"
+ "2) Define a filter\n"
+ "3) Specify name for virtual folder\n"
+ "4) Press create and wait until the scanning of the mail pool finishes\n"
+ "\n"
+ "The VFolder will be updated periodically and when claws-mail is initially opened\n"
+ "Manual update is available from the context menu of the VFolder.\n"
+ "\n"
+ "The supported folder types are MH and IMAP.\n"
+ "Messages in a VFolder cannot be updated.\n"
+ "\n"
+ "To activate the archiving feature go to /View/Create virtual folder\n"
+ "\n"
+ "Default options can be set in /Configuration/Preferences/Plugins"
+ "/vfolder"
+ );
+}
+
+struct PluginFeature* plugin_provides(void) {
+ static struct PluginFeature features[] =
+ { {PLUGIN_UTILITY, N_("VFolder")},
+ {PLUGIN_FOLDERCLASS, N_("VFolder")},
+ {PLUGIN_NOTHING, NULL} };
+ return features;
+}
diff --git a/src/plugins/vfolder/vfolder_prop.c b/src/plugins/vfolder/vfolder_prop.c
new file mode 100644
index 0000000..c7187aa
--- /dev/null
+++ b/src/plugins/vfolder/vfolder_prop.c
@@ -0,0 +1,456 @@
+/*
+ * $Id: $
+ */
+/* vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: */
+
+/*
+ * Virtual folder plugin for claws-mail
+ *
+ * Claws Mail is Copyright (C) 1999-2012 by the Claws Mail Team
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#include "claws-features.h"
+#endif
+
+#include <gtk/gtk.h>
+#include <glib.h>
+#include <glib/gi18n.h>
+
+#include "common/claws.h"
+#include "common/version.h"
+#include "plugin.h"
+
+#include "gtkutils.h"
+#include "mainwindow.h"
+#include "foldersel.h"
+#include "alertpanel.h"
+
+#include "vfolder_gtk.h"
+#include "vfolder.h"
+#include "vfolder_prop.h"
+
+#define HEADERS N_("Message _Headers")
+#define BODY N_("_Message body")
+#define BOTH N_("_Both")
+
+typedef struct {
+ GtkWidget* filter;
+ GtkWidget* frozen;
+ GtkWidget* deep_copy;
+ GtkWidget* source;
+ GtkWidget* label_btn;
+ GtkWidget* message_btn;
+ GtkWidget* both_btn;
+} PropsDialog;
+
+static void add_current_config(VFolderItem* item, PropsDialog* props) {
+ if (item->filter)
+ gtk_entry_set_text(GTK_ENTRY(props->filter), item->filter);
+ if (item->source) {
+ gchar* id = folder_item_get_identifier(item->source);
+ if (id) {
+ gtk_entry_set_text(GTK_ENTRY(props->source), id);
+ g_free(id);
+ }
+ }
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(props->frozen), item->frozen);
+/* gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(props->deep_copy), item->deep_copy);
+ switch (item->search) {
+ case SEARCH_BODY:
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(props->message_btn), TRUE);
+ case SEARCH_BOTH:
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(props->both_btn), TRUE);
+ case SEARCH_HEADERS:
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(props->label_btn), TRUE);
+ }*/
+}
+
+static gboolean is_source_widget(GtkWidget* widget) {
+ const gchar* name = gtk_widget_get_name(widget);
+
+ return (name && strcmp("source", name) == 0);
+}
+
+static void foldersel_cb(GtkWidget *widget, gpointer data) {
+ FolderItem *item;
+ gchar *item_id;
+ gint newpos = 0;
+ GtkWidget* entry = GTK_WIDGET(data);
+
+ item = foldersel_folder_sel(NULL, FOLDER_SEL_COPY, NULL, FALSE);
+ if (item && IS_VFOLDER_FOLDER_ITEM(item)) {
+ /* Cannot create virtual folder from virtual folder */
+ alertpanel_error(_("%s: Cannot create virtual folder from virtual folder"), item->name);
+ return;
+ }
+ else {
+ if (item && (item_id = folder_item_get_identifier(item)) != NULL) {
+ gtk_editable_delete_text(GTK_EDITABLE(entry), 0, -1);
+ gtk_editable_insert_text(GTK_EDITABLE(entry),
+ item_id, strlen(item_id), &newpos);
+ g_free(item_id);
+ }
+ debug_print("Source Folder: %s\n", gtk_entry_get_text(GTK_ENTRY(entry)));
+ }
+}
+
+static GtkWidget* vfolder_prop_row(GtkWidget* widget,
+ const gchar* label_markup,
+ gint width, gboolean center) {
+ GtkWidget* row = gtk_hbox_new(FALSE, 5);
+ GtkWidget* label = gtk_label_new(NULL);
+
+ gtk_widget_set_size_request(label, width, -1);
+ gtk_label_set_markup_with_mnemonic(GTK_LABEL(label), label_markup);
+ gtk_label_set_mnemonic_widget(GTK_LABEL(label), widget);
+ gtk_box_pack_start(GTK_BOX(row), label, FALSE, FALSE, 5);
+ gtk_box_pack_start(GTK_BOX(row), widget, TRUE, FALSE, 5);
+
+ if (is_source_widget(widget)) {
+ GtkWidget* btn = gtk_button_new_from_stock(GTK_STOCK_OPEN);
+ g_signal_connect(G_OBJECT(btn), "clicked", G_CALLBACK(foldersel_cb), widget);
+ gtk_box_pack_start(GTK_BOX(row), btn, FALSE, FALSE, 5);
+ }
+
+ return row;
+}
+
+static gboolean vfolder_set_search_type(VFolderItem* item, GtkWidget* list) {
+ GSList *btn_list, *btns;
+ gboolean active = FALSE;
+ GtkToggleButton* btn = NULL;
+
+ btn_list = gtk_radio_button_get_group(GTK_RADIO_BUTTON(list));
+ for (btns = btn_list; btns && !active; btns = g_slist_next(btns)) {
+ btn = GTK_TOGGLE_BUTTON(btns->data);
+ active = gtk_toggle_button_get_active(btn);
+ }
+ if (active) {
+ const gchar* label = gtk_button_get_label(GTK_BUTTON(btn));
+ if (label) {
+/* if (strcmp(BOTH, label) == 0) {
+ if (item->search != SEARCH_BOTH) {
+ item->search = SEARCH_BOTH;
+ return TRUE;
+ }
+ }
+ else if (strcmp(BODY, label) == 0) {
+ if (item->search != SEARCH_BODY) {
+ item->search = SEARCH_BODY;
+ return TRUE;
+ }
+ }
+ else {
+ if (item->search != SEARCH_HEADERS) {
+ item->search = SEARCH_HEADERS;
+ return TRUE;
+ }
+ }*/
+ }
+ }
+
+ return FALSE;
+}
+/*
+static void vfolder_copy_msginfo_list(gpointer data, gpointer user_data) {
+ MsgInfo* msg = (MsgInfo *) data;
+ MsgInfo* new_msg;
+ VFolderItem* item = (VFolderItem *) user_data;
+
+ g_return_if_fail(msg != NULL);
+ g_return_if_fail(item != NULL);
+
+ new_msg = procmsg_msginfo_copy(msg);
+ item->msginfos = g_slist_prepend(item->msginfos, new_msg);
+}
+
+static gboolean vfolder_search_headers(MsgInfo* msg, GPatternSpec* pattern) {
+ return ((msg->cc && g_pattern_match_string(pattern, msg->cc)) ||
+ (msg->from && g_pattern_match_string(pattern, msg->from)) ||
+ (msg->fromname && g_pattern_match_string(pattern, msg->fromname)) ||
+ (msg->inreplyto && g_pattern_match_string(pattern, msg->inreplyto)) ||
+ (msg->subject && g_pattern_match_string(pattern, msg->subject)) ||
+ (msg->to && g_pattern_match_string(pattern, msg->to)));
+}
+
+static gboolean vfolder_search_body(MsgInfo* msg, GPatternSpec* pattern) {
+ gchar* body;
+ gboolean found = FALSE;
+
+ body = procmsg_get_message_file(msg);
+ if (body) {
+ found = g_pattern_match_string(pattern, body);
+ g_free(body);
+ }
+
+ return found;
+}
+*/
+static MsgInfoList* vfolder_filter_msgs_list(MsgInfoList* msgs, VFolderItem* item) {
+ MsgInfoList *list = NULL, *tmp;
+ GPatternSpec* pattern;
+ MsgInfo* msg;
+
+ if (!item || item->filter == NULL)
+ return list;
+
+ pattern = g_pattern_spec_new(item->filter);
+
+ for (tmp = msgs; tmp; tmp = g_slist_next(tmp)) {
+ msg = (MsgInfo *) tmp->data;
+/* switch (item->search) {
+ case SEARCH_HEADERS:
+ if (vfolder_search_headers(msg, pattern))
+ list = g_slist_prepend(list, msg);
+ break;
+ case SEARCH_BODY:
+ if (vfolder_search_body(msg, pattern))
+ list = g_slist_prepend(list, msg);
+ break;
+ case SEARCH_BOTH:
+ if (vfolder_search_headers(msg, pattern)) {
+ list = g_slist_prepend(list, msg);
+ continue;
+ }
+ if (vfolder_search_body(msg, pattern))
+ list = g_slist_prepend(list, msg);
+ break;
+ }*/
+ }
+
+ g_pattern_spec_free(pattern);
+
+ return list;
+}
+
+static gboolean vfolder_create_msgs_list(VFolderItem* item, gboolean copy) {
+ MsgInfoList *msgs = NULL, *filtered = NULL;
+ gboolean ok = FALSE;
+ GSList* filelist = NULL;
+
+ if (item->filter && item->msg_filter_func) {
+// item->deep_copy = copy;
+ ok = TRUE;
+ msgs = folder_item_get_msg_list(item->source);
+ filtered = item->msg_filter_func(msgs, item);
+ if (filtered) {
+ filelist = procmsg_get_message_file_list(filtered);
+ if (filelist) {
+ gint n = folder_item_add_msgs(FOLDER_ITEM(item), filelist, FALSE);
+ FOLDER_ITEM(item)->last_num = n;
+ procmsg_message_file_list_free(filelist);
+ }
+ g_slist_free(filtered);
+ }
+ g_slist_free(msgs);
+ }
+ return ok;
+}
+
+void vfolder_set_msgs_filter(VFolderItem* vfolder_item) {
+ g_return_if_fail(vfolder_item != NULL);
+
+ vfolder_item->msg_filter_func = vfolder_filter_msgs_list;
+}
+
+gboolean vfolder_create_item_dialog(FolderItem* folder_item) {
+ gboolean created = FALSE;
+ VFolderItem* item = NULL;
+
+ g_return_val_if_fail(folder_item != NULL, created);
+ g_return_val_if_fail(IS_VFOLDER_FOLDER_ITEM(folder_item), created);
+
+ item = VFOLDER_ITEM(folder_item);
+ item->msg_filter_func = vfolder_filter_msgs_list;
+
+ if (vfolder_edit_item_dialog(item)) {
+ /* save properties */
+ if (FOLDER_ITEM_PROPS_OK != vfolder_folder_item_props_write(item))
+ created = FALSE;
+ else
+ created = TRUE;
+ }
+
+ return created;
+}
+
+gboolean vfolder_edit_item_dialog(VFolderItem* vfolder_item) {
+ gboolean ok = FALSE;
+ PropsDialog* props_dialog;
+ GtkWidget* dialog;
+ GtkWidget* content;
+ GtkWidget* row;
+ GtkWidget* box;
+ gint response;
+ gchar* name;
+ const gchar* str;
+ gboolean frozen, deep_copy;
+ FolderItem* source;
+ gchar* old_filter = NULL;
+
+ g_return_val_if_fail(vfolder_item != NULL, ok);
+
+ MainWindow *mainwin = mainwindow_get_mainwindow();
+ props_dialog = g_new0(PropsDialog, 1);
+ props_dialog->filter = gtk_entry_new();
+ props_dialog->frozen = gtk_check_button_new();
+ props_dialog->deep_copy = gtk_check_button_new();
+ props_dialog->source = gtk_entry_new();
+ props_dialog->label_btn =
+ gtk_radio_button_new_with_mnemonic(NULL, HEADERS);
+ props_dialog->message_btn =
+ gtk_radio_button_new_with_mnemonic_from_widget(
+ GTK_RADIO_BUTTON(props_dialog->label_btn), BODY);
+ props_dialog->both_btn =
+ gtk_radio_button_new_with_mnemonic_from_widget(
+ GTK_RADIO_BUTTON(props_dialog->label_btn), BOTH);
+ gtk_widget_set_name(props_dialog->source, "source");
+ add_current_config(vfolder_item, props_dialog);
+
+ dialog = gtk_dialog_new_with_buttons(
+ N_("Edit VFolder Properties"),
+ GTK_WINDOW(mainwin->window),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
+ NULL);
+ gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_REJECT);
+ content = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+
+ GtkWidget* vbox = gtk_vbox_new(FALSE, 5);
+
+ row = vfolder_prop_row(props_dialog->source, N_("_Source folder"), 110, FALSE);
+ gtk_box_pack_start(GTK_BOX(vbox), row, FALSE, FALSE, 5);
+
+ GtkWidget* frame1 = gtk_frame_new(_("Message filter"));
+ GtkWidget* vbox1 = gtk_vbox_new(TRUE, 2);
+ gtk_container_add(GTK_CONTAINER(frame1), vbox1);
+
+ row = vfolder_prop_row(props_dialog->filter, N_("_Filter"), 110, FALSE);
+ gtk_box_pack_start(GTK_BOX(vbox1), row, FALSE, FALSE, 5);
+
+ box = gtk_hbox_new(TRUE, 2);
+ gtk_box_pack_start(GTK_BOX(box), props_dialog->label_btn, TRUE, TRUE, 2);
+ gtk_box_pack_start(GTK_BOX(box), props_dialog->message_btn, TRUE, TRUE, 2);
+ gtk_box_pack_start(GTK_BOX(box), props_dialog->both_btn, TRUE, TRUE, 2);
+ gtk_box_pack_start(GTK_BOX(vbox1), box, FALSE, FALSE, 5);
+
+ gtk_box_pack_start(GTK_BOX(vbox), frame1, FALSE, FALSE, 5);
+
+ row = vfolder_prop_row(props_dialog->frozen, N_("F_reeze content"), 110, TRUE);
+ gtk_box_pack_start(GTK_BOX(vbox), row, FALSE, FALSE, 5);
+
+ row = vfolder_prop_row(props_dialog->deep_copy, N_("Co_py messages"), 110, TRUE);
+ gtk_box_pack_start(GTK_BOX(vbox), row, FALSE, FALSE, 5);
+
+ name = g_strconcat(FOLDER_ITEM(vfolder_item)->name, N_(": settings"), NULL);
+ GtkWidget* frame = gtk_frame_new(name);
+ g_free(name);
+ gtk_container_add(GTK_CONTAINER(frame), vbox);
+ gtk_widget_show_all(frame);
+
+ gtk_container_add(GTK_CONTAINER(content), frame);
+
+ response = gtk_dialog_run(GTK_DIALOG(dialog));
+ if (response == GTK_RESPONSE_ACCEPT) {
+ frozen = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(props_dialog->frozen));
+ deep_copy = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(props_dialog->deep_copy));
+
+ str = gtk_entry_get_text(GTK_ENTRY(props_dialog->filter));
+ if (str) {
+ old_filter = g_strdup(vfolder_item->filter);
+ if (strlen(str) == 0) {
+ if (vfolder_item->filter) {
+ g_free(vfolder_item->filter);
+ vfolder_item->filter = NULL;
+ ok = TRUE;
+ }
+ }
+ else {
+ if (!vfolder_item->filter || strcmp(vfolder_item->filter, str) != 0) {
+ g_free(vfolder_item->filter);
+ vfolder_item->filter = g_strdup(str);
+ ok = TRUE;
+ }
+ }
+ }
+ if (vfolder_set_search_type(vfolder_item, props_dialog->label_btn))
+ ok = TRUE;
+
+ str = gtk_entry_get_text(GTK_ENTRY(props_dialog->source));
+ if (str) {
+ source = folder_find_item_from_identifier(str);
+ if (source && (source->stype != F_NORMAL && source->stype != F_INBOX)) {
+ alertpanel_error(_("%s: Not suitable for virtual folders\n"
+ "Use only folder type: Normal or Inbox\n"), str);
+ g_free(vfolder_item->filter);
+ vfolder_item->filter = g_strdup(old_filter);
+ ok = FALSE;
+ goto error;
+ }
+
+ if (strlen(str) == 0) {
+ if (vfolder_item->source) {
+ vfolder_item->source = NULL;
+ folder_item_remove_all_msg(FOLDER_ITEM(vfolder_item));
+ ok = TRUE;
+ }
+ }
+ else {
+ folder_item_remove_all_msg(FOLDER_ITEM(vfolder_item));
+ gchar* id = (vfolder_item->source) ?
+ folder_item_get_identifier(vfolder_item->source) : NULL;
+ if (!id || strcmp(id, str) != 0)
+ vfolder_item->source = source;
+ if (vfolder_item->source) {
+ ok = vfolder_create_msgs_list(vfolder_item, deep_copy);
+ if (ok == FALSE) {
+ g_free(vfolder_item->filter);
+ vfolder_item->filter = g_strdup(old_filter);
+ goto error;
+ }
+ }
+ else {
+ g_free(vfolder_item->filter);
+ vfolder_item->filter = g_strdup(old_filter);
+ ok = FALSE;
+ goto error;
+ }
+ }
+ }
+
+ if (vfolder_item->frozen != frozen) {
+ vfolder_item->frozen = frozen;
+ ok = TRUE;
+ }
+
+/* if (vfolder_item->deep_copy != deep_copy) {
+ vfolder_item->deep_copy = deep_copy;
+ ok = TRUE;
+ }*/
+
+ }
+
+error:
+ gtk_widget_destroy(dialog);
+ g_free(props_dialog);
+ g_free(old_filter);
+
+ return ok;
+}
diff --git a/src/plugins/vfolder/vfolder_prop.h b/src/plugins/vfolder/vfolder_prop.h
new file mode 100644
index 0000000..04fb493
--- /dev/null
+++ b/src/plugins/vfolder/vfolder_prop.h
@@ -0,0 +1,43 @@
+/*
+ * $Id: $
+ */
+
+/* vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: */
+
+/*
+ * Virtual folder plugin for claws-mail
+ * Claws Mail is Copyright (C) 1999-2012 by the Claws Mail Team
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef __VFOLDER_PROP_H__
+#define __VFOLDER_PROP_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+#include "folder.h"
+#include "vfolder.h"
+#include <gtk/gtk.h>
+
+gboolean vfolder_create_item_dialog(FolderItem* folder_item);
+gboolean vfolder_edit_item_dialog(VFolderItem* vfolder_item);
+void vfolder_set_msgs_filter(VFolderItem* vfolder_item);
+
+G_END_DECLS
+
+#endif
commit e1f0f7f3918e1c778199165a971eb2863c86ad70
Author: Michael Rasmussen <mir at datanom.net>
Date: Sun Jun 8 18:50:28 2014 +0200
Prepare vfolder
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
index 6912a84..5576571 100644
--- a/src/plugins/Makefile.am
+++ b/src/plugins/Makefile.am
@@ -31,4 +31,5 @@ SUBDIRS = \
spamassassin \
spam_report \
tnef_parse \
- vcalendar
+ vcalendar \
+ vfolder
commit a6c14cf0bed0460dadf246bcf6d72e5c6ff32eee
Author: Michael Rasmussen <mir at datanom.net>
Date: Sun Jun 8 18:21:35 2014 +0200
Prepare for vfolder plugin
diff --git a/configure.ac b/configure.ac
index 771a313..2e8ee4b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1029,6 +1029,10 @@ AC_ARG_ENABLE(vcalendar-plugin,
[ --disable-vcalendar-plugin Do not build vcalendar plugin],
[enable_vcalendar_plugin=$enableval], [enable_vcalendar_plugin=auto])
+AC_ARG_ENABLE(vfolder-plugin,
+ [ --disable-vfolder-plugin Do not build vfolder plugin],
+ [enable_vfolder_plugin=$enableval], [enable_vfolder_plugin=auto])
+
dnl disabled by default
AC_ARG_ENABLE(demo-plugin,
[ --enable-demo-plugin Build demo plugin],
@@ -1058,6 +1062,7 @@ dnl Python: Python
dnl RSSyl: libxml2 libcurl
dnl SpamReport: libcurl
dnl vCalendar: libcurl
+dnl VFolder: none
dnl libcurl ********************************************************************
PKG_CHECK_MODULES(CURL, libcurl, HAVE_CURL=yes, HAVE_CURL=no)
@@ -1158,9 +1163,9 @@ if test x"$HAVE_PERL" = xyes; then
PERL_LDFLAGS=`echo $PERL_LDFLAGS |sed 's/-lc//'`
AC_MSG_RESULT(ok)
AC_MSG_NOTICE([Adding perl LIBS ${PERL_CFLAGS}])
-
+
if test x"$HAVE_PERL" = xyes; then
- AC_CHECK_LIB(perl,perl_alloc,[AC_DEFINE(HAVE_LIBPERL, 1, Check for libperl.)],
+ AC_CHECK_LIB(perl,perl_alloc,[AC_DEFINE(HAVE_LIBPERL, 1, Check for libperl.)],
[ HAVE_LIBPERL=no ])
fi
if test x"$HAVE_LIBPERL" = xno; then
@@ -1172,7 +1177,7 @@ if test x"$HAVE_PERL" = xyes; then
HAVE_LIBPERL=yes
else
AC_MSG_RESULT(no)
- fi
+ fi
fi
PERL="perl"
AC_SUBST(PERL)
@@ -1817,32 +1822,24 @@ else
AC_MSG_RESULT(no)
fi
-AC_MSG_CHECKING([whether to build vcalendar plugin])
-if test x"$enable_vcalendar_plugin" != xno; then
+AC_MSG_CHECKING([whether to build vfolder plugin])
+if test x"$enable_vfolder_plugin" != xno; then
dependencies_missing=""
- if test x"$HAVE_CURL" = xno; then
- dependencies_missing="libcurl $dependencies_missing"
- fi
-
- if test x"$HAVE_PERL" = xno; then
- dependencies_missing="perl $dependencies_missing"
- fi
-
if test x"$dependencies_missing" = x; then
- PLUGINS="$PLUGINS vcalendar"
+ PLUGINS="$PLUGINS vfolder"
AC_MSG_RESULT(yes)
- elif test x"$enable_vcalendar_plugin" = xauto; then
+ elif test x"$enable_vfolder_plugin" = xauto; then
AC_MSG_RESULT(no)
- AC_MSG_WARN("Plugin vcalendar will not be built; missing $dependencies_missing")
- enable_vcalendar_plugin=no
- MISSING_DEPS_PLUGINS="$MISSING_DEPS_PLUGINS vcalendar"
+ AC_MSG_WARN("Plugin vfolder will not be built; missing $dependencies_missing")
+ enable_vfolder_plugin=no
+ MISSING_DEPS_PLUGINS="$MISSING_DEPS_PLUGINS vfolder"
else
AC_MSG_RESULT(no)
- AC_MSG_ERROR("Plugin vcalendar cannot be built; missing $dependencies_missing")
+ AC_MSG_ERROR("Plugin vfolder cannot be built; missing $dependencies_missing")
fi
else
- DISABLED_PLUGINS="$DISABLED_PLUGINS vcalendar"
+ DISABLED_PLUGINS="$DISABLED_PLUGINS vfolder"
AC_MSG_RESULT(no)
fi
@@ -1878,6 +1875,7 @@ AM_CONDITIONAL(BUILD_SPAMASSASSIN_PLUGIN, test x"$enable_spamassassin_plugin" !=
AM_CONDITIONAL(BUILD_SPAM_REPORT_PLUGIN, test x"$enable_spam_report_plugin" != xno)
AM_CONDITIONAL(BUILD_TNEF_PARSE_PLUGIN, test x"$enable_tnef_parse_plugin" != xno)
AM_CONDITIONAL(BUILD_VCALENDAR_PLUGIN, test x"$enable_vcalendar_plugin" != xno)
+AM_CONDITIONAL(BUILD_VFOLDER_PLUGIN, test x"$enable_vfolder_plugin" != xno)
dnl ****************************
@@ -1933,6 +1931,7 @@ src/plugins/vcalendar/libical/libical/icalversion.h
src/plugins/vcalendar/libical/libical/Makefile
src/plugins/vcalendar/libical/design-data/Makefile
src/plugins/vcalendar/libical/scripts/Makefile
+src/plugins/vfolder/Makefile
doc/Makefile
doc/man/Makefile
tools/Makefile
-----------------------------------------------------------------------
hooks/post-receive
--
Claws Mail
More information about the Commits
mailing list