Mnemosyne-2.2.1/0000775000175000017500000000000012132772005014621 5ustar pbienstpbienst00000000000000Mnemosyne-2.2.1/mnemosyne/0000775000175000017500000000000012132772005016633 5ustar pbienstpbienst00000000000000Mnemosyne-2.2.1/mnemosyne/webserver/0000775000175000017500000000000012132772005020637 5ustar pbienstpbienst00000000000000Mnemosyne-2.2.1/mnemosyne/webserver/server.py0000644000175000017500000001144611765356020022531 0ustar pbienstpbienst00000000000000# # server.py # import os import cgi import socket import select import mimetypes from wsgiref.simple_server import WSGIServer, WSGIRequestHandler from mnemosyne.libmnemosyne import Mnemosyne # Avoid delays caused by Nagle's algorithm. # http://www.cmlenz.net/archives/2008/03/python-httplib-performance-problems realsocket = socket.socket def socketwrap(family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0): sockobj = realsocket(family, type, proto) sockobj.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) return sockobj socket.socket = socketwrap # Work around http://bugs.python.org/issue6085. def not_insane_address_string(self): host, port = self.client_address[:2] return "%s (no getfqdn)" % host WSGIRequestHandler.address_string = not_insane_address_string # Don't log (saves time on an embedded server). def dont_log(*kwargs): pass WSGIRequestHandler.log_message = dont_log class Server(WSGIServer): def __init__(self, port, data_dir, filename): WSGIServer.__init__(self, ("", port), WSGIRequestHandler) self.set_app(self.wsgi_app) self.stopped = False self.mnemosyne = Mnemosyne(upload_science_logs=True, interested_in_old_reps=True) self.mnemosyne.components.insert(0, ( ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator"))) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.main_widget", "MainWidget")) self.mnemosyne.components.append(\ ("mnemosyne.webserver.review_wdgt", "ReviewWdgt")) self.mnemosyne.components.append(\ ("mnemosyne.webserver.webserver_render_chain", "WebserverRenderChain")) self.mnemosyne.initialise(data_dir, filename, automatic_upgrades=False) self.mnemosyne.review_controller().set_render_chain("webserver") self.save_after_n_reps = self.mnemosyne.config()["save_after_n_reps"] self.mnemosyne.config()["save_after_n_reps"] = 1 self.mnemosyne.start_review() def serve_until_stopped(self): try: while not self.stopped: # We time out every 0.25 seconds, so that we changing # self.stopped can have an effect. if select.select([self.socket], [], [], 0.25)[0]: self.handle_request() finally: self.socket.close() self.mnemosyne.config()["save_after_n_reps"] = \ self.save_after_n_reps def stop(self): self.stopped = True def wsgi_app(self, environ, start_response): # All our request return to the root page, so if the path is '/', return # the html of the review widget. filename = environ["PATH_INFO"] if filename == "/": # Process clicked buttons in the form. form = cgi.FieldStorage(fp=environ["wsgi.input"], environ=environ) if "show_answer" in form: self.mnemosyne.review_widget().show_answer() if "grade" in form: grade = int(form["grade"].value) self.mnemosyne.review_widget().grade_answer(grade) # Serve the web page. response_headers = [("Content-type", "text/html")] start_response("200 OK", response_headers) return [self.mnemosyne.review_widget().to_html()] # We need to serve a media file. else: media_file = self.open_media_file(filename) if media_file is None: response_headers = [("Content-type", "text/html")] start_response("404 File not found", response_headers) return ["404 File not found"] else: response_headers = [("Content-type", self.guess_type(filename))] start_response("200 OK", response_headers) return [media_file.read()] def open_media_file(self, path): full_path = self.mnemosyne.database().media_dir() for word in path.split("/"): full_path = os.path.join(full_path, word) try: return file(full_path, "rb") except IOError: return None # Adapted from SimpleHTTPServer: def guess_type(self, path): base, ext = os.path.splitext(path) if ext in self.extensions_map: return self.extensions_map[ext] ext = ext.lower() if ext in self.extensions_map: return self.extensions_map[ext] else: return self.extensions_map[""] # Try to read system mimetypes. if not mimetypes.inited: mimetypes.init() extensions_map = mimetypes.types_map.copy() extensions_map.update({"": "application/octet-stream"}) # Default. Mnemosyne-2.2.1/mnemosyne/webserver/mnemosyne-webserver0000644000175000017500000000327112004450132024567 0ustar pbienstpbienst00000000000000#!/usr/bin/python # # mnemosyne_webserver # import os import socket from optparse import OptionParser port = 8513 # Hack to determine local IP. from openSM2sync.server import realsocket def localhost_IP(): s = realsocket(socket.AF_INET, socket.SOCK_DGRAM) s.connect(("google.com", 8000)) return s.getsockname()[0] # Parse options. parser = OptionParser() parser.usage = "%prog []" parser.add_option("-d", "--datadir", dest="data_dir", help="data directory", default=None) (options, args) = parser.parse_args() # Check if we have to override the data_dir determined in libmnemosyne, # either because we explicitly specified a data_dir on the command line, # or because there is a mnemosyne directory present in the current directory. # The latter is handy when Mnemosyne is run from a USB key, so that there # is no need to refer to a drive letter which can change from computer to # computer. data_dir = None if options.data_dir != None: data_dir = os.path.abspath(options.data_dir) elif os.path.exists(os.path.join(os.getcwdu(), "mnemosyne")) and \ os.path.isdir(os.path.join(os.getcwdu(), "mnemosyne")): data_dir = os.path.abspath(os.path.join(os.getcwdu(), "mnemosyne")) # Filename argument. if len(args) > 0: filename = os.path.abspath(args[0]) else: filename = None disclaimer = """Prototype of Mnemosyne web server. It works, but is not yet integrated in the desktop application, and has no security. """ print disclaimer print "Server listening on http://" + localhost_IP() + ":" + str(port) from mnemosyne.webserver.server import Server server = Server(port, data_dir, filename) server.serve_until_stopped() Mnemosyne-2.2.1/mnemosyne/webserver/webserver_renderer.py0000644000175000017500000000062711672612020025104 0ustar pbienstpbienst00000000000000# # webserver_renderer.py # from mnemosyne.libmnemosyne.renderers.html_css import HtmlCss class WebserverRenderer(HtmlCss): """Renders the question or the answer as html, to be embedded in another webpage. """ def render(self, fact_data, fact_keys, card_type, **render_args): return self.body(fact_data, fact_keys, card_type, **render_args) Mnemosyne-2.2.1/mnemosyne/webserver/webserver_render_chain.py0000644000175000017500000000137011765316435025731 0ustar pbienstpbienst00000000000000# # webserver_render_chain.py # from mnemosyne.libmnemosyne.filters.latex import Latex from mnemosyne.libmnemosyne.render_chain import RenderChain from mnemosyne.libmnemosyne.filters.html5_audio import Html5Audio from mnemosyne.libmnemosyne.filters.html5_video import Html5Video from mnemosyne.webserver.webserver_renderer import WebserverRenderer from mnemosyne.libmnemosyne.filters.escape_to_html import EscapeToHtml from mnemosyne.libmnemosyne.filters.non_latin_font_size_increase import \ NonLatinFontSizeIncrease class WebserverRenderChain(RenderChain): id = "webserver" filters = [Latex, EscapeToHtml, Html5Audio, Html5Video, NonLatinFontSizeIncrease] renderers = [WebserverRenderer] Mnemosyne-2.2.1/mnemosyne/webserver/review_wdgt.py0000644000175000017500000001102611765360102023537 0ustar pbienstpbienst00000000000000# # review_wdgt.py # import os from string import Template from mnemosyne.libmnemosyne.translator import _ from mnemosyne.libmnemosyne.ui_components.review_widget import ReviewWidget class ReviewWdgt(ReviewWidget): """I've tried fiddling with css to get the grades area always show up at the bottom of the screen, no matter the contents of the cards, but I never got this to work satisfactory both on Firefox and IE. There would always be issues with spurious scrollbars or the card areas not expanding to fill the entire screen. Therefore, we place the grades at the top, where they are also always at the same location for easy ergonomic access. """ def __init__(self, component_manager): ReviewWidget.__init__(self, component_manager) self.question_label = "" self.question = "" self.is_question_box_visible = True self.answer = "" self.answer_label = _("Answer:") self.is_answer_box_visible = True self.show_button = "" self.is_show_button_enabled = True self.is_grade_buttons_enabled = False self.status_bar = "" self.template = Template(""" Mnemosyne $buttons

$question_label

$question

$answer_label

$answer

$status_bar

""") def redraw_now(self): pass def show_answer(self): self.review_controller().show_answer() def grade_answer(self, grade): self.review_controller().grade_answer(grade) def set_question_box_visible(self, is_visible): self.is_question_box_visible = is_visible def set_answer_box_visible(self, is_visible): self.is_answer_box_visible = is_visible def set_question_label(self, text): self.question_label = text def set_question(self, text): self.question = text def set_answer(self, text): self.answer = text def clear_question(self): self.question = "" def clear_answer(self): self.answer = "" def update_show_button(self, text, is_default, is_enabled): self.show_button = text self.is_show_button_enabled = is_enabled def set_grades_enabled(self, is_enabled): self.is_grade_buttons_enabled = is_enabled def set_default_grade(self, grade): pass def update_status_bar_counters(self): scheduled_count, non_memorised_count, active_count = \ self.review_controller().counters() self.status_bar = "Sch.: %d Not mem.: %d Act.: %d" % \ (scheduled_count, non_memorised_count, active_count) def to_html(self): self.controller().heartbeat() card_css = "" card = self.review_controller().card if card: card_css = self.render_chain().\ renderer_for_card_type(card.card_type).card_type_css(card.card_type) buttons = "" if self.is_grade_buttons_enabled: buttons = "" for i in range(6): buttons += """
""" % (i, i) if self.is_show_button_enabled: buttons = """
""" % (self.show_button) if not self.question: self.question = " " # For esthetic reasons. if not self.answer: self.answer = " " return self.template.substitute(card_css=card_css, buttons=buttons, question_label=self.question_label, question=self.question, answer_label=self.answer_label, answer=self.answer, status_bar=self.status_bar).encode("utf-8") Mnemosyne-2.2.1/mnemosyne/webserver/__init__.py0000644000175000017500000000000011473002722022733 0ustar pbienstpbienst00000000000000Mnemosyne-2.2.1/mnemosyne/script/0000775000175000017500000000000012132772005020137 5ustar pbienstpbienst00000000000000Mnemosyne-2.2.1/mnemosyne/script/__init__.py0000664000175000017500000000243012007537650022255 0ustar pbienstpbienst00000000000000# # script # from mnemosyne.libmnemosyne import Mnemosyne as MnemosyneParent from mnemosyne.libmnemosyne.ui_components.main_widget import MainWidget from mnemosyne.libmnemosyne.ui_components.review_widget import ReviewWidget class ScriptReviewWidget(ReviewWidget): def redraw_now(self): pass class ScriptMainWidget(MainWidget): def __init__(self, component_manager): self.q_and_a = None def show_question(self, question, option0, option1, option2): print question, option0, option1, option2 if self.q_and_a is not None: for q, a in self.q_and_a.iteritems(): if question.startswith(q): return a raise NotImplementedError class Mnemosyne(MnemosyneParent): def __init__(self, data_dir=None): MnemosyneParent.__init__(self, upload_science_logs=False, interested_in_old_reps=True) self.components.insert(0, ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator")) self.components.append(\ ("mnemosyne.script", "ScriptMainWidget")) self.components.append(\ ("mnemosyne.script", "ScriptReviewWidget")) self.initialise(data_dir) Mnemosyne-2.2.1/mnemosyne/pyqt_ui/0000775000175000017500000000000012132772005020325 5ustar pbienstpbienst00000000000000Mnemosyne-2.2.1/mnemosyne/pyqt_ui/configuration_wdgt_cramming.py0000644000175000017500000000441512037215254026454 0ustar pbienstpbienst00000000000000# # configuration_wdgt_cramming.py # from PyQt4 import QtCore, QtGui from mnemosyne.libmnemosyne.translator import _ from mnemosyne.libmnemosyne.ui_components.configuration_widget import \ ConfigurationWidget from mnemosyne.pyqt_ui.ui_configuration_wdgt_cramming import \ Ui_ConfigurationWdgtCramming from mnemosyne.libmnemosyne.schedulers.cramming import RANDOM, \ EARLIEST_FIRST, LATEST_FIRST, MOST_LAPSES_FIRST class ConfigurationWdgtCramming(QtGui.QWidget, Ui_ConfigurationWdgtCramming, ConfigurationWidget): name = _("Cramming") def __init__(self, component_manager, parent): ConfigurationWidget.__init__(self, component_manager) QtGui.QDialog.__init__(self, parent) self.setupUi(self) if self.config()["cramming_order"] == RANDOM: self.order.setCurrentIndex(0) elif self.config()["cramming_order"] == EARLIEST_FIRST: self.order.setCurrentIndex(1) elif self.config()["cramming_order"] == LATEST_FIRST: self.order.setCurrentIndex(2) elif self.config()["cramming_order"] == MOST_LAPSES_FIRST: self.order.setCurrentIndex(3) if self.config()["cramming_store_state"] == True: self.store_state.setCheckState(QtCore.Qt.Checked) else: self.store_state.setCheckState(QtCore.Qt.Unchecked) def reset_to_defaults(self): answer = self.main_widget().show_question(\ _("Reset current tab to defaults?"), _("&Yes"), _("&No"), "") if answer == 1: return self.order.setCurrentIndex(0) self.store_state.setCheckState(QtCore.Qt.Checked) def apply(self): if self.order.currentIndex() == 0: self.config()["cramming_order"] = RANDOM elif self.order.currentIndex() == 1: self.config()["cramming_order"] = EARLIEST_FIRST elif self.order.currentIndex() == 2: self.config()["cramming_order"] = LATEST_FIRST elif self.order.currentIndex() == 3: self.config()["cramming_order"] = MOST_LAPSES_FIRST if self.store_state.checkState() == QtCore.Qt.Checked: self.config()["cramming_store_state"] = True else: self.config()["cramming_store_state"] = False Mnemosyne-2.2.1/mnemosyne/pyqt_ui/qwebview2.py0000644000175000017500000000152112064301010022573 0ustar pbienstpbienst00000000000000# # qwebview2.py # from PyQt4 import QtWebKit, QtGui from mnemosyne.libmnemosyne.translator import _ class QWebView2(QtWebKit.QWebView): """QWebView which restores the focus to the review widget, so that the keyboard shortcuts still continue to work. """ def focusInEvent(self, event): if hasattr(self.parent(), "restore_focus"): self.parent().restore_focus() QtWebKit.QWebView.focusInEvent(self, event) def contextMenuEvent(self, event): menu = QtGui.QMenu(self) action = self.pageAction(QtWebKit.QWebPage.Copy) # Note that to get the shortcut work, we need extra code in # review_wdgt.py. action.setShortcuts(QtGui.QKeySequence(_("Ctrl+C"))) menu.addAction(action) menu.exec_(self.mapToGlobal(event.pos())) Mnemosyne-2.2.1/mnemosyne/pyqt_ui/edit_card_dlg.py0000644000175000017500000001546612113344732023456 0ustar pbienstpbienst00000000000000# # edit_card_dlg.py # from PyQt4 import QtCore, QtGui from mnemosyne.libmnemosyne.translator import _ from mnemosyne.pyqt_ui.add_cards_dlg import AddEditCards from mnemosyne.pyqt_ui.ui_edit_card_dlg import Ui_EditCardDlg from mnemosyne.libmnemosyne.ui_components.dialogs import EditCardDialog class EditCardDlg(QtGui.QDialog, Ui_EditCardDlg, AddEditCards, EditCardDialog): page_up_down_signal = QtCore.pyqtSignal(int) UP = 0 DOWN = 1 def eventFilter(self, object, event): if event.type() == QtCore.QEvent.KeyPress: if event.key() == QtCore.Qt.Key_PageUp: self.page_up_down_signal.emit(self.UP) return True elif event.key() == QtCore.Qt.Key_PageDown: self.page_up_down_signal.emit(self.DOWN) return True else: return False return False def __init__(self, card, component_manager, allow_cancel=True, started_from_card_browser=False, parent=None): # Note: even though this is in essence an EditFactDlg, we don't use # 'fact' as argument, as 'fact' does not know anything about card # types. AddEditCards.__init__(self, component_manager) if parent is None: parent = self.main_widget() QtGui.QDialog.__init__(self, parent) self.setupUi(self) self.setWindowFlags(self.windowFlags() \ | QtCore.Qt.WindowMinMaxButtonsHint) self.setWindowFlags(self.windowFlags() \ & ~ QtCore.Qt.WindowContextHelpButtonHint) self.started_from_card_browser = started_from_card_browser self.before_apply_hook = None self.allow_cancel = allow_cancel if not allow_cancel: self.exit_button.setVisible(False) self.card = card self.initialise_card_types_combobox(_(self.card.card_type.name)) self.update_tags_combobox(self.card.tag_string()) state = self.config()["edit_card_dlg_state"] if state: self.restoreGeometry(state) # Make sure we can capture PageUp/PageDown keys before any of the # children (e.g. comboboxes) do so. if self.started_from_card_browser: for child in self.children(): child.installEventFilter(self) def update_card_widget(self, keep_data_from_previous_widget=True): AddEditCards.update_card_widget(self, keep_data_from_previous_widget) # Install event filters if we need to capture PageUp/PageDown. if self.started_from_card_browser: for child in self.card_type_widget.children(): # Make sure we don't install the filter twice. child.removeEventFilter(self) child.installEventFilter(self) def set_new_card(self, card): # Called from card browser. self.card = card self.card_types_widget.currentIndexChanged[QtCore.QString].\ disconnect(self.card_type_changed) for i in range(self.card_types_widget.count()): if unicode(self.card_types_widget.itemText(i)) \ == _(card.card_type.name): self.card_types_widget.setCurrentIndex(i) break self.card_types_widget.currentIndexChanged[QtCore.QString].\ connect(self.card_type_changed) self.update_card_widget(keep_data_from_previous_widget=False) self.update_tags_combobox(self.card.tag_string()) def _store_state(self): self.config()["edit_card_dlg_state"] = self.saveGeometry() def closeEvent(self, event): # Generated when clicking the window's close button. self._store_state() if self.allow_cancel: event.ignore() self.reject() else: self.main_widget().show_information(\ _("You are not allowed to cancel the merging.")) event.ignore() def keyPressEvent(self, event): # Note: for the following to work reliably, there should be no # shortcuts defined in the ui file. if event.key() == QtCore.Qt.Key_Escape or (event.modifiers() in \ [QtCore.Qt.ControlModifier, QtCore.Qt.AltModifier] and \ event.key() == QtCore.Qt.Key_E): if self.allow_cancel: self.reject() else: self.main_widget().show_information(\ _("You are not allowed to cancel the merging.")) event.ignore() elif self.OK_button.isEnabled() and event.modifiers() in \ [QtCore.Qt.ControlModifier, QtCore.Qt.AltModifier]: if event.key() in [QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return, QtCore.Qt.Key_O]: self.accept() elif event.key() == QtCore.Qt.Key_P: self.preview() else: QtGui.QDialog.keyPressEvent(self, event) def set_valid(self, valid): self.OK_button.setEnabled(valid) self.preview_button.setEnabled(valid) def accept(self): self._store_state() new_fact_data = self.card_type_widget.fact_data() new_tag_names = [tag.strip() for tag in \ unicode(self.tags.currentText()).split(',')] new_card_type_name = unicode(self.card_types_widget.currentText()) new_card_type = self.card_type_by_name[new_card_type_name] if new_fact_data == self.card.fact.data and \ ", ".join(new_tag_names) == self.card.tag_string() and \ new_card_type == self.card.card_type: # No need to update the dialog. QtGui.QDialog.reject(self) return if self.before_apply_hook: self.before_apply_hook() status = self.controller().edit_sister_cards(self.card.fact, new_fact_data, self.card.card_type, new_card_type, new_tag_names, self.correspondence) if status == 0: tag_text = ", ".join(new_tag_names) self.config()["last_used_tags_for_card_type_id"][new_card_type.id] \ = tag_text self.config()["edit_widget_size"] = (self.width(), self.height()) QtGui.QDialog.accept(self) def reject(self): # Override 'add cards' behaviour. changed = False for fact_key in self.card.fact.data: if fact_key in self.card_type_widget.fact_data() and \ self.card_type_widget.fact_data()[fact_key] \ != self.card.fact.data[fact_key]: changed = True break if changed: status = self.main_widget().show_question(\ _("Abandon changes to current card?"), _("&Yes"), _("&No"), "") if status == 0: QtGui.QDialog.reject(self) return else: QtGui.QDialog.reject(self) Mnemosyne-2.2.1/mnemosyne/pyqt_ui/statistics_wdgt_html.py0000644000175000017500000000126311647561074025156 0ustar pbienstpbienst00000000000000# # statistics_wdgt_html.py # from PyQt4 import QtCore, QtWebKit from mnemosyne.libmnemosyne.statistics_page import HtmlStatisticsPage from mnemosyne.libmnemosyne.ui_components.statistics_widget import \ StatisticsWidget class HtmlStatisticsWdgt(QtWebKit.QWebView, StatisticsWidget): used_for = HtmlStatisticsPage def __init__(self, component_manager, parent, page): StatisticsWidget.__init__(self, component_manager) QtWebKit.QWebView.__init__(self, parent) self.page = page def sizeHint(self): return QtCore.QSize(400, 320) def show_statistics(self, variant): self.setHtml(self.page.html) Mnemosyne-2.2.1/mnemosyne/pyqt_ui/ui_configuration_wdgt_card_appearance.py0000644000175000000000000002103312132771333027742 0ustar pbienstroot00000000000000# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'configuration_wdgt_card_appearance.ui' # # Created: Mon Apr 15 14:30:19 2013 # by: PyQt4 UI code generator 4.9.3 # # WARNING! All changes made in this file will be lost! from mnemosyne.libmnemosyne.translator import _ from PyQt4 import QtCore, QtGui try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: _fromUtf8 = lambda s: s class Ui_ConfigurationWdgtCardAppearance(object): def setupUi(self, ConfigurationWdgtCardAppearance): ConfigurationWdgtCardAppearance.setObjectName(_fromUtf8("ConfigurationWdgtCardAppearance")) ConfigurationWdgtCardAppearance.resize(374, 256) self.verticalLayout_2 = QtGui.QVBoxLayout(ConfigurationWdgtCardAppearance) self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2")) self.verticalLayout = QtGui.QVBoxLayout() self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) self.horizontalLayout = QtGui.QHBoxLayout() self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout")) self.label_2 = QtGui.QLabel(ConfigurationWdgtCardAppearance) self.label_2.setObjectName(_fromUtf8("label_2")) self.horizontalLayout.addWidget(self.label_2) self.card_types_widget = QtGui.QComboBox(ConfigurationWdgtCardAppearance) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.card_types_widget.sizePolicy().hasHeightForWidth()) self.card_types_widget.setSizePolicy(sizePolicy) self.card_types_widget.setObjectName(_fromUtf8("card_types_widget")) self.horizontalLayout.addWidget(self.card_types_widget) self.verticalLayout.addLayout(self.horizontalLayout) self.line_4 = QtGui.QFrame(ConfigurationWdgtCardAppearance) self.line_4.setFrameShape(QtGui.QFrame.HLine) self.line_4.setFrameShadow(QtGui.QFrame.Sunken) self.line_4.setObjectName(_fromUtf8("line_4")) self.verticalLayout.addWidget(self.line_4) self.gridLayout = QtGui.QGridLayout() self.gridLayout.setObjectName(_fromUtf8("gridLayout")) spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.gridLayout.addItem(spacerItem, 0, 0, 1, 1) spacerItem1 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.gridLayout.addItem(spacerItem1, 0, 1, 1, 1) spacerItem2 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.gridLayout.addItem(spacerItem2, 0, 2, 1, 1) self.verticalLayout.addLayout(self.gridLayout) self.line = QtGui.QFrame(ConfigurationWdgtCardAppearance) self.line.setFrameShape(QtGui.QFrame.HLine) self.line.setFrameShadow(QtGui.QFrame.Sunken) self.line.setObjectName(_fromUtf8("line")) self.verticalLayout.addWidget(self.line) self.horizontal_layout_bg_colour = QtGui.QHBoxLayout() self.horizontal_layout_bg_colour.setObjectName(_fromUtf8("horizontal_layout_bg_colour")) self.bg_label = QtGui.QLabel(ConfigurationWdgtCardAppearance) self.bg_label.setObjectName(_fromUtf8("bg_label")) self.horizontal_layout_bg_colour.addWidget(self.bg_label) self.background_button = QtGui.QPushButton(ConfigurationWdgtCardAppearance) self.background_button.setObjectName(_fromUtf8("background_button")) self.horizontal_layout_bg_colour.addWidget(self.background_button) spacerItem3 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.horizontal_layout_bg_colour.addItem(spacerItem3) self.align_label = QtGui.QLabel(ConfigurationWdgtCardAppearance) self.align_label.setObjectName(_fromUtf8("align_label")) self.horizontal_layout_bg_colour.addWidget(self.align_label) self.alignment = QtGui.QComboBox(ConfigurationWdgtCardAppearance) font = QtGui.QFont() font.setItalic(False) self.alignment.setFont(font) self.alignment.setObjectName(_fromUtf8("alignment")) self.alignment.addItem(_fromUtf8("")) self.alignment.addItem(_fromUtf8("")) self.alignment.addItem(_fromUtf8("")) self.horizontal_layout_bg_colour.addWidget(self.alignment) self.verticalLayout.addLayout(self.horizontal_layout_bg_colour) self.line_non_latin = QtGui.QFrame(ConfigurationWdgtCardAppearance) self.line_non_latin.setFrameShape(QtGui.QFrame.HLine) self.line_non_latin.setFrameShadow(QtGui.QFrame.Sunken) self.line_non_latin.setObjectName(_fromUtf8("line_non_latin")) self.verticalLayout.addWidget(self.line_non_latin) self.non_latin_layout = QtGui.QHBoxLayout() self.non_latin_layout.setObjectName(_fromUtf8("non_latin_layout")) self.label_non_latin_1 = QtGui.QLabel(ConfigurationWdgtCardAppearance) self.label_non_latin_1.setObjectName(_fromUtf8("label_non_latin_1")) self.non_latin_layout.addWidget(self.label_non_latin_1) self.non_latin_font_size_increase = QtGui.QSpinBox(ConfigurationWdgtCardAppearance) self.non_latin_font_size_increase.setObjectName(_fromUtf8("non_latin_font_size_increase")) self.non_latin_layout.addWidget(self.non_latin_font_size_increase) self.label_non_latin_2 = QtGui.QLabel(ConfigurationWdgtCardAppearance) self.label_non_latin_2.setObjectName(_fromUtf8("label_non_latin_2")) self.non_latin_layout.addWidget(self.label_non_latin_2) spacerItem4 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.non_latin_layout.addItem(spacerItem4) self.verticalLayout.addLayout(self.non_latin_layout) self.label_non_latin_3 = QtGui.QLabel(ConfigurationWdgtCardAppearance) self.label_non_latin_3.setWordWrap(True) self.label_non_latin_3.setObjectName(_fromUtf8("label_non_latin_3")) self.verticalLayout.addWidget(self.label_non_latin_3) spacerItem5 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) self.verticalLayout.addItem(spacerItem5) self.horizontalLayout_5 = QtGui.QHBoxLayout() self.horizontalLayout_5.setObjectName(_fromUtf8("horizontalLayout_5")) spacerItem6 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.horizontalLayout_5.addItem(spacerItem6) self.preview_button = QtGui.QPushButton(ConfigurationWdgtCardAppearance) self.preview_button.setAutoDefault(False) self.preview_button.setObjectName(_fromUtf8("preview_button")) self.horizontalLayout_5.addWidget(self.preview_button) spacerItem7 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.horizontalLayout_5.addItem(spacerItem7) self.verticalLayout.addLayout(self.horizontalLayout_5) self.verticalLayout_2.addLayout(self.verticalLayout) self.retranslateUi(ConfigurationWdgtCardAppearance) QtCore.QObject.connect(self.preview_button, QtCore.SIGNAL(_fromUtf8("clicked()")), ConfigurationWdgtCardAppearance.preview) QtCore.QObject.connect(self.card_types_widget, QtCore.SIGNAL(_fromUtf8("currentIndexChanged(QString)")), ConfigurationWdgtCardAppearance.card_type_changed) QtCore.QObject.connect(self.background_button, QtCore.SIGNAL(_fromUtf8("clicked()")), ConfigurationWdgtCardAppearance.update_background_colour) QtCore.QObject.connect(self.alignment, QtCore.SIGNAL(_fromUtf8("activated(int)")), ConfigurationWdgtCardAppearance.update_alignment) QtCore.QMetaObject.connectSlotsByName(ConfigurationWdgtCardAppearance) def retranslateUi(self, ConfigurationWdgtCardAppearance): ConfigurationWdgtCardAppearance.setWindowTitle(_('Form')) self.label_2.setText(_('Card type:')) self.bg_label.setText(_('Background:')) self.background_button.setText(_('Set colour')) self.align_label.setText(_('Alignment:')) self.alignment.setItemText(0, _('Left')) self.alignment.setItemText(1, _('Center')) self.alignment.setItemText(2, _('Right')) self.label_non_latin_1.setText(_('Increase size of non-latin characters by')) self.label_non_latin_2.setText(_('points.')) self.label_non_latin_3.setText(_('(This setting will be overridden in card types cloned from \'Vocabulary\'.)')) self.preview_button.setText(_('&Preview')) Mnemosyne-2.2.1/mnemosyne/pyqt_ui/ui_manage_card_types_dlg.py0000644000175000000000000000636712132771332025205 0ustar pbienstroot00000000000000# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'manage_card_types_dlg.ui' # # Created: Mon Apr 15 14:30:18 2013 # by: PyQt4 UI code generator 4.9.3 # # WARNING! All changes made in this file will be lost! from mnemosyne.libmnemosyne.translator import _ from PyQt4 import QtCore, QtGui try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: _fromUtf8 = lambda s: s class Ui_ManageCardTypesDlg(object): def setupUi(self, ManageCardTypesDlg): ManageCardTypesDlg.setObjectName(_fromUtf8("ManageCardTypesDlg")) ManageCardTypesDlg.resize(352, 245) ManageCardTypesDlg.setMinimumSize(QtCore.QSize(300, 240)) self.verticalLayout_2 = QtGui.QVBoxLayout(ManageCardTypesDlg) self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2")) self.verticalLayout = QtGui.QVBoxLayout() self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) self.label_2 = QtGui.QLabel(ManageCardTypesDlg) self.label_2.setObjectName(_fromUtf8("label_2")) self.verticalLayout.addWidget(self.label_2) self.cloned_card_types = QtGui.QListWidget(ManageCardTypesDlg) self.cloned_card_types.setObjectName(_fromUtf8("cloned_card_types")) self.verticalLayout.addWidget(self.cloned_card_types) self.horizontalLayout = QtGui.QHBoxLayout() self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout")) self.clone_button = QtGui.QPushButton(ManageCardTypesDlg) self.clone_button.setObjectName(_fromUtf8("clone_button")) self.horizontalLayout.addWidget(self.clone_button) self.rename_button = QtGui.QPushButton(ManageCardTypesDlg) self.rename_button.setObjectName(_fromUtf8("rename_button")) self.horizontalLayout.addWidget(self.rename_button) self.delete_button = QtGui.QPushButton(ManageCardTypesDlg) self.delete_button.setObjectName(_fromUtf8("delete_button")) self.horizontalLayout.addWidget(self.delete_button) self.exit_button = QtGui.QPushButton(ManageCardTypesDlg) self.exit_button.setObjectName(_fromUtf8("exit_button")) self.horizontalLayout.addWidget(self.exit_button) self.verticalLayout.addLayout(self.horizontalLayout) self.verticalLayout_2.addLayout(self.verticalLayout) self.retranslateUi(ManageCardTypesDlg) QtCore.QObject.connect(self.exit_button, QtCore.SIGNAL(_fromUtf8("clicked()")), ManageCardTypesDlg.reject) QtCore.QObject.connect(self.clone_button, QtCore.SIGNAL(_fromUtf8("clicked()")), ManageCardTypesDlg.clone_card_type) QtCore.QObject.connect(self.delete_button, QtCore.SIGNAL(_fromUtf8("clicked()")), ManageCardTypesDlg.delete_card_type) QtCore.QObject.connect(self.rename_button, QtCore.SIGNAL(_fromUtf8("clicked()")), ManageCardTypesDlg.rename_card_type) QtCore.QMetaObject.connectSlotsByName(ManageCardTypesDlg) def retranslateUi(self, ManageCardTypesDlg): ManageCardTypesDlg.setWindowTitle(_('Card type manager')) self.label_2.setText(_('Cloned card types:')) self.clone_button.setText(_('&New clone')) self.rename_button.setText(_('&Rename')) self.delete_button.setText(_('&Delete')) self.exit_button.setText(_('E&xit')) Mnemosyne-2.2.1/mnemosyne/pyqt_ui/ui_preview_cards_dlg.py0000644000175000000000000001213312132771340024360 0ustar pbienstroot00000000000000# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'preview_cards_dlg.ui' # # Created: Mon Apr 15 14:30:24 2013 # by: PyQt4 UI code generator 4.9.3 # # WARNING! All changes made in this file will be lost! from mnemosyne.libmnemosyne.translator import _ from qwebview2 import * from qpushbutton2 import * from PyQt4 import QtCore, QtGui try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: _fromUtf8 = lambda s: s class Ui_PreviewCardsDlg(object): def setupUi(self, PreviewCardsDlg): PreviewCardsDlg.setObjectName(_fromUtf8("PreviewCardsDlg")) PreviewCardsDlg.resize(369, 332) self.verticalLayout_4 = QtGui.QVBoxLayout(PreviewCardsDlg) self.verticalLayout_4.setObjectName(_fromUtf8("verticalLayout_4")) self.vertical_layout = QtGui.QVBoxLayout() self.vertical_layout.setObjectName(_fromUtf8("vertical_layout")) self.fact_view_name = QtGui.QLabel(PreviewCardsDlg) font = QtGui.QFont() font.setBold(True) font.setWeight(75) self.fact_view_name.setFont(font) self.fact_view_name.setText(_fromUtf8("")) self.fact_view_name.setObjectName(_fromUtf8("fact_view_name")) self.vertical_layout.addWidget(self.fact_view_name) self.question_box = QtGui.QVBoxLayout() self.question_box.setObjectName(_fromUtf8("question_box")) self.question_label = QtGui.QLabel(PreviewCardsDlg) self.question_label.setMaximumSize(QtCore.QSize(320, 16777215)) self.question_label.setObjectName(_fromUtf8("question_label")) self.question_box.addWidget(self.question_label) self.question = QWebView2(PreviewCardsDlg) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.question.sizePolicy().hasHeightForWidth()) self.question.setSizePolicy(sizePolicy) self.question.setMinimumSize(QtCore.QSize(295, 50)) self.question.setAcceptDrops(False) self.question.setUrl(QtCore.QUrl(_fromUtf8("about:blank"))) self.question.setObjectName(_fromUtf8("question")) self.question_box.addWidget(self.question) self.vertical_layout.addLayout(self.question_box) self.answer_box = QtGui.QVBoxLayout() self.answer_box.setObjectName(_fromUtf8("answer_box")) self.answer_label = QtGui.QLabel(PreviewCardsDlg) self.answer_label.setObjectName(_fromUtf8("answer_label")) self.answer_box.addWidget(self.answer_label) self.answer = QWebView2(PreviewCardsDlg) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.answer.sizePolicy().hasHeightForWidth()) self.answer.setSizePolicy(sizePolicy) self.answer.setMinimumSize(QtCore.QSize(295, 50)) self.answer.setAcceptDrops(False) self.answer.setUrl(QtCore.QUrl(_fromUtf8("about:blank"))) self.answer.setObjectName(_fromUtf8("answer")) self.answer_box.addWidget(self.answer) self.vertical_layout.addLayout(self.answer_box) self.horizontalLayout = QtGui.QHBoxLayout() self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout")) self.previous_button = QPushButton2(PreviewCardsDlg) self.previous_button.setObjectName(_fromUtf8("previous_button")) self.horizontalLayout.addWidget(self.previous_button) self.next_button = QPushButton2(PreviewCardsDlg) self.next_button.setObjectName(_fromUtf8("next_button")) self.horizontalLayout.addWidget(self.next_button) spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.horizontalLayout.addItem(spacerItem) self.OK_button = QPushButton2(PreviewCardsDlg) self.OK_button.setAutoDefault(True) self.OK_button.setDefault(True) self.OK_button.setObjectName(_fromUtf8("OK_button")) self.horizontalLayout.addWidget(self.OK_button) self.vertical_layout.addLayout(self.horizontalLayout) self.verticalLayout_4.addLayout(self.vertical_layout) self.retranslateUi(PreviewCardsDlg) QtCore.QObject.connect(self.previous_button, QtCore.SIGNAL(_fromUtf8("clicked()")), PreviewCardsDlg.previous) QtCore.QObject.connect(self.next_button, QtCore.SIGNAL(_fromUtf8("clicked()")), PreviewCardsDlg.next) QtCore.QObject.connect(self.OK_button, QtCore.SIGNAL(_fromUtf8("clicked()")), PreviewCardsDlg.close) QtCore.QMetaObject.connectSlotsByName(PreviewCardsDlg) def retranslateUi(self, PreviewCardsDlg): PreviewCardsDlg.setWindowTitle(_('Preview cards')) self.question_label.setText(_('Question:')) self.answer_label.setText(_('Answer:')) self.previous_button.setText(_('&Previous sister card')) self.next_button.setText(_('&Next sister card')) self.OK_button.setText(_('&OK')) from PyQt4 import QtWebKit Mnemosyne-2.2.1/mnemosyne/pyqt_ui/mnemosyne0000755000175000017500000001605112061600643022265 0ustar pbienstpbienst00000000000000#!/usr/bin/python # # Mnemosyne # import os import sys # Custom error handling on Windows. if sys.platform == "win32": import ctypes class Stderr(object): # Note: it would be nice to queue the messages and display them # using atexit, but but atexit does not seem to run. def write(self, text): if text.strip(): MessageBox = ctypes.windll.user32.MessageBoxA MessageBox(None, text, "Mnemosyne", 0) sys.stderr = Stderr() from optparse import OptionParser from PyQt4.QtGui import QApplication from mnemosyne.libmnemosyne import Mnemosyne # Parse options. parser = OptionParser() parser.usage = "%prog []" parser.add_option("-d", "--datadir", dest="data_dir", help="data directory", default=None) parser.add_option("--no-upgrades", dest="automatic_upgrades", action="store_false", help="do not upgrade automatically", default=True) parser.add_option("--debug", dest="debug_file", help="log debug information to FILE", metavar="FILE", default=None) (options, args) = parser.parse_args() # Check if we have to override the data_dir determined in libmnemosyne, # either because we explicitly specified a data_dir on the command line, # or because there is a mnemosyne directory present in the current directory. # The latter is handy when Mnemosyne is run from a USB key, so that there # is no need to refer to a drive letter which can change from computer to # computer. data_dir = None if options.data_dir != None: data_dir = os.path.abspath(options.data_dir) elif os.path.exists(os.path.join(os.getcwdu(), "mnemosyne")) and \ os.path.isdir(os.path.join(os.getcwdu(), "mnemosyne")): data_dir = os.path.abspath(os.path.join(os.getcwdu(), "mnemosyne")) # Filename argument. if len(args) > 0: filename = os.path.abspath(args[0]) else: filename = None # Load the Mnemosyne library. mnemosyne = Mnemosyne(upload_science_logs=True, interested_in_old_reps=True) # Initialise GUI toolkit. a = QApplication(sys.argv) a.setApplicationName("Mnemosyne") # Add other components we need. The translator should come first. # The UI components should come in the order they should be instantiated, # but apart from that, the order does not matter. mnemosyne.components.insert(0, ("mnemosyne.pyqt_ui.qt_translator", "QtTranslator")) mnemosyne.components.append(("mnemosyne.pyqt_ui.main_wdgt", "MainWdgt")) mnemosyne.components.append(("mnemosyne.pyqt_ui.review_wdgt", "ReviewWdgt")) mnemosyne.components.append(("mnemosyne.pyqt_ui.configuration", "PyQtConfiguration")) mnemosyne.components.append(("mnemosyne.pyqt_ui.pyqt_render_chain", "PyQtRenderChain")) mnemosyne.components.append(("mnemosyne.pyqt_ui.compact_database_dlg", "CompactDatabaseDlg")) mnemosyne.components.append(("mnemosyne.pyqt_ui.add_cards_dlg", "AddCardsDlg")) mnemosyne.components.append(("mnemosyne.pyqt_ui.edit_card_dlg", "EditCardDlg")) mnemosyne.components.append(("mnemosyne.pyqt_ui.browse_cards_dlg", "BrowseCardsDlg")) mnemosyne.components.append(("mnemosyne.pyqt_ui.activate_cards_dlg", "ActivateCardsDlg")) mnemosyne.components.append(("mnemosyne.pyqt_ui.manage_card_types_dlg", "ManageCardTypesDlg")) mnemosyne.components.append(("mnemosyne.pyqt_ui.manage_plugins_dlg", "ManagePluginsDlg")) mnemosyne.components.append(("mnemosyne.pyqt_ui.statistics_dlg", "StatisticsDlg")) mnemosyne.components.append(("mnemosyne.pyqt_ui.card_type_wdgt_generic", "GenericCardTypeWdgt")) mnemosyne.components.append(("mnemosyne.pyqt_ui.statistics_wdgts_plotting", "ScheduleWdgt")) mnemosyne.components.append(("mnemosyne.pyqt_ui.statistics_wdgts_plotting", "RetentionScoreWdgt")) mnemosyne.components.append(("mnemosyne.pyqt_ui.statistics_wdgts_plotting", "GradesWdgt")) mnemosyne.components.append(("mnemosyne.pyqt_ui.statistics_wdgts_plotting", "EasinessWdgt")) mnemosyne.components.append(("mnemosyne.pyqt_ui.statistics_wdgts_plotting", "CardsAddedWdgt")) mnemosyne.components.append(("mnemosyne.pyqt_ui.statistics_wdgt_html", "HtmlStatisticsWdgt")) mnemosyne.components.append(("mnemosyne.pyqt_ui.criterion_wdgt_default", "DefaultCriterionWdgt")) mnemosyne.components.append(("mnemosyne.pyqt_ui.configuration_dlg", "ConfigurationDlg")) mnemosyne.components.append(("mnemosyne.pyqt_ui.sync_dlg", "SyncDlg")) mnemosyne.components.append(("mnemosyne.pyqt_ui.qt_sync_server", "QtSyncServer")) mnemosyne.components.append(("mnemosyne.pyqt_ui.configuration_wdgt_main", "ConfigurationWdgtMain")) mnemosyne.components.append(("mnemosyne.pyqt_ui.configuration_wdgt_card_appearance", "ConfigurationWdgtCardAppearance")) mnemosyne.components.append(("mnemosyne.pyqt_ui.configuration_wdgt_sync_server", "ConfigurationWdgtSyncServer")) mnemosyne.components.append(("mnemosyne.pyqt_ui.getting_started_dlg", "GettingStartedDlg")) mnemosyne.components.append(("mnemosyne.pyqt_ui.tip_dlg", "TipDlg")) mnemosyne.components.append(("mnemosyne.pyqt_ui.about_dlg", "AboutDlg")) mnemosyne.components.append(("mnemosyne.pyqt_ui.import_dlg", "ImportDlg")) mnemosyne.components.append(("mnemosyne.pyqt_ui.export_dlg", "ExportDlg")) mnemosyne.components.append(("mnemosyne.pyqt_ui.export_metadata_dlg", "ExportMetadataDlg")) mnemosyne.components.append(("mnemosyne.pyqt_ui.prefill_tag_behaviour_plugin", "PrefillTagBehaviourPlugin")) mnemosyne.extra_components_for_plugin["CrammingPlugin"] = \ [("mnemosyne.pyqt_ui.review_wdgt_cramming", "ReviewWdgtCramming"), ("mnemosyne.pyqt_ui.configuration_wdgt_cramming", "ConfigurationWdgtCramming")] # Run Mnemosyne. mnemosyne.initialise(data_dir=data_dir, filename=filename, automatic_upgrades=options.automatic_upgrades, debug_file=options.debug_file) mnemosyne.main_widget().show() mnemosyne.main_widget().raise_() # Needed for OSX. if mnemosyne.config()["first_run"] == True: mnemosyne.controller().show_getting_started_dialog() mnemosyne.config()["first_run"] = False elif mnemosyne.config()["show_daily_tips"] == True: mnemosyne.controller().show_tip_dialog() a.exec_() mnemosyne.finalise() Mnemosyne-2.2.1/mnemosyne/pyqt_ui/ui_export_metadata_dlg.py0000644000175000000000000001264412132771337024721 0ustar pbienstroot00000000000000# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'export_metadata_dlg.ui' # # Created: Mon Apr 15 14:30:23 2013 # by: PyQt4 UI code generator 4.9.3 # # WARNING! All changes made in this file will be lost! from mnemosyne.libmnemosyne.translator import _ from PyQt4 import QtCore, QtGui try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: _fromUtf8 = lambda s: s class Ui_ExportMetadataDlg(object): def setupUi(self, ExportMetadataDlg): ExportMetadataDlg.setObjectName(_fromUtf8("ExportMetadataDlg")) ExportMetadataDlg.resize(455, 433) self.verticalLayout_2 = QtGui.QVBoxLayout(ExportMetadataDlg) self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2")) self.verticalLayout = QtGui.QVBoxLayout() self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) self.formLayout = QtGui.QFormLayout() self.formLayout.setObjectName(_fromUtf8("formLayout")) self.label = QtGui.QLabel(ExportMetadataDlg) self.label.setObjectName(_fromUtf8("label")) self.formLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.label) self.card_set_name = QtGui.QLineEdit(ExportMetadataDlg) self.card_set_name.setObjectName(_fromUtf8("card_set_name")) self.formLayout.setWidget(0, QtGui.QFormLayout.FieldRole, self.card_set_name) self.label_2 = QtGui.QLabel(ExportMetadataDlg) self.label_2.setObjectName(_fromUtf8("label_2")) self.formLayout.setWidget(2, QtGui.QFormLayout.LabelRole, self.label_2) self.author_name = QtGui.QLineEdit(ExportMetadataDlg) self.author_name.setObjectName(_fromUtf8("author_name")) self.formLayout.setWidget(2, QtGui.QFormLayout.FieldRole, self.author_name) self.label_3 = QtGui.QLabel(ExportMetadataDlg) self.label_3.setObjectName(_fromUtf8("label_3")) self.formLayout.setWidget(3, QtGui.QFormLayout.LabelRole, self.label_3) self.label_4 = QtGui.QLabel(ExportMetadataDlg) self.label_4.setObjectName(_fromUtf8("label_4")) self.formLayout.setWidget(5, QtGui.QFormLayout.LabelRole, self.label_4) self.date = QtGui.QDateEdit(ExportMetadataDlg) self.date.setObjectName(_fromUtf8("date")) self.formLayout.setWidget(5, QtGui.QFormLayout.FieldRole, self.date) self.label_5 = QtGui.QLabel(ExportMetadataDlg) self.label_5.setObjectName(_fromUtf8("label_5")) self.formLayout.setWidget(6, QtGui.QFormLayout.LabelRole, self.label_5) self.revision = QtGui.QSpinBox(ExportMetadataDlg) self.revision.setMinimum(1) self.revision.setMaximum(9999) self.revision.setObjectName(_fromUtf8("revision")) self.formLayout.setWidget(6, QtGui.QFormLayout.FieldRole, self.revision) self.author_email = QtGui.QLineEdit(ExportMetadataDlg) self.author_email.setObjectName(_fromUtf8("author_email")) self.formLayout.setWidget(3, QtGui.QFormLayout.FieldRole, self.author_email) self.tags = QtGui.QLineEdit(ExportMetadataDlg) self.tags.setObjectName(_fromUtf8("tags")) self.formLayout.setWidget(4, QtGui.QFormLayout.FieldRole, self.tags) self.label_7 = QtGui.QLabel(ExportMetadataDlg) self.label_7.setObjectName(_fromUtf8("label_7")) self.formLayout.setWidget(4, QtGui.QFormLayout.LabelRole, self.label_7) self.verticalLayout.addLayout(self.formLayout) self.label_6 = QtGui.QLabel(ExportMetadataDlg) self.label_6.setObjectName(_fromUtf8("label_6")) self.verticalLayout.addWidget(self.label_6) self.notes = QtGui.QPlainTextEdit(ExportMetadataDlg) self.notes.setObjectName(_fromUtf8("notes")) self.verticalLayout.addWidget(self.notes) self.horizontalLayout = QtGui.QHBoxLayout() self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout")) self.ok_button = QtGui.QPushButton(ExportMetadataDlg) self.ok_button.setObjectName(_fromUtf8("ok_button")) self.horizontalLayout.addWidget(self.ok_button) spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.horizontalLayout.addItem(spacerItem) self.verticalLayout.addLayout(self.horizontalLayout) self.verticalLayout_2.addLayout(self.verticalLayout) self.retranslateUi(ExportMetadataDlg) QtCore.QObject.connect(self.ok_button, QtCore.SIGNAL(_fromUtf8("clicked()")), ExportMetadataDlg.accept) QtCore.QMetaObject.connectSlotsByName(ExportMetadataDlg) ExportMetadataDlg.setTabOrder(self.card_set_name, self.author_name) ExportMetadataDlg.setTabOrder(self.author_name, self.author_email) ExportMetadataDlg.setTabOrder(self.author_email, self.tags) ExportMetadataDlg.setTabOrder(self.tags, self.date) ExportMetadataDlg.setTabOrder(self.date, self.revision) ExportMetadataDlg.setTabOrder(self.revision, self.notes) ExportMetadataDlg.setTabOrder(self.notes, self.ok_button) def retranslateUi(self, ExportMetadataDlg): ExportMetadataDlg.setWindowTitle(_('Export cards')) self.label.setText(_('Card set name:')) self.label_2.setText(_('Author name:')) self.label_3.setText(_('Author email:')) self.label_4.setText(_('Date:')) self.label_5.setText(_('Revision:')) self.label_7.setText(_('Tags:')) self.label_6.setText(_('Notes:')) self.ok_button.setText(_('&OK')) Mnemosyne-2.2.1/mnemosyne/pyqt_ui/ui_sync_dlg.py0000644000175000000000000001101412132771334022477 0ustar pbienstroot00000000000000# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'sync_dlg.ui' # # Created: Mon Apr 15 14:30:20 2013 # by: PyQt4 UI code generator 4.9.3 # # WARNING! All changes made in this file will be lost! from mnemosyne.libmnemosyne.translator import _ from PyQt4 import QtCore, QtGui try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: _fromUtf8 = lambda s: s class Ui_SyncDlg(object): def setupUi(self, SyncDlg): SyncDlg.setObjectName(_fromUtf8("SyncDlg")) SyncDlg.resize(337, 152) self.verticalLayout_2 = QtGui.QVBoxLayout(SyncDlg) self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2")) self.verticalLayout = QtGui.QVBoxLayout() self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) self.gridLayout = QtGui.QGridLayout() self.gridLayout.setObjectName(_fromUtf8("gridLayout")) self.label = QtGui.QLabel(SyncDlg) self.label.setObjectName(_fromUtf8("label")) self.gridLayout.addWidget(self.label, 0, 0, 1, 1) self.server = QtGui.QLineEdit(SyncDlg) self.server.setMinimumSize(QtCore.QSize(140, 0)) self.server.setInputMethodHints(QtCore.Qt.ImhUrlCharactersOnly) self.server.setObjectName(_fromUtf8("server")) self.gridLayout.addWidget(self.server, 0, 1, 1, 2) self.label_2 = QtGui.QLabel(SyncDlg) self.label_2.setObjectName(_fromUtf8("label_2")) self.gridLayout.addWidget(self.label_2, 1, 0, 1, 1) self.username = QtGui.QLineEdit(SyncDlg) self.username.setObjectName(_fromUtf8("username")) self.gridLayout.addWidget(self.username, 1, 1, 1, 5) self.label_4 = QtGui.QLabel(SyncDlg) self.label_4.setObjectName(_fromUtf8("label_4")) self.gridLayout.addWidget(self.label_4, 2, 0, 1, 1) self.password = QtGui.QLineEdit(SyncDlg) self.password.setEchoMode(QtGui.QLineEdit.Password) self.password.setObjectName(_fromUtf8("password")) self.gridLayout.addWidget(self.password, 2, 1, 1, 5) self.label_3 = QtGui.QLabel(SyncDlg) self.label_3.setObjectName(_fromUtf8("label_3")) self.gridLayout.addWidget(self.label_3, 0, 3, 1, 1) self.port = QtGui.QSpinBox(SyncDlg) self.port.setMinimum(1) self.port.setMaximum(99999) self.port.setObjectName(_fromUtf8("port")) self.gridLayout.addWidget(self.port, 0, 4, 1, 1) self.gridLayout.setColumnStretch(0, 1) self.gridLayout.setColumnStretch(1, 3) self.gridLayout.setColumnStretch(2, 1) self.gridLayout.setColumnStretch(3, 1) self.gridLayout.setColumnStretch(4, 1) self.verticalLayout.addLayout(self.gridLayout) self.check_for_edited_local_media_files = QtGui.QCheckBox(SyncDlg) self.check_for_edited_local_media_files.setObjectName(_fromUtf8("check_for_edited_local_media_files")) self.verticalLayout.addWidget(self.check_for_edited_local_media_files) self.horizontalLayout = QtGui.QHBoxLayout() self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout")) self.ok_button = QtGui.QPushButton(SyncDlg) self.ok_button.setDefault(True) self.ok_button.setObjectName(_fromUtf8("ok_button")) self.horizontalLayout.addWidget(self.ok_button) spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.horizontalLayout.addItem(spacerItem) self.cancel_button = QtGui.QPushButton(SyncDlg) self.cancel_button.setAutoDefault(False) self.cancel_button.setObjectName(_fromUtf8("cancel_button")) self.horizontalLayout.addWidget(self.cancel_button) self.verticalLayout.addLayout(self.horizontalLayout) self.verticalLayout_2.addLayout(self.verticalLayout) self.retranslateUi(SyncDlg) QtCore.QObject.connect(self.ok_button, QtCore.SIGNAL(_fromUtf8("clicked()")), SyncDlg.accept) QtCore.QObject.connect(self.cancel_button, QtCore.SIGNAL(_fromUtf8("clicked()")), SyncDlg.reject) QtCore.QMetaObject.connectSlotsByName(SyncDlg) def retranslateUi(self, SyncDlg): SyncDlg.setWindowTitle(_('Sync with server')) self.label.setText(_('Server:')) self.label_2.setText(_('Username:')) self.label_4.setText(_('Password:')) self.label_3.setText(_('Port:')) self.check_for_edited_local_media_files.setText(_('Check for changed media files on client')) self.ok_button.setText(_('&OK')) self.cancel_button.setText(_('&Cancel')) Mnemosyne-2.2.1/mnemosyne/pyqt_ui/card_type_tree_wdgt.py0000644000175000017500000002120112113343462024707 0ustar pbienstpbienst00000000000000# # card_type_tree_wdgt.py # from PyQt4 import QtCore, QtGui from mnemosyne.libmnemosyne.translator import _ from mnemosyne.libmnemosyne.component import Component from mnemosyne.libmnemosyne.criteria.default_criterion import DefaultCriterion # Code reuse through inheritance. from mnemosyne.pyqt_ui.tag_tree_wdgt import TagDelegate, TagsTreeWdgt # We hijack QTreeWidgetItem a bit and store extra data in a hidden column, so # that we don't need to implement a custom tree model. # The first column stores the string displayed, i.e. the card type id. # For card types, the second column stores the node id, in this case # the card type id. DISPLAY_STRING = 0 NODE = 1 class CardTypeDelegate(TagDelegate): def setEditorData(self, editor, index): # Get rid of the card count. self.previous_node_name = \ index.model().data(index).toString().rsplit(" (", 1)[0] editor.setText(self.previous_node_name) class CardTypesTreeWdgt(TagsTreeWdgt): """Displays all the card types in a tree together with check boxes.""" def __init__(self, component_manager, parent, before_using_libmnemosyne_db_hook=None, after_using_libmnemosyne_db_hook=None): TagsTreeWdgt.__init__(self, component_manager, parent, before_using_libmnemosyne_db_hook, after_using_libmnemosyne_db_hook) self.delegate = CardTypeDelegate(component_manager, self) self.tree_wdgt.setItemDelegate(self.delegate) def menu_rename(self): nodes = self.selected_nodes_which_can_be_renamed() # If there are tags selected, this means that we could only have got # after pressing return on an actual edit, due to our custom # 'keyPressEvent'. We should not continue in that case. if len(nodes) == 0: return from mnemosyne.pyqt_ui.ui_rename_card_type_dlg \ import Ui_RenameCardTypeDlg class RenameDlg(QtGui.QDialog, Ui_RenameCardTypeDlg): def __init__(self, old_card_type_name): QtGui.QDialog.__init__(self) self.setupUi(self) self.card_type_name.setText(old_card_type_name) old_card_type_name = self.card_type_with_id(unicode(nodes[0])).name dlg = RenameDlg(old_card_type_name) if dlg.exec_() == QtGui.QDialog.Accepted: self.rename_node(nodes[0], unicode(dlg.card_type_name.text())) def menu_delete(self): nodes = self.selected_nodes_which_can_be_deleted() if len(nodes) == 0: return if len(nodes) > 1: question = _("Delete these card types?") else: question = _("Delete this card type?") answer = self.main_widget().show_question\ (question, _("&OK"), _("&Cancel"), "") if answer == 1: # Cancel. return self.delete_nodes(nodes) def display(self, criterion=None): # Create criterion if needed. if criterion is None: criterion = DefaultCriterion(self.component_manager) # Determine number of cards at each level of the tree. root_count = 0 count_for_card_type = {} count_for_fact_view = {} for card_type in self.card_types(): card_type_count = 0 for fact_view in card_type.fact_views: count = self.database().card_count_for_fact_view \ (fact_view, active_only=False) card_type_count += count count_for_fact_view[fact_view] = count count_for_card_type[card_type] = card_type_count root_count += card_type_count # Fill widget. self.nodes_which_can_be_deleted = [] self.nodes_which_can_be_renamed = [] self.tree_wdgt.clear() self.card_type_fact_view_ids_for_node_item = {} root_item = QtGui.QTreeWidgetItem(self.tree_wdgt, [_("All card types (%d)") % root_count], 0) root_item.setFlags(root_item.flags() | \ QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsTristate) root_item.setCheckState(0, QtCore.Qt.Checked) for card_type in self.card_types(): card_type_item = QtGui.QTreeWidgetItem(root_item, ["%s (%d)" % \ (_(card_type.name), count_for_card_type[card_type])], 0) card_type_item.setFlags(card_type_item.flags() | \ QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsTristate) card_type_item.setCheckState(0, QtCore.Qt.Checked) card_type_item.setData(NODE, QtCore.Qt.DisplayRole, QtCore.QVariant(QtCore.QString(card_type.id))) if count_for_card_type[card_type] == 0 and \ self.database().is_user_card_type(card_type): self.nodes_which_can_be_deleted.append(card_type.id) if self.database().is_user_card_type(card_type): self.nodes_which_can_be_renamed.append(card_type.id) card_type_item.setFlags(card_type_item.flags() | \ QtCore.Qt.ItemIsEditable) for fact_view in card_type.fact_views: fact_view_item = QtGui.QTreeWidgetItem(card_type_item, ["%s (%d)" % (_(fact_view.name), count_for_fact_view[fact_view])], 0) fact_view_item.setFlags(fact_view_item.flags() | \ QtCore.Qt.ItemIsUserCheckable) if (card_type.id, fact_view.id) in \ criterion.deactivated_card_type_fact_view_ids: check_state = QtCore.Qt.Unchecked else: check_state = QtCore.Qt.Checked fact_view_item.setCheckState(0, check_state) self.card_type_fact_view_ids_for_node_item[fact_view_item] = \ (card_type.id, fact_view.id) self.tree_wdgt.expandAll() def checked_to_criterion(self, criterion): criterion.deactivated_card_type_fact_view_ids = set() for item, card_type_fact_view_ids in \ self.card_type_fact_view_ids_for_node_item.iteritems(): if item.checkState(0) == QtCore.Qt.Unchecked: criterion.deactivated_card_type_fact_view_ids.add(\ card_type_fact_view_ids) return criterion def save_criterion(self): self.saved_criterion = DefaultCriterion(self.component_manager) self.checked_to_criterion(self.saved_criterion) # Now we've saved the checked state of the tree. # Saving and restoring the selected state is less trivial, because # in the case of trees, the model indexes have parents which become # invalid when creating the widget. # The solution would be to save tags and reselect those in the new # widget. def restore_criterion(self): # See if any card types have been deleted meanwhile. old_card_type_ids = set([cursor[0] for cursor in \ self.saved_criterion.deactivated_card_type_fact_view_ids]) deleted_card_type_ids = set() for card_type_id in old_card_type_ids: try: card_type = self.card_type_with_id(card_type_id) except: deleted_card_type_ids.add(card_type_id) # Remove offending entries. deactivated_card_type_fact_view_ids = \ self.saved_criterion.deactivated_card_type_fact_view_ids for card_type_id, fact_view_id in deactivated_card_type_fact_view_ids: if card_type_id in deleted_card_type_ids: self.saved_criterion.deactivated_card_type_fact_view_ids.\ discard((card_type_id, fact_view_id)) self.display(self.saved_criterion) def rename_node(self, node, new_name): self.hibernate() card_type = self.card_type_with_id(unicode(node)) self.controller().rename_card_type(card_type, new_name) self.wakeup() def delete_nodes(self, nodes): self.hibernate() for node in nodes: card_type = self.card_type_with_id(unicode(node)) self.controller().delete_card_type(card_type) self.wakeup() def rebuild(self): """To be called when external events invalidate the tag tree, e.g. due to edits in the card browser widget. """ self.hibernate() # Now we've saved the checked state of the tree. # Saving and restoring the selected state is less trivial, because # in the case of trees, the model indexes have parents which become # invalid when creating the widget. # The solution would be to save card types and reselect those in the # new widget. self.wakeup()Mnemosyne-2.2.1/mnemosyne/pyqt_ui/card_type_wdgt_generic.py0000644000175000017500000001425612107377155025411 0ustar pbienstpbienst00000000000000# # card_type_wdgt_generic.py # from PyQt4 import QtCore, QtGui from mnemosyne.libmnemosyne.translator import _ from mnemosyne.pyqt_ui.qtextedit2 import QTextEdit2 from mnemosyne.libmnemosyne.ui_components.card_type_widget \ import GenericCardTypeWidget class GenericCardTypeWdgt(QtGui.QWidget, GenericCardTypeWidget): def __init__(self, component_manager, parent, card_type): QtGui.QWidget.__init__(self, parent) GenericCardTypeWidget.__init__(self, component_manager) self.card_type = card_type self.hboxlayout = QtGui.QHBoxLayout(self) self.hboxlayout.setMargin(0) self.vboxlayout = QtGui.QVBoxLayout() self.fact_key_for_edit_box = {} self.top_edit_box = None self.edit_boxes = [] self.fact_data_before_edit = {} # Does this card type need to deal with the hiding of pronunciation # keys? if "p_1" not in self.card_type.fact_keys(): pronunciation_hiding = None else: pronunciation_hiding = self.config().card_type_property(\ "hide_pronunciation_field", self.card_type, default=False) # Construct the rest of the dialog. parent.setTabOrder(parent.card_types_widget, parent.tags) for fact_key, fact_key_name in self.card_type.fact_keys_and_names: l = QtGui.QLabel(_(fact_key_name) + ":", self) self.vboxlayout.addWidget(l) if fact_key == "p_1": self.pronunciation_label = l self.pronunciation_label.setVisible(not pronunciation_hiding) t = QTextEdit2(self, pronunciation_hiding) self.edit_boxes.append(t) t.setTabChangesFocus(True) t.setUndoRedoEnabled(True) t.setReadOnly(False) if len(self.card_type.fact_keys_and_names) > 2: t.setMinimumSize(QtCore.QSize(0, 60)) else: t.setMinimumSize(QtCore.QSize(0, 106)) self.vboxlayout.addWidget(t) self.fact_key_for_edit_box[t] = fact_key if self.top_edit_box is None: self.top_edit_box = t parent.setTabOrder(parent.tags, t) else: parent.setTabOrder(previous_box, t) previous_box = t if fact_key == "p_1": self.pronunciation_box = t self.pronunciation_box.setVisible(not pronunciation_hiding) self.update_formatting(t) t.textChanged.connect(self.text_changed) t.currentCharFormatChanged.connect(self.reset_formatting) self.hboxlayout.addLayout(self.vboxlayout) self.resize(QtCore.QSize(QtCore.QRect(0,0,325,264).size()).\ expandedTo(self.minimumSizeHint())) if parent.component_type == "add_cards_dialog": parent.setTabOrder(t, parent.yet_to_learn_button) parent.setTabOrder(parent.yet_to_learn_button, parent.grade_2_button) parent.setTabOrder(parent.grade_2_button, parent.grade_3_button) parent.setTabOrder(parent.grade_3_button, parent.grade_4_button) parent.setTabOrder(parent.grade_4_button, parent.grade_5_button) parent.setTabOrder(parent.grade_5_button, parent.preview_button) parent.setTabOrder(parent.preview_button, parent.exit_button) else: parent.setTabOrder(t, parent.OK_button) parent.setTabOrder(parent.OK_button, parent.preview_button) parent.setTabOrder(parent.preview_button, parent.exit_button) self.top_edit_box.setFocus() def pronunciation_hiding_toggled(self, checked): self.config().set_card_type_property("hide_pronunciation_field", checked, self.card_type) self.pronunciation_label.setVisible(not checked) self.pronunciation_box.setVisible(not checked) for edit_box in self.edit_boxes: edit_box.pronunciation_hiding = checked def update_formatting(self, edit_box): # Font colour. fact_key = self.fact_key_for_edit_box[edit_box] colour = self.config().card_type_property(\ "font_colour", self.card_type, fact_key) if colour: edit_box.setTextColor(QtGui.QColor(colour)) # Background colour. colour = self.config().card_type_property(\ "background_colour", self.card_type) if colour: p = QtGui.QPalette() p.setColor(QtGui.QPalette.Active, QtGui.QPalette.Base, QtGui.QColor(colour)) edit_box.setPalette(p) # Font. font_string = self.config().card_type_property(\ "font", self.card_type, fact_key) if font_string: font = QtGui.QFont() font.fromString(font_string) edit_box.setCurrentFont(font) def reset_formatting(self): """Deleting all the text reverts back to the system font, so we have to force our custom font again. """ for edit_box in self.fact_key_for_edit_box: self.update_formatting(edit_box) def is_empty(self): for edit_box in self.fact_key_for_edit_box: if unicode(edit_box.document().toPlainText()): return False return True def is_changed(self): return self.fact_data() != self.fact_data_before_edit def fact_data(self): _fact_data = {} for edit_box, fact_key in self.fact_key_for_edit_box.iteritems(): _fact_data[fact_key] = unicode(edit_box.document().toPlainText()) return _fact_data def set_fact_data(self, fact_data): self.fact_data_before_edit = fact_data if fact_data: for edit_box, fact_key in self.fact_key_for_edit_box.iteritems(): if fact_key in fact_data: edit_box.setPlainText(fact_data[fact_key]) def clear(self): self.fact_data_before_edit = {} for edit_box in self.fact_key_for_edit_box: edit_box.setText("") self.top_edit_box.setFocus() def text_changed(self): self.parent().set_valid(\ self.card_type.is_fact_data_valid(self.fact_data())) Mnemosyne-2.2.1/mnemosyne/pyqt_ui/export_metadata_dlg.py0000664000175000017500000000727212044233437024721 0ustar pbienstpbienst00000000000000# # export_metadata_dlg.py # from PyQt4 import QtGui, QtCore from mnemosyne.libmnemosyne.translator import _ from mnemosyne.pyqt_ui.ui_export_metadata_dlg import Ui_ExportMetadataDlg from mnemosyne.libmnemosyne.ui_components.dialogs import ExportMetadataDialog class ExportMetadataDlg(QtGui.QDialog, Ui_ExportMetadataDlg, ExportMetadataDialog): def __init__(self, component_manager): ExportMetadataDialog.__init__(self, component_manager) QtGui.QDialog.__init__(self, self.main_widget()) self.setupUi(self) self.setWindowFlags(self.windowFlags() \ & ~ QtCore.Qt.WindowContextHelpButtonHint) self.setWindowFlags(self.windowFlags() \ & ~ QtCore.Qt.WindowCloseButtonHint) # Does not seem to work... self.author_name.setText(self.config()["author_name"]) self.author_email.setText(self.config()["author_email"]) self.date.setDate(QtCore.QDate.currentDate()) self.allow_cancel = True self.cancelled = False def activate(self): ExportMetadataDialog.activate(self) return self.exec_() def set_values(self, metadata): if "card_set_name" in metadata: self.card_set_name.setText(metadata["card_set_name"]) if "author_name" in metadata: self.author_name.setText(metadata["author_name"]) if "author_email" in metadata: self.author_email.setText(metadata["author_email"]) if "tags" in metadata: self.tags.setText(metadata["tags"]) if "date" in metadata: date = QtCore.QDate() date.fromString(metadata["date"]) self.date.setDate(date) if "revision" in metadata: self.revision.setValue(int(metadata["revision"])) if "notes" in metadata: self.notes.setPlainText(metadata["notes"]) def set_read_only(self): self.card_set_name.setReadOnly(True) self.author_name.setReadOnly(True) self.author_email.setReadOnly(True) self.tags.setReadOnly(True) self.date.setReadOnly(True) self.revision.setReadOnly(True) self.notes.setReadOnly(True) self.allow_cancel = False def closeEvent(self, event): # Generated when clicking the window's close button. if self.allow_cancel: event.ignore() self.reject() else: event.ignore() def keyPressEvent(self, event): # Note: for the following to work reliably, there should be no # shortcuts defined in the ui file. if event.key() == QtCore.Qt.Key_Escape or (event.modifiers() in \ [QtCore.Qt.ControlModifier, QtCore.Qt.AltModifier] and \ event.key() == QtCore.Qt.Key_E): if self.allow_cancel: self.reject() else: event.ignore() else: QtGui.QDialog.keyPressEvent(self, event) def reject(self): self.cancelled = True return QtGui.QDialog.reject(self) def values(self): if self.cancelled: return None metadata = {} metadata["card_set_name"] = unicode(self.card_set_name.text()) metadata["author_name"] = unicode(self.author_name.text()) metadata["author_email"] = unicode(self.author_email.text()) metadata["tags"] = unicode(self.tags.text()) metadata["date"] = unicode(self.date.date().toString()) metadata["revision"] = str(self.revision.value()) metadata["notes"] = unicode(self.notes.toPlainText()) self.config()["author_name"] = metadata["author_name"] self.config()["author_email"] = metadata["author_email"] return metadataMnemosyne-2.2.1/mnemosyne/pyqt_ui/ui_activate_cards_dlg.py0000644000175000000000000001171012132771333024501 0ustar pbienstroot00000000000000# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'activate_cards_dlg.ui' # # Created: Mon Apr 15 14:30:19 2013 # by: PyQt4 UI code generator 4.9.3 # # WARNING! All changes made in this file will be lost! from mnemosyne.libmnemosyne.translator import _ from PyQt4 import QtCore, QtGui try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: _fromUtf8 = lambda s: s class Ui_ActivateCardsDlg(object): def setupUi(self, ActivateCardsDlg): ActivateCardsDlg.setObjectName(_fromUtf8("ActivateCardsDlg")) ActivateCardsDlg.resize(593, 148) self.verticalLayout_3 = QtGui.QVBoxLayout(ActivateCardsDlg) self.verticalLayout_3.setObjectName(_fromUtf8("verticalLayout_3")) self.splitter = QtGui.QSplitter(ActivateCardsDlg) self.splitter.setOrientation(QtCore.Qt.Vertical) self.splitter.setObjectName(_fromUtf8("splitter")) self.layoutWidget = QtGui.QWidget(self.splitter) self.layoutWidget.setObjectName(_fromUtf8("layoutWidget")) self.saved_sets_layout = QtGui.QVBoxLayout(self.layoutWidget) self.saved_sets_layout.setMargin(0) self.saved_sets_layout.setObjectName(_fromUtf8("saved_sets_layout")) self.saved_sets_label = QtGui.QLabel(self.layoutWidget) self.saved_sets_label.setObjectName(_fromUtf8("saved_sets_label")) self.saved_sets_layout.addWidget(self.saved_sets_label) self.saved_sets = QtGui.QListWidget(self.layoutWidget) self.saved_sets.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.saved_sets.setObjectName(_fromUtf8("saved_sets")) self.saved_sets_layout.addWidget(self.saved_sets) self.layoutWidget1 = QtGui.QWidget(self.splitter) self.layoutWidget1.setObjectName(_fromUtf8("layoutWidget1")) self.criterion_layout = QtGui.QVBoxLayout(self.layoutWidget1) self.criterion_layout.setMargin(0) self.criterion_layout.setObjectName(_fromUtf8("criterion_layout")) self.tab_widget = QtGui.QTabWidget(self.layoutWidget1) self.tab_widget.setObjectName(_fromUtf8("tab_widget")) self.criterion_layout.addWidget(self.tab_widget) self.horizontalLayout_3 = QtGui.QHBoxLayout() self.horizontalLayout_3.setObjectName(_fromUtf8("horizontalLayout_3")) self.ok_button = QtGui.QPushButton(self.layoutWidget1) self.ok_button.setAutoDefault(True) self.ok_button.setDefault(True) self.ok_button.setObjectName(_fromUtf8("ok_button")) self.horizontalLayout_3.addWidget(self.ok_button) spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.horizontalLayout_3.addItem(spacerItem) self.save_button = QtGui.QPushButton(self.layoutWidget1) self.save_button.setAutoDefault(False) self.save_button.setObjectName(_fromUtf8("save_button")) self.horizontalLayout_3.addWidget(self.save_button) spacerItem1 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.horizontalLayout_3.addItem(spacerItem1) self.cancel_button = QtGui.QPushButton(self.layoutWidget1) self.cancel_button.setAutoDefault(False) self.cancel_button.setObjectName(_fromUtf8("cancel_button")) self.horizontalLayout_3.addWidget(self.cancel_button) self.criterion_layout.addLayout(self.horizontalLayout_3) self.verticalLayout_3.addWidget(self.splitter) self.retranslateUi(ActivateCardsDlg) self.tab_widget.setCurrentIndex(-1) QtCore.QObject.connect(self.ok_button, QtCore.SIGNAL(_fromUtf8("clicked()")), ActivateCardsDlg.accept) QtCore.QObject.connect(self.save_button, QtCore.SIGNAL(_fromUtf8("clicked()")), ActivateCardsDlg.save_set) QtCore.QObject.connect(self.cancel_button, QtCore.SIGNAL(_fromUtf8("clicked()")), ActivateCardsDlg.reject) QtCore.QObject.connect(self.saved_sets, QtCore.SIGNAL(_fromUtf8("itemActivated(QListWidgetItem*)")), ActivateCardsDlg.load_set) QtCore.QObject.connect(self.saved_sets, QtCore.SIGNAL(_fromUtf8("customContextMenuRequested(QPoint)")), ActivateCardsDlg.saved_sets_custom_menu) QtCore.QObject.connect(self.tab_widget, QtCore.SIGNAL(_fromUtf8("currentChanged(int)")), ActivateCardsDlg.change_widget) QtCore.QObject.connect(self.saved_sets, QtCore.SIGNAL(_fromUtf8("currentItemChanged(QListWidgetItem*,QListWidgetItem*)")), ActivateCardsDlg.change_set) QtCore.QObject.connect(self.saved_sets, QtCore.SIGNAL(_fromUtf8("itemDoubleClicked(QListWidgetItem*)")), ActivateCardsDlg.select_set_and_close) QtCore.QMetaObject.connectSlotsByName(ActivateCardsDlg) def retranslateUi(self, ActivateCardsDlg): ActivateCardsDlg.setWindowTitle(_('(De)activate cards')) self.saved_sets_label.setText(_('Saved sets:')) self.ok_button.setText(_('&OK')) self.save_button.setText(_('&Save this set for later use')) self.cancel_button.setText(_('&Cancel')) Mnemosyne-2.2.1/mnemosyne/pyqt_ui/ui_add_tags_dlg.py0000644000175000000000000000577312132771335023311 0ustar pbienstroot00000000000000# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'add_tags_dlg.ui' # # Created: Mon Apr 15 14:30:21 2013 # by: PyQt4 UI code generator 4.9.3 # # WARNING! All changes made in this file will be lost! from mnemosyne.libmnemosyne.translator import _ from PyQt4 import QtCore, QtGui try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: _fromUtf8 = lambda s: s class Ui_AddTagsDlg(object): def setupUi(self, AddTagsDlg): AddTagsDlg.setObjectName(_fromUtf8("AddTagsDlg")) AddTagsDlg.resize(274, 65) self.verticalLayout_2 = QtGui.QVBoxLayout(AddTagsDlg) self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2")) self.verticalLayout = QtGui.QVBoxLayout() self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) self.horizontalLayout = QtGui.QHBoxLayout() self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout")) self.label = QtGui.QLabel(AddTagsDlg) self.label.setObjectName(_fromUtf8("label")) self.horizontalLayout.addWidget(self.label) self.tags = QtGui.QComboBox(AddTagsDlg) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.tags.sizePolicy().hasHeightForWidth()) self.tags.setSizePolicy(sizePolicy) self.tags.setEditable(True) self.tags.setObjectName(_fromUtf8("tags")) self.horizontalLayout.addWidget(self.tags) self.verticalLayout.addLayout(self.horizontalLayout) self.hboxlayout = QtGui.QHBoxLayout() self.hboxlayout.setObjectName(_fromUtf8("hboxlayout")) self.ok_button = QtGui.QPushButton(AddTagsDlg) self.ok_button.setAutoDefault(True) self.ok_button.setDefault(True) self.ok_button.setObjectName(_fromUtf8("ok_button")) self.hboxlayout.addWidget(self.ok_button) spacerItem = QtGui.QSpacerItem(101, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.hboxlayout.addItem(spacerItem) self.cancel_button = QtGui.QPushButton(AddTagsDlg) self.cancel_button.setAutoDefault(False) self.cancel_button.setObjectName(_fromUtf8("cancel_button")) self.hboxlayout.addWidget(self.cancel_button) self.verticalLayout.addLayout(self.hboxlayout) self.verticalLayout_2.addLayout(self.verticalLayout) self.retranslateUi(AddTagsDlg) QtCore.QObject.connect(self.cancel_button, QtCore.SIGNAL(_fromUtf8("clicked()")), AddTagsDlg.reject) QtCore.QObject.connect(self.ok_button, QtCore.SIGNAL(_fromUtf8("clicked()")), AddTagsDlg.accept) QtCore.QMetaObject.connectSlotsByName(AddTagsDlg) def retranslateUi(self, AddTagsDlg): AddTagsDlg.setWindowTitle(_('Add tags')) self.label.setText(_('Tags:')) self.ok_button.setText(_('&OK')) self.cancel_button.setText(_('&Cancel')) import mnemosyne_rc Mnemosyne-2.2.1/mnemosyne/pyqt_ui/ui_configuration_wdgt_main.py0000644000175000000000000001753212132771333025607 0ustar pbienstroot00000000000000# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'configuration_wdgt_main.ui' # # Created: Mon Apr 15 14:30:19 2013 # by: PyQt4 UI code generator 4.9.3 # # WARNING! All changes made in this file will be lost! from mnemosyne.libmnemosyne.translator import _ from PyQt4 import QtCore, QtGui try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: _fromUtf8 = lambda s: s class Ui_ConfigurationWdgtMain(object): def setupUi(self, ConfigurationWdgtMain): ConfigurationWdgtMain.setObjectName(_fromUtf8("ConfigurationWdgtMain")) ConfigurationWdgtMain.resize(385, 393) self.verticalLayout_6 = QtGui.QVBoxLayout(ConfigurationWdgtMain) self.verticalLayout_6.setObjectName(_fromUtf8("verticalLayout_6")) self.verticalLayout_5 = QtGui.QVBoxLayout() self.verticalLayout_5.setObjectName(_fromUtf8("verticalLayout_5")) self.groupBox = QtGui.QGroupBox(ConfigurationWdgtMain) self.groupBox.setObjectName(_fromUtf8("groupBox")) self.verticalLayout = QtGui.QVBoxLayout(self.groupBox) self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) self.horizontalLayout_2 = QtGui.QHBoxLayout() self.horizontalLayout_2.setObjectName(_fromUtf8("horizontalLayout_2")) self.label_2 = QtGui.QLabel(self.groupBox) self.label_2.setObjectName(_fromUtf8("label_2")) self.horizontalLayout_2.addWidget(self.label_2) self.new_cards = QtGui.QComboBox(self.groupBox) self.new_cards.setObjectName(_fromUtf8("new_cards")) self.new_cards.addItem(_fromUtf8("")) self.new_cards.addItem(_fromUtf8("")) self.horizontalLayout_2.addWidget(self.new_cards) spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.horizontalLayout_2.addItem(spacerItem) self.verticalLayout.addLayout(self.horizontalLayout_2) self.horizontalLayout_3 = QtGui.QHBoxLayout() self.horizontalLayout_3.setObjectName(_fromUtf8("horizontalLayout_3")) self.label_3 = QtGui.QLabel(self.groupBox) self.label_3.setObjectName(_fromUtf8("label_3")) self.horizontalLayout_3.addWidget(self.label_3) self.scheduled_cards = QtGui.QComboBox(self.groupBox) self.scheduled_cards.setObjectName(_fromUtf8("scheduled_cards")) self.scheduled_cards.addItem(_fromUtf8("")) self.scheduled_cards.addItem(_fromUtf8("")) self.horizontalLayout_3.addWidget(self.scheduled_cards) spacerItem1 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.horizontalLayout_3.addItem(spacerItem1) self.verticalLayout.addLayout(self.horizontalLayout_3) self.horizontalLayout = QtGui.QHBoxLayout() self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout")) self.label = QtGui.QLabel(self.groupBox) self.label.setObjectName(_fromUtf8("label")) self.horizontalLayout.addWidget(self.label) self.non_memorised_cards = QtGui.QSpinBox(self.groupBox) self.non_memorised_cards.setMinimum(1) self.non_memorised_cards.setProperty("value", 10) self.non_memorised_cards.setObjectName(_fromUtf8("non_memorised_cards")) self.horizontalLayout.addWidget(self.non_memorised_cards) self.label_4 = QtGui.QLabel(self.groupBox) self.label_4.setObjectName(_fromUtf8("label_4")) self.horizontalLayout.addWidget(self.label_4) spacerItem2 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.horizontalLayout.addItem(spacerItem2) self.verticalLayout.addLayout(self.horizontalLayout) self.horizontalLayout_4 = QtGui.QHBoxLayout() self.horizontalLayout_4.setObjectName(_fromUtf8("horizontalLayout_4")) self.label_5 = QtGui.QLabel(self.groupBox) self.label_5.setObjectName(_fromUtf8("label_5")) self.horizontalLayout_4.addWidget(self.label_5) self.save_after_n_reps = QtGui.QSpinBox(self.groupBox) self.save_after_n_reps.setMinimum(1) self.save_after_n_reps.setMaximum(25) self.save_after_n_reps.setProperty("value", 10) self.save_after_n_reps.setObjectName(_fromUtf8("save_after_n_reps")) self.horizontalLayout_4.addWidget(self.save_after_n_reps) self.label_6 = QtGui.QLabel(self.groupBox) self.label_6.setObjectName(_fromUtf8("label_6")) self.horizontalLayout_4.addWidget(self.label_6) spacerItem3 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.horizontalLayout_4.addItem(spacerItem3) self.verticalLayout.addLayout(self.horizontalLayout_4) self.verticalLayout_5.addWidget(self.groupBox) self.audio_box = QtGui.QGroupBox(ConfigurationWdgtMain) self.audio_box.setObjectName(_fromUtf8("audio_box")) self.verticalLayout_2 = QtGui.QVBoxLayout(self.audio_box) self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2")) self.media_autoplay = QtGui.QCheckBox(self.audio_box) self.media_autoplay.setChecked(True) self.media_autoplay.setObjectName(_fromUtf8("media_autoplay")) self.verticalLayout_2.addWidget(self.media_autoplay) self.media_controls = QtGui.QCheckBox(self.audio_box) self.media_controls.setChecked(False) self.media_controls.setObjectName(_fromUtf8("media_controls")) self.verticalLayout_2.addWidget(self.media_controls) self.verticalLayout_5.addWidget(self.audio_box) self.groupBox_3 = QtGui.QGroupBox(ConfigurationWdgtMain) self.groupBox_3.setObjectName(_fromUtf8("groupBox_3")) self.verticalLayout_3 = QtGui.QVBoxLayout(self.groupBox_3) self.verticalLayout_3.setObjectName(_fromUtf8("verticalLayout_3")) self.upload_science_logs = QtGui.QCheckBox(self.groupBox_3) self.upload_science_logs.setChecked(True) self.upload_science_logs.setObjectName(_fromUtf8("upload_science_logs")) self.verticalLayout_3.addWidget(self.upload_science_logs) self.verticalLayout_5.addWidget(self.groupBox_3) self.groupBox_4 = QtGui.QGroupBox(ConfigurationWdgtMain) self.groupBox_4.setObjectName(_fromUtf8("groupBox_4")) self.verticalLayout_4 = QtGui.QVBoxLayout(self.groupBox_4) self.verticalLayout_4.setObjectName(_fromUtf8("verticalLayout_4")) self.languages = QtGui.QComboBox(self.groupBox_4) self.languages.setObjectName(_fromUtf8("languages")) self.verticalLayout_4.addWidget(self.languages) self.verticalLayout_5.addWidget(self.groupBox_4) self.verticalLayout_6.addLayout(self.verticalLayout_5) self.retranslateUi(ConfigurationWdgtMain) QtCore.QMetaObject.connectSlotsByName(ConfigurationWdgtMain) def retranslateUi(self, ConfigurationWdgtMain): ConfigurationWdgtMain.setWindowTitle(_('Form')) self.groupBox.setTitle(_('Scheduler')) self.label_2.setText(_('First show new cards')) self.new_cards.setItemText(0, _('in the order they were added')) self.new_cards.setItemText(1, _('in random order')) self.label_3.setText(_('Review memorised cards')) self.scheduled_cards.setItemText(0, _('most urgent first')) self.scheduled_cards.setItemText(1, _('in random order')) self.label.setText(_('Hold')) self.label_4.setText(_('non-memorised cards in your hand')) self.label_5.setText(_('Autosave after')) self.label_6.setText(_('repetitions')) self.audio_box.setTitle(_('Audio/video')) self.media_autoplay.setText(_('Start automatically when displaying card')) self.media_controls.setText(_('Show controls (pause, ...)')) self.groupBox_3.setTitle(_('Science')) self.upload_science_logs.setText(_('Upload anonymous science logs')) self.groupBox_4.setTitle(_('Language')) Mnemosyne-2.2.1/mnemosyne/pyqt_ui/ui_main_wdgt.py0000644000175000000000000003372712132771331022662 0ustar pbienstroot00000000000000# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'main_wdgt.ui' # # Created: Mon Apr 15 14:30:13 2013 # by: PyQt4 UI code generator 4.9.3 # # WARNING! All changes made in this file will be lost! from mnemosyne.libmnemosyne.translator import _ from PyQt4 import QtCore, QtGui try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: _fromUtf8 = lambda s: s class Ui_MainWdgt(object): def setupUi(self, MainWdgt): MainWdgt.setObjectName(_fromUtf8("MainWdgt")) MainWdgt.resize(315, 494) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(MainWdgt.sizePolicy().hasHeightForWidth()) MainWdgt.setSizePolicy(sizePolicy) icon = QtGui.QIcon() icon.addPixmap(QtGui.QPixmap(_fromUtf8(":/mnemosyne/pixmaps/mnemosyne.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) MainWdgt.setWindowIcon(icon) self.centralwidget = QtGui.QWidget(MainWdgt) self.centralwidget.setObjectName(_fromUtf8("centralwidget")) MainWdgt.setCentralWidget(self.centralwidget) self.menu_bar = QtGui.QMenuBar(MainWdgt) self.menu_bar.setGeometry(QtCore.QRect(0, 0, 315, 21)) self.menu_bar.setObjectName(_fromUtf8("menu_bar")) self.menu_Settings = QtGui.QMenu(self.menu_bar) self.menu_Settings.setObjectName(_fromUtf8("menu_Settings")) self.menu_Help = QtGui.QMenu(self.menu_bar) self.menu_Help.setObjectName(_fromUtf8("menu_Help")) self.menuFile = QtGui.QMenu(self.menu_bar) self.menuFile.setObjectName(_fromUtf8("menuFile")) self.menu_Cards = QtGui.QMenu(self.menu_bar) self.menu_Cards.setObjectName(_fromUtf8("menu_Cards")) MainWdgt.setMenuBar(self.menu_bar) self.status_bar = QtGui.QStatusBar(MainWdgt) self.status_bar.setObjectName(_fromUtf8("status_bar")) MainWdgt.setStatusBar(self.status_bar) self.tool_bar = QtGui.QToolBar(MainWdgt) self.tool_bar.setMovable(False) self.tool_bar.setIconSize(QtCore.QSize(22, 22)) self.tool_bar.setFloatable(False) self.tool_bar.setObjectName(_fromUtf8("tool_bar")) MainWdgt.addToolBar(QtCore.Qt.TopToolBarArea, self.tool_bar) self.actionActivateCards = QtGui.QAction(MainWdgt) self.actionActivateCards.setObjectName(_fromUtf8("actionActivateCards")) self.actionAddCards = QtGui.QAction(MainWdgt) icon1 = QtGui.QIcon() icon1.addPixmap(QtGui.QPixmap(_fromUtf8(":/mnemosyne/pixmaps/add.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionAddCards.setIcon(icon1) self.actionAddCards.setObjectName(_fromUtf8("actionAddCards")) self.actionConfigure = QtGui.QAction(MainWdgt) icon2 = QtGui.QIcon() icon2.addPixmap(QtGui.QPixmap(_fromUtf8(":/mnemosyne/pixmaps/configure.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionConfigure.setIcon(icon2) self.actionConfigure.setObjectName(_fromUtf8("actionConfigure")) self.actionDeleteCurrentCard = QtGui.QAction(MainWdgt) icon3 = QtGui.QIcon() icon3.addPixmap(QtGui.QPixmap(_fromUtf8(":/mnemosyne/pixmaps/delete.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionDeleteCurrentCard.setIcon(icon3) self.actionDeleteCurrentCard.setObjectName(_fromUtf8("actionDeleteCurrentCard")) self.actionEditCurrentCard = QtGui.QAction(MainWdgt) icon4 = QtGui.QIcon() icon4.addPixmap(QtGui.QPixmap(_fromUtf8(":/mnemosyne/pixmaps/edit.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionEditCurrentCard.setIcon(icon4) self.actionEditCurrentCard.setObjectName(_fromUtf8("actionEditCurrentCard")) self.actionBrowseCards = QtGui.QAction(MainWdgt) icon5 = QtGui.QIcon() icon5.addPixmap(QtGui.QPixmap(_fromUtf8(":/mnemosyne/pixmaps/cards.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionBrowseCards.setIcon(icon5) self.actionBrowseCards.setObjectName(_fromUtf8("actionBrowseCards")) self.actionExport = QtGui.QAction(MainWdgt) self.actionExport.setObjectName(_fromUtf8("actionExport")) self.actionFileExit = QtGui.QAction(MainWdgt) icon6 = QtGui.QIcon() icon6.addPixmap(QtGui.QPixmap(_fromUtf8(":/mnemosyne/pixmaps/exit.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionFileExit.setIcon(icon6) self.actionFileExit.setObjectName(_fromUtf8("actionFileExit")) self.actionFileNew = QtGui.QAction(MainWdgt) icon7 = QtGui.QIcon() icon7.addPixmap(QtGui.QPixmap(_fromUtf8("../../pixmaps/filenew.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionFileNew.setIcon(icon7) self.actionFileNew.setObjectName(_fromUtf8("actionFileNew")) self.actionFileOpen = QtGui.QAction(MainWdgt) icon8 = QtGui.QIcon() icon8.addPixmap(QtGui.QPixmap(_fromUtf8(":/mnemosyne/pixmaps/fileopen.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionFileOpen.setIcon(icon8) self.actionFileOpen.setObjectName(_fromUtf8("actionFileOpen")) self.actionFileSave = QtGui.QAction(MainWdgt) icon9 = QtGui.QIcon() icon9.addPixmap(QtGui.QPixmap(_fromUtf8(":/mnemosyne/pixmaps/filesave.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionFileSave.setIcon(icon9) self.actionFileSave.setObjectName(_fromUtf8("actionFileSave")) self.actionFileSaveAs = QtGui.QAction(MainWdgt) icon10 = QtGui.QIcon() icon10.addPixmap(QtGui.QPixmap(_fromUtf8(":/mnemosyne/pixmaps/filesaveas.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionFileSaveAs.setIcon(icon10) self.actionFileSaveAs.setObjectName(_fromUtf8("actionFileSaveAs")) self.actionAbout = QtGui.QAction(MainWdgt) self.actionAbout.setObjectName(_fromUtf8("actionAbout")) self.actionImport = QtGui.QAction(MainWdgt) self.actionImport.setObjectName(_fromUtf8("actionImport")) self.actionGettingStarted = QtGui.QAction(MainWdgt) self.actionGettingStarted.setObjectName(_fromUtf8("actionGettingStarted")) self.actionShowStatistics = QtGui.QAction(MainWdgt) icon11 = QtGui.QIcon() icon11.addPixmap(QtGui.QPixmap(_fromUtf8(":/mnemosyne/pixmaps/statistics.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionShowStatistics.setIcon(icon11) self.actionShowStatistics.setObjectName(_fromUtf8("actionShowStatistics")) self.actionTip = QtGui.QAction(MainWdgt) self.actionTip.setObjectName(_fromUtf8("actionTip")) self.actionManagePlugins = QtGui.QAction(MainWdgt) self.actionManagePlugins.setObjectName(_fromUtf8("actionManagePlugins")) self.actionManageTypes = QtGui.QAction(MainWdgt) self.actionManageTypes.setObjectName(_fromUtf8("actionManageTypes")) self.actionSync = QtGui.QAction(MainWdgt) self.actionSync.setObjectName(_fromUtf8("actionSync")) self.actionCompact = QtGui.QAction(MainWdgt) self.actionCompact.setObjectName(_fromUtf8("actionCompact")) self.actionFindDuplicates = QtGui.QAction(MainWdgt) self.actionFindDuplicates.setObjectName(_fromUtf8("actionFindDuplicates")) self.menu_Settings.addAction(self.actionConfigure) self.menu_Settings.addAction(self.actionManagePlugins) self.menu_Help.addAction(self.actionGettingStarted) self.menu_Help.addAction(self.actionTip) self.menu_Help.addSeparator() self.menu_Help.addAction(self.actionAbout) self.menuFile.addAction(self.actionFileNew) self.menuFile.addAction(self.actionFileOpen) self.menuFile.addAction(self.actionFileSave) self.menuFile.addAction(self.actionFileSaveAs) self.menuFile.addSeparator() self.menuFile.addAction(self.actionImport) self.menuFile.addAction(self.actionExport) self.menuFile.addAction(self.actionSync) self.menuFile.addAction(self.actionCompact) self.menuFile.addSeparator() self.menuFile.addAction(self.actionFileExit) self.menu_Cards.addAction(self.actionAddCards) self.menu_Cards.addAction(self.actionEditCurrentCard) self.menu_Cards.addAction(self.actionDeleteCurrentCard) self.menu_Cards.addSeparator() self.menu_Cards.addAction(self.actionBrowseCards) self.menu_Cards.addAction(self.actionActivateCards) self.menu_Cards.addAction(self.actionFindDuplicates) self.menu_Cards.addAction(self.actionManageTypes) self.menu_Cards.addSeparator() self.menu_Cards.addAction(self.actionShowStatistics) self.menu_bar.addAction(self.menuFile.menuAction()) self.menu_bar.addAction(self.menu_Cards.menuAction()) self.menu_bar.addAction(self.menu_Settings.menuAction()) self.menu_bar.addAction(self.menu_Help.menuAction()) self.tool_bar.addAction(self.actionAddCards) self.tool_bar.addAction(self.actionEditCurrentCard) self.tool_bar.addAction(self.actionDeleteCurrentCard) self.tool_bar.addAction(self.actionBrowseCards) self.tool_bar.addAction(self.actionShowStatistics) self.retranslateUi(MainWdgt) QtCore.QObject.connect(self.actionAddCards, QtCore.SIGNAL(_fromUtf8("triggered()")), MainWdgt.add_cards) QtCore.QObject.connect(self.actionFileNew, QtCore.SIGNAL(_fromUtf8("triggered()")), MainWdgt.file_new) QtCore.QObject.connect(self.actionFileOpen, QtCore.SIGNAL(_fromUtf8("triggered()")), MainWdgt.file_open) QtCore.QObject.connect(self.actionFileSave, QtCore.SIGNAL(_fromUtf8("triggered()")), MainWdgt.file_save) QtCore.QObject.connect(self.actionFileSaveAs, QtCore.SIGNAL(_fromUtf8("triggered()")), MainWdgt.file_save_as) QtCore.QObject.connect(self.actionFileExit, QtCore.SIGNAL(_fromUtf8("triggered()")), MainWdgt.close) QtCore.QObject.connect(self.actionEditCurrentCard, QtCore.SIGNAL(_fromUtf8("triggered()")), MainWdgt.edit_current_card) QtCore.QObject.connect(self.actionDeleteCurrentCard, QtCore.SIGNAL(_fromUtf8("triggered()")), MainWdgt.delete_current_card) QtCore.QObject.connect(self.actionManagePlugins, QtCore.SIGNAL(_fromUtf8("triggered()")), MainWdgt.manage_plugins) QtCore.QObject.connect(self.actionManageTypes, QtCore.SIGNAL(_fromUtf8("triggered()")), MainWdgt.manage_card_types) QtCore.QObject.connect(self.actionShowStatistics, QtCore.SIGNAL(_fromUtf8("triggered()")), MainWdgt.show_statistics) QtCore.QObject.connect(self.actionImport, QtCore.SIGNAL(_fromUtf8("triggered()")), MainWdgt.import_file) QtCore.QObject.connect(self.actionExport, QtCore.SIGNAL(_fromUtf8("triggered()")), MainWdgt.export_file) QtCore.QObject.connect(self.actionConfigure, QtCore.SIGNAL(_fromUtf8("triggered()")), MainWdgt.configure) QtCore.QObject.connect(self.actionActivateCards, QtCore.SIGNAL(_fromUtf8("triggered()")), MainWdgt.activate_cards) QtCore.QObject.connect(self.actionSync, QtCore.SIGNAL(_fromUtf8("triggered()")), MainWdgt.sync) QtCore.QObject.connect(self.actionBrowseCards, QtCore.SIGNAL(_fromUtf8("triggered()")), MainWdgt.browse_cards) QtCore.QObject.connect(self.actionTip, QtCore.SIGNAL(_fromUtf8("triggered()")), MainWdgt.show_tip) QtCore.QObject.connect(self.actionGettingStarted, QtCore.SIGNAL(_fromUtf8("triggered()")), MainWdgt.show_getting_started) QtCore.QObject.connect(self.actionAbout, QtCore.SIGNAL(_fromUtf8("triggered()")), MainWdgt.show_about) QtCore.QObject.connect(self.actionCompact, QtCore.SIGNAL(_fromUtf8("triggered()")), MainWdgt.compact_database) QtCore.QObject.connect(self.actionFindDuplicates, QtCore.SIGNAL(_fromUtf8("triggered()")), MainWdgt.find_duplicates) QtCore.QMetaObject.connectSlotsByName(MainWdgt) def retranslateUi(self, MainWdgt): self.menu_Settings.setTitle(_('&Settings')) self.menu_Help.setTitle(_('&Help')) self.menuFile.setTitle(_('&File')) self.menu_Cards.setTitle(_('&Cards')) self.tool_bar.setWindowTitle(_('toolBar')) self.actionActivateCards.setText(_('(De)a&ctivate cards...')) self.actionActivateCards.setShortcut(_('Ctrl+D')) self.actionAddCards.setText(_('&Add cards...')) self.actionAddCards.setShortcut(_('Ctrl+A')) self.actionConfigure.setText(_('&Configure Mnemosyne...')) self.actionDeleteCurrentCard.setText(_('&Delete current card')) self.actionDeleteCurrentCard.setShortcut(_('Del')) self.actionEditCurrentCard.setText(_('&Edit current card...')) self.actionEditCurrentCard.setShortcut(_('Ctrl+E')) self.actionBrowseCards.setText(_('&Browse cards...')) self.actionBrowseCards.setShortcut(_('Ctrl+B')) self.actionExport.setText(_('&Export...')) self.actionFileExit.setText(_('E&xit')) self.actionFileNew.setText(_('&New...')) self.actionFileNew.setShortcut(_('Ctrl+N')) self.actionFileOpen.setText(_('&Open...')) self.actionFileOpen.setShortcut(_('Ctrl+O')) self.actionFileSave.setText(_('&Save')) self.actionFileSave.setShortcut(_('Ctrl+S')) self.actionFileSaveAs.setText(_('Save &as...')) self.actionAbout.setText(_('&About')) self.actionImport.setText(_('&Import...')) self.actionGettingStarted.setText(_('&Getting started')) self.actionShowStatistics.setText(_('Show s&tatistics...')) self.actionShowStatistics.setShortcut(_('Ctrl+T')) self.actionTip.setText(_('&Tip of the day')) self.actionManagePlugins.setText(_('Manage &plugins...')) self.actionManagePlugins.setToolTip(_('Manage plugins')) self.actionManageTypes.setText(_('&Manage card types...')) self.actionSync.setText(_('S&ync...')) self.actionSync.setShortcut(_('Ctrl+Y')) self.actionCompact.setText(_('Compact...')) self.actionCompact.setToolTip(_('Compact database')) self.actionFindDuplicates.setText(_('Find duplicates')) import mnemosyne_rc Mnemosyne-2.2.1/mnemosyne/pyqt_ui/getting_started_dlg.py0000644000175000017500000000241211721410551024707 0ustar pbienstpbienst00000000000000# # intro_wizard_dlg.py # from PyQt4 import QtGui, QtCore from mnemosyne.pyqt_ui.ui_getting_started_dlg import Ui_GettingStartedDlg from mnemosyne.libmnemosyne.ui_components.dialogs import GettingStartedDialog class GettingStartedDlg(QtGui.QWizard, Ui_GettingStartedDlg, GettingStartedDialog): def __init__(self, component_manager): GettingStartedDialog.__init__(self, component_manager) QtGui.QWizard.__init__(self, self.main_widget()) self.setupUi(self) self.setWindowFlags(self.windowFlags() \ | QtCore.Qt.WindowMinMaxButtonsHint) self.setWindowFlags(self.windowFlags() \ & ~ QtCore.Qt.WindowContextHelpButtonHint) # Note: the svg file does not seem to work under windows. #watermark = QtGui.QPixmap(":/mnemosyne/pixmaps/mnemosyne.svg")\ # .scaledToHeight(200, QtCore.Qt.SmoothTransformation) watermark = QtGui.QPixmap(":/mnemosyne/pixmaps/mnemosyne.png") self.setPixmap(QtGui.QWizard.WatermarkPixmap, watermark) def activate(self): GettingStartedDialog.activate(self) self.show() def accept(self): self.config()["upload_science_logs"] = self.upload_box.isChecked() QtGui.QWizard.accept(self) Mnemosyne-2.2.1/mnemosyne/pyqt_ui/main_wdgt.py0000644000175000017500000001707612125037272022663 0ustar pbienstpbienst00000000000000# # main_wdgt.py # import sys from PyQt4 import QtCore, QtGui from mnemosyne.libmnemosyne.translator import _ from mnemosyne.pyqt_ui.ui_main_wdgt import Ui_MainWdgt from mnemosyne.libmnemosyne.ui_components.main_widget import MainWidget class MainWdgt(QtGui.QMainWindow, Ui_MainWdgt, MainWidget): def __init__(self, component_manager): MainWidget.__init__(self, component_manager) QtGui.QMainWindow.__init__(self) self.setupUi(self) # Qt designer does not allow setting multiple shortcuts per action. self.actionDeleteCurrentCard.setShortcuts\ ([QtCore.Qt.Key_Delete, QtCore.Qt.Key_Backspace]) self.status_bar_widgets = [] self.progress_bar = None self.progress_bar_update_interval = 1 self.progress_bar_last_shown_value = 0 def _store_state(self): self.config()["main_window_state"] = self.saveGeometry() def changeEvent(self, event): if event.type() == QtCore.QEvent.LanguageChange: self.retranslateUi(self) else: QtGui.QMainWindow.changeEvent(self, event) def createPopupMenu(self): # Don't create a silly popup menu saying ('toolBar'). pass def closeEvent(self, event): # Generated when clicking the window's close button. self._store_state() def activate(self): state = self.config()["main_window_state"] if state: self.restoreGeometry(state) self.timer = QtCore.QTimer() self.timer.timeout.connect(self.controller_heartbeat) self.timer.start(1000) # 1 sec. self.start_review() self.retranslateUi(self) def controller_heartbeat(self): # Need late binding to allow for inheritance. self.controller().heartbeat() def set_window_title(self, text): # Qt bug: seems to only work if no title was defined in the *.ui file. self.setWindowTitle(text) def top_window(self): for widget in QtGui.QApplication.topLevelWidgets(): if not widget.__class__.__name__.startswith("Q") and \ widget.__class__.__name__ != "MainWdgt" and \ widget.isVisible() == True: return widget return self def show_information(self, text): QtGui.QMessageBox.information(self.top_window(), _("Mnemosyne"), text, _("&OK")) def show_question(self, text, option0, option1, option2): return QtGui.QMessageBox.question(self.top_window(), _("Mnemosyne"), text, option0, option1, option2, 0, -1) def show_error(self, text): QtGui.QMessageBox.critical(self.top_window(), _("Mnemosyne"), text, _("&OK"), "", "", 0, -1) def default_font_size(self): return QtGui.qApp.font().pointSize() def get_filename_to_open(self, path, filter, caption=""): return unicode(QtGui.QFileDialog.\ getOpenFileName(self, caption, path, filter)) def get_filename_to_save(self, path, filter, caption=""): return unicode(QtGui.QFileDialog.\ getSaveFileName(self, caption, path, filter)) def set_status_bar_message(self, text): self.status_bar.showMessage(text) def set_progress_text(self, text): if self.progress_bar: self.progress_bar.close() self.progress_bar = None if not self.progress_bar: self.progress_bar = QtGui.QProgressDialog(self.top_window()) self.progress_bar.setWindowTitle(_("Mnemosyne")) self.progress_bar.setWindowModality(QtCore.Qt.WindowModal) self.progress_bar.setCancelButton(None) self.progress_bar.setMinimumDuration(0) self.progress_bar.setLabelText(text) self.progress_bar.setRange(0, 0) self.progress_bar_update_interval = 1 self.progress_bar_current_value = 0 self.progress_bar_last_shown_value = 0 self.progress_bar.setValue(0) self.progress_bar.show() def set_progress_range(self, maximum): self.progress_bar.setRange(0, maximum) def set_progress_update_interval(self, update_interval): update_interval = int(update_interval) if update_interval == 0: update_interval = 1 self.progress_bar_update_interval = update_interval def increase_progress(self, value): self.set_progress_value(self.progress_bar_current_value + value) def set_progress_value(self, value): # There is a possibility that 'value' does not visit all intermediate # integer values in the range, so we need to check and store the last # shown and the current value here. self.progress_bar_current_value = value if value - self.progress_bar_last_shown_value >= \ self.progress_bar_update_interval: self.progress_bar.setValue(value) self.progress_bar_last_shown_value = value # This automatically processes events too. Calling processEvents # explictly here might even cause some crashes. def close_progress(self): if self.progress_bar: self.progress_bar.close() self.progress_bar = None def enable_edit_current_card(self, is_enabled): self.actionEditCurrentCard.setEnabled(is_enabled) def enable_delete_current_card(self, is_enabled): self.actionDeleteCurrentCard.setEnabled(is_enabled) def enable_browse_cards(self, is_enabled): self.actionBrowseCards.setEnabled(is_enabled) def add_to_status_bar(self, widget): self.status_bar_widgets.append(widget) self.status_bar.addPermanentWidget(widget) def clear_status_bar(self): for widget in self.status_bar_widgets: self.status_bar.removeWidget(widget) self.status_bar_widgets = [] def file_new(self): self.controller().show_new_file_dialog() def file_open(self): self.controller().show_open_file_dialog() def file_save(self): self.controller().save_file() def file_save_as(self): self.controller().show_save_file_as_dialog() def compact_database(self): self.controller().show_compact_database_dialog() def import_file(self): self.controller().show_import_file_dialog() def export_file(self): self.controller().show_export_file_dialog() def import_file(self): self.controller().show_import_file_dialog() def sync(self): self.controller().show_sync_dialog() def add_cards(self): self.controller().show_add_cards_dialog() def edit_current_card(self): self.controller().show_edit_card_dialog() def delete_current_card(self): self.controller().delete_current_card() def browse_cards(self): self.controller().show_browse_cards_dialog() def activate_cards(self): self.controller().show_activate_cards_dialog() def find_duplicates(self): self.controller().find_duplicates() def manage_card_types(self): self.controller().show_manage_card_types_dialog() def configure(self): self.controller().show_configuration_dialog() def set_card_appearance(self): self.controller().show_card_appearance_dialog() def manage_plugins(self): self.controller().show_manage_plugins_dialog() def show_statistics(self): self.controller().show_statistics_dialog() def show_getting_started(self): self.controller().show_getting_started_dialog() def show_tip(self): self.controller().show_tip_dialog() def show_about(self): self.controller().show_about_dialog() Mnemosyne-2.2.1/mnemosyne/pyqt_ui/tip_dlg.py0000644000175000017500000002120212026040117022306 0ustar pbienstpbienst00000000000000# # tip_dlg.py # from PyQt4 import QtCore, QtGui from mnemosyne.libmnemosyne.translator import _ from mnemosyne.pyqt_ui.ui_tip_dlg import Ui_TipDlg from mnemosyne.libmnemosyne.ui_components.dialogs import TipDialog class TipDlg(QtGui.QDialog, Ui_TipDlg, TipDialog): def __init__(self, component_manager): TipDialog.__init__(self, component_manager) QtGui.QDialog.__init__(self, self.main_widget()) self.tips = [] self.tips.append(_("""For optimal results, it's best to do your repetitions every day.""")) self.tips.append(_("""You don't need to finish all your daily scheduled repetitions in a single session.""")) self.tips.append(_("""If you've been away for a few days, don't worry about your backlog. Do as many cards as you feel like to catch up, the rest will be automatically rescheduled to the future in the most optimal way.""")) self.tips.append(_("""Sister cards are cards which are based on the same information, e.g. a front-to-back card and the corresponding back-to-front card. Mnemosyne will avoid scheduling these on the same day.""")) self.tips.append(_("""The 'number of non-memorised cards to hold in your hand' setting determines how many cards you are trying to (re)learn at the same time. It does not tell you how many new cards you need to learn per day. You are the judge of that: you can learn more cards or less cards, depending on how you feel.""")) self.tips.append(_("""In summary, try to do your repetitions every day, but don't worry too much about getting the 'Scheduled' counter to zero, and certainly not about getting the 'Not memorised' counter to zero.""")) self.tips.append(_("""Grade 1 cards are different from grade 0 cards in the sense that they show up less often.""")) self.tips.append(_("""Use 'Learn ahead of schedule' sparingly. For cramming before an exam, it's much better to use the cramming scheduler plugin.""")) self.tips.append(_("""You can use keyboard shortcuts to do your repetitions. Enter, Return or Space stand for the default action. The number keys can be used for grading.""")) self.tips.append(_("""You can select which cards you wish to study in the '(De)activate cards' menu option.""")) self.tips.append(_("""It is recommended to put all your cards in a single database and use tag to organise them. Using '(De)activate cards' is much more convenient than having to load and unload several databases.""")) self.tips.append(_("""You can add multiple tags to a card by separating tags with a comma in the 'Tag(s)' input field.""")) self.tips.append(_("""You can organise tags in a hierarchy by using :: as separator, e.g. My book::Lesson 1.""")) self.tips.append(_("""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.""")) self.tips.append(_("""You can make clones of existing card types. This allows you to format cards in this type independently from cards in the original type. E.g. you can make a clone of 'Vocabulary', call it 'Thai' and set a Thai font specifically for this card type without disturbing your other cards.""")) self.tips.append(_("""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.""")) self.tips.append(_("""You can use basic HTML tags in your cards to control their appearance. However, if you want all the fields in a certain card type to look the same, it's easier to use the 'Set card appearance' menu option.""")) self.tips.append(_("""Using 'File - Sync', you can sync this machine with a remote server. Of course, that remote computer needs to have a server running, which can be started from the configuration screen on that remote machine.""")) self.tips.append(_(""" If you want to sync a mobile device with this computer, don't use 'File - Sync', but first enable a sync server in the configuration dialog, and then start the sync from the mobile device.""")) self.tips.append(_("""In the 'Activate cards' dialog, you can right-click on a saved set to rename or delete it.""")) self.tips.append(_("""In the 'Activate cards' dialog, you can double-click on a saved set to activate it and close the dialog.""")) self.tips.append(_("""Right-click on a tag name in the card browser to edit or delete it.""")) self.tips.append(_("""Double-click on a card or tag name in the card browser to edit them.""")) self.tips.append(_("""You can reorder columns in the card browser by dragging the header label.""")) self.tips.append(_("""You can resize columns in the card browser by dragging between the header labels.""")) self.tips.append(_("""When editing or previewing cards from the card browser, PageUp/PageDown can be used to move to the previous/next card.""")) self.tips.append(_("""In the 'Add cards' dialog, use Tab to move between different fields, Ctrl+Enter for 'Yet to learn', and Ctrl+2, etc. for the grades.""")) self.tips.append(_("""In the 'Edit card' dialog, use Tab to move between different fields and Ctrl+Enter to close the dialog.""")) self.tips.append(_("""Mnemosyne can use LaTeX to render mathematical formulas, e.g. <$>x^2+y^2=z^2. (For this, you need LaTeX and dvipng installed.)""")) self.tips.append(_("""The best way to backup your data is to copy your mnemosyne data directory and move it to a different drive. Mnemosyne keeps automatic backups, but that won't help you if that drive dies...""")) self.tips.append(_("""You can sort the cards in the 'Browse cards' dialog by by clicking on a column title. Clicking again changes the sort order.""")) self.tips.append(_("""If you want more fine-grained control over LaTeX's behaviour, see the explanation of the <$$>... and ... tags on Mnemosyne's website.""")) self.tips.append(_("""For optimal performance, keep your drives defragmented.""")) self.tips.append(_("""For optimal performance, do not put your database on a network drive.""")) self.tips.append(_("""For optimal performance, run 'File - Compact' from time to time, especially after deleting many cards.""")) self.tips.append(_("""Advanced users can customise more of Mnemosyne by editing the config.py file in their mnemosyne directory. They can also install additional plugins to customise Mnemosyne even further.""")) self.tips.append(_("""You can follow the development of Mnemosyne at Google+.""")) self.tips.append(_("""You can request new features and vote for exisiting requests at uservoice. This helps the developers decide what to work on next.""")) self.setupUi(self) self.setWindowFlags(self.windowFlags() \ | QtCore.Qt.WindowMinMaxButtonsHint) self.setWindowFlags(self.windowFlags() \ & ~ QtCore.Qt.WindowContextHelpButtonHint) if self.config()["show_daily_tips"] == True: self.show_tips.setCheckState(QtCore.Qt.Checked) else: self.show_tips.setCheckState(QtCore.Qt.Unchecked) # Note: the svg file does not seem to work under windows. #watermark = QtGui.QPixmap(":/mnemosyne/pixmaps/mnemosyne.svg").\ # scaledToHeight(200, QtCore.Qt.SmoothTransformation) watermark = QtGui.QPixmap(":/mnemosyne/pixmaps/mnemosyne.png") self.watermark.setPixmap(watermark) self.update_dialog() def activate(self): TipDialog.activate(self) self.show() def update_dialog(self): # We need an extra modulo operation here to deal with the possibility # of decreasing the number of tips during upgrade. tip = self.config()["current_tip"] % len(self.tips) self.tip_label.setText(self.tips[tip]) self.previous_button.setEnabled(tip != 0) self.next_button.setEnabled(tip != len(self.tips) - 1) def previous(self): self.config()["current_tip"] = \ (self.config()["current_tip"] - 1) % len(self.tips) self.update_dialog() def next(self): self.config()["current_tip"] = \ (self.config()["current_tip"] + 1) % len(self.tips) self.update_dialog() def reject(self): self.close() def closeEvent(self, event): self.config()["show_daily_tips"] = self.show_tips.isChecked() self.config()["current_tip"] = \ (self.config()["current_tip"] + 1) % len(self.tips) event.accept() Mnemosyne-2.2.1/mnemosyne/pyqt_ui/sync_dlg.py0000644000175000017500000002060312120041063022466 0ustar pbienstpbienst00000000000000# # sync_dlg.py # import sys from PyQt4 import QtCore, QtGui from mnemosyne.libmnemosyne.translator import _ from mnemosyne.pyqt_ui.ui_sync_dlg import Ui_SyncDlg from mnemosyne.libmnemosyne.utils import traceback_string from mnemosyne.libmnemosyne.ui_components.dialogs import SyncDialog # Thread synchronisation machinery to communicate the result of a question # box to the sync thread. answer = None mutex = QtCore.QMutex() dialog_closed = QtCore.QWaitCondition() class SyncThread(QtCore.QThread): """We do the syncing in a separate thread so that the GUI still stays responsive when waiting for the server. Note that in Qt, we cannot do GUI updates in the server thread, so we use the signal/slot mechanism to notify the main thread to do the necessary GUI operations. """ information_signal = QtCore.pyqtSignal(QtCore.QString) error_signal = QtCore.pyqtSignal(QtCore.QString) question_signal = QtCore.pyqtSignal(QtCore.QString, QtCore.QString, QtCore.QString, QtCore.QString) set_progress_text_signal = QtCore.pyqtSignal(QtCore.QString) set_progress_range_signal = QtCore.pyqtSignal(int) set_progress_update_interval_signal = QtCore.pyqtSignal(int) increase_progress_signal = QtCore.pyqtSignal(int) set_progress_value_signal = QtCore.pyqtSignal(int) close_progress_signal = QtCore.pyqtSignal() def __init__(self, mnemosyne, server, port, username, password): QtCore.QThread.__init__(self) self.mnemosyne = mnemosyne self.server = server self.port = port self.username = username self.password = password # A fast moving progress bar seems to cause crashes on Windows. self.show_numeric_progress_bar = (sys.platform != "win32") def run(self): try: # Libmnemosyne itself could also generate dialog messages, so # we temporarily override the main_widget with the threaded # routines in this class. self.mnemosyne.component_manager.components\ [None]["main_widget"].append(self) self.mnemosyne.controller().sync(self.server, self.port, self.username, self.password, ui=self) finally: self.mnemosyne.database().release_connection() self.mnemosyne.component_manager.components\ [None]["main_widget"].pop() def show_information(self, message): global answer mutex.lock() answer = None self.information_signal.emit(message) if not answer: dialog_closed.wait(mutex) mutex.unlock() def show_error(self, error): global answer mutex.lock() answer = None self.error_signal.emit(error) if not answer: dialog_closed.wait(mutex) mutex.unlock() def show_question(self, question, option0, option1, option2): global answer mutex.lock() answer = None self.question_signal.emit(question, option0, option1, option2) if not answer: dialog_closed.wait(mutex) mutex.unlock() return answer def set_progress_text(self, text): self.set_progress_text_signal.emit(text) def set_progress_range(self, maximum): if self.show_numeric_progress_bar: self.set_progress_range_signal.emit(maximum) def set_progress_update_interval(self, value): if self.show_numeric_progress_bar: self.set_progress_update_interval_signal.emit(value) def increase_progress(self, value): if self.show_numeric_progress_bar: self.increase_progress_signal.emit(value) def set_progress_value(self, value): if self.show_numeric_progress_bar: self.set_progress_value_signal.emit(value) def close_progress(self): self.close_progress_signal.emit() class SyncDlg(QtGui.QDialog, Ui_SyncDlg, SyncDialog): def __init__(self, component_manager): SyncDialog.__init__(self, component_manager) QtGui.QDialog.__init__(self, self.main_widget()) self.setupUi(self) self.setWindowFlags(self.windowFlags() \ | QtCore.Qt.WindowMinMaxButtonsHint) self.setWindowFlags(self.windowFlags() \ & ~ QtCore.Qt.WindowContextHelpButtonHint) if not self.config()["sync_help_shown"]: self.main_widget().show_information(\ _("Here, you can sync this machine with a remote server. Of course, that remote computer needs to have a server running, which can be started from the configuration screen on that remote machine.\n\nHowever, if you want to sync a mobile device with this machine here, you shouldn't use the menu option you just selected. In that case, this computer needs to be the server. So, first enable a sync server here, and then start the sync from the mobile device.")) self.config()["sync_help_shown"] = True self.server.setText(self.config()["server_for_sync_as_client"]) self.port.setValue(self.config()["port_for_sync_as_client"]) self.username.setText(self.config()["username_for_sync_as_client"]) self.password.setText(self.config()["password_for_sync_as_client"]) self.check_for_edited_local_media_files.setChecked(\ self.config()["check_for_edited_local_media_files"]) if self.config()["server_for_sync_as_client"]: self.ok_button.setFocus() self.can_reject = True # Since we will overwrite the true main widget in the thread, we need # to save it here. self.true_main_widget = self.main_widget() def activate(self): self.exec_() def accept(self): # Store input for later use. server = unicode(self.server.text()) port = self.port.value() username = unicode(self.username.text()) password = unicode(self.password.text()) self.config()["server_for_sync_as_client"] = server self.config()["port_for_sync_as_client"] = port self.config()["username_for_sync_as_client"] = username self.config()["password_for_sync_as_client"] = password self.config()["check_for_edited_local_media_files"] = \ self.check_for_edited_local_media_files.isChecked() # Prevent user from interrupting a sync. self.can_reject = False self.ok_button.setEnabled(False) self.cancel_button.setEnabled(False) # Do the actual sync in a separate thread. self.database().release_connection() self.thread = SyncThread(self, server, port, username, password) self.thread.information_signal.connect(\ self.threaded_show_information) self.thread.error_signal.connect(\ self.threaded_show_error) self.thread.question_signal.connect(\ self.threaded_show_question) self.thread.set_progress_text_signal.connect(\ self.true_main_widget.set_progress_text) self.thread.set_progress_range_signal.connect(\ self.true_main_widget.set_progress_range) self.thread.set_progress_update_interval_signal.connect(\ self.true_main_widget.set_progress_update_interval) self.thread.increase_progress_signal.connect(\ self.true_main_widget.increase_progress) self.thread.set_progress_value_signal.connect(\ self.true_main_widget.set_progress_value) self.thread.close_progress_signal.connect(\ self.true_main_widget.close_progress) self.thread.finished.connect(self.finish_sync) self.thread.start() def reject(self): if self.can_reject: QtGui.QDialog.reject(self) def finish_sync(self): QtGui.QDialog.accept(self) def threaded_show_information(self, message): global answer mutex.lock() self.true_main_widget.show_information(message) answer = True dialog_closed.wakeAll() mutex.unlock() def threaded_show_error(self, error): global answer mutex.lock() self.true_main_widget.show_error(error) answer = True dialog_closed.wakeAll() mutex.unlock() def threaded_show_question(self, question, option0, option1, option2): global answer mutex.lock() answer = self.true_main_widget.show_question(question, option0, option1, option2) dialog_closed.wakeAll() mutex.unlock() Mnemosyne-2.2.1/mnemosyne/pyqt_ui/ui_manage_plugins_dlg.py0000644000175000000000000001007612132771332024521 0ustar pbienstroot00000000000000# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'manage_plugins_dlg.ui' # # Created: Mon Apr 15 14:30:18 2013 # by: PyQt4 UI code generator 4.9.3 # # WARNING! All changes made in this file will be lost! from mnemosyne.libmnemosyne.translator import _ from PyQt4 import QtCore, QtGui try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: _fromUtf8 = lambda s: s class Ui_ManagePluginsDlg(object): def setupUi(self, ManagePluginsDlg): ManagePluginsDlg.setObjectName(_fromUtf8("ManagePluginsDlg")) ManagePluginsDlg.resize(382, 488) self.verticalLayout_2 = QtGui.QVBoxLayout(ManagePluginsDlg) self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2")) self.verticalLayout = QtGui.QVBoxLayout() self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) self.label = QtGui.QLabel(ManagePluginsDlg) self.label.setObjectName(_fromUtf8("label")) self.verticalLayout.addWidget(self.label) self.plugin_list = QtGui.QListWidget(ManagePluginsDlg) self.plugin_list.setMinimumSize(QtCore.QSize(350, 200)) self.plugin_list.setObjectName(_fromUtf8("plugin_list")) self.verticalLayout.addWidget(self.plugin_list) self.label_2 = QtGui.QLabel(ManagePluginsDlg) self.label_2.setObjectName(_fromUtf8("label_2")) self.verticalLayout.addWidget(self.label_2) self.plugin_description = QtGui.QTextBrowser(ManagePluginsDlg) self.plugin_description.setMinimumSize(QtCore.QSize(350, 200)) self.plugin_description.setObjectName(_fromUtf8("plugin_description")) self.verticalLayout.addWidget(self.plugin_description) self.hboxlayout = QtGui.QHBoxLayout() self.hboxlayout.setObjectName(_fromUtf8("hboxlayout")) self.ok_button = QtGui.QPushButton(ManagePluginsDlg) self.ok_button.setAutoDefault(True) self.ok_button.setDefault(True) self.ok_button.setObjectName(_fromUtf8("ok_button")) self.hboxlayout.addWidget(self.ok_button) self.install_button = QtGui.QPushButton(ManagePluginsDlg) self.install_button.setObjectName(_fromUtf8("install_button")) self.hboxlayout.addWidget(self.install_button) self.delete_button = QtGui.QPushButton(ManagePluginsDlg) self.delete_button.setObjectName(_fromUtf8("delete_button")) self.hboxlayout.addWidget(self.delete_button) self.exit_button = QtGui.QPushButton(ManagePluginsDlg) self.exit_button.setAutoDefault(False) self.exit_button.setObjectName(_fromUtf8("exit_button")) self.hboxlayout.addWidget(self.exit_button) self.verticalLayout.addLayout(self.hboxlayout) self.verticalLayout_2.addLayout(self.verticalLayout) self.retranslateUi(ManagePluginsDlg) QtCore.QObject.connect(self.exit_button, QtCore.SIGNAL(_fromUtf8("clicked()")), ManagePluginsDlg.reject) QtCore.QObject.connect(self.ok_button, QtCore.SIGNAL(_fromUtf8("clicked()")), ManagePluginsDlg.accept) QtCore.QObject.connect(self.install_button, QtCore.SIGNAL(_fromUtf8("clicked()")), ManagePluginsDlg.install_plugin) QtCore.QObject.connect(self.delete_button, QtCore.SIGNAL(_fromUtf8("clicked()")), ManagePluginsDlg.delete_plugin) QtCore.QObject.connect(self.plugin_list, QtCore.SIGNAL(_fromUtf8("currentItemChanged(QListWidgetItem*,QListWidgetItem*)")), ManagePluginsDlg.plugin_selected) QtCore.QObject.connect(self.plugin_list, QtCore.SIGNAL(_fromUtf8("itemClicked(QListWidgetItem*)")), ManagePluginsDlg.plugin_selected) QtCore.QMetaObject.connectSlotsByName(ManagePluginsDlg) def retranslateUi(self, ManagePluginsDlg): ManagePluginsDlg.setWindowTitle(_('Manage plugins')) self.label.setText(_('Installed plugins (active and inactive):')) self.label_2.setText(_('Plugin description:')) self.ok_button.setText(_('&OK')) self.install_button.setText(_('&Install new plugin')) self.delete_button.setText(_('&Delete plugin')) self.exit_button.setText(_('E&xit')) import mnemosyne_rc Mnemosyne-2.2.1/mnemosyne/pyqt_ui/preview_cards_dlg.py0000644000175000017500000000661512113345363024372 0ustar pbienstpbienst00000000000000# # Widget to preview set of sister cards # from PyQt4 import QtCore, QtGui from mnemosyne.libmnemosyne.translator import _ from mnemosyne.libmnemosyne.component import Component from mnemosyne.pyqt_ui.review_wdgt import QAOptimalSplit from mnemosyne.pyqt_ui.ui_preview_cards_dlg import Ui_PreviewCardsDlg class PreviewCardsDlg(QtGui.QDialog, Ui_PreviewCardsDlg, Component, QAOptimalSplit): page_up_down_signal = QtCore.pyqtSignal(int) UP = 0 DOWN = 1 def __init__(self, component_manager, cards, tag_text, parent=None): """We need to provide tag_text explicitly, since it's possible that the cards have not yet been added to the database. """ Component.__init__(self, component_manager) if parent is None: parent = self.main_widget() QtGui.QDialog.__init__(self, parent) self.setupUi(self) QAOptimalSplit.__init__(self) self.used_for_reviewing = False self.setWindowFlags(self.windowFlags() \ | QtCore.Qt.WindowMinMaxButtonsHint) self.setWindowFlags(self.windowFlags() \ & ~ QtCore.Qt.WindowContextHelpButtonHint) self.tag_text = tag_text self.cards = cards self.index = 0 state = self.config()["preview_cards_dlg_state"] if state: self.restoreGeometry(state) self.update_dialog() def keyPressEvent(self, event): """When this dialog is called from the card browser, PageUp and PageDown keys can be used to move the previous/next card in the list. """ if event.key() == QtCore.Qt.Key_PageUp: self.page_up_down_signal.emit(self.UP) elif event.key() == QtCore.Qt.Key_PageDown: self.page_up_down_signal.emit(self.DOWN) # Note QtGui.QWidget.keyPressEvent(self, event) does not seem to work, # so we handle the most common keypresses here too. if event.key() == QtCore.Qt.Key_Escape: self.reject() if event.key() in [QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return]: self.accept() else: QtGui.QWidget.keyPressEvent(self, event) def update_dialog(self): self.question_label.setText(_("Question: ") + self.tag_text) if len(self.cards) == 1: self.previous_button.setVisible(False) self.next_button.setVisible(False) self.fact_view_name.setVisible(False) card = self.cards[self.index] self.set_question(card.question()) self.set_answer(card.answer()) self.reveal_question() self.reveal_answer() self.fact_view_name.setText(_(card.fact_view.name) + " (" + \ str(self.index + 1) + "/" + str(len(self.cards)) + ")") self.previous_button.setEnabled(self.index != 0) self.next_button.setEnabled(self.index != len(self.cards) - 1) def previous(self): self.index -= 1 self.update_dialog() def next(self): self.index += 1 self.update_dialog() def _store_state(self): self.config()["preview_cards_dlg_state"] = self.saveGeometry() def closeEvent(self, event): # Generated when clicking the window's close button. self._store_state() def accept(self): # 'accept' does not generate a close event. self._store_state() return QtGui.QDialog.accept(self) Mnemosyne-2.2.1/mnemosyne/pyqt_ui/about_dlg.py0000664000175000017500000000306611763064402022650 0ustar pbienstpbienst00000000000000# # about_dlg.py # from PyQt4 import QtCore, QtGui from mnemosyne.version import version from mnemosyne.libmnemosyne.translator import _ from mnemosyne.pyqt_ui.ui_about_dlg import Ui_AboutDlg from mnemosyne.libmnemosyne.ui_components.dialogs import AboutDialog class AboutDlg(QtGui.QDialog, Ui_AboutDlg, AboutDialog): def __init__(self, component_manager): AboutDialog.__init__(self, component_manager) QtGui.QDialog.__init__(self, self.main_widget()) self.setupUi(self) self.setWindowFlags(self.windowFlags() \ | QtCore.Qt.WindowMinMaxButtonsHint) self.setWindowFlags(self.windowFlags() \ & ~ QtCore.Qt.WindowContextHelpButtonHint) # Note: the svg file does not seem to work under windows. #watermark = QtGui.QPixmap(":/mnemosyne/pixmaps/mnemosyne.svg").\ # scaledToHeight(200, QtCore.Qt.SmoothTransformation) watermark = QtGui.QPixmap(":/mnemosyne/pixmaps/mnemosyne.png") self.watermark.setPixmap(watermark) self.about_label.setText("" + _("Mnemosyne") + " " + version + "

" + \ _("Main author: Peter Bienstman") + "

" + \ _("""Invaluable contributions from many people are acknowledged here.""") + "

" + \ _("""Go to http://www.mnemosyne-proj.org for more information and source code.""")) def activate(self): AboutDialog.activate(self) self.show() Mnemosyne-2.2.1/mnemosyne/pyqt_ui/configuration_wdgt_main.py0000644000175000017500000001076012021577030025577 0ustar pbienstpbienst00000000000000# # configuration_wdgt_main.py # import sys from PyQt4 import QtCore, QtGui from mnemosyne.libmnemosyne.translator import _, \ iso6931_code_for_language_name, language_name_for_iso6931_code from mnemosyne.libmnemosyne.ui_components.configuration_widget import \ ConfigurationWidget from mnemosyne.pyqt_ui.ui_configuration_wdgt_main import \ Ui_ConfigurationWdgtMain class ConfigurationWdgtMain(QtGui.QWidget, Ui_ConfigurationWdgtMain, ConfigurationWidget): name = _("General") def __init__(self, component_manager, parent): ConfigurationWidget.__init__(self, component_manager) QtGui.QDialog.__init__(self, parent) self.setupUi(self) if self.config()["randomise_new_cards"] == True: self.new_cards.setCurrentIndex(1) else: self.new_cards.setCurrentIndex(0) if self.config()["randomise_scheduled_cards"] == True: self.scheduled_cards.setCurrentIndex(1) else: self.scheduled_cards.setCurrentIndex(0) self.non_memorised_cards.setValue(self.config()\ ["non_memorised_cards_in_hand"]) self.save_after_n_reps.setValue(self.config()\ ["save_after_n_reps"]) if self.config()["media_autoplay"] == True: self.media_autoplay.setCheckState(QtCore.Qt.Checked) else: self.media_autoplay.setCheckState(QtCore.Qt.Unchecked) if self.config()["media_controls"] == True: self.media_controls.setCheckState(QtCore.Qt.Checked) else: self.media_controls.setCheckState(QtCore.Qt.Unchecked) if self.config()["upload_science_logs"] == True: self.upload_science_logs.setCheckState(QtCore.Qt.Checked) else: self.upload_science_logs.setCheckState(QtCore.Qt.Unchecked) language_names = ["English"] for language in self.translator().supported_languages(): language_names.append(language_name_for_iso6931_code[language]) language_names.sort() for language_name in language_names: self.languages.addItem(language_name) self.languages.setCurrentIndex(self.languages.findText(\ language_name_for_iso6931_code[self.config()["ui_language"]])) self.media_autoplay.stateChanged.connect(self.changed_media_autoplay) if sys.platform == "win32": self.audio_box.hide() def changed_media_autoplay(self, state): if state == QtCore.Qt.Unchecked: self.media_controls.setCheckState(QtCore.Qt.Checked) def reset_to_defaults(self): answer = self.main_widget().show_question(\ _("Reset current tab to defaults?"), _("&Yes"), _("&No"), "") if answer == 1: return self.new_cards.setCurrentIndex(0) self.scheduled_cards.setCurrentIndex(0) self.non_memorised_cards.setValue(10) self.save_after_n_reps.setValue(10) self.media_autoplay.setCheckState(QtCore.Qt.Checked) self.media_controls.setCheckState(QtCore.Qt.Unchecked) self.upload_science_logs.setCheckState(QtCore.Qt.Checked) self.languages.setCurrentIndex(self.languages.findText("English")) def apply(self): self.config()["ui_language"] = iso6931_code_for_language_name(\ unicode(self.languages.currentText())) self.translator().set_language(self.config()["ui_language"]) if self.new_cards.currentIndex() == 1: self.config()["randomise_new_cards"] = True else: self.config()["randomise_new_cards"] = False if self.scheduled_cards.currentIndex() == 1: self.config()["randomise_scheduled_cards"] = True else: self.config()["randomise_scheduled_cards"] = False self.config()["non_memorised_cards_in_hand"] = \ self.non_memorised_cards.value() self.config()["save_after_n_reps"] = \ self.save_after_n_reps.value() if self.media_autoplay.checkState() == QtCore.Qt.Checked: self.config()["media_autoplay"] = True else: self.config()["media_autoplay"] = False if self.media_controls.checkState() == QtCore.Qt.Checked: self.config()["media_controls"] = True else: self.config()["media_controls"] = False if self.upload_science_logs.checkState() == QtCore.Qt.Checked: self.config()["upload_science_logs"] = True else: self.config()["upload_science_logs"] = False Mnemosyne-2.2.1/mnemosyne/pyqt_ui/ui_statistics_dlg.py0000644000175000000000000000404112132771334023717 0ustar pbienstroot00000000000000# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'statistics_dlg.ui' # # Created: Mon Apr 15 14:30:20 2013 # by: PyQt4 UI code generator 4.9.3 # # WARNING! All changes made in this file will be lost! from mnemosyne.libmnemosyne.translator import _ from PyQt4 import QtCore, QtGui try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: _fromUtf8 = lambda s: s class Ui_StatisticsDlg(object): def setupUi(self, StatisticsDlg): StatisticsDlg.setObjectName(_fromUtf8("StatisticsDlg")) StatisticsDlg.resize(564, 545) self.verticalLayout_2 = QtGui.QVBoxLayout(StatisticsDlg) self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2")) self.verticalLayout = QtGui.QVBoxLayout() self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) self.tab_widget = QtGui.QTabWidget(StatisticsDlg) self.tab_widget.setObjectName(_fromUtf8("tab_widget")) self.verticalLayout.addWidget(self.tab_widget) self.horizontalLayout = QtGui.QHBoxLayout() self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout")) spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.horizontalLayout.addItem(spacerItem) self.ok_button = QtGui.QPushButton(StatisticsDlg) self.ok_button.setAutoDefault(True) self.ok_button.setDefault(True) self.ok_button.setObjectName(_fromUtf8("ok_button")) self.horizontalLayout.addWidget(self.ok_button) self.verticalLayout.addLayout(self.horizontalLayout) self.verticalLayout_2.addLayout(self.verticalLayout) self.retranslateUi(StatisticsDlg) self.tab_widget.setCurrentIndex(-1) QtCore.QObject.connect(self.ok_button, QtCore.SIGNAL(_fromUtf8("clicked()")), StatisticsDlg.accept) QtCore.QMetaObject.connectSlotsByName(StatisticsDlg) def retranslateUi(self, StatisticsDlg): StatisticsDlg.setWindowTitle(_('Statistics')) self.ok_button.setText(_('&OK')) Mnemosyne-2.2.1/mnemosyne/pyqt_ui/card_set_name_dlg.py0000644000175000017500000000251412075734653024326 0ustar pbienstpbienst00000000000000# # card_set_name_dlg.py # from PyQt4 import QtCore, QtGui from mnemosyne.libmnemosyne.translator import _ from mnemosyne.libmnemosyne.ui_component import UiComponent from mnemosyne.pyqt_ui.ui_card_set_name_dlg import Ui_CardSetNameDlg class CardSetNameDlg(QtGui.QDialog, Ui_CardSetNameDlg, UiComponent): def __init__(self, component_manager, criterion, existing_names, parent): UiComponent.__init__(self, component_manager) QtGui.QDialog.__init__(self, parent) self.setWindowFlags(self.windowFlags() \ | QtCore.Qt.WindowMinMaxButtonsHint) self.setWindowFlags(self.windowFlags() \ & ~ QtCore.Qt.WindowContextHelpButtonHint) self.setupUi(self) self.criterion = criterion self.set_name.addItem(criterion.name) if criterion.name == "": self.ok_button.setEnabled(False) for name in sorted(existing_names): self.set_name.addItem(name) def text_changed(self): if self.set_name.currentText(): self.ok_button.setEnabled(True) else: self.ok_button.setEnabled(False) def reject(self): return QtGui.QDialog.reject(self) def accept(self): self.criterion.name = unicode(self.set_name.currentText()) return QtGui.QDialog.accept(self) Mnemosyne-2.2.1/mnemosyne/pyqt_ui/tag_tree_wdgt.py0000644000175000017500000003566212127504227023533 0ustar pbienstpbienst00000000000000# # tag_tree_wdgt.py # from PyQt4 import QtCore, QtGui from mnemosyne.libmnemosyne.translator import _ from mnemosyne.libmnemosyne.tag_tree import TagTree from mnemosyne.libmnemosyne.component import Component from mnemosyne.libmnemosyne.criteria.default_criterion import DefaultCriterion # We hijack QTreeWidgetItem a bit and store extra data in a hidden column, so # that we don't need to implement a custom tree model. # The first column stores the string displayed, i.e. the leaf part of the # hierachical tag name. The second column stores the node id, i.e. the # full tag name. DISPLAY_STRING = 0 NODE = 1 class TagDelegate(QtGui.QStyledItemDelegate): rename_node = QtCore.pyqtSignal(unicode, unicode) redraw_node = QtCore.pyqtSignal(unicode) def __init__(self, component_manager, parent=None): QtGui.QStyledItemDelegate.__init__(self, parent) self.previous_node_name = None def createEditor(self, parent, option, index): # Ideally, we want to capture the focusOut event here, to redraw the # card counts in case of an aborted edit by the user. One option to # achieve this is connecting the editingFinished signal instead of # returnPressed, but there is a long-standing bug in Qt causing this # signal to be emitted twice, with the second call sometimes coming # when the first one has not finished yet, which can cause crashes. # The other option is to reimplement focusOutEvent of the editor, but # that does not seem to work here easily in the context of Delegates. # Presumably subclassing QLineEdit would work, though, but at the cost # of added complexity. # # See also: # # http://www.qtforum.org/article/33631/qlineedit-the-signal-editingfinished-is-emitted-twice.html # http://bugreports.qt.nokia.com/browse/QTBUG-40 editor = QtGui.QStyledItemDelegate.createEditor\ (self, parent, option, index) editor.returnPressed.connect(self.commit_and_close_editor) return editor def setEditorData(self, editor, index): # We display the full node (i.e. all levels including ::), so that # the hierarchy can be changed upon editing. node_index = index.model().index(index.row(), NODE, index.parent()) self.previous_node_name = index.model().data(node_index).toString().\ replace("::" + _("Untagged"), "" ) editor.setText(self.previous_node_name) def commit_and_close_editor(self): editor = self.sender() if unicode(self.previous_node_name) == unicode(editor.text()): self.redraw_node.emit(self.previous_node_name) else: self.rename_node.emit(self.previous_node_name, editor.text()) self.closeEditor.emit(editor, QtGui.QAbstractItemDelegate.NoHint) class TagsTreeWdgt(QtGui.QWidget, Component): """Displays all the tags in a tree together with check boxes. If 'before_using_libmnemosyne_db_hook' and 'after_using_libmnemosyne_db' are set, these will be called before and after using libmnemosyne operations which can modify the database. Typical use case for this comes from a parent widget like the card browser, which needs to relinquish its control over the sqlite database first, before the tag tree operations can take place. """ def __init__(self, component_manager, parent, before_using_libmnemosyne_db_hook=None, after_using_libmnemosyne_db_hook=None): Component.__init__(self, component_manager) QtGui.QWidget.__init__(self, parent) self.before_using_libmnemosyne_db_hook = \ before_using_libmnemosyne_db_hook self.after_using_libmnemosyne_db_hook = \ after_using_libmnemosyne_db_hook self.layout = QtGui.QVBoxLayout(self) self.tree_wdgt = QtGui.QTreeWidget(self) self.tree_wdgt.setColumnCount(2) self.tree_wdgt.setColumnHidden(1, True) self.tree_wdgt.setColumnHidden(NODE, True) self.tree_wdgt.setHeaderHidden(True) self.tree_wdgt.setSelectionMode(\ QtGui.QAbstractItemView.ExtendedSelection) self.delegate = TagDelegate(component_manager, self) self.tree_wdgt.setItemDelegate(self.delegate) self.delegate.rename_node.connect(self.rename_node) self.delegate.redraw_node.connect(self.redraw_node) self.layout.addWidget(self.tree_wdgt) self.tree_wdgt.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.tree_wdgt.customContextMenuRequested.connect(\ self.context_menu) def selected_nodes_which_can_be_renamed(self): nodes = [] for index in self.tree_wdgt.selectedIndexes(): node_index = \ index.model().index(index.row(), NODE, index.parent()) node = index.model().data(node_index).toString() if node in self.nodes_which_can_be_renamed: nodes.append(node) return nodes def selected_nodes_which_can_be_deleted(self): nodes = [] for index in self.tree_wdgt.selectedIndexes(): node_index = \ index.model().index(index.row(), NODE, index.parent()) node = index.model().data(node_index).toString() if node in self.nodes_which_can_be_deleted: nodes.append(node) return nodes def context_menu(self, point): menu = QtGui.QMenu(self) to_rename = self.selected_nodes_which_can_be_renamed() if len(to_rename) >= 1: rename_action = QtGui.QAction(_("&Rename"), menu) rename_action.triggered.connect(self.menu_rename) rename_action.setShortcut(QtCore.Qt.Key_Enter) menu.addAction(rename_action) if len(to_rename) > 1: rename_action.setEnabled(False) to_delete = self.selected_nodes_which_can_be_deleted() if len(to_delete) >= 1: delete_action = QtGui.QAction(_("&Delete"), menu) delete_action.triggered.connect(self.menu_delete) delete_action.setShortcut(QtGui.QKeySequence.Delete) menu.addAction(delete_action) if len(to_delete) + len(to_rename) >= 1: menu.exec_(self.tree_wdgt.mapToGlobal(point)) def keyPressEvent(self, event): if event.key() in [QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return]: self.menu_rename() elif event.key() in [QtCore.Qt.Key_Delete, QtCore.Qt.Key_Backspace]: self.menu_delete() else: QtGui.QWidget.keyPressEvent(self, event) def menu_rename(self): nodes = self.selected_nodes_which_can_be_renamed() # If there are tags selected, this means that we could only have got # after pressing return on an actual edit, due to our custom # 'keyPressEvent'. We should not continue in that case. if len(nodes) == 0: return # We display the full node (i.e. all levels including ::), so that # the hierarchy can be changed upon editing. from mnemosyne.pyqt_ui.ui_rename_tag_dlg import Ui_RenameTagDlg class RenameDlg(QtGui.QDialog, Ui_RenameTagDlg): def __init__(self, old_tag_name): QtGui.QDialog.__init__(self) self.setupUi(self) self.tag_name.setText(\ old_tag_name.replace("::" + _("Untagged"), "" )) old_tag_name = nodes[0] dlg = RenameDlg(old_tag_name) if dlg.exec_() == QtGui.QDialog.Accepted: self.rename_node(nodes[0], unicode(dlg.tag_name.text())) def menu_delete(self): nodes = self.selected_nodes_which_can_be_deleted() if len(nodes) == 0: return if len(nodes) > 1: question = _("Delete these tags? Cards with these tags will not be deleted.") else: question = _("Delete this tag? Cards with this tag will not be deleted.") answer = self.main_widget().show_question\ (question, _("&OK"), _("&Cancel"), "") if answer == 1: # Cancel. return self.delete_nodes(nodes) def create_tree(self, tree, qt_parent): for node in tree: node_name = "%s (%d)" % \ (self.tag_tree.display_name_for_node[node], self.tag_tree.card_count_for_node[node]) node_item = QtGui.QTreeWidgetItem(qt_parent, [node_name, node], 0) node_item.setFlags(node_item.flags() | \ QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsTristate) if node not in ["__ALL__", "__UNTAGGED__"] and \ not "::" + _("Untagged") in node: node_item.setFlags(node_item.flags() | \ QtCore.Qt.ItemIsEditable) self.nodes_which_can_be_renamed.append(node) self.nodes_which_can_be_deleted.append(node) if node in self.tag_tree.tag_for_node: self.tag_for_node_item[node_item] = \ self.tag_tree.tag_for_node[node] node_item.setData(NODE, QtCore.Qt.DisplayRole, QtCore.QVariant(QtCore.QString(node))) self.create_tree(tree=self.tag_tree[node], qt_parent=node_item) def display(self, criterion=None): # Create criterion if needed. if criterion is None: criterion = DefaultCriterion(self.component_manager) for tag in self.database().tags(): criterion._tag_ids_active.add(tag._id) # Create tree. self.tag_tree = TagTree(self.component_manager) self.tree_wdgt.clear() self.tag_for_node_item = {} self.nodes_which_can_be_deleted = [] self.nodes_which_can_be_renamed = [] node = "__ALL__" node_name = "%s (%d)" % (self.tag_tree.display_name_for_node[node], self.tag_tree.card_count_for_node[node]) root = self.tag_tree[node] root_item = QtGui.QTreeWidgetItem(\ self.tree_wdgt, [node_name, node], 0) root_item.setFlags(root_item.flags() | \ QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsTristate) root_item.setCheckState(0, QtCore.Qt.Checked) self.create_tree(self.tag_tree[node], qt_parent=root_item) # Set forbidden tags. if len(criterion._tag_ids_forbidden): for node_item, tag in self.tag_for_node_item.iteritems(): if tag._id in criterion._tag_ids_forbidden: node_item.setCheckState(0, QtCore.Qt.Checked) else: node_item.setCheckState(0, QtCore.Qt.Unchecked) # Set active tags. else: # We first set all the tags inactive. We cannot do this in the # second branch of the upcoming 'if' statement, as then an # inactive parent tag coming later in the list will deactivate # active child tags coming earlier in the list. for node_item in self.tag_for_node_item: node_item.setCheckState(0, QtCore.Qt.Unchecked) for node_item, tag in self.tag_for_node_item.iteritems(): if tag._id in criterion._tag_ids_active: node_item.setCheckState(0, QtCore.Qt.Checked) # Restore state of the tree. self.tree_wdgt.expandAll() collapsed = self.config()["tag_tree_wdgt_state"] if collapsed is None: collapsed = [] iterator = QtGui.QTreeWidgetItemIterator(self.tree_wdgt) while iterator.value(): if unicode(iterator.value().text(1)) in collapsed: iterator.value().setExpanded(False) iterator += 1 def checked_to_active_tags_in_criterion(self, criterion): for item, tag in self.tag_for_node_item.iteritems(): if item.checkState(0) == QtCore.Qt.Checked: criterion._tag_ids_active.add(tag._id) criterion.forbidden_tags = set() return criterion def checked_to_forbidden_tags_in_criterion(self, criterion): for item, tag in self.tag_for_node_item.iteritems(): if item.checkState(0) == QtCore.Qt.Checked: criterion._tag_ids_forbidden.add(tag._id) criterion.active_tags = set(self.tag_for_node_item.values()) return criterion def save_criterion(self): self.saved_criterion = DefaultCriterion(self.component_manager) self.checked_to_active_tags_in_criterion(self.saved_criterion) # Now we've saved the checked state of the tree. # Saving and restoring the selected state is less trivial, because # in the case of trees, the model indexes have parents which become # invalid when creating the widget. # The solution would be to save tags and reselect those in the new # widget. def restore_criterion(self): new_criterion = DefaultCriterion(self.component_manager) for tag in self.database().tags(): if tag._id in self.saved_criterion._tag_ids_active: new_criterion._tag_ids_active.add(tag._id) self.display(new_criterion) def hibernate(self): """Save the current criterion and unload the database so that we can call libmnemosyne functions. """ self.save_criterion() if self.before_using_libmnemosyne_db_hook: self.before_using_libmnemosyne_db_hook() # Store which nodes are collapsed. collapsed = [] iterator = QtGui.QTreeWidgetItemIterator(self.tree_wdgt) while iterator.value(): if not iterator.value().isExpanded(): collapsed.append(unicode(iterator.value().text(1))) iterator += 1 self.config()["tag_tree_wdgt_state"] = collapsed def wakeup(self): """Restore the saved criterion and reload the database after calling libmnemosyne functions. """ self.restore_criterion() if self.after_using_libmnemosyne_db_hook: self.after_using_libmnemosyne_db_hook() def rename_node(self, node, new_name): self.hibernate() self.tag_tree.rename_node(unicode(node), unicode(new_name)) self.wakeup() def delete_nodes(self, nodes): self.hibernate() for node in nodes: self.tag_tree.delete_subtree(unicode(node)) self.wakeup() def redraw_node(self, node): """When renaming a tag to the same name, we need to redraw the node to show the card count again. """ # We do the redrawing in a rather hackish way now, simply by # recreating the widget. Could be sped up, but at the expense of more # complicated code. self.save_criterion() self.restore_criterion() def rebuild(self): """To be called when external events invalidate the tag tree, e.g. due to edits in the card browser widget. """ self.hibernate() self.tag_tree = TagTree(self.component_manager) self.wakeup() def closeEvent(self, event): self.hibernate() Mnemosyne-2.2.1/mnemosyne/pyqt_ui/import_dlg.py0000644000175000017500000000566512015437061023051 0ustar pbienstpbienst00000000000000# # import_dlg.py # import os from PyQt4 import QtGui, QtCore from mnemosyne.libmnemosyne.translator import _ from mnemosyne.pyqt_ui.ui_import_dlg import Ui_ImportDlg from mnemosyne.libmnemosyne.ui_components.dialogs import ImportDialog class ImportDlg(QtGui.QDialog, Ui_ImportDlg, ImportDialog): def __init__(self, component_manager): ImportDialog.__init__(self, component_manager) QtGui.QDialog.__init__(self, self.main_widget()) self.setupUi(self) # File formats. i = 0 current_index = None for format in self.component_manager.all("file_format"): if not format.import_possible: continue self.file_formats.addItem(_(format.description)) if type(format) == self.config()["import_format"]: current_index = i i += 1 if current_index is not None: self.file_formats.setCurrentIndex(current_index) # Extra tag. i = 0 current_index = None for tag in self.database().tags(): if tag.name == self.config()["import_extra_tag_names"]: current_index = i if tag.name != "__UNTAGGED__": self.tags.addItem(tag.name) i += 1 if current_index is not None: self.tags.setCurrentIndex(current_index) if self.config()["import_extra_tag_names"] == "": self.tags.insertItem(0, "") self.tags.setCurrentIndex(0) if "," in self.config()["import_extra_tag_names"]: self.tags.insertItem(0, self.config()["import_extra_tag_names"]) self.tags.setCurrentIndex(0) def file_format_changed(self): self.filename_box.setText("") def activate(self): ImportDialog.activate(self) self.exec_() def format(self): for _format in self.component_manager.all("file_format"): if _(_format.description) == \ unicode(self.file_formats.currentText()): return _format def browse(self): import_dir = self.config()["import_dir"] filename = self.main_widget().get_filename_to_open(import_dir, _(self.format().filename_filter)) self.filename_box.setText(filename) if filename: self.config()["import_dir"] = os.path.dirname(filename) def accept(self): filename = unicode(self.filename_box.text()) if filename and os.path.exists(filename): extra_tag_names = unicode(self.tags.currentText()) self.config()["import_extra_tag_names"] = extra_tag_names if not extra_tag_names: extra_tag_names = None self.config()["import_format"] = type(self.format()) self.format().do_import(filename, extra_tag_names) QtGui.QDialog.accept(self) else: self.main_widget().show_error(_("File does not exist.")) Mnemosyne-2.2.1/mnemosyne/pyqt_ui/compact_database_dlg.py0000664000175000017500000000550712046724166025017 0ustar pbienstpbienst00000000000000# # compact_database_dlg.py # from PyQt4 import QtCore, QtGui from mnemosyne.libmnemosyne.translator import _ from mnemosyne.pyqt_ui.ui_compact_database_dlg import \ Ui_CompactDatabaseDlg from mnemosyne.pyqt_ui.delete_unused_media_files_dlg import \ DeleteUnusedMediaFilesDlg from mnemosyne.libmnemosyne.ui_components.dialogs import \ CompactDatabaseDialog class CompactThread(QtCore.QThread): """We do this in a separate thread so that the GUI still stays responsive. """ compact_finished_signal = QtCore.pyqtSignal() def __init__(self, mnemosyne): QtCore.QThread.__init__(self) self.mnemosyne = mnemosyne def run(self): try: self.mnemosyne.database().compact() finally: self.mnemosyne.database().release_connection() self.compact_finished_signal.emit() class CompactDatabaseDlg(QtGui.QDialog, Ui_CompactDatabaseDlg, CompactDatabaseDialog): def __init__(self, component_manager): CompactDatabaseDialog.__init__(self, component_manager) QtGui.QDialog.__init__(self, self.main_widget()) self.setupUi(self) self.setWindowFlags(self.windowFlags() \ | QtCore.Qt.WindowMinMaxButtonsHint) self.setWindowFlags(self.windowFlags() \ & ~ QtCore.Qt.WindowContextHelpButtonHint) if not self.config()["compact_help_shown"]: self.main_widget().show_information(\ _("Here, you can delete media files which are no longer used. You can also compact the database, but this is only relevant if you deleted a large number of cards.")) self.config()["compact_help_shown"] = True def activate(self): self.exec_() def accept(self): compact_database = \ (self.compact_database.checkState() == QtCore.Qt.Checked) delete_unused_media_files = \ (self.delete_unused_media_files.checkState() == QtCore.Qt.Checked) if not (compact_database or delete_unused_media_files): QtGui.QDialog.accept(self) if delete_unused_media_files: unused_media_files = self.database().unused_media_files() if len(unused_media_files) != 0: DeleteUnusedMediaFilesDlg(\ self.component_manager, unused_media_files).activate() if compact_database: self.main_widget().set_progress_text(_("Compacting database...")) self.database().release_connection() self.thread = CompactThread(self) self.thread.compact_finished_signal.connect(self.finish_compact) self.thread.start() else: QtGui.QDialog.accept(self) def finish_compact(self): self.main_widget().close_progress() self.main_widget().show_information(_("Done!")) QtGui.QDialog.accept(self)Mnemosyne-2.2.1/mnemosyne/pyqt_ui/configuration_wdgt_card_appearance.py0000644000175000017500000002563712113344146027756 0ustar pbienstpbienst00000000000000# # configuration_wdgt_card_appearance.py # from copy import deepcopy 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.preview_cards_dlg import PreviewCardsDlg from mnemosyne.libmnemosyne.ui_components.configuration_widget import \ ConfigurationWidget from mnemosyne.pyqt_ui.ui_configuration_wdgt_card_appearance import \ Ui_ConfigurationWdgtCardAppearance class ConfigurationWdgtCardAppearance(QtGui.QWidget, Ui_ConfigurationWdgtCardAppearance, ConfigurationWidget): name = _("Card appearance") def __init__(self, component_manager, parent): ConfigurationWidget.__init__(self, component_manager) QtGui.QWidget.__init__(self, parent) self.setupUi(self) self.dynamic_widgets = [] self.affected_card_types = [] self.fact_key_names = [] self.non_latin_font_size_increase.setValue\ (self.config()['non_latin_font_size_increase']) # We calculate card_type_by_name here because these names can change # if the user chooses another translation. self.card_types_widget.addItem(_("")) self.card_type_by_name = {} for card_type in self.card_types(): self.card_type_by_name[_(card_type.name)] = card_type self.card_types_widget.addItem(_(card_type.name)) # Store backups in order to be able to revert our changes. self.old_font = deepcopy(self.config()["font"]) self.old_background_colour = \ deepcopy(self.config()["background_colour"]) self.old_font_colour = deepcopy(self.config()["font_colour"]) self.old_alignment = deepcopy(self.config()["alignment"]) def card_type_changed(self, new_card_type_name): if new_card_type_name == _(""): self.affected_card_types = self.card_types() self.fact_key_names = [_("Text")] for widget in [self.label_non_latin_1, self.label_non_latin_2, self.label_non_latin_3, self.line_non_latin, self.non_latin_font_size_increase]: widget.show() else: new_card_type_name = unicode(new_card_type_name) new_card_type = self.card_type_by_name[new_card_type_name] self.affected_card_types = [new_card_type] self.fact_key_names = new_card_type.fact_key_names() for widget in [self.label_non_latin_1, self.label_non_latin_2, self.label_non_latin_3, self.line_non_latin, self.non_latin_font_size_increase]: widget.hide() for widget in self.dynamic_widgets: self.gridLayout.removeWidget(widget) widget.close() self.dynamic_widgets = [] row = 0 self.font_buttons = QtGui.QButtonGroup() self.colour_buttons = QtGui.QButtonGroup() self.align_buttons = QtGui.QButtonGroup() self.align_buttons.setExclusive(False) for key_name in self.fact_key_names: label = QtGui.QLabel(_(key_name) + ":", self) self.gridLayout.addWidget(label, row, 0, 1, 1) self.dynamic_widgets.append(label) font = QtGui.QPushButton(_("Select font"), self) self.font_buttons.addButton(font, row) self.gridLayout.addWidget(font, row, 1, 1, 1) self.dynamic_widgets.append(font) colour = QtGui.QPushButton(_("Select colour"),self) self.colour_buttons.addButton(colour, row) self.gridLayout.addWidget(colour, row, 2, 1, 1) self.dynamic_widgets.append(colour) row += 1 self.gridLayout.setColumnStretch(1, 10) self.gridLayout.setColumnStretch(2, 10) self.font_buttons.buttonClicked[int].connect(self.update_font) self.colour_buttons.buttonClicked[int].\ connect(self.update_font_colour) current_alignment = self.config().card_type_property(\ "alignment", self.affected_card_types[0], default="center") if current_alignment == "left": self.alignment.setCurrentIndex(0) elif current_alignment == "center": self.alignment.setCurrentIndex(1) elif current_alignment == "right": self.alignment.setCurrentIndex(2) # Make font light if different alignments are active. self.alignment.setFont(self.font()) values = set() for card_type in self.affected_card_types: if not card_type.id in self.config()["alignment"]: values.add("center") else: values.add(self.config()["alignment"][card_type.id]) if len(values) > 1: self.alignment.font().setWeight(25) else: self.alignment.font().setWeight(50) self.adjustSize() def update_background_colour(self): # Determine current colour. current_rgb = self.config().card_type_property("background_colour", self.affected_card_types[0]) if current_rgb: current_colour = QtGui.QColor(current_rgb) else: current_colour = self.palette().color(QtGui.QPalette.Base) # Set new colour. colour = QtGui.QColorDialog.getColor(current_colour, self) if colour.isValid(): for card_type in self.affected_card_types: self.config().set_card_type_property("background_colour", colour.rgb(), card_type) def update_font(self, index): # Determine keys affected. if len(self.affected_card_types) > 1: affected_fact_key = None # Actually means all the keys. else: affected_fact_key = \ self.affected_card_types[0].fact_keys_and_names[index][0] # Determine current font. if len(self.affected_card_types) > 1: font_strings = set() for card_type in self.affected_card_types: font_strings.add(self.config().card_type_property(\ "font", card_type, "f")) if len(font_strings) > 1: font_string = None else: font_string = font_strings.pop() else: font_string = self.config().card_type_property(\ "font", self.affected_card_types[0], affected_fact_key) current_font = QtGui.QFont(self.font()) if font_string: current_font.fromString(font_string) # Set new font. font, ok = QtGui.QFontDialog.getFont(current_font, self) if ok: font_string = unicode(font.toString()) for card_type in self.affected_card_types: self.config().set_card_type_property("font", font_string, card_type, affected_fact_key) def update_font_colour(self, index): # Determine keys affected. if len(self.affected_card_types) > 1: affected_fact_key = None # Actually means all the keys. else: affected_fact_key = \ self.affected_card_types[0].fact_keys_and_names[index][0] # Determine current colour. if len(self.affected_card_types) > 1: current_rgb = self.config().card_type_property(\ "font_colour", self.card_type_with_id("1"), "f") else: current_rgb = self.config().card_type_property(\ "font_colour", self.affected_card_types[0], affected_fact_key) if current_rgb: current_colour = QtGui.QColor(current_rgb) else: current_colour = QtGui.QColor(QtCore.Qt.black) # Set new colour. colour = QtGui.QColorDialog.getColor(current_colour, self) if colour.isValid(): for card_type in self.affected_card_types: self.config().set_card_type_property("font_colour", colour.rgb(), card_type, affected_fact_key) def update_alignment(self, index): if index == 0: new_alignment = "left" elif index == 1: new_alignment = "center" elif index == 2: new_alignment = "right" for card_type in self.affected_card_types: self.config().set_card_type_property("alignment", new_alignment, card_type) self.alignment.font().setWeight(50) def apply(self): self.config()["non_latin_font_size_increase"] = \ self.non_latin_font_size_increase.value() for card_type in self.card_types(): for render_chain in self.component_manager.all("render_chain"): render_chain.renderer_for_card_type(card_type).\ update(card_type) def preview(self): card_type = self.affected_card_types[0] for render_chain in self.component_manager.all("render_chain"): render_chain.renderer_for_card_type(card_type).update(card_type) fact_data = {} for fact_key, fact_key_name in card_type.fact_keys_and_names: fact_data[fact_key] = _(fact_key_name) # Tmp hack for cloze. if fact_key == "text": fact_data[fact_key] = "[" + _(fact_key_name) + "]" fact = Fact(fact_data) cards = card_type.create_sister_cards(fact) tag_text = "" dlg = PreviewCardsDlg(self.component_manager, cards, tag_text, self) dlg.exec_() def reset_to_defaults(self): if len(self.affected_card_types) > 1: message = _("Reset all card types to default system font?") else: message = _("Reset '%s' to default system font?") \ % (_(self.affected_card_types[0].name)) result = self.main_widget().show_question(\ message, _("&Yes"), _("&No"), "") if result == 1: return self.non_latin_font_size_increase.setValue(0) if len(self.affected_card_types) > 1: self.config()["font"] = {} self.config()["background_colour"] = {} self.config()["font_colour"] = {} self.config()["alignment"] = {} else: card_type_id = self.affected_card_types[0].id self.config()["font"].pop(card_type_id, None) self.config()["background_colour"].pop(card_type_id, None) self.config()["font_colour"].pop(card_type_id, None) self.config()["alignment"].pop(card_type_id, None) self.alignment.setCurrentIndex(1) def reject(self): self.config()["font"] = self.old_font self.config()["background_colour"] = self.old_background_colour self.config()["font_colour"] = self.old_font_colour self.config()["alignment"] = self.old_alignment for card_type in self.card_types(): for render_chain in self.component_manager.all("render_chain"): render_chain.renderer_for_card_type(card_type).\ update(card_type) Mnemosyne-2.2.1/mnemosyne/pyqt_ui/ui_delete_unused_media_files_dlg.py0000644000175000000000000000532212132771337026701 0ustar pbienstroot00000000000000# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'delete_unused_media_files_dlg.ui' # # Created: Mon Apr 15 14:30:22 2013 # by: PyQt4 UI code generator 4.9.3 # # WARNING! All changes made in this file will be lost! from mnemosyne.libmnemosyne.translator import _ from PyQt4 import QtCore, QtGui try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: _fromUtf8 = lambda s: s class Ui_DeleteUnusedMediaFilesDlg(object): def setupUi(self, DeleteUnusedMediaFilesDlg): DeleteUnusedMediaFilesDlg.setObjectName(_fromUtf8("DeleteUnusedMediaFilesDlg")) DeleteUnusedMediaFilesDlg.resize(388, 263) self.verticalLayout_2 = QtGui.QVBoxLayout(DeleteUnusedMediaFilesDlg) self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2")) self.verticalLayout = QtGui.QVBoxLayout() self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) self.label = QtGui.QLabel(DeleteUnusedMediaFilesDlg) self.label.setObjectName(_fromUtf8("label")) self.verticalLayout.addWidget(self.label) self.file_list = QtGui.QTextBrowser(DeleteUnusedMediaFilesDlg) self.file_list.setObjectName(_fromUtf8("file_list")) self.verticalLayout.addWidget(self.file_list) self.horizontalLayout = QtGui.QHBoxLayout() self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout")) self.ok_button = QtGui.QPushButton(DeleteUnusedMediaFilesDlg) self.ok_button.setDefault(True) self.ok_button.setObjectName(_fromUtf8("ok_button")) self.horizontalLayout.addWidget(self.ok_button) spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.horizontalLayout.addItem(spacerItem) self.cancel_button = QtGui.QPushButton(DeleteUnusedMediaFilesDlg) self.cancel_button.setObjectName(_fromUtf8("cancel_button")) self.horizontalLayout.addWidget(self.cancel_button) self.verticalLayout.addLayout(self.horizontalLayout) self.verticalLayout_2.addLayout(self.verticalLayout) self.retranslateUi(DeleteUnusedMediaFilesDlg) QtCore.QObject.connect(self.ok_button, QtCore.SIGNAL(_fromUtf8("clicked()")), DeleteUnusedMediaFilesDlg.accept) QtCore.QObject.connect(self.cancel_button, QtCore.SIGNAL(_fromUtf8("clicked()")), DeleteUnusedMediaFilesDlg.reject) QtCore.QMetaObject.connectSlotsByName(DeleteUnusedMediaFilesDlg) def retranslateUi(self, DeleteUnusedMediaFilesDlg): DeleteUnusedMediaFilesDlg.setWindowTitle(_('Delete media')) self.label.setText(_('Delete these unused media files?')) self.ok_button.setText(_('&OK')) self.cancel_button.setText(_('&Cancel')) Mnemosyne-2.2.1/mnemosyne/pyqt_ui/ui_rename_tag_dlg.py0000644000175000000000000000473412132771335023641 0ustar pbienstroot00000000000000# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'rename_tag_dlg.ui' # # Created: Mon Apr 15 14:30:21 2013 # by: PyQt4 UI code generator 4.9.3 # # WARNING! All changes made in this file will be lost! from mnemosyne.libmnemosyne.translator import _ from PyQt4 import QtCore, QtGui try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: _fromUtf8 = lambda s: s class Ui_RenameTagDlg(object): def setupUi(self, RenameTagDlg): RenameTagDlg.setObjectName(_fromUtf8("RenameTagDlg")) RenameTagDlg.resize(366, 82) self.verticalLayout_2 = QtGui.QVBoxLayout(RenameTagDlg) self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2")) self.verticalLayout = QtGui.QVBoxLayout() self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) self.label = QtGui.QLabel(RenameTagDlg) self.label.setObjectName(_fromUtf8("label")) self.verticalLayout.addWidget(self.label) self.tag_name = QtGui.QLineEdit(RenameTagDlg) self.tag_name.setObjectName(_fromUtf8("tag_name")) self.verticalLayout.addWidget(self.tag_name) self.horizontalLayout = QtGui.QHBoxLayout() self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout")) self.ok_button = QtGui.QPushButton(RenameTagDlg) self.ok_button.setDefault(True) self.ok_button.setObjectName(_fromUtf8("ok_button")) self.horizontalLayout.addWidget(self.ok_button) spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.horizontalLayout.addItem(spacerItem) self.cancel_button = QtGui.QPushButton(RenameTagDlg) self.cancel_button.setObjectName(_fromUtf8("cancel_button")) self.horizontalLayout.addWidget(self.cancel_button) self.verticalLayout.addLayout(self.horizontalLayout) self.verticalLayout_2.addLayout(self.verticalLayout) self.retranslateUi(RenameTagDlg) QtCore.QObject.connect(self.ok_button, QtCore.SIGNAL(_fromUtf8("clicked()")), RenameTagDlg.accept) QtCore.QObject.connect(self.cancel_button, QtCore.SIGNAL(_fromUtf8("clicked()")), RenameTagDlg.reject) QtCore.QMetaObject.connectSlotsByName(RenameTagDlg) def retranslateUi(self, RenameTagDlg): RenameTagDlg.setWindowTitle(_('Rename tag')) self.label.setText(_('Enter new tag name:')) self.ok_button.setText(_('&OK')) self.cancel_button.setText(_('&Cancel')) Mnemosyne-2.2.1/mnemosyne/pyqt_ui/qpushbutton2.py0000644000175000017500000000046311655722010023356 0ustar pbienstpbienst00000000000000# # qpushbutton2.py # from PyQt4 import QtGui class QPushButton2(QtGui.QPushButton): """QPushButton which throws away key repeats.""" def keyPressEvent(self, event): if not event.isAutoRepeat(): return QtGui.QPushButton.keyPressEvent(self, event) Mnemosyne-2.2.1/mnemosyne/pyqt_ui/configuration.py0000644000175000017500000000411212115614512023541 0ustar pbienstpbienst00000000000000# # configuration.py # import os from mnemosyne.libmnemosyne.hook import Hook class PyQtConfiguration(Hook): used_for = "configuration_defaults" def run(self): for key, value in \ {"list_font": None, "last_used_card_type_id": "", "is_last_used_tags_per_card_type": False, "last_used_tags_for_card_type_id": {}, "last_used_tags": "", "sort_column": None, "sort_order": None, "previous_statistics_page": 0, "previous_configuration_wdgt": 0, "previous_variant_for_statistics_page": {}, # dict[page] = variant "main_window_state": None, "add_cards_dlg_state": None, "preview_cards_dlg_state": None, "edit_card_dlg_state": None, "plugins_dlg_state": None, "clone_help_shown": False, "compact_help_shown": False, "browse_cards_dlg_state": None, "browse_cards_dlg_splitter_1_state": None, "browse_cards_dlg_splitter_2_state": None, "browse_cards_dlg_table_settings": None, "browse_cards_dlg_sorting_warning_shown": False, "tag_tree_wdgt_state": None, "statistics_dlg_state": None, "configuration_dlg_state": None, "activate_cards_dlg_state": None, "activate_cards_dlg_splitter_state": None, "sync_help_shown": False, "server_for_sync_as_client": "", "port_for_sync_as_client": 8512, "username_for_sync_as_client": "", "password_for_sync_as_client": "", "port_for_sync_as_server": 8512, "remote_access_username": "", "remote_access_password": "", "started_add_edit_cards_n_times": 0, "started_browse_cards_n_times": 0, "showed_help_on_renaming_sets": False, "showed_help_on_double_clicking_sets": False }.items(): self.config().setdefault(key, value) Mnemosyne-2.2.1/mnemosyne/pyqt_ui/activate_cards_dlg.py0000644000175000017500000002247512127504025024510 0ustar pbienstpbienst00000000000000# # activate_cards_dlg.py # from PyQt4 import QtCore, QtGui from mnemosyne.libmnemosyne.translator import _ from mnemosyne.pyqt_ui.card_set_name_dlg import CardSetNameDlg from mnemosyne.pyqt_ui.ui_activate_cards_dlg import Ui_ActivateCardsDlg from mnemosyne.libmnemosyne.ui_components.dialogs import ActivateCardsDialog class ActivateCardsDlg(QtGui.QDialog, Ui_ActivateCardsDlg, ActivateCardsDialog): def __init__(self, component_manager): ActivateCardsDialog.__init__(self, component_manager) QtGui.QDialog.__init__(self, self.main_widget()) self.setupUi(self) self.setWindowFlags(self.windowFlags() \ | QtCore.Qt.WindowMinMaxButtonsHint) self.setWindowFlags(self.windowFlags() \ & ~ QtCore.Qt.WindowContextHelpButtonHint) # Initialise widgets. criterion = self.database().current_criterion() self.criterion_classes = \ self.component_manager.all("criterion") current_criterion = self.database().current_criterion() self.widget_for_criterion_type = {} for criterion_class in self.criterion_classes: widget = self.component_manager.current\ ("criterion_widget", used_for=criterion_class)\ (self.component_manager, self) self.tab_widget.addTab(widget, criterion_class.criterion_type) self.widget_for_criterion_type[criterion_class.criterion_type] \ = widget self.tab_widget.setCurrentWidget(self.widget_for_criterion_type\ [current_criterion.criterion_type]) self.tab_widget.tabBar().setVisible(self.tab_widget.count() > 1) self.tab_widget.currentWidget().display_criterion(current_criterion) # Restore state. state = self.config()["activate_cards_dlg_state"] if state: self.restoreGeometry(state) splitter_state = self.config()["activate_cards_dlg_splitter_state"] if not splitter_state: self.splitter.setSizes([100, 350]) else: self.splitter.restoreState(splitter_state) # Should go last, otherwise the selection of the saved sets pane will # always be cleared. self.update_saved_sets_pane() def keyPressEvent(self, event): if event.key() in [QtCore.Qt.Key_Delete, QtCore.Qt.Key_Backspace]: self.delete_set() else: QtGui.QDialog.keyPressEvent(self, event) def change_widget(self, index): self.saved_sets.clearSelection() def activate(self): self.exec_() def update_saved_sets_pane(self): self.saved_sets.clear() self.criteria_by_name = {} active_name = "" active_criterion = self.database().current_criterion() for criterion in self.database().criteria(): if criterion._id != 1: self.criteria_by_name[criterion.name] = criterion self.saved_sets.addItem(criterion.name) if criterion == active_criterion: active_name = criterion.name self.saved_sets.sortItems() if active_name: item = self.saved_sets.findItems(active_name, QtCore.Qt.MatchExactly)[0] self.saved_sets.setCurrentItem(\ item, QtGui.QItemSelectionModel.Rows) else: self.saved_sets.clearSelection() splitter_sizes = self.splitter.sizes() if self.saved_sets.count() == 0: self.splitter.setSizes([0, sum(splitter_sizes)]) else: if splitter_sizes[0] == 0: # First time we add a set. self.splitter.setSizes([0.3* sum(splitter_sizes), 0.7 * sum(splitter_sizes)]) def saved_sets_custom_menu(self, pos): menu = QtGui.QMenu() menu.addAction(_("Delete"), self.delete_set) menu.addAction(_("Rename"), self.rename_set) menu.exec_(self.saved_sets.mapToGlobal(pos)) def save_set(self): criterion = self.tab_widget.currentWidget().criterion() if criterion.is_empty(): self.main_widget().show_error(\ _("This set can never contain any cards!")) return CardSetNameDlg(self.component_manager, criterion, self.criteria_by_name.keys(), self).exec_() if not criterion.name: # User cancelled. return if criterion.name in self.criteria_by_name.keys(): answer = self.main_widget().show_question(_("Update this set?"), _("&OK"), _("&Cancel"), "") if answer == 1: # Cancel. return original_criterion = self.criteria_by_name[criterion.name] criterion._id = original_criterion._id criterion.id = original_criterion.id self.database().update_criterion(criterion) else: self.database().add_criterion(criterion) self.update_saved_sets_pane() item = self.saved_sets.findItems(criterion.name, QtCore.Qt.MatchExactly)[0] self.saved_sets.setCurrentItem(item) if self.config()["showed_help_on_renaming_sets"] == False: self.main_widget().show_information(\ _("You can right-click on the name of a saved set to rename or delete it.")) self.config()["showed_help_on_renaming_sets"] = True def delete_set(self): if not self.saved_sets.currentItem(): return answer = self.main_widget().show_question(_("Delete this set?"), _("&OK"), _("&Cancel"), "") if answer == 1: # Cancel. return -1 else: name = unicode(self.saved_sets.currentItem().text()) criterion = self.criteria_by_name[name] self.database().delete_criterion(criterion) self.database().save() self.update_saved_sets_pane() def rename_set(self): name = unicode(self.saved_sets.currentItem().text()) criterion = self.criteria_by_name[name] criterion.name = name other_names = self.criteria_by_name.keys() other_names.remove(name) CardSetNameDlg(self.component_manager, criterion, other_names, self).exec_() if criterion.name == name: # User cancelled. return self.database().update_criterion(criterion) self.database().save() self.update_saved_sets_pane() item = self.saved_sets.findItems(criterion.name, QtCore.Qt.MatchExactly)[0] self.saved_sets.setCurrentItem(item) # load_set gets triggered by ItemActivated, but this does not happen # when the user changes the sets through the arrow keys (Qt bug?). # Therefore, we also catch currentItemChanged and forward it to # change_set, but to prevent unwanted firing when loading the widget # for the first time (which would erase the current criterion in case # it is not a saved criterion), we discard this event if previous_item # is None. # # To test when editing this code: initial start, with and without # current criterion being a saved criterion, changing the set through # clicking or through the arrows. def load_set(self, item, dummy=None): # Sometimes item is None, e.g. during the process of deleting a saved # set, so we need to discard the event then. if item is None: return name = unicode(item.text()) criterion = self.criteria_by_name[name] self.tab_widget.setCurrentWidget(self.widget_for_criterion_type\ [criterion.criterion_type]) self.tab_widget.currentWidget().display_criterion(criterion) # Restore the selection that got cleared in change_widget. item = self.saved_sets.findItems(criterion.name, QtCore.Qt.MatchExactly)[0] self.saved_sets.setCurrentItem(item) def change_set(self, item, previous_item): if previous_item is not None: self.load_set(item) def select_set_and_close(self, item): self.load_set(item) self.accept() def _store_state(self): self.config()["activate_cards_dlg_state"] = \ self.saveGeometry() self.config()["activate_cards_dlg_splitter_state"] = \ self.splitter.saveState() def closeEvent(self, event): # Generated when clicking the window's close button. self._store_state() # This allows the state of the tag tree to be saved. self.tab_widget.currentWidget().close() def accept(self): criterion = self.tab_widget.currentWidget().criterion() if criterion.is_empty(): self.main_widget().show_error(\ _("This set can never contain any cards!")) return if self.saved_sets.count() != 0 and self.config()\ ["showed_help_on_double_clicking_sets"] == False: self.main_widget().show_information(\ _("You can double-click on the name of a saved set to activate it and close the dialog.")) self.config()["showed_help_on_double_clicking_sets"] = True # 'accept' does not generate a close event. self.database().set_current_criterion(criterion) self._store_state() return QtGui.QDialog.accept(self) Mnemosyne-2.2.1/mnemosyne/pyqt_ui/ui_configuration_wdgt_sync_server.py0000644000175000000000000000762312132771335027227 0ustar pbienstroot00000000000000# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'configuration_wdgt_sync_server.ui' # # Created: Mon Apr 15 14:30:20 2013 # by: PyQt4 UI code generator 4.9.3 # # WARNING! All changes made in this file will be lost! from mnemosyne.libmnemosyne.translator import _ from PyQt4 import QtCore, QtGui try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: _fromUtf8 = lambda s: s class Ui_ConfigurationWdgtSyncServer(object): def setupUi(self, ConfigurationWdgtSyncServer): ConfigurationWdgtSyncServer.setObjectName(_fromUtf8("ConfigurationWdgtSyncServer")) ConfigurationWdgtSyncServer.resize(349, 299) self.verticalLayout_3 = QtGui.QVBoxLayout(ConfigurationWdgtSyncServer) self.verticalLayout_3.setObjectName(_fromUtf8("verticalLayout_3")) self.run_sync_server = QtGui.QGroupBox(ConfigurationWdgtSyncServer) self.run_sync_server.setCheckable(True) self.run_sync_server.setObjectName(_fromUtf8("run_sync_server")) self.verticalLayout = QtGui.QVBoxLayout(self.run_sync_server) self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) self.gridLayout = QtGui.QGridLayout() self.gridLayout.setObjectName(_fromUtf8("gridLayout")) self.label_2 = QtGui.QLabel(self.run_sync_server) self.label_2.setObjectName(_fromUtf8("label_2")) self.gridLayout.addWidget(self.label_2, 0, 0, 1, 1) self.username = QtGui.QLineEdit(self.run_sync_server) self.username.setObjectName(_fromUtf8("username")) self.gridLayout.addWidget(self.username, 0, 1, 1, 2) self.label_4 = QtGui.QLabel(self.run_sync_server) self.label_4.setObjectName(_fromUtf8("label_4")) self.gridLayout.addWidget(self.label_4, 1, 0, 1, 1) self.password = QtGui.QLineEdit(self.run_sync_server) self.password.setEchoMode(QtGui.QLineEdit.Password) self.password.setObjectName(_fromUtf8("password")) self.gridLayout.addWidget(self.password, 1, 1, 1, 2) self.label_3 = QtGui.QLabel(self.run_sync_server) self.label_3.setObjectName(_fromUtf8("label_3")) self.gridLayout.addWidget(self.label_3, 2, 0, 1, 1) self.port = QtGui.QSpinBox(self.run_sync_server) self.port.setMinimum(1) self.port.setMaximum(99999) self.port.setObjectName(_fromUtf8("port")) self.gridLayout.addWidget(self.port, 2, 1, 1, 1) spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.gridLayout.addItem(spacerItem, 2, 2, 1, 1) self.verticalLayout.addLayout(self.gridLayout) self.check_for_edited_local_media_files = QtGui.QCheckBox(self.run_sync_server) self.check_for_edited_local_media_files.setObjectName(_fromUtf8("check_for_edited_local_media_files")) self.verticalLayout.addWidget(self.check_for_edited_local_media_files) spacerItem1 = QtGui.QSpacerItem(20, 124, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) self.verticalLayout.addItem(spacerItem1) self.server_status = QtGui.QLabel(self.run_sync_server) self.server_status.setObjectName(_fromUtf8("server_status")) self.verticalLayout.addWidget(self.server_status) self.verticalLayout_3.addWidget(self.run_sync_server) self.retranslateUi(ConfigurationWdgtSyncServer) QtCore.QMetaObject.connectSlotsByName(ConfigurationWdgtSyncServer) def retranslateUi(self, ConfigurationWdgtSyncServer): ConfigurationWdgtSyncServer.setWindowTitle(_('Form')) self.run_sync_server.setTitle(_('Allow other devices to sync with this computer')) self.label_2.setText(_('Username:')) self.label_4.setText(_('Password:')) self.label_3.setText(_('Port:')) self.check_for_edited_local_media_files.setText(_('Check for changed media files on server')) self.server_status.setText(_('Server status')) Mnemosyne-2.2.1/mnemosyne/pyqt_ui/configuration_wdgt_sync_server.py0000644000175000017500000000703712113344305027217 0ustar pbienstpbienst00000000000000# # configuration_wdgt_sync_server.py # import socket import httplib from PyQt4 import QtGui from mnemosyne.libmnemosyne.translator import _ from mnemosyne.libmnemosyne.ui_components.configuration_widget import \ ConfigurationWidget from mnemosyne.pyqt_ui.ui_configuration_wdgt_sync_server import \ Ui_ConfigurationWdgtSyncServer # Hack to determine local IP. from openSM2sync.server import realsocket def localhost_IP(): s = realsocket(socket.AF_INET, socket.SOCK_DGRAM) s.connect(("google.com", 8000)) return s.getsockname()[0] class ConfigurationWdgtSyncServer(QtGui.QWidget, Ui_ConfigurationWdgtSyncServer, ConfigurationWidget): name = _("Sync server") def __init__(self, component_manager, parent): ConfigurationWidget.__init__(self, component_manager) QtGui.QDialog.__init__(self, parent) self.setupUi(self) self.initially_running = self.is_server_running() self.run_sync_server.setChecked(self.config()["run_sync_server"]) self.port.setValue(self.config()["port_for_sync_as_server"]) self.username.setText(self.config()["remote_access_username"]) self.password.setText(self.config()["remote_access_password"]) self.check_for_edited_local_media_files.setChecked(\ self.config()["check_for_edited_local_media_files"]) if self.is_server_running(): self.server_status.setText(_("Server running on ") + \ localhost_IP() + ".") else: self.server_status.setText(_("Server NOT running.")) def is_server_running(self): timeout = socket.getdefaulttimeout() try: socket.setdefaulttimeout(0.1) con = httplib.HTTPConnection(localhost_IP(), self.config()["port_for_sync_as_server"]) con.request("GET", "/status") assert "OK" in con.getresponse().read() socket.setdefaulttimeout(timeout) return True except socket.error: socket.setdefaulttimeout(timeout) return False def reset_to_defaults(self): answer = self.main_widget().show_question(\ _("Reset current tab to defaults?"), _("&Yes"), _("&No"), "") if answer == 1: return self.run_sync_server.setChecked(False) self.port.setValue(8512) self.username.setText("") self.password.setText("") self.check_for_edited_local_media_files.setChecked(False) def apply(self): self.config()["run_sync_server"] = self.run_sync_server.isChecked() self.config()["port_for_sync_as_server"] = self.port.value() self.config()["remote_access_username"] = unicode(self.username.text()) self.config()["remote_access_password"] = unicode(self.password.text()) self.config()["check_for_edited_local_media_files"] = \ self.check_for_edited_local_media_files.isChecked() self.component_manager.current("sync_server").deactivate() if self.config()["run_sync_server"]: self.component_manager.current("sync_server").activate() if not self.initially_running and self.is_server_running(): self.main_widget().show_information(\ _("Server now running on ") + localhost_IP() + ".") else: self.component_manager.current("sync_server").deactivate() if self.initially_running and not self.is_server_running(): self.main_widget().show_information(\ _("Server stopped.")) Mnemosyne-2.2.1/mnemosyne/pyqt_ui/ui_convert_card_type_keys_dlg.py0000644000175000000000000000674512132771332026305 0ustar pbienstroot00000000000000# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'convert_card_type_keys_dlg.ui' # # Created: Mon Apr 15 14:30:18 2013 # by: PyQt4 UI code generator 4.9.3 # # WARNING! All changes made in this file will be lost! from mnemosyne.libmnemosyne.translator import _ from PyQt4 import QtCore, QtGui try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: _fromUtf8 = lambda s: s class Ui_ConvertCardTypeKeysDlg(object): def setupUi(self, ConvertCardTypeKeysDlg): ConvertCardTypeKeysDlg.setObjectName(_fromUtf8("ConvertCardTypeKeysDlg")) ConvertCardTypeKeysDlg.resize(260, 105) self.verticalLayout_2 = QtGui.QVBoxLayout(ConvertCardTypeKeysDlg) self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2")) self.verticalLayout = QtGui.QVBoxLayout() self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) self.label_2 = QtGui.QLabel(ConvertCardTypeKeysDlg) self.label_2.setMinimumSize(QtCore.QSize(250, 40)) self.label_2.setWordWrap(True) self.label_2.setObjectName(_fromUtf8("label_2")) self.verticalLayout.addWidget(self.label_2) self.gridLayout = QtGui.QGridLayout() self.gridLayout.setObjectName(_fromUtf8("gridLayout")) self.label = QtGui.QLabel(ConvertCardTypeKeysDlg) font = QtGui.QFont() font.setBold(False) font.setWeight(50) self.label.setFont(font) self.label.setObjectName(_fromUtf8("label")) self.gridLayout.addWidget(self.label, 0, 0, 1, 1) self.label_3 = QtGui.QLabel(ConvertCardTypeKeysDlg) font = QtGui.QFont() font.setBold(False) font.setWeight(50) self.label_3.setFont(font) self.label_3.setObjectName(_fromUtf8("label_3")) self.gridLayout.addWidget(self.label_3, 0, 1, 1, 1) self.verticalLayout.addLayout(self.gridLayout) self.horizontalLayout = QtGui.QHBoxLayout() self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout")) self.ok_button = QtGui.QPushButton(ConvertCardTypeKeysDlg) self.ok_button.setEnabled(False) self.ok_button.setDefault(True) self.ok_button.setObjectName(_fromUtf8("ok_button")) self.horizontalLayout.addWidget(self.ok_button) spacerItem = QtGui.QSpacerItem(208, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.horizontalLayout.addItem(spacerItem) self.cancel_button = QtGui.QPushButton(ConvertCardTypeKeysDlg) self.cancel_button.setObjectName(_fromUtf8("cancel_button")) self.horizontalLayout.addWidget(self.cancel_button) self.verticalLayout.addLayout(self.horizontalLayout) self.verticalLayout_2.addLayout(self.verticalLayout) self.retranslateUi(ConvertCardTypeKeysDlg) QtCore.QObject.connect(self.ok_button, QtCore.SIGNAL(_fromUtf8("clicked()")), ConvertCardTypeKeysDlg.accept) QtCore.QObject.connect(self.cancel_button, QtCore.SIGNAL(_fromUtf8("clicked()")), ConvertCardTypeKeysDlg.reject) QtCore.QMetaObject.connectSlotsByName(ConvertCardTypeKeysDlg) def retranslateUi(self, ConvertCardTypeKeysDlg): ConvertCardTypeKeysDlg.setWindowTitle(_('Convert card type data')) self.label_2.setText(_('Set the correspondence between data in the old and the new card type:')) self.label.setText(_('Old:')) self.label_3.setText(_('New:')) self.ok_button.setText(_('&OK')) self.cancel_button.setText(_('&Cancel')) Mnemosyne-2.2.1/mnemosyne/pyqt_ui/ui_import_dlg.py0000644000175000000000000001123612132771336023045 0ustar pbienstroot00000000000000# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'import_dlg.ui' # # Created: Mon Apr 15 14:30:22 2013 # by: PyQt4 UI code generator 4.9.3 # # WARNING! All changes made in this file will be lost! from mnemosyne.libmnemosyne.translator import _ from PyQt4 import QtCore, QtGui try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: _fromUtf8 = lambda s: s class Ui_ImportDlg(object): def setupUi(self, ImportDlg): ImportDlg.setObjectName(_fromUtf8("ImportDlg")) ImportDlg.resize(292, 192) self.gridLayout = QtGui.QGridLayout(ImportDlg) self.gridLayout.setObjectName(_fromUtf8("gridLayout")) self.vboxlayout = QtGui.QVBoxLayout() self.vboxlayout.setObjectName(_fromUtf8("vboxlayout")) self.textLabel_5 = QtGui.QLabel(ImportDlg) self.textLabel_5.setWordWrap(False) self.textLabel_5.setObjectName(_fromUtf8("textLabel_5")) self.vboxlayout.addWidget(self.textLabel_5) self.file_formats = QtGui.QComboBox(ImportDlg) self.file_formats.setEditable(False) self.file_formats.setAutoCompletion(True) self.file_formats.setDuplicatesEnabled(False) self.file_formats.setObjectName(_fromUtf8("file_formats")) self.vboxlayout.addWidget(self.file_formats) self.textLabel1 = QtGui.QLabel(ImportDlg) self.textLabel1.setWordWrap(False) self.textLabel1.setObjectName(_fromUtf8("textLabel1")) self.vboxlayout.addWidget(self.textLabel1) self.hboxlayout = QtGui.QHBoxLayout() self.hboxlayout.setObjectName(_fromUtf8("hboxlayout")) self.filename_box = QtGui.QLineEdit(ImportDlg) self.filename_box.setObjectName(_fromUtf8("filename_box")) self.hboxlayout.addWidget(self.filename_box) self.browse_button = QtGui.QPushButton(ImportDlg) self.browse_button.setAutoDefault(False) self.browse_button.setObjectName(_fromUtf8("browse_button")) self.hboxlayout.addWidget(self.browse_button) self.vboxlayout.addLayout(self.hboxlayout) self.textLabel2 = QtGui.QLabel(ImportDlg) self.textLabel2.setWordWrap(False) self.textLabel2.setObjectName(_fromUtf8("textLabel2")) self.vboxlayout.addWidget(self.textLabel2) self.tags = QtGui.QComboBox(ImportDlg) self.tags.setEditable(True) self.tags.setAutoCompletion(True) self.tags.setDuplicatesEnabled(False) self.tags.setObjectName(_fromUtf8("tags")) self.vboxlayout.addWidget(self.tags) self.hboxlayout1 = QtGui.QHBoxLayout() self.hboxlayout1.setObjectName(_fromUtf8("hboxlayout1")) self.ok_button = QtGui.QPushButton(ImportDlg) self.ok_button.setDefault(True) self.ok_button.setObjectName(_fromUtf8("ok_button")) self.hboxlayout1.addWidget(self.ok_button) spacerItem = QtGui.QSpacerItem(201, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.hboxlayout1.addItem(spacerItem) self.cancel_button = QtGui.QPushButton(ImportDlg) self.cancel_button.setAutoDefault(False) self.cancel_button.setDefault(False) self.cancel_button.setObjectName(_fromUtf8("cancel_button")) self.hboxlayout1.addWidget(self.cancel_button) self.vboxlayout.addLayout(self.hboxlayout1) self.gridLayout.addLayout(self.vboxlayout, 0, 0, 1, 1) self.retranslateUi(ImportDlg) QtCore.QObject.connect(self.cancel_button, QtCore.SIGNAL(_fromUtf8("clicked()")), ImportDlg.reject) QtCore.QObject.connect(self.browse_button, QtCore.SIGNAL(_fromUtf8("clicked()")), ImportDlg.browse) QtCore.QObject.connect(self.ok_button, QtCore.SIGNAL(_fromUtf8("clicked()")), ImportDlg.accept) QtCore.QObject.connect(self.file_formats, QtCore.SIGNAL(_fromUtf8("currentIndexChanged(int)")), ImportDlg.file_format_changed) QtCore.QMetaObject.connectSlotsByName(ImportDlg) ImportDlg.setTabOrder(self.filename_box, self.browse_button) ImportDlg.setTabOrder(self.browse_button, self.file_formats) ImportDlg.setTabOrder(self.file_formats, self.tags) ImportDlg.setTabOrder(self.tags, self.ok_button) ImportDlg.setTabOrder(self.ok_button, self.cancel_button) def retranslateUi(self, ImportDlg): ImportDlg.setWindowTitle(_('Import from file')) self.textLabel_5.setText(_('File format:')) self.textLabel1.setText(_('File to import from:')) self.browse_button.setText(_('&Browse')) self.textLabel2.setText(_('Add additional tag(s) to cards:')) self.ok_button.setText(_('&OK')) self.ok_button.setShortcut(_('Alt+O')) self.cancel_button.setText(_('&Cancel')) Mnemosyne-2.2.1/mnemosyne/pyqt_ui/ui_review_wdgt.py0000644000175000000000000001401512132771340023224 0ustar pbienstroot00000000000000# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'review_wdgt.ui' # # Created: Mon Apr 15 14:30:23 2013 # by: PyQt4 UI code generator 4.9.3 # # WARNING! All changes made in this file will be lost! from mnemosyne.libmnemosyne.translator import _ from qwebview2 import * from qpushbutton2 import * from PyQt4 import QtCore, QtGui try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: _fromUtf8 = lambda s: s class Ui_ReviewWdgt(object): def setupUi(self, ReviewWdgt): ReviewWdgt.setObjectName(_fromUtf8("ReviewWdgt")) ReviewWdgt.resize(315, 352) ReviewWdgt.setWindowTitle(_fromUtf8("")) self.verticalLayout_5 = QtGui.QVBoxLayout(ReviewWdgt) self.verticalLayout_5.setMargin(0) self.verticalLayout_5.setObjectName(_fromUtf8("verticalLayout_5")) self.vertical_layout = QtGui.QVBoxLayout() self.vertical_layout.setMargin(9) self.vertical_layout.setObjectName(_fromUtf8("vertical_layout")) self.question_box = QtGui.QVBoxLayout() self.question_box.setObjectName(_fromUtf8("question_box")) self.question_label = QtGui.QLabel(ReviewWdgt) self.question_label.setObjectName(_fromUtf8("question_label")) self.question_box.addWidget(self.question_label) self.question = QWebView2(ReviewWdgt) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.question.sizePolicy().hasHeightForWidth()) self.question.setSizePolicy(sizePolicy) self.question.setMinimumSize(QtCore.QSize(295, 50)) self.question.setAcceptDrops(False) self.question.setUrl(QtCore.QUrl(_fromUtf8("about:blank"))) self.question.setObjectName(_fromUtf8("question")) self.question_box.addWidget(self.question) self.vertical_layout.addLayout(self.question_box) self.answer_box = QtGui.QVBoxLayout() self.answer_box.setObjectName(_fromUtf8("answer_box")) self.answer_label = QtGui.QLabel(ReviewWdgt) self.answer_label.setObjectName(_fromUtf8("answer_label")) self.answer_box.addWidget(self.answer_label) self.answer = QWebView2(ReviewWdgt) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.answer.sizePolicy().hasHeightForWidth()) self.answer.setSizePolicy(sizePolicy) self.answer.setMinimumSize(QtCore.QSize(295, 50)) self.answer.setAcceptDrops(False) self.answer.setUrl(QtCore.QUrl(_fromUtf8("about:blank"))) self.answer.setObjectName(_fromUtf8("answer")) self.answer_box.addWidget(self.answer) self.vertical_layout.addLayout(self.answer_box) self.show_button = QPushButton2(ReviewWdgt) self.show_button.setObjectName(_fromUtf8("show_button")) self.vertical_layout.addWidget(self.show_button) self.grades = QtGui.QGroupBox(ReviewWdgt) self.grades.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) self.grades.setObjectName(_fromUtf8("grades")) self._2 = QtGui.QVBoxLayout(self.grades) self._2.setObjectName(_fromUtf8("_2")) self.horizontalLayout = QtGui.QHBoxLayout() self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout")) self.grade_0_button = QPushButton2(self.grades) self.grade_0_button.setObjectName(_fromUtf8("grade_0_button")) self.horizontalLayout.addWidget(self.grade_0_button) self.grade_1_button = QPushButton2(self.grades) self.grade_1_button.setObjectName(_fromUtf8("grade_1_button")) self.horizontalLayout.addWidget(self.grade_1_button) self.line = QtGui.QFrame(self.grades) self.line.setFrameShape(QtGui.QFrame.VLine) self.line.setFrameShadow(QtGui.QFrame.Sunken) self.line.setObjectName(_fromUtf8("line")) self.horizontalLayout.addWidget(self.line) self.grade_2_button = QPushButton2(self.grades) self.grade_2_button.setObjectName(_fromUtf8("grade_2_button")) self.horizontalLayout.addWidget(self.grade_2_button) self.grade_3_button = QPushButton2(self.grades) self.grade_3_button.setObjectName(_fromUtf8("grade_3_button")) self.horizontalLayout.addWidget(self.grade_3_button) self.grade_4_button = QPushButton2(self.grades) self.grade_4_button.setObjectName(_fromUtf8("grade_4_button")) self.horizontalLayout.addWidget(self.grade_4_button) self.grade_5_button = QPushButton2(self.grades) self.grade_5_button.setObjectName(_fromUtf8("grade_5_button")) self.horizontalLayout.addWidget(self.grade_5_button) self._2.addLayout(self.horizontalLayout) self.vertical_layout.addWidget(self.grades) self.verticalLayout_5.addLayout(self.vertical_layout) self.retranslateUi(ReviewWdgt) QtCore.QObject.connect(self.show_button, QtCore.SIGNAL(_fromUtf8("clicked()")), ReviewWdgt.show_answer) QtCore.QMetaObject.connectSlotsByName(ReviewWdgt) def retranslateUi(self, ReviewWdgt): self.question_label.setText(_('Question:')) self.answer_label.setText(_('Answer:')) self.show_button.setText(_('Show &answer')) self.grades.setTitle(_('Grade your answer:')) self.grade_0_button.setText(_('0')) self.grade_0_button.setShortcut(_('0')) self.grade_1_button.setText(_('1')) self.grade_1_button.setShortcut(_('1')) self.grade_2_button.setText(_('2')) self.grade_2_button.setShortcut(_('2')) self.grade_3_button.setText(_('3')) self.grade_3_button.setShortcut(_('3')) self.grade_4_button.setText(_('4')) self.grade_4_button.setShortcut(_('4')) self.grade_5_button.setText(_('5')) self.grade_5_button.setShortcut(_('5')) from PyQt4 import QtWebKit Mnemosyne-2.2.1/mnemosyne/pyqt_ui/manage_plugins_dlg.py0000644000175000017500000001043212113345271024514 0ustar pbienstpbienst00000000000000# # manage_plugins_dlg.py # import os from PyQt4 import QtCore, QtGui from mnemosyne.libmnemosyne.translator import _ from mnemosyne.pyqt_ui.ui_manage_plugins_dlg import Ui_ManagePluginsDlg from mnemosyne.libmnemosyne.ui_components.dialogs import ManagePluginsDialog class ManagePluginsDlg(QtGui.QDialog, Ui_ManagePluginsDlg, ManagePluginsDialog): def __init__(self, component_manager): ManagePluginsDialog.__init__(self, component_manager) QtGui.QDialog.__init__(self, self.main_widget()) self.setupUi(self) self.setWindowFlags(self.windowFlags() \ | QtCore.Qt.WindowMinMaxButtonsHint) self.setWindowFlags(self.windowFlags() \ & ~ QtCore.Qt.WindowContextHelpButtonHint) self.last_selected_row = 0 self.build_plugin_list() state = self.config()["plugins_dlg_state"] if state: self.restoreGeometry(state) def build_plugin_list(self): plugin_dir = os.path.join(self.config().data_dir, "plugins") self.can_be_deleted = [filename.rsplit(".", 1)[0] for \ filename in os.listdir(plugin_dir) \ if filename.endswith(".manifest")] self.plugin_list.clear() self.previously_active = {} self.plugin_with_name = {} for plugin in self.plugins(): list_item = QtGui.QListWidgetItem(_(plugin.name)) list_item.setFlags(list_item.flags() \ | QtCore.Qt.ItemIsUserCheckable) self.plugin_with_name[_(plugin.name)] = plugin active = \ plugin.__class__.__name__ in self.config()["active_plugins"] self.previously_active[_(plugin.name)] = active if active: list_item.setCheckState(QtCore.Qt.Checked) else: list_item.setCheckState(QtCore.Qt.Unchecked) self.plugin_list.addItem(list_item) self.plugin_list.setCurrentRow(self.last_selected_row) self.plugin_description.setText(_(self.plugins()[0].description)) self.delete_button.setEnabled(\ self.plugins()[0].__class__.__name__ in self.can_be_deleted) def plugin_selected(self, list_item, dummy=None): if list_item is None: # Sometimes Qt fires spurious events. return # If we get there through activating of the item, make sure we move # the selection to the activated item. self.plugin_list.setCurrentItem(list_item) plugin = self.plugin_with_name[unicode(list_item.text())] self.plugin_description.setText(_(plugin.description)) self.delete_button.setEnabled(\ plugin.__class__.__name__ in self.can_be_deleted) def activate(self): self.exec_() def _store_state(self): self.config()["plugins_dlg_state"] = self.saveGeometry() def closeEvent(self, event): # Generated when clicking the window's close button. self._store_state() def accept(self): # 'accept' does not generate a close event. self._store_state() for index in range(self.plugin_list.count()): list_item = self.plugin_list.item(index) plugin_name = unicode(list_item.text()) if list_item.checkState() == QtCore.Qt.Checked and \ self.previously_active[plugin_name] == False: self.plugin_with_name[plugin_name].activate() elif list_item.checkState() == QtCore.Qt.Unchecked and \ self.previously_active[plugin_name] == True: self.plugin_with_name[plugin_name].deactivate() return QtGui.QDialog.accept(self) def install_plugin(self): self.last_selected_row = self.plugin_list.currentRow() self.controller().install_plugin() self.build_plugin_list() def delete_plugin(self): plugin_name = unicode(self.plugin_list.selectedItems()[0].text()) question = _("Are you sure you want to delete the plugin") + " \"" + \ plugin_name + "\" " + _("and not just deactivate it?") answer = self.main_widget().show_question(question, _("Delete"), _("Cancel"), "") if answer == 1: # Cancel return self.controller().delete_plugin(self.plugin_with_name[plugin_name]) self.build_plugin_list() Mnemosyne-2.2.1/mnemosyne/pyqt_ui/convert_card_type_keys_dlg.py0000644000175000017500000000740212113344610026267 0ustar pbienstpbienst00000000000000# # convert_card_type_keys_dlg.py # from PyQt4 import QtCore, QtGui from mnemosyne.libmnemosyne.translator import _ from mnemosyne.pyqt_ui.ui_convert_card_type_keys_dlg import \ Ui_ConvertCardTypeKeysDlg class ConvertCardTypeKeysDlg(QtGui.QDialog, Ui_ConvertCardTypeKeysDlg): def __init__(self, old_card_type, new_card_type, correspondence, check_required_fact_keys=True, parent=None): QtGui.QDialog.__init__(self, parent) self.setupUi(self) self.setWindowFlags(self.windowFlags() \ | QtCore.Qt.WindowMinMaxButtonsHint) self.setWindowFlags(self.windowFlags() \ & ~ QtCore.Qt.WindowContextHelpButtonHint) self.old_card_type = old_card_type self.new_card_type = new_card_type self.correspondence = correspondence self.check_required_fact_keys = check_required_fact_keys self.comboboxes = {} index = 1 for old_fact_key, old_fact_key_name in \ old_card_type.fact_keys_and_names: label = QtGui.QLabel(self) label.setText(_(old_fact_key_name) + ":") font = QtGui.QFont() font.setWeight(50) font.setBold(False) label.setFont(font) self.gridLayout.addWidget(label, index, 0, 1, 1) combobox = QtGui.QComboBox(self) for new_fact_key, new_key_name in \ new_card_type.fact_keys_and_names: combobox.addItem(_(new_key_name)) combobox.addItem(_("")) combobox.setCurrentIndex(combobox.count()-1) self.gridLayout.addWidget(combobox, index, 1, 1, 1) self.comboboxes[old_fact_key] = combobox index += 1 combobox.currentIndexChanged.connect(self.combobox_updated) def combobox_updated(self): self.ok_button.setEnabled(False) self.correspondence.clear() for old_fact_key, old_fact_key_name in \ self.old_card_type.fact_keys_and_names: new_fact_key_name = \ unicode(self.comboboxes[old_fact_key].currentText()) if new_fact_key_name != _(""): self.ok_button.setEnabled(True) new_fact_key = \ self.new_card_type.fact_key_with_name(new_fact_key_name) if new_fact_key in self.correspondence.values(): QtGui.QMessageBox.critical(self, _("Mnemosyne"), _("No duplicate in new fact keys allowed."), _("&OK"), "", "", 0, -1) self.ok_button.setEnabled(False) return self.correspondence[old_fact_key] = new_fact_key if self.check_required_fact_keys: for fact_key in self.new_card_type.required_fact_keys: if fact_key not in self.correspondence.values(): self.ok_button.setEnabled(False) if len(self.correspondence) == \ len(self.old_card_type.fact_keys()): QtGui.QMessageBox.critical(self, _("Mnemosyne"), _("A required field is missing."), _("&OK"), "", "", 0, -1) return def accept(self): self.correspondence.clear() for old_fact_key, old_fact_key_name in \ self.old_card_type.fact_keys_and_names: new_fact_key_name = \ unicode(self.comboboxes[old_fact_key].currentText()) if new_fact_key_name != _(""): new_fact_key = \ self.new_card_type.fact_key_with_name(new_fact_key_name) self.correspondence[old_fact_key] = new_fact_key QtGui.QDialog.accept(self) Mnemosyne-2.2.1/mnemosyne/pyqt_ui/review_wdgt_cramming.py0000644000175000017500000000426612101445403025103 0ustar pbienstpbienst00000000000000# # review_wdgt_cramming.py # from PyQt4 import QtCore, QtGui from mnemosyne.libmnemosyne.translator import _ from mnemosyne.pyqt_ui.review_wdgt import ReviewWdgt class ReviewWdgtCramming(ReviewWdgt): def __init__(self, component_manager): ReviewWdgt.__init__(self, component_manager) self.grade_0_button.setText(_("&Wrong")) self.grade_1_button.hide() self.line.hide() self.grade_2_button.hide() self.grade_3_button.hide() self.grade_4_button.hide() self.grade_5_button.setText(_("&Right")) self.grade_5_button.setFocus() parent = self.parent() self.wrong = QtGui.QLabel("", parent.status_bar) self.unseen = QtGui.QLabel("", parent.status_bar) self.active = QtGui.QLabel("", parent.status_bar) parent.clear_status_bar() parent.add_to_status_bar(self.wrong) parent.add_to_status_bar(self.unseen) parent.add_to_status_bar(self.active) def changeEvent(self, event): if event.type() == QtCore.QEvent.LanguageChange: self.retranslateUi(self) # Upon start, there will be a change event before the grade # buttons have been created. if hasattr(self, "grade_0_button"): self.grade_0_button.setText(_("&Wrong")) self.grade_5_button.setText(_("&Right")) QtGui.QWidget.changeEvent(self, event) def keyPressEvent(self, event): if self.review_controller().is_answer_showing(): if event.key() in [QtCore.Qt.Key_0, QtCore.Qt.Key_1, QtCore.Qt.Key_W]: return self.grade_answer(0) elif event.key() in [QtCore.Qt.Key_2, QtCore.Qt.Key_3, QtCore.Qt.Key_4, QtCore.Qt.Key_5, QtCore.Qt.Key_R]: return self.grade_answer(5) ReviewWdgt.keyPressEvent(self, event) def update_status_bar_counters(self): wrong_count, unseen_count, active_count = \ self.review_controller().counters() self.wrong.setText(_("Wrong: %d ") % wrong_count) self.unseen.setText(_("Unseen: %d ") % unseen_count) self.active.setText(_("Active: %d ") % active_count) Mnemosyne-2.2.1/mnemosyne/pyqt_ui/tip_after_starting_n_times.py0000664000175000017500000000253112113345537026313 0ustar pbienstpbienst00000000000000# # tip_after_starting_n_times.py # from mnemosyne.pyqt_ui.tip_dlg import TipDlg from mnemosyne.libmnemosyne.translator import _ from mnemosyne.libmnemosyne.component import Component class TipAfterStartingNTimes(Component): """Mixin class to show different tips after opening a dialog N times. 'started_n_times_counter' is a string to be used in config to keep track of how many times the dialog was openened. 'tip_after_n_times' is a dictionary like {2: "tip"}. The counter is not increased after the last tip has been reached, such that new tips can be added later. """ started_n_times_counter = "" tip_after_n_times = {} def show_tip_after_starting_n_times(self): counter = self.config()[self.started_n_times_counter] if counter in self.tip_after_n_times: tip_dlg = TipDlg(self.component_manager) tip_dlg.setWindowTitle(_("Mnemosyne")) tip_dlg.show_tips.hide() tip_dlg.previous_button.hide() tip_dlg.next_button.hide() tip_dlg.tip_label.setText(_(self.tip_after_n_times[counter])) tip_dlg.closeEvent = lambda event : event.accept() tip_dlg.exec_() if counter <= max(self.tip_after_n_times.keys()): self.config()[self.started_n_times_counter] = counter + 1 Mnemosyne-2.2.1/mnemosyne/pyqt_ui/ui_tip_dlg.py0000644000175000000000000001231412132771336022325 0ustar pbienstroot00000000000000# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'tip_dlg.ui' # # Created: Mon Apr 15 14:30:22 2013 # by: PyQt4 UI code generator 4.9.3 # # WARNING! All changes made in this file will be lost! from mnemosyne.libmnemosyne.translator import _ from PyQt4 import QtCore, QtGui try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: _fromUtf8 = lambda s: s class Ui_TipDlg(object): def setupUi(self, TipDlg): TipDlg.setObjectName(_fromUtf8("TipDlg")) TipDlg.resize(435, 212) self.vboxlayout = QtGui.QVBoxLayout(TipDlg) self.vboxlayout.setObjectName(_fromUtf8("vboxlayout")) self.vboxlayout1 = QtGui.QVBoxLayout() self.vboxlayout1.setContentsMargins(5, -1, 5, -1) self.vboxlayout1.setObjectName(_fromUtf8("vboxlayout1")) self.hboxlayout = QtGui.QHBoxLayout() self.hboxlayout.setObjectName(_fromUtf8("hboxlayout")) self.watermark = QtGui.QLabel(TipDlg) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.watermark.sizePolicy().hasHeightForWidth()) self.watermark.setSizePolicy(sizePolicy) self.watermark.setPixmap(QtGui.QPixmap(_fromUtf8("image0"))) self.watermark.setScaledContents(True) self.watermark.setWordWrap(False) self.watermark.setObjectName(_fromUtf8("watermark")) self.hboxlayout.addWidget(self.watermark) self.vboxlayout2 = QtGui.QVBoxLayout() self.vboxlayout2.setObjectName(_fromUtf8("vboxlayout2")) self.tip_label_2 = QtGui.QLabel(TipDlg) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.Minimum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.tip_label_2.sizePolicy().hasHeightForWidth()) self.tip_label_2.setSizePolicy(sizePolicy) self.tip_label_2.setWordWrap(False) self.tip_label_2.setObjectName(_fromUtf8("tip_label_2")) self.vboxlayout2.addWidget(self.tip_label_2) self.tip_label = QtGui.QLabel(TipDlg) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.MinimumExpanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.tip_label.sizePolicy().hasHeightForWidth()) self.tip_label.setSizePolicy(sizePolicy) self.tip_label.setText(_fromUtf8("")) self.tip_label.setAlignment(QtCore.Qt.AlignVCenter) self.tip_label.setWordWrap(True) self.tip_label.setOpenExternalLinks(True) self.tip_label.setObjectName(_fromUtf8("tip_label")) self.vboxlayout2.addWidget(self.tip_label) self.hboxlayout.addLayout(self.vboxlayout2) self.vboxlayout1.addLayout(self.hboxlayout) self.line1 = QtGui.QFrame(TipDlg) self.line1.setFrameShape(QtGui.QFrame.HLine) self.line1.setFrameShadow(QtGui.QFrame.Sunken) self.line1.setObjectName(_fromUtf8("line1")) self.vboxlayout1.addWidget(self.line1) self.hboxlayout1 = QtGui.QHBoxLayout() self.hboxlayout1.setObjectName(_fromUtf8("hboxlayout1")) self.show_tips = QtGui.QCheckBox(TipDlg) self.show_tips.setChecked(True) self.show_tips.setObjectName(_fromUtf8("show_tips")) self.hboxlayout1.addWidget(self.show_tips) spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.hboxlayout1.addItem(spacerItem) self.previous_button = QtGui.QPushButton(TipDlg) self.previous_button.setObjectName(_fromUtf8("previous_button")) self.hboxlayout1.addWidget(self.previous_button) self.next_button = QtGui.QPushButton(TipDlg) self.next_button.setObjectName(_fromUtf8("next_button")) self.hboxlayout1.addWidget(self.next_button) self.OK_button = QtGui.QPushButton(TipDlg) self.OK_button.setDefault(True) self.OK_button.setObjectName(_fromUtf8("OK_button")) self.hboxlayout1.addWidget(self.OK_button) self.vboxlayout1.addLayout(self.hboxlayout1) self.vboxlayout.addLayout(self.vboxlayout1) self.retranslateUi(TipDlg) QtCore.QObject.connect(self.OK_button, QtCore.SIGNAL(_fromUtf8("clicked()")), TipDlg.close) QtCore.QObject.connect(self.previous_button, QtCore.SIGNAL(_fromUtf8("clicked()")), TipDlg.previous) QtCore.QObject.connect(self.next_button, QtCore.SIGNAL(_fromUtf8("clicked()")), TipDlg.next) QtCore.QMetaObject.connectSlotsByName(TipDlg) def retranslateUi(self, TipDlg): TipDlg.setWindowTitle(_('Tip of the day')) self.tip_label_2.setText(_('Did you know...?')) self.show_tips.setText(_('&Show tips on startup')) self.show_tips.setShortcut(_('Alt+S')) self.previous_button.setText(_('&Previous')) self.previous_button.setShortcut(_('Alt+P')) self.next_button.setText(_('&Next')) self.next_button.setShortcut(_('Alt+N')) self.OK_button.setText(_('&Close')) self.OK_button.setShortcut(_('Alt+C')) Mnemosyne-2.2.1/mnemosyne/pyqt_ui/pyqt_render_chain.py0000644000175000017500000000230412045736514024402 0ustar pbienstpbienst00000000000000# # pyqt_render_chain.py # import sys from mnemosyne.libmnemosyne.filters.latex import Latex from mnemosyne.libmnemosyne.render_chain import RenderChain from mnemosyne.libmnemosyne.renderers.html_css import HtmlCss from mnemosyne.libmnemosyne.filters.RTL_handler import RTLHandler from mnemosyne.libmnemosyne.filters.html5_audio import Html5Audio from mnemosyne.libmnemosyne.filters.html5_video import Html5Video from mnemosyne.libmnemosyne.filters.expand_paths import ExpandPaths from mnemosyne.libmnemosyne.filters.escape_to_html import EscapeToHtml from mnemosyne.libmnemosyne.filters.non_latin_font_size_increase import \ NonLatinFontSizeIncrease if sys.platform == "win32": from mnemosyne.pyqt_ui.mplayer_audio import MplayerAudio from mnemosyne.pyqt_ui.mplayer_video import MplayerVideo class PyQtRenderChain(RenderChain): id = "default" if sys.platform == "win32": filters = [Latex, EscapeToHtml, ExpandPaths, MplayerAudio, MplayerVideo, RTLHandler, NonLatinFontSizeIncrease] else: filters = [Latex, EscapeToHtml, ExpandPaths, Html5Audio, Html5Video, RTLHandler, NonLatinFontSizeIncrease] renderers = [HtmlCss] Mnemosyne-2.2.1/mnemosyne/pyqt_ui/prefill_tag_behaviour_plugin.py0000664000175000017500000000161112050707350026610 0ustar pbienstpbienst00000000000000# # prefill_tag_behaviour_plugin.py # from PyQt4 import QtCore, QtGui from mnemosyne.libmnemosyne.translator import _ from mnemosyne.libmnemosyne.plugin import Plugin class PrefillTagBehaviourPlugin(Plugin): name = _("Prefill tag behaviour") description = \ _("""When creating new cards, Mnemosyne normally prefills the 'Tag(s)' field with the last value you used, regardless of card type.\n With this plugin, Mnemosyne will for each card type remember the last tag you used, such that e.g. Chinese cards get a prefilled tag like "My Chinese textbook::Chapter 10", whereas Front-to-Back cards get "European Capitals".""") def activate(self): Plugin.activate(self) self.config()["is_last_used_tags_per_card_type"] = True def deactivate(self): Plugin.deactivate(self) self.config()["is_last_used_tags_per_card_type"] = False Mnemosyne-2.2.1/mnemosyne/pyqt_ui/ui_card_set_name_dlg.py0000644000175000000000000000376312132771333024322 0ustar pbienstroot00000000000000# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'card_set_name_dlg.ui' # # Created: Mon Apr 15 14:30:19 2013 # by: PyQt4 UI code generator 4.9.3 # # WARNING! All changes made in this file will be lost! from mnemosyne.libmnemosyne.translator import _ from PyQt4 import QtCore, QtGui try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: _fromUtf8 = lambda s: s class Ui_CardSetNameDlg(object): def setupUi(self, CardSetNameDlg): CardSetNameDlg.setObjectName(_fromUtf8("CardSetNameDlg")) CardSetNameDlg.resize(312, 36) self.verticalLayout = QtGui.QVBoxLayout(CardSetNameDlg) self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) self.horizontalLayout = QtGui.QHBoxLayout() self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout")) self.label = QtGui.QLabel(CardSetNameDlg) self.label.setObjectName(_fromUtf8("label")) self.horizontalLayout.addWidget(self.label) self.set_name = QtGui.QComboBox(CardSetNameDlg) self.set_name.setEditable(True) self.set_name.setObjectName(_fromUtf8("set_name")) self.horizontalLayout.addWidget(self.set_name) self.ok_button = QtGui.QPushButton(CardSetNameDlg) self.ok_button.setDefault(True) self.ok_button.setObjectName(_fromUtf8("ok_button")) self.horizontalLayout.addWidget(self.ok_button) self.verticalLayout.addLayout(self.horizontalLayout) self.retranslateUi(CardSetNameDlg) QtCore.QObject.connect(self.ok_button, QtCore.SIGNAL(_fromUtf8("clicked()")), CardSetNameDlg.accept) QtCore.QObject.connect(self.set_name, QtCore.SIGNAL(_fromUtf8("editTextChanged(QString)")), CardSetNameDlg.text_changed) QtCore.QMetaObject.connectSlotsByName(CardSetNameDlg) def retranslateUi(self, CardSetNameDlg): CardSetNameDlg.setWindowTitle(_('Card set name')) self.label.setText(_('Card set name:')) self.ok_button.setText(_('&OK')) Mnemosyne-2.2.1/mnemosyne/pyqt_ui/delete_unused_media_files_dlg.py0000664000175000017500000000207311723363227026704 0ustar pbienstpbienst00000000000000# # delete_unused_media_files_dlg.py # from PyQt4 import QtCore, QtGui from mnemosyne.libmnemosyne.component import Component from mnemosyne.pyqt_ui.ui_delete_unused_media_files_dlg import \ Ui_DeleteUnusedMediaFilesDlg class DeleteUnusedMediaFilesDlg(QtGui.QDialog, Ui_DeleteUnusedMediaFilesDlg, Component): def __init__(self, component_manager, unused_media_files): Component.__init__(self, component_manager) QtGui.QDialog.__init__(self, self.main_widget()) self.setupUi(self) self.setWindowFlags(self.windowFlags() \ | QtCore.Qt.WindowMinMaxButtonsHint) self.setWindowFlags(self.windowFlags() \ & ~ QtCore.Qt.WindowContextHelpButtonHint) self.unused_media_files = unused_media_files self.file_list.setText("\n".join(self.unused_media_files)) def activate(self): self.exec_() def accept(self): self.database().delete_unused_media_files(self.unused_media_files) QtGui.QDialog.accept(self) Mnemosyne-2.2.1/mnemosyne/pyqt_ui/ui_remove_tags_dlg.py0000644000175000000000000000506512132771336024051 0ustar pbienstroot00000000000000# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'remove_tags_dlg.ui' # # Created: Mon Apr 15 14:30:21 2013 # by: PyQt4 UI code generator 4.9.3 # # WARNING! All changes made in this file will be lost! from mnemosyne.libmnemosyne.translator import _ from PyQt4 import QtCore, QtGui try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: _fromUtf8 = lambda s: s class Ui_RemoveTagsDlg(object): def setupUi(self, RemoveTagsDlg): RemoveTagsDlg.setObjectName(_fromUtf8("RemoveTagsDlg")) RemoveTagsDlg.resize(257, 260) self.verticalLayout_2 = QtGui.QVBoxLayout(RemoveTagsDlg) self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2")) self.verticalLayout = QtGui.QVBoxLayout() self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) self.label = QtGui.QLabel(RemoveTagsDlg) self.label.setObjectName(_fromUtf8("label")) self.verticalLayout.addWidget(self.label) self.tag_list = QtGui.QListWidget(RemoveTagsDlg) self.tag_list.setObjectName(_fromUtf8("tag_list")) self.verticalLayout.addWidget(self.tag_list) self.hboxlayout = QtGui.QHBoxLayout() self.hboxlayout.setObjectName(_fromUtf8("hboxlayout")) self.ok_button = QtGui.QPushButton(RemoveTagsDlg) self.ok_button.setAutoDefault(True) self.ok_button.setDefault(True) self.ok_button.setObjectName(_fromUtf8("ok_button")) self.hboxlayout.addWidget(self.ok_button) spacerItem = QtGui.QSpacerItem(101, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.hboxlayout.addItem(spacerItem) self.cancel_button = QtGui.QPushButton(RemoveTagsDlg) self.cancel_button.setAutoDefault(False) self.cancel_button.setObjectName(_fromUtf8("cancel_button")) self.hboxlayout.addWidget(self.cancel_button) self.verticalLayout.addLayout(self.hboxlayout) self.verticalLayout_2.addLayout(self.verticalLayout) self.retranslateUi(RemoveTagsDlg) QtCore.QObject.connect(self.cancel_button, QtCore.SIGNAL(_fromUtf8("clicked()")), RemoveTagsDlg.reject) QtCore.QObject.connect(self.ok_button, QtCore.SIGNAL(_fromUtf8("clicked()")), RemoveTagsDlg.accept) QtCore.QMetaObject.connectSlotsByName(RemoveTagsDlg) def retranslateUi(self, RemoveTagsDlg): RemoveTagsDlg.setWindowTitle(_('Remove tags')) self.label.setText(_('Tags to remove:')) self.ok_button.setText(_('&OK')) self.cancel_button.setText(_('&Cancel')) import mnemosyne_rc Mnemosyne-2.2.1/mnemosyne/pyqt_ui/statistics_dlg.py0000644000175000017500000001243311712726175023732 0ustar pbienstpbienst00000000000000# # statistics_dlg.py # from PyQt4 import QtCore, QtGui from mnemosyne.libmnemosyne.translator import _ from mnemosyne.libmnemosyne.component import Component from mnemosyne.pyqt_ui.ui_statistics_dlg import Ui_StatisticsDlg from mnemosyne.libmnemosyne.ui_components.dialogs import StatisticsDialog class StatisticsDlg(QtGui.QDialog, Ui_StatisticsDlg, StatisticsDialog): """A tab widget containing several statistics pages. The number and names of the tab pages are determined at run time. """ def __init__(self, component_manager): StatisticsDialog.__init__(self, component_manager) QtGui.QDialog.__init__(self, self.main_widget()) def activate(self): self.setupUi(self) self.setWindowFlags(self.windowFlags() \ | QtCore.Qt.WindowMinMaxButtonsHint) self.setWindowFlags(self.windowFlags() \ & ~ QtCore.Qt.WindowContextHelpButtonHint) previous_page_index = self.config()["previous_statistics_page"] page_index = 0 for page in self.component_manager.all("statistics_page"): page = page(self.component_manager) self.tab_widget.addTab(StatisticsPageWdgt(self.component_manager, self, page, page_index), _(page.name)) page_index += 1 self.tab_widget.tabBar().setVisible(self.tab_widget.count() > 1) if previous_page_index >= self.tab_widget.count(): previous_page_index = 0 self.tab_widget.setCurrentIndex(previous_page_index) self.display_page(previous_page_index) state = self.config()["statistics_dlg_state"] if state: self.restoreGeometry(state) # Only now do we connect the signal in order to have lazy # instantiation. self.tab_widget.currentChanged[int].connect(self.display_page) self.exec_() def _store_state(self): self.config()["statistics_dlg_state"] = self.saveGeometry() def closeEvent(self, event): # Generated when clicking the window's close button. self._store_state() def accept(self): # 'accept' does not generate a close event. self._store_state() return QtGui.QDialog.accept(self) def display_page(self, page_index): page = self.tab_widget.widget(page_index) self.config()["previous_statistics_page"] = page_index self.config()["previous_variant_for_statistics_page"]\ .setdefault(page_index, 0) variant_index = self.config()\ ["previous_variant_for_statistics_page"][page_index] if variant_index >= page.combobox.count(): variant_index = 0 page.combobox.setCurrentIndex(variant_index) page.display_variant(variant_index) class StatisticsPageWdgt(QtGui.QWidget, Component): """A page in the StatisticsDlg tab widget. This page widget only contains a combobox to select different variants of the page. The widget that displays the statistics information itself is only generated when it becomes visible. """ def __init__(self, component_manager, parent, statistics_page, page_index): Component.__init__(self, component_manager) QtGui.QWidget.__init__(self, parent) self.statistics_page = statistics_page self.page_index = page_index self.vbox_layout = QtGui.QVBoxLayout(self) self.combobox = QtGui.QComboBox(self) self.variant_ids = [] self.variant_widgets = [] self.current_variant_widget = None variants = statistics_page.variants if not variants: variants = [(0, _("Default"))] for variant_id, variant_name in variants: self.variant_ids.append(variant_id) self.variant_widgets.append(None) self.combobox.addItem(unicode(_(variant_name))) if len(self.variant_ids) <= 1 or \ self.statistics_page.show_variants_in_combobox == False: self.combobox.hide() self.vbox_layout.addWidget(self.combobox) self.combobox.currentIndexChanged.connect(self.display_variant) def display_variant(self, variant_index): """Lazy creation of the actual widget that displays the statistics.""" # Hide the previous widget if there was once. if self.current_variant_widget: self.vbox_layout.removeWidget(self.current_variant_widget) self.current_variant_widget.hide() # Create widget if it has not been shown before. if not self.variant_widgets[variant_index]: self.statistics_page.prepare_statistics\ (self.variant_ids[variant_index]) widget_class = self.component_manager.current(\ "statistics_widget", used_for=self.statistics_page.__class__) widget = widget_class(self.component_manager, self, self.statistics_page) widget.show_statistics(self.variant_ids[variant_index]) self.variant_widgets[variant_index] = widget # Show the widget created earlier. self.current_variant_widget = self.variant_widgets[variant_index] self.vbox_layout.addWidget(self.current_variant_widget) self.current_variant_widget.show() self.config()["previous_variant_for_statistics_page"]\ [self.page_index] = variant_index Mnemosyne-2.2.1/mnemosyne/pyqt_ui/ui_criterion_wdgt_default.py0000644000175000000000000000371412132771334025434 0ustar pbienstroot00000000000000# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'criterion_wdgt_default.ui' # # Created: Mon Apr 15 14:30:20 2013 # by: PyQt4 UI code generator 4.9.3 # # WARNING! All changes made in this file will be lost! from mnemosyne.libmnemosyne.translator import _ from PyQt4 import QtCore, QtGui try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: _fromUtf8 = lambda s: s class Ui_DefaultCriterionWdgt(object): def setupUi(self, DefaultCriterionWdgt): DefaultCriterionWdgt.setObjectName(_fromUtf8("DefaultCriterionWdgt")) DefaultCriterionWdgt.resize(583, 427) self.verticalLayout = QtGui.QVBoxLayout(DefaultCriterionWdgt) self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) self.gridLayout = QtGui.QGridLayout() self.gridLayout.setObjectName(_fromUtf8("gridLayout")) self.label = QtGui.QLabel(DefaultCriterionWdgt) self.label.setObjectName(_fromUtf8("label")) self.gridLayout.addWidget(self.label, 0, 0, 1, 1) self.active_or_forbidden = QtGui.QComboBox(DefaultCriterionWdgt) self.active_or_forbidden.setObjectName(_fromUtf8("active_or_forbidden")) self.active_or_forbidden.addItem(_fromUtf8("")) self.active_or_forbidden.addItem(_fromUtf8("")) self.gridLayout.addWidget(self.active_or_forbidden, 0, 1, 1, 1) self.verticalLayout.addLayout(self.gridLayout) self.retranslateUi(DefaultCriterionWdgt) QtCore.QObject.connect(self.active_or_forbidden, QtCore.SIGNAL(_fromUtf8("currentIndexChanged(int)")), DefaultCriterionWdgt.criterion_changed) QtCore.QMetaObject.connectSlotsByName(DefaultCriterionWdgt) def retranslateUi(self, DefaultCriterionWdgt): self.label.setText(_('Activate cards from these card types:')) self.active_or_forbidden.setItemText(0, _('having any of these tags:')) self.active_or_forbidden.setItemText(1, _('not having any of these tags:')) Mnemosyne-2.2.1/mnemosyne/pyqt_ui/browse_cards_dlg.py0000644000175000017500000010417112131260212024173 0ustar pbienstpbienst00000000000000# # browse_cards_dlg.py # import sys import time import locale from PyQt4 import QtCore, QtGui, QtSql from mnemosyne.libmnemosyne.tag import Tag from mnemosyne.libmnemosyne.fact import Fact from mnemosyne.libmnemosyne.card import Card from mnemosyne.libmnemosyne.translator import _ from mnemosyne.libmnemosyne.component import Component from mnemosyne.pyqt_ui.tag_tree_wdgt import TagsTreeWdgt from mnemosyne.pyqt_ui.ui_browse_cards_dlg import Ui_BrowseCardsDlg from mnemosyne.pyqt_ui.card_type_tree_wdgt import CardTypesTreeWdgt from mnemosyne.libmnemosyne.ui_components.dialogs import BrowseCardsDialog from mnemosyne.libmnemosyne.criteria.default_criterion import DefaultCriterion from mnemosyne.pyqt_ui.convert_card_type_keys_dlg import \ ConvertCardTypeKeysDlg from mnemosyne.pyqt_ui.tip_after_starting_n_times import \ TipAfterStartingNTimes _ID = 0 ID = 1 CARD_TYPE_ID = 2 _FACT_ID = 3 FACT_VIEW_ID = 4 QUESTION = 5 ANSWER = 6 TAGS = 7 GRADE = 8 NEXT_REP = 9 LAST_REP = 10 EASINESS = 11 ACQ_REPS = 12 RET_REPS = 13 LAPSES = 14 ACQ_REPS_SINCE_LAPSE = 15 RET_REPS_SINCE_LAPSE = 16 CREATION_TIME = 17 MODIFICATION_TIME = 18 EXTRA_DATA = 19 SCHEDULER_DATA = 20 ACTIVE = 21 class CardModel(QtSql.QSqlTableModel, Component): def __init__(self, component_manager): QtSql.QSqlTableModel.__init__(self) Component.__init__(self, component_manager) self.search_string = "" self.adjusted_now = self.scheduler().adjusted_now() try: self.date_format = locale.nl_langinfo(locale.D_FMT) except: self.date_format = "%m/%d/%y" self.background_colour_for_card_type_id = {} for card_type_id, rgb in \ self.config()["background_colour"].iteritems(): # If the card type has been deleted since, don't bother. if not card_type_id in self.component_manager.card_type_with_id: continue self.background_colour_for_card_type_id[card_type_id] = \ QtGui.QColor(rgb) self.font_colour_for_card_type_id = {} for card_type_id in self.config()["font_colour"]: if not card_type_id in self.component_manager.card_type_with_id: continue first_key = \ self.card_type_with_id(card_type_id).fact_keys_and_names[0][0] self.font_colour_for_card_type_id[card_type_id] = QtGui.QColor(\ self.config()["font_colour"][card_type_id][first_key]) def data(self, index, role=QtCore.Qt.DisplayRole): if role == QtCore.Qt.TextColorRole: card_type_id_index = self.index(index.row(), CARD_TYPE_ID) card_type_id = unicode(QtSql.QSqlTableModel.data(\ self, card_type_id_index).toString()) colour = QtGui.QColor(QtCore.Qt.black) if card_type_id in self.font_colour_for_card_type_id: colour = self.font_colour_for_card_type_id[card_type_id] return QtCore.QVariant(colour) if role == QtCore.Qt.BackgroundColorRole: card_type_id_index = self.index(index.row(), CARD_TYPE_ID) card_type_id = unicode(QtSql.QSqlTableModel.data(\ self, card_type_id_index).toString()) if card_type_id in self.background_colour_for_card_type_id: return QtCore.QVariant(\ self.background_colour_for_card_type_id[card_type_id]) else: return QtCore.QVariant(\ QtGui.qApp.palette().color(QtGui.QPalette.Base)) column = index.column() if role == QtCore.Qt.TextAlignmentRole and column not in \ (QUESTION, ANSWER, TAGS): return QtCore.QVariant(QtCore.Qt.AlignCenter) if role == QtCore.Qt.FontRole and column not in \ (QUESTION, ANSWER, TAGS): active_index = self.index(index.row(), ACTIVE) active = QtSql.QSqlTableModel.data(self, active_index).toInt()[0] font = QtGui.QFont() if not active: font.setStrikeOut(True) return QtCore.QVariant(font) if role != QtCore.Qt.DisplayRole: return QtSql.QSqlTableModel.data(self, index, role) # Display roles to format some columns in a more pretty way. Note that # sorting still uses the orginal database keys, which is good # for speed. if column == GRADE: grade = QtSql.QSqlTableModel.data(self, index).toInt()[0] if grade == -1: return QtCore.QVariant(_("Yet to learn")) else: return QtCore.QVariant(grade) if column == NEXT_REP: next_rep = QtSql.QSqlTableModel.data(self, index, role).toInt()[0] if next_rep == -1: return QtCore.QVariant("") return QtCore.QVariant(\ self.scheduler().next_rep_to_interval_string(next_rep)) if column == LAST_REP: last_rep = QtSql.QSqlTableModel.data(self, index, role).toInt()[0] if last_rep == -1: return QtCore.QVariant("") return QtCore.QVariant(\ self.scheduler().last_rep_to_interval_string(last_rep)) if column == EASINESS: old_data = QtSql.QSqlTableModel.data(self, index, role).toString() return QtCore.QVariant("%.2f" % float(old_data)) if column in (CREATION_TIME, MODIFICATION_TIME): old_data = QtSql.QSqlTableModel.data(self, index, role).toInt()[0] return QtCore.QVariant(time.strftime(self.date_format, time.localtime(old_data))) return QtSql.QSqlTableModel.data(self, index, role) class QA_Delegate(QtGui.QStyledItemDelegate, Component): # http://stackoverflow.com/questions/1956542/ # how-to-make-item-view-render-rich-html-text-in-qt def __init__(self, component_manager, Q_or_A, parent=None): Component.__init__(self, component_manager) QtGui.QStyledItemDelegate.__init__(self, parent) self.doc = QtGui.QTextDocument(self) self.Q_or_A = Q_or_A # We need to reimplement the database access functions here using Qt's # database driver. Otherwise, both Qt and libmnemosyne try to claim # ownership at the same time. We don't reconstruct everything in order # to save time. This could in theory give problems if the browser render # chain makes use of this extra information, but that seems unlikely. def tag(self, _id): query = QtSql.QSqlQuery(\ "select name from tags where _id=%d" % (_id, )) query.first() tag = Tag(unicode(query.value(0).toString()), "dummy_id") tag._id = _id return tag def fact(self, _id): # Create dictionary with fact.data. fact_data = {} query = QtSql.QSqlQuery(\ "select key, value from data_for_fact where _fact_id=%d" % (_id, )) query.next() while query.isValid(): fact_data[unicode(query.value(0).toString())] = \ unicode(query.value(1).toString()) query.next() # Create fact. fact = Fact(fact_data, "dummy_id") fact._id = _id return fact def card(self, _id): query = QtSql.QSqlQuery("""select _fact_id, card_type_id, fact_view_id, extra_data from cards where _id=%d""" % (_id, )) query.first() fact = self.fact(query.value(0).toInt()[0]) # Note that for the card type, we turn to the component manager as # opposed to this database, as we would otherwise miss the built-in # system card types card_type = self.card_type_with_id(unicode(query.value(1).toString())) fact_view_id = unicode(query.value(2).toString()) for fact_view in card_type.fact_views: if fact_view.id == fact_view_id: card = Card(card_type, fact, fact_view) # We need extra_data to display the cloze cards. extra_data = unicode(query.value(3).toString()) if extra_data == "": card.extra_data = {} else: card.extra_data = eval(extra_data) break # Let's not add tags to speed things up, they don't affect the card # browser renderer #query = QtSql.QSqlQuery("""select _tag_id from tags_for_card # where _card_id=%d""" % (_id, )) #query.next() #while query.isValid(): # card.tags.add(self.tag(query.value(0).toInt()[0])) # query.next() return card def paint(self, painter, option, index): optionV4 = QtGui.QStyleOptionViewItemV4(option) self.initStyleOption(optionV4, index) if optionV4.widget: style = optionV4.widget.style() else: style = QtGui.QApplication.style() # Get the data. _id_index = index.model().index(index.row(), _ID) _id = index.model().data(_id_index).toInt()[0] ignore_text_colour = bool(optionV4.state & QtGui.QStyle.State_Selected) search_string = index.model().search_string card = self.card(_id) if self.Q_or_A == QUESTION: self.doc.setHtml(card.question(render_chain="card_browser", ignore_text_colour=ignore_text_colour, search_string=search_string)) else: self.doc.setHtml(card.answer(render_chain="card_browser", ignore_text_colour=ignore_text_colour, search_string=search_string)) # Paint the item without the text. optionV4.text = QtCore.QString() style.drawControl(QtGui.QStyle.CE_ItemViewItem, optionV4, painter) context = QtGui.QAbstractTextDocumentLayout.PaintContext() # Highlight text if item is selected. if optionV4.state & QtGui.QStyle.State_Selected: context.palette.setColor(QtGui.QPalette.Text, optionV4.palette.color(QtGui.QPalette.Active, QtGui.QPalette.HighlightedText)) rect = \ style.subElementRect(QtGui.QStyle.SE_ItemViewItemText, optionV4) painter.save() # No longer used (done in model for all columns), # but kept for reference. #if not (optionV4.state & QtGui.QStyle.State_Selected) and \ # not (optionV4.state & QtGui.QStyle.State_MouseOver): # painter.fillRect(rect, QtGui.QColor("red")) painter.translate(rect.topLeft()) painter.translate(0, 3) # There seems to be a small offset needed... painter.setClipRect(rect.translated(-rect.topLeft())) self.doc.documentLayout().draw(painter, context) painter.restore() class BrowseCardsDlg(QtGui.QDialog, Ui_BrowseCardsDlg, BrowseCardsDialog, TipAfterStartingNTimes): started_n_times_counter = "started_browse_cards_n_times" tip_after_n_times = \ {3 : _("Right-click on a tag name in the card browser to edit or delete it."), 6 : _("Double-click on a card or tag name in the card browser to edit them."), 9 : _("You can reorder columns in the card browser by dragging the header label."), 12 : _("You can resize columns in the card browser by dragging between the header labels."), 15 : _("When editing or previewing cards from the card browser, PageUp/PageDown can be used to move to the previous/next card."), 18 : _("You change the relative size of the card list, card type tree and tag tree by dragging the dividers between them.")} def __init__(self, component_manager): BrowseCardsDialog.__init__(self, component_manager) self.show_tip_after_starting_n_times() QtGui.QDialog.__init__(self, self.main_widget()) self.setupUi(self) self.setWindowFlags(self.windowFlags() \ | QtCore.Qt.WindowMinMaxButtonsHint) self.setWindowFlags(self.windowFlags() \ & ~ QtCore.Qt.WindowContextHelpButtonHint) self.saved_index = None self.card_model = None # Set up card type tree. self.container_1 = QtGui.QWidget(self.splitter_1) self.layout_1 = QtGui.QVBoxLayout(self.container_1) self.label_1 = QtGui.QLabel(_("Show cards from these card types:"), self.container_1) self.layout_1.addWidget(self.label_1) self.card_type_tree_wdgt = \ CardTypesTreeWdgt(component_manager, self.container_1, self.unload_qt_database, self.display_card_table) self.layout_1.addWidget(self.card_type_tree_wdgt) self.splitter_1.insertWidget(0, self.container_1) # Set up tag tree plus search box. self.container_2 = QtGui.QWidget(self.splitter_1) self.layout_2 = QtGui.QVBoxLayout(self.container_2) self.label_2 = QtGui.QLabel(_("having any of these tags:"), self.container_2) self.layout_2.addWidget(self.label_2) self.tag_tree_wdgt = \ TagsTreeWdgt(component_manager, self.container_2, self.unload_qt_database, self.display_card_table) self.layout_2.addWidget(self.tag_tree_wdgt) self.label_3 = QtGui.QLabel(_("containing this text in the cards:"), self.container_2) self.layout_2.addWidget(self.label_3) self.search_box = QtGui.QLineEdit(self.container_2) self.search_box.textChanged.connect(self.search_text_changed) self.timer = QtCore.QTimer(self) self.timer.setSingleShot(True) self.timer.timeout.connect(self.update_filter) self.search_box.setFocus() self.layout_2.addWidget(self.search_box) self.splitter_1.insertWidget(1, self.container_2) # Fill tree widgets. criterion = self.database().current_criterion() self.card_type_tree_wdgt.display(criterion) self.tag_tree_wdgt.display(criterion) # When starting the widget, we default with the current criterion # as filter. In this case, we can make a shortcut simply by selecting # on 'active=1' self.display_card_table(run_filter=False) self.card_model.setFilter("cards.active=1") self.card_model.select() self.update_card_counters() self.card_type_tree_wdgt.tree_wdgt.\ itemClicked.connect(self.update_filter) self.tag_tree_wdgt.tree_wdgt.\ itemClicked.connect(self.update_filter) # Context menu. self.table.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.table.customContextMenuRequested.connect(self.context_menu) # Restore state. state = self.config()["browse_cards_dlg_state"] if state: self.restoreGeometry(state) splitter_1_state = self.config()["browse_cards_dlg_splitter_1_state"] if not splitter_1_state: self.splitter_1.setSizes([230, 320]) else: self.splitter_1.restoreState(splitter_1_state) splitter_2_state = self.config()["browse_cards_dlg_splitter_2_state"] if not splitter_2_state: self.splitter_2.setSizes([333, 630]) else: self.splitter_2.restoreState(splitter_2_state) for column in (_ID, ID, CARD_TYPE_ID, _FACT_ID, FACT_VIEW_ID, ACQ_REPS_SINCE_LAPSE, RET_REPS_SINCE_LAPSE, EXTRA_DATA, ACTIVE, SCHEDULER_DATA): self.table.setColumnHidden(column, True) def context_menu(self, point): menu = QtGui.QMenu(self) edit_action = QtGui.QAction(_("&Edit"), menu) edit_action.setShortcut(QtCore.Qt.CTRL + QtCore.Qt.Key_E) edit_action.triggered.connect(self.menu_edit) menu.addAction(edit_action) preview_action = QtGui.QAction(_("&Preview"), menu) preview_action.setShortcut(QtCore.Qt.CTRL + QtCore.Qt.Key_P) preview_action.triggered.connect(self.menu_preview) menu.addAction(preview_action) delete_action = QtGui.QAction(_("&Delete"), menu) delete_action.setShortcut(QtGui.QKeySequence.Delete) delete_action.triggered.connect(self.menu_delete) menu.addAction(delete_action) menu.addSeparator() change_card_type_action = QtGui.QAction(_("Change card &type"), menu) change_card_type_action.triggered.connect(self.menu_change_card_type) menu.addAction(change_card_type_action) menu.addSeparator() add_tags_action = QtGui.QAction(_("&Add tags"), menu) add_tags_action.triggered.connect(self.menu_add_tags) menu.addAction(add_tags_action) remove_tags_action = QtGui.QAction(_("&Remove tags"), menu) remove_tags_action.triggered.connect(self.menu_remove_tags) menu.addAction(remove_tags_action) indexes = self.table.selectionModel().selectedRows() if len(indexes) > 1: edit_action.setEnabled(False) preview_action.setEnabled(False) if len(indexes) >= 1: menu.exec_(self.table.mapToGlobal(point)) def keyPressEvent(self, event): if len(self.table.selectionModel().selectedRows()) == 0: QtGui.QDialog.keyPressEvent(self, event) if event.key() in [QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return]: self.menu_edit() elif event.key() == QtCore.Qt.Key_E and \ event.modifiers() == QtCore.Qt.ControlModifier: self.menu_edit() elif event.key() == QtCore.Qt.Key_P and \ event.modifiers() == QtCore.Qt.ControlModifier: self.menu_preview() elif event.key() == QtCore.Qt.Key_F and \ event.modifiers() == QtCore.Qt.ControlModifier: self.search_box.setFocus() elif event.key() in [QtCore.Qt.Key_Delete, QtCore.Qt.Key_Backspace]: self.menu_delete() else: QtGui.QDialog.keyPressEvent(self, event) def cards_from_single_selection(self): selected_rows = self.table.selectionModel().selectedRows() if len(selected_rows) == 0: return [] index = selected_rows[0] _fact_id_index = index.model().index(\ index.row(), _FACT_ID, index.parent()) _fact_id = index.model().data(_fact_id_index).toInt()[0] fact = self.database().fact(_fact_id, is_id_internal=True) return self.database().cards_from_fact(fact) def facts_from_selection(self): _fact_ids = set() for index in self.table.selectionModel().selectedRows(): _fact_id_index = index.model().index(\ index.row(), _FACT_ID, index.parent()) _fact_id = index.model().data(_fact_id_index).toInt()[0] _fact_ids.add(_fact_id) facts = [] for _fact_id in _fact_ids: facts.append(self.database().fact(_fact_id, is_id_internal=True)) return facts def _card_ids_from_selection(self): _card_ids = set() for index in self.table.selectionModel().selectedRows(): _card_id_index = index.model().index(\ index.row(), _ID, index.parent()) _card_id = index.model().data(_card_id_index).toInt()[0] _card_ids.add(_card_id) return _card_ids def menu_edit(self, index=None): # 'index' gets passed if this function gets called through the # table.doubleClicked event. cards = self.cards_from_single_selection() if len(cards) == 0: return self.edit_dlg = self.component_manager.current("edit_card_dialog")\ (cards[0], self.component_manager, started_from_card_browser=True, parent=self) self.edit_dlg.before_apply_hook = self.unload_qt_database self.edit_dlg.page_up_down_signal.connect(self.page_up_down_edit) if self.edit_dlg.exec_() == QtGui.QDialog.Accepted: self.display_card_table() self.card_type_tree_wdgt.rebuild() self.tag_tree_wdgt.rebuild() # Avoid multiple connections. self.edit_dlg.page_up_down_signal.disconnect(self.page_up_down_edit) def page_up_down_edit(self, up_down): current_row = self.table.selectionModel().selectedRows()[0].row() if up_down == self.edit_dlg.UP: shift = -1 elif up_down == self.edit_dlg.DOWN: shift = 1 self.table.selectRow(current_row + shift) self.edit_dlg.set_new_card(self.cards_from_single_selection()[0]) def menu_preview(self): from mnemosyne.pyqt_ui.preview_cards_dlg import PreviewCardsDlg cards = self.cards_from_single_selection() tag_text = cards[0].tag_string() self.preview_dlg = \ PreviewCardsDlg(self.component_manager, cards, tag_text, self) self.preview_dlg.page_up_down_signal.connect(\ self.page_up_down_preview) self.preview_dlg.exec_() # Avoid multiple connections. self.preview_dlg.page_up_down_signal.disconnect(\ self.page_up_down_preview) def page_up_down_preview(self, up_down): from mnemosyne.pyqt_ui.preview_cards_dlg import PreviewCardsDlg current_row = self.table.selectionModel().selectedRows()[0].row() if up_down == PreviewCardsDlg.UP: shift = -1 elif up_down == PreviewCardsDlg.DOWN: shift = 1 self.table.selectRow(current_row + shift) self.preview_dlg.index = 0 self.preview_dlg.cards = self.cards_from_single_selection() self.preview_dlg.tag_text = self.preview_dlg.cards[0].tag_string() self.preview_dlg.update_dialog() def menu_delete(self): answer = self.main_widget().show_question\ (_("Go ahead with delete? Sister cards will be deleted as well."), _("&OK"), _("&Cancel"), "") if answer == 1: # Cancel. return facts = [] for index in self.table.selectionModel().selectedRows(): _fact_id_index = index.model().index(\ index.row(), _FACT_ID, index.parent()) _fact_id = index.model().data(_fact_id_index).toInt()[0] facts.append(self.database().fact(_fact_id, is_id_internal=True)) self.unload_qt_database() self.saved_selection = [] self.controller().delete_facts_and_their_cards(facts) self.display_card_table() self.card_type_tree_wdgt.rebuild() self.tag_tree_wdgt.rebuild() def menu_change_card_type(self): # Test if all selected cards have the same card type. current_card_type_ids = set() for index in self.table.selectionModel().selectedRows(): card_type_id_index = index.model().index(\ index.row(), CARD_TYPE_ID, index.parent()) card_type_id = \ unicode(index.model().data(card_type_id_index).toString()) current_card_type_ids.add(card_type_id) if len(current_card_type_ids) > 1: self.main_widget().show_error\ (_("The selected cards should have the same card type.")) return current_card_type = self.card_type_with_id(current_card_type_ids.pop()) # Get new card type. Use a dict as backdoor to return values # from the dialog. return_values = {} from mnemosyne.pyqt_ui.change_card_type_dlg import ChangeCardTypeDlg dlg = ChangeCardTypeDlg(self.component_manager, current_card_type, return_values, parent=self) if dlg.exec_() != QtGui.QDialog.Accepted: return new_card_type = return_values["new_card_type"] # Get correspondence. self.correspondence = {} if not current_card_type.fact_keys().issubset(new_card_type.fact_keys()): dlg = ConvertCardTypeKeysDlg(current_card_type, new_card_type, self.correspondence, check_required_fact_keys=True, parent=self) if dlg.exec_() != QtGui.QDialog.Accepted: return # Start the actual conversion. facts = self.facts_from_selection() self.unload_qt_database() self.controller().change_card_type(facts, current_card_type, new_card_type, self.correspondence) self.display_card_table() self.card_type_tree_wdgt.rebuild() self.tag_tree_wdgt.rebuild() def menu_add_tags(self): # Get new tag names. Use a dict as backdoor to return values # from the dialog. return_values = {} from mnemosyne.pyqt_ui.add_tags_dlg import AddTagsDlg dlg = AddTagsDlg(self.component_manager, return_values, parent=self) if dlg.exec_() != QtGui.QDialog.Accepted: return # Add the tags. _card_ids = self._card_ids_from_selection() self.unload_qt_database() for tag_name in return_values["tag_names"]: if not tag_name: continue tag = self.database().get_or_create_tag_with_name(tag_name) self.database().add_tag_to_cards_with_internal_ids(tag, _card_ids) self.display_card_table() self.tag_tree_wdgt.rebuild() def menu_remove_tags(self): # Figure out the tags used by the selected cards. _card_ids = self._card_ids_from_selection() tags = self.database().tags_from_cards_with_internal_ids(_card_ids) # Get new tag names. Use a dict as backdoor to return values # from the dialog. return_values = {} from mnemosyne.pyqt_ui.remove_tags_dlg import RemoveTagsDlg dlg = RemoveTagsDlg(self, tags, return_values) if dlg.exec_() != QtGui.QDialog.Accepted: return # Remove the tags. self.unload_qt_database() for tag_name in return_values["tag_names"]: if not tag_name: continue tag = self.database().get_or_create_tag_with_name(tag_name) self.database().remove_tag_from_cards_with_internal_ids(\ tag, _card_ids) self.display_card_table() self.tag_tree_wdgt.rebuild() def load_qt_database(self): self.database().release_connection() qt_db = QtSql.QSqlDatabase.addDatabase("QSQLITE") qt_db.setDatabaseName(self.database().path()) if not qt_db.open(): QtGui.QMessageBox.warning(None, _("Mnemosyne"), _("Database error: ") + qt_db.lastError().text()) sys.exit(1) def unload_qt_database(self): # Don't save state twice when closing dialog. if self.card_model is None: return self.saved_index = self.table.indexAt(QtCore.QPoint(0,0)) self.saved_selection = self.table.selectionModel().selectedRows() if not self.config()["start_card_browser_sorted"]: self.table.horizontalHeader().setSortIndicator\ (-1, QtCore.Qt.AscendingOrder) self.config()["browse_cards_dlg_table_settings"] \ = self.table.horizontalHeader().saveState() self.table.setModel(QtGui.QStandardItemModel()) del self.card_model self.card_model = None QtSql.QSqlDatabase.removeDatabase(\ QtSql.QSqlDatabase.database().connectionName()) def display_card_table(self, run_filter=True): self.load_qt_database() self.card_model = CardModel(self.component_manager) self.card_model.setTable("cards") headers = {QUESTION: _("Question"), ANSWER: _("Answer"), TAGS: _("Tags"), GRADE: _("Grade"), NEXT_REP: _("Next rep"), LAST_REP: _("Last rep"), EASINESS: _("Easiness"), ACQ_REPS: _("Learning\nreps"), RET_REPS: _("Review\nreps"), LAPSES: _("Lapses"), CREATION_TIME: _("Created"), MODIFICATION_TIME: _("Modified")} for key, value in headers.iteritems(): self.card_model.setHeaderData(key, QtCore.Qt.Horizontal, QtCore.QVariant(value)) self.table.setModel(self.card_model) self.table.horizontalHeader().sectionClicked.connect(\ self.horizontal_header_section_clicked) table_settings = self.config()["browse_cards_dlg_table_settings"] if table_settings: self.table.horizontalHeader().restoreState(table_settings) self.table.horizontalHeader().setMovable(True) self.table.setItemDelegateForColumn(\ QUESTION, QA_Delegate(self.component_manager, QUESTION, self)) self.table.setItemDelegateForColumn(\ ANSWER, QA_Delegate(self.component_manager, ANSWER, self)) self.table.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers) # Since this function can get called multiple times, we need to make # sure there is only a single connection for the double-click event. try: self.table.doubleClicked.disconnect(self.menu_edit) except TypeError: pass self.table.doubleClicked.connect(self.menu_edit) self.table.verticalHeader().hide() query = QtSql.QSqlQuery("select count() from tags") query.first() self.tag_count = query.value(0).toInt()[0] if run_filter: self.update_filter() # Needed after tag rename. if self.saved_index: # All of the statements below are needed. # Qt does not (yet) seem to allow to restore the previous column # correctly. self.saved_index = self.card_model.index(self.saved_index.row(), self.saved_index.column()) self.table.scrollTo(self.saved_index) self.table.scrollTo(self.saved_index, QtGui.QAbstractItemView.PositionAtTop) # Restore selection. old_selection_mode = self.table.selectionMode() self.table.setSelectionMode(QtGui.QAbstractItemView.MultiSelection) # Note that there seem to be serious Qt preformance problems with # selectRow, so we only do this for a small number of rows. if len(self.saved_selection) < 10: for index in self.saved_selection: self.table.selectRow(index.row()) self.table.setSelectionMode(old_selection_mode) def horizontal_header_section_clicked(self, index): if not self.config()["browse_cards_dlg_sorting_warning_shown"]: self.main_widget().show_information(\ _("You chose to sort this table. Operations in the card browser could now be slower. Next time you start the card browser, the table will be unsorted again.")) self.config()["browse_cards_dlg_sorting_warning_shown"] = True def activate(self): self.exec_() def search_text_changed(self): # Don't immediately start updating the filter, but wait until the last # keypress was 300 ms ago. self.timer.start(300) def update_filter(self): # Card types and fact views. criterion = DefaultCriterion(self.component_manager) self.card_type_tree_wdgt.checked_to_criterion(criterion) filter = "" for card_type_id, fact_view_id in \ criterion.deactivated_card_type_fact_view_ids: filter += """not (cards.fact_view_id='%s' and cards.card_type_id='%s') and """ \ % (fact_view_id, card_type_id) filter = filter.rsplit("and ", 1)[0] # Tags. self.tag_tree_wdgt.checked_to_active_tags_in_criterion(criterion) if len(criterion._tag_ids_active) == 0: filter = "_id='not_there'" elif len(criterion._tag_ids_active) != self.tag_count: if filter: filter += "and " # Determine all _card_ids. query = QtSql.QSqlQuery("select _id from cards") all__card_ids = set() while query.next(): all__card_ids.add(str(query.value(0).toInt()[0])) # Determine _card_ids of card with an active tag. query = "select _card_id from tags_for_card where _tag_id in (" for _tag_id in criterion._tag_ids_active: query += "'%s', " % (_tag_id, ) query = query[:-2] + ")" query = QtSql.QSqlQuery(query) active__card_ids = set() while query.next(): active__card_ids.add(str(query.value(0).toInt()[0])) # Construct most optimal query. if len(active__card_ids) > len(all__card_ids)/2: filter += "_id not in (" + \ ",".join(all__card_ids - active__card_ids) + ")" else: filter += "_id in (" + ",".join(active__card_ids) + ")" # Search string. search_string = unicode(self.search_box.text()).replace("'", "''") self.card_model.search_string = search_string if search_string: if filter: filter += "and " filter += "(question like '%%%s%%' or answer like '%%%s%%')" \ % (search_string, search_string) self.card_model.setFilter(filter) self.card_model.select() self.update_card_counters() def update_card_counters(self): filter = self.card_model.filter() # Selected count. query_string = "select count() from cards" if filter: query_string += " where " + filter query = QtSql.QSqlQuery(query_string) query.first() selected = query.value(0).toInt()[0] # Active selected count. if not filter: query_string += " where active=1" else: query_string += " and active=1" query = QtSql.QSqlQuery(query_string) query.first() active = query.value(0).toInt()[0] self.counter_label.setText(\ _("%d cards shown, of which %d active.") % (selected, active)) def _store_state(self): self.config()["browse_cards_dlg_state"] = self.saveGeometry() self.config()["browse_cards_dlg_splitter_1_state"] = \ self.splitter_1.saveState() self.config()["browse_cards_dlg_splitter_2_state"] = \ self.splitter_2.saveState() def closeEvent(self, event): # Generated when clicking the window's close button. self._store_state() self.unload_qt_database() # This allows the state of the tag tree to be saved. self.tag_tree_wdgt.close() def reject(self): # Generated when pressing escape. self.unload_qt_database() return QtGui.QDialog.reject(self) def accept(self): # 'accept' does not generate a close event. self._store_state() self.unload_qt_database() return QtGui.QDialog.accept(self) Mnemosyne-2.2.1/mnemosyne/pyqt_ui/configuration_dlg.py0000644000175000017500000000466412021577553024414 0ustar pbienstpbienst00000000000000# # configuration_dlg.py # from PyQt4 import QtCore, QtGui from mnemosyne.libmnemosyne.translator import _ from mnemosyne.pyqt_ui.ui_configuration_dlg import Ui_ConfigurationDlg from mnemosyne.libmnemosyne.ui_components.dialogs import ConfigurationDialog class ConfigurationDlg(QtGui.QDialog, Ui_ConfigurationDlg, ConfigurationDialog): """A tab widget containing several configuration widgets. The number and names of the tab pages are determined at run time. """ def __init__(self, component_manager): ConfigurationDialog.__init__(self, component_manager) QtGui.QDialog.__init__(self, self.main_widget()) self.setupUi(self) self.setWindowFlags(self.windowFlags() \ | QtCore.Qt.WindowMinMaxButtonsHint) self.setWindowFlags(self.windowFlags() \ & ~ QtCore.Qt.WindowContextHelpButtonHint) for widget in self.component_manager.all("configuration_widget"): widget = widget(self.component_manager, parent=self) self.tab_widget.addTab(widget, _(widget.name)) self.tab_widget.tabBar().setVisible(self.tab_widget.count() > 1) widget_index = self.config()["previous_configuration_wdgt"] if widget_index >= self.tab_widget.count(): widget_index = 0 self.config()["previous_configuration_wdgt"] = 0 self.tab_widget.setCurrentIndex(widget_index) self.ok_button.setFocus() state = self.config()["configuration_dlg_state"] if state: self.restoreGeometry(state) def activate(self): self.exec_() def _store_state(self): self.config()["configuration_dlg_state"] = self.saveGeometry() def closeEvent(self, event): # Generated when clicking the window's close button. self._store_state() def accept(self): self.config()["previous_configuration_wdgt"] = \ self.tab_widget.currentIndex() for index in range(self.tab_widget.count()): self.tab_widget.widget(index).apply() self._store_state() return QtGui.QDialog.accept(self) def reject(self): for index in range(self.tab_widget.count()): if hasattr(self.tab_widget.widget(index), "reject"): self.tab_widget.widget(index).reject() return QtGui.QDialog.reject(self) def reset_to_defaults(self): self.tab_widget.currentWidget().reset_to_defaults() Mnemosyne-2.2.1/mnemosyne/pyqt_ui/ui_clone_card_type_dlg.py0000644000175000000000000000651312132771332024663 0ustar pbienstroot00000000000000# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'clone_card_type_dlg.ui' # # Created: Mon Apr 15 14:30:18 2013 # by: PyQt4 UI code generator 4.9.3 # # WARNING! All changes made in this file will be lost! from mnemosyne.libmnemosyne.translator import _ from PyQt4 import QtCore, QtGui try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: _fromUtf8 = lambda s: s class Ui_CloneCardTypeDlg(object): def setupUi(self, CloneCardTypeDlg): CloneCardTypeDlg.setObjectName(_fromUtf8("CloneCardTypeDlg")) CloneCardTypeDlg.resize(400, 100) CloneCardTypeDlg.setMinimumSize(QtCore.QSize(400, 100)) self.verticalLayout_2 = QtGui.QVBoxLayout(CloneCardTypeDlg) self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2")) self.verticalLayout = QtGui.QVBoxLayout() self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) self.gridLayout = QtGui.QGridLayout() self.gridLayout.setMargin(1) self.gridLayout.setObjectName(_fromUtf8("gridLayout")) self.label = QtGui.QLabel(CloneCardTypeDlg) self.label.setObjectName(_fromUtf8("label")) self.gridLayout.addWidget(self.label, 0, 0, 1, 1) self.parent_type = QtGui.QComboBox(CloneCardTypeDlg) self.parent_type.setObjectName(_fromUtf8("parent_type")) self.gridLayout.addWidget(self.parent_type, 0, 1, 1, 1) self.label_2 = QtGui.QLabel(CloneCardTypeDlg) self.label_2.setObjectName(_fromUtf8("label_2")) self.gridLayout.addWidget(self.label_2, 1, 0, 1, 1) self.name = QtGui.QLineEdit(CloneCardTypeDlg) self.name.setObjectName(_fromUtf8("name")) self.gridLayout.addWidget(self.name, 1, 1, 1, 1) self.verticalLayout.addLayout(self.gridLayout) self.horizontalLayout_3 = QtGui.QHBoxLayout() self.horizontalLayout_3.setObjectName(_fromUtf8("horizontalLayout_3")) self.OK_button = QtGui.QPushButton(CloneCardTypeDlg) self.OK_button.setEnabled(False) self.OK_button.setObjectName(_fromUtf8("OK_button")) self.horizontalLayout_3.addWidget(self.OK_button) spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.horizontalLayout_3.addItem(spacerItem) self.cancel_button = QtGui.QPushButton(CloneCardTypeDlg) self.cancel_button.setObjectName(_fromUtf8("cancel_button")) self.horizontalLayout_3.addWidget(self.cancel_button) self.verticalLayout.addLayout(self.horizontalLayout_3) self.verticalLayout_2.addLayout(self.verticalLayout) self.retranslateUi(CloneCardTypeDlg) QtCore.QObject.connect(self.OK_button, QtCore.SIGNAL(_fromUtf8("clicked()")), CloneCardTypeDlg.accept) QtCore.QObject.connect(self.cancel_button, QtCore.SIGNAL(_fromUtf8("clicked()")), CloneCardTypeDlg.reject) QtCore.QObject.connect(self.name, QtCore.SIGNAL(_fromUtf8("textChanged(QString)")), CloneCardTypeDlg.name_changed) QtCore.QMetaObject.connectSlotsByName(CloneCardTypeDlg) def retranslateUi(self, CloneCardTypeDlg): CloneCardTypeDlg.setWindowTitle(_('Clone card type')) self.label.setText(_('Cloned from:')) self.label_2.setText(_('Clone name:')) self.OK_button.setText(_('&OK')) self.cancel_button.setText(_('&Cancel')) Mnemosyne-2.2.1/mnemosyne/pyqt_ui/ui_edit_card_dlg.py0000644000175000000000000001032412132771331023441 0ustar pbienstroot00000000000000# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'edit_card_dlg.ui' # # Created: Mon Apr 15 14:30:17 2013 # by: PyQt4 UI code generator 4.9.3 # # WARNING! All changes made in this file will be lost! from mnemosyne.libmnemosyne.translator import _ from PyQt4 import QtCore, QtGui try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: _fromUtf8 = lambda s: s class Ui_EditCardDlg(object): def setupUi(self, EditCardDlg): EditCardDlg.setObjectName(_fromUtf8("EditCardDlg")) EditCardDlg.resize(209, 100) self.horizontalLayout_2 = QtGui.QHBoxLayout(EditCardDlg) self.horizontalLayout_2.setObjectName(_fromUtf8("horizontalLayout_2")) self.vbox_layout = QtGui.QVBoxLayout() self.vbox_layout.setObjectName(_fromUtf8("vbox_layout")) self.gridlayout = QtGui.QGridLayout() self.gridlayout.setObjectName(_fromUtf8("gridlayout")) self.label_2 = QtGui.QLabel(EditCardDlg) self.label_2.setObjectName(_fromUtf8("label_2")) self.gridlayout.addWidget(self.label_2, 0, 0, 1, 1) self.card_types_widget = QtGui.QComboBox(EditCardDlg) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.card_types_widget.sizePolicy().hasHeightForWidth()) self.card_types_widget.setSizePolicy(sizePolicy) self.card_types_widget.setObjectName(_fromUtf8("card_types_widget")) self.gridlayout.addWidget(self.card_types_widget, 0, 1, 1, 1) self.label = QtGui.QLabel(EditCardDlg) self.label.setObjectName(_fromUtf8("label")) self.gridlayout.addWidget(self.label, 1, 0, 1, 1) self.tags = QtGui.QComboBox(EditCardDlg) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.tags.sizePolicy().hasHeightForWidth()) self.tags.setSizePolicy(sizePolicy) self.tags.setEditable(True) self.tags.setObjectName(_fromUtf8("tags")) self.gridlayout.addWidget(self.tags, 1, 1, 1, 1) self.vbox_layout.addLayout(self.gridlayout) self.button_row = QtGui.QHBoxLayout() self.button_row.setObjectName(_fromUtf8("button_row")) self.OK_button = QtGui.QPushButton(EditCardDlg) self.OK_button.setDefault(True) self.OK_button.setObjectName(_fromUtf8("OK_button")) self.button_row.addWidget(self.OK_button) spacerItem = QtGui.QSpacerItem(70, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.button_row.addItem(spacerItem) self.preview_button = QtGui.QPushButton(EditCardDlg) self.preview_button.setAutoDefault(False) self.preview_button.setObjectName(_fromUtf8("preview_button")) self.button_row.addWidget(self.preview_button) spacerItem1 = QtGui.QSpacerItem(70, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.button_row.addItem(spacerItem1) self.exit_button = QtGui.QPushButton(EditCardDlg) self.exit_button.setAutoDefault(False) self.exit_button.setObjectName(_fromUtf8("exit_button")) self.button_row.addWidget(self.exit_button) self.vbox_layout.addLayout(self.button_row) self.horizontalLayout_2.addLayout(self.vbox_layout) self.retranslateUi(EditCardDlg) QtCore.QObject.connect(self.preview_button, QtCore.SIGNAL(_fromUtf8("clicked()")), EditCardDlg.preview) QtCore.QObject.connect(self.OK_button, QtCore.SIGNAL(_fromUtf8("clicked()")), EditCardDlg.accept) QtCore.QObject.connect(self.exit_button, QtCore.SIGNAL(_fromUtf8("clicked()")), EditCardDlg.reject) QtCore.QMetaObject.connectSlotsByName(EditCardDlg) def retranslateUi(self, EditCardDlg): EditCardDlg.setWindowTitle(_('Edit card')) self.label_2.setText(_('Card type:')) self.label.setText(_('Tags:')) self.OK_button.setText(_('&OK')) self.preview_button.setText(_('&Preview')) self.exit_button.setText(_('&Exit')) import mnemosyne_rc Mnemosyne-2.2.1/mnemosyne/pyqt_ui/ui_getting_started_dlg.py0000644000175000000000000001731112132771336024722 0ustar pbienstroot00000000000000# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'getting_started_dlg.ui' # # Created: Mon Apr 15 14:30:22 2013 # by: PyQt4 UI code generator 4.9.3 # # WARNING! All changes made in this file will be lost! from mnemosyne.libmnemosyne.translator import _ from PyQt4 import QtCore, QtGui try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: _fromUtf8 = lambda s: s class Ui_GettingStartedDlg(object): def setupUi(self, GettingStartedDlg): GettingStartedDlg.setObjectName(_fromUtf8("GettingStartedDlg")) GettingStartedDlg.resize(693, 450) GettingStartedDlg.setMinimumSize(QtCore.QSize(600, 450)) GettingStartedDlg.setWizardStyle(QtGui.QWizard.ClassicStyle) GettingStartedDlg.setOptions(QtGui.QWizard.IgnoreSubTitles) GettingStartedDlg.setTitleFormat(QtCore.Qt.PlainText) self.intro = QtGui.QWizardPage() self.intro.setObjectName(_fromUtf8("intro")) self.verticalLayout_3 = QtGui.QVBoxLayout(self.intro) self.verticalLayout_3.setObjectName(_fromUtf8("verticalLayout_3")) self.intro_lbl = QtGui.QLabel(self.intro) self.intro_lbl.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop) self.intro_lbl.setWordWrap(True) self.intro_lbl.setMargin(12) self.intro_lbl.setObjectName(_fromUtf8("intro_lbl")) self.verticalLayout_3.addWidget(self.intro_lbl) GettingStartedDlg.addPage(self.intro) self.grades02 = QtGui.QWizardPage() self.grades02.setObjectName(_fromUtf8("grades02")) self.verticalLayout_4 = QtGui.QVBoxLayout(self.grades02) self.verticalLayout_4.setObjectName(_fromUtf8("verticalLayout_4")) self.grades02_lbl = QtGui.QLabel(self.grades02) self.grades02_lbl.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop) self.grades02_lbl.setWordWrap(True) self.grades02_lbl.setMargin(12) self.grades02_lbl.setObjectName(_fromUtf8("grades02_lbl")) self.verticalLayout_4.addWidget(self.grades02_lbl) GettingStartedDlg.addPage(self.grades02) self.grades35 = QtGui.QWizardPage() self.grades35.setObjectName(_fromUtf8("grades35")) self.verticalLayout_5 = QtGui.QVBoxLayout(self.grades35) self.verticalLayout_5.setObjectName(_fromUtf8("verticalLayout_5")) self.grades35_lbl = QtGui.QLabel(self.grades35) self.grades35_lbl.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop) self.grades35_lbl.setWordWrap(True) self.grades35_lbl.setMargin(12) self.grades35_lbl.setObjectName(_fromUtf8("grades35_lbl")) self.verticalLayout_5.addWidget(self.grades35_lbl) GettingStartedDlg.addPage(self.grades35) self.statistics = QtGui.QWizardPage() self.statistics.setObjectName(_fromUtf8("statistics")) self.verticalLayout = QtGui.QVBoxLayout(self.statistics) self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) self.statistics_lbl = QtGui.QLabel(self.statistics) self.statistics_lbl.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop) self.statistics_lbl.setWordWrap(True) self.statistics_lbl.setMargin(12) self.statistics_lbl.setObjectName(_fromUtf8("statistics_lbl")) self.verticalLayout.addWidget(self.statistics_lbl) self.upload_box = QtGui.QCheckBox(self.statistics) self.upload_box.setEnabled(True) self.upload_box.setChecked(True) self.upload_box.setObjectName(_fromUtf8("upload_box")) self.verticalLayout.addWidget(self.upload_box) GettingStartedDlg.addPage(self.statistics) self.ready = QtGui.QWizardPage() self.ready.setObjectName(_fromUtf8("ready")) self.verticalLayout_2 = QtGui.QVBoxLayout(self.ready) self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2")) self.ready_lbl = QtGui.QLabel(self.ready) self.ready_lbl.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop) self.ready_lbl.setWordWrap(True) self.ready_lbl.setMargin(12) self.ready_lbl.setObjectName(_fromUtf8("ready_lbl")) self.verticalLayout_2.addWidget(self.ready_lbl) GettingStartedDlg.addPage(self.ready) self.retranslateUi(GettingStartedDlg) QtCore.QMetaObject.connectSlotsByName(GettingStartedDlg) def retranslateUi(self, GettingStartedDlg): GettingStartedDlg.setWindowTitle(_('Wizard')) self.intro.setTitle(_('Introduction')) self.intro_lbl.setText(_('Welcome to Mnemosyne, a flash card program named both after the Greek goddess of Memory and a type of butterfly.\n\nMnemosyne makes it more efficient to study, focusing on the cards you\'re most likely to forget and not wasting your time on things you know well.\n\nFor that, Mnemosyne decides when to show you the cards, and you\'ll need to rate how well you remember them.\n\nLet\'s look at the meaning of these ratings now.')) self.grades02.setTitle(_('Memorising new cards')) self.grades02_lbl.setText(_('Grades range from 0 to 5.\n\nWhen you are learning new cards, use grades 0 and 1 to signal that you have not yet memorised them. Grade 1 cards are becoming more familiar than grade 0 cards, and will be repeated less often.\n\nThese cards will be repeatedly shown until you give them a grade 2 or higher. This means that you\'ve memorised the card and that you\'ll be able to remember it for one or two days. The \'Not memorised\' counter will decrease by one.\n\nThis card will be scheduled at some future date, when you\'re likely still be able to remember it with some effort, without having forgotten it completely. This is most efficient for the learning process.\n')) self.grades35.setTitle(_('Reviewing previously memorised cards')) self.grades35_lbl.setText(_('If you study these cards again tomorrow, the \'Scheduled\' counter will tell you how many previously memorised cards you need to review. These are grade 2 to 5 cards.\n\nIf a card reappears too soon, and you\'re able to remember it without any effort, rate the card a 5. The interval to see this card again will be a lot longer.\n\nIf the interval is just right, so that you remember it, albeit with some effort, use grade 4.\n\nIf, however, it takes you significant effort to remember the answer, and you think the interval was too long, then rate the card 3 or even 2.\n\nIf you fail to remember it altogether, rate it either 0 or 1, and after you have finished reviewing all the scheduled cards, it will appear repeatedly until you think you\'ll be able to remember it again for a few days.')) self.statistics.setTitle(_('Statistics')) self.statistics_lbl.setText(_('If you\'re into statistics, Mnemosyne keeps detailed logs of your revisions.\n\nNot only that, but if you want, Mnemosyne can upload transparently a completely anonymous version of these logs to a central site for analysis, so that you can help making the scheduling algorithm better. In this way, you also contribute to scientific research on long-term memory.\n\nUncheck the following box if you do not want to do this.')) self.upload_box.setText(_('Upload anonymous logs (can be changed later)')) self.ready.setTitle(_('Ready to start')) self.ready_lbl.setText(_('Now you\'re ready to start!\n\nAdd new cards by clicking on the icon with the \'plus\' sign in the top left.\n\nRemember, there is no need to worry about saving your work, this will be done automatically.\n\nFor best results, it\'s suggested to do your revisions every day, although Mnemosyne will try to cope if you\'ve missed a few days.\n\nFor more documentation, see http://www.mnemosyne-proj.org.\n\nHappy learning!')) Mnemosyne-2.2.1/mnemosyne/pyqt_ui/ui_add_cards_dlg.py0000644000175000000000000001454412132771331023437 0ustar pbienstroot00000000000000# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'add_cards_dlg.ui' # # Created: Mon Apr 15 14:30:17 2013 # by: PyQt4 UI code generator 4.9.3 # # WARNING! All changes made in this file will be lost! from mnemosyne.libmnemosyne.translator import _ from PyQt4 import QtCore, QtGui try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: _fromUtf8 = lambda s: s class Ui_AddCardsDlg(object): def setupUi(self, AddCardsDlg): AddCardsDlg.setObjectName(_fromUtf8("AddCardsDlg")) AddCardsDlg.resize(317, 170) self.horizontalLayout_2 = QtGui.QHBoxLayout(AddCardsDlg) self.horizontalLayout_2.setObjectName(_fromUtf8("horizontalLayout_2")) self.vbox_layout = QtGui.QVBoxLayout() self.vbox_layout.setObjectName(_fromUtf8("vbox_layout")) self.gridlayout = QtGui.QGridLayout() self.gridlayout.setObjectName(_fromUtf8("gridlayout")) self.label_2 = QtGui.QLabel(AddCardsDlg) self.label_2.setObjectName(_fromUtf8("label_2")) self.gridlayout.addWidget(self.label_2, 0, 0, 1, 1) self.card_types_widget = QtGui.QComboBox(AddCardsDlg) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.card_types_widget.sizePolicy().hasHeightForWidth()) self.card_types_widget.setSizePolicy(sizePolicy) self.card_types_widget.setObjectName(_fromUtf8("card_types_widget")) self.gridlayout.addWidget(self.card_types_widget, 0, 1, 1, 1) self.label = QtGui.QLabel(AddCardsDlg) self.label.setObjectName(_fromUtf8("label")) self.gridlayout.addWidget(self.label, 1, 0, 1, 1) self.tags = QtGui.QComboBox(AddCardsDlg) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.tags.sizePolicy().hasHeightForWidth()) self.tags.setSizePolicy(sizePolicy) self.tags.setEditable(True) self.tags.setObjectName(_fromUtf8("tags")) self.gridlayout.addWidget(self.tags, 1, 1, 1, 1) self.vbox_layout.addLayout(self.gridlayout) self.grade_buttons = QtGui.QGroupBox(AddCardsDlg) self.grade_buttons.setObjectName(_fromUtf8("grade_buttons")) self.vboxlayout = QtGui.QVBoxLayout(self.grade_buttons) self.vboxlayout.setObjectName(_fromUtf8("vboxlayout")) self.hboxlayout = QtGui.QHBoxLayout() self.hboxlayout.setObjectName(_fromUtf8("hboxlayout")) self.yet_to_learn_button = QtGui.QPushButton(self.grade_buttons) self.yet_to_learn_button.setAutoDefault(True) self.yet_to_learn_button.setDefault(True) self.yet_to_learn_button.setObjectName(_fromUtf8("yet_to_learn_button")) self.hboxlayout.addWidget(self.yet_to_learn_button) self.line = QtGui.QFrame(self.grade_buttons) self.line.setFrameShape(QtGui.QFrame.VLine) self.line.setFrameShadow(QtGui.QFrame.Sunken) self.line.setObjectName(_fromUtf8("line")) self.hboxlayout.addWidget(self.line) self.grade_2_button = QtGui.QPushButton(self.grade_buttons) self.grade_2_button.setAutoDefault(False) self.grade_2_button.setObjectName(_fromUtf8("grade_2_button")) self.hboxlayout.addWidget(self.grade_2_button) self.grade_3_button = QtGui.QPushButton(self.grade_buttons) self.grade_3_button.setAutoDefault(False) self.grade_3_button.setObjectName(_fromUtf8("grade_3_button")) self.hboxlayout.addWidget(self.grade_3_button) self.grade_4_button = QtGui.QPushButton(self.grade_buttons) self.grade_4_button.setAutoDefault(False) self.grade_4_button.setObjectName(_fromUtf8("grade_4_button")) self.hboxlayout.addWidget(self.grade_4_button) self.grade_5_button = QtGui.QPushButton(self.grade_buttons) self.grade_5_button.setAutoDefault(False) self.grade_5_button.setObjectName(_fromUtf8("grade_5_button")) self.hboxlayout.addWidget(self.grade_5_button) self.vboxlayout.addLayout(self.hboxlayout) self.vbox_layout.addWidget(self.grade_buttons) self.hboxlayout1 = QtGui.QHBoxLayout() self.hboxlayout1.setObjectName(_fromUtf8("hboxlayout1")) self.preview_button = QtGui.QPushButton(AddCardsDlg) self.preview_button.setAutoDefault(False) self.preview_button.setObjectName(_fromUtf8("preview_button")) self.hboxlayout1.addWidget(self.preview_button) spacerItem = QtGui.QSpacerItem(101, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.hboxlayout1.addItem(spacerItem) self.exit_button = QtGui.QPushButton(AddCardsDlg) self.exit_button.setAutoDefault(False) self.exit_button.setObjectName(_fromUtf8("exit_button")) self.hboxlayout1.addWidget(self.exit_button) self.vbox_layout.addLayout(self.hboxlayout1) self.horizontalLayout_2.addLayout(self.vbox_layout) self.retranslateUi(AddCardsDlg) QtCore.QObject.connect(self.exit_button, QtCore.SIGNAL(_fromUtf8("clicked()")), AddCardsDlg.reject) QtCore.QObject.connect(self.preview_button, QtCore.SIGNAL(_fromUtf8("clicked()")), AddCardsDlg.preview) QtCore.QMetaObject.connectSlotsByName(AddCardsDlg) def retranslateUi(self, AddCardsDlg): AddCardsDlg.setWindowTitle(_('Add cards')) self.label_2.setText(_('Card type:')) self.label.setText(_('Tags:')) self.grade_buttons.setTitle(_('Select initial grade:')) self.yet_to_learn_button.setToolTip(_('You have yet to learn this.')) self.yet_to_learn_button.setText(_('&Yet to learn')) self.grade_2_button.setToolTip(_('You know this, but just barely.')) self.grade_2_button.setText(_('&2')) self.grade_3_button.setToolTip(_('You know this, but not very well.')) self.grade_3_button.setText(_('&3')) self.grade_4_button.setToolTip(_('You know this.')) self.grade_4_button.setText(_('&4')) self.grade_5_button.setToolTip(_('You know this very well.')) self.grade_5_button.setText(_('&5')) self.preview_button.setText(_('&Preview')) self.exit_button.setText(_('&Exit')) import mnemosyne_rc Mnemosyne-2.2.1/mnemosyne/pyqt_ui/manage_card_types_dlg.py0000644000175000017500000000712512113341755025200 0ustar pbienstpbienst00000000000000# # manage_card_types_dlg.py # from PyQt4 import QtCore, QtGui from mnemosyne.libmnemosyne.translator import _ from mnemosyne.libmnemosyne.card_type import CardType from mnemosyne.pyqt_ui.clone_card_type_dlg import CloneCardTypeDlg from mnemosyne.pyqt_ui.ui_manage_card_types_dlg import Ui_ManageCardTypesDlg from mnemosyne.libmnemosyne.ui_components.dialogs import ManageCardTypesDialog class ManageCardTypesDlg(QtGui.QDialog, Ui_ManageCardTypesDlg, ManageCardTypesDialog): def __init__(self, component_manager): ManageCardTypesDialog.__init__(self, component_manager) QtGui.QDialog.__init__(self, self.main_widget()) self.setupUi(self) self.setWindowFlags(self.windowFlags() \ | QtCore.Qt.WindowMinMaxButtonsHint) self.setWindowFlags(self.windowFlags() \ & ~ QtCore.Qt.WindowContextHelpButtonHint) self.update() def activate(self): self.exec_() def update(self): self.cloned_card_types.clear() self.card_type_with_item = {} for card_type in self.card_types(): if self.database().is_user_card_type(card_type): name = "%s (%s)" % (_(card_type.name), _(card_type.__class__.__bases__[0].name)) item = QtGui.QListWidgetItem(name) self.cloned_card_types.addItem(item) self.card_type_with_item[item] = card_type if self.cloned_card_types.count() == 0: self.rename_button.setEnabled(False) self.delete_button.setEnabled(False) else: self.rename_button.setEnabled(True) self.delete_button.setEnabled(True) self.cloned_card_types.item(0).setSelected(True) def clone_card_type(self): if not self.config()["clone_help_shown"]: self.main_widget().show_information(\ _("Here, you can make clones of existing card types. This allows you to format cards in this type independently from cards in the original type. E.g. you can make a clone of 'Vocabulary', call it 'Thai' and set a Thai font specifically for this card type without disturbing your other cards.")) self.config()["clone_help_shown"] = True dlg = CloneCardTypeDlg(self, self.component_manager) dlg.exec_() self.update() def delete_card_type(self): if len(self.cloned_card_types.selectedItems()) == 0: return answer = self.main_widget().show_question\ (_("Delete this card type?"), _("&OK"), _("&Cancel"), "") if answer == 1: # Cancel. return card_type = self.card_type_with_item\ [self.cloned_card_types.selectedItems()[0]] self.controller().delete_card_type(card_type) self.update() def rename_card_type(self): if len(self.cloned_card_types.selectedItems()) == 0: return from mnemosyne.pyqt_ui.ui_rename_card_type_dlg \ import Ui_RenameCardTypeDlg class RenameDlg(QtGui.QDialog, Ui_RenameCardTypeDlg): def __init__(self, old_card_type_name): QtGui.QDialog.__init__(self) self.setupUi(self) self.card_type_name.setText(old_card_type_name) card_type = self.card_type_with_item\ [self.cloned_card_types.selectedItems()[0]] dlg = RenameDlg(card_type.name) if dlg.exec_() == QtGui.QDialog.Accepted: new_name = unicode(dlg.card_type_name.text()) self.controller().rename_card_type(card_type, new_name) self.update() Mnemosyne-2.2.1/mnemosyne/pyqt_ui/remove_tags_dlg.py0000644000175000017500000000237611733043044024046 0ustar pbienstpbienst00000000000000# # remove_tags_dlg.py # from PyQt4 import QtGui, QtCore from mnemosyne.pyqt_ui.ui_remove_tags_dlg import Ui_RemoveTagsDlg class RemoveTagsDlg(QtGui.QDialog, Ui_RemoveTagsDlg): def __init__(self, parent, tags, return_values): QtGui.QDialog.__init__(self, parent) self.setupUi(self) self.setWindowFlags(self.windowFlags() \ | QtCore.Qt.WindowMinMaxButtonsHint) self.setWindowFlags(self.windowFlags() \ & ~ QtCore.Qt.WindowContextHelpButtonHint) self.return_values = return_values for tag in tags: if tag.name != "__UNTAGGED__": list_item = QtGui.QListWidgetItem(tag.name) list_item.setFlags(list_item.flags() | QtCore.Qt.ItemIsUserCheckable) list_item.setCheckState(QtCore.Qt.Unchecked) self.tag_list.addItem(list_item) def accept(self): self.return_values["tag_names"] = [] for index in range(self.tag_list.count()): list_item = self.tag_list.item(index) if list_item.checkState() == QtCore.Qt.Checked: self.return_values["tag_names"].append(\ unicode(list_item.text())) return QtGui.QDialog.accept(self) Mnemosyne-2.2.1/mnemosyne/pyqt_ui/ui_about_dlg.py0000644000175000000000000000726312132771332022646 0ustar pbienstroot00000000000000# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'about_dlg.ui' # # Created: Mon Apr 15 14:30:18 2013 # by: PyQt4 UI code generator 4.9.3 # # WARNING! All changes made in this file will be lost! from mnemosyne.libmnemosyne.translator import _ from PyQt4 import QtCore, QtGui try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: _fromUtf8 = lambda s: s class Ui_AboutDlg(object): def setupUi(self, AboutDlg): AboutDlg.setObjectName(_fromUtf8("AboutDlg")) AboutDlg.resize(435, 212) self.verticalLayout = QtGui.QVBoxLayout(AboutDlg) self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) self.vboxlayout = QtGui.QVBoxLayout() self.vboxlayout.setContentsMargins(5, -1, 5, -1) self.vboxlayout.setObjectName(_fromUtf8("vboxlayout")) self._2 = QtGui.QHBoxLayout() self._2.setObjectName(_fromUtf8("_2")) self.watermark = QtGui.QLabel(AboutDlg) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.watermark.sizePolicy().hasHeightForWidth()) self.watermark.setSizePolicy(sizePolicy) self.watermark.setPixmap(QtGui.QPixmap(_fromUtf8("image0"))) self.watermark.setScaledContents(True) self.watermark.setWordWrap(False) self.watermark.setObjectName(_fromUtf8("watermark")) self._2.addWidget(self.watermark) self._3 = QtGui.QVBoxLayout() self._3.setObjectName(_fromUtf8("_3")) self.about_label = QtGui.QLabel(AboutDlg) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.MinimumExpanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.about_label.sizePolicy().hasHeightForWidth()) self.about_label.setSizePolicy(sizePolicy) self.about_label.setText(_fromUtf8("")) self.about_label.setTextFormat(QtCore.Qt.RichText) self.about_label.setAlignment(QtCore.Qt.AlignVCenter) self.about_label.setWordWrap(True) self.about_label.setOpenExternalLinks(True) self.about_label.setObjectName(_fromUtf8("about_label")) self._3.addWidget(self.about_label) spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) self._3.addItem(spacerItem) self._2.addLayout(self._3) self.vboxlayout.addLayout(self._2) self.line1 = QtGui.QFrame(AboutDlg) self.line1.setFrameShape(QtGui.QFrame.HLine) self.line1.setFrameShadow(QtGui.QFrame.Sunken) self.line1.setObjectName(_fromUtf8("line1")) self.vboxlayout.addWidget(self.line1) self._4 = QtGui.QHBoxLayout() self._4.setObjectName(_fromUtf8("_4")) spacerItem1 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self._4.addItem(spacerItem1) self.OK_button = QtGui.QPushButton(AboutDlg) self.OK_button.setDefault(True) self.OK_button.setObjectName(_fromUtf8("OK_button")) self._4.addWidget(self.OK_button) self.vboxlayout.addLayout(self._4) self.verticalLayout.addLayout(self.vboxlayout) self.retranslateUi(AboutDlg) QtCore.QObject.connect(self.OK_button, QtCore.SIGNAL(_fromUtf8("clicked()")), AboutDlg.accept) QtCore.QMetaObject.connectSlotsByName(AboutDlg) def retranslateUi(self, AboutDlg): AboutDlg.setWindowTitle(_('About Mnemosyne')) self.OK_button.setText(_('&OK')) self.OK_button.setShortcut(_('Alt+C')) Mnemosyne-2.2.1/mnemosyne/pyqt_ui/qtextedit2.py0000644000175000017500000000675012107377162023011 0ustar pbienstpbienst00000000000000# # qtextedit2.py # from PyQt4 import QtCore, QtGui from mnemosyne.libmnemosyne.translator import _ class QTextEdit2(QtGui.QTextEdit): """QTextEdit with extra options in popup menu.""" def __init__(self, parent, pronunciation_hiding=None): """'pronunciation_hiding' is set to None when there is no pronunciation key to hide, and to True or False when there is one to hide. """ QtGui.QTextEdit.__init__(self, parent) self.pronunciation_hiding = pronunciation_hiding self.setAcceptRichText(False) def contextMenuEvent(self, e): popup = self.createStandardContextMenu() popup.addSeparator() popup.addAction(_("Insert &image"), self.insert_img, QtGui.QKeySequence(_("Ctrl+I"))) popup.addAction(_("Insert &sound"), self.insert_sound, QtGui.QKeySequence(_("Ctrl+S"))) popup.addAction(_("Insert vi&deo"), self.insert_video, QtGui.QKeySequence(_("Ctrl+D"))) popup.addAction(_("Insert &Flash"), self.insert_flash, QtGui.QKeySequence(_("Ctrl+F"))) if self.pronunciation_hiding in [True, False]: popup.addSeparator() self.hide_action = QtGui.QAction(\ _("&Hide pronunciation field for this card type"), popup) self.hide_action.setCheckable(True) self.hide_action.setChecked(self.pronunciation_hiding) self.hide_action.toggled.connect(\ self.parent().pronunciation_hiding_toggled) popup.addAction(self.hide_action) popup.exec_(e.globalPos()) def keyPressEvent(self, event): if event.key() == QtCore.Qt.Key_I and event.modifiers() == \ QtCore.Qt.ControlModifier: self.insert_img() elif event.key() == QtCore.Qt.Key_S and event.modifiers() == \ QtCore.Qt.ControlModifier: self.insert_sound() elif event.key() == QtCore.Qt.Key_D and event.modifiers() == \ QtCore.Qt.ControlModifier: self.insert_video() elif event.key() == QtCore.Qt.Key_F and event.modifiers() == \ QtCore.Qt.ControlModifier: self.insert_flash() else: QtGui.QTextEdit.keyPressEvent(self, event) def insert_img(self): filter = "(*.png *.gif *.jpg *.bmp *.jpeg *.svg *.tiff" + \ " *.PNG *.GIF *.jpg *.BMP *.JPEG *.SVG *.TIFF)" filename = self.parent().controller().show_insert_img_dialog(filter) if filename: self.insertPlainText("") def insert_sound(self): filter = "(*.wav *.mp3 *.ogg *.WAV *.MP3 *.OGG)" filename = self.parent().controller().show_insert_sound_dialog(filter) if filename: self.insertPlainText("