class OficinaActivity(activity.Activity):

    def __init__(self, handle):
        """Initialize the OficinaActivity object.

            @param  self
            @param  handle

        """
        activity.Activity.__init__(self, handle)
        self.max_participants = 1

        logging.debug('Starting Paint activity (Oficina)')

        self.fixed = Gtk.Fixed()
        self._width = Gdk.Screen.width()
        self._height = Gdk.Screen.height()
        self.fixed.show()
        self.fixed.modify_bg(Gtk.StateType.NORMAL,
                             style.COLOR_WHITE.get_gdk_color())

        self.textview = Gtk.TextView()

        self.textview.set_events(Gdk.EventMask.POINTER_MOTION_MASK |
                                 Gdk.EventMask.POINTER_MOTION_HINT_MASK |
                                 Gdk.EventMask.BUTTON_PRESS_MASK |
                                 Gdk.EventMask.BUTTON_RELEASE_MASK |
                                 Gdk.EventMask.BUTTON_MOTION_MASK |
                                 Gdk.EventMask.TOUCH_MASK)

        self.textview.connect('event', self.__textview_event_cb)
        self.textview.connect("motion_notify_event",
                              self.__textview_mouse_move_cb)

        self.fixed.put(self.textview, 0, 0)

        # These attributes are used in other classes, so they should be public
        self.area = Area(self)
        self.area.show()
        self.fixed.put(self.area, 0, 0)

        self.board = BulletinBoard(self)

        self.fixed.put(self.board.fixed, 0, 0)

        self._sw = Gtk.ScrolledWindow()
        self._sw.set_kinetic_scrolling(False)
        self._sw.show()
        self._sw.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
        self.set_canvas(self._sw)

        self.toolset_intialize_from_journal()

        toolbar_box = DrawToolbarBox(self)

        toolbar_box.toolbar.insert(self.board.button, -1)

        #toolbar_box.toolbar.insert(self.board.share_button, -1)
        #toolbar_box.toolbar.insert(self.board.button, -1)
        self.board.button.show()
        toolbar_box.show_all()
        #self.board.box_button.hide()
        #self.board.share_button.hide()

        self.connect("key_press_event", self.key_press)

        # setup self.area only once

        def map_cp(widget):

            def size_allocate_cb(widget, allocation):
                widget.disconnect(self._setup_handle)
                self.area.setup(allocation.width, allocation.height)
                self.center_area()

            self.canvas.add_with_viewport(self.fixed)
            # to remove the border, we need set the shadowtype
            # in the viewport child of the scrolledwindow
            self.canvas.get_children()[0].set_shadow_type(Gtk.ShadowType.NONE)
            self.disconnect(self._setup_handle)
            self._setup_handle = self._sw.connect('size_allocate',
                                                  size_allocate_cb)

        self._setup_handle = self.connect('map', map_cp)

        # Handle screen rotation
        Gdk.Screen.get_default().connect('size-changed', self._configure_cb)

    def _configure_cb(self, event):
        ''' Rotate the drawing after a screen rotation '''
        width = Gdk.Screen.width()
        height = Gdk.Screen.height()
        if (self._width > self._height) != (width > height):
            GObject.timeout_add(100, self.area.rotate_right, self.area)
        self._width = width
        self._height = height

    def key_press(self, widget, event):
        print event.keyval
        if event.keyval == 45:
            self.area.change_line_size(-1)
        if event.keyval == 43:
            self.area.change_line_size(1)

    def read_file(self, file_path):
        '''Read file from Sugar Journal.'''
        logging.debug('reading file %s, mimetype: %s, title: %s',
                      file_path, self.metadata['mime_type'],
                      self.metadata['title'])

        self.area.load_from_file(file_path)

        def size_allocate_cb(widget, allocation):
            logging.error('read file size allocate')
            self.fixed.disconnect(self._setup_handle)
            width = self.area.drawing_canvas_data.get_width()
            height = self.area.drawing_canvas_data.get_height()
            if self.area.drawing_canvas is None:
                self.area.setup(width, height)
            # The scrolled window is confused with a image of the same size
            # of the canvas when the toolbars popup and the scrolls
            # keep visible.
            if height > allocation.height or width > allocation.width:
                self.canvas.set_policy(Gtk.PolicyType.AUTOMATIC,
                                       Gtk.PolicyType.AUTOMATIC)
            else:
                self.canvas.set_policy(Gtk.PolicyType.NEVER,
                                       Gtk.PolicyType.AUTOMATIC)

            self.center_area()

        self.canvas.add_with_viewport(self.fixed)
        # to remove the border, we need set the shadowtype
        # in the viewport child of the scrolledwindow
        self.canvas.get_children()[0].set_shadow_type(Gtk.ShadowType.NONE)
        self.canvas.get_children()[0].set_border_width(0)

        self.disconnect(self._setup_handle)
        self._setup_handle = self.fixed.connect('size_allocate',
                                                size_allocate_cb)

        # disassociate with journal entry to avoid overwrite (SL #1771)
        if self.metadata['mime_type'] != "image/png":
            self._jobject.object_id = None
            last_point_posi = self.metadata['title'].rfind('.')
            if last_point_posi > -1:
                title = self.metadata['title'][0:last_point_posi] + '.png'
                self.metadata['title'] = title
            logging.error('title: %s', self.metadata['title'])

    def write_file(self, file_path):
        '''Save file on Sugar Journal. '''

        width, height = self.area.get_size_request()

        logging.debug('writting %s w=%s h=%s' % (file_path, width, height))
        if self.area.text_in_progress:
            self.area.d.text(self.area, 0, 0)

        self.area.getout()
        self.area.drawing_canvas.write_to_png(file_path)
        self.metadata['mime_type'] = 'image/png'
        self.metadata['state'] = json.dumps(self.area.tool)
        logging.debug('Wrote metadata[\'state\']: %s', self.metadata['state'])

    def _get_area_displacement(self):
        """Return the point to use as top left corner in order to move
        the drawing area and center it on the canvas.

        """
        canvas_width = self.canvas.get_allocation().width
        canvas_height = self.canvas.get_allocation().height
        area_width, area_height = self.area.get_size_request()

        # Avoid 'x' and 'y' to be outside the screen
        x = max(0, (canvas_width - area_width) / 2)
        y = max(0, (canvas_height - area_height) / 2)
        return x, y

    def center_area(self):
        x, y = self._get_area_displacement()
        self.fixed.move(self.area, x, y)

    def move_textview(self, dx, dy):
        x, y = self._get_area_displacement()
        self.fixed.move(self.textview, x + dx, y + dy)

    def toolset_intialize_from_journal(self):
        try:
            self.area.tool = json.loads(self.metadata['state'])
            logging.debug('self.area.tool %s', self.area.tool)
        except Exception as e:
            logging.error("exception %s", e)

    def __textview_event_cb(self, widget, event):
        if event.type in (Gdk.EventType.TOUCH_BEGIN,
                          Gdk.EventType.TOUCH_CANCEL, Gdk.EventType.TOUCH_END,
                          Gdk.EventType.BUTTON_PRESS,
                          Gdk.EventType.BUTTON_RELEASE):
            x = int(event.get_coords()[1])
            y = int(event.get_coords()[2])
            if event.type in (Gdk.EventType.TOUCH_BEGIN,
                              Gdk.EventType.BUTTON_PRESS):
                self._initial_textview_touch_x = x
                self._initial_textview_touch_y = y
            elif event.type in (Gdk.EventType.TOUCH_END,
                                Gdk.EventType.BUTTON_RELEASE):
                # be sure the textview don't have a selection pending
                # and put the cursor at the end of the text
                text_buf = self.textview.get_buffer()
                end_text_iter = text_buf.get_end_iter()
                text_buf.select_range(end_text_iter, end_text_iter)

    def __textview_mouse_move_cb(self, widget, event):
        x = event.x
        y = event.y
        if event.get_state() & Gdk.ModifierType.BUTTON1_MASK:
            dx = x - self._initial_textview_touch_x
            dy = y - self._initial_textview_touch_y
            tv_alloc = self.textview.get_allocation()
            self.move_textview(tv_alloc.x + dx, tv_alloc.y + dy)
class OficinaActivity(activity.Activity):
    def __init__(self, handle):
        """Initialize the OficinaActivity object.

            @param  self
            @param  handle

        """
        activity.Activity.__init__(self, handle)
        self.max_participants = 1

        logging.debug('Starting Paint activity (Oficina)')

        self.fixed = Gtk.Fixed()
        self._width = Gdk.Screen.width()
        self._height = Gdk.Screen.height()
        self.fixed.show()
        self.fixed.modify_bg(Gtk.StateType.NORMAL,
                             style.COLOR_WHITE.get_gdk_color())

        self.textview = Gtk.TextView()

        self.textview.set_events(Gdk.EventMask.POINTER_MOTION_MASK
                                 | Gdk.EventMask.POINTER_MOTION_HINT_MASK
                                 | Gdk.EventMask.BUTTON_PRESS_MASK
                                 | Gdk.EventMask.BUTTON_RELEASE_MASK
                                 | Gdk.EventMask.BUTTON_MOTION_MASK
                                 | Gdk.EventMask.TOUCH_MASK)

        self.textview.connect('event', self.__textview_event_cb)
        self.textview.connect("motion_notify_event",
                              self.__textview_mouse_move_cb)

        self.fixed.put(self.textview, 0, 0)

        # These attributes are used in other classes, so they should be public
        self.area = Area(self)
        self.area.show()
        self.fixed.put(self.area, 0, 0)

        self.board = BulletinBoard(self)

        self.fixed.put(self.board.fixed, 0, 0)

        self._sw = Gtk.ScrolledWindow()
        self._sw.set_kinetic_scrolling(False)
        self._sw.show()
        self._sw.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
        self.set_canvas(self._sw)

        self.toolset_intialize_from_journal()

        toolbar_box = DrawToolbarBox(self)

        toolbar_box.toolbar.insert(self.board.button, -1)

        #toolbar_box.toolbar.insert(self.board.share_button, -1)
        #toolbar_box.toolbar.insert(self.board.button, -1)
        self.board.button.show()
        toolbar_box.show_all()
        #self.board.box_button.hide()
        #self.board.share_button.hide()

        self.connect("key_press_event", self.key_press)

        # setup self.area only once

        def map_cp(widget):
            def size_allocate_cb(widget, allocation):
                widget.disconnect(self._setup_handle)
                self.area.setup(allocation.width, allocation.height)
                self.center_area()

            self.canvas.add_with_viewport(self.fixed)
            # to remove the border, we need set the shadowtype
            # in the viewport child of the scrolledwindow
            self.canvas.get_children()[0].set_shadow_type(Gtk.ShadowType.NONE)
            self.disconnect(self._setup_handle)
            self._setup_handle = self._sw.connect('size_allocate',
                                                  size_allocate_cb)

        self._setup_handle = self.connect('map', map_cp)

        # Handle screen rotation
        Gdk.Screen.get_default().connect('size-changed', self._configure_cb)

    def _configure_cb(self, event):
        ''' Rotate the drawing after a screen rotation '''
        width = Gdk.Screen.width()
        height = Gdk.Screen.height()
        if (self._width > self._height) != (width > height):
            GObject.timeout_add(100, self.area.rotate_right, self.area)
        self._width = width
        self._height = height

    def key_press(self, widget, event):
        print event.keyval
        if event.keyval == 45:
            self.area.change_line_size(-1)
        if event.keyval == 43:
            self.area.change_line_size(1)

    def read_file(self, file_path):
        '''Read file from Sugar Journal.'''
        logging.debug('reading file %s, mimetype: %s, title: %s', file_path,
                      self.metadata['mime_type'], self.metadata['title'])

        self.area.load_from_file(file_path)

        def size_allocate_cb(widget, allocation):
            logging.error('read file size allocate')
            self.fixed.disconnect(self._setup_handle)
            width = self.area.drawing_canvas_data.get_width()
            height = self.area.drawing_canvas_data.get_height()
            if self.area.drawing_canvas is None:
                self.area.setup(width, height)
            # The scrolled window is confused with a image of the same size
            # of the canvas when the toolbars popup and the scrolls
            # keep visible.
            if height > allocation.height or width > allocation.width:
                self.canvas.set_policy(Gtk.PolicyType.AUTOMATIC,
                                       Gtk.PolicyType.AUTOMATIC)
            else:
                self.canvas.set_policy(Gtk.PolicyType.NEVER,
                                       Gtk.PolicyType.AUTOMATIC)

            self.center_area()

        self.canvas.add_with_viewport(self.fixed)
        # to remove the border, we need set the shadowtype
        # in the viewport child of the scrolledwindow
        self.canvas.get_children()[0].set_shadow_type(Gtk.ShadowType.NONE)
        self.canvas.get_children()[0].set_border_width(0)

        self.disconnect(self._setup_handle)
        self._setup_handle = self.fixed.connect('size_allocate',
                                                size_allocate_cb)

        # disassociate with journal entry to avoid overwrite (SL #1771)
        if self.metadata['mime_type'] != "image/png":
            self._jobject.object_id = None
            last_point_posi = self.metadata['title'].rfind('.')
            if last_point_posi > -1:
                title = self.metadata['title'][0:last_point_posi] + '.png'
                self.metadata['title'] = title
            logging.error('title: %s', self.metadata['title'])

    def write_file(self, file_path):
        '''Save file on Sugar Journal. '''

        width, height = self.area.get_size_request()

        logging.debug('writting %s w=%s h=%s' % (file_path, width, height))
        if self.area.text_in_progress:
            self.area.d.text(self.area, 0, 0)

        self.area.getout()
        self.area.drawing_canvas.write_to_png(file_path)
        self.metadata['mime_type'] = 'image/png'
        self.metadata['state'] = json.dumps(self.area.tool)
        logging.debug('Wrote metadata[\'state\']: %s', self.metadata['state'])

    def _get_area_displacement(self):
        """Return the point to use as top left corner in order to move
        the drawing area and center it on the canvas.

        """
        canvas_width = self.canvas.get_allocation().width
        canvas_height = self.canvas.get_allocation().height
        area_width, area_height = self.area.get_size_request()

        # Avoid 'x' and 'y' to be outside the screen
        x = max(0, (canvas_width - area_width) / 2)
        y = max(0, (canvas_height - area_height) / 2)
        return x, y

    def center_area(self):
        x, y = self._get_area_displacement()
        self.fixed.move(self.area, x, y)

    def move_textview(self, dx, dy):
        x, y = self._get_area_displacement()
        self.fixed.move(self.textview, x + dx, y + dy)

    def toolset_intialize_from_journal(self):
        try:
            self.area.tool = json.loads(self.metadata['state'])
            logging.debug('self.area.tool %s', self.area.tool)
        except Exception as e:
            logging.error("exception %s", e)

    def __textview_event_cb(self, widget, event):
        if event.type in (Gdk.EventType.TOUCH_BEGIN,
                          Gdk.EventType.TOUCH_CANCEL, Gdk.EventType.TOUCH_END,
                          Gdk.EventType.BUTTON_PRESS,
                          Gdk.EventType.BUTTON_RELEASE):
            x = int(event.get_coords()[1])
            y = int(event.get_coords()[2])
            if event.type in (Gdk.EventType.TOUCH_BEGIN,
                              Gdk.EventType.BUTTON_PRESS):
                self._initial_textview_touch_x = x
                self._initial_textview_touch_y = y
            elif event.type in (Gdk.EventType.TOUCH_END,
                                Gdk.EventType.BUTTON_RELEASE):
                # be sure the textview don't have a selection pending
                # and put the cursor at the end of the text
                text_buf = self.textview.get_buffer()
                end_text_iter = text_buf.get_end_iter()
                text_buf.select_range(end_text_iter, end_text_iter)

    def __textview_mouse_move_cb(self, widget, event):
        x = event.x
        y = event.y
        if event.get_state() & Gdk.ModifierType.BUTTON1_MASK:
            dx = x - self._initial_textview_touch_x
            dy = y - self._initial_textview_touch_y
            tv_alloc = self.textview.get_allocation()
            self.move_textview(tv_alloc.x + dx, tv_alloc.y + dy)