diff --git a/changelog.md b/changelog.md index 46824ef..9bd1983 100644 --- a/changelog.md +++ b/changelog.md @@ -4,6 +4,7 @@ * Improvements in the audio player module: * When modifying volume of the playing audio, it will decrease or increase the volume by 2% instead of 5%. + * For users with multiple soundcards, there is a new tab in the preferences dialogue of Socializer, called sound. From there, you can define what soundcard will be used for input and output. ## Changes in version 0.19 (13.03.2019) diff --git a/src/interactors/configuration.py b/src/interactors/configuration.py index ab64287..339af31 100644 --- a/src/interactors/configuration.py +++ b/src/interactors/configuration.py @@ -7,8 +7,8 @@ from . import base class configurationInteractor(base.baseInteractor): - def create_tab(self, tab): - getattr(self.view, "create_"+tab)() + def create_tab(self, tab, arglist=dict()): + getattr(self.view, "create_"+tab)(**arglist) def set_setting(self, tab, setting, value): self.view.set_value(tab, setting, value) @@ -60,5 +60,8 @@ class configurationInteractor(base.baseInteractor): self.presenter.update_setting(section="load_at_startup", setting="audio_albums", value=self.view.get_value("startup", "audio_albums")) self.presenter.update_setting(section="load_at_startup", setting="video_albums", value=self.view.get_value("startup", "video_albums")) self.presenter.update_setting(section="load_at_startup", setting="communities", value=self.view.get_value("startup", "communities")) + self.presenter.update_app_setting(section="sound", setting="input_device", value=self.view.get_value("sound", "input")) + self.presenter.update_app_setting(section="sound", setting="output_device", value=self.view.get_value("sound", "output")) + self.presenter.update_app_setting(section="app-settings", setting="use_proxy", value=self.view.get_value("general", "use_proxy")) + self.presenter.save_app_settings_file() self.presenter.save_settings_file() - self.presenter.update_proxy(self.view.get_value("general", "use_proxy")) \ No newline at end of file diff --git a/src/presenters/configuration.py b/src/presenters/configuration.py index f57aeec..3979225 100644 --- a/src/presenters/configuration.py +++ b/src/presenters/configuration.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals +import sound_lib.input, sound_lib.output import config from mysc import restart from . import base @@ -9,6 +10,8 @@ class configurationPresenter(base.basePresenter): def __init__(self, session, view, interactor): self.session = session super(configurationPresenter, self).__init__(view=view, interactor=interactor, modulename="configuration") + # Control requirement for a restart of the application. + self.needs_restart = False self.create_config() self.run() @@ -57,6 +60,11 @@ class configurationPresenter(base.basePresenter): self.send_message("set", tab="startup", setting="audio_albums", value=self.session.settings["load_at_startup"]["audio_albums"]) self.send_message("set", tab="startup", setting="video_albums", value=self.session.settings["load_at_startup"]["video_albums"]) self.send_message("set", tab="startup", setting="communities", value=self.session.settings["load_at_startup"]["communities"]) + self.input_devices = sound_lib.input.Input.get_device_names() + self.output_devices = sound_lib.output.Output.get_device_names() + self.send_message("create_tab", tab="sound", arglist=dict(input_devices=self.input_devices, output_devices=self.output_devices, soundpacks=[])) + self.send_message("set", tab="sound", setting="input", value=config.app["sound"]["input_device"]) + self.send_message("set", tab="sound", setting="output", value=config.app["sound"]["output_device"]) def update_setting(self, section, setting, value): if section not in self.session.settings: @@ -68,10 +76,21 @@ class configurationPresenter(base.basePresenter): def save_settings_file(self): self.session.settings.write() - def update_proxy(self, proxy_value): - if proxy_value != config.app["app-settings"]["use_proxy"]: - config.app["app-settings"]["use_proxy"] = proxy_value - config.app.write() + def update_app_setting(self, section, setting, value): + if section not in config.app: + raise AttributeError("The configuration section is not present in the spec file.") + if setting not in config.app[section]: + raise AttributeError("The setting you specified is not present in the config file.") + # check if certain settings have been changed so we'd restart the client. + # List of app settings that require a restart after being changed. + settings_needing_restart = ["use_proxy", "input_device", "output_device"] + if value != config.app[section][setting] and setting in settings_needing_restart: + self.needs_restart = True + config.app[section][setting] = value + + def save_app_settings_file(self): + config.app.write() + if self.needs_restart: self.send_message("restart_program") def restart_application(self): diff --git a/src/views/dialogs/configuration.py b/src/views/dialogs/configuration.py index 35a09d1..2996410 100644 --- a/src/views/dialogs/configuration.py +++ b/src/views/dialogs/configuration.py @@ -65,6 +65,48 @@ class loadAtStartup(wx.Panel, widgetUtils.BaseDialog): sizer.Add(self.communities, 0, wx.ALL, 5) self.SetSizer(sizer) +class sound(wx.Panel, widgetUtils.BaseDialog): + def __init__(self, panel, input_devices, output_devices, soundpacks): + super(sound, self).__init__(panel) + sizer = wx.BoxSizer(wx.VERTICAL) + output_label = wx.StaticText(self, wx.NewId(), _("Output device")) + self.output = wx.ComboBox(self, wx.NewId(), choices=output_devices, style=wx.CB_READONLY) + self.output.SetSize(self.output.GetBestSize()) + outputBox = wx.BoxSizer(wx.HORIZONTAL) + outputBox.Add(output_label, 0, wx.ALL, 5) + outputBox.Add(self.output, 0, wx.ALL, 5) + sizer.Add(outputBox, 0, wx.ALL, 5) + input_label = wx.StaticText(self, wx.NewId(), _("Input device")) + self.input = wx.ComboBox(self, wx.NewId(), choices=input_devices, style=wx.CB_READONLY) + self.input.SetSize(self.input.GetBestSize()) + inputBox = wx.BoxSizer(wx.HORIZONTAL) + inputBox.Add(input_label, 0, wx.ALL, 5) + inputBox.Add(self.input, 0, wx.ALL, 5) + sizer.Add(inputBox, 0, wx.ALL, 5) +# soundBox = wx.BoxSizer(wx.VERTICAL) +# soundpack_label = wx.StaticText(self, wx.NewId(), _(u"Sound pack")) +# self.soundpack = wx.ComboBox(self, -1, choices=soundpacks, style=wx.CB_READONLY) +# self.soundpack.SetSize(self.soundpack.GetBestSize()) +# soundBox.Add(soundpack_label, 0, wx.ALL, 5) +# soundBox.Add(self.soundpack, 0, wx.ALL, 5) +# sizer.Add(soundBox, 0, wx.ALL, 5) + self.SetSizer(sizer) + + def on_keypress(self, event, *args, **kwargs): + """ Invert movement of up and down arrow keys when dealing with a wX Slider. + See https://github.com/manuelcortez/TWBlue/issues/261 + and http://trac.wxwidgets.org/ticket/2068 + """ + keycode = event.GetKeyCode() + if keycode == wx.WXK_UP: + return self.volumeCtrl.SetValue(self.volumeCtrl.GetValue()+1) + elif keycode == wx.WXK_DOWN: + return self.volumeCtrl.SetValue(self.volumeCtrl.GetValue()-1) + event.Skip() + + def get(self, control): + return getattr(self, control).GetStringSelection() + class configurationDialog(widgetUtils.BaseDialog): def __init__(self, title): @@ -86,6 +128,10 @@ class configurationDialog(widgetUtils.BaseDialog): self.startup = loadAtStartup(self.notebook) self.notebook.AddPage(self.startup, _("Optional buffers")) + def create_sound(self, input_devices, output_devices, soundpacks): + self.sound = sound(self.notebook, input_devices, output_devices, soundpacks) + self.notebook.AddPage(self.sound, _("Sound settings")) + def realize(self): self.sizer.Add(self.notebook, 0, wx.ALL, 5) ok_cancel_box = wx.BoxSizer(wx.HORIZONTAL)