X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/a3669332df65cfae18e7540a267bc3400a64aa09..6dcf9888aaa148e9f6d63e7d4d78b9fb6df34b9e:/src/gtk/textctrl.cpp diff --git a/src/gtk/textctrl.cpp b/src/gtk/textctrl.cpp index 5a550f140b..4417e2c99c 100644 --- a/src/gtk/textctrl.cpp +++ b/src/gtk/textctrl.cpp @@ -11,12 +11,16 @@ #include "wx/wxprec.h" #include "wx/textctrl.h" -#include "wx/utils.h" -#include "wx/intl.h" -#include "wx/log.h" + +#ifndef WX_PRECOMP + #include "wx/intl.h" + #include "wx/log.h" + #include "wx/utils.h" + #include "wx/panel.h" + #include "wx/settings.h" +#endif + #include "wx/math.h" -#include "wx/settings.h" -#include "wx/panel.h" #include "wx/strconv.h" #include "wx/fontutil.h" // for wxNativeFontInfo (GetNativeFontInfo()) @@ -32,7 +36,6 @@ // data //----------------------------------------------------------------------------- -extern wxCursor g_globalCursor; extern wxWindowGTK *g_delayedFocus; // ---------------------------------------------------------------------------- @@ -451,7 +454,8 @@ gtk_text_changed_callback( GtkWidget *widget, wxTextCtrl *win ) if (g_isIdle) wxapp_install_idle_handler(); - win->SetModified(); + if ( win->MarkDirtyOnChange() ) + win->MarkDirty(); wxCommandEvent event( wxEVT_COMMAND_TEXT_UPDATED, win->GetId() ); event.SetEventObject( win ); @@ -459,6 +463,48 @@ gtk_text_changed_callback( GtkWidget *widget, wxTextCtrl *win ) } } +//----------------------------------------------------------------------------- +// clipboard events: "copy-clipboard", "cut-clipboard", "paste-clipboard" +//----------------------------------------------------------------------------- + +// common part of the event handlers below +static void +handle_text_clipboard_callback( GtkWidget *widget, wxTextCtrl *win, + wxEventType eventType, const gchar * signal_name) +{ + wxClipboardTextEvent event( eventType, win->GetId() ); + event.SetEventObject( win ); + if ( win->GetEventHandler()->ProcessEvent( event ) ) + { + // don't let the default processing to take place if we did something + // ourselves in the event handler + g_signal_stop_emission_by_name (widget, signal_name); + } +} + +extern "C" { +static void +gtk_copy_clipboard_callback( GtkWidget *widget, wxTextCtrl *win ) +{ + handle_text_clipboard_callback( + widget, win, wxEVT_COMMAND_TEXT_COPY, "copy-clipboard" ); +} + +static void +gtk_cut_clipboard_callback( GtkWidget *widget, wxTextCtrl *win ) +{ + handle_text_clipboard_callback( + widget, win, wxEVT_COMMAND_TEXT_CUT, "cut-clipboard" ); +} + +static void +gtk_paste_clipboard_callback( GtkWidget *widget, wxTextCtrl *win ) +{ + handle_text_clipboard_callback( + widget, win, wxEVT_COMMAND_TEXT_PASTE, "paste-clipboard" ); +} +} + //----------------------------------------------------------------------------- // "expose_event" from scrolled window and textview //----------------------------------------------------------------------------- @@ -506,11 +552,13 @@ END_EVENT_TABLE() void wxTextCtrl::Init() { + m_dontMarkDirty = m_ignoreNextUpdate = m_modified = false; + SetUpdateFont(false); - m_text = - m_vScrollbar = (GtkWidget *)NULL; + + m_text = NULL; m_frozenness = 0; m_gdkHandCursor = NULL; m_gdkXTermCursor = NULL; @@ -557,9 +605,6 @@ bool wxTextCtrl::Create( wxWindow *parent, return false; } - - m_vScrollbarVisible = false; - bool multi_line = (style & wxTE_MULTILINE) != 0; if (multi_line) @@ -573,6 +618,8 @@ bool wxTextCtrl::Create( wxWindow *parent, m_widget = gtk_scrolled_window_new( NULL, NULL ); gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( m_widget ), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC ); + // for ScrollLines/Pages + m_scrollBar[1] = (GtkRange*)((GtkScrolledWindow*)m_widget)->vscrollbar; // Insert view into scrolled window gtk_container_add( GTK_CONTAINER(m_widget), m_text ); @@ -600,8 +647,7 @@ bool wxTextCtrl::Create( wxWindow *parent, gtk_text_view_set_wrap_mode( GTK_TEXT_VIEW( m_text ), wrap ); - if (!HasFlag(wxNO_BORDER)) - gtk_scrolled_window_set_shadow_type( GTK_SCROLLED_WINDOW(m_widget), GTK_SHADOW_IN ); + GtkScrolledWindowSetBorder(m_widget, style); gtk_widget_add_events( GTK_WIDGET(m_text), GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK ); @@ -614,7 +660,7 @@ bool wxTextCtrl::Create( wxWindow *parent, m_text = gtk_entry_new(); if (style & wxNO_BORDER) - g_object_set( GTK_ENTRY(m_text), "has-frame", FALSE, NULL ); + g_object_set (m_text, "has-frame", FALSE, NULL); } m_parent->DoAddChild( this ); @@ -626,7 +672,6 @@ bool wxTextCtrl::Create( wxWindow *parent, if (multi_line) { gtk_widget_show(m_text); - SetVScrollAdjustment(gtk_scrolled_window_get_vadjustment((GtkScrolledWindow*)m_widget)); } if (!value.empty()) @@ -718,6 +763,13 @@ bool wxTextCtrl::Create( wxWindow *parent, G_CALLBACK (gtk_text_changed_callback), this); } + g_signal_connect (m_text, "copy-clipboard", + G_CALLBACK (gtk_copy_clipboard_callback), this); + g_signal_connect (m_text, "cut-clipboard", + G_CALLBACK (gtk_cut_clipboard_callback), this); + g_signal_connect (m_text, "paste-clipboard", + G_CALLBACK (gtk_paste_clipboard_callback), this); + m_cursor = wxCursor( wxCURSOR_IBEAM ); wxTextAttr attrDef(GetForegroundColour(), GetBackgroundColour(), GetFont()); @@ -765,6 +817,13 @@ void wxTextCtrl::SetValue( const wxString &value ) { wxCHECK_RET( m_text != NULL, wxT("invalid text ctrl") ); + // the control won't be modified any more as we programmatically replace + // all the existing text, so reset the flag and don't set it again (and do + // it now, before the text event handler is ran so that IsModified() called + // from there returns the expected value) + m_modified = false; + DontMarkDirtyOnNextChange(); + if (m_windowStyle & wxTE_MULTILINE) { const wxCharBuffer buffer(wxGTK_CONV(value)); @@ -779,17 +838,20 @@ void wxTextCtrl::SetValue( const wxString &value ) gtk_text_buffer_set_text( m_buffer, buffer, strlen(buffer) ); } - else + else // single line { - gtk_entry_set_text( GTK_ENTRY(m_text), wxGTK_CONV( value ) ); + // gtk_entry_set_text() emits two "changed" signals because internally + // it calls gtk_editable_delete_text() and gtk_editable_insert_text() + // but we want to have only one event + IgnoreNextTextUpdate(); + + gtk_entry_set_text( GTK_ENTRY(m_text), wxGTK_CONV(value) ); } // GRG, Jun/2000: Changed this after a lot of discussion in // the lists. wxWidgets 2.2 will have a set of flags to // customize this behaviour. SetInsertionPoint(0); - - m_modified = false; } void wxTextCtrl::WriteText( const wxString &text ) @@ -806,14 +868,19 @@ void wxTextCtrl::WriteText( const wxString &text ) return; } - // gtk_text_changed_callback() will set m_modified to true but m_modified - // shouldn't be changed by the program writing to the text control itself, - // so save the old value and restore when we're done - bool oldModified = m_modified; + // we're changing the text programmatically + DontMarkDirtyOnNextChange(); if ( m_windowStyle & wxTE_MULTILINE ) { - // TODO: Call whatever is needed to delete the selection. + // First remove the selection if there is one + // TODO: Is there an easier GTK specific way to do this? + long from, to; + GetSelection(&from, &to); + if (from != to) + Remove(from, to); + + // Insert the text wxGtkTextInsert( m_text, m_buffer, m_defaultStyle, buffer ); GtkAdjustment *adj = gtk_scrolled_window_get_vadjustment( GTK_SCROLLED_WINDOW(m_widget) ); @@ -837,8 +904,6 @@ void wxTextCtrl::WriteText( const wxString &text ) // Bring entry's cursor uptodate. gtk_editable_set_position( GTK_EDITABLE(m_text), len ); } - - m_modified = oldModified; } void wxTextCtrl::AppendText( const wxString &text ) @@ -1080,11 +1145,6 @@ void wxTextCtrl::DiscardEdits() // max text length support // ---------------------------------------------------------------------------- -void wxTextCtrl::IgnoreNextTextUpdate() -{ - m_ignoreNextUpdate = true; -} - bool wxTextCtrl::IgnoreTextUpdate() { if ( m_ignoreNextUpdate ) @@ -1097,6 +1157,18 @@ bool wxTextCtrl::IgnoreTextUpdate() return false; } +bool wxTextCtrl::MarkDirtyOnChange() +{ + if ( m_dontMarkDirty ) + { + m_dontMarkDirty = false; + + return false; + } + + return true; +} + void wxTextCtrl::SetMaxLength(unsigned long len) { if ( !HasFlag(wxTE_MULTILINE) ) @@ -1601,9 +1673,6 @@ void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent& event) void wxTextCtrl::OnInternalIdle() { - wxCursor cursor = m_cursor; - if (g_globalCursor.Ok()) cursor = g_globalCursor; - if (g_delayedFocus == this) { if (GTK_WIDGET_REALIZED(m_widget))