#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())
// data
//-----------------------------------------------------------------------------
-extern wxCursor g_globalCursor;
extern wxWindowGTK *g_delayedFocus;
// ----------------------------------------------------------------------------
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 );
}
}
+//-----------------------------------------------------------------------------
+// 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
//-----------------------------------------------------------------------------
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;
return false;
}
-
- m_vScrollbarVisible = false;
-
bool multi_line = (style & wxTE_MULTILINE) != 0;
if (multi_line)
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 );
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 );
if (multi_line)
{
gtk_widget_show(m_text);
- SetVScrollAdjustment(gtk_scrolled_window_get_vadjustment((GtkScrolledWindow*)m_widget));
}
if (!value.empty())
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());
{
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));
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 )
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) );
// Bring entry's cursor uptodate.
gtk_editable_set_position( GTK_EDITABLE(m_text), len );
}
-
- m_modified = oldModified;
}
void wxTextCtrl::AppendText( const wxString &text )
// max text length support
// ----------------------------------------------------------------------------
-void wxTextCtrl::IgnoreNextTextUpdate()
-{
- m_ignoreNextUpdate = true;
-}
-
bool wxTextCtrl::IgnoreTextUpdate()
{
if ( m_ignoreNextUpdate )
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) )
void wxTextCtrl::OnInternalIdle()
{
- wxCursor cursor = m_cursor;
- if (g_globalCursor.Ok()) cursor = g_globalCursor;
-
if (g_delayedFocus == this)
{
if (GTK_WIDGET_REALIZED(m_widget))