# Copyright 2007 Owen Taylor
# Copyright 2010 Jorn Baayen
#
# This file is part of Reinteract and distributed under the terms
# of the BSD license. See the file COPYING in the Reinteract
# distribution for full details.
#
########################################################################

import gtk

class CustomResult(object):
    def create_widget(self):
        raise NotImplementedError()

    def print_result(self, print_context, render):
        """Measure the result for printing or print it. If this isn't overridden, then
        the printing code will fall back to unicode(result). The result should be
        printed starting at a y position of 0 - an appropriate translation will already
        be set on the print context obtained with print_context.get_cairo_context().

        @param print_context: gtk.PrintContext where printing is occurring
        @render: if False, then we're measuring for pagination, and the routine should
          simply return the height. If True, then the routine should print the object
          and also return the height.

        """
        raise NotImplementedError()

class ResultWidget(gtk.DrawingArea):
    """Base class for custom result widgets that draw their own content"""

    __gsignals__ = {
    }

    def __init__(self):
        gtk.DrawingArea.__init__(self)

        self.parent_style_set_id = 0
        self.notify_resolution_id = 0

    def do_screen_changed(self, previous_screen):
        if self.notify_resolution_id > 0:
            previous_screen.handler_disconnect(self.notify_resolution_id)
            self.notify_resolution_id = 0

        screen = self.get_screen()
        if screen:
            self.notify_resolution_id = \
                screen.connect("notify::resolution", self._on_notify_resolution)
            self.sync_dpi(screen.get_resolution())

    def do_parent_set(self, previous_parent):
        # We follow the parent GtkTextView text size.
        if self.parent_style_set_id > 0:
            previous_parent.handler_disconnect(self.parent_style_set_id)
            self.parent_style_set_id = 0

        if self.parent:
            self.parent_style_set_id = \
                self.parent.connect("style-set", self._on_parent_style_set)
            self.sync_style(self.parent.style)

    def _on_notify_resolution(self, screen, param_spec):
        self.sync_dpi(screen.get_resolution())

    def _on_parent_style_set(self, widget, previous_style):
        self.sync_style(self.parent.style)

        self.queue_resize()

    def sync_dpi(self, dpi):
        pass

    def sync_style(self, style):
        pass

def show_menu(widget, event, save_callback=None):
    """Convenience function to create a right-click menu with a Save As option"""

    toplevel = widget.get_toplevel()
        
    menu = gtk.Menu()
    menu.attach_to_widget(widget, None)
    menu_item = gtk.ImageMenuItem(stock_id=gtk.STOCK_SAVE_AS)
    menu_item.show()
    menu.add(menu_item)
        
    def on_selection_done(menu):
        menu.destroy()
    menu.connect('selection-done', on_selection_done)
            
    def on_activate(menu):
        chooser = gtk.FileChooserDialog("Save As...", toplevel, gtk.FILE_CHOOSER_ACTION_SAVE,
                                        (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
                                         gtk.STOCK_SAVE,   gtk.RESPONSE_OK))
        chooser.set_default_response(gtk.RESPONSE_OK)
        response = chooser.run()
        filename = None
        if response == gtk.RESPONSE_OK:
            filename = chooser.get_filename()
                        
        chooser.destroy()

        if filename is not None:
            save_callback(filename)
                    
    menu_item.connect('activate', on_activate)
    menu.popup(None, None, None, event.button, event.time)

@@ -1421,22 +1421,18 @@
  do_
-screen_changed
+parent_set
 (sel
@@ -1443,22 +1443,22 @@
 revious_
-screen
+parent
 ):%0A     
@@ -1464,115 +1464,257 @@
     
-if self.notify_resolution_id %3E 0:%0A            previous_screen.handler_disconnect(self.notify_resolution_id)
+# Multiple independent screens is unlikely to ever come up, and assuming%0A        # this is much easier to get right than tracking the current screen%0A        screen = gtk.gdk.screen_get_default()%0A%0A        # We follow the parent GtkTextView text size.
 %0A   
@@ -1722,51 +1722,53 @@
     
-   
+if
  self.
-notify_resolution
+parent_style_set
 _id 
-= 0%0A%0A
+%3E 0:%0A    
         
 scre
@@ -1767,53 +1767,110 @@
     
-screen = self.get_screen()%0A        if screen:
+previous_parent.handler_disconnect(self.parent_style_set_id)%0A            self.parent_style_set_id = 0%0A
 %0A   
@@ -1870,27 +1870,26 @@
  0%0A%0A        
-   
+if
  self.notify
@@ -1899,32 +1899,29 @@
 solution_id 
-= %5C%0A    
+%3E 0:%0A
             
@@ -1931,47 +1931,32 @@
 een.
-connect(%22notify::resolution%22, 
+handler_disconnect(
 self.
-_on_
 noti
@@ -1968,16 +1968,19 @@
 solution
+_id
 )%0A      
@@ -1994,151 +1994,69 @@
 elf.
-sync_dpi(screen.get_resolution())%0A%0A    def do_parent_set(self, previous_parent):%0A        # We follow the parent GtkTextView text size.%0A
+notify_resolution_id = 0%0A%0A        if self.parent:%0A   
         
 if s
@@ -2043,34 +2043,32 @@
 ent:%0A           
-if
  self.parent_sty
@@ -2069,36 +2069,35 @@
 nt_style_set_id 
-%3E 0:
+= %5C
 %0A            pre
@@ -2097,48 +2097,54 @@
     
-previous_parent.handler_disconnect(
+    self.parent.connect(%22style-set%22, 
 self.
+_on_
 pare
@@ -2147,35 +2147,32 @@
 parent_style_set
-_id
 )%0A            se
@@ -2178,44 +2178,19 @@
 elf.
-parent_style_set_id = 0%0A%0A        if 
+sync_style(
 self
@@ -2188,33 +2188,40 @@
 tyle(self.parent
-:
+.style)%0A
 %0A            sel
@@ -2222,32 +2222,33 @@
    self.
-parent_style_set
+notify_resolution
 _id = %5C%0A
@@ -2260,34 +2260,29 @@
            s
-elf.par
+cre
 en
-t
 .connect(%22st
@@ -2283,92 +2283,106 @@
 ct(%22
-style-set%22, self._on_parent_style_set)%0A            self.sync_style(self.parent.style
+notify::resolution%22, self._on_notify_resolution)%0A            self.sync_dpi(screen.get_resolution()
 )%0A%0A 

fix disconnecting from the screen's resolution signal