def setup_sound(self): if sys.platform == 'win32' and \ cfg.get_string("sound/type") == "sequencer-device": # just in case c:\home\.solfegerc is wrong cfg.set_string("sound/type", "winsynth") if self.m_options.no_sound \ or cfg.get_string("sound/type") == "fake-synth": soundcard.initialise_using_fake_synth( self.m_options.verbose_sound_init) elif cfg.get_string("sound/type") == "alsa-sequencer": if alsaseq: try: clientid, portid = self.get_list("sound/alsa-client-port") except ValueError: clientid, portid = (None, None) try: soundcard.initialise_alsa_sequencer( (clientid, portid), self.m_options.verbose_sound_init) except alsaseq.SequencerError, e: logging.debug( "initialise_alsa_sequencer failed. Using fake synth.") self.display_sound_init_error_message(e) soundcard.initialise_using_fake_synth(True) return else: if solfege.splash_win: solfege.splash_win.hide() gu.dialog_ok( _("The pyalsa Python module is missing"), solfege.win, _("Solfege was configured to use the Python modules from www.alsa-project.org, but the modules were not found. You must reconfigure sound in the preferences window (Ctrl-F12) or restart Solfege in a way that it finds the modules." )) soundcard.initialise_using_fake_synth(True) if solfege.splash_win: solfege.splash_win.show()
def load_frontpage(self): """ Load the front page file set in the config database into solfege.app.m_frontpage_data """ filename = self.get_string("app/frontpage") if filename == self.debug_front_page and not solfege.app.m_options.debug: self.set_string("app/frontpage", self.default_front_page) filename = self.default_front_page if not os.path.isfile(filename): filename = self.default_front_page try: solfege.app.m_frontpage_data = frontpage.load_tree(filename) except Exception: if solfege.splash_win: solfege.splash_win.hide() solfege.app.m_frontpage_data = frontpage.load_tree( self.default_front_page) self.set_string('app/frontpage', self.default_front_page) gu.dialog_ok( _("Loading front page '%s' failed. Using default page." % filename), parent=self, secondary_text="\n".join( traceback.format_exception(*sys.exc_info()))) if solfege.splash_win: solfege.splash_win.show() self.display_frontpage()
def start_gui(datadir): if not options.profile: if cfg.get_bool("app/noprofilemanager"): options.profile = cfg.get_string("app/last_profile") elif do_profiles(): if solfege.splash_win: solfege.splash_win.hide() p = ProfileManager(cfg.get_string("app/last_profile")) ret = p.run() if ret == Gtk.ResponseType.ACCEPT: options.profile = p.get_profile() cfg.set_string("app/last_profile", "" if not options.profile else options.profile) elif ret in (Gtk.ResponseType.CLOSE, Gtk.ResponseType.DELETE_EVENT): Gtk.main_quit() return p.destroy() if solfege.splash_win: solfege.splash_win.show() cfg.set_bool('config/no_random', bool(options.no_random)) lessonfile.infocache = lessonfile.InfoCache() def f(s): if solfege.splash_win: solfege.splash_win.show_progress(s) if solfege.splash_win: solfege.splash_win.show_progress(_("Opening statistics database")) try: solfege.db = statistics.DB(f, profile=options.profile) except sqlite3.OperationalError, e: solfege.splash_win.hide() gu.dialog_ok(_(u"Failed to open the statistics database:\n«%s»") % str(e).decode(sys.getfilesystemencoding(), 'replace'), secondary_text=_("Click OK to exit the program. Then try to quit all other instances of the program, or reboot the computer. You can only run one instance of GNU Solfege at once.")) sys.exit()
def _add_idbyname_lesson(self, p, filename): """ p is a lessonfile.LessonfileCommon parser that has parsed the file. """ not_ok = len([ q.music for q in p.m_questions if not isinstance(q.music, self.ok_music_types) ]) ok = len([ q.music for q in p.m_questions if isinstance(q.music, self.ok_music_types) ]) if not_ok > 0: if ok > 0: do_add = gu.dialog_yesno( _("Not all music types are supported. This file contain %(ok)i supported questions and %(not_ok)i that are not supported. The unsupported questions will be ignored. Add any way?" % locals()), self) else: gu.dialog_ok( _("Could not add the lesson file. It has no questions with a music object with supported music type." ), self) do_add = False else: do_add = True if do_add: self.m_changed = True self._add_common(filename)
def on_select_exercise(self, item, filename): """ This method is called when the user has selected an exercise to add. """ module = lessonfile.infocache.get(filename, 'module') if module not in ('harmonicinterval', 'melodicinterval', 'idbyname'): print( "Only harmonicinterval, melodicinterval and idbyname module exercises are working now. Ignoring..." ) return if module == 'idbyname': parsetree.Identifier.check_ns = False p = lessonfile.LessonfileCommon() p.parse_file(filename) parsetree.Identifier.check_ns = True if not [ q for q in p.m_questions if isinstance(q.music, lessonfile.MpdParsable) ]: gu.dialog_ok( _("This lesson file cannot be exported because some of the music in the file are not parsable by the mpd module." ), self) return self.m_changed = True self.g_liststore.append( (filename, self.get_lessonfile_title(filename), 3, 3, 4))
def setup_sound(self): if sys.platform == 'win32' and \ cfg.get_string("sound/type") == "sequencer-device": # just in case c:\home\.solfegerc is wrong cfg.set_string("sound/type", "winsynth") if self.m_options.no_sound \ or cfg.get_string("sound/type") == "fake-synth": soundcard.initialise_using_fake_synth(self.m_options.verbose_sound_init) elif cfg.get_string("sound/type") == "alsa-sequencer": if alsaseq: try: clientid, portid = self.get_list("sound/alsa-client-port") except ValueError: clientid, portid = (None, None) try: soundcard.initialise_alsa_sequencer((clientid, portid), self.m_options.verbose_sound_init) except alsaseq.SequencerError, e: logging.debug("initialise_alsa_sequencer failed. Using fake synth.") self.display_sound_init_error_message(e) soundcard.initialise_using_fake_synth(True) return else: if solfege.splash_win: solfege.splash_win.hide() gu.dialog_ok(_("The pyalsa Python module is missing"), solfege.win, _("Solfege was configured to use the Python modules from www.alsa-project.org, but the modules were not found. You must reconfigure sound in the preferences window (Ctrl-F12) or restart Solfege in a way that it finds the modules.")) soundcard.initialise_using_fake_synth(True) if solfege.splash_win: solfege.splash_win.show()
def post_constructor(self): self.m_frontpage_merge_id = None self.create_frontpage_menu() self.g_ui_manager.add_ui_from_file("help-menu.xml") if sys.platform != 'linux2': self.g_ui_manager.get_widget( '/Menubar/HelpMenu/SetupPyAlsa').hide() if solfege.app.m_sound_init_exception is not None: if solfege.splash_win: solfege.splash_win.destroy() solfege.splash_win = None solfege.app.display_sound_init_error_message( solfege.app.m_sound_init_exception) item = self.g_ui_manager.get_widget("/Menubar/FileMenu/FrontPagesMenu") item.connect('activate', lambda s: self.create_frontpage_menu()) try: i18n.locale_setup_failed print("\n".join( textwrap.wrap( "Translations are disabled because your locale settings are broken. This is not a bug in GNU Solfege, so don't report it. The README file distributed with the program has some more details." )), file=sys.stderr) except AttributeError: pass for filename in lessonfile.infocache.frontpage.iter_old_format_files(): gu.dialog_ok( _("Cannot load front page file"), self, _("The file «%s» is saved in an old file format. The file can be converted by editing and saving it with an older version of Solfege. Versions from 3.16.0 to 3.20.4 should do the job." ) % filename)
def on_start_practise(self): self.m_t.m_custom_mode = not ( ('white_keys_weight' in self.m_t.m_P.header) or ('black_keys_weight' in self.m_t.m_P.header)) super(Gui, self).on_start_practise() self.g_flashbar.require_size([ _("Click 'New tone' to begin."), _("Correct, but you have already solved this question"), _("Wrong, but you have already solved this question"), ]) if self.m_t.m_custom_mode: for notename, value in zip(mpd.MusicalPitch.notenames, self.get_list('custom_mode_cfg')): try: value = float(value) except ValueError: value = 0.0 self.set_float('%s_weight' % notename, value) else: if 'white_keys_weight' in self.m_t.m_P.header: if type(self.m_t.m_P.header.white_keys_weight) == list \ and len(self.m_t.m_P.header.white_keys_weight) == 7: for idx, n in enumerate(mpd.MusicalPitch.natural_notenames): try: weight = float(self.m_t.m_P.header.white_keys_weight[idx]) except ValueError: weight = 0.0 self.set_float('%s_weight' % n, weight) else: gu.dialog_ok("The white_keys_weight variable in the lesson file '%s' had wrong type" % os.path.abspath(self.m_t.m_P.m_filename), msgtype=Gtk.MessageType.WARNING) else: for idx, n in enumerate(mpd.MusicalPitch.notenames): self.set_float('%s_weight' % n, 0.0) if 'black_keys_weight' in self.m_t.m_P.header: if type(self.m_t.m_P.header.black_keys_weight) == list \ and len(self.m_t.m_P.header.black_keys_weight) == 5: for idx, n in enumerate(mpd.MusicalPitch.sharp_notenames): try: weight = float(self.m_t.m_P.header.black_keys_weight[idx]) except ValueError: weight = 0.0 self.set_float('%s_weight' % n, weight) else: gu.dialog_ok("The black_keys_weight variable in the lesson file '%s' had wrong type" % os.path.abspath(self.m_t.m_P.m_filename), msgtype=Gtk.MessageType.WARNING) else: for idx, n in enumerate(('cis', 'dis', 'fis', 'gis', 'ais')): self.set_float('%s_weight' % n, 0.0) if self.m_t.m_custom_mode: self.g_config_elems.show() self.m_t.m_statistics.reset_custom_mode_session(self.m_t.m_P.m_filename) else: self.g_config_elems.hide() self.m_t.m_statistics.reset_session() self.g_statview.g_heading.set_text("%s - %s" % (_("Identify tone"), self.m_t.m_P.header.title)) self.set_percentage_label() self.g_flashbar.delayed_flash(self.short_delay, _("Click 'New tone' to begin.")) self.std_buttons_start_practise() self.m_t.q_status = self.QSTATUS_NO
def enter_test_mode(self): if 'enter_test_mode' not in dir(self.get_view()): gu.dialog_ok(_("The '%s' exercise module does not support test yet." % self.m_viewer), self) return self.m_action_groups['NotExit'].set_sensitive(False) self.g = self.get_view().g_notebook.get_nth_page(0) self.get_view().g_notebook.get_nth_page(0).reparent(self.main_box) self.get_view().g_notebook.hide() self.get_view().enter_test_mode()
def edit_file(fn): if fn in Editor.instance_dict: Editor.instance_dict[fn].present() else: try: win = Editor(fn) win.show() except IOError, e: gu.dialog_ok(_("Loading file '%(filename)s' failed: %(msg)s") % {'filename': fn, 'msg': str(e).decode('utf8', 'replace')})
def do_test_complete(self): self.on_end_practise() req = self.m_t.m_P.get_test_requirement() self.g_cancel_test.hide() solfege.win.exit_test_mode() passed, res = solfege.db.get_test_status(self.m_t.m_P.m_filename) if res >= req: gu.dialog_ok(_("Test completed!\nYour score was %(score).1f%%.\nThe test requirement was %(requirement).1f%%.") % {'score': res * 100, 'requirement': req * 100}) else: gu.dialog_ok(_("Test failed.\nYour score was %(score).1f%%.\nThe test requirement was %(requirement).1f%%.") % {'score': res * 100, 'requirement': req * 100})
def on_export(self, widget): iter = self.g_liststore.get_iter_first() all_files_ok = True while iter: if self.g_liststore.get(iter, self.STORE_FILENAME) == (None,): all_files_ok = False iter = self.g_liststore.iter_next(iter) if not all_files_ok: gu.dialog_ok("Can not run because some exercises are not found.") return export_to = \ self.select_empty_directory(_("Select where to export the files")) if not export_to: return progress_dialog = gtk.Dialog(_("Exporting training set"), self, 0, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)) progress_dialog.show() label = gtk.Label() label.set_markup('<span weight="bold">%s</span>' % gu.escape(_("Export training set"))) label.show() progress_dialog.vbox.pack_start(label, False) def _cancel(widget, response): solfege.app.m_abort_export = True progress_dialog.connect('response', _cancel) progress_bar = gtk.ProgressBar() progress_bar.show() progress_dialog.vbox.pack_start(progress_bar) # We have to make a version of the data without gtk widgets v = [] iter = self.g_liststore.get_iter_first() while iter: v.append({ 'filename': \ unicode(self.g_liststore.get_value(iter, self.STORE_FILENAME)), 'count': self.g_liststore.get_value(iter, self.STORE_COUNT), 'repeat': self.g_liststore.get_value(iter, self.STORE_REPEAT), 'delay': self.g_liststore.get_value(iter, self.STORE_DELAY), }) iter = self.g_liststore.iter_next(iter) output_format = [k for k in self.g_output if self.g_output[k].get_active()][0] progress_dialog.queue_draw() while gtk.events_pending(): gtk.main_iteration(0) time.sleep(0.1) while gtk.events_pending(): gtk.main_iteration(0) try: for prog in solfege.app.export_training_set(v, export_to, output_format, self.g_named_tracks.get_active()): progress_bar.set_fraction(prog) while gtk.events_pending(): gtk.main_iteration(0) progress_dialog.destroy() except osutils.BinaryBaseException, e: progress_dialog.destroy() solfege.win.display_error_message2(e.msg1, e.msg2)
def enter_test_mode(self): if 'enter_test_mode' not in dir(self.get_view()): gu.dialog_ok( _("The '%s' exercise module does not support test yet." % self.m_viewer), self) return self.m_action_groups['NotExit'].set_sensitive(False) self.g = self.get_view().g_notebook.get_nth_page(0) self.get_view().g_notebook.get_nth_page(0).reparent(self.main_box) self.get_view().g_notebook.hide() self.get_view().enter_test_mode()
def edit_file(fn): if fn in Editor.instance_dict: Editor.instance_dict[fn].present() else: try: win = Editor(fn) win.show() except IOError as e: gu.dialog_ok( _("Loading file '%(filename)s' failed: %(msg)s") % { 'filename': fn, 'msg': str(e) }, solfege.win)
def acc_ff(renderer, path, accel_key, accel_mods, hw_key): is_unique = True for notename in notenames: if (notename != notenames[int(path)] and cfg.get_string('idtone/tone_%s_ak' % notename) == unichr(accel_key)): is_unique = False break if not is_unique: gu.dialog_ok(_(u"The accelerator in use for the tone “%s”. You have to choose another key.") % solfege.mpd.MusicalPitch.new_from_notename(notename).get_user_notename(), parent=self, msgtype=Gtk.MessageType.ERROR) return it = self.g_idtone_accels.get_iter(path) cfg.set_string('idtone/tone_%s_ak' % notenames[int(path)], unichr(accel_key)) self.g_idtone_accels.set(it, 1, unichr(accel_key)) return True
def acc_ff(renderer, path, accel_key, accel_mods, hw_key): is_unique = True for interval in intervals: if (interval != intervals[int(path)] and cfg.get_string('interval_input/%s' % interval) == unichr(accel_key)): is_unique = False break if not is_unique: gu.dialog_ok(_(u"The accelerator in use for “%s”. You have to choose another key.") % mpd.Interval.new_from_int(intervals.index(interval)).get_name(), parent=self, msgtype=Gtk.MessageType.ERROR) return it = self.g_interval_accels.get_iter(path) cfg.set_string('interval_input/%s' % intervals[int(path)], unichr(accel_key)) self.g_interval_accels.set(it, 1, unichr(accel_key)) return True
def new_question(self, *w): def exception_cleanup(): self.m_t.q_status = self.m_t.QSTATUS_NO self.std_buttons_exception_cleanup() try: g = self.m_t.new_question() if g == self.m_t.OK: self.m_t.play_question() self.std_buttons_new_question() self.g_w.grab_focus() self.g_w.set_score(self.m_t.m_score) self.g_c.set_editable(True) except Duration.BadStringException, e: gu.dialog_ok("Lesson file error", secondary_text=u"Bad rhythm string in the elements variable of the lessonfile. Only digits and dots expected: %s" % unicode(e)) exception_cleanup()
def _add_idbyname_lesson(self, p, filename): """ p is a lessonfile.LessonfileCommon parser that has parsed the file. """ not_ok = len([q.music for q in p.m_questions if not isinstance(q.music, self.ok_music_types)]) ok = len([q.music for q in p.m_questions if isinstance(q.music, self.ok_music_types)]) if not_ok > 0: if ok > 0: do_add = gu.dialog_yesno(_("Not all music types are supported. This file contain %(ok)i supported questions and %(not_ok)i that are not supported. The unsupported questions will be ignored. Add any way?" % locals())) else: gu.dialog_ok(_("Could not add the lesson file. It has no questions with a music object with supported music type.")) do_add = False else: do_add = True if do_add: self.m_changed = True self._add_common(filename)
def on_select_exercise(self, item, filename): """ This method is called when the user has selected an exercise to add. """ module = lessonfile.infocache.get(filename, 'module') if module not in ('harmonicinterval', 'melodicinterval', 'idbyname'): print "Only harmonicinterval, melodicinterval and idbyname module exercises are working now. Ignoring..." return if module == 'idbyname': p = lessonfile.LessonfileCommon() p.parse_file(filename) if not [q for q in p.m_questions if isinstance(q.music, lessonfile.MpdParsable)]: gu.dialog_ok(_("This lesson file cannot be exported because some of the music in the file are not parsable by the mpd module.")) return self.m_changed = True self.g_liststore.append(( filename, self.get_lessonfile_title(filename), 3, 3, 4))
def start_gui(datadir): if not options.profile: if cfg.get_bool("app/noprofilemanager"): options.profile = cfg.get_string("app/last_profile") elif do_profiles(): if solfege.splash_win: solfege.splash_win.hide() p = ProfileManager(cfg.get_string("app/last_profile")) ret = p.run() if ret == Gtk.ResponseType.ACCEPT: options.profile = p.get_profile() cfg.set_string("app/last_profile", "" if not options.profile else options.profile) elif ret in (Gtk.ResponseType.CLOSE, Gtk.ResponseType.DELETE_EVENT): Gtk.main_quit() return p.destroy() if solfege.splash_win: solfege.splash_win.show() cfg.set_bool('config/no_random', bool(options.no_random)) lessonfile.infocache = lessonfile.InfoCache() def f(s): if solfege.splash_win: solfege.splash_win.show_progress(s) if solfege.splash_win: solfege.splash_win.show_progress(_("Opening statistics database")) try: solfege.db = statistics.DB(f, profile=options.profile) except sqlite3.OperationalError, e: solfege.splash_win.hide() gu.dialog_ok( _(u"Failed to open the statistics database:\n«%s»") % str(e).decode(sys.getfilesystemencoding(), 'replace'), secondary_text= _("Click OK to exit the program. Then try to quit all other instances of the program, or reboot the computer. You can only run one instance of GNU Solfege at once." )) sys.exit()
def acc_ff(renderer, path, accel_key, accel_mods, hw_key): is_unique = True for notename in notenames: if (notename != notenames[int(path)] and cfg.get_string( 'idtone/tone_%s_ak' % notename) == unichr(accel_key)): is_unique = False break if not is_unique: gu.dialog_ok(_( u"The accelerator in use for the tone “%s”. You have to choose another key." ) % solfege.mpd.MusicalPitch.new_from_notename( notename).get_user_notename(), parent=self, msgtype=Gtk.MessageType.ERROR) return it = self.g_idtone_accels.get_iter(path) cfg.set_string('idtone/tone_%s_ak' % notenames[int(path)], unichr(accel_key)) self.g_idtone_accels.set(it, 1, unichr(accel_key)) return True
def acc_ff(renderer, path, accel_key, accel_mods, hw_key): is_unique = True for interval in intervals: if (interval != intervals[int(path)] and cfg.get_string( 'interval_input/%s' % interval) == unichr(accel_key)): is_unique = False break if not is_unique: gu.dialog_ok(_( u"The accelerator in use for “%s”. You have to choose another key." ) % mpd.Interval.new_from_int( intervals.index(interval)).get_name(), parent=self, msgtype=Gtk.MessageType.ERROR) return it = self.g_interval_accels.get_iter(path) cfg.set_string('interval_input/%s' % intervals[int(path)], unichr(accel_key)) self.g_interval_accels.set(it, 1, unichr(accel_key)) return True
def on_start_practise(self): self.m_t.m_custom_mode = not ( ('white_keys_weight' in self.m_t.m_P.header) or ('black_keys_weight' in self.m_t.m_P.header)) super(Gui, self).on_start_practise() self.g_flashbar.require_size([ _("Click 'New tone' to begin."), _("Correct, but you have already solved this question"), _("Wrong, but you have already solved this question"), ]) if 'white_keys_weight' in self.m_t.m_P.header: if type(self.m_t.m_P.header.white_keys_weight) == list \ and len(self.m_t.m_P.header.white_keys_weight) == 7: for idx, n in enumerate(('c', 'd', 'e', 'f', 'g', 'a', 'b')): self.set_float('%s_weight' % n, self.m_t.m_P.header.white_keys_weight[idx]) else: gu.dialog_ok("The white_keys_weight variable in the lesson file '%s' had wrong type" % os.path.abspath(self.m_t.m_P.m_filename), msgtype=gtk.MESSAGE_WARNING) else: for idx, n in enumerate(('c', 'd', 'e', 'f', 'g', 'a', 'b')): self.set_float('%s_weight' % n, 0.0) if 'black_keys_weight' in self.m_t.m_P.header: if type(self.m_t.m_P.header.black_keys_weight) == list \ and len(self.m_t.m_P.header.black_keys_weight) == 5: for idx, n in enumerate(('cis', 'dis', 'fis', 'gis', 'ais')): self.set_float('%s_weight' % n, self.m_t.m_P.header.black_keys_weight[idx]) else: gu.dialog_ok("The black_keys_weight variable in the lesson file '%s' had wrong type" % os.path.abspath(self.m_t.m_P.m_filename), msgtype=gtk.MESSAGE_WARNING) else: for idx, n in enumerate(('cis', 'dis', 'fis', 'gis', 'ais')): self.set_float('%s_weight' % n, 0.0) if self.m_t.m_custom_mode: self.g_config_elems.show() else: self.g_config_elems.hide() self.m_t.m_statistics.reset_session() self.g_statview.g_heading.set_text("%s - %s" % (_("Identify tone"), self.m_t.m_P.header.title)) self.set_percentage_label() self.g_flashbar.delayed_flash(self.short_delay, _("Click 'New tone' to begin.")) self.std_buttons_start_practise() self.m_t.q_status = self.QSTATUS_NO
def post_constructor(self): self.m_frontpage_merge_id = None self.create_frontpage_menu() self.g_ui_manager.add_ui_from_file("help-menu.xml") if sys.platform != 'linux2': self.g_ui_manager.get_widget('/Menubar/HelpMenu/SetupPyAlsa').hide() if solfege.app.m_sound_init_exception is not None: if solfege.splash_win: solfege.splash_win.destroy() solfege.splash_win = None solfege.app.display_sound_init_error_message(solfege.app.m_sound_init_exception) item = self.g_ui_manager.get_widget("/Menubar/FileMenu/FrontPagesMenu") item.connect('activate', lambda s: self.create_frontpage_menu()) try: i18n.locale_setup_failed print("\n".join(textwrap.wrap("Translations are disabled because your locale settings are broken. This is not a bug in GNU Solfege, so don't report it. The README file distributed with the program has some more details.")), file=sys.stderr) except AttributeError: pass for filename in lessonfile.infocache.frontpage.iter_old_format_files(): gu.dialog_ok(_("Cannot load front page file"), self, _("The file «%s» is saved in an old file format. The file can be converted by editing and saving it with an older version of Solfege. Versions from 3.16.0 to 3.20.4 should do the job.") % filename)
def load_frontpage(self): """ Load the front page file set in the config database into solfege.app.m_frontpage_data """ filename = self.get_string("app/frontpage") if filename == self.debug_front_page and not solfege.app.m_options.debug: self.set_string("app/frontpage", self.default_front_page) filename = self.default_front_page if not os.path.isfile(filename): filename = self.default_front_page try: solfege.app.m_frontpage_data = frontpage.load_tree(filename) except Exception: if solfege.splash_win: solfege.splash_win.hide() solfege.app.m_frontpage_data = frontpage.load_tree(self.default_front_page) self.set_string('app/frontpage', self.default_front_page) gu.dialog_ok(_("Loading front page '%s' failed. Using default page." % filename), parent=self, secondary_text="\n".join(traceback.format_exception(*sys.exc_info()))) if solfege.splash_win: solfege.splash_win.show() self.display_frontpage()
def load_file(self, filename): """ This function can load both format version 1.0 and 2.0 """ tree = et.ElementTree() tree.parse(filename) # section.find('text').text will be none if it was not set # when saved, and we need a string. if tree.find("title").text: self.g_title.set_text(tree.find("title").text) else: self.g_title.set_text("") sheet = tree.find("sheet") if tree.find('output_format').text == 'latex': self.g_latex_radio.set_active(True) else: self.g_latex_radio.set_active(False) self.g_liststore.clear() self.m_sections = [] for section in tree.findall("section"): d = {} lessonfilename = section.find('filename') if lessonfilename == None: # fileformat 1.0 lessonfile.require_mgr() lesson_id = section.find('lesson_id').text lessonfilename = lessonfile.mgr.get(lesson_id, 'filename') lessonfilename = lessonfile.mk_uri(lessonfilename) else: lessonfilename = lessonfilename.text # It seems that the elementtree parser will return str if # there are no non-ascii chars in the filename. So lets # make unicode of it if it is str if isinstance(lessonfilename, str): lessonfilename = unicode(lessonfilename) d['filename'] = lessonfilename # section.find('text').text will be none if it was not set # when saved, and d['title'] need to be a string if section.find('title').text: d['title'] = section.find('title').text else: d['title'] = "" if section.find('intervals') != None: d['intervals'] = eval(section.find('intervals').text, {}, {}) else: if lessonfile.infocache.get(lessonfilename, 'module') == 'harmonicinterval': d['intervals'] = [] gu.dialog_ok("FIXME: «%s» was saved with a buggy version of solfege, so you must set the intervals by selecting the file in the dialog and clicking the intervals to be asked. Sorry!" % lessonfilename) d['count'] = int(section.find('count').text) d['line_len'] = int(section.find('line_len').text) d['qtype'] = int(section.find('qtype').text) d['questions'] = [] for question in section.findall("question"): q = {'question': {}, 'answer': {}} q['question']['music'] = question.find("students").find("music").text q['question']['name'] = question.find("students").find("name").text q['answer']['music'] = question.find("teachers").find("music").text q['answer']['name'] = question.find("teachers").find("name").text d['questions'].append(q) self.m_sections.append(d) try: # Check that the filename is valid lessonfile.infocache.get(lessonfilename, 'title') self.g_liststore.append((d['title'], lessonfilename)) except lessonfile.infocache.InfoCacheException, e: self.g_liststore.append((_("«%s» not found") % str(e), None)) self.g_treeview.set_cursor((0,))
def setup_sound(self): if sys.platform == 'win32' and \ cfg.get_string("sound/type") == "sequencer-device": # just in case c:\home\.solfegerc is wrong cfg.set_string("sound/type", "winsynth") if self.m_options.no_sound \ or cfg.get_string("sound/type") == "fake-synth": soundcard.initialise_using_fake_synth(self.m_options.verbose_sound_init) elif cfg.get_string("sound/type") == "alsa-sequencer": if alsaseq: try: clientid, portid = self.get_list("sound/alsa-client-port") except ValueError: clientid, portid = (None, None) try: soundcard.initialise_alsa_sequencer((clientid, portid), self.m_options.verbose_sound_init) except alsaseq.SequencerError as e: logging.debug("initialise_alsa_sequencer failed. Using fake synth.") self.display_sound_init_error_message(e) soundcard.initialise_using_fake_synth(True) return else: if solfege.splash_win: solfege.splash_win.hide() gu.dialog_ok(_("The pyalsa Python module is missing"), solfege.win, _("Solfege was configured to use the Python modules from www.alsa-project.org, but the modules were not found. You must reconfigure sound in the preferences window (Ctrl-F12) or restart Solfege in a way that it finds the modules.")) soundcard.initialise_using_fake_synth(True) if solfege.splash_win: solfege.splash_win.show() elif cfg.get_string("sound/type") == "winsynth": try: soundcard.initialise_winsynth(cfg.get_int("sound/synth_number"), verbose_init=self.m_options.verbose_sound_init) except ImportError as e: self.display_sound_init_error_message(e) cfg.set_string("sound/type", "fake-synth") soundcard.initialise_using_fake_synth(True) return except RuntimeError as e: # We can get here if winmidi.output_devices() in winsynth # __init__ returns no devices. Don't know when, but it could # happen. gu.display_exception_message(e) cfg.set_string("sound/type", "fake-synth") soundcard.initialise_using_fake_synth(True) return if cfg.get_int("sound/synth_number") != soundcard.synth.m_devnum: solfege.win.display_error_message2(_("MIDI setup"), _("MIDI Device %(olddev)i not available. Will use device %(newdev)i.") % {'olddev': cfg.get_int("sound/synth_number"), 'newdev': soundcard.synth.m_devnum}) cfg.set_int("sound/synth_number", soundcard.synth.m_devnum) elif cfg.get_string("sound/type") == "external-midiplayer": soundcard.initialise_external_midiplayer( verbose_init=self.m_options.verbose_sound_init) soundcard.synth.error_report_cb = solfege.win.display_error_message elif cfg.get_string("sound/type") == '': solfege.win.display_error_message( _("You should configure sound from the 'Sound' page " "of the preferences window.")) elif cfg.get_string("sound/type") == "sequencer-device": try: soundcard.initialise_devicefile( cfg.get_string("sound/device_file"), cfg.get_int("sound/synth_number"), verbose_init=self.m_options.verbose_sound_init) except (soundcard.SoundInitException, OSError, ImportError) as e: self.m_sound_init_exception = e soundcard.initialise_using_fake_synth(True) if cfg.get_string("programs/csound") == "AUTODETECT": for p in osutils.find_csound_executables(): cfg.set_string("programs/csound", p) break else: # If not csound binary was found, then we set the string empty. # This means that autodetection will only happen the first time # you run the program. But later will newly installed binaries # be shown in the combo box of the preferences window. cfg.set_string("programs/csound", "") if cfg.get_string("programs/mma") == "AUTODETECT": for p in osutils.find_mma_executables(cfg.get_list("app/win32_ignore_drives")): cfg.set_string("programs/mma", p) break else: cfg.set_string("programs/mma", "")
def on_start_practise(self): self.m_t.m_custom_mode = not ( ('white_keys_weight' in self.m_t.m_P.header) or ('black_keys_weight' in self.m_t.m_P.header)) super(Gui, self).on_start_practise() self.g_flashbar.require_size([ _("Click 'New tone' to begin."), _("Correct, but you have already solved this question"), _("Wrong, but you have already solved this question"), ]) if self.m_t.m_custom_mode: for notename, value in zip(mpd.MusicalPitch.notenames, self.get_list('custom_mode_cfg')): try: value = float(value) except ValueError: value = 0.0 self.set_float('%s_weight' % notename, value) else: if 'white_keys_weight' in self.m_t.m_P.header: if type(self.m_t.m_P.header.white_keys_weight) == list \ and len(self.m_t.m_P.header.white_keys_weight) == 7: for idx, n in enumerate( mpd.MusicalPitch.natural_notenames): try: weight = float( self.m_t.m_P.header.white_keys_weight[idx]) except ValueError: weight = 0.0 self.set_float('%s_weight' % n, weight) else: gu.dialog_ok( "The white_keys_weight variable in the lesson file '%s' had wrong type" % os.path.abspath(self.m_t.m_P.m_filename), msgtype=Gtk.MessageType.WARNING) else: for idx, n in enumerate(mpd.MusicalPitch.notenames): self.set_float('%s_weight' % n, 0.0) if 'black_keys_weight' in self.m_t.m_P.header: if type(self.m_t.m_P.header.black_keys_weight) == list \ and len(self.m_t.m_P.header.black_keys_weight) == 5: for idx, n in enumerate(mpd.MusicalPitch.sharp_notenames): try: weight = float( self.m_t.m_P.header.black_keys_weight[idx]) except ValueError: weight = 0.0 self.set_float('%s_weight' % n, weight) else: gu.dialog_ok( "The black_keys_weight variable in the lesson file '%s' had wrong type" % os.path.abspath(self.m_t.m_P.m_filename), msgtype=Gtk.MessageType.WARNING) else: for idx, n in enumerate(('cis', 'dis', 'fis', 'gis', 'ais')): self.set_float('%s_weight' % n, 0.0) if self.m_t.m_custom_mode: self.g_config_elems.show() self.m_t.m_statistics.reset_custom_mode_session( self.m_t.m_P.m_filename) else: self.g_config_elems.hide() self.m_t.m_statistics.reset_session() self.g_statview.g_heading.set_text( "%s - %s" % (_("Identify tone"), self.m_t.m_P.header.title)) self.set_percentage_label() self.g_flashbar.delayed_flash(self.short_delay, _("Click 'New tone' to begin.")) self.std_buttons_start_practise() self.m_t.q_status = self.QSTATUS_NO
def load_file(self, filename): tree = et.ElementTree() tree.parse(filename) if tree.getroot().get("fileformat_version") != "2.0": e = Exception("PractiseSheet") e.msg1 = _("Cannot read old file format") e.msg2 = _( "To convert the file to the new file format, you must open and save it in an older version of Solfege. Versions from 3.16.0 to 3.20.4 should do the job." ) raise e # section.find('text').text will be none if it was not set # when saved, and we need a string. if tree.find("title").text: self.g_title.set_text(tree.find("title").text) else: self.g_title.set_text("") if tree.find('output_format').text == 'latex': self.g_latex_radio.set_active(True) else: self.g_latex_radio.set_active(False) self.g_liststore.clear() self.m_sections = [] for section in tree.findall("section"): d = {} lessonfilename = section.find('filename').text # It seems that the elementtree parser will return str if # there are no non-ascii chars in the filename. So lets # make unicode of it if it is str if isinstance(lessonfilename, str): lessonfilename = str(lessonfilename) d['filename'] = lessonfilename # section.find('text').text will be none if it was not set # when saved, and d['title'] need to be a string if section.find('title').text: d['title'] = section.find('title').text else: d['title'] = "" if section.find('intervals') is not None: d['intervals'] = eval(section.find('intervals').text, {}, {}) else: if lessonfile.infocache.get(lessonfilename, 'module') == 'harmonicinterval': d['intervals'] = [] gu.dialog_ok( "FIXME: «%s» was saved with a buggy version of solfege, so you must set the intervals by selecting the file in the dialog and clicking the intervals to be asked. Sorry!" % lessonfilename, self) d['count'] = int(section.find('count').text) d['line_len'] = int(section.find('line_len').text) d['qtype'] = int(section.find('qtype').text) d['questions'] = [] for question in section.findall("question"): q = {'question': {}, 'answer': {}} q['question']['music'] = question.find("students").find( "music").text q['question']['name'] = question.find("students").find( "name").text q['answer']['music'] = question.find("teachers").find( "music").text q['answer']['name'] = question.find("teachers").find( "name").text d['questions'].append(q) self.m_sections.append(d) try: # Check that the filename is valid lessonfile.infocache.get(lessonfilename, 'title') self.g_liststore.append((d['title'], lessonfilename)) except lessonfile.infocache.InfoCacheException as e: self.g_liststore.append((_("«%s» not found") % str(e), None)) self.g_treeview.set_cursor((0, )) self.m_filename = filename
def start_gui(datadir): cfg.set_bool('config/no_random', bool(options.no_random)) lessonfile.infocache = lessonfile.InfoCache() def f(s): if solfege.splash_win: solfege.splash_win.show_progress(s) if solfege.splash_win: solfege.splash_win.show_progress(_("Creating application window")) solfege.app = application.SolfegeApp(options) solfege.win = w = MainWin(options, datadir) solfege.app.setup_sound() w.post_constructor() solfege.win.load_frontpage() w.show() if solfege.splash_win: solfege.splash_win.destroy() solfege.splash_win = None if not options.profile: if cfg.get_bool("app/noprofilemanager"): options.profile = cfg.get_string("app/last_profile") elif do_profiles(): if solfege.splash_win: solfege.splash_win.hide() options.profile = solfege.win.run_startup_profile_manager() if solfege.splash_win: solfege.splash_win.show() if solfege.splash_win: solfege.splash_win.show_progress(_("Opening statistics database")) try: solfege.db = statistics.DB(f, profile=options.profile) except sqlite3.OperationalError as e: if solfege.splash_win: solfege.splash_win.hide() gu.dialog_ok( _("Failed to open the statistics database:\n«%s»") % str(e).decode(sys.getfilesystemencoding(), 'replace'), solfege.win, secondary_text=_("Click OK to exit the program. Then try to quit all other instances of the program, or reboot the computer. You can only run one instance of GNU Solfege at once.")) sys.exit() def ef(t, value, traceback): if options.debug: msg = "ehooked:" + str(value) else: msg = str(value) if issubclass(t, lessonfile.LessonfileException): w.display_error_message(msg, str(t)) elif issubclass(t, osutils.ExecutableDoesNotExist): if len(value.args) > 1: w.display_error_message2(value.args[0], "\n".join(value.args[1:])) else: w.display_error_message(msg, str(t)) else: sys.__excepthook__(t, value, traceback) if not options.disable_exception_handler: sys.excepthook = ef print(time.time() - start_time) # We parse all lesson files when we are idle to save a half a # second the first time the user searches all lesson files using # Ctrl-F. lessonfile.infocache.parse_all_files(True) if options.screenshots: make_screenshots.make_screenshots() if options.lessonfile: solfege.app.practise_lessonfile(options.lessonfile)
def on_export(self, widget): iter = self.g_liststore.get_iter_first() all_files_ok = True while iter: if self.g_liststore.get(iter, self.STORE_FILENAME) == (None, ): all_files_ok = False iter = self.g_liststore.iter_next(iter) if not all_files_ok: gu.dialog_ok("Can not run because some exercises are not found.") return export_to = \ self.select_empty_directory(_("Select where to export the files")) if not export_to: return progress_dialog = gtk.Dialog(_("Exporting training set"), self, 0, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)) progress_dialog.show() label = gtk.Label() label.set_markup('<span weight="bold">%s</span>' % gu.escape(_("Export training set"))) label.show() progress_dialog.vbox.pack_start(label, False) def _cancel(widget, response): solfege.app.m_abort_export = True progress_dialog.connect('response', _cancel) progress_bar = gtk.ProgressBar() progress_bar.show() progress_dialog.vbox.pack_start(progress_bar) # We have to make a version of the data without gtk widgets v = [] iter = self.g_liststore.get_iter_first() while iter: v.append({ 'filename': \ unicode(self.g_liststore.get_value(iter, self.STORE_FILENAME)), 'count': self.g_liststore.get_value(iter, self.STORE_COUNT), 'repeat': self.g_liststore.get_value(iter, self.STORE_REPEAT), 'delay': self.g_liststore.get_value(iter, self.STORE_DELAY), }) iter = self.g_liststore.iter_next(iter) output_format = [ k for k in self.g_output if self.g_output[k].get_active() ][0] progress_dialog.queue_draw() while gtk.events_pending(): gtk.main_iteration(0) time.sleep(0.1) while gtk.events_pending(): gtk.main_iteration(0) try: for prog in solfege.app.export_training_set( v, export_to, output_format, self.g_named_tracks.get_active()): progress_bar.set_fraction(prog) while gtk.events_pending(): gtk.main_iteration(0) progress_dialog.destroy() except osutils.BinaryBaseException, e: progress_dialog.destroy() solfege.win.display_error_message2(e.msg1, e.msg2)
def load_file(self, filename): tree = et.ElementTree() tree.parse(filename) if tree.getroot().get("fileformat_version") != "2.0": e = Exception("PractiseSheet") e.msg1 = _("Cannot read old file format") e.msg2 = _("To convert the file to the new file format, you must open and save it in an older version of Solfege. Versions from 3.16.0 to 3.20.4 should do the job.") raise e # section.find('text').text will be none if it was not set # when saved, and we need a string. if tree.find("title").text: self.g_title.set_text(tree.find("title").text) else: self.g_title.set_text("") sheet = tree.find("sheet") if tree.find('output_format').text == 'latex': self.g_latex_radio.set_active(True) else: self.g_latex_radio.set_active(False) self.g_liststore.clear() self.m_sections = [] for section in tree.findall("section"): d = {} lessonfilename = section.find('filename').text # It seems that the elementtree parser will return str if # there are no non-ascii chars in the filename. So lets # make unicode of it if it is str if isinstance(lessonfilename, str): lessonfilename = unicode(lessonfilename) d['filename'] = lessonfilename # section.find('text').text will be none if it was not set # when saved, and d['title'] need to be a string if section.find('title').text: d['title'] = section.find('title').text else: d['title'] = "" if section.find('intervals') != None: d['intervals'] = eval(section.find('intervals').text, {}, {}) else: if lessonfile.infocache.get(lessonfilename, 'module') == 'harmonicinterval': d['intervals'] = [] gu.dialog_ok(u"FIXME: «%s» was saved with a buggy version of solfege, so you must set the intervals by selecting the file in the dialog and clicking the intervals to be asked. Sorry!" % lessonfilename) d['count'] = int(section.find('count').text) d['line_len'] = int(section.find('line_len').text) d['qtype'] = int(section.find('qtype').text) d['questions'] = [] for question in section.findall("question"): q = {'question': {}, 'answer': {}} q['question']['music'] = question.find("students").find("music").text q['question']['name'] = question.find("students").find("name").text q['answer']['music'] = question.find("teachers").find("music").text q['answer']['name'] = question.find("teachers").find("name").text d['questions'].append(q) self.m_sections.append(d) try: # Check that the filename is valid lessonfile.infocache.get(lessonfilename, 'title') self.g_liststore.append((d['title'], lessonfilename)) except lessonfile.infocache.InfoCacheException, e: self.g_liststore.append((_(u"«%s» not found") % str(e), None)) self.g_treeview.set_cursor((0,))
def setup_sound(self): if sys.platform == 'win32' and \ cfg.get_string("sound/type") == "sequencer-device": # just in case c:\home\.solfegerc is wrong cfg.set_string("sound/type", "winsynth") if self.m_options.no_sound \ or cfg.get_string("sound/type") == "fake-synth": soundcard.initialise_using_fake_synth( self.m_options.verbose_sound_init) elif cfg.get_string("sound/type") == "alsa-sequencer": if alsaseq: try: clientid, portid = self.get_list("sound/alsa-client-port") except ValueError: clientid, portid = (None, None) try: soundcard.initialise_alsa_sequencer( (clientid, portid), self.m_options.verbose_sound_init) except alsaseq.SequencerError as e: logging.debug( "initialise_alsa_sequencer failed. Using fake synth.") self.display_sound_init_error_message(e) soundcard.initialise_using_fake_synth(True) return else: if solfege.splash_win: solfege.splash_win.hide() gu.dialog_ok( _("The pyalsa Python module is missing"), solfege.win, _("Solfege was configured to use the Python modules from www.alsa-project.org, but the modules were not found. You must reconfigure sound in the preferences window (Ctrl-F12) or restart Solfege in a way that it finds the modules." )) soundcard.initialise_using_fake_synth(True) if solfege.splash_win: solfege.splash_win.show() elif cfg.get_string("sound/type") == "winsynth": try: soundcard.initialise_winsynth( cfg.get_int("sound/synth_number"), verbose_init=self.m_options.verbose_sound_init) except ImportError as e: self.display_sound_init_error_message(e) cfg.set_string("sound/type", "fake-synth") soundcard.initialise_using_fake_synth(True) return except RuntimeError as e: # We can get here if winmidi.output_devices() in winsynth # __init__ returns no devices. Don't know when, but it could # happen. gu.display_exception_message(e) cfg.set_string("sound/type", "fake-synth") soundcard.initialise_using_fake_synth(True) return if cfg.get_int("sound/synth_number") != soundcard.synth.m_devnum: solfege.win.display_error_message2( _("MIDI setup"), _("MIDI Device %(olddev)i not available. Will use device %(newdev)i." ) % { 'olddev': cfg.get_int("sound/synth_number"), 'newdev': soundcard.synth.m_devnum }) cfg.set_int("sound/synth_number", soundcard.synth.m_devnum) elif cfg.get_string("sound/type") == "external-midiplayer": soundcard.initialise_external_midiplayer( verbose_init=self.m_options.verbose_sound_init) soundcard.synth.error_report_cb = solfege.win.display_error_message elif cfg.get_string("sound/type") == '': solfege.win.display_error_message( _("You should configure sound from the 'Sound' page " "of the preferences window.")) elif cfg.get_string("sound/type") == "sequencer-device": try: soundcard.initialise_devicefile( cfg.get_string("sound/device_file"), cfg.get_int("sound/synth_number"), verbose_init=self.m_options.verbose_sound_init) except (soundcard.SoundInitException, OSError, ImportError) as e: self.m_sound_init_exception = e soundcard.initialise_using_fake_synth(True) if cfg.get_string("programs/csound") == "AUTODETECT": for p in osutils.find_csound_executables(): cfg.set_string("programs/csound", p) break else: # If not csound binary was found, then we set the string empty. # This means that autodetection will only happen the first time # you run the program. But later will newly installed binaries # be shown in the combo box of the preferences window. cfg.set_string("programs/csound", "") if cfg.get_string("programs/mma") == "AUTODETECT": for p in osutils.find_mma_executables( cfg.get_list("app/win32_ignore_drives")): cfg.set_string("programs/mma", p) break else: cfg.set_string("programs/mma", "")