X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/648d2bb8f4f7297de680c82cefe8aa37254b55cb..cb98e78b1e363e70d07360728c49b6dd21f36f7c:/src/gtk/textctrl.cpp diff --git a/src/gtk/textctrl.cpp b/src/gtk/textctrl.cpp index 7133259dcb..8275b82b16 100644 --- a/src/gtk/textctrl.cpp +++ b/src/gtk/textctrl.cpp @@ -22,6 +22,7 @@ #include "wx/math.h" #endif +#include "wx/scopeguard.h" #include "wx/strconv.h" #include "wx/fontutil.h" // for wxNativeFontInfo (GetNativeFontInfo()) @@ -243,10 +244,10 @@ static void wxGtkTextApplyTagsFromAttr(GtkWidget *text, const wxArrayInt& tabs = attr.GetTabs(); - wxString tagname = _T("WXTABS"); + wxString tagname = wxT("WXTABS"); g_snprintf(buf, sizeof(buf), "WXTABS"); for (size_t i = 0; i < tabs.GetCount(); i++) - tagname += wxString::Format(_T(" %d"), tabs[i]); + tagname += wxString::Format(wxT(" %d"), tabs[i]); const wxWX2MBbuf buftag = tagname.utf8_str(); @@ -350,7 +351,7 @@ extern "C" { static void au_check_word( GtkTextIter *s, GtkTextIter *e ) { - static const char *URIPrefixes[] = + static const char *const URIPrefixes[] = { "http://", "ftp://", @@ -621,16 +622,10 @@ void wxTextCtrl::Init() m_text = NULL; m_showPositionOnThaw = NULL; - m_gdkHandCursor = NULL; - m_gdkXTermCursor = NULL; } wxTextCtrl::~wxTextCtrl() { - if(m_gdkHandCursor) - gdk_cursor_unref(m_gdkHandCursor); - if(m_gdkXTermCursor) - gdk_cursor_unref(m_gdkXTermCursor); } wxTextCtrl::wxTextCtrl( wxWindow *parent, @@ -692,7 +687,7 @@ bool wxTextCtrl::Create( wxWindow *parent, GTKSetWrapMode(); - GtkScrolledWindowSetBorder(m_widget, style); + GTKScrolledWindowSetBorder(m_widget, style); gtk_widget_add_events( GTK_WIDGET(m_text), GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK ); @@ -703,6 +698,9 @@ bool wxTextCtrl::Create( wxWindow *parent, // a single-line text control: no need for scrollbars m_widget = m_text = gtk_entry_new(); + // work around probable bug in GTK+ 2.18 when calling WriteText on a + // new, empty control, see http://trac.wxwidgets.org/ticket/11409 + gtk_entry_get_text((GtkEntry*)m_text); if (style & wxNO_BORDER) g_object_set (m_text, "has-frame", FALSE, NULL); @@ -759,8 +757,6 @@ bool wxTextCtrl::Create( wxWindow *parent, if (style & wxTE_AUTO_URL) { GtkTextIter start, end; - m_gdkHandCursor = gdk_cursor_new(GDK_HAND2); - m_gdkXTermCursor = gdk_cursor_new(GDK_XTERM); // We create our wxUrl tag here for slight efficiency gain - we // don't have to check for the tag existance in callbacks, @@ -818,6 +814,11 @@ GtkEditable *wxTextCtrl::GetEditable() const return GTK_EDITABLE(m_text); } +GtkEntry *wxTextCtrl::GetEntry() const +{ + return GTK_ENTRY(m_text); +} + // ---------------------------------------------------------------------------- // flags handling // ---------------------------------------------------------------------------- @@ -1252,6 +1253,7 @@ bool wxTextCtrl::Enable( bool enable ) } gtk_widget_set_sensitive( m_text, enable ); + SetCursor(enable ? wxCursor(wxCURSOR_IBEAM) : wxCursor()); return true; } @@ -1332,14 +1334,14 @@ void wxTextCtrl::SetSelection( long from, long to ) { wxCHECK_RET( m_text != NULL, wxT("invalid text ctrl") ); - if (from == -1 && to == -1) - { - from = 0; - to = GetValue().length(); - } - if ( IsMultiLine() ) { + if (from == -1 && to == -1) + { + from = 0; + to = GetValue().length(); + } + GtkTextIter fromi, toi; gtk_text_buffer_get_iter_at_offset( m_buffer, &fromi, from ); gtk_text_buffer_get_iter_at_offset( m_buffer, &toi, to ); @@ -1612,7 +1614,7 @@ void wxTextCtrl::ChangeFontGlobally() // // TODO: it can be implemented much more efficiently for GTK2 wxASSERT_MSG( IsMultiLine(), - _T("shouldn't be called for single line controls") ); + wxT("shouldn't be called for single line controls") ); wxString value = GetValue(); if ( !value.empty() ) @@ -1664,7 +1666,7 @@ bool wxTextCtrl::SetStyle( long start, long end, const wxTextAttr& style ) gint l = gtk_text_buffer_get_char_count( m_buffer ); wxCHECK_MSG( start >= 0 && end <= l, false, - _T("invalid range in wxTextCtrl::SetStyle") ); + wxT("invalid range in wxTextCtrl::SetStyle") ); GtkTextIter starti, endi; gtk_text_buffer_get_iter_at_offset( m_buffer, &starti, start ); @@ -1679,6 +1681,50 @@ bool wxTextCtrl::SetStyle( long start, long end, const wxTextAttr& style ) return false; } +bool wxTextCtrl::GetStyle(long position, wxTextAttr& style) +{ + if ( !IsMultiLine() ) + { + // no styles for GtkEntry + return false; + } + + gint l = gtk_text_buffer_get_char_count( m_buffer ); + + wxCHECK_MSG( position >= 0 && position <= l, false, + wxT("invalid range in wxTextCtrl::GetStyle") ); + + GtkTextIter positioni; + gtk_text_buffer_get_iter_at_offset(m_buffer, &positioni, position); + + // Obtain a copy of the default attributes + GtkTextAttributes * const + pattr = gtk_text_view_get_default_attributes(GTK_TEXT_VIEW(m_text)); + wxON_BLOCK_EXIT1( g_free, pattr ); + + // And query GTK for the attributes at the given position using it as base + if ( !gtk_text_iter_get_attributes(&positioni, pattr) ) + { + style = m_defaultStyle; + } + else // have custom attributes + { + style.SetBackgroundColour(pattr->appearance.bg_color); + style.SetTextColour(pattr->appearance.fg_color); + + const wxGtkString + pangoFontString(pango_font_description_to_string(pattr->font)); + + wxFont font; + if ( font.SetNativeFontInfo(wxString(pangoFontString)) ) + style.SetFont(font); + + // TODO: set alignment, tabs and indents + } + + return true; +} + void wxTextCtrl::DoApplyWidgetStyle(GtkRcStyle *style) { gtk_widget_modify_style(m_text, style); @@ -1819,13 +1865,11 @@ void wxTextCtrl::OnUrlMouseEvent(wxMouseEvent& event) gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(m_text), &end, x, y); if (!gtk_text_iter_has_tag(&end, tag)) { - gdk_window_set_cursor(gtk_text_view_get_window(GTK_TEXT_VIEW(m_text), - GTK_TEXT_WINDOW_TEXT), m_gdkXTermCursor); + SetCursor(wxCursor(wxCURSOR_IBEAM)); return; } - gdk_window_set_cursor(gtk_text_view_get_window(GTK_TEXT_VIEW(m_text), - GTK_TEXT_WINDOW_TEXT), m_gdkHandCursor); + SetCursor(wxCursor(wxCURSOR_HAND)); start = end; if(!gtk_text_iter_begins_tag(&start, tag))