5 #define YUILogComponent "gtk"
6 #include <yui/Libyui_config.h>
10 #include <YDialogSpy.h>
11 #include <gdk/gdkkeysyms.h>
14 #include "ygtkwindow.h"
27 #define DEFAULT_CHAR_WIDTH 60
28 #define DEFAULT_CHAR_HEIGHT 28
29 #define DEFAULT_PIXEL_WIDTH 330
30 #define DEFAULT_PIXEL_HEIGHT 200
42 GdkCursor *m_busyCursor;
46 YGWindowCloseFn m_canClose;
51 m_widget = ygtk_window_new();
52 gtk_container_set_resize_mode (GTK_CONTAINER (m_widget), GTK_RESIZE_PARENT);
53 g_object_ref_sink (G_OBJECT (m_widget));
54 gtk_window_set_has_resize_grip (GTK_WINDOW (m_widget), TRUE);
63 std::stack<YDialog *> &stack = YDialog::_dialogStack;
64 YDialog *ylast = stack.size() ? stack.top() : 0;
65 if (ylast == ydialog) {
66 if (stack.size() > 1) {
76 GtkWindow *parent = NULL;
79 parent = GTK_WINDOW (yglast->m_window->getWidget());
81 GtkWindow *window = GTK_WINDOW (m_widget);
85 gtk_window_set_title (window,
"");
86 gtk_window_set_modal (window, TRUE);
87 gtk_window_set_transient_for (window, parent);
88 gtk_window_set_type_hint (window, GDK_WINDOW_TYPE_HINT_DIALOG);
89 AtkObject *peer = gtk_widget_get_accessible (GTK_WIDGET (window));
91 atk_object_set_role (peer, ATK_ROLE_DIALOG);
94 #ifdef LIBYUI_VERSION_NUM
95 #if LIBYUI_VERSION_AT_LEAST(2,42,3)
96 gtk_window_set_title (window, YUI::app()->applicationTitle().c_str());
97 GdkPixbuf *pixbuf = YGUtils::loadPixbuf (YUI::app()->applicationIcon());
99 gtk_window_set_default_icon (pixbuf);
100 g_object_unref (G_OBJECT (pixbuf));
104 gtk_window_set_title (window,
"YaST");
108 gtk_window_set_title (window,
"YaST");
110 if (YGUI::ui()->unsetBorder())
111 gtk_window_set_decorated (window, FALSE);
118 int width = YGUtils::getCharsWidth (m_widget, DEFAULT_CHAR_WIDTH);
119 width += DEFAULT_PIXEL_WIDTH;
120 int height = YGUtils::getCharsHeight (m_widget, DEFAULT_CHAR_HEIGHT);
121 height += DEFAULT_PIXEL_HEIGHT;
123 if (YGUI::ui()->isSwsingle())
124 height += YGUtils::getCharsHeight (m_widget, 10);
126 width = MIN (width, YUI::app()->displayWidth());
127 height = MIN (height, YUI::app()->displayHeight());
129 gtk_window_set_default_size (window, width, height);
130 gtk_window_resize(window, width, height);
132 if (YGUI::ui()->setFullscreen())
133 gtk_window_fullscreen (window);
134 else if (YUI::app()->displayWidth() <= 800 || YUI::app()->displayHeight() <= 600)
136 gtk_window_maximize (window);
139 gtk_window_set_role (window,
"yast2");
145 g_signal_connect (G_OBJECT (m_widget),
"delete-event",
146 G_CALLBACK (close_window_cb),
this);
147 g_signal_connect_after (G_OBJECT (m_widget),
"key-press-event",
148 G_CALLBACK (key_pressed_cb),
this);
149 g_signal_connect (G_OBJECT (m_widget),
"focus-in-event",
150 G_CALLBACK (focus_in_event_cb),
this);
152 g_signal_connect_after (G_OBJECT (m_widget),
"realize",
153 G_CALLBACK (realize_cb),
this);
160 g_object_unref (G_OBJECT (m_busyCursor));
161 gtk_widget_destroy (m_widget);
162 g_object_unref (G_OBJECT (m_widget));
166 { gtk_widget_show (m_widget); }
171 gdk_window_set_cursor (gtk_widget_get_window(m_widget), NULL);
178 GdkDisplay *display = gtk_widget_get_display (m_widget);
179 m_busyCursor = gdk_cursor_new_for_display (display, GDK_WATCH);
180 g_object_ref (G_OBJECT (m_busyCursor));
183 gdk_window_set_cursor (gtk_widget_get_window(m_widget), m_busyCursor);
187 void setChild (YWidget *new_child)
189 GtkWidget *child = gtk_bin_get_child (GTK_BIN (m_widget));
191 gtk_container_remove (GTK_CONTAINER (m_widget), child);
193 child = YGWidget::get (new_child)->getLayout();
194 gtk_container_add (GTK_CONTAINER (m_widget), child);
201 window->m_refcount++;
204 static void unref (
YGWindow *window)
206 if (--window->m_refcount == 0) {
207 bool is_main_window = (window == main_window);
215 GtkWidget *getWidget() {
return m_widget; }
216 YWidget *getChild() {
return m_child; }
221 if (!m_canClose || m_canClose (m_canCloseData))
222 YGUI::ui()->sendEvent (
new YCancelEvent());
225 static gboolean close_window_cb (GtkWidget *widget, GdkEvent *event,
234 static gboolean key_pressed_cb (GtkWidget *widget, GdkEventKey *event,
238 if (event->keyval == GDK_KEY_Escape &&
239 main_window != pThis) {
245 if (event->state & GDK_SHIFT_MASK) {
246 switch (event->keyval) {
248 YGUI::ui()->askSaveLogs();
254 if ((event->state & GDK_CONTROL_MASK) && (event->state & GDK_SHIFT_MASK)
255 && (event->state & GDK_MOD1_MASK)) {
256 yuiMilestone() <<
"Caught YaST2 magic key combination\n";
258 switch (event->keyval) {
260 YGUI::ui()->makeScreenShot();
263 YGUI::ui()->toggleRecordMacro();
266 YGUI::ui()->askPlayMacro();
269 YGUI::ui()->sendEvent (
new YDebugEvent());
272 yuiMilestone() <<
"Starting xterm\n";
273 ret = system (
"/usr/bin/xterm &");
275 yuiError() <<
"Can't launch xterm (error code" << ret <<
")" << std::endl;
278 yuiMilestone() <<
"Opening dialog spy" << std::endl;
279 YDialogSpy::showDialogSpy();
280 YGUI::ui()->normalCursor();
289 static gboolean focus_in_event_cb (GtkWidget *widget, GdkEventFocus *event)
290 { gtk_window_set_urgency_hint (GTK_WINDOW (widget), FALSE);
return FALSE; }
292 static void realize_cb (GtkWidget *widget,
YGWindow *pThis)
293 { pThis->busyCursor(); }
296 YGDialog::YGDialog (YDialogType dialogType, YDialogColorMode colorMode)
297 : YDialog (dialogType, colorMode),
298 YGWidget (this, NULL, GTK_TYPE_HBOX, NULL)
301 m_stickyTitle =
false;
302 m_containee = gtk_event_box_new();
303 if (dialogType == YMainDialog && main_window)
304 m_window = main_window;
306 m_window =
new YGWindow (dialogType == YMainDialog,
this);
307 YGWindow::ref (m_window);
309 if (colorMode != YDialogNormalColor) {
311 GtkWidget *icon = gtk_image_new_from_stock
312 (colorMode == YDialogWarnColor ? GTK_STOCK_DIALOG_WARNING : GTK_STOCK_DIALOG_INFO,
313 GTK_ICON_SIZE_DIALOG);
314 gtk_misc_set_alignment (GTK_MISC (icon), 0.5, 0);
315 gtk_misc_set_padding (GTK_MISC (icon), 0, 12);
317 gtk_box_pack_start (GTK_BOX (getWidget()), icon, FALSE, FALSE, 12);
318 gtk_box_pack_start (GTK_BOX (getWidget()), m_containee, TRUE, TRUE, 0);
321 gtk_box_pack_start (GTK_BOX (getWidget()), m_containee, TRUE, TRUE, 0);
322 gtk_widget_show_all (getWidget());
328 m_window->setChild (
this);
331 YGDialog::~YGDialog()
333 YGWindow::unref (m_window);
336 void YGDialog::openInternal()
341 void YGDialog::activate()
343 m_window->setChild (
this);
346 void YGDialog::present()
348 GtkWindow *window = GTK_WINDOW (m_window->getWidget());
349 if (!gtk_window_is_active (window))
350 gtk_window_set_urgency_hint (window, TRUE);
355 YDialog *ydialog = YDialog::currentDialog (
false);
357 return static_cast <
YGDialog *> (ydialog);
361 GtkWindow *YGDialog::currentWindow()
363 YGDialog *ydialog = YGDialog::currentDialog();
365 return GTK_WINDOW (ydialog->m_window->getWidget());
369 void YGDialog::setCloseCallback (YGWindowCloseFn canClose,
void *canCloseData)
371 m_window->m_canClose = canClose;
372 m_window->m_canCloseData = canCloseData;
375 void YGDialog::unsetCloseCallback()
377 m_window->m_canClose = NULL;
380 void YGDialog::normalCursor()
382 m_window->normalCursor();
385 void YGDialog::busyCursor()
387 m_window->busyCursor();
392 void YGDialog::doSetSize (
int width,
int height)
397 GtkWidget *window = m_window->getWidget();
398 if (gtk_widget_get_realized (window)) {
399 gtk_widget_queue_resize (window);
400 width = MIN (width, YUI::app()->displayWidth());
401 height = MIN (height, YUI::app()->displayHeight());
402 if (isMainDialog()) {
403 GtkAllocation allocation;
404 gtk_widget_get_allocation(window, &allocation);
405 if (allocation.width < width || allocation.height < height) {
407 width = MAX (width, allocation.width),
408 height = MAX (height, allocation.height);
415 gtk_window_resize (GTK_WINDOW (window), width, height);
417 gtk_window_set_default_size (GTK_WINDOW (window), width, height);
420 void YGDialog::highlight (YWidget *ywidget)
423 static gboolean draw_highlight_cb (GtkWidget *widget, cairo_t *cr)
425 int w = gtk_widget_get_allocated_width(widget);
426 int h = gtk_widget_get_allocated_height(widget);
428 cairo_rectangle (cr, 0, 0, w, h);
429 cairo_set_source_rgb (cr, 0xff/255.0, 0x88/255.0, 0);
434 static bool hasWindow (GtkWidget *widget)
436 if (gtk_widget_get_has_window(widget))
439 for (GList *children = gdk_window_peek_children (gtk_widget_get_window(widget));
440 children; children = children->next) {
441 GdkWindow *child = (GdkWindow *) children->data;
443 gdk_window_get_user_data (child, &data);
444 if ((GtkWidget *) data == widget)
451 static YWidget *previousWidget = NULL;
452 if (previousWidget && previousWidget->isValid()) {
453 YGWidget *prev = YGWidget::get (previousWidget);
455 GtkWidget *widget = prev->getWidget();
456 if (inner::hasWindow (widget)) {
457 gtk_widget_override_background_color (widget, GTK_STATE_FLAG_NORMAL, NULL);
458 gtk_widget_override_color (widget, GTK_STATE_FLAG_NORMAL, NULL);
461 g_signal_handlers_disconnect_by_func (widget,
462 (gpointer) inner::draw_highlight_cb, NULL);
463 gtk_widget_queue_draw (widget);
468 YGWidget *ygwidget = YGWidget::get (ywidget);
470 GtkWidget *widget = ygwidget->getWidget();
471 if (inner::hasWindow (widget)) {
472 GdkRGBA bg_color = { 0, 0xffff, 0xaaaa, 0 };
473 GdkRGBA base_color = { 0, 0xffff, 0xeeee, 0 };
474 gtk_widget_override_background_color (widget, GTK_STATE_FLAG_NORMAL, &bg_color);
475 gtk_widget_override_color (widget, GTK_STATE_FLAG_NORMAL, &base_color);
478 g_signal_connect (G_OBJECT (widget),
"draw",
479 G_CALLBACK (inner::draw_highlight_cb), NULL);
480 gtk_widget_queue_draw (widget);
484 previousWidget = ywidget;
487 void YGDialog::setTitle (
const std::string &title,
bool sticky)
491 if (!m_stickyTitle || sticky) {
492 GtkWindow *window = GTK_WINDOW (m_window->getWidget());
493 gchar *str = g_strdup_printf (
"%s - YaST", title.c_str());
494 gtk_window_set_title (window, str);
496 m_stickyTitle = sticky;
502 void ygdialog_setTitle (
const gchar *title, gboolean sticky);
505 void ygdialog_setTitle (
const gchar *title, gboolean sticky)
507 YGDialog::currentDialog()->setTitle (title, sticky);
510 void YGDialog::setIcon (
const std::string &icon)
512 GtkWindow *window = GTK_WINDOW (m_window->getWidget());
513 GdkPixbuf *pixbuf = YGUtils::loadPixbuf (icon);
515 gtk_window_set_icon (window, pixbuf);
516 g_object_unref (G_OBJECT (pixbuf));
520 typedef bool (*FindWidgetsCb) (YWidget *widget,
void *data) ;
522 static void findWidgets (
523 std::list <YWidget *> *widgets, YWidget *widget, FindWidgetsCb find_cb,
void *cb_data)
525 if (find_cb (widget, cb_data))
526 widgets->push_back (widget);
527 for (YWidgetListConstIterator it = widget->childrenBegin();
528 it != widget->childrenEnd(); it++)
529 findWidgets (widgets, *it, find_cb, cb_data);
532 static bool IsFunctionWidget (YWidget *widget,
void *data)
533 {
return widget->functionKey() == GPOINTER_TO_INT (data); }
535 YWidget *YGDialog::getFunctionWidget (
int key)
537 std::list <YWidget *> widgets;
538 findWidgets (&widgets,
this, IsFunctionWidget, GINT_TO_POINTER (key));
539 return widgets.empty() ? NULL : widgets.front();
542 static bool IsClassWidget (YWidget *widget,
void *data)
543 {
return !strcmp (widget->widgetClass(), (
char *) data); }
545 std::list <YWidget *> YGDialog::getClassWidgets (
const char *className)
547 std::list <YWidget *> widgets;
548 findWidgets (&widgets,
this, IsClassWidget, (
void *) className);
552 YDialog *YGWidgetFactory::createDialog (YDialogType dialogType, YDialogColorMode colorMode)
553 {
return new YGDialog (dialogType, colorMode); }
555 YEvent *YGDialog::waitForEventInternal (
int timeout_millisec)
556 {
return YGUI::ui()->waitInput (timeout_millisec,
true); }
558 YEvent *YGDialog::pollEventInternal()
559 {
return YGUI::ui()->waitInput (0,
false); }