Index: gnome-sudoku/src/lib/printing.py
===================================================================
--- gnome-sudoku/src/lib/printing.py	(revision 8865)
+++ gnome-sudoku/src/lib/printing.py	(working copy)
@@ -4,268 +4,6 @@
 from gettext import gettext as _
 from gettext import ngettext
 
-class GridDrawer:
-
-    X = 0
-    Y = 1
-
-    def __init__ (self,
-                  gpc,
-                  grid_size=9,
-                  grid_side_size=500,
-                  start_at=(800,50),
-                  default_color=(0,0,0),
-                  label=None,
-                  label_font=('Arial','12'),
-                  ):
-        self.gpc = gpc
-        self.grid_size = grid_size
-        self.label = label
-        self.label_font=gnomeprint.font_find_closest(*label_font)
-        self.grid_side_size = grid_side_size
-        self.start_at = start_at
-        self.increment = float(grid_side_size) / grid_size
-        self.left_upper = start_at
-        self.right_lower = self.left_upper[0]+self.grid_side_size,self.left_upper[1]-self.grid_side_size
-        self.box_size = math.sqrt(grid_size)
-        # get the right font size for our increment...
-        self.increment * 0.7
-        # start with our maximum font...
-        max_size=36
-        self.font = gnomeprint.font_find_closest('Sans Bold',max_size)
-        self.default_color = default_color
-        while self.font.get_width_utf8('1')> (self.increment * 0.4) and\
-                  self.font.get_ascender()> (self.increment * 0.4):
-            max_size = max_size - 1
-            self.font = gnomeprint.font_find_closest('Helvetica',
-                                                     max_size)
-        self.THICK_WIDTH = 1 + float(max_size) / 8
-        self.gpc.setfont(
-            self.font
-            )
-        self.gpc.setrgbcolor(*self.default_color)
-
-    def finish (self):
-        self.gpc.showpage()
-
-    def draw_label (self, x, y, label, font=None, color=None):
-        if label:
-            if type(label)!=str: print 'Funny... label ',label,'is a ',type(label)
-            self.gpc.moveto(x,y)
-            self.gpc.setfont(self.label_font)
-            self.gpc.show(label)
-            self.gpc.setfont(self.font) #reset
-
-    def draw_number (self, x, y, val, font=None, color=None):
-        if not font: font = self.font
-        self.gpc.setfont(font)
-        if color: self.gpc.setrgbcolor(*color)
-        move_to = list(self.left_upper)
-        char_w=font.get_width_utf8(str(val))
-        char_h = font.get_ascender()
-        move_to[self.X] += (self.increment * x + (self.increment - char_w)/2)
-        move_to[self.Y] = move_to[self.Y] - (((y+1) * self.increment) - (self.increment - char_h)/2)
-        self.gpc.moveto(*move_to)
-        self.gpc.show(str(val))
-        if color: self.gpc.setrgbcolor(*self.default_color) #unset color
-
-    def draw_grid (self):
-        for direction in self.X,self.Y:
-            opposite = int(not direction)
-            for n in range(self.grid_size+1):                
-                start_pos = list(self.left_upper)                                  
-                if direction==self.Y:
-                    start_pos[direction]=self.left_upper[direction]-self.increment*n
-                else:
-                    start_pos[direction]=self.left_upper[direction]+self.increment*n
-                # double the thickness of our borders and box borders...
-                # e.g. 0, 3, 6, 9
-                length_adjustment = 0
-                if n % self.box_size == 0:
-                    self.gpc.setlinewidth(self.THICK_WIDTH)
-                    # correct start position to take into account our
-                    # width so that corners don't look funny.
-                    if True or n==0 or n==self.box_size:
-                        length_adjustment = self.THICK_WIDTH/2
-                        if direction==self.X:
-                            start_pos[direction] = start_pos[direction]+length_adjustment
-                        else:
-                            start_pos[direction] = start_pos[direction]-length_adjustment
-                # get in position...
-                self.gpc.moveto(*start_pos)
-                # draw our line...
-                dest_pos = start_pos
-                if direction==self.Y:
-                    dest_pos[opposite]=dest_pos[opposite]+self.grid_side_size+length_adjustment*2
-                else:
-                    dest_pos[opposite]=dest_pos[opposite]-self.grid_side_size-length_adjustment*2
-                self.gpc.lineto(*dest_pos)
-                self.gpc.stroke()
-                # Reset our width to normal if need be...
-                if n % self.box_size == 0: self.gpc.setlinewidth(1)                
-
-class SudokuDrawer (GridDrawer):
-    def __init__ (self,
-                  sudoku_grid, # A SudokuGrid, a InteractiveSudoku/SudokuSolver, or a SudokuGridDisplay
-                  gpc,
-                  grid_size=9,
-                  grid_side_size=500,
-                  start_at=(800,50),
-                  label=None,
-                  label_font=('Arial',12),
-                  ):
-        """Draw a sudoku grid.
-
-        If we're labelling, we put our label above the start_at
-        """
-        if isinstance(sudoku_grid,gsudoku.SudokuGameDisplay):
-            self.sudoku_grid = sudoku_grid.grid
-            self.sgd = sudoku_grid
-        else:
-            self.sudoku_grid = sudoku_grid
-            self.sgd = None
-        GridDrawer.__init__(self,
-                            gpc,
-                            grid_size=grid_size,
-                            grid_side_size=grid_side_size,
-                            start_at=start_at,
-                            label=label,
-                            label_font=label_font,
-                            )
-        self.alt_font = gnomeprint.font_find_closest('Sans Italic',
-                                                     self.font.get_size()*0.85
-                                                     )
-        
-        self.alt_color = .4,.4,.4
-        
-    def draw_sudoku (self):
-        if self.label: self.draw_label(self.start_at[0],
-                                       self.start_at[1]+self.label_font.get_ascender(),
-                                       self.label,)
-        for x in range(self.grid_size):
-            for y in range(self.grid_size):
-                if isinstance(self.sudoku_grid,sudoku.SudokuSolver):
-                    val = self.sudoku_grid.virgin._get_(x,y)
-                    if val: self.draw_number(x,y,val)
-                    elif self.sudoku_grid._get_(x,y):
-                        if not self.sgd:
-                            color=self.alt_color
-                        else:
-                            trackers=self.sgd.trackers_for_point(x,y)
-                            if trackers:
-                                tracker=trackers[0]
-                                color=self.sgd.get_tracker_color(tracker)
-                            else:
-                                color = self.alt_color
-                        self.draw_number(
-                            x,y,
-                            self.sudoku_grid._get_(x,y),
-                            self.alt_font,
-                            color,
-                            )
-                else:
-                    val = self.sudoku_grid._get_(x,y)
-                    if val: self.draw_number(x,y,val)
-
-MINIMUM_SQUARE_SIZE=135
-
-class SudokuPrinter:
-    def __init__ (self,
-                  sudokus,
-                  margin=50,
-                  sudokus_per_page=None,
-                  dialog_parent=None
-                  ):
-        self.drawn = False
-        self.margin = margin
-        self.sudokus_per_page=sudokus_per_page
-        self.dialog_parent = dialog_parent
-        try:
-            self.nsudokus = len(sudokus) # number of sudokus we're printing
-        except TypeError,AttributeError:
-            sudokus = [sudokus] # assume they passed us one sudoku by
-            self.nsudokus = 1        # mistake and be nice
-        self.sudokus = sudokus
-        self.job = gnomeprint.Job(gnomeprint.config_default())
-
-    def run (self):
-        self.dialog = gnomeprint.ui.Dialog(self.job,
-                                      ngettext("Print Sudoku","Print Sudokus",
-                                               self.nsudokus),
-                                      0)
-        if self.dialog_parent: self.dialog.set_transient_for(self.dialog_parent)
-        self.dialog.connect('response',self.response_cb)
-        self.dialog.show()
-
-    def response_cb (self, dialog, response):
-        if response == gnomeprint.ui.DIALOG_RESPONSE_CANCEL:
-            dialog.hide()            
-        elif response == gnomeprint.ui.DIALOG_RESPONSE_PREVIEW:
-            if not self.drawn: self.draw_sudokus()
-            w=gnomeprint.ui.JobPreview(self.job,_('Print Preview'))
-            w.set_transient_for(dialog)
-            w.set_property('allow-grow',1)
-            w.set_property('allow-shrink',1)
-            w.show_all()
-            w.present()
-        elif response == gnomeprint.ui.DIALOG_RESPONSE_PRINT:
-            if not self.drawn: self.draw_sudokus()
-            self.job.print_()
-            dialog.hide()
-
-            
-    def draw_sudokus (self):
-        self.gpc = self.job.get_context()    
-        width,height = gnomeprint.job_get_page_size_from_config(self.job.get_config())
-        self.margin = 50
-        top = height-self.margin
-        bottom = self.margin
-        left = self.margin
-        right = width
-        if not self.sudokus_per_page:
-            self.sudokus_per_page = self.nsudokus
-            dimensions, square_size = fit_squares_in_rectangle(width,height,self.sudokus_per_page,self.margin)
-            while square_size < MINIMUM_SQUARE_SIZE:
-                self.sudokus_per_page = self.sudokus_per_page - 1
-                dimensions, square_size = fit_squares_in_rectangle(width,height,self.sudokus_per_page,self.margin)
-        else:
-            dimensions,square_size =  fit_squares_in_rectangle(width,height,self.sudokus_per_page,self.margin)
-        count = 0
-        for sudoku in self.sudokus:
-            if type(sudoku)==tuple:
-                label = sudoku[1]
-                sudoku = sudoku[0]
-            else:
-                label = None
-            if count % self.sudokus_per_page == 0:
-                if count: self.gpc.showpage()
-                self.gpc.beginpage('%s'%(count/self.sudokus_per_page+1))
-                pos = [1,1]
-                left_start,top_start=self.margin,top
-            else:
-                # move from left to right, top to bottom
-                if pos[0] < dimensions[0]:
-                    left_start = left_start + square_size + self.margin
-                    pos[0] += 1
-                else:
-                    top_start = top_start - square_size - self.margin # down ...
-                    left_start = self.margin                          # ...and to the left
-                    pos[0] = 1
-                    pos[1] += 1
-            drawer = SudokuDrawer(sudoku,
-                                  self.gpc,
-                                  start_at=(left_start,top_start),
-                                  grid_side_size=square_size,
-                                  label=label
-                                  )
-            drawer.draw_grid()
-            drawer.draw_sudoku()
-            count += 1
-        if count: self.gpc.showpage()
-        self.job.close()
-        self.drawn = True
-        
-
 def fit_squares_in_rectangle (width, height, n, margin=0):
     """Optimally fit squares into a rectangle.
 
@@ -294,8 +32,74 @@
             best_fit = n_across,n_down
     if best_fit:
         return best_fit,best_square_size
-        
+
+class SudokuPrinterNew:
+    def __init__ (self,
+                  sudokus,
+                  main_window,
+                  margin=50,
+                  sudokus_per_page=1,
+                  ):
+        self.drawn = False
+        self.margin = margin
+        self.sudokus_per_page=sudokus_per_page
+        self.n_sudokus = len(sudokus)
+        self.sudokus = sudokus
+        self.print_op = gtk.PrintOperation()
+        self.print_op.connect( "begin-print", self.begin_print)
+        self.print_op.connect("draw-page", self.draw_page)
+        self.main_window = main_window
+
+    def begin_print(self, operation, context):
+        import math
+        pages = int(math.ceil(self.n_sudokus / self.sudokus_per_page))
+        operation.set_n_pages(pages)
+
+    def draw_page(self, operation, context, page_nr):
+        import pango
+        import sudoku_thumber
+
+        margin = 25
+        cr = context.get_cairo_context()
+        width = context.get_width()
+        height = context.get_height()
+
+        best_fit,best_square_size = fit_squares_in_rectangle(width, height, self.sudokus_per_page, margin)
+
+        start = int(page_nr*self.sudokus_per_page)
+        sudokus_on_page = self.sudokus[start : start+int(self.sudokus_per_page)]
+
+        left = margin
+        top = margin
+        pos = [1,1]
+        for sudoku in sudokus_on_page:
+            if type(sudoku)==tuple:
+                label = sudoku[1]
+                sudoku = sudoku[0]
+
+            if isinstance(sudoku, gsudoku.SudokuGameDisplay):
+                sudoku = sudoku.grid
+
+            sudoku_thumber.draw_sudoku (cr, sudoku.grid, None, best_square_size, left, top)
+            if pos[0] < best_fit[0]:
+                left = left + best_square_size + margin
+                pos[0] += 1
+            else:
+                top = top + best_square_size + margin
+                left = margin
+                pos[0] = 1
+                pos[1] += 1
+
+
 def print_sudokus(*args,**kwargs):
-    sp = SudokuPrinter(*args,**kwargs)
-    sp.run()
+    sp = SudokuPrinterNew(*args,**kwargs)
+    res = sp.print_op.run(gtk.PRINT_OPERATION_ACTION_PRINT_DIALOG, sp.main_window)
+    if res == gtk.PRINT_OPERATION_RESULT_ERROR:
+        error_dialog = gtk.MessageDialog(main_window,
+                                      gtk.DIALOG_DESTROY_WITH_PARENT,
+                                      gtk.MESSAGE_ERROR,
+                                      gtk.BUTTONS_CLOSE,
+                                      "Error printing file:\n")
+        error_dialog.connect("response", lambda w,id: w.destroy())
+        error_dialog.show()
 
Index: gnome-sudoku/src/lib/sudoku_thumber.py
===================================================================
--- gnome-sudoku/src/lib/sudoku_thumber.py	(revision 8865)
+++ gnome-sudoku/src/lib/sudoku_thumber.py	(working copy)
@@ -5,54 +5,75 @@
 
 SUDOKU_SIZE = 9
 N_BOXES = 3
-FONT_SIZE = 9
-SQUARE_SIZE = 11
-THICK = 2 #SIZE/33 or 1
-BORDER = THICK*2
-THIN = 1 #SIZE/100 or 1
+
 PENCIL_GREY = (0.3,0.3,0.3)
-LINE_GREY = (0.4,0.4,0.4)
-SIZE = (
-    (2 * (BORDER+THICK)) # OUTER BORDER
-    +
-    ((N_BOXES - 1) * THICK) # INNER THICK LINES
-    +
-    (SQUARE_SIZE * SUDOKU_SIZE) # WHITE SPACE IN SQUARES
-    +
-    (SUDOKU_SIZE - N_BOXES - 1)
-    )
-    
-(SQUARE_SIZE * SUDOKU_SIZE) + (N_BOXES)*THICK + (SUDOKU_SIZE-N_BOXES)*THIN
+BACKGROUND_COLOR = (1.,1.,1.)
 
-sudoku = [[0, 0, 2, 3, 4, 5, 6, 0, 0]]*SUDOKU_SIZE
-played = [[1,2,0,0,0,0,0,0,0,0]]+[[0,0,0,0,0,0,0,0,0,0]]*8
+def draw_sudoku (cr, sudoku, played, size, offset_x=0, offset_y=0, border_color=(1.0,1.0,1.0), line_color=(0.0,0.0,0.0)):
 
-def make_image_surface (sudoku, played, highlight_color):
-    surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, SIZE, SIZE)
-    cr = cairo.Context(surface)
+    THIN = size / 100.
+    THICK = THIN * 2.
+    BORDER = THICK
+
+    WHITE_SPACE = (size
+                   - 2 * BORDER
+                   - 2 * THICK
+                   - (N_BOXES - 1) * THICK
+                   - (N_BOXES * 2) * THIN
+                  )
+
+    SQUARE_SIZE = WHITE_SPACE / SUDOKU_SIZE
+    FONT_SIZE = SQUARE_SIZE 
+
+    outer = {}
+    outer["left"]   = offset_x
+    outer["right"]  = offset_x + size
+    outer["top"]    = offset_y
+    outer["bottom"] = offset_y + size
+
+    # Entire background
+    cr.set_source_rgb(1.,1.,1.)
+    cr.rectangle(outer["left"],
+                 outer["top"],
+                 size,
+                 size)
+    cr.fill()
+
+    # Outer border
+    cr.set_line_join(cairo.LINE_JOIN_ROUND)
     cr.set_line_width(BORDER)
-    cr.set_line_join(cairo.LINE_JOIN_ROUND)
-    cr.rectangle(BORDER*.5,
-                 BORDER*.5,
-                 (SIZE-(BORDER)),
-                 (SIZE-(BORDER)),
-        )
-    cr.set_source_rgb(1,1,1)
+    cr.rectangle(outer["left"]   + BORDER/2.0,
+                 outer["top"]    + BORDER/2.0,
+                 size            - BORDER,
+                 size            - BORDER)
+
+    # Inner background
+    cr.set_source_rgb(*BACKGROUND_COLOR)
     cr.fill_preserve()
-    cr.set_source_rgb(*highlight_color)
+    #Border box
+    cr.set_source_rgb(*border_color)
     cr.stroke()
-    cr.set_source_rgb(*LINE_GREY)
+
+    #Outer thick lines 
+    cr.set_line_join(cairo.LINE_JOIN_MITER)
     cr.set_line_width(THICK)
-    cr.rectangle(BORDER,
-                 BORDER,
-                 (SIZE-(BORDER+2*THICK)),
-                 (SIZE-(BORDER+2*THICK)),
-        )
+    cr.rectangle(outer["left"]   + BORDER +   THICK/2.0,
+                 outer["top"]    + BORDER +   THICK/2.0,
+                 size            - BORDER*2 - THICK,
+                 size            - BORDER*2 - THICK)
+
+    cr.set_source_rgb(*line_color)
     cr.stroke()
-    small_size = SIZE / float(SUDOKU_SIZE)
+
+    inner = {}
+    inner["left"]   = outer["left"]   + BORDER + THICK
+    inner["right"]  = outer["right"]  - BORDER - THICK
+    inner["top"]    = outer["top"]    + BORDER + THICK
+    inner["bottom"] = outer["bottom"] - BORDER - THICK
+
+    pos = {}
     position = BORDER + THICK
-    pos = {}
-    pos[0] = position + (SQUARE_SIZE/2.0)
+    pos[0] = position + SQUARE_SIZE/2.
     last_line = 0
     for n in range(1,SUDOKU_SIZE):
         if n % N_BOXES == 0:
@@ -63,18 +84,18 @@
             cr.set_line_width(THIN)
             position += SQUARE_SIZE + last_line/2.0 + THIN/2.0
             last_line = THIN
-        pos[n] = position + ((last_line + SQUARE_SIZE)/2.0)
-        cr.move_to(BORDER,position)
-        cr.line_to(SIZE-BORDER,position)
-        cr.move_to(position,BORDER)
-        cr.line_to(position,SIZE-BORDER)
+        pos[n] = position + last_line/2. + SQUARE_SIZE/2.0
+        cr.move_to(BORDER+THICK/2.+offset_x, position+offset_y)
+        cr.line_to(size-BORDER-THICK/2.+offset_x, position+offset_y)
+        cr.move_to(position+offset_x, BORDER+THICK/2.+offset_y)
+        cr.line_to(position+offset_x, size-BORDER-THICK/2.+offset_y)
         cr.stroke()
     cr.set_font_size(FONT_SIZE)
     for x in range(SUDOKU_SIZE):
         for y in range(SUDOKU_SIZE):
-            cr.move_to(pos[x],pos[y])
+            cr.move_to(pos[x]+offset_x,pos[y]+offset_y)
             letter = None
-            if sudoku[y][x]:
+            if sudoku and sudoku[y][x]:
                 letter = str(sudoku[y][x])
                 cr.select_font_face("",
                          cairo.FONT_SLANT_NORMAL,
@@ -94,15 +115,40 @@
                     cr.text_extents(letter)
                     )
             if letter:
-                cr.move_to(pos[x]-(xadvance/2.0),
-                           pos[y]+(height/2.0))
+                cr.move_to(pos[x]+offset_x-(xadvance/2.0),
+                           pos[y]+offset_y+(height/2.0))
                 cr.show_text(letter)
-    return surface
 
-def make_pixbuf (sudoku, played, highlight_color):
-    surf = make_image_surface(sudoku,played,highlight_color)
-    pixbuf = gtk.gdk.pixbuf_new_from_data(surf.get_data(), gtk.gdk.COLORSPACE_RGB,
-                                          True, 8, SIZE, SIZE, SIZE*4)
-    del surf
+def make_pixbuf (sudoku, played, border_color, line_color=(0.4,0.4,0.4)):
+    size = 120
+    surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, size, size)
+    cr = cairo.Context(surface)
+    draw_sudoku(cr, sudoku, played,  size, 0, 0, border_color, line_color)
+    pixbuf = gtk.gdk.pixbuf_new_from_data(surface.get_data(), gtk.gdk.COLORSPACE_RGB,
+                                          True, 8, surface.get_width(), surface.get_height(), surface.get_stride())
+    del surface
     return pixbuf
 
+if __name__ == "__main__":
+    sudoku = [[0, 0, 2, 3, 4, 5, 6, 0, 0]]*SUDOKU_SIZE
+    played = [[1,2,0,0,0,0,0,0,0,0]]+[[0,0,0,0,0,0,0,0,0,0]]*8
+
+
+    size = 250
+    line_color=(0.0,0.0,0.0)
+    border_color=(1.0,0.0,0.0)
+    surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 750, 750)
+    cr = cairo.Context(surface)
+    draw_sudoku(cr, sudoku, played,  size, 100, 250, border_color, line_color)
+    pb = gtk.gdk.pixbuf_new_from_data(surface.get_data(), gtk.gdk.COLORSPACE_RGB,
+                                          True, 8, surface.get_width(), surface.get_height(), surface.get_stride())
+    del surface
+
+
+    w = gtk.Window()
+    img = gtk.Image()
+    img.set_from_pixbuf(pb)
+    w.add(img)
+    w.show_all()
+    gtk.main()
+
Index: gnome-sudoku/src/lib/game_selector.py
===================================================================
--- gnome-sudoku/src/lib/game_selector.py	(revision 8865)
+++ gnome-sudoku/src/lib/game_selector.py	(working copy)
@@ -290,21 +290,17 @@
         sudokus = [(sudoku.sudoku_grid_from_string(puzzle),
                     "%s (%.2f)"%(sudoku.get_difficulty_category_name(d),d)
                     ) for puzzle,d in sudokus]
-        from printing import SudokuPrinter
-        sp = SudokuPrinter(sudokus,
-                           sudokus_per_page=self.sudokusPerPageSpinButton.get_adjustment().get_value(),
-                           dialog_parent=self.dialog)
+        from printing import SudokuPrinterNew
+        sp = SudokuPrinterNew(sudokus,
+                           self.dialog,
+                           sudokus_per_page=self.sudokusPerPageSpinButton.get_adjustment().get_value())
+
         self.sudokus_printed = sudokus
-        sp.run()
-        sp.dialog.connect('response',
-                          self.print_dialog_response_cb)
+        response = sp.print_op.run(gtk.PRINT_OPERATION_ACTION_PRINT_DIALOG, sp.main_window)
 
-    def print_dialog_response_cb (self, dialog, response):
-        if response == gnomeprint.ui.DIALOG_RESPONSE_CANCEL:
+        if response   == gtk.PRINT_OPERATION_RESULT_ERROR:
             pass
-        elif response == gnomeprint.ui.DIALOG_RESPONSE_PREVIEW:
-            pass
-        elif response==gnomeprint.ui.DIALOG_RESPONSE_PRINT:
+        elif response == gtk.PRINT_OPERATION_RESULT_APPLY:
             if self.markAsPlayedToggle.get_active():
                 for sud,lab in self.sudokus_printed:
                     jar = {}
@@ -316,6 +312,5 @@
             self.dialog.hide()
 
     def run_dialog (self):
-        #self.setup_dialog()
         self.dialog.show()
 
Index: gnome-sudoku/src/lib/main.py
===================================================================
--- gnome-sudoku/src/lib/main.py	(revision 8865)
+++ gnome-sudoku/src/lib/main.py	(working copy)
@@ -815,7 +815,7 @@
 
     @simple_debug
     def print_game (self, *args):
-        printing.print_sudokus([self.gsd])
+        printing.print_sudokus([self.gsd], self.w)
 
     @simple_debug
     def print_multiple_games (self, *args):
