[frogr] Convert FrogrMainView in a subclass of GtkApplicationWindow
- From: Mario Sanchez Prada <msanchez src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [frogr] Convert FrogrMainView in a subclass of GtkApplicationWindow
- Date: Tue, 27 Nov 2012 10:48:16 +0000 (UTC)
commit 1cb07b8328e949b9b4a7a8474b0604c4b53f872d
Author: Mario Sanchez Prada <msanchez gnome org>
Date: Sat Nov 17 03:06:03 2012 +0100
Convert FrogrMainView in a subclass of GtkApplicationWindow
src/frogr-controller.c | 81 +-
src/frogr-file-loader.c | 4 +-
src/frogr-main-view.c | 3000 +++++++++++++++++++++++------------------------
src/frogr-main-view.h | 6 +-
4 files changed, 1488 insertions(+), 1603 deletions(-)
---
diff --git a/src/frogr-controller.c b/src/frogr-controller.c
index 835f5f8..79d1f37 100644
--- a/src/frogr-controller.c
+++ b/src/frogr-controller.c
@@ -305,19 +305,19 @@ _g_application_startup_cb (GApplication *app, gpointer data)
static void
_g_application_activate_cb (GApplication *app, gpointer data)
{
- FrogrController *self = FROGR_CONTROLLER (data);
- FrogrControllerPrivate *priv = FROGR_CONTROLLER_GET_PRIVATE (self);
- GtkWindow *mainview_window = NULL;
+ FrogrControllerPrivate *priv = FROGR_CONTROLLER_GET_PRIVATE (data);
DEBUG ("%s", "Application activated!\n");
- mainview_window = frogr_main_view_get_window (priv->mainview);
- gtk_window_present (mainview_window);
+ /* Show the UI */
+ gtk_widget_show_all (GTK_WIDGET(priv->mainview));
+ gtk_window_present (GTK_WINDOW (priv->mainview));
}
static void
_g_application_open_files_cb (GApplication *app, GFile **files, gint n_files, gchar *hint, gpointer data)
{
+ FrogrControllerPrivate *priv = FROGR_CONTROLLER_GET_PRIVATE (data);
GSList *fileuris = NULL;
int i = 0;
@@ -334,13 +334,16 @@ _g_application_open_files_cb (GApplication *app, GFile **files, gint n_files, gc
if (fileuris)
gdk_threads_add_idle (_load_pictures_on_idle, fileuris);
+
+ /* Show the UI */
+ gtk_widget_show_all (GTK_WIDGET(priv->mainview));
+ gtk_window_present (GTK_WINDOW (priv->mainview));
}
static void
_g_application_shutdown_cb (GApplication *app, gpointer data)
{
- FrogrController *self = FROGR_CONTROLLER (data);
- FrogrControllerPrivate *priv = FROGR_CONTROLLER_GET_PRIVATE (self);
+ FrogrControllerPrivate *priv = FROGR_CONTROLLER_GET_PRIVATE (data);
DEBUG ("%s", "Shutting down application...");
@@ -349,8 +352,7 @@ _g_application_shutdown_cb (GApplication *app, gpointer data)
while (gtk_events_pending ())
gtk_main_iteration ();
- g_object_unref (priv->mainview);
-
+ gtk_widget_destroy (GTK_WIDGET (priv->mainview));
priv->app_running = FALSE;
frogr_config_save_all (priv->config);
@@ -504,11 +506,7 @@ _handle_flicksoup_error (FrogrController *self, GError *error, gboolean notify_u
}
if (notify_user && error_function)
- {
- GtkWindow *window = NULL;
- window = frogr_main_view_get_window (priv->mainview);
- error_function (window, msg);
- }
+ error_function (GTK_WINDOW (priv->mainview), msg);
DEBUG ("%s", msg);
g_free (msg);
@@ -575,15 +573,13 @@ _get_auth_url_cb (GObject *obj, GAsyncResult *res, gpointer data)
auth_url = fsp_session_get_auth_url_finish (priv->session, res, &error);
if (auth_url != NULL && error == NULL)
{
- GtkWindow *window = NULL;
gchar *url_with_permissions = NULL;
url_with_permissions = g_strdup_printf ("%s&perms=write", auth_url);
frogr_util_open_uri (url_with_permissions);
/* Run the auth confirmation dialog */
- window = frogr_main_view_get_window (priv->mainview);
- frogr_auth_dialog_show (window, CONFIRM_AUTHORIZATION);
+ frogr_auth_dialog_show (GTK_WINDOW (priv->mainview), CONFIRM_AUTHORIZATION);
DEBUG ("Auth URL: %s", url_with_permissions);
@@ -702,13 +698,10 @@ _cancel_authorization_on_timeout (gpointer data)
if (priv->fetching_auth_url || priv->fetching_auth_token || priv->fetching_token_replacement)
{
- GtkWindow *window = NULL;
-
frogr_controller_cancel_ongoing_requests (self);
frogr_main_view_hide_progress (priv->mainview);
- window = frogr_main_view_get_window (priv->mainview);
- _show_auth_failed_dialog (window, _("Authorization failed (timed out)"), FALSE);
+ _show_auth_failed_dialog (GTK_WINDOW (priv->mainview), _("Authorization failed (timed out)"), FALSE);
}
return FALSE;
@@ -1925,7 +1918,6 @@ _show_details_dialog_on_idle (GSList *pictures)
FrogrControllerPrivate *priv = NULL;
FrogrMainView *mainview = NULL;
FrogrModel *model = NULL;
- GtkWindow *window = NULL;
GSList *tags_list = NULL;
controller = frogr_controller_get_instance ();
@@ -1942,8 +1934,7 @@ _show_details_dialog_on_idle (GSList *pictures)
tags_list = frogr_model_get_tags (model);
/* Sets already pre-fetched: show the dialog */
- window = frogr_main_view_get_window (priv->mainview);
- frogr_details_dialog_show (window, pictures, tags_list);
+ frogr_details_dialog_show (GTK_WINDOW (priv->mainview), pictures, tags_list);
/* FrogrController's responsibility over this list ends here */
g_slist_foreach (pictures, (GFunc) g_object_unref, NULL);
@@ -1959,7 +1950,6 @@ _show_add_tags_dialog_on_idle (GSList *pictures)
FrogrControllerPrivate *priv = NULL;
FrogrMainView *mainview = NULL;
FrogrModel *model = NULL;
- GtkWindow *window = NULL;
GSList *tags_list = NULL;
controller = frogr_controller_get_instance ();
@@ -1976,8 +1966,7 @@ _show_add_tags_dialog_on_idle (GSList *pictures)
tags_list = frogr_model_get_tags (model);
/* Sets already pre-fetched: show the dialog */
- window = frogr_main_view_get_window (priv->mainview);
- frogr_add_tags_dialog_show (window, pictures, tags_list);
+ frogr_add_tags_dialog_show (GTK_WINDOW (priv->mainview), pictures, tags_list);
/* FrogrController's responsibility over this list ends here */
g_slist_foreach (pictures, (GFunc) g_object_unref, NULL);
@@ -1993,7 +1982,6 @@ _show_create_new_set_dialog_on_idle (GSList *pictures)
FrogrControllerPrivate *priv = NULL;
FrogrMainView *mainview = NULL;
FrogrModel *model = NULL;
- GtkWindow *window = NULL;
GSList *photosets = NULL;
controller = frogr_controller_get_instance ();
@@ -2009,8 +1997,7 @@ _show_create_new_set_dialog_on_idle (GSList *pictures)
model = frogr_main_view_get_model (priv->mainview);
photosets = frogr_model_get_photosets (model);
- window = frogr_main_view_get_window (priv->mainview);
- frogr_create_new_set_dialog_show (window, pictures, photosets);
+ frogr_create_new_set_dialog_show (GTK_WINDOW (priv->mainview), pictures, photosets);
/* FrogrController's responsibility over this list ends here */
g_slist_foreach (pictures, (GFunc) g_object_unref, NULL);
@@ -2026,7 +2013,6 @@ _show_add_to_set_dialog_on_idle (GSList *pictures)
FrogrControllerPrivate *priv = NULL;
FrogrMainView *mainview = NULL;
FrogrModel *model = NULL;
- GtkWindow *window = NULL;
GSList *photosets = NULL;
controller = frogr_controller_get_instance ();
@@ -2042,11 +2028,10 @@ _show_add_to_set_dialog_on_idle (GSList *pictures)
model = frogr_main_view_get_model (priv->mainview);
photosets = frogr_model_get_photosets (model);
- window = frogr_main_view_get_window (priv->mainview);
if (frogr_model_n_photosets (model) > 0)
- frogr_add_to_set_dialog_show (window, pictures, photosets);
+ frogr_add_to_set_dialog_show (GTK_WINDOW (priv->mainview), pictures, photosets);
else if (priv->photosets_fetched)
- frogr_util_show_info_dialog (window, _("No sets found"));
+ frogr_util_show_info_dialog (GTK_WINDOW (priv->mainview), _("No sets found"));
/* FrogrController's responsibility over this list ends here */
g_slist_foreach (pictures, (GFunc) g_object_unref, NULL);
@@ -2062,7 +2047,6 @@ _show_add_to_group_dialog_on_idle (GSList *pictures)
FrogrControllerPrivate *priv = NULL;
FrogrMainView *mainview = NULL;
FrogrModel *model = NULL;
- GtkWindow *window = NULL;
GSList *groups = NULL;
controller = frogr_controller_get_instance ();
@@ -2078,11 +2062,10 @@ _show_add_to_group_dialog_on_idle (GSList *pictures)
model = frogr_main_view_get_model (priv->mainview);
groups = frogr_model_get_groups (model);
- window = frogr_main_view_get_window (priv->mainview);
if (frogr_model_n_groups (model) > 0)
- frogr_add_to_group_dialog_show (window, pictures, groups);
+ frogr_add_to_group_dialog_show (GTK_WINDOW (priv->mainview), pictures, groups);
else if (priv->groups_fetched)
- frogr_util_show_info_dialog (window, _("No groups found"));
+ frogr_util_show_info_dialog (GTK_WINDOW (priv->mainview), _("No groups found"));
/* FrogrController's responsibility over this list ends here */
g_slist_foreach (pictures, (GFunc) g_object_unref, NULL);
@@ -2492,22 +2475,18 @@ void
frogr_controller_show_about_dialog (FrogrController *self)
{
FrogrControllerPrivate *priv = NULL;
- GtkWindow *window = NULL;
g_return_if_fail(FROGR_IS_CONTROLLER (self));
- priv = FROGR_CONTROLLER_GET_PRIVATE (self);
- window = frogr_main_view_get_window (priv->mainview);
-
/* Run the about dialog */
- frogr_about_dialog_show (window);
+ priv = FROGR_CONTROLLER_GET_PRIVATE (self);
+ frogr_about_dialog_show (GTK_WINDOW (priv->mainview));
}
void
frogr_controller_show_auth_dialog (FrogrController *self)
{
FrogrControllerPrivate *priv = NULL;
- GtkWindow *window = NULL;
g_return_if_fail(FROGR_IS_CONTROLLER (self));
@@ -2519,23 +2498,19 @@ frogr_controller_show_auth_dialog (FrogrController *self)
return;
/* Run the auth dialog */
- window = frogr_main_view_get_window (priv->mainview);
- frogr_auth_dialog_show (window, REQUEST_AUTHORIZATION);
+ frogr_auth_dialog_show (GTK_WINDOW (priv->mainview), REQUEST_AUTHORIZATION);
}
void
frogr_controller_show_settings_dialog (FrogrController *self)
{
FrogrControllerPrivate *priv = NULL;
- GtkWindow *window = NULL;
g_return_if_fail(FROGR_IS_CONTROLLER (self));
- priv = FROGR_CONTROLLER_GET_PRIVATE (self);
- window = frogr_main_view_get_window (priv->mainview);
-
/* Run the auth dialog */
- frogr_settings_dialog_show (window);
+ priv = FROGR_CONTROLLER_GET_PRIVATE (self);
+ frogr_settings_dialog_show (GTK_WINDOW (priv->mainview));
}
void
@@ -2765,15 +2740,13 @@ frogr_controller_upload_pictures (FrogrController *self)
/* Upload pictures */
if (!frogr_controller_is_authorized (self))
{
- GtkWindow *window = NULL;
gchar *msg = NULL;
msg = g_strdup_printf (_("You need to properly authorize %s before"
" uploading any pictures to Flickr.\n"
"Please re-authorize it."), APP_SHORTNAME);
- window = frogr_main_view_get_window (priv->mainview);
- frogr_util_show_error_dialog (window, msg);
+ frogr_util_show_error_dialog (GTK_WINDOW (priv->mainview), msg);
g_free (msg);
}
else
diff --git a/src/frogr-file-loader.c b/src/frogr-file-loader.c
index a5e2a2e..dd9a061 100644
--- a/src/frogr-file-loader.c
+++ b/src/frogr-file-loader.c
@@ -757,7 +757,6 @@ _check_filesize_limits (FrogrFileLoader *self, FrogrPicture *picture)
if (picture_filesize > max_filesize)
{
- GtkWindow *window = NULL;
gchar *msg = NULL;
/* First %s is the title of the picture (filename of the file by
@@ -768,8 +767,7 @@ _check_filesize_limits (FrogrFileLoader *self, FrogrPicture *picture)
frogr_picture_get_title (picture),
frogr_util_get_datasize_string (max_filesize));
- window = frogr_main_view_get_window (priv->mainview);
- frogr_util_show_error_dialog (window, msg);
+ frogr_util_show_error_dialog (GTK_WINDOW (priv->mainview), msg);
g_free (msg);
keep_going = FALSE;
diff --git a/src/frogr-main-view.c b/src/frogr-main-view.c
index 4c92ef6..fda8bc7 100644
--- a/src/frogr-main-view.c
+++ b/src/frogr-main-view.c
@@ -58,7 +58,7 @@
FROGR_TYPE_MAIN_VIEW, \
FrogrMainViewPrivate))
-G_DEFINE_TYPE (FrogrMainView, frogr_main_view, G_TYPE_OBJECT)
+G_DEFINE_TYPE (FrogrMainView, frogr_main_view, GTK_TYPE_APPLICATION_WINDOW)
/* Private Data */
@@ -74,8 +74,6 @@ typedef struct _FrogrMainViewPrivate {
gboolean tooltips_enabled;
gint n_selected_pictures;
- GtkApplication *gtk_app;
- GtkWindow *window;
gchar *project_name;
gchar *project_dir;
gchar *project_filepath;
@@ -124,12 +122,6 @@ typedef struct _FrogrMainViewPrivate {
} FrogrMainViewPrivate;
-/* Properties */
-enum {
- PROP_0,
- PROP_GTK_APPLICATION
-};
-
/* Icon view treeview */
enum {
FILEURI_COL,
@@ -139,6 +131,8 @@ enum {
/* Prototypes */
+static void _initialize_ui (FrogrMainView *self);
+static gboolean _maybe_show_auth_dialog_on_idle (FrogrMainView *self);
static void _load_project_action (GSimpleAction *action, GVariant *parameter, gpointer data);
static void _save_project_action (GSimpleAction *action, GVariant *parameter, gpointer data);
static void _save_project_as_action (GSimpleAction *action, GVariant *parameter, gpointer data);
@@ -151,8 +145,6 @@ static void _quit_action (GSimpleAction *action, GVariant *parameter, gpointer d
static void _update_project_path (FrogrMainView *self, const gchar *path);
static void _update_window_title (FrogrMainView *self, gboolean dirty);
-static gboolean _maybe_show_auth_dialog_on_idle (FrogrMainView *self);
-
#ifdef MAC_INTEGRATION
static gboolean osx_can_activate_cb(GtkWidget* widget, guint signal_id, gpointer data);
static void _tweak_menu_bar_for_mac (FrogrMainView *self);
@@ -278,1914 +270,1889 @@ static void _update_ui (FrogrMainView *self);
/* Private API */
-static void
-_load_project_action (GSimpleAction *action,
- GVariant *parameter,
- gpointer data)
-{
- _load_project_dialog (FROGR_MAIN_VIEW (data));
-}
-
-static void
-_save_project_action (GSimpleAction *action,
- GVariant *parameter,
- gpointer data)
-{
- _save_current_project (FROGR_MAIN_VIEW (data));
-}
-
-static void
-_save_project_as_action (GSimpleAction *action,
- GVariant *parameter,
- gpointer data)
-{
- _save_project_as_dialog (FROGR_MAIN_VIEW (data));
-}
-
-static void
-_authorize_action (GSimpleAction *action,
- GVariant *parameter,
- gpointer data)
-{
- FrogrMainViewPrivate *priv = NULL;
- priv = FROGR_MAIN_VIEW_GET_PRIVATE (data);
- frogr_controller_show_auth_dialog (priv->controller);
-}
-
-static void
-_preferences_action (GSimpleAction *action,
- GVariant *parameter,
- gpointer data)
-{
- FrogrMainViewPrivate *priv = NULL;
- priv = FROGR_MAIN_VIEW_GET_PRIVATE (data);
- frogr_controller_show_settings_dialog (priv->controller);
-}
+static GActionEntry app_entries[] = {
+ { "load_project", _load_project_action, NULL, NULL, NULL },
+ { "save_project", _save_project_action, NULL, NULL, NULL },
+ { "save_project_as", _save_project_as_action, NULL, NULL, NULL },
+ { "authorize", _authorize_action, NULL, NULL, NULL },
+ { "preferences", _preferences_action, NULL, NULL, NULL },
+ { "help", _help_action, NULL, NULL, NULL },
+ { "about", _about_action, NULL, NULL, NULL },
+ { "quit", _quit_action, NULL, NULL, NULL },
+};
static void
-_about_action (GSimpleAction *action,
- GVariant *parameter,
- gpointer data)
+_initialize_ui (FrogrMainView *self)
{
FrogrMainViewPrivate *priv = NULL;
- priv = FROGR_MAIN_VIEW_GET_PRIVATE (data);
- frogr_controller_show_about_dialog (priv->controller);
-}
-
-static void
-_help_action (GSimpleAction *action,
- GVariant *parameter,
- gpointer data)
-{
- frogr_util_open_uri ("ghelp:frogr");
-}
-
-static void
-_quit_action (GSimpleAction *action,
- GVariant *parameter,
- gpointer data)
-{
- _quit_application (FROGR_MAIN_VIEW (data));
-}
-
-static void
-_update_project_path (FrogrMainView *self, const gchar *path)
-{
- FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
-
- /* Early return if nothing changed */
- if (!g_strcmp0 (priv->project_filepath, path))
- return;
-
- g_free (priv->project_name);
- g_free (priv->project_dir);
- g_free (priv->project_filepath);
-
- if (!path)
- {
- priv->project_name = NULL;
- priv->project_dir = NULL;
- priv->project_filepath = NULL;
- }
- else
- {
- GFile *file = NULL;
- GFile *dir = NULL;
- GFileInfo *file_info = NULL;
- gchar *dir_path = NULL;
- const gchar *home_dir = NULL;
-
- /* Get the display name in beautiful UTF-8 */
- file = g_file_new_for_path (path);
- file_info = g_file_query_info (file,
- G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
- G_FILE_QUERY_INFO_NONE,
- NULL,
- NULL);
- priv->project_name = g_strdup (g_file_info_get_display_name (file_info));
-
- /* Get the base directory, in beautiful UTF-8 too */
- dir = g_file_get_parent (file);
- dir_path = g_file_get_parse_name (dir);
- home_dir = g_get_home_dir ();
- if (g_str_has_prefix (dir_path, home_dir))
- {
- gchar *tmp_path = NULL;
+ GtkApplication *gtk_app;
+ GtkBuilder *builder;
+ GtkWidget *main_vbox;
+ GtkWidget *icon_view;
+ GtkWidget *status_bar;
+ GtkWidget *progress_dialog;
+ GtkWidget *progress_vbox;
+ GtkWidget *progress_bar;
+ GtkWidget *progress_label;
+ GtkWidget *toolbar;
+ const gchar *icons_path = NULL;
+ gchar *full_path = NULL;
+ GList *icons = NULL;
- tmp_path = dir_path;
- dir_path = g_strdup_printf ("~%s", &dir_path[g_utf8_strlen (home_dir, -1)]);
- g_free (tmp_path);
- }
- priv->project_dir = dir_path;
+ priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
- /* Finally, store the raw path too */
- priv->project_filepath = g_strdup (path);
+ /* Provide a default icon list in several sizes */
+ icons_path = frogr_util_get_icons_dir ();
+ full_path = g_strdup_printf ("%s/" MAIN_VIEW_ICON("128x128"), icons_path);
+ icons = g_list_prepend (icons, gdk_pixbuf_new_from_file (full_path, NULL));
+ g_free (full_path);
- g_object_unref (file);
- g_object_unref (dir);
- }
-}
+ full_path = g_strdup_printf ("%s/" MAIN_VIEW_ICON("64x64"), icons_path);
+ icons = g_list_prepend (icons, gdk_pixbuf_new_from_file (full_path, NULL));
+ g_free (full_path);
-static void
-_update_window_title (FrogrMainView *self, gboolean dirty)
-{
- FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
+ full_path = g_strdup_printf ("%s/" MAIN_VIEW_ICON("48x48"), icons_path);
+ icons = g_list_prepend (icons, gdk_pixbuf_new_from_file (full_path, NULL));
+ g_free (full_path);
- gchar *session_string = NULL;
- gchar *window_title = NULL;
+ full_path = g_strdup_printf ("%s/" MAIN_VIEW_ICON("32x32"), icons_path);
+ icons = g_list_prepend (icons, gdk_pixbuf_new_from_file (full_path, NULL));
+ g_free (full_path);
- session_string = priv->project_name
- ? g_strdup_printf ("%s%s (%s) - ", (dirty ? "*" : ""),
- priv->project_name, priv->project_dir)
- : g_strdup("");
+ full_path = g_strdup_printf ("%s/" MAIN_VIEW_ICON("24x24"), icons_path);
+ icons = g_list_prepend (icons, gdk_pixbuf_new_from_file (full_path, NULL));
+ g_free (full_path);
- window_title = g_strdup_printf ("%s%s", session_string, APP_SHORTNAME);
- g_free (session_string);
+ full_path = g_strdup_printf ("%s/" MAIN_VIEW_ICON("16x16"), icons_path);
+ icons = g_list_prepend (icons, gdk_pixbuf_new_from_file (full_path, NULL));
+ g_free (full_path);
- gtk_window_set_title (GTK_WINDOW (priv->window), window_title);
- g_free (window_title);
-}
+ gtk_window_set_default_icon_list (icons);
+ g_list_foreach (icons, (GFunc) g_object_unref, NULL);
+ g_list_free (icons);
-static gboolean
-_maybe_show_auth_dialog_on_idle (FrogrMainView *self)
-{
- FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
+ /* Get widgets from GtkBuilder */
+ builder = gtk_builder_new ();
+ priv->builder = builder;
- if (!frogr_controller_is_authorized (priv->controller))
- {
- /* Show authorization dialog if needed */
- frogr_controller_show_auth_dialog (priv->controller);
- }
+ full_path = g_strdup_printf ("%s/" UI_MAIN_VIEW_FILE, frogr_util_get_app_data_dir ());
+ gtk_builder_add_from_file (builder, full_path, NULL);
+ g_free (full_path);
- return FALSE;
-}
+ main_vbox = GTK_WIDGET (gtk_builder_get_object (builder, "main_window_vbox"));
+ gtk_container_add (GTK_CONTAINER (self), main_vbox);
-#ifdef MAC_INTEGRATION
-static gboolean
-osx_can_activate_cb(GtkWidget* widget, guint signal_id, gpointer data)
-{
- return gtk_widget_is_sensitive(widget);
-}
+ /* Menu bar */
+ priv->menu_bar = GTK_WIDGET (gtk_builder_get_object (builder, "menu_bar"));
+ gtk_widget_show_all (priv->menu_bar);
-static void
-_tweak_menu_bar_for_mac (FrogrMainView *self)
-{
- FrogrMainViewPrivate *priv = NULL;
- GtkOSXApplication *osx_app = NULL;
- GtkWidget *menu_item = NULL;
+#ifndef MAC_INTEGRATION
+ gtk_box_pack_start (GTK_BOX (main_vbox), priv->menu_bar, FALSE, FALSE, 0);
+ gtk_box_reorder_child (GTK_BOX (main_vbox), priv->menu_bar, 0);
+#endif
- priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
+ /* App menu */
+ full_path = g_strdup_printf ("%s/" UI_APP_MENU_FILE, frogr_util_get_app_data_dir ());
+ gtk_builder_add_from_file (builder, full_path, NULL);
+ g_free (full_path);
- osx_app = g_object_new (GTK_TYPE_OSX_APPLICATION, NULL);
- gtk_osxapplication_set_menu_bar (osx_app, GTK_MENU_SHELL(priv->menu_bar));
+ gtk_app = gtk_window_get_application (GTK_WINDOW (self));
+ g_action_map_add_action_entries (G_ACTION_MAP (gtk_app),
+ app_entries, G_N_ELEMENTS (app_entries),
+ self);
+ gtk_application_set_app_menu (GTK_APPLICATION (gtk_app),
+ G_MENU_MODEL (gtk_builder_get_object (builder, "app-menu")));
- /* Relocate the 'about' menu item in the app menu */
- menu_item = GTK_WIDGET (gtk_builder_get_object (priv->builder, "about_menu_item"));
- gtk_osxapplication_insert_app_menu_item (osx_app, menu_item, 0);
- gtk_osxapplication_insert_app_menu_item (osx_app, gtk_separator_menu_item_new (), 1);
- gtk_widget_show_all (menu_item);
+ toolbar = GTK_WIDGET (gtk_builder_get_object (builder, "toolbar"));
+ gtk_style_context_add_class (gtk_widget_get_style_context (toolbar),
+ GTK_STYLE_CLASS_PRIMARY_TOOLBAR);
- /* Relocate the 'authorize' menu item in the app menu */
- menu_item = GTK_WIDGET (gtk_builder_get_object (priv->builder, "authorize_menu_item"));
- gtk_osxapplication_insert_app_menu_item (osx_app, menu_item, 2);
- gtk_widget_show_all (menu_item);
+ icon_view = GTK_WIDGET (gtk_builder_get_object (builder, "icon_view"));
+ priv->icon_view = icon_view;
- /* Relocate the 'accounts' menu item in the app menu */
- menu_item = GTK_WIDGET (gtk_builder_get_object (priv->builder, "accounts_menu_item"));
- gtk_osxapplication_insert_app_menu_item (osx_app, menu_item, 3);
- gtk_osxapplication_insert_app_menu_item (osx_app, gtk_separator_menu_item_new (), 4);
- gtk_widget_show_all (menu_item);
+ status_bar = GTK_WIDGET (gtk_builder_get_object (builder, "status_bar"));
+ priv->status_bar = status_bar;
- /* Relocate the 'preferences' menu item in the app menu */
- menu_item = GTK_WIDGET (gtk_builder_get_object (priv->builder, "preferences_menu_item"));
- gtk_osxapplication_insert_app_menu_item (osx_app, menu_item, 5);
- gtk_osxapplication_insert_app_menu_item (osx_app, gtk_separator_menu_item_new (), 6);
- gtk_widget_show_all (menu_item);
+ /* Get actions from GtkBuilder */
+ priv->load_project_action =
+ GTK_ACTION (gtk_builder_get_object (builder, "load_project_action"));
+ priv->save_project_action =
+ GTK_ACTION (gtk_builder_get_object (builder, "save_project_action"));
+ priv->save_project_as_action =
+ GTK_ACTION (gtk_builder_get_object (builder, "save_project_as_action"));
+ priv->load_pictures_action =
+ GTK_ACTION (gtk_builder_get_object (builder, "load_pictures_action"));
+ priv->remove_pictures_action =
+ GTK_ACTION (gtk_builder_get_object (builder, "remove_pictures_action"));
+ priv->upload_pictures_action =
+ GTK_ACTION (gtk_builder_get_object (builder, "upload_pictures_action"));
+ priv->open_in_external_viewer_action =
+ GTK_ACTION (gtk_builder_get_object (builder,
+ "open_in_external_viewer_action"));
+ priv->auth_action =
+ GTK_ACTION (gtk_builder_get_object (builder, "auth_action"));
+ priv->preferences_action =
+ GTK_ACTION (gtk_builder_get_object (builder, "preferences_action"));
+ priv->add_tags_action =
+ GTK_ACTION (gtk_builder_get_object (builder, "add_tags_action"));
+ priv->edit_details_action =
+ GTK_ACTION (gtk_builder_get_object (builder, "edit_details_action"));
+ priv->add_to_group_action =
+ GTK_ACTION (gtk_builder_get_object (builder, "add_to_group_action"));
+ priv->add_to_set_action =
+ GTK_ACTION (gtk_builder_get_object (builder, "add_to_set_action"));
+ priv->add_to_new_set_action =
+ GTK_ACTION (gtk_builder_get_object (builder, "add_to_new_set_action"));
+ priv->help_action =
+ GTK_ACTION (gtk_builder_get_object (builder, "help_action"));
+ priv->about_action =
+ GTK_ACTION (gtk_builder_get_object (builder, "about_action"));
+ priv->enable_tooltips_action =
+ GTK_TOGGLE_ACTION (gtk_builder_get_object (builder,
+ "enable_tooltips_action"));
+ priv->sort_by_title_action =
+ GTK_TOGGLE_ACTION (gtk_builder_get_object (builder,
+ "sort_by_title_action"));
+ priv->sort_by_date_taken_action =
+ GTK_TOGGLE_ACTION (gtk_builder_get_object (builder,
+ "sort_by_date_taken_action"));
+ priv->sort_as_loaded_action =
+ GTK_TOGGLE_ACTION (gtk_builder_get_object (builder,
+ "sort_as_loaded_action"));
+ priv->reversed_order_action =
+ GTK_TOGGLE_ACTION (gtk_builder_get_object (builder,
+ "reversed_order_action"));
+ /* Set Keyboard shortcuts */
+ _setup_keyboard_shortcuts (self);
- /* Hide the traditional application menu that won't be shown in the Mac */
- menu_item = GTK_WIDGET (gtk_builder_get_object (priv->builder, "frogr_menu_item"));
- gtk_widget_hide (menu_item);
+ /* Init main model's state description */
+ _update_state_description (self);
- /* Make sure accelerators are visible when needed */
- g_signal_connect(priv->menu_bar, "can-activate-accel",
- G_CALLBACK(osx_can_activate_cb), NULL);
+ /* Init the details of the current project */
+ _update_project_path (self, NULL);
- gtk_osxapplication_ready(osx_app);
-}
-#endif
+ /* Initialize sorting criteria and reverse in the UI */
+ if (priv->sorting_criteria == SORT_BY_TITLE)
+ gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priv->sort_by_title_action), TRUE);
+ else if (priv->sorting_criteria == SORT_BY_DATE)
+ gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priv->sort_by_date_taken_action), TRUE);
+ else
+ gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priv->sort_as_loaded_action), TRUE);
-static void
-_setup_keyboard_shortcuts (FrogrMainView *self)
-{
- FrogrMainViewPrivate *priv = NULL;
- GtkAccelGroup *accel = NULL;
- GtkWidget *menu_item = NULL;
+ gtk_toggle_action_set_active (priv->reversed_order_action, priv->sorting_reversed);
- priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
+ /* Initialize 'tooltips enabled' in the UI */
+ gtk_toggle_action_set_active (priv->enable_tooltips_action, priv->tooltips_enabled);
- accel = gtk_accel_group_new();
- gtk_window_add_accel_group(priv->window, accel);
+ /* Initialize extra widgets */
- menu_item = GTK_WIDGET (gtk_builder_get_object (priv->builder, "load_pictures_menu_item"));
- gtk_widget_add_accelerator(menu_item, "activate", accel, GDK_KEY_l,
- GDK_PRIMARY_MODIFIER, GTK_ACCEL_VISIBLE);
+ /* /\* Accounts menu *\/ */
+ /* priv->accounts_menu_item = */
+ /* GTK_WIDGET (gtk_builder_get_object (builder, "accounts_menu_item")); */
- menu_item = GTK_WIDGET (gtk_builder_get_object (priv->builder, "edit_details_menu_item"));
- gtk_widget_add_accelerator(menu_item, "activate", accel, GDK_KEY_d,
- GDK_PRIMARY_MODIFIER, GTK_ACCEL_VISIBLE);
+ /* "Add to set" menu needs to be assigned to a var so we control
+ its visibility directly because it has no action assigned to it */
+ priv->add_to_set_menu_item =
+ GTK_WIDGET (gtk_builder_get_object (builder, "add_to_set_menu_item"));
- menu_item = GTK_WIDGET (gtk_builder_get_object (priv->builder, "add_tags_menu_item"));
- gtk_widget_add_accelerator(menu_item, "activate", accel, GDK_KEY_t,
- GDK_PRIMARY_MODIFIER, GTK_ACCEL_VISIBLE);
+ /* populate accounts submenu from model */
+ _populate_accounts_submenu (self);
- menu_item = GTK_WIDGET (gtk_builder_get_object (priv->builder, "add_to_group_menu_item"));
- gtk_widget_add_accelerator(menu_item, "activate", accel, GDK_KEY_g,
- GDK_PRIMARY_MODIFIER, GTK_ACCEL_VISIBLE);
+ /* create contextual menus for right-clicks */
+ priv->pictures_ctxt_menu =
+ GTK_WIDGET (gtk_builder_get_object (builder, "ctxt_menu"));
- menu_item = GTK_WIDGET (gtk_builder_get_object (priv->builder, "add_to_existing_set_menu_item"));
- gtk_widget_add_accelerator(menu_item, "activate", accel, GDK_KEY_p,
- GDK_PRIMARY_MODIFIER, GTK_ACCEL_VISIBLE);
+ /* Initialize drag'n'drop support */
+ _initialize_drag_n_drop (self);
- menu_item = GTK_WIDGET (gtk_builder_get_object (priv->builder, "create_new_set_menu_item"));
- gtk_widget_add_accelerator(menu_item, "activate", accel, GDK_KEY_p,
- GDK_PRIMARY_MODIFIER | GDK_SHIFT_MASK, GTK_ACCEL_VISIBLE);
+ /* Create and hide progress bar dialog for uploading pictures */
+ progress_dialog = gtk_dialog_new_with_buttons (NULL,
+ GTK_WINDOW (self),
+ GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL,
+ NULL);
+ gtk_window_set_title (GTK_WINDOW (progress_dialog), APP_SHORTNAME);
- menu_item = GTK_WIDGET (gtk_builder_get_object (priv->builder, "open_in_external_viewer_menu_item"));
- gtk_widget_add_accelerator(menu_item, "activate", accel, GDK_KEY_v,
- GDK_PRIMARY_MODIFIER | GDK_SHIFT_MASK, GTK_ACCEL_VISIBLE);
+ gtk_dialog_set_response_sensitive (GTK_DIALOG (progress_dialog),
+ GTK_RESPONSE_CANCEL, TRUE);
- menu_item = GTK_WIDGET (gtk_builder_get_object (priv->builder, "upload_all_menu_item"));
- gtk_widget_add_accelerator(menu_item, "activate", accel, GDK_KEY_u,
- GDK_PRIMARY_MODIFIER | GDK_SHIFT_MASK, GTK_ACCEL_VISIBLE);
-}
+ gtk_container_set_border_width (GTK_CONTAINER (progress_dialog), 6);
+ gtk_window_set_default_size (GTK_WINDOW (progress_dialog), 250, -1);
-static void
-_populate_accounts_submenu (FrogrMainView *self)
-{
- FrogrMainViewPrivate *priv = NULL;
- FrogrAccount *account = NULL;
- GtkWidget *menu_item = NULL;
- GSList *accounts = NULL;
- GSList *item = NULL;
- gchar *account_str = NULL;
+ progress_vbox = gtk_dialog_get_content_area (GTK_DIALOG (progress_dialog));
- priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
- priv->accounts_menu = NULL;
+ progress_label = gtk_label_new (NULL);
+ gtk_box_pack_start (GTK_BOX (progress_vbox), progress_label, FALSE, FALSE, 6);
- accounts = frogr_controller_get_all_accounts (priv->controller);
- if (g_slist_length (accounts) > 0)
- priv->accounts_menu = gtk_menu_new ();
+ progress_bar = gtk_progress_bar_new ();
+ gtk_progress_bar_set_show_text (GTK_PROGRESS_BAR (progress_bar), TRUE);
- for (item = accounts; item; item = g_slist_next (item))
- {
- account = FROGR_ACCOUNT (item->data);
+ gtk_box_pack_start (GTK_BOX (progress_vbox), progress_bar, FALSE, FALSE, 6);
- /* Do not use the full name here since it could be the same for
- different users, thus wouldn't be useful at all for the
- matter of selecting one account or another. */
- account_str = g_strdup (frogr_account_get_username (account));
- menu_item = gtk_check_menu_item_new_with_label (account_str);
- g_free (account_str);
+ gtk_widget_hide (progress_dialog);
+ priv->progress_dialog = progress_dialog;
+ priv->progress_bar = progress_bar;
+ priv->progress_label = progress_label;
+ priv->progress_is_showing = FALSE;
+ priv->state_description = NULL;
- g_object_set_data (G_OBJECT (menu_item), "frogr-account", account);
+ /* Initialize model */
+ priv->tree_model = GTK_TREE_MODEL (gtk_list_store_new (3,
+ G_TYPE_STRING,
+ GDK_TYPE_PIXBUF,
+ G_TYPE_POINTER));
+ gtk_icon_view_set_model (GTK_ICON_VIEW (icon_view), priv->tree_model);
+ gtk_icon_view_set_pixbuf_column (GTK_ICON_VIEW (icon_view), PIXBUF_COL);
+ gtk_icon_view_set_selection_mode (GTK_ICON_VIEW (icon_view),
+ GTK_SELECTION_MULTIPLE);
+ gtk_icon_view_set_columns (GTK_ICON_VIEW (icon_view), -1);
+ gtk_icon_view_set_item_width (GTK_ICON_VIEW (icon_view), IV_THUMB_WIDTH + IV_THUMB_PADDING);
+ gtk_icon_view_set_item_padding (GTK_ICON_VIEW (icon_view), IV_THUMB_PADDING);
+ gtk_icon_view_set_column_spacing (GTK_ICON_VIEW (icon_view), IV_THUMB_PADDING);
+ gtk_icon_view_set_row_spacing (GTK_ICON_VIEW (icon_view), IV_THUMB_PADDING);
+ gtk_widget_set_has_tooltip (icon_view, TRUE);
- g_signal_connect (G_OBJECT (menu_item), "activate",
- G_CALLBACK (_on_account_menu_item_toggled),
- self);
- gtk_menu_shell_append (GTK_MENU_SHELL (priv->accounts_menu), menu_item);
+ gtk_window_set_default_size (GTK_WINDOW (self), MINIMUM_WINDOW_WIDTH, MINIMUM_WINDOW_HEIGHT);
+
+ /* Init status bar */
+ priv->sb_context_id =
+ gtk_statusbar_get_context_id (GTK_STATUSBAR (priv->status_bar),
+ "Status bar messages");
+
+ /* Connect signals */
+ g_signal_connect (G_OBJECT (self), "delete-event",
+ G_CALLBACK (_on_main_view_delete_event),
+ self);
+
+ g_signal_connect (G_OBJECT (priv->icon_view), "query-tooltip",
+ G_CALLBACK (_on_icon_view_query_tooltip),
+ self);
+
+ g_signal_connect (G_OBJECT (priv->icon_view), "selection-changed",
+ G_CALLBACK (_on_icon_view_selection_changed),
+ self);
+
+ g_signal_connect (G_OBJECT (priv->progress_dialog), "response",
+ G_CALLBACK(_progress_dialog_response),
+ self);
+
+ g_signal_connect (G_OBJECT (priv->progress_dialog),
+ "delete-event",
+ G_CALLBACK(_progress_dialog_delete_event),
+ self);
+
+ gtk_builder_connect_signals (builder, self);
+
+#ifdef MAC_INTEGRATION
+ _tweak_menu_bar_for_mac (self);
+#endif
+
+ /* Update window title */
+ _update_window_title (self, FALSE);
+
+ /* Update UI */
+ _update_ui (FROGR_MAIN_VIEW (self));
+
+ /* Show the auth dialog, if needed, on idle */
+ g_idle_add ((GSourceFunc) _maybe_show_auth_dialog_on_idle, self);
+}
+
+static gboolean
+_maybe_show_auth_dialog_on_idle (FrogrMainView *self)
+{
+ FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
+
+ if (!frogr_controller_is_authorized (priv->controller))
+ {
+ /* Show authorization dialog if needed */
+ frogr_controller_show_auth_dialog (priv->controller);
}
- /* gtk_menu_item_set_submenu (GTK_MENU_ITEM (priv->accounts_menu_item), priv->accounts_menu); */
+ return FALSE;
+}
- if (priv->accounts_menu)
- gtk_widget_show_all (priv->accounts_menu);
+static void
+_load_project_action (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer data)
+{
+ _load_project_dialog (FROGR_MAIN_VIEW (data));
}
static void
-_initialize_drag_n_drop (FrogrMainView *self)
+_save_project_action (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer data)
{
- FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
+ _save_current_project (FROGR_MAIN_VIEW (data));
+}
- gtk_drag_dest_set (priv->icon_view, GTK_DEST_DEFAULT_ALL,
- NULL, 0, GDK_ACTION_COPY );
- gtk_drag_dest_add_uri_targets (priv->icon_view);
+static void
+_save_project_as_action (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer data)
+{
+ _save_project_as_dialog (FROGR_MAIN_VIEW (data));
+}
- g_signal_connect(G_OBJECT(priv->icon_view), "drag-data-received",
- G_CALLBACK(_on_icon_view_drag_data_received),
- self);
+static void
+_authorize_action (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer data)
+{
+ FrogrMainViewPrivate *priv = NULL;
+ priv = FROGR_MAIN_VIEW_GET_PRIVATE (data);
+ frogr_controller_show_auth_dialog (priv->controller);
}
static void
-_on_icon_view_drag_data_received (GtkWidget *widget,
- GdkDragContext *context,
- gint x, gint y,
- GtkSelectionData *selection_data,
- guint info, guint time,
- gpointer data)
+_preferences_action (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer data)
{
- FrogrMainView *self = NULL;
FrogrMainViewPrivate *priv = NULL;
- GdkAtom target;
- GSList *fileuris_list = NULL;
- const guchar *files_string = NULL;
- gchar **fileuris_array = NULL;
- gint i;
+ priv = FROGR_MAIN_VIEW_GET_PRIVATE (data);
+ frogr_controller_show_settings_dialog (priv->controller);
+}
+
+static void
+_about_action (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer data)
+{
+ FrogrMainViewPrivate *priv = NULL;
+ priv = FROGR_MAIN_VIEW_GET_PRIVATE (data);
+ frogr_controller_show_about_dialog (priv->controller);
+}
+
+static void
+_help_action (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer data)
+{
+ frogr_util_open_uri ("ghelp:frogr");
+}
+
+static void
+_quit_action (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer data)
+{
+ _quit_application (FROGR_MAIN_VIEW (data));
+}
+
+static void
+_update_project_path (FrogrMainView *self, const gchar *path)
+{
+ FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
+
+ /* Early return if nothing changed */
+ if (!g_strcmp0 (priv->project_filepath, path))
+ return;
+
+ g_free (priv->project_name);
+ g_free (priv->project_dir);
+ g_free (priv->project_filepath);
+
+ if (!path)
+ {
+ priv->project_name = NULL;
+ priv->project_dir = NULL;
+ priv->project_filepath = NULL;
+ }
+ else
+ {
+ GFile *file = NULL;
+ GFile *dir = NULL;
+ GFileInfo *file_info = NULL;
+ gchar *dir_path = NULL;
+ const gchar *home_dir = NULL;
+
+ /* Get the display name in beautiful UTF-8 */
+ file = g_file_new_for_path (path);
+ file_info = g_file_query_info (file,
+ G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
+ G_FILE_QUERY_INFO_NONE,
+ NULL,
+ NULL);
+ priv->project_name = g_strdup (g_file_info_get_display_name (file_info));
- self = FROGR_MAIN_VIEW (data);
- priv = FROGR_MAIN_VIEW_GET_PRIVATE (data);
+ /* Get the base directory, in beautiful UTF-8 too */
+ dir = g_file_get_parent (file);
+ dir_path = g_file_get_parse_name (dir);
+ home_dir = g_get_home_dir ();
+ if (g_str_has_prefix (dir_path, home_dir))
+ {
+ gchar *tmp_path = NULL;
- /* Do nothing when the application is busy doing something else */
- if (FROGR_STATE_IS_BUSY(frogr_controller_get_state (priv->controller)))
- return;
+ tmp_path = dir_path;
+ dir_path = g_strdup_printf ("~%s", &dir_path[g_utf8_strlen (home_dir, -1)]);
+ g_free (tmp_path);
+ }
+ priv->project_dir = dir_path;
- target = gtk_selection_data_get_target (selection_data);
+ /* Finally, store the raw path too */
+ priv->project_filepath = g_strdup (path);
- if (!gtk_targets_include_uri (&target, 1))
- return;
+ g_object_unref (file);
+ g_object_unref (dir);
+ }
+}
- /* Get GSList with the list of files */
- files_string = gtk_selection_data_get_data (selection_data);
+static void
+_update_window_title (FrogrMainView *self, gboolean dirty)
+{
+ FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
- fileuris_array = g_strsplit ((const gchar*)files_string, "\r\n", -1);
- for (i = 0; fileuris_array[i]; i++)
- {
- if (fileuris_array[i] && fileuris_array[i][0] != '\0')
- fileuris_list = g_slist_append (fileuris_list, g_strdup (fileuris_array[i]));
- }
+ gchar *session_string = NULL;
+ gchar *window_title = NULL;
- /* Load pictures */
- if (fileuris_list != NULL)
- _load_pictures (FROGR_MAIN_VIEW (self), fileuris_list);
+ session_string = priv->project_name
+ ? g_strdup_printf ("%s%s (%s) - ", (dirty ? "*" : ""),
+ priv->project_name, priv->project_dir)
+ : g_strdup("");
- /* Finish drag and drop */
- gtk_drag_finish (context, TRUE, FALSE, time);
+ window_title = g_strdup_printf ("%s%s", session_string, APP_SHORTNAME);
+ g_free (session_string);
- /* Free */
- g_strfreev (fileuris_array);
+ gtk_window_set_title (GTK_WINDOW (self), window_title);
+ g_free (window_title);
}
-void
-_on_action_activated (GtkAction *action, gpointer data)
+#ifdef MAC_INTEGRATION
+static gboolean
+osx_can_activate_cb(GtkWidget* widget, guint signal_id, gpointer data)
{
- FrogrMainView *mainview = FROGR_MAIN_VIEW (data);
- FrogrMainViewPrivate *priv = NULL;
-
- priv = FROGR_MAIN_VIEW_GET_PRIVATE (data);
- if (action == priv->load_project_action)
- _load_project_dialog (mainview);
- else if (action == priv->save_project_action)
- _save_current_project (mainview);
- else if (action == priv->save_project_as_action)
- _save_project_as_dialog (mainview);
- else if (action == priv->load_pictures_action)
- _load_pictures_dialog (mainview);
- else if (action == priv->remove_pictures_action)
- _remove_selected_pictures (mainview);
- else if (action == priv->upload_pictures_action)
- _upload_pictures (mainview);
- else if (action == priv->open_in_external_viewer_action)
- _open_pictures_in_external_viewer (mainview);
- else if (action == priv->add_tags_action)
- _add_tags_to_pictures (mainview);
- else if (action == priv->edit_details_action)
- _edit_selected_pictures (mainview);
- else if (action == priv->add_to_group_action)
- _add_pictures_to_group (mainview);
- else if (action == priv->add_to_set_action)
- _add_pictures_to_existing_set (mainview);
- else if (action == priv->add_to_new_set_action)
- _add_pictures_to_new_set (mainview);
+ return gtk_widget_is_sensitive(widget);
}
-void
-_on_toggle_action_changed (GtkToggleAction *action,
- gpointer data)
+static void
+_tweak_menu_bar_for_mac (FrogrMainView *self)
{
- gboolean checked;
- FrogrMainView *mainview = FROGR_MAIN_VIEW (data);
FrogrMainViewPrivate *priv = NULL;
+ GtkOSXApplication *osx_app = NULL;
+ GtkWidget *menu_item = NULL;
- priv = FROGR_MAIN_VIEW_GET_PRIVATE (data);
-
- checked = gtk_toggle_action_get_active (action);
- if (action == priv->enable_tooltips_action)
- {
- frogr_config_set_mainview_enable_tooltips (priv->config, checked);
- priv->tooltips_enabled = checked;
- }
- else if (action == priv->reversed_order_action)
- {
- _reorder_pictures (mainview, priv->sorting_criteria, checked);
- frogr_config_set_mainview_sorting_reversed (priv->config, checked);
- }
- else if (checked)
- {
- /* Radio buttons handling here (only care about 'em when checked) */
-
- SortingCriteria criteria = SORT_AS_LOADED;
-
- if (action == priv->sort_by_title_action)
- criteria = SORT_BY_TITLE;
- else if (action == priv->sort_by_date_taken_action)
- criteria = SORT_BY_DATE;
+ priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
- _reorder_pictures (mainview, criteria, priv->sorting_reversed);
- frogr_config_set_mainview_sorting_criteria (priv->config, criteria);
- }
+ osx_app = g_object_new (GTK_TYPE_OSX_APPLICATION, NULL);
+ gtk_osxapplication_set_menu_bar (osx_app, GTK_MENU_SHELL(priv->menu_bar));
- /* State for check menu items should be immediately stored */
- frogr_config_save_settings (priv->config);
-}
+ /* Relocate the 'about' menu item in the app menu */
+ menu_item = GTK_WIDGET (gtk_builder_get_object (priv->builder, "about_menu_item"));
+ gtk_osxapplication_insert_app_menu_item (osx_app, menu_item, 0);
+ gtk_osxapplication_insert_app_menu_item (osx_app, gtk_separator_menu_item_new (), 1);
+ gtk_widget_show_all (menu_item);
-gboolean
-_on_icon_view_key_press_event (GtkWidget *widget,
- GdkEventKey *event,
- gpointer data)
-{
- FrogrMainView *mainview = FROGR_MAIN_VIEW (data);
- FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (data);
+ /* Relocate the 'authorize' menu item in the app menu */
+ menu_item = GTK_WIDGET (gtk_builder_get_object (priv->builder, "authorize_menu_item"));
+ gtk_osxapplication_insert_app_menu_item (osx_app, menu_item, 2);
+ gtk_widget_show_all (menu_item);
- /* Actions are only allowed in IDLE state */
- if (frogr_controller_get_state (priv->controller) != FROGR_STATE_IDLE)
- return TRUE;
+ /* Relocate the 'accounts' menu item in the app menu */
+ menu_item = GTK_WIDGET (gtk_builder_get_object (priv->builder, "accounts_menu_item"));
+ gtk_osxapplication_insert_app_menu_item (osx_app, menu_item, 3);
+ gtk_osxapplication_insert_app_menu_item (osx_app, gtk_separator_menu_item_new (), 4);
+ gtk_widget_show_all (menu_item);
- /* Do nothing if there's no picture loaded yet */
- if (!_n_pictures (mainview))
- return TRUE;
+ /* Relocate the 'preferences' menu item in the app menu */
+ menu_item = GTK_WIDGET (gtk_builder_get_object (priv->builder, "preferences_menu_item"));
+ gtk_osxapplication_insert_app_menu_item (osx_app, menu_item, 5);
+ gtk_osxapplication_insert_app_menu_item (osx_app, gtk_separator_menu_item_new (), 6);
+ gtk_widget_show_all (menu_item);
- /* Remove selected pictures if pressed Supr */
- if ((event->type == GDK_KEY_PRESS) && (event->keyval == GDK_KEY_Delete))
- _remove_selected_pictures (mainview);
+ /* Hide the traditional application menu that won't be shown in the Mac */
+ menu_item = GTK_WIDGET (gtk_builder_get_object (priv->builder, "frogr_menu_item"));
+ gtk_widget_hide (menu_item);
- /* Show contextual menu if pressed the 'Menu' key */
- if (event->type == GDK_KEY_PRESS && event->keyval == GDK_KEY_Menu
- && priv->n_selected_pictures > 0)
- {
- GtkMenu *menu = GTK_MENU (priv->pictures_ctxt_menu);
- gtk_menu_popup (menu, NULL, NULL, NULL, NULL,
- 0, gtk_get_current_event_time ());
- }
+ /* Make sure accelerators are visible when needed */
+ g_signal_connect(priv->menu_bar, "can-activate-accel",
+ G_CALLBACK(osx_can_activate_cb), NULL);
- return FALSE;
+ gtk_osxapplication_ready(osx_app);
}
+#endif
-gboolean
-_on_icon_view_button_press_event (GtkWidget *widget,
- GdkEventButton *event,
- gpointer data)
+static void
+_setup_keyboard_shortcuts (FrogrMainView *self)
{
- FrogrMainView *mainview = FROGR_MAIN_VIEW (data);
- FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (data);
- GtkTreePath *path;
-
- /* Actions are only allowed in IDLE state */
- if (frogr_controller_get_state (priv->controller) != FROGR_STATE_IDLE)
- return TRUE;
+ FrogrMainViewPrivate *priv = NULL;
+ GtkAccelGroup *accel = NULL;
+ GtkWidget *menu_item = NULL;
- /* Do nothing if there's no picture loaded yet */
- if (!_n_pictures (mainview))
- return TRUE;
+ priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
- /* Check if we clicked on top of an item */
- if (gtk_icon_view_get_item_at_pos (GTK_ICON_VIEW (priv->icon_view),
- event->x,
- event->y,
- &path,
- NULL))
- {
- gboolean path_selected =
- gtk_icon_view_path_is_selected (GTK_ICON_VIEW (priv->icon_view), path);
+ accel = gtk_accel_group_new();
+ gtk_window_add_accel_group(GTK_WINDOW (self), accel);
- /* Check whether it's needed to keep this item as the only selection */
- if (((event->button == 1) && path_selected)
- || ((event->button == 3) && !path_selected))
- {
- if (!(event->state & GDK_SHIFT_MASK)
- && !(event->state & GDK_CONTROL_MASK))
- {
- /* Deselect all items if not pressing Ctrl or shift */
- gtk_icon_view_unselect_all (GTK_ICON_VIEW (priv->icon_view));
- }
+ menu_item = GTK_WIDGET (gtk_builder_get_object (priv->builder, "load_pictures_menu_item"));
+ gtk_widget_add_accelerator(menu_item, "activate", accel, GDK_KEY_l,
+ GDK_PRIMARY_MODIFIER, GTK_ACCEL_VISIBLE);
- /* Now select the item */
- gtk_icon_view_select_path (GTK_ICON_VIEW (priv->icon_view), path);
+ menu_item = GTK_WIDGET (gtk_builder_get_object (priv->builder, "edit_details_menu_item"));
+ gtk_widget_add_accelerator(menu_item, "activate", accel, GDK_KEY_d,
+ GDK_PRIMARY_MODIFIER, GTK_ACCEL_VISIBLE);
- }
+ menu_item = GTK_WIDGET (gtk_builder_get_object (priv->builder, "add_tags_menu_item"));
+ gtk_widget_add_accelerator(menu_item, "activate", accel, GDK_KEY_t,
+ GDK_PRIMARY_MODIFIER, GTK_ACCEL_VISIBLE);
- /* Perform the right action: edit picture or show ctxt menu */
- if ((event->button == 1) /* left button */
- && (event->type == GDK_2BUTTON_PRESS ) /* doubleclick */
- && !(event->state & GDK_SHIFT_MASK) /* not shift */
- && !(event->state & GDK_CONTROL_MASK)) /* not Ctrl */
- {
- /* edit selected item */
- _edit_selected_pictures (mainview);
- }
- else if ((event->button == 3) /* right button */
- && (event->type == GDK_BUTTON_PRESS)) /* single click */
- {
- /* Show contextual menu */
- gtk_menu_popup (GTK_MENU (priv->pictures_ctxt_menu),
- NULL, NULL, NULL, NULL,
- event->button,
- gtk_get_current_event_time ());
- }
+ menu_item = GTK_WIDGET (gtk_builder_get_object (priv->builder, "add_to_group_menu_item"));
+ gtk_widget_add_accelerator(menu_item, "activate", accel, GDK_KEY_g,
+ GDK_PRIMARY_MODIFIER, GTK_ACCEL_VISIBLE);
- /* Free */
- gtk_tree_path_free (path);
- }
+ menu_item = GTK_WIDGET (gtk_builder_get_object (priv->builder, "add_to_existing_set_menu_item"));
+ gtk_widget_add_accelerator(menu_item, "activate", accel, GDK_KEY_p,
+ GDK_PRIMARY_MODIFIER, GTK_ACCEL_VISIBLE);
- return FALSE;
+ menu_item = GTK_WIDGET (gtk_builder_get_object (priv->builder, "create_new_set_menu_item"));
+ gtk_widget_add_accelerator(menu_item, "activate", accel, GDK_KEY_p,
+ GDK_PRIMARY_MODIFIER | GDK_SHIFT_MASK, GTK_ACCEL_VISIBLE);
+
+ menu_item = GTK_WIDGET (gtk_builder_get_object (priv->builder, "open_in_external_viewer_menu_item"));
+ gtk_widget_add_accelerator(menu_item, "activate", accel, GDK_KEY_v,
+ GDK_PRIMARY_MODIFIER | GDK_SHIFT_MASK, GTK_ACCEL_VISIBLE);
+
+ menu_item = GTK_WIDGET (gtk_builder_get_object (priv->builder, "upload_all_menu_item"));
+ gtk_widget_add_accelerator(menu_item, "activate", accel, GDK_KEY_u,
+ GDK_PRIMARY_MODIFIER | GDK_SHIFT_MASK, GTK_ACCEL_VISIBLE);
}
-void
-_on_account_menu_item_toggled (GtkWidget *widget, gpointer self)
+static void
+_populate_accounts_submenu (FrogrMainView *self)
{
FrogrMainViewPrivate *priv = NULL;
FrogrAccount *account = NULL;
- gboolean checked = FALSE;
+ GtkWidget *menu_item = NULL;
+ GSList *accounts = NULL;
+ GSList *item = NULL;
+ gchar *account_str = NULL;
priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
- checked = gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (widget));
- account = g_object_get_data (G_OBJECT (widget), "frogr-account");
+ priv->accounts_menu = NULL;
- /* Only set the account if checked */
- if (checked && account)
- {
- DEBUG ("Selected account %s (%s)",
- frogr_account_get_id (account),
- frogr_account_get_username (account));
+ accounts = frogr_controller_get_all_accounts (priv->controller);
+ if (g_slist_length (accounts) > 0)
+ priv->accounts_menu = gtk_menu_new ();
- frogr_controller_set_active_account (priv->controller, account);
- }
- else if (account)
+ for (item = accounts; item; item = g_slist_next (item))
{
- /* If manually unchecked the currently active account, set it again */
- FrogrAccount *active_account = frogr_controller_get_active_account (priv->controller);
- if (frogr_account_equal (active_account, account))
- gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (widget), TRUE);
+ account = FROGR_ACCOUNT (item->data);
+
+ /* Do not use the full name here since it could be the same for
+ different users, thus wouldn't be useful at all for the
+ matter of selecting one account or another. */
+ account_str = g_strdup (frogr_account_get_username (account));
+ menu_item = gtk_check_menu_item_new_with_label (account_str);
+ g_free (account_str);
+
+ g_object_set_data (G_OBJECT (menu_item), "frogr-account", account);
+
+ g_signal_connect (G_OBJECT (menu_item), "activate",
+ G_CALLBACK (_on_account_menu_item_toggled),
+ self);
+ gtk_menu_shell_append (GTK_MENU_SHELL (priv->accounts_menu), menu_item);
}
+
+ /* gtk_menu_item_set_submenu (GTK_MENU_ITEM (priv->accounts_menu_item), priv->accounts_menu); */
+
+ if (priv->accounts_menu)
+ gtk_widget_show_all (priv->accounts_menu);
}
static void
-_quit_application (FrogrMainView *self)
+_initialize_drag_n_drop (FrogrMainView *self)
{
FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
- g_application_quit (G_APPLICATION (priv->gtk_app));
-}
-static gboolean
-_on_main_view_delete_event (GtkWidget *widget,
- GdkEvent *event,
- gpointer self)
-{
- _quit_application (FROGR_MAIN_VIEW (self));
- return TRUE;
+ gtk_drag_dest_set (priv->icon_view, GTK_DEST_DEFAULT_ALL,
+ NULL, 0, GDK_ACTION_COPY );
+ gtk_drag_dest_add_uri_targets (priv->icon_view);
+
+ g_signal_connect(G_OBJECT(priv->icon_view), "drag-data-received",
+ G_CALLBACK(_on_icon_view_drag_data_received),
+ self);
}
-static gboolean
-_on_icon_view_query_tooltip (GtkWidget *icon_view,
- gint x, gint y,
- gboolean keyboard_mode,
- GtkTooltip *tooltip,
- gpointer data)
+static void
+_on_icon_view_drag_data_received (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x, gint y,
+ GtkSelectionData *selection_data,
+ guint info, guint time,
+ gpointer data)
{
FrogrMainView *self = NULL;
FrogrMainViewPrivate *priv = NULL;
- GtkTreePath *path;
- gint bw_x;
- gint bw_y;
-
- /* No tooltips in keyboard mode... yet */
- if (keyboard_mode)
- return FALSE;
+ GdkAtom target;
+ GSList *fileuris_list = NULL;
+ const guchar *files_string = NULL;
+ gchar **fileuris_array = NULL;
+ gint i;
self = FROGR_MAIN_VIEW (data);
- priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
-
- /* Disabled by configuration */
- if (!frogr_config_get_mainview_enable_tooltips (priv->config))
- return FALSE;
-
- /* Check whether we're asking for a tooltip over a picture */
- gtk_icon_view_convert_widget_to_bin_window_coords (GTK_ICON_VIEW (icon_view),
- x, y, &bw_x, &bw_y);
- if (gtk_icon_view_get_item_at_pos (GTK_ICON_VIEW (icon_view), bw_x, bw_y, &path, NULL))
- {
- FrogrPicture *picture;
- GtkTreeIter iter;
- gchar *tooltip_str = NULL;
- gchar *filesize = NULL;
- gchar *filesize_str = NULL;
- gchar *filesize_markup = NULL;
- gchar *datetime_markup = NULL;
- const gchar *datetime = NULL;
-
- /* Get needed information */
- gtk_tree_model_get_iter (priv->tree_model, &iter, path);
- gtk_tree_model_get (priv->tree_model,
- &iter,
- FPICTURE_COL, &picture,
- -1);
-
- /* Bail out here if needed */
- if (!picture || !FROGR_IS_PICTURE (picture))
- return FALSE;
-
- /* Build the tooltip text with basic info: title, size */
- filesize = frogr_util_get_datasize_string (frogr_picture_get_filesize (picture));
- datetime = frogr_picture_get_datetime (picture);
- if (datetime)
- {
- gchar *datetime_str = NULL;
+ priv = FROGR_MAIN_VIEW_GET_PRIVATE (data);
- /* String showind the date and time a picture was taken */
- datetime_str = g_strdup_printf (_("Taken: %s"), datetime);
- datetime_markup = g_strdup_printf ("\n<i>%s</i>", datetime_str);
- g_free (datetime_str);
- }
+ /* Do nothing when the application is busy doing something else */
+ if (FROGR_STATE_IS_BUSY(frogr_controller_get_state (priv->controller)))
+ return;
- filesize_str = g_strdup_printf (_("File size: %s"), filesize);
- filesize_markup = g_strdup_printf ("<i>%s</i>", filesize_str);
+ target = gtk_selection_data_get_target (selection_data);
- tooltip_str = g_strdup_printf ("<b>%s</b>\n%s%s",
- frogr_picture_get_title (picture),
- filesize_markup,
- datetime_markup ? datetime_markup : "");
+ if (!gtk_targets_include_uri (&target, 1))
+ return;
- gtk_tooltip_set_markup (tooltip, tooltip_str);
+ /* Get GSList with the list of files */
+ files_string = gtk_selection_data_get_data (selection_data);
- /* Free memory */
- gtk_tree_path_free (path);
- g_free (tooltip_str);
- g_free (filesize);
- g_free (filesize_str);
- g_free (filesize_markup);
- g_free (datetime_markup);
- return TRUE;
+ fileuris_array = g_strsplit ((const gchar*)files_string, "\r\n", -1);
+ for (i = 0; fileuris_array[i]; i++)
+ {
+ if (fileuris_array[i] && fileuris_array[i][0] != '\0')
+ fileuris_list = g_slist_append (fileuris_list, g_strdup (fileuris_array[i]));
}
- return FALSE;
-}
-
-static void
-_on_icon_view_selection_changed (GtkWidget *icon_view, gpointer data)
-{
- FrogrMainView *self = FROGR_MAIN_VIEW (data);
- FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
- GList *selected_pictures = NULL;
- gint len = 0;
-
- /* We save the value here to avoid traversing all the list whenever
- we need to check the number of selected pictures */
- selected_pictures =
- gtk_icon_view_get_selected_items (GTK_ICON_VIEW (priv->icon_view));
-
- len = g_list_length (selected_pictures);
-
- g_list_foreach (selected_pictures, (GFunc)gtk_tree_path_free, NULL);
- g_list_free (selected_pictures);
+ /* Load pictures */
+ if (fileuris_list != NULL)
+ _load_pictures (FROGR_MAIN_VIEW (self), fileuris_list);
- priv->n_selected_pictures = len;
+ /* Finish drag and drop */
+ gtk_drag_finish (context, TRUE, FALSE, time);
- /* Update sensitiveness for actions */
- _update_sensitiveness (self);
+ /* Free */
+ g_strfreev (fileuris_array);
}
-static GSList *
-_get_selected_pictures (FrogrMainView *self)
+void
+_on_action_activated (GtkAction *action, gpointer data)
{
- FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
- GSList *pictures = NULL;
- GList *selected_pictures;
- GList *item;
-
- /* Iterate over selected items */
- selected_pictures =
- gtk_icon_view_get_selected_items (GTK_ICON_VIEW (priv->icon_view));
- for (item = selected_pictures; item; item = g_list_next (item))
- {
- FrogrPicture *picture;
- GtkTreePath *path;
- GtkTreeIter iter;
-
- /* Get needed information */
- path = (GtkTreePath *)(item->data);
- gtk_tree_model_get_iter (priv->tree_model, &iter, path);
- gtk_tree_model_get (priv->tree_model,
- &iter,
- FPICTURE_COL, &picture,
- -1);
-
- /* Add the picture to the list */
- pictures = g_slist_prepend (pictures, g_object_ref (picture));
- gtk_tree_path_free (path);
- }
-
- g_list_free (selected_pictures);
+ FrogrMainView *mainview = FROGR_MAIN_VIEW (data);
+ FrogrMainViewPrivate *priv = NULL;
- return pictures;
+ priv = FROGR_MAIN_VIEW_GET_PRIVATE (data);
+ if (action == priv->load_project_action)
+ _load_project_dialog (mainview);
+ else if (action == priv->save_project_action)
+ _save_current_project (mainview);
+ else if (action == priv->save_project_as_action)
+ _save_project_as_dialog (mainview);
+ else if (action == priv->load_pictures_action)
+ _load_pictures_dialog (mainview);
+ else if (action == priv->remove_pictures_action)
+ _remove_selected_pictures (mainview);
+ else if (action == priv->upload_pictures_action)
+ _upload_pictures (mainview);
+ else if (action == priv->open_in_external_viewer_action)
+ _open_pictures_in_external_viewer (mainview);
+ else if (action == priv->add_tags_action)
+ _add_tags_to_pictures (mainview);
+ else if (action == priv->edit_details_action)
+ _edit_selected_pictures (mainview);
+ else if (action == priv->add_to_group_action)
+ _add_pictures_to_group (mainview);
+ else if (action == priv->add_to_set_action)
+ _add_pictures_to_existing_set (mainview);
+ else if (action == priv->add_to_new_set_action)
+ _add_pictures_to_new_set (mainview);
}
-static gint
-_n_pictures (FrogrMainView *self)
+void
+_on_toggle_action_changed (GtkToggleAction *action,
+ gpointer data)
{
- FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
-
- /* Just return the number of pictures in the model */
- return frogr_model_n_pictures (priv->model);
-}
+ gboolean checked;
+ FrogrMainView *mainview = FROGR_MAIN_VIEW (data);
+ FrogrMainViewPrivate *priv = NULL;
-static void
-_load_project_dialog_response_cb (GtkDialog *dialog,
- gint response,
- gpointer data)
-{
- FrogrMainView *self = FROGR_MAIN_VIEW (data);
+ priv = FROGR_MAIN_VIEW_GET_PRIVATE (data);
- if (response == GTK_RESPONSE_ACCEPT)
+ checked = gtk_toggle_action_get_active (action);
+ if (action == priv->enable_tooltips_action)
{
- gchar *filename = NULL;
+ frogr_config_set_mainview_enable_tooltips (priv->config, checked);
+ priv->tooltips_enabled = checked;
+ }
+ else if (action == priv->reversed_order_action)
+ {
+ _reorder_pictures (mainview, priv->sorting_criteria, checked);
+ frogr_config_set_mainview_sorting_reversed (priv->config, checked);
+ }
+ else if (checked)
+ {
+ /* Radio buttons handling here (only care about 'em when checked) */
- filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
- if (filename != NULL)
- {
- FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
+ SortingCriteria criteria = SORT_AS_LOADED;
- /* Load from disk and update project's path */
- frogr_controller_load_project_from_file (priv->controller, filename);
- _update_project_path (self, filename);
+ if (action == priv->sort_by_title_action)
+ criteria = SORT_BY_TITLE;
+ else if (action == priv->sort_by_date_taken_action)
+ criteria = SORT_BY_DATE;
- g_free (filename);
- }
+ _reorder_pictures (mainview, criteria, priv->sorting_reversed);
+ frogr_config_set_mainview_sorting_criteria (priv->config, criteria);
}
- gtk_widget_destroy (GTK_WIDGET (dialog));
+ /* State for check menu items should be immediately stored */
+ frogr_config_save_settings (priv->config);
}
-static void
-_load_project_dialog (FrogrMainView *self)
+gboolean
+_on_icon_view_key_press_event (GtkWidget *widget,
+ GdkEventKey *event,
+ gpointer data)
{
- FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
- GtkWidget *dialog;
- GtkFileFilter *filter;
+ FrogrMainView *mainview = FROGR_MAIN_VIEW (data);
+ FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (data);
- dialog = gtk_file_chooser_dialog_new (_("Select File"),
- GTK_WINDOW (priv->window),
- GTK_FILE_CHOOSER_ACTION_SAVE,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
- NULL);
+ /* Actions are only allowed in IDLE state */
+ if (frogr_controller_get_state (priv->controller) != FROGR_STATE_IDLE)
+ return TRUE;
- gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), FALSE);
- gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (dialog), TRUE);
+ /* Do nothing if there's no picture loaded yet */
+ if (!_n_pictures (mainview))
+ return TRUE;
- /* Let's allow text files only */
- filter = gtk_file_filter_new ();
- gtk_file_filter_add_mime_type (filter, "text/*");
- gtk_file_filter_set_name (filter, _("Text Files"));
- gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
+ /* Remove selected pictures if pressed Supr */
+ if ((event->type == GDK_KEY_PRESS) && (event->keyval == GDK_KEY_Delete))
+ _remove_selected_pictures (mainview);
- g_signal_connect (G_OBJECT (dialog), "response",
- G_CALLBACK (_load_project_dialog_response_cb), self);
+ /* Show contextual menu if pressed the 'Menu' key */
+ if (event->type == GDK_KEY_PRESS && event->keyval == GDK_KEY_Menu
+ && priv->n_selected_pictures > 0)
+ {
+ GtkMenu *menu = GTK_MENU (priv->pictures_ctxt_menu);
+ gtk_menu_popup (menu, NULL, NULL, NULL, NULL,
+ 0, gtk_get_current_event_time ());
+ }
- gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
- gtk_widget_show_all (dialog);
+ return FALSE;
}
-static void
-_save_current_project (FrogrMainView *self)
+gboolean
+_on_icon_view_button_press_event (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer data)
{
- FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
+ FrogrMainView *mainview = FROGR_MAIN_VIEW (data);
+ FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (data);
+ GtkTreePath *path;
- if (priv->project_filepath)
- _save_project_to_file (self, priv->project_filepath);
- else
- _save_project_as_dialog (self);
-}
+ /* Actions are only allowed in IDLE state */
+ if (frogr_controller_get_state (priv->controller) != FROGR_STATE_IDLE)
+ return TRUE;
-static void
-_save_project_to_file (FrogrMainView *self, const gchar *filepath)
-{
- FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
+ /* Do nothing if there's no picture loaded yet */
+ if (!_n_pictures (mainview))
+ return TRUE;
- /* Save to disk and update project's path */
- frogr_controller_save_project_to_file (priv->controller, filepath);
- _update_project_path (self, filepath);
+ /* Check if we clicked on top of an item */
+ if (gtk_icon_view_get_item_at_pos (GTK_ICON_VIEW (priv->icon_view),
+ event->x,
+ event->y,
+ &path,
+ NULL))
+ {
+ gboolean path_selected =
+ gtk_icon_view_path_is_selected (GTK_ICON_VIEW (priv->icon_view), path);
- /* Update title marking it as non-dirty (just saved) */
- _update_window_title (self, FALSE);
-}
+ /* Check whether it's needed to keep this item as the only selection */
+ if (((event->button == 1) && path_selected)
+ || ((event->button == 3) && !path_selected))
+ {
+ if (!(event->state & GDK_SHIFT_MASK)
+ && !(event->state & GDK_CONTROL_MASK))
+ {
+ /* Deselect all items if not pressing Ctrl or shift */
+ gtk_icon_view_unselect_all (GTK_ICON_VIEW (priv->icon_view));
+ }
-static void
-_save_project_as_dialog_response_cb (GtkDialog *dialog, gint response, gpointer data)
-{
- FrogrMainView *self = FROGR_MAIN_VIEW (data);
+ /* Now select the item */
+ gtk_icon_view_select_path (GTK_ICON_VIEW (priv->icon_view), path);
- if (response == GTK_RESPONSE_ACCEPT)
- {
- gchar *filename = NULL;
+ }
- filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
- if (filename != NULL)
- _save_project_to_file (self, filename);
+ /* Perform the right action: edit picture or show ctxt menu */
+ if ((event->button == 1) /* left button */
+ && (event->type == GDK_2BUTTON_PRESS ) /* doubleclick */
+ && !(event->state & GDK_SHIFT_MASK) /* not shift */
+ && !(event->state & GDK_CONTROL_MASK)) /* not Ctrl */
+ {
+ /* edit selected item */
+ _edit_selected_pictures (mainview);
+ }
+ else if ((event->button == 3) /* right button */
+ && (event->type == GDK_BUTTON_PRESS)) /* single click */
+ {
+ /* Show contextual menu */
+ gtk_menu_popup (GTK_MENU (priv->pictures_ctxt_menu),
+ NULL, NULL, NULL, NULL,
+ event->button,
+ gtk_get_current_event_time ());
+ }
- g_free (filename);
+ /* Free */
+ gtk_tree_path_free (path);
}
- gtk_widget_destroy (GTK_WIDGET (dialog));
+ return FALSE;
}
-static void
-_save_project_as_dialog (FrogrMainView *self)
+void
+_on_account_menu_item_toggled (GtkWidget *widget, gpointer self)
{
- FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
- GtkWidget *dialog;
-
- dialog = gtk_file_chooser_dialog_new (_("Select Destination"),
- GTK_WINDOW (priv->window),
- GTK_FILE_CHOOSER_ACTION_SAVE,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
- NULL);
-
- gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), _("Untitled Project"));
- gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
- gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), FALSE);
- gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (dialog), TRUE);
-
- g_signal_connect (G_OBJECT (dialog), "response",
- G_CALLBACK (_save_project_as_dialog_response_cb), self);
-
- gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
- gtk_widget_show_all (dialog);
-}
+ FrogrMainViewPrivate *priv = NULL;
+ FrogrAccount *account = NULL;
+ gboolean checked = FALSE;
-static void
-_load_pictures_dialog_response_cb (GtkDialog *dialog, gint response, gpointer data)
-{
- FrogrMainView *self = FROGR_MAIN_VIEW (data);
+ priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
+ checked = gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (widget));
+ account = g_object_get_data (G_OBJECT (widget), "frogr-account");
- if (response == GTK_RESPONSE_ACCEPT)
+ /* Only set the account if checked */
+ if (checked && account)
{
- GSList *fileuris;
+ DEBUG ("Selected account %s (%s)",
+ frogr_account_get_id (account),
+ frogr_account_get_username (account));
- /* Add selected pictures to icon view area */
- fileuris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
- if (fileuris != NULL)
- _load_pictures (FROGR_MAIN_VIEW (self), fileuris);
+ frogr_controller_set_active_account (priv->controller, account);
+ }
+ else if (account)
+ {
+ /* If manually unchecked the currently active account, set it again */
+ FrogrAccount *active_account = frogr_controller_get_active_account (priv->controller);
+ if (frogr_account_equal (active_account, account))
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (widget), TRUE);
}
-
- gtk_widget_destroy (GTK_WIDGET (dialog));
}
static void
-_load_pictures_dialog (FrogrMainView *self)
+_quit_application (FrogrMainView *self)
{
- FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
- GtkWidget *dialog;
- GtkFileFilter *all_filter;
- GtkFileFilter *image_filter;
- GtkFileFilter *video_filter;
- gint i;
+ GtkApplication *gtk_app = gtk_window_get_application (GTK_WINDOW (self));
+ g_application_quit (G_APPLICATION (gtk_app));
+}
-#ifdef MAC_INTEGRATION
- const gchar * const *supported_images;
- const gchar * const *supported_videos;
-#else
- const gchar * const *supported_mimetypes;
-#endif
+static gboolean
+_on_main_view_delete_event (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer self)
+{
+ _quit_application (FROGR_MAIN_VIEW (self));
+ return TRUE;
+}
- dialog = gtk_file_chooser_dialog_new (_("Select a Picture"),
- GTK_WINDOW (priv->window),
- GTK_FILE_CHOOSER_ACTION_OPEN,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
- NULL);
+static gboolean
+_on_icon_view_query_tooltip (GtkWidget *icon_view,
+ gint x, gint y,
+ gboolean keyboard_mode,
+ GtkTooltip *tooltip,
+ gpointer data)
+{
+ FrogrMainView *self = NULL;
+ FrogrMainViewPrivate *priv = NULL;
+ GtkTreePath *path;
+ gint bw_x;
+ gint bw_y;
- /* Set images filter */
- all_filter = gtk_file_filter_new ();
- image_filter = gtk_file_filter_new ();
- video_filter = gtk_file_filter_new ();
+ /* No tooltips in keyboard mode... yet */
+ if (keyboard_mode)
+ return FALSE;
-#ifdef MAC_INTEGRATION
- /* Workaround for Mac OSX, where GNOME VFS daemon won't be running,
- so we can't check filter by mime type (will be text/plain) */
- supported_images = frogr_util_get_supported_images ();
- for (i = 0; supported_images[i]; i++)
- {
- gtk_file_filter_add_pattern (image_filter, supported_images[i]);
- gtk_file_filter_add_pattern (all_filter, supported_images[i]);
- }
+ self = FROGR_MAIN_VIEW (data);
+ priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
- supported_videos = frogr_util_get_supported_videos ();
- for (i = 0; supported_videos[i]; i++)
- {
- gtk_file_filter_add_pattern (video_filter, supported_videos[i]);
- gtk_file_filter_add_pattern (all_filter, supported_videos[i]);
- }
-#else
- supported_mimetypes = frogr_util_get_supported_mimetypes ();
- for (i = 0; supported_mimetypes[i]; i++)
- {
- if (g_str_has_prefix (supported_mimetypes[i], "image"))
- gtk_file_filter_add_mime_type (image_filter, supported_mimetypes[i]);
- else
- gtk_file_filter_add_mime_type (video_filter, supported_mimetypes[i]);
+ /* Disabled by configuration */
+ if (!frogr_config_get_mainview_enable_tooltips (priv->config))
+ return FALSE;
- gtk_file_filter_add_mime_type (all_filter, supported_mimetypes[i]);
- }
-#endif
+ /* Check whether we're asking for a tooltip over a picture */
+ gtk_icon_view_convert_widget_to_bin_window_coords (GTK_ICON_VIEW (icon_view),
+ x, y, &bw_x, &bw_y);
+ if (gtk_icon_view_get_item_at_pos (GTK_ICON_VIEW (icon_view), bw_x, bw_y, &path, NULL))
+ {
+ FrogrPicture *picture;
+ GtkTreeIter iter;
+ gchar *tooltip_str = NULL;
+ gchar *filesize = NULL;
+ gchar *filesize_str = NULL;
+ gchar *filesize_markup = NULL;
+ gchar *datetime_markup = NULL;
+ const gchar *datetime = NULL;
- gtk_file_filter_set_name (all_filter, _("All Files"));
- gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), all_filter);
+ /* Get needed information */
+ gtk_tree_model_get_iter (priv->tree_model, &iter, path);
+ gtk_tree_model_get (priv->tree_model,
+ &iter,
+ FPICTURE_COL, &picture,
+ -1);
- gtk_file_filter_set_name (image_filter, _("Image Files"));
- gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), image_filter);
+ /* Bail out here if needed */
+ if (!picture || !FROGR_IS_PICTURE (picture))
+ return FALSE;
- gtk_file_filter_set_name (video_filter, _("Video Files"));
- gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), video_filter);
+ /* Build the tooltip text with basic info: title, size */
+ filesize = frogr_util_get_datasize_string (frogr_picture_get_filesize (picture));
+ datetime = frogr_picture_get_datetime (picture);
+ if (datetime)
+ {
+ gchar *datetime_str = NULL;
- gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
- gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (dialog), FALSE);
+ /* String showind the date and time a picture was taken */
+ datetime_str = g_strdup_printf (_("Taken: %s"), datetime);
+ datetime_markup = g_strdup_printf ("\n<i>%s</i>", datetime_str);
+ g_free (datetime_str);
+ }
- g_signal_connect (G_OBJECT (dialog), "response",
- G_CALLBACK (_load_pictures_dialog_response_cb), self);
+ filesize_str = g_strdup_printf (_("File size: %s"), filesize);
+ filesize_markup = g_strdup_printf ("<i>%s</i>", filesize_str);
- gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
- gtk_widget_show_all (dialog);
-}
+ tooltip_str = g_strdup_printf ("<b>%s</b>\n%s%s",
+ frogr_picture_get_title (picture),
+ filesize_markup,
+ datetime_markup ? datetime_markup : "");
-static gboolean
-_pictures_selected_required_check (FrogrMainView *self)
-{
- FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
+ gtk_tooltip_set_markup (tooltip, tooltip_str);
- if (priv->n_selected_pictures == 0)
- {
- frogr_util_show_error_dialog (priv->window,
- _("You need to select some pictures first"));
- return FALSE;
+ /* Free memory */
+ gtk_tree_path_free (path);
+ g_free (tooltip_str);
+ g_free (filesize);
+ g_free (filesize_str);
+ g_free (filesize_markup);
+ g_free (datetime_markup);
+ return TRUE;
}
- return TRUE;
+ return FALSE;
}
static void
-_add_tags_to_pictures (FrogrMainView *self)
+_on_icon_view_selection_changed (GtkWidget *icon_view, gpointer data)
{
+ FrogrMainView *self = FROGR_MAIN_VIEW (data);
FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
+ GList *selected_pictures = NULL;
+ gint len = 0;
- if (!_pictures_selected_required_check (self))
- return;
+ /* We save the value here to avoid traversing all the list whenever
+ we need to check the number of selected pictures */
+ selected_pictures =
+ gtk_icon_view_get_selected_items (GTK_ICON_VIEW (priv->icon_view));
- /* Call the controller to add tags to them */
- frogr_controller_show_add_tags_dialog (priv->controller,
- _get_selected_pictures (self));
-}
+ len = g_list_length (selected_pictures);
-static void
-_add_pictures_to_new_set (FrogrMainView *self)
-{
- FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
+ g_list_foreach (selected_pictures, (GFunc)gtk_tree_path_free, NULL);
+ g_list_free (selected_pictures);
- if (!_pictures_selected_required_check (self))
- return;
+ priv->n_selected_pictures = len;
- /* Call the controller to add the pictures to sets */
- frogr_controller_show_create_new_set_dialog (priv->controller,
- _get_selected_pictures (self));
+ /* Update sensitiveness for actions */
+ _update_sensitiveness (self);
}
-static void
-_add_pictures_to_existing_set (FrogrMainView *self)
+static GSList *
+_get_selected_pictures (FrogrMainView *self)
{
FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
+ GSList *pictures = NULL;
+ GList *selected_pictures;
+ GList *item;
- if (!_pictures_selected_required_check (self))
- return;
+ /* Iterate over selected items */
+ selected_pictures =
+ gtk_icon_view_get_selected_items (GTK_ICON_VIEW (priv->icon_view));
+ for (item = selected_pictures; item; item = g_list_next (item))
+ {
+ FrogrPicture *picture;
+ GtkTreePath *path;
+ GtkTreeIter iter;
- /* Call the controller to add the pictures to sets */
- frogr_controller_show_add_to_set_dialog (priv->controller,
- _get_selected_pictures (self));
-}
+ /* Get needed information */
+ path = (GtkTreePath *)(item->data);
+ gtk_tree_model_get_iter (priv->tree_model, &iter, path);
+ gtk_tree_model_get (priv->tree_model,
+ &iter,
+ FPICTURE_COL, &picture,
+ -1);
-static void
-_add_pictures_to_group (FrogrMainView *self)
-{
- FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
+ /* Add the picture to the list */
+ pictures = g_slist_prepend (pictures, g_object_ref (picture));
+ gtk_tree_path_free (path);
+ }
- if (!_pictures_selected_required_check (self))
- return;
+ g_list_free (selected_pictures);
- /* Call the controller to add the pictures to sets */
- frogr_controller_show_add_to_group_dialog (priv->controller,
- _get_selected_pictures (self));
+ return pictures;
}
-static void
-_edit_selected_pictures (FrogrMainView *self)
+static gint
+_n_pictures (FrogrMainView *self)
{
FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
- if (!_pictures_selected_required_check (self))
- return;
-
- /* Call the controller to edit them */
- frogr_controller_show_details_dialog (priv->controller,
- _get_selected_pictures (self));
+ /* Just return the number of pictures in the model */
+ return frogr_model_n_pictures (priv->model);
}
static void
-_open_pictures_in_external_viewer (FrogrMainView *self)
+_load_project_dialog_response_cb (GtkDialog *dialog,
+ gint response,
+ gpointer data)
{
- GSList *pictures = NULL;
+ FrogrMainView *self = FROGR_MAIN_VIEW (data);
- if (!_pictures_selected_required_check (self))
- return;
+ if (response == GTK_RESPONSE_ACCEPT)
+ {
+ gchar *filename = NULL;
+
+ filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
+ if (filename != NULL)
+ {
+ FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
+
+ /* Load from disk and update project's path */
+ frogr_controller_load_project_from_file (priv->controller, filename);
+ _update_project_path (self, filename);
+
+ g_free (filename);
+ }
+ }
- pictures = _get_selected_pictures (self);
- frogr_util_open_pictures_in_viewer (pictures);
- g_slist_free (pictures);
+ gtk_widget_destroy (GTK_WIDGET (dialog));
}
static void
-_remove_selected_pictures (FrogrMainView *self)
+_load_project_dialog (FrogrMainView *self)
{
- FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
- GSList *selected_pictures;
- GSList *item;
+ GtkWidget *dialog;
+ GtkFileFilter *filter;
- if (!_pictures_selected_required_check (self))
- return;
+ dialog = gtk_file_chooser_dialog_new (_("Select File"),
+ GTK_WINDOW (self),
+ GTK_FILE_CHOOSER_ACTION_SAVE,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+ NULL);
- /* Remove from model */
- selected_pictures = _get_selected_pictures (self);
- for (item = selected_pictures; item; item = g_slist_next (item))
- {
- FrogrPicture *picture = FROGR_PICTURE (item->data);
- frogr_model_remove_picture (priv->model, picture);
- }
+ gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), FALSE);
+ gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (dialog), TRUE);
- /* Update UI */
- _update_ui (self);
+ /* Let's allow text files only */
+ filter = gtk_file_filter_new ();
+ gtk_file_filter_add_mime_type (filter, "text/*");
+ gtk_file_filter_set_name (filter, _("Text Files"));
+ gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
- /* Free */
- g_slist_free (selected_pictures);
+ g_signal_connect (G_OBJECT (dialog), "response",
+ G_CALLBACK (_load_project_dialog_response_cb), self);
+
+ gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
+ gtk_widget_show_all (dialog);
}
static void
-_load_pictures (FrogrMainView *self, GSList *fileuris)
+_save_current_project (FrogrMainView *self)
{
FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
- frogr_controller_load_pictures (priv->controller, fileuris);
+
+ if (priv->project_filepath)
+ _save_project_to_file (self, priv->project_filepath);
+ else
+ _save_project_as_dialog (self);
}
static void
-_upload_pictures (FrogrMainView *self)
+_save_project_to_file (FrogrMainView *self, const gchar *filepath)
{
FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
- gtk_icon_view_unselect_all (GTK_ICON_VIEW (priv->icon_view));
- frogr_controller_upload_pictures (priv->controller);
+ /* Save to disk and update project's path */
+ frogr_controller_save_project_to_file (priv->controller, filepath);
+ _update_project_path (self, filepath);
+
+ /* Update title marking it as non-dirty (just saved) */
+ _update_window_title (self, FALSE);
}
static void
-_reorder_pictures (FrogrMainView *self, SortingCriteria criteria, gboolean reversed)
+_save_project_as_dialog_response_cb (GtkDialog *dialog, gint response, gpointer data)
{
- FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
- GSList *list_as_loaded = NULL;
- GSList *current_list = NULL;
- GSList *current_item = NULL;
- gint *new_order = 0;
- gint current_pos = 0;
- gint new_pos = 0;
+ FrogrMainView *self = FROGR_MAIN_VIEW (data);
- gchar *property_name = NULL;
+ if (response == GTK_RESPONSE_ACCEPT)
+ {
+ gchar *filename = NULL;
- priv->sorting_criteria = criteria;
- priv->sorting_reversed = reversed;
+ filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
+ if (filename != NULL)
+ _save_project_to_file (self, filename);
- if (!_n_pictures (self))
- return;
+ g_free (filename);
+ }
- /* Choose the property to sort by */
- switch (criteria)
- {
- case SORT_AS_LOADED:
- property_name = NULL;
- break;
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+}
- case SORT_BY_TITLE:
- property_name = g_strdup ("title");
- break;
+static void
+_save_project_as_dialog (FrogrMainView *self)
+{
+ GtkWidget *dialog;
- case SORT_BY_DATE:
- property_name = g_strdup ("datetime");
- break;
+ dialog = gtk_file_chooser_dialog_new (_("Select Destination"),
+ GTK_WINDOW (self),
+ GTK_FILE_CHOOSER_ACTION_SAVE,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+ NULL);
- default:
- g_assert_not_reached ();
- }
+ gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), _("Untitled Project"));
+ gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
+ gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), FALSE);
+ gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (dialog), TRUE);
- /* Temporarily save the current list, and alloc an array to
- represent the new order compared to the old positions */
- current_list = g_slist_copy (priv->sorted_pictures);
- new_order = g_new0 (gint, g_slist_length (current_list));
+ g_signal_connect (G_OBJECT (dialog), "response",
+ G_CALLBACK (_save_project_as_dialog_response_cb), self);
- /* Use the original list (as loaded) as reference for sorting */
- list_as_loaded = g_slist_copy (frogr_model_get_pictures (priv->model));
- if (property_name)
- list_as_loaded = g_slist_sort_with_data (list_as_loaded,
- (GCompareDataFunc) _compare_pictures_by_property,
- (gchar*) property_name);
- /* Update the list of pictures */
- if (priv->sorted_pictures)
- {
- g_slist_foreach (priv->sorted_pictures, (GFunc)g_object_unref, NULL);
- g_slist_free (priv->sorted_pictures);
- }
- priv->sorted_pictures = list_as_loaded;
- g_slist_foreach (priv->sorted_pictures, (GFunc)g_object_ref, NULL);
+ gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
+ gtk_widget_show_all (dialog);
+}
- /* If we're reordering in reverse order, reverse the result list */
- if (reversed)
- priv->sorted_pictures = g_slist_reverse (priv->sorted_pictures);
+static void
+_load_pictures_dialog_response_cb (GtkDialog *dialog, gint response, gpointer data)
+{
+ FrogrMainView *self = FROGR_MAIN_VIEW (data);
- /* Build the new_order array and update the treeview */
- current_pos = 0;
- for (current_item = current_list; current_item; current_item = g_slist_next (current_item))
+ if (response == GTK_RESPONSE_ACCEPT)
{
- new_pos = g_slist_index (priv->sorted_pictures, current_item->data);
- new_order[new_pos] = current_pos++;
+ GSList *fileuris;
+
+ /* Add selected pictures to icon view area */
+ fileuris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
+ if (fileuris != NULL)
+ _load_pictures (FROGR_MAIN_VIEW (self), fileuris);
}
- gtk_list_store_reorder (GTK_LIST_STORE (priv->tree_model), new_order);
- g_slist_free (current_list);
- g_free (new_order);
- g_free (property_name);
+ gtk_widget_destroy (GTK_WIDGET (dialog));
}
-static gint
-_compare_pictures_by_property (FrogrPicture *p1, FrogrPicture *p2,
- const gchar *property_name)
+static void
+_load_pictures_dialog (FrogrMainView *self)
{
- GParamSpec *pspec1 = NULL;
- GParamSpec *pspec2 = NULL;
- GValue value1 = { 0 };
- GValue value2 = { 0 };
- gint result = 0;
-
- g_return_val_if_fail (FROGR_IS_PICTURE (p1), 0);
- g_return_val_if_fail (FROGR_IS_PICTURE (p2), 0);
-
- pspec1 = g_object_class_find_property (G_OBJECT_GET_CLASS (p1), property_name);
- pspec2 = g_object_class_find_property (G_OBJECT_GET_CLASS (p2), property_name);
+ GtkWidget *dialog;
+ GtkFileFilter *all_filter;
+ GtkFileFilter *image_filter;
+ GtkFileFilter *video_filter;
+ gint i;
- /* They should be the same! */
- if (pspec1->value_type != pspec2->value_type)
- return 0;
+#ifdef MAC_INTEGRATION
+ const gchar * const *supported_images;
+ const gchar * const *supported_videos;
+#else
+ const gchar * const *supported_mimetypes;
+#endif
- g_value_init (&value1, pspec1->value_type);
- g_value_init (&value2, pspec1->value_type);
+ dialog = gtk_file_chooser_dialog_new (_("Select a Picture"),
+ GTK_WINDOW (self),
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+ NULL);
- g_object_get_property (G_OBJECT (p1), property_name, &value1);
- g_object_get_property (G_OBJECT (p2), property_name, &value2);
+ /* Set images filter */
+ all_filter = gtk_file_filter_new ();
+ image_filter = gtk_file_filter_new ();
+ video_filter = gtk_file_filter_new ();
- if (G_VALUE_HOLDS_BOOLEAN (&value1))
- result = g_value_get_boolean (&value1) - g_value_get_boolean (&value2);
- else if (G_VALUE_HOLDS_INT (&value1))
- result = g_value_get_int (&value1) - g_value_get_int (&value2);
- else if (G_VALUE_HOLDS_LONG (&value1))
- result = g_value_get_long (&value1) - g_value_get_long (&value2);
- else if (G_VALUE_HOLDS_STRING (&value1))
+#ifdef MAC_INTEGRATION
+ /* Workaround for Mac OSX, where GNOME VFS daemon won't be running,
+ so we can't check filter by mime type (will be text/plain) */
+ supported_images = frogr_util_get_supported_images ();
+ for (i = 0; supported_images[i]; i++)
{
- const gchar *str1 = NULL;
- const gchar *str2 = NULL;
- gchar *str1_cf = NULL;
- gchar *str2_cf = NULL;
+ gtk_file_filter_add_pattern (image_filter, supported_images[i]);
+ gtk_file_filter_add_pattern (all_filter, supported_images[i]);
+ }
- /* Comparison of strings require some additional work to take
- into account the different rules for each locale */
- str1 = g_value_get_string (&value1);
- str2 = g_value_get_string (&value2);
+ supported_videos = frogr_util_get_supported_videos ();
+ for (i = 0; supported_videos[i]; i++)
+ {
+ gtk_file_filter_add_pattern (video_filter, supported_videos[i]);
+ gtk_file_filter_add_pattern (all_filter, supported_videos[i]);
+ }
+#else
+ supported_mimetypes = frogr_util_get_supported_mimetypes ();
+ for (i = 0; supported_mimetypes[i]; i++)
+ {
+ if (g_str_has_prefix (supported_mimetypes[i], "image"))
+ gtk_file_filter_add_mime_type (image_filter, supported_mimetypes[i]);
+ else
+ gtk_file_filter_add_mime_type (video_filter, supported_mimetypes[i]);
- str1_cf = g_utf8_casefold (str1 ? str1 : "", -1);
- str2_cf = g_utf8_casefold (str2 ? str2 : "", -1);
+ gtk_file_filter_add_mime_type (all_filter, supported_mimetypes[i]);
+ }
+#endif
- result = g_utf8_collate (str1_cf, str2_cf);
+ gtk_file_filter_set_name (all_filter, _("All Files"));
+ gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), all_filter);
- g_free (str1_cf);
- g_free (str2_cf);
- }
- else
- g_warning ("Unsupported type for property used for sorting");
+ gtk_file_filter_set_name (image_filter, _("Image Files"));
+ gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), image_filter);
- g_value_unset (&value1);
- g_value_unset (&value2);
+ gtk_file_filter_set_name (video_filter, _("Video Files"));
+ gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), video_filter);
- return result;
-}
+ gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
+ gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (dialog), FALSE);
-static void
-_progress_dialog_response (GtkDialog *dialog,
- gint response_id,
- gpointer data)
-{
- FrogrMainView *self = FROGR_MAIN_VIEW (data);
- FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
+ g_signal_connect (G_OBJECT (dialog), "response",
+ G_CALLBACK (_load_pictures_dialog_response_cb), self);
- frogr_controller_cancel_ongoing_requests (priv->controller);
- gtk_widget_hide (priv->progress_dialog);
+ gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
+ gtk_widget_show_all (dialog);
}
static gboolean
-_progress_dialog_delete_event (GtkWidget *widget,
- GdkEvent *event,
- gpointer data)
+_pictures_selected_required_check (FrogrMainView *self)
{
- FrogrMainView *self = FROGR_MAIN_VIEW (data);
FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
- frogr_controller_cancel_ongoing_requests (priv->controller);
- gtk_widget_hide (priv->progress_dialog);
+ if (priv->n_selected_pictures == 0)
+ {
+ frogr_util_show_error_dialog (GTK_WINDOW (self),
+ _("You need to select some pictures first"));
+ return FALSE;
+ }
return TRUE;
}
static void
-_controller_state_changed (FrogrController *controller,
- FrogrControllerState state,
- gpointer data)
+_add_tags_to_pictures (FrogrMainView *self)
{
- FrogrMainView *mainview = FROGR_MAIN_VIEW (data);
- _update_ui (mainview);
+ FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
+
+ if (!_pictures_selected_required_check (self))
+ return;
+
+ /* Call the controller to add tags to them */
+ frogr_controller_show_add_tags_dialog (priv->controller,
+ _get_selected_pictures (self));
}
static void
-_controller_active_account_changed (FrogrController *controller,
- FrogrAccount *account,
- gpointer data)
+_add_pictures_to_new_set (FrogrMainView *self)
{
- FrogrMainView *mainview = NULL;
+ FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
- mainview = FROGR_MAIN_VIEW (data);
- _update_state_description (mainview);
- _update_account_menu_items (mainview);
- _update_ui (mainview);
+ if (!_pictures_selected_required_check (self))
+ return;
+
+ /* Call the controller to add the pictures to sets */
+ frogr_controller_show_create_new_set_dialog (priv->controller,
+ _get_selected_pictures (self));
}
static void
-_controller_accounts_changed (FrogrController *controller,
- gpointer data)
+_add_pictures_to_existing_set (FrogrMainView *self)
{
- FrogrMainView *mainview = NULL;
+ FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
- /* Re-populate the accounts submenu */
- mainview = FROGR_MAIN_VIEW (data);
- _populate_accounts_submenu (mainview);
- _update_ui (mainview);
+ if (!_pictures_selected_required_check (self))
+ return;
- DEBUG ("%s", "Accounts list changed");
+ /* Call the controller to add the pictures to sets */
+ frogr_controller_show_add_to_set_dialog (priv->controller,
+ _get_selected_pictures (self));
}
static void
-_model_picture_added (FrogrController *controller,
- FrogrPicture *picture,
- gpointer data)
+_add_pictures_to_group (FrogrMainView *self)
{
- FrogrMainView *self = FROGR_MAIN_VIEW (data);
FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
- GdkPixbuf *pixbuf = NULL;
- const gchar *fileuri = NULL;
- GtkTreeIter iter;
- /* Add to GtkIconView */
- fileuri = frogr_picture_get_fileuri (picture);
- pixbuf = frogr_picture_get_pixbuf (picture);
+ if (!_pictures_selected_required_check (self))
+ return;
- gtk_list_store_append (GTK_LIST_STORE (priv->tree_model), &iter);
- gtk_list_store_set (GTK_LIST_STORE (priv->tree_model), &iter,
- FILEURI_COL, fileuri,
- PIXBUF_COL, pixbuf,
- FPICTURE_COL, picture,
- -1);
+ /* Call the controller to add the pictures to sets */
+ frogr_controller_show_add_to_group_dialog (priv->controller,
+ _get_selected_pictures (self));
+}
- /* Update the list */
- priv->sorted_pictures = g_slist_append (priv->sorted_pictures,
- g_object_ref (picture));
+static void
+_edit_selected_pictures (FrogrMainView *self)
+{
+ FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
- /* Reorder if needed */
- if (priv->sorting_criteria != SORT_AS_LOADED || priv->sorting_reversed)
- frogr_main_view_reorder_pictures (self);
+ if (!_pictures_selected_required_check (self))
+ return;
- /* Update upload size in state description */
- _update_state_description (self);
+ /* Call the controller to edit them */
+ frogr_controller_show_details_dialog (priv->controller,
+ _get_selected_pictures (self));
}
static void
-_model_picture_removed (FrogrController *controller,
- FrogrPicture *picture,
- gpointer data)
+_open_pictures_in_external_viewer (FrogrMainView *self)
{
- FrogrMainView *self = FROGR_MAIN_VIEW (data);
- FrogrMainViewPrivate *priv = NULL;
- GtkTreeModel *tree_model = NULL;
- GtkTreeIter iter;
-
- /* Check items in the icon_view */
- priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
+ GSList *pictures = NULL;
- tree_model = gtk_icon_view_get_model (GTK_ICON_VIEW (priv->icon_view));
- if (gtk_tree_model_get_iter_first (tree_model, &iter))
- {
- /* Look for the picture and remove it */
- do
- {
- FrogrPicture *picture_from_ui;
+ if (!_pictures_selected_required_check (self))
+ return;
- /* Get needed information */
- gtk_tree_model_get (priv->tree_model,
- &iter,
- FPICTURE_COL, &picture_from_ui,
- -1);
+ pictures = _get_selected_pictures (self);
+ frogr_util_open_pictures_in_viewer (pictures);
+ g_slist_free (pictures);
+}
- if (picture_from_ui == picture)
- {
- /* Remove from the GtkIconView and break loop */
- gtk_list_store_remove (GTK_LIST_STORE (priv->tree_model), &iter);
+static void
+_remove_selected_pictures (FrogrMainView *self)
+{
+ FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
+ GSList *selected_pictures;
+ GSList *item;
- /* Update the list */
- priv->sorted_pictures = g_slist_remove (priv->sorted_pictures, picture);
- g_object_unref (picture);
+ if (!_pictures_selected_required_check (self))
+ return;
- break;
- }
- }
- while (gtk_tree_model_iter_next (tree_model, &iter));
+ /* Remove from model */
+ selected_pictures = _get_selected_pictures (self);
+ for (item = selected_pictures; item; item = g_slist_next (item))
+ {
+ FrogrPicture *picture = FROGR_PICTURE (item->data);
+ frogr_model_remove_picture (priv->model, picture);
}
- /* Update upload size in state description */
- _update_state_description (self);
+ /* Update UI */
+ _update_ui (self);
+
+ /* Free */
+ g_slist_free (selected_pictures);
}
static void
-_model_changed (FrogrController *controller, gpointer data)
+_load_pictures (FrogrMainView *self, GSList *fileuris)
{
- /* Reflect that the current state is 'dirty' in the title */
- _update_window_title (FROGR_MAIN_VIEW (data), TRUE);
+ FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
+ frogr_controller_load_pictures (priv->controller, fileuris);
}
static void
-_model_deserialized (FrogrController *controller, gpointer data)
+_upload_pictures (FrogrMainView *self)
{
- /* Reflect that the current state is not 'dirty' (just loaded) */
- _update_window_title (FROGR_MAIN_VIEW (data), FALSE);
+ FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
+
+ gtk_icon_view_unselect_all (GTK_ICON_VIEW (priv->icon_view));
+ frogr_controller_upload_pictures (priv->controller);
}
static void
-_update_account_menu_items (FrogrMainView *mainview)
+_reorder_pictures (FrogrMainView *self, SortingCriteria criteria, gboolean reversed)
{
- FrogrMainViewPrivate *priv = NULL;
+ FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
+ GSList *list_as_loaded = NULL;
+ GSList *current_list = NULL;
+ GSList *current_item = NULL;
+ gint *new_order = 0;
+ gint current_pos = 0;
+ gint new_pos = 0;
- priv = FROGR_MAIN_VIEW_GET_PRIVATE (mainview);
- if (priv->accounts_menu && GTK_IS_CONTAINER (priv->accounts_menu))
+ gchar *property_name = NULL;
+
+ priv->sorting_criteria = criteria;
+ priv->sorting_reversed = reversed;
+
+ if (!_n_pictures (self))
+ return;
+
+ /* Choose the property to sort by */
+ switch (criteria)
{
- FrogrAccount *active_account = NULL;
- FrogrAccount *account = NULL;
- GList *all_items = NULL;
- GList *item = NULL;
- GtkWidget *menu_item = NULL;
+ case SORT_AS_LOADED:
+ property_name = NULL;
+ break;
- active_account = frogr_controller_get_active_account (priv->controller);
- all_items = gtk_container_get_children (GTK_CONTAINER (priv->accounts_menu));
- for (item = all_items; item; item = g_list_next (item))
- {
- gboolean value;
+ case SORT_BY_TITLE:
+ property_name = g_strdup ("title");
+ break;
- menu_item = GTK_WIDGET (item->data);
- account = g_object_get_data (G_OBJECT (menu_item), "frogr-account");
+ case SORT_BY_DATE:
+ property_name = g_strdup ("datetime");
+ break;
- if (account == active_account)
- value = TRUE;
- else
- value = FALSE;
+ default:
+ g_assert_not_reached ();
+ }
- gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), value);
- }
- g_list_free (all_items);
+ /* Temporarily save the current list, and alloc an array to
+ represent the new order compared to the old positions */
+ current_list = g_slist_copy (priv->sorted_pictures);
+ new_order = g_new0 (gint, g_slist_length (current_list));
+
+ /* Use the original list (as loaded) as reference for sorting */
+ list_as_loaded = g_slist_copy (frogr_model_get_pictures (priv->model));
+ if (property_name)
+ list_as_loaded = g_slist_sort_with_data (list_as_loaded,
+ (GCompareDataFunc) _compare_pictures_by_property,
+ (gchar*) property_name);
+ /* Update the list of pictures */
+ if (priv->sorted_pictures)
+ {
+ g_slist_foreach (priv->sorted_pictures, (GFunc)g_object_unref, NULL);
+ g_slist_free (priv->sorted_pictures);
}
-}
-
-static void
-_update_state_description (FrogrMainView *mainview)
-{
- FrogrMainViewPrivate *priv = NULL;
+ priv->sorted_pictures = list_as_loaded;
+ g_slist_foreach (priv->sorted_pictures, (GFunc)g_object_ref, NULL);
- priv = FROGR_MAIN_VIEW_GET_PRIVATE (mainview);
+ /* If we're reordering in reverse order, reverse the result list */
+ if (reversed)
+ priv->sorted_pictures = g_slist_reverse (priv->sorted_pictures);
- g_free (priv->state_description);
- priv->state_description = _craft_state_description (mainview);
+ /* Build the new_order array and update the treeview */
+ current_pos = 0;
+ for (current_item = current_list; current_item; current_item = g_slist_next (current_item))
+ {
+ new_pos = g_slist_index (priv->sorted_pictures, current_item->data);
+ new_order[new_pos] = current_pos++;
+ }
+ gtk_list_store_reorder (GTK_LIST_STORE (priv->tree_model), new_order);
- /* Do not force updating the status bar when loading pictures */
- if (frogr_controller_get_state (priv->controller) != FROGR_STATE_LOADING_PICTURES)
- frogr_main_view_set_status_text (mainview, priv->state_description);
+ g_slist_free (current_list);
+ g_free (new_order);
+ g_free (property_name);
}
-static gchar *
-_craft_state_description (FrogrMainView *mainview)
+static gint
+_compare_pictures_by_property (FrogrPicture *p1, FrogrPicture *p2,
+ const gchar *property_name)
{
- FrogrMainViewPrivate *priv = NULL;
- FrogrAccount *account = NULL;
- GSList *pictures = NULL;
- guint n_pictures = 0;
- const gchar *login = NULL;
- gchar *description = NULL;
- gchar *login_str = NULL;
- gchar *bandwidth_str = NULL;
- gchar *upload_size_str = NULL;
- gboolean is_pro = FALSE;
+ GParamSpec *pspec1 = NULL;
+ GParamSpec *pspec2 = NULL;
+ GValue value1 = { 0 };
+ GValue value2 = { 0 };
+ gint result = 0;
- priv = FROGR_MAIN_VIEW_GET_PRIVATE (mainview);
- account = frogr_controller_get_active_account (priv->controller);
+ g_return_val_if_fail (FROGR_IS_PICTURE (p1), 0);
+ g_return_val_if_fail (FROGR_IS_PICTURE (p2), 0);
- if (!FROGR_IS_ACCOUNT (account) || !frogr_account_has_extra_info (account))
- return g_strdup (_("Not connected to Flickr"));
+ pspec1 = g_object_class_find_property (G_OBJECT_GET_CLASS (p1), property_name);
+ pspec2 = g_object_class_find_property (G_OBJECT_GET_CLASS (p2), property_name);
- /* Just use the username here ant not the fullname (when available),
- since it could happen that the full name was the same for two
- different usernames from the same frogr user, thus making
- impossible to distinguish which account you are using. */
- login = frogr_account_get_username (account);
- is_pro = frogr_account_is_pro (account);
+ /* They should be the same! */
+ if (pspec1->value_type != pspec2->value_type)
+ return 0;
- /* Login string, showing the user is PRO (second '%s') if so. */
- login_str = g_strdup_printf (_("Connected as %s%s"), login,
- (is_pro ? _(" (PRO account)") : ""));
+ g_value_init (&value1, pspec1->value_type);
+ g_value_init (&value2, pspec1->value_type);
- /* Pro users do not have any limit of quota, so it makes no sense to
- permanently show that they have 2.0 GB / 2.0 GB remaining */
- if (!is_pro)
+ g_object_get_property (G_OBJECT (p1), property_name, &value1);
+ g_object_get_property (G_OBJECT (p2), property_name, &value2);
+
+ if (G_VALUE_HOLDS_BOOLEAN (&value1))
+ result = g_value_get_boolean (&value1) - g_value_get_boolean (&value2);
+ else if (G_VALUE_HOLDS_INT (&value1))
+ result = g_value_get_int (&value1) - g_value_get_int (&value2);
+ else if (G_VALUE_HOLDS_LONG (&value1))
+ result = g_value_get_long (&value1) - g_value_get_long (&value2);
+ else if (G_VALUE_HOLDS_STRING (&value1))
{
- gchar *remaining_bw_str = NULL;
- gchar *max_bw_str = NULL;
- gulong remaining_bw;
- gulong max_bw;
+ const gchar *str1 = NULL;
+ const gchar *str2 = NULL;
+ gchar *str1_cf = NULL;
+ gchar *str2_cf = NULL;
- remaining_bw = frogr_account_get_remaining_bandwidth (account);
- max_bw = frogr_account_get_max_bandwidth (account);
+ /* Comparison of strings require some additional work to take
+ into account the different rules for each locale */
+ str1 = g_value_get_string (&value1);
+ str2 = g_value_get_string (&value2);
- remaining_bw_str = frogr_util_get_datasize_string (remaining_bw);
- max_bw_str = frogr_util_get_datasize_string (max_bw);
+ str1_cf = g_utf8_casefold (str1 ? str1 : "", -1);
+ str2_cf = g_utf8_casefold (str2 ? str2 : "", -1);
- if (remaining_bw_str && max_bw_str)
- {
- /* Will show in the status bar the amount of data (in KB, MB
- or GB) the user is currently allowed to upload to flicker
- till the end of the month, in a CURRENT / MAX fashion.
- The '-' at the beginning is just a separator, since more
- blocks of text will be shown in the status bar too. */
- bandwidth_str = g_strdup_printf (_(" - %s / %s remaining"),
- remaining_bw_str,
- max_bw_str);
- }
+ result = g_utf8_collate (str1_cf, str2_cf);
- g_free (remaining_bw_str);
- g_free (max_bw_str);
+ g_free (str1_cf);
+ g_free (str2_cf);
}
+ else
+ g_warning ("Unsupported type for property used for sorting");
- /* Check size of the loaded pictures, if any */
- pictures = frogr_model_get_pictures (priv->model);
- n_pictures = frogr_model_n_pictures (priv->model);
- if (n_pictures)
- {
- GSList *item = NULL;
- gulong total_size = 0;
- gchar *total_size_str = NULL;
-
- for (item = pictures; item; item = g_slist_next (item))
- total_size += frogr_picture_get_filesize (FROGR_PICTURE (item->data));
-
- total_size_str = frogr_util_get_datasize_string (total_size);
+ g_value_unset (&value1);
+ g_value_unset (&value2);
- /* Will show in the status bar the amount of pictures and data
- (in KB, MB or GB) that would be uploaded as the sum of the
- sizes for every picture loaded in the application */
- upload_size_str = g_strdup_printf (ngettext (" - %d file to upload (%s)",
- " - %d files to upload (%s)",
- n_pictures),
- n_pictures, total_size_str);
- g_free (total_size_str);
- }
+ return result;
+}
- /* Build the final string */
- description = g_strdup_printf ("%s%s%s",
- login_str,
- (bandwidth_str ? bandwidth_str : ""),
- (upload_size_str ? upload_size_str : ""));
- g_free (login_str);
- g_free (bandwidth_str);
- g_free (upload_size_str);
+static void
+_progress_dialog_response (GtkDialog *dialog,
+ gint response_id,
+ gpointer data)
+{
+ FrogrMainView *self = FROGR_MAIN_VIEW (data);
+ FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
- return description;
+ frogr_controller_cancel_ongoing_requests (priv->controller);
+ gtk_widget_hide (priv->progress_dialog);
}
-static void
-_update_sensitiveness (FrogrMainView *self)
+static gboolean
+_progress_dialog_delete_event (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer data)
{
+ FrogrMainView *self = FROGR_MAIN_VIEW (data);
FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
- /* gboolean has_accounts = FALSE; */
- gboolean has_pics = FALSE;
- gint n_selected_pics = 0;
- /* Set sensitiveness */
- switch (frogr_controller_get_state (priv->controller))
- {
- case FROGR_STATE_LOADING_PICTURES:
- case FROGR_STATE_UPLOADING_PICTURES:
- gtk_action_set_sensitive (priv->load_project_action, FALSE);
- gtk_action_set_sensitive (priv->save_project_action, FALSE);
- gtk_action_set_sensitive (priv->save_project_as_action, FALSE);
- gtk_action_set_sensitive (priv->load_pictures_action, FALSE);
- gtk_action_set_sensitive (priv->remove_pictures_action, FALSE);
- gtk_action_set_sensitive (priv->upload_pictures_action, FALSE);
- gtk_action_set_sensitive (priv->open_in_external_viewer_action, FALSE);
- gtk_action_set_sensitive (priv->add_tags_action, FALSE);
- gtk_action_set_sensitive (priv->edit_details_action, FALSE);
- gtk_action_set_sensitive (priv->add_to_group_action, FALSE);
- gtk_action_set_sensitive (priv->add_to_set_action, FALSE);
- gtk_action_set_sensitive (priv->add_to_new_set_action, FALSE);
- /* gtk_widget_set_sensitive (priv->accounts_menu_item, FALSE); */
- gtk_widget_set_sensitive (priv->add_to_set_menu_item, FALSE);
- break;
+ frogr_controller_cancel_ongoing_requests (priv->controller);
+ gtk_widget_hide (priv->progress_dialog);
- case FROGR_STATE_IDLE:
- has_pics = (_n_pictures (self) > 0);
- /* has_accounts = (priv->accounts_menu != NULL); */
- n_selected_pics = priv->n_selected_pictures;
+ return TRUE;
+}
- gtk_action_set_sensitive (priv->load_project_action, TRUE);
- gtk_action_set_sensitive (priv->save_project_action, TRUE);
- gtk_action_set_sensitive (priv->save_project_as_action, TRUE);
- gtk_action_set_sensitive (priv->load_pictures_action, TRUE);
- /* gtk_widget_set_sensitive (priv->accounts_menu_item, has_accounts); */
- gtk_action_set_sensitive (priv->upload_pictures_action, has_pics);
- gtk_action_set_sensitive (priv->remove_pictures_action, n_selected_pics > 0);
- gtk_action_set_sensitive (priv->open_in_external_viewer_action, n_selected_pics > 0);
- gtk_action_set_sensitive (priv->add_tags_action, n_selected_pics > 0);
- gtk_action_set_sensitive (priv->edit_details_action, n_selected_pics > 0);
- gtk_action_set_sensitive (priv->add_to_group_action, n_selected_pics > 0);
- gtk_action_set_sensitive (priv->add_to_set_action, n_selected_pics > 0);
- gtk_action_set_sensitive (priv->add_to_new_set_action, n_selected_pics > 0);
- gtk_widget_set_sensitive (priv->add_to_set_menu_item, n_selected_pics > 0);
- break;
+static void
+_controller_state_changed (FrogrController *controller,
+ FrogrControllerState state,
+ gpointer data)
+{
+ FrogrMainView *mainview = FROGR_MAIN_VIEW (data);
+ _update_ui (mainview);
+}
- default:
- g_warning ("Invalid state reached!!");
- }
+static void
+_controller_active_account_changed (FrogrController *controller,
+ FrogrAccount *account,
+ gpointer data)
+{
+ FrogrMainView *mainview = NULL;
+
+ mainview = FROGR_MAIN_VIEW (data);
+ _update_state_description (mainview);
+ _update_account_menu_items (mainview);
+ _update_ui (mainview);
}
static void
-_update_ui (FrogrMainView *self)
+_controller_accounts_changed (FrogrController *controller,
+ gpointer data)
{
- FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
+ FrogrMainView *mainview = NULL;
- /* Set sensitiveness */
- _update_sensitiveness (self);
+ /* Re-populate the accounts submenu */
+ mainview = FROGR_MAIN_VIEW (data);
+ _populate_accounts_submenu (mainview);
+ _update_ui (mainview);
- /* Update status bar from model's state description */
- if (frogr_controller_get_state (priv->controller) == FROGR_STATE_IDLE)
- frogr_main_view_set_status_text (self, priv->state_description);
+ DEBUG ("%s", "Accounts list changed");
}
static void
-_frogr_main_view_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
+_model_picture_added (FrogrController *controller,
+ FrogrPicture *picture,
+ gpointer data)
{
- FrogrMainView *self = FROGR_MAIN_VIEW (object);
+ FrogrMainView *self = FROGR_MAIN_VIEW (data);
FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
+ GdkPixbuf *pixbuf = NULL;
+ const gchar *fileuri = NULL;
+ GtkTreeIter iter;
- switch (prop_id)
- {
- case PROP_GTK_APPLICATION:
- priv->gtk_app = GTK_APPLICATION (g_value_get_object (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
+ /* Add to GtkIconView */
+ fileuri = frogr_picture_get_fileuri (picture);
+ pixbuf = frogr_picture_get_pixbuf (picture);
-static void
-_frogr_main_view_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (object);
+ gtk_list_store_append (GTK_LIST_STORE (priv->tree_model), &iter);
+ gtk_list_store_set (GTK_LIST_STORE (priv->tree_model), &iter,
+ FILEURI_COL, fileuri,
+ PIXBUF_COL, pixbuf,
+ FPICTURE_COL, picture,
+ -1);
- switch (prop_id)
- {
- case PROP_GTK_APPLICATION:
- g_value_set_object (value, priv->gtk_app);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
+ /* Update the list */
+ priv->sorted_pictures = g_slist_append (priv->sorted_pictures,
+ g_object_ref (picture));
-static GActionEntry app_entries[] = {
- { "load_project", _load_project_action, NULL, NULL, NULL },
- { "save_project", _save_project_action, NULL, NULL, NULL },
- { "save_project_as", _save_project_as_action, NULL, NULL, NULL },
- { "authorize", _authorize_action, NULL, NULL, NULL },
- { "preferences", _preferences_action, NULL, NULL, NULL },
- { "help", _help_action, NULL, NULL, NULL },
- { "about", _about_action, NULL, NULL, NULL },
- { "quit", _quit_action, NULL, NULL, NULL },
-};
+ /* Reorder if needed */
+ if (priv->sorting_criteria != SORT_AS_LOADED || priv->sorting_reversed)
+ frogr_main_view_reorder_pictures (self);
+
+ /* Update upload size in state description */
+ _update_state_description (self);
+}
-static GObject *
-_frogr_main_view_constructor (GType type,
- guint n_construct_properties,
- GObjectConstructParam *construct_properties)
+static void
+_model_picture_removed (FrogrController *controller,
+ FrogrPicture *picture,
+ gpointer data)
{
- GObject *object = NULL;
- FrogrMainView *self = NULL;
+ FrogrMainView *self = FROGR_MAIN_VIEW (data);
FrogrMainViewPrivate *priv = NULL;
- GtkBuilder *builder;
- GtkWidget *main_vbox;
- GtkWidget *icon_view;
- GtkWidget *status_bar;
- GtkWidget *progress_dialog;
- GtkWidget *progress_vbox;
- GtkWidget *progress_bar;
- GtkWidget *progress_label;
- GtkWidget *toolbar;
- gchar *full_path;
-
- /* Chain up to the parent's constructor first */
- object =
- G_OBJECT_CLASS (frogr_main_view_parent_class)->constructor (type,
- n_construct_properties,
- construct_properties);
- self = FROGR_MAIN_VIEW (object);
- priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
-
- /* Get widgets from GtkBuilder */
- builder = gtk_builder_new ();
- priv->builder = builder;
-
- full_path = g_strdup_printf ("%s/" UI_MAIN_VIEW_FILE, frogr_util_get_app_data_dir ());
- gtk_builder_add_from_file (builder, full_path, NULL);
- g_free (full_path);
+ GtkTreeModel *tree_model = NULL;
+ GtkTreeIter iter;
- priv->window = GTK_WINDOW (gtk_application_window_new (GTK_APPLICATION (priv->gtk_app)));
- gtk_application_window_set_show_menubar (GTK_APPLICATION_WINDOW (priv->window), TRUE);
+ /* Check items in the icon_view */
+ priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
- main_vbox = GTK_WIDGET (gtk_builder_get_object (builder, "main_window_vbox"));
- gtk_container_add (GTK_CONTAINER (priv->window), main_vbox);
+ tree_model = gtk_icon_view_get_model (GTK_ICON_VIEW (priv->icon_view));
+ if (gtk_tree_model_get_iter_first (tree_model, &iter))
+ {
+ /* Look for the picture and remove it */
+ do
+ {
+ FrogrPicture *picture_from_ui;
- /* Menu bar */
- priv->menu_bar = GTK_WIDGET (gtk_builder_get_object (builder, "menu_bar"));
- gtk_widget_show_all (priv->menu_bar);
+ /* Get needed information */
+ gtk_tree_model_get (priv->tree_model,
+ &iter,
+ FPICTURE_COL, &picture_from_ui,
+ -1);
-#ifndef MAC_INTEGRATION
- gtk_box_pack_start (GTK_BOX (main_vbox), priv->menu_bar, FALSE, FALSE, 0);
- gtk_box_reorder_child (GTK_BOX (main_vbox), priv->menu_bar, 0);
-#endif
+ if (picture_from_ui == picture)
+ {
+ /* Remove from the GtkIconView and break loop */
+ gtk_list_store_remove (GTK_LIST_STORE (priv->tree_model), &iter);
- /* App menu */
- full_path = g_strdup_printf ("%s/" UI_APP_MENU_FILE, frogr_util_get_app_data_dir ());
- gtk_builder_add_from_file (builder, full_path, NULL);
- g_free (full_path);
- g_action_map_add_action_entries (G_ACTION_MAP (priv->gtk_app),
- app_entries, G_N_ELEMENTS (app_entries),
- self);
- gtk_application_set_app_menu (GTK_APPLICATION (priv->gtk_app),
- G_MENU_MODEL (gtk_builder_get_object (builder, "app-menu")));
+ /* Update the list */
+ priv->sorted_pictures = g_slist_remove (priv->sorted_pictures, picture);
+ g_object_unref (picture);
- toolbar = GTK_WIDGET (gtk_builder_get_object (builder, "toolbar"));
- gtk_style_context_add_class (gtk_widget_get_style_context (toolbar),
- GTK_STYLE_CLASS_PRIMARY_TOOLBAR);
+ break;
+ }
+ }
+ while (gtk_tree_model_iter_next (tree_model, &iter));
+ }
- icon_view = GTK_WIDGET (gtk_builder_get_object (builder, "icon_view"));
- priv->icon_view = icon_view;
+ /* Update upload size in state description */
+ _update_state_description (self);
+}
- status_bar = GTK_WIDGET (gtk_builder_get_object (builder, "status_bar"));
- priv->status_bar = status_bar;
+static void
+_model_changed (FrogrController *controller, gpointer data)
+{
+ /* Reflect that the current state is 'dirty' in the title */
+ _update_window_title (FROGR_MAIN_VIEW (data), TRUE);
+}
- /* Get actions from GtkBuilder */
- priv->load_project_action =
- GTK_ACTION (gtk_builder_get_object (builder, "load_project_action"));
- priv->save_project_action =
- GTK_ACTION (gtk_builder_get_object (builder, "save_project_action"));
- priv->save_project_as_action =
- GTK_ACTION (gtk_builder_get_object (builder, "save_project_as_action"));
- priv->load_pictures_action =
- GTK_ACTION (gtk_builder_get_object (builder, "load_pictures_action"));
- priv->remove_pictures_action =
- GTK_ACTION (gtk_builder_get_object (builder, "remove_pictures_action"));
- priv->upload_pictures_action =
- GTK_ACTION (gtk_builder_get_object (builder, "upload_pictures_action"));
- priv->open_in_external_viewer_action =
- GTK_ACTION (gtk_builder_get_object (builder,
- "open_in_external_viewer_action"));
- priv->auth_action =
- GTK_ACTION (gtk_builder_get_object (builder, "auth_action"));
- priv->preferences_action =
- GTK_ACTION (gtk_builder_get_object (builder, "preferences_action"));
- priv->add_tags_action =
- GTK_ACTION (gtk_builder_get_object (builder, "add_tags_action"));
- priv->edit_details_action =
- GTK_ACTION (gtk_builder_get_object (builder, "edit_details_action"));
- priv->add_to_group_action =
- GTK_ACTION (gtk_builder_get_object (builder, "add_to_group_action"));
- priv->add_to_set_action =
- GTK_ACTION (gtk_builder_get_object (builder, "add_to_set_action"));
- priv->add_to_new_set_action =
- GTK_ACTION (gtk_builder_get_object (builder, "add_to_new_set_action"));
- priv->help_action =
- GTK_ACTION (gtk_builder_get_object (builder, "help_action"));
- priv->about_action =
- GTK_ACTION (gtk_builder_get_object (builder, "about_action"));
- priv->enable_tooltips_action =
- GTK_TOGGLE_ACTION (gtk_builder_get_object (builder,
- "enable_tooltips_action"));
- priv->sort_by_title_action =
- GTK_TOGGLE_ACTION (gtk_builder_get_object (builder,
- "sort_by_title_action"));
- priv->sort_by_date_taken_action =
- GTK_TOGGLE_ACTION (gtk_builder_get_object (builder,
- "sort_by_date_taken_action"));
- priv->sort_as_loaded_action =
- GTK_TOGGLE_ACTION (gtk_builder_get_object (builder,
- "sort_as_loaded_action"));
- priv->reversed_order_action =
- GTK_TOGGLE_ACTION (gtk_builder_get_object (builder,
- "reversed_order_action"));
- /* Set Keyboard shortcuts */
- _setup_keyboard_shortcuts (self);
+static void
+_model_deserialized (FrogrController *controller, gpointer data)
+{
+ /* Reflect that the current state is not 'dirty' (just loaded) */
+ _update_window_title (FROGR_MAIN_VIEW (data), FALSE);
+}
- /* Init main model's state description */
- _update_state_description (self);
+static void
+_update_account_menu_items (FrogrMainView *mainview)
+{
+ FrogrMainViewPrivate *priv = NULL;
- /* Init the details of the current project */
- _update_project_path (self, NULL);
+ priv = FROGR_MAIN_VIEW_GET_PRIVATE (mainview);
+ if (priv->accounts_menu && GTK_IS_CONTAINER (priv->accounts_menu))
+ {
+ FrogrAccount *active_account = NULL;
+ FrogrAccount *account = NULL;
+ GList *all_items = NULL;
+ GList *item = NULL;
+ GtkWidget *menu_item = NULL;
- /* Initialize sorting criteria and reverse in the UI */
- if (priv->sorting_criteria == SORT_BY_TITLE)
- gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priv->sort_by_title_action), TRUE);
- else if (priv->sorting_criteria == SORT_BY_DATE)
- gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priv->sort_by_date_taken_action), TRUE);
- else
- gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priv->sort_as_loaded_action), TRUE);
+ active_account = frogr_controller_get_active_account (priv->controller);
+ all_items = gtk_container_get_children (GTK_CONTAINER (priv->accounts_menu));
+ for (item = all_items; item; item = g_list_next (item))
+ {
+ gboolean value;
- gtk_toggle_action_set_active (priv->reversed_order_action, priv->sorting_reversed);
+ menu_item = GTK_WIDGET (item->data);
+ account = g_object_get_data (G_OBJECT (menu_item), "frogr-account");
- /* Initialize 'tooltips enabled' in the UI */
- gtk_toggle_action_set_active (priv->enable_tooltips_action, priv->tooltips_enabled);
+ if (account == active_account)
+ value = TRUE;
+ else
+ value = FALSE;
- /* Initialize extra widgets */
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), value);
+ }
+ g_list_free (all_items);
+ }
+}
- /* /\* Accounts menu *\/ */
- /* priv->accounts_menu_item = */
- /* GTK_WIDGET (gtk_builder_get_object (builder, "accounts_menu_item")); */
+static void
+_update_state_description (FrogrMainView *mainview)
+{
+ FrogrMainViewPrivate *priv = NULL;
- /* "Add to set" menu needs to be assigned to a var so we control
- its visibility directly because it has no action assigned to it */
- priv->add_to_set_menu_item =
- GTK_WIDGET (gtk_builder_get_object (builder, "add_to_set_menu_item"));
+ priv = FROGR_MAIN_VIEW_GET_PRIVATE (mainview);
- /* populate accounts submenu from model */
- _populate_accounts_submenu (self);
+ g_free (priv->state_description);
+ priv->state_description = _craft_state_description (mainview);
- /* create contextual menus for right-clicks */
- priv->pictures_ctxt_menu =
- GTK_WIDGET (gtk_builder_get_object (builder, "ctxt_menu"));
+ /* Do not force updating the status bar when loading pictures */
+ if (frogr_controller_get_state (priv->controller) != FROGR_STATE_LOADING_PICTURES)
+ frogr_main_view_set_status_text (mainview, priv->state_description);
+}
- /* Initialize drag'n'drop support */
- _initialize_drag_n_drop (self);
+static gchar *
+_craft_state_description (FrogrMainView *mainview)
+{
+ FrogrMainViewPrivate *priv = NULL;
+ FrogrAccount *account = NULL;
+ GSList *pictures = NULL;
+ guint n_pictures = 0;
+ const gchar *login = NULL;
+ gchar *description = NULL;
+ gchar *login_str = NULL;
+ gchar *bandwidth_str = NULL;
+ gchar *upload_size_str = NULL;
+ gboolean is_pro = FALSE;
- /* Create and hide progress bar dialog for uploading pictures */
- progress_dialog = gtk_dialog_new_with_buttons (NULL,
- priv->window,
- GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_STOCK_CANCEL,
- GTK_RESPONSE_CANCEL,
- NULL);
- gtk_window_set_title (GTK_WINDOW (progress_dialog), APP_SHORTNAME);
+ priv = FROGR_MAIN_VIEW_GET_PRIVATE (mainview);
+ account = frogr_controller_get_active_account (priv->controller);
- gtk_dialog_set_response_sensitive (GTK_DIALOG (progress_dialog),
- GTK_RESPONSE_CANCEL, TRUE);
+ if (!FROGR_IS_ACCOUNT (account) || !frogr_account_has_extra_info (account))
+ return g_strdup (_("Not connected to Flickr"));
- gtk_container_set_border_width (GTK_CONTAINER (progress_dialog), 6);
- gtk_window_set_default_size (GTK_WINDOW (progress_dialog), 250, -1);
+ /* Just use the username here ant not the fullname (when available),
+ since it could happen that the full name was the same for two
+ different usernames from the same frogr user, thus making
+ impossible to distinguish which account you are using. */
+ login = frogr_account_get_username (account);
+ is_pro = frogr_account_is_pro (account);
- progress_vbox = gtk_dialog_get_content_area (GTK_DIALOG (progress_dialog));
+ /* Login string, showing the user is PRO (second '%s') if so. */
+ login_str = g_strdup_printf (_("Connected as %s%s"), login,
+ (is_pro ? _(" (PRO account)") : ""));
- progress_label = gtk_label_new (NULL);
- gtk_box_pack_start (GTK_BOX (progress_vbox), progress_label, FALSE, FALSE, 6);
+ /* Pro users do not have any limit of quota, so it makes no sense to
+ permanently show that they have 2.0 GB / 2.0 GB remaining */
+ if (!is_pro)
+ {
+ gchar *remaining_bw_str = NULL;
+ gchar *max_bw_str = NULL;
+ gulong remaining_bw;
+ gulong max_bw;
- progress_bar = gtk_progress_bar_new ();
- gtk_progress_bar_set_show_text (GTK_PROGRESS_BAR (progress_bar), TRUE);
+ remaining_bw = frogr_account_get_remaining_bandwidth (account);
+ max_bw = frogr_account_get_max_bandwidth (account);
- gtk_box_pack_start (GTK_BOX (progress_vbox), progress_bar, FALSE, FALSE, 6);
+ remaining_bw_str = frogr_util_get_datasize_string (remaining_bw);
+ max_bw_str = frogr_util_get_datasize_string (max_bw);
- gtk_widget_hide (progress_dialog);
- priv->progress_dialog = progress_dialog;
- priv->progress_bar = progress_bar;
- priv->progress_label = progress_label;
- priv->progress_is_showing = FALSE;
- priv->state_description = NULL;
+ if (remaining_bw_str && max_bw_str)
+ {
+ /* Will show in the status bar the amount of data (in KB, MB
+ or GB) the user is currently allowed to upload to flicker
+ till the end of the month, in a CURRENT / MAX fashion.
+ The '-' at the beginning is just a separator, since more
+ blocks of text will be shown in the status bar too. */
+ bandwidth_str = g_strdup_printf (_(" - %s / %s remaining"),
+ remaining_bw_str,
+ max_bw_str);
+ }
- /* Initialize model */
- priv->tree_model = GTK_TREE_MODEL (gtk_list_store_new (3,
- G_TYPE_STRING,
- GDK_TYPE_PIXBUF,
- G_TYPE_POINTER));
- gtk_icon_view_set_model (GTK_ICON_VIEW (icon_view), priv->tree_model);
- gtk_icon_view_set_pixbuf_column (GTK_ICON_VIEW (icon_view), PIXBUF_COL);
- gtk_icon_view_set_selection_mode (GTK_ICON_VIEW (icon_view),
- GTK_SELECTION_MULTIPLE);
- gtk_icon_view_set_columns (GTK_ICON_VIEW (icon_view), -1);
- gtk_icon_view_set_item_width (GTK_ICON_VIEW (icon_view), IV_THUMB_WIDTH + IV_THUMB_PADDING);
- gtk_icon_view_set_item_padding (GTK_ICON_VIEW (icon_view), IV_THUMB_PADDING);
- gtk_icon_view_set_column_spacing (GTK_ICON_VIEW (icon_view), IV_THUMB_PADDING);
- gtk_icon_view_set_row_spacing (GTK_ICON_VIEW (icon_view), IV_THUMB_PADDING);
- gtk_widget_set_has_tooltip (icon_view, TRUE);
+ g_free (remaining_bw_str);
+ g_free (max_bw_str);
+ }
- gtk_window_set_default_size (priv->window, MINIMUM_WINDOW_WIDTH, MINIMUM_WINDOW_HEIGHT);
+ /* Check size of the loaded pictures, if any */
+ pictures = frogr_model_get_pictures (priv->model);
+ n_pictures = frogr_model_n_pictures (priv->model);
+ if (n_pictures)
+ {
+ GSList *item = NULL;
+ gulong total_size = 0;
+ gchar *total_size_str = NULL;
- /* Init status bar */
- priv->sb_context_id =
- gtk_statusbar_get_context_id (GTK_STATUSBAR (priv->status_bar),
- "Status bar messages");
+ for (item = pictures; item; item = g_slist_next (item))
+ total_size += frogr_picture_get_filesize (FROGR_PICTURE (item->data));
- /* Connect signals */
- g_signal_connect (G_OBJECT (priv->window), "delete-event",
- G_CALLBACK (_on_main_view_delete_event),
- self);
+ total_size_str = frogr_util_get_datasize_string (total_size);
- g_signal_connect (G_OBJECT (priv->icon_view), "query-tooltip",
- G_CALLBACK (_on_icon_view_query_tooltip),
- self);
+ /* Will show in the status bar the amount of pictures and data
+ (in KB, MB or GB) that would be uploaded as the sum of the
+ sizes for every picture loaded in the application */
+ upload_size_str = g_strdup_printf (ngettext (" - %d file to upload (%s)",
+ " - %d files to upload (%s)",
+ n_pictures),
+ n_pictures, total_size_str);
+ g_free (total_size_str);
+ }
- g_signal_connect (G_OBJECT (priv->icon_view), "selection-changed",
- G_CALLBACK (_on_icon_view_selection_changed),
- self);
+ /* Build the final string */
+ description = g_strdup_printf ("%s%s%s",
+ login_str,
+ (bandwidth_str ? bandwidth_str : ""),
+ (upload_size_str ? upload_size_str : ""));
+ g_free (login_str);
+ g_free (bandwidth_str);
+ g_free (upload_size_str);
- g_signal_connect (G_OBJECT (priv->progress_dialog), "response",
- G_CALLBACK(_progress_dialog_response),
- self);
+ return description;
+}
- g_signal_connect (G_OBJECT (priv->progress_dialog),
- "delete-event",
- G_CALLBACK(_progress_dialog_delete_event),
- self);
+static void
+_update_sensitiveness (FrogrMainView *self)
+{
+ FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
+ /* gboolean has_accounts = FALSE; */
+ gboolean has_pics = FALSE;
+ gint n_selected_pics = 0;
- gtk_builder_connect_signals (builder, self);
+ /* Set sensitiveness */
+ switch (frogr_controller_get_state (priv->controller))
+ {
+ case FROGR_STATE_LOADING_PICTURES:
+ case FROGR_STATE_UPLOADING_PICTURES:
+ gtk_action_set_sensitive (priv->load_project_action, FALSE);
+ gtk_action_set_sensitive (priv->save_project_action, FALSE);
+ gtk_action_set_sensitive (priv->save_project_as_action, FALSE);
+ gtk_action_set_sensitive (priv->load_pictures_action, FALSE);
+ gtk_action_set_sensitive (priv->remove_pictures_action, FALSE);
+ gtk_action_set_sensitive (priv->upload_pictures_action, FALSE);
+ gtk_action_set_sensitive (priv->open_in_external_viewer_action, FALSE);
+ gtk_action_set_sensitive (priv->add_tags_action, FALSE);
+ gtk_action_set_sensitive (priv->edit_details_action, FALSE);
+ gtk_action_set_sensitive (priv->add_to_group_action, FALSE);
+ gtk_action_set_sensitive (priv->add_to_set_action, FALSE);
+ gtk_action_set_sensitive (priv->add_to_new_set_action, FALSE);
+ /* gtk_widget_set_sensitive (priv->accounts_menu_item, FALSE); */
+ gtk_widget_set_sensitive (priv->add_to_set_menu_item, FALSE);
+ break;
- /* Show the UI */
- gtk_widget_show_all (GTK_WIDGET(priv->window));
+ case FROGR_STATE_IDLE:
+ has_pics = (_n_pictures (self) > 0);
+ /* has_accounts = (priv->accounts_menu != NULL); */
+ n_selected_pics = priv->n_selected_pictures;
-#ifdef MAC_INTEGRATION
- _tweak_menu_bar_for_mac (self);
-#endif
+ gtk_action_set_sensitive (priv->load_project_action, TRUE);
+ gtk_action_set_sensitive (priv->save_project_action, TRUE);
+ gtk_action_set_sensitive (priv->save_project_as_action, TRUE);
+ gtk_action_set_sensitive (priv->load_pictures_action, TRUE);
+ /* gtk_widget_set_sensitive (priv->accounts_menu_item, has_accounts); */
+ gtk_action_set_sensitive (priv->upload_pictures_action, has_pics);
+ gtk_action_set_sensitive (priv->remove_pictures_action, n_selected_pics > 0);
+ gtk_action_set_sensitive (priv->open_in_external_viewer_action, n_selected_pics > 0);
+ gtk_action_set_sensitive (priv->add_tags_action, n_selected_pics > 0);
+ gtk_action_set_sensitive (priv->edit_details_action, n_selected_pics > 0);
+ gtk_action_set_sensitive (priv->add_to_group_action, n_selected_pics > 0);
+ gtk_action_set_sensitive (priv->add_to_set_action, n_selected_pics > 0);
+ gtk_action_set_sensitive (priv->add_to_new_set_action, n_selected_pics > 0);
+ gtk_widget_set_sensitive (priv->add_to_set_menu_item, n_selected_pics > 0);
+ break;
- /* Update window title */
- _update_window_title (self, FALSE);
+ default:
+ g_warning ("Invalid state reached!!");
+ }
+}
- /* Update UI */
- _update_ui (FROGR_MAIN_VIEW (self));
+static void
+_update_ui (FrogrMainView *self)
+{
+ FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
- /* Show the auth dialog, if needed, on idle */
- g_idle_add ((GSourceFunc) _maybe_show_auth_dialog_on_idle, self);
+ /* Set sensitiveness */
+ _update_sensitiveness (self);
- return object;
+ /* Update status bar from model's state description */
+ if (frogr_controller_get_state (priv->controller) == FROGR_STATE_IDLE)
+ frogr_main_view_set_status_text (self, priv->state_description);
}
static void
@@ -2243,7 +2210,6 @@ _frogr_main_view_finalize (GObject *object)
g_free (priv->project_dir);
g_free (priv->project_filepath);
g_free (priv->state_description);
- gtk_widget_destroy (GTK_WIDGET (priv->window));
G_OBJECT_CLASS(frogr_main_view_parent_class)->finalize (object);
}
@@ -2253,20 +2219,9 @@ frogr_main_view_class_init (FrogrMainViewClass *klass)
{
GObjectClass *obj_class = (GObjectClass *)klass;
- obj_class->set_property = _frogr_main_view_set_property;
- obj_class->get_property = _frogr_main_view_get_property;
- obj_class->constructor = _frogr_main_view_constructor;
obj_class->dispose = _frogr_main_view_dispose;
obj_class->finalize = _frogr_main_view_finalize;
- g_object_class_install_property (obj_class,
- PROP_GTK_APPLICATION,
- g_param_spec_object ("gtk-application",
- "gtk-application",
- "GtkApplication associated to the main view",
- GTK_TYPE_APPLICATION,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
g_type_class_add_private (obj_class, sizeof (FrogrMainViewPrivate));
}
@@ -2274,46 +2229,13 @@ static void
frogr_main_view_init (FrogrMainView *self)
{
FrogrMainViewPrivate *priv = NULL;
- const gchar *icons_path = NULL;
- gchar *full_path = NULL;
- GList *icons = NULL;
- /* Init model, controller and configuration */
+ /* Initialize internal state NOT related with the UI */
priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
priv->model = frogr_model_new ();
priv->controller = g_object_ref (frogr_controller_get_instance ());
priv->config = g_object_ref (frogr_config_get_instance ());
- /* Provide a default icon list in several sizes */
- icons_path = frogr_util_get_icons_dir ();
- full_path = g_strdup_printf ("%s/" MAIN_VIEW_ICON("128x128"), icons_path);
- icons = g_list_prepend (icons, gdk_pixbuf_new_from_file (full_path, NULL));
- g_free (full_path);
-
- full_path = g_strdup_printf ("%s/" MAIN_VIEW_ICON("64x64"), icons_path);
- icons = g_list_prepend (icons, gdk_pixbuf_new_from_file (full_path, NULL));
- g_free (full_path);
-
- full_path = g_strdup_printf ("%s/" MAIN_VIEW_ICON("48x48"), icons_path);
- icons = g_list_prepend (icons, gdk_pixbuf_new_from_file (full_path, NULL));
- g_free (full_path);
-
- full_path = g_strdup_printf ("%s/" MAIN_VIEW_ICON("32x32"), icons_path);
- icons = g_list_prepend (icons, gdk_pixbuf_new_from_file (full_path, NULL));
- g_free (full_path);
-
- full_path = g_strdup_printf ("%s/" MAIN_VIEW_ICON("24x24"), icons_path);
- icons = g_list_prepend (icons, gdk_pixbuf_new_from_file (full_path, NULL));
- g_free (full_path);
-
- full_path = g_strdup_printf ("%s/" MAIN_VIEW_ICON("16x16"), icons_path);
- icons = g_list_prepend (icons, gdk_pixbuf_new_from_file (full_path, NULL));
- g_free (full_path);
-
- gtk_window_set_default_icon_list (icons);
- g_list_foreach (icons, (GFunc) g_object_unref, NULL);
- g_list_free (icons);
-
/* Initialize sorting criteria and reverse */
priv->sorted_pictures = NULL;
priv->sorting_criteria = frogr_config_get_mainview_sorting_criteria (priv->config);
@@ -2354,21 +2276,15 @@ frogr_main_view_init (FrogrMainView *self)
FrogrMainView *
frogr_main_view_new (GtkApplication *app)
{
- GObject *new = g_object_new (FROGR_TYPE_MAIN_VIEW,
- "gtk-application", app,
- NULL);
- return FROGR_MAIN_VIEW (new);
-}
-
-GtkWindow *
-frogr_main_view_get_window (FrogrMainView *self)
-{
- FrogrMainViewPrivate *priv = NULL;
-
- g_return_val_if_fail(FROGR_IS_MAIN_VIEW (self), NULL);
+ FrogrMainView *mainview =
+ FROGR_MAIN_VIEW (g_object_new (FROGR_TYPE_MAIN_VIEW,
+ "application", app,
+ "show-menubar", TRUE,
+ NULL));
- priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
- return priv->window;
+ /* Now initialize all the stuff strictly related to the UI */
+ _initialize_ui (mainview);
+ return mainview;
}
void
diff --git a/src/frogr-main-view.h b/src/frogr-main-view.h
index 686b62f..7d4e85a 100644
--- a/src/frogr-main-view.h
+++ b/src/frogr-main-view.h
@@ -39,20 +39,18 @@ typedef struct _FrogrMainViewClass FrogrMainViewClass;
struct _FrogrMainViewClass
{
- GObjectClass parent_class;
+ GtkApplicationWindowClass parent_class;
};
struct _FrogrMainView
{
- GObject parent;
+ GtkApplicationWindow parent;
};
GType frogr_main_view_get_type (void) G_GNUC_CONST;
FrogrMainView *frogr_main_view_new (GtkApplication *app);
-GtkWindow *frogr_main_view_get_window (FrogrMainView *self);
-
void frogr_main_view_set_status_text (FrogrMainView *self, const gchar *text);
void frogr_main_view_show_progress (FrogrMainView *self, const gchar *text);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]