libyui-gtk  2.44.5
 All Classes Functions
YGWizard.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 "ygtkwizard.h"
11 #include "YWizard.h"
12 #include "YPushButton.h"
13 #include "YAlignment.h"
14 #include "YReplacePoint.h"
15 #include "YGDialog.h"
16 
17 class YGWizard : public YWizard, public YGWidget
18 {
19  YReplacePoint *m_replacePoint;
20 
21  /* YCP requires us to allow people to use YPushButton API on the wizard buttons.
22  Wizard already has handlers for them; this seems like bad design.
23 
24  We could support wrapping right in our framework. One way, would be to subclass
25  YWidgetOpt to have a wrapping field where we would set a GtkWidget*. Then,
26  classes should pass opt to YGWidget and it would create a shallow instance
27  around it. However, this isn't really doable. The problem is that, like
28  in this case, the API isn't really exact; events must be sent as YWizard events.
29  */
30  struct YGWButton : public YPushButton {
31  /* Thin class; just changes the associated button label and keeps track
32  of id change. */
33  YGWButton (YGWizard *parent, GtkWidget *widget, const std::string &label)
34  : YPushButton (parent, label), m_widget (widget), m_wizard (parent)
35  {
36  setWidgetRep (NULL);
37  setLabel (label);
38  ygtk_wizard_set_button_ptr_id (getWizard(), widget, this);
39  }
40 
41  virtual void setLabel (const std::string &label)
42  {
43  YPushButton::setLabel (label);
44 
45  // notice: we can't use functionKey() to deduce the icon because yast
46  // tools code differ from the text-mode to the GUIs when setting buttons
47  // up, and the opt_f10 and so on will not be set in the GUI code
48  YGtkWizard *wizard = getWizard();
49  std::string _label = YGUtils::mapKBAccel (label);
50  ygtk_wizard_set_button_label (wizard, getWidget(), _label.c_str(), NULL);
51  }
52 
53  virtual void setEnabled (bool enable)
54  {
55  YWidget::setEnabled (enable);
56  ygtk_wizard_enable_button (getWizard(), getWidget(), enable);
57  }
58 
59  virtual bool setKeyboardFocus()
60  {
61  gtk_widget_grab_focus (getWidget());
62  return gtk_widget_is_focus (getWidget());
63  }
64 
65  virtual int preferredWidth() { return 0; }
66  virtual int preferredHeight() { return 0; }
67  virtual void setSize (int w, int h) {}
68 
69  inline GtkWidget *getWidget() { return m_widget; }
70  inline YGtkWizard *getWizard() { return YGTK_WIZARD (m_wizard->getWidget()); }
71 
72  private:
73  GtkWidget *m_widget;
74  YGWizard *m_wizard;
75  };
76 
77  YGWButton *m_back_button, *m_abort_button, *m_next_button, *m_notes_button;
78  // release notes button would be a little more hassle to support; yast-qt
79  // doesn't support it too anyway.
80 
81 public:
82  YGWizard (YWidget *parent, const std::string &backButtonLabel,
83  const std::string &abortButtonLabel, const std::string &nextButtonLabel,
84  YWizardMode wizardMode)
85  : YWizard (NULL, backButtonLabel, abortButtonLabel, nextButtonLabel, wizardMode)
86  , YGWidget (this, parent, YGTK_TYPE_WIZARD, NULL)
87  {
88  setBorder (0);
89  YGtkWizard *wizard = getWizard();
90 
91  //** Application area
92  {
93  YAlignment *align = YUI::widgetFactory()->createAlignment (this,
94  YAlignCenter, YAlignCenter);
95  align->setStretchable (YD_HORIZ, true);
96  align->setStretchable (YD_VERT, true);
97 
98  m_replacePoint = YUI::widgetFactory()->createReplacePoint ((YWidget *) align);
99  YUI::widgetFactory()->createEmpty ((YWidget *) m_replacePoint);
100  m_replacePoint->showChild();
101  }
102 
103  //** Steps/tree pane
104  bool steps_enabled = wizardMode == YWizardMode_Steps;
105  bool tree_enabled = wizardMode == YWizardMode_Tree;
106  if (steps_enabled && tree_enabled) {
107  yuiError() << "YGWizard doesn't support both steps and tree enabled at the "
108  "same time.\nDisabling the steps...\n";
109  steps_enabled = false;
110  }
111  if (steps_enabled)
112  ygtk_wizard_enable_steps (wizard);
113  if (tree_enabled)
114  ygtk_wizard_enable_tree (wizard);
115 
116  //** Setting the bottom buttons
117  m_back_button = new YGWButton (this, wizard->back_button, backButtonLabel);
118  m_abort_button = new YGWButton (this, wizard->abort_button, abortButtonLabel);
119  m_next_button = new YGWButton (this, wizard->next_button, nextButtonLabel);
120  m_notes_button = new YGWButton (this, wizard->release_notes_button, std::string());
121  ygtk_wizard_set_default_button (wizard, wizard->next_button);
122 
123  //** All event are sent through this signal together with an id
124  g_signal_connect (G_OBJECT (getWidget()), "action-triggered",
125  G_CALLBACK (action_triggered_cb), this);
126  }
127 
128  virtual ~YGWizard()
129  {
130  // m_back/abort/next_button are added as children and
131  // so will be freed by ~YContainerWidget
132  }
133 
134  inline YGtkWizard *getWizard()
135  { return YGTK_WIZARD (getWidget()); }
136 
137  virtual YReplacePoint *contentsReplacePoint() const
138  { return m_replacePoint; }
139 
140  virtual YPushButton *backButton() const
141  { return m_back_button; }
142  virtual YPushButton *abortButton() const
143  { return m_abort_button; }
144  virtual YPushButton *nextButton() const
145  { return m_next_button; }
146 
147  virtual void setButtonLabel (YPushButton *button, const std::string &label)
148  {
149  button->setLabel (label);
150  }
151 
152  virtual void setHelpText (const std::string &_text)
153  {
154  std::string productName = YUI::app()->productName();
155  std::string text(_text);
156  YGUtils::replace (text, "&product;", 9, productName.c_str());
157  ygtk_wizard_set_help_text (getWizard(), text.c_str());
158  }
159 
160  virtual void setDialogIcon (const std::string &icon)
161  {
162  if (!ygtk_wizard_set_header_icon (getWizard(), icon.c_str()))
163  yuiWarning() << "YGWizard: could not load image: " << icon << std::endl;
164  YGDialog::currentDialog()->setIcon (icon);
165  }
166 
167  virtual void setDialogHeading (const std::string &heading)
168  {
169  ygtk_wizard_set_header_text (getWizard(), heading.c_str());
170  YGDialog::currentDialog()->setTitle (heading, false);
171  }
172 
173  virtual void setDialogTitle (const std::string &title)
174  {
175  YGDialog::currentDialog()->setTitle (title, true);
176  }
177 
178  virtual void addStepHeading (const std::string &text)
179  {
180  ygtk_wizard_add_step_header (getWizard(), text.c_str());
181  }
182 
183  virtual void addStep (const std::string &text, const std::string &id)
184  {
185  ygtk_wizard_add_step (getWizard(), text.c_str(), id.c_str());
186  }
187 
188  virtual void setCurrentStep (const std::string &id)
189  {
190  if (!ygtk_wizard_set_current_step (getWizard(), id.c_str()))
191  yuiError() << "YGWizard: there is no step with id " << id << std::endl;
192  }
193 
194  virtual void deleteSteps()
195  {
196  ygtk_wizard_clear_steps (getWizard());
197  }
198 
199  virtual void updateSteps()
200  {}
201 
202  virtual void addTreeItem (const std::string &parentID, const std::string &text,
203  const std::string &id)
204  {
205  if (!ygtk_wizard_add_tree_item (getWizard(), parentID.c_str(),
206  text.c_str(), id.c_str()))
207  yuiError() << "YGWizard: there is no tree item with id " << parentID << std::endl;
208  }
209 
210  virtual void selectTreeItem (const std::string &id)
211  {
212  if (!ygtk_wizard_select_tree_item (getWizard(), id.c_str()))
213  yuiError() << "YGWizard: there is no tree item with id " << id << std::endl;
214  }
215 
216  virtual std::string currentTreeSelection()
217  {
218  const char *selected = ygtk_wizard_get_tree_selection (getWizard());
219  if (selected)
220  return selected;
221  return std::string();
222  }
223 
224  virtual void deleteTreeItems()
225  {
226  ygtk_wizard_clear_tree (getWizard());
227  }
228 
229  virtual void addMenu (const std::string &text, const std::string &id)
230  {
231  std::string str = YGUtils::mapKBAccel (text);
232  ygtk_wizard_add_menu (getWizard(), str.c_str(), id.c_str());
233  }
234 
235  virtual void addSubMenu (const std::string &parentID, const std::string &text,
236  const std::string &id)
237  {
238  std::string str = YGUtils::mapKBAccel(text);
239  if (!ygtk_wizard_add_sub_menu (getWizard(), parentID.c_str(), str.c_str(),
240  id.c_str()))
241  yuiError() << "YGWizard: there is no menu item with id " << parentID << std::endl;
242  }
243 
244  virtual void addMenuEntry (const std::string &parentID, const std::string &text,
245  const std::string &id)
246  {
247  std::string str = YGUtils::mapKBAccel (text);
248  if (!ygtk_wizard_add_menu_entry (getWizard(), parentID.c_str(),
249  str.c_str(), id.c_str()))
250  yuiError() << "YGWizard: there is no menu item with id " << parentID << std::endl;
251  }
252 
253  virtual void addMenuSeparator (const std::string & parentID)
254  {
255  if (!ygtk_wizard_add_menu_separator (getWizard(), parentID.c_str()))
256  yuiError() << "YGWizard: there is no menu item with id " << parentID << std::endl;
257  }
258 
259  virtual void deleteMenus()
260  {
261  ygtk_wizard_clear_menu (getWizard());
262  }
263 
264  virtual void showReleaseNotesButton (const std::string &label, const std::string &id)
265  {
266  std::string str = YGUtils::mapKBAccel (label.c_str());
267  ygtk_wizard_set_button_label (getWizard(), m_notes_button->getWidget(), str.c_str(), NULL);
268  ygtk_wizard_set_button_str_id (getWizard(), m_notes_button->getWidget(), id.c_str());
269  }
270 
271  virtual void hideReleaseNotesButton()
272  {
273  ygtk_wizard_set_button_label (getWizard(), m_notes_button->getWidget(), NULL, NULL);
274  }
275 
276  virtual void retranslateInternalButtons()
277  {}
278 
279  static void action_triggered_cb (YGtkWizard *wizard, gpointer id,
280  gint id_type, YGWizard *pThis)
281  {
282  if ((GType) id_type == G_TYPE_STRING)
283  YGUI::ui()->sendEvent (new YMenuEvent ((char *) id));
284  else
285  YGUI::ui()->sendEvent (new YWidgetEvent ((YWidget *) id, YEvent::Activated));
286  }
287 
288  // YGWidget
289  virtual void doAddChild (YWidget *ychild, GtkWidget *container)
290  {
291  if (ychild->widgetRep()) // don't actually add the button wrappers
292  ygtk_wizard_set_child (getWizard(), YGWidget::get (ychild)->getLayout());
293  }
294 
295  YGWIDGET_IMPL_CONTAINER (YWizard)
296 };
297 
298 YWizard *YGOptionalWidgetFactory::createWizard (YWidget *parent,
299  const std::string &backButtonLabel, const std::string &abortButtonLabel,
300  const std::string &nextButtonLabel, YWizardMode wizardMode)
301 {
302  return new YGWizard (parent, backButtonLabel, abortButtonLabel, nextButtonLabel,
303  wizardMode);
304 }
305