[almanah] Add text file and database export support
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [almanah] Add text file and database export support
- Date: Wed, 21 Apr 2010 20:50:50 +0000 (UTC)
commit 446ac9684147a484309ff99ec59d8bb798f01f5f
Author: Philip Withnall <philip tecnocode co uk>
Date: Wed Apr 21 21:44:11 2010 +0100
Add text file and database export support
data/almanah.ui | 8 ++
src/import-export-dialog.c | 164 +++++++++++++++++++++++++++++++++++++++-----
src/main-window.c | 11 +++
src/main.c | 2 +
src/main.h | 1 +
src/storage-manager.c | 6 ++
src/storage-manager.h | 2 +
7 files changed, 177 insertions(+), 17 deletions(-)
---
diff --git a/data/almanah.ui b/data/almanah.ui
index f7a106b..f053073 100644
--- a/data/almanah.ui
+++ b/data/almanah.ui
@@ -17,6 +17,13 @@
</object>
</child>
<child>
+ <object class="GtkAction" id="almanah_ui_export">
+ <property name="name">file-export</property>
+ <property name="label" translatable="yes">_Exportâ?¦</property>
+ <signal name="activate" handler="mw_export_activate_cb"/>
+ </object>
+ </child>
+ <child>
<object class="GtkAction" id="almanah_ui_page_setup">
<property name="stock-id">gtk-page-setup</property>
<property name="name">file-page-setup</property>
@@ -221,6 +228,7 @@
<menubar name="almanah_mw_menu_bar">
<menu action="almanah_ui_file">
<menuitem action="almanah_ui_import"/>
+ <menuitem action="almanah_ui_export"/>
<separator/>
<menuitem action="almanah_ui_page_setup"/>
<menuitem action="almanah_ui_print_preview"/>
diff --git a/src/import-export-dialog.c b/src/import-export-dialog.c
index ad252ee..e35e680 100644
--- a/src/import-export-dialog.c
+++ b/src/import-export-dialog.c
@@ -28,27 +28,38 @@
#include "main-window.h"
typedef gboolean (*ImportFunc) (AlmanahImportExportDialog *self, AlmanahImportResultsDialog *results_dialog, GError **error);
+typedef gboolean (*ExportFunc) (AlmanahImportExportDialog *self, GError **error);
typedef struct {
const gchar *name; /* translatable */
const gchar *import_description; /* translatable */
- GtkFileChooserAction import_action;
+ const gchar *export_description; /* translatable */
+ GtkFileChooserAction action;
ImportFunc import_func;
+ ExportFunc export_func;
} ImportExportModeDetails;
static gboolean import_text_files (AlmanahImportExportDialog *self, AlmanahImportResultsDialog *results_dialog, GError **error);
+static gboolean export_text_files (AlmanahImportExportDialog *self, GError **error);
+
static gboolean import_database (AlmanahImportExportDialog *self, AlmanahImportResultsDialog *results_dialog, GError **error);
+static gboolean export_database (AlmanahImportExportDialog *self, GError **error);
static const ImportExportModeDetails import_export_modes[] = {
{ N_("Text Files"),
N_("Select a folder containing text files, one per entry, with names in the format 'yyyy-mm-dd', and no extension. "
"Any and all such files will be imported."),
+ N_("Select a folder to export the entries to as text files, one per entry, with names in the format 'yyyy-mm-dd', and no extension. "
+ "All entries will be exported, unencrypted in plain text format."),
GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
- import_text_files },
+ import_text_files,
+ export_text_files },
{ N_("Database"),
N_("Select a database file created by Almanah Diary to import."),
+ N_("Select a filename for a complete copy of the unencrypted Almanah Diary database to be given."),
GTK_FILE_CHOOSER_ACTION_OPEN,
- import_database }
+ import_database,
+ export_database }
};
static void response_cb (GtkDialog *dialog, gint response_id, AlmanahImportExportDialog *self);
@@ -59,6 +70,7 @@ void ied_file_chooser_selection_changed_cb (GtkFileChooser *file_chooser, Almana
void ied_file_chooser_file_activated_cb (GtkFileChooser *file_chooser, AlmanahImportExportDialog *self);
struct _AlmanahImportExportDialogPrivate {
+ gboolean import; /* TRUE if we're in import mode, FALSE otherwise */
GtkComboBox *mode_combo_box;
GtkListStore *mode_store;
guint current_mode; /* index into import_export_modes */
@@ -153,6 +165,7 @@ almanah_import_export_dialog_new (gboolean import)
}
priv = import_export_dialog->priv;
+ priv->import = import;
/* Grab our child widgets */
priv->mode_combo_box = GTK_COMBO_BOX (gtk_builder_get_object (builder, "almanah_ied_mode_combo_box"));
@@ -351,7 +364,7 @@ import_text_files (AlmanahImportExportDialog *self, AlmanahImportResultsDialog *
g_assert (file != NULL);
/* Load the content */
- if (g_file_load_contents (file, NULL, &contents, &length, NULL, error) == FALSE) {
+ if (g_file_load_contents (file, NULL, &contents, &length, NULL, &child_error) == FALSE) {
g_object_unref (file);
g_object_unref (file_info);
break; /* let the error get handled by the code just after the loop */
@@ -393,6 +406,80 @@ finish:
}
static gboolean
+export_text_files (AlmanahImportExportDialog *self, GError **error)
+{
+ AlmanahImportExportDialogPrivate *priv = self->priv;
+ GFile *folder;
+ GSList *entries;
+ GtkTextBuffer *buffer;
+ gboolean success = FALSE;
+ GError *child_error = NULL;
+
+ /* Get the output folder */
+ folder = gtk_file_chooser_get_file (priv->file_chooser);
+ g_assert (folder != NULL);
+
+ /* Build a text buffer to use when getting all the entries */
+ buffer = gtk_text_buffer_new (NULL);
+
+ /* Get the list of entries */
+ entries = almanah_storage_manager_get_entries (almanah->storage_manager);
+
+ for (; entries != NULL; entries = g_slist_delete_link (entries, entries)) {
+ AlmanahEntry *entry = ALMANAH_ENTRY (entries->data);
+ GDate date;
+ gchar *filename, *content;
+ GFile *file;
+ GtkTextIter start_iter, end_iter;
+
+ /* Get the filename */
+ almanah_entry_get_date (entry, &date);
+ filename = g_strdup_printf ("%04u-%02u-%02u", g_date_get_year (&date), g_date_get_month (&date), g_date_get_day (&date));
+ file = g_file_get_child (folder, filename);
+ g_free (filename);
+
+ /* Get the entry contents */
+ if (almanah_entry_get_content (entry, buffer, TRUE, &child_error) == FALSE) {
+ /* Error */
+ g_object_unref (file);
+ g_object_unref (entry);
+ break;
+ }
+
+ g_object_unref (entry);
+
+ gtk_text_buffer_get_bounds (buffer, &start_iter, &end_iter);
+ content = gtk_text_buffer_get_text (buffer, &start_iter, &end_iter, FALSE);
+
+ /* Create the file */
+ if (g_file_replace_contents (file, content, strlen (content), NULL, FALSE,
+ G_FILE_CREATE_PRIVATE | G_FILE_CREATE_REPLACE_DESTINATION, NULL, NULL, &child_error) == FALSE) {
+ /* Error */
+ g_object_unref (file);
+ g_free (content);
+ break;
+ }
+
+ g_object_unref (file);
+ g_free (content);
+ }
+
+ /* Check if the loop was broken due to an error */
+ if (child_error != NULL) {
+ g_propagate_error (error, child_error);
+ goto finish;
+ }
+
+ success = TRUE;
+
+finish:
+ g_object_unref (folder);
+ g_object_unref (buffer);
+
+ return success;
+}
+
+static gboolean
import_database (AlmanahImportExportDialog *self, AlmanahImportResultsDialog *results_dialog, GError **error)
{
GFile *file;
@@ -457,12 +544,35 @@ import_database (AlmanahImportExportDialog *self, AlmanahImportResultsDialog *re
return TRUE;
}
+static gboolean
+export_database (AlmanahImportExportDialog *self, GError **error)
+{
+ AlmanahImportExportDialogPrivate *priv = self->priv;
+ GFile *source, *destination;
+ gboolean success;
+
+ /* Get the output file */
+ destination = gtk_file_chooser_get_file (priv->file_chooser);
+ g_assert (destination != NULL);
+
+ /* Get the input file (current unencrypted database) */
+ source = g_file_new_for_path (almanah_storage_manager_get_filename (almanah->storage_manager, TRUE));
+
+ /* Copy the current database to that location */
+ success = g_file_copy (source, destination, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, error);
+
+ g_object_unref (source);
+ g_object_unref (destination);
+
+ return success;
+}
+
static void
response_cb (GtkDialog *dialog, gint response_id, AlmanahImportExportDialog *self)
{
GError *error = NULL;
AlmanahImportExportDialogPrivate *priv = self->priv;
- AlmanahImportResultsDialog *results_dialog;
+ AlmanahImportResultsDialog *results_dialog = NULL; /* shut up, gcc */
/* Just return if the user pressed Cancel */
if (response_id != GTK_RESPONSE_OK) {
@@ -470,16 +580,21 @@ response_cb (GtkDialog *dialog, gint response_id, AlmanahImportExportDialog *sel
return;
}
- /* Import the entries according to the selected method. It's OK if we block here, since the dialogue should
- * be running in its own main loop. */
- results_dialog = almanah_import_results_dialog_new ();
- import_export_modes[priv->current_mode].import_func (self, results_dialog, &error);
+ if (priv->import == TRUE) {
+ /* Import the entries according to the selected method.
+ * It's OK if we block, since the dialogue should be running in its own main loop. */
+ results_dialog = almanah_import_results_dialog_new ();
+ import_export_modes[priv->current_mode].import_func (self, results_dialog, &error);
+ } else {
+ /* Export the entries according to the selected method. */
+ import_export_modes[priv->current_mode].export_func (self, &error);
+ }
/* Check for errors (e.g. errors opening databases or files; not errors importing individual entries once we have the content to import) */
if (error != NULL) {
/* Show an error */
GtkWidget *error_dialog = gtk_message_dialog_new (GTK_WINDOW (self), GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR,
- GTK_BUTTONS_OK, _("Import failed"));
+ GTK_BUTTONS_OK, (priv->import == TRUE) ? _("Import failed") : _("Export failed"));
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (error_dialog), "%s", error->message);
gtk_dialog_run (GTK_DIALOG (error_dialog));
gtk_widget_destroy (error_dialog);
@@ -488,13 +603,26 @@ response_cb (GtkDialog *dialog, gint response_id, AlmanahImportExportDialog *sel
gtk_widget_hide (GTK_WIDGET (self));
} else {
- /* Show the results dialogue */
- gtk_widget_hide (GTK_WIDGET (self));
- gtk_widget_show_all (GTK_WIDGET (results_dialog));
- gtk_dialog_run (GTK_DIALOG (results_dialog));
+ if (priv->import == TRUE) {
+ /* Show the results dialogue */
+ gtk_widget_hide (GTK_WIDGET (self));
+ gtk_widget_show_all (GTK_WIDGET (results_dialog));
+ gtk_dialog_run (GTK_DIALOG (results_dialog));
+ } else {
+ /* Show a success message */
+ GtkWidget *message_dialog;
+
+ gtk_widget_hide (GTK_WIDGET (self));
+ message_dialog = gtk_message_dialog_new (GTK_WINDOW (self), GTK_DIALOG_MODAL, GTK_MESSAGE_INFO,
+ GTK_BUTTONS_OK, _("Export successful"));
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (message_dialog), _("The diary was successfully exported."));
+ gtk_dialog_run (GTK_DIALOG (message_dialog));
+ gtk_widget_destroy (message_dialog);
+ }
}
- gtk_widget_destroy (GTK_WIDGET (results_dialog));
+ if (priv->import == TRUE)
+ gtk_widget_destroy (GTK_WIDGET (results_dialog));
}
void
@@ -510,8 +638,10 @@ ied_mode_combo_box_changed_cb (GtkComboBox *combo_box, AlmanahImportExportDialog
priv->current_mode = new_mode;
/* Change the dialogue */
- gtk_file_chooser_set_action (priv->file_chooser, import_export_modes[priv->current_mode].import_action);
- gtk_label_set_text (priv->description_label, _(import_export_modes[priv->current_mode].import_description));
+ gtk_file_chooser_set_action (priv->file_chooser, import_export_modes[priv->current_mode].action);
+ gtk_label_set_text (priv->description_label,
+ (priv->import == TRUE) ? _(import_export_modes[priv->current_mode].import_description)
+ : _(import_export_modes[priv->current_mode].export_description));
}
void
diff --git a/src/main-window.c b/src/main-window.c
index 1dd00fc..98595e5 100644
--- a/src/main-window.c
+++ b/src/main-window.c
@@ -63,6 +63,7 @@ static void mw_definition_removed_cb (AlmanahStorageManager *storage_manager, co
/* GtkBuilder callbacks */
void mw_calendar_day_selected_cb (GtkCalendar *calendar, AlmanahMainWindow *main_window);
void mw_import_activate_cb (GtkAction *action, AlmanahMainWindow *main_window);
+void mw_export_activate_cb (GtkAction *action, AlmanahMainWindow *main_window);
void mw_page_setup_activate_cb (GtkAction *action, AlmanahMainWindow *main_window);
void mw_print_preview_activate_cb (GtkAction *action, AlmanahMainWindow *main_window);
void mw_print_activate_cb (GtkAction *action, AlmanahMainWindow *main_window);
@@ -697,6 +698,16 @@ mw_import_activate_cb (GtkAction *action, AlmanahMainWindow *main_window)
}
void
+mw_export_activate_cb (GtkAction *action, AlmanahMainWindow *main_window)
+{
+ if (almanah->export_dialog == NULL)
+ almanah->export_dialog = GTK_WIDGET (almanah_import_export_dialog_new (FALSE));
+
+ gtk_widget_show_all (almanah->export_dialog);
+ gtk_dialog_run (GTK_DIALOG (almanah->export_dialog));
+}
+
+void
mw_page_setup_activate_cb (GtkAction *action, AlmanahMainWindow *main_window)
{
almanah_print_page_setup ();
diff --git a/src/main.c b/src/main.c
index 5c5e0de..b208397 100644
--- a/src/main.c
+++ b/src/main.c
@@ -75,6 +75,8 @@ almanah_quit (void)
gtk_widget_destroy (almanah->date_entry_dialog);
if (almanah->import_dialog != NULL)
gtk_widget_destroy (almanah->import_dialog);
+ if (almanah->export_dialog != NULL)
+ gtk_widget_destroy (almanah->export_dialog);
#ifdef ENABLE_ENCRYPTION
if (almanah->preferences_dialog != NULL)
gtk_widget_destroy (almanah->preferences_dialog);
diff --git a/src/main.h b/src/main.h
index 8010a97..085c3df 100644
--- a/src/main.h
+++ b/src/main.h
@@ -47,6 +47,7 @@ typedef struct {
GtkWidget *date_entry_dialog;
GtkWidget *definition_manager_window;
GtkWidget *import_dialog;
+ GtkWidget *export_dialog;
#ifdef ENABLE_ENCRYPTION
GtkWidget *preferences_dialog;
#endif /* ENABLE_ENCRYPTION */
diff --git a/src/storage-manager.c b/src/storage-manager.c
index f012394..845f544 100644
--- a/src/storage-manager.c
+++ b/src/storage-manager.c
@@ -1160,3 +1160,9 @@ almanah_storage_manager_remove_definition (AlmanahStorageManager *self, const gc
return FALSE;
}
+
+const gchar *
+almanah_storage_manager_get_filename (AlmanahStorageManager *self, gboolean plain)
+{
+ return (plain == TRUE) ? self->priv->plain_filename : self->priv->filename;
+}
diff --git a/src/storage-manager.h b/src/storage-manager.h
index 46a770d..ad09d08 100644
--- a/src/storage-manager.h
+++ b/src/storage-manager.h
@@ -93,6 +93,8 @@ AlmanahDefinition *almanah_storage_manager_get_definition (AlmanahStorageManager
gboolean almanah_storage_manager_add_definition (AlmanahStorageManager *self, AlmanahDefinition *definition);
gboolean almanah_storage_manager_remove_definition (AlmanahStorageManager *self, const gchar *definition_text);
+const gchar *almanah_storage_manager_get_filename (AlmanahStorageManager *self, gboolean plain);
+
G_END_DECLS
#endif /* !ALMANAH_STORAGE_MANAGER_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]