/// QasTools: Desktop toolset for the Linux sound system ALSA.
/// \copyright See COPYING file.

#include "settings_dialog.hpp"
#include "desktop_items_setup.hpp"
#include "qastools_config.hpp"
#include "wdg/scroll_area_vertical.hpp"
#include <QCheckBox>
#include <QGroupBox>
#include <QHBoxLayout>
#include <QPushButton>
#include <QSplitter>
#include <QStandardItemModel>
#include <QVBoxLayout>
#include <iostream>

namespace Views
{

Settings_Dialog::Settings_Dialog ( QWidget * parent_n, Qt::WindowFlags flags_n )
: Views::Multi_Page_Dialog ( parent_n, flags_n )
{
  {
    QString title_str ( tr ( "Settings" ) );
    setWindowTitle (
        QString ( "%1 - %2" ).arg ( PROGRAM_TITLE ).arg ( title_str ) );
    set_title_str ( title_str );
  }

  _vspace = qMax ( 0, fontMetrics ().height () * 2 / 3 );

  add_pages_begin ();
  init_page_startup ();
  init_page_appearance ();
  init_page_input ();
  init_page_sys_tray ();
  add_pages_end ();

  // Update states
  update_inputs_vis_state ();
}

Settings_Dialog::~Settings_Dialog () = default;

void
Settings_Dialog::init_page_startup ()
{
  QGroupBox * box_device ( new QGroupBox );
  box_device->setTitle ( tr ( "Startup mixer device" ) );
  {
    QVBoxLayout * lay_dev_sel ( new QVBoxLayout );

    _start_btn_device[ 0 ] = new QRadioButton ( tr ( "Default" ) );
    _start_btn_device[ 1 ] = new QRadioButton ( tr ( "From last session" ) );
    _start_btn_device[ 2 ] = new QRadioButton ( tr ( "User defined" ) );

    _start_btn_grp_device = new QButtonGroup ( this );
    _start_btn_grp_device->addButton ( _start_btn_device[ 0 ], 0 );
    _start_btn_grp_device->addButton ( _start_btn_device[ 1 ], 1 );
    _start_btn_grp_device->addButton ( _start_btn_device[ 2 ], 2 );

    _start_dev_user = new QWidget;
    _start_dev_user_edit = new QLineEdit;
    QLabel * lbl_user ( new QLabel ( tr ( "User device:" ) ) );
    QLabel * lbl_example ( new QLabel ( tr ( "e.g. hw:0" ) ) );

    connect ( _start_btn_grp_device,
              SIGNAL ( buttonClicked ( QAbstractButton * ) ),
              this,
              SLOT ( change_startup () ) );

    connect ( _start_dev_user_edit,
              SIGNAL ( editingFinished () ),
              this,
              SLOT ( change_startup () ) );

    QHBoxLayout * lay_dev_user ( new QHBoxLayout );
    lay_dev_user->setContentsMargins ( 0, 0, 0, 0 );
    lay_dev_user->addWidget ( lbl_user );
    lay_dev_user->addWidget ( _start_dev_user_edit );
    lay_dev_user->addWidget ( lbl_example );
    lay_dev_user->addStretch ( 1 );
    _start_dev_user->setLayout ( lay_dev_user );

    lay_dev_sel->addWidget ( _start_btn_device[ 0 ] );
    lay_dev_sel->addWidget ( _start_btn_device[ 1 ] );
    lay_dev_sel->addWidget ( _start_btn_device[ 2 ] );
    lay_dev_sel->addWidget ( _start_dev_user );
    lay_dev_sel->addStretch ( 1 );

    box_device->setLayout ( lay_dev_sel );
  }

  // Container widget
  QWidget * wdg_all ( new QWidget );
  {
    QVBoxLayout * lay_wdg ( new QVBoxLayout );
    lay_wdg->setContentsMargins ( 0, 0, 0, 0 );
    lay_wdg->addWidget ( box_device );
    lay_wdg->addStretch ( 1 );
    wdg_all->setLayout ( lay_wdg );
  }

  _page_startup = wdg_all;
  add_page_vscroll ( tr ( "Startup" ), _page_startup );
}

void
Settings_Dialog::init_page_appearance ()
{
  QGroupBox * box_sliders ( new QGroupBox );
  box_sliders->setTitle ( tr ( "Sliders" ) );
  {
    _btn_show_sliders_labels =
        new QCheckBox ( tr ( "Show slider value labels" ) );
    connect ( _btn_show_sliders_labels,
              SIGNAL ( toggled ( bool ) ),
              this,
              SLOT ( change_appearance () ) );

    QVBoxLayout * lay_sliders ( new QVBoxLayout );
    lay_sliders->addWidget ( _btn_show_sliders_labels );
    box_sliders->setLayout ( lay_sliders );
  }

  QGroupBox * box_controls ( new QGroupBox );
  box_controls->setTitle ( tr ( "Controls" ) );
  {
    _btn_show_tool_tips = new QCheckBox ( tr ( "Show tooltips" ) );
    connect ( _btn_show_tool_tips,
              SIGNAL ( toggled ( bool ) ),
              this,
              SLOT ( change_appearance () ) );

    QVBoxLayout * lay_controls ( new QVBoxLayout );
    lay_controls->addWidget ( _btn_show_tool_tips );
    box_controls->setLayout ( lay_controls );
  }

  // Container widget
  QWidget * wdg_all ( new QWidget );
  {
    QVBoxLayout * lay_wdg ( new QVBoxLayout );
    lay_wdg->setContentsMargins ( 0, 0, 0, 0 );
    lay_wdg->addWidget ( box_sliders );
    lay_wdg->addSpacing ( _vspace );
    lay_wdg->addWidget ( box_controls );
    lay_wdg->addStretch ( 1 );
    wdg_all->setLayout ( lay_wdg );
  }

  _page_appearance = wdg_all;
  add_page_vscroll ( tr ( "Appearance" ), _page_appearance );
}

void
Settings_Dialog::init_page_input ()
{
  QGroupBox * box_mwheel ( new QGroupBox );
  box_mwheel->setTitle ( tr ( "Mouse wheel" ) );
  {
    QLabel * lbl_info ( new QLabel (
        tr ( "Number of turns for a slider change from 0% to 100%" ) ) );

    const unsigned int range[ 2 ] = { 1, 150 };

    _mwheel_turns_input = new QDoubleSpinBox;
    _mwheel_turns_input->setRange ( range[ 0 ] / 10.0, range[ 1 ] / 10.0 );
    _mwheel_turns_input->setSingleStep ( 0.1 );
    _mwheel_turns_input->setDecimals ( 1 );

    _mwheel_turns_slider = new QSlider ( Qt::Horizontal );
    _mwheel_turns_slider->setRange ( range[ 0 ], range[ 1 ] );
    _mwheel_turns_slider->setSingleStep ( 1 );
    _mwheel_turns_slider->setPageStep ( 10 );

    connect ( _mwheel_turns_slider,
              &QSlider::valueChanged,
              this,
              &Settings_Dialog::wheel_turns_slider_changed );

    connect ( _mwheel_turns_input,
              &QDoubleSpinBox::valueChanged,
              this,
              &Settings_Dialog::wheel_turns_input_changed );

    connect ( _mwheel_turns_input,
              &QDoubleSpinBox::valueChanged,
              this,
              &Settings_Dialog::change_input );

    // Layout
    QHBoxLayout * lay_input ( new QHBoxLayout );
    lay_input->setContentsMargins ( 0, 0, 0, 0 );
    lay_input->addWidget ( _mwheel_turns_input );
    lay_input->addWidget ( _mwheel_turns_slider );

    QVBoxLayout * lay_mwheel ( new QVBoxLayout );
    lay_mwheel->addWidget ( lbl_info );
    lay_mwheel->addLayout ( lay_input );
    box_mwheel->setLayout ( lay_mwheel );
  }

  // Container widget
  QWidget * wdg_all ( new QWidget );
  {
    QVBoxLayout * lay_wdg ( new QVBoxLayout );
    lay_wdg->setContentsMargins ( 0, 0, 0, 0 );
    lay_wdg->addWidget ( box_mwheel );
    lay_wdg->addStretch ( 1 );
    wdg_all->setLayout ( lay_wdg );
  }

  _page_input = wdg_all;
  add_page_vscroll ( tr ( "Input" ), _page_input );
}

void
Settings_Dialog::init_page_sys_tray ()
{
  _tray_btn_show_icon = new QCheckBox ( tr ( "Show tray icon" ) );
  _tray_btn_on_close = new QCheckBox ( tr ( "Close to tray" ) );
  _tray_btn_show_volume_icon = new QCheckBox ( tr ( "Show volume icon" ) );

  connect ( _tray_btn_show_icon,
            SIGNAL ( toggled ( bool ) ),
            this,
            SLOT ( change_tray_visibility () ) );

  connect ( _tray_btn_on_close,
            SIGNAL ( toggled ( bool ) ),
            this,
            SLOT ( change_tray_visibility () ) );

  connect ( _tray_btn_show_volume_icon,
            SIGNAL ( toggled ( bool ) ),
            this,
            SLOT ( change_tray_icon () ) );

  QGroupBox * box_icon ( new QGroupBox );
  box_icon->setTitle ( tr ( "System tray usage" ) );
  {
    QVBoxLayout * lay_gbox ( new QVBoxLayout );
    lay_gbox->addWidget ( _tray_btn_show_icon );
    lay_gbox->addWidget ( _tray_btn_show_volume_icon );
    lay_gbox->addWidget ( _tray_btn_on_close );
    box_icon->setLayout ( lay_gbox );
  }

  QGroupBox * box_balloon ( new QGroupBox );
  box_balloon->setTitle ( tr ( "Notification balloon" ) );
  {
    _tray_btn_balloon_show = new QCheckBox;
    _tray_btn_balloon_show->setText (
        tr ( "Show balloon on a volume change" ) );

    connect ( _tray_btn_balloon_show,
              SIGNAL ( toggled ( bool ) ),
              this,
              SLOT ( change_tray_balloon () ) );

    QVBoxLayout * lay_balloon_time ( new QVBoxLayout );
    lay_balloon_time->setContentsMargins ( 0, 0, 0, 0 );
    {
      QString str_lt ( tr ( "Balloon lifetime" ) );
      QLabel * lbl_lifetime ( new QLabel ( str_lt + ":" ) );
      //: ms - abbreviation for milliseconds
      QLabel * lbl_ms ( new QLabel ( tr ( "ms" ) ) );

      const int range[ 2 ] = { 100, 10000 };

      _tray_balloon_time_input = new QSpinBox;
      _tray_balloon_time_input->setRange ( range[ 0 ], range[ 1 ] );
      _tray_balloon_time_input->setSingleStep ( 100 );
      _tray_balloon_time_input->setToolTip ( str_lt );

      connect ( _tray_balloon_time_input,
                SIGNAL ( valueChanged ( int ) ),
                this,
                SLOT ( change_tray_balloon () ) );

      QHBoxLayout * lay_input ( new QHBoxLayout );
      lay_input->setContentsMargins ( 0, 0, 0, 0 );
      lay_input->addWidget ( lbl_lifetime );
      lay_input->addWidget ( _tray_balloon_time_input );
      lay_input->addWidget ( lbl_ms );
      lay_input->addStretch ( 1 );

      lay_balloon_time->addLayout ( lay_input );
    }
    _tray_balloon_time = new QWidget;
    _tray_balloon_time->setLayout ( lay_balloon_time );

    QVBoxLayout * lay_balloon ( new QVBoxLayout );
    lay_balloon->addWidget ( _tray_btn_balloon_show );
    lay_balloon->addWidget ( _tray_balloon_time );
    box_balloon->setLayout ( lay_balloon );
  }

  QGroupBox * box_device ( new QGroupBox );
  box_device->setTitle ( tr ( "Mini mixer device" ) );
  {
    _tray_btn_device[ 0 ] = new QRadioButton ( tr ( "Default" ) );
    _tray_btn_device[ 1 ] =
        new QRadioButton ( tr ( "Current (same as in main mixer window)" ) );
    _tray_btn_device[ 2 ] = new QRadioButton ( tr ( "User defined" ) );

    _tray_btn_grp_device = new QButtonGroup ( this );
    _tray_btn_grp_device->addButton ( _tray_btn_device[ 0 ], 0 );
    _tray_btn_grp_device->addButton ( _tray_btn_device[ 1 ], 1 );
    _tray_btn_grp_device->addButton ( _tray_btn_device[ 2 ], 2 );

    _tray_dev_user = new QWidget;
    _tray_dev_user_edit = new QLineEdit;
    QLabel * lbl_user ( new QLabel ( tr ( "User device:" ) ) );
    QLabel * lbl_example ( new QLabel ( tr ( "e.g. hw:0" ) ) );

    connect ( _tray_btn_grp_device,
              SIGNAL ( buttonClicked ( QAbstractButton * ) ),
              this,
              SLOT ( change_tray_mixer_dev () ) );

    connect ( _tray_dev_user_edit,
              SIGNAL ( editingFinished () ),
              this,
              SLOT ( change_tray_mixer_dev () ) );

    QHBoxLayout * lay_dev_user ( new QHBoxLayout );
    lay_dev_user->setContentsMargins ( 0, 0, 0, 0 );
    lay_dev_user->addWidget ( lbl_user );
    lay_dev_user->addWidget ( _tray_dev_user_edit );
    lay_dev_user->addWidget ( lbl_example );
    lay_dev_user->addStretch ( 1 );
    _tray_dev_user->setLayout ( lay_dev_user );

    QVBoxLayout * lay_dev_sel ( new QVBoxLayout );
    lay_dev_sel->addWidget ( _tray_btn_device[ 0 ] );
    lay_dev_sel->addWidget ( _tray_btn_device[ 1 ] );
    lay_dev_sel->addWidget ( _tray_btn_device[ 2 ] );
    lay_dev_sel->addWidget ( _tray_dev_user );
    lay_dev_sel->addStretch ( 1 );

    box_device->setLayout ( lay_dev_sel );
  }

  QGroupBox * box_mwheel = new QGroupBox;
  box_mwheel->setTitle ( tr ( "Mouse wheel" ) );
  {
    QLabel * lbl_info ( new QLabel (
        tr ( "Number of turns for a volume change from 0% to 100%" ) ) );

    const unsigned int range[ 2 ] = { 1, 150 };

    _tray_mwheel_turns_input = new QDoubleSpinBox;
    _tray_mwheel_turns_input->setRange ( range[ 0 ] / 10.0, range[ 1 ] / 10.0 );
    _tray_mwheel_turns_input->setSingleStep ( 0.1 );
    _tray_mwheel_turns_input->setDecimals ( 1 );

    _tray_mwheel_turns_slider = new QSlider ( Qt::Horizontal );
    _tray_mwheel_turns_slider->setRange ( range[ 0 ], range[ 1 ] );
    _tray_mwheel_turns_slider->setSingleStep ( 1 );
    _tray_mwheel_turns_slider->setPageStep ( 10 );

    connect ( _tray_mwheel_turns_slider,
              &QSlider::valueChanged,
              this,
              &Settings_Dialog::tray_wheel_turns_slider_changed );

    connect ( _tray_mwheel_turns_input,
              &QDoubleSpinBox::valueChanged,
              this,
              &Settings_Dialog::tray_wheel_turns_input_changed );

    connect ( _tray_mwheel_turns_input,
              &QDoubleSpinBox::valueChanged,
              this,
              &Settings_Dialog::change_tray_input );

    // Layout
    QHBoxLayout * lay_input = new QHBoxLayout;
    lay_input->setContentsMargins ( 0, 0, 0, 0 );
    lay_input->addWidget ( _tray_mwheel_turns_input );
    lay_input->addWidget ( _tray_mwheel_turns_slider );

    QVBoxLayout * lay_mwheel = new QVBoxLayout;
    lay_mwheel->addWidget ( lbl_info );
    lay_mwheel->addLayout ( lay_input );
    box_mwheel->setLayout ( lay_mwheel );
  }

  _tray_wdg_grp_ballon = box_balloon;
  _tray_wdg_grp_device = box_device;

  // Container widget
  QWidget * wdg_all ( new QWidget );
  {
    QVBoxLayout * lay_wdg ( new QVBoxLayout );
    lay_wdg->setContentsMargins ( 0, 0, 0, 0 );
    lay_wdg->addWidget ( box_icon );
    lay_wdg->addSpacing ( _vspace );
    lay_wdg->addWidget ( box_balloon );
    lay_wdg->addSpacing ( _vspace );
    lay_wdg->addWidget ( box_device );
    lay_wdg->addSpacing ( _vspace );
    lay_wdg->addWidget ( box_mwheel );
    lay_wdg->addStretch ( 1 );
    wdg_all->setLayout ( lay_wdg );
  }

  _page_sys_tray = wdg_all;
  add_page_vscroll ( tr ( "System tray" ), _page_sys_tray );
}

void
Settings_Dialog::set_setup ( Desktop_Items_Setup * setup_n )
{
  _dsetup = setup_n;

  if ( _dsetup != nullptr ) {
    restoreGeometry ( _dsetup->settings_dialog.window_geometry () );
    restore_splitter_state ( _dsetup->settings_dialog.splitter_state () );

    update_inputs_values ();

    // Select current page
    if ( _dsetup->settings_dialog.page () >= num_pages () ) {
      _dsetup->settings_dialog.set_page ( 0 );
    }
    set_current_page_idx ( _dsetup->settings_dialog.page () );
  }
}

void
Settings_Dialog::update_inputs_values ()
{
  if ( _dsetup == nullptr ) {
    return;
  }

  _updating_values = true;

  // Startup
  {
    unsigned int idx ( _dsetup->start_device_mode () );
    if ( idx > Desktop_Items_Setup::MIXER_DEV_LAST ) {
      idx = 0;
    }
    _start_btn_device[ idx ]->setChecked ( true );
  }
  _start_dev_user_edit->setText ( _dsetup->start_user_device () );

  // Appearance
  _btn_show_sliders_labels->setChecked (
      _dsetup->main_window.mixer.show_slider_value_labels () );
  _btn_show_tool_tips->setChecked (
      _dsetup->main_window.mixer.show_tool_tips () );

  // Input
  {
    const int value ( _dsetup->main_window.inputs.wheel_degrees () );
    _mwheel_turns_slider->setValue ( value / 36 );
    _mwheel_turns_input->setValue ( value / 360.0 );
  }

  // System tray
  _tray_btn_on_close->setChecked ( _dsetup->tray_on_close () );
  _tray_btn_show_icon->setChecked ( _dsetup->tray_show_icon () );
  _tray_btn_show_volume_icon->setChecked ( _dsetup->tray.show_volume_icon () );

  _tray_btn_balloon_show->setChecked ( _dsetup->tray.balloon_enabled () );
  _tray_balloon_time_input->setValue ( _dsetup->tray.balloon_lifetime () );

  {
    unsigned int idx = _dsetup->tray.device_mode ();
    if ( idx > Tray::Setup::MIXER_DEV_LAST ) {
      idx = 0;
    }
    _tray_btn_device[ idx ]->setChecked ( true );
  }
  _tray_dev_user_edit->setText ( _dsetup->tray.user_device () );

  _tray_mwheel_turns_slider->setValue ( _dsetup->tray.wheel_degrees () / 36 );
  _tray_mwheel_turns_input->setValue ( _dsetup->tray.wheel_degrees () / 360.0 );

  update_inputs_vis_state ();

  _updating_values = false;
}

void
Settings_Dialog::update_inputs_vis_state ()
{
  const bool has_setup ( _dsetup != nullptr );
  _page_startup->setEnabled ( has_setup );
  _page_appearance->setEnabled ( has_setup );
  _page_input->setEnabled ( has_setup );
  _page_sys_tray->setEnabled ( has_setup );

  if ( !has_setup ) {
    return;
  }

  _start_dev_user->setEnabled ( ( _dsetup->start_device_mode () ==
                                  Desktop_Items_Setup::MIXER_DEV_USER ) );

  {
    bool flag ( _dsetup->tray_on_close () || _dsetup->tray_show_icon () );
    _tray_wdg_grp_ballon->setEnabled ( flag );
    _tray_wdg_grp_device->setEnabled ( flag );
  }

  _tray_balloon_time->setEnabled ( _dsetup->tray.balloon_enabled () );

  _tray_dev_user->setEnabled (
      ( _dsetup->tray.device_mode () == Tray::Setup::MIXER_DEV_USER ) );
}

void
Settings_Dialog::wheel_turns_slider_changed ( int value_n )
{
  _mwheel_turns_input->setValue ( value_n / 10.0 );
}

void
Settings_Dialog::wheel_turns_input_changed ( double value_n )
{
  _mwheel_turns_slider->setValue ( value_n * 10.0 );
}

void
Settings_Dialog::tray_wheel_turns_slider_changed ( int value_n )
{
  _tray_mwheel_turns_input->setValue ( value_n / 10.0 );
}

void
Settings_Dialog::tray_wheel_turns_input_changed ( double value_n )
{
  _tray_mwheel_turns_slider->setValue ( value_n * 10.0 );
}

void
Settings_Dialog::change_startup ()
{
  if ( ( _dsetup == nullptr ) || _updating_values ) {
    return;
  }

  bool changed ( false );
  int idx = _start_btn_grp_device->checkedId ();
  if ( ( idx >= 0 ) && ( idx <= Desktop_Items_Setup::MIXER_DEV_LAST ) ) {
    if ( _dsetup->set_start_device_mode (
             static_cast< Desktop_Items_Setup::Mixer_Device > ( idx ) ) ) {
      changed = true;
    }
  }

  if ( _dsetup->set_start_user_device ( _start_dev_user_edit->text () ) ) {
    changed = true;
  }

  if ( changed ) {
    update_inputs_vis_state ();
  }
}

void
Settings_Dialog::change_appearance ()
{
  if ( ( _dsetup == nullptr ) || _updating_values ) {
    return;
  }

  bool changed = false;

  if ( _dsetup->main_window.mixer.set_show_slider_value_labels (
           _btn_show_sliders_labels->isChecked () ) ) {
    changed = true;
  }
  if ( _dsetup->main_window.mixer.set_show_tool_tips (
           _btn_show_tool_tips->isChecked () ) ) {
    changed = true;
  }

  if ( changed ) {
    // std::cout << "sig_change_mixer_view()\n";
    Q_EMIT sig_change_mixer_view ();
  }
}

void
Settings_Dialog::change_input ()
{
  if ( ( _dsetup == nullptr ) || _updating_values ) {
    return;
  }

  bool changed = false;

  {
    int value = _mwheel_turns_input->value () * 360.0;
    if ( value >= 0 ) {
      if ( _dsetup->main_window.inputs.set_wheel_degrees ( value ) ) {
        changed = true;
      }
    }
  }

  if ( changed ) {
    // std::cout << "sig_change_input()\n";
    Q_EMIT sig_change_input ();
  }
}

void
Settings_Dialog::change_tray_visibility ()
{
  if ( ( _dsetup == nullptr ) || _updating_values ) {
    return;
  }

  bool changed ( false );

  if ( _dsetup->set_tray_on_close ( _tray_btn_on_close->isChecked () ) ) {
    changed = true;
  }

  if ( _dsetup->set_tray_show_icon ( _tray_btn_show_icon->isChecked () ) ) {
    changed = true;
  }

  if ( changed ) {
    // std::cout << "sig_change_tray_visibility()\n";
    update_inputs_vis_state ();
    Q_EMIT sig_change_tray_visibility ();
  }
}

void
Settings_Dialog::change_tray_icon ()
{
  if ( ( _dsetup == nullptr ) || _updating_values ) {
    return;
  }

  bool changed ( false );

  if ( _dsetup->tray.set_show_volume_icon (
           _tray_btn_show_volume_icon->isChecked () ) ) {
    changed = true;
  }

  if ( changed ) {
    // std::cout << "sig_change_tray_icon()\n";
    Q_EMIT sig_change_tray_icon ();
  }
}

void
Settings_Dialog::change_tray_balloon ()
{
  if ( ( _dsetup == nullptr ) || _updating_values ) {
    return;
  }

  bool changed ( false );

  if ( _dsetup->tray.set_balloon_enabled (
           _tray_btn_balloon_show->isChecked () ) ) {
    changed = true;
  }

  if ( _tray_balloon_time_input->value () >= 0 ) {
    if ( _dsetup->tray.set_balloon_lifetime (
             _tray_balloon_time_input->value () ) ) {
      changed = true;
    }
  }

  if ( changed ) {
    // std::cout << "sig_change_tray_balloon()\n";
    update_inputs_vis_state ();
    Q_EMIT sig_change_tray_balloon ();
  }
}

void
Settings_Dialog::change_tray_mixer_dev ()
{
  if ( ( _dsetup == nullptr ) || _updating_values ) {
    return;
  }

  bool changed = false;

  {
    int idx = _tray_btn_grp_device->checkedId ();
    if ( ( idx >= 0 ) && ( idx <= Tray::Setup::MIXER_DEV_LAST ) ) {
      if ( _dsetup->tray.set_device_mode (
               static_cast< Tray::Setup::Mixer_Device > ( idx ) ) ) {
        changed = true;
      }
    }
  }

  if ( _dsetup->tray.set_user_device ( _tray_dev_user_edit->text () ) ) {
    changed = true;
  }

  if ( changed ) {
    // std::cout << "sig_change_tray_mixer_dev()\n";
    update_inputs_vis_state ();
    Q_EMIT sig_change_tray_mixer_dev ();
  }
}

void
Settings_Dialog::change_tray_input ()
{
  if ( ( _dsetup == nullptr ) || _updating_values ) {
    return;
  }

  bool changed = false;

  {
    int value = _tray_mwheel_turns_input->value () * 360.0;
    if ( value >= 0 ) {
      if ( _dsetup->tray.set_wheel_degrees ( value ) ) {
        changed = true;
      }
    }
  }

  if ( changed ) {
    // std::cout << "sig_change_tray_input()\n";
    Q_EMIT sig_change_tray_input ();
  }
}

void
Settings_Dialog::save_state ()
{
  if ( _dsetup != nullptr ) {
    _dsetup->settings_dialog.set_page ( current_page_idx () );
    _dsetup->settings_dialog.set_window_geometry ( saveGeometry () );
    _dsetup->settings_dialog.set_splitter_state ( splitter_state () );
  }
}

void
Settings_Dialog::closeEvent ( QCloseEvent * event_n )
{
  // Save settings
  save_state ();
  // Call super
  Views::Multi_Page_Dialog::closeEvent ( event_n );
}

} // namespace Views
