libyui-gtk  2.43.3
 All Classes
YGInputField.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 "ygtkfieldentry.h"
11 
12 #include <YInputField.h>
13 
14 class YGInputField : public YInputField, public YGLabeledWidget
15 {
16 public:
17  YGInputField (YWidget *parent, const std::string &label, bool passwordMode)
18  : YInputField (NULL, label, passwordMode),
19  YGLabeledWidget (this, parent, label, YD_HORIZ,
20  YGTK_TYPE_FIELD_ENTRY, NULL)
21  {
22  gtk_widget_set_size_request (getWidget(), 0, -1); // let min size, set width
23  YGtkFieldEntry *field = YGTK_FIELD_ENTRY (getWidget());
24  ygtk_field_entry_add_field (field, 0);
25 
26  GtkEntry *entry = ygtk_field_entry_get_field_widget (field, 0);
27  gtk_entry_set_activates_default (entry, TRUE);
28  gtk_entry_set_visibility (entry, !passwordMode);
29 
30  connect (getWidget(), "field-entry-changed", G_CALLBACK (value_changed_cb), this);
31  }
32 
33  // YInputField
34  virtual std::string value()
35  {
36  YGtkFieldEntry *field = YGTK_FIELD_ENTRY (getWidget());
37  return ygtk_field_entry_get_field_text (field, 0);
38  }
39 
40  virtual void setValue (const std::string &text)
41  {
42  BlockEvents block (this);
43  YGtkFieldEntry *field = YGTK_FIELD_ENTRY (getWidget());
44  ygtk_field_entry_set_field_text (field, 0, text.c_str());
45  }
46 
47  void updateProps()
48  {
49  YGtkFieldEntry *field = YGTK_FIELD_ENTRY (getWidget());
50  ygtk_field_entry_setup_field (field, 0, inputMaxLength(), validChars().c_str());
51  }
52 
53  virtual void setInputMaxLength (int len)
54  {
55  YInputField::setInputMaxLength (len);
56  updateProps();
57  }
58 
59  virtual void setValidChars (const std::string &validChars)
60  {
61  YInputField::setValidChars (validChars);
62  updateProps();
63  }
64 
65  // callbacks
66  static void value_changed_cb (YGtkFieldEntry *entry, gint field_nb, YGInputField *pThis)
67  { pThis->emitEvent (YEvent::ValueChanged); }
68 
69  // YGWidget
70  virtual bool doSetKeyboardFocus()
71  {
72  YGtkFieldEntry *field = YGTK_FIELD_ENTRY (getWidget());
73  return ygtk_field_entry_set_focus (field);
74  }
75 
76  virtual unsigned int getMinSize (YUIDimension dim)
77  { return dim == YD_HORIZ ? (shrinkable() ? 30 : 200) : 0; }
78 
79  YGLABEL_WIDGET_IMPL (YInputField)
80 };
81 
82 YInputField *YGWidgetFactory::createInputField (YWidget *parent, const std::string &label,
83  bool passwordMode)
84 {
85  return new YGInputField (parent, label, passwordMode);
86 }
87 
88 #include "YTimeField.h"
89 
90 class YGTimeField : public YTimeField, public YGLabeledWidget
91 {
92 public:
93  YGTimeField (YWidget *parent, const std::string &label)
94  : YTimeField (NULL, label),
95  YGLabeledWidget (this, parent, label, YD_HORIZ,
96  YGTK_TYPE_FIELD_ENTRY, NULL)
97  {
98  YGtkFieldEntry *field = YGTK_FIELD_ENTRY (getWidget());
99  ygtk_field_entry_add_field (field, ':');
100  ygtk_field_entry_add_field (field, ':');
101  ygtk_field_entry_setup_field (field, 0, 2, "0123456789");
102  ygtk_field_entry_setup_field (field, 1, 2, "0123456789");
103 
104  connect (getWidget(), "field-entry-changed", G_CALLBACK (value_changed_cb), this);
105  }
106 
107  // YTimeField
108  virtual void setValue (const std::string &time)
109  {
110  BlockEvents block (this);
111  if (time.empty()) return;
112  char hours[3], mins[3];
113  sscanf (time.c_str(), "%2s:%2s", hours, mins);
114 
115  YGtkFieldEntry *entry = YGTK_FIELD_ENTRY (getWidget());
116  ygtk_field_entry_set_field_text (entry, 0, hours);
117  ygtk_field_entry_set_field_text (entry, 1, mins);
118  }
119 
120  virtual std::string value()
121  {
122  const gchar *hours, *mins;
123  YGtkFieldEntry *entry = YGTK_FIELD_ENTRY (getWidget());
124  hours = ygtk_field_entry_get_field_text (entry, 0);
125  mins = ygtk_field_entry_get_field_text (entry, 1);
126 
127  gchar *time = g_strdup_printf ("%02d:%02d:00", atoi (hours), atoi (mins));
128  std::string str (time);
129  g_free (time);
130  return str;
131  }
132 
133  // callbacks
134  static void value_changed_cb (YGtkFieldEntry *entry, gint field_nb,
135  YGTimeField *pThis)
136  { pThis->emitEvent (YEvent::ValueChanged); }
137 
138  YGLABEL_WIDGET_IMPL (YTimeField)
139 };
140 
141 YTimeField *YGOptionalWidgetFactory::createTimeField (YWidget *parent, const std::string &label)
142 { return new YGTimeField (parent, label); }
143 
144 #include "YDateField.h"
145 #include "ygtkmenubutton.h"
146 
147 class YGDateField : public YDateField, public YGLabeledWidget
148 {
149 GtkWidget *m_calendar, *m_popup_calendar;
150 
151 public:
152  YGDateField (YWidget *parent, const std::string &label)
153  : YDateField (NULL, label),
154  YGLabeledWidget (this, parent, label, YD_HORIZ, YGTK_TYPE_FIELD_ENTRY, NULL)
155  {
156  ygtk_field_entry_add_field (getField(), '-');
157  ygtk_field_entry_add_field (getField(), '-');
158  ygtk_field_entry_add_field (getField(), '-');
159  ygtk_field_entry_setup_field (getField(), 0, 4, "0123456789");
160  ygtk_field_entry_setup_field (getField(), 1, 2, "0123456789");
161  ygtk_field_entry_setup_field (getField(), 2, 2, "0123456789");
162 
163  m_calendar = gtk_calendar_new();
164  gtk_widget_show (m_calendar);
165  GtkWidget *popup = ygtk_popup_window_new (m_calendar);
166 
167  GtkWidget *menu_button = ygtk_menu_button_new_with_label ("");
168  ygtk_menu_button_set_popup (YGTK_MENU_BUTTON (menu_button), popup);
169  gtk_widget_show (menu_button);
170  gtk_box_pack_start (GTK_BOX (getWidget()), menu_button, FALSE, TRUE, 6);
171 
172  connect (getWidget(), "field-entry-changed", G_CALLBACK (value_changed_cb), this);
173  connect (m_calendar, "day-selected", G_CALLBACK (calendar_changed_cb), this);
174  g_signal_connect (G_OBJECT (m_calendar), "day-selected-double-click",
175  G_CALLBACK (double_click_cb), popup);
176  }
177 
178  inline GtkCalendar *getCalendar()
179  { return GTK_CALENDAR (m_calendar); }
180  inline YGtkFieldEntry *getField()
181  { return YGTK_FIELD_ENTRY (getWidget()); }
182 
183  // YDateField
184  virtual void setValue (const std::string &date)
185  {
186  BlockEvents block (this);
187  if (date.empty()) return;
188  char year[5], month[3], day[3];
189  sscanf (date.c_str(), "%4s-%2s-%2s", year, month, day);
190 
191  gtk_calendar_select_month (getCalendar(), atoi (month)-1, atoi (year));
192  gtk_calendar_select_day (getCalendar(), atoi (day));
193 
194  ygtk_field_entry_set_field_text (getField(), 0, year);
195  ygtk_field_entry_set_field_text (getField(), 1, month);
196  ygtk_field_entry_set_field_text (getField(), 2, day);
197  }
198 
199  virtual std::string value()
200  {
201  const gchar *year, *month, *day;
202  year = ygtk_field_entry_get_field_text (getField(), 0);
203  month = ygtk_field_entry_get_field_text (getField(), 1);
204  day = ygtk_field_entry_get_field_text (getField(), 2);
205 
206  gchar *time = g_strdup_printf ("%04d-%02d-%02d", atoi (year),
207  atoi (month), atoi (day));
208  std::string str (time);
209  g_free (time);
210  return str;
211  }
212 
213  // callbacks
214  static void value_changed_cb (YGtkFieldEntry *entry, gint field_nb,
215  YGDateField *pThis)
216  {
217  int year, month, day;
218  year = atoi (ygtk_field_entry_get_field_text (pThis->getField(), 0));
219  month = atoi (ygtk_field_entry_get_field_text (pThis->getField(), 1));
220  day = atoi (ygtk_field_entry_get_field_text (pThis->getField(), 2));
221 
222  if (day < 1 || day > 31 || month < 1 || month > 12)
223  return; // avoid GtkCalendar warnings
224 
225  g_signal_handlers_block_by_func (pThis->getCalendar(),
226  (gpointer) calendar_changed_cb, pThis);
227 
228  gtk_calendar_select_month (pThis->getCalendar(), month-1, year);
229  gtk_calendar_select_day (pThis->getCalendar(), day);
230 
231  g_signal_handlers_unblock_by_func (pThis->getCalendar(),
232  (gpointer) calendar_changed_cb, pThis);
233 
234  pThis->emitEvent (YEvent::ValueChanged);
235  }
236 
237  static void calendar_changed_cb (GtkCalendar *calendar, YGDateField *pThis)
238  {
239  guint year, month, day;
240  gtk_calendar_get_date (calendar, &year, &month, &day);
241  month += 1; // GTK calendar months go from 0 to 11
242 
243  gchar *year_str, *month_str, *day_str;
244  year_str = g_strdup_printf ("%d", year);
245  month_str = g_strdup_printf ("%d", month);
246  day_str = g_strdup_printf ("%d", day);
247 
248  g_signal_handlers_block_by_func (pThis->getField(),
249  (gpointer) value_changed_cb, pThis);
250 
251  YGtkFieldEntry *entry = pThis->getField();
252  ygtk_field_entry_set_field_text (entry, 0, year_str);
253  ygtk_field_entry_set_field_text (entry, 1, month_str);
254  ygtk_field_entry_set_field_text (entry, 2, day_str);
255 
256  g_signal_handlers_unblock_by_func (pThis->getField(),
257  (gpointer) value_changed_cb, pThis);
258 
259  g_free (year_str);
260  g_free (month_str);
261  g_free (day_str);
262 
263  pThis->emitEvent (YEvent::ValueChanged);
264  }
265 
266  static void double_click_cb (GtkCalendar *calendar, YGtkPopupWindow *popup)
267  {
268  // close popup
269  gtk_widget_hide (GTK_WIDGET (popup));
270  }
271 
272  YGLABEL_WIDGET_IMPL (YDateField)
273 };
274 
275 YDateField *YGOptionalWidgetFactory::createDateField (YWidget *parent, const std::string &label)
276 { return new YGDateField (parent, label); }
277 
278 #include "YTimezoneSelector.h"
279 #include "ygtktimezonepicker.h"
280 
281 class YGTimezoneSelector : public YTimezoneSelector, public YGWidget
282 {
283 public:
284  YGTimezoneSelector (YWidget *parent, const std::string &pixmap,
285  const std::map <std::string, std::string> &timezones)
286  : YTimezoneSelector (NULL, pixmap, timezones),
287  YGWidget (this, parent, YGTK_TYPE_TIME_ZONE_PICKER, NULL)
288  {
289  setStretchable (YD_HORIZ, true);
290  setStretchable (YD_VERT, true);
291  ygtk_time_zone_picker_set_map (YGTK_TIME_ZONE_PICKER (getWidget()),
292  pixmap.c_str(), convert_code_to_name, (gpointer) &timezones);
293 
294  connect (getWidget(), "zone-clicked", G_CALLBACK (zone_clicked_cb), this);
295  }
296 
297  // YTimezoneSelector
298  virtual std::string currentZone() const
299  {
300  YGTimezoneSelector *pThis = const_cast <YGTimezoneSelector *> (this);
301  const gchar *zone = ygtk_time_zone_picker_get_current_zone (
302  YGTK_TIME_ZONE_PICKER (pThis->getWidget()));
303  if (zone)
304  return zone;
305  return std::string();
306  }
307 
308  virtual void setCurrentZone (const std::string &zone, bool zoom)
309  {
310  BlockEvents block (this);
311  ygtk_time_zone_picker_set_current_zone (YGTK_TIME_ZONE_PICKER (getWidget()),
312  zone.c_str(), zoom);
313  }
314 
315  // YGtkTimeZonePicker
316  static const gchar *convert_code_to_name (const gchar *code, gpointer pData)
317  {
318  const std::map <std::string, std::string> *timezones =
319  (std::map <std::string, std::string> *) pData;
320  std::map <std::string, std::string>::const_iterator name =
321  timezones->find (code);
322  if (name == timezones->end())
323  return NULL;
324  return name->second.c_str();
325  }
326 
327  // callbacks
328  static void zone_clicked_cb (YGtkTimeZonePicker *picker, const gchar *zone,
329  YGTimezoneSelector *pThis)
330  { pThis->emitEvent (YEvent::ValueChanged); }
331 
332  YGWIDGET_IMPL_COMMON (YTimezoneSelector)
333 };
334 
335 YTimezoneSelector *YGOptionalWidgetFactory::createTimezoneSelector (YWidget *parent,
336  const std::string &pixmap, const std::map <std::string, std::string> &timezones)
337 { return new YGTimezoneSelector (parent, pixmap, timezones); }
338