/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ /* e-storage.c * * Copyright (C) 2000 Helix Code, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * * Author: Ettore Perazzoli */ #ifdef HAVE_CONFIG_H #include <config.h> #endif #include <gtk/gtkobject.h> #include <gtk/gtksignal.h> #include <gnome.h> #include <gal/util/e-util.h> #include "e-folder-tree.h" #include "e-storage.h" #define PARENT_TYPE GTK_TYPE_OBJECT static GtkObjectClass *parent_class = NULL; #define ES_CLASS(obj) \ E_STORAGE_CLASS (GTK_OBJECT (obj)->klass) struct _EStoragePrivate { EFolderTree *folder_tree; }; enum { NEW_FOLDER, REMOVED_FOLDER, LAST_SIGNAL }; static guint signals[LAST_SIGNAL] = { 0 }; /* Destroy notification function for the folders in the tree. */ static void folder_destroy_notify (EFolderTree *tree, const char *path, void *data, void *closure) { EFolder *e_folder; if (data == NULL) { /* The root folder has no EFolder associated to it. */ return; } e_folder = E_FOLDER (data); gtk_object_unref (GTK_OBJECT (e_folder)); } /* GtkObject methods. */ static void destroy (GtkObject *object) { EStorage *storage; EStoragePrivate *priv; storage = E_STORAGE (object); priv = storage->priv; if (priv->folder_tree != NULL) e_folder_tree_destroy (priv->folder_tree); (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); } /* EStorage methods. */ static GList * impl_get_subfolder_paths (EStorage *storage, const char *path) { EStoragePrivate *priv; priv = storage->priv; return e_folder_tree_get_subfolders (priv->folder_tree, path); } static EFolder * impl_get_folder (EStorage *storage, const char *path) { EStoragePrivate *priv; EFolder *e_folder; priv = storage->priv; e_folder = (EFolder *) e_folder_tree_get_folder (priv->folder_tree, path); return e_folder; } static const char * impl_get_name (EStorage *storage) { return _("(No name)"); } static void impl_async_create_folder (EStorage *storage, const char *path, const char *type, const char *description, EStorageResultCallback callback, void *data) { (* callback) (storage, E_STORAGE_NOTIMPLEMENTED, data); } static void impl_async_remove_folder (EStorage *storage, const char *path, EStorageResultCallback callback, void *data) { (* callback) (storage, E_STORAGE_NOTIMPLEMENTED, data); } /* Initialization. */ static void class_init (EStorageClass *class) { GtkObjectClass *object_class; object_class = GTK_OBJECT_CLASS (class); parent_class = gtk_type_class (gtk_object_get_type ()); object_class->destroy = destroy; class->get_subfolder_paths = impl_get_subfolder_paths; class->get_folder = impl_get_folder; class->get_name = impl_get_name; class->async_create_folder = impl_async_create_folder; class->async_remove_folder = impl_async_remove_folder; signals[NEW_FOLDER] = gtk_signal_new ("new_folder", GTK_RUN_FIRST, object_class->type, GTK_SIGNAL_OFFSET (EStorageClass, new_folder), gtk_marshal_NONE__STRING, GTK_TYPE_NONE, 1, GTK_TYPE_STRING); signals[REMOVED_FOLDER] = gtk_signal_new ("removed_folder", GTK_RUN_FIRST, object_class->type, GTK_SIGNAL_OFFSET (EStorageClass, removed_folder), gtk_marshal_NONE__STRING, GTK_TYPE_NONE, 1, GTK_TYPE_STRING); gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL); } static void init (EStorage *storage) { EStoragePrivate *priv; priv = g_new (EStoragePrivate, 1); priv->folder_tree = e_folder_tree_new (folder_destroy_notify, NULL); storage->priv = priv; } /* Creation. */ void e_storage_construct (EStorage *storage) { g_return_if_fail (storage != NULL); g_return_if_fail (E_IS_STORAGE (storage)); GTK_OBJECT_UNSET_FLAGS (GTK_OBJECT (storage), GTK_FLOATING); } EStorage * e_storage_new (void) { EStorage *new; new = gtk_type_new (e_storage_get_type ()); e_storage_construct (new); return new; } gboolean e_storage_path_is_absolute (const char *path) { g_return_val_if_fail (path != NULL, FALSE); return *path == G_DIR_SEPARATOR; } gboolean e_storage_path_is_relative (const char *path) { g_return_val_if_fail (path != NULL, FALSE); return *path != G_DIR_SEPARATOR; } GList * e_storage_get_subfolder_paths (EStorage *storage, const char *path) { g_return_val_if_fail (storage != NULL, NULL); g_return_val_if_fail (E_IS_STORAGE (storage), NULL); g_return_val_if_fail (path != NULL, NULL); g_return_val_if_fail (g_path_is_absolute (path), NULL); return (* ES_CLASS (storage)->get_subfolder_paths) (storage, path); } EFolder * e_storage_get_folder (EStorage *storage, const char *path) { g_return_val_if_fail (storage != NULL, NULL); g_return_val_if_fail (E_IS_STORAGE (storage), NULL); g_return_val_if_fail (path != NULL, NULL); g_return_val_if_fail (e_storage_path_is_absolute (path), NULL); return (* ES_CLASS (storage)->get_folder) (storage, path); } const char * e_storage_get_name (EStorage *storage) { g_return_val_if_fail (storage != NULL, NULL); g_return_val_if_fail (E_IS_STORAGE (storage), NULL); return (* ES_CLASS (storage)->get_name) (storage); } /* Folder operations. */ void e_storage_async_create_folder (EStorage *storage, const char *path, const char *type, const char *description, EStorageResultCallback callback, void *data) { g_return_if_fail (storage != NULL); g_return_if_fail (E_IS_STORAGE (storage)); g_return_if_fail (path != NULL); g_return_if_fail (g_path_is_absolute (path)); g_return_if_fail (type != NULL); g_return_if_fail (callback != NULL); (* ES_CLASS (storage)->async_create_folder) (storage, path, type, description, callback, data); } void e_storage_async_remove_folder (EStorage *storage, const char *path, EStorageResultCallback callback, void *data) { g_return_if_fail (storage != NULL); g_return_if_fail (E_IS_STORAGE (storage)); g_return_if_fail (path != NULL); g_return_if_fail (g_path_is_absolute (path)); g_return_if_fail (callback != NULL); (* ES_CLASS (storage)->async_remove_folder) (storage, path, callback, data); } const char * e_storage_result_to_string (EStorageResult result) { switch (result) { case E_STORAGE_OK: return _("No error"); case E_STORAGE_GENERICERROR: return _("Generic error"); case E_STORAGE_EXISTS: return _("A folder with the same name already exists"); case E_STORAGE_INVALIDTYPE: return _("The specified folder type is not valid"); case E_STORAGE_IOERROR: return _("I/O error"); case E_STORAGE_NOSPACE: return _("Not enough space to create the folder"); case E_STORAGE_NOTFOUND: return _("The specified folder was not found"); case E_STORAGE_NOTIMPLEMENTED: return _("Function not implemented in this storage"); case E_STORAGE_PERMISSIONDENIED: return _("Permission denied"); case E_STORAGE_UNSUPPORTEDOPERATION: return _("Operation not supported"); case E_STORAGE_UNSUPPORTEDTYPE: return _("The specified type is not supported in this storage"); default: return _("Unknown error"); } } /* Public utility functions. */ struct _GetPathForPhysicalUriForeachData { const char *physical_uri; char *retval; }; typedef struct _GetPathForPhysicalUriForeachData GetPathForPhysicalUriForeachData; static void get_path_for_physical_uri_foreach (EFolderTree *folder_tree, const char *path, void *path_data, void *user_data) { GetPathForPhysicalUriForeachData *foreach_data; const char *physical_uri; EFolder *e_folder; foreach_data = (GetPathForPhysicalUriForeachData *) user_data; if (foreach_data->retval != NULL) return; e_folder = (EFolder *) path_data; if (e_folder == NULL) return; physical_uri = e_folder_get_physical_uri (e_folder); if (strcmp (foreach_data->physical_uri, physical_uri) == 0) foreach_data->retval = g_strdup (path); } /** * e_storage_get_path_for_physical_uri: * @storage: A storage * @physical_uri: A physical URI * * Look for the folder having the specified @physical_uri. * * Return value: The path of the folder having the specified @physical_uri in * @storage. If such a folder does not exist, just return NULL. The return * value must be freed by the caller. **/ char * e_storage_get_path_for_physical_uri (EStorage *storage, const char *physical_uri) { GetPathForPhysicalUriForeachData foreach_data; EStoragePrivate *priv; g_return_val_if_fail (storage != NULL, NULL); g_return_val_if_fail (E_IS_STORAGE (storage), NULL); g_return_val_if_fail (physical_uri != NULL, NULL); priv = storage->priv; foreach_data.physical_uri = physical_uri; foreach_data.retval = NULL; e_folder_tree_foreach (priv->folder_tree, get_path_for_physical_uri_foreach, &foreach_data); return foreach_data.retval; } /* Protected functions. */ /* These functions are used by subclasses to add and remove folders from the state stored in the storage object. */ gboolean e_storage_new_folder (EStorage *storage, const char *path, EFolder *e_folder) { EStoragePrivate *priv; g_return_val_if_fail (storage != NULL, FALSE); g_return_val_if_fail (E_IS_STORAGE (storage), FALSE); g_return_val_if_fail (path != NULL, FALSE); g_return_val_if_fail (g_path_is_absolute (path), FALSE); g_return_val_if_fail (e_folder != NULL, FALSE); g_return_val_if_fail (E_IS_FOLDER (e_folder), FALSE); priv = storage->priv; if (! e_folder_tree_add (priv->folder_tree, path, e_folder)) return FALSE; gtk_signal_emit (GTK_OBJECT (storage), signals[NEW_FOLDER], path); return TRUE; } gboolean e_storage_removed_folder (EStorage *storage, const char *path) { EStoragePrivate *priv; g_return_val_if_fail (storage != NULL, FALSE); g_return_val_if_fail (E_IS_STORAGE (storage), FALSE); g_return_val_if_fail (path != NULL, FALSE); g_return_val_if_fail (g_path_is_absolute (path), FALSE); priv = storage->priv; if (e_folder_tree_get_folder (priv->folder_tree, path) == NULL) return FALSE; gtk_signal_emit (GTK_OBJECT (storage), signals[REMOVED_FOLDER], path); e_folder_tree_remove (priv->folder_tree, path); return TRUE; } E_MAKE_TYPE (e_storage, "EStorage", EStorage, class_init, init, PARENT_TYPE) 1.16&id=a44c192a2f5c31ae449c6b008b8a42bcc7ee099d'>Sync to new bsd.autotools.mk</a></td><td>ade</td><td><span title='2010-12-04 15:34:27 +0800'>2010-12-04</span></td><td>1</td><td><span class='deletions'>-1</span>/<span class='insertions'>+1</span></td></tr> <tr><td class='commitgraph'>* </td><td><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/commit/graphics/jpeg?h=mate-1.16&id=f5c1a124cf26199af9a8deaa2c22291ca2dd02d7'>- fix spelling</a></td><td>dinoex</td><td><span title='2010-08-27 12:43:45 +0800'>2010-08-27</span></td><td>1</td><td><span class='deletions'>-1</span>/<span class='insertions'>+1</span></td></tr> <tr><td class='commitgraph'>* </td><td><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/commit/graphics/jpeg?h=mate-1.16&id=ce9a4e21a98d5c9b37b4db3ad94d5f22120f7fce'>- update description</a></td><td>dinoex</td><td><span title='2010-08-27 04:42:41 +0800'>2010-08-27</span></td><td>1</td><td><span class='deletions'>-9</span>/<span class='insertions'>+5</span></td></tr> <tr><td class='commitgraph'>* </td><td><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/commit/graphics/jpeg?h=mate-1.16&id=b52237dc1447aa799e5627348bd87a76b3aa3020'>- update to 8b</a></td><td>dinoex</td><td><span title='2010-06-08 01:31:10 +0800'>2010-06-08</span></td><td>2</td><td><span class='deletions'>-6</span>/<span class='insertions'>+6</span></td></tr> <tr><td class='commitgraph'>* </td><td><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/commit/graphics/jpeg?h=mate-1.16&id=9ad2963ad7be402e9612102fbf1d013c0001aeda'>- use DISTVERSION</a></td><td>dinoex</td><td><span title='2010-06-06 16:31:24 +0800'>2010-06-06</span></td><td>1</td><td><span class='deletions'>-1</span>/<span class='insertions'>+2</span></td></tr> <tr><td class='commitgraph'>* </td><td><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/commit/graphics/jpeg?h=mate-1.16&id=26b7392839c774dc06626cc39e23c8aecb00ad10'>Bump PORTREVISION to force registration of the conflict with</a></td><td>rene</td><td><span title='2010-04-30 02:31:32 +0800'>2010-04-30</span></td><td>1</td><td><span class='deletions'>-1</span>/<span class='insertions'>+1</span></td></tr> <tr><td class='commitgraph'>* </td><td><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/commit/graphics/jpeg?h=mate-1.16&id=e7cf7f5cbd71d4684c277d6801d59bf6078c7c0a'>Register mutual CONFLICTS.</a></td><td>rene</td><td><span title='2010-04-28 14:18:17 +0800'>2010-04-28</span></td><td>1</td><td><span class='deletions'>-0</span>/<span class='insertions'>+1</span></td></tr> <tr><td class='commitgraph'>* </td><td><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/commit/graphics/jpeg?h=mate-1.16&id=4343738152e702f8f97d73c33f85108aa4dfec3b'>- update to 8a</a></td><td>dinoex</td><td><span title='2010-03-09 23:10:26 +0800'>2010-03-09</span></td><td>3</td><td><span class='deletions'>-22</span>/<span class='insertions'>+23</span></td></tr> <tr><td class='commitgraph'>* </td><td><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/commit/graphics/jpeg?h=mate-1.16&id=417c6c4ed6314cab19a5aa75a5eaa2e5e8369d5e'>- cleanup comment, ggostscript5 is gone</a></td><td>dinoex</td><td><span title='2010-02-05 19:58:18 +0800'>2010-02-05</span></td><td>1</td><td><span class='deletions'>-2</span>/<span class='insertions'>+0</span></td></tr> <tr><td class='commitgraph'>* </td><td><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/commit/graphics/jpeg?h=mate-1.16&id=444a47ba39d176ab6be5d165b2147eacd2897112'>- update to jpeg-8</a></td><td>dinoex</td><td><span title='2010-02-05 19:46:55 +0800'>2010-02-05</span></td><td>7</td><td><span class='deletions'>-59</span>/<span class='insertions'>+56</span></td></tr> <tr><td class='commitgraph'>* </td><td><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/commit/graphics/jpeg?h=mate-1.16&id=af1fc7a24eda71b11fbfc0bc73c1d53d079e5b57'>-Repocopy devel/libtool15 -> libtool22 and libltdl15 -> libltdl22.</a></td><td>mezz</td><td><span title='2009-08-03 03:36:34 +0800'>2009-08-03</span></td><td>1</td><td><span class='deletions'>-1</span>/<span class='insertions'>+1</span></td></tr> <tr><td class='commitgraph'>* </td><td><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/commit/graphics/jpeg?h=mate-1.16&id=f66043401d219e6bee08b710c77b732eb36060b5'>- update to jpeg7</a></td><td>dinoex</td><td><span title='2009-07-18 19:11:29 +0800'>2009-07-18</span></td><td>11</td><td><span class='deletions'>-2034</span>/<span class='insertions'>+297</span></td></tr> <tr><td class='commitgraph'>* </td><td><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/commit/graphics/jpeg?h=mate-1.16&id=05c262ec6dc08ca02aadad52c711366528feacb5'>- add missing patch</a></td><td>dinoex</td><td><span title='2008-08-13 16:23:08 +0800'>2008-08-13</span></td><td>2</td><td><span class='deletions'>-1</span>/<span class='insertions'>+16</span></td></tr> <tr><td class='commitgraph'>* </td><td><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/commit/graphics/jpeg?h=mate-1.16&id=3af35f874a74a4cf7c67024069b8f035195b2d6b'>- fix autoconf problems with jconfig.h</a></td><td>dinoex</td><td><span title='2008-08-12 22:06:38 +0800'>2008-08-12</span></td><td>2</td><td><span class='deletions'>-21</span>/<span class='insertions'>+1</span></td></tr> <tr><td class='commitgraph'>* </td><td><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/commit/graphics/jpeg?h=mate-1.16&id=9929e6e40636a78e9661aef68f9f1e93ffb87913'>- fix HAVE_STDLIB_H macrosA</a></td><td>dinoex</td><td><span title='2008-08-10 15:14:59 +0800'>2008-08-10</span></td><td>2</td><td><span class='deletions'>-6</span>/<span class='insertions'>+38</span></td></tr> <tr><td class='commitgraph'>* </td><td><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/commit/graphics/jpeg?h=mate-1.16&id=5bf1579122d94b9783858f1030b06a3c5ad1b325'>- use USE_LDCONFIG</a></td><td>dinoex</td><td><span title='2007-01-13 12:53:26 +0800'>2007-01-13</span></td><td>1</td><td><span class='deletions'>-1</span>/<span class='insertions'>+1</span></td></tr> <tr><td class='commitgraph'>* </td><td><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/commit/graphics/jpeg?h=mate-1.16&id=da880765886f48c0ac8fd253e5601d04ea853215'>Conversion to a single libtool environment.</a></td><td>ade</td><td><span title='2006-02-23 18:40:44 +0800'>2006-02-23</span></td><td>3</td><td><span class='deletions'>-14</span>/<span class='insertions'>+10</span></td></tr> <tr><td class='commitgraph'>* </td><td><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/commit/graphics/jpeg?h=mate-1.16&id=8d9d5197561118544281733430b48b0b60884450'>Mass-conversion to the USE_AUTOTOOLS New World Order. The code present</a></td><td>ade</td><td><span title='2005-11-15 14:52:12 +0800'>2005-11-15</span></td><td>1</td><td><span class='deletions'>-1</span>/<span class='insertions'>+1</span></td></tr> <tr><td class='commitgraph'>* </td><td><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/commit/graphics/jpeg?h=mate-1.16&id=20ae5d21784290841c477193a9c33b1732557dd5'>- add SHA checksum</a></td><td>dinoex</td><td><span title='2005-11-13 17:26:50 +0800'>2005-11-13</span></td><td>1</td><td><span class='deletions'>-0</span>/<span class='insertions'>+3</span></td></tr>