コード例 #1
0
    def __init__(self, name, **kwargs):
        self.enable_changed = Event(str, bool)
        self.enable_changed += self.on_enabled_changed
        self._is_enabled = False
        self._init = None

        self.name = name
        self.is_enabled = kwargs.get('is_enabled', True)
コード例 #2
0
class ScenarioModel:

    name_changed = Event(str)
    current_exercise_changed = Event(int, object)
    scenario_loaded = Event(int, int)
    scenario_ended = Event()

    def __init__(self):
        self._name = 'NONE'
        self.exercises = []
        self.widgets = []
        self._index = 0
        self.correct_count = 0

    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, value):
        self._name = value
        self.name_changed.emit(value)

    @property
    def current_exercise(self):
        return self.exercises[self.index] if self.index < self.total else None

    @property
    def current_widget(self):
        return self.widgets[self.index] if self.index < self.total else None

    @property
    def index(self):
        return self._index

    @index.setter
    def index(self, value):
        self._index = value
        self.current_exercise_changed.emit(value, self.current_widget)

    @property
    def total(self):
        return len(self.exercises)

    def set_exercises(self, exercises_wids_tuple):
        self.reset()
        self.widgets, self.exercises = zip(*exercises_wids_tuple)
        self.scenario_loaded.emit(self.index, self.total)
        self.current_exercise_changed.emit(self.index, self.current_widget)

    def check_answer(self, answer):
        self.correct_count += 1 if self.current_exercise.check_answer(answer) else 0
        self.index += 1

    def reset(self):
        self._index = 0
        self.correct_count = 0
コード例 #3
0
class BaseExerciseWidget(QWidget):

    send_answer_event = Event()

    def __init__(self, exercise, parent=None):
        super().__init__(parent)
        self.data = exercise
        self.__init_ui()

    def __init_ui(self):
        self.grid = QGridLayout(self)
        self.setLayout(self.grid)

        self._init_quest_field()
        self._init_answer_field()

    def _init_quest_field(self):
        self.questTypeLbl = QLabel(self)
        self.questTypeLbl.setText(self.data.question_type.ui)
        self.questTypeLbl.setAlignment(Qt.AlignCenter)
        self.questTypeLbl.setSizePolicy(QSizePolicy.Preferred,
                                        QSizePolicy.Fixed)
        self.grid.addWidget(self.questTypeLbl, 0, 0, 1, 1)

        self.questLbl = QLabel(self)
        style = QUEST_LBL_CSS if len(
            self.data.question) > 1 else QUEST_KAN_LBL_CSS
        self.questLbl.setStyleSheet(style)
        self.questLbl.setAlignment(Qt.AlignCenter)
        self.questLbl.setText(self.data.question)
        self.grid.addWidget(self.questLbl, 1, 0, 1, 1)

    def _init_answer_field(self):
        pass
コード例 #4
0
class CrossWidgetEvents:
    change_screen_event = Event(int)
    clsoe_main_window_event = Event()
    load_scenario_event = Event(object, str, bool)
    show_message_event = Event(str, str, str)
    start_editor_event = Event(EditorMode, list)
    reload_scenarios_event = Event()
    locale_changed_event = Event()
    show_question_event = Event(str, str, object)
コード例 #5
0
class Module:
    __slots__ = ('name', '_is_enabled', '_init', 'enable_changed')

    def __init__(self, name, **kwargs):
        self.enable_changed = Event(str, bool)
        self.enable_changed += self.on_enabled_changed
        self._is_enabled = False
        self._init = None

        self.name = name
        self.is_enabled = kwargs.get('is_enabled', True)

    @property
    def ui_name(self):
        return self.init.get_name() if self.init else self.name

    @property
    def is_enabled(self):
        return self._is_enabled

    @is_enabled.setter
    def is_enabled(self, value):
        if self._is_enabled == value:
            return
        self._is_enabled = value
        self.enable_changed.emit(self.name, value)

    @property
    def init(self):
        return self._init

    def activate_module(self):
        self._init = get_module_init(self.name)
        self._is_enabled = self._init is not None

    def deactivate_module(self):
        self._is_enabled = False
        self._init = None

    def on_enabled_changed(self, name, value):
        self.activate_module() if value \
            else self.deactivate_module()
コード例 #6
0
ファイル: scenario.py プロジェクト: Serega-SPb/lang_tutor
 def __init__(self, mod, quest_type, lazy_init):
     self.module = mod
     self.quest_type_changed = Event(str)
     if isinstance(quest_type, str):
         func = self.module.init.translate_local if self.module.init else lambda x: quest_type
         qt = QuestType(quest_type, func)
     else:
         qt = quest_type
     self._quest_type = NotifyProperty('quest_type', qt)
     self._quest_type += self.quest_type_changed.emit
     self.lazy_init = lazy_init
     self._data = None
コード例 #7
0
class EditorBlockModel:

    keys_changed = Event(list)
    kanji_changed = Event(object)
    update_kanji_event = Event()
    update_label_event = Event()

    def __init__(self):
        self.kanji = None
        self.prop_path = ''
        self._keys = NotifyProperty('keys', list())
        self._keys += self.keys_changed.emit
        self.update_kanji_event += self.update_label_event.emit
        self.update_kanji_event += lambda: self.kanji_changed.emit(self.kanji)

    def set_kanji(self, value):
        self.kanji = value
        self.kanji_changed.emit(value)

    @property
    def keys(self):
        return self._keys.get()

    @keys.setter
    def keys(self, value):
        self._keys.set(value)

    def set_kanji_prop(self, prop_name, value):
        @ChangeMemento(f'{self.prop_path}.{prop_name}',
                       self.update_kanji_event)
        def memento_func():
            setattr(self.kanji, prop_name, value)

        if not self.kanji or getattr(self.kanji, prop_name) == value:
            return
        memento_func()
コード例 #8
0
class EditorBlockModel:

    word_changed = Event(object)
    update_word_event = Event()
    update_label_event = Event()

    def __init__(self):
        self.word = None
        self.prop_path = ''
        self.update_word_event += self.update_label_event.emit
        self.update_word_event += lambda: self.word_changed.emit(self.word)

    def set_word(self, value):
        self.word = value
        self.word_changed.emit(value)

    def set_word_prop(self, prop_name, value):
        @ChangeMemento(f'{self.prop_path}.{prop_name}', self.update_word_event)
        def memento_func():
            setattr(self.word, prop_name, value)

        if not self.word or getattr(self.word, prop_name) == value:
            return
        memento_func()
コード例 #9
0
ファイル: main_model.py プロジェクト: Serega-SPb/lang_tutor
class MainModel:

    modules_changed = Event(list)
    scenarios_changed = Event(list)
    locales_changed = Event(list)

    is_applied_settings_changed = Event(bool)
    is_options_enabled_changed = Event(bool)

    current_locale_changed = Event(str)
    modules_dir_changed = Event(str)
    scenarios_dir_changed = Event(str)

    def __init__(self):
        self.data_loader = DataLoader()
        self._is_options_enabled = NotifyProperty('is_options_enabled', False)
        self._is_options_enabled += self.is_options_enabled_changed.emit
        self._editor_mode = NotifyProperty('editor_mode', 0)

        self.locales = []
        self._is_applied_settings = NotifyProperty('is_applied_settings', True)
        self._is_applied_settings += self.is_applied_settings_changed.emit
        self._current_locale = NotifyProperty('current_locale')
        self._current_locale += self.current_locale_changed.emit
        self._modules_dir = ''
        self._scenarios_dir = ''

    @property
    def is_debug(self):
        return self.data_loader.is_debug

    @property
    def modules(self):
        return self.data_loader.modules.values()

    @property
    def scenarios(self):
        return self.data_loader.scenarios.values()

    def update_modules(self):
        self.modules_changed.emit(self.modules)

    def update_scenarios(self):
        self.scenarios_changed.emit(self.scenarios)

    @property
    def is_options_enabled(self):
        return self._is_options_enabled.get()

    @is_options_enabled.setter
    def is_options_enabled(self, value):
        self._is_options_enabled.set(value)

    @property
    def editor_mode(self):
        return self._editor_mode.get()

    @editor_mode.setter
    def editor_mode(self, value):
        self._editor_mode.set(value)

    def set_locales(self, values):
        self.locales = values
        self.locales_changed.emit(values)

    @property
    def is_applied_settings(self):
        return self._is_applied_settings.get()

    @is_applied_settings.setter
    def is_applied_settings(self, value):
        self._is_applied_settings.set(value)

    @property
    def current_locale(self):
        return self._current_locale.get()

    @current_locale.setter
    def current_locale(self, value):
        self._current_locale.set(value)
        self.is_applied_settings = False

    @property
    def modules_dir(self):
        return self._modules_dir

    @modules_dir.setter
    def modules_dir(self, value):
        self._modules_dir = value
        self.modules_dir_changed.emit(value)
        self.is_applied_settings = False

    @property
    def scenarios_dir(self):
        return self._scenarios_dir

    @scenarios_dir.setter
    def scenarios_dir(self, value):
        self._scenarios_dir = value
        self.is_applied_settings = False
        self.scenarios_dir_changed.emit(value)
コード例 #10
0
class MementoManager(metaclass=Singleton):

    can_undo_changed = Event(bool)
    can_redo_changed = Event(bool)
    index_changed = Event(int)

    def __init__(self):
        self.logger = logger
        self.super_subject = None

    def set_subject(self, subject):
        self._index = -1
        self._history = []
        self.subject = subject
        self.update_status()

    @property
    def index(self):
        return self._index

    @property
    def can_undo(self):
        return self._index >= 0

    @property
    def can_redo(self):
        return self._index < len(self._history) - 1

    def save(self, memento):
        memento.save(self.subject)
        if self.has_changes(memento):
            self._index += 1
            if self._index < len(self._history):
                self._history = self._history[:self._index]
            self._history.append(memento)
            self.update_status()
        self.logger.debug(f'SAVE {str(memento)} (ID={self._index})')

    def has_changes(self, memento):
        def check_equal(memento_1, memento_2):
            return type(memento_1) == type(
                memento_2) and memento_1.prop_path == memento_2.prop_path

        last_mementos = [
            m for m in self._history[:self._index + 1][::-1]
            if check_equal(m, memento)
        ]
        return not last_mementos[0] == memento if len(
            last_mementos) > 0 else True

    def cancel(self):
        while self.can_undo:
            self.undo()

    def undo(self):
        if not self.can_undo:
            return
        hist = self._history[self._index]
        hist.undo(self.subject)
        self._index -= 1
        self.logger.debug(f'UNDO {str(hist)}')
        self.update_status()

    def redo(self):
        if not self.can_redo:
            return
        self._index += 1
        hist = self._history[self._index]
        hist.redo(self.subject)
        self.logger.debug(f'REDO {str(hist)}')
        self.update_status()

    def update_status(self):
        self.can_undo_changed.emit(self.can_undo)
        self.can_redo_changed.emit(self.can_redo)
        self.index_changed.emit(self.index)
コード例 #11
0
class EditorModel:

    SC_DATA = 'scenario_data'

    scenario_changed = Event(object)
    scenario_name_changed = Event(str)
    can_undo_changed = Event(bool)
    can_redo_changed = Event(bool)
    can_save_changed = Event(bool)
    blocks_changed = Event(list)

    quest_types_changed = Event(list)
    current_quest_type_changed = Event(str)
    current_sc_block_index_changed = Event(int)
    current_data_index_changed = Event(int)
    current_sc_block_changed = Event(object)
    current_data_changed = Event(object, str)

    listitem_widget_changed = Event(object)
    block_widget_changed = Event(object)

    update_scenario_event = Event()
    update_scenario_name_event = Event()
    update_curr_sc_block = Event()
    update_current_quest_type_event = Event()

    def __init__(self):
        self._scenario = NotifyProperty('scenario')
        self._scenario += self.scenario_changed.emit
        self._blocks = NotifyProperty('blocks', list())
        self._blocks += self.blocks_changed.emit

        self._quest_types = NotifyProperty('quest_types_changed', list())
        self._quest_types += self.quest_types_changed.emit
        self._current_sc_block_index = NotifyProperty('current_sc_block_index',
                                                      -1)
        self._current_sc_block_index += self.current_sc_block_index_changed.emit
        self._current_data_index = NotifyProperty('current_data_index', -1)
        self._current_data_index += self.current_data_index_changed.emit
        self._current_data_index += lambda x: self.send_data()

        self._listitem_widget = NotifyProperty('listitem_widget')
        self._listitem_widget += self.listitem_widget_changed.emit
        self._block_widget = NotifyProperty('_block_widget')
        self._block_widget += self.block_widget_changed.emit
        self.update_scenario_event += self.update_scenario
        self.update_scenario_name_event += self.update_scenario_name
        self.update_curr_sc_block += self.send_sc_block
        self.update_current_quest_type_event += lambda: self.current_quest_type_changed.emit(
            self.current_quest_type)

    # region Top lvl
    @property
    def scenario(self):
        return self._scenario.get()

    @scenario.setter
    def scenario(self, value):
        self._scenario.set(value)

    @property
    def blocks(self):
        return self._blocks.get()

    @blocks.setter
    def blocks(self, value):
        self._blocks.set(value)

    def append_scenario_data(self, sc_data):
        prop_path = f'{self.SC_DATA}.[{len(self.scenario.scenario_data)}]'
        AddMemento(prop_path, self.update_scenario_event)\
            (self.scenario.scenario_data.append)(sc_data)
        self.scenario_changed.emit(self.scenario)

    def remove_scenario_data(self, sc_data):
        prop_path = f'{self.SC_DATA}.[{self.scenario.scenario_data.index(sc_data)}]'
        RemoveMemento(prop_path, self.update_scenario_event)\
            (self.scenario.scenario_data.remove)(sc_data)
        self.scenario_changed.emit(self.scenario)

    # endregion

    # region Mid lvl

    @property
    def quest_types(self):
        return self._quest_types.get()

    @quest_types.setter
    def quest_types(self, value):
        self._quest_types.set(value)

    @property
    def current_quest_type(self):
        return self.get_current_sc_block().quest_type

    @current_quest_type.setter
    def current_quest_type(self, value):
        @ChangeMemento(self.get_block_prop_path('quest_type'),
                       self.update_current_quest_type_event)
        def wrapper():
            self.get_current_sc_block().quest_type = value
            self.current_quest_type_changed.emit(value.value)

        curr_bl = self.get_current_sc_block()

        if curr_bl is None or curr_bl.quest_type == value:
            return
        wrapper()

    @property
    def current_sc_block_index(self):
        return self._current_sc_block_index.get()

    @current_sc_block_index.setter
    def current_sc_block_index(self, value):
        self._current_sc_block_index.set(value)

    @property
    def current_data_index(self):
        return self._current_data_index.get()

    @current_data_index.setter
    def current_data_index(self, value):
        self._current_data_index.set(value)

    def get_current_sc_block(self):
        index = self.current_sc_block_index
        return self.scenario.scenario_data[index] \
            if 0 <= index < len(self.scenario.scenario_data) else None

    def get_current_data(self):
        index = self.current_data_index
        sc_block = self.get_current_sc_block()
        return sc_block.data[index] \
            if 0 <= index < len(sc_block.data) else None

    def get_block_prop_path(self, prop_name):
        return f'{self.SC_DATA}.[{self.current_sc_block_index}].{prop_name}'

    def append_block_data(self, value):
        data = self.scenario.scenario_data[self.current_sc_block_index].data
        prop_path = f"{self.get_block_prop_path('data')}.[{len(data)}]"
        AddMemento(prop_path, self.update_curr_sc_block)(data.append)(value)
        self.current_kanji_index = len(data) - 1
        self.send_sc_block()

    def remove_block_data(self, value):
        data = self.scenario.scenario_data[self.current_sc_block_index].data
        prop_path = f"{self.get_block_prop_path('data')}.[{data.index(value)}]"
        RemoveMemento(prop_path, self.update_curr_sc_block)(data.remove)(value)
        self.current_kanji_index = -1
        self.send_sc_block()

    # endregion

    @property
    def listitem_widget(self):
        return self._listitem_widget.get()

    @listitem_widget.setter
    def listitem_widget(self, value):
        self._listitem_widget.set(value)

    @property
    def block_widget(self):
        return self._block_widget.get()

    @block_widget.setter
    def block_widget(self, value):
        self._block_widget.set(value)

    def update_scenario(self):
        self.scenario_changed.emit(self.scenario)

    def update_scenario_name(self):
        self.scenario_name_changed.emit(self.scenario.name)

    def send_sc_block(self):
        self.current_sc_block_changed.emit(self.get_current_sc_block())

    def send_data(self):
        prop_path = f"{self.get_block_prop_path('data')}.[{self.current_data_index}]"
        self.current_data_changed.emit(self.get_current_data(), prop_path)