5 #define YUILogComponent "gtk"
6 #include <yui/Libyui_config.h>
10 #include <YDialogSpy.h>
11 #include <gdk/gdkkeysyms.h>
14 #include "ygtkwindow.h"
29 #define DEFAULT_CHAR_WIDTH 60
30 #define DEFAULT_CHAR_HEIGHT 28
31 #define DEFAULT_PIXEL_WIDTH 330
32 #define DEFAULT_PIXEL_HEIGHT 200
44 GdkCursor *m_busyCursor;
48 YGWindowCloseFn m_canClose;
53 m_widget = ygtk_window_new();
54 gtk_container_set_resize_mode (GTK_CONTAINER (m_widget), GTK_RESIZE_PARENT);
55 g_object_ref_sink (G_OBJECT (m_widget));
56 gtk_window_set_has_resize_grip (GTK_WINDOW (m_widget), TRUE);
65 std::stack<YDialog *> &stack = YDialog::_dialogStack;
66 YDialog *ylast = stack.size() ? stack.top() : 0;
67 if (ylast == ydialog) {
68 if (stack.size() > 1) {
78 GtkWindow *parent = NULL;
81 parent = GTK_WINDOW (yglast->m_window->getWidget());
83 GtkWindow *window = GTK_WINDOW (m_widget);
87 gtk_window_set_title (window,
"");
88 gtk_window_set_modal (window, TRUE);
89 gtk_window_set_transient_for (window, parent);
90 gtk_window_set_type_hint (window, GDK_WINDOW_TYPE_HINT_DIALOG);
91 AtkObject *peer = gtk_widget_get_accessible (GTK_WIDGET (window));
93 atk_object_set_role (peer, ATK_ROLE_DIALOG);
96 #ifdef LIBYUI_VERSION_NUM
97 #if LIBYUI_VERSION_AT_LEAST(2,42,3)
98 gtk_window_set_title (window, YUI::app()->applicationTitle().c_str());
99 GdkPixbuf *pixbuf = YGUtils::loadPixbuf (YUI::app()->applicationIcon());
101 gtk_window_set_default_icon (pixbuf);
102 g_object_unref (G_OBJECT (pixbuf));
106 gtk_window_set_title (window,
"YaST");
110 gtk_window_set_title (window,
"YaST");
112 if (YGUI::ui()->unsetBorder())
113 gtk_window_set_decorated (window, FALSE);
120 int width = YGUtils::getCharsWidth (m_widget, DEFAULT_CHAR_WIDTH);
121 width += DEFAULT_PIXEL_WIDTH;
122 int height = YGUtils::getCharsHeight (m_widget, DEFAULT_CHAR_HEIGHT);
123 height += DEFAULT_PIXEL_HEIGHT;
125 if (YGUI::ui()->isSwsingle())
126 height += YGUtils::getCharsHeight (m_widget, 10);
128 width = MIN (width, YUI::app()->displayWidth());
129 height = MIN (height, YUI::app()->displayHeight());
131 gtk_window_set_default_size (window, width, height);
132 gtk_window_resize(window, width, height);
134 if (YGUI::ui()->setFullscreen())
135 gtk_window_fullscreen (window);
136 else if (YUI::app()->displayWidth() <= 800 || YUI::app()->displayHeight() <= 600)
138 gtk_window_maximize (window);
141 gtk_window_set_role (window,
"yast2");
147 g_signal_connect (G_OBJECT (m_widget),
"delete-event",
148 G_CALLBACK (close_window_cb),
this);
149 g_signal_connect_after (G_OBJECT (m_widget),
"key-press-event",
150 G_CALLBACK (key_pressed_cb),
this);
151 g_signal_connect (G_OBJECT (m_widget),
"focus-in-event",
152 G_CALLBACK (focus_in_event_cb),
this);
154 g_signal_connect_after (G_OBJECT (m_widget),
"realize",
155 G_CALLBACK (realize_cb),
this);
162 g_object_unref (G_OBJECT (m_busyCursor));
163 gtk_widget_destroy (m_widget);
164 g_object_unref (G_OBJECT (m_widget));
168 { gtk_widget_show (m_widget); }
173 gdk_window_set_cursor (gtk_widget_get_window(m_widget), NULL);
180 GdkDisplay *display = gtk_widget_get_display (m_widget);
181 m_busyCursor = gdk_cursor_new_for_display (display, GDK_WATCH);
182 g_object_ref (G_OBJECT (m_busyCursor));
185 gdk_window_set_cursor (gtk_widget_get_window(m_widget), m_busyCursor);
189 void setChild (YWidget *new_child)
191 GtkWidget *child = gtk_bin_get_child (GTK_BIN (m_widget));
193 gtk_container_remove (GTK_CONTAINER (m_widget), child);
195 child = YGWidget::get (new_child)->getLayout();
196 gtk_container_add (GTK_CONTAINER (m_widget), child);
203 window->m_refcount++;
206 static void unref (
YGWindow *window)
208 if (--window->m_refcount == 0) {
209 bool is_main_window = (window == main_window);
217 GtkWidget *getWidget() {
return m_widget; }
218 YWidget *getChild() {
return m_child; }
223 if (!m_canClose || m_canClose (m_canCloseData))
224 YGUI::ui()->sendEvent (
new YCancelEvent());
227 static gboolean close_window_cb (GtkWidget *widget, GdkEvent *event,
236 static gboolean key_pressed_cb (GtkWidget *widget, GdkEventKey *event,
240 if (event->keyval == GDK_KEY_Escape &&
241 main_window != pThis) {
247 if (event->state & GDK_SHIFT_MASK) {
248 switch (event->keyval) {
250 YGUI::ui()->askSaveLogs();
256 if ((event->state & GDK_CONTROL_MASK) && (event->state & GDK_SHIFT_MASK)
257 && (event->state & GDK_MOD1_MASK)) {
258 yuiMilestone() <<
"Caught YaST2 magic key combination\n";
260 switch (event->keyval) {
262 YGUI::ui()->makeScreenShot();
265 YGUI::ui()->toggleRecordMacro();
268 YGUI::ui()->askPlayMacro();
271 YGUI::ui()->sendEvent (
new YDebugEvent());
274 yuiMilestone() <<
"Starting xterm\n";
275 ret = system (
"/usr/bin/xterm &");
277 yuiError() <<
"Can't launch xterm (error code" << ret <<
")" << std::endl;
280 yuiMilestone() <<
"Opening dialog spy" << std::endl;
281 YDialogSpy::showDialogSpy();
282 YGUI::ui()->normalCursor();
291 static gboolean focus_in_event_cb (GtkWidget *widget, GdkEventFocus *event)
292 { gtk_window_set_urgency_hint (GTK_WINDOW (widget), FALSE);
return FALSE; }
294 static void realize_cb (GtkWidget *widget,
YGWindow *pThis)
295 { pThis->busyCursor(); }
298 YGDialog::YGDialog (YDialogType dialogType, YDialogColorMode colorMode)
299 : YDialog (dialogType, colorMode),
300 YGWidget (this, NULL, YGTK_HBOX_NEW(0), NULL)
303 m_stickyTitle =
false;
304 m_containee = gtk_event_box_new();
305 if (dialogType == YMainDialog && main_window)
306 m_window = main_window;
308 m_window =
new YGWindow (dialogType == YMainDialog,
this);
309 YGWindow::ref (m_window);
311 if (colorMode != YDialogNormalColor) {
313 GtkWidget *icon = gtk_image_new_from_icon_name
314 (colorMode == YDialogWarnColor ?
"dialog-warning" :
"dialog-information",
315 GTK_ICON_SIZE_DIALOG);
317 gtk_misc_set_alignment (GTK_MISC (icon), 0.5, 0);
318 gtk_misc_set_padding (GTK_MISC (icon), 0, 12);
320 gtk_box_pack_start (GTK_BOX (getWidget()), icon, FALSE, FALSE, 12);
321 gtk_box_pack_start (GTK_BOX (getWidget()), m_containee, TRUE, TRUE, 0);
324 gtk_box_pack_start (GTK_BOX (getWidget()), m_containee, TRUE, TRUE, 0);
325 gtk_widget_show_all (getWidget());
331 m_window->setChild (
this);
334 YGDialog::~YGDialog()
336 YGWindow::unref (m_window);
339 void YGDialog::openInternal()
344 void YGDialog::activate()
346 m_window->setChild (
this);
349 void YGDialog::present()
351 GtkWindow *window = GTK_WINDOW (m_window->getWidget());
352 if (!gtk_window_is_active (window))
353 gtk_window_set_urgency_hint (window, TRUE);
358 YDialog *ydialog = YDialog::currentDialog (
false);
360 return static_cast <
YGDialog *> (ydialog);
364 GtkWindow *YGDialog::currentWindow()
366 YGDialog *ydialog = YGDialog::currentDialog();
368 return GTK_WINDOW (ydialog->m_window->getWidget());
372 void YGDialog::setCloseCallback (YGWindowCloseFn canClose,
void *canCloseData)
374 m_window->m_canClose = canClose;
375 m_window->m_canCloseData = canCloseData;
378 void YGDialog::unsetCloseCallback()
380 m_window->m_canClose = NULL;
383 void YGDialog::normalCursor()
385 m_window->normalCursor();
388 void YGDialog::busyCursor()
390 m_window->busyCursor();
395 void YGDialog::doSetSize (
int width,
int height)
400 GtkWidget *window = m_window->getWidget();
401 if (gtk_widget_get_realized (window)) {
402 gtk_widget_queue_resize (window);
403 width = MIN (width, YUI::app()->displayWidth());
404 height = MIN (height, YUI::app()->displayHeight());
405 if (isMainDialog()) {
406 GtkAllocation allocation;
407 gtk_widget_get_allocation(window, &allocation);
408 if (allocation.width < width || allocation.height < height) {
410 width = MAX (width, allocation.width),
411 height = MAX (height, allocation.height);
418 gtk_window_resize (GTK_WINDOW (window), width, height);
420 gtk_window_set_default_size (GTK_WINDOW (window), width, height);
423 void YGDialog::highlight (YWidget *ywidget)
426 static gboolean draw_highlight_cb (GtkWidget *widget, cairo_t *cr)
428 int w = gtk_widget_get_allocated_width(widget);
429 int h = gtk_widget_get_allocated_height(widget);
431 cairo_rectangle (cr, 0, 0, w, h);
432 cairo_set_source_rgb (cr, 0xff/255.0, 0x88/255.0, 0);
437 static bool hasWindow (GtkWidget *widget)
439 if (gtk_widget_get_has_window(widget))
442 for (GList *children = gdk_window_peek_children (gtk_widget_get_window(widget));
443 children; children = children->next) {
444 GdkWindow *child = (GdkWindow *) children->data;
446 gdk_window_get_user_data (child, &data);
447 if ((GtkWidget *) data == widget)
454 static YWidget *previousWidget = NULL;
455 if (previousWidget && previousWidget->isValid()) {
456 YGWidget *prev = YGWidget::get (previousWidget);
458 GtkWidget *widget = prev->getWidget();
459 if (inner::hasWindow (widget)) {
460 gtk_widget_override_background_color (widget, GTK_STATE_FLAG_NORMAL, NULL);
461 gtk_widget_override_color (widget, GTK_STATE_FLAG_NORMAL, NULL);
464 g_signal_handlers_disconnect_by_func (widget,
465 (gpointer) inner::draw_highlight_cb, NULL);
466 gtk_widget_queue_draw (widget);
471 YGWidget *ygwidget = YGWidget::get (ywidget);
473 GtkWidget *widget = ygwidget->getWidget();
474 if (inner::hasWindow (widget)) {
475 GdkRGBA bg_color = { 0, 0xffff, 0xaaaa, 0 };
476 GdkRGBA base_color = { 0, 0xffff, 0xeeee, 0 };
477 gtk_widget_override_background_color (widget, GTK_STATE_FLAG_NORMAL, &bg_color);
478 gtk_widget_override_color (widget, GTK_STATE_FLAG_NORMAL, &base_color);
481 g_signal_connect (G_OBJECT (widget),
"draw",
482 G_CALLBACK (inner::draw_highlight_cb), NULL);
483 gtk_widget_queue_draw (widget);
487 previousWidget = ywidget;
490 void YGDialog::setTitle (
const std::string &title,
bool sticky)
494 if (!m_stickyTitle || sticky) {
495 GtkWindow *window = GTK_WINDOW (m_window->getWidget());
496 gchar *str = g_strdup_printf (
"%s - YaST", title.c_str());
497 gtk_window_set_title (window, str);
499 m_stickyTitle = sticky;
505 void ygdialog_setTitle (
const gchar *title, gboolean sticky);
508 void ygdialog_setTitle (
const gchar *title, gboolean sticky)
510 YGDialog::currentDialog()->setTitle (title, sticky);
513 void YGDialog::setIcon (
const std::string &icon)
515 GtkWindow *window = GTK_WINDOW (m_window->getWidget());
516 GdkPixbuf *pixbuf = YGUtils::loadPixbuf (icon);
518 gtk_window_set_icon (window, pixbuf);
519 g_object_unref (G_OBJECT (pixbuf));
523 typedef bool (*FindWidgetsCb) (YWidget *widget,
void *data) ;
525 static void findWidgets (
526 std::list <YWidget *> *widgets, YWidget *widget, FindWidgetsCb find_cb,
void *cb_data)
528 if (find_cb (widget, cb_data))
529 widgets->push_back (widget);
530 for (YWidgetListConstIterator it = widget->childrenBegin();
531 it != widget->childrenEnd(); it++)
532 findWidgets (widgets, *it, find_cb, cb_data);
535 static bool IsFunctionWidget (YWidget *widget,
void *data)
536 {
return widget->functionKey() == GPOINTER_TO_INT (data); }
538 YWidget *YGDialog::getFunctionWidget (
int key)
540 std::list <YWidget *> widgets;
541 findWidgets (&widgets,
this, IsFunctionWidget, GINT_TO_POINTER (key));
542 return widgets.empty() ? NULL : widgets.front();
545 static bool IsClassWidget (YWidget *widget,
void *data)
546 {
return !strcmp (widget->widgetClass(), (
char *) data); }
548 std::list <YWidget *> YGDialog::getClassWidgets (
const char *className)
550 std::list <YWidget *> widgets;
551 findWidgets (&widgets,
this, IsClassWidget, (
void *) className);
555 YDialog *YGWidgetFactory::createDialog (YDialogType dialogType, YDialogColorMode colorMode)
556 {
return new YGDialog (dialogType, colorMode); }
558 YEvent *YGDialog::waitForEventInternal (
int timeout_millisec)
559 {
return YGUI::ui()->waitInput (timeout_millisec,
true); }
561 YEvent *YGDialog::pollEventInternal()
562 {
return YGUI::ui()->waitInput (0,
false); }