diff options
Diffstat (limited to 'app/wlib/gtklib/gtktext.c')
-rw-r--r-- | app/wlib/gtklib/gtktext.c | 524 |
1 files changed, 524 insertions, 0 deletions
diff --git a/app/wlib/gtklib/gtktext.c b/app/wlib/gtklib/gtktext.c new file mode 100644 index 0000000..8da31d3 --- /dev/null +++ b/app/wlib/gtklib/gtktext.c @@ -0,0 +1,524 @@ +/** \file gtktext.c + * Multi line text entry + */ + +/* XTrkCad - Model Railroad CAD + * Copyright (C) 2005 Dave Bullis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#define GTK_ENABLE_BROKEN +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "gtkint.h" + +/* + * Disable USE_TEXTVIEW to use the deprecated gtk_text + */ +#define USE_TEXTVIEW + +/* + ***************************************************************************** + * + * Multi-line Text Boxes + * + ***************************************************************************** + */ + +struct wText_t { + WOBJ_COMMON + wPos_t width, height; + int changed; + GtkWidget * text; + GtkWidget * vscroll; + }; + +EXPORT void wTextClear( + wText_p bt ) +{ +#ifdef USE_TEXTVIEW + GtkTextBuffer * tb; +#endif + if (bt->text == 0) abort(); +#ifdef USE_TEXTVIEW + tb = gtk_text_view_get_buffer( GTK_TEXT_VIEW(bt->text) ); + gtk_text_buffer_set_text( tb, "", -1 ); + if (bt->option & BO_READONLY) + gtk_text_view_set_editable( GTK_TEXT_VIEW(bt->text), FALSE ); +#else + gtk_text_set_point( GTK_TEXT(bt->text), 0 ); + gtk_text_forward_delete( GTK_TEXT(bt->text), gtk_text_get_length( GTK_TEXT(bt->text) ) ); + if (bt->option & BO_READONLY) + gtk_text_set_editable( GTK_TEXT(bt->text), FALSE ); +#endif + bt->changed = FALSE; +} + +/** + * Add text to a multiline text field. Font is selected as requested. + * Bold is supported if the flags BT_BOLD is set as flags for the entry + * field. For bold, pango text markup is used + * + * + * \param bt IN the text field + * \param text IN text to add + */ + +EXPORT void wTextAppend( + wText_p bt, + const char * text ) +{ +#ifdef USE_TEXTVIEW + GtkTextBuffer * tb; + GtkTextIter ti1, ti2; +// PangoFontDescription *pfd; +#else + static GdkFont * fixedRegularFont = NULL; + static GdkFont * fixedBoldFont = NULL; + static GdkFont * variableRegularFont = NULL; + static GdkFont * variableBoldFont = NULL; + GdkFont * regularFont = NULL; + GdkFont * boldFont = NULL; +#endif + wBool_t doBold; + char * cp; + int len; + + if (bt->text == 0) abort(); +#ifdef USE_TEXTVIEW + tb = gtk_text_view_get_buffer( GTK_TEXT_VIEW(bt->text) ); + //if ((bt->option&BT_FIXEDFONT)) { + ///* creating PangoFontDescription from string, specified in entry */ + //pfd = pango_font_description_from_string("Monospace"); + ///* setting label's font */ + //gtk_widget_modify_font(GTK_WIDGET(tb), pfd); + ///* freeing PangoFontDescription, cause it has been copied by prev. call */ + //pango_font_description_free(pfd); + //} +#else + if ((bt->option&BT_FIXEDFONT)) { + if (fixedRegularFont==NULL) + fixedRegularFont = gdk_font_load( "-*-courier-medium-r-*-*-12-*-*-*-*-*-iso8859-*" ); + if (fixedBoldFont==NULL) + fixedBoldFont = gdk_font_load( "-*-courier-bold-r-*-*-12-*-*-*-*-*-iso8859-*" ); + regularFont = fixedRegularFont; + boldFont = fixedBoldFont; + } else { + if (variableRegularFont==NULL) + variableRegularFont = gdk_font_load( "-*-helvetica-medium-r-*-*-12-*-*-*-*-*-iso8859-*" ); + if (variableBoldFont==NULL) + variableBoldFont = gdk_font_load( "-*-helvetica-bold-r-*-*-12-*-*-*-*-*-iso8859-*" ); + regularFont = variableRegularFont; + boldFont = variableBoldFont; + } +#endif + /*gtk_text_freeze( GTK_TEXT (bt->text) );*/ + doBold = FALSE; + text = gtkConvertInput( text ); + while ( text && *text ) { + if ( (bt->option & BT_DOBOLD) != 0 && + ( cp = strchr( text, doBold?'>':'<' ) ) != NULL ) { + len = cp-text; + cp++; + } else { + len = -1; + cp = NULL; + } + if ( len != 0 ) { +#ifdef USE_TEXTVIEW + gtk_text_buffer_get_bounds( tb, &ti1, &ti2 ); + if ( !doBold ) + gtk_text_buffer_insert( tb, &ti2, text, len ); + else + gtk_text_buffer_insert_with_tags_by_name( tb, &ti2, text, len, "bold", NULL ); +#else + gtk_text_insert( GTK_TEXT(bt->text), doBold?boldFont:regularFont, &bt->text->style->black, NULL, text, len ); +#endif + } + text = cp; + doBold = !doBold; + } + /*gtk_text_set_point( GTK_TEXT(bt->text), gtk_text_get_length( GTK_TEXT(bt->text) )-1 );*/ + /*gtk_text_thaw( GTK_TEXT (bt->text) );*/ + bt->changed = FALSE; +} + +EXPORT void gtkTextFreeze( + wText_p bt ) +{ +#ifdef USE_TEXTVIEW + gtk_text_view_set_editable( GTK_TEXT_VIEW(bt->text), FALSE ); +#else + gtk_text_freeze( GTK_TEXT (bt->text) ); +#endif +} + +EXPORT void gtkTextThaw( + wText_p bt ) +{ +#ifdef USE_TEXTVIEW + gtk_text_view_set_editable( GTK_TEXT_VIEW(bt->text), TRUE ); +#else + gtk_text_thaw( GTK_TEXT (bt->text) ); +#endif +} + +EXPORT void wTextReadFile( + wText_p bt, + const char * fileName ) +{ + FILE * f; + char buff[BUFSIZ+1]; + if (fileName) { + f = fopen( fileName, "r" ); + if (f == NULL) { + perror( fileName ); + return; + } + while (fgets( buff, sizeof buff, f ) != NULL ) { + wTextAppend( bt, buff ); + } + } +} + + +#ifdef USE_TEXTVIEW +static char * gtkGetText( + wText_p bt ) +{ + GtkTextBuffer * tb; + GtkTextIter ti1, ti2; + char * cp; + if (bt->text == 0) abort(); + tb = gtk_text_view_get_buffer( GTK_TEXT_VIEW(bt->text) ); + gtk_text_buffer_get_bounds( tb, &ti1, &ti2 ); + cp = gtk_text_buffer_get_text( tb, &ti1, &ti2, FALSE ); + cp = gtkConvertOutput( cp ); + return cp; +} +#endif + + +EXPORT wBool_t wTextSave( + wText_p bt, + const char * fileName ) +{ +#ifndef USE_TEXTVIEW + int siz, pos, cnt; +#endif + FILE * f; + char * cp; + + f = fopen( fileName, "w" ); + if (f==NULL) { + wNoticeEx( NT_ERROR, fileName, "Ok", NULL ); + return FALSE; + } +#ifdef USE_TEXTVIEW + cp = gtkGetText( bt ); + fwrite( cp, 1, strlen(cp), f ); + free(cp); +#else + siz = gtk_text_get_length( GTK_TEXT(bt->text) ); + pos = 0; + cnt = BUFSIZ; + while (pos<siz) { + if (pos+cnt>siz) + cnt = siz-pos; + cp = gtk_editable_get_chars( GTK_EDITABLE(bt->text), pos, pos+cnt ); + if (cp == NULL) + break; + fwrite( cp, 1, cnt, f ); + free(cp); + pos += cnt; + } +#endif + fclose(f); + return TRUE; +} + + +EXPORT wBool_t wTextPrint( + wText_p bt ) +{ + wPrinterStream_p f; +#ifndef USE_TEXTVIEW + int siz, pos, cnt; +#endif + char * cp; + + f = wPrinterOpen(); + if (f==NULL) { + return FALSE; + } +#ifdef USE_TEXTVIEW + cp = gtkGetText( bt ); + wPrinterWrite( f, cp, strlen(cp) ); + free(cp); + +#else + siz = gtk_text_get_length( GTK_TEXT(bt->text) ); + pos = 0; + cnt = BUFSIZ; + while (pos<siz) { + if (pos+cnt>siz) + cnt = siz-pos; + cp = gtk_editable_get_chars( GTK_EDITABLE(bt->text), pos, pos+cnt ); + if (cp == NULL) + break; + wPrinterWrite( f, cp, cnt ); + free(cp); + pos += cnt; + } +#endif + wPrinterClose(f); + return TRUE; +} + + +EXPORT int wTextGetSize( + wText_p bt ) +{ +#ifdef USE_TEXTVIEW + char * cp = gtkGetText( bt ); + int len = strlen( cp ); + free( cp ); + return len; +#else + return (int)gtk_text_get_length( GTK_TEXT(bt->text) ); +#endif +} + + +EXPORT void wTextGetText( + wText_p bt, + char * text, + int len ) +{ + char * cp; +#ifdef USE_TEXTVIEW + cp = gtkGetText(bt); + strncpy( text, cp, len ); + free( cp ); +#else + cp = gtk_editable_get_chars( GTK_EDITABLE(bt->text), 0, len ); + strncpy( text, cp, len ); +#endif +} + + +EXPORT void wTextSetReadonly ( + wText_p bt, + wBool_t ro ) +{ +#ifdef USE_TEXTVIEW + gtk_text_view_set_editable( GTK_TEXT_VIEW(bt->text), !ro ); +#else + gtk_text_set_editable( GTK_TEXT(bt->text), !ro ); +#endif + if (ro) { + bt->option |= BO_READONLY; + } else { + bt->option &= ~BO_READONLY; + } +} + + +EXPORT wBool_t wTextGetModified( + wText_p bt ) +{ + return bt->changed; +} + + +EXPORT void wTextSetSize( + wText_p bt, + wPos_t w, + wPos_t h ) +{ +#ifdef USE_TEXTVIEW + gtk_widget_set_size_request( bt->widget, w, h ); +// gtk_widget_set_size_request( bt->text, w-15, h ); +// gtk_widget_set_size_request( bt->vscroll, 15, h ); +#else + gtk_widget_set_usize( bt->widget, w, h ); + gtk_widget_set_usize( bt->text, w-15, h ); + gtk_widget_set_usize( bt->vscroll, 15, h ); + gtk_widget_queue_resize( GTK_WIDGET(bt->widget) ); + gtk_widget_queue_resize( GTK_WIDGET(bt->text) ); + gtk_widget_queue_resize( GTK_WIDGET(bt->vscroll) ); +#endif + bt->w = w; + bt->h = h; +} + + +EXPORT void wTextComputeSize( + wText_p bt, + int rows, + int cols, + wPos_t *width, + wPos_t *height ) +{ + *width = rows * 7; + *height = cols * 14; +} + + +EXPORT void wTextSetPosition( + wText_p bt, + int pos ) +{ +#ifdef USE_TEXTVIEW + /* TODO */ +#else + GTK_TEXT(bt->text)->first_line_start_index = pos; + gtk_text_set_word_wrap( GTK_TEXT(bt->text), TRUE ); + gtk_text_set_point( GTK_TEXT(bt->text), pos ); +#endif +} + +static void textChanged( + GtkWidget * widget, + wText_p bt ) +{ + if (bt == 0) + return; + bt->changed = TRUE; +} + +/** + * Create a multi line text entry widget. The created widget is + * configured as requested by the BT_* flags. This includes Monospaced + * font for BT_FIXEDFONT, readonly for BT_READONLY and a markup for + * bold when setup via BT_BOLD. + * + * \param parent IN parent window + * \param x,y IN position + * \param helpstr IN label for linking into help system + * \param labelStr IN label + * \param option IN widget options + * \param width, height IN size of widget + * \return handle for new widget + */ + +EXPORT wText_p wTextCreate( + wWin_p parent, + wPos_t x, + wPos_t y, + const char * helpStr, + const char * labelStr, + long option, + wPos_t width, + wPos_t height ) +{ + wText_p bt; +#ifdef USE_TEXTVIEW + GtkTextBuffer * tb; + PangoFontDescription *pfd; +#else + GtkRequisition requisition; +#endif + bt = gtkAlloc( parent, B_MULTITEXT, x, y, labelStr, sizeof *bt, NULL ); + gtkComputePos( (wControl_p)bt ); + bt->width = width; + bt->height = height; + bt->option = option; + gtkComputePos( (wControl_p)bt ); + +#ifdef USE_TEXTVIEW + bt->widget = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (bt->widget), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + bt->text = gtk_text_view_new(); + if (bt->text == 0) abort(); + gtk_container_add (GTK_CONTAINER (bt->widget), bt->text); + tb = gtk_text_view_get_buffer( GTK_TEXT_VIEW(bt->text) ); + gtk_text_buffer_create_tag( tb, "bold", "weight", PANGO_WEIGHT_BOLD, NULL); +/* gtk_text_buffer_create_tag( tb, "italic", "style", PANGO_STYLE_ITALIC, NULL); */ +/* gtk_text_buffer_create_tag( tb, "bolditalic", "weight", PANGO_WEIGHT_BOLD, "style", PANGO_STYLE_ITALIC, NULL); */ + if ((bt->option & BT_FIXEDFONT)) { + /* creating PangoFontDescription from string, specified in entry */ + pfd = pango_font_description_from_string("Monospace"); + /* setting label's font */ + gtk_widget_modify_font(GTK_WIDGET(bt->text), pfd); + /* freeing PangoFontDescription, cause it has been copied by prev. call */ + pango_font_description_free(pfd); + } + bt->vscroll = gtk_vscrollbar_new( GTK_TEXT_VIEW(bt->text)->vadjustment ); + if (bt->vscroll == 0) abort(); +#else + bt->widget = gtk_hbox_new( FALSE, 0 ); + bt->text = gtk_text_new( NULL, NULL ); + if (bt->text == 0) abort(); + gtk_box_pack_start( GTK_BOX(bt->widget), bt->text, FALSE, FALSE, 0 ); + bt->vscroll = gtk_vscrollbar_new( GTK_TEXT(bt->text)->vadj ); + if (bt->vscroll == 0) abort(); + gtk_box_pack_start( GTK_BOX(bt->widget), bt->vscroll, FALSE, FALSE, 0 ); +#endif + if (option&BT_CHARUNITS) { + width *= 7; + height *= 14; + } + gtk_widget_show( bt->text ); + gtk_widget_show( bt->vscroll ); + gtk_widget_show( bt->widget ); +#ifdef USE_TEXTVIEW +// gtk_widget_set_size_request( GTK_WIDGET(bt->text), width, height ); +// gtk_widget_set_size_request( GTK_WIDGET(bt->vscroll), -1, height ); + gtk_widget_set_size_request( GTK_WIDGET(bt->widget), width+15/*requisition.width*/, height ); +#else + gtk_widget_set_usize( GTK_WIDGET(bt->text), width, height ); + gtk_widget_set_usize( GTK_WIDGET(bt->vscroll), -1, height ); + gtk_widget_size_request( GTK_WIDGET(bt->vscroll), &requisition ); + gtk_widget_set_usize( GTK_WIDGET(bt->widget), width+15/*requisition.width*/, height ); +#endif + if (bt->option&BO_READONLY) { +#ifdef USE_TEXTVIEW + gtk_text_view_set_editable( GTK_TEXT_VIEW(bt->text), FALSE ); + gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(bt->text), FALSE); +#else + gtk_text_set_editable( GTK_TEXT(bt->text), FALSE ); +#endif + } + +#ifdef USE_TEXTVIEW + gtk_fixed_put( GTK_FIXED(parent->widget), bt->widget, bt->realX, bt->realY ); +#else + gtk_container_add( GTK_CONTAINER(parent->widget), bt->widget ); + gtk_widget_set_uposition( bt->widget, bt->realX, bt->realY ); +#endif + gtkControlGetSize( (wControl_p)bt ); + if (labelStr) + bt->labelW = gtkAddLabel( (wControl_p)bt, labelStr ); +#ifdef USE_TEXTVIEW + gtk_text_view_set_wrap_mode( GTK_TEXT_VIEW(bt->text), GTK_WRAP_WORD ); +#else + gtk_text_set_word_wrap( GTK_TEXT(bt->text), TRUE ); +#endif + gtk_widget_realize( bt->text ); + gtkAddButton( (wControl_p)bt ); + gtkAddHelpString( bt->widget, helpStr ); +#ifdef USE_TEXTVIEW + g_signal_connect( G_OBJECT(tb), "changed", GTK_SIGNAL_FUNC(textChanged), bt ); +#else + gtk_signal_connect( GTK_OBJECT(bt->text), "changed", GTK_SIGNAL_FUNC(textChanged), bt ); +#endif + return bt; +} |