]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkfilechooserdialog.c
remove some explicit #defines of PROFILE_FILE_CHOOSER because they break
[~andy/gtk] / gtk / gtkfilechooserdialog.c
index 6de17f1a7a6273606460df088168ff11ad97cac4..db1e5744105d59d9d5de888622a7b0e0edb60b9e 100644 (file)
  */
 
 #include <config.h>
+#include "gtkfilechooserprivate.h"
 #include "gtkfilechooserdialog.h"
 #include "gtkfilechooserwidget.h"
 #include "gtkfilechooserutils.h"
 #include "gtkfilechooserembed.h"
 #include "gtkfilesystem.h"
 #include "gtktypebuiltins.h"
+#include "gtkintl.h"
+#include "gtkalias.h"
 
 #include <stdarg.h>
 
-struct _GtkFileChooserDialogPrivate
-{
-  GtkWidget *widget;
-  
-  char *file_system;
-
-  /* for use with GtkFileChooserEmbed */
-  gint default_width;
-  gint default_height;
-  gboolean resize_horizontally;
-  gboolean resize_vertically;
-};
-
 #define GTK_FILE_CHOOSER_DIALOG_GET_PRIVATE(o)  (GTK_FILE_CHOOSER_DIALOG (o)->priv)
 
 static void gtk_file_chooser_dialog_class_init (GtkFileChooserDialogClass *class);
@@ -59,6 +49,8 @@ static void     gtk_file_chooser_dialog_get_property (GObject               *obj
                                                      GValue                *value,
                                                      GParamSpec            *pspec);
 
+static void     gtk_file_chooser_dialog_map          (GtkWidget             *widget);
+static void     gtk_file_chooser_dialog_unmap        (GtkWidget             *widget);
 static void     gtk_file_chooser_dialog_style_set    (GtkWidget             *widget,
                                                      GtkStyle              *previous_style);
 
@@ -94,7 +86,7 @@ gtk_file_chooser_dialog_get_type (void)
        NULL                                                        /* interface_data */
       };
 
-      file_chooser_dialog_type = g_type_register_static (GTK_TYPE_DIALOG, "GtkFileChooserDialog",
+      file_chooser_dialog_type = g_type_register_static (GTK_TYPE_DIALOG, I_("GtkFileChooserDialog"),
                                                         &file_chooser_dialog_info, 0);
       g_type_add_interface_static (file_chooser_dialog_type,
                                   GTK_TYPE_FILE_CHOOSER,
@@ -117,6 +109,8 @@ gtk_file_chooser_dialog_class_init (GtkFileChooserDialogClass *class)
   gobject_class->get_property = gtk_file_chooser_dialog_get_property;
   gobject_class->finalize = gtk_file_chooser_dialog_finalize;
 
+  widget_class->map       = gtk_file_chooser_dialog_map;
+  widget_class->unmap     = gtk_file_chooser_dialog_unmap;
   widget_class->style_set = gtk_file_chooser_dialog_style_set;
 
   _gtk_file_chooser_install_properties (gobject_class);
@@ -162,7 +156,35 @@ static void
 file_chooser_widget_file_activated (GtkFileChooser       *chooser,
                                    GtkFileChooserDialog *dialog)
 {
-  gtk_window_activate_default (GTK_WINDOW (dialog));
+  GList *children, *l;
+
+  if (gtk_window_activate_default (GTK_WINDOW (dialog)))
+    return;
+
+  /* There probably isn't a default widget, so make things easier for the
+   * programmer by looking for a reasonable button on our own.
+   */
+
+  children = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area));
+
+  for (l = children; l; l = l->next)
+    {
+      GtkWidget *widget;
+      int response_id;
+
+      widget = GTK_WIDGET (l->data);
+      response_id = gtk_dialog_get_response_for_widget (GTK_DIALOG (dialog), widget);
+      if (response_id == GTK_RESPONSE_ACCEPT
+         || response_id == GTK_RESPONSE_OK
+         || response_id == GTK_RESPONSE_YES
+         || response_id == GTK_RESPONSE_APPLY)
+       {
+         gtk_widget_activate (widget); /* Should we gtk_dialog_response (dialog, response_id) instead? */
+         break;
+       }
+    }
+
+  g_list_free (children);
 }
 
 static void
@@ -183,6 +205,29 @@ file_chooser_widget_update_hints (GtkFileChooserDialog *dialog)
                                 GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE);
 }
 
+static void
+clamp_to_screen (GtkWidget *widget,
+                gint      *width,
+                gint      *height)
+{
+  GdkScreen *screen;
+  int monitor_num;
+  GdkRectangle monitor;
+
+  g_return_if_fail (GTK_WIDGET_REALIZED (widget));
+  
+  screen = gtk_widget_get_screen (widget);
+  monitor_num = gdk_screen_get_monitor_at_window (screen, widget->window);
+
+  gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
+
+  if (width)
+    *width = MIN (*width, (monitor.width * 3) / 4);
+
+  if (height)
+    *height = MIN (*height, (monitor.height * 3) / 4);
+}
+
 static void
 file_chooser_widget_default_realized_size_changed (GtkWidget            *widget,
                                                   GtkFileChooserDialog *dialog)
@@ -261,12 +306,14 @@ file_chooser_widget_default_realized_size_changed (GtkWidget            *widget,
   priv->resize_horizontally = resize_horizontally;
   priv->resize_vertically = resize_vertically;
 
-  /* FIXME: We should make sure that we arent' bigger than the current screen */
   if (dx != 0 || dy != 0)
     {
-      gtk_window_resize (GTK_WINDOW (dialog),
-                        cur_width + dx,
-                        cur_height + dy);
+      gint new_width = cur_width + dx;
+      gint new_height = cur_height + dy;
+
+      clamp_to_screen (GTK_WIDGET (dialog), &new_width, &new_height);
+      
+      gtk_window_resize (GTK_WINDOW (dialog), new_width, new_height);
     }
 
   /* Only store the size if we can resize in that direction. */
@@ -343,8 +390,6 @@ gtk_file_chooser_dialog_constructor (GType                  type,
   _gtk_file_chooser_set_delegate (GTK_FILE_CHOOSER (object),
                                  GTK_FILE_CHOOSER (priv->widget));
 
-  _gtk_file_chooser_embed_initial_focus (GTK_FILE_CHOOSER_EMBED (priv->widget));
-
   gtk_widget_pop_composite_child ();
 
   return object;
@@ -433,6 +478,39 @@ set_default_size (GtkFileChooserDialog *dialog)
 }
 #endif
 
+/* GtkWidget::map handler */
+static void
+gtk_file_chooser_dialog_map (GtkWidget *widget)
+{
+  GtkFileChooserDialog *dialog = GTK_FILE_CHOOSER_DIALOG (widget);
+  GtkFileChooserDialogPrivate *priv = GTK_FILE_CHOOSER_DIALOG_GET_PRIVATE (dialog);
+
+  if (!GTK_WIDGET_MAPPED (priv->widget))
+    gtk_widget_map (priv->widget);
+
+  GTK_WIDGET_CLASS (parent_class)->map (widget);
+
+  _gtk_file_chooser_embed_initial_focus (GTK_FILE_CHOOSER_EMBED (priv->widget));
+}
+
+/* GtkWidget::unmap handler */
+static void
+gtk_file_chooser_dialog_unmap (GtkWidget *widget)
+{
+  GtkFileChooserDialog *dialog = GTK_FILE_CHOOSER_DIALOG (widget);
+  GtkFileChooserDialogPrivate *priv = GTK_FILE_CHOOSER_DIALOG_GET_PRIVATE (dialog);
+
+  GTK_WIDGET_CLASS (parent_class)->unmap (widget);
+
+  /* See bug #145470.  We unmap the GtkFileChooserWidget so that if the dialog
+   * is remapped, the widget will be remapped as well.  Implementations should
+   * refresh their contents when this happens, as some applications keep a
+   * single file chooser alive and map/unmap it as needed, rather than creating
+   * a new file chooser every time they need one.
+   */
+  gtk_widget_unmap (priv->widget);
+}
+
 static void
 gtk_file_chooser_dialog_style_set (GtkWidget *widget,
                                   GtkStyle  *previous_style)
@@ -465,14 +543,11 @@ response_cb (GtkDialog *dialog,
 
   priv = GTK_FILE_CHOOSER_DIALOG_GET_PRIVATE (dialog);
 
-  /* Ugh, try to filter out cancel-type responses */
-  if (response_id == GTK_RESPONSE_NONE
-      || response_id == GTK_RESPONSE_REJECT
-      || response_id == GTK_RESPONSE_DELETE_EVENT
-      || response_id == GTK_RESPONSE_CANCEL
-      || response_id == GTK_RESPONSE_CLOSE
-      || response_id == GTK_RESPONSE_NO
-      || response_id == GTK_RESPONSE_HELP)
+  /* Act only on response IDs we recognize */
+  if (!(response_id == GTK_RESPONSE_ACCEPT
+       || response_id == GTK_RESPONSE_OK
+       || response_id == GTK_RESPONSE_YES
+       || response_id == GTK_RESPONSE_APPLY))
     return;
 
   if (!_gtk_file_chooser_embed_should_respond (GTK_FILE_CHOOSER_EMBED (priv->widget)))
@@ -548,8 +623,8 @@ gtk_file_chooser_dialog_new (const gchar         *title,
  * gtk_file_chooser_dialog_new_with_backend:
  * @title: Title of the dialog, or %NULL
  * @parent: Transient parent of the dialog, or %NULL
- * @backend: The name of the specific filesystem backend to use.
  * @action: Open or save mode for the dialog
+ * @backend: The name of the specific filesystem backend to use.
  * @first_button_text: stock ID or text to go in the first button, or %NULL
  * @Varargs: response ID for the first button, then additional (button, id) pairs, ending with %NULL
  *
@@ -581,3 +656,6 @@ gtk_file_chooser_dialog_new_with_backend (const gchar          *title,
 
   return result;
 }
+
+#define __GTK_FILE_CHOOSER_DIALOG_C__
+#include "gtkaliasdef.c"