/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ /* e-local-folder.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 */ /* The metafile goes like this: mail This is the folder where I store mail from my gf http://www.somewhere.net FIXME: Do we want to use a namespace for this? FIXME: Do we want to have an internationalized description? */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include "e-util/e-util.h" #include "e-util/e-xml-utils.h" #include "e-local-folder.h" #define PARENT_TYPE E_TYPE_FOLDER static EFolderClass *parent_class = NULL; #define URI_PREFIX "file://" #define URI_PREFIX_LEN 7 #define METADATA_FILE_NAME "folder-metadata.xml" #define METADATA_FILE_NAME_LEN 19 struct _ELocalFolderPrivate { int dummy; }; static char * get_string_value (xmlNode *node, const char *name) { xmlNode *p; xmlChar *xml_string; char *retval; p = e_xml_get_child_by_name (node, (xmlChar *) name); if (p == NULL) return NULL; p = e_xml_get_child_by_name (p, (xmlChar *) "text"); if (p == NULL) return NULL; xml_string = xmlNodeListGetString (node->doc, p, 1); retval = g_strdup ((char *) xml_string); xmlFree (xml_string); return retval; } static gboolean construct_loading_metadata (ELocalFolder *local_folder, const char *path) { EFolder *folder; xmlDoc *doc; xmlNode *root; char *type; char *description; char *metadata_path; char *physical_uri; folder = E_FOLDER (local_folder); metadata_path = g_concat_dir_and_file (path, METADATA_FILE_NAME); doc = xmlParseFile (metadata_path); if (doc == NULL) { g_free (metadata_path); return FALSE; } root = xmlDocGetRootElement (doc); if (root == NULL || strcmp (root->name, "efolder") != 0) { g_free (metadata_path); xmlFreeDoc (doc); return FALSE; } type = get_string_value (root, "type"); description = get_string_value (root, "description"); e_folder_construct (folder, g_basename (path), type, description); g_free (type); g_free (description); xmlFreeDoc (doc); physical_uri = g_strconcat (URI_PREFIX, path, NULL); e_folder_set_physical_uri (folder, physical_uri); g_free (physical_uri); g_free (metadata_path); return TRUE; } static gboolean save_metadata (ELocalFolder *local_folder) { EFolder *folder; xmlDoc *doc; xmlNode *root; const char *physical_directory; char *physical_path; folder = E_FOLDER (local_folder); doc = xmlNewDoc ((xmlChar *) "1.0"); root = xmlNewDocNode (doc, NULL, (xmlChar *) "efolder", NULL); xmlDocSetRootElement (doc, root); xmlNewChild (root, NULL, (xmlChar *) "type", (xmlChar *) e_folder_get_type_string (folder)); if (e_folder_get_description (folder) != NULL) xmlNewChild (root, NULL, (xmlChar *) "description", (xmlChar *) e_folder_get_description (folder)); physical_directory = e_folder_get_physical_uri (folder) + URI_PREFIX_LEN - 1; physical_path = g_concat_dir_and_file (physical_directory, METADATA_FILE_NAME); if (xmlSaveFile (physical_path, doc) < 0) { unlink (physical_path); g_free (physical_path); xmlFreeDoc (doc); return FALSE; } g_free (physical_path); xmlFreeDoc (doc); return TRUE; } /* GtkObject methods. */ static void destroy (GtkObject *object) { /* No ELocalFolder-specific data to free. */ (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); } static void class_init (ELocalFolderClass *klass) { GtkObjectClass *object_class; parent_class = gtk_type_class (e_folder_get_type ()); object_class = GTK_OBJECT_CLASS (klass); object_class->destroy = destroy; } static void init (ELocalFolder *local_folder) { } void e_local_folder_construct (ELocalFolder *local_folder, const char *name, const char *type, const char *description) { g_return_if_fail (local_folder != NULL); g_return_if_fail (E_IS_LOCAL_FOLDER (local_folder)); g_return_if_fail (name != NULL); g_return_if_fail (type != NULL); e_folder_construct (E_FOLDER (local_folder), name, type, description); } EFolder * e_local_folder_new (const char *name, const char *type, const char *description) { ELocalFolder *local_folder; g_return_val_if_fail (name != NULL, NULL); g_return_val_if_fail (type != NULL, NULL); local_folder = gtk_type_new (e_local_folder_get_type ()); e_local_folder_construct (local_folder, name, type, description); return E_FOLDER (local_folder); } EFolder * e_local_folder_new_from_path (const char *path) { EFolder *folder; g_return_val_if_fail (g_path_is_absolute (path), NULL); folder = gtk_type_new (e_local_folder_get_type ()); if (! construct_loading_metadata (E_LOCAL_FOLDER (folder), path)) { gtk_object_unref (GTK_OBJECT (folder)); return NULL; } return folder; } gboolean e_local_folder_save (ELocalFolder *local_folder) { g_return_val_if_fail (local_folder != NULL, FALSE); g_return_val_if_fail (E_IS_LOCAL_FOLDER (local_folder), FALSE); g_return_val_if_fail (e_folder_get_physical_uri (E_FOLDER (local_folder)) != NULL, FALSE); return save_metadata (local_folder); } E_MAKE_TYPE (e_local_folder, "ELocalFolder", ELocalFolder, class_init, init, PARENT_TYPE) td>1-95/+203 * (Fix bug #934: Add Right-click item to hide the shortcut bar)Jason Leach2001-01-145-4/+64 * Initial steps to support Drag 'n Drop in the tree view.Ettore Perazzoli2001-01-145-115/+255 * Unref our copy, and then destroy.Miguel de Icaza2001-01-133-0/+19 * Ok, talked to Ettore. Going back to TOPLEVEL non-POPUP.Miguel de Icaza2001-01-131-1/+1 * Ok, talked to Ettore. Going back to TOPLEVEL non-POPUP.Miguel de Icaza2001-01-131-4/+6 * Add an ::asyncCopyFolder method to the ShellComponent interface. MoveEttore Perazzoli2001-01-134-6/+80 * Remove nice toplevel window.Miguel de Icaza2001-01-132-1/+5 * Minor comment fixup.Ettore Perazzoli2001-01-131-1/+1 * Rename `::addFolderAsync' into `::createFolderAsync'.Ettore Perazzoli2001-01-134-10/+21 * CreateDan Winship2001-01-132-0/+14 * Added translation strings.Miguel de Icaza2001-01-123-4/+14 * Remove "window" from the moniker path.Miguel de Icaza2001-01-123-2/+10 * More fixesIain Holmes2001-01-121-0/+5 * Some warnings cleanupsIain Holmes2001-01-123-8/+4 * Typo! Doh!Iain Holmes2001-01-121-1/+1 * Fix make distIain Holmes2001-01-121-1/+1 * Fix prototype (command_new_view): ditto. (command_new_mail_message):Miguel de Icaza2001-01-122-1/+18 * Remove the "Already have view for..." message. People keep assuming it'sDan Winship2001-01-122-2/+5 * Will it work?Iain Holmes2001-01-123-4/+3 * add the importer part 1Iain Holmes2001-01-1214-1/+1815 * Fix prototype (command_new_view): ditto.Miguel de Icaza2001-01-102-18/+25 * New function to update a folder given its URI. Plus associated changes toDan Winship2001-01-053-27/+82 * Fix a bug in `evolution_shell_client_user_select_folder()' that couldEttore Perazzoli2000-12-292-8/+13 * Fix a crash when the user tries to "Submit bug report" but doesn't haveJason Leach2000-12-263-4/+17 * Destroy the dialog after a double click.Iain Holmes2000-12-152-1/+4 * Change the function to have the same signature as the double click callback.Iain Holmes2000-12-142-0/+9 * Slightly updated the startup warning message for the release.Ettore Perazzoli2000-12-142-2/+7 * Update the splash animation to fit with the new splash design.Ettore Perazzoli2000-12-142-1/+5 * Return TRUE as we have handled the event.Jeffrey Stedfast2000-12-132-0/+7 * Pass path+1 rather than path to get_type_for_storage, to match theDan Winship2000-12-132-1/+7 * Connect a button-press-event signal on the splash screen so users canJeffrey Stedfast2000-12-122-1/+18 * return NULL if no {folder,storage} is found. (get_control_for_uri): returnDan Winship2000-12-122-1/+13 * Complete the code to associate a URI and a folder type to the toplevelEttore Perazzoli2000-12-0916-106/+288 * update to GNOME_Evolution_Shell.oafinfoMichael Meeks2000-12-085-4/+10 * Start implementing a physical URI property for the toplevel nodes inEttore Perazzoli2000-12-0516-43/+187 * Handle a NIL return value from `oaf_activate_from_id' withoutEttore Perazzoli2000-12-052-1/+8 * return NULL if we can't create a view.Michael Meeks2000-12-052-1/+12 * New `createNewView' method in `Evolution::Shell'. Register the shellEttore Perazzoli2000-12-0512-81/+296 * removed #ifdef ENABLE_NLS/#endif on Miguel's request.Gediminas Paulauskas2000-11-301-2/+0 * Update - hopefully I assigned blame correctly :-)JP Rosevear2000-11-282-0/+7 * de-register a component's UI if it dies.Michael Meeks2000-11-282-0/+10 * Install Evolution IDL's into datadir/idl.Peter Williams2000-11-262-0/+10 * Plug leaks of the fullname and fulldefaultname.Federico Mena Quintero2000-11-255-33/+57 * Plug leak; mark the CORBA sequence so that it will be released.Federico Mena Quintero2000-11-252-0/+7 * add (e_shell_view_construct): hook up to system_exception on ui_container.Michael Meeks2000-11-142-0/+22 * Update the remaining "IDL:Evolution*" to "IDL:GNOME/Evolution*" to sync upMatt Bissiri2000-11-113-3/+10 * A very, long, very tedious IDL API rename and re-scoping;Michael Meeks2000-11-1138-466/+475 * Make the panes of the EPaned not shrinkable beyond their minimum size.Christopher James Lahey2000-11-092-4/+9 * Fix typo in a comment.Matt Bissiri2000-11-082-1/+5 * Pass full_name, not folder_name to callback.Dan Winship2000-11-082-1/+6 * Fixed a couple of warnings.Ettore Perazzoli2000-11-072-5/+11 * Make the shell pop-up a warning dialog per component when a componentEttore Perazzoli2000-11-074-5/+81 * Fixed a missing `CORBA_Object_duplicate()' problem. This should fixEttore Perazzoli2000-11-072-1/+6 * Added #include <config.h>Kjartan Maraas2000-11-072-0/+8 * Added a `--no-splash' option to the shell.Ettore Perazzoli2000-11-044-20/+60 * Fix the name of the signal passed to gtk_signal_new so that this actuallyDan Winship2000-11-042-1/+6 * The big api rename ...Michael Meeks2000-11-025-13/+13 * Make this take "highlighted" as well.Dan Winship2000-11-026-4/+20 * Moving the executive summarys now :)Iain Holmes2000-11-025-0/+100 * Add "highligted" field to Folder. Add update_folder method toDan Winship2000-11-0218-61/+373 * modified or added a bunch of .cvsignore to ignore generated files, whichGediminas Paulauskas2000-11-011-0/+2 * No longer include <db.h>52000-10-262-1/+6 * AM_GNOME_GETTEXT doesn't use $(datadir)/locale as the locale dir. (ItDan Winship2000-10-242-1/+5 * update to new UI handlerMichael Meeks2000-10-217-20/+28 * If there is no view save the default uri instead. (socket_destroy_cb):Iain Holmes2000-10-202-1/+10 * update for new UI handler.Michael Meeks2000-10-193-6/+11 * If the widget is not realized don't do anything, to prevent BadGC's atIain Holmes2000-10-193-2/+40 * Save the settings before the view is destroyed. (e_shell_quit): Don't saveIain Holmes2000-10-184-31/+57 * Add a typecast.Dan Winship2000-10-177-6/+25 * Check if there are any files in default_user that are not in ~/evolutionIain Holmes2000-10-165-3/+162 * Use an EScrollFrame instead of a GtkScrolledWindow for the folderEttore Perazzoli2000-10-152-41/+39 * if we are in LDAP mode then merge in the extra few items, otherwise justMichael Meeks2000-10-151-1/+1 * 31337 splash screen for the shell's startup sequence.Ettore Perazzoli2000-10-155-5/+549 * *e-shell-folder-creation-dialog.glade: Added focus to the folder-name textAnna Marie Dirks2000-10-143-0/+6 * Fixed the spec on this.Christopher James Lahey2000-10-112-2/+6 * Changed this to use the built in cells.Christopher James Lahey2000-10-112-17/+7 * Adapted this for the new ETable system.Christopher James Lahey2000-10-112-14/+16 * Change paths in such a way as to require HEAD bonobo.Michael Meeks2000-10-092-2/+15 * initialize priv->sockets to NULL, fixes startup crash on non-ia32Matt Wilson2000-10-082-0/+6 * Backported (from EVOLUTION_0_5_1) the code that allowed the shell toEttore Perazzoli2000-10-072-3/+109 * call _set_compare_function after inserting the storage.Chris Toshok2000-10-072-0/+6 * add a freeze / thaw pair to reduce flicker on switching controls.Michael Meeks2000-10-063-11/+15 * #include <gal/widgets/e-gui-utils.h>Chris Toshok2000-10-063-3/+8 * add #include for libgnomeui/gnome-messagebox.hChris Toshok2000-10-062-0/+6 * Disable summary stuff, it appears to be badly broken.Michael Meeks2000-10-055-75/+83 * ui/evolution-addressbook-ldap.xml, ui/evolution-addressbook.xml,Matt Bissiri2000-10-042-3/+15 * remove evil usize set.Michael Meeks2000-10-042-1/+4 * Fixed a bug that caused the "Create new shortcut group" dialog not toEttore Perazzoli2000-10-032-0/+7 * if we're not displaying folders, the current folder is NULL. (class_init):Chris Toshok2000-10-033-3/+16 * add storage_selected behavior - loop over the listeners callingChris Toshok2000-10-037-6/+96 * `EvolutionStorageSetViewListener', wrapper for the CORBAEttore Perazzoli2000-10-034-0/+353 * fix typo. (impl_StorageSetView_remove_listener): same.Chris Toshok2000-10-035-29/+143 * pass storage_set_view_interface as second argument toChris Toshok2000-10-032-1/+10 * kill.Michael Meeks2000-10-033-66/+77 * set the new node's compare function. (insert_folders): same.Chris Toshok2000-10-032-2/+11 * track e-tree sort api change. (treepath_compare): same. (new_folder_cb):Chris Toshok2000-10-032-10/+13 * pass NULL for the open/closed pixbuf of the tree renderer. we'll let itChris Toshok2000-10-032-21/+21 * Added the ability for the shell to export the storage set view as aEttore Perazzoli2000-10-0210-5/+583 * Add a `::remove_listener' method to Evolution::Storage.Ettore Perazzoli2000-10-023-7/+101 * Get the title bar for the folder view to use TigerT's pin icon for theEttore Perazzoli2000-09-292-10/+26 * Minor stylistical fixup.Ettore Perazzoli2000-09-291-2/+4 * Don't print "Folder registered successfully" if it didn't. (Duh. :)Dan Winship2000-09-292-3/+7 * If the startup folder cannot be open, default to the local Inbox.Ettore Perazzoli2000-09-282-5/+12 * Fix a bunch of EShortcutView problems. It's still buggy, but at leastEttore Perazzoli2000-09-274-19/+147 * Update the shortcut bar in the shell view to match the changes in theEttore Perazzoli2000-09-267-158/+431 * Fix a refcounting problem with the local storage. ("Somebody" added aEttore Perazzoli2000-09-252-2/+4 * Updates for the Bonobo changes from Michael who is having someEttore Perazzoli2000-09-233-19/+14 * Dear native speakers,Federico Mena Quintero2000-09-222-1/+5 * s/Bonobo_UIHandler/Bonobo_UIContainer/Michael Meeks2000-09-218-7/+35 * Added check for gnome-app-lib. Removed directories that have been moved toChristopher James Lahey2000-09-1829-42/+59 * Everywhere add a -DEVOLUTION_DATADIR=${datadir} in the Makefile.amMichael Meeks2000-09-172-1/+6 * #include <bonobo-win.h>, not <bonobo-app.h>, which doesn't existEttore Perazzoli2000-09-162-1/+5 * foreach_data should be set to the caller-supplied data, not the tree itemDan Winship2000-09-152-4/+9 * Fixed bug #536 Popup folder tree button doesn't expandIain Holmes2000-09-152-4/+6 * add bonobo_ui_handler_unset_container to stop menus screwing up.Michael Meeks2000-09-142-2/+6 * Move a couple of helpers into Bonobo before more people start the re-buildMichael Meeks2000-09-142-18/+4 * Added $(GNOME_PRINT_LIBS) to evolution_LDADD.Christopher James Lahey2000-09-142-0/+5 * Get the status bar playing ball.Michael Meeks2000-09-142-31/+50 * re-order to suit and add freeze / thaw, update paths to toggles, removeMichael Meeks2000-09-142-16/+23 * The Commit from hell that breaks all UI related stuff;Michael Meeks2000-09-148-288/+213 * Make the pop-up folder bar pop down after a folder is selected.Ettore Perazzoli2000-09-132-5/+24 * Thou shalt add a space after `-I' when invoking `orbit-idl'.Ettore Perazzoli2000-09-132-1/+6 * Little UTF-8 fixLauris Kaplinski2000-09-132-2/+10 * Remove ui.xml stuff which was breaking distcheck.Ettore Perazzoli2000-09-132-4/+5 * Tidy some xml.Michael Meeks2000-09-131-105/+0 * Initialize libunicodeDan Winship2000-09-122-1/+6 * Fixed some warnings.Christopher James Lahey2000-09-122-2/+6 * Fix some annoying warnings in the folder selection dialog.Ettore Perazzoli2000-09-122-2/+12 * Remove debugging message.Ettore Perazzoli2000-09-122-2/+4 * Make `EvolutionStorage' and `ELocalstorage' actually update the CORBAEttore Perazzoli2000-09-127-14/+103 * Grmpf.Ettore Perazzoli2000-09-111-1/+1 * Unset the `GTK_FLOATING' flag when constructing anEttore Perazzoli2000-09-112-0/+8 * Fully support setting the display name in the tree. It seems to work.Ettore Perazzoli2000-09-115-81/+155 * Use the name of the storage or the folder in the storage set view,Ettore Perazzoli2000-09-103-5/+26 * Fixed some warnings.Christopher James Lahey2000-09-102-1/+6 * Fix a possible crash when viewing no folder.Ettore Perazzoli2000-09-102-1/+6 * Some UTF-8 fixes and experimental 16-bit unicode font supportLauris Kaplinski2000-09-092-1/+6 * Fix a stupid crash caused by not taking account of the fact that theEttore Perazzoli2000-09-092-0/+9 * Fix `e_folder_tree_get_folder()' so that it returns NULL (instead ofEttore Perazzoli2000-09-092-0/+8 * Make EvolutionStorage support multiple listeners.Ettore Perazzoli2000-09-092-28/+116 * Implemented a new `EFolderTree' object. Make `EStorage' use itEttore Perazzoli2000-09-096-187/+522 * Fix Chris' fixes.Ettore Perazzoli2000-09-093-6/+14 * Added base ETableModel functions.Christopher James Lahey2000-09-094-4/+62 * Changed so that ::set_owner is called after setting up the localEttore Perazzoli2000-09-085-19/+92 * Ooops, I did not mean to add those.Ettore Perazzoli2000-09-082-283/+0 * A simple explanation of what is going on here, as it's easy to getEttore Perazzoli2000-09-081-0/+14 * Added new interfaces to be exposed by the local storage, so thatEttore Perazzoli2000-09-0820-54/+1240 * Preliminaries for new UI handler.Michael Meeks2000-09-082-3/+109 * A bit more e_utf8 wrappers here and thereLauris Kaplinski2000-09-022-2/+8 * free node_data. (removed_storage_cb): same. (new_storage_cb): don't freeChris Toshok2000-09-021-0/+9 * free node_data. (removed_storage_cb): same. (new_storage_cb): don't freeChris Toshok2000-09-021-12/+8 * Strdup path when setting the callback data.Christopher James Lahey2000-09-023-2/+7 * initialize delayed_selection = NULL;Chris Toshok2000-09-012-0/+5 * Changed `Evolution::Storage' so that the displayed name for a folderEttore Perazzoli2000-09-017-37/+62 * add delayed_selection to _EShellViewPrivate. (new_folder_cb): newChris Toshok2000-09-012-0/+59 * Strip off newlines when setting the messages in the statusbar, so thatEttore Perazzoli2000-08-292-3/+22 * Make the shell start up components through a OAF query forEttore Perazzoli2000-08-283-13/+96 * convert to use ETree instead of GtkCTree.Chris Toshok2000-08-26