Commit d2cb6c6e authored by Alexander Larsson's avatar Alexander Larsson Committed by Alexander Larsson

Make sure grab-notify is emitted on toplevels as well as child widgets.

2006-05-22  Alexander Larsson  <alexl@redhat.com>

	* gtk/gtkmain.c:
	Make sure grab-notify is emitted on toplevels as well as
	child widgets.

	* gtk/Makefile.am:
	* gtk/gtkwin32embedwidget.[ch]
	Add new widget used for win32 port to embed gtk+
	widgets in windows dialog.

	* gtk/gtkmarshalers.list:
	Add POINTER:VOID

	* gtk/gtkprintoperation-private.h:
	* gtk/gtkprintoperation.[ch]:
	Generic support for custom widgets in print dialog.

	* gtk/gtkprintoperation-win32.c:
	Implement custom widget support for win32.

	* tests/print-editor.c:
	Allow setting of font using custom widgets in the print dialog.
parent fb3eeb86
2006-05-22 Alexander Larsson <alexl@redhat.com>
* gtk/gtkmain.c:
Make sure grab-notify is emitted on toplevels as well as
child widgets.
* gtk/Makefile.am:
* gtk/gtkwin32embedwidget.[ch]
Add new widget used for win32 port to embed gtk+
widgets in windows dialog.
* gtk/gtkmarshalers.list:
Add POINTER:VOID
* gtk/gtkprintoperation-private.h:
* gtk/gtkprintoperation.[ch]:
Generic support for custom widgets in print dialog.
* gtk/gtkprintoperation-win32.c:
Implement custom widget support for win32.
* tests/print-editor.c:
Allow setting of font using custom widgets in the print dialog.
2006-05-22 Behdad Esfahbod <behdad@gnome.org>
Rollback the following changes, to fix it the proper way in Pango:
......
2006-05-22 Alexander Larsson <alexl@redhat.com>
* gtk/gtkmain.c:
Make sure grab-notify is emitted on toplevels as well as
child widgets.
* gtk/Makefile.am:
* gtk/gtkwin32embedwidget.[ch]
Add new widget used for win32 port to embed gtk+
widgets in windows dialog.
* gtk/gtkmarshalers.list:
Add POINTER:VOID
* gtk/gtkprintoperation-private.h:
* gtk/gtkprintoperation.[ch]:
Generic support for custom widgets in print dialog.
* gtk/gtkprintoperation-win32.c:
Implement custom widget support for win32.
* tests/print-editor.c:
Allow setting of font using custom widgets in the print dialog.
2006-05-22 Behdad Esfahbod <behdad@gnome.org>
Rollback the following changes, to fix it the proper way in Pango:
......
......@@ -623,8 +623,8 @@ gtk_c_sources += \
gtktrayicon-x11.c
else
if USE_WIN32
gtk_private_h_sources += gtkwin32embed.h
gtk_c_sources += gtkplug-win32.c gtksocket-win32.c gtkwin32embed.c
gtk_private_h_sources += gtkwin32embed.h gtkwin32embedwidget.h
gtk_c_sources += gtkplug-win32.c gtksocket-win32.c gtkwin32embed.c gtkwin32embedwidget.c
else
gtk_c_sources += gtkplug-stub.c gtksocket-stub.c
endif
......@@ -778,7 +778,7 @@ libgtk_directfb_2_0_la_LDFLAGS = $(libtool_opts)
libgtk_x11_2_0_la_LIBADD = $(libadd)
libgtk_linux_fb_2_0_la_LIBADD = $(libadd)
libgtk_win32_2_0_la_LIBADD = $(libadd) -lole32 -lgdi32 -lcomdlg32 -lwinspool
libgtk_win32_2_0_la_LIBADD = $(libadd) -lole32 -lgdi32 -lcomdlg32 -lwinspool -lcomctl32
libgtk_win32_2_0_la_DEPENDENCIES = $(gtk_def) $(gtk_win32_res)
libgtk_quartz_2_0_la_LIBADD = $(libadd)
libgtk_directfb_2_0_la_LIBADD = $(libadd)
......
......@@ -1560,8 +1560,7 @@ gtk_grab_notify (GtkWindowGroup *group,
info.is_grabbed = FALSE;
if (group == gtk_window_get_group (toplevel))
gtk_container_foreach (GTK_CONTAINER (toplevel),
gtk_grab_notify_foreach, &info);
gtk_grab_notify_foreach (GTK_WIDGET (toplevel), &info);
g_object_unref (toplevel);
}
......
......@@ -52,6 +52,7 @@ NONE:INT,BOOL
NONE:INT,INT
NONE:NONE
NONE:STRING,INT,POINTER
POINTER:VOID
STRING:DOUBLE
VOID:DOUBLE
VOID:BOOLEAN
......
......@@ -57,7 +57,8 @@ struct _GtkPrintOperationPrivate
guint manual_orientation : 1;
double manual_scale;
GtkPageSet manual_page_set;
GtkWidget *custom_widget;
gpointer platform_data;
GDestroyNotify free_platform_data;
......
......@@ -33,7 +33,11 @@
#include "gtkprint-win32.h"
#include "gtkintl.h"
#include "gtkinvisible.h"
#include "gtkplug.h"
#include "gtkstock.h"
#include "gtkalias.h"
#include "gtk.h"
#include "gtkwin32embedwidget.h"
#define MAX_PAGE_RANGES 20
#define STATUS_POLLING_TIME 2000
......@@ -53,6 +57,8 @@ typedef struct {
HANDLE printerHandle;
int job_id;
guint timeout_id;
GtkWidget *embed_widget;
} GtkPrintOperationWin32;
static void win32_poll_status (GtkPrintOperation *op);
......@@ -593,7 +599,6 @@ get_parent_hwnd (GtkWidget *widget)
return gdk_win32_drawable_get_handle (widget->window);
}
static void
devnames_to_settings (GtkPrintSettings *settings,
HANDLE hDevNames)
......@@ -1267,6 +1272,126 @@ print_callback_new (void)
return &callback->iPrintDialogCallback;
}
static void
plug_grab_notify (GtkWidget *widget,
gboolean was_grabbed,
GtkPrintOperation *op)
{
EnableWindow(GetAncestor (GDK_WINDOW_HWND (widget->window), GA_ROOT),
was_grabbed);
}
static BOOL CALLBACK
pageDlgProc (HWND wnd, UINT message, WPARAM wparam, LPARAM lparam)
{
GtkPrintOperation *op;
GtkPrintOperationWin32 *op_win32;
if (message == WM_INITDIALOG)
{
PROPSHEETPAGEW *page = (PROPSHEETPAGEW *)lparam;
GtkWidget *plug;
op = GTK_PRINT_OPERATION ((gpointer)page->lParam);
op_win32 = op->priv->platform_data;
SetWindowLongPtrW(wnd, GWLP_USERDATA, (LONG_PTR)op);
plug = _gtk_win32_embed_widget_new ((GdkNativeWindow) wnd);
op_win32->embed_widget = plug;
gtk_container_add (GTK_CONTAINER (plug), op->priv->custom_widget);
gtk_widget_show (op->priv->custom_widget);
gtk_widget_show (plug);
gdk_window_focus (plug->window, GDK_CURRENT_TIME);
/* This dialog is modal, so we grab the embed widget */
gtk_grab_add (plug);
/* When we lose the grab we need to disable the print dialog */
g_signal_connect (plug, "grab-notify", G_CALLBACK (plug_grab_notify), op);
return FALSE;
}
else if (message == WM_DESTROY)
{
op = GTK_PRINT_OPERATION (GetWindowLongPtrW(wnd, GWLP_USERDATA));
op_win32 = op->priv->platform_data;
g_signal_emit_by_name (op, "custom-widget-apply", op->priv->custom_widget);
gtk_widget_destroy (op_win32->embed_widget);
op_win32->embed_widget = NULL;
op->priv->custom_widget = NULL;
}
else
{
op = GTK_PRINT_OPERATION (GetWindowLongPtrW(wnd, GWLP_USERDATA));
op_win32 = op->priv->platform_data;
return _gtk_win32_embed_widget_dialog_procedure (GTK_WIN32_EMBED_WIDGET (op_win32->embed_widget),
wnd, message, wparam, lparam);
}
return FALSE;
}
static HPROPSHEETPAGE
create_application_page (GtkPrintOperation *op)
{
HPROPSHEETPAGE hpage;
PROPSHEETPAGEW page;
DLGTEMPLATE *template;
HGLOBAL htemplate;
LONG base_units;
WORD baseunitX, baseunitY;
WORD *array;
GtkRequisition requisition;
const char *app_name;
/* Make the template the size of the custom widget size request */
gtk_widget_size_request (op->priv->custom_widget, &requisition);
base_units = GetDialogBaseUnits();
baseunitX = LOWORD(base_units);
baseunitY = HIWORD(base_units);
htemplate = GlobalAlloc (GMEM_MOVEABLE,
sizeof (DLGTEMPLATE) + sizeof(WORD) * 3);
template = GlobalLock (htemplate);
template->style = WS_CHILDWINDOW | DS_CONTROL;
template->dwExtendedStyle = WS_EX_CONTROLPARENT;
template->cdit = 0;
template->x = MulDiv(0, 4, baseunitX);
template->y = MulDiv(0, 8, baseunitY);
template->cx = MulDiv(requisition.width, 4, baseunitX);
template->cy = MulDiv(requisition.height, 8, baseunitY);
array = (WORD *) (template+1);
*array++ = 0; /* menu */
*array++ = 0; /* class */
*array++ = 0; /* title */
memset(&page, 0, sizeof (page));
page.dwSize = sizeof (page);
page.dwFlags = PSP_DLGINDIRECT | PSP_USETITLE | PSP_PREMATURE;
page.hInstance = GetModuleHandle (NULL);
page.pResource = template;
app_name = g_get_application_name ();
if (app_name == NULL)
app_name = "Application";
page.pszTitle = g_utf8_to_utf16 (app_name,
-1, NULL, NULL, NULL);
page.pfnDlgProc = pageDlgProc;
page.pfnCallback = NULL;
page.lParam = (LPARAM) op;
hpage = CreatePropertySheetPageW(&page);
GlobalUnlock (htemplate);
/* TODO: We're leaking htemplate here... */
return hpage;
}
GtkPrintOperationResult
_gtk_print_operation_platform_backend_run_dialog (GtkPrintOperation *op,
GtkWindow *parent,
......@@ -1281,9 +1406,14 @@ _gtk_print_operation_platform_backend_run_dialog (GtkPrintOperation *op,
GtkPrintOperationResult result;
GtkPrintOperationWin32 *op_win32;
IPrintDialogCallback *callback;
HPROPSHEETPAGE prop_page;
*do_print = FALSE;
op_win32 = g_new0 (GtkPrintOperationWin32, 1);
op->priv->platform_data = op_win32;
op->priv->free_platform_data = (GDestroyNotify) op_win32_free;
if (parent == NULL)
{
invisible = gtk_invisible_new ();
......@@ -1338,8 +1468,18 @@ _gtk_print_operation_platform_backend_run_dialog (GtkPrintOperation *op,
printdlgex->hInstance = 0;
printdlgex->lpPrintTemplateName = NULL;
printdlgex->lpCallback = NULL;
printdlgex->nPropertyPages = 0;
printdlgex->lphPropertyPages = NULL;
g_signal_emit_by_name (op, "create-custom-widget",
&op->priv->custom_widget);
if (op->priv->custom_widget) {
prop_page = create_application_page (op);
printdlgex->nPropertyPages = 1;
printdlgex->lphPropertyPages = &prop_page;
} else {
printdlgex->nPropertyPages = 0;
printdlgex->lphPropertyPages = NULL;
}
printdlgex->nStartPage = START_PAGE_GENERAL;
printdlgex->dwResultAction = 0;
......@@ -1348,7 +1488,7 @@ _gtk_print_operation_platform_backend_run_dialog (GtkPrintOperation *op,
callback = print_callback_new ();
printdlgex->lpCallback = (IUnknown *)callback;
got_gdk_events_message = RegisterWindowMessage ("GDK_WIN32_GOT_EVENTS");
hResult = PrintDlgExW(printdlgex);
IUnknown_Release ((IUnknown *)callback);
gdk_win32_set_modal_dialog_libgtk_only (NULL);
......@@ -1426,9 +1566,6 @@ _gtk_print_operation_platform_backend_run_dialog (GtkPrintOperation *op,
goto out;
}
op_win32 = g_new (GtkPrintOperationWin32, 1);
op->priv->platform_data = op_win32;
op->priv->free_platform_data = (GDestroyNotify) op_win32_free;
op_win32->hdc = printdlgex->hDC;
op_win32->devmode = printdlgex->hDevMode;
op_win32->devnames = printdlgex->hDevNames;
......
......@@ -36,6 +36,8 @@ enum {
DRAW_PAGE,
END_PRINT,
STATUS_CHANGED,
CREATE_CUSTOM_WIDGET,
CUSTOM_WIDGET_APPLY,
LAST_SIGNAL
};
......@@ -230,6 +232,29 @@ gtk_print_operation_get_property (GObject *object,
}
}
static GtkWidget *
gtk_print_operation_create_custom_widget (GtkPrintOperation *operation)
{
return NULL;
}
static gboolean
custom_widget_accumulator (GSignalInvocationHint *ihint,
GValue *return_accu,
const GValue *handler_return,
gpointer dummy)
{
gboolean continue_emission;
GtkWidget *widget;
widget = g_value_get_pointer (handler_return);
if (widget != NULL)
g_value_set_pointer (return_accu, widget);
continue_emission = (widget == NULL);
return continue_emission;
}
static void
gtk_print_operation_class_init (GtkPrintOperationClass *class)
{
......@@ -238,6 +263,8 @@ gtk_print_operation_class_init (GtkPrintOperationClass *class)
gobject_class->set_property = gtk_print_operation_set_property;
gobject_class->get_property = gtk_print_operation_get_property;
gobject_class->finalize = gtk_print_operation_finalize;
class->create_custom_widget = gtk_print_operation_create_custom_widget;
g_type_class_add_private (gobject_class, sizeof (GtkPrintOperationPrivate));
......@@ -384,12 +411,60 @@ gtk_print_operation_class_init (GtkPrintOperationClass *class)
*/
signals[STATUS_CHANGED] =
g_signal_new (I_("status-changed"),
G_TYPE_FROM_CLASS (class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkPrintOperationClass, status_changed),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
G_TYPE_FROM_CLASS (class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkPrintOperationClass, status_changed),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
/**
* GtkPrintOperation::get-custom-widget:
* @operation: the #GtkPrintOperation on which the signal was emitted
*
* Gets emitted when displaying the print dialog. If you return a
* widget in a handler for this signal it will be added to a custom
* tab in the print dialog. You typically return a container widget
* with multiple widgets in it.
*
* The print dialog owns the returned widget, and its lifetime
* isn't controlled by the app. However, the widget is guaranteed
* to stay around until the custom-widget-apply signal is emitted
* on the operation. Then you can read out any information you need
* from the widgets.
*
* Since: 2.10
*/
signals[CREATE_CUSTOM_WIDGET] =
g_signal_new (I_("create-custom-widget"),
G_TYPE_FROM_CLASS (class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkPrintOperationClass, create_custom_widget),
custom_widget_accumulator, NULL,
_gtk_marshal_POINTER__VOID,
G_TYPE_POINTER, 0);
/**
* GtkPrintOperation::custom-widget-apply:
* @operation: the #GtkPrintOperation on which the signal was emitted
* @widget: the custom widget added in create-custom-widget
*
* This signal gets emitted right before begin-print if you added
* a custom widget in the create-custom-widget handler. When you get
* this signal you should read the information from the custom widgets,
* as the widgets are not guaraneed to be around at a later time.
*
* Since: 2.10
*/
signals[CUSTOM_WIDGET_APPLY] =
g_signal_new (I_("custom-widget-apply"),
G_TYPE_FROM_CLASS (class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkPrintOperationClass, custom_widget_apply),
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, GTK_TYPE_WIDGET);
/**
* GtkPrintOperation:default-page-setup:
......
......@@ -80,6 +80,10 @@ struct _GtkPrintOperationClass
void (*end_print) (GtkPrintOperation *operation,
GtkPrintContext *context);
void (*status_changed) (GtkPrintOperation *operation);
GtkWidget *(*create_custom_widget) (GtkPrintOperation *operation);
void (*custom_widget_apply) (GtkPrintOperation *operation,
GtkWidget *widget);
/* Padding for future expansion */
void (*_gtk_reserved1) (void);
......
This diff is collapsed.
/* GTK - The GIMP Toolkit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* Modified by the GTK+ Team and others 1997-2006. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#ifndef __GTK_WIN32_EMBED_WIDGET_H__
#define __GTK_WIN32_EMBED_WIDGET_H__
#include <gdk/gdk.h>
#include <gtk/gtkwindow.h>
#include "win32/gdkwin32.h"
G_BEGIN_DECLS
#define GTK_TYPE_WIN32_EMBED_WIDGET (gtk_win32_embed_widget_get_type ())
#define GTK_WIN32_EMBED_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_WIN32_EMBED_WIDGET, GtkWin32EmbedWidget))
#define GTK_WIN32_EMBED_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_WIN32_EMBED_WIDGET, GtkWin32EmbedWidgetClass))
#define GTK_IS_WIN32_EMBED_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_WIN32_EMBED_WIDGET))
#define GTK_IS_WIN32_EMBED_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_WIN32_EMBED_WIDGET))
#define GTK_WIN32_EMBED_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_WIN32_EMBED_WIDGET, GtkWin32EmbedWidgetClass))
typedef struct _GtkWin32EmbedWidget GtkWin32EmbedWidget;
typedef struct _GtkWin32EmbedWidgetClass GtkWin32EmbedWidgetClass;
struct _GtkWin32EmbedWidget
{
GtkWindow window;
GdkWindow *parent_window;
gpointer old_window_procedure;
};
struct _GtkWin32EmbedWidgetClass
{
GtkWindowClass parent_class;
/* Padding for future expansion */
void (*_gtk_reserved1) (void);
void (*_gtk_reserved2) (void);
void (*_gtk_reserved3) (void);
void (*_gtk_reserved4) (void);
};
GType gtk_win32_embed_widget_get_type (void) G_GNUC_CONST;
GtkWidget* _gtk_win32_embed_widget_new (GdkNativeWindow parent_id);
BOOL _gtk_win32_embed_widget_dialog_procedure (GtkWin32EmbedWidget *embed_widget,
HWND wnd, UINT message, WPARAM wparam, LPARAM lparam);
G_END_DECLS
#endif /* __GTK_WIN32_EMBED_WIDGET_H__ */
......@@ -245,6 +245,8 @@ typedef struct {
char *text;
PangoLayout *layout;
GList *page_breaks;
GtkWidget *font_button;
char *font;
} PrintData;
static void
......@@ -265,7 +267,7 @@ begin_print (GtkPrintOperation *operation,
print_data->layout = gtk_print_context_create_layout (context);
desc = pango_font_description_from_string ("Sans 12");
desc = pango_font_description_from_string (print_data->font);
pango_layout_set_font_description (print_data->layout, desc);
pango_font_description_free (desc);
......@@ -391,6 +393,42 @@ status_changed_cb (GtkPrintOperation *op,
update_statusbar ();
}
static GtkWidget *
create_custom_widget (GtkPrintOperation *operation,
PrintData *data)
{
GtkWidget *vbox, *hbox, *font, *label;
vbox = gtk_vbox_new (FALSE, 0);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
hbox = gtk_hbox_new (FALSE, 8);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
label = gtk_label_new ("Font:");
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
font = gtk_font_button_new_with_font (data->font);
gtk_box_pack_start (GTK_BOX (hbox), font, FALSE, FALSE, 0);
gtk_widget_show (font);
data->font_button = font;
return vbox;
}
static void
custom_widget_apply (GtkPrintOperation *operation,
GtkWidget *widget,
PrintData *data)
{
const char *selected_font;
selected_font = gtk_font_button_get_font_name (GTK_FONT_BUTTON (data->font_button));
g_free (data->font);
data->font = g_strdup (selected_font);
}
static void
do_print (GtkAction *action)
{
......@@ -401,6 +439,7 @@ do_print (GtkAction *action)
GError *error;
print_data.text = get_text ();
print_data.font = g_strdup ("Sans 12");
print = gtk_print_operation_new ();
......@@ -414,7 +453,9 @@ do_print (GtkAction *action)
g_signal_connect (print, "begin_print", G_CALLBACK (begin_print), &print_data);
g_signal_connect (print, "draw_page", G_CALLBACK (draw_page), &print_data);
g_signal_connect (print, "create_custom_widget", G_CALLBACK (create_custom_widget), &print_data);
g_signal_connect (print, "custom_widget_apply", G_CALLBACK (custom_widget_apply), &print_data);
error = NULL;
res = gtk_print_operation_run (print, GTK_WINDOW (main_window), &error);
......@@ -447,8 +488,10 @@ do_print (GtkAction *action)
g_signal_connect (print, "status_changed",
G_CALLBACK (status_changed_cb), NULL);
}
g_object_unref (print);
g_free (print_data.text);
g_free (print_data.font);
}
static void
......@@ -671,6 +714,7 @@ create_window (void)
int
main (int argc, char **argv)
{
g_set_application_name ("Print editor");
gtk_init (&argc, &argv);
create_window ();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment