X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/c79146df7ece620777b8e4aa9ad98a8b7be2bac7..81f6ea4a29eb815dbed0adea369efdc8fece0269:/src/gtk/textctrl.cpp?ds=sidebyside diff --git a/src/gtk/textctrl.cpp b/src/gtk/textctrl.cpp index f918d8154f..ea62e18185 100644 --- a/src/gtk/textctrl.cpp +++ b/src/gtk/textctrl.cpp @@ -7,10 +7,6 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) -#pragma implementation "textctrl.h" -#endif - // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" @@ -42,7 +38,6 @@ extern bool g_isIdle; // data //----------------------------------------------------------------------------- -extern bool g_blockEventsOnDrag; extern wxCursor g_globalCursor; extern wxWindowGTK *g_delayedFocus; @@ -51,6 +46,25 @@ extern wxWindowGTK *g_delayedFocus; // ---------------------------------------------------------------------------- #ifdef __WXGTK20__ +extern "C" { +static void wxGtkOnRemoveTag(GtkTextBuffer *buffer, + GtkTextTag *tag, + GtkTextIter *start, + GtkTextIter *end, + char *prefix) +{ + gchar *name; + g_object_get (tag, "name", &name, NULL); + + if (!name || strncmp(name, prefix, strlen(prefix))) + // anonymous tag or not starting with prefix - don't remove + g_signal_stop_emission_by_name(buffer, "remove_tag"); + + g_free(name); +} +} + +extern "C" { static void wxGtkTextApplyTagsFromAttr(GtkTextBuffer *text_buffer, const wxTextAttr& attr, GtkTextIter *start, @@ -59,6 +73,11 @@ static void wxGtkTextApplyTagsFromAttr(GtkTextBuffer *text_buffer, static gchar buf[1024]; GtkTextTag *tag; + gulong remove_handler_id = g_signal_connect( text_buffer, "remove_tag", + G_CALLBACK(wxGtkOnRemoveTag), gpointer("WX")); + gtk_text_buffer_remove_all_tags(text_buffer, start, end); + g_signal_handler_disconnect( text_buffer, remove_handler_id ); + if (attr.HasFont()) { char *font_string; @@ -100,12 +119,52 @@ static void wxGtkTextApplyTagsFromAttr(GtkTextBuffer *text_buffer, "background-gdk", colBg, NULL ); gtk_text_buffer_apply_tag (text_buffer, tag, start, end); } + + if (attr.HasAlignment()) + { + GtkTextIter para_start, para_end = *end; + gtk_text_buffer_get_iter_at_line( text_buffer, + ¶_start, + gtk_text_iter_get_line(start) ); + gtk_text_iter_forward_line(¶_end); + + remove_handler_id = g_signal_connect( text_buffer, "remove_tag", + G_CALLBACK(wxGtkOnRemoveTag), + gpointer("WXALIGNMENT")); + gtk_text_buffer_remove_all_tags( text_buffer, ¶_start, ¶_end ); + g_signal_handler_disconnect( text_buffer, remove_handler_id ); + + GtkJustification align; + switch (attr.GetAlignment()) + { + default: + align = GTK_JUSTIFY_LEFT; + break; + case wxTEXT_ALIGNMENT_RIGHT: + align = GTK_JUSTIFY_RIGHT; + break; + case wxTEXT_ALIGNMENT_CENTER: + align = GTK_JUSTIFY_CENTER; + break; + // gtk+ doesn't support justify as of gtk+-2.7.4 + } + + g_snprintf(buf, sizeof(buf), "WXALIGNMENT %d", align); + tag = gtk_text_tag_table_lookup( gtk_text_buffer_get_tag_table( text_buffer ), + buf ); + if (!tag) + tag = gtk_text_buffer_create_tag( text_buffer, buf, + "justification", align, NULL ); + gtk_text_buffer_apply_tag( text_buffer, tag, ¶_start, ¶_end ); + } +} } +extern "C" { static void wxGtkTextInsert(GtkWidget *text, GtkTextBuffer *text_buffer, const wxTextAttr& attr, - wxCharBuffer buffer) + const wxCharBuffer& buffer) { gint start_offset; @@ -120,7 +179,9 @@ static void wxGtkTextInsert(GtkWidget *text, wxGtkTextApplyTagsFromAttr(text_buffer, attr, &start, &iter); } +} #else +extern "C" { static void wxGtkTextInsert(GtkWidget *text, const wxTextAttr& attr, const char *txt, @@ -138,6 +199,7 @@ static void wxGtkTextInsert(GtkWidget *text, gtk_text_insert( GTK_TEXT(text), font, colFg, colBg, txt, len ); } +} #endif // GTK 1.x // ---------------------------------------------------------------------------- @@ -264,7 +326,7 @@ au_check_word( GtkTextIter *s, GtkTextIter *e ) GtkTextIter start = *s, end = *e; GtkTextBuffer *buffer = gtk_text_iter_get_buffer(s); - + // Get our special link tag GtkTextTag *tag = gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(buffer), "wxUrl"); @@ -614,9 +676,8 @@ bool wxTextCtrl::Create( wxWindow *parent, wrap = GTK_WRAP_WORD_CHAR; } else -#else - wrap = GTK_WRAP_WORD; #endif + wrap = GTK_WRAP_WORD; } gtk_text_view_set_wrap_mode( GTK_TEXT_VIEW( m_text ), wrap ); @@ -856,7 +917,7 @@ void wxTextCtrl::CalculateScrollbar() wxString wxTextCtrl::GetValue() const { - wxCHECK_MSG( m_text != NULL, wxT(""), wxT("invalid text ctrl") ); + wxCHECK_MSG( m_text != NULL, wxEmptyString, wxT("invalid text ctrl") ); wxString tmp; if (m_windowStyle & wxTE_MULTILINE) @@ -908,6 +969,12 @@ void wxTextCtrl::SetValue( const wxString &value ) if (gtk_text_buffer_get_char_count(m_buffer) != 0) IgnoreNextTextUpdate(); + if ( !buffer ) + { + // what else can we do? at least don't crash... + return; + } + gtk_text_buffer_set_text( m_buffer, buffer, strlen(buffer) ); #else @@ -1003,6 +1070,12 @@ void wxTextCtrl::WriteText( const wxString &text ) #else wxCharBuffer buffer( wxConvUTF8.cWC2MB( wxConvLocal.cWX2WC( text ) ) ); #endif + if ( !buffer ) + { + // what else can we do? at least don't crash... + return; + } + gtk_editable_insert_text( GTK_EDITABLE(m_text), buffer, strlen(buffer), &len ); #else @@ -1032,7 +1105,7 @@ wxString wxTextCtrl::GetLineText( long lineNo ) const if (text) { - wxString buf(wxT("")); + wxString buf; long i; int currentLine = 0; for (i = 0; currentLine != lineNo && text[i]; i++ ) @@ -1053,12 +1126,12 @@ wxString wxTextCtrl::GetLineText( long lineNo ) const #else GtkTextIter line; gtk_text_buffer_get_iter_at_line(m_buffer,&line,lineNo); - GtkTextIter end; - gtk_text_buffer_get_end_iter(m_buffer,&end ); + GtkTextIter end = line; + gtk_text_iter_forward_to_line_end(&end); gchar *text = gtk_text_buffer_get_text(m_buffer,&line,&end,TRUE); wxString result(wxGTK_CONV_BACK(text)); g_free(text); - return result.BeforeFirst(wxT('\n')); + return result; #endif } else @@ -1079,6 +1152,15 @@ bool wxTextCtrl::PositionToXY(long pos, long *x, long *y ) const { if ( m_windowStyle & wxTE_MULTILINE ) { +#ifdef __WXGTK20__ + GtkTextIter iter; + gtk_text_buffer_get_iter_at_offset(m_buffer, &iter, pos); + if (gtk_text_iter_is_end(&iter)) + return false; + + *y = gtk_text_iter_get_line(&iter); + *x = gtk_text_iter_get_line_offset(&iter); +#else wxString text = GetValue(); // cast to prevent warning. But pos really should've been unsigned. @@ -1099,6 +1181,7 @@ bool wxTextCtrl::PositionToXY(long pos, long *x, long *y ) const else (*x)++; } +#endif } else // single line control { @@ -1121,17 +1204,45 @@ long wxTextCtrl::XYToPosition(long x, long y ) const { if (!(m_windowStyle & wxTE_MULTILINE)) return 0; +#ifdef __WXGTK20__ + GtkTextIter iter; + if (y >= gtk_text_buffer_get_line_count (m_buffer)) + return -1; + + gtk_text_buffer_get_iter_at_line(m_buffer, &iter, y); + if (x >= gtk_text_iter_get_chars_in_line (&iter)) + return -1; + + return gtk_text_iter_get_offset(&iter) + x; +#else long pos=0; for( int i=0; i last_line) + return -1; + + GtkTextIter iter; + gtk_text_buffer_get_iter_at_line(m_buffer, &iter, lineNo); + // get_chars_in_line return includes paragraph delimiters, so need to subtract 1 IF it is not the last line + return gtk_text_iter_get_chars_in_line(&iter) - ((lineNo == last_line) ? 0 : 1); + } + else +#endif + { + wxString str = GetLineText (lineNo); + return (int) str.Length(); + } } int wxTextCtrl::GetNumberOfLines() const @@ -1472,7 +1583,7 @@ long wxTextCtrl::GetInsertionPoint() const else #endif { - return (long) GET_EDITABLE_POS(m_text); + return (long) GET_EDITABLE_POS(m_text); } } @@ -1686,7 +1797,7 @@ bool wxTextCtrl::IsModified() const void wxTextCtrl::Clear() { - SetValue( wxT("") ); + SetValue( wxEmptyString ); } void wxTextCtrl::OnChar( wxKeyEvent &key_event ) @@ -1857,6 +1968,7 @@ bool wxTextCtrl::SetStyle( long start, long end, const wxTextAttr& style ) // nothing to do return true; } + #ifdef __WXGTK20__ gint l = gtk_text_buffer_get_char_count( m_buffer ); @@ -1873,8 +1985,6 @@ bool wxTextCtrl::SetStyle( long start, long end, const wxTextAttr& style ) wxTextAttr attr = wxTextAttr::Combine(style, m_defaultStyle, this); wxGtkTextApplyTagsFromAttr( m_buffer, attr, &starti, &endi ); - - return true; #else // VERY dirty way to do that - removes the required text and re-adds it // with styling (FIXME) @@ -1892,14 +2002,14 @@ bool wxTextCtrl::SetStyle( long start, long end, const wxTextAttr& style ) gtk_editable_delete_text( GTK_EDITABLE(m_text), start, end ); gtk_editable_set_position( GTK_EDITABLE(m_text), start ); -#if wxUSE_UNICODE + #if wxUSE_UNICODE wxWX2MBbuf buf = tmp.mbc_str(); const char *txt = buf; size_t txtlen = strlen(buf); -#else + #else const char *txt = tmp; size_t txtlen = tmp.length(); -#endif + #endif // use the attributes from style which are set in it and fall back // first to the default style and then to the text control default @@ -1913,13 +2023,13 @@ bool wxTextCtrl::SetStyle( long start, long end, const wxTextAttr& style ) gtk_editable_set_position( GTK_EDITABLE(m_text), old_pos ); */ SetInsertionPoint( old_pos ); #endif + return true; } - else // singe line - { - // cannot do this for GTK+'s Entry widget - return false; - } + + // else single line + // cannot do this for GTK+'s Entry widget + return false; } void wxTextCtrl::DoApplyWidgetStyle(GtkRcStyle *style) @@ -2044,7 +2154,7 @@ void wxTextCtrl::Freeze() gtk_widget_set_sensitive(m_widget, false); g_object_ref(m_buffer); gtk_text_view_set_buffer(GTK_TEXT_VIEW(m_text), gtk_text_buffer_new(NULL)); - } + } #else gtk_text_freeze(GTK_TEXT(m_text)); #endif