Example #1
0
def play_mediafile(typeid, filename):
    global _mediaplayer
    if sys.platform == 'win32' and typeid == 'wav':
        winsound.PlaySound(filename, winsound.SND_FILENAME | winsound.SND_ASYNC)
    else:
        args = [cfg.get_string("sound/%s_player" % typeid)]
        # We only add %s_player_options if is is a non empty string,
        # since args should not contain any empty strings.
        if cfg.get_string("sound/%s_player_options"% typeid):
            args.extend(
             cfg.get_string("sound/%s_player_options"% typeid).split(" "))
        found = False
        for i, s in enumerate(args):
            if '%s' in s:
                args[i] = args[i] % os.path.abspath(filename)
                found = True
        if not found:
            args.append(os.path.abspath(filename))
        if _mediaplayer and _mediaplayer.poll() == None:
            _mediaplayer.kill()
            _mediaplaer  = None
        try:
            if sys.platform == 'win32':
                info = subprocess.STARTUPINFO()
                info.dwFlags = 1
                info.wShowWindow = 0
                _mediaplayer = osutils.Popen(args=args, startupinfo=info)
            else:
                _mediaplayer = osutils.Popen(args=args)
        except OSError, e:
            raise osutils.BinaryForMediaPlayerException(typeid,
                cfg.get_string("sound/%s_player" % typeid), e)
Example #2
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, 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()
Example #3
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, 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()
Example #4
0
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()
Example #5
0
 def on_edit_file(self, menuitem, linked):
     try:
         try:
             subprocess.call((cfg.get_string("programs/text-editor"),
                          lessonfile.uri_expand(self.m_model[linked])))
         except OSError, e:
              raise osutils.BinaryForProgramException("Text editor", cfg.get_string("programs/text-editor"), e)
     except osutils.BinaryForProgramException, e:
         solfege.win.display_error_message2(e.msg1, e.msg2)
Example #6
0
 def on_edit_file(self, menuitem, linked):
     try:
         try:
             subprocess.call((cfg.get_string("programs/text-editor"),
                          lessonfile.uri_expand(self.m_model[linked])))
         except OSError, e:
              raise osutils.BinaryForProgramException("Text editor", cfg.get_string("programs/text-editor"), e)
     except osutils.BinaryForProgramException, e:
         solfege.win.display_error_message2(e.msg1, e.msg2)
Example #7
0
 def __init__(self, parent, error_text):
     gtk.Dialog.__init__(self, _("Make bug report"), parent,
             buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT))
     self.m_error_text = error_text
     self.add_button(_("See complete _report"), RESPONSE_SEE)
     self.add_button(_("_Send"), RESPONSE_SEND)
     self.set_default_size(400, 400)
     sizegroup = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL)
     self.g_email = gtk.Entry()
     self.vbox.pack_start(
         gu.hig_label_widget(_("_Email:"), self.g_email, sizegroup),
         False)
     self.g_mangled_email = gtk.Label()
     self.vbox.pack_start(
         gu.hig_label_widget(_("Mangled email address:"), self.g_mangled_email,
             sizegroup), False)
     self.g_email.set_text(cfg.get_string('user/email'))
     self.g_email.connect('changed', self.on_update_mangle)
     self.g_description = gtk.Entry()
     self.vbox.pack_start(
         gu.hig_label_widget(_("S_hort description:"), self.g_description,
                  sizegroup), False)
     label = gtk.Label(_("_Describe how to produce the error message:"))
     label.set_use_underline(True)
     label.set_alignment(0.0, 0.5)
     self.vbox.pack_start(label, False)
     self.g_tw = gtk.TextView()
     self.g_tw.set_wrap_mode(gtk.WRAP_WORD)
     self.g_tw.set_border_width(10)
     # translators, please notice that the word NO_DESCRIPTION must not be
     # translated in this string.
     self.g_tw.get_buffer().insert_at_cursor(_("""Describe as exactly as you can what you did when this error occurred. If you give no description at all, you make it very difficult to track down this bug. You should replace this text with your description, and also remove the "bug-tag" in the bottom of this text so that this bug is not automatically sorted among the bug reports with no description.\n\n(bug-tag: NO_DESCRIPTION)"""))
     label.set_mnemonic_widget(self.g_tw)
     self.vbox.pack_start(self.g_tw)
     self.show_all()
Example #8
0
 def create_interval_accels_config(self, parent):
     it, page_vbox = self.new_page_box(parent, _("Interval keyboard accelerators"))
     self.g_interval_accels = Gtk.ListStore(GObject.TYPE_STRING,
         GObject.TYPE_STRING)
     intervals = ['minor2', 'major2', 'minor3', 'major3',
                  'perfect4', 'diminished5', 'perfect5', 'minor6',
                  'major6', 'minor7', 'major7', 'perfect8',
                  'minor9', 'major9', 'minor10', 'major10']
     for interval in intervals:
         self.g_interval_accels.append((
             mpd.Interval.new_from_int(intervals.index(interval)).get_name(),
             cfg.get_string('interval_input/%s' % interval)))
     self.g_intervals_treeview = Gtk.TreeView(self.g_interval_accels)
     renderer = Gtk.CellRendererText()
     column = Gtk.TreeViewColumn(_("Interval"), renderer, text=0)
     self.g_intervals_treeview.append_column(column)
     renderer = Gtk.CellRendererAccel()
     renderer.set_property('editable', 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
     renderer.connect('accel-edited', acc_ff)
     column = Gtk.TreeViewColumn(_i("keyboard|Key"), renderer, text=1)
     self.g_intervals_treeview.append_column(column)
     page_vbox.pack_start(self.g_intervals_treeview, True, True, 0)
     hbox = Gtk.HBox()
     page_vbox.pack_start(hbox, False, False, 0)
     layouts = {'ascii': (_('ASCII'), u'1qaz2wsx3edc4rfv'),
                'dvorak': (_('Dvorak'), u"1'a;2,oq3.ej4puk"),
     }
     
     def set_buttons(widget, layout):
         v = layouts[layout][1]
         idx = 0
         it = self.g_interval_accels.get_iter_first()
         while True:
             self.g_interval_accels.set_value(it, 1, v[idx])
             cfg.set_string('interval_input/%s' % intervals[idx], v[idx])
             it = self.g_interval_accels.iter_next(it)
             idx += 1
             
             if not it:
                 break
     for key in layouts:
         btn = Gtk.Button(layouts[key][0])
         btn.connect('clicked', set_buttons, key)
         hbox.pack_start(btn, True, True, 0)
Example #9
0
def nComboBox(exname, name, default, popdown_strings):
    c = gtk.combo_box_new_text()
    for n in popdown_strings:
        c.append_text(n)
    c.m_exname = exname
    c.m_name = name
    val = cfg.get_string("%s/%s=X" % (c.m_exname, c.m_name))
    if val == 'X':
        cfg.set_int("%s/%s" % (exname, name), popdown_strings.index(default))
        c.set_active(popdown_strings.index(default))
    else:
        try:
            i = cfg.get_int("%s/%s" % (c.m_exname, c.m_name))
        except ValueError:
            i = 0
            cfg.set_int("%s/%s" % (c.m_exname, c.m_name), 0)
        if i >= len(popdown_strings):
            i = 0
            cfg.set_int("%s/%s" % (c.m_exname, c.m_name), 0)
        c.set_active(cfg.get_int("%s/%s" % (c.m_exname, c.m_name)))

    def f(combobox):
        cfg.set_int("%s/%s" % (exname, name), combobox.get_active())

    c.connect('changed', f)
    return c
Example #10
0
 def __init__(self, parent, error_text):
     Gtk.Dialog.__init__(self, _("Make bug report"), parent,
             buttons=(Gtk.STOCK_CANCEL, Gtk.ResponseType.REJECT))
     self.m_error_text = error_text
     self.add_button(_("_Send"), RESPONSE_SEND)
     self.set_default_size(400, 400)
     sizegroup = Gtk.SizeGroup(Gtk.SizeGroupMode.HORIZONTAL)
     l = Gtk.Label(_("Information about the version of GNU Solfege, your operating system and Python version, and the Python traceback (error message) will be sent to the crash database. Your email will not be published or shared, but we might contact you by email if we have further questions about your crash report."))
     l.set_line_wrap(True)
     l.show()
     self.vbox.pack_start(l, False, False, 0)
     self.g_email = Gtk.Entry()
     self.vbox.pack_start(
         gu.hig_label_widget(_("_Email:"), self.g_email, sizegroup),
         False, False, 0)
     self.g_email.set_text(cfg.get_string('user/email'))
     # 140 is max in the solfege.org database
     self.g_description = Gtk.Entry()
     self.g_description.set_max_length(140)
     self.vbox.pack_start(
         gu.hig_label_widget(_("S_hort description:"), self.g_description,
                  sizegroup), False, False, 0)
     label = Gtk.Label(label=_("_Describe how to produce the error message:"))
     label.set_use_underline(True)
     label.set_alignment(0.0, 0.5)
     self.vbox.pack_start(label, False, False, 0)
     self.g_tw = Gtk.TextView()
     self.g_tw.set_wrap_mode(Gtk.WrapMode.WORD)
     self.g_tw.set_border_width(10)
     label.set_mnemonic_widget(self.g_tw)
     self.vbox.pack_start(self.g_tw, True, True, 0)
     self.show_all()
Example #11
0
def nComboBox(exname, name, default, popdown_strings):
    c = Gtk.ComboBoxText()
    for n in popdown_strings:
        c.append_text(n)
    c.m_exname = exname
    c.m_name = name
    val = cfg.get_string("%s/%s=X" % (c.m_exname, c.m_name))
    if val == 'X':
        cfg.set_int("%s/%s" % (exname, name),
            popdown_strings.index(default))
        c.set_active(popdown_strings.index(default))
    else:
        try:
            i = cfg.get_int("%s/%s" % (c.m_exname, c.m_name))
        except ValueError:
            i = 0
            cfg.set_int("%s/%s" % (c.m_exname, c.m_name), 0)
        if i >= len(popdown_strings):
            i = 0
            cfg.set_int("%s/%s" % (c.m_exname, c.m_name), 0)
        c.set_active(cfg.get_int("%s/%s" % (c.m_exname, c.m_name)))
    def f(combobox):
        cfg.set_int("%s/%s" % (exname, name), combobox.get_active())
    c.connect('changed', f)
    return c
Example #12
0
    def create_gui_config(self):
        i_iter, page_vbox = self.new_page_box(None, _("Interface"))

        self.g_mainwin_user_resizeable = gu.nCheckButton(
            'gui', 'mainwin_user_resizeable', _("_Resizeable main window"))
        page_vbox.pack_start(self.g_mainwin_user_resizeable, False, False, 0)

        # Combobox to select language
        hbox = Gtk.HBox()
        hbox.set_spacing(6)
        label = Gtk.Label()
        label.set_text_with_mnemonic(_("Select _language:"))
        hbox.pack_start(label, False, False, 0)
        self.g_language = Gtk.ComboBoxText()
        for n in languages.languages:
            self.g_language.append_text(n)
        label.set_mnemonic_widget(self.g_language)
        if sys.platform == 'win32':
            lang = winlang.win32_get_langenviron()
            if lang in languages.languages:
                idx = languages.languages.index(lang)
            elif lang == 'C':
                idx = languages.C_locale_idx
            else:
                idx = 0
        else:
            lang = cfg.get_string('app/lc_messages')
            if lang in languages.languages:
                idx = languages.languages.index(lang)
            elif lang == 'C':
                idx = languages.C_locale_idx
            else:
                idx = 0
        self.g_language.set_active(idx)

        def f(combobox):
            if combobox.get_active() == languages.C_locale_idx:
                lang = "C"
            else:
                lang = languages.languages[combobox.get_active()]
            cfg.set_string('app/lc_messages', lang)
            if sys.platform == 'win32':
                if combobox.get_active():
                    winlang.win32_put_langenviron(lang)
                else:
                    winlang.win32_put_langenviron(None)

        self.g_language.connect_after('changed', f)
        hbox.pack_start(self.g_language, False, False, 0)
        page_vbox.pack_start(hbox, False, False, 0)
        l = Gtk.Label(label=_(
            "You have to restart the program for the language change to take effect."
        ))
        l.set_alignment(0.0, 0.5)
        page_vbox.pack_start(l, False, False, 0)

        self.create_idtone_accels_config(i_iter)
        self.create_interval_accels_config(i_iter)
Example #13
0
 def create_idtone_accels_config(self, parent):
     it, page_vbox = self.new_page_box(parent, _("Identify tone keyboard accelerators"))
     self.g_idtone_accels = Gtk.ListStore(GObject.TYPE_STRING,
         GObject.TYPE_STRING)
     notenames = ('c', 'cis', 'd', 'dis', 'e', 'f', 'fis',
                  'g', 'gis', 'a', 'ais', 'b')
     for notename in notenames:
         self.g_idtone_accels.append((
             solfege.mpd.MusicalPitch.new_from_notename(notename).get_user_notename(),
             cfg.get_string('idtone/tone_%s_ak' % notename)))
     self.g_treeview = Gtk.TreeView(self.g_idtone_accels)
     renderer = Gtk.CellRendererText()
     column = Gtk.TreeViewColumn(_("Note name"), renderer, text=0)
     self.g_treeview.append_column(column)
     renderer = Gtk.CellRendererAccel()
     renderer.set_property('editable', True)
     
     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
     renderer.connect('accel-edited', acc_ff)
     column = Gtk.TreeViewColumn(_i("keyboard|Key"), renderer, text=1)
     self.g_treeview.append_column(column)
     page_vbox.pack_start(self.g_treeview, True, True, 0)
     layouts = {'ascii': (_('ASCII'), u'awsedfujikol'),
                'dvorak': (_('Dvorak'), u'a,o.eughctrn'),
     }
     hbox = Gtk.HBox()
     page_vbox.pack_start(hbox, False, False, 0)
     
     def set_buttons(widget, layout):
         v = layouts[layout][1]
         idx = 0
         it = self.g_idtone_accels.get_iter_first()
         while True:
             self.g_idtone_accels.set_value(it, 1, v[idx])
             cfg.set_string('idtone/tone_%s_ak' % notenames[idx], v[idx])
             it = self.g_idtone_accels.iter_next(it)
             idx += 1
             if not it:
                 break
     for key in layouts:
         btn = Gtk.Button(layouts[key][0])
         btn.connect('clicked', set_buttons, key)
         hbox.pack_start(btn, True, True, 0)
Example #14
0
                def do_convert(from_format, to_format):
                    """
                    Return False if we think the convert failed.
                    """
                    app_cfg_name = "app/%s_to_%s_cmd" % (from_format, to_format)
                    if from_format == 'midi':
                        from_ext = 'mid'
                    else:
                        from_ext = from_format
                    to_ext = to_format
                    if not cfg.get_string(app_cfg_name):
                        solfege.win.display_error_message2("Config variable not defined", "The missing or empty variable was '%s'" % app_cfg_name)
                        return False
                    try:
                        inout = {
                            'in': os.path.join(export_dir,
                                    "%s.%s" % (trackname % track_idx, from_ext)),
                            'out': os.path.join(export_dir,
                                    "%s.%s" % (trackname % track_idx, to_ext))}
                        opts = cfg.get_string(app_cfg_name + '_options').split(" ")
                        opts = [x % inout for x in opts]
                        # For some reasong setting the executable arg does
                        # not work for Python 2.5.2
                        try:
                            subprocess.call(
                                [cfg.get_string(app_cfg_name)] + opts)
                        except OSError as e:
                            raise osutils.BinaryForMediaConvertorException(app_cfg_name,
                                cfg.get_string(app_cfg_name), e)

                        if os.path.exists(os.path.join(export_dir, "%s.%s" % (trackname % track_idx, to_ext))):
                            os.remove(os.path.join(export_dir, "%s.%s" % (trackname % track_idx, from_ext)))
                        else:
                            # This means that the program failed to generate
                            # the WAV file. We set output_format to 'midi'
                            # because we don't want to display this error for
                            # every single file.
                            output_format = 'midi'
                            solfege.win.display_error_message2("External program must have failed", "The file in %(from)s format was not generated from the %(to)s file as expected. Please check your setup in the preferences window (CTRL-F12)." % {'to': to_format.upper(), 'from': from_format.upper()})
                    except (TypeError, KeyError):
                        solfege.win.display_error_message2("%(from)s to %(to)s config error", "There was a format string error. Will not generate WAV files. Please check the app/midi_to_wav_cmd config variable." % {'from': from_format, 'to': to_format})
                        output_format = 'midi'
                    return True
Example #15
0
    def create_gui_config(self):
        i_iter, page_vbox = self.new_page_box(None, _("Interface"))

        self.g_mainwin_user_resizeable = gu.nCheckButton('gui',
          'mainwin_user_resizeable', _("_Resizeable main window"))
        page_vbox.pack_start(self.g_mainwin_user_resizeable, False, False, 0)

        # Combobox to select language
        hbox = Gtk.HBox()
        hbox.set_spacing(6)
        label = Gtk.Label()
        label.set_text_with_mnemonic(_("Select _language:"))
        hbox.pack_start(label, False, False, 0)
        self.g_language = Gtk.ComboBoxText()
        for n in languages.languages:
            self.g_language.append_text(n)
        label.set_mnemonic_widget(self.g_language)
        if sys.platform == 'win32':
            lang = winlang.win32_get_langenviron()
            if lang in languages.languages:
                idx = languages.languages.index(lang)
            elif lang == 'C':
                idx = languages.C_locale_idx
            else:
                idx = 0
        else:
            lang = cfg.get_string('app/lc_messages')
            if lang in languages.languages:
                idx = languages.languages.index(lang)
            elif lang == 'C':
                idx = languages.C_locale_idx
            else:
                idx = 0
        self.g_language.set_active(idx)

        def f(combobox):
            if combobox.get_active() == languages.C_locale_idx:
                lang = "C"
            else:
                lang = languages.languages[combobox.get_active()]
            cfg.set_string('app/lc_messages', lang)
            if sys.platform == 'win32':
                if combobox.get_active():
                    winlang.win32_put_langenviron(lang)
                else:
                    winlang.win32_put_langenviron(None)
        self.g_language.connect_after('changed', f)
        hbox.pack_start(self.g_language, False, False, 0)
        page_vbox.pack_start(hbox, False, False, 0)
        l = Gtk.Label(label=_("You have to restart the program for the language change to take effect."))
        l.set_alignment(0.0, 0.5)
        page_vbox.pack_start(l, False, False, 0)

        self.create_idtone_accels_config(i_iter)
        self.create_interval_accels_config(i_iter)
Example #16
0
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()
Example #17
0
def sComboBox(exname, name, strings):
    liststore = Gtk.ListStore(str)
    for s in strings:
        liststore.append([s])
    g = Gtk.ComboBox.new_with_model_and_entry(liststore)
    g.set_entry_text_column(0)
    g.get_child().set_text(cfg.get_string("%s/%s" % (exname, name)))
    g.connect('changed', lambda w:
            cfg.set_string("%s/%s" % (exname, name),
                           w.get_child().get_text()))
    return g
Example #18
0
def sComboBox(exname, name, strings):
    liststore = Gtk.ListStore(str)
    for s in strings:
        liststore.append([s])
    g = Gtk.ComboBox.new_with_model_and_entry(liststore)
    g.set_entry_text_column(0)
    g.get_child().set_text(cfg.get_string("%s/%s" % (exname, name)))
    g.connect('changed', lambda w:
            cfg.set_string("%s/%s" % (exname, name),
                           w.get_child().get_text().decode("utf-8")))
    return g
Example #19
0
 def run_startup_profile_manager(self):
     """
     Select a user profile to use. Return its name.
     Quit program if user selects that.
     """
     p = ProfileManager(self, cfg.get_string("app/last_profile"))
     ret = p.run()
     if ret == Gtk.ResponseType.ACCEPT:
         profile = p.get_profile()
         cfg.set_string("app/last_profile", "" if not profile else profile)
         p.destroy()
         return profile
     else:
         self.quit_program()
Example #20
0
 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
Example #21
0
 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
Example #22
0
 def run_startup_profile_manager(self):
     """
     Select a user profile to use. Return its name.
     Quit program if user selects that.
     """
     p = ProfileManager(self, cfg.get_string("app/last_profile"))
     ret = p.run()
     if ret == Gtk.ResponseType.ACCEPT:
         profile = p.get_profile()
         cfg.set_string("app/last_profile", "" if not profile else profile)
         p.destroy()
         return profile
     else:
         self.quit_program()
Example #23
0
def play_mediafile(typeid, filename):
    global _mediaplayer
    if sys.platform == 'win32' and typeid == 'wav':
        winsound.PlaySound(filename,
                           winsound.SND_FILENAME | winsound.SND_ASYNC)
    else:
        args = [cfg.get_string("sound/%s_player" % typeid)]
        # We only add %s_player_options if is is a non empty string,
        # since args should not contain any empty strings.
        if cfg.get_string("sound/%s_player_options" % typeid):
            args.extend(
                cfg.get_string("sound/%s_player_options" % typeid).split(" "))
        found = False
        for i, s in enumerate(args):
            if '%s' in s:
                args[i] = args[i] % os.path.abspath(filename)
                found = True
                break
        # Remove left over %s, just in case the user entered more than
        # one in the preferences window.
        args = [x for x in args if x != '%s']
        if not found:
            args.append(os.path.abspath(filename))
        if _mediaplayer and _mediaplayer.poll() == None:
            _mediaplayer.kill()
            _mediaplaer = None
        try:
            if sys.platform == 'win32':
                info = subprocess.STARTUPINFO()
                info.dwFlags = 1
                info.wShowWindow = 0
                _mediaplayer = osutils.Popen(args=args, startupinfo=info)
            else:
                _mediaplayer = osutils.Popen(args=args)
        except OSError, e:
            raise osutils.BinaryForMediaPlayerException(
                typeid, cfg.get_string("sound/%s_player" % typeid), e)
Example #24
0
def presetup(app_defaults_filename, system_filename, user_filename):
    if not os.path.exists(filesystem.app_data()):
        os.makedirs(filesystem.app_data())
    if not os.path.exists(filesystem.user_data()):
        os.makedirs(filesystem.user_data())
    try:
        cfg.initialise(app_defaults_filename, system_filename, user_filename)
    except UnicodeDecodeError:
        traceback.print_exc()
        print(file=sys.stderr)
        print("\n".join(
            textwrap.wrap(
                "Your %s file is not properly utf8 encoded. Most likely"
                " it is the path to some external program that contain non-ascii"
                " characters. Please edit or delete the file. Or email it to"
                " [email protected], and he will tell you what the problem is." %
                filesystem.rcfile().encode("ascii", "backslashreplace"))),
              file=sys.stderr)
        print(file=sys.stderr)
        sys.exit("I give up (solfege.py)")
    except cfg.CfgParseException as e:
        i18n.setup(".")
        a, b = os.path.split(user_filename)
        renamed_fn = os.path.join(a, "BAD-" + b)
        m = Gtk.MessageDialog(None, Gtk.DialogFlags.MODAL,
                              Gtk.MessageType.ERROR, Gtk.ButtonsType.NONE,
                              _("Parsing %s failed") % filesystem.rcfile())
        m.format_secondary_text(
            str(e) + "\n\n" +
            _("We cannot recover from this, we can rename the corrupt file to %s and then start the program."
              % renamed_fn))
        m.add_buttons("Rename", 10)
        m.add_buttons(Gtk.STOCK_QUIT, 11)
        m.set_default_response(11)
        ret = m.run()
        if ret == 10:
            os.rename(user_filename, renamed_fn)
            m.destroy()
            cfg.initialise(app_defaults_filename, system_filename,
                           user_filename)
        else:
            sys.exit(1)
    # MIGRATION from 2.9.2 to 2.9.3
    if cfg.get_string("app/lc_messages") == 'C (english)':
        cfg.set_string("app/lc_messages", "C")
Example #25
0
 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
Example #26
0
 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
Example #27
0
def presetup(app_defaults_filename, system_filename, user_filename):
    if not os.path.exists(filesystem.app_data()):
        os.makedirs(filesystem.app_data())
    if not os.path.exists(filesystem.user_data()):
        os.makedirs(filesystem.user_data())
    try:
        cfg.initialise(app_defaults_filename, system_filename, user_filename)
    except UnicodeDecodeError:
        traceback.print_exc()
        print(file=sys.stderr)
        print("\n".join(textwrap.wrap(
              "Your %s file is not properly utf8 encoded. Most likely"
              " it is the path to some external program that contain non-ascii"
              " characters. Please edit or delete the file. Or email it to"
              " [email protected], and he will tell you what the problem is." % filesystem.rcfile().encode("ascii", "backslashreplace"))), file=sys.stderr)
        print(file=sys.stderr)
        sys.exit("I give up (solfege.py)")
    except cfg.CfgParseException as e:
        i18n.setup(".")
        a, b = os.path.split(user_filename)
        renamed_fn = os.path.join(a, "BAD-" + b)
        m = Gtk.MessageDialog(None, Gtk.DialogFlags.MODAL, Gtk.MessageType.ERROR,
                Gtk.ButtonsType.NONE,
                _("Parsing %s failed") % filesystem.rcfile())
        m.format_secondary_text(str(e) + "\n\n" + _("We cannot recover from this, we can rename the corrupt file to %s and then start the program." % renamed_fn))
        m.add_buttons("Rename", 10)
        m.add_buttons(Gtk.STOCK_QUIT, 11)
        m.set_default_response(11)
        ret = m.run()
        if ret == 10:
            os.rename(user_filename, renamed_fn)
            m.destroy()
            cfg.initialise(app_defaults_filename, system_filename, user_filename)
        else:
            sys.exit(1)
    # MIGRATION from 2.9.2 to 2.9.3
    if cfg.get_string("app/lc_messages") == 'C (english)':
        cfg.set_string("app/lc_messages", "C")
Example #28
0
                def do_convert(from_format, to_format):
                    """
                    Return False if we think the convert failed.
                    """
                    app_cfg_name = "app/%s_to_%s_cmd" % (from_format,
                                                         to_format)
                    if from_format == 'midi':
                        from_ext = 'mid'
                    else:
                        from_ext = from_format
                    to_ext = to_format
                    if not cfg.get_string(app_cfg_name):
                        solfege.win.display_error_message2(
                            "Config variable not defined",
                            "The missing or empty variable was '%s'" %
                            app_cfg_name)
                        return False
                    try:
                        inout = {
                            'in':
                            os.path.join(
                                export_dir,
                                "%s.%s" % (trackname % track_idx, from_ext)),
                            'out':
                            os.path.join(
                                export_dir,
                                "%s.%s" % (trackname % track_idx, to_ext))
                        }
                        opts = cfg.get_string(app_cfg_name +
                                              '_options').split(" ")
                        opts = [x % inout for x in opts]
                        # For some reasong setting the executable arg does
                        # not work for Python 2.5.2
                        try:
                            subprocess.call([cfg.get_string(app_cfg_name)] +
                                            opts)
                        except OSError, e:
                            raise osutils.BinaryForMediaConvertorException(
                                app_cfg_name, cfg.get_string(app_cfg_name), e)

                        if os.path.exists(
                                os.path.join(
                                    export_dir, "%s.%s" %
                                    (trackname % track_idx, to_ext))):
                            os.remove(
                                os.path.join(
                                    export_dir, "%s.%s" %
                                    (trackname % track_idx, from_ext)))
                        else:
                            # This means that the program failed to generate
                            # the WAV file. We set output_format to 'midi'
                            # because we don't want to display this error for
                            # every single file.
                            output_format = 'midi'
                            solfege.win.display_error_message2(
                                "External program must have failed",
                                "The file in %(from)s format was not generated from the %(to)s file as expected. Please check your setup in the preferences window (CTRL-F12)."
                                % {
                                    'to': to_format.upper(),
                                    'from': from_format.upper()
                                })
Example #29
0
    def create_idtone_accels_config(self, parent):
        it, page_vbox = self.new_page_box(
            parent, _("Identify tone keyboard accelerators"))
        self.g_idtone_accels = Gtk.ListStore(GObject.TYPE_STRING,
                                             GObject.TYPE_STRING)
        notenames = ('c', 'cis', 'd', 'dis', 'e', 'f', 'fis', 'g', 'gis', 'a',
                     'ais', 'b')
        for notename in notenames:
            self.g_idtone_accels.append(
                (solfege.mpd.MusicalPitch.new_from_notename(
                    notename).get_user_notename(),
                 cfg.get_string('idtone/tone_%s_ak' % notename)))
        self.g_treeview = Gtk.TreeView(self.g_idtone_accels)
        renderer = Gtk.CellRendererText()
        column = Gtk.TreeViewColumn(_("Note name"), renderer, text=0)
        self.g_treeview.append_column(column)
        renderer = Gtk.CellRendererAccel()
        renderer.set_property('editable', True)

        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

        renderer.connect('accel-edited', acc_ff)
        column = Gtk.TreeViewColumn(_i("keyboard|Key"), renderer, text=1)
        self.g_treeview.append_column(column)
        page_vbox.pack_start(self.g_treeview, True, True, 0)
        layouts = {
            'ascii': (_('ASCII'), u'awsedfujikol'),
            'dvorak': (_('Dvorak'), u'a,o.eughctrn'),
        }
        hbox = Gtk.HBox()
        page_vbox.pack_start(hbox, False, False, 0)

        def set_buttons(widget, layout):
            v = layouts[layout][1]
            idx = 0
            it = self.g_idtone_accels.get_iter_first()
            while True:
                self.g_idtone_accels.set_value(it, 1, v[idx])
                cfg.set_string('idtone/tone_%s_ak' % notenames[idx], v[idx])
                it = self.g_idtone_accels.iter_next(it)
                idx += 1
                if not it:
                    break

        for key in layouts:
            btn = Gtk.Button(layouts[key][0])
            btn.connect('clicked', set_buttons, key)
            hbox.pack_start(btn, True, True, 0)
Example #30
0
 def test_set_str(self):
     cfg.set_string("abc/def", "str string")
     cfg.set_string("abc/ghi", "unicode string ØÆÅ")
     self.assertTrue(isinstance(cfg.get_string("abc/def"), str))
     self.assertTrue(isinstance(cfg.get_string("abc/ghi"), str))
Example #31
0
class SolfegeApp(cfg.ConfigUtils):
    def __init__(self, options):
        """
        options -- command line options parsed by optparse
        """
        cfg.ConfigUtils.__init__(self, 'solfege-app')
        lessonfile.MusicBaseClass.temp_dir = tempfile.mkdtemp(
            prefix="solfege-")
        os.environ['SOLFEGETEMPDIR'] = lessonfile.MusicBaseClass.temp_dir
        # test_mode is when we are running a test from the Tests menu
        self.m_test_mode = False
        self.m_options = options
        self.m_teachers = {}
        self.m_running_exercise = None
        self.m_sound_init_exception = None
        #
        self.m_userman_language = "C"
        for lang in i18n.langs():
            if os.path.isdir(os.path.join('help', lang)):
                self.m_userman_language = lang
                break

    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()
        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, e:
                self.display_sound_init_error_message(e)
                cfg.set_string("sound/type", "fake-synth")
                soundcard.initialise_using_fake_synth(True)
                return
Example #32
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", "")
Example #33
0
              " it is the path to some external program that contain non-ascii"
              " characters. Please edit or delete the file. Or email it to"
              " [email protected], and he will tell you what the problem is." % filesystem.rcfile().encode("ascii", "backslashreplace")))
        print >> sys.stderr
        sys.exit("I give up (solfege.py)")
    except cfg.CfgParseException, e:
        i18n.setup(".")
        a, b = os.path.split(user_filename)
        renamed_fn = os.path.join(a, "BAD-"+b)
        m = Gtk.MessageDialog(None, Gtk.DialogFlags.MODAL, Gtk.MessageType.ERROR,
                Gtk.ButtonsType.NONE,
                _("Parsing %s failed") % filesystem.rcfile())
        m.format_secondary_text(str(e) + "\n\n" + _("We cannot recover from this, we can rename the corrupt file to %s and then start the program." % renamed_fn))
        m.add_buttons("Rename", 10)
        m.add_buttons(Gtk.STOCK_QUIT, 11)
        m.set_default_response(11)
        ret = m.run()

        if ret == 10:
            os.rename(user_filename, renamed_fn)
            m.destroy()
            cfg.initialise(app_defaults_filename, system_filename, user_filename)

        else:
            sys.exit(1)
    # MIGRATION from 2.9.2 to 2.9.3

    if cfg.get_string("app/lc_messages") == 'C (english)':
        cfg.set_string("app/lc_messages", "C")

Example #34
0
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)
Example #35
0
    def create_interval_accels_config(self, parent):
        it, page_vbox = self.new_page_box(parent,
                                          _("Interval keyboard accelerators"))
        self.g_interval_accels = Gtk.ListStore(GObject.TYPE_STRING,
                                               GObject.TYPE_STRING)
        intervals = [
            'minor2', 'major2', 'minor3', 'major3', 'perfect4', 'diminished5',
            'perfect5', 'minor6', 'major6', 'minor7', 'major7', 'perfect8',
            'minor9', 'major9', 'minor10', 'major10'
        ]
        for interval in intervals:
            self.g_interval_accels.append(
                (mpd.Interval.new_from_int(
                    intervals.index(interval)).get_name(),
                 cfg.get_string('interval_input/%s' % interval)))
        self.g_intervals_treeview = Gtk.TreeView(self.g_interval_accels)
        renderer = Gtk.CellRendererText()
        column = Gtk.TreeViewColumn(_("Interval"), renderer, text=0)
        self.g_intervals_treeview.append_column(column)
        renderer = Gtk.CellRendererAccel()
        renderer.set_property('editable', 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

        renderer.connect('accel-edited', acc_ff)
        column = Gtk.TreeViewColumn(_i("keyboard|Key"), renderer, text=1)
        self.g_intervals_treeview.append_column(column)
        page_vbox.pack_start(self.g_intervals_treeview, True, True, 0)
        hbox = Gtk.HBox()
        page_vbox.pack_start(hbox, False, False, 0)
        layouts = {
            'ascii': (_('ASCII'), u'1qaz2wsx3edc4rfv'),
            'dvorak': (_('Dvorak'), u"1'a;2,oq3.ej4puk"),
        }

        def set_buttons(widget, layout):
            v = layouts[layout][1]
            idx = 0
            it = self.g_interval_accels.get_iter_first()
            while True:
                self.g_interval_accels.set_value(it, 1, v[idx])
                cfg.set_string('interval_input/%s' % intervals[idx], v[idx])
                it = self.g_interval_accels.iter_next(it)
                idx += 1
                if not it:
                    break

        for key in layouts:
            btn = Gtk.Button(layouts[key][0])
            btn.connect('clicked', set_buttons, key)
            hbox.pack_start(btn, True, True, 0)
Example #36
0
    def _write(self, k, directory, filename, logger):
        assert k in ('question', 'answer')
        f = open(os.path.join(directory, filename), 'w')
        print >> f, r"\documentclass{article}"
        print >> f, "%%\n%% Created by GNU Solfege %s\n%%" % buildinfo.VERSION_STRING
        print >> f, r"\title{%s}" % _tr(self.m_title)
        print >> f, r"\usepackage[margin=1.0cm]{geometry}"
        print >> f, r"\begin{document}"
        print >> f, r"\maketitle"

        def finish_table(scores, answers):
            for idx, score in enumerate(scores):
                print >> f, score
                if idx != len(scores) - 1:
                    print >> f, "&"
            print >> f, r"\\"
            for idx, answer in enumerate(answers):
                print >> f, answer

                if idx != len(scores) - 1:
                    print >> f, "&"
            print >> f, r"\\"
        for section in self.m_data:
            print >> f, r"\section{%s}" % _tr(section.m_title)
            first_row = True
            for idx, question_dict in enumerate(section):

                if idx % section.m_line_len == 0:

                    if first_row:
                        print >> f, r"\begin{tabular}{%s}" % ('c' * section.m_line_len)
                        first_row = False

                    else:
                        finish_table(scores, answers)
                    scores = []
                    answers = []

                if r"\score" in question_dict[k]['music']:
                    scores.append("\n".join((r"\begin{lilypond}",
                                question_dict[k]['music'], r"\end{lilypond}")))

                else:
                    scores.append("\n".join((r"\begin[fragment]{lilypond}",
                                question_dict[k]['music'], r"\end{lilypond}")))
                answers.append(question_dict[k]['name'].replace("#", r"\#"))
            finish_table(scores, answers)
            print >> f, r"\end{tabular}"
        print >> f, r"\end{document}"
        f.close()
        # Duplicate of the code in HtmlSheetWriter._write
        args = [cfg.get_string("programs/lilypond-book"),
                "--out", self.lilyout, filename]

        if sys.platform == 'win32':

            if not os.path.exists(cfg.get_string("programs/lilypond-book")):
                # We to the strerror trick to get the translation for free.
                raise osutils.BinaryForProgramException("lilypond-book",
                    cfg.get_string("programs/lilypond-book"),
                    OSError(2, os.strerror(2)))
            args.insert(0, sys.executable)
        logger.write("\nRunning LilyPond\n", "h1")
        try:
            p = osutils.Popen(args, cwd=directory, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
            while 1:
                p.poll()
                # returncode != None means that the process has finished

                if p.returncode != None:
                    break
                while 1:
                    s = p.stdout.readline()

                    if not s:
                        break
                    logger.write(s)
                time.sleep(1)
            p.wait()
        except OSError, e:
            raise osutils.BinaryForProgramException("lilypond-book",
                cfg.get_string("programs/lilypond-book"), e)
Example #37
0
    def _write(self, k, directory, filename, logger):
        assert k in ('question', 'answer')
        f = codecs.open(os.path.join(directory, filename), 'w', 'utf-8')
        print >> f, "<html>"
        print >> f, "<!--\n    Generated by GNU Solfege %s\n-->" % buildinfo.VERSION_STRING
        print >> f, "<link rel='stylesheet' href='style.css' type='text/css'/>"
        print >> f, '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">'
        print >> f, "<body>"
        print >> f, "<h1>%s</h1>" % _tr(self.m_title)
        for section in self.m_data:
            print >> f, "<h2>%s</h2>" % _tr(section.m_title)
            print >> f, "<table>"
            first_row = True
            for idx, question_dict in enumerate(section):
                if idx % section.m_line_len == 0:

                    if not first_row:
                        print >> f, "</tr>"
                        first_row = False
                    print >> f, "<tr>"
                print >> f, "<td class='lilycode'>"
                # each question is in a table too
                print >> f, "<table><tr><td>"

                if r"\score" in question_dict[k]['music']:
                    print >> f, "<lilypond>"

                else:
                    print >> f, "<lilypond fragment relative>"
                print >> f, question_dict[k]['music']
                print >> f, "</lilypond>"
                print >> f, "</td></tr><tr><td class='answer'>"
                print >> f, question_dict[k]['name']
                print >> f, "</td></tr></table>"
                print >> f, "</td>"
            print >> f, "</table>"
        print >> f, "</body>"
        f.close()
        args = [cfg.get_string("programs/lilypond-book"),
                "--out", self.lilyout, filename]
        # The lilypond-book.py script is not an executable on MS Windows,
        # so the user have to set the full path to the python script in the
        # preferences window. Then use the same Python interpreter as
        # Solfege itself to run lilypond-book.py

        if sys.platform == 'win32':

            if not os.path.exists(cfg.get_string("programs/lilypond-book")):
                # We to the strerror trick to get the translation for free.
                raise osutils.BinaryForProgramException("lilypond-book",
                    cfg.get_string("programs/lilypond-book"),
                    OSError(2, os.strerror(2)))
            args.insert(0, sys.executable)
        logger.write("\nRunning LilyPond\n", "h1")
        try:
            p = osutils.Popen(args, cwd=directory, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
            while 1:
                p.poll()
                # returncode != None means that the process has finished

                if p.returncode != None:
                    break
                while 1:
                    s = p.stdout.readline()

                    if not s:
                        break
                    logger.write(s)
                time.sleep(1)
            p.wait()
        except OSError, e:
            raise osutils.BinaryForProgramException("lilypond-book",
                cfg.get_string("programs/lilypond-book"), e)
Example #38
0
 def binary_changed_cb(widget, binary):
     widget.warning.props.visible = not bool(
         osutils.find_progs(
             (cfg.get_string('programs/%s' % binary), )))
Example #39
0
def check_rcfile():
    """See default.config for rcfileversion values, meanings and
    a description of how to add config variables.
    """
    rcfileversion = 21
    if cfg.get_int("app/rcfileversion") > rcfileversion:
        cfg.drop_user_config()
        return
    if cfg.get_int("app/rcfileversion") <= 1:
        if not "example-files" in cfg.get_string('config/lessoncollections'):
            cfg.set_string(
                'config/lessoncollections', "%s example-files" %
                cfg.get_string('config/lessoncollections'))
    if cfg.get_int("app/rcfileversion") <= 5:
        # This is more complicated that necessary to fix an old
        # error.
        if cfg.get_string("sound/commandline"):
            cfg.del_key("sound/commandline")
    if cfg.get_int("app/rcfileversion") <= 3:
        cfg.set_list("config/lessoncollections",
                     cfg.get_string("config/lessoncollections").split())
    if cfg.get_int("app/rcfileversion") <= 4:
        cfg.del_key("config/web_browser")
    if sys.platform == 'win32':
        if cfg.get_string('sound/wav_player'):
            cfg.del_key('sound/wav_player')
    if cfg.get_int("app/rcfileversion") <= 5:
        cfg.set_string("mainwin/history_back_ak", "<alt>Left")
        cfg.set_string("mainwin/history_forward_ak", "<alt>Right")
        cfg.set_string("mainwin/history_reload_ak", "<ctrl>r")
    if cfg.get_int("app/rcfileversion") <= 6:
        cfg.set_list("config/lessoncollections", ['solfege', 'user'])
    if cfg.get_int("app/rcfileversion") <= 7:
        cfg.set_int("rhythm/countin_perc", 80)
    if cfg.get_int("app/rcfileversion") <= 8:
        cfg.del_key("singinterval/highest_tone")
        cfg.del_key("singinterval/lowest_tone")
        cfg.del_key("melodicinterval/highest_tone")
        cfg.del_key("melodicinterval/lowest_tone")
        cfg.del_key("harmonicinterval/highest_tone")
        cfg.del_key("harmonicinterval/lowest_tone")
    if cfg.get_int("app/rcfileversion") <= 9:
        cfg.del_section("mainwin")
    if cfg.get_int("app/rcfileversion") <= 10:
        cfg.del_section("lessoncollections")
        cfg.del_key("config/lessoncollections")
        for n in cfg.iterate_sections():
            cfg.del_key("%s/lessoncollection" % n)
            cfg.del_key("%s/lessonfile" % n)
    if cfg.get_int("app/rcfileversion") <= 11:
        for s in ('rhythm', 'rhythmtapping2'):
            cfg.del_key("%s/countin_perc" % s)
            cfg.del_key("%s/rhythm_perc" % s)
    if cfg.get_int("app/rcfileversion") <= 12:
        cfg.del_key("sound/card_info")
    if cfg.get_int("app/rcfileversion") <= 13:
        cfg.del_key("config/lowest_instrument_velocity")
        cfg.del_key("config/middle_instrument_velocity")
        cfg.del_key("config/highest_instrument_velocity")
        cfg.del_key("config/preferred_instrument_velocity")
    if cfg.get_int("app/rcfileversion") <= 14:
        # We have to split the midi_to_wav_cmd into two strings, and
        # moving the options to *_options, so that midi_to_wav_cmd only
        # have the name of the binary. This to allow binaries in dirs
        # with spaces.
        for k in ("midi_to_wav", "wav_to_mp3", "wav_to_ogg"):
            v = cfg.get_string("app/%s_cmd" % k).split(" ")
            cfg.set_string("app/%s_cmd" % k, v[0])
            cfg.set_string("app/%s_cmd_options" % k, " ".join(v[1:]))
    if cfg.get_int("app/rcfileversion") <= 15:
        for k in ("midi", "wav", "mp3", "ogg"):
            v = cfg.get_string("sound/%s_player" % k).split(" ")
            cfg.set_string("sound/%s_player" % k, v[0])
            cfg.set_string("sound/%s_player_options" % k, " ".join(v[1:]))
    if cfg.get_int("app/rcfileversion") < 17:
        v = cfg.get_string("app/frontpage").split("/")
        if v[0] == u"exercises" and v[1] != u"standard":
            cfg.set_string("app/frontpage",
                           u"/".join([v[0], u"standard"] + v[1:]))
    if cfg.get_int("app/rcfileversion") < 18:
        cfg.del_key("gui/web_browser_as_help_browser")
    if cfg.get_int("app/rcfileversion") < 19:
        for ex in ('singinterval', 'melodicinterval'):
            if cfg.get_int("%s/maximum_number_of_intervals" % ex) == 10:
                cfg.set_int("%s/maximum_number_of_intervals" % ex, 12)
    if cfg.get_int("app/rcfileversion") < 20:
        cfg.del_key("gui/reserved_vspace")
    if cfg.get_int("app/rcfileversion") < 21:
        for ex in ("melodicinterval", "harmonicinterval"):
            i = cfg.get_int("%s/inputwidget" % ex)
            if i > 0:
                cfg.set_int("%s/inputwidget" % ex, i + 1)

    cfg.set_int("app/rcfileversion", rcfileversion)
    try:
        a = mpd.notename_to_int(cfg.get_string("user/lowest_pitch"))
        b = mpd.notename_to_int(cfg.get_string("user/highest_pitch"))
    except mpd.InvalidNotenameException:
        if cfg.get_string("user/sex") == "male":
            cfg.set_string("user/highest_pitch", "e'")
            cfg.set_string("user/lowest_pitch", "c")
        else:
            cfg.set_string("user/highest_pitch", "e''")
            cfg.set_string("user/lowest_pitch", "c'")
Example #40
0
         # __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), e:
         self.m_sound_init_exception = e
Example #41
0
    def _write(self, k, directory, filename, logger):
        assert k in ('question', 'answer')
        f = open(os.path.join(directory, filename), 'w')
        print(r"\documentclass{article}", file=f)
        print("%%\n%% Created by GNU Solfege %s\n%%" %
              buildinfo.VERSION_STRING,
              file=f)
        print(r"\title{%s}" % _tr(self.m_title), file=f)
        print(r"\usepackage[margin=1.0cm]{geometry}", file=f)
        print(r"\begin{document}", file=f)
        print(r"\maketitle", file=f)

        def finish_table(scores, answers):
            for idx, score in enumerate(scores):
                print(score, file=f)
                if idx != len(scores) - 1:
                    print("&", file=f)
            print(r"\\", file=f)
            for idx, answer in enumerate(answers):
                print(answer, file=f)
                if idx != len(scores) - 1:
                    print("&", file=f)
            print(r"\\", file=f)

        for section in self.m_data:
            print(r"\section{%s}" % _tr(section.m_title), file=f)
            first_row = True
            for idx, question_dict in enumerate(section):
                if idx % section.m_line_len == 0:
                    if first_row:
                        print(r"\begin{tabular}{%s}" %
                              ('c' * section.m_line_len),
                              file=f)
                        first_row = False
                    else:
                        finish_table(scores, answers)
                    scores = []
                    answers = []
                if r"\score" in question_dict[k]['music']:
                    scores.append("\n".join(
                        (r"\begin{lilypond}", question_dict[k]['music'],
                         r"\end{lilypond}")))
                else:
                    scores.append("\n".join(
                        (r"\begin[fragment]{lilypond}",
                         question_dict[k]['music'], r"\end{lilypond}")))
                answers.append(question_dict[k]['name'].replace("#", r"\#"))
            finish_table(scores, answers)
            print(r"\end{tabular}", file=f)
        print(r"\end{document}", file=f)
        f.close()
        # Duplicate of the code in HtmlSheetWriter._write
        args = [
            cfg.get_string("programs/lilypond-book"), "--out", self.lilyout,
            filename
        ]
        if sys.platform == 'win32':
            if not os.path.exists(cfg.get_string("programs/lilypond-book")):
                # We to the strerror trick to get the translation for free.
                raise osutils.BinaryForProgramException(
                    "lilypond-book", cfg.get_string("programs/lilypond-book"),
                    OSError(2, os.strerror(2)))
            args.insert(0, sys.executable)
        logger.write("\nRunning LilyPond\n", "h1")
        try:
            p = subprocess.Popen(args,
                                 cwd=directory,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.STDOUT)
            while 1:
                p.poll()
                # returncode is not None means that the process has finished
                if p.returncode is not None:
                    break
                while 1:
                    s = p.stdout.readline()
                    s = s.decode(locale.getpreferredencoding())
                    if not s:
                        break
                    logger.write(s)
                time.sleep(1)
            p.wait()
        except OSError as e:
            raise osutils.BinaryForProgramException(
                "lilypond-book", cfg.get_string("programs/lilypond-book"), e)
        logger.write("\nRunning LaTeX\n", "h1")
        try:
            p = subprocess.Popen((cfg.get_string("programs/latex"),
                                  "--interaction=nonstopmode", filename),
                                 cwd=os.path.join(directory, self.lilyout),
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.STDOUT)
            while 1:
                p.poll()
                # returncode is not None means that the process has finished
                if p.returncode is not None:
                    break
                while 1:
                    while Gtk.events_pending():
                        Gtk.main_iteration()
                    s = p.stdout.readline()
                    s = s.decode(locale.getpreferredencoding())
                    if not s:
                        break
                    logger.write(s)
                time.sleep(1)
        except OSError as e:
            raise osutils.BinaryForProgramException(
                "latex", cfg.get_string("programs/latex"), e)
        f = open(os.path.join(directory, 'README.txt'), 'w')
        print("\n".join(
            textwrap.wrap(
                "The files you are looking for are lilyout%(sep)sanswers.dvi and lilyout%(sep)squestions.dvi"
                % {'sep': os.path.sep})),
              file=f)
        f.close()
Example #42
0
    def add_gui_for_external_programs(self, page_vbox):
        box, category_vbox = gu.hig_category_vbox(_("Audio File Players"))
        page_vbox.pack_start(box, False)
        format_info = {}
        if sys.platform != 'win32':
            format_info = {'wav': {
                 # testfile is a file in lesson-files/share
                 'testfile': 'fifth-small-220.00.wav',
                 'label': _("WAV:"),
                 # players is a list of tuples. The tuple has to or more
                 # items. The first is the binary, and the rest is possible
                 # sets of command line options that might work.
                 # '/path/to/player', 'comandline', '
                 'players': [
                        ('gst-launch', 'playbin uri=file://%s',
                                       'filesrc location=%s ! wavparse ! alsasink'),
                        ('play', ''),
                        ('aplay', ''),
                        ('esdplay', ''),
                 ],
                }
            }
        format_info['midi'] = {
             'testfile': 'fanfare.midi',
             'label': _("MIDI:"),
             'players': [
                         ('gst-launch', 'playbin uri=file://%s',
                                        'filesrc location=exercises/standard/lesson-files/share/fanfare.midi ! wildmidi ! alsasink'),
                         ('timidity', '-idqq %s'),
                         ('drvmidi', ''),
                         ('playmidi', ''),
             ],
            }
        format_info['mp3'] = {
             'testfile': 'fanfare.mp3',
             'label': _("MP3:"),
             'players': [
                        ('gst-launch', 'playbin uri=file://%s',
                                       'filesrc location=%s ! mad ! alsasink'),
                        ('mpg123', ''),
                        ('alsaplayer', ''),
             ],
            }
        format_info['ogg'] = {
             'testfile': 'fanfare.ogg',
             'label': _("OGG:"),
             'players': [
                        ('gst-launch', 'playbin uri=file://%s',
                                       'filesrc location=%s ! oggdemux ! vorbisdec ! audioconvert ! alsasink'),
                        ('ogg123', ''),
                        ('alsaplayer', ''),
             ],
            }
        sizegroup = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL)
        for formatid, format in format_info.items():
            cmd_liststore = gtk.ListStore(gobject.TYPE_STRING)
            for player_data in format['players']:
                cmd_liststore.append((player_data[0],))
            cmd_combo = gtk.ComboBoxEntry(cmd_liststore)
            cmd_combo.set_tooltip_text(_("Enter the name of the program. An absolute path is required only if the executable is not found on the PATH."))
            cmd_combo.opts = gtk.combo_box_entry_new_text()
            cmd_combo.opts.set_tooltip_text(_("The command line options required. Write %s where you want the name of the file to be played. Or omit it to have it added to the end of the string."))
            cmd_combo.child.set_text(cfg.get_string('sound/%s_player' % formatid))
            cmd_combo.opts.child.set_text(cfg.get_string('sound/%s_player_options' % formatid))
            for s in format['players']:
                if s[0] == cmd_combo.child.get_text():
                    for o in s[1:]:
                        cmd_combo.opts.append_text(o)

            def _changed(widget, formatid):
                if widget.get_active() != -1:
                    widget.opts.get_model().clear()
                    format = format_info[formatid]
                    for player_options in format['players'][widget.get_active()][1:]:
                        widget.opts.append_text(player_options)
                    widget.opts.child.set_text(format['players'][widget.get_active()][1])
                self.set_string('sound/%s_player' % formatid,
                                widget.child.get_text())
                widget.testbutton.set_sensitive(bool(
                    osutils.find_progs((widget.child.get_text(),))))

            def _opts_changed(widget, formatid):
                self.set_string('sound/%s_player_options' % formatid,
                                widget.child.get_text())
            cmd_combo.connect('changed', _changed, formatid)
            cmd_combo.opts.connect('changed', _opts_changed, formatid)
            testbutton = gtk.Button(_("_Test").replace("_", ""))
            testbutton.set_tooltip_text(_("This button is clickable only if the binary is found."))
            cmd_combo.testbutton = testbutton
            testbutton.connect('clicked', self.test_XXX_player,
                           formatid, format['testfile'])
            testbutton.set_sensitive(bool(
                    osutils.find_progs((cmd_combo.child.get_text(),))))
            box = gu.hig_label_widget(format['label'],
                                      [cmd_combo, cmd_combo.opts, testbutton],
                                      sizegroup, True, True)
            category_vbox.pack_start(box)
Example #43
0
 def _write(self, k, directory, filename, logger):
     assert k in ('question', 'answer')
     f = codecs.open(os.path.join(directory, filename), 'w', 'utf-8')
     print("<html>", file=f)
     print("<!--\n    Generated by GNU Solfege %s\n-->" %
           buildinfo.VERSION_STRING,
           file=f)
     print("<link rel='stylesheet' href='style.css' type='text/css'/>",
           file=f)
     print(
         '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">',
         file=f)
     print("<body>", file=f)
     print("<h1>%s</h1>" % _tr(self.m_title), file=f)
     for section in self.m_data:
         print("<h2>%s</h2>" % _tr(section.m_title), file=f)
         print("<table>", file=f)
         first_row = True
         for idx, question_dict in enumerate(section):
             if idx % section.m_line_len == 0:
                 if not first_row:
                     print("</tr>", file=f)
                     first_row = False
                 print("<tr>", file=f)
             print("<td class='lilycode'>", file=f)
             # each question is in a table too
             print("<table><tr><td>", file=f)
             if r"\score" in question_dict[k]['music']:
                 print("<lilypond>", file=f)
             else:
                 print("<lilypond fragment relative>", file=f)
             print(question_dict[k]['music'], file=f)
             print("</lilypond>", file=f)
             print("</td></tr><tr><td class='answer'>", file=f)
             print(question_dict[k]['name'], file=f)
             print("</td></tr></table>", file=f)
             print("</td>", file=f)
         print("</table>", file=f)
     print("</body>", file=f)
     f.close()
     args = [
         cfg.get_string("programs/lilypond-book"), "--out", self.lilyout,
         filename
     ]
     # The lilypond-book.py script is not an executable on MS Windows,
     # so the user have to set the full path to the python script in the
     # preferences window. Then use the same Python interpreter as
     # Solfege itself to run lilypond-book.py
     if sys.platform == 'win32':
         if not os.path.exists(cfg.get_string("programs/lilypond-book")):
             # We to the strerror trick to get the translation for free.
             raise osutils.BinaryForProgramException(
                 "lilypond-book", cfg.get_string("programs/lilypond-book"),
                 OSError(2, os.strerror(2)))
         args.insert(0, sys.executable)
     logger.write("\nRunning LilyPond\n", "h1")
     try:
         p = subprocess.Popen(args,
                              cwd=directory,
                              stdout=subprocess.PIPE,
                              stderr=subprocess.STDOUT)
         while 1:
             p.poll()
             # returncode is not None means that the process has finished
             if p.returncode is not None:
                 break
             while 1:
                 s = p.stdout.readline()
                 s = s.decode(locale.getpreferredencoding())
                 if not s:
                     break
                 logger.write(s)
             time.sleep(1)
         p.wait()
     except OSError as e:
         raise osutils.BinaryForProgramException(
             "lilypond-book", cfg.get_string("programs/lilypond-book"), e)
     f = open(os.path.join(directory, 'README.txt'), 'w')
     print("\n".join(
         textwrap.wrap(
             "The files answers.html and questions.html in this directory are temporaty files. The HTML files you are looking for are lilyout%(sep)sanswers.html and lilyout%(sep)squestions.html"
             % {'sep': os.path.sep})),
           file=f)
     f.close()
Example #44
0
 def csound_changed_cb(widget, bin):
     self.set_string('programs/%s' % bin, widget.child.get_text())
     widget.warning.props.visible = not bool(
         osutils.find_progs((cfg.get_string('programs/%s' % bin),)))
Example #45
0
    def _write(self, k, directory, filename, logger):
        assert k in ('question', 'answer')
        f = open(os.path.join(directory, filename), 'w')
        print >> f, r"\documentclass{article}"
        print >> f, "%%\n%% Created by GNU Solfege %s\n%%" % buildinfo.VERSION_STRING
        print >> f, r"\title{%s}" % _tr(self.m_title)
        print >> f, r"\usepackage[margin=1.0cm]{geometry}"
        print >> f, r"\begin{document}"
        print >> f, r"\maketitle"

        def finish_table(scores, answers):
            for idx, score in enumerate(scores):
                print >> f, score
                if idx != len(scores) - 1:
                    print >> f, "&"
            print >> f, r"\\"
            for idx, answer in enumerate(answers):
                print >> f, answer
                if idx != len(scores) - 1:
                    print >> f, "&"
            print >> f, r"\\"

        for section in self.m_data:
            print >> f, r"\section{%s}" % _tr(section.m_title)
            first_row = True
            for idx, question_dict in enumerate(section):
                if idx % section.m_line_len == 0:
                    if first_row:
                        print >> f, r"\begin{tabular}{%s}" % (
                            'c' * section.m_line_len)
                        first_row = False
                    else:
                        finish_table(scores, answers)
                    scores = []
                    answers = []
                if r"\score" in question_dict[k]['music']:
                    scores.append("\n".join(
                        (r"\begin{lilypond}", question_dict[k]['music'],
                         r"\end{lilypond}")))
                else:
                    scores.append("\n".join(
                        (r"\begin[fragment]{lilypond}",
                         question_dict[k]['music'], r"\end{lilypond}")))
                answers.append(question_dict[k]['name'].replace("#", r"\#"))
            finish_table(scores, answers)
            print >> f, r"\end{tabular}"
        print >> f, r"\end{document}"
        f.close()
        # Duplicate of the code in HtmlSheetWriter._write
        args = [
            cfg.get_string("programs/lilypond-book"), "--out", self.lilyout,
            filename
        ]
        if sys.platform == 'win32':
            if not os.path.exists(cfg.get_string("programs/lilypond-book")):
                # We to the strerror trick to get the translation for free.
                raise osutils.BinaryForProgramException(
                    "lilypond-book", cfg.get_string("programs/lilypond-book"),
                    OSError(2, os.strerror(2)))
            args.insert(0, sys.executable)
        logger.write("\nRunning LilyPond\n", "h1")
        try:
            p = osutils.Popen(args,
                              cwd=directory,
                              stdout=subprocess.PIPE,
                              stderr=subprocess.STDOUT)
            while 1:
                p.poll()
                # returncode != None means that the process has finished
                if p.returncode != None:
                    break
                while 1:
                    s = p.stdout.readline()
                    if not s:
                        break
                    logger.write(s)
                time.sleep(1)
            p.wait()
        except OSError, e:
            raise osutils.BinaryForProgramException(
                "lilypond-book", cfg.get_string("programs/lilypond-book"), e)
Example #46
0
         self.display_sound_init_error_message(e)
         cfg.set_string("sound/type", "fake-synth")
         soundcard.initialise_using_fake_synth(True)
         return
     except RuntimeError, 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), e:
         self.m_sound_init_exception = e
Example #47
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", "")
Example #48
0
if not os.path.exists(filesystem.app_data()):
    os.makedirs(filesystem.app_data())
if not os.path.exists(filesystem.user_data()):
    os.makedirs(filesystem.user_data())

try:
    cfg.initialise("default.config", None, filesystem.rcfile())
except UnicodeDecodeError, e:
    traceback.print_exc()
    print >> sys.stderr
    print >> sys.stderr, "\n".join(textwrap.wrap(
          "Your %s file is not properly utf8 encoded. Most likely"
          " it is the path to some external program that contain non-ascii"
          " characters. Please edit or delete the file. Or email it to"
          " [email protected], and he will tell you what the problem is." % filesystem.rcfile().encode("ascii", "backslashreplace")))
    print >> sys.stderr
    sys.exit("I give up (solfege.py)")


# i18n should be imported very early in program init because it setup
# the _ and _i functions for the whole program.
import solfege.i18n
# MIGRATION from 2.9.2 to 2.9.3
if cfg.get_string("app/lc_messages") == 'C (english)':
    cfg.set_string("app/lc_messages", "C")
solfege.i18n.setup(".", cfg.get_string("app/lc_messages"))

import solfege.startup

solfege.startup.start_app(".")
Example #49
0
def check_rcfile():
    """See default.config for rcfileversion values, meanings and
    a description of how to add config variables.
    """
    rcfileversion = 21
    if cfg.get_int("app/rcfileversion") > rcfileversion:
        cfg.drop_user_config()
        return
    if cfg.get_int("app/rcfileversion") <= 1:
        if not "example-files" in cfg.get_string('config/lessoncollections'):
            cfg.set_string('config/lessoncollections',
                "%s example-files" % cfg.get_string('config/lessoncollections'))
    if cfg.get_int("app/rcfileversion") <= 5:
        # This is more complicated that necessary to fix an old
        # error.
        if cfg.get_string("sound/commandline"):
            cfg.del_key("sound/commandline")
    if cfg.get_int("app/rcfileversion") <= 3:
        cfg.set_list("config/lessoncollections",
            cfg.get_string("config/lessoncollections").split())
    if cfg.get_int("app/rcfileversion") <= 4:
        cfg.del_key("config/web_browser")
    if sys.platform == 'win32':
        if cfg.get_string('sound/wav_player'):
            cfg.del_key('sound/wav_player')
    if cfg.get_int("app/rcfileversion") <= 5:
        cfg.set_string("mainwin/history_back_ak", "<alt>Left")
        cfg.set_string("mainwin/history_forward_ak", "<alt>Right")
        cfg.set_string("mainwin/history_reload_ak", "<ctrl>r")
    if cfg.get_int("app/rcfileversion") <= 6:
        cfg.set_list("config/lessoncollections", ['solfege', 'user'])
    if cfg.get_int("app/rcfileversion") <= 7:
        cfg.set_int("rhythm/countin_perc", 80)
    if cfg.get_int("app/rcfileversion") <= 8:
        cfg.del_key("singinterval/highest_tone")
        cfg.del_key("singinterval/lowest_tone")
        cfg.del_key("melodicinterval/highest_tone")
        cfg.del_key("melodicinterval/lowest_tone")
        cfg.del_key("harmonicinterval/highest_tone")
        cfg.del_key("harmonicinterval/lowest_tone")
    if cfg.get_int("app/rcfileversion") <= 9:
        cfg.del_section("mainwin")
    if cfg.get_int("app/rcfileversion") <= 10:
        cfg.del_section("lessoncollections")
        cfg.del_key("config/lessoncollections")
        for n in cfg.iterate_sections():
            cfg.del_key("%s/lessoncollection" % n)
            cfg.del_key("%s/lessonfile" % n)
    if cfg.get_int("app/rcfileversion") <= 11:
        for s in ('rhythm', 'rhythmtapping2'):
            cfg.del_key("%s/countin_perc" % s)
            cfg.del_key("%s/rhythm_perc" % s)
    if cfg.get_int("app/rcfileversion") <= 12:
        cfg.del_key("sound/card_info")
    if cfg.get_int("app/rcfileversion") <= 13:
        cfg.del_key("config/lowest_instrument_velocity")
        cfg.del_key("config/middle_instrument_velocity")
        cfg.del_key("config/highest_instrument_velocity")
        cfg.del_key("config/preferred_instrument_velocity")
    if cfg.get_int("app/rcfileversion") <= 14:
        # We have to split the midi_to_wav_cmd into two strings, and
        # moving the options to *_options, so that midi_to_wav_cmd only
        # have the name of the binary. This to allow binaries in dirs
        # with spaces.
        for k in ("midi_to_wav", "wav_to_mp3", "wav_to_ogg"):
            v = cfg.get_string("app/%s_cmd" % k).split(" ")
            cfg.set_string("app/%s_cmd" % k, v[0])
            cfg.set_string("app/%s_cmd_options" % k, " ".join(v[1:]))
    if cfg.get_int("app/rcfileversion") <= 15:
        for k in ("midi", "wav", "mp3", "ogg"):
            v = cfg.get_string("sound/%s_player" % k).split(" ")
            cfg.set_string("sound/%s_player" % k, v[0])
            cfg.set_string("sound/%s_player_options" % k,
                " ".join(v[1:]))
    if cfg.get_int("app/rcfileversion") < 17:
        v = cfg.get_string("app/frontpage").split("/")
        if v[0] == "exercises" and v[1] != "standard":
            cfg.set_string("app/frontpage",
                           "/".join([v[0], "standard"] + v[1:]))
    if cfg.get_int("app/rcfileversion") < 18:
        cfg.del_key("gui/web_browser_as_help_browser")
    if cfg.get_int("app/rcfileversion") < 19:
        for ex in ('singinterval', 'melodicinterval'):
            if cfg.get_int("%s/maximum_number_of_intervals" % ex) == 10:
                cfg.set_int("%s/maximum_number_of_intervals" % ex, 12)
    if cfg.get_int("app/rcfileversion") < 20:
        cfg.del_key("gui/reserved_vspace")
    if cfg.get_int("app/rcfileversion") < 21:
        for ex in ("melodicinterval", "harmonicinterval"):
            i = cfg.get_int("%s/inputwidget" % ex)
            if i > 0:
                cfg.set_int("%s/inputwidget" % ex, i + 1)

    cfg.set_int("app/rcfileversion", rcfileversion)
    try:
        a = mpd.notename_to_int(cfg.get_string("user/lowest_pitch"))
        b = mpd.notename_to_int(cfg.get_string("user/highest_pitch"))
    except mpd.InvalidNotenameException:
        if cfg.get_string("user/sex") == "male":
            cfg.set_string("user/highest_pitch", "e'")
            cfg.set_string("user/lowest_pitch", "c")
        else:
            cfg.set_string("user/highest_pitch", "e''")
            cfg.set_string("user/lowest_pitch", "c'")
Example #50
0
 def binary_changed_cb(widget, binary):
     widget.warning.props.visible = not bool(
         osutils.find_progs((cfg.get_string('programs/%s' % binary),)))
Example #51
0
                " characters. Please edit or delete the file. Or email it to"
                " [email protected], and he will tell you what the problem is." %
                filesystem.rcfile().encode("ascii", "backslashreplace")))
        print >> sys.stderr
        sys.exit("I give up (solfege.py)")
    except cfg.CfgParseException, e:
        i18n.setup(".")
        a, b = os.path.split(user_filename)
        renamed_fn = os.path.join(a, "BAD-" + b)
        m = Gtk.MessageDialog(None, Gtk.DialogFlags.MODAL,
                              Gtk.MessageType.ERROR, Gtk.ButtonsType.NONE,
                              _("Parsing %s failed") % filesystem.rcfile())
        m.format_secondary_text(
            str(e) + "\n\n" +
            _("We cannot recover from this, we can rename the corrupt file to %s and then start the program."
              % renamed_fn))
        m.add_buttons("Rename", 10)
        m.add_buttons(Gtk.STOCK_QUIT, 11)
        m.set_default_response(11)
        ret = m.run()
        if ret == 10:
            os.rename(user_filename, renamed_fn)
            m.destroy()
            cfg.initialise(app_defaults_filename, system_filename,
                           user_filename)
        else:
            sys.exit(1)
    # MIGRATION from 2.9.2 to 2.9.3
    if cfg.get_string("app/lc_messages") == 'C (english)':
        cfg.set_string("app/lc_messages", "C")
Example #52
0
 def test_set_str(self):
     cfg.set_string("abc/def", "str string")
     cfg.set_string("abc/ghi", u"unicode string ØÆÅ")
     self.assert_(isinstance(cfg.get_string("abc/def"), unicode))
     self.assert_(isinstance(cfg.get_string("abc/ghi"), unicode))
Example #53
0
if sys.platform == 'win32':
    # Migration added in solfege 3.9.0.
    try:
        if not os.path.exists(filesystem.app_data()):
            if os.path.exists(
                    os.path.join(filesystem.get_home_dir(), ".solfege")):
                shutil.copytree(
                    os.path.join(filesystem.get_home_dir(), ".solfege"),
                    filesystem.app_data())
            else:
                os.mkdir(filesystem.app_data())
        if not os.path.exists(filesystem.rcfile()):
            if os.path.exists(
                    os.path.join(filesystem.get_home_dir(), ".solfegerc")):
                shutil.copy(
                    os.path.join(filesystem.get_home_dir(), ".solfegerc"),
                    filesystem.rcfile())
    except (IOError, os.error) as e:
        print("Migration failed:", e)

from solfege import presetup
presetup.presetup("default.config", None, filesystem.rcfile())

# i18n should be imported very early in program init because it setup
# the _ and _i functions for the whole program.

from solfege import i18n
i18n.setup(".", cfg.get_string("app/lc_messages"))
import solfege.startup
solfege.startup.start_app(".")
Example #54
0
from solfege import cfg
from solfege import filesystem

if sys.platform == 'win32':
    # Migration added in solfege 3.9.0.
    try:
        if not os.path.exists(filesystem.app_data()):
            if os.path.exists(os.path.join(filesystem.get_home_dir(), ".solfege")):
                shutil.copytree(os.path.join(filesystem.get_home_dir(), ".solfege"),
                                filesystem.app_data())
            else:
                os.mkdir(filesystem.app_data())
        if not os.path.exists(filesystem.rcfile()):
            if os.path.exists(os.path.join(filesystem.get_home_dir(), ".solfegerc")):
                shutil.copy(os.path.join(filesystem.get_home_dir(), ".solfegerc"),
                            filesystem.rcfile())
    except (IOError, os.error) as e:
        print("Migration failed:", e)

from solfege import presetup
presetup.presetup("default.config", None, filesystem.rcfile())

# i18n should be imported very early in program init because it setup
# the _ and _i functions for the whole program.

from solfege import i18n
i18n.setup(".", cfg.get_string("app/lc_messages"))
import solfege.startup
solfege.startup.start_app(".")