libyui-gtk  2.43.7
 All Classes
YGText.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 <string>
9 #include "YGUtils.h"
10 #include "YGWidget.h"
11 #include "ygtktextview.h"
12 
14 {
15 int maxChars;
16 
17 public:
18  YGTextView (YWidget *ywidget, YWidget *parent, const std::string &label, bool editable)
19  : YGScrolledWidget (ywidget, parent, label, YD_VERT,
20  YGTK_TYPE_TEXT_VIEW, "wrap-mode", GTK_WRAP_WORD_CHAR,
21  "editable", editable, NULL)
22  {
23  setPolicy (GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
24  maxChars = -1;
25  connect (getBuffer(), "changed", G_CALLBACK (text_changed_cb), this);
26  }
27 
28  GtkTextBuffer* getBuffer()
29  { return gtk_text_view_get_buffer (GTK_TEXT_VIEW (getWidget())); }
30 
31  int getCharsNb()
32  { return gtk_text_buffer_get_char_count (getBuffer()); }
33 
34  void setCharsNb (int max_chars)
35  {
36  maxChars = max_chars;
37  if (maxChars != -1 && getCharsNb() > maxChars)
38  truncateText (maxChars);
39  }
40 
41  void truncateText(int pos)
42  {
43  BlockEvents block (this);
44  GtkTextIter start_it, end_it;
45  gtk_text_buffer_get_iter_at_offset (getBuffer(), &start_it, pos);
46  gtk_text_buffer_get_end_iter (getBuffer(), &end_it);
47  gtk_text_buffer_delete (getBuffer(), &start_it, &end_it);
48  }
49 
50  void setText (const std::string &text)
51  {
52  BlockEvents block (this);
53  gtk_text_buffer_set_text (getBuffer(), text.c_str(), -1);
54  }
55 
56  void appendText (const std::string &text)
57  {
58  GtkTextIter end_it;
59  gtk_text_buffer_get_end_iter (getBuffer(), &end_it);
60  gtk_text_buffer_insert (getBuffer(), &end_it, text.c_str(), -1);
61  }
62 
63  std::string getText()
64  {
65  GtkTextIter start_it, end_it;
66  gtk_text_buffer_get_bounds (getBuffer(), &start_it, &end_it);
67 
68  gchar* text = gtk_text_buffer_get_text (getBuffer(), &start_it, &end_it, FALSE);
69  std::string str (text);
70  g_free (text);
71  return str;
72  }
73 
74  void scrollToBottom()
75  {
76 #if 1
77  YGUtils::scrollWidget (gtk_scrollable_get_vadjustment(GTK_SCROLLABLE (getWidget())), false);
78 #else
79  GtkTextBuffer *buffer = getBuffer();
80  GtkTextIter iter;
81  gtk_text_buffer_get_end_iter (buffer, &iter);
82  gtk_text_iter_set_line_offset (&iter, 0);
83 
84  GtkTextMark *mark = gtk_text_buffer_get_mark (buffer, "scroll");
85  if (mark)
86  gtk_text_buffer_move_mark (buffer, mark, &iter);
87  else
88  mark = gtk_text_buffer_create_mark (buffer, "scroll", &iter, TRUE);
89 
90  GtkTextView *view = GTK_TEXT_VIEW (getWidget());
91  gtk_text_view_scroll_mark_onscreen (view, mark);
92 #endif
93  }
94 
95  // Event callbacks
96  static void text_changed_cb (GtkTextBuffer *buffer, YGTextView *pThis)
97  {
98  if (pThis->maxChars != -1 && pThis->getCharsNb() > pThis->maxChars) {
99  pThis->truncateText (pThis->maxChars);
100  gtk_widget_error_bell (pThis->getWidget());
101  }
102  pThis->emitEvent (YEvent::ValueChanged);
103  }
104 };
105 
106 #include "YMultiLineEdit.h"
107 
108 class YGMultiLineEdit : public YMultiLineEdit, public YGTextView
109 {
110 public:
111  YGMultiLineEdit (YWidget *parent, const std::string &label)
112  : YMultiLineEdit (NULL, label)
113  , YGTextView (this, parent, label, true)
114  {}
115 
116  // YMultiLineEdit
117  virtual void setValue (const std::string &text)
118  { YGTextView::setText (text); }
119 
120  virtual std::string value()
121  { return YGTextView::getText(); }
122 
123  virtual void setInputMaxLength (int nb)
124  {
125  YGTextView::setCharsNb (nb);
126  YMultiLineEdit::setInputMaxLength (nb);
127  }
128 
129  // YGWidget
130 
131  virtual unsigned int getMinSize (YUIDimension dim)
132  {
133  if (dim == YD_VERT) {
134  int height = YGUtils::getCharsHeight (getWidget(), defaultVisibleLines());
135  return MAX (10, height);
136  }
137  return 30;
138  }
139 
140  YGLABEL_WIDGET_IMPL (YMultiLineEdit)
141 };
142 
143 YMultiLineEdit *YGWidgetFactory::createMultiLineEdit (YWidget *parent, const std::string &label)
144 {
145  return new YGMultiLineEdit (parent, label);
146 }
147 
148 #include "YLogView.h"
149 
150 class YGLogView : public YLogView, public YGTextView
151 {
152 std::string m_text;
153 
154 public:
155  YGLogView (YWidget *parent, const std::string &label, int visibleLines, int maxLines)
156  : YLogView (NULL, label, visibleLines, maxLines)
157  , YGTextView (this, parent, label, false)
158  {}
159 
160  // YLogView
161  virtual void displayLogText (const std::string &text)
162  {
163  // libyui calls clearText before setting it: let's ignore it
164  if (text.empty()) return;
165 
166  if (text.compare (0, m_text.size(), m_text) == 0) {
167  if (text.size() == m_text.size()) return;
168 
169  // appending text: avoid flickering and allow user to scroll freely
170  GtkAdjustment *vadj = gtk_scrollable_get_vadjustment(GTK_SCROLLABLE (getWidget()));
171  bool autoScroll = gtk_adjustment_get_value(vadj) >= gtk_adjustment_get_upper(vadj) - gtk_adjustment_get_page_size(vadj);
172 
173  std::string diff (text.substr (m_text.size()));
174  YGTextView::appendText (diff);
175  if (autoScroll)
176  YGTextView::scrollToBottom();
177 
178  }
179  else {
180  YGTextView::setText (text);
181  YGTextView::scrollToBottom();
182  }
183  m_text = text;
184  }
185 
186  // YGWidget
187  virtual unsigned int getMinSize (YUIDimension dim)
188  {
189  if (dim == YD_VERT) {
190  int height = YGUtils::getCharsHeight (getWidget(), visibleLines());
191  return MAX (80, height);
192  }
193  return 50;
194  }
195 
196  YGLABEL_WIDGET_IMPL (YLogView)
197 };
198 
199 YLogView *YGWidgetFactory::createLogView (YWidget *parent, const std::string &label,
200  int visibleLines, int maxLines)
201 {
202  return new YGLogView (parent, label, visibleLines, maxLines);
203 }
204 
205 #include "YRichText.h"
206 #include "ygtkhtmlwrap.h"
207 
208 class YGRichText : public YRichText, YGScrolledWidget
209 {
210 public:
211  YGRichText (YWidget *parent, const std::string &text, bool plainText)
212  : YRichText (NULL, text, plainText)
213  , YGScrolledWidget (this, parent, ygtk_html_wrap_get_type(), NULL)
214  {
215  ygtk_html_wrap_init (getWidget());
216  ygtk_html_wrap_connect_link_clicked (getWidget(), link_clicked_cb, this);
217  setText (text, plainText);
218  }
219 
220  void setPlainText (const std::string &text)
221  {
222  ygtk_html_wrap_set_text (getWidget(), text.c_str(), TRUE);
223  }
224 
225  void setRichText (const std::string &text)
226  {
227 #if 0 // current done at the XHTML treatment level, we may want to enable
228  // this code so that we replace the entity for all widgets
229  std::string text (_text);
230  std::string productName = YUI::app()->productName();
231  YGUtils::replace (text, "&product;", 9, productName.c_str());
232 #endif
233  ygtk_html_wrap_set_text (getWidget(), text.c_str(), FALSE);
234  }
235 
236  void scrollToBottom()
237  {
238  ygtk_html_wrap_scroll (getWidget(), FALSE);
239  }
240 
241  void setText (const std::string &text, bool plain_mode)
242  {
243  plain_mode ? setPlainText (text) : setRichText (text);
244  if (autoScrollDown())
245  scrollToBottom();
246  }
247 
248  // YRichText
249  virtual void setValue (const std::string &text)
250  {
251  YRichText::setValue (text);
252  setText (text, plainTextMode());
253  }
254 
255  virtual void setAutoScrollDown (bool on)
256  {
257  YRichText::setAutoScrollDown (on);
258  if (on) scrollToBottom();
259  }
260 
261  virtual void setPlainTextMode (bool plain_mode)
262  {
263  YRichText::setPlainTextMode (plain_mode);
264  if (plain_mode != plainTextMode())
265  setText (value(), plain_mode);
266  }
267 
268  // callbacks
269  static void link_clicked_cb (GtkWidget *widget, const char *url, gpointer data)
270  { YGUI::ui()->sendEvent (new YMenuEvent (url)); }
271 
272  // YGWidget
273  virtual unsigned int getMinSize (YUIDimension dim)
274  { return shrinkable() ? 10 : 100; }
275 
276  YGWIDGET_IMPL_COMMON (YRichText)
277 };
278 
279 
280 YRichText *YGWidgetFactory::createRichText (YWidget *parent, const std::string &text,
281  bool plainTextMode)
282 {
283  return new YGRichText (parent, text, plainTextMode);
284 }
285