Beispiel #1
0
 def reset_hotkey(self):
     """Reset the system for the next stream of hotkey up/down events"""
     self.hotkey_pressed = False
     if not self.canvas.selected:
         return
     self.canvas.selected.end_select_action(0)
     pub.sendMessage('update_shape_viewer')
Beispiel #2
0
    def redraw_all(self, update_thumb=False, dc=None, resizing=False):
        """
        Redraws all shapes that have been drawn. self.text is used to show text
        characters as they're being typed, as new Text/Note objects have not
        been added to self.shapes at this point.
        dc is used as the DC for printing.
        """
        if not dc:
            dc = wx.BufferedDC(None, self.buffer)
            dc.Clear()

        for s in self.shapes:
            if not resizing:
                s.draw(dc, True)
            else:
                if not isinstance(s, Highlighter):
                    s.draw(dc, True)

        if self.text:
            self.text.draw(dc, True)
        if self.copy:
            self.copy.draw(dc, True)
        self.Refresh()
        if update_thumb:
            pub.sendMessage('thumbs.update_current')
Beispiel #3
0
    def change_tool(self, new=None, canvas=None):
        if not canvas:
            canvas = self.canvas

        self.util.change_tool(canvas, new)
        canvas.change_tool()
        pub.sendMessage('gui.preview.refresh')
Beispiel #4
0
    def add_undo(self):
        """Creates an undo point. NEED to change this for memory improvements"""
        l = self.clone_shapes()
        self.undo_list.append(l)

        if self.redo_list:
            self.redo_list = []
        pub.sendMessage('gui.mark_unsaved')
Beispiel #5
0
 def paste_text(self, text, x, y, colour):
     """Pastes a string onto the canvas, as a Text object"""
     self.shape = Text(self, colour, 1)
     self.shape.text = text
     self.shape.left_down(x, y)
     self.shape.left_up(x, y)
     self.text = None
     pub.sendMessage('canvas.change_tool')
     self.redraw_all(True)
Beispiel #6
0
    def on_swap(self, event):
        """Swaps foreground/background colours"""
        background, colour = self.get_background_colour(), self.get_colour()
        self.background.SetColour(colour)
        self.colour.SetColour(background)
        self.gui.util.colour = background

        if not self.transparent.IsChecked():
            self.gui.util.background = background
        pub.sendMessage('canvas.change_tool')
Beispiel #7
0
    def on_transparency(self, event):
        """Toggles transparency in the shapes' background"""
        self.gui.util.transparent = False

        if event.Checked() and not self.gui.canvas.selected:
            self.gui.util.transparent = True

        if self.gui.canvas.selected:
            self.gui.canvas.toggle_transparent()
        pub.sendMessage('canvas.change_tool')
Beispiel #8
0
def load_image(path, canvas, image_class):
    """
    Loads an image into the given Whyteboard tab. bitmap is the path to an
    image file to create a bitmap from.
    image_class = tools.Image *CLASS ITSELF*
    """
    logger.debug("Loading [%s] and creating an Image object", path)
    image = wx.Bitmap(path)
    shape = image_class(canvas, image, path)
    shape.left_down(0, 0)  # renders, updates scrollbars
    pub.sendMessage("thumbs.update_current")
Beispiel #9
0
    def add_shape(self, shape):
        """ Adds a shape to the shape list managed by the canvas. """
        self.add_undo()
        self.shapes.append(shape)

        if self.selected:
            self.deselect_shape()
            self.redraw_all()
        if self.text:
            self.text = None
        if self.copy:
            self.copy = None
            self.redraw_all()
        pub.sendMessage('update_shape_viewer')
Beispiel #10
0
    def on_rename(self, event=None, sheet=None):
        if sheet is None:
            sheet = self.current_tab
        current_name = self.tabs.GetPageText(sheet)
        dlg = wx.TextEntryDialog(self, _("Rename this sheet to:"), _("Rename sheet"))
        dlg.SetValue(current_name)

        if dlg.ShowModal() == wx.ID_CANCEL:
            dlg.Destroy()
        else:
            val = dlg.GetValue()
            if val:
                logger.debug("Renaming sheet [%s] to [%s]", current_name, val)
                self.tabs.SetPageText(sheet, val)
                pub.sendMessage('sheet.rename', _id=sheet, text=val)
Beispiel #11
0
    def on_change_tab(self, event=None):
        """Updates tab vars, scrolls thumbnails and selects tree node"""
        self.canvas = self.tabs.GetCurrentPage()
        self.update_panels(False)
        self.current_tab = self.tabs.GetSelection()

        self.update_panels(True)
        self.thumbs.thumbs[self.current_tab].update()
        self.thumbs.ScrollChildIntoView(self.thumbs.thumbs[self.current_tab])
        self.control.change_tool()  # updates canvas' shape

        if self.notes.tabs:
            tree_id = self.notes.tabs[self.current_tab]
            self.notes.tree.SelectItem(tree_id, True)
        pub.sendMessage('update_shape_viewer')
Beispiel #12
0
    def change_tool(self, event=None, _id=None):
        """
        Toggles the tool buttons on/off
        """
        new = self.gui.util.tool
        if event and not _id:
            new = int(event.GetId())
        elif _id:
            new = _id

        for button in self.tools.values():
            button.SetValue(False)

        self.tools[new].SetValue(True)
        pub.sendMessage('canvas.change_tool', new=new)
Beispiel #13
0
    def delete_selected(self):
        """Deletes the selected shape"""
        if not self.selected:
            return

        if isinstance(self.selected, Media):
            self.selected.remove_panel()
        else:
            if isinstance(self.selected, Note):
                self.gui.notes.tree.Delete(self.selected.tree_id)
            self.add_undo()
            self.shapes.remove(self.selected)
        pub.sendMessage('update_shape_viewer')
        self.selected = None
        self.redraw_all(True)
Beispiel #14
0
    def update(self, value, var_name, add_undo=True):
        """Updates the given utility variable and the selected shape"""
        setattr(self.gui.util, var_name, value)

        if self.gui.canvas.selected:
            if add_undo:
                self.gui.canvas.add_undo()
            if var_name == u"background" and not self.transparent.IsChecked():
                self.gui.canvas.selected.background = value
            elif var_name != u"background":
                setattr(self.gui.canvas.selected, var_name, value)
            self.gui.canvas.redraw_all(True)
            pub.sendMessage('update_shape_viewer')

        pub.sendMessage('canvas.change_tool')
        self.preview.Refresh()
Beispiel #15
0
    def on_drop_tab(self, event):
        """
        Update the thumbs/notes so that they're poiting to the new tab position.
        Show a progress dialog, as all thumbnails must be updated.
        """
        if event.GetSelection() == event.GetOldSelection():
            return

        self.show_progress_dialog(_("Loading..."))
        self.dialog.Show()
        self.on_change_tab()

        pub.sendMessage('sheet.move', event=event, tab_count=self.tab_count)
        self.on_done_load()
        wx.MilliSleep(100)  # try and stop user dragging too many tabs quickly
        wx.SafeYield()
        pub.sendMessage('update_shape_viewer')
Beispiel #16
0
    def on_undo_tab(self, event=None, tab=None):
        """
        Undoes the last closed tab from the list.
        Re-creates the canvas from the saved shapes/undo/redo lists
        """
        if not self.closed_tabs:
            return
        if not tab:
            tab = self.closed_tabs.pop()
        else:
            tab = self.closed_tabs.pop(self.closed_tabs.index(tab))

        self.on_new_tab(name=tab['name'], wb=True)
        self.canvas.restore_sheet(tab['shapes'], tab['undo'], tab['redo'],
                                  tab['size'], tab['medias'], tab['viewport'])
        pub.sendMessage('update_shape_viewer')
        self.menu.make_closed_tabs_menu()
Beispiel #17
0
    def clear(self, keep_images=False):
        """Removes all shapes. Images can be specified to not be removed."""
        if not self.medias and not self.shapes:
            return

        for m in self.medias:
            m.remove_panel()
        self.medias = []
        images = []

        if self.shapes:
            self.add_undo()
            if keep_images:
                for x in self.shapes:
                    if isinstance(x, Image):
                        images.append(x)

        self.shapes = images
        pub.sendMessage('update_shape_viewer')
        self.redraw_all(update_thumb=True)
Beispiel #18
0
    def perform(self, list_a, list_b):
        """ Perform undo/redo. list_a: to remove from / list b: append to """
        if not list_a:
            return
        list_b.append(list(self.shapes))
        self.shapes = list_a.pop()
        self.deselect_shape()
        self.redraw_all(True)

        pub.sendMessage('note.delete_sheet_items')  # lazy way of doing things...
        for x in self.shapes:
            if isinstance(x, Note):
                pub.sendMessage('note.add', note=x)
        pub.sendMessage('gui.mark_unsaved')
        pub.sendMessage('update_shape_viewer')
Beispiel #19
0
    def update_config(self, new_config):
        old_config = Config().config
        if new_config['language'] != old_config['language']:
            wx.MessageBox(_("Whyteboard will be translated into %s when restarted")
                          % _(new_config['language']), u"Whyteboard")
            
        if 'default_font' in new_config:
            if new_config['default_font'] and not self.util.font:
                self.util.font = wx.FFont(1, wx.FONTFAMILY_DEFAULT)
                self.util.font.SetNativeFontInfoFromString(new_config['default_font'])

        # Toggles the items under "View" menu. Ignore the colour grid for now
        for menu_item in ['statusbar', 'toolbar', 'tool_preview']:
            method = getattr(self, "on_" + menu_item)
            if new_config[menu_item]:
                method(None, True)
            else:
                method(None, False)

        new_config.write()
        Config().config = new_config

        if new_config['bmp_select_transparent'] != old_config['bmp_select_transparent']:
            self.canvas.copy = None

        if not new_config['tool_preview']:
            self.control.preview.Hide()
        else:
            self.control.preview.Show()
            pub.sendMessage('gui.preview.refresh')

        wx.CallAfter(self.on_colour_grid, None, new_config['colour_grid'])

        #  too lazy to check if each colour has changed - just remake it
        self.canvas.redraw_all()
        self.control.grid.Clear(True)
        self.control.make_colour_grid()
        self.control.grid.Layout()
Beispiel #20
0
    def restore_sheet(self, shapes, undo_list, redo_list, size, medias, viewport):
        """
        Restores itself (e.g. from undoing closing a sheet.)
        """
        self.shapes = shapes
        self.undo_list = undo_list
        self.redo_list = redo_list
        self.medias = medias

        for media in medias:
            media.canvas = self
            media.make_panel()

        for shape in shapes:
            shape.canvas = self
            if isinstance(shape, Note):
                pub.sendMessage('note.add', note=shape)

        wx.Yield()
        self.resize(size)
        self.Scroll(viewport[0], viewport[1])
        self.redraw_all()
        pub.sendMessage('thumbs.update_current')
Beispiel #21
0
    def make_tools(self):
        # create some shapes
        self.rect = whyteboard.tools.Rectangle(self.canvas, (0, 0, 0), 1)
        self.rect.x = 150
        self.rect.y = 150
        self.rect.width, self.rect.height = 50, 50

        self.text = whyteboard.tools.Text(self.canvas, (0, 0, 0), 3)
        self.text.x = 150
        self.text.y = 150
        self.text.text = "blah blah"  # 'x' extent of 58
        self.text.find_extent()

        self.circle = whyteboard.tools.Circle(self.canvas, (0, 0, 0), 1)
        self.circle.radius = 25
        self.circle.x = 250
        self.circle.y = 250

        # add shapes to canvas, update the shapes for hit testing
        shapes = [self.rect, self.text, self.circle]
        for shape in shapes:
            pub.sendMessage('shape.add', shape=shape)
            shape.sort_handles()
Beispiel #22
0
    def left_up(self, event):
        """
        Called when the left mouse button is released.
        """
        if os.name == "nt" and not self.shape.drawing:
            if self.HasCapture():
                self.ReleaseMouse()

        if self.resizing:
            logger.debug("End resizing.")
            self.resizing = False
            self.redraw_all(True)  # update thumb for new canvas size
            self.Layout()
            if self.copy:
                self.draw_shape(self.copy)  # draw back the GCDC
            return
        if self.drawing or isinstance(self.shape, Text):
            before = len(self.shapes)
            self.shape.left_up(*self.convert_coords(event))
            if not isinstance(self.shape, Media):
                if len(self.shapes) - before:
                    pub.sendMessage('canvas.change_tool')
                    pub.sendMessage('thumbs.update_current')
            self.drawing = False
Beispiel #23
0
    def OnData(self, x, y, d):
        """
        Handles drag/dropping files, text or bitmap items
        """
        if self.GetData():
            df = self.do.GetReceivedFormat().GetType()

            if df in [wx.DF_UNICODETEXT, wx.DF_TEXT]:
                pub.sendMessage('canvas.paste_text', text=self.textdo.GetText(),
                                x=x, y=y)

            elif df == wx.DF_FILENAME:
                for x, name in enumerate(self.filedo.GetFilenames()):
                    pub.sendMessage('gui.open_file', filename=name)

            elif df == wx.DF_BITMAP:
                pub.sendMessage('canvas.paste_image', image=self.bmpdo.GetBitmap(),
                                x=x, y=y, ignore=True)
        return d
Beispiel #24
0
 def on_colour_grid(self, event=None, force=None):
     val = self.get_toggle_value(ID_COLOUR_GRID, force)
     self.control.toggle_colour_grid(val)
     self.menu.check(ID_COLOUR_GRID, val)
     pub.sendMessage('gui.preview.refresh')
Beispiel #25
0
    def recreate_save(self, filename, save_data):
        """
        Recreates the saved .wtbd file's state
        """
        logger.debug("Recreating save file")
        self.filename = filename
        self.gui.show_progress_dialog(_("Loading..."))
        self.gui.remove_all_sheets()

        # change program settings and update the Preview window
        self.colour = save_data[0][0]
        self.thickness = save_data[0][1]
        self.tool = save_data[0][2]
        self.gui.control.change_tool(_id=self.tool)  # toggle button
        self.gui.control.colour.SetColour(self.colour)
        self.gui.control.thickness.SetSelection(self.thickness - 1)

        # re-create tabs and its saved drawings
        for x in save_data[1]:
            self.gui.on_new_tab(name=save_data[3][x])
            size = (Config().default_width(), Config().default_height())
            try:
                size = save_data[4][x]
            except KeyError:
                pass
            self.gui.canvas.resize(size)

            try:
                media = save_data[5][x]
                for m in media:
                    m.canvas = self.gui.canvas
                    m.load()
                    self.gui.canvas.medias.append(m)
            except KeyError:
                break

            for shape in save_data[1][x]:
                try:
                    shape.canvas = self.gui.canvas  # restore canvas
                    shape.load()  # restore unpickleable settings
                    self.gui.canvas.add_shape(shape)
                except Exception:
                    break
            self.gui.canvas.redraw_all(True)

        # close progress bar, handle older file versions gracefully
        wx.PostEvent(self.gui, self.gui.LoadEvent())
        self.mark_saved()
        self.saved_version = save_data[0][4]
        pub.sendMessage("canvas.change_tool")
        self.gui.tabs.SetSelection(save_data[0][3])
        self.gui.on_change_tab()
        self.gui.SetTitle(u"%s - %s" % (os.path.basename(filename), self.gui.title))
        self.gui.closed_tabs = list()

        try:
            if save_data[0][5]:
                logger.debug("Setting default font from save file: [%s]", save_data[0][5])
                font = wx.FFont(1, wx.FONTFAMILY_DEFAULT)
                font.SetNativeFontInfoFromString(save_data[0][5])
                self.font = font
        except IndexError:
            pass

        #  Don't save .wtbd file of future versions as current, older version
        if version_is_greater(self.saved_version, meta.version):
            self.update_version = False
Beispiel #26
0
 def update_panels(self, select):
     """Updates thumbnail panel's text"""
     pub.sendMessage('thumbs.text.highlight', tab=self.current_tab,
                     select=select)
Beispiel #27
0
 def wrapper(self, shape, x=None, item=None):
     x, item = self.do_move(shape)
     fn(self, shape, x, item)
     pub.sendMessage('update_shape_viewer')
     self.redraw_all(True)
Beispiel #28
0
    def __init__(self):
        """
        Initialise utility, status/menu/tool bar, tabs, ctrl panel + bindings.
        """
        wx.Frame.__init__(self, None, title=_("Untitled") + u" - %s" % self.title)
        self.util = Utility(self)

        meta.find_transparent()  # important
        logger.info("Transparency supported: %s", meta.transparent)
        
        if meta.transparent:
            try:
                x = self.util.items.index(Highlighter)
            except ValueError:
                self.util.items.insert(1, Highlighter)

        self.can_paste = check_clipboard()
        self.process = None
        self.pid = None
        self.dialog = None
        self.convert_cancelled = False
        self.shape_viewer_open = False
        self.help = None
        self.hotkey_pressed = False  # for hotkey timer
        self.hotkey_timer = None
        self.tab_count = 1
        self.tab_total = 1
        self.current_tab = 0
        self.closed_tabs = []
        self.hotkeys = []

        style = (fnb.FNB_X_ON_TAB | fnb.FNB_NO_X_BUTTON | fnb.FNB_VC8 |
                 fnb.FNB_DROPDOWN_TABS_LIST | fnb.FNB_MOUSE_MIDDLE_CLOSES_TABS |
                 fnb.FNB_NO_NAV_BUTTONS)

        self.control = ControlPanel(self)
        self.tabs = fnb.FlatNotebook(self, agwStyle=style)
        self.canvas = Canvas(self.tabs, self, (Config().default_width(), Config().default_height()))
        self.panel = SidePanel(self)

        self.thumbs = self.panel.thumbs
        self.notes = self.panel.notes
        self.tabs.AddPage(self.canvas, _("Sheet") + u" 1")

        box = wx.BoxSizer(wx.HORIZONTAL)  # position windows side-by-side
        box.Add(self.control, 0, wx.EXPAND)
        box.Add(self.tabs, 1, wx.EXPAND)
        box.Add(self.panel, 0, wx.EXPAND)
        self.SetSizer(box)
        self.SetSizeWH(800, 600)

        if os.name == "posix":
            self.canvas.SetFocus()  # makes EVT_CHAR_HOOK trigger
        if 'mac' != os.name:
            self.Maximize(True)

        self.paste_check_count = PASTE_CHECK_COUNT - 1
        wx.UpdateUIEvent.SetUpdateInterval(75)
        #wx.UpdateUIEvent.SetMode(wx.UPDATE_UI_PROCESS_SPECIFIED)

        self.SetIcon(icon.getIcon())
        self.SetExtraStyle(wx.WS_EX_PROCESS_UI_UPDATES)
        self.SetDropTarget(CanvasDropTarget())
        self.statusbar = self.CreateStatusBar()
        self._print = Print(self)

        self.filehistory = wx.FileHistory(8)
        self.config = wx.Config()
        self.load_history_file()
        self.filehistory.Load(self.config)

        self.menu = Menu(self)
        self.toolbar = self.CreateToolBar() 
        Toolbar.configure(self.toolbar, self.can_paste)
        self.SetMenuBar(self.menu.menu)
        self.set_menu_from_config()
        self.do_bindings()
        self.find_help()
        
        pub.sendMessage('thumbs.update_current')
        self.update_panels(True)
        wx.CallAfter(self.UpdateWindowUI)