libyui-gtk  2.49.0
YGDumbTab.cc
1 /********************************************************************
2  * YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
3  ********************************************************************/
4 
5 #define YUILogComponent "gtk"
6 #include <yui/Libyui_config.h>
7 #include "YGUI.h"
8 #include "YGWidget.h"
9 #include "YGUtils.h"
10 #include "YDumbTab.h"
11 #include <gtk/gtk.h>
12 #include "ygtkratiobox.h"
13 #include "YGMacros.h"
14 
15 class YGDumbTab : public YDumbTab, public YGWidget
16 {
17  GtkWidget *m_containee;
18  GtkWidget *m_last_tab;
19 
20 public:
21  YGDumbTab (YWidget *parent)
22  : YDumbTab (NULL),
23  YGWidget (this, parent, GTK_TYPE_NOTEBOOK, NULL)
24  {
25  m_containee = gtk_event_box_new();
26  g_object_ref_sink (G_OBJECT (m_containee));
27  gtk_widget_show (m_containee);
28 
29  m_last_tab = 0;
30  // GTK+ keeps the notebook size set to the biggset page. We can't
31  // do this since pages are set dynamically, but at least don't let
32  // the notebook reduce its size.
33  ygtk_adj_size_set_only_expand (YGTK_ADJ_SIZE (m_adj_size), TRUE);
34 
35  connect (getWidget(), "switch-page", G_CALLBACK (switch_page_cb), this);
36  }
37 
38  virtual ~YGDumbTab()
39  {
40  gtk_widget_destroy (m_containee);
41  g_object_unref (G_OBJECT (m_containee));
42  }
43 
44  virtual GtkWidget *getContainer()
45  { return m_containee; }
46 
47  virtual void addItem (YItem *item)
48  {
49  BlockEvents block (this);
50  YDumbTab::addItem (item);
51  GtkWidget *tab_label, *image = 0, *label;
52  label = gtk_label_new (YGUtils::mapKBAccel (item->label()).c_str());
53  gtk_label_set_use_underline (GTK_LABEL (label), TRUE);
54  if (item->hasIconName()) {
55  std::string path = iconFullPath (item->iconName());
56  GdkPixbuf *pixbuf = YGUtils::loadPixbuf (path);
57  if (pixbuf) {
58  image = gtk_image_new_from_pixbuf (pixbuf);
59  g_object_unref (G_OBJECT (pixbuf));
60  }
61  }
62  if (image) {
63  tab_label = YGTK_HBOX_NEW(6);
64  gtk_box_set_homogeneous (GTK_BOX (tab_label), FALSE);
65  gtk_box_pack_start (GTK_BOX (tab_label), image, FALSE, TRUE, 0);
66  gtk_box_pack_start (GTK_BOX (tab_label), label, TRUE, TRUE, 0);
67  }
68  else
69  tab_label = label;
70  gchar *label_id = g_strdup_printf ("label-%d", item->index());
71  g_object_set_data (G_OBJECT (getWidget()), label_id, label);
72  g_free (label_id);
73  gtk_widget_show_all (tab_label);
74 
75  GtkNotebook *notebook = GTK_NOTEBOOK (getWidget());
76 
77  GtkWidget *page = gtk_event_box_new();
78  gtk_widget_show (page);
79  item->setData ((void *) page);
80  g_object_set_data (G_OBJECT (page), "yitem", item);
81 
82  gtk_notebook_append_page (notebook, page, tab_label);
83  selectItem (item, item->selected() || !m_last_tab /*first tab*/);
84  }
85 
86  virtual void deleteAllItems()
87  {
88  GList *children = gtk_container_get_children (GTK_CONTAINER (getWidget()));
89  for (GList *i = children; i; i = i->next)
90  gtk_container_remove (GTK_CONTAINER (getWidget()), (GtkWidget *) i->data);
91  g_list_free (children);
92  YDumbTab::deleteAllItems();
93  }
94 
95  // to re-use the same widget in all tabs (m_fixed), we will remove and
96  // add to the tabs' child as tabs are changed
97  void syncTabPage()
98  {
99  if (m_last_tab)
100  gtk_container_remove (GTK_CONTAINER (m_last_tab), m_containee);
101 
102  GtkNotebook *notebook = GTK_NOTEBOOK (getWidget());
103  int nb = gtk_notebook_get_current_page (notebook);
104  m_last_tab = gtk_notebook_get_nth_page (notebook, nb);
105  gtk_container_add (GTK_CONTAINER (m_last_tab), m_containee);
106  }
107 
108  virtual YItem *selectedItem()
109  {
110  GtkNotebook *notebook = GTK_NOTEBOOK (getWidget());
111  int nb = gtk_notebook_get_current_page (notebook);
112  if (nb < 0) return NULL;
113  GtkWidget *child = gtk_notebook_get_nth_page (notebook, nb);
114  return (YItem *) g_object_get_data (G_OBJECT (child), "yitem");
115  }
116 
117  virtual void selectItem (YItem *item, bool selected)
118  {
119  if (selected) {
120  BlockEvents block (this);
121  GtkWidget *child = (GtkWidget *) item->data();
122  int page = gtk_notebook_page_num (GTK_NOTEBOOK (getWidget()), child);
123 
124  gtk_notebook_set_current_page (GTK_NOTEBOOK (getWidget()), page);
125  syncTabPage();
126  }
127  YDumbTab::selectItem (item, selected);
128  }
129 
130  virtual void shortcutChanged()
131  {
132  for (YItemConstIterator it = itemsBegin(); it != itemsEnd(); it++) {
133  YItem *item = *it;
134  gchar *label_id = g_strdup_printf ("label-%d", item->index());
135  GtkWidget *label;
136  label = (GtkWidget *) g_object_get_data (G_OBJECT (getWidget()), label_id);
137  g_free (label_id);
138 
139  std::string text = YGUtils::mapKBAccel (item->label());
140  gtk_label_set_text (GTK_LABEL (label), text.c_str());
141  gtk_label_set_use_underline (GTK_LABEL (label), TRUE);
142  }
143  }
144 
145  // callbacks
146  static void switch_page_cb (GtkNotebook *notebook, GtkWidget *page,
147  guint tab_nb, YGDumbTab *pThis)
148  {
149  GtkWidget *child = gtk_notebook_get_nth_page (notebook, tab_nb);
150  YItem *item = (YItem *) g_object_get_data (G_OBJECT (child), "yitem");
151 
152  pThis->YDumbTab::selectItem (item);
153  YGUI::ui()->sendEvent (new YMenuEvent (item));
154  pThis->syncTabPage();
155  }
156 
157  // NOTE copy of Qt one
158  void activate()
159  {
160  // send an activation event for this widget
161  if ( notify() )
162  YGUI::ui()->sendEvent( new YWidgetEvent( this,YEvent::Activated ) );
163  }
164 
165 
166  YGWIDGET_IMPL_CONTAINER (YDumbTab)
167 };
168 
169 YDumbTab *YGOptionalWidgetFactory::createDumbTab (YWidget *parent)
170 { return new YGDumbTab (parent); }
171