libyui-gtk  2.44.2
 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_add_field (field, ':');
102  ygtk_field_entry_setup_field (field, 0, 2, "0123456789");
103  ygtk_field_entry_setup_field (field, 1, 2, "0123456789");
104  ygtk_field_entry_setup_field (field, 2, 2, "0123456789");
105 
106  connect (getWidget(), "field-entry-changed", G_CALLBACK (value_changed_cb), this);
107  }
108 
109  // YTimeField
110  virtual void setValue (const std::string &time)
111  {
112  BlockEvents block (this);
113  if (time.empty()) return;
114  char hours[3], mins[3], secs[3];
115  sscanf (time.c_str(), "%2s:%2s:%2s", hours, mins, secs);
116 
117  YGtkFieldEntry *entry = YGTK_FIELD_ENTRY (getWidget());
118  ygtk_field_entry_set_field_text (entry, 0, hours);
119  ygtk_field_entry_set_field_text (entry, 1, mins);
120  ygtk_field_entry_set_field_text (entry, 2, secs);
121  }
122 
123  virtual std::string value()
124  {
125  const gchar *hours, *mins, *secs;
126  YGtkFieldEntry *entry = YGTK_FIELD_ENTRY (getWidget());
127  hours = ygtk_field_entry_get_field_text (entry, 0);
128  mins = ygtk_field_entry_get_field_text (entry, 1);
129  secs = ygtk_field_entry_get_field_text (entry, 2);
130 
131  gchar *time = g_strdup_printf ("%02d:%02d:%02d", atoi (hours), atoi (mins), atoi (secs));
132  std::string str (time);
133  g_free (time);
134  return str;
135  }
136 
137  // callbacks
138  static void value_changed_cb (YGtkFieldEntry *entry, gint field_nb,
139  YGTimeField *pThis)
140  { pThis->emitEvent (YEvent::ValueChanged); }
141 
142  YGLABEL_WIDGET_IMPL (YTimeField)
143 };
144 
145 YTimeField *YGOptionalWidgetFactory::createTimeField (YWidget *parent, const std::string &label)
146 { return new YGTimeField (parent, label); }
147 
148 #include "YDateField.h"
149 #include "ygtkmenubutton.h"
150 
151 class YGDateField : public YDateField, public YGLabeledWidget
152 {
153 GtkWidget *m_calendar, *m_popup_calendar;
154 
155 public:
156  YGDateField (YWidget *parent, const std::string &label)
157  : YDateField (NULL, label),
158  YGLabeledWidget (this, parent, label, YD_HORIZ, YGTK_TYPE_FIELD_ENTRY, NULL)
159  {
160  ygtk_field_entry_add_field (getField(), '-');
161  ygtk_field_entry_add_field (getField(), '-');
162  ygtk_field_entry_add_field (getField(), '-');
163  ygtk_field_entry_setup_field (getField(), 0, 4, "0123456789");
164  ygtk_field_entry_setup_field (getField(), 1, 2, "0123456789");
165  ygtk_field_entry_setup_field (getField(), 2, 2, "0123456789");
166 
167  m_calendar = gtk_calendar_new();
168  gtk_widget_show (m_calendar);
169  GtkWidget *popup = ygtk_popup_window_new (m_calendar);
170 
171  GtkWidget *menu_button = ygtk_menu_button_new_with_label ("");
172  ygtk_menu_button_set_popup (YGTK_MENU_BUTTON (menu_button), popup);
173  gtk_widget_show (menu_button);
174  gtk_box_pack_start (GTK_BOX (getWidget()), menu_button, FALSE, TRUE, 6);
175 
176  connect (getWidget(), "field-entry-changed", G_CALLBACK (value_changed_cb), this);
177  connect (m_calendar, "day-selected", G_CALLBACK (calendar_changed_cb), this);
178  g_signal_connect (G_OBJECT (m_calendar), "day-selected-double-click",
179  G_CALLBACK (double_click_cb), popup);
180  }
181 
182  inline GtkCalendar *getCalendar()
183  { return GTK_CALENDAR (m_calendar); }
184  inline YGtkFieldEntry *getField()
185  { return YGTK_FIELD_ENTRY (getWidget()); }
186 
187  // YDateField
188  virtual void setValue (const std::string &date)
189  {
190  BlockEvents block (this);
191  if (date.empty()) return;
192  char year[5], month[3], day[3];
193  sscanf (date.c_str(), "%4s-%2s-%2s", year, month, day);
194 
195  gtk_calendar_select_month (getCalendar(), atoi (month)-1, atoi (year));
196  gtk_calendar_select_day (getCalendar(), atoi (day));
197 
198  ygtk_field_entry_set_field_text (getField(), 0, year);
199  ygtk_field_entry_set_field_text (getField(), 1, month);
200  ygtk_field_entry_set_field_text (getField(), 2, day);
201  }
202 
203  virtual std::string value()
204  {
205  const gchar *year, *month, *day;
206  year = ygtk_field_entry_get_field_text (getField(), 0);
207  month = ygtk_field_entry_get_field_text (getField(), 1);
208  day = ygtk_field_entry_get_field_text (getField(), 2);
209 
210  gchar *time = g_strdup_printf ("%04d-%02d-%02d", atoi (year),
211  atoi (month), atoi (day));
212  std::string str (time);
213  g_free (time);
214  return str;
215  }
216 
217  // callbacks
218  static void value_changed_cb (YGtkFieldEntry *entry, gint field_nb,
219  YGDateField *pThis)
220  {
221  int year, month, day;
222  year = atoi (ygtk_field_entry_get_field_text (pThis->getField(), 0));
223  month = atoi (ygtk_field_entry_get_field_text (pThis->getField(), 1));
224  day = atoi (ygtk_field_entry_get_field_text (pThis->getField(), 2));
225 
226  if (day < 1 || day > 31 || month < 1 || month > 12)
227  return; // avoid GtkCalendar warnings
228 
229  g_signal_handlers_block_by_func (pThis->getCalendar(),
230  (gpointer) calendar_changed_cb, pThis);
231 
232  gtk_calendar_select_month (pThis->getCalendar(), month-1, year);
233  gtk_calendar_select_day (pThis->getCalendar(), day);
234 
235  g_signal_handlers_unblock_by_func (pThis->getCalendar(),
236  (gpointer) calendar_changed_cb, pThis);
237 
238  pThis->emitEvent (YEvent::ValueChanged);
239  }
240 
241  static void calendar_changed_cb (GtkCalendar *calendar, YGDateField *pThis)
242  {
243  guint year, month, day;
244  gtk_calendar_get_date (calendar, &year, &month, &day);
245  month += 1; // GTK calendar months go from 0 to 11
246 
247  gchar *year_str, *month_str, *day_str;
248  year_str = g_strdup_printf ("%d", year);
249  month_str = g_strdup_printf ("%d", month);
250  day_str = g_strdup_printf ("%d", day);
251 
252  g_signal_handlers_block_by_func (pThis->getField(),
253  (gpointer) value_changed_cb, pThis);
254 
255  YGtkFieldEntry *entry = pThis->getField();
256  ygtk_field_entry_set_field_text (entry, 0, year_str);
257  ygtk_field_entry_set_field_text (entry, 1, month_str);
258  ygtk_field_entry_set_field_text (entry, 2, day_str);
259 
260  g_signal_handlers_unblock_by_func (pThis->getField(),
261  (gpointer) value_changed_cb, pThis);
262 
263  g_free (year_str);
264  g_free (month_str);
265  g_free (day_str);
266 
267  pThis->emitEvent (YEvent::ValueChanged);
268  }
269 
270  static void double_click_cb (GtkCalendar *calendar, YGtkPopupWindow *popup)
271  {
272  // close popup
273  gtk_widget_hide (GTK_WIDGET (popup));
274  }
275 
276  YGLABEL_WIDGET_IMPL (YDateField)
277 };
278 
279 YDateField *YGOptionalWidgetFactory::createDateField (YWidget *parent, const std::string &label)
280 { return new YGDateField (parent, label); }
281 
282 #include "YTimezoneSelector.h"
283 #include "ygtktimezonepicker.h"
284 
285 class YGTimezoneSelector : public YTimezoneSelector, public YGWidget
286 {
287 public:
288  YGTimezoneSelector (YWidget *parent, const std::string &pixmap,
289  const std::map <std::string, std::string> &timezones)
290  : YTimezoneSelector (NULL, pixmap, timezones),
291  YGWidget (this, parent, YGTK_TYPE_TIME_ZONE_PICKER, NULL)
292  {
293  setStretchable (YD_HORIZ, true);
294  setStretchable (YD_VERT, true);
295  ygtk_time_zone_picker_set_map (YGTK_TIME_ZONE_PICKER (getWidget()),
296  pixmap.c_str(), convert_code_to_name, (gpointer) &timezones);
297 
298  connect (getWidget(), "zone-clicked", G_CALLBACK (zone_clicked_cb), this);
299  }
300 
301  // YTimezoneSelector
302  virtual std::string currentZone() const
303  {
304  YGTimezoneSelector *pThis = const_cast <YGTimezoneSelector *> (this);
305  const gchar *zone = ygtk_time_zone_picker_get_current_zone (
306  YGTK_TIME_ZONE_PICKER (pThis->getWidget()));
307  if (zone)
308  return zone;
309  return std::string();
310  }
311 
312  virtual void setCurrentZone (const std::string &zone, bool zoom)
313  {
314  BlockEvents block (this);
315  ygtk_time_zone_picker_set_current_zone (YGTK_TIME_ZONE_PICKER (getWidget()),
316  zone.c_str(), zoom);
317  }
318 
319  // YGtkTimeZonePicker
320  static const gchar *convert_code_to_name (const gchar *code, gpointer pData)
321  {
322  const std::map <std::string, std::string> *timezones =
323  (std::map <std::string, std::string> *) pData;
324  std::map <std::string, std::string>::const_iterator name =
325  timezones->find (code);
326  if (name == timezones->end())
327  return NULL;
328  return name->second.c_str();
329  }
330 
331  // callbacks
332  static void zone_clicked_cb (YGtkTimeZonePicker *picker, const gchar *zone,
333  YGTimezoneSelector *pThis)
334  { pThis->emitEvent (YEvent::ValueChanged); }
335 
336  YGWIDGET_IMPL_COMMON (YTimezoneSelector)
337 };
338 
339 YTimezoneSelector *YGOptionalWidgetFactory::createTimezoneSelector (YWidget *parent,
340  const std::string &pixmap, const std::map <std::string, std::string> &timezones)
341 { return new YGTimezoneSelector (parent, pixmap, timezones); }
342