X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/155ce4f18462c0a8e6348cc31e73bee490fcb12d..ad653fa23069c5d9378247084f03c9a718c3ad62:/src/gtk/textentry.cpp diff --git a/src/gtk/textentry.cpp b/src/gtk/textentry.cpp index a1dad35bc6..f8f9730d6d 100644 --- a/src/gtk/textentry.cpp +++ b/src/gtk/textentry.cpp @@ -43,33 +43,50 @@ extern "C" void wx_gtk_insert_text_callback(GtkEditable *editable, - const gchar * WXUNUSED(new_text), + const gchar * new_text, gint WXUNUSED(new_text_length), gint * WXUNUSED(position), wxTextEntry *text) { - // we should only be called if we have a max len limit at all GtkEntry *entry = GTK_ENTRY (editable); - const int text_length = gtk_entry_get_text_length(entry); #if GTK_CHECK_VERSION(3,0,0) || defined(GSEAL_ENABLE) const int text_max_length = gtk_entry_buffer_get_max_length(gtk_entry_get_buffer(entry)); #else const int text_max_length = entry->text_max_length; #endif - wxCHECK_RET(text_max_length, "shouldn't be called"); - // check that we don't overflow the max length limit - // - // FIXME: this doesn't work when we paste a string which is going to be - // truncated - if (text_length == text_max_length) + bool handled = false; + + // check that we don't overflow the max length limit if we have it + if ( text_max_length ) { - // we don't need to run the base class version at all - g_signal_stop_emission_by_name (editable, "insert_text"); + const int text_length = gtk_entry_get_text_length(entry); + + // We can't use new_text_length as it is in bytes while we want to count + // characters (in first approximation, anyhow...). + if ( text_length + g_utf8_strlen(new_text, -1) > text_max_length ) + { + // Prevent the new text from being inserted. + handled = true; + + // Currently we don't insert anything at all, but it would be better to + // insert as many characters as would fit into the text control and + // only discard the rest. + + // Notify the user code about overflow. + text->SendMaxLenEvent(); + } + } - text->SendMaxLenEvent(); + if ( !handled && text->GTKEntryOnInsertText(new_text) ) + { + // If we already handled the new text insertion, don't do it again. + handled = true; } + + if ( handled ) + g_signal_stop_emission_by_name (editable, "insert_text"); } //----------------------------------------------------------------------------- @@ -100,21 +117,21 @@ static void wx_gtk_copy_clipboard_callback( GtkWidget *widget, wxWindow *win ) { DoHandleClipboardCallback( - widget, win, wxEVT_COMMAND_TEXT_COPY, "copy-clipboard" ); + widget, win, wxEVT_TEXT_COPY, "copy-clipboard" ); } static void wx_gtk_cut_clipboard_callback( GtkWidget *widget, wxWindow *win ) { DoHandleClipboardCallback( - widget, win, wxEVT_COMMAND_TEXT_CUT, "cut-clipboard" ); + widget, win, wxEVT_TEXT_CUT, "cut-clipboard" ); } static void wx_gtk_paste_clipboard_callback( GtkWidget *widget, wxWindow *win ) { DoHandleClipboardCallback( - widget, win, wxEVT_COMMAND_TEXT_PASTE, "paste-clipboard" ); + widget, win, wxEVT_TEXT_PASTE, "paste-clipboard" ); } } // extern "C" @@ -380,50 +397,48 @@ void wxTextEntry::SetMaxLength(unsigned long len) return; gtk_entry_set_max_length(entry, len); - - // there is a bug in GTK+ 1.2.x: "changed" signal is emitted even if we had - // tried to enter more text than allowed by max text length and the text - // wasn't really changed - // - // to detect this and generate TEXT_MAXLEN event instead of TEXT_CHANGED - // one in this case we also catch "insert_text" signal - // - // when max len is set to 0 we disconnect our handler as it means that we - // shouldn't check anything any more - if ( len ) - { - g_signal_connect - ( - entry, - "insert_text", - G_CALLBACK(wx_gtk_insert_text_callback), - this - ); - } - else // no max length - { - g_signal_handlers_disconnect_by_func - ( - entry, - (gpointer)wx_gtk_insert_text_callback, - this - ); - } } void wxTextEntry::SendMaxLenEvent() { // remember that the next changed signal is to be ignored to avoid - // generating a dummy wxEVT_COMMAND_TEXT_UPDATED event + // generating a dummy wxEVT_TEXT event //IgnoreNextTextUpdate(); wxWindow * const win = GetEditableWindow(); - wxCommandEvent event(wxEVT_COMMAND_TEXT_MAXLEN, win->GetId()); + wxCommandEvent event(wxEVT_TEXT_MAXLEN, win->GetId()); event.SetEventObject(win); event.SetString(GetValue()); win->HandleWindowEvent(event); } +// ---------------------------------------------------------------------------- +// IM handling +// ---------------------------------------------------------------------------- + +int wxTextEntry::GTKIMFilterKeypress(GdkEventKey* event) const +{ +#if GTK_CHECK_VERSION(2, 22, 0) + if ( gtk_check_version(2, 12, 0) == 0 ) + return gtk_entry_im_context_filter_keypress(GetEntry(), event); +#else // GTK+ < 2.22 + wxUnusedVar(event); +#endif // GTK+ 2.22+ + + return FALSE; +} + +void wxTextEntry::GTKConnectInsertTextSignal(GtkEntry* entry) +{ + g_signal_connect(entry, "insert_text", + G_CALLBACK(wx_gtk_insert_text_callback), this); +} + +bool wxTextEntry::GTKEntryOnInsertText(const char* text) +{ + return GetEditableWindow()->GTKOnInsertText(text); +} + // ---------------------------------------------------------------------------- // margins support // ----------------------------------------------------------------------------