[gbrainy] PDF support new files



commit 2336b9b4d13cc09bf3303abd7a80630d86368930
Author: Jordi Mas <jmas softcatala org>
Date:   Sun Nov 21 11:33:47 2010 +0100

    PDF support new files

 src/Clients/Classical/Dialogs/PdfExportDialog.cs   |  137 +++++++
 .../Classical/Dialogs/ui/PdfExportDialog.ui        |  395 ++++++++++++++++++++
 src/Clients/Classical/Widgets/BrowseFile.cs        |  116 ++++++
 src/Clients/Classical/Widgets/SimpleLabel.cs       |  100 +++++
 src/Core/Main/PdfExporter.cs                       |   92 +++++
 5 files changed, 840 insertions(+), 0 deletions(-)
---
diff --git a/src/Clients/Classical/Dialogs/PdfExportDialog.cs b/src/Clients/Classical/Dialogs/PdfExportDialog.cs
new file mode 100644
index 0000000..a523327
--- /dev/null
+++ b/src/Clients/Classical/Dialogs/PdfExportDialog.cs
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2010 Jordi Mas i Hernàndez <jmas softcatala org>
+ *
+ * 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.
+ */
+
+using System;
+using System.IO;
+using Gtk;
+using Mono.Unix;
+
+using gbrainy.Core.Main;
+using gbrainy.Clients.Classical.Widgets;
+
+namespace gbrainy.Clients.Classical.Dialogs
+{
+	public class PdfExportDialog : BuilderDialog
+	{
+		[GtkBeans.Builder.Object] Gtk.HBox hbox_file;
+		[GtkBeans.Builder.Object] Gtk.SpinButton games_spinbutton;	
+		[GtkBeans.Builder.Object] Gtk.SpinButton gamesperpage_spinbutton;
+		[GtkBeans.Builder.Object] Gtk.CheckButton colorblindcheckbutton;
+		[GtkBeans.Builder.Object] Gtk.RadioButton rb_easy;
+		[GtkBeans.Builder.Object] Gtk.RadioButton rb_medium;
+		[GtkBeans.Builder.Object] Gtk.RadioButton rb_master;
+		[GtkBeans.Builder.Object] Gtk.CheckButton checkbox_logic;
+		[GtkBeans.Builder.Object] Gtk.CheckButton checkbox_calculation;
+		[GtkBeans.Builder.Object] Gtk.CheckButton checkbox_verbal;
+	
+		BrowseFile file;
+
+		public PdfExportDialog () : base ("PdfExportDialog.ui", "pdfexportbox")
+		{
+			games_spinbutton.Value = 10;
+			gamesperpage_spinbutton.Value = 4;
+			checkbox_logic.Active = checkbox_calculation.Active = checkbox_verbal.Active = true;
+
+			// Use defaults from Preferences
+		 	switch ((GameDifficulty) Preferences.GetIntValue (Preferences.DifficultyKey)) {
+			case GameDifficulty.Easy:	
+				rb_easy.Active = rb_easy.HasFocus = true;
+				break;
+			case GameDifficulty.Medium:
+				rb_medium.Active = rb_medium.HasFocus = true;
+				break;
+			case GameDifficulty.Master:
+				rb_master.Active = rb_master.HasFocus = true;
+				break;
+			}
+			// File selection
+			string def_file;
+
+			def_file = System.IO.Path.Combine (
+				Environment.GetFolderPath (Environment.SpecialFolder.MyDocuments),
+				"games.pdf");
+
+			file = new BrowseFile (hbox_file, def_file, true);
+
+			FileFilter[] filters = new FileFilter [2];
+			filters[0] = new FileFilter ();
+			filters[0].AddPattern ("*.pdf");
+			filters[0].Name = Catalog.GetString ("PDF files");
+
+			filters[1] = new FileFilter ();
+			filters[1].AddPattern ("*.*");
+			filters[1].Name = Catalog.GetString ("All files");
+
+			file.Filters = filters;
+		}
+
+		GameDifficulty Difficulty {
+			get {
+				if (rb_easy.Active)
+					return GameDifficulty.Easy;
+
+				if (rb_master.Active)
+					return GameDifficulty.Master;
+
+				return GameDifficulty.Medium;
+			}
+		}
+
+		void OnOK (object sender, EventArgs args)
+		{
+			GameSession.Types types = GameSession.Types.None;
+
+			if (checkbox_logic.Active)
+				types |= GameSession.Types.LogicPuzzles;
+
+			if (checkbox_calculation.Active)
+				types |= GameSession.Types.CalculationTrainers;
+
+			if (checkbox_verbal.Active)
+				types |= GameSession.Types.VerbalAnalogies; 
+			
+			GeneratePdf (types,
+				(int) games_spinbutton.Value,
+				(int) gamesperpage_spinbutton.Value, 
+				Difficulty,
+				colorblindcheckbutton.Active,
+				file.Filename);
+		}
+
+		void GeneratePdf (GameSession.Types types, int num_games, int gamespage, GameDifficulty difficulty, bool colorblind, string filename)
+		{
+			Game [] games;
+			GameManager gm;
+			
+			games = new Game [num_games];
+			gm = new GameManager ();
+			gm.ColorBlind = colorblind;
+			gm.Difficulty = difficulty;
+			GtkClient.GameManagerPreload (gm);
+			gm.GameType = types;
+		
+			for (int n = 0; n < num_games; n++)
+			{
+				 games [n] = gm.GetPuzzle (); 
+			}
+			
+			PdfExporter.GeneratePdf (games, gamespage, filename);
+		}
+	}
+}
diff --git a/src/Clients/Classical/Dialogs/ui/PdfExportDialog.ui b/src/Clients/Classical/Dialogs/ui/PdfExportDialog.ui
new file mode 100644
index 0000000..6b10352
--- /dev/null
+++ b/src/Clients/Classical/Dialogs/ui/PdfExportDialog.ui
@@ -0,0 +1,395 @@
+<?xml version="1.0"?>
+<interface>
+  <!-- interface-requires gtk+ 2.12 -->
+  <!-- interface-naming-policy toplevel-contextual -->
+  <object class="GtkDialog" id="pdfexportbox">
+    <property name="visible">True</property>
+    <property name="border_width">7</property>
+    <property name="title" translatable="yes">PDF export</property>
+    <property name="type_hint">dialog</property>
+    <property name="has_separator">False</property>
+    <child internal-child="vbox">
+      <object class="GtkVBox" id="pdfbox">
+        <property name="visible">True</property>
+        <child>
+          <object class="GtkLabel" id="label_intro">
+            <property name="visible">True</property>
+            <property name="xalign">0</property>
+            <property name="yalign">0</property>
+            <property name="ypad">5</property>
+            <property name="label" translatable="yes">This option allows to export a set of games in a PDF file. You can complete the puzzles without a computer.</property>
+            <property name="wrap">True</property>
+          </object>
+          <packing>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkVBox" id="vbox_general">
+            <property name="visible">True</property>
+            <child>
+              <object class="GtkLabel" id="label33">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="yalign">0</property>
+                <property name="label" translatable="yes">&lt;b&gt;General Settings&lt;/b&gt;</property>
+                <property name="use_markup">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkCheckButton" id="colorblindcheckbutton">
+                <property name="label" translatable="yes">Skip games that use colors (friendly to colorblind users)</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">False</property>
+                <property name="use_underline">True</property>
+                <property name="draw_indicator">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="position">2</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkVBox" id="vbox_gametypes">
+            <property name="visible">True</property>
+            <child>
+              <object class="GtkLabel" id="label26">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="yalign">0</property>
+                <property name="ypad">5</property>
+                <property name="label" translatable="yes">&lt;b&gt;Game Types&lt;/b&gt;</property>
+                <property name="use_markup">True</property>
+                <property name="single_line_mode">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkCheckButton" id="checkbox_logic">
+                <property name="label" translatable="yes">Logic</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">False</property>
+                <property name="draw_indicator">True</property>
+              </object>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkCheckButton" id="checkbox_calculation">
+                <property name="label" translatable="yes">Calculation</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">False</property>
+                <property name="use_underline">True</property>
+                <property name="draw_indicator">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="padding">2</property>
+                <property name="position">2</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkCheckButton" id="checkbox_verbal">
+                <property name="label" translatable="yes">Verbal</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">False</property>
+                <property name="draw_indicator">True</property>
+              </object>
+              <packing>
+                <property name="position">3</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="position">3</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkVBox" id="vbox_dificfulty">
+            <property name="visible">True</property>
+            <child>
+              <object class="GtkLabel" id="label27">
+                <property name="height_request">25</property>
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">&lt;b&gt;Difficulty Level&lt;/b&gt;</property>
+                <property name="use_markup">True</property>
+                <property name="single_line_mode">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkRadioButton" id="rb_easy">
+                <property name="label" translatable="yes">Easy</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">False</property>
+                <property name="use_underline">True</property>
+                <property name="draw_indicator">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkRadioButton" id="rb_medium">
+                <property name="label" translatable="yes">Medium</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">False</property>
+                <property name="use_underline">True</property>
+                <property name="draw_indicator">True</property>
+                <property name="group">rb_easy</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">2</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkRadioButton" id="rb_master">
+                <property name="label" translatable="yes">Master</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">False</property>
+                <property name="use_underline">True</property>
+                <property name="draw_indicator">True</property>
+                <property name="group">rb_easy</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">3</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="position">4</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkVBox" id="vbox_ngames">
+            <property name="visible">True</property>
+            <child>
+              <object class="GtkLabel" id="label29">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="yalign">0</property>
+                <property name="ypad">5</property>
+                <property name="label" translatable="yes">&lt;b&gt;Number of games&lt;/b&gt;</property>
+                <property name="use_markup">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkHBox" id="hbox11">
+                <property name="visible">True</property>
+                <child>
+                  <object class="GtkTable" id="table5">
+                    <property name="visible">True</property>
+                    <property name="n_rows">2</property>
+                    <property name="n_columns">2</property>
+                    <child>
+                      <object class="GtkLabel" id="label31">
+                        <property name="visible">True</property>
+                        <property name="xalign">0</property>
+                        <property name="xpad">5</property>
+                        <property name="label" translatable="yes">Total number of games:</property>
+                      </object>
+                      <packing>
+                        <property name="x_options">GTK_FILL</property>
+                        <property name="y_options"></property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="label32">
+                        <property name="visible">True</property>
+                        <property name="xalign">0</property>
+                        <property name="xpad">5</property>
+                        <property name="label" translatable="yes">Number of games per page:</property>
+                      </object>
+                      <packing>
+                        <property name="top_attach">1</property>
+                        <property name="bottom_attach">2</property>
+                        <property name="x_options">GTK_FILL</property>
+                        <property name="y_options"></property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkSpinButton" id="gamesperpage_spinbutton">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="adjustment">adjustment2</property>
+                        <property name="climb_rate">1</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="right_attach">2</property>
+                        <property name="top_attach">1</property>
+                        <property name="bottom_attach">2</property>
+                        <property name="y_options"></property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkSpinButton" id="games_spinbutton">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="adjustment">adjustment3</property>
+                        <property name="climb_rate">1</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="right_attach">2</property>
+                        <property name="y_options"></property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="position">5</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkVBox" id="vbox_file">
+            <property name="visible">True</property>
+            <child>
+              <object class="GtkLabel" id="label1">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="yalign">0</property>
+                <property name="label" translatable="yes">&lt;b&gt;Output File&lt;/b&gt;</property>
+                <property name="use_markup">True</property>
+              </object>
+              <packing>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkHBox" id="hbox_file">
+                <property name="visible">True</property>
+                <child>
+                  <placeholder/>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+              </object>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="position">6</property>
+          </packing>
+        </child>
+        <child internal-child="action_area">
+          <object class="GtkHButtonBox" id="dialog-action_area3">
+            <property name="visible">True</property>
+            <property name="layout_style">end</property>
+            <child>
+              <object class="GtkButton" id="cancelbutton2">
+                <property name="label">gtk-cancel</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="receives_default">False</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="okbutton">
+                <property name="label">_Save</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="receives_default">False</property>
+                <property name="use_stock">True</property>
+                <signal name="clicked" handler="OnOK"/>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="pack_type">end</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <action-widgets>
+      <action-widget response="-6">cancelbutton2</action-widget>
+      <action-widget response="-5">okbutton</action-widget>
+    </action-widgets>
+  </object>
+  <object class="GtkAdjustment" id="adjustment1">
+    <property name="lower">4</property>
+    <property name="upper">60</property>
+    <property name="step_increment">1</property>
+    <property name="page_increment">10</property>
+  </object>
+  <object class="GtkAdjustment" id="adjustment2">
+    <property name="lower">2</property>
+    <property name="upper">10</property>
+    <property name="step_increment">1</property>
+    <property name="page_increment">10</property>
+  </object>
+  <object class="GtkAdjustment" id="adjustment3">
+    <property name="lower">4</property>
+    <property name="upper">200</property>
+    <property name="step_increment">1</property>
+    <property name="page_increment">10</property>
+  </object>
+</interface>
diff --git a/src/Clients/Classical/Widgets/BrowseFile.cs b/src/Clients/Classical/Widgets/BrowseFile.cs
new file mode 100644
index 0000000..0e13aa5
--- /dev/null
+++ b/src/Clients/Classical/Widgets/BrowseFile.cs
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2009 Jordi Mas i Hernàndez <jmas softcatala org>
+ *
+ * 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.
+ */
+
+using System;
+using Gtk;
+using Mono.Unix;
+
+
+namespace gbrainy.Clients.Classical.Widgets
+{
+	// Adds a text box + browse button into a given hbox parent configuring
+	// the standard browsedirectory widget for the application
+	public class BrowseFile
+	{
+		Entry filename;
+		Button browse;
+		bool browse_file;
+		Gtk.FileFilter[] filters;
+		string default_dir;
+
+		public virtual event EventHandler FileSelectedChanged;
+
+		public BrowseFile (HBox parent, string file, bool browse_file)
+		{
+			this.browse_file = browse_file;
+			filename = new Entry ();
+			browse = new Button (Catalog.GetString ("Browse..."));
+			Filename = file;
+
+			browse.Clicked += new EventHandler (OnBrowse);
+
+			parent.Add (filename);
+			parent.Add (browse);
+
+			Gtk.Box.BoxChild box = (Gtk.Box.BoxChild) parent[browse];
+			box.Expand = false;
+			box.Fill = false;
+
+			parent.ShowAll ();
+		}
+
+		public string Filename {
+			get { return filename.Text; }
+			set { 
+				if (value == null)
+					filename.Text = string.Empty;
+				else
+					filename.Text = value;
+			}
+		}
+
+		public string DefaultDirectory {
+			set {
+				if (browse_file == false)
+					throw new InvalidOperationException ("Default directory can only be set when browsing files");
+				
+				default_dir = value;
+			}
+		}
+
+		public Gtk.FileFilter[] Filters {
+			set { filters = value; }
+		}
+
+		void OnBrowse (object o, EventArgs args)
+		{
+			FileChooserDialog chooser_dialog = new FileChooserDialog (
+				Catalog.GetString ("Open Location") , null,
+				browse_file ? FileChooserAction.Open : FileChooserAction.SelectFolder);
+
+
+			if (browse_file) {
+				if (default_dir != null)
+					chooser_dialog.SetCurrentFolder (default_dir);
+			}
+			else {
+				chooser_dialog.SetCurrentFolder (filename.Text);
+			}
+
+			chooser_dialog.AddButton (Stock.Cancel, ResponseType.Cancel);
+			chooser_dialog.AddButton (Stock.Open, ResponseType.Ok);
+			chooser_dialog.DefaultResponse = ResponseType.Ok;
+			chooser_dialog.LocalOnly = false;
+
+			if (filters != null) {
+				foreach (Gtk.FileFilter filter in filters)
+					chooser_dialog.AddFilter (filter);
+			}
+
+			if (chooser_dialog.Run () == (int) ResponseType.Ok) {
+				filename.Text = chooser_dialog.Filename;
+
+				if (FileSelectedChanged != null)
+					FileSelectedChanged (this, EventArgs.Empty);
+			}
+
+			chooser_dialog.Destroy ();
+		}
+	}
+}
diff --git a/src/Clients/Classical/Widgets/SimpleLabel.cs b/src/Clients/Classical/Widgets/SimpleLabel.cs
new file mode 100644
index 0000000..35b9df9
--- /dev/null
+++ b/src/Clients/Classical/Widgets/SimpleLabel.cs
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2009 Jordi Mas i Hernàndez <jmas softcatala org>
+ *
+ * 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.
+ */
+
+using System;
+using Gtk;
+
+namespace gbrainy.Clients.Classical.Widgets
+{
+	//
+	// Simple Label control that draws a piece of text
+	//
+	public class SimpleLabel : DrawingArea
+	{
+		string text;
+		int width_margin, height_margin;
+
+		public SimpleLabel ()
+		{
+			UseMarkup = true;
+		}
+
+		public bool UseMarkup  { get; set; }
+
+		public string Text {
+			get { return text;}
+			set {
+				if (text == value)
+					return;
+
+				text = value;
+				QueueDraw ();
+			}
+		}
+
+		public int WidthMargin {
+			set {
+				if (width_margin == value)
+					return;
+
+				width_margin = value;
+				QueueDraw ();
+			}
+		}
+
+		public int HeightMargin {
+			set {
+				if (height_margin == value)
+					return;
+
+				height_margin = value;
+				QueueDraw ();
+			}
+		}
+
+		protected override bool OnExposeEvent (Gdk.EventExpose args)
+		{
+			if (String.IsNullOrEmpty (text))
+				return base.OnExposeEvent (args);
+
+			int winWidth, winHeight;
+			Gdk.GC light = Style.ForegroundGC (StateType.Normal);
+			args.Window.GetSize (out winWidth, out winHeight);
+
+			using (Pango.Layout layout = new Pango.Layout (this.PangoContext))
+			{
+				if (Direction == Gtk.TextDirection.Rtl)
+					layout.Alignment = Pango.Alignment.Right;					
+				else
+					layout.Alignment = Pango.Alignment.Left;
+		
+				layout.Width = (winWidth - width_margin * 2) * (int) Pango.Scale.PangoScale;
+
+				if (UseMarkup)
+					layout.SetMarkup (text);
+				else
+					layout.SetText (text);
+
+				args.Window.DrawLayout (light, width_margin, height_margin, layout);
+			}
+
+			return base.OnExposeEvent (args);
+		}
+	}
+}
diff --git a/src/Core/Main/PdfExporter.cs b/src/Core/Main/PdfExporter.cs
new file mode 100644
index 0000000..f550d5d
--- /dev/null
+++ b/src/Core/Main/PdfExporter.cs
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2010 Jordi Mas i Hernàndez <jmas softcatala org>
+ *
+ * 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.
+ */
+
+using System;
+using Mono.Unix;
+
+using Cairo;
+using gbrainy.Core.Libraries;
+
+namespace gbrainy.Core.Main
+{
+	// Generates a single PDF document with the selected games		
+	static public class PdfExporter
+	{
+		static public void GeneratePdf (Game [] games, int games_page, string file)
+		{
+			const int width = 400, height = 400, margin = 20, question_height = 100;
+			int x, y, cnt;
+			Game puzzle;
+			
+			PdfSurface pdf = new PdfSurface (file, (width + margin) * 2, 
+				(height + margin + question_height) * games_page / 2);
+
+			CairoContextEx cr = new CairoContextEx (pdf, "sans 12", 72);
+			x = y = cnt = 0;
+
+			// TODO:
+			//	- Solution page
+			//	- Puzzles that are not shown correctly
+			for (int i = 0; i < games.Length; i++)
+			{
+				puzzle = games [i];
+				puzzle.Begin ();
+
+				cnt++;
+
+				cr.Save ();
+				cr.Translate (x, y);
+				cr.Rectangle (0, 0, width, height + question_height);
+				cr.Clip ();
+
+				// Draw question				
+				cr.SetPangoFontSize (12);
+				cr.UseMarkup = true;
+				cr.DrawStringWithWrapping (20, 10, puzzle.Question, width - 20);
+				cr.Stroke ();
+				cr.UseMarkup = false;
+
+				// Draw from question_height up height since from 0 to question_height is the question
+				// Translate adds always to previous matrix's transformation
+				cr.Translate (0, question_height);						
+				puzzle.DrawPreview (cr, width, height, false);
+				x += width + margin;
+				if (x > width + margin) {
+					x = 0;
+					y += height + margin + question_height;
+				}
+				cr.Restore ();
+				cr.Stroke ();
+
+				if (cnt >= games_page) {
+					cr.ShowPage ();
+					cnt = x = y = 0;
+				}
+			}
+
+			if (y > 0) {
+				cr.ShowPage ();
+			}
+
+			pdf.Finish ();
+			((IDisposable)cr).Dispose();
+			return;
+		}
+	}
+}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]