anjuta-extras r15 - in trunk: . plugins/scintilla
- From: mcora svn gnome org
- To: svn-commits-list gnome org
- Subject: anjuta-extras r15 - in trunk: . plugins/scintilla
- Date: Wed, 8 Apr 2009 22:53:39 +0000 (UTC)
Author: mcora
Date: Wed Apr 8 22:53:39 2009
New Revision: 15
URL: http://svn.gnome.org/viewvc/anjuta-extras?rev=15&view=rev
Log:
* plugins/scintilla/anjuta-breakpoint-enabled-16.xpm:
* plugins/scintilla/anjuta-editor-scintilla.schemas:
* plugins/scintilla/print.c (set_layout_tab_width),
(IntFromHexDigit), (string_to_color),
(anjuta_print_job_info_style_load_font),
(anjuta_print_job_info_style_clear_attributes),
(anjuta_print_job_info_style_set_attributes),
(anjuta_print_job_info_style_set_color_attributes),
(anjuta_print_job_info_style_init),
(anjuta_print_job_info_style_destroy),
(anjuta_print_job_info_style_new), (anjuta_print_job_info_destroy),
(anjuta_print_job_info_new), (anjuta_print_get_style),
(anjuta_print_apply_style), (anjuta_setup_layout),
(anjuta_print_update_page_size_and_margins),
(anjuta_print_layout_line), (anjuta_draw_header),
(anjuta_draw_linenum), (anjuta_end_print), (anjuta_draw_page),
(anjuta_paginate), (anjuta_print_begin), (anjuta_print_setup),
(anjuta_print):
* plugins/scintilla/print.h:
* plugins/scintilla/properties.cxx:
* plugins/scintilla/properties.h:
more files.
Added:
trunk/plugins/scintilla/anjuta-breakpoint-enabled-16.xpm
trunk/plugins/scintilla/anjuta-editor-scintilla.schemas
trunk/plugins/scintilla/print.c
trunk/plugins/scintilla/print.h
trunk/plugins/scintilla/properties.cxx
trunk/plugins/scintilla/properties.h
Modified:
trunk/ChangeLog
Added: trunk/plugins/scintilla/anjuta-breakpoint-enabled-16.xpm
==============================================================================
--- (empty file)
+++ trunk/plugins/scintilla/anjuta-breakpoint-enabled-16.xpm Wed Apr 8 22:53:39 2009
@@ -0,0 +1,47 @@
+/* XPM */
+static char *anjuta_breakpoint_enabled_16_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 25 1",
+" c #A70101",
+". c #A50202",
+"X c #B31B1B",
+"o c #B61F1F",
+"O c #B62222",
+"+ c #B82828",
+"@ c #BC3737",
+"# c #EC1C1C",
+"$ c #EE2929",
+"% c #F13838",
+"& c #F34848",
+"* c #F45757",
+"= c #F46666",
+"- c #F87777",
+"; c #FA8686",
+": c #FB9797",
+"> c #F8A7A7",
+", c #FBB6B6",
+"< c #FDC7C7",
+"1 c #FCD8D8",
+"2 c #FEE6E6",
+"3 c #A70303",
+"4 c #A70202",
+"5 c #A60404",
+"6 c None",
+/* pixels */
+"6666666666666666",
+"666663....366666",
+"66665 2221@36666",
+"6665 11<111 3666",
+"665 1<,,,,<1 366",
+"65 1,>>>,>>,1 46",
+"6.<>::::::;;:<.6",
+"6.1;;;;--==**<.6",
+"6.1--=**&&*&&<.6",
+"6.,-&&&&&&%&=,.6",
+"63O,=%%%%%$=>O 6",
+"664O>=$$$$*>O 66",
+"6664+>&##*>o4666",
+"6666 +>,,:X46666",
+"66666 ....366666",
+"6666666666666666"
+};
Added: trunk/plugins/scintilla/anjuta-editor-scintilla.schemas
==============================================================================
--- (empty file)
+++ trunk/plugins/scintilla/anjuta-editor-scintilla.schemas Wed Apr 8 22:53:39 2009
@@ -0,0 +1,373 @@
+<gconfschemafile>
+ <schemalist>
+ <schema>
+ <key>/schemas/apps/anjuta/preferences/autocomplete.choose.single</key>
+ <applyto>/apps/anjuta/preferences/autocomplete.choose.single</applyto>
+ <owner>anjuta</owner>
+ <type>bool</type>
+ <default>FALSE</default>
+ <locale name="C" />
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/anjuta/preferences/xml.auto.close.tags</key>
+ <applyto>/apps/anjuta/preferences/xml.auto.close.tags</applyto>
+ <owner>anjuta</owner>
+ <type>bool</type>
+ <default>TRUE</default>
+ <locale name="C" />
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/anjuta/preferences/autocompleteword.automatic</key>
+ <applyto>/apps/anjuta/preferences/autocompleteword.automatic</applyto>
+ <owner>anjuta</owner>
+ <type>int</type>
+ <default>3</default>
+ <locale name="C" />
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/anjuta/preferences/fold</key>
+ <applyto>/apps/anjuta/preferences/fold</applyto>
+ <owner>anjuta</owner>
+ <type>bool</type>
+ <default>TRUE</default>
+ <locale name="C" />
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/anjuta/preferences/fold.comment</key>
+ <applyto>/apps/anjuta/preferences/fold.comment</applyto>
+ <owner>anjuta</owner>
+ <type>bool</type>
+ <default>TRUE</default>
+ <locale name="C" />
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/anjuta/preferences/fold.comment.python</key>
+ <applyto>/apps/anjuta/preferences/fold.comment.python</applyto>
+ <owner>anjuta</owner>
+ <type>bool</type>
+ <default>TRUE</default>
+ <locale name="C" />
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/anjuta/preferences/fold.quotes.python</key>
+ <applyto>/apps/anjuta/preferences/fold.quotes.python</applyto>
+ <owner>anjuta</owner>
+ <type>bool</type>
+ <default>TRUE</default>
+ <locale name="C" />
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/anjuta/preferences/fold.html</key>
+ <applyto>/apps/anjuta/preferences/fold.html</applyto>
+ <owner>anjuta</owner>
+ <type>bool</type>
+ <default>TRUE</default>
+ <locale name="C" />
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/anjuta/preferences/fold.compact</key>
+ <applyto>/apps/anjuta/preferences/fold.compact</applyto>
+ <owner>anjuta</owner>
+ <type>bool</type>
+ <default>TRUE</default>
+ <locale name="C" />
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/anjuta/preferences/fold.underline</key>
+ <applyto>/apps/anjuta/preferences/fold.underline</applyto>
+ <owner>anjuta</owner>
+ <type>bool</type>
+ <default>TRUE</default>
+ <locale name="C" />
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/anjuta/preferences/fold.on.open</key>
+ <applyto>/apps/anjuta/preferences/fold.on.open</applyto>
+ <owner>anjuta</owner>
+ <type>bool</type>
+ <default>FALSE</default>
+ <locale name="C" />
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/anjuta/preferences/disable.syntax.hilighting</key>
+ <applyto>/apps/anjuta/preferences/disable.syntax.hilighting</applyto>
+ <owner>anjuta</owner>
+ <type>bool</type>
+ <default>FALSE</default>
+ <locale name="C" />
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/anjuta/preferences/braces.check</key>
+ <applyto>/apps/anjuta/preferences/braces.check</applyto>
+ <owner>anjuta</owner>
+ <type>bool</type>
+ <default>TRUE</default>
+ <locale name="C" />
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/anjuta/preferences/strip.trailing.spaces</key>
+ <applyto>/apps/anjuta/preferences/strip.trailing.spaces</applyto>
+ <owner>anjuta</owner>
+ <type>bool</type>
+ <default>FALSE</default>
+ <locale name="C" />
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/anjuta/preferences/editor.doseol</key>
+ <applyto>/apps/anjuta/preferences/editor.doseol</applyto>
+ <owner>anjuta</owner>
+ <type>bool</type>
+ <default>FALSE</default>
+ <locale name="C" />
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/anjuta/preferences/editor.wrapbookmarks</key>
+ <applyto>/apps/anjuta/preferences/editor.wrapbookmarks</applyto>
+ <owner>anjuta</owner>
+ <type>bool</type>
+ <default>TRUE</default>
+ <locale name="C" />
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/anjuta/preferences/edge.column</key>
+ <applyto>/apps/anjuta/preferences/edge.column</applyto>
+ <owner>anjuta</owner>
+ <type>int</type>
+ <default>80</default>
+ <locale name="C" />
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/anjuta/preferences/caret.period</key>
+ <applyto>/apps/anjuta/preferences/caret.period</applyto>
+ <owner>anjuta</owner>
+ <type>int</type>
+ <default>350</default>
+ <locale name="C" />
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/anjuta/preferences/caret.width</key>
+ <applyto>/apps/anjuta/preferences/caret.width</applyto>
+ <owner>anjuta</owner>
+ <type>int</type>
+ <default>2</default>
+ <locale name="C" />
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/anjuta/preferences/margin.linenumber.width</key>
+ <applyto>/apps/anjuta/preferences/margin.linenumber.width</applyto>
+ <owner>anjuta</owner>
+ <type>int</type>
+ <default>40</default>
+ <locale name="C" />
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/anjuta/preferences/indent.automatic</key>
+ <applyto>/apps/anjuta/preferences/indent.automatic</applyto>
+ <owner>anjuta</owner>
+ <type>bool</type>
+ <default>TRUE</default>
+ <locale name="C" />
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/anjuta/preferences/indent.maintain</key>
+ <applyto>/apps/anjuta/preferences/indent.maintain</applyto>
+ <owner>anjuta</owner>
+ <type>bool</type>
+ <default>FALSE</default>
+ <locale name="C" />
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/anjuta/preferences/tab.indents</key>
+ <applyto>/apps/anjuta/preferences/tab.indents</applyto>
+ <owner>anjuta</owner>
+ <type>bool</type>
+ <default>FALSE</default>
+ <locale name="C" />
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/anjuta/preferences/backspace.unindents</key>
+ <applyto>/apps/anjuta/preferences/backspace.unindents</applyto>
+ <owner>anjuta</owner>
+ <type>bool</type>
+ <default>FALSE</default>
+ <locale name="C" />
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/anjuta/preferences/indent.closing</key>
+ <applyto>/apps/anjuta/preferences/indent.closing</applyto>
+ <owner>anjuta</owner>
+ <type>bool</type>
+ <default>FALSE</default>
+ <locale name="C" />
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/anjuta/preferences/indent.opening</key>
+ <applyto>/apps/anjuta/preferences/indent.opening</applyto>
+ <owner>anjuta</owner>
+ <type>bool</type>
+ <default>FALSE</default>
+ <locale name="C" />
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/anjuta/preferences/use.tabs</key>
+ <applyto>/apps/anjuta/preferences/use.tabs</applyto>
+ <owner>anjuta</owner>
+ <type>bool</type>
+ <default>TRUE</default>
+ <locale name="C" />
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/anjuta/preferences/indent.size</key>
+ <applyto>/apps/anjuta/preferences/indent.size</applyto>
+ <owner>anjuta</owner>
+ <type>int</type>
+ <default>4</default>
+ <locale name="C" />
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/anjuta/preferences/tabsize</key>
+ <applyto>/apps/anjuta/preferences/tabsize</applyto>
+ <owner>anjuta</owner>
+ <type>int</type>
+ <default>4</default>
+ <locale name="C" />
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/anjuta/preferences/view.eol</key>
+ <applyto>/apps/anjuta/preferences/view.eol</applyto>
+ <owner>anjuta</owner>
+ <type>bool</type>
+ <default>FALSE</default>
+ <locale name="C" />
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/anjuta/preferences/view.indentation.guides</key>
+ <applyto>/apps/anjuta/preferences/view.indentation.guides</applyto>
+ <owner>anjuta</owner>
+ <type>bool</type>
+ <default>FALSE</default>
+ <locale name="C" />
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/anjuta/preferences/whitespace</key>
+ <applyto>/apps/anjuta/preferences/whitespace</applyto>
+ <owner>anjuta</owner>
+ <type>bool</type>
+ <default>FALSE</default>
+ <locale name="C" />
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/anjuta/preferences/view.indentation.whitespace</key>
+ <applyto>/apps/anjuta/preferences/view.indentation.whitespace</applyto>
+ <owner>anjuta</owner>
+ <type>bool</type>
+ <default>FALSE</default>
+ <locale name="C" />
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/anjuta/preferences/view.line.wrap</key>
+ <applyto>/apps/anjuta/preferences/view.line.wrap</applyto>
+ <owner>anjuta</owner>
+ <type>bool</type>
+ <default>FALSE</default>
+ <locale name="C" />
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/anjuta/preferences/margin.linenumber.visible</key>
+ <applyto>/apps/anjuta/preferences/margin.linenumber.visible</applyto>
+ <owner>anjuta</owner>
+ <type>bool</type>
+ <default>TRUE</default>
+ <locale name="C" />
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/anjuta/preferences/margin.marker.visible</key>
+ <applyto>/apps/anjuta/preferences/margin.marker.visible</applyto>
+ <owner>anjuta</owner>
+ <type>bool</type>
+ <default>TRUE</default>
+ <locale name="C" />
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/anjuta/preferences/margin.fold.visible</key>
+ <applyto>/apps/anjuta/preferences/margin.fold.visible</applyto>
+ <owner>anjuta</owner>
+ <type>bool</type>
+ <default>TRUE</default>
+ <locale name="C" />
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/anjuta/preferences/print.linenumber.count</key>
+ <applyto>/apps/anjuta/preferences/print.linenumber.count</applyto>
+ <owner>anjuta</owner>
+ <type>int</type>
+ <default>1</default>
+ <locale name="C" />
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/anjuta/preferences/print.linewrap</key>
+ <applyto>/apps/anjuta/preferences/print.linewrap</applyto>
+ <owner>anjuta</owner>
+ <type>bool</type>
+ <default>TRUE</default>
+ <locale name="C" />
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/anjuta/preferences/print.header</key>
+ <applyto>/apps/anjuta/preferences/print.header</applyto>
+ <owner>anjuta</owner>
+ <type>bool</type>
+ <default>TRUE</default>
+ <locale name="C" />
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/anjuta/preferences/print.color</key>
+ <applyto>/apps/anjuta/preferences/print.color</applyto>
+ <owner>anjuta</owner>
+ <type>bool</type>
+ <default>TRUE</default>
+ <locale name="C" />
+ </schema>
+
+ </schemalist>
+</gconfschemafile>
Added: trunk/plugins/scintilla/print.c
==============================================================================
--- (empty file)
+++ trunk/plugins/scintilla/print.c Wed Apr 8 22:53:39 2009
@@ -0,0 +1,976 @@
+/*
+ * print.c
+ *
+ * Copyright (C) 2002 Biswapesh Chattopadhyay <biswapesh_chatterjee tcscal co in>
+ * Copyright (C) 2002 Naba Kumar <kh_naba users sourceforge net>
+ * Copyright (C) 2008 Sebastien Granjoux <seb sfo free fr>
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <ctype.h>
+#include <string.h>
+
+#include <libanjuta/anjuta-utils.h>
+#include <libanjuta/anjuta-preferences.h>
+#include <libanjuta/anjuta-debug.h>
+
+#include "print.h"
+
+#define GTK
+#undef PLAT_GTK
+#define PLAT_GTK 1
+
+#include "Scintilla.h"
+#include "ScintillaWidget.h"
+#include "print.h"
+#include "properties.h"
+
+#define AN_PRINT_FONT_BODY_DEFAULT "courier"
+#define AN_PRINT_FONT_SIZE_BODY_DEFAULT 10
+#define AN_PRINT_MAX_STYLES 256
+#define AN_PRINT_LINENUMBER_STYLE 33
+#define AN_PRINT_DEFAULT_TEXT_STYLE 32
+#define AN_PRINT_HEADER_SIZE_FACTOR 2.2
+#define AN_PRINT_LINE_NUMBER_SEPARATION 12
+#define AN_PRINT_PAGINATION_CHUNK_SIZE 3
+
+typedef struct _PrintJobInfoStyle
+{
+ PangoFontDescription *font;
+ GList *attrs;
+
+ gchar *font_name;
+ gboolean italics;
+ gboolean bold;
+ gint size;
+
+ GdkColor fore_color;
+ GdkColor back_color;
+
+} PrintJobInfoStyle;
+
+typedef struct _PrintPageInfo
+{
+ guint pos;
+ guint line;
+} PrintPageInfo;
+
+typedef struct _PrintJobInfo
+{
+ TextEditor *te;
+
+ /* Print Buffer */
+ gchar *buffer;
+ guint buffer_size;
+
+ /* Page offset */
+ GArray *pages;
+
+ /* Style pool */
+ PrintJobInfoStyle* styles_pool[AN_PRINT_MAX_STYLES];
+
+ /* Preferences */
+ gboolean print_header;
+ gboolean print_color;
+ gboolean print_line_numbers;
+ gboolean wrapping;
+ gint tab_width;
+ gint zoom_factor;
+
+ /* Margin in points */
+ gdouble page_width;
+ gdouble page_height;
+ gdouble margin_top;
+ gdouble margin_bottom;
+ gdouble margin_left;
+ gdouble margin_right;
+ gdouble header_height;
+ gdouble numbers_width;
+ gdouble numbers_height;
+
+ /* GC state */
+ guint current_style;
+ guint current_page;
+ guint current_pos;
+ guint current_line;
+ gdouble current_height;
+
+ /* layout objects */
+ PangoLayout *layout;
+ PangoLayout *line_numbers_layout;
+ PangoLayout *header_layout;
+
+ /* Progress */
+ AnjutaStatus* status;
+
+} PrintJobInfo;
+
+/* Helper functions
+ *---------------------------------------------------------------------------*/
+
+static void
+set_layout_tab_width (PangoLayout *layout, gint width)
+{
+ gchar *str;
+ gint tab_width = 0;
+
+ str = g_strnfill (width, ' ');
+ pango_layout_set_text (layout, str, -1);
+ g_free (str);
+
+ pango_layout_get_size (layout, &tab_width, NULL);
+
+ if (tab_width > 0)
+ {
+ PangoTabArray *tab_array;
+
+ tab_array = pango_tab_array_new (1, FALSE);
+
+ pango_tab_array_set_tab (tab_array,
+ 0,
+ PANGO_TAB_LEFT,
+ tab_width);
+ pango_layout_set_tabs (layout, tab_array);
+
+ pango_tab_array_free (tab_array);
+ }
+}
+
+static int
+IntFromHexDigit(const char ch) {
+ if (isdigit(ch))
+ return ch - '0';
+ else if (ch >= 'A' && ch <= 'F')
+ return ch - 'A' + 10;
+ else if (ch >= 'a' && ch <= 'f')
+ return ch - 'a' + 10;
+ else
+ return 0;
+}
+
+static void
+string_to_color (const char *val, GdkColor* color)
+{
+ /* g_print ("Color = %s\n", val); */
+ color->red = (IntFromHexDigit(val[1]) * 16 + IntFromHexDigit(val[2])) * 256;
+ color->green = (IntFromHexDigit(val[3]) * 16 + IntFromHexDigit(val[4])) * 256;
+ color->blue = (IntFromHexDigit(val[5]) * 16 + IntFromHexDigit(val[6])) * 256;
+}
+
+/* Style info object
+ *---------------------------------------------------------------------------*/
+
+static void
+anjuta_print_job_info_style_load_font (PrintJobInfoStyle *pis)
+{
+ gchar *font_desc, *tmp;
+ gint size = 12;
+
+ g_return_if_fail (pis->font_name);
+
+ /* Setup font */
+ font_desc = g_strdup (pis->font_name);
+ if (pis->size > 0)
+ {
+ size = pis->size;
+ tmp = font_desc;
+ font_desc = g_strdup_printf ("%s %d", tmp, pis->size);
+ g_free (tmp);
+ }
+ if (pis->font)
+ pango_font_description_free (pis->font);
+
+ DEBUG_PRINT ("Print font loading: %s", font_desc);
+ pis->font = pango_font_description_from_string (font_desc);
+ g_free (font_desc);
+}
+
+static void
+anjuta_print_job_info_style_clear_attributes (PrintJobInfoStyle *pis)
+{
+ if (pis->attrs != NULL)
+ g_list_foreach (pis->attrs, (GFunc)pango_attribute_destroy, NULL);
+ g_list_free (pis->attrs);
+ pis->attrs = NULL;
+}
+
+static void
+anjuta_print_job_info_style_set_attributes (PrintJobInfoStyle *pis)
+{
+ PangoAttribute *attr;
+
+ /* Use attribute for font shape */
+ if (pis->bold)
+ {
+ attr = pango_attr_weight_new (PANGO_WEIGHT_BOLD);
+ pis->attrs = g_list_prepend (pis->attrs, attr);
+ }
+ if (pis->italics)
+ {
+ attr = pango_attr_style_new (PANGO_STYLE_ITALIC);
+ pis->attrs = g_list_prepend (pis->attrs, attr);
+ }
+}
+
+static void
+anjuta_print_job_info_style_set_color_attributes (PrintJobInfoStyle *pis)
+{
+ PangoAttribute *attr;
+
+ /* Use attribute for color */
+
+ /* Remove background colors */
+ /*attr = pango_attr_background_new (pis->back_color.red, pis->back_color.green, pis->back_color.blue);
+ pis->attrs = g_list_prepend (pis->attrs, attr);*/
+ attr = pango_attr_foreground_new (pis->fore_color.red, pis->fore_color.green, pis->fore_color.blue);
+ pis->attrs = g_list_prepend (pis->attrs, attr);
+}
+
+static void
+anjuta_print_job_info_style_init (PrintJobInfoStyle *pis, PropsID prop,
+ gchar* lang, guint style)
+{
+ gchar *style_key, *style_string, *val, *opt;
+
+ style_key = g_strdup_printf ("style.%s.%0d", lang, style);
+ style_string = sci_prop_get_expanded (prop, style_key);
+ g_free (style_key);
+ if (!style_string) return;
+
+ val = g_strdup(style_string);
+ opt = val;
+
+ while (opt) {
+ char *cpComma, *colon;
+
+ cpComma = strchr(opt, ',');
+ if (cpComma)
+ *cpComma = '\0';
+ colon = strchr(opt, ':');
+ if (colon)
+ *colon++ = '\0';
+
+ if (0 == strcmp(opt, "italics"))
+ pis->italics = TRUE;
+ if (0 == strcmp(opt, "notitalics"))
+ pis->italics = FALSE;
+ if (0 == strcmp(opt, "bold"))
+ pis->bold = TRUE;
+ if (0 == strcmp(opt, "notbold"))
+ pis->bold = FALSE;
+ if (0 == strcmp(opt, "font")) {
+ g_free (pis->font_name);
+ pis->font_name = g_strdup(colon);
+ }
+ if (0 == strcmp(opt, "fore"))
+ string_to_color(colon, &pis->fore_color);
+ if (0 == strcmp(opt, "back"))
+ string_to_color(colon, &pis->back_color);
+ if (0 == strcmp(opt, "size"))
+ pis->size = atoi(colon);
+ if (cpComma)
+ opt = cpComma + 1;
+ else
+ opt = 0;
+ }
+ g_free(val);
+ g_free(style_string);
+}
+
+static void
+anjuta_print_job_info_style_destroy (PrintJobInfoStyle *pis) {
+ if (pis) {
+ if (pis->attrs)
+ {
+ g_list_foreach (pis->attrs, (GFunc)pango_attribute_destroy, NULL);
+ g_list_free (pis->attrs);
+ }
+ if (pis->font) pango_font_description_free (pis->font);
+ if (pis->font_name) g_free (pis->font_name);
+ g_free(pis);
+ }
+}
+
+static PrintJobInfoStyle*
+anjuta_print_job_info_style_new (PropsID prop, gchar* lang,
+ guint style, gint font_zoom_factor, gboolean color)
+{
+ PrintJobInfoStyle* pis;
+
+ g_return_val_if_fail (prop > 0, NULL);
+ g_return_val_if_fail (style < 256, NULL);
+
+ pis = g_new0 (PrintJobInfoStyle, 1);
+
+ pis->font = NULL;
+ pis->font_name = g_strdup(AN_PRINT_FONT_BODY_DEFAULT);
+ pis->bold = FALSE;
+ pis->italics = FALSE;
+ pis->size = AN_PRINT_FONT_SIZE_BODY_DEFAULT;
+
+ /* Black */
+ pis->fore_color.red = 0;
+ pis->fore_color.green = 0;
+ pis->fore_color.blue = 0;
+
+ /* White */
+ pis->back_color.red = (gushort)(-1);
+ pis->back_color.green = (gushort)(-1);
+ pis->back_color.blue = (gushort)(-1);
+
+ /* Set default style first */
+ anjuta_print_job_info_style_init (pis, prop, "*", 32);
+ if (lang && strlen(lang) > 0) {
+ anjuta_print_job_info_style_init (pis, prop, lang, 32);
+ }
+ /* Then the specific style */
+ anjuta_print_job_info_style_init (pis, prop, "*", style);
+ if (lang && strlen(lang) > 0) {
+ anjuta_print_job_info_style_init (pis, prop, lang, style);
+ }
+
+ pis->size += font_zoom_factor;
+
+ anjuta_print_job_info_style_clear_attributes (pis);
+ anjuta_print_job_info_style_load_font (pis);
+
+ if (!pis->font) {
+ g_warning ("Cannot load document font: %s. Trying Default font: %s.",
+ pis->font_name, AN_PRINT_FONT_BODY_DEFAULT);
+ if (pis->font_name)
+ g_free (pis->font_name);
+ pis->font_name = g_strdup (AN_PRINT_FONT_BODY_DEFAULT);
+ anjuta_print_job_info_style_load_font (pis);
+ }
+ if (!pis->font) {
+ pis->bold = FALSE;
+ anjuta_print_job_info_style_load_font (pis);
+ }
+ if (!pis->font) {
+ pis->italics = FALSE;
+ anjuta_print_job_info_style_load_font (pis);
+ }
+ if (!pis->font) {
+ pis->size = AN_PRINT_FONT_SIZE_BODY_DEFAULT;
+ anjuta_print_job_info_style_load_font (pis);
+ }
+ if (!pis->font) {
+ anjuta_print_job_info_style_destroy (pis);
+ return NULL;
+ }
+
+ anjuta_print_job_info_style_set_attributes (pis);
+
+ if (color)
+ {
+ anjuta_print_job_info_style_set_color_attributes (pis);
+ }
+
+ return pis;
+}
+
+static void
+anjuta_print_job_info_destroy(PrintJobInfo *pji)
+{
+ int i;
+
+ g_return_if_fail (pji);
+
+ if (pji->pages != NULL)
+ g_array_free (pji->pages, TRUE);
+
+ if (pji->layout != NULL)
+ g_object_unref (pji->layout);
+
+ if (pji->line_numbers_layout != NULL)
+ g_object_unref (pji->line_numbers_layout);
+
+ if (pji->header_layout != NULL)
+ g_object_unref (pji->header_layout);
+
+ if (pji->buffer != NULL)
+ g_free(pji->buffer);
+
+ for (i = 0; i < AN_PRINT_MAX_STYLES; i++)
+ {
+ if (pji->styles_pool[i])
+ anjuta_print_job_info_style_destroy (pji->styles_pool[i]);
+ }
+ g_free(pji);
+}
+
+static PrintJobInfo*
+anjuta_print_job_info_new (TextEditor *te)
+{
+ PrintJobInfo *pji;
+
+ pji = g_new0(PrintJobInfo, 1);
+
+ pji->te = te;
+ pji->pages = g_array_new (FALSE, FALSE, sizeof (PrintPageInfo));
+
+ return pji;
+}
+
+static PrintJobInfoStyle*
+anjuta_print_get_style (PrintJobInfo *pji, gint style)
+{
+ PrintJobInfoStyle* pis;
+
+ pis = pji->styles_pool[style];
+
+ if (!pis) {
+ gchar* language;
+ language = (gchar*) aneditor_command(pji->te->editor_id, ANE_GETLANGUAGE,0, 0);
+ pis = anjuta_print_job_info_style_new (pji->te->props_base,
+ language, style, pji->zoom_factor, pji->print_color);
+ pji->styles_pool[style] = pis;
+ }
+
+ if (!pis && style != AN_PRINT_DEFAULT_TEXT_STYLE) {
+ pis = anjuta_print_get_style (pji, AN_PRINT_DEFAULT_TEXT_STYLE);
+ }
+
+ return pis;
+}
+
+/* Change style of main layout */
+static void
+anjuta_print_apply_style (PrintJobInfo *pji, gint style, guint start, guint end)
+{
+ PrintJobInfoStyle* pis;
+
+ pis = anjuta_print_get_style (pji, style);
+ g_return_if_fail (pis != NULL);
+
+ pango_layout_set_font_description (pji->layout, pis->font);
+
+ if (pis->attrs)
+ {
+ PangoAttrList *attr_list;
+ PangoAttrList *new_list = NULL;
+ GList *node;
+
+ attr_list = pango_layout_get_attributes (pji->layout);
+ if ((attr_list == NULL) || (start == 0))
+ {
+ attr_list = pango_attr_list_new ();
+ new_list = attr_list;
+ }
+
+ for (node = g_list_first (pis->attrs); node != NULL; node = g_list_next (node))
+ {
+ PangoAttribute *a = pango_attribute_copy ((PangoAttribute *)node->data);
+
+ a->start_index = start;
+ a->end_index = end;
+
+ pango_attr_list_insert (attr_list, a);
+ }
+ pango_layout_set_attributes (pji->layout, attr_list);
+ if (new_list) pango_attr_list_unref (new_list);
+ }
+}
+
+static void
+anjuta_setup_layout (PrintJobInfo *pji, GtkPrintContext *context)
+{
+ g_return_if_fail (pji->layout == NULL);
+
+ /* Layout for header */
+ if (pji->print_header)
+ {
+ pji->layout = gtk_print_context_create_pango_layout (context);
+ anjuta_print_apply_style (pji, AN_PRINT_DEFAULT_TEXT_STYLE, 0, G_MAXUINT);
+
+ g_return_if_fail (pji->header_layout == NULL);
+ pji->header_layout = pji->layout;
+ }
+
+ /* Layout for line numbers */
+ if (pji->print_line_numbers)
+ {
+ pji->layout = gtk_print_context_create_pango_layout (context);
+ anjuta_print_apply_style (pji, AN_PRINT_LINENUMBER_STYLE, 0, G_MAXUINT);
+
+ g_return_if_fail (pji->line_numbers_layout == NULL);
+ pji->line_numbers_layout = pji->layout;
+
+ pango_layout_set_alignment (pji->line_numbers_layout, PANGO_ALIGN_RIGHT);
+ }
+
+ /* Layout for the text */
+ pji->layout = gtk_print_context_create_pango_layout (context);
+ anjuta_print_apply_style (pji, AN_PRINT_DEFAULT_TEXT_STYLE, 0, G_MAXUINT);
+
+ if (pji->wrapping)
+ {
+ pango_layout_set_wrap (pji->layout, PANGO_WRAP_WORD_CHAR);
+ }
+ set_layout_tab_width (pji->layout, pji->tab_width);
+}
+
+static void
+anjuta_print_update_page_size_and_margins (PrintJobInfo *pji, GtkPrintContext *context)
+{
+ GtkPageSetup *page_setup;
+
+ page_setup = gtk_print_context_get_page_setup (context);
+
+ pji->margin_left = gtk_page_setup_get_left_margin (page_setup, GTK_UNIT_POINTS);
+ pji->margin_right = gtk_page_setup_get_right_margin (page_setup, GTK_UNIT_POINTS);
+ pji->margin_top = gtk_page_setup_get_top_margin (page_setup, GTK_UNIT_POINTS);
+ pji->margin_bottom = gtk_page_setup_get_bottom_margin (page_setup, GTK_UNIT_POINTS);
+
+ pji->page_width = gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_POINTS);
+ pji->page_height = gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_POINTS);
+
+ if (pji->print_line_numbers)
+ {
+ gint line_count;
+ gchar *str;
+ gint padding;
+ PangoRectangle rect;
+
+ line_count = text_editor_get_total_lines (pji->te) + 1;
+ for (padding = 1; line_count >= 10; padding++) line_count /= 10;
+ str = g_strnfill (padding, '9');
+ pango_layout_set_text (pji->line_numbers_layout, str, -1);
+ g_free (str);
+
+ pango_layout_get_extents (pji->line_numbers_layout, NULL, &rect);
+
+ pji->numbers_width = ((gdouble) rect.width + (gdouble)AN_PRINT_LINE_NUMBER_SEPARATION) / (gdouble) PANGO_SCALE;
+ pji->numbers_height = (gdouble) rect.height / (gdouble) PANGO_SCALE;
+ }
+ else
+ {
+ pji->numbers_width = 0.0;
+ pji->numbers_height = 0.0;
+ }
+
+ if (pji->print_header)
+ {
+ PangoContext *pango_context;
+ PangoFontMetrics* font_metrics;
+ const PangoFontDescription *font;
+ gdouble ascent;
+ gdouble descent;
+
+ pango_context = gtk_print_context_create_pango_context (context);
+ font = pango_layout_get_font_description (pji->header_layout);
+ pango_context_set_font_description (pango_context, font);
+
+ font_metrics = pango_context_get_metrics (pango_context, font, gtk_get_default_language());
+
+ ascent = (gdouble) pango_font_metrics_get_ascent (font_metrics);
+ descent = (gdouble) pango_font_metrics_get_descent (font_metrics);
+ pango_font_metrics_unref (font_metrics);
+ g_object_unref (pango_context);
+
+ pji->header_height = (gdouble)(ascent + descent) / PANGO_SCALE;
+ pji->header_height *= AN_PRINT_HEADER_SIZE_FACTOR;
+ }
+ else
+ {
+ pji->header_height = 0.0;
+ }
+
+ pango_layout_set_width (pji->layout, (pji->page_width - pji->margin_left - pji->numbers_width - pji->margin_right) * PANGO_SCALE);
+}
+
+static void
+anjuta_print_layout_line (PrintJobInfo *pji)
+{
+ gchar utf8_char[4];
+ gchar style;
+ const gchar *text;
+ GString *line_buffer;
+ guint last_change;
+ gint current_style;
+
+ /* Read a complete line */
+ line_buffer = g_string_new (NULL);
+ last_change = 0;
+ current_style = pji->buffer[pji->current_pos *2 + 1];
+
+ for (text = &pji->buffer[pji->current_pos * 2]; (*text != '\n') && (pji->current_pos < pji->buffer_size); text = &pji->buffer[pji->current_pos * 2])
+ {
+ gint len;
+
+ /* Buffer contains data bytes merged with style bytes */
+ utf8_char[0] = text[0];
+ utf8_char[1] = text[2];
+ utf8_char[2] = text[4];
+ utf8_char[3] = text[8];
+ style = text[1];
+
+ /* Change style if necessary */
+ if (style != current_style)
+ {
+ anjuta_print_apply_style (pji, current_style, last_change, line_buffer->len);
+ last_change = line_buffer->len;
+ current_style= style;
+ }
+
+ /* Append character */
+ len = g_utf8_next_char (utf8_char) - utf8_char;
+ g_string_append_len (line_buffer, utf8_char, len);
+
+ pji->current_pos += len;
+ }
+ pji->current_pos++;
+
+ anjuta_print_apply_style (pji, current_style, last_change, G_MAXUINT);
+ if (line_buffer->len == 0)
+ {
+ /* Empty line, display just one space */
+ pango_layout_set_text (pji->layout," ", 1);
+ }
+ else
+ {
+ pango_layout_set_text (pji->layout,line_buffer->str, line_buffer->len);
+ }
+
+ g_string_free (line_buffer, TRUE);
+}
+
+static void
+anjuta_draw_header (PrintJobInfo * pji, cairo_t *cr)
+{
+ gchar *text1 = g_strdup_printf (_("File: %s"), pji->te->filename);
+ gchar *text2 = g_strdup_printf ("%d", pji->current_page + 1);
+ gdouble baseline;
+ gdouble header_width;
+ gdouble layout_width;
+ PangoLayoutIter *iter;
+ PangoRectangle rect;
+ PangoLayoutLine* line;
+ gdouble x;
+
+ pango_cairo_update_layout (cr, pji->header_layout);
+
+ header_width = pji->page_width - pji->margin_left - pji->margin_right;
+
+ /* Print filename on left */
+ pango_layout_set_text (pji->header_layout, text1, -1);
+ iter = pango_layout_get_iter (pji->header_layout);
+ baseline = (gdouble) pango_layout_iter_get_baseline (iter) / (gdouble) PANGO_SCALE;
+
+ x =pji->margin_left;
+
+ line = pango_layout_iter_get_line_readonly (iter);
+ pango_layout_iter_free (iter);
+ cairo_move_to (cr, x, pji->margin_top + baseline);
+ pango_cairo_show_layout_line (cr, line);
+
+ /* Print page number on right */
+ pango_layout_set_text (pji->header_layout, text2, -1);
+ iter = pango_layout_get_iter (pji->header_layout);
+ baseline = (gdouble) pango_layout_iter_get_baseline (iter) / (gdouble) PANGO_SCALE;
+
+ pango_layout_get_extents (pji->header_layout, NULL, &rect);
+ layout_width = (double) rect.width / (double) PANGO_SCALE;
+ x = pji->margin_left + header_width - layout_width;
+
+ line = pango_layout_iter_get_line_readonly (iter);
+ pango_layout_iter_free (iter);
+ cairo_move_to (cr, x, pji->margin_top + baseline);
+ pango_cairo_show_layout_line (cr, line);
+
+ g_free (text1);
+ g_free (text2);
+}
+
+static void
+anjuta_draw_linenum (PrintJobInfo * pji, cairo_t *cr)
+{
+ gchar *text = g_strdup_printf ("%d", pji->current_line);
+ gdouble baseline;
+ gdouble layout_width;
+ PangoLayoutIter *iter;
+ PangoRectangle rect;
+ gdouble x;
+
+ pango_cairo_update_layout (cr, pji->line_numbers_layout);
+
+ /* Print line number on right */
+ pango_layout_set_text (pji->line_numbers_layout, text, -1);
+ iter = pango_layout_get_iter (pji->line_numbers_layout);
+ baseline = (gdouble) pango_layout_iter_get_baseline (iter) / (gdouble) PANGO_SCALE;
+ pango_layout_iter_free (iter);
+
+ pango_layout_get_extents (pji->line_numbers_layout, NULL, &rect);
+ layout_width = (double) rect.width / (double) PANGO_SCALE;
+ x = pji->margin_left + pji->numbers_width - layout_width - AN_PRINT_LINE_NUMBER_SEPARATION;
+
+ cairo_move_to (cr, x, pji->current_height);
+ pango_cairo_show_layout (cr, pji->line_numbers_layout);
+
+ g_free (text);
+}
+
+static void
+anjuta_end_print (GtkPrintOperation *operation,
+ GtkPrintContext *context,
+ PrintJobInfo *pji)
+{
+ anjuta_print_job_info_destroy (pji);
+}
+
+static void
+anjuta_draw_page (GtkPrintOperation *operation,
+ GtkPrintContext *context,
+ gint page_nr,
+ PrintJobInfo *pji)
+{
+ cairo_t *cr;
+ gdouble x;
+ gboolean done;
+ guint page_end;
+
+ g_return_if_fail (GTK_IS_PRINT_CONTEXT (context));
+
+ pji->current_page = page_nr;
+
+ cr = gtk_print_context_get_cairo_context (context);
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_translate (cr,
+ -1 * pji->margin_left,
+ -1 * pji->margin_top);
+
+ if (pji->print_header)
+ {
+ anjuta_draw_header (pji, cr);
+ }
+
+ pji->current_pos = g_array_index (pji->pages, PrintPageInfo, page_nr).pos;
+ pji->current_line = g_array_index (pji->pages, PrintPageInfo, page_nr).line;
+ if (pji->pages->len <= (page_nr + 1))
+ {
+ page_end = pji->buffer_size;
+ }
+ else
+ {
+ page_end = g_array_index (pji->pages, PrintPageInfo, page_nr + 1).pos;
+ }
+
+ pango_cairo_update_layout (cr, pji->layout);
+
+ x = pji->margin_left + pji->numbers_width;
+ pji->current_height = pji->margin_top + pji->header_height;
+
+ done = pji->current_pos >= page_end;
+ while (!done)
+ {
+ PangoRectangle rect;
+ gdouble height;
+ guint start;
+
+ /* Draw line number */
+ if (pji->print_line_numbers)
+ {
+ anjuta_draw_linenum (pji, cr);
+ }
+
+ /* Layout one line */
+ start = pji->current_pos;
+ anjuta_print_layout_line (pji);
+
+ /* Draw line */
+ cairo_move_to (cr, x, pji->current_height);
+ pango_cairo_show_layout (cr, pji->layout);
+
+ /* Print next line */
+ pango_layout_get_extents (pji->layout, NULL, &rect);
+ height = rect.height / PANGO_SCALE;
+ if (height < pji->numbers_height)
+ {
+ height = pji->numbers_height;
+ }
+ pji->current_height += height;
+ pji->current_line ++;
+
+ done = pji->current_pos >= page_end;
+ }
+}
+
+static gboolean
+anjuta_paginate (GtkPrintOperation *operation,
+ GtkPrintContext *context,
+ PrintJobInfo *pji)
+{
+ gdouble text_height;
+ guint page_count;
+ gboolean done;
+
+ text_height = pji->page_height - pji->margin_top - pji->header_height - pji->header_height;
+ page_count = 0;
+ done = pji->current_pos >= pji->buffer_size;
+
+ /* Mark beginning of a page */
+ if (pji->pages->len == pji->current_page)
+ {
+ PrintPageInfo info = {pji->current_pos, pji->current_line};
+ g_array_append_val (pji->pages, info);
+ }
+
+ while (!done && (page_count < AN_PRINT_PAGINATION_CHUNK_SIZE))
+ {
+ PangoRectangle rect;
+ gdouble height;
+ guint start;
+
+ /* Layout one line */
+ start = pji->current_pos;
+ anjuta_print_layout_line (pji);
+ pango_layout_get_extents (pji->layout, NULL, &rect);
+ height = rect.height / PANGO_SCALE;
+
+ if (height < pji->numbers_height)
+ {
+ height = pji->numbers_height;
+ }
+
+ pji->current_height += height;
+ if (pji->current_height > text_height)
+ {
+ PrintPageInfo info = {start, pji->current_line};
+
+ /* New page */
+ pji->current_page++;
+ pji->current_height = height;
+ g_array_append_val (pji->pages, info);
+ page_count++;
+ }
+ pji->current_line++;
+
+ done = pji->current_pos >= pji->buffer_size;
+ }
+
+ gtk_print_operation_set_n_pages (operation, pji->pages->len);
+
+ return done;
+}
+
+/* Second function called after displaying print dialog but before start
+ * printing */
+static void
+anjuta_print_begin (GtkPrintOperation *operation,
+ GtkPrintContext *context,
+ PrintJobInfo *pji)
+{
+ gint i;
+
+ /* Load Buffer to be printed. The buffer loaded is the text/style combination.*/
+ pji->buffer_size = scintilla_send_message(SCINTILLA(pji->te->scintilla), SCI_GETLENGTH, 0, 0);
+ pji->buffer = (gchar *) aneditor_command(pji->te->editor_id, ANE_GETSTYLEDTEXT, 0, pji->buffer_size);
+ if (pji->buffer == NULL)
+ {
+ anjuta_util_dialog_error(NULL, _("Unable to get text buffer for printing"));
+ gtk_print_operation_cancel (operation);
+ anjuta_print_job_info_destroy(pji);
+ }
+
+ /* State variables initializations */
+ g_array_set_size (pji->pages, 0);
+ for (i = 0; i < AN_PRINT_MAX_STYLES; i++) pji->styles_pool[i] = NULL;
+ pji->current_style = 0;
+ pji->current_page = 0;
+ pji->current_pos = 0;
+ pji->current_height = 0.0;
+ pji->current_line = 1;
+
+ /* setup layout */
+ anjuta_setup_layout (pji, context);
+
+ /* Margin settings */
+ anjuta_print_update_page_size_and_margins (pji, context);
+}
+
+/* First print function called before displayed print dialog */
+static GtkPrintOperation*
+anjuta_print_setup (AnjutaPreferences *p, TextEditor *te)
+{
+ PrintJobInfo *pji;
+ GtkPrintOperation* operation;
+
+ scintilla_send_message (SCINTILLA (te->scintilla), SCI_COLOURISE, 0, -1);
+
+ /* Anjuta print layout object */
+ pji = anjuta_print_job_info_new(te);
+
+ /* Set preferences */
+ pji->print_line_numbers =
+ anjuta_preferences_get_int_with_default (p, PRINT_LINENUM_COUNT, 1);
+ pji->print_header =
+ anjuta_preferences_get_int_with_default (p, PRINT_HEADER, 1);
+ pji->print_color =
+ anjuta_preferences_get_int_with_default (p, PRINT_COLOR, 1);
+ pji->wrapping =
+ anjuta_preferences_get_int_with_default (p, PRINT_WRAP, 1);
+ pji->tab_width =
+ anjuta_preferences_get_int_with_default (p, TAB_SIZE, 8);
+ pji->zoom_factor = anjuta_preferences_get_int (te->preferences,
+ TEXT_ZOOM_FACTOR);
+
+
+ /* Set progress bar */
+ pji->status = anjuta_shell_get_status (te->shell, NULL);
+ anjuta_status_progress_reset (pji->status);
+ anjuta_status_progress_add_ticks (pji->status, 100);
+
+ /* Gtk print operation object */
+ operation = gtk_print_operation_new ();
+
+ gtk_print_operation_set_job_name (operation, te->filename);
+ gtk_print_operation_set_show_progress (operation, TRUE);
+
+ g_signal_connect (G_OBJECT (operation), "begin-print",
+ G_CALLBACK (anjuta_print_begin), pji);
+ g_signal_connect (G_OBJECT (operation), "paginate",
+ G_CALLBACK (anjuta_paginate), pji);
+ g_signal_connect (G_OBJECT (operation), "draw-page",
+ G_CALLBACK (anjuta_draw_page), pji);
+ g_signal_connect (G_OBJECT (operation), "end-print",
+ G_CALLBACK (anjuta_end_print), pji);
+
+ return operation;
+}
+
+void
+anjuta_print (gboolean preview, AnjutaPreferences *p, TextEditor *te)
+{
+ GtkPrintOperation* operation;
+
+ if (te == NULL)
+ {
+ anjuta_util_dialog_error (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET(te))),
+ _("No file to print!"));
+ return;
+ }
+
+ operation = anjuta_print_setup (p, te);
+ gtk_print_operation_run (operation,
+ preview ? GTK_PRINT_OPERATION_ACTION_PREVIEW :
+ GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
+ NULL, NULL);
+ g_object_unref (operation);
+}
Added: trunk/plugins/scintilla/print.h
==============================================================================
--- (empty file)
+++ trunk/plugins/scintilla/print.h Wed Apr 8 22:53:39 2009
@@ -0,0 +1,40 @@
+/*
+ * print.h
+ *
+ * Copyright (C) 2002 Biswapesh Chattopadhyay <biswapesh_chatterjee tcscal co in>
+ * Copyright (C) 2002 Naba Kumar <kh_naba users sourceforge net>
+ * Copyright (C) 2008 Sebastien Granjoux <seb sfo free fr>
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AN_PRINTING_PRINT_H
+#define AN_PRINTING_PRINT_H
+
+#include "text_editor.h"
+
+G_BEGIN_DECLS
+
+void anjuta_print (gboolean preview, AnjutaPreferences *p, TextEditor *te);
+
+#define PRINT_HEADER "print.header"
+#define PRINT_WRAP "print.linewrap"
+#define PRINT_LINENUM_COUNT "print.linenumber.count"
+#define PRINT_LANDSCAPE "print.landscape"
+#define PRINT_COLOR "print.color"
+
+G_END_DECLS
+
+#endif /* AN_PRINTING_PRINT_H */
Added: trunk/plugins/scintilla/properties.cxx
==============================================================================
--- (empty file)
+++ trunk/plugins/scintilla/properties.cxx Wed Apr 8 22:53:39 2009
@@ -0,0 +1,556 @@
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include <libanjuta/anjuta-utils.h>
+#include <libanjuta/anjuta-debug.h>
+
+#define GTK
+#undef PLAT_GTK
+#define PLAT_GTK 1
+
+#include "PropSet.h"
+#include "properties_cxx.h"
+#include "properties.h"
+
+bool PropSetFile::caseSensitiveFilenames = false;
+
+PropSetFile::PropSetFile(bool lowerKeys_) : lowerKeys(lowerKeys_) {}
+
+PropSetFile::~PropSetFile() {}
+
+/**
+ * Get a line of input. If end of line escaped with '\\' then continue reading.
+ */
+static bool GetFullLine(const char *&fpc, int &lenData, char *s, int len) {
+ bool continuation = true;
+ s[0] = '\0';
+ while ((len > 1) && lenData > 0) {
+ char ch = *fpc;
+ fpc++;
+ lenData--;
+ if ((ch == '\r') || (ch == '\n')) {
+ if (!continuation) {
+ if ((lenData > 0) && (ch == '\r') && ((*fpc) == '\n')) {
+ // munch the second half of a crlf
+ fpc++;
+ lenData--;
+ }
+ *s = '\0';
+ return true;
+ }
+ } else if ((ch == '\\') && (lenData > 0) && ((*fpc == '\r') || (*fpc == '\n'))) {
+ continuation = true;
+ if ((lenData > 1) && ((*fpc == '\r') && (*(fpc+1) == '\r') || (*fpc == '\n') && (*(fpc+1) == '\n')))
+ continuation = false;
+ else if ((lenData > 2) && ((*fpc == '\r') && (*(fpc+1) == '\n') && (*(fpc+2) == '\n' || *(fpc+2) == '\r')))
+ continuation = false;
+ } else {
+ continuation = false;
+ *s++ = ch;
+ *s = '\0';
+ len--;
+ }
+ }
+ return false;
+}
+
+static bool IsSpaceOrTab(char ch) {
+ return (ch == ' ') || (ch == '\t');
+}
+
+static bool IsCommentLine(const char *line) {
+ while (IsSpaceOrTab(*line)) ++line;
+ return (*line == '#');
+}
+
+bool PropSetFile::ReadLine(const char *lineBuffer, bool ifIsTrue, const char *directoryForImports) {
+ if (!IsSpaceOrTab(lineBuffer[0])) // If clause ends with first non-indented line
+ ifIsTrue = true;
+ if (isprefix(lineBuffer, "if ")) {
+ const char *expr = lineBuffer + strlen("if") + 1;
+ ifIsTrue = GetInt(expr) != 0;
+ } else if (isprefix(lineBuffer, "import ") && directoryForImports) {
+ char importPath[1024];
+ strcpy(importPath, directoryForImports);
+ strcat(importPath, lineBuffer + strlen("import") + 1);
+ strcat(importPath, ".properties");
+ Read(importPath, directoryForImports);
+ } else if (ifIsTrue && !IsCommentLine(lineBuffer)) {
+ Set(lineBuffer);
+ }
+ return ifIsTrue;
+}
+
+void PropSetFile::ReadFromMemory(const char *data, int len, const char *directoryForImports) {
+ const char *pd = data;
+ char lineBuffer[60000];
+ bool ifIsTrue = true;
+ while (len > 0) {
+ GetFullLine(pd, len, lineBuffer, sizeof(lineBuffer));
+ if (lowerKeys) {
+ for (int i=0; lineBuffer[i] && (lineBuffer[i] != '='); i++) {
+ if ((lineBuffer[i] >= 'A') && (lineBuffer[i] <= 'Z')) {
+ lineBuffer[i] = static_cast<char>(lineBuffer[i] - 'A' + 'a');
+ }
+ }
+ }
+ ifIsTrue = ReadLine(lineBuffer, ifIsTrue, directoryForImports);
+ }
+}
+
+bool PropSetFile::Read(const char *filename, const char *directoryForImports) {
+#ifdef __vms
+ FILE *rcfile = fopen(filename, "r");
+#else
+ FILE *rcfile = fopen(filename, "rb");
+#endif
+ if (rcfile) {
+ unsigned int lenFile;
+ char *propsData;
+
+ fseek (rcfile, 0, SEEK_END);
+ lenFile = ftell (rcfile);
+ fseek (rcfile, 0, SEEK_SET);
+ propsData = new char[lenFile];
+ lenFile = fread(propsData, 1, lenFile, rcfile);
+ fclose(rcfile);
+ ReadFromMemory(propsData, lenFile, directoryForImports);
+ delete[] propsData;
+ return true;
+
+ } else {
+ //printf("Could not open <%s>\n", filename);
+ return false;
+ }
+}
+
+static inline char MakeUpperCase(char ch) {
+ if (ch < 'a' || ch > 'z')
+ return ch;
+ else
+ return static_cast<char>(ch - 'a' + 'A');
+}
+
+static bool StringEqual(const char *a, const char *b, size_t len, bool caseSensitive) {
+ if (caseSensitive) {
+ for (size_t i = 0; i < len; i++) {
+ if (a[i] != b[i])
+ return false;
+ }
+ } else {
+ for (size_t i = 0; i < len; i++) {
+ if (MakeUpperCase(a[i]) != MakeUpperCase(b[i]))
+ return false;
+ }
+ }
+ return true;
+}
+
+// Match file names to patterns allowing for a '*' suffix or prefix.
+static bool MatchWild(const char *pattern, size_t lenPattern, const char *fileName, bool caseSensitive) {
+ size_t lenFileName = strlen(fileName);
+ if (lenFileName == lenPattern) {
+ if (StringEqual(pattern, fileName, lenFileName, caseSensitive)) {
+ return true;
+ }
+ }
+ if (lenFileName >= lenPattern-1) {
+ if (pattern[0] == '*') {
+ // Matching suffixes
+ return StringEqual(pattern+1, fileName + lenFileName - (lenPattern-1), lenPattern-1, caseSensitive);
+ } else if (pattern[lenPattern-1] == '*') {
+ // Matching prefixes
+ return StringEqual(pattern, fileName, lenPattern-1, caseSensitive);
+ }
+ }
+ return false;
+}
+
+SString PropSetFile::GetWildUsingStart(const PropSet &psStart, const char *keybase, const char *filename) {
+
+ for (int root = 0; root < hashRoots; root++) {
+ for (Property *p = props[root]; p; p = p->next) {
+ if (isprefix(p->key, keybase)) {
+ char *orgkeyfile = p->key + strlen(keybase);
+ char *keyfile = NULL;
+
+ if (strncmp(orgkeyfile, "$(", 2) == 0) {
+ const char *cpendvar = strchr(orgkeyfile, ')');
+ if (cpendvar) {
+ SString var(orgkeyfile, 2, cpendvar-orgkeyfile);
+ SString s = psStart.GetExpanded(var.c_str());
+ keyfile = StringDup(s.c_str());
+ }
+ }
+ char *keyptr = keyfile;
+
+ if (keyfile == NULL)
+ keyfile = orgkeyfile;
+
+ for (;;) {
+ char *del = strchr(keyfile, ';');
+ if (del == NULL)
+ del = keyfile + strlen(keyfile);
+ if (MatchWild(keyfile, del - keyfile, filename, caseSensitiveFilenames)) {
+ delete []keyptr;
+ return p->val;
+ }
+ if (*del == '\0')
+ break;
+ keyfile = del + 1;
+ }
+ delete []keyptr;
+
+ if (0 == strcmp(p->key, keybase)) {
+ return p->val;
+ }
+ }
+ }
+ }
+ if (superPS) {
+ // Failed here, so try in super property set
+ return static_cast<PropSetFile *>(superPS)->GetWildUsingStart(psStart, keybase, filename);
+ } else {
+ return "";
+ }
+}
+
+SString PropSetFile::GetWild(const char *keybase, const char *filename) {
+ return GetWildUsingStart(*this, keybase, filename);
+}
+
+// GetNewExpand does not use Expand as it has to use GetWild with the filename for each
+// variable reference found.
+SString PropSetFile::GetNewExpand(const char *keybase, const char *filename) {
+ char *base = StringDup(GetWild(keybase, filename).c_str());
+ char *cpvar = strstr(base, "$(");
+ int maxExpands = 1000; // Avoid infinite expansion of recursive definitions
+ while (cpvar && (maxExpands > 0)) {
+ const char *cpendvar = strchr(cpvar, ')');
+ if (cpendvar) {
+ int lenvar = cpendvar - cpvar - 2; // Subtract the $()
+ char *var = StringDup(cpvar + 2, lenvar);
+ SString val = GetWild(var, filename);
+ if (0 == strcmp(var, keybase))
+ val.clear(); // Self-references evaluate to empty string
+ size_t newlenbase = strlen(base) + val.length() - lenvar;
+ char *newbase = new char[newlenbase];
+ strncpy(newbase, base, cpvar - base);
+ strcpy(newbase + (cpvar - base), val.c_str());
+ strcpy(newbase + (cpvar - base) + val.length(), cpendvar + 1);
+ delete []var;
+ delete []base;
+ base = newbase;
+ }
+ cpvar = strstr(base, "$(");
+ maxExpands--;
+ }
+ SString sret = base;
+ delete []base;
+ return sret;
+}
+
+/**
+ * Initiate enumeration.
+ */
+bool PropSetFile::GetFirst(char **key, char **val) {
+ for (int i = 0; i < hashRoots; i++) {
+ for (Property *p = props[i]; p; p = p->next) {
+ if (p) {
+ *key = p->key;
+ *val = p->val;
+ enumnext = p->next; // GetNext will begin here ...
+ enumhash = i; // ... in this block
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+/**
+ * Continue enumeration.
+ */
+bool PropSetFile::GetNext(char ** key, char ** val) {
+ bool firstloop = true;
+
+ // search begins where we left it : in enumhash block
+ for (int i = enumhash; i < hashRoots; i++) {
+ if (!firstloop)
+ enumnext = props[i]; // Begin with first property in block
+ // else : begin where we left
+ firstloop = false;
+
+ for (Property *p = enumnext; p; p = p->next) {
+ if (p) {
+ *key = p->key;
+ *val = p->val;
+ enumnext = p->next; // for GetNext
+ enumhash = i;
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+
+
+// Global property bank for anjuta.
+static GList *anjuta_propset;
+
+static PropSetFile*
+get_propset(PropsID pi)
+{
+ PropSetFile* p;
+ if(pi < 0 || (guint)pi >= g_list_length(anjuta_propset))
+ {
+ DEBUG_PRINT("%s", "Invalid PropSetFile handle");
+ return NULL;
+ }
+ p = (PropSetFile*)g_list_nth_data(anjuta_propset, pi);
+ if (p == NULL)
+ DEBUG_PRINT("%s", "Trying to access already destroyed PropSetFile object");
+ return p;
+}
+
+// Followings are the C++ to C interface for the PropSetFile
+
+PropsID
+sci_prop_set_new(void)
+{
+ PropsID handle;
+ PropSetFile *p;
+ gint length;
+
+ length = g_list_length(anjuta_propset);
+ p = new PropSetFile;
+ anjuta_propset = g_list_append(anjuta_propset, (gpointer)p);
+ handle = g_list_length(anjuta_propset);
+ if (length == handle)
+ {
+ DEBUG_PRINT("%s", "Unable to create PropSetFile Object");
+ return -1;
+ }
+ return handle-1;
+}
+
+gpointer
+sci_prop_get_pointer(PropsID handle)
+{
+ PropSetFile* p;
+ p = get_propset(handle);
+ return (gpointer)p;
+}
+
+void
+sci_prop_set_destroy(PropsID handle)
+{
+ PropSetFile* p;
+ p = get_propset(handle);
+ if(!p) return;
+ g_list_nth(anjuta_propset, handle)->data = NULL;
+ delete p;
+}
+
+void
+sci_prop_set_parent(PropsID handle1, PropsID handle2)
+{
+ PropSetFile *p1, *p2;
+ p1 = get_propset(handle1);
+ p2 = get_propset(handle2);
+ if(!p1 || !p2) return;
+ p1->superPS = p2;
+}
+
+void
+sci_prop_set_with_key(PropsID handle, const gchar *key, const gchar *val)
+{
+ PropSetFile* p;
+ p = get_propset(handle);
+ if(!p) return;
+ if(val)
+ p->Set(key, val);
+ else
+ p->Set(key, "");
+}
+
+void
+sci_prop_set_int_with_key (PropsID p, const gchar *key, int value)
+{
+ gchar *str;
+ str = g_strdup_printf ("%d", value);
+ sci_prop_set_with_key (p, key, str);
+ g_free (str);
+}
+
+void
+sci_prop_set(PropsID handle, const gchar *keyval)
+{
+ PropSetFile* p;
+ p = get_propset (handle);
+ if(!p) return;
+ p->Set(keyval);
+}
+
+gchar*
+sci_prop_get(PropsID handle, const gchar *key)
+{
+ PropSetFile* p;
+ SString s;
+ if (!key) return NULL;
+ p = get_propset(handle);
+ if(!p) return NULL;
+ s = p->Get(key);
+ if (strlen(s.c_str()) == 0) return NULL;
+ return g_strdup(s.c_str());
+}
+
+gchar*
+sci_prop_get_expanded(PropsID handle, const gchar *key)
+{
+ PropSetFile* p;
+ SString s;
+ p = get_propset(handle);
+ if(!p) return NULL;
+ s = p->GetExpanded(key);
+ if (strlen(s.c_str()) == 0) return NULL;
+ return g_strdup(s.c_str());
+}
+
+gchar*
+sci_prop_expand(PropsID handle, const gchar *withvars)
+{
+ PropSetFile* p;
+ SString s;
+ p = get_propset(handle);
+ if(!p) return NULL;
+ s = p->Expand(withvars);
+ if (strlen(s.c_str()) == 0) return NULL;
+ return g_strdup(s.c_str());
+}
+
+int
+sci_prop_get_int(PropsID handle, const gchar *key, gint defaultValue=0)
+{
+ PropSetFile* p;
+ p = get_propset(handle);
+ if(!p) return defaultValue;
+ return p->GetInt(key, defaultValue);
+}
+
+gchar*
+sci_prop_get_wild(PropsID handle, const gchar *keybase, const gchar *filename)
+{
+ PropSetFile* p;
+ SString s;
+ p = get_propset(handle);
+ if(!p) return NULL;
+ s = p->GetWild(keybase, filename);
+ if (strlen(s.c_str()) == 0) return NULL;
+ return g_strdup(s.c_str());
+}
+
+gchar*
+sci_prop_get_new_expand(PropsID handle, const gchar *keybase, const gchar *filename)
+{
+ PropSetFile* p;
+ SString s;
+ p = get_propset(handle);
+ if(!p) return NULL;
+ s = p->GetNewExpand(keybase, filename);
+ if (strlen(s.c_str()) == 0) return NULL;
+ return g_strdup(s.c_str());
+}
+
+/* GList of strings operations */
+static GList *
+sci_prop_glist_from_string (const gchar *string)
+{
+ gchar *str, *temp, buff[256];
+ GList *list;
+ gchar *word_start, *word_end;
+ gboolean the_end;
+
+ list = NULL;
+ the_end = FALSE;
+ temp = g_strdup (string);
+ str = temp;
+ if (!str)
+ return NULL;
+
+ while (1)
+ {
+ gint i;
+ gchar *ptr;
+
+ /* Remove leading spaces */
+ while (isspace (*str) && *str != '\0')
+ str++;
+ if (*str == '\0')
+ break;
+
+ /* Find start and end of word */
+ word_start = str;
+ while (!isspace (*str) && *str != '\0')
+ str++;
+ word_end = str;
+
+ /* Copy the word into the buffer */
+ for (ptr = word_start, i = 0; ptr < word_end; ptr++, i++)
+ buff[i] = *ptr;
+ buff[i] = '\0';
+ if (strlen (buff))
+ list = g_list_append (list, g_strdup (buff));
+ if (*str == '\0')
+ break;
+ }
+ if (temp)
+ g_free (temp);
+ return list;
+}
+
+/* Get the list of strings as GList from a property value.
+ Strings are splitted from white spaces */
+GList *
+sci_prop_glist_from_data (guint props, const gchar *id)
+{
+ gchar *str;
+ GList *list;
+
+ str = sci_prop_get (props, id);
+ list = sci_prop_glist_from_string (str);
+ g_free(str);
+ return list;
+}
+
+void
+sci_prop_clear(PropsID handle)
+{
+ PropSetFile* p;
+ p = get_propset(handle);
+ if(!p) return;
+ p->Clear();
+}
+
+void
+sci_prop_read_from_memory(PropsID handle, const gchar *data, gint len,
+ const gchar *directoryForImports=0)
+{
+ PropSetFile* p;
+ p = get_propset(handle);
+ if(!p) return;
+ p->ReadFromMemory(data, len, directoryForImports);
+}
+
+void
+sci_prop_read(PropsID handle, const gchar *filename, const gchar *directoryForImports)
+{
+ PropSetFile* p;
+ p = get_propset(handle);
+ if(!p) return;
+ p->Read( filename, directoryForImports);
+}
Added: trunk/plugins/scintilla/properties.h
==============================================================================
--- (empty file)
+++ trunk/plugins/scintilla/properties.h Wed Apr 8 22:53:39 2009
@@ -0,0 +1,55 @@
+/*
+ * properties.h Copyright (C) 2000 Kh. Naba Kumar Singh
+ *
+ * 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
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _PROPERTIES_H_
+#define _PROPERTIES_H_
+
+
+#include <glib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef gint PropsID;
+
+PropsID sci_prop_set_new (void);
+void sci_prop_set_destroy (PropsID p);
+gpointer sci_prop_get_pointer (PropsID p);
+
+void sci_prop_set_with_key (PropsID p, const gchar *key, const gchar *val);
+void sci_prop_set_int_with_key (PropsID p, const gchar *key, int val);
+void sci_prop_set (PropsID p, const gchar *keyval);
+gchar* sci_prop_get (PropsID p, const gchar *key);
+gchar* sci_prop_get_expanded (PropsID p, const gchar *key);
+gchar* sci_prop_expand (PropsID p, const gchar *withvars);
+int sci_prop_get_int (PropsID p, const gchar *key, gint defaultValue);
+gchar* sci_prop_get_wild (PropsID p, const gchar *keybase, const gchar *filename);
+gchar* sci_prop_get_new_expand (PropsID p, const gchar *keybase, const gchar *filename);
+void sci_prop_clear (PropsID p);
+void sci_prop_read_from_memory (PropsID p, const gchar *data,
+ gint len, const gchar *directoryForImports);
+void sci_prop_read (PropsID p, const gchar *filename, const gchar *directoryForImports);
+void sci_prop_set_parent (PropsID p1, PropsID p2);
+GList* sci_prop_glist_from_data (guint props, const gchar* id);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PROPERTIES_H_ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]