コード例 #1
0
    def __init__(self, filename, id_, item, text):
        self.filename = filename
        self.id_ = id_
        self.item = item
        self.original = text
        self.mtimer = None
        self.tmrunning = False
        config = coreaux_api.get_interface_configuration('wxgui')
        self.DELAY = config.get_int('text_min_upd_time')

        # Do not set the text now, otherwise for example URLs won't be
        # highlighted in blue
        # wx.TE_PROCESS_TAB seems to have no effect...
        self.area = TextUrlCtrl(editor.tabs[item].panel,
                                value='',
                                style=wx.TE_MULTILINE | wx.TE_DONTWRAP
                                | wx.TE_NOHIDESEL)

        font = self.area.GetFont()
        font = wx.Font(font.GetPointSize(), wx.FONTFAMILY_TELETYPE,
                       font.GetStyle(), font.GetWeight(), font.GetUnderlined())
        self.area.SetFont(font)

        # Set the text after setting the font, so for example URLs will be
        # correctly highlighted in blue
        self.area.SetValue(text)

        wx.GetApp().root.accmanager.register_text_ctrl(self.area)

        self.textctrl_nav_keys = {
            # The Ctrl+Enter in the menu isn't processed when the TextCtrl is
            #   focused; wx.TE_PROCESS_ENTER seems to have no effect either...
            wx.WXK_RETURN:
            self._handle_enter_on_textctrl,
            wx.WXK_ESCAPE:
            self._navigate_textctrl_backward,
        }

        # wx.TE_PROCESS_TAB seems to have no effect...
        if not config.get_bool('text_process_tab'):
            # Note that this natively still lets Ctrl+(Shift+)Tab navigate as
            #  expected
            self.textctrl_nav_keys[wx.WXK_TAB] = self._handle_tab_on_textctrl

        self.area.Bind(wx.EVT_KEY_DOWN, self._handle_key_down)

        self.area.Bind(wx.EVT_TEXT, self._handle_text)
        editor.apply_editor_event.bind(self._handle_apply)
        editor.check_modified_state_event.bind(
            self._handle_check_editor_modified)
        editor.close_editor_event.bind(self._handle_close)
コード例 #2
0
ファイル: about.py プロジェクト: xguse/outspline
    def __init__(self, parent):
        wx.SplitterWindow.__init__(self, parent, style=wx.SP_LIVE_UPDATE)

        self.tree = wx.TreeCtrl(self,
                                style=wx.TR_HAS_BUTTONS | wx.TR_HIDE_ROOT
                                | wx.TR_SINGLE | wx.TR_FULL_ROW_HIGHLIGHT)

        self.STYLE_HEAD = wx.TextAttr(
            font=wx.Font(14, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL,
                         wx.FONTWEIGHT_BOLD))
        self.STYLE_NORMAL = wx.TextAttr(
            font=wx.Font(10, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL,
                         wx.FONTWEIGHT_NORMAL))
        self.STYLE_BOLD = wx.TextAttr(
            font=wx.Font(10, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL,
                         wx.FONTWEIGHT_BOLD))
        self.STYLE_ITALIC = wx.TextAttr(
            font=wx.Font(10, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_ITALIC,
                         wx.FONTWEIGHT_NORMAL))

        self.tree.AddRoot(text='root')
        self.init_info()

        self.textw = TextUrlCtrl(self,
                                 value='',
                                 style=wx.TE_MULTILINE | wx.TE_READONLY
                                 | wx.TE_DONTWRAP)

        self.SplitVertically(self.tree, self.textw)

        # Prevent the window from unsplitting when dragging the sash to the
        # border
        self.SetMinimumPaneSize(20)
        self.SetSashPosition(120)

        self.Bind(wx.EVT_SPLITTER_DCLICK, self.veto_dclick)
        self.tree.Bind(wx.EVT_TREE_BEGIN_LABEL_EDIT, self.veto_label_edit)
        self.tree.Bind(wx.EVT_TREE_SEL_CHANGED, self.retrieve_info)

        self.tree.SelectItem(
            self.tree.GetFirstChild(self.tree.GetRootItem())[0])
コード例 #3
0
class TextArea(object):
    def __init__(self, filename, id_, item, text):
        self.filename = filename
        self.id_ = id_
        self.item = item
        self.original = text
        self.mtimer = None
        self.tmrunning = False
        config = coreaux_api.get_interface_configuration('wxgui')
        self.DELAY = config.get_int('text_min_upd_time')

        # Do not set the text now, otherwise for example URLs won't be
        # highlighted in blue
        # wx.TE_PROCESS_TAB seems to have no effect...
        self.area = TextUrlCtrl(editor.tabs[item].panel,
                                value='',
                                style=wx.TE_MULTILINE | wx.TE_DONTWRAP
                                | wx.TE_NOHIDESEL)

        font = self.area.GetFont()
        font = wx.Font(font.GetPointSize(), wx.FONTFAMILY_TELETYPE,
                       font.GetStyle(), font.GetWeight(), font.GetUnderlined())
        self.area.SetFont(font)

        # Set the text after setting the font, so for example URLs will be
        # correctly highlighted in blue
        self.area.SetValue(text)

        wx.GetApp().root.accmanager.register_text_ctrl(self.area)

        self.textctrl_nav_keys = {
            # The Ctrl+Enter in the menu isn't processed when the TextCtrl is
            #   focused; wx.TE_PROCESS_ENTER seems to have no effect either...
            wx.WXK_RETURN:
            self._handle_enter_on_textctrl,
            wx.WXK_ESCAPE:
            self._navigate_textctrl_backward,
        }

        # wx.TE_PROCESS_TAB seems to have no effect...
        if not config.get_bool('text_process_tab'):
            # Note that this natively still lets Ctrl+(Shift+)Tab navigate as
            #  expected
            self.textctrl_nav_keys[wx.WXK_TAB] = self._handle_tab_on_textctrl

        self.area.Bind(wx.EVT_KEY_DOWN, self._handle_key_down)

        self.area.Bind(wx.EVT_TEXT, self._handle_text)
        editor.apply_editor_event.bind(self._handle_apply)
        editor.check_modified_state_event.bind(
            self._handle_check_editor_modified)
        editor.close_editor_event.bind(self._handle_close)

    def _handle_key_down(self, event):
        try:
            self.textctrl_nav_keys[event.GetKeyCode()](event)
        except KeyError:
            event.Skip()
        # Don't skip the event if the navigation is done
        #event.Skip()

    def _handle_enter_on_textctrl(self, event):
        # This method must get the same arguments as
        #  _navigate_textctrl_backward
        if event.ControlDown():
            if event.ShiftDown():
                for item in editor.tabs:
                    editor.tabs[item].apply()
            else:
                editor.tabs[self.item].apply()
        else:
            event.Skip()

    def _handle_tab_on_textctrl(self, event):
        # This method must get the same arguments as
        #  _navigate_textctrl_backward
        # Note that this natively still lets Ctrl+(Shift+)Tab navigate as
        #  expected
        if event.ShiftDown():
            self._navigate_textctrl_backward(event)
        else:
            self.area.Navigate(flags=wx.NavigationKeyEvent.IsForward)

    def _navigate_textctrl_backward(self, event):
        # This method must get the same arguments as _handle_tab_on_textctrl
        try:
            captionbar = editor.tabs[self.item].get_plugin_captionbars()[-1]
        except IndexError:
            # No plugins installed/enabled
            self.area.Navigate(flags=wx.NavigationKeyEvent.IsBackward)
        else:
            if captionbar.IsCollapsed():
                captionbar.SetFocus()
            else:
                self.area.Navigate(flags=wx.NavigationKeyEvent.IsBackward)

    def _handle_text(self, event):
        if not (self.tmrunning):
            # Always set modified when (re)starting the timer, in fact it's not
            # possible that the textarea can be unmodified, except for the
            # only case where the original state is actually restored, but in
            # that case the modified state will be restored to False anyway if
            # and when the timer executes its action
            self.area.SetModified(True)
        else:
            self.mtimer.cancel()

        self.tmrunning = True
        self.mtimer = Timer(self.DELAY, self._reset_timer)
        self.mtimer.name = "wxtextarea"
        self.mtimer.start()

        event.Skip()

    def _reset_timer(self):
        self.tmrunning = False
        self._set_modified()

    def _set_modified(self):
        if self.area.GetValue() == self.original:
            self.area.SetModified(False)
        else:
            self.area.SetModified(True)

    def _reset_modified(self):
        self.original = self.area.GetValue()
        self.area.SetModified(False)

    def _is_modified(self):
        self._set_modified()
        return self.area.IsModified()

    def _handle_apply(self, kwargs):
        if kwargs['filename'] == self.filename and kwargs['id_'] == self.id_ \
                                                    and self._is_modified():
            core_api.update_item_text(self.filename, self.id_,
                                      self.area.GetValue(), kwargs['group'],
                                      kwargs['description'])
            self._refresh_mod_state()

    def _refresh_mod_state(self):
        treedb = tree.dbs[self.filename]
        tabtitle = editor.Editor.make_title(self.area.GetLineText(0))
        wx.GetApp().nb_right.set_editor_title(self.item, tabtitle)

        self._reset_modified()

    def _handle_check_editor_modified(self, kwargs):
        if kwargs['filename'] == self.filename and kwargs['id_'] == self.id_ \
                                                    and self._is_modified():
            editor.tabs[self.item].set_modified()

    def _handle_close(self, kwargs):
        if kwargs['filename'] == self.filename and kwargs['id_'] == self.id_:
            if self.mtimer:
                self.mtimer.cancel()
            # It's necessary to explicitly unbind the handlers, otherwise this
            # object will never be garbage-collected due to circular
            # references, and the automatic unbinding won't work
            editor.apply_editor_event.bind(self._handle_apply, False)
            editor.check_modified_state_event.bind(
                self._handle_check_editor_modified, False)
            editor.close_editor_event.bind(self._handle_close, False)

    def cut(self):
        self.area.Cut()

    def copy(self):
        self.area.Copy()

    def paste(self):
        self.area.Paste()

    def select_all(self):
        self.area.SetSelection(-1, -1)

    def can_cut(self):
        return self.area.CanCut()

    def can_copy(self):
        return self.area.CanCopy()

    def can_paste(self):
        return self.area.CanPaste()
コード例 #4
0
ファイル: about.py プロジェクト: xguse/outspline
class InfoBox(wx.SplitterWindow):
    tree = None
    textw = None
    STYLE_HEAD = None
    STYLE_NORMAL = None
    STYLE_BOLD = None
    STYLE_ITALIC = None

    def __init__(self, parent):
        wx.SplitterWindow.__init__(self, parent, style=wx.SP_LIVE_UPDATE)

        self.tree = wx.TreeCtrl(self,
                                style=wx.TR_HAS_BUTTONS | wx.TR_HIDE_ROOT
                                | wx.TR_SINGLE | wx.TR_FULL_ROW_HIGHLIGHT)

        self.STYLE_HEAD = wx.TextAttr(
            font=wx.Font(14, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL,
                         wx.FONTWEIGHT_BOLD))
        self.STYLE_NORMAL = wx.TextAttr(
            font=wx.Font(10, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL,
                         wx.FONTWEIGHT_NORMAL))
        self.STYLE_BOLD = wx.TextAttr(
            font=wx.Font(10, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL,
                         wx.FONTWEIGHT_BOLD))
        self.STYLE_ITALIC = wx.TextAttr(
            font=wx.Font(10, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_ITALIC,
                         wx.FONTWEIGHT_NORMAL))

        self.tree.AddRoot(text='root')
        self.init_info()

        self.textw = TextUrlCtrl(self,
                                 value='',
                                 style=wx.TE_MULTILINE | wx.TE_READONLY
                                 | wx.TE_DONTWRAP)

        self.SplitVertically(self.tree, self.textw)

        # Prevent the window from unsplitting when dragging the sash to the
        # border
        self.SetMinimumPaneSize(20)
        self.SetSashPosition(120)

        self.Bind(wx.EVT_SPLITTER_DCLICK, self.veto_dclick)
        self.tree.Bind(wx.EVT_TREE_BEGIN_LABEL_EDIT, self.veto_label_edit)
        self.tree.Bind(wx.EVT_TREE_SEL_CHANGED, self.retrieve_info)

        self.tree.SelectItem(
            self.tree.GetFirstChild(self.tree.GetRootItem())[0])

    def init_info(self):
        self.tree.AppendItem(self.tree.GetRootItem(),
                             text='License',
                             data=wx.TreeItemData({'req': 'lic'}))

        self.tree.AppendItem(self.tree.GetRootItem(),
                             text='Info',
                             data=wx.TreeItemData({'req': 'cor'}))

        # Do not use the configuration because it could have entries about
        # addons that aren't actually installed
        addons = coreaux_api.get_components_info()["addons"]

        for type_ in ('Extensions', 'Interfaces', 'Plugins'):
            typeitem = self.tree.AppendItem(self.tree.GetRootItem(),
                                            text=type_,
                                            data=wx.TreeItemData({
                                                'req': 'lst',
                                                'type_': type_
                                            }))
            for addon in addons[type_]:
                self.tree.AppendItem(typeitem,
                                     text=addon,
                                     data=wx.TreeItemData({
                                         'req': 'inf',
                                         'type_': type_,
                                         'addon': addon
                                     }))

    def compose_license(self):
        self.textw.AppendText(coreaux_api.get_license())

    def compose_main_info(self):
        coreinfo = coreaux_api.get_core_info()

        self.textw.SetDefaultStyle(self.STYLE_BOLD)
        self.textw.AppendText('Core version: ')
        self.textw.SetDefaultStyle(self.STYLE_NORMAL)
        self.textw.AppendText(coreinfo.version)

        self.textw.SetDefaultStyle(self.STYLE_BOLD)
        self.textw.AppendText('\nWebsite: ')
        self.textw.SetDefaultStyle(self.STYLE_NORMAL)
        self.textw.AppendText(coreinfo.website)

        self.textw.SetDefaultStyle(self.STYLE_BOLD)
        self.textw.AppendText('\nAuthor: ')
        self.textw.SetDefaultStyle(self.STYLE_NORMAL)
        self.textw.AppendText('Dario Giovannetti <*****@*****.**>')

        self.textw.SetDefaultStyle(self.STYLE_BOLD)
        self.textw.AppendText('\nContributors: ')
        self.textw.SetDefaultStyle(self.STYLE_NORMAL)

        try:
            contributors = coreinfo.contributors
        except AttributeError:
            pass
        else:
            for c in contributors:
                self.textw.AppendText('\n\t{}'.format(c))

        self.textw.SetDefaultStyle(self.STYLE_BOLD)
        self.textw.AppendText('\n\nInstalled components:')
        self.textw.SetDefaultStyle(self.STYLE_NORMAL)
        cinfo = coreaux_api.get_components_info()["info"]
        for cname in cinfo:
            self.textw.AppendText('\n\t{} {} ({})'.format(
                cname, cinfo[cname].version, cinfo[cname].release_date))

    def compose_addon_info(self, type_, addon):
        info = {
            "Extensions": coreaux_api.import_extension_info,
            "Interfaces": coreaux_api.import_interface_info,
            "Plugins": coreaux_api.import_plugin_info,
        }[type_](addon)

        config = coreaux_api.get_configuration()(type_)(addon)

        self.textw.SetDefaultStyle(self.STYLE_HEAD)
        self.textw.AppendText('{}\n'.format(addon))

        self.textw.SetDefaultStyle(self.STYLE_NORMAL)

        self.textw.AppendText('{}\n'.format(info.description))

        self.textw.SetDefaultStyle(self.STYLE_BOLD)
        self.textw.AppendText('\nEnabled: ')
        self.textw.SetDefaultStyle(self.STYLE_NORMAL)
        self.textw.AppendText('yes' if config.get_bool('enabled') else 'no')

        self.textw.SetDefaultStyle(self.STYLE_BOLD)
        self.textw.AppendText('\nVersion: ')
        self.textw.SetDefaultStyle(self.STYLE_NORMAL)
        self.textw.AppendText(info.version)

        self.textw.SetDefaultStyle(self.STYLE_BOLD)
        self.textw.AppendText('\nWebsite: ')
        self.textw.SetDefaultStyle(self.STYLE_NORMAL)
        self.textw.AppendText(info.website)

        self.textw.SetDefaultStyle(self.STYLE_BOLD)

        if len(info.authors) > 1:
            self.textw.AppendText('\nAuthors:')
            self.textw.SetDefaultStyle(self.STYLE_NORMAL)

            for a in info.authors:
                self.textw.AppendText('\n\t{}'.format(a))
        else:
            self.textw.AppendText('\nAuthor: ')
            self.textw.SetDefaultStyle(self.STYLE_NORMAL)
            self.textw.AppendText(info.authors[0])

        self.textw.SetDefaultStyle(self.STYLE_BOLD)
        self.textw.AppendText('\nContributors:')
        self.textw.SetDefaultStyle(self.STYLE_NORMAL)

        try:
            contributors = info.contributors
        except AttributeError:
            pass
        else:
            for c in contributors:
                self.textw.AppendText('\n\t{}'.format(c))

        self.textw.SetDefaultStyle(self.STYLE_BOLD)
        self.textw.AppendText('\nComponent: ')
        self.textw.SetDefaultStyle(self.STYLE_NORMAL)
        cinfo = coreaux_api.get_components_info()
        cname = cinfo["addons"][type_][addon]
        component = cinfo["info"][cname]
        self.textw.AppendText('{} {} ({})'.format(cname, component.version,
                                                  component.release_date))

        self.textw.SetDefaultStyle(self.STYLE_BOLD)
        self.textw.AppendText('\nDependencies:')
        self.textw.SetDefaultStyle(self.STYLE_NORMAL)

        try:
            deps = info.dependencies
        except AttributeError:
            pass
        else:
            for d in deps:
                self.textw.AppendText('\n\t{} {}.x'.format(*d))

        self.textw.SetDefaultStyle(self.STYLE_BOLD)
        self.textw.AppendText('\nOptional dependencies:')
        self.textw.SetDefaultStyle(self.STYLE_NORMAL)

        try:
            opts = info.optional_dependencies
        except AttributeError:
            pass
        else:
            for o in opts:
                self.textw.AppendText('\n\t{} {}.x'.format(*o))

    def compose_list(self, type_):
        # Do not use the configuration because it could have entries about
        # addons that aren't actually installed
        info = coreaux_api.get_components_info()["addons"]
        self.textw.SetDefaultStyle(self.STYLE_BOLD)
        self.textw.AppendText('{}:\n'.format(type_))

        for addon in info[type_]:
            config = coreaux_api.get_configuration()(type_)(addon)

            if config.get_bool('enabled'):
                self.textw.SetDefaultStyle(self.STYLE_NORMAL)
                self.textw.AppendText('\t{}\n'.format(addon))
            else:
                self.textw.SetDefaultStyle(self.STYLE_ITALIC)
                self.textw.AppendText('\t{} [disabled]\n'.format(addon))

    def veto_dclick(self, event):
        event.Veto()

    def veto_label_edit(self, event):
        event.Veto()

    def retrieve_info(self, event):
        self.textw.Clear()
        self.textw.SetDefaultStyle(self.STYLE_NORMAL)
        data = self.tree.GetPyData(event.GetItem())
        if data['req'] == 'lic':
            self.compose_license()
        elif data['req'] == 'cor':
            self.compose_main_info()
        elif data['req'] == 'lst':
            self.compose_list(data['type_'])
        elif data['req'] == 'inf':
            self.compose_addon_info(data['type_'], data['addon'])
        # Scroll back to top
        self.textw.ShowPosition(0)