Improve window management

This first commit will replace gnc_ui_get_toplevel with two functions
- gnc_ui_get_gtk_window (widget): tries to find the immediate GtkWindow the given widget belongs to
- gnc_ui_get_main_window: looks for the main window that's the final transient parent widget
  can be traced back to. In the absence of widget, this will behave as gnc_ui_get_toplevel did
  and return the first active or mapped window.
This commit is contained in:
Geert Janssens
2017-11-25 15:08:31 +01:00
parent 12bad5cec8
commit 68103dd02d
11 changed files with 77 additions and 36 deletions

View File

@@ -187,7 +187,7 @@ static gboolean autosave_timeout_cb(gpointer user_data)
return FALSE;
/* Store the current toplevel window for later use. */
toplevel = gnc_ui_get_toplevel();
toplevel = GTK_WIDGET (gnc_ui_get_main_window (NULL));
/* Lookup preference to show an explanatory dialog, if wanted. */
show_explanation =

View File

@@ -140,8 +140,7 @@ gnc_file_dialog (const char * title,
gtk_window_set_modal(GTK_WINDOW(file_box), TRUE);
/*
gtk_window_set_transient_for(GTK_WINDOW(file_box),
GTK_WINDOW(gnc_ui_get_toplevel()));
gtk_window_set_transient_for(GTK_WINDOW(file_box), gnc_ui_get_main_window(NULL));
*/
if (filters != NULL)
@@ -199,7 +198,7 @@ show_session_error (QofBackendError io_error,
const char *newfile,
GNCFileDialogType type)
{
GtkWidget *parent = gnc_ui_get_toplevel();
GtkWidget *parent = GTK_WIDGET (gnc_ui_get_main_window(NULL));
GtkWidget *dialog;
gboolean uh_oh = TRUE;
const char *fmt, *label;
@@ -570,7 +569,7 @@ gnc_file_new (void)
gboolean
gnc_file_query_save (gboolean can_cancel)
{
GtkWidget *parent = gnc_ui_get_toplevel();
GtkWidget *parent = GTK_WIDGET (gnc_ui_get_main_window(NULL));
QofBook *current_book;
if (!gnc_current_session_exist())
@@ -777,7 +776,7 @@ RESTART:
GtkWindow *parent = gnc_get_splash_screen();
if (!parent)
parent = GTK_WINDOW(gnc_ui_get_toplevel());
parent = gnc_ui_get_main_window(NULL);
if (! gnc_uri_is_file_uri (newfile)) /* Hide the db password in error messages */
displayname = gnc_uri_normalize_uri ( newfile, FALSE);
@@ -949,7 +948,7 @@ RESTART:
uh_oh = TRUE;
// XXX: should pull out the file name here */
gnc_error_dialog(gnc_ui_get_toplevel(), msg, "");
gnc_error_dialog(GTK_WIDGET (gnc_ui_get_main_window(NULL)), msg, "");
g_free (msg);
}
if (template_root != NULL)
@@ -1309,7 +1308,7 @@ gnc_file_save (void)
if (qof_book_is_readonly(qof_session_get_book(session)))
{
gint response = gnc_ok_cancel_dialog(gnc_ui_get_toplevel(),
gint response = gnc_ok_cancel_dialog(GTK_WIDGET (gnc_ui_get_main_window(NULL)),
GTK_RESPONSE_CANCEL,
_("The database was opened read-only. "
"Do you want to save it to a different place?"));

View File

@@ -60,7 +60,7 @@ gnc_ok_cancel_dialog(GtkWidget *parent,
va_list args;
if (parent == NULL)
parent = gnc_ui_get_toplevel();
parent = GTK_WIDGET (gnc_ui_get_main_window(NULL));
va_start(args, format);
buffer = g_strdup_vprintf(format, args);
@@ -108,7 +108,7 @@ gnc_verify_dialog(GtkWidget *parent, gboolean yes_is_default,
va_list args;
if (parent == NULL)
parent = gnc_ui_get_toplevel();
parent = GTK_WIDGET (gnc_ui_get_main_window(NULL));
va_start(args, format);
buffer = g_strdup_vprintf(format, args);
@@ -151,7 +151,7 @@ gnc_info_dialog(GtkWidget *parent, const gchar *format, ...)
va_list args;
if (parent == NULL)
parent = gnc_ui_get_toplevel();
parent = GTK_WIDGET (gnc_ui_get_main_window (NULL));
va_start(args, format);
buffer = g_strdup_vprintf(format, args);
@@ -190,7 +190,7 @@ gnc_warning_dialog_common(GtkWidget *parent, const gchar *format, va_list args)
gchar *buffer;
if (parent == NULL)
parent = GTK_WIDGET(gnc_ui_get_toplevel());
parent = GTK_WIDGET(gnc_ui_get_main_window(NULL));
buffer = g_strdup_vprintf(format, args);
dialog = gtk_message_dialog_new (GTK_WINDOW(parent),
@@ -237,7 +237,7 @@ gnc_error_dialog_common(GtkWidget *parent, const gchar *format, va_list args)
gchar *buffer;
if (parent == NULL)
parent = GTK_WIDGET(gnc_ui_get_toplevel());
parent = GTK_WIDGET(gnc_ui_get_main_window(NULL));
buffer = g_strdup_vprintf(format, args);
dialog = gtk_message_dialog_new (GTK_WINDOW(parent),

View File

@@ -1601,14 +1601,13 @@ static guint gnc_statusbar_notification_messageid = 0;
* statusbar by generate_statusbar_lastmodified_message. */
static gboolean statusbar_notification_off(gpointer user_data_unused)
{
GtkWidget *widget = gnc_ui_get_toplevel();
GncMainWindow *mainwindow = GNC_MAIN_WINDOW (gnc_ui_get_main_window (NULL));
//g_warning("statusbar_notification_off\n");
if (gnc_statusbar_notification_messageid == 0)
return FALSE;
if (widget && GNC_IS_MAIN_WINDOW(widget))
if (mainwindow)
{
GncMainWindow *mainwindow = GNC_MAIN_WINDOW(widget);
GtkWidget *statusbar = gnc_main_window_get_statusbar(GNC_WINDOW(mainwindow));
gtk_statusbar_remove(GTK_STATUSBAR(statusbar), 0, gnc_statusbar_notification_messageid);
gnc_statusbar_notification_messageid = 0;
@@ -2671,16 +2670,16 @@ GncMainWindow *
gnc_main_window_new (void)
{
GncMainWindow *window;
GtkWidget *old_window;
GtkWindow *old_window;
window = g_object_new (GNC_TYPE_MAIN_WINDOW, NULL);
gtk_window_set_default_size(GTK_WINDOW(window), 800, 600);
old_window = gnc_ui_get_toplevel();
old_window = gnc_ui_get_main_window (NULL);
if (old_window)
{
gint width, height;
gtk_window_get_size (GTK_WINDOW (old_window), &width, &height);
gtk_window_get_size (old_window, &width, &height);
gtk_window_resize (GTK_WINDOW (window), width, height);
if ((gdk_window_get_state((gtk_widget_get_window (GTK_WIDGET(old_window))))
& GDK_WINDOW_STATE_MAXIMIZED) != 0)
@@ -4555,16 +4554,33 @@ gnc_main_window_show_all_windows(void)
#endif
}
/** Get a pointer to the first active top level window. If there is
* none, return the first mapped window or NULL
* if there is none.
*
* @return A pointer to a GtkWindow object. */
GtkWidget *
gnc_ui_get_toplevel (void)
GtkWindow *
gnc_ui_get_gtk_window (GtkWidget *widget)
{
GtkWidget *toplevel;
if (!widget)
return NULL;
toplevel = gtk_widget_get_toplevel (widget);
if (toplevel && GTK_IS_WINDOW (toplevel))
return GTK_WINDOW (toplevel);
else
return NULL;
}
GtkWindow *
gnc_ui_get_main_window (GtkWidget *widget)
{
GList *window;
GtkWindow *toplevel = gnc_ui_get_gtk_window (widget);
while (toplevel && !GNC_IS_MAIN_WINDOW (toplevel))
toplevel = gtk_window_get_transient_for(toplevel);
if (toplevel)
return toplevel;
for (window = active_windows; window; window = window->next)
if (gtk_window_is_active (GTK_WINDOW (window->data)))
return window->data;

View File

@@ -141,7 +141,34 @@ gboolean gnc_get_username_password (GtkWidget *parent,
/* Managing the GUI Windows *****************************************/
GtkWidget *gnc_ui_get_toplevel (void);
/** Get a pointer to the widget's immediate top level GtkWindow. This can be a dialog
* window or a GncMainWindow. If the widget is not a child of
* a GtkWindow (yet), NULL is returned.
*
* @param widget the widget to find a GtkWindow for.
* @return A pointer to a GtkWindow object or NULL if no toplevel was found. */
GtkWindow *gnc_ui_get_gtk_window (GtkWidget *widget);
/** Get a pointer to the final GncMainWindow widget is rooted
* in. If widget is a child of a GncMainWindow return that window.
* If it's a child of a dialog window recursively query the
* dialog's transient parent until the first parent that's a GncMainWindow
* and return that. If widget is NULL or not part of any GtkWindow,
* get a pointer to the first active top level window. If there is
* none, return the first mapped window. If there's no mapped window
* return NULL.
*
* An example of why searching for a GncMainWindow makes sense: suppose
* a user has opened a search dialog for vendors and in that dialog has
* clicked "View vendor invoices". This opens another search window in
* which the user can click "View/Edit bill". Clicking that button should
* open a new tab in the GncMainWindow from which the first search dialog
* was opened.
*
* @param widget the widget to find a GncMainWindow for.
* @return A pointer to a GtkWindow object. */
GtkWindow *gnc_ui_get_main_window (GtkWidget *widget);
/* Changing the GUI Cursor ******************************************/

View File

@@ -553,7 +553,7 @@ sxftd_ok_clicked(SXFromTransInfo *sxfti)
{
if ( sx_error == SXFTD_ERRNO_UNBALANCED_XACTION )
{
gnc_error_dialog( gnc_ui_get_toplevel(), "%s",
gnc_error_dialog (NULL, "%s",
_( "The Scheduled Transaction is unbalanced. "
"You are strongly encouraged to correct this situation." ) );
}
@@ -781,7 +781,7 @@ gnc_sx_create_from_trans( Transaction *trans )
{
if ( errno == SXFTD_ERRNO_OPEN_XACTION )
{
gnc_error_dialog( gnc_ui_get_toplevel(), "%s",
gnc_error_dialog (NULL, "%s",
_( "Cannot create a Scheduled Transaction "
"from a Transaction currently "
"being edited. Please Enter the "

View File

@@ -229,7 +229,7 @@ gnc_file_aqbanking_import(const gchar *aqbanking_importername,
/* Before importing the results, if this is a new book, let user specify
* book options, since they affect how transactions are created */
if (gnc_is_new_book())
gnc_new_book_option_display(gnc_ui_get_toplevel());
gnc_new_book_option_display (GTK_WIDGET (gnc_ui_get_main_window(NULL)));
/* Import the results */
ieci = gnc_ab_import_context(context, AWAIT_TRANSACTIONS,

View File

@@ -919,7 +919,7 @@ int ofx_proc_account_cb(struct OfxAccountData data, void * account_user_data)
* calling 'gnc_import_select_account', allow the user to set book
* options. */
if (new_book)
new_book = gnc_new_book_option_display(gnc_ui_get_toplevel());
new_book = gnc_new_book_option_display (GTK_WIDGET (gnc_ui_get_main_window (NULL)));
gnc_utf8_strip_invalid(data.account_name);
gnc_utf8_strip_invalid(data.account_id);

View File

@@ -3617,8 +3617,7 @@ gnc_ui_qif_import_assistant_make(QIFImportWindow *qif_win)
get_assistant_widgets(qif_win, builder);
/* Make this window stay on top */
gtk_window_set_transient_for (GTK_WINDOW (qif_win->window),
GTK_WINDOW (gnc_ui_get_toplevel ()));
gtk_window_set_transient_for (GTK_WINDOW (qif_win->window), gnc_ui_get_main_window(NULL));
/* Build the details of all GtkTreeView widgets. */
build_views(qif_win);

View File

@@ -413,7 +413,7 @@ gnc_plugin_page_report_create_widget( GncPluginPage *page )
report = GNC_PLUGIN_PAGE_REPORT(page);
priv = GNC_PLUGIN_PAGE_REPORT_GET_PRIVATE(report);
topLvl = GTK_WINDOW(gnc_ui_get_toplevel());
topLvl = gnc_ui_get_main_window (NULL);
// priv->html = gnc_html_new( topLvl );
priv->html = gnc_html_factory_create_html();
gnc_html_set_parent( priv->html, topLvl );

View File

@@ -232,8 +232,8 @@ gnc_report_edit_options(SCM report, GtkWindow *parent)
options = scm_call_1(get_options, report);
if (options == SCM_BOOL_F)
{
gnc_warning_dialog(GTK_WIDGET(gnc_ui_get_toplevel()), "%s",
_("There are no options for this report."));
gnc_warning_dialog (GTK_WIDGET (parent), "%s",
_("There are no options for this report."));
return FALSE;
}