...
 
Commits (92)
version 3.2.9.1
---------------
Bugs fixed:
* Missing files in the 3.2.9 tarball (#747980)
version 3.2.9
-------------
Bugs fixed:
* Flickr: forbidden when trying to upload (#732557)
* Facebook: fixed the authorization process.
New or updated application translations:
* Basque (Iñaki Larrañaga Murgoitio)
* Bosnian (Samir Ribic)
* Finnish (Lasse Liehu)
* Ελληνικά, Σύγχρονα (Tom Tryfonidis)
version 3.2.8
-------------
Bugs fixed:
* set G_APPLICATION_HANDLES_COMMAND_LINE for the application (#728341)
* web album: fixed thumbnail size (#727775)
New or updated application translations:
* Polish (Piotr Drąg)
version 3.2.7
-------------
Bugs fixed:
* Cannot Save As with uppercase .JPG (#721281)
* Fix build failing without libtiff installed. (Robert Roth) (#722183)
* Fixed continuous reloading of the current image.
* Website link in about windows is wrong. (#725262)
New or updated manual translations:
* Greek (Dimitris Spingos (Δημήτρης Σπίγγος))
version 3.2.6
-------------
Bugs fixed:
* Rotating image destroys XMP and IPTC metadata. (#719622)
* Command line ignored for the second window. (#712716)
version 3.2.5
-------------
Bugs fixed:
* Media viewer: fixed progress bar behaviour in gtk+ 3.10
* Empty file format options dialog after canceling it once. (#711788)
* Fixed endless image reloading for some images.
* Fixed display of the manual.
* Default parameters for image resizing are misleading. (Christian
Krause) (#710479)
version 3.2.4
-------------
Bugs fixed:
* Fixed error when rotating jpeg images. (#709698)
* Fixed broken window layout with gtk+ 3.10 (#708800)
* Fixed crash when opening the preferences dialog.
* Find duplicates: fixed crash when using a predefined directory
(Christian Krause) (#706697)
* Fixed crash when attempting to play a video under special
circumstances. (Christian Krause) (#706343)
* Fixed crash when copying or moving files. (#705877)
New or updated application translations:
* Indonesian Translation (Andika Triwidada)
* Latvian (Rūdolfs Mazurs)
version 3.2.3
-------------
Bugs fixed:
* Flickr: allow to use a facebook or google account. (#703534)
* Thumbnail list: images drawn with wrong offset. (#702538)
* Fixed the video player stopping after saving a screenshot.
* Fixed saving of TGA images.
* Fixed the size of the toolbar in fullscreen mode.
* Show the cursor again after stopping the slideshow.
* Web services: do not delete the previous account when creating a new one.
New or updated application translations:
* Russian (Yuri Myasoedov)
version 3.2.2
-------------
Bugs fixed:
* Resize, Convert: correctly set the destination folder.
* Fixed the file list style with Gtk+ 3.8
version 3.2.1
-------------
Bugs fixed:
* Facebook: fixed authentication.
* Slideshow: fixed audio playback.
* Filter-bar: fixed the spin button width for the file size control.
* Bookmarks: fixed ability to modify the bookmarks.
* Image viewer: allow to use button 2 to drag the image.
* Fixed unrecognized configure option --disable-libjson-glib (#696783)
version 3.2.0
-------------
......
m4_define([gthumb_major_version], [3])
m4_define([gthumb_minor_version], [2])
m4_define([gthumb_micro_version], [0])
m4_define([gthumb_micro_version], [9])
m4_define([gthumb_version],
[gthumb_major_version.gthumb_minor_version.gthumb_micro_version])
[gthumb_major_version.gthumb_minor_version.gthumb_micro_version.1])
m4_define([gthumb_api_version],
[gthumb_major_version.gthumb_minor_version])
......@@ -216,7 +216,8 @@ AC_ARG_ENABLE([gstreamer],
if test x$enable_gstreamer = xyes ; then
PKG_CHECK_MODULES(GSTREAMER,
[gstreamer-1.0 >= $GSTREAMER_REQUIRED
gstreamer-plugins-base-1.0 >= $GSTREAMER_REQUIRED],
gstreamer-plugins-base-1.0 >= $GSTREAMER_REQUIRED
gstreamer-video-1.0 >= $GSTREAMER_REQUIRED],
[AC_DEFINE(HAVE_GSTREAMER, 1, [Have gstreamer])
enable_gstreamer=yes],
[enable_gstreamer=no])
......
......@@ -4,6 +4,7 @@ icondir = $(pkgdatadir)/icons
icon_DATA = filmholes.png
EXTRA_DIST = \
gthumb.svg \
selection.svg \
$(icon_DATA)
......
This diff is collapsed.
......@@ -24,6 +24,7 @@ icons_DATA = \
site-photobucket.png \
site-picasaweb.png \
site-twentythree.png \
tag.png \
tool-adjust-colors.png \
tool-adjust-contrast.png \
tool-crop.png \
......
......@@ -5,6 +5,7 @@ context = actions
iconsdir = $(themedir)/$(size)/$(context)
icons_DATA = \
browser-mode.png \
zoom-fit-height.png \
zoom-fit-width.png
......
This diff is collapsed.
......@@ -20,10 +20,10 @@
<schema id="org.gnome.gthumb.resize-images" path="/org/gnome/gthumb/resize-images/">
<key name="width" type="i">
<default>640</default>
<default>100</default>
</key>
<key name="height" type="i">
<default>480</default>
<default>100</default>
</key>
<key name="unit" enum="org.gnome.gthumb.GthUnit">
<default>'percentage'</default>
......
......@@ -24,30 +24,147 @@
#include <gthumb.h>
#define UPDATE_DELAY 200
typedef struct {
GthBrowser *browser;
GtkBuilder *builder;
GtkWidget *dialog;
GtkWidget *uri_list;
gboolean do_not_update;
char *last_selected_uri;
gulong bookmarks_changed_id;
gulong update_from_entry_id;
gboolean entry_changed;
} DialogData;
static void
entry_activate_cb (GtkEntry *entry,
DialogData *data);
static void
set_bookmark_data (DialogData *data,
const char *name,
const char *location)
{
g_signal_handlers_block_by_func (_gtk_builder_get_widget (data->builder, "entry_name"), entry_activate_cb, data);
g_signal_handlers_block_by_func (_gtk_builder_get_widget (data->builder, "entry_location"), entry_activate_cb, data);
gtk_entry_set_text (GTK_ENTRY (_gtk_builder_get_widget (data->builder, "entry_name")), name);
gtk_entry_set_text (GTK_ENTRY (_gtk_builder_get_widget (data->builder, "entry_location")), location);
g_signal_handlers_unblock_by_func (_gtk_builder_get_widget (data->builder, "entry_location"), entry_activate_cb, data);
g_signal_handlers_unblock_by_func (_gtk_builder_get_widget (data->builder, "entry_name"), entry_activate_cb, data);
data->entry_changed = FALSE;
}
static void
update_dialog_from_bookmark_file (DialogData *data,
const char *uri)
{
GBookmarkFile *bookmarks;
GFile *file;
char *location;
char *name;
bookmarks = gth_main_get_default_bookmarks ();
file = g_file_new_for_uri (uri);
location = g_file_get_parse_name (file);
name = g_bookmark_file_get_title (bookmarks, uri, NULL);
if (name == NULL)
name = g_file_get_basename (file);
set_bookmark_data (data, name, location);
g_free (name);
g_free (location);
g_object_unref (file);
}
static void
update_current_entry (DialogData *data,
gboolean *update_selected_uri)
{
const char *name;
const char *location;
GFile *file;
char *uri;
GBookmarkFile *bookmarks;
if (update_selected_uri != NULL)
*update_selected_uri = TRUE;
if (data->last_selected_uri == NULL)
return;
if (! data->entry_changed)
return;
data->entry_changed = FALSE;
name = gtk_entry_get_text (GTK_ENTRY (_gtk_builder_get_widget (data->builder, "entry_name")));
location = gtk_entry_get_text (GTK_ENTRY (_gtk_builder_get_widget (data->builder, "entry_location")));
file = g_file_parse_name (location);
uri = g_file_get_uri (file);
bookmarks = gth_main_get_default_bookmarks ();
gth_uri_list_update_uri (GTH_URI_LIST (data->uri_list), data->last_selected_uri, uri, name);
gth_uri_list_update_bookmarks (GTH_URI_LIST (data->uri_list), bookmarks);
gth_main_bookmarks_changed ();
if (g_strcmp0 (data->last_selected_uri, uri) != 0) {
g_free (data->last_selected_uri);
data->last_selected_uri = g_strdup (uri);
if (update_selected_uri != NULL)
*update_selected_uri = FALSE;
}
g_free (uri);
g_object_unref (file);
}
static void
uri_list_selection_changed_cb (GtkTreeSelection *treeselection,
gpointer user_data)
{
DialogData *data = user_data;
GtkTreeModel *model;
GtkTreeIter iter;
char *uri;
gboolean update_selected_uri;
model = gtk_tree_view_get_model (GTK_TREE_VIEW (data->uri_list));
if (! gtk_tree_selection_get_selected (treeselection,
&model,
&iter))
{
return;
}
uri = gth_uri_list_get_uri (GTH_URI_LIST (data->uri_list), &iter);
if (uri == NULL)
return;
update_current_entry (data, &update_selected_uri);
if (update_selected_uri) {
g_free (data->last_selected_uri);
data->last_selected_uri = uri;
}
update_dialog_from_bookmark_file (data, uri);
}
/* called when the main dialog is closed. */
static void
destroy_cb (GtkWidget *widget,
destroy_cb (GtkWidget *widget,
DialogData *data)
{
if (data->update_from_entry_id != 0)
g_source_remove (data->update_from_entry_id);
update_current_entry (data, NULL);
gth_browser_set_dialog (data->browser, "bookmarks", NULL);
g_signal_handler_disconnect (gth_main_get_default_monitor (), data->bookmarks_changed_id);
g_object_unref (data->builder);
g_free (data);
}
......@@ -60,18 +177,21 @@ remove_cb (GtkWidget *widget,
char *uri;
GBookmarkFile *bookmarks;
GError *error = NULL;
uri = gth_uri_list_get_selected (GTH_URI_LIST (data->uri_list));
if (uri == NULL)
return;
bookmarks = gth_main_get_default_bookmarks ();
if (! g_bookmark_file_remove_item (bookmarks, uri, &error)) {
if (g_bookmark_file_remove_item (bookmarks, uri, &error)) {
gth_uri_list_remove_uri (GTH_URI_LIST (data->uri_list), uri);
gth_main_bookmarks_changed ();
}
else {
_gtk_error_dialog_from_gerror_show (GTK_WINDOW (data->dialog), _("Could not remove the bookmark"), error);
g_clear_error (&error);
}
gth_main_bookmarks_changed ();
g_free (uri);
}
......@@ -81,14 +201,14 @@ go_to_cb (GtkWidget *widget,
DialogData *data)
{
char *uri;
uri = gth_uri_list_get_selected (GTH_URI_LIST (data->uri_list));
if (uri != NULL) {
GFile *location;
location = g_file_new_for_uri (uri);
gth_browser_go_to (data->browser, location, NULL);
g_object_unref (location);
g_free (uri);
}
......@@ -99,10 +219,49 @@ static void
bookmarks_changed_cb (GthMonitor *monitor,
DialogData *data)
{
GBookmarkFile *bookmarks;
GBookmarkFile *bookmarks;
char *uri;
GtkTreeSelection *selection;
gboolean selected;
if (data->entry_changed)
return;
uri = gth_uri_list_get_selected (GTH_URI_LIST (data->uri_list));
g_free (data->last_selected_uri);
data->last_selected_uri = NULL; /* do no update the entry */
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (data->uri_list));
g_signal_handlers_block_by_func (selection, uri_list_selection_changed_cb, data);
bookmarks = gth_main_get_default_bookmarks ();
gth_uri_list_set_bookmarks (GTH_URI_LIST (data->uri_list), bookmarks);
g_signal_handlers_unblock_by_func (selection, uri_list_selection_changed_cb, data);
selected = FALSE;
if (uri != NULL)
selected = gth_uri_list_select_uri (GTH_URI_LIST (data->uri_list), uri);
if (! selected) {
/* select the last one */
char **uris;
char *last_uri;
int i;
uris = g_bookmark_file_get_uris (bookmarks, NULL);
last_uri = NULL;
for (i = 0; uris[i] != NULL; i++)
last_uri = uris[i];
if (last_uri != NULL)
gth_uri_list_select_uri (GTH_URI_LIST (data->uri_list), last_uri);
else
set_bookmark_data (data, "", "");
g_strfreev (uris);
}
g_free (uri);
}
......@@ -129,51 +288,28 @@ uri_list_row_activated_cb (GtkTreeView *tree_view,
GtkTreeIter iter;
char *uri;
GFile *location;
tree_model = gtk_tree_view_get_model (tree_view);
if (! gtk_tree_model_get_iter (tree_model, &iter, path))
return;
uri = gth_uri_list_get_uri (GTH_URI_LIST (tree_view), &iter);
if (uri == NULL)
return;
location = g_file_new_for_uri (uri);
gth_browser_go_to (data->browser, location, NULL);
g_object_unref (location);
g_free (uri);
}
static gboolean
save_bookmarks_cb (gpointer user_data)
static void
entry_activate_cb (GtkEntry *entry,
DialogData *data)
{
DialogData *data = user_data;
const char *name;
const char *location;
GFile *file;
char *uri;
GBookmarkFile *bookmarks;
if (data->update_from_entry_id != 0) {
g_source_remove (data->update_from_entry_id);
data->update_from_entry_id = 0;
}
name = gtk_entry_get_text (GTK_ENTRY (_gtk_builder_get_widget (data->builder, "entry_name")));
location = gtk_entry_get_text (GTK_ENTRY (_gtk_builder_get_widget (data->builder, "entry_location")));
file = g_file_parse_name (location);
uri = g_file_get_uri (file);
bookmarks = gth_main_get_default_bookmarks ();
g_bookmark_file_set_title (bookmarks, uri, name);
gth_main_bookmarks_changed ();
g_free (uri);
g_object_unref (file);
return FALSE;
update_current_entry (data, NULL);
}
......@@ -181,70 +317,7 @@ static void
entry_changed_cb (GtkEditable *editable,
DialogData *data)
{
if (data->update_from_entry_id != 0) {
g_source_remove (data->update_from_entry_id);
data->update_from_entry_id = 0;
}
data->update_from_entry_id = gdk_threads_add_timeout (UPDATE_DELAY, save_bookmarks_cb, data);
}
static void
update_dialog_from_bookmark_file (DialogData *data,
const char *uri)
{
GBookmarkFile *bookmarks;
GFile *file;
char *location;
char *name;
bookmarks = gth_main_get_default_bookmarks ();
file = g_file_new_for_uri (uri);
location = g_file_get_parse_name (file);
name = g_bookmark_file_get_title (bookmarks, uri, NULL);
if (name == NULL)
name = g_strdup (location);
g_signal_handlers_block_by_func (_gtk_builder_get_widget (data->builder, "entry_name"), entry_changed_cb, data);
g_signal_handlers_block_by_func (_gtk_builder_get_widget (data->builder, "entry_location"), entry_changed_cb, data);
gtk_entry_set_text (GTK_ENTRY (_gtk_builder_get_widget (data->builder, "entry_name")), name);
gtk_entry_set_text (GTK_ENTRY (_gtk_builder_get_widget (data->builder, "entry_location")), location);
g_signal_handlers_unblock_by_func (_gtk_builder_get_widget (data->builder, "entry_location"), entry_changed_cb, data);
g_signal_handlers_unblock_by_func (_gtk_builder_get_widget (data->builder, "entry_name"), entry_changed_cb, data);
g_free (name);
g_free (location);
g_object_unref (file);
}
static void
uri_list_selection_changed_cb (GtkTreeSelection *treeselection,
gpointer user_data)
{
DialogData *data = user_data;
GtkTreeModel *model;
GtkTreeIter iter;
char *uri;
model = gtk_tree_view_get_model (GTK_TREE_VIEW (data->uri_list));
if (! gtk_tree_selection_get_selected (treeselection,
&model,
&iter))
{
return;
}
uri = gth_uri_list_get_uri (GTH_URI_LIST (data->uri_list), &iter);
if (uri == NULL)
return;
update_dialog_from_bookmark_file (data, uri);
g_free (uri);
data->entry_changed = TRUE;
}
......@@ -259,7 +332,7 @@ dlg_bookmarks (GthBrowser *browser)
GtkWidget *bm_go_to_button;
GBookmarkFile *bookmarks;
GtkTreeSelection *selection;
if (gth_browser_get_dialog (browser, "bookmarks") != NULL) {
gtk_window_present (GTK_WINDOW (gth_browser_get_dialog (browser, "bookmarks")));
return;
......@@ -267,9 +340,9 @@ dlg_bookmarks (GthBrowser *browser)
data = g_new0 (DialogData, 1);
data->browser = browser;
data->do_not_update = FALSE;
data->builder = _gtk_builder_new_from_file ("bookmarks.ui", "bookmarks");
data->update_from_entry_id = 0;
data->last_selected_uri = NULL;
data->entry_changed = FALSE;
/* Get the widgets. */
......@@ -282,9 +355,10 @@ dlg_bookmarks (GthBrowser *browser)
bm_remove_button = _gtk_builder_get_widget (data->builder, "bm_remove_button");
bm_close_button = _gtk_builder_get_widget (data->builder, "bm_close_button");
bm_go_to_button = _gtk_builder_get_widget (data->builder, "bm_go_to_button");
data->uri_list = gth_uri_list_new ();
gtk_widget_show (data->uri_list);
gtk_widget_set_vexpand (data->uri_list, TRUE);
gtk_container_add (GTK_CONTAINER (bm_list_container), data->uri_list);
gtk_label_set_mnemonic_widget (GTK_LABEL (bm_bookmarks_label), data->uri_list);
......@@ -293,37 +367,45 @@ dlg_bookmarks (GthBrowser *browser)
bookmarks = gth_main_get_default_bookmarks ();
gth_uri_list_set_bookmarks (GTH_URI_LIST (data->uri_list), bookmarks);
data->bookmarks_changed_id = g_signal_connect (gth_main_get_default_monitor (),
data->bookmarks_changed_id = g_signal_connect (gth_main_get_default_monitor (),
"bookmarks-changed",
G_CALLBACK (bookmarks_changed_cb),
G_CALLBACK (bookmarks_changed_cb),
data);
/* Set the signals handlers. */
g_signal_connect (G_OBJECT (data->dialog),
g_signal_connect (G_OBJECT (data->dialog),
"destroy",
G_CALLBACK (destroy_cb),
data);
g_signal_connect_swapped (G_OBJECT (bm_close_button),
g_signal_connect_swapped (G_OBJECT (bm_close_button),
"clicked",
G_CALLBACK (gtk_widget_destroy),
G_OBJECT (data->dialog));
g_signal_connect (G_OBJECT (bm_remove_button),
g_signal_connect (G_OBJECT (bm_remove_button),
"clicked",
G_CALLBACK (remove_cb),
data);
g_signal_connect (G_OBJECT (bm_go_to_button),
g_signal_connect (G_OBJECT (bm_go_to_button),
"clicked",
G_CALLBACK (go_to_cb),
data);
g_signal_connect (G_OBJECT (data->uri_list),
g_signal_connect (G_OBJECT (data->uri_list),
"order-changed",
G_CALLBACK (uri_list_order_changed_cb),
data);
g_signal_connect (G_OBJECT (data->uri_list),
g_signal_connect (G_OBJECT (data->uri_list),
"row-activated",
G_CALLBACK (uri_list_row_activated_cb),
data);
g_signal_connect (_gtk_builder_get_widget (data->builder, "entry_location"),
"activate",
G_CALLBACK (entry_activate_cb),
data);
g_signal_connect (_gtk_builder_get_widget (data->builder, "entry_name"),
"activate",
G_CALLBACK (entry_activate_cb),
data);
g_signal_connect (_gtk_builder_get_widget (data->builder, "entry_location"),
"changed",
G_CALLBACK (entry_changed_cb),
......@@ -341,7 +423,7 @@ dlg_bookmarks (GthBrowser *browser)
/* run dialog. */
gtk_window_set_transient_for (GTK_WINDOW (data->dialog),
gtk_window_set_transient_for (GTK_WINDOW (data->dialog),
GTK_WINDOW (browser));
gtk_window_set_modal (GTK_WINDOW (data->dialog), FALSE);
gtk_widget_show (data->dialog);
......
......@@ -85,6 +85,7 @@ static int *YCbCr_R_Cr_Tab = NULL;
static int *YCbCr_G_Cb_Tab = NULL;
static int *YCbCr_G_Cr_Tab = NULL;
static int *YCbCr_B_Cb_Tab = NULL;
static GStaticMutex Tables_Mutex = G_STATIC_MUTEX_INIT;
#define SCALE_FACTOR 16
......@@ -96,6 +97,8 @@ static int *YCbCr_B_Cb_Tab = NULL;
static void
CMYK_table_init (void)
{
g_static_mutex_lock (&Tables_Mutex);
if (CMYK_Tab == NULL) {
int v, k, i;
double k1;
......@@ -110,12 +113,16 @@ CMYK_table_init (void)
CMYK_Tab[i++] = (double) v * k1;
}
}
g_static_mutex_unlock (&Tables_Mutex);
}
static void
YCbCr_tables_init (void)
{
g_static_mutex_lock (&Tables_Mutex);
if (YCbCr_R_Cr_Tab == NULL) {
int i, v;
......@@ -125,12 +132,14 @@ YCbCr_tables_init (void)
YCbCr_B_Cb_Tab = g_new (int, 256);
for (i = 0, v = -128; i <= 255; i++, v++) {
YCbCr_R_Cr_Tab[i] = SCALE_DOWN (SCALE_UP(1.402) * v + ONE_HALF);
YCbCr_R_Cr_Tab[i] = SCALE_DOWN (SCALE_UP (1.402) * v + ONE_HALF);
YCbCr_G_Cb_Tab[i] = - SCALE_UP (0.34414) * v;
YCbCr_G_Cr_Tab[i] = - SCALE_UP (0.71414) * v + ONE_HALF;
YCbCr_B_Cb_Tab[i] = SCALE_DOWN (SCALE_UP(1.77200) * v + ONE_HALF);
YCbCr_B_Cb_Tab[i] = SCALE_DOWN (SCALE_UP (1.77200) * v + ONE_HALF);
}
}
g_static_mutex_unlock (&Tables_Mutex);
}
......
......@@ -78,8 +78,8 @@ gth_image_saver_jpeg_get_control (GthImageSaver *base)
int i;
int active_idx;
if (self->priv->builder == NULL)
self->priv->builder = _gtk_builder_new_from_file ("jpeg-options.ui", "cairo_io");
_g_object_unref (self->priv->builder);
self->priv->builder = _gtk_builder_new_from_file ("jpeg-options.ui", "cairo_io");
active_idx = 0;
extensions = g_strsplit (gth_image_saver_get_extensions (base), " ", -1);
......@@ -396,7 +396,7 @@ _cairo_surface_write_as_jpeg (cairo_surface_t *image,
/* convert scanline from RGBA to RGB packed */
_cairo_copy_line_as_rgba (buf, pixels, w, FALSE);
_cairo_copy_line_as_rgba_big_endian (buf, pixels, w, FALSE);
/* write scanline */
jbuf = (JSAMPROW *)(&buf);
......@@ -482,7 +482,7 @@ gth_image_saver_jpeg_save_image (GthImageSaver *base,
gboolean result;
pixbuf = gth_image_get_pixbuf (image);
pixbuf_type = get_pixbuf_type_from_mime_type (mime_type);
pixbuf_type = _gdk_pixbuf_get_type_from_mime_type (mime_type);
result = gdk_pixbuf_save_to_bufferv (pixbuf,
buffer,
buffer_size,
......
......@@ -67,8 +67,8 @@ gth_image_saver_png_get_control (GthImageSaver *base)
{
GthImageSaverPng *self = GTH_IMAGE_SAVER_PNG (base);
if (self->priv->builder == NULL)
self->priv->builder = _gtk_builder_new_from_file ("png-options.ui", "cairo_io");
_g_object_unref (self->priv->builder);
self->priv->builder = _gtk_builder_new_from_file ("png-options.ui", "cairo_io");
gtk_adjustment_set_value (GTK_ADJUSTMENT (_gtk_builder_get_widget (self->priv->builder, "png_compression_adjustment")),
g_settings_get_int (self->priv->settings, PREF_PNG_COMPRESSION_LEVEL));
......@@ -276,7 +276,7 @@ _cairo_surface_write_as_png (cairo_surface_t *image,
buf = g_new (guchar, width * bpp);
ptr = pixels;
for (row = 0; row < height; ++row) {
_cairo_copy_line_as_rgba (buf, ptr, width, alpha);
_cairo_copy_line_as_rgba_big_endian (buf, ptr, width, alpha);
png_write_rows (cairo_png_data->png_ptr, &buf, 1);
ptr += rowstride;
......@@ -366,4 +366,5 @@ gth_image_saver_png_init (GthImageSaverPng *self)
{
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_IMAGE_SAVER_PNG, GthImageSaverPngPrivate);
self->priv->settings = g_settings_new (GTHUMB_IMAGE_SAVERS_PNG_SCHEMA);
self->priv->builder = NULL;
}
......@@ -51,8 +51,8 @@ gth_image_saver_tga_get_control (GthImageSaver *base)
{
GthImageSaverTga *self = GTH_IMAGE_SAVER_TGA (base);
if (self->priv->builder == NULL)
self->priv->builder = _gtk_builder_new_from_file ("tga-options.ui", "cairo_io");
_g_object_unref (self->priv->builder);
self->priv->builder = _gtk_builder_new_from_file ("tga-options.ui", "cairo_io");
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (_gtk_builder_get_widget (self->priv->builder, "tga_rle_compression_checkbutton")),
g_settings_get_boolean (self->priv->settings, PREF_TGA_RLE_COMPRESSION));
......@@ -260,7 +260,7 @@ _cairo_surface_write_as_tga (cairo_surface_t *image,
ptr = pixels;
for (row = 0; row < height; ++row) {
_cairo_copy_line_as_rgba (buf, ptr, width, alpha);
_cairo_copy_line_as_rgba_little_endian (buf, ptr, width, alpha);
if (rle_compression)
rle_write (buffer_data, buf, width, out_bpp, error);
......@@ -357,4 +357,5 @@ gth_image_saver_tga_init (GthImageSaverTga *self)
{
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_IMAGE_SAVER_TGA, GthImageSaverTgaPrivate);
self->priv->settings = g_settings_new (GTHUMB_IMAGE_SAVERS_TGA_SCHEMA);
self->priv->builder = NULL;
}
......@@ -76,8 +76,8 @@ gth_image_saver_tiff_get_control (GthImageSaver *base)
int active_idx;
GthTiffCompression compression_type;
if (self->priv->builder == NULL)
self->priv->builder = _gtk_builder_new_from_file ("tiff-options.ui", "cairo_io");
_g_object_unref (self->priv->builder);
self->priv->builder = _gtk_builder_new_from_file ("tiff-options.ui", "cairo_io");
active_idx = 0;
extensions = g_strsplit (gth_image_saver_get_extensions (base), " ", -1);
......@@ -439,7 +439,7 @@ _cairo_surface_write_as_tiff (cairo_surface_t *image,
/* Now write the TIFF data. */
ptr = pixels;
for (row = 0; row < rows; row++) {
_cairo_copy_line_as_rgba (buf, ptr, cols, alpha);
_cairo_copy_line_as_rgba_big_endian (buf, ptr, cols, alpha);
if (TIFFWriteScanline (tif, buf, row, 0) < 0) {
g_set_error (error,
GDK_PIXBUF_ERROR,
......@@ -525,7 +525,7 @@ gth_image_saver_tiff_save_image (GthImageSaver *base,
gboolean result;
pixbuf = gth_image_get_pixbuf (image);
pixbuf_type = get_pixbuf_type_from_mime_type (mime_type);
pixbuf_type = _gdk_pixbuf_get_type_from_mime_type (mime_type);
result = gdk_pixbuf_save_to_bufferv (pixbuf,
buffer,
buffer_size,
......
......@@ -55,8 +55,8 @@ gth_image_saver_webp_get_control (GthImageSaver *base)
{
GthImageSaverWebp *self = GTH_IMAGE_SAVER_WEBP (base);
if (self->priv->builder == NULL)
self->priv->builder = _gtk_builder_new_from_file ("webp-options.ui", "cairo_io");
_g_object_unref (self->priv->builder);
self->priv->builder = _gtk_builder_new_from_file ("webp-options.ui", "cairo_io");
gtk_adjustment_set_value (GTK_ADJUSTMENT (GET_WIDGET ("quality_adjustment")),
g_settings_get_int (self->priv->settings, PREF_WEBP_QUALITY));
......@@ -395,4 +395,5 @@ gth_image_saver_webp_init (GthImageSaverWebp *self)
{
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_IMAGE_SAVER_WEBP, GthImageSaverWebpPrivate);
self->priv->settings = g_settings_new (GTHUMB_IMAGE_SAVERS_WEBP_SCHEMA);
self->priv->builder = NULL;
}
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.16.0 on Fri Oct 11 19:38:40 2013 -->
<interface>
<requires lib="gtk+" version="2.16"/>
<!-- interface-requires gtk+ 3.0 -->
<object class="GtkListStore" id="results_liststore">
<columns>
<!-- column-name catalog -->
......@@ -38,7 +39,6 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<property name="use_stock">True</property>
</object>
<packing>
......@@ -54,7 +54,6 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<property name="use_stock">True</property>
</object>
<packing>
......@@ -70,7 +69,6 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<property name="use_stock">True</property>
</object>
<packing>
......@@ -111,7 +109,7 @@
<property name="yalign">0</property>
<property name="stock">gtk-dialog-info</property>
<property name="pixel_size">24</property>
<property name="icon-size">6</property>
<property name="icon_size">6</property>
</object>
</child>
</object>
......@@ -326,7 +324,6 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
</object>
<packing>
<property name="expand">False</property>
......@@ -341,7 +338,6 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
</object>
<packing>
<property name="expand">False</property>
......@@ -387,7 +383,7 @@
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
......@@ -415,7 +411,7 @@
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
......
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.16.0 on Fri Oct 11 20:06:34 2013 -->
<interface>
<requires lib="gtk+" version="2.16"/>
<!-- interface-requires gtk+ 3.0 -->
<object class="GtkListStore" id="group_by_liststore">
<columns>
<!-- column-name type -->
......@@ -10,28 +11,6 @@
<!-- column-name icon-name -->
<column type="gchararray"/>
</columns>
<data>
<row>
<col id="0">0</col>
<col id="1" translatable="yes">Date photo was taken</col>
<col id="2">camera-photo</col>
</row>
<row>
<col id="0">1</col>
<col id="1" translatable="yes">File modified date</col>
<col id="2">appointment-soon</col>
</row>
<row>
<col id="0">2</col>
<col id="1" translatable="yes">Tag</col>
<col id="2" translatable="yes">tag</col>
</row>
<row>
<col id="0">3</col>
<col id="1" translatable="yes">Tag (embedded)</col>
<col id="2" translatable="yes">tag</col>
</row>
</data>
</object>
<object class="GtkImage" id="image1">
<property name="visible">True</property>
......@@ -62,7 +41,6 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<property name="use_stock">True</property>
</object>
<packing>
......@@ -79,7 +57,6 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<property name="use_stock">True</property>
</object>
<packing>
......@@ -95,7 +72,6 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
</object>
......@@ -137,7 +113,7 @@
<property name="yalign">0</property>
<property name="pixel_size">48</property>
<property name="icon_name">file-catalog</property>
<property name="icon-size">6</property>
<property name="icon_size">6</property>
</object>
</child>
</object>
......@@ -233,7 +209,6 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="use_underline">True</property>
<property name="xalign">0</property>
<property name="draw_indicator">True</property>
......@@ -251,7 +226,6 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="xalign">0</property>
<property name="draw_indicator">True</property>
</object>
......@@ -278,7 +252,6 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="xalign">0</property>
<property name="draw_indicator">True</property>
</object>
......
......@@ -122,6 +122,41 @@ dlg_organize_files (GthBrowser *browser,
gtk_widget_show (info_bar);
gtk_container_add (GTK_CONTAINER (GET_WIDGET ("info_alignment")), info_bar);
{
GtkListStore *list_store = (GtkListStore *) GET_WIDGET ("group_by_liststore");
GtkTreeIter iter;
gtk_list_store_append (list_store, &iter);
gtk_list_store_set (list_store, &iter,
0, GTH_GROUP_POLICY_DIGITALIZED_DATE,
1, _("Date photo was taken"),
2, "camera-photo",
-1);
gtk_list_store_append (list_store, &iter);
gtk_list_store_set (list_store, &iter,
0, GTH_GROUP_POLICY_MODIFIED_DATE,
1, _("File modified date"),
2, "appointment-soon",
-1);
gtk_list_store_append (list_store, &iter);
gtk_list_store_set (list_store, &iter,
0, GTH_GROUP_POLICY_TAG,
1, _("Tag"),
2, "tag",
-1);
gtk_list_store_append (list_store, &iter);
gtk_list_store_set (list_store, &iter,
0, GTH_GROUP_POLICY_TAG_EMBEDDED,
1, _("Tag (embedded)"),
2, "tag",
-1);
}
gtk_combo_box_set_active (GTK_COMBO_BOX (GET_WIDGET ("group_by_combobox")), 0);
/* Set the signals handlers. */
g_signal_connect (G_OBJECT (data->dialog),
......
......@@ -663,10 +663,12 @@ gth_comment_update_from_general_attributes (GthFileData *file_data)
metadata = (GthMetadata *) g_file_info_get_attribute_object (file_data->info, "general::datetime");
if (metadata != NULL) {
GthMetadata *comment_time;
text = gth_metadata_get_raw (metadata);
metadata = (GthMetadata *) g_file_info_get_attribute_object (file_data->info, "comment::time");
if (metadata != NULL) {
if (! dom_str_equal (gth_metadata_get_raw (metadata), text)) {
comment_time = (GthMetadata *) g_file_info_get_attribute_object (file_data->info, "comment::time");
if (comment_time != NULL) {
if (! dom_str_equal (gth_metadata_get_raw (comment_time), text)) {
gth_comment_set_time_from_exif_format (comment, gth_metadata_get_raw (metadata));
write_comment = TRUE;
}
......@@ -700,14 +702,13 @@ gth_comment_update_from_general_attributes (GthFileData *file_data)
g_file_make_directory (comment_directory, NULL, NULL);
buffer = gth_comment_to_data (comment, &size);
_g_file_write (comment_file,
FALSE,
G_FILE_CREATE_NONE,
buffer,
size,
NULL,
NULL);
if (_g_file_write (comment_file,
FALSE,
G_FILE_CREATE_NONE,
buffer,
size,
NULL,
NULL))
{
GFile *parent;
GList *list;
......
......@@ -238,6 +238,7 @@ ok_clicked_cb (GtkWidget *widget,
gth_browser_exec_task (data->browser, task, FALSE);
gtk_widget_destroy (data->dialog);
g_object_unref (task);
g_free (thumbnail_caption);
g_free (theme_name);
g_free (file_extension);
......@@ -720,7 +721,7 @@ dlg_contact_sheet (GthBrowser *browser,
else
s_value = g_strdup (get_home_uri ());
}
gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (GET_WIDGET ("destination_filechooserbutton")), s_value);
gtk_file_chooser_set_uri (GTK_FILE_CHOOSER (GET_WIDGET ("destination_filechooserbutton")), s_value);
g_free (s_value);
s_value = _g_settings_get_uri (data->settings, PREF_CONTACT_SHEET_TEMPLATE);
......
......@@ -184,6 +184,7 @@ ok_clicked_cb (GtkWidget *widget,
gth_browser_exec_task (data->browser, task, FALSE);
gtk_widget_destroy (data->dialog);
g_object_unref (task);
gth_contact_sheet_theme_unref (theme);
g_free (file_extension);
g_free (mime_type);
......@@ -259,7 +260,7 @@ dlg_image_wall (GthBrowser *browser,
else
s_value = g_strdup (get_home_uri ());
}
gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (GET_WIDGET ("destination_filechooserbutton")), s_value);
gtk_file_chooser_set_uri (GTK_FILE_CHOOSER (GET_WIDGET ("destination_filechooserbutton")), s_value);
g_free (s_value);
s_value = _g_settings_get_uri (data->settings, PREF_IMAGE_WALL_TEMPLATE);
......
......@@ -199,9 +199,9 @@ dlg_convert_format (GthBrowser *browser,
}
first_file_data = (GthFileData *) data->file_list->data;
gtk_file_chooser_set_file (GTK_FILE_CHOOSER (GET_WIDGET ("destination_filechooserbutton")),
first_file_data->file,
NULL);
_gtk_file_chooser_set_file_parent (GTK_FILE_CHOOSER (GET_WIDGET ("destination_filechooserbutton")),
first_file_data->file,
NULL);
/* Set the signals handlers. */
......
......@@ -1116,6 +1116,7 @@ exiv2_write_metadata_private (Exiv2::Image::AutoPtr image,
ed["Exif.Image.DateTime"] = date_time;
g_free (date_time);
}
ed.sortByKey();
// IPTC Data
......@@ -1164,6 +1165,7 @@ exiv2_write_metadata_private (Exiv2::Image::AutoPtr image,
g_free (key);
}
id.sortByKey();
g_strfreev (attributes);
// XMP Data
......@@ -1174,13 +1176,6 @@ exiv2_write_metadata_private (Exiv2::Image::AutoPtr image,
gpointer metadatum = (GthMetadata *) g_file_info_get_attribute_object (info, attributes[i]);
char *key = exiv2_key_from_attribute (attributes[i]);
// Remove existing tags of the same type.
// Seems to be needed for storing category keywords.
// Not exactly sure why!
/*Exiv2::XmpData::iterator iter = xd.findKey (Exiv2::XmpKey (key));
if (iter != xd.end ())
xd.erase (iter);*/
try {
const char *value_type;
......@@ -1220,6 +1215,7 @@ exiv2_write_metadata_private (Exiv2::Image::AutoPtr image,
g_free (key);
}
xd.sortByKey();
g_strfreev (attributes);
try {
......
......@@ -260,24 +260,27 @@ ask_authorization_dialog_redirected_cb (OAuthAskAuthorizationDialog *dialog,
uri = oauth_ask_authorization_dialog_get_uri (dialog);
if (g_str_has_prefix (uri, FACEBOOK_REDIRECT_URI)) {
const char *uri_data;
GHashTable *data;
const char *access_token;
const char *state;
uri_data = uri + strlen (FACEBOOK_REDIRECT_URI "#");
data = soup_form_decode (uri_data);
access_token = NULL;
state = g_hash_table_lookup (data, "state");
if (g_strcmp0 (state, self->priv->state) == 0) {
access_token = g_hash_table_lookup (data, "access_token");
_facebook_service_set_access_token (self, access_token);
GHashTable *data = NULL;
const char *access_token = NULL;
uri_data = strchr (uri, '#');
if (uri_data != NULL) {
const char *state;
uri_data = uri_data + 1;
data = soup_form_decode (uri_data);
state = g_hash_table_lookup (data, "state");
if (g_strc