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.c308
1 files changed, 227 insertions, 81 deletions
diff --git a/app/wlib/gtklib/gtktext.c b/app/wlib/gtklib/gtktext.c
index 8da31d3..e067f43 100644
--- a/app/wlib/gtklib/gtktext.c
+++ b/app/wlib/gtklib/gtktext.c
@@ -1,5 +1,5 @@
/** \file gtktext.c
- * Multi line text entry
+ * Multi-line Text Boxes
*/
/* XTrkCad - Model Railroad CAD
@@ -24,7 +24,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-
+#include <math.h>
+#include "i18n.h"
#include "gtkint.h"
/*
@@ -32,13 +33,18 @@
*/
#define USE_TEXTVIEW
-/*
- *****************************************************************************
- *
- * Multi-line Text Boxes
- *
- *****************************************************************************
- */
+
+struct PrintData {
+ wText_p tb;
+ gint lines_per_page;
+ gdouble font_size;
+ gchar **lines;
+ gint total_lines;
+ gint total_pages;
+};
+
+#define HEADER_HEIGHT 20.0
+#define HEADER_GAP 8.5
struct wText_t {
WOBJ_COMMON
@@ -69,16 +75,6 @@ EXPORT void wTextClear(
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 )
@@ -86,7 +82,6 @@ EXPORT void wTextAppend(
#ifdef USE_TEXTVIEW
GtkTextBuffer * tb;
GtkTextIter ti1, ti2;
-// PangoFontDescription *pfd;
#else
static GdkFont * fixedRegularFont = NULL;
static GdkFont * fixedBoldFont = NULL;
@@ -102,14 +97,6 @@ EXPORT void wTextAppend(
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)
@@ -251,42 +238,224 @@ EXPORT wBool_t wTextSave(
fclose(f);
return TRUE;
}
+/**
+ * Begin the printing by retrieving the contents of the text box and
+ * count the lines of text.
+ *
+ * \param operation IN the GTK print operation
+ * \param context IN print context
+ * \param pd IN data structure for user data
+ *
+ */
+
+static void
+begin_print (GtkPrintOperation *operation,
+ GtkPrintContext *context,
+ struct PrintData *pd)
+{
+ gchar *contents;
+ gdouble height;
+
+ contents = gtkGetText( pd->tb );
+ pd->lines = g_strsplit (contents, "\n", 0);
+
+ /* Count the total number of lines in the file. */
+ /* ignore the header lines */
+ pd->total_lines = 6;
+ while (pd->lines[pd->total_lines] != NULL)
+ pd->total_lines++;
+
+ /* Based on the height of the page and font size, calculate how many lines can be
+ * rendered on a single page. A padding of 3 is placed between lines as well.
+ * Space for page header, table header and footer lines is subtracted from the total size
+ */
+ height = gtk_print_context_get_height (context) - (pd->font_size + 3) - 2 * ( HEADER_HEIGHT + HEADER_GAP );
+ pd->lines_per_page = floor (height / (pd->font_size + 3));
+ pd->total_pages = (pd->total_lines - 1) / pd->lines_per_page + 1;
+ gtk_print_operation_set_n_pages (operation, pd->total_pages);
+
+ free( contents );
+}
+/**
+ * Draw the page, which includes a header with the file name and page number along
+ * with one page of text with a font of "Monospace 10".
+ *
+ * \param operation IN the GTK print operation
+ * \param context IN print context
+ * \param page_nr IN page to print
+ * \param pd IN data structure for user data
+ *
+ *
+ */
+
+static void
+draw_page (GtkPrintOperation *operation,
+ GtkPrintContext *context,
+ gint page_nr,
+ struct PrintData *pd )
+{
+ cairo_t *cr;
+ PangoLayout *layout;
+ gdouble width, text_height, height;
+ gint line, i, text_width, layout_height;
+ PangoFontDescription *desc;
+ gchar *page_str;
+
+ cr = gtk_print_context_get_cairo_context (context);
+ width = gtk_print_context_get_width (context);
+
+ layout = gtk_print_context_create_pango_layout (context);
+ desc = pango_font_description_from_string ("Monospace");
+ pango_font_description_set_size (desc, pd->font_size * PANGO_SCALE);
+
+ /*
+ * render the header line with document type parts list on left and
+ * first line of layout title on right
+ */
+
+ pango_layout_set_font_description (layout, desc);
+ pango_layout_set_text (layout, pd->lines[ 0 ], -1); // document type
+ pango_layout_set_width (layout, -1);
+ pango_layout_set_alignment (layout, PANGO_ALIGN_LEFT);
+ pango_layout_get_size (layout, NULL, &layout_height);
+ text_height = (gdouble) layout_height / PANGO_SCALE;
+
+ cairo_move_to (cr, 0, (HEADER_HEIGHT - text_height) / 2);
+ pango_cairo_show_layout (cr, layout);
+
+ pango_layout_set_text (layout, pd->lines[ 2 ], -1); // layout title
+ pango_layout_get_size (layout, &text_width, NULL);
+ pango_layout_set_alignment (layout, PANGO_ALIGN_RIGHT);
+
+ cairo_move_to (cr, width - (text_width / PANGO_SCALE),
+ (HEADER_HEIGHT - text_height) / 2);
+ pango_cairo_show_layout (cr, layout);
+
+ /* Render the column header */
+ cairo_move_to (cr, 0, HEADER_HEIGHT + HEADER_GAP + pd->font_size + 3 );
+ pango_layout_set_text (layout, pd->lines[ 6 ], -1);
+ pango_cairo_show_layout (cr, layout);
+ cairo_rel_move_to (cr, 0, pd->font_size + 3 );
+ pango_layout_set_text (layout, pd->lines[ 7 ], -1);
+ pango_cairo_show_layout (cr, layout);
+
+ /* Render the page text with the specified font and size. */
+ cairo_rel_move_to (cr, 0, pd->font_size + 3 );
+ line = page_nr * pd->lines_per_page + 8;
+ for (i = 0; i < pd->lines_per_page && line < pd->total_lines; i++)
+ {
+ pango_layout_set_text (layout, pd->lines[line], -1);
+ pango_cairo_show_layout (cr, layout);
+ cairo_rel_move_to (cr, 0, pd->font_size + 3);
+ line++;
+ }
+
+ /*
+ * Render the footer line with date on the left and page number
+ * on the right
+ */
+ pango_layout_set_text (layout, pd->lines[ 5 ], -1); // date
+ pango_layout_set_width (layout, -1);
+ pango_layout_set_alignment (layout, PANGO_ALIGN_LEFT);
+ pango_layout_get_size (layout, NULL, &layout_height);
+ text_height = (gdouble) layout_height / PANGO_SCALE;
+
+ height = gtk_print_context_get_height (context);
+ cairo_move_to (cr, 0, height - ((HEADER_HEIGHT - text_height) / 2));
+ pango_cairo_show_layout (cr, layout);
+
+ page_str = g_strdup_printf (_("%d of %d"), page_nr + 1, pd->total_pages); // page number
+ pango_layout_set_text( layout, page_str, -1 );
+ pango_layout_get_size (layout, &text_width, NULL);
+ pango_layout_set_alignment (layout, PANGO_ALIGN_RIGHT);
+
+ cairo_move_to (cr, width - (text_width / PANGO_SCALE),
+ height - ((HEADER_HEIGHT - text_height) / 2));
+ pango_cairo_show_layout (cr, layout);
+
+ g_free (page_str);
+ g_object_unref (layout);
+ pango_font_description_free (desc);
+}
+
+/**
+ * Clean up after the printing operation since it is done.
+ *
+ * \param operation IN the GTK print operation
+ * \param context IN print context
+ * \param pd IN data structure for user data
+ *
+ *
+ */
+static void
+end_print (GtkPrintOperation *operation,
+ GtkPrintContext *context,
+ struct PrintData *pd)
+{
+ g_strfreev (pd->lines);
+ free( pd );
+}
+
+/**
+ * Print the content of a multi line text box. This function is only used
+ * for printing the parts list. So it makes some assumptions on the structure
+ * and the content. Change if the multi line entry is changed.
+ * The deprecated gtk_text is not supported by this function.
+ *
+ * Thanks to Andrew Krause's book for a good starting point.
+ *
+ * \param bt IN the text field
+ * \return TRUE on success, FALSE on error
+ */
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;
+ GtkPrintOperation *operation;
+ GtkWidget *dialog;
+ GError *error = NULL;
+ gint res;
+ struct PrintData *data;
+
+ /* Create a new print operation, applying saved print settings if they exist. */
+ operation = gtk_print_operation_new ();
+ WlibApplySettings( operation );
+
+ data = malloc(sizeof( struct PrintData));
+ data->font_size = 10.0;
+ data->tb = bt;
+
+ g_signal_connect (G_OBJECT (operation), "begin_print",
+ G_CALLBACK (begin_print), (gpointer) data);
+ g_signal_connect (G_OBJECT (operation), "draw_page",
+ G_CALLBACK (draw_page), (gpointer) data);
+ g_signal_connect (G_OBJECT (operation), "end_print",
+ G_CALLBACK (end_print), (gpointer) data);
+
+ /* Run the default print operation that will print the selected file. */
+ res = gtk_print_operation_run (operation, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
+ GTK_WINDOW(gtkMainW->gtkwin), &error);
+
+ /* If the print operation was accepted, save the new print settings. */
+ if (res == GTK_PRINT_OPERATION_RESULT_APPLY)
+ {
+ WlibSaveSettings( operation );
}
-#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;
+ /* Otherwise, report that the print operation has failed. */
+ else if (error)
+ {
+ dialog = gtk_message_dialog_new (GTK_WINDOW (gtkMainW->gtkwin),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
+ error->message);
+
+ g_error_free (error);
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
}
-#endif
- wPrinterClose(f);
+ g_object_unref (operation);
+
return TRUE;
}
@@ -402,21 +571,7 @@ static void textChanged(
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,
@@ -430,7 +585,6 @@ EXPORT wText_p wTextCreate(
wText_p bt;
#ifdef USE_TEXTVIEW
GtkTextBuffer * tb;
- PangoFontDescription *pfd;
#else
GtkRequisition requisition;
#endif
@@ -453,14 +607,6 @@ EXPORT wText_p wTextCreate(
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