1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk/textentry.cpp
3 // Purpose: wxTextEntry implementation for wxGTK
4 // Author: Vadim Zeitlin
7 // Copyright: (c) 2007 Vadim Zeitlin <vadim@wxwindows.org>
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
11 // ============================================================================
13 // ============================================================================
15 // ----------------------------------------------------------------------------
17 // ----------------------------------------------------------------------------
19 // for compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
27 #include "wx/window.h"
28 #include "wx/textctrl.h"
31 #include "wx/textentry.h"
33 #include "wx/gtk/private.h"
35 // ============================================================================
36 // signal handlers implementation
37 // ============================================================================
42 // "insert_text" handler for GtkEntry
44 wx_gtk_insert_text_callback(GtkEditable
*editable
,
45 const gchar
*new_text
,
50 // we should only be called if we have a max len limit at all
51 GtkEntry
*entry
= GTK_ENTRY (editable
);
53 wxCHECK_RET( entry
->text_max_length
, _T("shouldn't be called") );
55 // check that we don't overflow the max length limit
57 // FIXME: this doesn't work when we paste a string which is going to be
59 if ( entry
->text_length
== entry
->text_max_length
)
61 // we don't need to run the base class version at all
62 g_signal_stop_emission_by_name (editable
, "insert_text");
64 text
->SendMaxLenEvent();
70 // ============================================================================
71 // wxTextEntry implementation
72 // ============================================================================
74 // ----------------------------------------------------------------------------
76 // ----------------------------------------------------------------------------
78 void wxTextEntry::WriteText(const wxString
& value
)
80 GtkEditable
* const edit
= GetEditable();
82 // remove the selection if there is one and suppress the text change event
83 // generated by this: we only want to generate one event for this change,
86 EventsSuppressor
noevents(this);
87 gtk_editable_delete_selection(edit
);
90 // insert new text at the cursor position
91 gint len
= gtk_editable_get_position(edit
);
92 gtk_editable_insert_text
95 wxGTK_CONV_FONT(value
, GetEditableWindow()->GetFont()),
96 -1, // text: length: compute it using strlen()
97 &len
// will be updated to position after the text end
100 // and move cursor to the end of new text
101 gtk_editable_set_position(edit
, len
);
104 wxString
wxTextEntry::GetValue() const
106 const wxGtkString
value(gtk_editable_get_chars(GetEditable(), 0, -1));
108 return wxGTK_CONV_BACK_FONT(value
, GetEditableWindow()->GetFont());
111 void wxTextEntry::Remove(long from
, long to
)
113 gtk_editable_delete_text(GetEditable(), from
, to
);
116 // ----------------------------------------------------------------------------
117 // clipboard operations
118 // ----------------------------------------------------------------------------
120 void wxTextEntry::Copy()
122 gtk_editable_copy_clipboard(GetEditable());
125 void wxTextEntry::Cut()
127 gtk_editable_cut_clipboard(GetEditable());
130 void wxTextEntry::Paste()
132 gtk_editable_paste_clipboard(GetEditable());
135 // ----------------------------------------------------------------------------
137 // ----------------------------------------------------------------------------
139 void wxTextEntry::Undo()
141 // TODO: not implemented
144 void wxTextEntry::Redo()
146 // TODO: not implemented
149 bool wxTextEntry::CanUndo() const
154 bool wxTextEntry::CanRedo() const
159 // ----------------------------------------------------------------------------
161 // ----------------------------------------------------------------------------
163 void wxTextEntry::SetInsertionPoint(long pos
)
165 gtk_editable_set_position(GetEditable(), pos
);
168 long wxTextEntry::GetInsertionPoint() const
170 return gtk_editable_get_position(GetEditable());
173 long wxTextEntry::GetLastPosition() const
175 // this can't be implemented for arbitrary GtkEditable so only do it for
177 GtkEntry
* const entry
= GTK_ENTRY(GetEditable());
179 return entry
? entry
->text_length
: - 1;
182 // ----------------------------------------------------------------------------
184 // ----------------------------------------------------------------------------
186 void wxTextEntry::SetSelection(long from
, long to
)
188 gtk_editable_select_region(GetEditable(), from
, to
);
191 void wxTextEntry::GetSelection(long *from
, long *to
) const
194 if ( gtk_editable_get_selection_bounds(GetEditable(), &start
, &end
) )
196 // the output must always be in order, although in GTK+ it isn't
206 // for compatibility with MSW return the empty selection at cursor
208 end
= GetInsertionPoint();
218 // ----------------------------------------------------------------------------
220 // ----------------------------------------------------------------------------
222 bool wxTextEntry::IsEditable() const
224 return gtk_editable_get_editable(GetEditable());
227 void wxTextEntry::SetEditable(bool editable
)
229 gtk_editable_set_editable(GetEditable(), editable
);
232 // ----------------------------------------------------------------------------
234 // ----------------------------------------------------------------------------
236 void wxTextEntry::SetMaxLength(unsigned long len
)
238 GtkEntry
* const entry
= GTK_ENTRY(GetEditable());
242 gtk_entry_set_max_length(entry
, len
);
244 // there is a bug in GTK+ 1.2.x: "changed" signal is emitted even if we had
245 // tried to enter more text than allowed by max text length and the text
246 // wasn't really changed
248 // to detect this and generate TEXT_MAXLEN event instead of TEXT_CHANGED
249 // one in this case we also catch "insert_text" signal
251 // when max len is set to 0 we disconnect our handler as it means that we
252 // shouldn't check anything any more
259 G_CALLBACK(wx_gtk_insert_text_callback
),
263 else // no max length
265 g_signal_handlers_disconnect_by_func
268 (gpointer
)wx_gtk_insert_text_callback
,
274 void wxTextEntry::SendMaxLenEvent()
276 // remember that the next changed signal is to be ignored to avoid
277 // generating a dummy wxEVT_COMMAND_TEXT_UPDATED event
278 //IgnoreNextTextUpdate();
280 wxWindow
* const win
= const_cast<wxWindow
*>(GetEditableWindow());
281 wxCommandEvent
event(wxEVT_COMMAND_TEXT_MAXLEN
, win
->GetId());
282 event
.SetEventObject(win
);
283 event
.SetString(GetValue());
284 win
->GetEventHandler()->ProcessEvent(event
);