5 #define YUILogComponent "gtk" 6 #include <yui/Libyui_config.h> 10 #include <YDialogSpy.h> 11 #include <YPushButton.h> 12 #include <gdk/gdkkeysyms.h> 15 #include "ygtkwindow.h" 30 #define DEFAULT_CHAR_WIDTH 60 31 #define DEFAULT_CHAR_HEIGHT 28 32 #define DEFAULT_PIXEL_WIDTH 330 33 #define DEFAULT_PIXEL_HEIGHT 200 45 GdkCursor *m_busyCursor;
49 YGWindowCloseFn m_canClose;
54 m_widget = ygtk_window_new();
56 g_object_ref_sink (G_OBJECT (m_widget));
66 std::stack<YDialog *> &stack = YDialog::_dialogStack;
67 YDialog *ylast = stack.size() ? stack.top() : 0;
68 if (ylast == ydialog) {
69 if (stack.size() > 1) {
79 GtkWindow *parent = NULL;
82 parent = GTK_WINDOW (yglast->m_window->getWidget());
84 GtkWindow *window = GTK_WINDOW (m_widget);
86 std::string dialogTitle =
"YaSt";
88 #ifdef LIBYUI_VERSION_NUM 89 #if LIBYUI_VERSION_AT_LEAST(2,42,3) 90 dialogTitle = YUI::app()->applicationTitle();
95 gtk_window_set_title (window, dialogTitle.c_str());
96 gtk_window_set_modal (window, TRUE);
97 gtk_window_set_transient_for (window, parent);
98 gtk_window_set_type_hint (window, GDK_WINDOW_TYPE_HINT_DIALOG);
99 AtkObject *peer = gtk_widget_get_accessible (GTK_WIDGET (window));
101 atk_object_set_role (peer, ATK_ROLE_DIALOG);
104 gtk_window_set_title (window, dialogTitle.c_str());
105 #ifdef LIBYUI_VERSION_NUM 106 #if LIBYUI_VERSION_AT_LEAST(2,42,3) 107 GdkPixbuf *pixbuf = YGUtils::loadPixbuf (YUI::app()->applicationIcon());
109 gtk_window_set_default_icon (pixbuf);
110 g_object_unref (G_OBJECT (pixbuf));
114 if (YGUI::ui()->unsetBorder())
115 gtk_window_set_decorated (window, FALSE);
122 int width = YGUtils::getCharsWidth (m_widget, DEFAULT_CHAR_WIDTH);
123 width += DEFAULT_PIXEL_WIDTH;
124 int height = YGUtils::getCharsHeight (m_widget, DEFAULT_CHAR_HEIGHT);
125 height += DEFAULT_PIXEL_HEIGHT;
127 if (YGUI::ui()->isSwsingle())
128 height += YGUtils::getCharsHeight (m_widget, 10);
130 width = MIN (width, YUI::app()->displayWidth());
131 height = MIN (height, YUI::app()->displayHeight());
133 gtk_window_set_default_size (window, width, height);
134 gtk_window_resize(window, width, height);
136 if (YGUI::ui()->setFullscreen())
137 gtk_window_fullscreen (window);
138 else if (YUI::app()->displayWidth() <= 800 || YUI::app()->displayHeight() <= 600)
140 gtk_window_maximize (window);
143 gtk_window_set_role (window,
"yast2");
149 g_signal_connect (G_OBJECT (m_widget),
"delete-event",
150 G_CALLBACK (close_window_cb),
this);
151 g_signal_connect_after (G_OBJECT (m_widget),
"key-press-event",
152 G_CALLBACK (key_pressed_cb),
this);
153 g_signal_connect (G_OBJECT (m_widget),
"focus-in-event",
154 G_CALLBACK (focus_in_event_cb),
this);
156 g_signal_connect_after (G_OBJECT (m_widget),
"realize",
157 G_CALLBACK (realize_cb),
this);
164 g_object_unref (G_OBJECT (m_busyCursor));
165 gtk_widget_destroy (m_widget);
166 g_object_unref (G_OBJECT (m_widget));
170 { gtk_widget_show (m_widget); }
175 gdk_window_set_cursor (gtk_widget_get_window(m_widget), NULL);
182 GdkDisplay *display = gtk_widget_get_display (m_widget);
183 m_busyCursor = gdk_cursor_new_for_display (display, GDK_WATCH);
184 g_object_ref (G_OBJECT (m_busyCursor));
187 GdkDisplay *display = gtk_widget_get_display (m_widget);
188 gdk_window_set_cursor (gtk_widget_get_window(m_widget), m_busyCursor);
189 gdk_display_sync(display);
194 void setChild (YWidget *new_child)
196 GtkWidget *child = gtk_bin_get_child (GTK_BIN (m_widget));
198 gtk_container_remove (GTK_CONTAINER (m_widget), child);
200 child = YGWidget::get (new_child)->getLayout();
201 gtk_container_add (GTK_CONTAINER (m_widget), child);
208 window->m_refcount++;
211 static void unref (
YGWindow *window)
213 if (--window->m_refcount == 0) {
214 bool is_main_window = (window == main_window);
222 GtkWidget *getWidget() {
return m_widget; }
223 YWidget *getChild() {
return m_child; }
228 if (!m_canClose || m_canClose (m_canCloseData))
229 YGUI::ui()->sendEvent (
new YCancelEvent());
232 static gboolean close_window_cb (GtkWidget *widget, GdkEvent *event,
241 static gboolean key_pressed_cb (GtkWidget *widget, GdkEventKey *event,
245 if (event->keyval == GDK_KEY_Escape &&
246 main_window != pThis) {
252 if (event->state & GDK_SHIFT_MASK) {
253 switch (event->keyval) {
255 YGUI::ui()->askSaveLogs();
261 if ((event->state & GDK_CONTROL_MASK) && (event->state & GDK_SHIFT_MASK)
262 && (event->state & GDK_MOD1_MASK)) {
263 yuiMilestone() <<
"Caught YaST2 magic key combination\n";
265 switch (event->keyval) {
267 YGUI::ui()->makeScreenShot();
270 YGUI::ui()->toggleRecordMacro();
273 YGUI::ui()->askPlayMacro();
276 YGUI::ui()->sendEvent (
new YDebugEvent());
279 yuiMilestone() <<
"Starting xterm\n";
280 ret = system (
"/usr/bin/xterm &");
282 yuiError() <<
"Can't launch xterm (error code" << ret <<
")" << std::endl;
285 yuiMilestone() <<
"Opening dialog spy" << std::endl;
286 YDialogSpy::showDialogSpy();
287 YGUI::ui()->normalCursor();
296 static gboolean focus_in_event_cb (GtkWidget *widget, GdkEventFocus *event)
297 { gtk_window_set_urgency_hint (GTK_WINDOW (widget), FALSE);
return FALSE; }
299 static void realize_cb (GtkWidget *widget,
YGWindow *pThis)
300 { pThis->busyCursor(); }
303 YGDialog::YGDialog (YDialogType dialogType, YDialogColorMode colorMode)
304 : YDialog (dialogType, colorMode),
305 YGWidget (this, NULL, YGTK_HBOX_NEW(0), NULL)
308 m_stickyTitle =
false;
309 m_containee = gtk_event_box_new();
310 if (dialogType == YMainDialog && main_window)
311 m_window = main_window;
313 m_window =
new YGWindow (dialogType == YMainDialog,
this);
314 YGWindow::ref (m_window);
316 if (colorMode != YDialogNormalColor) {
318 GtkWidget *icon = gtk_image_new_from_icon_name
319 (colorMode == YDialogWarnColor ?
"dialog-warning" :
"dialog-information",
320 GTK_ICON_SIZE_DIALOG);
323 gtk_widget_set_halign (icon, GTK_ALIGN_CENTER);
324 gtk_widget_set_valign (icon, GTK_ALIGN_START);
327 gtk_widget_set_margin_start (icon, 0);
328 gtk_widget_set_margin_end (icon, 0);
329 gtk_widget_set_margin_top (icon, 12);
330 gtk_widget_set_margin_bottom (icon, 12);
332 gtk_box_pack_start (GTK_BOX (getWidget()), icon, FALSE, FALSE, 12);
333 gtk_box_pack_start (GTK_BOX (getWidget()), m_containee, TRUE, TRUE, 0);
336 gtk_box_pack_start (GTK_BOX (getWidget()), m_containee, TRUE, TRUE, 0);
337 gtk_widget_show_all (getWidget());
343 m_window->setChild (
this);
346 YGDialog::~YGDialog()
348 YGWindow::unref (m_window);
353 YDialog::setDefaultButton( 0 );
354 if ( newDefaultButton )
356 newDefaultButton->setKeyboardFocus();
357 YDialog::setDefaultButton(newDefaultButton);
361 void YGDialog::openInternal()
366 void YGDialog::activate()
368 m_window->setChild (
this);
371 void YGDialog::present()
373 GtkWindow *window = GTK_WINDOW (m_window->getWidget());
374 if (!gtk_window_is_active (window))
375 gtk_window_set_urgency_hint (window, TRUE);
380 YDialog *ydialog = YDialog::currentDialog (
false);
382 return static_cast <
YGDialog *> (ydialog);
386 GtkWindow *YGDialog::currentWindow()
388 YGDialog *ydialog = YGDialog::currentDialog();
390 return GTK_WINDOW (ydialog->m_window->getWidget());
394 void YGDialog::setCloseCallback (YGWindowCloseFn canClose,
void *canCloseData)
396 m_window->m_canClose = canClose;
397 m_window->m_canCloseData = canCloseData;
400 void YGDialog::unsetCloseCallback()
402 m_window->m_canClose = NULL;
405 void YGDialog::normalCursor()
407 m_window->normalCursor();
410 void YGDialog::busyCursor()
412 m_window->busyCursor();
417 void YGDialog::doSetSize (
int width,
int height)
422 GtkWidget *window = m_window->getWidget();
425 gtk_window_get_size(GTK_WINDOW (window), &w, &h);
427 if (w < width || h < height) {
429 width = MAX (width, w),
430 height = MAX (height, h);
433 if (gtk_widget_get_realized (window)) {
434 gtk_widget_queue_resize (window);
435 width = MIN (width, YUI::app()->displayWidth());
436 height = MIN (height, YUI::app()->displayHeight());
437 if (isMainDialog()) {
438 GtkAllocation allocation;
439 gtk_widget_get_allocation(window, &allocation);
440 if (allocation.width < width || allocation.height < height) {
442 width = MAX (width, allocation.width),
443 height = MAX (height, allocation.height);
450 gtk_window_resize (GTK_WINDOW (window), width, height);
452 gtk_window_set_default_size (GTK_WINDOW (window), width, height);
455 void YGDialog::highlight (YWidget *ywidget)
458 static gboolean draw_highlight_cb (GtkWidget *widget, cairo_t *cr)
460 int w = gtk_widget_get_allocated_width(widget);
461 int h = gtk_widget_get_allocated_height(widget);
463 cairo_rectangle (cr, 0, 0, w, h);
464 cairo_set_source_rgb (cr, 0xff/255.0, 0x88/255.0, 0);
469 static bool hasWindow (GtkWidget *widget)
471 if (gtk_widget_get_has_window(widget))
474 for (GList *children = gdk_window_peek_children (gtk_widget_get_window(widget));
475 children; children = children->next) {
476 GdkWindow *child = (GdkWindow *) children->data;
478 gdk_window_get_user_data (child, &data);
479 if ((GtkWidget *) data == widget)
486 static YWidget *previousWidget = NULL;
487 if (previousWidget && previousWidget->isValid()) {
488 YGWidget *prev = YGWidget::get (previousWidget);
490 GtkWidget *widget = prev->getWidget();
491 if (inner::hasWindow (widget)) {
492 gtk_widget_override_background_color (widget, GTK_STATE_FLAG_NORMAL, NULL);
493 gtk_widget_override_color (widget, GTK_STATE_FLAG_NORMAL, NULL);
496 g_signal_handlers_disconnect_by_func (widget,
497 (gpointer) inner::draw_highlight_cb, NULL);
498 gtk_widget_queue_draw (widget);
503 YGWidget *ygwidget = YGWidget::get (ywidget);
505 GtkWidget *widget = ygwidget->getWidget();
506 if (inner::hasWindow (widget)) {
507 GdkRGBA bg_color = { 0, 0xffff, 0xaaaa, 0 };
508 GdkRGBA base_color = { 0, 0xffff, 0xeeee, 0 };
509 gtk_widget_override_background_color (widget, GTK_STATE_FLAG_NORMAL, &bg_color);
510 gtk_widget_override_color (widget, GTK_STATE_FLAG_NORMAL, &base_color);
513 g_signal_connect (G_OBJECT (widget),
"draw",
514 G_CALLBACK (inner::draw_highlight_cb), NULL);
515 gtk_widget_queue_draw (widget);
519 previousWidget = ywidget;
522 void YGDialog::setTitle (
const std::string &title,
bool sticky)
526 if (!m_stickyTitle || sticky) {
527 GtkWindow *window = GTK_WINDOW (m_window->getWidget());
528 gchar *str = g_strdup_printf (
"%s - YaST", title.c_str());
529 gtk_window_set_title (window, str);
531 m_stickyTitle = sticky;
537 void ygdialog_setTitle (
const gchar *title, gboolean sticky);
540 void ygdialog_setTitle (
const gchar *title, gboolean sticky)
542 YGDialog::currentDialog()->setTitle (title, sticky);
545 void YGDialog::setIcon (
const std::string &icon)
547 GtkWindow *window = GTK_WINDOW (m_window->getWidget());
548 GdkPixbuf *pixbuf = YGUtils::loadPixbuf (icon);
550 gtk_window_set_icon (window, pixbuf);
551 g_object_unref (G_OBJECT (pixbuf));
555 typedef bool (*FindWidgetsCb) (YWidget *widget,
void *data) ;
557 static void findWidgets (
558 std::list <YWidget *> *widgets, YWidget *widget, FindWidgetsCb find_cb,
void *cb_data)
560 if (find_cb (widget, cb_data))
561 widgets->push_back (widget);
562 for (YWidgetListConstIterator it = widget->childrenBegin();
563 it != widget->childrenEnd(); it++)
564 findWidgets (widgets, *it, find_cb, cb_data);
567 static bool IsFunctionWidget (YWidget *widget,
void *data)
568 {
return widget->functionKey() == GPOINTER_TO_INT (data); }
570 YWidget *YGDialog::getFunctionWidget (
int key)
572 std::list <YWidget *> widgets;
573 findWidgets (&widgets,
this, IsFunctionWidget, GINT_TO_POINTER (key));
574 return widgets.empty() ? NULL : widgets.front();
577 static bool IsClassWidget (YWidget *widget,
void *data)
578 {
return !strcmp (widget->widgetClass(), (
char *) data); }
580 std::list <YWidget *> YGDialog::getClassWidgets (
const char *className)
582 std::list <YWidget *> widgets;
583 findWidgets (&widgets,
this, IsClassWidget, (
void *) className);
587 YDialog *YGWidgetFactory::createDialog (YDialogType dialogType, YDialogColorMode colorMode)
588 {
return new YGDialog (dialogType, colorMode); }
590 YEvent *YGDialog::waitForEventInternal (
int timeout_millisec)
591 {
return YGUI::ui()->waitInput (timeout_millisec,
true); }
593 YEvent *YGDialog::pollEventInternal()
594 {
return YGUI::ui()->waitInput (0,
false); }
void setDefaultButton(YPushButton *newDefaultButton)
Set the dialog's default button.