summaryrefslogtreecommitdiff
path: root/app/wlib/gtklib/gtktext.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/wlib/gtklib/gtktext.c')
-rw-r--r--app/wlib/gtklib/gtktext.c524
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;
+}