* Added modest_signal_mgr_disconnect, for disconnecting a single handler
* Added the signal parametter to modest_signal_mgr_connect, this way we can add multiple connections for the same object
* Renamed modest_window_mgr_(set/get)_modal_dialog to modest_window_mgt_(set/get)_modal because we can set a normal window as modal as well
* Implemented a queue of modal dialogs in the window mgr, this way if the top one is removed the second one becomes the topmost
pmo-trunk-r3441
if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
printf ("DEBUG1: %s\n", __FUNCTION__);
- const gboolean created = modest_run_account_setup_wizard (NULL);
+ const gboolean created = modest_ui_actions_run_account_setup_wizard (NULL);
printf ("DEBUG1: %s\n", __FUNCTION__);
if (!created) {
g_debug ("modest: %s: no account exists even after offering, "
if (response_id == GTK_RESPONSE_CANCEL) {
/* This is mostly copied from
* src/maemo/modest-account-settings-dialog.c */
- if (priv->dirty)
- {
+ if (priv->dirty) {
GtkDialog *dialog = GTK_DIALOG (hildon_note_new_confirmation (GTK_WINDOW (self),
_("imum_nc_wizard_confirm_lose_changes")));
/* TODO: These button names will be ambiguous, and not specified in the UI specification. */
const gint dialog_response = gtk_dialog_run (dialog);
gtk_widget_destroy (GTK_WIDGET (dialog));
- if (dialog_response != GTK_RESPONSE_OK)
- {
- /* This is a nasty hack. murrayc. */
+ if (dialog_response != GTK_RESPONSE_OK) {
/* Don't let the dialog close */
g_signal_stop_emission_by_name (wizard_dialog, "response");
}
if (check_for_active_account (self, account_name)) {
/* The warning text depends on the account type: */
gchar *txt = NULL;
+ gint response;
+
if (modest_account_mgr_get_store_protocol (account_mgr, account_name)
== MODEST_PROTOCOL_STORE_POP) {
txt = g_strdup_printf (_("emev_nc_delete_mailbox"),
g_free (txt);
txt = NULL;
- if (gtk_dialog_run (dialog) == GTK_RESPONSE_OK) {
+ response = gtk_dialog_run (dialog);
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+ while (gtk_events_pending ())
+ gtk_main_iteration ();
+
+ if (response == GTK_RESPONSE_OK) {
/* Remove account. If it succeeds then it also removes
- the account from the ModestAccountView: */
-
+ the account from the ModestAccountView: */
gboolean is_default = FALSE;
gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
if (default_account_name && (strcmp (default_account_name, account_name) == 0))
g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);
}
}
- gtk_widget_destroy (GTK_WIDGET (dialog));
g_free (account_title);
- }
-
+ }
g_free (account_name);
}
}
{
/* The response has already been handled by the wizard dialog itself,
* creating the new account.
- */
-
+ */
/* Destroy the dialog: */
- if (dialog) {
+ if (dialog)
gtk_widget_destroy (GTK_WIDGET (dialog));
- modest_window_mgr_set_modal_dialog (
- modest_runtime_get_window_mgr(), NULL);
- }
}
static void
on_new_button_clicked (GtkWidget *button, ModestAccountViewWindow *self)
{
- GtkDialog *wizard, *dialog;
+ GtkDialog *wizard;
+ GtkWindow *dialog;
/* Show the easy-setup wizard: */
- dialog = modest_window_mgr_get_modal_dialog (modest_runtime_get_window_mgr());
+ dialog = modest_window_mgr_get_modal (modest_runtime_get_window_mgr());
if (dialog && MODEST_IS_EASYSETUP_WIZARD_DIALOG(dialog)) {
/* old wizard is active already;
*/
- gtk_window_present (GTK_WINDOW(dialog));
+ gtk_window_present (dialog);
return;
}
/* there is no such wizard yet */
- wizard = GTK_DIALOG(modest_easysetup_wizard_dialog_new ());
- modest_window_mgr_set_modal_dialog (modest_runtime_get_window_mgr(),
- GTK_DIALOG(wizard));
+ wizard = GTK_DIALOG (modest_easysetup_wizard_dialog_new ());
+ modest_window_mgr_set_modal (modest_runtime_get_window_mgr(),
+ GTK_WINDOW (wizard));
/* if there is already another modal dialog, make it non-modal */
if (dialog)
#include "modest-tny-platform-factory.h"
#include "modest-tny-msg.h"
#include "modest-tny-folder.h"
+#include "modest-tny-account.h"
#include "modest-address-book.h"
#include "modest-text-utils.h"
#include <tny-simple-list.h>
static void remove_tags (WPTextBuffer *buffer);
+static void on_account_removed (TnyAccountStore *account_store,
+ TnyAccount *account,
+ gpointer user_data);
+
+
static void DEBUG_BUFFER (WPTextBuffer *buffer)
{
#ifdef DEBUG
gboolean can_undo, can_redo;
gulong clipboard_change_handler_id;
gulong default_clipboard_change_handler_id;
+ gulong account_removed_handler_id;
gchar *clipboard_text;
TnyMsg *draft_msg;
priv->can_redo = FALSE;
priv->clipboard_change_handler_id = 0;
priv->default_clipboard_change_handler_id = 0;
+ priv->account_removed_handler_id = 0;
priv->clipboard_text = NULL;
priv->sent = FALSE;
priv->default_clipboard_change_handler_id))
g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
priv->default_clipboard_change_handler_id);
+
+ if (priv->account_removed_handler_id &&
+ g_signal_handler_is_connected (modest_runtime_get_account_store (),
+ priv->account_removed_handler_id))
+ g_signal_handler_disconnect(modest_runtime_get_account_store (),
+ priv->account_removed_handler_id);
}
static void
priv->update_caption_visibility = TRUE;
modest_msg_edit_window_reset_modified (MODEST_MSG_EDIT_WINDOW (obj));
+
+ /* Track account-removed signal, this window should be closed
+ in the case we're creating a mail associated to the account
+ that is deleted */
+ priv->account_removed_handler_id =
+ g_signal_connect (G_OBJECT (modest_runtime_get_account_store ()),
+ "account_removed",
+ G_CALLBACK(on_account_removed),
+ obj);
return (ModestWindow*) obj;
}
gtk_text_buffer_remove_all_tags (GTK_TEXT_BUFFER (buffer), &start, &end);
}
+
+static void
+on_account_removed (TnyAccountStore *account_store,
+ TnyAccount *account,
+ gpointer user_data)
+{
+ /* Do nothing if it's a store account, because we use the
+ transport to send the messages */
+ if (tny_account_get_account_type(account) == TNY_ACCOUNT_TYPE_TRANSPORT) {
+ const gchar *parent_acc = NULL;
+ const gchar *our_acc = NULL;
+
+ our_acc = modest_window_get_active_account (MODEST_WINDOW (user_data));
+ parent_acc = modest_tny_account_get_parent_modest_account_name_for_server_account (account);
+ /* Close this window if I'm showing a message of the removed account */
+ if (strcmp (parent_acc, our_acc) == 0)
+ modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (user_data));
+ }
+}
static void
on_destroy_dialog (GtkDialog *dialog)
{
- if (dialog == modest_window_mgr_get_modal_dialog (modest_runtime_get_window_mgr()))
- modest_window_mgr_set_modal_dialog (modest_runtime_get_window_mgr(),
- NULL);
gtk_widget_destroy (GTK_WIDGET(dialog));
-}
-
-
-/* is there already a modal dialog? if so, return TRUE, if not set this
- * dialog to be the registered one */
-static void
-check_modal_and_set_maybe (GtkDialog *dialog)
-{
- GtkDialog *old_modal;
-
- old_modal =
- modest_window_mgr_get_modal_dialog (modest_runtime_get_window_mgr());
-
- if (!old_modal) {
- gtk_window_set_modal (GTK_WINDOW(dialog), TRUE);
- } else {
- /* un-modalize the old one; the one on top should be the
- * modal one */
- gtk_window_set_modal (GTK_WINDOW(old_modal), FALSE);
- gtk_window_set_modal (GTK_WINDOW(dialog), TRUE);
- }
-
- /* this will be the new modal dialog */
- modest_window_mgr_set_modal_dialog (modest_runtime_get_window_mgr(),
- dialog);
+ if (gtk_events_pending ())
+ gtk_main_iteration ();
}
gint
gint response;
dialog = hildon_note_new_confirmation (parent_window, message);
- check_modal_and_set_maybe (GTK_DIALOG(dialog));
+ modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
+ GTK_WINDOW (dialog));
response = gtk_dialog_run (GTK_DIALOG (dialog));
_("mcen_bd_yes"), GTK_RESPONSE_YES,
_("mcen_bd_no"), GTK_RESPONSE_NO,
NULL);
- check_modal_and_set_maybe (GTK_DIALOG(dialog));
+ modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog));
response = gtk_dialog_run (GTK_DIALOG (dialog));
on_destroy_dialog (GTK_DIALOG(dialog));
GtkWidget *note;
note = hildon_note_new_information (parent_window, message);
- check_modal_and_set_maybe (GTK_DIALOG(note));
+ modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
+ GTK_WINDOW (note));
g_signal_connect_swapped (note,
"response",
/* Build dialog */
dialog = hildon_sort_dialog_new (parent_window);
- check_modal_and_set_maybe (GTK_DIALOG(dialog));
+ modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
+ GTK_WINDOW (dialog));
/* Fill sort keys */
switch (type) {
G_CALLBACK(on_cert_dialog_response),
(gpointer) certificate);
- check_modal_and_set_maybe (GTK_DIALOG(note));
+ modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
+ GTK_WINDOW (note));
response = gtk_dialog_run(GTK_DIALOG(note));
on_destroy_dialog (GTK_DIALOG(note));
* so we know what buttons to show. */
GtkWidget *dialog = GTK_WIDGET (hildon_note_new_confirmation (GTK_WINDOW (main_window),
prompt));
- check_modal_and_set_maybe (GTK_DIALOG(dialog));
+ modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
+ GTK_WINDOW (dialog));
const int response = gtk_dialog_run (GTK_DIALOG (dialog));
retval = (response == GTK_RESPONSE_YES) || (response == GTK_RESPONSE_OK);
*/
#include "modest-signal-mgr.h"
+#include <string.h>
typedef struct {
guint handler_id;
+ gchar *signal_name;
GObject *obj;
} SignalHandler;
GSList *
-modest_signal_mgr_connect (GSList *lst, GObject *instance, const gchar *detail,
- GCallback handler, gpointer data)
+modest_signal_mgr_connect (GSList *lst,
+ GObject *instance,
+ const gchar *signal_name,
+ GCallback handler,
+ gpointer data)
{
SignalHandler *sighandler;
g_return_val_if_fail (instance, lst);
- g_return_val_if_fail (detail, lst);
+ g_return_val_if_fail (signal_name, lst);
g_return_val_if_fail (handler, lst);
sighandler = g_new (SignalHandler, 1);
- sighandler->obj = g_object_ref (instance);
- sighandler->handler_id = g_signal_connect (instance, detail, handler, data);
+ sighandler->obj = g_object_ref (instance);
+ sighandler->handler_id = g_signal_connect (instance, signal_name, handler, data);
+ sighandler->signal_name = g_strdup (signal_name);
return g_slist_prepend (lst, (gpointer)sighandler);
}
handler = (SignalHandler*)cursor->data;
if (handler && handler->obj && G_IS_OBJECT(handler->obj)) {
if (g_signal_handler_is_connected (handler->obj, handler->handler_id)) {
- /* g_debug ("%p: disconnecting %d", handler->obj, handler->handler_id); */
g_signal_handler_disconnect (handler->obj, handler->handler_id);
}
g_object_unref (handler->obj);
}
g_slist_free (lst);
}
+
+static gboolean
+obj_in_a_signal_handler (gconstpointer a,
+ gconstpointer b)
+{
+ SignalHandler *handler, *list_item_handler;
+
+ list_item_handler = (SignalHandler *) a;
+ handler = (SignalHandler *) b;
+
+ if (list_item_handler->obj == handler->obj &&
+ !strcmp (list_item_handler->signal_name, handler->signal_name))
+ return 0;
+ else
+ return 1;
+}
+
+GSList *
+modest_signal_mgr_disconnect (GSList *list,
+ GObject *instance,
+ const gchar *signal_name)
+{
+ GSList *item = NULL;
+ SignalHandler *signal_handler = NULL, *tmp = NULL;
+
+ tmp = g_new (SignalHandler, 1);
+ tmp->obj = instance;
+ tmp->signal_name = g_strdup (signal_name);
+
+ /* Find the element */
+ item = g_slist_find_custom (list, tmp, obj_in_a_signal_handler);
+ g_return_val_if_fail (item != NULL, list);
+
+ /* Disconnect the signal */
+ signal_handler = (SignalHandler *) item->data;
+ g_signal_handler_disconnect (signal_handler->obj, signal_handler->handler_id);
+
+ /* Free the handlers */
+ g_free (signal_handler->signal_name);
+ g_free (signal_handler);
+ g_free (tmp->signal_name);
+ g_free (tmp);
+
+ /* Remove item from list */
+ return g_slist_delete_link (list, item);
+}
*
* TRUE if this succeeded, FALSE otherwise.
*/
-GSList *modest_signal_mgr_connect (GSList *lst, GObject *instance, const gchar *detail,
- GCallback handler, gpointer data);
+GSList * modest_signal_mgr_connect (GSList *lst,
+ GObject *instance,
+ const gchar *signal_name,
+ GCallback handler,
+ gpointer data);
+
+/**
+ * modest_signal_mgr_disconnect:
+ * @list:
+ * @instance:
+ *
+ * disconnect the handler for a particular object for a particular signal
+ *
+ * Returns:
+ **/
+GSList * modest_signal_mgr_disconnect (GSList *list,
+ GObject *instance,
+ const gchar *signal_name);
+
/**
* modest_signal_mgr_disconnect_all_and_destroy:
+ * @lst: the list of signal handlers
*
* disconnect all signals in the list, and destroy the list
- *
*/
-void modest_signal_mgr_disconnect_all_and_destroy (GSList *lst);
+void modest_signal_mgr_disconnect_all_and_destroy (GSList *lst);
+
G_END_DECLS
#endif /*__MODEST_SIGNAL_MGR__*/
* returns: TRUE if an account was created. FALSE if the user cancelled.
*/
gboolean
-modest_run_account_setup_wizard (ModestWindow *win)
+modest_ui_actions_run_account_setup_wizard (ModestWindow *win)
{
- gboolean result = FALSE;
- GtkDialog *wizard, *dialog;
+ gboolean result = FALSE;
+ GtkWindow *dialog, *wizard;
+ gint dialog_response;
/* Show the easy-setup wizard: */
- dialog = modest_window_mgr_get_modal_dialog (modest_runtime_get_window_mgr());
+ dialog = modest_window_mgr_get_modal (modest_runtime_get_window_mgr());
if (dialog && MODEST_IS_EASYSETUP_WIZARD_DIALOG(dialog)) {
/* old wizard is active already;
*/
}
- /* there is no such wizard yet */
-
- wizard = GTK_DIALOG(modest_easysetup_wizard_dialog_new ());
- if (!wizard) {
- g_printerr ("modest: failed to create easysetup wizard\n");
- return FALSE;
- }
-
- modest_window_mgr_set_modal_dialog
- (modest_runtime_get_window_mgr(), GTK_DIALOG(wizard));
-
-
- /* there is no such wizard yet */
- wizard = GTK_DIALOG(modest_easysetup_wizard_dialog_new ());
- modest_window_mgr_set_modal_dialog (modest_runtime_get_window_mgr(),
- GTK_DIALOG(wizard));
-
- /* make it non-modal; if though we register it as a modal dialog above
- * apparently, making it modal *at all* gives hangs -- FIXME: check this*/
- gtk_window_set_modal (GTK_WINDOW(dialog), FALSE);
+ /* there is no such wizard yet */
+ wizard = GTK_WINDOW (modest_easysetup_wizard_dialog_new ());
+ modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), wizard);
/* always present a main window in the background
* we do it here, so we cannot end up with to wizards (as this
/* make sure the mainwindow is visible */
gtk_widget_show_all (GTK_WIDGET(win));
gtk_window_present (GTK_WINDOW(win));
-
- gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
+ dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
+ gtk_widget_destroy (GTK_WIDGET (wizard));
+ if (gtk_events_pending ())
+ gtk_main_iteration ();
- /* Don't make this a modal window, because secondary windows will then
- * be unusable, freezing the UI: */
- /* gtk_window_set_modal (GTK_WINDOW (wizard), TRUE); */
-
- gint dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
- if (dialog_response == GTK_RESPONSE_CANCEL)
+ if (dialog_response == GTK_RESPONSE_CANCEL) {
result = FALSE;
- else {
+ } else {
/* Check whether an account was created: */
result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
}
- gtk_widget_destroy (GTK_WIDGET (wizard));
-
- /* clear it from the window mgr */
- modest_window_mgr_set_modal_dialog
- (modest_runtime_get_window_mgr(), NULL);
-
return result;
}
}
void
-modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
+modest_ui_actions_on_accounts (GtkAction *action,
+ ModestWindow *win)
{
/* This is currently only implemented for Maemo */
#ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
- if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
- modest_run_account_setup_wizard (win);
+ if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
+ modest_ui_actions_run_account_setup_wizard (win);
return;
- } else {
- /* Show the list of accounts: */
- GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
- gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW (win));
+ } else {
+ /* Show the list of accounts */
+ GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
+ gtk_window_set_transient_for (account_win, GTK_WINDOW (win));
- /* The accounts dialog must be modal */
- gtk_window_set_modal (GTK_WINDOW (account_win), TRUE);
- modest_maemo_show_dialog_and_forget (GTK_WINDOW (win), account_win);
+ /* The accounts dialog must be modal */
+ modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), account_win);
+ modest_maemo_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win));
}
#else
GtkWidget *dialog, *label;
/* if there are no accounts yet, just show the wizard */
if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
- const gboolean created = modest_run_account_setup_wizard (win);
- if (!created)
- return;
+ if (!modest_ui_actions_run_account_setup_wizard (win))
+ return;
}
account_name = g_strdup (modest_window_get_active_account (win));
(folder_type == TNY_FOLDER_TYPE_OUTBOX)) {
/* we cannot edit without a valid account... */
if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
- const gboolean created = modest_run_account_setup_wizard(parent_win);
- if (!created)
+ if (!modest_ui_actions_run_account_setup_wizard(parent_win))
goto cleanup;
}
win = modest_msg_edit_window_new (msg, account, TRUE);
/* we need an account when editing */
if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
- const gboolean created = modest_run_account_setup_wizard (win);
- if (!created)
+ if (!modest_ui_actions_run_account_setup_wizard (win))
return;
}
if (!account_name) {
/* Run account setup wizard */
- const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
- if (!created)
+ if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window)))
return;
}
account_name));
if (!transport_account) {
/* Run account setup wizard */
- const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
- if (!created)
+ if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
return;
}
/* Show the account creation wizard dialog.
* returns: TRUE if an account was created. FALSE if the user cancelled.
*/
-gboolean modest_run_account_setup_wizard (ModestWindow *win);
+gboolean modest_ui_actions_run_account_setup_wizard (ModestWindow *win);
gint modest_ui_actions_msgs_move_to_confirmation (GtkWindow *win,
TnyFolder *dest_folder,
GdkEvent *event,
ModestWindowMgr *self);
+static gboolean on_modal_window_close (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer user_data);
+
+static void on_modal_dialog_close (GtkDialog *dialog,
+ gint arg1,
+ gpointer user_data);
+
static const gchar* get_show_toolbar_key (GType window_type,
gboolean fullscreen);
GList *window_list;
ModestWindow *main_window;
- GtkDialog *modal_dialog;
+
+ GMutex *queue_lock;
+ GQueue *modal_windows;
gboolean fullscreen_mode;
GHashTable *viewer_handlers;
guint closing_time;
+
+ GSList *modal_handler_uids;
};
#define MODEST_WINDOW_MGR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
MODEST_TYPE_WINDOW_MGR, \
priv->window_list = NULL;
priv->main_window = NULL;
priv->fullscreen_mode = FALSE;
- priv->modal_dialog = NULL;
+
+ priv->modal_windows = g_queue_new ();
+ priv->queue_lock = g_mutex_new ();
priv->preregistered_uids = NULL;
priv->viewer_handlers = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
priv->closing_time = 0;
+
+ priv->modal_handler_uids = NULL;
}
static void
priv->viewer_handlers = NULL;
}
- if (priv->modal_dialog) {
- g_warning ("%s: forgot to destroy a modal dialog somewhere",
- __FUNCTION__);
- gtk_widget_destroy (GTK_WIDGET(priv->modal_dialog));
- priv->modal_dialog = NULL;
+ modest_signal_mgr_disconnect_all_and_destroy (priv->modal_handler_uids);
+
+ if (priv->modal_windows) {
+ g_mutex_lock (priv->queue_lock);
+ g_queue_free (priv->modal_windows);
+ priv->modal_windows = NULL;
+ g_mutex_unlock (priv->queue_lock);
}
+ g_mutex_free (priv->queue_lock);
/* Do not unref priv->main_window because it does not hold a
new reference */
sent = modest_msg_edit_window_get_sent (MODEST_MSG_EDIT_WINDOW (window));
/* Save currently edited message to Drafts if it was not sent */
if (!sent && modest_msg_edit_window_is_modified (MODEST_MSG_EDIT_WINDOW (window))) {
+
+ /* Raise the window if it's minimized */
+ if (!gtk_window_has_toplevel_focus (GTK_WINDOW (window)))
+ gtk_window_present (GTK_WINDOW (window));
response =
modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
}
-GtkDialog*
-modest_window_mgr_get_modal_dialog (ModestWindowMgr *self)
+GtkWindow *
+modest_window_mgr_get_modal (ModestWindowMgr *self)
{
ModestWindowMgrPrivate *priv;
g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), NULL);
priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
- return priv->modal_dialog;
+ return g_queue_peek_head (priv->modal_windows);
}
-GtkDialog*
-modest_window_mgr_set_modal_dialog (ModestWindowMgr *self, GtkDialog *dialog)
+void
+modest_window_mgr_set_modal (ModestWindowMgr *self,
+ GtkWindow *window)
{
+ GtkWindow *old_modal;
ModestWindowMgrPrivate *priv;
-
- g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), NULL);
+
+ g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
+ g_return_if_fail (GTK_IS_WINDOW (window));
+
priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
+ g_mutex_lock (priv->queue_lock);
+ old_modal = g_queue_peek_head (priv->modal_windows);
+ g_mutex_unlock (priv->queue_lock);
- return priv->modal_dialog = dialog;
+ if (!old_modal) {
+ gtk_window_set_modal (window, TRUE);
+ } else {
+ /* un-modalize the old one; the one on top should be the
+ * modal one */
+ gtk_window_set_transient_for (window, GTK_WINDOW(old_modal));
+ gtk_window_set_modal (window, TRUE);
+ }
+
+ /* this will be the new modal window */
+ g_mutex_lock (priv->queue_lock);
+ g_queue_push_head (priv->modal_windows, window);
+ g_mutex_unlock (priv->queue_lock);
+
+ if (GTK_IS_DIALOG (window))
+ /* Note that response is not always enough because it
+ could be captured and removed easily by dialogs but
+ works for most of situations */
+ priv->modal_handler_uids =
+ modest_signal_mgr_connect (priv->modal_handler_uids,
+ G_OBJECT (window),
+ "response",
+ G_CALLBACK (on_modal_dialog_close),
+ self);
+ else
+ priv->modal_handler_uids =
+ modest_signal_mgr_connect (priv->modal_handler_uids,
+ G_OBJECT (window),
+ "delete-event",
+ G_CALLBACK (on_modal_window_close),
+ self);
}
win = g_list_next (win);
}
}
+
+static gboolean
+idle_top_modal (gpointer data)
+{
+ ModestWindowMgr *self = MODEST_WINDOW_MGR (data);
+ ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
+ GtkWindow *topmost;
+
+ /* Get the top modal */
+ g_mutex_lock (priv->queue_lock);
+ topmost = (GtkWindow *) g_queue_peek_head (priv->modal_windows);
+ g_mutex_unlock (priv->queue_lock);
+
+ /* Show it */
+ if (topmost)
+ gtk_window_present (topmost);
+
+ return FALSE;
+}
+
+static void
+remove_modal_from_queue (GtkWidget *widget,
+ ModestWindowMgr *self)
+{
+ ModestWindowMgrPrivate *priv;
+ GList *item = NULL;
+
+ priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
+
+ /* Remove from queue. We don't use remove, because we want to
+ exit if the widget does not belong to the queue */
+ g_mutex_lock (priv->queue_lock);
+ item = g_queue_find (priv->modal_windows, widget);
+ if (!item) {
+ g_warning ("Trying to remove a modal window that is not registered");
+ g_mutex_unlock (priv->queue_lock);
+ return;
+ }
+ g_queue_unlink (priv->modal_windows, item);
+ g_mutex_unlock (priv->queue_lock);
+
+ /* Disconnect handler */
+ priv->modal_handler_uids =
+ modest_signal_mgr_disconnect (priv->modal_handler_uids,
+ G_OBJECT (widget),
+ GTK_IS_DIALOG (widget) ?
+ "response" :
+ "destroy-event");
+
+ /* Schedule the next one for being shown */
+ g_idle_add (idle_top_modal, self);
+}
+
+static gboolean
+on_modal_window_close (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer user_data)
+{
+ ModestWindowMgr *self = MODEST_WINDOW_MGR (user_data);
+
+ /* Remove modal window from queue */
+ remove_modal_from_queue (widget, self);
+
+ /* Continue */
+ return FALSE;
+}
+
+static void
+on_modal_dialog_close (GtkDialog *dialog,
+ gint arg1,
+ gpointer user_data)
+{
+ ModestWindowMgr *self = MODEST_WINDOW_MGR (user_data);
+
+ /* Remove modal window from queue */
+ remove_modal_from_queue (GTK_WIDGET (dialog), self);
+}
+
/**
- * modest_window_mgr_get_modal_dialog:
+ * modest_window_mgr_get_modal:
* @self: a #ModestWindowMgr
*
- * get the modal dialog; if it's NULL, there's no active dialog
+ * get the modal window; if it's NULL, there's no active modal window
*
- * Returns: the modal dialog or NULL
+ * Returns: the modal window or NULL
**/
-GtkDialog* modest_window_mgr_get_modal_dialog (ModestWindowMgr *self);
+GtkWindow* modest_window_mgr_get_modal (ModestWindowMgr *self);
/**
*
* Returns: the modal dialog just set
**/
-GtkDialog* modest_window_mgr_set_modal_dialog (ModestWindowMgr *self,
- GtkDialog *dialog);
-
+void modest_window_mgr_set_modal (ModestWindowMgr *self,
+ GtkWindow *window);
/**
* modest_window_mgr_prevent_hibernation_while_window_is_shown: