<commit_before>#
# add_cards_dlg.py <Peter.Bienstman<EMAIL>>
#

import copy

from PyQt4 import QtCore, QtGui

from mnemosyne.libmnemosyne.fact import Fact
from mnemosyne.libmnemosyne.translator import _
from mnemosyne.libmnemosyne.component import Component
from mnemosyne.pyqt_ui.ui_add_cards_dlg import Ui_AddCardsDlg
from mnemosyne.pyqt_ui.preview_cards_dlg import PreviewCardsDlg
from mnemosyne.libmnemosyne.ui_components.dialogs import AddCardsDialog
from mnemosyne.pyqt_ui.card_type_wdgt_generic import GenericCardTypeWdgt
from mnemosyne.pyqt_ui.convert_card_type_keys_dlg import \
     ConvertCardTypeKeysDlg
from mnemosyne.pyqt_ui.tip_after_starting_n_times import \
     TipAfterStartingNTimes


class AddEditCards(TipAfterStartingNTimes):

    """Code shared between the add and the edit dialogs."""

    started_n_times_counter = "started_add_edit_cards_n_times"
    tip_after_n_times = \
        {3: _("You can add multiple tags to a card by separating tags with a comma in the 'Tag(s)' input field."),
         6: _("You can organise tags in a hierarchy by using :: as separator, e.g. My book::Lesson 1."),
         9: _("You can add images and sounds to your cards. Right-click on an input field when editing a card to bring up a pop-up menu to do so."),
         12: _("If for a certain card type cloned from Vocabulary you don't need a pronunciation field, you can hide it by right-clicking on it and using the pop-up menu."),
         15: _("You can use Tab to move between the fields. For 'Add cards', use Ctrl+Enter for 'Yet to learn', and Ctrl+2, etc. for the grades. For 'Edit card', use Ctrl-Enter to close.")}

    def activate(self):
        self.show_tip_after_starting_n_times()
        self.exec_()

    def initialise_card_types_combobox(self, current_card_type_name):
        # We calculate card_type_by_name here because these names can change
        # if the user chooses another translation.
        self.card_type_by_name = {}
        self.card_type = None
        self.card_type_index = 0
        self.card_type_widget = None
        for card_type in self.card_types():
            if _(card_type.name) == current_card_type_name:
                self.card_type = card_type
                self.card_type_index = self.card_types_widget.count()
            self.card_type_by_name[_(card_type.name)] = card_type
            self.card_types_widget.addItem(_(card_type.name))
        if not self.card_type:
            self.card_type = self.card_types()[0]
            self.card_type_index = 0
        self.card_types_widget.setCurrentIndex(self.card_type_index)
        # Now that the combobox is filled, we can connect the signal.
        self.card_types_widget.currentIndexChanged[QtCore.QString].\
            connect(self.card_type_changed)
        self.correspondence = {}  # Used when changing card types.
        self.update_card_widget()

    def update_card_widget(self, keep_data_from_previous_widget=True):
        # Determine data to put into card widget. Since we want to share this
        # code between the 'add' and the 'edit' dialogs, we put the reference
        # to self.card (which only exists in the 'edit' dialog) inside a try
        # statement.
        if self.card_type_widget:  # Get data from previous card widget.
            prefill_fact_data = self.card_type_widget.fact_data()
            self.card_type_widget.close()
            self.card_type_widget = None
        else:
            try:  # Get data from fact passed to the 'edit' dialog.
                prefill_fact_data = self.card.fact.data
            except:  # Start from scratch in the 'add' dialog.
                prefill_fact_data = None
        # Transform keys in dictionary if the card type has changed, but don't
        # edit the fact just yet.
        if prefill_fact_data and self.correspondence:
            old_prefill_fact_data = copy.copy(prefill_fact_data)
            prefill_fact_data = {}
            for fact_key in old_prefill_fact_data:
                if fact_key in self.correspondence:
                    value = old_prefill_fact_data[fact_key]
                    prefill_fact_data[self.correspondence[fact_key]] = value
        # If we just want to force a new card in the dialog, e.g. by pressing
        # PageUp or PageDown in the card browser, don't bother with trying to
        # keep old data.
        if not keep_data_from_previous_widget:
            prefill_fact_data = self.card.fact.data
        # Show new card type widget.
        card_type_name = unicode(self.card_types_widget.currentText())
        self.card_type = self.card_type_by_name[card_type_name]
        try:
            self.card_type_widget = self.component_manager.current \
                ("card_type_widget", used_for=self.card_type.__class__) \
                (self.component_manager, parent=self)
        except:
            if not self.card_type_widget:
                self.card_type_widget = self.component_manager.current \
                    ("generic_card_type_widget")(self.component_manager,
                    parent=self, card_type=self.card_type)
        self.card_type_widget.set_fact_data(prefill_fact_data)
        self.card_type_widget.show()
        self.vbox_layout.insertWidget(1, self.card_type_widget)

    def update_tags_combobox(self, current_tag_name):
        all_current_tag_names = current_tag_name.split(", ")
        existing_current_tag_names = []
        self.tags.clear()
        for tag in self.database().tags():
            if tag.name != "__UNTAGGED__":
                self.tags.addItem(tag.name)
            if tag.name in all_current_tag_names:
                existing_current_tag_names.append(tag.name)
        current_tag_name = ", ".join(existing_current_tag_names)
        # For the 'special' tags, we add them at the top.
        self.tags.setInsertPolicy(QtGui.QComboBox.InsertAtTop)
        if "," in current_tag_name:
            self.tags.addItem(current_tag_name)
        if current_tag_name == "":
            self.tags.addItem(current_tag_name)
        for i in range(self.tags.count()):
            if self.tags.itemText(i) == current_tag_name:
                self.tags.setCurrentIndex(i)
                break

    def card_type_changed(self, new_card_type_name):
        new_card_type_name = unicode(new_card_type_name)
        new_card_type = self.card_type_by_name[new_card_type_name]
        self.config()["last_used_card_type_id"] = new_card_type.id
        if new_card_type.id not in \
            self.config()["last_used_tags_for_card_type_id"]:
            self.config()["last_used_tags_for_card_type_id"]\
                [new_card_type.id] = ""
        if not unicode(self.tags.currentText()) \
            or self.card_type_widget.is_empty():
            self.update_tags_combobox(self.config()\
                ["last_used_tags_for_card_type_id"][new_card_type.id])
        if self.card_type.fact_keys().issubset(new_card_type.fact_keys()) or \
            self.card_type_widget.is_empty():
            self.update_card_widget()
            return
        dlg = ConvertCardTypeKeysDlg(self.card_type, new_card_type,
            self.correspondence, check_required_fact_keys=False, parent=self)
        if dlg.exec_() != QtGui.QDialog.Accepted:
            # Set correspondence so as not to erase previous data.
            self.correspondence = {key: key \
                for key in self.card_type.fact_keys()}
            self.card_types_widget.setCurrentIndex(self.card_type_index)
            return
        else:
            self.update_card_widget()

    def preview(self):
        fact_data = self.card_type_widget.fact_data()
        fact = Fact(fact_data)
        cards = self.card_type.create_sister_cards(fact)
        tag_text = unicode(self.tags.currentText())
        dlg = PreviewCardsDlg(self.component_manager, cards, tag_text, self)
        dlg.exec_()
<commit_msg>Revert Python 2.7 construct to 2.6.<commit_after>#
# add_cards_dlg.py <Peter.Bienstman<EMAIL>>
#

import copy

from PyQt4 import QtCore, QtGui

from mnemosyne.libmnemosyne.fact import Fact
from mnemosyne.libmnemosyne.translator import _
from mnemosyne.libmnemosyne.component import Component
from mnemosyne.pyqt_ui.ui_add_cards_dlg import Ui_AddCardsDlg
from mnemosyne.pyqt_ui.preview_cards_dlg import PreviewCardsDlg
from mnemosyne.libmnemosyne.ui_components.dialogs import AddCardsDialog
from mnemosyne.pyqt_ui.card_type_wdgt_generic import GenericCardTypeWdgt
from mnemosyne.pyqt_ui.convert_card_type_keys_dlg import \
     ConvertCardTypeKeysDlg
from mnemosyne.pyqt_ui.tip_after_starting_n_times import \
     TipAfterStartingNTimes


class AddEditCards(TipAfterStartingNTimes):

    """Code shared between the add and the edit dialogs."""

    started_n_times_counter = "started_add_edit_cards_n_times"
    tip_after_n_times = \
        {3: _("You can add multiple tags to a card by separating tags with a comma in the 'Tag(s)' input field."),
         6: _("You can organise tags in a hierarchy by using :: as separator, e.g. My book::Lesson 1."),
         9: _("You can add images and sounds to your cards. Right-click on an input field when editing a card to bring up a pop-up menu to do so."),
         12: _("If for a certain card type cloned from Vocabulary you don't need a pronunciation field, you can hide it by right-clicking on it and using the pop-up menu."),
         15: _("You can use Tab to move between the fields. For 'Add cards', use Ctrl+Enter for 'Yet to learn', and Ctrl+2, etc. for the grades. For 'Edit card', use Ctrl-Enter to close.")}

    def activate(self):
        self.show_tip_after_starting_n_times()
        self.exec_()

    def initialise_card_types_combobox(self, current_card_type_name):
        # We calculate card_type_by_name here because these names can change
        # if the user chooses another translation.
        self.card_type_by_name = {}
        self.card_type = None
        self.card_type_index = 0
        self.card_type_widget = None
        for card_type in self.card_types():
            if _(card_type.name) == current_card_type_name:
                self.card_type = card_type
                self.card_type_index = self.card_types_widget.count()
            self.card_type_by_name[_(card_type.name)] = card_type
            self.card_types_widget.addItem(_(card_type.name))
        if not self.card_type:
            self.card_type = self.card_types()[0]
            self.card_type_index = 0
        self.card_types_widget.setCurrentIndex(self.card_type_index)
        # Now that the combobox is filled, we can connect the signal.
        self.card_types_widget.currentIndexChanged[QtCore.QString].\
            connect(self.card_type_changed)
        self.correspondence = {}  # Used when changing card types.
        self.update_card_widget()

    def update_card_widget(self, keep_data_from_previous_widget=True):
        # Determine data to put into card widget. Since we want to share this
        # code between the 'add' and the 'edit' dialogs, we put the reference
        # to self.card (which only exists in the 'edit' dialog) inside a try
        # statement.
        if self.card_type_widget:  # Get data from previous card widget.
            prefill_fact_data = self.card_type_widget.fact_data()
            self.card_type_widget.close()
            self.card_type_widget = None
        else:
            try:  # Get data from fact passed to the 'edit' dialog.
                prefill_fact_data = self.card.fact.data
            except:  # Start from scratch in the 'add' dialog.
                prefill_fact_data = None
        # Transform keys in dictionary if the card type has changed, but don't
        # edit the fact just yet.
        if prefill_fact_data and self.correspondence:
            old_prefill_fact_data = copy.copy(prefill_fact_data)
            prefill_fact_data = {}
            for fact_key in old_prefill_fact_data:
                if fact_key in self.correspondence:
                    value = old_prefill_fact_data[fact_key]
                    prefill_fact_data[self.correspondence[fact_key]] = value
        # If we just want to force a new card in the dialog, e.g. by pressing
        # PageUp or PageDown in the card browser, don't bother with trying to
        # keep old data.
        if not keep_data_from_previous_widget:
            prefill_fact_data = self.card.fact.data
        # Show new card type widget.
        card_type_name = unicode(self.card_types_widget.currentText())
        self.card_type = self.card_type_by_name[card_type_name]
        try:
            self.card_type_widget = self.component_manager.current \
                ("card_type_widget", used_for=self.card_type.__class__) \
                (self.component_manager, parent=self)
        except:
            if not self.card_type_widget:
                self.card_type_widget = self.component_manager.current \
                    ("generic_card_type_widget")(self.component_manager,
                    parent=self, card_type=self.card_type)
        self.card_type_widget.set_fact_data(prefill_fact_data)
        self.card_type_widget.show()
        self.vbox_layout.insertWidget(1, self.card_type_widget)

    def update_tags_combobox(self, current_tag_name):
        all_current_tag_names = current_tag_name.split(", ")
        existing_current_tag_names = []
        self.tags.clear()
        for tag in self.database().tags():
            if tag.name != "__UNTAGGED__":
                self.tags.addItem(tag.name)
            if tag.name in all_current_tag_names:
                existing_current_tag_names.append(tag.name)
        current_tag_name = ", ".join(existing_current_tag_names)
        # For the 'special' tags, we add them at the top.
        self.tags.setInsertPolicy(QtGui.QComboBox.InsertAtTop)
        if "," in current_tag_name:
            self.tags.addItem(current_tag_name)
        if current_tag_name == "":
            self.tags.addItem(current_tag_name)
        for i in range(self.tags.count()):
            if self.tags.itemText(i) == current_tag_name:
                self.tags.setCurrentIndex(i)
                break

    def card_type_changed(self, new_card_type_name):
        new_card_type_name = unicode(new_card_type_name)
        new_card_type = self.card_type_by_name[new_card_type_name]
        self.config()["last_used_card_type_id"] = new_card_type.id
        if new_card_type.id not in \
            self.config()["last_used_tags_for_card_type_id"]:
            self.config()["last_used_tags_for_card_type_id"]\
                [new_card_type.id] = ""
        if not unicode(self.tags.currentText()) \
            or self.card_type_widget.is_empty():
            self.update_tags_combobox(self.config()\
                ["last_used_tags_for_card_type_id"][new_card_type.id])
        if self.card_type.fact_keys().issubset(new_card_type.fact_keys()) or \
            self.card_type_widget.is_empty():
            self.update_card_widget()
            return
        dlg = ConvertCardTypeKeysDlg(self.card_type, new_card_type,
            self.correspondence, check_required_fact_keys=False, parent=self)
        if dlg.exec_() != QtGui.QDialog.Accepted:
            # Set correspondence so as not to erase previous data.
            self.correspondence = {}
            for key in self.card_type.fact_keys():
                self.correspondence[key] = key
            self.card_types_widget.setCurrentIndex(self.card_type_index)
            return
        else:
            self.update_card_widget()

    def preview(self):
        fact_data = self.card_type_widget.fact_data()
        fact = Fact(fact_data)
        cards = self.card_type.create_sister_cards(fact)
        tag_text = unicode(self.tags.currentText())
        dlg = PreviewCardsDlg(self.component_manager, cards, tag_text, self)
        dlg.exec_()

{'fraction_non_alphanumeric': 0.08017676767676768, 'fraction_numerical': 0.00202020202020202, 'mean_word_length': 2.613366788321168, 'pattern_counts': {'":': 4, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5553741', 'n_tokens_mistral': 4934, 'n_tokens_neox': 4790, 'n_words': 1115}