Exemplo n.º 1
0
    def create_forests(self, filename=None, clear=False):
        """ This will read sentences to parse. One sentence per line, no periods etc.

        :param filename: not used
        :param clear: start with empty
        """
        if clear:
            treelist = ['hello']
        else:
            treelist = self.load_treelist_from_text_file(self.__class__.default_treeset_file) or \
                       ['hello']

        # Clear this screen before we start creating a mess
        ctrl.disable_undo()  # disable tracking of changes (e.g. undo)
        if self.forest:
            self.forest.retire_from_drawing()
        self.forests = []

        grammar = load_grammar(filename=running_environment.plugins_path +
                               '/mgtdbpE/mg0.txt')

        for line in treelist:
            sentence = line.strip()
            if (not sentence) or sentence.startswith('#'):
                continue
            syn = classes.get('SyntaxConnection')()
            syn.sentence = sentence
            syn.lexicon = grammar
            forest = Forest(gloss_text=sentence, syntax=syn)
            self.forests.append(forest)
        self.current_index = 0
        self.forest = self.forests[0]
        # allow change tracking (undo) again
        ctrl.resume_undo()
Exemplo n.º 2
0
    def create_forests(self, filename=None, clear=False):
        """ This will read sentences to parse. One sentence per line, no periods etc.

        :param filename: not used
        :param clear: start with empty
        """
        if clear:
            treelist = ['hello']
        else:
            treelist = self.load_treelist_from_text_file(self.__class__.default_treeset_file) or \
                       ['hello']

        # Clear this screen before we start creating a mess
        ctrl.disable_undo() # disable tracking of changes (e.g. undo)
        if self.forest:
            self.forest.retire_from_drawing()
        self.forests = []

        grammar = load_grammar(filename=running_environment.plugins_path + '/mgtdbpE/mg0.txt')

        for line in treelist:
            sentence = line.strip()
            if (not sentence) or sentence.startswith('#'):
                continue
            syn = classes.get('SyntaxConnection')()
            syn.sentence = sentence
            syn.lexicon = grammar
            forest = Forest(gloss_text=sentence, syntax=syn)
            self.forests.append(forest)
        self.current_index = 0
        self.forest = self.forests[0]
        # allow change tracking (undo) again
        ctrl.resume_undo()
Exemplo n.º 3
0
 def trigger_but_suppress_undo(self, *args, **kwargs):
     if ctrl.main.init_done:
         ctrl.disable_undo()
         self.disable_undo_and_message = True
         self.run(*args, **kwargs)
         self.disable_undo_and_message = False
         ctrl.resume_undo()
Exemplo n.º 4
0
 def redo(self):
     """ Move forward in the undo stack
     :return: None
     """
     if self._current < len(self._stack) - 1:
         self._current += 1
     else:
         log.info('redo [%s]: In last action' % self._current)
         return
     ctrl.disable_undo()
     ctrl.multiselection_start()
     ctrl.forest.halt_drawing = True
     msg, snapshot = self._stack[self._current]
     affected = set()
     for obj, transitions, transition_type in snapshot.values():
         obj.move_to_later(transitions)
         if transition_type == CREATED:
             ctrl.forest.add_to_scene(obj)
         elif transition_type == DELETED:
             ctrl.free_drawing.delete_item(obj, ignore_consequences=True)
         affected.add(obj)
     ctrl.forest.edge_visibility_check()
     for obj, transitions, transition_type in snapshot.values():
         obj.after_model_update(transitions.keys(), transition_type)
         if getattr(obj.__class__, 'syntactic_object', False):
             node = ctrl.forest.nodes_from_synobs.get(obj.uid, None)
             if node and node not in affected:
                 node.after_model_update([], transition_type)
     ctrl.forest.flush_and_rebuild_temporary_items()
     log.info('redo [%s]: %s' % (self._current, msg))
     ctrl.multiselection_end()
     ctrl.resume_undo()
     ctrl.forest.halt_drawing = False
     print('------redo finished: ', msg, self._current)
Exemplo n.º 5
0
    def action_triggered(self, state_arg=None):
        """ Trigger action with parameters received from action data object and designated UI element
        :param state_arg: argument provided by some triggers, e.g. toggle buttons. We don't forward
         this, instead it is saved in self.state_arg, method can use it from there if needed.
        :return: None
        """

        if not self.isEnabled():
            return
        self.state_arg = state_arg
        # -- Redraw and undo flags: these are on by default, can be switched off by action method
        ctrl.action_redraw = True
        # Disable undo if necessary
        if not self.undoable:
            ctrl.disable_undo()

        # Call method
        try:
            message = self.method(*self.args)
            error = None
        except:
            message = ''
            error = "Action %r ('%s')<br/>" % (self, self.key)
            error += '<br/>'.join(traceback.format_exception(*sys.exc_info()))
            print("Unexpected error:", sys.exc_info())
            traceback.print_exc()
        # Restore undo state to what it was
        if not self.undoable:
            ctrl.resume_undo()
        if self.disable_undo_and_message:
            ctrl.main.action_finished(undoable=False)
        else:
            ctrl.main.action_finished(m=message or self.command,
                                      undoable=self.undoable and not ctrl.undo_disabled,
                                      error=error)
Exemplo n.º 6
0
    def create_forests(self, treelist=None):
        """ This will read sentences to parse. One sentence per line, no periods etc. 

        :param treelist: lines of file like above.
        """
        if not treelist:
            treelist = []

        # Clear this screen before we start creating a mess
        ctrl.disable_undo()  # disable tracking of changes (e.g. undo)
        if self.forest:
            self.forest.retire_from_drawing()
        self.forests = []

        start = 0
        end = 10

        for line in treelist:
            sentence = line.strip()
            if (not sentence) or sentence.startswith('#'):
                continue
            forest = Forest(gloss_text=sentence)
            self.forests.append(forest)
            parser = Parser(grammar.g, -0.0001, forest=forest)
            my_success, my_dnodes = parser.parse(sentence=sentence, start='C')
            print(my_success)
        self.current_index = 0
        self.forest = self.forests[0]
        # allow change tracking (undo) again
        ctrl.resume_undo()
Exemplo n.º 7
0
    def create_forests(self, filename=None, clear=False):
        """ This will read example sentences in form used by Ginsburg / Fong parser

        1 Tom read a book. (Chomsky 2015:10) ['C','Tpres',['D','n','Tom'],'v*','read','a','n',
        'book']
        2 They expected John to win. (Chomsky 2015:10) ['C','Tpast',['D','n','they'],'v*','expect',
        'toT',['D','n','John'],'vUnerg','win']
        3 Who do you expect to win. (Chomsky 2015:10) ['C_Q','Tpres',['D','n','you'],'v*','expect',
        'toT',['Q','n','who'],'vUnerg','win']

        :param treelist: lines of file like above. Lines that don't begin with number are ignored.
        """
        if clear:
            treelist = []
        else:
            treelist = self.load_treelist_from_text_file(
                self.__class__.default_treeset_file) or []

        # Clear this screen before we start creating a mess
        ctrl.disable_undo()  # disable tracking of changes (e.g. undo)
        if self.forest:
            self.forest.retire_from_drawing()
        self.forests = []

        start = 0
        end = 10
        ug = Generate()

        for line in treelist:
            if "Japanese" in line:
                ug.language = "Japanese"
            elif "English" in line:
                ug.language = "English"
            sentence, lbracket, target_str = line.partition('[')
            if not (sentence and lbracket and target_str):
                continue
            sentence = sentence.strip()
            sentence_number = sentence[0]

            if not sentence_number.isdigit():
                continue
            sentence_number = int(sentence_number)
            if end and sentence_number > end:
                break
            elif sentence_number < start:
                continue
            sentence = sentence[2:]  # remove number and the space after it
            target_example = eval(lbracket + target_str)
            ug.out(sentence_number, sentence, target_example)
            forest = Forest(gloss_text=sentence)
            self.forests.append(forest)
            so = ug.generate_derivation(target_example, forest=forest)
            ug.out("MRGOperations", ug.merge_counter)
            ug.out("FTInheritanceOp", ug.inheritance_counter)
            ug.out("FTCheckOp", ug.feature_check_counter)
        self.current_index = 0
        self.forest = self.forests[0]
        # allow change tracking (undo) again
        ctrl.resume_undo()
Exemplo n.º 8
0
    def create_forests(self, filename=None, clear=False):
        """ This will read example sentences in form used by Ginsburg / Fong parser

        1 Tom read a book. (Chomsky 2015:10) ['C','Tpres',['D','n','Tom'],'v*','read','a','n',
        'book']
        2 They expected John to win. (Chomsky 2015:10) ['C','Tpast',['D','n','they'],'v*','expect',
        'toT',['D','n','John'],'vUnerg','win']
        3 Who do you expect to win. (Chomsky 2015:10) ['C_Q','Tpres',['D','n','you'],'v*','expect',
        'toT',['Q','n','who'],'vUnerg','win']

        :param treelist: lines of file like above. Lines that don't begin with number are ignored.
        """
        if clear:
            treelist = []
        else:
            treelist = self.load_treelist_from_text_file(self.__class__.default_treeset_file) or []

        # Clear this screen before we start creating a mess
        ctrl.disable_undo()  # disable tracking of changes (e.g. undo)
        if self.forest:
            self.forest.retire_from_drawing()
        self.forests = []

        start = 0
        end = 10
        ug = Generate()

        for line in treelist:
            if "Japanese" in line:
                ug.language = "Japanese"
            elif "English" in line:
                ug.language = "English"
            sentence, lbracket, target_str = line.partition("[")
            if not (sentence and lbracket and target_str):
                continue
            sentence = sentence.strip()
            sentence_number = sentence[0]

            if not sentence_number.isdigit():
                continue
            sentence_number = int(sentence_number)
            if end and sentence_number > end:
                break
            elif sentence_number < start:
                continue
            sentence = sentence[2:]  # remove number and the space after it
            target_example = eval(lbracket + target_str)
            ug.out(sentence_number, sentence, target_example)
            forest = Forest(gloss_text=sentence)
            self.forests.append(forest)
            so = ug.generate_derivation(target_example, forest=forest)
            ug.out("MRGOperations", ug.merge_counter)
            ug.out("FTInheritanceOp", ug.inheritance_counter)
            ug.out("FTCheckOp", ug.feature_check_counter)
        self.current_index = 0
        self.forest = self.forests[0]
        # allow change tracking (undo) again
        ctrl.resume_undo()
Exemplo n.º 9
0
 def set_forest(self, forest, force=False):
     if (not forest) or (forest is self.forest and not force):
         return self.current_index, forest
     elif self.forest:
         self.forest.retire_from_display()
     self.current_index = self.forests.index(forest)
     ctrl.undo_pile = set()
     self.forest = forest
     ctrl.disable_undo()
     if forest.is_parsed:
         forest.show_parse(forest.current_parse_index)
     forest.prepare_for_drawing()
     ctrl.resume_undo()
     ctrl.main.forest_changed.emit()
Exemplo n.º 10
0
    def enable_plugin(self, plugin_key, reload=False):
        """ Start one plugin: save data, replace required classes with plugin classes, load data.

        """
        self.active_plugin_setup = self.load_plugin(plugin_key)
        if not self.active_plugin_setup:
            return
        self.clear_all()
        ctrl.disable_undo()
        if reload:
            available = []
            for key in sys.modules:
                if key.startswith(plugin_key):
                    available.append(key)
            if getattr(self.active_plugin_setup, 'reload_order', None):
                to_reload = [
                    x for x in self.active_plugin_setup.reload_order
                    if x in available
                ]
            else:
                to_reload = sorted(available)
            for mod_name in to_reload:
                importlib.reload(sys.modules[mod_name])
                print('reloaded ', mod_name)
                log.info('reloaded module %s' % mod_name)

        if hasattr(self.active_plugin_setup, 'plugin_parts'):
            for classobj in self.active_plugin_setup.plugin_parts:
                base_class = classes.find_base_model(classobj)
                if base_class:
                    classes.add_mapping(base_class, classobj)
                    m = "replacing %s with %s " % (base_class.__name__,
                                                   classobj.__name__)
                else:
                    m = "adding %s " % classobj.__name__
                log.info(m)
                print(m)
        if hasattr(self.active_plugin_setup, 'help_file'):
            dir_path = os.path.dirname(
                os.path.realpath(self.active_plugin_setup.__file__))
            print(dir_path)
            self.ui_manager.set_help_source(dir_path,
                                            self.active_plugin_setup.help_file)
        if hasattr(self.active_plugin_setup, 'start_plugin'):
            self.active_plugin_setup.start_plugin(self, ctrl, prefs)
        self.init_forest_keepers()
        ctrl.resume_undo()
        prefs.active_plugin_name = plugin_key
Exemplo n.º 11
0
 def derive_from_editable_lexicon(self, sentence, lexdata, semantics=''):
     """ Take edited version of get_editable_lexicon output and try derivation with it.
     """
     grammar = load_grammar(g=lexdata)
     self.lexicon = grammar
     ctrl.disable_undo()
     f = ctrl.forest
     f.clear()
     self.sentence = sentence
     self.parser = Parser(grammar, -0.0001, forest=f)
     # parser doesn't return anything, it pushes derivation steps to forest
     self.parser.parse(sentence=self.sentence, start='C')
     ds = f.derivation_steps
     ds.derivation_step_index = len(ds.derivation_steps) - 1
     ds.jump_to_derivation_step(ds.derivation_step_index)
     f.prepare_for_drawing()
     ctrl.resume_undo()
Exemplo n.º 12
0
 def derive_from_editable_lexicon(self, sentence, lexdata, semantics=''):
     """ Take edited version of get_editable_lexicon output and try derivation with it.
     """
     grammar = load_grammar(g=lexdata)
     self.lexicon = grammar
     ctrl.disable_undo()
     f = ctrl.forest
     f.clear()
     self.sentence = sentence
     self.parser = Parser(grammar, -0.0001, forest=f)
     # parser doesn't return anything, it pushes derivation steps to forest
     self.parser.parse(sentence=self.sentence, start='C')
     ds = f.derivation_steps
     ds.derivation_step_index = len(ds.derivation_steps) - 1
     ds.jump_to_derivation_step(ds.derivation_step_index)
     f.prepare_for_drawing()
     ctrl.resume_undo()
Exemplo n.º 13
0
    def undo(self):
        """ Move backward in the undo stack
        :return: None
        """
        if not self._stack:
            return
        if self._current == 0:
            log.info('undo [%s]: Cannot undo further' % self._current)
            return
        ctrl.disable_undo()
        ctrl.multiselection_start()
        ctrl.forest.halt_drawing = True
        msg, snapshot = self._stack[self._current]
        affected = set()
        for obj, transitions, transition_type in snapshot.values():
            obj.revert_to_earlier(transitions)
            if transition_type == CREATED:
                ctrl.free_drawing.delete_item(obj, ignore_consequences=True)
            elif transition_type == DELETED:
                ctrl.forest.add_to_scene(obj)
            affected.add(obj)
            if hasattr(obj, 'update_visibility'):
                obj.update_visibility()
        ctrl.forest.edge_visibility_check()
        for obj, transitions, transition_type in snapshot.values():
            if transition_type == CREATED:
                revtt = DELETED
            elif transition_type == DELETED:
                revtt = CREATED
            else:
                revtt = transition_type
            obj.after_model_update(transitions.keys(), revtt)
            if getattr(obj.__class__, 'syntactic_object', False):
                node = ctrl.forest.nodes_from_synobs.get(obj.uid, None)
                if node and node not in affected:
                    node.after_model_update([], revtt)
        ctrl.forest.flush_and_rebuild_temporary_items()
        log.info('undo [%s]: %s' % (self._current, msg))
        ctrl.multiselection_end()
        ctrl.resume_undo()
        self._current -= 1
        ctrl.forest.halt_drawing = False

        print('-------undo finished', self._current)
Exemplo n.º 14
0
    def action_triggered(self, state_arg=None):
        """ Trigger action with parameters received from action data object and designated UI element
        :param state_arg: argument provided by some triggers, e.g. toggle buttons. We don't forward
         this, instead it is saved in self.state_arg, method can use it from there if needed.
        :return: None
        """

        if not self.isEnabled():
            return
        self.state_arg = state_arg
        # -- Redraw and undo flags: these are on by default, can be switched off by action method
        ctrl.action_redraw = True
        # Disable undo if necessary
        if not self.undoable:
            ctrl.disable_undo()

        # Call method
        try:
            message = self.method(*self.args)
            error = None
        except:
            message = ''
            error = "Action %r ('%s')<br/>" % (self, self.key)
            error += '<br/>'.join(traceback.format_exception(*sys.exc_info()))
            print("Unexpected error:", sys.exc_info())
            traceback.print_exc()
        # Restore undo state to what it was
        if not self.undoable:
            ctrl.resume_undo()
        if self.disable_undo_and_message:
            ctrl.main.action_finished(undoable=False)
        else:
            sc = self.shortcut()
            if sc:
                sc = sc.toString()
                sc = sc.replace('Ctrl', running_environment.cmd_or_ctrl)
                reply = f'({sc}) {message or self.command}'
            else:
                reply = message or self.command
            ctrl.main.action_finished(m=reply,
                                      undoable=self.undoable
                                      and not ctrl.undo_disabled,
                                      error=error)
Exemplo n.º 15
0
    def enable_plugin(self, plugin_key, reload=False):
        """ Start one plugin: save data, replace required classes with plugin classes, load data.

        """
        self.active_plugin_setup = self.load_plugin(plugin_key)
        if not self.active_plugin_setup:
            return
        self.clear_all()
        ctrl.disable_undo()
        if reload:
            available = []
            for key in sys.modules:
                if key.startswith(plugin_key):
                    available.append(key)
            if getattr(self.active_plugin_setup, 'reload_order', None):
                to_reload = [x for x in self.active_plugin_setup.reload_order if x in available]
            else:
                to_reload = sorted(available)
            for mod_name in to_reload:
                importlib.reload(sys.modules[mod_name])
                print('reloaded ', mod_name)
                log.info('reloaded module %s' % mod_name)

        if hasattr(self.active_plugin_setup, 'plugin_parts'):
            for classobj in self.active_plugin_setup.plugin_parts:
                base_class = classes.find_base_model(classobj)
                if base_class:
                    classes.add_mapping(base_class, classobj)
                    m = "replacing %s with %s " % (base_class.__name__, classobj.__name__)
                else:
                    m = "adding %s " % classobj.__name__
                log.info(m)
                print(m)
        if hasattr(self.active_plugin_setup, 'help_file'):
            dir_path = os.path.dirname(os.path.realpath(self.active_plugin_setup.__file__))
            print(dir_path)
            self.ui_manager.set_help_source(dir_path, self.active_plugin_setup.help_file)
        if hasattr(self.active_plugin_setup, 'start_plugin'):
            self.active_plugin_setup.start_plugin(self, ctrl, prefs)
        self.init_forest_keepers()
        ctrl.resume_undo()
        prefs.active_plugin_name = plugin_key
Exemplo n.º 16
0
 def change_forest(self):
     """ Tells the scene to remove current trees and related data and
     change it to a new one. Signal 'forest_changed' is already sent by forest keeper.
     """
     ctrl.disable_undo()
     if self.forest:
         self.forest.retire_from_drawing()
     if not self.forest_keeper.forest:
         self.forest_keeper.create_forests(clear=True)
     self.forest = self.forest_keeper.forest
     self.settings_manager.set_forest(self.forest)
     if self.forest.is_parsed:
         if self.forest.derivation_steps:
             ds = self.forest.derivation_steps
             if not ds.activated:
                 print('jumping to derivation step: ', ds.derivation_step_index)
                 ds.jump_to_derivation_step(ds.derivation_step_index)
         else:
             print('no derivation steps')
     self.forest.prepare_for_drawing()
     ctrl.resume_undo()
Exemplo n.º 17
0
 def disable_current_plugin(self):
     """ Disable the current plugin and load the default trees instead.
     :param clear: if True, have empty treeset, if False, try to load default kataja treeset."""
     if not self.active_plugin_setup:
         return
     ctrl.disable_undo()
     if hasattr(self.active_plugin_setup, 'tear_down_plugin'):
         self.active_plugin_setup.tear_down_plugin(self, ctrl, prefs)
     self.clear_all()
     # print(classes.base_name_to_plugin_class)
     # if hasattr(self.active_plugin_setup, 'plugin_parts'):
     #     for classobj in self.active_plugin_setup.plugin_parts:
     #         class_name = classobj.__name__
     #         if class_name:
     #             log.info(f'removing {class_name}')
     #             print(f'removing {class_name}')
     #             classes.remove_class(class_name)
     classes.restore_default_classes()
     self.init_forest_keepers()
     ctrl.resume_undo()
     prefs.active_plugin_name = ''
Exemplo n.º 18
0
 def disable_current_plugin(self):
     """ Disable the current plugin and load the default trees instead.
     :param clear: if True, have empty treeset, if False, try to load default kataja treeset."""
     if not self.active_plugin_setup:
         return
     ctrl.disable_undo()
     if hasattr(self.active_plugin_setup, 'tear_down_plugin'):
         self.active_plugin_setup.tear_down_plugin(self, ctrl, prefs)
     self.clear_all()
     # print(classes.base_name_to_plugin_class)
     # if hasattr(self.active_plugin_setup, 'plugin_parts'):
     #     for classobj in self.active_plugin_setup.plugin_parts:
     #         class_name = classobj.__name__
     #         if class_name:
     #             log.info(f'removing {class_name}')
     #             print(f'removing {class_name}')
     #             classes.remove_class(class_name)
     classes.restore_default_classes()
     self.init_forest_keepers()
     ctrl.resume_undo()
     prefs.active_plugin_name = ''
Exemplo n.º 19
0
 def prepare_for_drawing(self):
     """ Prepares the forest instance to be displayed in graph scene --
      called when switching forests
     :return: None
     """
     self.in_display = True
     ctrl.disable_undo()
     if not self.is_parsed:
         self.syntax.create_derivation(self)
         self.after_model_update('nodes', 0)
         self.is_parsed = True
     ctrl.add_watcher(self, 'palette_changed')
     ctrl.main.update_colors()
     self.add_all_to_scene()
     self.update_visualization()
     self.scene.keep_updating_visible_area = True
     self.scene.manual_zoom = False
     self.draw()  # do draw once to avoid having the first draw in undo stack.
     ctrl.graph_scene.fit_to_window()
     ctrl.resume_undo()
     ctrl.graph_view.setFocus()
Exemplo n.º 20
0
 def redo(self):
     """ Move forward in the undo stack
     :return: None
     """
     if self._current < len(self._stack) - 1:
         self._current += 1
     else:
         log.info('redo [%s]: In last action' % self._current)
         return
     ctrl.disable_undo()
     ctrl.multiselection_start()
     self.forest.halt_drawing = True
     msg, snapshot = self._stack[self._current]
     for obj, transitions, transition_type in snapshot.values():
         obj.move_to_later(transitions, transition_type)
     self.forest.edge_visibility_check()
     self.forest.flush_and_rebuild_temporary_items()
     log.info('redo [%s]: %s' % (self._current, msg))
     ctrl.multiselection_end()
     ctrl.resume_undo()
     self.forest.halt_drawing = False
     print('------redo finished: ', msg, self._current)
Exemplo n.º 21
0
 def redo(self):
     """ Move forward in the undo stack
     :return: None
     """
     if self._current < len(self._stack) - 1:
         self._current += 1
     else:
         log.info('redo [%s]: In last action' % self._current)
         return
     ctrl.disable_undo()
     ctrl.multiselection_start()
     ctrl.forest.halt_drawing = True
     msg, snapshot = self._stack[self._current]
     for obj, transitions, transition_type in snapshot.values():
         obj.move_to_later(transitions, transition_type)
     ctrl.forest.edge_visibility_check()
     ctrl.forest.flush_and_rebuild_temporary_items()
     log.info('redo [%s]: %s' % (self._current, msg))
     ctrl.multiselection_end()
     ctrl.resume_undo()
     ctrl.forest.halt_drawing = False
     print('------redo finished: ', msg, self._current)
Exemplo n.º 22
0
 def prepare_for_drawing(self):
     """ Prepares the forest instance to be displayed in graph scene --
      called when switching forests
     :return: None
     """
     self.in_display = True
     ctrl.disable_undo()
     if not self.is_parsed:
         self.syntax.create_derivation(self)
         self.after_model_update('nodes', 0)
         self.is_parsed = True
         self.forest_edited()
     ctrl.add_watcher(self, 'palette_changed')
     ctrl.main.update_colors()
     self.add_all_to_scene()
     self.update_visualization()
     self.scene.keep_updating_visible_area = True
     self.scene.manual_zoom = False
     self.draw()  # do draw once to avoid having the first draw in undo stack.
     ctrl.graph_scene.fit_to_window()
     ctrl.resume_undo()
     ctrl.graph_view.setFocus()
Exemplo n.º 23
0
 def change_forest(self):
     """ Tells the scene to remove current trees and related data and
     change it to a new one. Signal 'forest_changed' is already sent by forest keeper.
     """
     ctrl.disable_undo()
     if self.forest:
         self.forest.retire_from_drawing()
     if not self.forest_keeper.forest:
         self.forest_keeper.create_forests(clear=True)
     self.forest = self.forest_keeper.forest
     self.settings_manager.set_forest(self.forest)
     if self.forest.is_parsed:
         if self.forest.derivation_steps:
             ds = self.forest.derivation_steps
             if not ds.activated:
                 print('jumping to derivation step: ',
                       ds.derivation_step_index)
                 ds.jump_to_derivation_step(ds.derivation_step_index)
         else:
             print('no derivation steps')
     self.forest.prepare_for_drawing()
     ctrl.resume_undo()
Exemplo n.º 24
0
    def prepare_for_drawing(self):
        """ Prepares the forest instance to be displayed in graph scene --
         called when switching forests
        :return: None
        """
        self.in_display = True
        ctrl.disable_undo()
        self.connect_main()
        if not self.is_parsed:
            self.init_factories()
            self.syntax.create_derivation(forest=self, lexicon=ctrl.document.lexicon)
            self.after_model_update('nodes', 0)
            self.is_parsed = True
            self.show_parse(0)
            self.forest_edited()

        ctrl.main.update_colors()
        self.add_all_to_scene()
        self.update_visualization()
        self.draw()  # do draw once to avoid having the first draw in undo stack.
        ctrl.view_manager.update_viewport(ViewUpdateReason.NEW_FOREST)
        ctrl.resume_undo()
        ctrl.graph_view.setFocus()
Exemplo n.º 25
0
    def undo(self):
        """ Move backward in the undo stack
        :return: None
        """
        if not self._stack:
            return
        #if self._current == 0:
        #    log.info('undo [%s]: Cannot undo further' % self._current)
        #    return
        ctrl.disable_undo()
        ctrl.multiselection_start()
        self.forest.halt_drawing = True
        msg, snapshot = self._stack[self._current]
        for obj, transitions, transition_type in snapshot.values():
            obj.revert_to_earlier(transitions, transition_type)
        self.forest.edge_visibility_check()
        self.forest.flush_and_rebuild_temporary_items()
        log.info('undo [%s]: %s' % (self._current, msg))
        ctrl.multiselection_end()
        ctrl.resume_undo()
        self._current -= 1
        self.forest.halt_drawing = False

        print('-------undo finished', self._current)
Exemplo n.º 26
0
    def undo(self):
        """ Move backward in the undo stack
        :return: None
        """
        if not self._stack:
            return
        #if self._current == 0:
        #    log.info('undo [%s]: Cannot undo further' % self._current)
        #    return
        ctrl.disable_undo()
        ctrl.multiselection_start()
        ctrl.forest.halt_drawing = True
        msg, snapshot = self._stack[self._current]
        for obj, transitions, transition_type in snapshot.values():
            obj.revert_to_earlier(transitions, transition_type)
        ctrl.forest.edge_visibility_check()
        ctrl.forest.flush_and_rebuild_temporary_items()
        log.info('undo [%s]: %s' % (self._current, msg))
        ctrl.multiselection_end()
        ctrl.resume_undo()
        self._current -= 1
        ctrl.forest.halt_drawing = False

        print('-------undo finished', self._current)
Exemplo n.º 27
0
 def trigger_but_suppress_undo(self, *args, **kwargs):
     ctrl.disable_undo()
     self.disable_undo_and_message = True
     self.action_triggered(*args, **kwargs)
     self.disable_undo_and_message = False
     ctrl.resume_undo()
Exemplo n.º 28
0
    def method(self, filename=''):
        """ Open file browser to load a kataja data file
        :param filename: optional filename, if given, no file dialog is displayed
        :return: None
        """
        m = ctrl.main
        # fileName  = QtGui.QFileDialog.getOpenFileName(self,
        # self.tr("Open File"),
        # QtCore.QDir.currentPath())
        file_help = """All (*.kataja *.zkataja *.dict *.zdict *.json *.zjson);;
    Kataja files (*.kataja);; Packed Kataja files (*.zkataja);;
    Python dict dumps (*.dict);; Packed python dicts (*.zdict);;
    JSON dumps (*.json);; Packed JSON (*.zjson);;
    Text files containing bracket trees (*.txt, *.tex)"""

        # inspection doesn't recognize that getOpenFileName is static, switch it
        # off:
        # noinspection PyTypeChecker,PyCallByClass
        if not filename:
            filename, filetypes = QtWidgets.QFileDialog.getOpenFileName(ctrl.main,
                                                                        "Open "
                                                                        "KatajaMain "
                                                                        "trees", "",
                                                                        file_help)
        if not filename:
            return
        save_format = 'dict'
        zipped = False
        for key, value, in file_extensions.items():
            if filename.endswith(value):
                i = key.split('.')
                zipped = len(i) == 2
                save_format = i[0]
                break

        m.clear_all()
        if zipped:
            if save_format == 'json' or save_format == 'dict':
                f = gzip.open(filename, 'rt')
            elif save_format == 'pickle':
                f = gzip.open(filename, 'rb')
            else:
                log.info("Failed to load '%s'. Unknown format." % filename)
                return
        else:
            if save_format == 'pickle':
                f = open(filename, 'rb')
            else:
                f = open(filename, 'r')
                # import codecs
                # f = codecs.open(filename, 'rb', encoding = 'utf-8')

        if save_format == 'pickle':
            pickle_worker = pickle.Unpickler(f)
            data = pickle_worker.load()
        elif save_format == 'dict':
            data = ast.literal_eval(f.read())
            # data = eval(f.read())
        elif save_format == 'json':
            data = json.load(f)
        else:
            f.close()
            log.info("Failed to load '%s'. Unknown format." % filename)
            return

        f.close()
        # prefs.update(data['preferences'].__dict__)
        # qt_prefs.update(prefs)
        ctrl.disable_undo()
        m.load_objects(data, m)
        ctrl.resume_undo()
        ctrl.call_watchers(self.forest_keeper, 'document_changed')
        m.change_forest()
        log.info("Loaded '%s'." % filename)
Exemplo n.º 29
0
    def create_forests(self, filename=None, clear=False):
        """ This will read list of strings where each line defines a trees or an element of trees.
        This can be used to reset the KatajaDocument if no treeset or an empty treeset is given.

        It is common to override this method in plugins to provide custom commands for e.g.
        running parsers.

        Example of tree this can read:

        [.AspP [.Asp\\Ininom] [.vP [.KP [.K\\ng ] [.DP [.D´ [.D ] [.NP\\lola ]] [.KP [.K\\ng]
        [.DP [.D´ [.D ] [.NP\\alila ] ] [.KP\\{ni Maria} ]]]]] [.v´ [.v ] [.VP [.V ] [.KP\\{ang tubig}]]]]]
        Ininom = drank
        ng = NG
        ng = NG
        lola = grandma
        alila = servant
        ni Maria = NG Maria
        ang tubig = ANG water
        'Maria's grandmother's servant drank the water'

        :param filename: (optional) file to load from
        :param clear: (optional) if True, start with an empty treeset and don't attempt to load
        examples
        """
        print('************* create forests ****************')

        if clear:
            treelist = []
        else:
            treelist = self.load_treelist_from_text_file(
                self.__class__.default_treeset_file) or []

        # Clear this screen before we start creating a mess
        ctrl.disable_undo()  # disable tracking of changes (e.g. undo)
        if self.forest:
            self.forest.retire_from_drawing()
        self.forests = []

        # buildstring is the bracket trees or trees.
        buildstring = []
        # definitions includes given definitions for constituents of this trees
        definitions = {}
        # gloss_text is the gloss for whole trees
        gloss_text = ''
        # comments are internal notes about the trees, displayed as help text or something
        comments = []
        started_forest = False

        syntax_class = classes.get('SyntaxConnection')

        for line in treelist:
            line = line.strip()
            #line.split('=', 1)
            parts = line.split('=', 1)
            # comment line
            if line.startswith('#'):
                if started_forest:
                    comments.append(line[1:])
            # Definition line
            elif len(parts) > 1 and not line.startswith('['):
                started_forest = True
                word = parts[0].strip()
                values = parts[1]
                definitions[word] = values
            # Gloss text:
            elif line.startswith("'"):
                if started_forest:
                    if line.endswith("'"):
                        line = line[:-1]
                    gloss_text = line[1:]
            # empty line: finalize this forest
            elif started_forest and not line:
                syn = syntax_class()
                syn.sentence = buildstring
                syn.lexicon = definitions
                forest = Forest(gloss_text=gloss_text,
                                comments=comments,
                                syntax=syn)
                self.forests.append(forest)
                started_forest = False
            # trees definition starts a new forest
            elif line and not started_forest:
                started_forest = True
                buildstring = line
                definitions = {}
                gloss_text = ''
                comments = []
            # another trees definition, append to previous
            elif line:
                buildstring += '\n' + line
        if started_forest:  # make sure that the last forest is also added
            syn = syntax_class()
            syn.sentence = buildstring
            syn.lexicon = definitions
            forest = Forest(gloss_text=gloss_text,
                            comments=comments,
                            syntax=syn)
            self.forests.append(forest)
        if not self.forests:
            syn = syntax_class()
            forest = Forest(gloss_text='', comments=[], syntax=syn)
            self.forests.append(forest)
        self.current_index = 0
        self.forest = self.forests[0]
        # allow change tracking (undo) again
        ctrl.resume_undo()
Exemplo n.º 30
0
 def trigger_but_suppress_undo(self, *args, **kwargs):
     ctrl.disable_undo()
     self.disable_undo_and_message = True
     self.action_triggered(*args, **kwargs)
     self.disable_undo_and_message = False
     ctrl.resume_undo()
Exemplo n.º 31
0
    def method(self, filename=''):
        """ Open file browser to load a kataja data file
        :param filename: optional filename, if given, no file dialog is displayed
        :return: None
        """
        m = ctrl.main
        # fileName  = QtGui.QFileDialog.getOpenFileName(self,
        # self.tr("Open File"),
        # QtCore.QDir.currentPath())
        file_help = """All (*.kataja *.zkataja *.dict *.zdict *.json *.zjson);;
    Kataja files (*.kataja);; Packed Kataja files (*.zkataja);;
    Python dict dumps (*.dict);; Packed python dicts (*.zdict);;
    JSON dumps (*.json);; Packed JSON (*.zjson);;
    Text files containing bracket trees (*.txt, *.tex)"""

        # inspection doesn't recognize that getOpenFileName is static, switch it
        # off:
        # noinspection PyTypeChecker,PyCallByClass
        if not filename:
            filename, filetypes = QtWidgets.QFileDialog.getOpenFileName(ctrl.main,
                                                                        "Open "
                                                                        "KatajaMain "
                                                                        "trees", "",
                                                                        file_help)
        if not filename:
            return
        save_format = 'dict'
        zipped = False
        for key, value, in file_extensions.items():
            if filename.endswith(value):
                i = key.split('.')
                zipped = len(i) == 2
                save_format = i[0]
                break

        m.clear_all()
        if zipped:
            if save_format == 'json' or save_format == 'dict':
                f = gzip.open(filename, 'rt')
            elif save_format == 'pickle':
                f = gzip.open(filename, 'rb')
            else:
                log.info("Failed to load '%s'. Unknown format." % filename)
                return
        else:
            if save_format == 'pickle':
                f = open(filename, 'rb')
            else:
                f = open(filename, 'r')
                # import codecs
                # f = codecs.open(filename, 'rb', encoding = 'utf-8')

        if save_format == 'pickle':
            pickle_worker = pickle.Unpickler(f)
            data = pickle_worker.load()
        elif save_format == 'dict':
            data = ast.literal_eval(f.read())
            # data = eval(f.read())
        elif save_format == 'json':
            data = json.load(f)
        else:
            f.close()
            log.info("Failed to load '%s'. Unknown format." % filename)
            return

        f.close()
        # prefs.update(data['preferences'].__dict__)
        # qt_prefs.update(prefs)
        ctrl.disable_undo()
        m.load_objects(data, m)
        ctrl.resume_undo()
        ctrl.call_watchers(self.forest_keeper, 'document_changed')
        m.change_forest()
        log.info("Loaded '%s'." % filename)
Exemplo n.º 32
0
 def disable_signaling(self):
     # shut down side effects
     self._stored_init_state = self.init_done
     self.init_done = False
     ctrl.disable_undo()
     self.blockSignals(True)
Exemplo n.º 33
0
    def run(self, *args, fetch_params=True, print_command=True, **kwargs):
        """ Trigger action with parameters received from action data object and designated UI
        element
        :return: None
        """
        if not self.isEnabled():
            return
        # Prepare to use alt_command in feedback if the action supports it
        command = self.command
        if self.isCheckable() and self.isChecked() and self.command_alt:
            command = self.command_alt

        # -- Redraw and undo flags: these are on by default, can be switched off by action method
        ctrl.action_redraw = True

        # Disable undo if necessary
        if not self.undoable:
            ctrl.disable_undo()
        self.autoplay = True

        # manually given commands have their parameters, and the command prompt has taken
        # care for logging them. Commands run by UI triggers use a helper method
        # 'prepare_parameters' to set args before running the command. The command being run
        # is logged and made available in command prompt so that the user has better grasp of
        # inner workings of Kataja.

        if fetch_params:
            args, kwargs = self.prepare_parameters(args, kwargs)

        if print_command:
            # Print the command into console
            m = super(self.__class__, self)
            if m.method == self.method and m.k_action_uid:
                action_name = m.k_action_uid
            else:
                action_name = self.k_action_uid
            arg_parts = [repr(a) for a in args]
            kwarg_parts = [f'{key}={repr(value)}' for key, value in kwargs.items()]
            command_string = action_name + '(' + ', '.join(arg_parts + kwarg_parts) + ')'
            log.info('>>> ' + command_string)
            log.log_handler.add_to_command_backlog(command_string)
        try:
            message = self.method(*args, **kwargs)
            error = None
        except:
            message = ''
            error = "Action %r ('%s')<br/>" % (self, self.key)
            error += '<br/>'.join(traceback.format_exception(*sys.exc_info()))
            log.error("Unexpected error: %s" % str(sys.exc_info()))
            traceback.print_exc()
        # Restore undo state to what it was
        if not self.undoable:
            ctrl.resume_undo()
        if self.disable_undo_and_message:
            ctrl.main.action_finished(undoable=False, play=self.autoplay)
        else:
            sc = self.shortcut()
            if sc:
                sc = sc.toString()
                sc = sc.replace('Ctrl', running_environment.cmd_or_ctrl)
                reply = f'({sc}) {message or command}'
            else:
                reply = message
            ctrl.main.action_finished(m=reply, undoable=self.undoable and not ctrl.undo_disabled,
                                      error=error, play=self.autoplay)
Exemplo n.º 34
0
    def create_forests(self, filename=None, clear=False):
        """ This will read list of strings where each line defines a trees or an element of trees.
        This can be used to reset the KatajaDocument if no treeset or an empty treeset is given.

        It is common to override this method in plugins to provide custom commands for e.g.
        running parsers.

        Example of tree this can read:

        [.AspP [.Asp\\Ininom] [.vP [.KP [.K\\ng ] [.DP [.D´ [.D ] [.NP\\lola ]] [.KP [.K\\ng]
        [.DP [.D´ [.D ] [.NP\\alila ] ] [.KP\\{ni Maria} ]]]]] [.v´ [.v ] [.VP [.V ] [.KP\\{ang tubig}]]]]]
        Ininom = drank
        ng = NG
        ng = NG
        lola = grandma
        alila = servant
        ni Maria = NG Maria
        ang tubig = ANG water
        'Maria's grandmother's servant drank the water'

        :param filename: (optional) file to load from
        :param clear: (optional) if True, start with an empty treeset and don't attempt to load
        examples
        """
        print("************* create forests ****************")

        if clear:
            treelist = []
        else:
            treelist = self.load_treelist_from_text_file(self.__class__.default_treeset_file) or []

        # Clear this screen before we start creating a mess
        ctrl.disable_undo()  # disable tracking of changes (e.g. undo)
        if self.forest:
            self.forest.retire_from_drawing()
        self.forests = []

        # buildstring is the bracket trees or trees.
        buildstring = []
        # definitions includes given definitions for constituents of this trees
        definitions = {}
        # gloss_text is the gloss for whole trees
        gloss_text = ""
        # comments are internal notes about the trees, displayed as help text or something
        comments = []
        started_forest = False

        syntax_class = classes.get("SyntaxConnection")

        for line in treelist:
            line = line.strip()
            # line.split('=', 1)
            parts = line.split("=", 1)
            # comment line
            if line.startswith("#"):
                if started_forest:
                    comments.append(line[1:])
            # Definition line
            elif len(parts) > 1 and not line.startswith("["):
                started_forest = True
                word = parts[0].strip()
                values = parts[1]
                definitions[word] = values
            # Gloss text:
            elif line.startswith("'"):
                if started_forest:
                    if line.endswith("'"):
                        line = line[:-1]
                    gloss_text = line[1:]
            # empty line: finalize this forest
            elif started_forest and not line:
                syn = syntax_class()
                syn.sentence = buildstring
                syn.lexicon = definitions
                forest = Forest(gloss_text=gloss_text, comments=comments, syntax=syn)
                self.forests.append(forest)
                started_forest = False
            # trees definition starts a new forest
            elif line and not started_forest:
                started_forest = True
                buildstring = line
                definitions = {}
                gloss_text = ""
                comments = []
            # another trees definition, append to previous
            elif line:
                buildstring += "\n" + line
        if started_forest:  # make sure that the last forest is also added
            syn = syntax_class()
            syn.sentence = buildstring
            syn.lexicon = definitions
            forest = Forest(gloss_text=gloss_text, comments=comments, syntax=syn)
            self.forests.append(forest)
        if not self.forests:
            syn = syntax_class()
            forest = Forest(gloss_text="", comments=[], syntax=syn)
            self.forests.append(forest)
        self.current_index = 0
        self.forest = self.forests[0]
        # allow change tracking (undo) again
        ctrl.resume_undo()