[gthumb: 8/57] renamed catalog-web-exporter as gth-web-exporter
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gthumb: 8/57] renamed catalog-web-exporter as gth-web-exporter
- Date: Sun, 20 Jun 2010 16:22:25 +0000 (UTC)
commit 082c7e7237fbc092e5d24629c1c7a2c0bea40337
Author: Paolo Bacchilega <paobac src gnome org>
Date: Fri Jun 4 10:39:35 2010 +0200
renamed catalog-web-exporter as gth-web-exporter
started porting of the web exporter to the new system
extensions/webalbums/catalog-web-exporter.c | 3209 ---------------------------
extensions/webalbums/catalog-web-exporter.h | 188 --
extensions/webalbums/gth-web-exporter.c | 2922 ++++++++++++++++++++++++
extensions/webalbums/gth-web-exporter.h | 101 +
4 files changed, 3023 insertions(+), 3397 deletions(-)
---
diff --git a/extensions/webalbums/gth-web-exporter.c b/extensions/webalbums/gth-web-exporter.c
new file mode 100644
index 0000000..ee83216
--- /dev/null
+++ b/extensions/webalbums/gth-web-exporter.c
@@ -0,0 +1,2922 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2003-2010 Free Software Foundation, 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 Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include <string.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <time.h>
+#include <locale.h>
+#include <ctype.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <gthumb.h>
+#include "gth-web-exporter.h"
+#include "albumtheme-private.h"
+
+#define DATE_FORMAT _("%d %B %Y, %H:%M")
+#define DEFAULT_THUMB_SIZE 100
+#define DEFAULT_INDEX_FILE "index.html"
+#define SAVING_TIMEOUT 5
+
+/* Default subdirectories.
+ * - Used as fallback when gconf values are empty or not accessible
+ * - Please keep in sync with values in gthumb.schemas.in
+ */
+
+#define DEFAULT_WEB_DIR_PREVIEWS "previews"
+#define DEFAULT_WEB_DIR_THUMBNAILS "thumbnails"
+#define DEFAULT_WEB_DIR_IMAGES "images"
+#define DEFAULT_WEB_DIR_HTML_IMAGES "html"
+#define DEFAULT_WEB_DIR_HTML_INDEXES "html"
+#define DEFAULT_WEB_DIR_THEME_FILES "theme"
+
+
+typedef enum {
+ GTH_VISIBILITY_ALWAYS = 0,
+ GTH_VISIBILITY_INDEX,
+ GTH_VISIBILITY_IMAGE
+} GthTagVisibility;
+
+typedef enum {
+ GTH_IMAGE_TYPE_IMAGE = 0,
+ GTH_IMAGE_TYPE_THUMBNAIL,
+ GTH_IMAGE_TYPE_PREVIEW
+} GthAttrImageType;
+
+enum {
+ START_COPYING,
+ LAST_SIGNAL
+};
+
+extern int yyparse (void);
+extern GFileInputStream *yy_istream;
+
+static GObjectClass *parent_class = NULL;
+static guint gth_web_exporter_signals[LAST_SIGNAL] = { 0 };
+
+typedef struct {
+ GthFileData *file_data;
+ char *comment;
+ char *place;
+ char *date_time;
+ char *dest_filename;
+ GdkPixbuf *image;
+ int image_width, image_height;
+ GdkPixbuf *thumb;
+ int thumb_width, thumb_height;
+ GdkPixbuf *preview;
+ int preview_width, preview_height;
+ gboolean caption_set;
+ gboolean no_preview;
+} ImageData;
+
+#define IMAGE_DATA(x) ((ImageData*)(x))
+
+
+typedef struct {
+ char *previews;
+ char *thumbnails;
+ char *images;
+ char *html_images;
+ char *html_indexes;
+ char *theme_files;
+} AlbumDirs;
+
+
+struct _GthWebExporterPrivate {
+ GthBrowser *browser;
+
+ GList *file_list; /* GFile elements. */
+
+ char *header;
+ char *footer;
+ int page_rows; /* Number of rows and columns
+ * each page must have. */
+ int page_cols;
+ gboolean single_index;
+ gboolean use_subfolders;
+ AlbumDirs directories;
+ char *index_file;
+
+ GFile *style_dir;
+ GFile *target_dir; /* Save files in this location. */
+ GFile *target_tmp_dir;
+
+ char *info;
+
+ int thumb_width;
+ int thumb_height;
+
+ gboolean copy_images;
+ GthSortMethod sort_method;
+ GtkSortType sort_type;
+
+ gboolean resize_images;
+ int resize_max_width;
+ int resize_max_height;
+
+ int preview_min_width;
+ int preview_min_height;
+
+ int preview_max_width;
+ int preview_max_height;
+
+ guint16 index_caption_mask;
+ guint16 image_caption_mask;
+
+ /**/
+
+ ImageLoader *iloader;
+ GList *current_file; /* Next file to be loaded. */
+
+ int n_images; /* Used for the progress signal.*/
+ int n_images_done;
+ int n_pages;
+ int page;
+ int image;
+ GList *index_parsed;
+ GList *thumbnail_parsed;
+ GList *image_parsed;
+
+ GList *current_image;
+ guint saving_timeout;
+ ImageData *eval_image;
+
+ gboolean interrupted;
+};
+
+
+static ImageData *
+image_data_new (GthFileData *file_data,
+ int file_idx)
+{
+ ImageData *idata;
+ CommentData *cdata;
+
+ idata = g_new0 (ImageData, 1);
+
+ cdata = comments_load_comment (file->path, TRUE);
+ if (cdata != NULL) {
+ idata->comment = g_strdup (cdata->comment);
+ idata->place = g_strdup (cdata->place);
+ if (cdata->time != 0) {
+ struct tm *tm;
+ char time_txt[50];
+ tm = localtime (&(cdata->time));
+ if (tm->tm_hour + tm->tm_min + tm->tm_sec == 0)
+ strftime (time_txt, 50, _("%d %B %Y"), tm);
+ else
+ strftime (time_txt, 50, _("%d %B %Y, %H:%M"), tm);
+ idata->date_time = g_locale_to_utf8 (time_txt, -1, 0, 0, 0);
+ }
+ else
+ idata->date_time = NULL;
+ comment_data_free (cdata);
+ }
+ else {
+ idata->comment = NULL;
+ idata->place = NULL;
+ idata->date_time = NULL;
+ }
+
+ idata->file_data = file_data_ref (file);
+ idata->dest_filename = g_strdup_printf ("%03d-%s",
+ file_idx,
+ file_name_from_path (file->path));
+
+ idata->image = NULL;
+ idata->image_width = 0;
+ idata->image_height = 0;
+
+ idata->thumb = NULL;
+ idata->thumb_width = 0;
+ idata->thumb_height = 0;
+
+ idata->preview = NULL;
+ idata->preview_width = 0;
+ idata->preview_height = 0;
+
+ idata->caption_set = FALSE;
+ idata->no_preview = FALSE;
+
+ return idata;
+}
+
+
+static void
+image_data_free (ImageData *idata)
+{
+ g_free (idata->comment);
+ g_free (idata->place);
+ g_free (idata->date_time);
+ file_data_unref (idata->file_data);
+ g_free (idata->dest_filename);
+
+ if (idata->image != NULL)
+ g_object_unref (idata->image);
+ if (idata->thumb != NULL)
+ g_object_unref (idata->thumb);
+ if (idata->preview != NULL)
+ g_object_unref (idata->preview);
+
+ g_free (idata);
+}
+
+
+static void
+free_parsed_docs (GthWebExporter *self)
+{
+ if (self->priv->index_parsed != NULL) {
+ gth_parsed_doc_free (self->priv->index_parsed);
+ self->priv->index_parsed = NULL;
+ }
+
+ if (self->priv->thumbnail_parsed != NULL) {
+ gth_parsed_doc_free (self->priv->thumbnail_parsed);
+ self->priv->thumbnail_parsed = NULL;
+ }
+
+ if (self->priv->image_parsed != NULL) {
+ gth_parsed_doc_free (self->priv->image_parsed);
+ self->priv->image_parsed = NULL;
+ }
+}
+
+
+static GFile *
+gfile_get_style_dir (GthWebExporter *self,
+ const char *style)
+{
+ GFile *dir;
+ GFile *style_dir;
+
+ if (style == NULL)
+ return NULL;
+
+ dir = gfile_get_home_dir ();
+ style_dir = gfile_append_path (dir,
+ ".gnome2",
+ "gthumb",
+ "albumthemes",
+ style,
+ NULL);
+ g_object_unref (dir);
+
+ if (! gfile_path_is_dir (style_dir)) {
+ g_object_unref (style_dir);
+
+ style_dir = gfile_new_va (GTHUMB_DATADIR,
+ "gthumb",
+ "albumthemes",
+ style,
+ NULL);
+ if (! gfile_path_is_dir (style_dir)) {
+ g_object_unref (style_dir);
+ style_dir = NULL;
+ }
+ }
+
+ return style_dir;
+}
+
+
+/* FIXME */
+
+
+#define RETURN_IMAGE_FIELD(image, field) { \
+ if (image == NULL) \
+ return 0; \
+ else \
+ return image->field; \
+}
+
+
+static int
+get_var_value (const char *var_name,
+ gpointer data)
+{
+ GthWebExporter *self = data;
+
+ if (strcmp (var_name, "image_idx") == 0)
+ return self->priv->image + 1;
+ else if (strcmp (var_name, "images") == 0)
+ return self->priv->n_images;
+ else if (strcmp (var_name, "page_idx") == 0)
+ return self->priv->page + 1;
+ else if (strcmp (var_name, "page_rows") == 0)
+ return self->priv->page_rows;
+ else if (strcmp (var_name, "page_cols") == 0)
+ return self->priv->page_cols;
+ else if (strcmp (var_name, "pages") == 0)
+ return self->priv->n_pages;
+ else if (strcmp (var_name, "preview_min_width") == 0)
+ return self->priv->preview_min_width;
+ else if (strcmp (var_name, "preview_min_height") == 0)
+ return self->priv->preview_min_height;
+ else if (strcmp (var_name, "index") == 0)
+ return GTH_VISIBILITY_INDEX;
+ else if (strcmp (var_name, "image") == 0)
+ return GTH_VISIBILITY_IMAGE;
+ else if (strcmp (var_name, "always") == 0)
+ return GTH_VISIBILITY_ALWAYS;
+
+ else if (strcmp (var_name, "image_width") == 0)
+ RETURN_IMAGE_FIELD (self->priv->eval_image, image_width)
+ else if (strcmp (var_name, "image_height") == 0)
+ RETURN_IMAGE_FIELD (self->priv->eval_image, image_height)
+ else if (strcmp (var_name, "preview_width") == 0)
+ RETURN_IMAGE_FIELD (self->priv->eval_image, preview_width)
+ else if (strcmp (var_name, "preview_height") == 0)
+ RETURN_IMAGE_FIELD (self->priv->eval_image, preview_height)
+ else if (strcmp (var_name, "thumb_width") == 0)
+ RETURN_IMAGE_FIELD (self->priv->eval_image, thumb_width)
+ else if (strcmp (var_name, "thumb_height") == 0)
+ RETURN_IMAGE_FIELD (self->priv->eval_image, thumb_height)
+
+ else if (strcmp (var_name, "image_dim_visibility_index") == 0)
+ return self->priv->index_caption_mask & GTH_CAPTION_IMAGE_DIM;
+ else if (strcmp (var_name, "file_name_visibility_index") == 0)
+ return self->priv->index_caption_mask & GTH_CAPTION_FILE_NAME;
+ else if (strcmp (var_name, "file_path_visibility_index") == 0)
+ return self->priv->index_caption_mask & GTH_CAPTION_FILE_PATH;
+ else if (strcmp (var_name, "file_size_visibility_index") == 0)
+ return self->priv->index_caption_mask & GTH_CAPTION_FILE_SIZE;
+ else if (strcmp (var_name, "comment_visibility_index") == 0)
+ return self->priv->index_caption_mask & GTH_CAPTION_COMMENT;
+ else if (strcmp (var_name, "place_visibility_index") == 0)
+ return self->priv->index_caption_mask & GTH_CAPTION_PLACE;
+ else if (strcmp (var_name, "date_time_visibility_index") == 0)
+ return self->priv->index_caption_mask & GTH_CAPTION_DATE_TIME;
+ else if (strcmp (var_name, "exif_date_time_visibility_index") == 0)
+ return self->priv->index_caption_mask & GTH_CAPTION_EXIF_DATE_TIME;
+ else if (strcmp (var_name, "exif_exposure_time_visibility_index") == 0)
+ return self->priv->index_caption_mask & GTH_CAPTION_EXIF_EXPOSURE_TIME;
+ else if (strcmp (var_name, "exif_exposure_mode_visibility_index") == 0)
+ return self->priv->index_caption_mask & GTH_CAPTION_EXIF_EXPOSURE_MODE;
+ else if (strcmp (var_name, "exif_flash_visibility_index") == 0)
+ return self->priv->index_caption_mask & GTH_CAPTION_EXIF_FLASH;
+ else if (strcmp (var_name, "exif_shutter_speed_visibility_index") == 0)
+ return self->priv->index_caption_mask & GTH_CAPTION_EXIF_SHUTTER_SPEED;
+ else if (strcmp (var_name, "exif_aperture_value_visibility_index") == 0)
+ return self->priv->index_caption_mask & GTH_CAPTION_EXIF_APERTURE_VALUE;
+ else if (strcmp (var_name, "exif_focal_length_visibility_index") == 0)
+ return self->priv->index_caption_mask & GTH_CAPTION_EXIF_FOCAL_LENGTH;
+ else if (strcmp (var_name, "exif_camera_model_visibility_index") == 0)
+ return self->priv->index_caption_mask & GTH_CAPTION_EXIF_CAMERA_MODEL;
+
+ else if (strcmp (var_name, "image_dim_visibility_image") == 0)
+ return self->priv->image_caption_mask & GTH_CAPTION_IMAGE_DIM;
+ else if (strcmp (var_name, "file_name_visibility_image") == 0)
+ return self->priv->image_caption_mask & GTH_CAPTION_FILE_NAME;
+ else if (strcmp (var_name, "file_path_visibility_image") == 0)
+ return self->priv->image_caption_mask & GTH_CAPTION_FILE_PATH;
+ else if (strcmp (var_name, "file_size_visibility_image") == 0)
+ return self->priv->image_caption_mask & GTH_CAPTION_FILE_SIZE;
+ else if (strcmp (var_name, "comment_visibility_image") == 0)
+ return self->priv->image_caption_mask & GTH_CAPTION_COMMENT;
+ else if (strcmp (var_name, "place_visibility_image") == 0)
+ return self->priv->image_caption_mask & GTH_CAPTION_PLACE;
+ else if (strcmp (var_name, "date_time_visibility_image") == 0)
+ return self->priv->image_caption_mask & GTH_CAPTION_DATE_TIME;
+ else if (strcmp (var_name, "exif_date_time_visibility_image") == 0)
+ return self->priv->image_caption_mask & GTH_CAPTION_EXIF_DATE_TIME;
+ else if (strcmp (var_name, "exif_exposure_time_visibility_image") == 0)
+ return self->priv->image_caption_mask & GTH_CAPTION_EXIF_EXPOSURE_TIME;
+ else if (strcmp (var_name, "exif_exposure_mode_visibility_image") == 0)
+ return self->priv->image_caption_mask & GTH_CAPTION_EXIF_EXPOSURE_MODE;
+ else if (strcmp (var_name, "exif_flash_visibility_image") == 0)
+ return self->priv->image_caption_mask & GTH_CAPTION_EXIF_FLASH;
+ else if (strcmp (var_name, "exif_shutter_speed_visibility_image") == 0)
+ return self->priv->image_caption_mask & GTH_CAPTION_EXIF_SHUTTER_SPEED;
+ else if (strcmp (var_name, "exif_aperture_value_visibility_image") == 0)
+ return self->priv->image_caption_mask & GTH_CAPTION_EXIF_APERTURE_VALUE;
+ else if (strcmp (var_name, "exif_focal_length_visibility_image") == 0)
+ return self->priv->image_caption_mask & GTH_CAPTION_EXIF_FOCAL_LENGTH;
+ else if (strcmp (var_name, "exif_camera_model_visibility_image") == 0)
+ return self->priv->image_caption_mask & GTH_CAPTION_EXIF_CAMERA_MODEL;
+
+ else if (strcmp (var_name, "copy_originals") == 0)
+ return self->priv->copy_images;
+
+ g_warning ("[GetVarValue] Unknown variable name: %s", var_name);
+
+ return 0;
+}
+
+
+static int
+expression_value (GthWebExporter *self,
+ GthExpr *expr)
+{
+ gth_expr_set_get_var_value_func (expr, get_var_value, self);
+ return gth_expr_eval (expr);
+}
+
+
+static int
+gth_tag_get_idx (GthTag *tag,
+ GthWebExporter *self,
+ int default_value,
+ int max_value)
+{
+ GList *scan;
+ int retval = default_value;
+
+ for (scan = tag->value.arg_list; scan; scan = scan->next) {
+ GthVar *var = scan->data;
+
+ if (strcmp (var->name, "idx_relative") == 0) {
+ retval = default_value + expression_value (self, var->value.expr);
+ break;
+
+ } else if (strcmp (var->name, "idx") == 0) {
+ retval = expression_value (self, var->value.expr) - 1;
+ break;
+ }
+ }
+
+ retval = MIN (retval, max_value);
+ retval = MAX (retval, 0);
+
+ return retval;
+}
+
+
+static int
+get_image_idx (GthTag *tag,
+ GthWebExporter *self)
+{
+ return gth_tag_get_idx (tag, self, self->priv->image, self->priv->n_images - 1);
+}
+
+
+static int
+get_page_idx (GthTag *tag,
+ GthWebExporter *self)
+{
+ return gth_tag_get_idx (tag, self, self->priv->page, self->priv->n_pages - 1);
+}
+
+
+static int
+gth_tag_get_var (GthWebExporter *self,
+ GthTag *tag,
+ const char *var_name)
+{
+ GList *scan;
+
+ for (scan = tag->value.arg_list; scan; scan = scan->next) {
+ GthVar *var = scan->data;
+ if (strcmp (var->name, var_name) == 0)
+ return expression_value (self, var->value.expr);
+ }
+
+ return 0;
+}
+
+
+static const char *
+gth_tag_get_str (GthWebExporter *self,
+ GthTag *tag,
+ const char *var_name)
+{
+ GList *scan;
+
+ for (scan = tag->value.arg_list; scan; scan = scan->next) {
+ GthVar *var = scan->data;
+ if (strcmp (var->name, var_name) == 0) {
+ GthCell *cell = gth_expr_get(var->value.expr);
+ if (cell->type == GTH_CELL_TYPE_VAR)
+ return cell->value.var;
+ }
+ }
+
+ return NULL;
+}
+
+
+static int
+get_page_idx_from_image_idx (GthWebExporter *self,
+ int image_idx)
+{
+ if (self->priv->single_index)
+ return 0;
+ else
+ return image_idx / (self->priv->page_rows * self->priv->page_cols);
+}
+
+
+static gboolean
+line_is_void (const char *line)
+{
+ const char *scan;
+
+ if (line == NULL)
+ return TRUE;
+
+ for (scan = line; *scan != '\0'; scan++)
+ if ((*scan != ' ')
+ && (*scan != '\t')
+ && (*scan != '\n'))
+ return FALSE;
+
+ return TRUE;
+}
+
+
+/* write a line when no error is pending */
+
+static void
+_write_line (GFileOutputStream *ostream,
+ GError **error,
+ const char *line)
+{
+ if (error != NULL && *error != NULL)
+ return;
+
+ gfile_output_stream_write (ostream, error, line);
+}
+
+
+static void
+_write_locale_line (GFileOutputStream *ostream,
+ GError **error,
+ const char *line)
+{
+ char *utf8_line;
+
+ utf8_line = g_locale_to_utf8 (line, -1, 0, 0, 0);
+ _write_line (ostream, error, utf8_line);
+ g_free (utf8_line);
+}
+
+
+static void
+write_line (GFileOutputStream *ostream,
+ GError **error,
+ const char *line)
+{
+ if (line_is_void (line))
+ return;
+
+ _write_line (ostream, error, line);
+}
+
+
+static void
+write_markup_escape_line (GFileOutputStream *ostream,
+ GError **error,
+ const char *line)
+{
+ char *e_line;
+
+ if (line_is_void (line))
+ return;
+
+ e_line = _g_escape_text_for_html (line, -1);
+ _write_line (ostream, error, e_line);
+ g_free (e_line);
+}
+
+
+static void
+write_markup_escape_locale_line (GFileOutputStream *ostream,
+ GError **error,
+ const char *line)
+{
+ char *e_line;
+
+ if (line == NULL)
+ return;
+ if (*line == 0)
+ return;
+
+ e_line = _g_escape_text_for_html (line, -1);
+ _write_locale_line (ostream, error, e_line);
+ g_free (e_line);
+}
+
+
+/* GFile to string */
+
+static char *
+gfile_get_relative_uri (GFile *file,
+ GFile *relative_to)
+{
+ char *escaped;
+ char *relative_uri;
+ char *result;
+
+ escaped = gfile_get_uri (file);
+ relative_uri = gfile_get_uri (relative_to);
+
+ result = get_path_relative_to_uri (escaped, relative_uri);
+
+ g_free (relative_uri);
+ g_free (escaped);
+
+ return result;
+}
+
+
+static char *
+gfile_get_relative_path (GFile *file,
+ GFile *relative_to)
+{
+ char *escaped, *unescaped;
+
+ escaped = gfile_get_relative_uri (file, relative_to);
+ unescaped = g_uri_unescape_string (escaped, NULL);
+
+ g_free (escaped);
+
+ return unescaped;
+}
+
+
+/* construct a GFile for a GthWebExporter */
+
+
+GFile *
+get_album_file (GthWebExporter *self,
+ GFile *target_dir,
+ const char *subdir,
+ const char *filename)
+{
+ return _g_file_get_child (target_dir,
+ (self->priv->use_subfolders ? subdir : filename),
+ (self->priv->use_subfolders ? filename : NULL),
+ NULL);
+}
+
+
+GFile *
+get_html_index_dir (GthWebExporter *self,
+ const int page,
+ GFile *target_dir)
+{
+ if (page == 0)
+ return g_file_dup (target_dir);
+ else
+ return get_album_file (self, target_dir, self->priv->directories.html_indexes, NULL);
+}
+
+
+GFile *
+get_html_image_dir (GthWebExporter *self,
+ GFile *target_dir)
+{
+ return get_album_file (self, target_dir, self->priv->directories.html_images, NULL);
+}
+
+
+GFile *
+get_theme_file (GthWebExporter *self,
+ GFile *target_dir,
+ const char *filename)
+{
+ return get_album_file (self, target_dir, self->priv->directories.theme_files, filename);
+}
+
+
+GFile *
+get_html_index_file (GthWebExporter *self,
+ const int page,
+ GFile *target_dir)
+{
+ GFile *dir, *result;
+ char *filename;
+
+ if (page == 0)
+ filename = g_strdup (self->priv->index_file);
+ else
+ filename = g_strdup_printf ("page%03d.htpl", page + 1);
+ dir = get_html_index_dir (self, page, target_dir);
+ result = get_album_file (self, dir, filename, NULL);
+
+ g_free (filename);
+ g_object_unref (dir);
+
+ return result;
+}
+
+
+GFile *
+get_html_image_file (GthWebExporter *self,
+ ImageData *image_data,
+ GFile *target_dir)
+{
+ char *filename;
+ GFile *result;
+
+ filename = g_strconcat (image_data->dest_filename, ".html", NULL);
+ result = get_album_file (self, target_dir, self->priv->directories.html_images, filename);
+
+ g_free (filename);
+
+ return result;
+}
+
+
+GFile *
+get_thumbnail_file (GthWebExporter *self,
+ ImageData *image_data,
+ GFile *target_dir)
+{
+ char *filename;
+ GFile *result;
+
+ filename = g_strconcat (image_data->dest_filename, ".small", ".jpeg", NULL);
+ result = get_album_file (self, target_dir, self->priv->directories.thumbnails, filename);
+
+ g_free (filename);
+
+ return result;
+}
+
+
+GFile *
+get_image_file (GthWebExporter *self,
+ ImageData *image_data,
+ GFile *target_dir)
+{
+ GFile *result;
+
+ if (self->priv->copy_images)
+ result = get_album_file (self, target_dir, self->priv->directories.images, image_data->dest_filename);
+ else
+ result = g_file_dup (image_data->file_data->file);
+
+ return result;
+}
+
+
+GFile *
+get_preview_file (GthWebExporter *self,
+ ImageData *image_data,
+ GFile *target_dir)
+{
+ GFile *result;
+
+ if (image_data->no_preview) {
+ result = get_image_file (self, image_data, target_dir);
+ }
+ else {
+ char *filename;
+
+ filename = g_strconcat (image_data->dest_filename, ".medium", ".jpeg", NULL);
+ result = get_album_file (self, target_dir, self->priv->directories.previews, filename);
+
+ g_free (filename);
+ }
+
+ return result;
+}
+
+
+static char*
+get_current_date (void)
+{
+ time_t t;
+ struct tm *tp;
+ char s[100];
+
+ t = time (NULL);
+ tp = localtime (&t);
+ strftime (s, 99, DATE_FORMAT, tp);
+
+ return g_locale_to_utf8 (s, -1, 0, 0, 0);
+}
+
+
+static int
+is_alpha_string (char *s,
+ size_t maxlen)
+{
+ if (s == NULL)
+ return 0;
+
+ while ((maxlen > 0) && (*s != '\0') && isalpha (*s)) {
+ maxlen--;
+ s++;
+ }
+
+ return ((maxlen == 0) || (*s == '\0'));
+}
+
+
+static char*
+get_current_language (void)
+{
+ char *language = NULL;
+ char *tmp_locale;
+ char *locale;
+ char *underline;
+ size_t len;
+
+ tmp_locale = setlocale (LC_ALL, NULL);
+ if (tmp_locale == NULL)
+ return NULL;
+ locale = g_strdup (tmp_locale);
+
+ /* FIXME: complete LC_ALL -> RFC 3066 */
+
+ underline = strchr (locale, '_');
+ if (underline != NULL)
+ *underline = '\0';
+
+ len = strlen (locale);
+ if (((len == 2) || (len == 3)) && is_alpha_string (locale, len))
+ language = g_locale_to_utf8 (locale, -1, 0, 0, 0);
+
+ g_free (locale);
+
+ return language;
+}
+
+
+static char *
+get_hf_text (const char *utf8_text)
+{
+ const char *s;
+ GString *r;
+ char *r_str;
+
+ if (utf8_text == NULL)
+ return NULL;
+
+ if (g_utf8_strchr (utf8_text, -1, '%') == NULL)
+ return g_strdup (utf8_text);
+
+ r = g_string_new (NULL);
+ for (s = utf8_text; *s != 0; s = g_utf8_next_char (s)) {
+ gunichar ch = g_utf8_get_char (s);
+
+ if (ch == '%') {
+ s = g_utf8_next_char (s);
+
+ if (*s == 0) {
+ g_string_append_unichar (r, ch);
+ break;
+ }
+
+ ch = g_utf8_get_char (s);
+ switch (ch) {
+ char *t;
+
+ case '%':
+ g_string_append (r, "%");
+ break;
+
+ case 'd':
+ t = get_current_date ();
+ g_string_append (r, t);
+ g_free (t);
+ break;
+ }
+ } else
+ g_string_append_unichar (r, ch);
+ }
+
+ r_str = r->str;
+ g_string_free (r, FALSE);
+
+ return r_str;
+}
+
+
+
+static GthAttrImageType
+get_attr_image_type_from_tag (GthWebExporter *self,
+ GthTag *tag)
+{
+ if (gth_tag_get_var (self, tag, "thumbnail") != 0)
+ return GTH_IMAGE_TYPE_THUMBNAIL;
+
+ if (gth_tag_get_var (self, tag, "preview") != 0)
+ return GTH_IMAGE_TYPE_PREVIEW;
+
+ return GTH_IMAGE_TYPE_IMAGE;
+}
+
+
+static void
+gth_parsed_doc_print (GList *document,
+ GFile *relative_to,
+ GthWebExporter *self,
+ GFileOutputStream *ostream,
+ GError **error,
+ gboolean allow_table)
+{
+ GList *scan;
+
+ for (scan = document; scan; scan = scan->next) {
+ GthTag *tag = scan->data;
+ ImageData *idata;
+ GFile *file;
+ GFile *dir;
+ char *line = NULL;
+ char *image_src = NULL;
+ char *unescaped_path = NULL;
+ int idx;
+ int image_width;
+ int image_height;
+ int max_size;
+ int r, c;
+ int value;
+ const char *src;
+ char *src_attr;
+ const char *class = NULL;
+ char *class_attr = NULL;
+ const char *alt = NULL;
+ char *alt_attr = NULL;
+ const char *id = NULL;
+ char *id_attr = NULL;
+ gboolean relative;
+ GList *scan;
+
+
+ if (error != NULL && *error != NULL)
+ return;
+
+ switch (tag->type) {
+ case GTH_TAG_HEADER:
+ line = get_hf_text (self->priv->header);
+ write_markup_escape_line (ostream, error, line);
+ break;
+
+ case GTH_TAG_FOOTER:
+ line = get_hf_text (self->priv->footer);
+ write_markup_escape_line (ostream, error, line);
+ break;
+
+ case GTH_TAG_LANGUAGE:
+ line = get_current_language ();
+ write_markup_escape_line (ostream, error, line);
+ break;
+
+ case GTH_TAG_THEME_LINK:
+ src = gth_tag_get_str (self, tag, "src");
+ if (src == NULL)
+ break;
+
+ file = get_theme_file (self,
+ self->priv->target_dir,
+ src);
+ line = gfile_get_relative_uri (file, relative_to);
+
+ write_markup_escape_line (ostream, error, line);
+
+ g_object_unref (file);
+ break;
+
+ case GTH_TAG_IMAGE:
+ idx = get_image_idx (tag, self);
+ idata = g_list_nth (self->priv->file_list, idx)->data;
+ self->priv->eval_image = idata;
+
+ switch (get_attr_image_type_from_tag (self, tag)) {
+ case GTH_IMAGE_TYPE_THUMBNAIL:
+ file = get_thumbnail_file (self,
+ idata,
+ self->priv->target_dir);
+ image_width = idata->thumb_width;
+ image_height = idata->thumb_height;
+ break;
+
+ case GTH_IMAGE_TYPE_PREVIEW:
+ file = get_preview_file (self,
+ idata,
+ self->priv->target_dir);
+ image_width = idata->preview_width;
+ image_height = idata->preview_height;
+ break;
+
+ case GTH_IMAGE_TYPE_IMAGE:
+ file = get_image_file (self,
+ idata,
+ self->priv->target_dir);
+ image_width = idata->image_width;
+ image_height = idata->image_height;
+ break;
+ }
+
+ image_src = gfile_get_relative_uri (file, relative_to);
+ src_attr = _g_escape_text_for_html (image_src, -1);
+
+ class = gth_tag_get_str (self, tag, "class");
+ if (class)
+ class_attr = g_strdup_printf (" class=\"%s\"", class);
+ else
+ class_attr = g_strdup ("");
+
+ max_size = gth_tag_get_var (self, tag, "max_size");
+ if (max_size > 0)
+ scale_keeping_ratio (&image_width,
+ &image_height,
+ max_size,
+ max_size,
+ FALSE);
+
+ alt = gth_tag_get_str (self, tag, "alt");
+ if (alt != NULL)
+ alt_attr = g_strdup (alt);
+ else {
+ char *unescaped_path;
+
+ unescaped_path = g_uri_unescape_string (image_src, NULL);
+ alt_attr = _g_escape_text_for_html (unescaped_path, -1);
+ g_free (unescaped_path);
+ }
+
+ id = gth_tag_get_str (self, tag, "id");
+ if (id != NULL)
+ id_attr = g_strdup_printf (" id=\"%s\"", id);
+ else
+ id_attr = g_strdup ("");
+
+ line = g_strdup_printf ("<img src=\"%s\" alt=\"%s\" width=\"%d\" height=\"%d\"%s%s />",
+ src_attr,
+ alt_attr,
+ image_width,
+ image_height,
+ id_attr,
+ class_attr);
+ write_line (ostream, error, line);
+
+ g_free (src_attr);
+ g_free (id_attr);
+ g_free (alt_attr);
+ g_free (class_attr);
+ g_free (image_src);
+ g_object_unref (file);
+ break;
+
+ case GTH_TAG_IMAGE_LINK:
+ idx = get_image_idx (tag, self);
+ idata = g_list_nth (self->priv->file_list, idx)->data;
+ file = get_html_image_file (self,
+ idata,
+ self->priv->target_dir);
+ line = gfile_get_relative_uri (file, relative_to);
+ write_markup_escape_line (ostream, error, line);
+
+ g_object_unref (file);
+ break;
+
+ case GTH_TAG_IMAGE_IDX:
+ line = g_strdup_printf ("%d", get_image_idx (tag, self) + 1);
+ write_line (ostream, error, line);
+ break;
+
+ case GTH_TAG_IMAGE_DIM:
+ idx = get_image_idx (tag, self);
+ idata = g_list_nth (self->priv->file_list, idx)->data;
+ line = g_strdup_printf ("%dx%d",
+ idata->image_width,
+ idata->image_height);
+ write_line (ostream, error, line);
+ break;
+
+ case GTH_TAG_IMAGES:
+ line = g_strdup_printf ("%d", self->priv->n_images);
+ write_line (ostream, error, line);
+ break;
+
+ case GTH_TAG_FILENAME:
+ idx = get_image_idx (tag, self);
+ idata = g_list_nth (self->priv->file_list, idx)->data;
+ self->priv->eval_image = idata;
+
+ switch (get_attr_image_type_from_tag (self, tag)) {
+ case GTH_IMAGE_TYPE_THUMBNAIL:
+ file = get_thumbnail_file (self,
+ idata,
+ self->priv->target_dir);
+ break;
+
+ case GTH_IMAGE_TYPE_PREVIEW:
+ file = get_preview_file (self,
+ idata,
+ self->priv->target_dir);
+ break;
+
+ case GTH_IMAGE_TYPE_IMAGE:
+ file = get_image_file (self,
+ idata,
+ self->priv->target_dir);
+ break;
+ }
+
+ relative = (gth_tag_get_var (self, tag, "with_relative_path") != 0);
+
+ if (relative)
+ unescaped_path = gfile_get_relative_path (file,
+ relative_to);
+ else
+ unescaped_path = gfile_get_path (file);
+
+
+ if (relative || (gth_tag_get_var (self, tag, "with_path") != 0)) {
+ line = unescaped_path;
+ } else {
+ line = g_strdup (file_name_from_path (unescaped_path));
+ g_free (unescaped_path);
+ }
+
+ if (gth_tag_get_var (self, tag, "utf8") != 0)
+ write_markup_escape_locale_line (ostream, error, line);
+ else
+ write_markup_escape_line (ostream, error, line);
+
+ g_object_unref (file);
+ break;
+
+ case GTH_TAG_FILEPATH:
+ idx = get_image_idx (tag, self);
+ idata = g_list_nth (self->priv->file_list, idx)->data;
+ self->priv->eval_image = idata;
+
+ switch (get_attr_image_type_from_tag (self, tag)) {
+ case GTH_IMAGE_TYPE_THUMBNAIL:
+ file = get_thumbnail_file (self,
+ idata,
+ self->priv->target_dir);
+ break;
+
+ case GTH_IMAGE_TYPE_PREVIEW:
+ file = get_preview_file (self,
+ idata,
+ self->priv->target_dir);
+ break;
+
+ case GTH_IMAGE_TYPE_IMAGE:
+ file = get_image_file (self,
+ idata,
+ self->priv->target_dir);
+ break;
+ }
+
+ dir = g_file_get_parent (file);
+
+ relative = (gth_tag_get_var (self, tag, "relative_path") != 0);
+
+ if (relative)
+ line = gfile_get_relative_path (dir,
+ relative_to);
+ else
+ line = gfile_get_path (dir);
+
+ if (gth_tag_get_var (self, tag, "utf8") != 0)
+ write_markup_escape_locale_line (ostream, error, line);
+ else
+ write_markup_escape_line (ostream, error, line);
+
+ g_object_unref (dir);
+ g_object_unref (file);
+ break;
+
+ case GTH_TAG_FILESIZE:
+ idx = get_image_idx (tag, self);
+ idata = g_list_nth (self->priv->file_list, idx)->data;
+ line = g_format_size_for_display (idata->file_data->size);
+ write_markup_escape_line (ostream, error, line);
+ break;
+
+ case GTH_TAG_COMMENT:
+ idx = get_image_idx (tag, self);
+ idata = g_list_nth (self->priv->file_list, idx)->data;
+ self->priv->eval_image = idata;
+
+ if (idata->comment == NULL)
+ break;
+
+ max_size = gth_tag_get_var (self, tag, "max_size");
+ if (max_size <= 0)
+ line = g_strdup (idata->comment);
+ else {
+ char *comment;
+
+ comment = g_strndup (idata->comment, max_size);
+ if (strlen (comment) < strlen (idata->comment))
+ line = g_strconcat (comment, "...", NULL);
+ else
+ line = g_strdup (comment);
+ g_free (comment);
+ }
+
+ write_markup_escape_line (ostream, error, line);
+ break;
+
+ case GTH_TAG_PLACE:
+ idx = get_image_idx (tag, self);
+ idata = g_list_nth (self->priv->file_list, idx)->data;
+ self->priv->eval_image = idata;
+
+ if (idata->place == NULL)
+ break;
+
+ max_size = gth_tag_get_var (self, tag, "max_size");
+ if (max_size <= 0)
+ line = g_strdup (idata->place);
+ else
+ {
+ char *place = g_strndup (idata->place, max_size);
+ if (strlen (place) < strlen (idata->place))
+ line = g_strconcat (place, "...", NULL);
+ else
+ line = g_strdup (place);
+ g_free (place);
+ }
+
+ write_markup_escape_line (ostream, error, line);
+ break;
+
+ case GTH_TAG_DATE_TIME:
+ idx = get_image_idx (tag, self);
+ idata = g_list_nth (self->priv->file_list, idx)->data;
+ self->priv->eval_image = idata;
+
+ if (idata->date_time == NULL)
+ break;
+
+ max_size = gth_tag_get_var (self, tag, "max_size");
+ if (max_size <= 0)
+ line = g_strdup (idata->date_time);
+ else {
+ char *date_time = g_strndup (idata->date_time, max_size);
+ if (strlen (date_time) < strlen (idata->date_time))
+ line = g_strconcat (date_time, "...", NULL);
+ else
+ line = g_strdup (date_time);
+ g_free (date_time);
+ }
+
+ write_markup_escape_line (ostream, error, line);
+ break;
+
+ case GTH_TAG_PAGE_LINK:
+ if (gth_tag_get_var (self, tag, "image_idx") != 0) {
+ int image_idx;
+ image_idx = get_image_idx (tag, self);
+ idx = get_page_idx_from_image_idx (self, image_idx);
+ }
+ else
+ idx = get_page_idx (tag, self);
+
+ file = get_html_index_file (self,
+ idx,
+ self->priv->target_dir);
+ line = gfile_get_relative_uri (file, relative_to);
+ write_markup_escape_line (ostream, error, line);
+
+ g_object_unref (file);
+ break;
+
+ case GTH_TAG_PAGE_IDX:
+ line = g_strdup_printf ("%d", get_page_idx (tag, self) + 1);
+ write_line (ostream, error, line);
+ break;
+
+ case GTH_TAG_PAGE_ROWS:
+ line = g_strdup_printf ("%d", self->priv->page_rows);
+ write_line (ostream, error, line);
+ break;
+
+ case GTH_TAG_PAGE_COLS:
+ line = g_strdup_printf ("%d", self->priv->page_cols);
+ write_line (ostream, error, line);
+ break;
+
+ case GTH_TAG_PAGES:
+ line = g_strdup_printf ("%d", self->priv->n_pages);
+ write_line (ostream, error, line);
+ break;
+
+ case GTH_TAG_TABLE:
+ if (! allow_table)
+ break;
+
+ if (self->priv->single_index)
+ self->priv->page_rows = (self->priv->n_images + self->priv->page_cols - 1) / self->priv->page_cols;
+
+ /* this may not work correctly if single_index is set */
+ for (r = 0; r < self->priv->page_rows; r++) {
+ if (self->priv->image < self->priv->n_images)
+ write_line (ostream, error, " <tr class=\"tr_index\">\n");
+ else
+ write_line (ostream, error, " <tr class=\"tr_empty_index\">\n");
+ for (c = 0; c < self->priv->page_cols; c++) {
+ if (self->priv->image < self->priv->n_images) {
+ write_line (ostream, error, " <td class=\"td_index\">\n");
+ gth_parsed_doc_print (self->priv->thumbnail_parsed,
+ relative_to,
+ self,
+ ostream,
+ error,
+ FALSE);
+ write_line (ostream, error, " </td>\n");
+ self->priv->image++;
+ }
+ else {
+ write_line (ostream, error, " <td class=\"td_empty_index\">\n");
+ write_line (ostream, error, " \n");
+ write_line (ostream, error, " </td>\n");
+ }
+ }
+ write_line (ostream, error, " </tr>\n");
+ }
+ break;
+
+ case GTH_TAG_THUMBS:
+ if (! allow_table)
+ break;
+
+ for (r = 0; r < (self->priv->single_index ? self->priv->n_images : self->priv->page_rows * self->priv->page_cols); r++)
+ {
+ if (self->priv->image >= self->priv->n_images)
+ break;
+ gth_parsed_doc_print (self->priv->thumbnail_parsed,
+ relative_to,
+ self,
+ ostream,
+ error,
+ FALSE);
+ self->priv->image++;
+ }
+ break;
+
+ case GTH_TAG_DATE:
+ line = get_current_date ();
+ write_markup_escape_line (ostream, error, line);
+ break;
+
+ case GTH_TAG_HTML:
+ write_line (ostream, error, tag->value.html);
+ break;
+
+ case GTH_TAG_EXIF_EXPOSURE_TIME:
+ idx = get_image_idx (tag, self);
+ idata = g_list_nth (self->priv->file_list, idx)->data;
+ line = get_metadata_tagset_string (idata->file_data,
+ TAG_NAME_SETS[EXPTIME_TAG_NAMES]);
+ write_markup_escape_line (ostream, error, line);
+ break;
+
+ case GTH_TAG_EXIF_EXPOSURE_MODE:
+ idx = get_image_idx (tag, self);
+ idata = g_list_nth (self->priv->file_list, idx)->data;
+ line = get_metadata_tagset_string (idata->file_data,
+ TAG_NAME_SETS[EXPMODE_TAG_NAMES]);
+ write_markup_escape_line (ostream, error, line);
+ break;
+
+ case GTH_TAG_EXIF_FLASH:
+ idx = get_image_idx (tag, self);
+ idata = g_list_nth (self->priv->file_list, idx)->data;
+ line = get_metadata_tagset_string (idata->file_data,
+ TAG_NAME_SETS[FLASH_TAG_NAMES]);
+ write_markup_escape_line (ostream, error, line);
+ break;
+
+ case GTH_TAG_EXIF_SHUTTER_SPEED:
+ idx = get_image_idx (tag, self);
+ idata = g_list_nth (self->priv->file_list, idx)->data;
+ line = get_metadata_tagset_string (idata->file_data,
+ TAG_NAME_SETS[SHUTTERSPEED_TAG_NAMES]);
+ write_markup_escape_line (ostream, error, line);
+ break;
+
+ case GTH_TAG_EXIF_APERTURE_VALUE:
+ idx = get_image_idx (tag, self);
+ idata = g_list_nth (self->priv->file_list, idx)->data;
+ line = get_metadata_tagset_string (idata->file_data,
+ TAG_NAME_SETS[APERTURE_TAG_NAMES]);
+ write_markup_escape_line (ostream, error, line);
+ break;
+
+ case GTH_TAG_EXIF_FOCAL_LENGTH:
+ idx = get_image_idx (tag, self);
+ idata = g_list_nth (self->priv->file_list, idx)->data;
+ line = get_metadata_tagset_string (idata->file_data,
+ TAG_NAME_SETS[FOCAL_TAG_NAMES]);
+ write_markup_escape_line (ostream, error, line);
+ break;
+
+ case GTH_TAG_EXIF_DATE_TIME:
+ idx = get_image_idx (tag, self);
+ idata = g_list_nth (self->priv->file_list, idx)->data;
+ {
+ time_t t;
+ struct tm *tp;
+ char s[100];
+
+ t = get_exif_time (idata->file_data);
+ if (t != 0) {
+ tp = localtime (&t);
+ strftime (s, 99, DATE_FORMAT, tp);
+ line = g_locale_to_utf8 (s, -1, 0, 0, 0);
+ write_markup_escape_line (ostream, error, line);
+ }
+ else
+ write_line (ostream, error, "-");
+
+ }
+ break;
+
+ case GTH_TAG_EXIF_CAMERA_MODEL:
+ idx = get_image_idx (tag, self);
+ idata = g_list_nth (self->priv->file_list, idx)->data;
+ line = get_metadata_tagset_string (idata->file_data,
+ TAG_NAME_SETS[MAKE_TAG_NAMES]);
+ write_markup_escape_line (ostream, error, line);
+ g_free (line);
+
+ write_line (ostream, error, " ");
+
+ line = get_metadata_tagset_string (idata->file_data,
+ TAG_NAME_SETS[MODEL_TAG_NAMES]);
+ write_markup_escape_line (ostream, error, line);
+ break;
+
+ case GTH_TAG_SET_VAR:
+ break;
+
+ case GTH_TAG_EVAL:
+ idx = get_image_idx (tag, self);
+ idata = g_list_nth (self->priv->file_list, idx)->data;
+ self->priv->eval_image = idata;
+
+ value = gth_tag_get_var (self, tag, "expr");
+
+ line = g_strdup_printf ("%d", value);
+ write_line (ostream, error, line);
+ break;
+
+ case GTH_TAG_IF:
+ idx = MIN (self->priv->image, self->priv->n_images - 1);
+ idata = g_list_nth (self->priv->file_list, idx)->data;
+ self->priv->eval_image = idata;
+
+ for (scan = tag->value.cond_list; scan; scan = scan->next) {
+ GthCondition *cond = scan->data;
+ if (expression_value (self, cond->expr) != 0) {
+ gth_parsed_doc_print (cond->document,
+ relative_to,
+ self,
+ ostream,
+ error,
+ FALSE);
+ break;
+ }
+ }
+ break;
+
+ case GTH_TAG_TEXT:
+ if ((tag->value.arg_list == NULL) && (tag->document != NULL)) {
+ GthTag *child = tag->document->data;
+
+ if (child->type != GTH_TAG_HTML)
+ break;
+ line = g_strdup (_(child->value.html));
+ write_markup_escape_line (ostream, error, line);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ g_free (line);
+ }
+}
+
+
+
+static gboolean
+gfile_parsed_doc_print (GthWebExporter *self,
+ GList *document,
+ GFile *file,
+ GFile *relative_to)
+{
+ GFileOutputStream *ostream;
+ GError *error = NULL;
+ gboolean result;
+
+ gfile_debug (DEBUG_INFO, "save html file", file);
+
+ ostream = g_file_replace (file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, &error);
+
+ if (error) {
+ gfile_warning ("Cannot open html file for writing",
+ file,
+ error);
+ }
+ else {
+ gth_parsed_doc_print (document,
+ relative_to,
+ self,
+ ostream,
+ &error,
+ TRUE);
+ }
+
+ g_output_stream_close (G_OUTPUT_STREAM(ostream), NULL, &error);
+ g_object_unref (ostream);
+
+ result = (error == NULL);
+ g_clear_error (&error);
+
+ return result;
+}
+
+
+static void
+delete_temp_dir_ready_cb (GError *error,
+ gpointer user_data)
+{
+ GthWebExporter *self = user_data;
+
+ if ((self->priv->error == NULL) && (error != NULL))
+ self->priv->error = g_error_copy (error);
+ gth_task_completed (GTH_TASK (self), self->priv->error);
+}
+
+
+static void
+cleanup_and_terminate (GthWebExporter *self,
+ GError *error)
+{
+ GList *file_list;
+
+ if (error != NULL)
+ self->priv->error = g_error_copy (error);
+
+ if (self->priv->file_list != NULL) {
+ g_list_foreach (self->priv->file_list, (GFunc) image_data_free, NULL);
+ g_list_free (self->priv->file_list);
+ self->priv->file_list = NULL;
+ }
+
+ file_list = g_list_append (NULL, self->priv->target_tmp_dir);
+ _g_delete_files_async (file_list,
+ TRUE,
+ TRUE,
+ NULL,
+ delete_temp_dir_ready_cb,
+ self);
+}
+
+
+static void
+copy_to_destination_ready_cb (GObject *object,
+ GError *error,
+ gpointer user_data)
+{
+ cleanup_and_terminate (GTH_WEB_EXPORTER (user_data), error);
+}
+
+
+static void
+save_other_files_progress_cb (GObject *object,
+ const char *description,
+ const char *details,
+ gboolean pulse,
+ double fraction,
+ gpointer user_data)
+{
+ GthWebExporter *self = user_data;
+
+ gth_task_progress (GTH_TASK (self),
+ description,
+ details,
+ pulse,
+ fraction);
+}
+
+
+static void
+save_other_files_dialog_cb (gboolean opened,
+ gpointer user_data)
+{
+ gth_task_dialog (GTH_TASK (user_data), opened);
+}
+
+
+static void
+save_other_files_ready_cb (GObject *object,
+ GError *error,
+ gpointer user_data)
+{
+ GthWebExporter *self = user_data;
+
+ if (error != NULL) {
+ cleanup_and_terminate (self, error);
+ return;
+ }
+
+ source = gth_file_data_new (self->priv->target_tmp_dir, NULL);
+ _g_copy_file_async (source,
+ self->priv->target_dir,
+ FALSE,
+ G_FILE_COPY_NONE,
+ GTH_OVERWRITE_RESPONSE_UNSPECIFIED,
+ G_PRIORITY_NORMAL,
+ gth_task_get_cancellable (GTH_TASK (self)),
+ save_other_files_progress_cb,
+ self,
+ save_other_files_dialog_cb,
+ self,
+ copy_to_destination_ready_cb,
+ self);
+}
+
+
+static void
+save_other_files (GthWebExporter *self)
+{
+ GFileEnumerator *enumerator;
+ GError *error = NULL;
+ GFileInfo *info;
+ GList *files;
+
+ enumerator = g_file_enumerate_children (self->priv->style_dir,
+ G_FILE_ATTRIBUTE_STANDARD_NAME "," G_FILE_ATTRIBUTE_STANDARD_TYPE,
+ 0,
+ gth_task_get_cancellable (GTH_TASK (self)),
+ &error);
+
+ if (error != NULL) {
+ cleanup_and_terminate (self, error);
+ return;
+ }
+
+ files = NULL;
+ while ((error == NULL) && ((info = g_file_enumerator_next_file (enumerator, NULL, &error)) != NULL)) {
+ const char *name;
+ GFile *source;
+ GFile *destination;
+
+ if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY) {
+ g_object_unref (info);
+ continue;
+ }
+
+ name = g_file_info_get_name (info);
+
+ if ((strcmp (name, "index.gthtml") == 0)
+ || (strcmp (name, "thumbnail.gthtml") == 0)
+ || (strcmp (name, "image.gthtml") == 0))
+ {
+ g_object_unref (info);
+ continue;
+ }
+
+ source = g_file_get_child (self->priv->style_dir, name);
+ files = g_list_prepend (files, source);
+
+ g_object_unref (source);
+ g_object_unref (info);
+ }
+
+ g_object_unref (enumerator);
+
+ if (error == NULL)
+ _g_copy_files_async (files,
+ self->priv->target_tmp_dir,
+ FALSE,
+ G_FILE_COPY_NONE,
+ G_PRIORITY_NORMAL,
+ gth_task_get_cancellable (GTH_TASK (self)),
+ save_other_files_progress_cb,
+ self,
+ save_other_files_dialog_cb,
+ self,
+ save_other_files_ready_cb,
+ self);
+ else
+ cleanup_and_terminate (self, error);
+
+ _g_object_list_unref (files);
+}
+
+
+static gboolean save_thumbnail (gpointer data);
+
+
+static void
+save_next_thumbnail (GthWebExporter *self)
+{
+ self->priv->current_image = self->priv->current_image->next;
+ self->priv->image++;
+ self->priv->saving_timeout = g_idle_add (save_thumbnail, data);
+}
+
+
+static void
+save_thumbnail_ready_cb (GthFileData *file_data,
+ GError *error,
+ gpointer data)
+{
+ GthWebExporter *self = data;
+ ImageData *image_data;
+
+ if (error != NULL) {
+ cleanup_and_terminate (self, error);
+ return;
+ }
+
+ image_data = self->priv->current_image->data;
+ g_object_unref (image_data->thumb);
+ image_data->thumb = NULL;
+
+ save_next_thumbnail (self);
+}
+
+
+static gboolean
+save_thumbnail (gpointer data)
+{
+ GthWebExporter *self = data;
+ ImageData *image_data;
+
+ if (self->priv->saving_timeout != 0) {
+ g_source_remove (self->priv->saving_timeout);
+ self->priv->saving_timeout = 0;
+ }
+
+ if (self->priv->current_image == NULL) {
+ save_other_files (self);
+ return FALSE;
+ }
+
+ image_data = self->priv->current_image->data;
+ if (image_data->thumb != NULL) {
+ GFile *destination;
+ GthFileData *file_data;
+
+ gth_task_progress (GTH_TASK (self),
+ _("Saving thumbnails"),
+ NULL,
+ FALSE,
+ (double) (self->priv->image + 1) / (self->priv->n_images + 1));
+
+ destination = get_thumbnail_file (self, image_data, self->priv->target_tmp_dir);
+ file_data = gth_file_data_new (destination, NULL);
+ _gdk_pixbuf_save_async (image_data->thumb,
+ file_data,
+ "image/jpeg",
+ TRUE,
+ save_thumbnail_ready_cb,
+ self);
+
+ g_object_unref (file_data);
+ g_object_unref (destination);
+ }
+
+ save_next_thumbnail (self);
+
+ return FALSE;
+}
+
+
+static void
+save_thumbnails (GthWebExporter *self)
+{
+ gth_task_progress (GTH_TASK (self), _("Saving thumbnails"), NULL, TRUE, 0);
+
+ self->priv->image = 0;
+ self->priv->current_image = self->priv->file_list;
+ self->priv->saving_timeout = g_idle_add (save_thumbnail, self);
+}
+
+
+static gboolean
+save_html_image (gpointer data)
+{
+ GthWebExporter *self = data;
+ ImageData *image_data;
+ GFile *file;
+ GFile *relative_to;
+
+ if (self->priv->saving_timeout != 0) {
+ g_source_remove (self->priv->saving_timeout);
+ self->priv->saving_timeout = 0;
+ }
+
+ if (self->priv->current_image == NULL) {
+ save_thumbnails (self);
+ return FALSE;
+ }
+
+ gth_task_progress (GTH_TASK (self),
+ _("Saving HTML pages: Images"),
+ NULL,
+ FALSE,
+ (double) (self->priv->image + 1) / (self->priv->n_images + 1));
+
+ image_data = self->priv->current_image->data;
+ file = get_html_image_file (self, image_data, self->priv->target_tmp_dir);
+ relative_to = get_html_image_dir (self, self->priv->target_dir);
+ gfile_parsed_doc_print (self, self->priv->image_parsed, file, relative_to);
+
+ g_object_unref (file);
+ g_object_unref (relative_to);
+
+ /**/
+
+ self->priv->current_image = self->priv->current_image->next;
+ self->priv->image++;
+ self->priv->saving_timeout = g_idle_add (save_html_image, data);
+
+ return FALSE;
+}
+
+
+static void
+save_html_images (GthWebExporter *self)
+{
+ /*exporter_set_info (self, _("Saving HTML pages: Images")); FIXME */
+
+ self->priv->image = 0;
+ self->priv->current_image = self->priv->file_list;
+ self->priv->saving_timeout = g_idle_add (save_html_image, self);
+}
+
+
+static gboolean
+save_html_index (gpointer data)
+{
+ GthWebExporter *self = data;
+ GFile *file;
+ GFile *relative_to;
+
+ if (self->priv->saving_timeout != 0) {
+ g_source_remove (self->priv->saving_timeout);
+ self->priv->saving_timeout = 0;
+ }
+
+ if (self->priv->page >= self->priv->n_pages) {
+ save_html_images (self);
+ return FALSE;
+ }
+
+ /* write index.html and pageXXX.html */
+
+ gth_task_progress (GTH_TASK (self),
+ _("Saving HTML pages: Indexes"),
+ NULL,
+ FALSE,
+ (double) (self->priv->page + 1) / (self->priv->n_pages + 1));
+
+ file = get_html_index_file (self, self->priv->page, self->priv->target_tmp_dir);
+ relative_to = get_html_index_dir (self, self->priv->page, self->priv->target_dir);
+ gfile_parsed_doc_print (self, self->priv->index_parsed, file, relative_to);
+
+ g_object_unref (file);
+ g_object_unref (relative_to);
+
+ /**/
+
+ self->priv->page++;
+ self->priv->saving_timeout = g_idle_add (save_html_index, data);
+
+ return FALSE;
+}
+
+
+static void
+save_html_files (GthWebExporter *self)
+{
+ gth_task_progress (GTH_TASK (self),
+ _("Saving HTML pages: Indexes"),
+ NULL,
+ TRUE,
+ 0);
+
+ self->priv->image = 0;
+ self->priv->eval_image = NULL;
+ self->priv->page = 0;
+ self->priv->saving_timeout = g_idle_add (save_html_index, self);
+}
+
+
+static void load_current_file (GthWebExporter *self);
+
+
+static void
+load_next_file (GthWebExporter *self)
+{
+ if (self->priv->interrupted) {
+ GError *error;
+
+ error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_CANCELLED, "");
+ cleanup_and_terminate (self, error);
+ g_error_free (error);
+
+ return;
+ }
+
+ if (self->priv->current_file != NULL) {
+ ImageData *image_data = self->priv->current_file->data;
+
+ if (image_data->preview != NULL) {
+ g_object_unref (image_data->preview);
+ image_data->preview = NULL;
+ }
+
+ if (image_data->image != NULL) {
+ g_object_unref (image_data->image);
+ image_data->image = NULL;
+ }
+ }
+
+ self->priv->n_images_done++;
+ self->priv->current_file = self->priv->current_file->next;
+ load_current_file (self);
+}
+
+
+static gboolean
+load_next_file_cb (gpointer data)
+{
+ GthWebExporter *self = data;
+
+ if (self->priv->saving_timeout != 0) {
+ g_source_remove (self->priv->saving_timeout);
+ self->priv->saving_timeout = 0;
+ }
+
+ load_next_file (self);
+
+ return FALSE;
+}
+
+
+static void
+save_image_preview_ready_cb (GthFileData *file_data,
+ GError *error,
+ gpointer data)
+{
+ GthWebExporter *self = data;
+
+ if (error != NULL) {
+ cleanup_and_terminate (self, error);
+ return;
+ }
+
+ self->priv->saving_timeout = g_idle_add (load_next_file_cb, self);
+}
+
+
+static gboolean
+save_image_preview (gpointer data)
+{
+ GthWebExporter *self = data;
+ ImageData *image_data;
+
+ if (self->priv->saving_timeout != 0) {
+ g_source_remove (self->priv->saving_timeout);
+ self->priv->saving_timeout = 0;
+ }
+
+ image_data = self->priv->current_file->data;
+ if (! image_data->no_preview && (image_data->preview != NULL)) {
+ GFile *destination;
+ GthFileData *file_data;
+
+ /* exporter_set_info (self, _("Saving images")); FIXME */
+
+ destination = get_preview_file (self, image_data, self->priv->target_tmp_dir);
+ file_data = gth_file_data_new (destination, NULL);
+ _gdk_pixbuf_save_async (image_data->preview,
+ file_data,
+ "image/jpeg",
+ TRUE,
+ save_image_preview_ready_cb,
+ self);
+
+ g_object_unref (file_data);
+ g_object_unref (destination);
+ }
+ else
+ self->priv->saving_timeout = g_idle_add (load_next_file_cb, self);
+
+ return FALSE;
+}
+
+
+static void
+save_resized_image_ready_cd (GthFileData *file_data,
+ GError *error,
+ gpointer data)
+{
+ GthWebExporter *self = data;
+
+ if (error != NULL) {
+ cleanup_and_terminate (self, error);
+ return;
+ }
+
+ self->priv->saving_timeout = g_idle_add (save_image_preview, self);
+}
+
+
+static gboolean
+save_resized_image (gpointer data)
+{
+ GthWebExporter *self = data;
+ ImageData *image_data;
+
+ if (self->priv->saving_timeout != 0) {
+ g_source_remove (self->priv->saving_timeout);
+ self->priv->saving_timeout = 0;
+ }
+
+ image_data = self->priv->current_file->data;
+ if (self->priv->copy_images && (image_data->image != NULL)) {
+ GFile *destination;
+ GthFileData *file_data;
+
+ /* exporter_set_info (self, _("Saving images")); FIXME */
+
+ destination = get_image_file (self, image_data, self->priv->target_tmp_dir);
+ file_data = gth_file_data_new (destination, NULL);
+ _gdk_pixbuf_save_async (image_data->image,
+ file_data,
+ "image/jpeg",
+ TRUE,
+ save_resized_image_ready_cd,
+ self);
+
+ g_object_unref (file_data);
+ g_object_unref (destination);
+ }
+ else
+ self->priv->saving_timeout = g_idle_add (save_image_preview, self);
+
+ return FALSE;
+}
+
+
+static gboolean
+copy_current_image (GthWebExporter *self)
+{
+ ImageData *image_data;
+ GFile *destination;
+
+ if (self->priv->saving_timeout != 0) {
+ g_source_remove (self->priv->saving_timeout);
+ self->priv->saving_timeout = 0;
+ }
+
+ /* This function is used when "Copy originals to destination" is
+ enabled, and resizing is NOT enabled. This allows us to use a
+ lossless copy (and rotate). When resizing is enabled, a lossy
+ save has to be used. */
+
+ /* exporter_set_info (self, _("Copying original images")); FIXME */
+
+ image_data = self->priv->current_file->data;
+ destination = get_image_file (self, image_data, self->priv->target_tmp_dir);
+ if (g_file_copy (image_data->file_data->file,
+ destination,
+ G_FILE_COPY_NONE,
+ gth_task_get_cancellable (GTH_TASK (self)),
+ NULL,
+ NULL,
+ &error))
+ {
+ if (g_content_type_equals (gth_file_data_get_mime_type (image_data->file_data), "image/jpeg")) {
+ /* FIXME
+
+ char *uri;
+ uri = gfile_get_uri (dfile);
+
+ GthTransform transform;
+
+ FileData *fd;
+ fd = file_data_new (uri);
+ transform = get_orientation_from_fd (fd);
+
+ if (transform > 1) {
+ apply_transformation_jpeg (fd,
+ transform,
+ JPEG_MCU_ACTION_TRIM,
+ NULL);
+ }
+
+ file_data_unref (fd);
+ g_free (uri);
+
+ */
+ }
+
+ self->priv->saving_timeout = g_idle_add (save_image_preview, self);
+ }
+ else
+ cleanup_and_terminate (self, error);
+
+ g_object_unref (destination);
+
+ return FALSE;
+}
+
+
+static GdkPixbuf *
+pixbuf_scale (const GdkPixbuf *src,
+ int dest_width,
+ int dest_height,
+ GdkInterpType interp_type)
+{
+ GdkPixbuf *dest;
+
+ if (! gdk_pixbuf_get_has_alpha (src))
+ return gdk_pixbuf_scale_simple (src, dest_width, dest_height, interp_type);
+
+ g_return_val_if_fail (src != NULL, NULL);
+ g_return_val_if_fail (dest_width > 0, NULL);
+ g_return_val_if_fail (dest_height > 0, NULL);
+
+ dest = gdk_pixbuf_new (GDK_COLORSPACE_RGB, gdk_pixbuf_get_has_alpha (src), 8, dest_width, dest_height);
+ if (dest == NULL)
+ return NULL;
+
+ gdk_pixbuf_composite_color (src,
+ dest,
+ 0, 0, dest_width, dest_height, 0, 0,
+ (double) dest_width / gdk_pixbuf_get_width (src),
+ (double) dest_height / gdk_pixbuf_get_height (src),
+ interp_type,
+ 255,
+ 0, 0,
+ 200,
+ 0xFFFFFF,
+ 0xFFFFFF);
+
+ return dest;
+}
+
+
+static void
+image_loader_ready_cb (GthImageLoader *iloader,
+ GError *error,
+ gpointer data)
+{
+ GthWebExporter *self = data;
+ ImageData *idata;
+ GdkPixbuf *pixbuf;
+
+ if (error != NULL) {
+ load_next_file (self);
+ return;
+ }
+
+ idata = (ImageData *) self->priv->current_file->data;
+
+ /* image */
+
+ idata->image = pixbuf = g_object_ref (gth_image_loader_get_pixbuf (iloader));
+ if (self->priv->copy_images && self->priv->resize_images) {
+ int w = gdk_pixbuf_get_width (pixbuf);
+ int h = gdk_pixbuf_get_height (pixbuf);
+ if (scale_keeping_ratio (&w, &h,
+ self->priv->resize_max_width,
+ self->priv->resize_max_height,
+ FALSE))
+ {
+ GdkPixbuf *scaled;
+
+ scaled = pixbuf_scale (pixbuf, w, h, GDK_INTERP_BILINEAR);
+ g_object_unref (idata->image);
+ idata->image = scaled;
+ }
+ }
+
+ idata->image_width = gdk_pixbuf_get_width (idata->image);
+ idata->image_height = gdk_pixbuf_get_height (idata->image);
+
+ /* preview */
+
+ idata->preview = pixbuf = g_object_ref (gth_image_loader_get_pixbuf (iloader));
+ if ((self->priv->preview_max_width > 0) && (self->priv->preview_max_height > 0)) {
+ int w = gdk_pixbuf_get_width (pixbuf);
+ int h = gdk_pixbuf_get_height (pixbuf);
+
+ if (scale_keeping_ratio_min (&w, &h,
+ self->priv->preview_min_width,
+ self->priv->preview_min_height,
+ self->priv->preview_max_width,
+ self->priv->preview_max_height,
+ FALSE))
+ {
+ GdkPixbuf *scaled;
+ scaled = pixbuf_scale (pixbuf, w, h, GDK_INTERP_BILINEAR);
+ g_object_unref (idata->preview);
+ idata->preview = scaled;
+ }
+ }
+
+ idata->preview_width = gdk_pixbuf_get_width (idata->preview);
+ idata->preview_height = gdk_pixbuf_get_height (idata->preview);
+
+ idata->no_preview = ((idata->preview_width == idata->image_width)
+ && (idata->preview_height == idata->image_height));
+
+ if (idata->no_preview && (idata->preview != NULL)) {
+ g_object_unref (idata->preview);
+ idata->preview = NULL;
+ }
+
+ /* thumbnail. */
+
+ idata->thumb = pixbuf = image_loader_get_pixbuf (iloader);
+ g_object_ref (idata->thumb);
+
+ if ((self->priv->thumb_width > 0) && (self->priv->thumb_height > 0)) {
+ int w = gdk_pixbuf_get_width (pixbuf);
+ int h = gdk_pixbuf_get_height (pixbuf);
+
+ if (scale_keeping_ratio (&w, &h,
+ self->priv->thumb_width,
+ self->priv->thumb_height,
+ FALSE))
+ {
+ GdkPixbuf *scaled;
+
+ scaled = pixbuf_scale (pixbuf, w, h, GDK_INTERP_BILINEAR);
+ g_object_unref (idata->thumb);
+ idata->thumb = scaled;
+ }
+ }
+
+ idata->thumb_width = gdk_pixbuf_get_width (idata->thumb);
+ idata->thumb_height = gdk_pixbuf_get_height (idata->thumb);
+
+ /* save the image */
+
+ if (self->priv->copy_images) {
+ if (self->priv->resize_images) {
+ /* exporter_set_info (self, _("Saving images")); FIXME */
+ self->priv->saving_timeout = g_idle_add (save_resized_image, self);
+ }
+ else
+ copy_current_image (self);
+ }
+ else
+ self->priv->saving_timeout = g_idle_add (save_image_preview, self);
+}
+
+
+static void
+load_current_file (GthWebExporter *self)
+{
+ GthFileData *file_data;
+
+ if (self->priv->current_file == NULL) {
+ /* FIXME
+ if ((self->priv->sort_method != GTH_SORT_METHOD_NONE)
+ && (self->priv->sort_method != GTH_SORT_METHOD_MANUAL))
+ self->priv->file_list = g_list_sort (self->priv->file_list, get_sortfunc (self));
+ */
+ if (self->priv->sort_type == GTK_SORT_DESCENDING)
+ self->priv->file_list = g_list_reverse (self->priv->file_list);
+ save_html_files (self);
+
+ return;
+ }
+
+ file_data = IMAGE_DATA (self->priv->current_file->data)->file_data;
+ gth_task_progress (GTH_TASK (self),
+ _("Loading images"),
+ g_file_info_get_display_name (file_data->info),
+ FALSE,
+ (double) (self->priv->n_images_done + 1) / (self->priv->n_images + 1));
+ gth_image_loader_set_file_data (self->priv->iloader, file_data);
+ gth_image_loader_start (self->priv->iloader);
+}
+
+
+static GList *
+parse_template (GFile *file)
+{
+ GList *result = NULL;
+ GError *error = NULL;
+
+ yy_parsed_doc = NULL;
+ yy_istream = g_file_read (file, NULL, &error);
+ if (error == NULL) {
+ if (yyparse () == 0)
+ result = yy_parsed_doc;
+ else
+ debug (DEBUG_INFO, "<<syntax error>>");
+
+ g_input_stream_close (G_INPUT_STREAM (yy_istream), NULL, &error);
+ g_object_unref (yy_istream);
+ }
+ else {
+ g_warning ("%s", error->message);
+ g_clear_error (&error);
+ }
+
+ return result;
+}
+
+
+static void
+parse_theme_files (GthWebExporter *self)
+{
+ GFile *template;
+ GList *scan;
+
+ free_parsed_docs (self);
+
+ self->priv->image = 0;
+
+ /* read and parse index.gthtml */
+
+ template = g_file_get_child (self->priv->style_dir, "index.gthtml");
+ self->priv->index_parsed = parse_template (template);
+ if (self->priv->index_parsed == NULL) {
+ GthTag *tag = gth_tag_new (GTH_TAG_TABLE, NULL);
+ self->priv->index_parsed = g_list_prepend (NULL, tag);
+ }
+ g_object_unref (template);
+
+ /* read and parse thumbnail.gthtml */
+
+ template = g_file_get_child (self->priv->style_dir, "thumbnail.gthtml");
+ self->priv->thumbnail_parsed = parse_template (template);
+ if (self->priv->thumbnail_parsed == NULL) {
+ GthExpr *expr;
+ GthVar *var;
+ GList *vars = NULL;
+ GthTag *tag;
+
+ expr = gth_expr_new ();
+ gth_expr_push_constant (expr, 0);
+ var = gth_var_new_expression ("idx_relative", expr);
+ vars = g_list_prepend (vars, var);
+
+ expr = gth_expr_new ();
+ gth_expr_push_constant (expr, 1);
+ var = gth_var_new_expression ("thumbnail", expr);
+ vars = g_list_prepend (vars, var);
+
+ tag = gth_tag_new (GTH_TAG_IMAGE, vars);
+ self->priv->thumbnail_parsed = g_list_prepend (NULL, tag);
+ }
+ g_object_unref (template);
+
+ /* Read and parse image.gthtml */
+
+ template = g_file_get_child (self->priv->style_dir, "image.gthtml");
+ self->priv->image_parsed = parse_template (template);
+ if (self->priv->image_parsed == NULL) {
+ GthExpr *expr;
+ GthVar *var;
+ GList *vars = NULL;
+ GthTag *tag;
+
+ expr = gth_expr_new ();
+ gth_expr_push_constant (expr, 0);
+ var = gth_var_new_expression ("idx_relative", expr);
+ vars = g_list_prepend (vars, var);
+
+ expr = gth_expr_new ();
+ gth_expr_push_constant (expr, 0);
+ var = gth_var_new_expression ("thumbnail", expr);
+ vars = g_list_prepend (vars, var);
+
+ tag = gth_tag_new (GTH_TAG_IMAGE, vars);
+ self->priv->image_parsed = g_list_prepend (NULL, tag);
+ }
+ g_object_unref (template);
+
+ /* read index.html and set variables. */
+
+ for (scan = self->priv->index_parsed; scan; scan = scan->next) {
+ GthTag *tag = scan->data;
+ int width, height;
+
+ switch (tag->type) {
+ case GTH_TAG_SET_VAR:
+
+ width = gth_tag_get_var (self, tag, "thumbnail_width");
+ height = gth_tag_get_var (self, tag, "thumbnail_height");
+
+ if ((width != 0) && (height != 0)) {
+ debug (DEBUG_INFO, "thumbnail --> %dx%d", width, height);
+ gth_web_exporter_set_thumb_size (self, width, height);
+ break;
+ }
+
+ /**/
+
+ width = gth_tag_get_var (self, tag, "preview_width");
+ height = gth_tag_get_var (self, tag, "preview_height");
+
+ if ((width != 0) && (height != 0)) {
+ debug (DEBUG_INFO, "preview --> %dx%d", width, height);
+ gth_web_exporter_set_preview_size (self, width, height);
+ break;
+ }
+
+ width = gth_tag_get_var (self, tag, "preview_min_width");
+ height = gth_tag_get_var (self, tag, "preview_min_height");
+
+ if ((width != 0) && (height != 0)) {
+ debug (DEBUG_INFO, "preview min --> %dx%d", width, height);
+ gth_web_exporter_set_preview_min_size (self, width, height);
+ break;
+ }
+
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+
+static gboolean
+make_album_dir (GFile *parent,
+ const char *child_name,
+ GError **error)
+{
+ GFile *child;
+ gboolean result;
+
+ child = g_file_get_child (parent, child_name);
+ result = g_file_make_directory (child, NULL, error);
+
+ g_object_unref (child);
+
+ return result;
+}
+
+
+static void
+gth_web_exporter_exec (GthTask *task)
+{
+ GthWebExporter *self;
+ GthFileData *file_data;
+ GError *error = NULL;
+
+ g_return_if_fail (GTH_IS_WEB_EXPORTER (object));
+
+ self = GTH_WEB_EXPORTER (task);
+
+ if (self->priv->file_list == NULL) {
+ cleanup_and_terminate (self, NULL);
+ return;
+ }
+
+ self->priv->n_images = g_list_length (self->priv->file_list);
+ if (! self->priv->single_index) {
+ self->priv->n_pages = self->priv->n_images / (self->priv->page_rows * self->priv->page_cols);
+ if (self->priv->n_images % (self->priv->page_rows * self->priv->page_cols) > 0)
+ self->priv->n_pages++;
+ }
+ else
+ self->priv->n_pages = 1;
+
+ /*
+ * check that the style directory is not NULL. A NULL indicates that
+ * the folder of the selected style has been deleted or renamed
+ * before the user started the export. It is unlikely.
+ */
+
+ if (self->priv->style_dir == NULL) { /* FIXME */
+ error = g_error_new_literal (GTHUMB_ERROR, GTH_ERROR_GENERIC, _("Could not find the style folder"));
+ cleanup_and_terminate (self, error);
+ return;
+ }
+
+ /* get index file name and subdirs from gconf (hidden prefs) */
+
+ self->priv->index_file = eel_gconf_get_string (PREF_EXP_WEB_INDEX_FILE, DEFAULT_INDEX_FILE);
+ self->priv->directories.previews = eel_gconf_get_string (PREF_EXP_WEB_DIR_PREVIEWS, DEFAULT_WEB_DIR_PREVIEWS);
+ self->priv->directories.thumbnails = eel_gconf_get_string (PREF_EXP_WEB_DIR_THUMBNAILS, DEFAULT_WEB_DIR_THUMBNAILS);
+ self->priv->directories.images = eel_gconf_get_string (PREF_EXP_WEB_DIR_IMAGES, DEFAULT_WEB_DIR_IMAGES);
+ self->priv->directories.html_images = eel_gconf_get_string (PREF_EXP_WEB_DIR_HTML_IMAGES, DEFAULT_WEB_DIR_HTML_IMAGES);
+ self->priv->directories.html_indexes = eel_gconf_get_string (PREF_EXP_WEB_DIR_HTML_INDEXES, DEFAULT_WEB_DIR_HTML_INDEXES);
+ self->priv->directories.theme_files = eel_gconf_get_string (PREF_EXP_WEB_DIR_THEME_FILES, DEFAULT_WEB_DIR_THEME_FILES);
+
+ /* get tmp dir */
+
+ self->priv->target_tmp_dir = gfile_get_temp_dir_name (); /* FIXME */
+ if (self->priv->target_tmp_dir == NULL) {
+ error = g_error_new_literal (GTHUMB_ERROR, GTH_ERROR_GENERIC, _("Could not create a temporary folder"));
+ cleanup_and_terminate (self, error);
+ return;
+ }
+
+ if (self->priv->use_subfolders) {
+ if (! make_album_dir (self->priv->target_tmp_dir, self->priv->directories.previews, &error)) {
+ cleanup_and_terminate (self, error);
+ return;
+ }
+ if (! make_album_dir (self->priv->target_tmp_dir, self->priv->directories.thumbnails, &error)) {
+ cleanup_and_terminate (self, error);
+ return;
+ }
+ if (self->priv->copy_images && ! make_album_dir (self->priv->target_tmp_dir, self->priv->directories.images, &error)) {
+ cleanup_and_terminate (self, error);
+ return;
+ }
+ if (! make_album_dir (self->priv->target_tmp_dir, self->priv->directories.html_images, &error)) {
+ cleanup_and_terminate (self, error);
+ return;
+ }
+ if ((self->priv->n_pages > 1) && ! make_album_dir (self->priv->target_tmp_dir, self->priv->directories.html_indexes, &error)) {
+ cleanup_and_terminate (self, error);
+ return;
+ }
+ if (! make_album_dir (self->priv->target_tmp_dir, self->priv->directories.theme_files, &error)) {
+ cleanup_and_terminate (self, error);
+ return;
+ }
+ }
+
+ parse_theme_files (self);
+
+ /* Load thumbnails. */
+
+ self->priv->iloader = gth_image_loader_new (FALSE);
+ g_signal_connect (G_OBJECT (self->priv->iloader),
+ "ready",
+ G_CALLBACK (image_loader_ready_cb),
+ self);
+
+ self->priv->n_images_done = 0;
+ self->priv->current_file = self->priv->file_list;
+ load_current_file (self);
+}
+
+
+static void
+gth_web_exporter_finalize (GObject *object)
+{
+ GthWebExporter *self;
+
+ g_return_if_fail (GTH_IS_WEB_EXPORTER (object));
+
+ self = GTH_WEB_EXPORTER (object);
+ g_free (self->priv->header);
+ g_free (self->priv->footer);
+ _g_object_unref (self->priv->style_dir);
+ _g_object_unref (self->priv->target_dir);
+ _g_object_unref (self->priv->target_tmp_dir);
+
+ g_free (self->priv->directories.previews);
+ g_free (self->priv->directories.thumbnails);
+ g_free (self->priv->directories.images);
+ g_free (self->priv->directories.html_images);
+ g_free (self->priv->directories.html_indexes);
+ g_free (self->priv->directories.theme_files);
+
+ g_free (self->priv->index_file);
+ g_free (self->priv->info);
+ if (self->priv->file_list != NULL) {
+ g_list_foreach (self->priv->file_list, (GFunc) image_data_free, NULL);
+ g_list_free (self->priv->file_list);
+ }
+ _g_object_unref (self->priv->iloader);
+ free_parsed_docs (self);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+
+static void
+gth_web_exporter_class_init (GthWebExporterClass *klass)
+{
+ GObjectClass *object_class;
+ GthTaskClass *task_class;
+
+ parent_class = g_type_class_peek_parent (klass);
+ g_type_class_add_private (klass, sizeof (GthWebExporterPrivate));
+
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = gth_web_exporter_finalize;
+
+ task_class = GTH_TASK_CLASS (klass);
+ task_class->exec = gth_web_exporter_exec;
+
+ /* FIXME: delete if not useful */
+ gth_web_exporter_signals[START_COPYING] =
+ g_signal_new ("start-copying",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GthWebExporterClass, start_copying),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+}
+
+
+static void
+gth_web_exporter_init (GthWebExporter *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_WEB_EXPORTER, GthWebExporterPrivate);
+
+ self->priv->header = NULL;
+ self->priv->footer = NULL;
+ self->priv->style_dir = NULL;
+
+ self->priv->base_tmp_dir = NULL;
+ self->priv->target_tmp_dir = NULL;
+
+ self->priv->use_subfolders = TRUE;
+ self->priv->directories.previews = NULL;
+ self->priv->directories.thumbnails = NULL;
+ self->priv->directories.images = NULL;
+ self->priv->directories.html_images = NULL;
+ self->priv->directories.html_indexes = NULL;
+ self->priv->directories.theme_files = NULL;
+
+ self->priv->index_file = g_strdup (DEFAULT_INDEX_FILE);
+ self->priv->file_list = NULL;
+ self->priv->iloader = NULL;
+
+ self->priv->thumb_width = DEFAULT_THUMB_SIZE;
+ self->priv->thumb_height = DEFAULT_THUMB_SIZE;
+
+ self->priv->copy_images = FALSE;
+ self->priv->resize_images = FALSE;
+ self->priv->resize_max_width = 0;
+ self->priv->resize_max_height = 0;
+
+ self->priv->single_index = FALSE;
+
+ self->priv->preview_min_width = 0;
+ self->priv->preview_min_height = 0;
+ self->priv->preview_max_width = 0;
+ self->priv->preview_max_height = 0;
+
+ self->priv->index_caption_mask = GTH_CAPTION_IMAGE_DIM | GTH_CAPTION_FILE_SIZE;
+ self->priv->image_caption_mask = GTH_CAPTION_COMMENT | GTH_CAPTION_PLACE | GTH_CAPTION_EXIF_DATE_TIME;
+}
+
+
+GType
+gth_web_exporter_get_type (void)
+{
+ static GType type = 0;
+
+ if (! type) {
+ GTypeInfo type_info = {
+ sizeof (GthWebExporterClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) gth_web_exporter_class_init,
+ NULL,
+ NULL,
+ sizeof (GthWebExporter),
+ 0,
+ (GInstanceInitFunc) gth_web_exporter_init
+ };
+
+ type = g_type_register_static (GTH_TYPE_TASK,
+ "GthWebExporter",
+ &type_info,
+ 0);
+ }
+
+ return type;
+}
+
+
+GthTask *
+gth_web_exporter_new (GthBrowser *browser,
+ GList *file_list)
+{
+ GthWebExporter *self;
+ GList *scan;
+ int file_idx;
+
+ g_return_val_if_fail (window != NULL, NULL);
+
+ self = (GthWebExporter *) g_object_new (GTH_TYPE_WEB_EXPORTER, NULL);
+
+ self->priv->browser = browser;
+
+ file_idx = 0;
+ for (scan = file_list; scan; scan = scan->next) {
+ GthFileData *file = scan->data;
+ self->priv->file_list = g_list_prepend (self->priv->file_list, image_data_new (file, file_idx++));
+ }
+ self->priv->file_list = g_list_reverse (self->priv->file_list);
+
+ return (GthTask *) self;
+}
+
+
+void
+gth_web_exporter_set_header (GthWebExporter *self,
+ const char *header)
+{
+ g_return_if_fail (GTH_IS_WEB_EXPORTER (self));
+ g_free (self->priv->header);
+ self->priv->header = g_strdup (header);
+}
+
+
+void
+gth_web_exporter_set_footer (GthWebExporter *self,
+ const char *footer)
+{
+ g_return_if_fail (GTH_IS_WEB_EXPORTER (self));
+ g_free (self->priv->footer);
+ self->priv->footer = g_strdup (footer);
+}
+
+
+void
+gth_web_exporter_set_style (GthWebExporter *self,
+ const char *style)
+{
+ g_return_if_fail (GTH_IS_WEB_EXPORTER (self));
+ UNREF (self->priv->style_dir);
+ self->priv->style_dir = gfile_get_style_dir (self, style);
+}
+
+
+void
+gth_web_exporter_set_location (GthWebExporter *self,
+ const char *location)
+{
+ g_return_if_fail (GTH_IS_WEB_EXPORTER (self));
+ UNREF (self->priv->target_dir);
+ self->priv->target_dir = gfile_new (location);
+}
+
+
+void
+gth_web_exporter_set_use_subfolders (GthWebExporter *self,
+ gboolean use_subfolders)
+{
+ g_return_if_fail (GTH_IS_WEB_EXPORTER (self));
+ self->priv->use_subfolders = use_subfolders;
+}
+
+
+void
+gth_web_exporter_set_copy_images (GthWebExporter *self,
+ gboolean copy)
+{
+ g_return_if_fail (GTH_IS_WEB_EXPORTER (self));
+ self->priv->copy_images = copy;
+}
+
+
+void
+gth_web_exporter_set_resize_images (GthWebExporter *self,
+ gboolean resize,
+ int max_width,
+ int max_height)
+{
+ g_return_if_fail (GTH_IS_WEB_EXPORTER (self));
+ self->priv->resize_images = resize;
+ if (resize) {
+ self->priv->resize_max_width = max_width;
+ self->priv->resize_max_height = max_height;
+ }
+ else {
+ self->priv->resize_max_width = 0;
+ self->priv->resize_max_height = 0;
+ }
+}
+
+
+void
+gth_web_exporter_set_sorted (GthWebExporter *self,
+ GthSortMethod method,
+ GtkSortType sort_type)
+{
+ g_return_if_fail (GTH_IS_WEB_EXPORTER (self));
+ self->priv->sort_method = method;
+ self->priv->sort_type = sort_type;
+}
+
+
+void
+gth_web_exporter_set_row_col (GthWebExporter *self,
+ int rows,
+ int cols)
+{
+ g_return_if_fail (GTH_IS_WEB_EXPORTER (self));
+ self->priv->page_rows = rows;
+ self->priv->page_cols = cols;
+}
+
+
+void
+gth_web_exporter_set_single_index (GthWebExporter *self,
+ gboolean single)
+{
+ g_return_if_fail (GTH_IS_WEB_EXPORTER (self));
+ self->priv->single_index = single;
+}
+
+
+void
+gth_web_exporter_set_thumb_size (GthWebExporter *self,
+ int width,
+ int height)
+{
+ g_return_if_fail (GTH_IS_WEB_EXPORTER (self));
+ self->priv->thumb_width = width;
+ self->priv->thumb_height = height;
+}
+
+
+void
+gth_web_exporter_set_preview_size (GthWebExporter *self,
+ int width,
+ int height)
+{
+ g_return_if_fail (GTH_IS_WEB_EXPORTER (self));
+
+ if (self->priv->copy_images
+ && self->priv->resize_images
+ && (self->priv->resize_max_width > 0)
+ && (self->priv->resize_max_height > 0))
+ {
+ if (width > self->priv->resize_max_width)
+ width = self->priv->resize_max_width;
+ if (height > self->priv->resize_max_height)
+ height = self->priv->resize_max_height;
+ }
+
+ self->priv->preview_max_width = width;
+ self->priv->preview_max_height = height;
+}
+
+
+void
+gth_web_exporter_set_preview_min_size (GthWebExporter *self,
+ int width,
+ int height)
+{
+ g_return_if_fail (GTH_IS_WEB_EXPORTER (self));
+
+ self->priv->preview_min_width = width;
+ self->priv->preview_min_height = height;
+}
+
+
+void
+gth_web_exporter_set_image_caption (GthWebExporter *self,
+ GthCaptionFields caption)
+{
+ g_return_if_fail (GTH_IS_WEB_EXPORTER (self));
+ self->priv->image_caption_mask = caption;
+}
+
+
+guint16
+gth_web_exporter_get_image_caption (GthWebExporter *self)
+{
+ return self->priv->image_caption_mask;
+}
+
+
+void
+gth_web_exporter_set_index_caption (GthWebExporter *self,
+ GthCaptionFields caption)
+{
+ g_return_if_fail (GTH_IS_WEB_EXPORTER (self));
+ self->priv->index_caption_mask = caption;
+}
+
+
+guint16
+gth_web_exporter_get_index_caption (GthWebExporter *self)
+{
+ return self->priv->index_caption_mask;
+}
diff --git a/extensions/webalbums/gth-web-exporter.h b/extensions/webalbums/gth-web-exporter.h
new file mode 100644
index 0000000..effb72e
--- /dev/null
+++ b/extensions/webalbums/gth-web-exporter.h
@@ -0,0 +1,101 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2003-2010 Free Software Foundation, 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 Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GTH_WEB_EXPORTER_H
+#define GTH_WEB_EXPORTER_H
+
+#include <glib.h>
+#include <gio/gio.h>
+#include <gtk/gtk.h>
+#include <gthumb.h>
+
+#define GTH_WEB_EXPORTER_TYPE (gth_web_exporter_get_type ())
+#define GTH_WEB_EXPORTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTH_WEB_EXPORTER_TYPE, GthWebExporter))
+#define GTH_WEB_EXPORTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTH_WEB_EXPORTER_TYPE, GthWebExporterClass))
+#define GTH_IS_WEB_EXPORTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTH_WEB_EXPORTER_TYPE))
+#define GTH_IS_WEB_EXPORTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTH_WEB_EXPORTER_TYPE))
+#define GTH_WEB_EXPORTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTH_WEB_EXPORTER_TYPE, GthWebExporterClass))
+
+typedef struct _GthWebExporter GthWebExporter;
+typedef struct _GthWebExporterClass GthWebExporterClass;
+typedef struct _GthWebExporterPrivate GthWebExporterPrivate;
+
+struct _GthWebExporter {
+ GthTask __parent;
+ GthWebExporterPrivate *priv;
+
+};
+
+struct _GthWebExporterClass {
+ GthTaskClass __parent;
+
+ /* -- signals -- */
+
+ void (*start_copying) (GthWebExporter *self);
+};
+
+GType gth_web_exporter_get_type (void);
+GthTask * gth_web_exporter_new (GthBrowser *browser,
+ GList *file_list);
+void gth_web_exporter_set_header (GthWebExporter *self,
+ const char *header);
+void gth_web_exporter_set_footer (GthWebExporter *self,
+ const char *footer);
+void gth_web_exporter_set_style (GthWebExporter *self,
+ const char *style);
+void gth_web_exporter_set_location (GthWebExporter *self,
+ const char *location);
+void gth_web_exporter_set_use_subfolders (GthWebExporter *self,
+ gboolean use_subfolders);
+void gth_web_exporter_set_row_col (GthWebExporter *self,
+ int rows,
+ int cols);
+void gth_web_exporter_set_thumb_size (GthWebExporter *self,
+ int width,
+ int height);
+void gth_web_exporter_set_preview_size (GthWebExporter *self,
+ int width,
+ int height);
+void gth_web_exporter_set_copy_images (GthWebExporter *self,
+ gboolean copy);
+void gth_web_exporter_set_resize_images (GthWebExporter *self,
+ gboolean resize,
+ int max_width,
+ int max_height);
+void gth_web_exporter_set_sorted (GthWebExporter *self,
+ GthSortMethod method,
+ GtkSortType sort_type);
+void gth_web_exporter_set_row_col (GthWebExporter *self,
+ int rows,
+ int cols);
+void gth_web_exporter_set_single_index (GthWebExporter *self,
+ gboolean copy);
+void gth_web_exporter_set_image_caption (GthWebExporter *self,
+ GthCaptionFields caption);
+guint16 gth_web_exporter_get_image_caption (GthWebExporter *self);
+void gth_web_exporter_set_index_caption (GthWebExporter *self,
+ GthCaptionFields caption);
+guint16 gth_web_exporter_get_index_caption (GthWebExporter *self);
+void gth_web_exporter_export (GthWebExporter *self);
+void gth_web_exporter_interrupt (GthWebExporter *self);
+
+#endif /* GTH_WEB_EXPORTER_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]