pax_global_header00006660000000000000000000000064135453451210014515gustar00rootroot0000000000000052 comment=18474e1b6d1460724c6433a7eb873fca46ad2393 qastools-v0.22.0/000077500000000000000000000000001354534512100136315ustar00rootroot00000000000000qastools-v0.22.0/.gitignore000066400000000000000000000000311354534512100156130ustar00rootroot00000000000000qastools.layout *.cbTemp qastools-v0.22.0/CHANGELOG000066400000000000000000000075041354534512100150510ustar00rootroot000000000000002010-10-03 Sebastian Holtermann * Switch to MIT license * Remove xwmw.org references * CMake: Modernize CMakeLists.txt * CMake: Use AUTOMOC * Bug fixes * Release version 0.22 2016-04-27 Sebastian Holtermann * all: Console messages flushed as single complete strings * all: System function error evaluation * all: Don't enforce compiler flags -fPIC -fPIE * all: Bug fixes * Release version 0.21 2016-04-26 Sebastian Holtermann * all: Qt5 only. Qt4 support removed. * all: Compile with C++11 (required) * all: Compiler warning fixes * all: Bug fixes * Release version 0.20 2014-12-09 Sebastian Holtermann * Release version 0.18.1 2014-11-23 Sebastian Holtermann * all: Desktop files: "Categories" list extended with "Qt" * all: Desktop files: "Keywords" list added * all: Desktop files: Italian translation updated (submitted by Alexey Loginov) * all: Desktop files: Russian translation updated (submitted by Alexey Loginov) 2014-10-12 Sebastian Holtermann * all: Using NDEBUG for simple debugging removed * all: Setting NDEBUG for compilation removed 2014-07-27 Sebastian Holtermann * Release version 0.18.0 2014-07-25 Sebastian Holtermann * QasMixer: Soundcard hotplug detection using udev 2014-07-24 Sebastian Holtermann * QasMixer: Slider width limited * QasMixer: Slider handles are always square (height may +/-1 from square to stay odd) * QasMixer: Keyboard volume higher/lower/mute keys work on sliders and switches 2012-05-09 Sebastian Holtermann * all: Compiler error and warning fixes for gcc-4.7 * Release version 0.17.2 2012-01-30 Sebastian Holtermann * shared: Painting fixed for Qt 4.8 * Release version 0.17.1 2012-01-17 Sebastian Holtermann * all: setting names for state save/restore changed/regrouped * all: smart main window sizeHint() to get a useable window size after leaving fullscreen * all: new dialog base classes * all: new common info dialog - uses QListView page selection intead of tabs * shared: device selection style tweaks: selected item now emphasized by a thin frame * shared: device selection style tweaks: Rounded selection area * shared: use QSplitter instead of QDockwidget for device selection view. It couldn't be detached anyway and size restoring works more reliable. * shared: more functionality sharing among applications (window size calculation, etc.) * qasconfig: settings directory changed to shared ~/.config/qastools/ (was ~/.config/qasconfig/) * qasconfig: new basic command line options (--version, --help, etc.) * qashctl: new basic command line options (--version, --help, etc.) * qasmixer: settings dialog based on common dialog class * qasmixer: settings dialog label tweaks * qasmixer: new application icon * Release version 0.17.0 2011-12-21 Sebastian Holtermann * qashctl: wrong destructor call order on close fixed * shared: several new/delete sequences replaced with QScopedPointer * Release version 0.16.2 2011-12-15 Sebastian Holtermann * all: Manpages updated * shared: freed memory access fix * cmake: Support for single application builds * Release version 0.16.1 2011-12-03 Sebastian Holtermann * QasTools replaces separate QasConfig and QasMixer packages * QasHctl: QasHctl forked out of QasMixer into separate application * QasHctl: Wrong pixmap in switch widgets fixed * QasMixer: Command line arguments -D and -c fixed * QasMixer: Command line arguments descriptions added in manpage * All: Info dialog adapted to QasTools * First release of QasTools package * Release version 0.16.0 qastools-v0.22.0/CMakeLists.txt000066400000000000000000000070371354534512100164000ustar00rootroot00000000000000CMAKE_MINIMUM_REQUIRED ( VERSION 3.6 ) PROJECT ( QasTools VERSION 0.22.0 LANGUAGES CXX ) # Default build type IF ( NOT CMAKE_BUILD_TYPE ) SET ( CMAKE_BUILD_TYPE Release ) ENDIF ( NOT CMAKE_BUILD_TYPE ) IF ( NOT BUILD_LIST ) SET ( BUILD_LIST "qascommon,qasconfig,qashctl,qasmixer" ) ENDIF ( NOT BUILD_LIST ) # program/package/version suffix IF ( NOT PROGRAM_SUFFIX ) SET ( PROGRAM_SUFFIX "" ) ENDIF ( NOT PROGRAM_SUFFIX ) IF ( NOT VERSION_SUFFIX ) SET ( VERSION_SUFFIX "" ) ENDIF ( NOT VERSION_SUFFIX ) IF ( NOT PACKAGE_SUFFIX ) SET ( PACKAGE_SUFFIX "" ) ENDIF ( NOT PACKAGE_SUFFIX ) # Package name IF ( NOT PACKAGE_TITLE ) SET ( PACKAGE_TITLE "QasTools" ) ENDIF ( NOT PACKAGE_TITLE ) IF ( NOT PACKAGE_NAME ) SET ( PACKAGE_NAME "qastools${PACKAGE_SUFFIX}" ) ENDIF ( NOT PACKAGE_NAME ) # Package version SET ( PACKAGE_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}" ) SET ( PACKAGE_VERSION_MINOR "${PROJECT_VERSION_MINOR}" ) SET ( PACKAGE_VERSION_PATCH "${PROJECT_VERSION_PATCH}" ) SET ( PACKAGE_VERSION "${PACKAGE_VERSION_MAJOR}.${PACKAGE_VERSION_MINOR}.${PACKAGE_VERSION_PATCH}${VERSION_SUFFIX}" ) # Installation directories IF ( NOT INSTALL_DIR_BIN ) SET ( INSTALL_DIR_BIN "bin" ) ENDIF ( NOT INSTALL_DIR_BIN ) IF ( NOT INSTALL_DIR_MAN ) SET ( INSTALL_DIR_MAN "share/man/man1" ) ENDIF ( NOT INSTALL_DIR_MAN ) IF ( NOT INSTALL_DIR_DESKTOP ) SET ( INSTALL_DIR_DESKTOP "share/applications" ) ENDIF ( NOT INSTALL_DIR_DESKTOP ) IF ( NOT INSTALL_DIR_DATA ) SET ( INSTALL_DIR_DATA "share/${PACKAGE_NAME}" ) ENDIF ( NOT INSTALL_DIR_DATA ) IF ( NOT INSTALL_DIR_L10N ) SET ( INSTALL_DIR_L10N "${INSTALL_DIR_DATA}/l10n" ) ENDIF ( NOT INSTALL_DIR_L10N ) IF ( NOT INSTALL_DIR_APP_ICONS ) SET ( INSTALL_DIR_APP_ICONS "${INSTALL_DIR_DATA}/icons" ) ENDIF ( NOT INSTALL_DIR_APP_ICONS ) IF ( NOT INSTALL_DIR_WIDGETS_GRAPHICS ) SET ( INSTALL_DIR_WIDGETS_GRAPHICS "${INSTALL_DIR_DATA}/widgets" ) ENDIF ( NOT INSTALL_DIR_WIDGETS_GRAPHICS ) # Icon installation directories IF ( NOT INSTALL_DIR_ICONS_PNG_16 ) SET ( INSTALL_DIR_ICONS_PNG_16 "share/icons/hicolor/16x16/apps" ) ENDIF ( NOT INSTALL_DIR_ICONS_PNG_16 ) IF ( NOT INSTALL_DIR_ICONS_PNG_32 ) SET ( INSTALL_DIR_ICONS_PNG_32 "share/icons/hicolor/32x32/apps" ) ENDIF ( NOT INSTALL_DIR_ICONS_PNG_32 ) IF ( NOT INSTALL_DIR_ICONS_PNG_48 ) SET ( INSTALL_DIR_ICONS_PNG_48 "share/icons/hicolor/48x48/apps" ) ENDIF ( NOT INSTALL_DIR_ICONS_PNG_48 ) IF ( NOT INSTALL_DIR_ICONS_PNG_64 ) SET ( INSTALL_DIR_ICONS_PNG_64 "share/icons/hicolor/64x64/apps" ) ENDIF ( NOT INSTALL_DIR_ICONS_PNG_64 ) IF ( NOT INSTALL_DIR_ICONS_SVG ) SET ( INSTALL_DIR_ICONS_SVG "share/icons/hicolor/scalable/apps" ) ENDIF ( NOT INSTALL_DIR_ICONS_SVG ) # Localization file prefix SET ( L10N_PREFIX "${PACKAGE_NAME}_" ) # Shared resources SET ( SHARED_RES_DIR "${CMAKE_CURRENT_SOURCE_DIR}/shared" ) SET ( SHARED_SRC_DIR "${SHARED_RES_DIR}/src" ) SET ( SHARED_INC_DIR "${SHARED_RES_DIR}/src" ) # Installation IF ( NOT SKIP_LICENSE_INSTALL ) INSTALL( FILES "COPYING" DESTINATION ${INSTALL_DIR_DATA} ) ENDIF ( NOT SKIP_LICENSE_INSTALL ) # Process subdirectories IF ( ${BUILD_LIST} MATCHES "qascommon" ) ADD_SUBDIRECTORY ( i18n ) ADD_SUBDIRECTORY ( shared ) ENDIF ( ${BUILD_LIST} MATCHES "qascommon" ) IF ( ${BUILD_LIST} MATCHES "qasconfig" ) ADD_SUBDIRECTORY ( qasconfig ) ENDIF ( ${BUILD_LIST} MATCHES "qasconfig" ) IF ( ${BUILD_LIST} MATCHES "qashctl" ) ADD_SUBDIRECTORY ( qashctl ) ENDIF ( ${BUILD_LIST} MATCHES "qashctl" ) IF ( ${BUILD_LIST} MATCHES "qasmixer" ) ADD_SUBDIRECTORY ( qasmixer ) ENDIF ( ${BUILD_LIST} MATCHES "qasmixer" ) qastools-v0.22.0/COPYING000066400000000000000000000020421354534512100146620ustar00rootroot00000000000000 Copyright QasTools contributors. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. qastools-v0.22.0/Makefile000066400000000000000000000001671354534512100152750ustar00rootroot00000000000000 all: debug release debug: cd ~/build/qastools/debug && make -j8 release: cd ~/build/qastools/release && make -j8 qastools-v0.22.0/README.md000066400000000000000000000012601354534512100151070ustar00rootroot00000000000000# About QasTools is a collection of Qt-based mixer and setup tools for the Linux sound system ALSA. ## Copying QasTools is distributed under the terms in the COPYING text file that comes with this package. ## Installation QasTools uses the CMake build system. For a system wide installation type: ``` tar -xjf qastools_X.Y.Z.bz2 cd qastools_X.Y.Z mkdir build cd build cmake .. make -j8 sudo make install ``` For a local build instead call: ``` tar -xjf qastools_X.Y.Z.bz2 cd qastools_X.Y.Z mkdir install mkdir build cd build cmake .. -DCMAKE_INSTALL_PREFIX=../install make -j8 make install ``` Authors ------- QasTools was written by: Sebastian Holtermann qastools-v0.22.0/TODO000066400000000000000000000005131354534512100143200ustar00rootroot00000000000000* ctl element selection for the minimixer (master,line, etc.) * volume/switch preset safe/restore (on startup) * Option to enable/disable slider animations * Option for desktop autostart (another .desktop file for autostart?) * sliders/switches grouping * volume meters * K system styled sliders/meters * USB plug in/out detection qastools-v0.22.0/i18n/000077500000000000000000000000001354534512100144105ustar00rootroot00000000000000qastools-v0.22.0/i18n/CMakeLists.txt000066400000000000000000000007431354534512100171540ustar00rootroot00000000000000# Find modules FIND_PACKAGE ( Qt5LinguistTools ) # Find translations source files FILE ( GLOB ts_files "ts/*.ts" ) # Setup translations build target QT5_ADD_TRANSLATION ( qm_files ${ts_files} ) ADD_CUSTOM_TARGET ( translations ALL DEPENDS ${qm_files} ) # Install translations FOREACH ( qm_src ${qm_files} ) STRING( REGEX REPLACE ".*app_" "${L10N_PREFIX}" qm_name ${qm_src} ) INSTALL( FILES ${qm_src} RENAME ${qm_name} DESTINATION ${INSTALL_DIR_L10N} ) ENDFOREACH ( qm_src ) qastools-v0.22.0/i18n/app.pro000066400000000000000000000341321354534512100157150ustar00rootroot00000000000000 HEADERS = \ ../qasconfig/src/desktop_items.hpp \ ../qasconfig/src/info_texts.hpp \ ../qasconfig/src/main_window.hpp \ ../qasconfig/src/qsnd/alsa_config_model.hpp \ ../qasconfig/src/static_tree.hpp \ ../qasconfig/src/static_tree_model.hpp \ ../qasconfig/src/views/alsa_config_view.hpp \ ../qashctl/src/desktop_items.hpp \ ../qashctl/src/info_texts.hpp \ ../qashctl/src/main_window.hpp \ ../qashctl/src/main_window_setup.hpp \ ../qashctl/src/mwdg/mixer_hctl.hpp \ ../qashctl/src/mwdg/mixer_hctl_edit_bool.hpp \ ../qashctl/src/mwdg/mixer_hctl_edit_enum.hpp \ ../qashctl/src/mwdg/mixer_hctl_edit_int.hpp \ ../qashctl/src/mwdg/mixer_hctl_edit_unsupported.hpp \ ../qashctl/src/mwdg/mixer_hctl_editor.hpp \ ../qashctl/src/mwdg/mixer_hctl_editor_data.hpp \ ../qashctl/src/mwdg/mixer_hctl_int_proxies_group.hpp \ ../qashctl/src/mwdg/mixer_hctl_int_proxy_column.hpp \ ../qashctl/src/mwdg/mixer_hctl_int_proxy_slider.hpp \ ../qashctl/src/mwdg/mixer_hctl_proxies_group.hpp \ ../qashctl/src/mwdg/mixer_hctl_proxy.hpp \ ../qashctl/src/mwdg/mixer_hctl_proxy_enum.hpp \ ../qashctl/src/mwdg/mixer_hctl_proxy_switch.hpp \ ../qashctl/src/mwdg/mixer_hctl_slider_status_widget.hpp \ ../qashctl/src/mwdg/mixer_hctl_table_model.hpp \ ../qashctl/src/mwdg/mixer_hctl_tree_model.hpp \ ../qashctl/src/views/mixer_hctl.hpp \ ../qashctl/src/views/mixer_hctl_setup.hpp \ ../qasmixer/src/cmd_options.hpp \ ../qasmixer/src/desktop_items.hpp \ ../qasmixer/src/desktop_items_setup.hpp \ ../qasmixer/src/info_texts.hpp \ ../qasmixer/src/init_globals.hpp \ ../qasmixer/src/main_window.hpp \ ../qasmixer/src/main_window_setup.hpp \ ../qasmixer/src/mwdg/mixer_gui_state.hpp \ ../qasmixer/src/mwdg/mixer_separation_info.hpp \ ../qasmixer/src/mwdg/mixer_simple_setup.hpp \ ../qasmixer/src/mwdg/mixer_sliders.hpp \ ../qasmixer/src/mwdg/mixer_sliders_proxies_column.hpp \ ../qasmixer/src/mwdg/mixer_sliders_proxies_group.hpp \ ../qasmixer/src/mwdg/mixer_sliders_proxy_slider.hpp \ ../qasmixer/src/mwdg/mixer_sliders_proxy_switch.hpp \ ../qasmixer/src/mwdg/mixer_sliders_status_widget.hpp \ ../qasmixer/src/mwdg/mixer_switches.hpp \ ../qasmixer/src/mwdg/mixer_switches_proxies_group.hpp \ ../qasmixer/src/mwdg/mixer_switches_proxy_enum.hpp \ ../qasmixer/src/mwdg/mixer_switches_proxy_switch.hpp \ ../qasmixer/src/tray_mixer.hpp \ ../qasmixer/src/tray_mixer_balloon.hpp \ ../qasmixer/src/tray_mixer_icon.hpp \ ../qasmixer/src/tray_mixer_mdev_setup.hpp \ ../qasmixer/src/tray_mixer_view_setup.hpp \ ../qasmixer/src/views/mixer_simple.hpp \ ../qasmixer/src/views/mixer_simple_setup.hpp \ ../qasmixer/src/views/settings_dialog.hpp \ ../qasmixer/src/views/settings_dialog_setup.hpp \ ../shared/src/dpe/image.hpp \ ../shared/src/dpe/image_allocator.hpp \ ../shared/src/dpe/image_request.hpp \ ../shared/src/dpe/image_set.hpp \ ../shared/src/dpe/image_set_group.hpp \ ../shared/src/dpe/image_set_meta.hpp \ ../shared/src/dpe/image_set_state.hpp \ ../shared/src/dpe/is_buffer.hpp \ ../shared/src/dpe/is_buffer_handle.hpp \ ../shared/src/dpe/paint_job.hpp \ ../shared/src/dpe/painter.hpp \ ../shared/src/dpe/painter_simple.hpp \ ../shared/src/dpe/painter_thread.hpp \ ../shared/src/dpe/painter_thread_shared.hpp \ ../shared/src/license_texts.hpp \ ../shared/src/mwdg/controls_delegate.hpp \ ../shared/src/mwdg/controls_view.hpp \ ../shared/src/mwdg/ctl_arg_view.hpp \ ../shared/src/mwdg/ctl_arg_view_card.hpp \ ../shared/src/mwdg/ctl_arg_view_integer.hpp \ ../shared/src/mwdg/ctl_arg_view_string.hpp \ ../shared/src/mwdg/event_types.hpp \ ../shared/src/mwdg/inputs_setup.hpp \ ../shared/src/mwdg/mixer_device_setup.hpp \ ../shared/src/mwdg/mixer_style.hpp \ ../shared/src/mwdg/slider_status_widget.hpp \ ../shared/src/qsnd/alsa.hpp \ ../shared/src/qsnd/alsa_config_watcher.hpp \ ../shared/src/qsnd/alsa_i18n.hpp \ ../shared/src/qsnd/card_info.hpp \ ../shared/src/qsnd/cards_model.hpp \ ../shared/src/qsnd/controls_database.hpp \ ../shared/src/qsnd/controls_model.hpp \ ../shared/src/qsnd/ctl_address.hpp \ ../shared/src/qsnd/ctl_address_argument.hpp \ ../shared/src/qsnd/ctl_format.hpp \ ../shared/src/qsnd/ctl_format_argument.hpp \ ../shared/src/qsnd/event_types.hpp \ ../shared/src/qsnd/mixer_hctl.hpp \ ../shared/src/qsnd/mixer_hctl_elem.hpp \ ../shared/src/qsnd/mixer_hctl_elem_group.hpp \ ../shared/src/qsnd/mixer_hctl_info_db.hpp \ ../shared/src/qsnd/mixer_simple.hpp \ ../shared/src/qsnd/mixer_simple_elem.hpp \ ../shared/src/qsnd/mixer_simple_filter.hpp \ ../shared/src/qsnd/mixer_simple_filter_name.hpp \ ../shared/src/qsnd/model_keys.hpp \ ../shared/src/qsnd/pcm_device_info.hpp \ ../shared/src/qsnd/pcm_subdevice_info.hpp \ ../shared/src/qsnd/pcm_subdevices_info.hpp \ ../shared/src/single_application.hpp \ ../shared/src/unix_signal_handler.hpp \ ../shared/src/views/basic_dialog.hpp \ ../shared/src/views/device_selection_view.hpp \ ../shared/src/views/device_selection_view_setup.hpp \ ../shared/src/views/info_dialog.hpp \ ../shared/src/views/message_widget.hpp \ ../shared/src/views/multi_page_dialog.hpp \ ../shared/src/views/view_base.hpp \ ../shared/src/views/view_base_setup.hpp \ ../shared/src/views/view_utility.hpp \ ../shared/src/wdg/balloon_widget.hpp \ ../shared/src/wdg/color_methods.hpp \ ../shared/src/wdg/cubic_curve.hpp \ ../shared/src/wdg/ds_imaging.hpp \ ../shared/src/wdg/ds_slider.hpp \ ../shared/src/wdg/ds_slider_meta_bg.hpp \ ../shared/src/wdg/ds_slider_painter_bevelled.hpp \ ../shared/src/wdg/ds_slider_test.hpp \ ../shared/src/wdg/ds_slider_test_dialog.hpp \ ../shared/src/wdg/ds_switch.hpp \ ../shared/src/wdg/ds_switch_painter_circle.hpp \ ../shared/src/wdg/ds_switch_painter_close.hpp \ ../shared/src/wdg/ds_switch_painter_svg.hpp \ ../shared/src/wdg/ds_widget_painter.hpp \ ../shared/src/wdg/ds_widget_style_db.hpp \ ../shared/src/wdg/ds_widget_types.hpp \ ../shared/src/wdg/equal_columns_layout.hpp \ ../shared/src/wdg/equal_columns_layout_group.hpp \ ../shared/src/wdg/event_types.hpp \ ../shared/src/wdg/fill_columns_layout.hpp \ ../shared/src/wdg/label_elide.hpp \ ../shared/src/wdg/label_width.hpp \ ../shared/src/wdg/layout_weights.hpp \ ../shared/src/wdg/pad_focus_info.hpp \ ../shared/src/wdg/pad_proxies_column.hpp \ ../shared/src/wdg/pad_proxies_group.hpp \ ../shared/src/wdg/pad_proxy.hpp \ ../shared/src/wdg/pad_proxy_enum.hpp \ ../shared/src/wdg/pad_proxy_slider.hpp \ ../shared/src/wdg/pad_proxy_style.hpp \ ../shared/src/wdg/pad_proxy_switch.hpp \ ../shared/src/wdg/pass_events.hpp \ ../shared/src/wdg/scroll_area_horizontal.hpp \ ../shared/src/wdg/scroll_area_vertical.hpp \ ../shared/src/wdg/sliders_pad.hpp \ ../shared/src/wdg/sliders_pad_data.hpp \ ../shared/src/wdg/sliders_pad_footer.hpp \ ../shared/src/wdg/sliders_pad_header.hpp \ ../shared/src/wdg/sliders_pad_header_data.hpp \ ../shared/src/wdg/sliders_pad_layout.hpp \ ../shared/src/wdg/sliders_pad_style.hpp \ ../shared/src/wdg/switches_area.hpp \ ../shared/src/wdg/switches_pad.hpp \ ../shared/src/wdg/switches_pad_widgets.hpp \ ../shared/src/wdg/switches_pad_widgets_group.hpp \ ../shared/src/wdg/text_browser.hpp \ ../shared/src/wdg/tree_view_kv.hpp \ ../shared/src/wdg/uint_mapper.hpp SOURCES = \ ../qasconfig/src/desktop_items.cpp \ ../qasconfig/src/info_texts.cpp \ ../qasconfig/src/main.cpp \ ../qasconfig/src/main_window.cpp \ ../qasconfig/src/qsnd/alsa_config_model.cpp \ ../qasconfig/src/static_tree.cpp \ ../qasconfig/src/static_tree_model.cpp \ ../qasconfig/src/views/alsa_config_view.cpp \ ../qashctl/src/desktop_items.cpp \ ../qashctl/src/info_texts.cpp \ ../qashctl/src/main.cpp \ ../qashctl/src/main_window.cpp \ ../qashctl/src/main_window_setup.cpp \ ../qashctl/src/mwdg/mixer_hctl.cpp \ ../qashctl/src/mwdg/mixer_hctl_edit_bool.cpp \ ../qashctl/src/mwdg/mixer_hctl_edit_enum.cpp \ ../qashctl/src/mwdg/mixer_hctl_edit_int.cpp \ ../qashctl/src/mwdg/mixer_hctl_edit_unsupported.cpp \ ../qashctl/src/mwdg/mixer_hctl_editor.cpp \ ../qashctl/src/mwdg/mixer_hctl_editor_data.cpp \ ../qashctl/src/mwdg/mixer_hctl_int_proxies_group.cpp \ ../qashctl/src/mwdg/mixer_hctl_int_proxy_column.cpp \ ../qashctl/src/mwdg/mixer_hctl_int_proxy_slider.cpp \ ../qashctl/src/mwdg/mixer_hctl_proxies_group.cpp \ ../qashctl/src/mwdg/mixer_hctl_proxy.cpp \ ../qashctl/src/mwdg/mixer_hctl_proxy_enum.cpp \ ../qashctl/src/mwdg/mixer_hctl_proxy_switch.cpp \ ../qashctl/src/mwdg/mixer_hctl_slider_status_widget.cpp \ ../qashctl/src/mwdg/mixer_hctl_table_model.cpp \ ../qashctl/src/mwdg/mixer_hctl_tree_model.cpp \ ../qashctl/src/views/mixer_hctl.cpp \ ../qashctl/src/views/mixer_hctl_setup.cpp \ ../qasmixer/src/cmd_options.cpp \ ../qasmixer/src/desktop_items.cpp \ ../qasmixer/src/desktop_items_setup.cpp \ ../qasmixer/src/info_texts.cpp \ ../qasmixer/src/init_globals.cpp \ ../qasmixer/src/main.cpp \ ../qasmixer/src/main_window.cpp \ ../qasmixer/src/main_window_setup.cpp \ ../qasmixer/src/mwdg/mixer_gui_state.cpp \ ../qasmixer/src/mwdg/mixer_separation_info.cpp \ ../qasmixer/src/mwdg/mixer_simple_setup.cpp \ ../qasmixer/src/mwdg/mixer_sliders.cpp \ ../qasmixer/src/mwdg/mixer_sliders_proxies_column.cpp \ ../qasmixer/src/mwdg/mixer_sliders_proxies_group.cpp \ ../qasmixer/src/mwdg/mixer_sliders_proxy_slider.cpp \ ../qasmixer/src/mwdg/mixer_sliders_proxy_switch.cpp \ ../qasmixer/src/mwdg/mixer_sliders_status_widget.cpp \ ../qasmixer/src/mwdg/mixer_switches.cpp \ ../qasmixer/src/mwdg/mixer_switches_proxies_group.cpp \ ../qasmixer/src/mwdg/mixer_switches_proxy_enum.cpp \ ../qasmixer/src/mwdg/mixer_switches_proxy_switch.cpp \ ../qasmixer/src/tray_mixer.cpp \ ../qasmixer/src/tray_mixer_balloon.cpp \ ../qasmixer/src/tray_mixer_icon.cpp \ ../qasmixer/src/tray_mixer_mdev_setup.cpp \ ../qasmixer/src/tray_mixer_view_setup.cpp \ ../qasmixer/src/views/mixer_simple.cpp \ ../qasmixer/src/views/mixer_simple_setup.cpp \ ../qasmixer/src/views/settings_dialog.cpp \ ../qasmixer/src/views/settings_dialog_setup.cpp \ ../shared/src/dpe/image.cpp \ ../shared/src/dpe/image_allocator.cpp \ ../shared/src/dpe/image_request.cpp \ ../shared/src/dpe/image_set.cpp \ ../shared/src/dpe/image_set_group.cpp \ ../shared/src/dpe/image_set_meta.cpp \ ../shared/src/dpe/image_set_state.cpp \ ../shared/src/dpe/is_buffer.cpp \ ../shared/src/dpe/is_buffer_handle.cpp \ ../shared/src/dpe/paint_job.cpp \ ../shared/src/dpe/painter.cpp \ ../shared/src/dpe/painter_simple.cpp \ ../shared/src/dpe/painter_thread.cpp \ ../shared/src/dpe/painter_thread_shared.cpp \ ../shared/src/license_texts.cpp \ ../shared/src/mwdg/controls_delegate.cpp \ ../shared/src/mwdg/controls_view.cpp \ ../shared/src/mwdg/ctl_arg_view.cpp \ ../shared/src/mwdg/ctl_arg_view_card.cpp \ ../shared/src/mwdg/ctl_arg_view_integer.cpp \ ../shared/src/mwdg/ctl_arg_view_string.cpp \ ../shared/src/mwdg/event_types.cpp \ ../shared/src/mwdg/inputs_setup.cpp \ ../shared/src/mwdg/mixer_device_setup.cpp \ ../shared/src/mwdg/mixer_style.cpp \ ../shared/src/mwdg/slider_status_widget.cpp \ ../shared/src/qsnd/alsa.cpp \ ../shared/src/qsnd/alsa_config_watcher.cpp \ ../shared/src/qsnd/card_info.cpp \ ../shared/src/qsnd/cards_model.cpp \ ../shared/src/qsnd/controls_database.cpp \ ../shared/src/qsnd/controls_model.cpp \ ../shared/src/qsnd/ctl_address.cpp \ ../shared/src/qsnd/ctl_address_argument.cpp \ ../shared/src/qsnd/ctl_format.cpp \ ../shared/src/qsnd/ctl_format_argument.cpp \ ../shared/src/qsnd/event_types.cpp \ ../shared/src/qsnd/mixer_hctl.cpp \ ../shared/src/qsnd/mixer_hctl_elem.cpp \ ../shared/src/qsnd/mixer_hctl_elem_group.cpp \ ../shared/src/qsnd/mixer_hctl_info_db.cpp \ ../shared/src/qsnd/mixer_simple.cpp \ ../shared/src/qsnd/mixer_simple_elem.cpp \ ../shared/src/qsnd/mixer_simple_filter.cpp \ ../shared/src/qsnd/mixer_simple_filter_name.cpp \ ../shared/src/qsnd/pcm_device_info.cpp \ ../shared/src/qsnd/pcm_subdevice_info.cpp \ ../shared/src/qsnd/pcm_subdevices_info.cpp \ ../shared/src/single_application.cpp \ ../shared/src/unix_signal_handler.cpp \ ../shared/src/views/basic_dialog.cpp \ ../shared/src/views/device_selection_view.cpp \ ../shared/src/views/device_selection_view_setup.cpp \ ../shared/src/views/info_dialog.cpp \ ../shared/src/views/message_widget.cpp \ ../shared/src/views/multi_page_dialog.cpp \ ../shared/src/views/view_base.cpp \ ../shared/src/views/view_base_setup.cpp \ ../shared/src/views/view_utility.cpp \ ../shared/src/wdg/balloon_widget.cpp \ ../shared/src/wdg/color_methods.cpp \ ../shared/src/wdg/cubic_curve.cpp \ ../shared/src/wdg/ds_imaging.cpp \ ../shared/src/wdg/ds_slider.cpp \ ../shared/src/wdg/ds_slider_meta_bg.cpp \ ../shared/src/wdg/ds_slider_painter_bevelled.cpp \ ../shared/src/wdg/ds_slider_test.cpp \ ../shared/src/wdg/ds_slider_test_dialog.cpp \ ../shared/src/wdg/ds_switch.cpp \ ../shared/src/wdg/ds_switch_painter_circle.cpp \ ../shared/src/wdg/ds_switch_painter_close.cpp \ ../shared/src/wdg/ds_switch_painter_svg.cpp \ ../shared/src/wdg/ds_widget_painter.cpp \ ../shared/src/wdg/ds_widget_style_db.cpp \ ../shared/src/wdg/equal_columns_layout.cpp \ ../shared/src/wdg/equal_columns_layout_group.cpp \ ../shared/src/wdg/event_types.cpp \ ../shared/src/wdg/fill_columns_layout.cpp \ ../shared/src/wdg/label_elide.cpp \ ../shared/src/wdg/label_width.cpp \ ../shared/src/wdg/layout_weights.cpp \ ../shared/src/wdg/pad_focus_info.cpp \ ../shared/src/wdg/pad_proxies_column.cpp \ ../shared/src/wdg/pad_proxies_group.cpp \ ../shared/src/wdg/pad_proxy.cpp \ ../shared/src/wdg/pad_proxy_enum.cpp \ ../shared/src/wdg/pad_proxy_slider.cpp \ ../shared/src/wdg/pad_proxy_style.cpp \ ../shared/src/wdg/pad_proxy_switch.cpp \ ../shared/src/wdg/pass_events.cpp \ ../shared/src/wdg/scroll_area_horizontal.cpp \ ../shared/src/wdg/scroll_area_vertical.cpp \ ../shared/src/wdg/sliders_pad.cpp \ ../shared/src/wdg/sliders_pad_data.cpp \ ../shared/src/wdg/sliders_pad_footer.cpp \ ../shared/src/wdg/sliders_pad_header.cpp \ ../shared/src/wdg/sliders_pad_header_data.cpp \ ../shared/src/wdg/sliders_pad_layout.cpp \ ../shared/src/wdg/sliders_pad_style.cpp \ ../shared/src/wdg/switches_area.cpp \ ../shared/src/wdg/switches_pad.cpp \ ../shared/src/wdg/switches_pad_widgets.cpp \ ../shared/src/wdg/switches_pad_widgets_group.cpp \ ../shared/src/wdg/text_browser.cpp \ ../shared/src/wdg/tree_view_kv.cpp \ ../shared/src/wdg/uint_mapper.cpp qastools-v0.22.0/i18n/ts/000077500000000000000000000000001354534512100150365ustar00rootroot00000000000000qastools-v0.22.0/i18n/ts/app_cs.ts000066400000000000000000001523321354534512100166610ustar00rootroot00000000000000 UTF-8 ALSA::CTL_Arg_Name CARD Karta SOCKET ZÁSUVKA CTL CTL ALSA::CTL_Elem_IFace_Name CARD Karta HWDEP Zařízení MIXER Směšovač PCM PCM RAWMIDI SurovéMIDI TIMER Časomíra SEQUENCER Sekvencer Unknown Neznámý ALSA::CTL_Elem_Type_Name NONE Žádný BOOLEAN Booleánský INTEGER Celočíselný ENUMERATED Vyjmenovaný BYTES Byty IEC958 IEC958 INTEGER64 Integer64 Unknown Neznámý ALSA::Channel_Name Front Left Vpředu vlevo Front Right Vpředu vpravo Rear Left Vzadu vlevo Rear Right Vzadu vpravo Front Center Vpředu uprostřed Woofer Basový reproduktor Side Left Strana vlevo Side Right Strana vpravo Rear Center Vzadu uprostřed ALSA::Elem_Name Master Hlavní Speaker Reproduktor Headphone Sluchátka Headphone LFE Sluchátka LFE Headphone Center Sluchátka uprostřed Front Vpředu Auto-Mute Mode Režim automatického ztlumení Front Mic Mik. vpředu Front Mic Boost Zesílení mik. vpředu Mic Mikrofon Mic Boost Zesílení mik Phone Telefon Surround Okolí Video Video Center Střed Side Strana Capture Zachytávání Beep Pípnutí PC Speaker Reproduktor PC Bass Basy Treble Výšky Channel Mode Kanálový režim Auto Gain Control Ovládání auto. zesílení Mic Select Výběr mikrofonu Internal Mic Vnitřní mik. Int Mic Vnitřní mik. External Mic Vnější mik. Ext Mic Vnější mik. Mic Boost (+20dB) Zesílení mik (+20dB) External Amplifier Vnější zesilovač Input Source Vstupní zdroj ALSA::Enum_Value 1ch 1 kan. 2ch 2 kan. 3ch 3 kan. 4ch 4 kan. 5ch 5 kan. 6ch 6 kan. 7ch 7 kan. 8ch 8 kan. Internal Mic Vnitřní mik. Mic Mikrofon Front Mic Mik. vpředu Enabled Povoleno Disabled Zakázáno Mic1 Mik. 1 Mic2 Mik. 2 Mic3 Mik. 3 Mic4 Mik. 4 Video Video Phone Telefon ALSA::Flags not readable nečitelný readable čitelný not writable nezapisovatelný writable zapisovatelný not volatile ne nestálý volatile nestálý not active nečinný active činný MWdg::Inputs_Setup s "s" is an abbreviation for "split" or "separate". Something like "j" for "joined" or "c" for "channel" may be appropriate, too. roz l "l" is an abbreviation for "level" úr m "m" is an abbreviation for "mute" zt p "p" is an abbreviation for "playback" c "c" is an abbreviation for "capture" or "record" nah Split &channels Used in the context menu (slider/switch right click menu) Rozdělit &kanály Join &channels Used in the context menu (slider/switch right click menu) Spojit &kanály &Level channels Used in the context menu (slider/switch right click menu) &Srovnat rozdíly kanálů MWdg::Mixer_HCTL Element name Název prvku Joined Spojeno Element index Ukazatel prvku Channel %1 Kanál %1 Ch. %1 Kan.%1 Index: %1 Ukazatel: %1 Channel: %2 Kanál: %2 Index: Ukazatel: Device: Zařízení: Flags: Příznaky: Channels: Kanály: Num. id: Čísel. ID: Device Zařízení Flags Příznaky Channel count Počet kanálů Numeric Id Číselné ID Subdevice Podzařízení No element selected Nebyl vybrán žádný prvek MWdg::Mixer_HCTL_Edit_Int minimum Nejméně maximum Nejvíce Integer range: Celočíselný rozsah: Decibel range: Rozsah decibelů: Channel %1 Kanál %1 Index %1 Ukazatel %1 MWdg::Mixer_HCTL_Edit_Unsupported Elements of the type %1 are not supported Prvky typu %1 nejsou podporovány MWdg::Mixer_HCTL_Int_Proxy_Column %1 dB Decibel value string template %1 dB %1 % Percent value string template %1 % MWdg::Mixer_HCTL_Table_Model %1,%2 %1,%2 Name Název Element name Název prvku Idx Idx - abbreviation for Index Ukaz Element index Index prvku Device Zařízení Type Typ Element type Typ prvku Ch. Ch. - abbreviation for Channel Kan. Channel count Počet kanálů Flags Příznaky Id ID Numeric Id Číselné ID MWdg::Mixer_Sliders &Mute &Ztlumit &Mute all &Ztlumit vše Un&mute &Zrušit ztlumení Un&mute all &Zrušit ztlumení u všeho Toggle &mutes Přepnout &ztlumení Playback slider Posuvník přehrávání Capture slider Posuvník nahrávání Playback switch Přepínač přehrávání Capture switch Přepínač nahrávání %1 (%2) %1 (%2) MWdg::Mixer_Sliders_Proxies_Column %1 dB %1 dB %1 % %1 % MWdg::Mixer_Switches %1 (%2) %1 (%2) Playback selection Výběr přehrávání Playback switch Přepínač přehrávání Capture selection Výběr nahrávání Capture switch Přepínač nahrávání MWdg::Slider_Status_Widget Slider value Hodnota posuvníku Value Hodnota Max. Nejvíce Maximum Nejvíce Min. Nejméně Minimum Nejméně Volume Hlasitost Current volume Nynější hlasitost Volume maximum Nejvyšší hlasitost Volume minimum Nejnižší hlasitost Decibel Decibel Current Decibel value Nynější hodnota decibelů Decibel maximum Nejvíce decibelů Decibel minimum Nejméně decibelů Element name Název prvku Close slider value display Zavřít zobrazení hodnoty posuvníku Main_Window &Fullscreen mode Režim na &celou obrazovku Exit &fullscreen mode Ukončit režim na ce&lou obrazovku &Quit &Ukončit &Settings &Nastavení Ctrl+s Ctrl+S &Refresh &Obnovit Show &device selection Ukázat výběr &zařízení &Info &O programu &File &Soubor &View &Pohled &Help &Nápověda Mixer device Zařízení směšovače QSnd::Alsa_Config_Model Key Klíč Value Hodnota QSnd::Mixer_HCTL Empty device name Prázdný název zařízení QSnd::Mixer_Simple Empty device name Prázdný název zařízení Tray_Mixer_Balloon Volume is at %1% Hlasitost je na %1% Show mixer Ukázat směšovač Volume muted Hlasitost ztlumena Tray_Mixer_Icon &Show mixer &Ukázat směšovač Ctrl+s Ctrl+S &Close %1 %1 will be replaced with the program title &Zavřít %1 Views::Alsa_Config_View ALSA configuration Nastavení Alsa &Expand &Rozbalit Co&llapse &Složit &Sort &Třídit Depth: Hloubka: Views::Basic_Dialog &Close &Zavřít Views::Device_Selection_View &Close device selection &Zavřít výběr zařízení Plugin Přídavný modul Views::Info_Dialog Info Informace %1 - %2 %1 - %2 About O programu Internet Internet Home page Domovská stránka Project page Projektová stránka Developers Vývojáři Translators Překladatelé Information People License %1 is a collection of desktop applications for the Linux sound system %2. %1 je sbírka programů pro linuxový zvukový systém %2. Contributors Přispěvatelé The license file %1 is not available. Soubor s povolením %1 není dostupný. &Information &Informace &People &Lidé &License &Povolení &Close &Zavřít Views::Message_Widget Mixer device couldn't be opened Zařízení směšovače se nepodařilo otevřít No device selected Nebylo vybráno žádné zařízení Function Funkce Address Adresa Error Chyba Views::Mixer_Simple Show playback Ukázat přehrávání Show capture Ukázat zachytávání Show playback elements Ukázat ovládání přehrávání Show capture elements Ukázat ovládání zachytávání Views::Settings_Dialog Settings Nastavení Startup Spuštění Sliders Appearance Vzhled Input Vstup System tray Oznamovací oblast panelu &Close &Zavřít Startup mixer device Zařízení spouštěcího směšovače From last session Z posledního sezení Simple mixer view Jednoduchý pohled na směšovač Show slider value labels Ukázat štítky s hodnotami posuvníku Mouse wheel Kolečko myši Number of turns for a slider change from 0% to 100% Počet kroků pro změnu posuvníku z 0% na 100% Show tray icon Ukázat ikonu v oznamovací oblasti Close to tray Zavřít do oznamovací oblasti panelu System tray usage Používání oznamovací oblasti panelu Notification balloon Bublina s oznámením Show balloon on a volume change Při změně hlasitosti ukázat bublinu Balloon lifetime Délka života bubliny ms ms - abbreviation for milliseconds ms Mini mixer device Zařízení malého směšovače Default Výchozí Current (same as in main mixer window) Nynější (stejné jako v hlavním okně se směšovačem) User defined Stanoveno uživatelem User device: Uživatelské zařízení: e.g. hw:0 Např. hw:0 qastools-v0.22.0/i18n/ts/app_de.ts000066400000000000000000001475711354534512100166550ustar00rootroot00000000000000 UTF-8 ALSA::CTL_Arg_Name CARD Karte SOCKET Socket CTL CTL ALSA::CTL_Elem_IFace_Name CARD Karte HWDEP Gerätespez. MIXER Mixer PCM PCM RAWMIDI Rohmidi TIMER Zeitgeber SEQUENCER Sequencer Unknown Unbekannt ALSA::CTL_Elem_Type_Name NONE Unbekannt BOOLEAN Bool INTEGER Integer ENUMERATED Aufzählung BYTES Bytes IEC958 IEC958 INTEGER64 Integer64 Unknown Unbekannt ALSA::Channel_Name Front Left Vorne links Front Right Vorne rechts Rear Left Hinten links Rear Right Hinten rechts Front Center Vorne Mitte Woofer Tieftöner Side Left Seite links Side Right Seite rechts Rear Center Hinten Mitte ALSA::Elem_Name Master Hauptregler Speaker Lautsprecher Headphone Kopfhörer Headphone LFE Kopfhörer LFE Headphone Center Kopfhörer Mitte Front Vorne Auto-Mute Mode Auto-Stumm-Modus Front Mic Mik. Vorne Front Mic Boost Mik. Vorne Verstärkung Mic Mikrofon Mic Boost Mik. Verstärkung Phone Telefon Surround Umgebung Video Video Center Mitte Side Seite Capture Aufnahme Beep Signalton PC Speaker PC Lautsprecher Bass Bässe Treble Höhen Channel Mode Kanal Modus Auto Gain Control Autom. Verst.-Regelung Mic Select Mikrofonwahl Internal Mic Internes Mik. Int Mic Internes Mik. External Mic Externes Mik. Ext Mic Externes Mik. Mic Boost (+20dB) Mik. Verst. (+20dB) External Amplifier Externer Verstärker Input Source Eingangsquelle ALSA::Enum_Value 1ch 1 Kan. 2ch 2 Kan. 3ch 3 Kan. 4ch 4 Kan. 5ch 5 Kan. 6ch 6 Kan. 7ch 7 Kan. 8ch 8 Kan. Internal Mic Internes Mik. Mic Mikrofon Front Mic Mik. Vorne Enabled Aktiviert Disabled Deaktiviert Mic1 Mik. 1 Mic2 Mik. 2 Mic3 Mik. 3 Mic4 Mik. 4 Video Video Phone Telefon ALSA::Flags not readable nicht lesbar readable lesbar not writable nicht schreibbar writable schreibbar not volatile nicht volatil volatile volatil not active nicht aktiv active aktiv MWdg::Inputs_Setup s "s" is an abbreviation for "split" or "separate". Something like "j" for "joined" or "c" for "channel" may be appropriate, too. Trennen t l "l" is an abbreviation for "level" Nivellieren n m "m" is an abbreviation for "mute" Stumm s p "p" is an abbreviation for "playback" Wiedergabe w c "c" is an abbreviation for "capture" or "record" Aufnahme a Split &channels Used in the context menu (slider/switch right click menu) &Kanäle trennen Join &channels Used in the context menu (slider/switch right click menu) &Kanäle verbinden &Level channels Used in the context menu (slider/switch right click menu) Kanäle &nivellieren MWdg::Mixer_HCTL Element name Elementname Joined Verbunden Element index Elementindex Channel %1 Kanal %1 Ch. %1 Kan. %1 Index: %1 Index: %1 Channel: %2 Kanal: %2 Index: Index: Device: Gerät: Flags: Flaggen: Channels: Kanäle: Num. id: Num. id: Device Gerät Flags Flaggen Channel count Kanalanzahl Numeric Id Numerische Id Subdevice Untergerät No element selected Kein Element ausgewählt MWdg::Mixer_HCTL_Edit_Int minimum Minimum maximum Maximum Integer range: Integerbereich: Decibel range: Dezibelbereich: Channel %1 Kanal %1 Index %1 Index %1 MWdg::Mixer_HCTL_Edit_Unsupported Elements of the type %1 are not supported Elemente vom Typ %1 werden nicht unterstützt MWdg::Mixer_HCTL_Int_Proxy_Column %1 dB Decibel value string template %1 dB %1 % Percent value string template %1 % MWdg::Mixer_HCTL_Table_Model %1,%2 %1,%2 Name Name Element name Elementname Idx Idx - abbreviation for Index Idx Element index Elementindex Device Gerät Type Typ Element type Elementtyp Ch. Ch. - abbreviation for Channel Kan. Channel count Kanalanzahl Flags Flaggen Id Id Numeric Id Numerische Id MWdg::Mixer_Sliders &Mute Aus&schalten &Mute all Alle aus&schalten Un&mute Ein&schalten Un&mute all Alle Ein&schalten Toggle &mutes Um&schalten Playback slider Wiedergabeschieber Capture slider Aufnahmeschieber Playback switch Wiedergabeschalter Capture switch Aufnahmeschalter %1 (%2) %1 (%2) MWdg::Mixer_Sliders_Proxies_Column %1 dB %1 dB %1 % %1 % MWdg::Mixer_Switches %1 (%2) %1 (%2) Playback selection Wiedergabeauswahl Playback switch Wiedergabeschalter Capture selection Aufnahmeauswahl Capture switch Aufnahmeschalter MWdg::Slider_Status_Widget Slider value Reglerwert Value Wert Max. Max. Maximum Maximum Min. Min. Minimum Minimum Volume Lautstärke Current volume Aktuelle Lautstärke Volume maximum Lautstärken-Maximum Volume minimum Lautstärken-Minimum Decibel Dezibel Current Decibel value Aktueller Dezibel-Wert Decibel maximum Dezibel-Maximum Decibel minimum Dezibel-Minimum Element name Elementname Close slider value display Reglerwertanzeige schließen Main_Window &Fullscreen mode Voll&bildmodus Exit &fullscreen mode Voll&bildmodus verlassen &Quit &Beenden &Settings &Einstellungen Ctrl+s Ctrl+e &Refresh Auff&rischen Show &device selection &Geräteauswahl anzeigen &Info &Über &File &Datei &View &Ansicht &Help &Hilfe QSnd::Alsa_Config_Model Key Schlüssel Value Wert QSnd::Mixer_HCTL Empty device name Gerätename ist leer QSnd::Mixer_Simple Empty device name Gerätename ist leer Tray_Mixer_Balloon Volume is at %1% Lautstärke ist bei %1% Show mixer Mixer anzeigen Volume muted Stummgeschaltet Tray_Mixer_Icon &Show mixer Mixer &anzeigen Ctrl+s Ctrl+s &Close %1 %1 will be replaced with the program title %1 &beenden Views::Alsa_Config_View ALSA configuration ALSA-Konfiguration &Expand &Ausklappen Co&llapse &Einklappen &Sort &Sortieren Depth: Tiefe: Views::Basic_Dialog &Close &Schließen Views::Device_Selection_View &Close device selection Geräteauswahl &schließen Mixer device Mixergerät Views::Info_Dialog Info Über About Über Internet Im Internet Home page Hauptseite Project page Projektseite Developers Entwickler Translators Übersetzer Information Information People Leute License Lizenz %1 is a collection of desktop applications for the Linux sound system %2. %1 ist eine Sammlung von Schreibtischanwendungen für die Linux-Klang-Architektur %2. Contributors Mitwirkende The license file %1 is not available. Die Lizenzdatei %1 ist nicht verfügbar. Views::Message_Widget Mixer device couldn't be opened Das Gerät konnte nicht geöffnet werden No device selected Kein Gerät ausgewählt Function Funktion Address Adresse Error Fehler Views::Mixer_Simple Show playback Wiedergabe anzeigen Show capture Aufnahme anzeigen Show playback elements Wiedergabe-Elemente anzeigen Show capture elements Aufnahme-Elemente anzeigen Views::Settings_Dialog Settings Einstellungen Startup Start Sliders Schieberegler Appearance Erscheinungsbild Input Eingabe System tray Systemleiste Startup mixer device Mixergerät beim Start From last session Von letzter Sitzung Show slider value labels Reglerwerte anzeigen Mouse wheel Mausrad Number of turns for a slider change from 0% to 100% Umdrehungen für eine Schieberänderung von 0% auf 100% Show tray icon Symbol anzeigen Close to tray In Systemleiste schließen System tray usage Systemleistennutzung Notification balloon Benachrichtigungsballon Show balloon on a volume change Ballon bei einer Lautstärkenänderung anzeigen Balloon lifetime Ballon-Lebensdauer ms ms - abbreviation for milliseconds ms Mini mixer device Minimixergerät Default Standard Current (same as in main mixer window) Aktuell (das Gleiche wie im Mixerfenster) User defined Benutzerdefiniert User device: Benutzergerät: e.g. hw:0 z.B. hw:0 qastools-v0.22.0/i18n/ts/app_default.ts000066400000000000000000001515171354534512100177040ustar00rootroot00000000000000 ALSA::CTL_Arg_Name CARD Card SOCKET Socket CTL CTL ALSA::CTL_Elem_IFace_Name CARD Card HWDEP MIXER PCM RAWMIDI TIMER SEQUENCER Unknown ALSA::CTL_Elem_Type_Name NONE BOOLEAN INTEGER ENUMERATED BYTES IEC958 INTEGER64 Unknown ALSA::Channel_Name Front Left Front Right Rear Left Rear Right Front Center Woofer Side Left Side Right Rear Center ALSA::Elem_Name Auto Gain Control Auto-Mute Mode Bass Beep Capture Center Channel Mode External Amplifier External Mic Ext Mic Front Front Mic Front Mic Boost Headphone Headphone LFE Headphone Center Input Source Internal Mic Int Mic Master Mic Mic Boost Mic Boost (+20dB) Mic Select PC Speaker Phone Side Speaker Surround Treble Video ALSA::Enum_Value Enabled Disabled 1ch 2ch 3ch 4ch 5ch 6ch 7ch 8ch Front Mic Internal Mic Mic Mic1 Mic2 Mic3 Mic4 Video Phone ALSA::Flags not readable readable not writable writable not volatile volatile not active active MWdg::Inputs_Setup s "s" is an abbreviation for "split" or "separate". Something like "j" for "joined" or "c" for "channel" may be appropriate, too. l "l" is an abbreviation for "level" m "m" is an abbreviation for "mute" p "p" is an abbreviation for "playback" c "c" is an abbreviation for "capture" or "record" Split &channels Used in the context menu (slider/switch right click menu) Join &channels Used in the context menu (slider/switch right click menu) &Level channels Used in the context menu (slider/switch right click menu) MWdg::Mixer_HCTL Element name Joined Element index Channel %1 Ch. %1 Index: %1 Channel: %2 Index: Device: Flags: Channels: Num. id: Device Flags Channel count Numeric Id Subdevice No element selected MWdg::Mixer_HCTL_Edit_Int minimum maximum Integer range: Decibel range: Channel %1 Index %1 MWdg::Mixer_HCTL_Edit_Unsupported Elements of the type %1 are not supported MWdg::Mixer_HCTL_Int_Proxy_Column %1 dB Decibel value string template %1 % Percent value string template MWdg::Mixer_HCTL_Table_Model %1,%2 Name Element name Idx Idx - abbreviation for Index Element index Device Type Element type Ch. Ch. - abbreviation for Channel Channel count Flags Id Numeric Id MWdg::Mixer_Sliders &Mute &Mute all Un&mute Un&mute all Toggle &mutes Playback slider Capture slider Playback switch Capture switch %1 (%2) MWdg::Mixer_Sliders_Proxies_Column %1 dB %1 % MWdg::Mixer_Switches %1 (%2) Playback selection Playback switch Capture selection Capture switch MWdg::Slider_Status_Widget Slider value Value Max. Maximum Min. Minimum Volume Current volume Volume maximum Volume minimum Decibel Current Decibel value Decibel maximum Decibel minimum Element name Close slider value display Main_Window &Fullscreen mode Exit &fullscreen mode &Quit &Settings Ctrl+s &Refresh Show &device selection &Info &File &View &Help QSnd::Alsa_Config_Model Key Value QSnd::Mixer_HCTL Empty device name QSnd::Mixer_Simple Empty device name Tray_Mixer_Balloon Volume is at %1% Show mixer Volume muted Tray_Mixer_Icon &Show mixer Ctrl+s &Close %1 %1 will be replaced with the program title Views::Alsa_Config_View ALSA configuration &Expand Co&llapse &Sort Depth: Views::Basic_Dialog &Close Views::Device_Selection_View &Close device selection Plugin Views::Info_Dialog Info About %1 is a collection of desktop applications for the Linux sound system %2. Internet Home page Project page Developers Translators Information People License Contributors The license file %1 is not available. Views::Message_Widget Mixer device couldn't be opened No device selected Function Address Error Views::Mixer_Simple Show playback Show capture Show playback elements Show capture elements Views::Settings_Dialog Settings Startup Sliders Appearance Input System tray Startup mixer device From last session Show slider value labels Mouse wheel Number of turns for a slider change from 0% to 100% Show tray icon Close to tray System tray usage Notification balloon Show balloon on a volume change Balloon lifetime ms ms - abbreviation for milliseconds Mini mixer device Default Current (same as in main mixer window) User defined User device: e.g. hw:0 qastools-v0.22.0/i18n/ts/app_es.ts000066400000000000000000001546021354534512100166650ustar00rootroot00000000000000 ALSA::CTL_Arg_Name CARD Mapa SOCKET CTL ALSA::CTL_Elem_IFace_Name CARD Mapa HWDEP Dispositivo MIXER Mezcla Mezclador PCM Pulse Code Modulation PCM RAWMIDI Midi puro RAW Midi TIMER Tempo Temporizador SEQUENCER Seq Secuenciador Unknown Desconocido ALSA::CTL_Elem_Type_Name NONE Nada BOOLEAN Bool Booleano INTEGER Entero ENUMERATED Enumerado Numerado BYTES Bytes IEC958 S/PDIF IEC958 INTEGER64 Entero64 Unknown Desconocido ALSA::Channel_Name Front Left Frontal Izquierdo Front Right Frontal Derecho Rear Left Trasero Izquierdo Rear Right Trasero Derecho Front Center Frontal Central Woofer SubWoofer Graves Side Left Lado Izquierdo Side Right Lado Derecho Rear Center Trasero Central ALSA::Elem_Name Auto Gain Control Ganancia automática Auto-Mute Mode Modo Auto-Mute Bass Graves Bajos Beep Señal Beep Capture Captura Center Centro Channel Mode Modo de canal External Amplifier Amplificador externo External Mic Micrófono externo Ext Mic Mix ext Front Frontal Front Mic Mic frontal Front Mic Boost Ganancia mic frontal Headphone Auriculares Headphone LFE Auriculares lateral Headphone Center Auriculares centro Input Source Entrada Internal Mic Micrófono interno Int Mic Mic interno Master Maestro Mic Mic Mic Boost Ganancia mic Mic Boost (+20dB) Ganancia mic (+20dB) Mic Select Selección mic PC Speaker Altavoz PC Phone Teléfono Side Lado Speaker Altavoz Surround Surround Envolvente Treble Altos Agudos Video Video ALSA::Enum_Value Enabled Activado Disabled Desactivado 1ch o1 canal 1 2ch o2 canal 2 3ch o3 canal 3 4ch o4 canal 4 5ch o5 canal 5 6ch o6 canal 6 7ch o7 canal 7 8ch o8 canal 8 Front Mic Micrófono frontal Internal Mic Micrófono interno Mic Mic Micrófono Mic1 i1 Mic 1 Mic2 i2 Mic 2 Mic3 i3 Mic 3 Mic4 i4 Mic 4 Video Video Phone Teléfono ALSA::Flags not readable no legible readable legible not writable no escribible writable escribible not volatile no volatil volatile volatil not active no activo active activo MWdg::Inputs_Setup s "s" is an abbreviation for "split" or "separate". Something like "j" for "joined" or "c" for "channel" may be appropriate, too. separado s l "l" is an abbreviation for "level" nivel n m "m" is an abbreviation for "mute" mutar m p "p" is an abbreviation for "playback" reproducción r c "c" is an abbreviation for "capture" or "record" captura c Split &channels Used in the context menu (slider/switch right click menu) Separar &canales Join &channels Used in the context menu (slider/switch right click menu) Unir &canales &Level channels Used in the context menu (slider/switch right click menu) &nivel canales MWdg::Mixer_HCTL Element name Nombre del elemento Joined Unido Element index Índice del elemento Channel %1 Canal %1 Ch. %1 Ch. %1 Index: %1 Índice: %1 Channel: %2 Canal: %2 Index: Índice: Device: Dispositivo: Flags: Estado: Channels: Canales: Num. id: Núm. Id.: Device Dispositivo Flags Estado Channel count Contador de canal Numeric Id Id. numérico Subdevice Subdispositivo No element selected Nada seleccionado MWdg::Mixer_HCTL_Edit_Int minimum mínimo maximum máximo Integer range: Rango entero: Decibel range: Rando dB: Channel %1 Canal %1 Index %1 Índice %1 MWdg::Mixer_HCTL_Edit_Unsupported Elements of the type %1 are not supported Elementos del tipo %1 NO soportados. MWdg::Mixer_HCTL_Int_Proxy_Column %1 dB Decibel value string template %1 dB %1 % Percent value string template %1 % MWdg::Mixer_HCTL_Table_Model %1,%2 %1,%2 Name Nombre Element name Nombre del elemento Idx Idx - abbreviation for Index Idx Element index Índice del elemento Device Dispositivo Type Tipo Element type Tipo elem. Ch. Ch. - abbreviation for Channel Ch. Channel count Contador de canal Flags Estado Id Id Numeric Id Id. numérico MWdg::Mixer_Sliders &Mute &Silenciar &Mute all &Silenciar todo Un&mute Des&silenciar Un&mute all Des&silenciar todo Toggle &mutes Alternat &silencios Playback slider Deslizador de reproducción Capture slider Deslizador de captura Playback switch Interruptor de reproducción Capture switch Interruptor de captura %1 (%2) %1 (%2) MWdg::Mixer_Sliders_Proxies_Column %1 dB %1 dB %1 % %1 % MWdg::Mixer_Switches %1 (%2) %1 (%2) Playback selection Selección de reproducción Playback switch Interruptor de reproducción Capture selection Selección de captura Capture switch Interruptor de captura MWdg::Slider_Status_Widget Slider value Valor deslizador Value Valor Max. Máx. Maximum Máximo Min. Mín. Minimum Mínimo Volume Volumen Current volume Volumen actual Volume maximum Volumen máximo Volume minimum Volumen mínimo Decibel Decibelios Current Decibel value Valor actual de dB Decibel maximum dB máximo Decibel minimum dB mínimo Element name Nombre del elemento Close slider value display deslizador reducido (valor mostrado) Main_Window &Fullscreen mode &Pantalla completa Exit &fullscreen mode Salir de &pantalla completa &Quit &Cerrar &Settings &Preferencias Ctrl+s Ctrl+s &Refresh &Actualizar Show &device selection &Dispositivo &Info &Información &File &Fichero &View &Ver &Help &Ayuda Mixer device Dispositivo de mezcla QSnd::Alsa_Config_Model Key Clave Value Valor QSnd::Mixer_HCTL Empty device name Dispositivo sin nombre QSnd::Mixer_Simple Empty device name Dispositivo sin nombre Tray_Mixer_Balloon Volume is at %1% Volumen al %1% Show mixer Mostrar mezclador Volume muted Silenciado Tray_Mixer_Icon &Show mixer Alzar Ctrl+s Ctrl+s &Close %1 %1 will be replaced with the program title &Cerrar %1 Views::Alsa_Config_View ALSA configuration Configuración ALSA &Expand &Expandir Co&llapse &Colapsar &Sort &Ordenar Depth: Profundidad: Views::Basic_Dialog &Close &Cerrar Views::Device_Selection_View &Close device selection &Cerrar selección de dispositivo Plugin Views::Info_Dialog Info Información %1 - %2 %1 - %2 About Acerca de Internet Internet Home page Auspicia Project page Página Developers Desarrolladores Translators Traductores Information People License %1 is a collection of desktop applications for the Linux sound system %2. Contributors Colaboran The license file %1 is not available. Licencia %1 no disponible. &Information &Información &People &Gente &License &Licencia &Close &Cerrar Views::Message_Widget Mixer device couldn't be opened El dispositivo de mezcla no se pudo abrir No device selected Nada seleccionado Function Función Address Error Error Views::Mixer_Simple Show playback Mostrar reproducción Show capture Mostrar captura Show playback elements Mostrar elementos de reproducción Show capture elements Mostrar elementos de captura Views::Settings_Dialog Settings Preferencias Startup Sliders Appearance Apariencia Input Entrada System tray Icono de bandeja &Close &Cerrar Startup mixer device From last session Simple mixer view Mezclador Show slider value labels Mostrar valor Mouse wheel Rueda del ratón Number of turns for a slider change from 0% to 100% Giros para cambar del 0% al 100% Show tray icon Mostrar icono en bandeja Close to tray Cerrar en bandeja System tray usage Uso de bandeja del sistema Notification balloon Notificación Show balloon on a volume change Mostrar en balón Balloon lifetime Tiempo de notificación ms ms - abbreviation for milliseconds milisegundos ms Mini mixer device Control en bandeja Default Por defecto Current (same as in main mixer window) Seleccionado User defined Específico User device: Dispositivo de usuario: e.g. hw:0 ej. hw:0 qastools-v0.22.0/i18n/ts/app_he.ts000066400000000000000000001524661354534512100166600ustar00rootroot00000000000000 ALSA::CTL_Arg_Name CARD כרטיס SOCKET שקע CTL ‏CTL ALSA::CTL_Elem_IFace_Name CARD כרטיס HWDEP MIXER מערבל PCM RAWMIDI TIMER קוצב זמן SEQUENCER סקוונסר Unknown לא מוכר ALSA::CTL_Elem_Type_Name NONE BOOLEAN INTEGER ENUMERATED BYTES IEC958 INTEGER64 Unknown לא מוכר ALSA::Channel_Name Front Left חזית שמאל Front Right חזית ימין Rear Left עורף שמאל Rear Right עורף ימין Front Center חזית מרכז Woofer וופר Side Left צד שמאל Side Right צד ימין Rear Center מרכז עורף ALSA::Elem_Name Auto Gain Control בקרת תוספת אוטומטית Auto-Mute Mode מצב השתק-אוטומטי Bass בס Beep ביפ Capture לכידה Center מרכז Channel Mode מצב ערוץ External Amplifier מגבר חיצוני External Mic מיקרופון חיצוני Ext Mic מיקרופון חיצוני Front חזית Front Mic מיקרופון חזיתי Front Mic Boost מינוף מיקרופון חזיתי Headphone אוזנייה Headphone LFE אוזנייה LFE Headphone Center אוזנייה מרכז Input Source קלט מקור Internal Mic מיקרופון פנימי Int Mic מיקרופון פנימי Master ראשי Mic מיקרופון Mic Boost מינוף מיקרופון Mic Boost (+20dB) מינוף מיקרופון (‎+20דציבל) Mic Select ברירת מיקרופון PC Speaker רמקול PC Phone טלפון Side צד Speaker רמקול Surround סראונד Treble לשלש, פי שלושה טרבל Video וידאו ALSA::Enum_Value Enabled מאופשר Disabled מנוטרל 1ch 1ער 2ch 2ער 3ch 3ער 4ch 4ער 5ch 5ער 6ch 6ער 7ch 7ער 8ch 8ער Front Mic מיקרופון חזיתי Internal Mic מיקרופון פנימי Mic מיק Mic1 מיק1 Mic2 מיק2 Mic3 מיק3 Mic4 מיק4 Video וידאו Phone טלפון ALSA::Flags not readable לא קריא readable בר קריאה קריא not writable לא כתיב writable בר כתיבה כתיב not volatile לא נדיף volatile נדיף not active לא פעיל active פעיל MWdg::Inputs_Setup s "s" is an abbreviation for "split" or "separate". Something like "j" for "joined" or "c" for "channel" may be appropriate, too. פ l "l" is an abbreviation for "level" א m "m" is an abbreviation for "mute" ש p "p" is an abbreviation for "playback" פ c "c" is an abbreviation for "capture" or "record" ל Split &channels Used in the context menu (slider/switch right click menu) פצל &ערוצים Join &channels Used in the context menu (slider/switch right click menu) מזג שלב &ערוצים &Level channels Used in the context menu (slider/switch right click menu) &אזן ערוצים MWdg::Mixer_HCTL Element name שם אלמנט Joined משולבים Element index מפתח אלמנט Channel %1 ערוץ %1 Ch. %1 ער. %1 Index: %1 מדד: %1 Channel: %2 ערוץ: %2 Index: מדד: Device: התקן: Flags: דגלים: Channels: ערוצים: Num. id: מזהה מס׳: Device התקן Flags דגלים Channel count ספירת ערוץ Numeric Id מזהה מספרי Subdevice התקן משנה No element selected לא נבחר אלמנט MWdg::Mixer_HCTL_Edit_Int minimum מינימום maximum מקסימום Integer range: טווח מספר: Decibel range: טווח דציבל: Channel %1 ערוץ %1 Index %1 מדד %1 MWdg::Mixer_HCTL_Edit_Unsupported Elements of the type %1 are not supported אלמנטים של הטיפוס %1 אינם נתמכים MWdg::Mixer_HCTL_Int_Proxy_Column %1 dB Decibel value string template %1 דציבל %1 % Percent value string template MWdg::Mixer_HCTL_Table_Model %1,%2 Name שם Element name שם אלמנט Idx Idx - abbreviation for Index מדד Element index מפתח אלמנט Device התקן Type טיפוס Element type טיפוס אלמנט Ch. Ch. - abbreviation for Channel ער. Channel count ספירת ערוץ Flags דגלים Id מזהה Numeric Id מזהה מספרי MWdg::Mixer_Sliders &Mute &השתק &Mute all &השתק הכל Un&mute איין &השתקה Un&mute all &איין השתקה מוחלטת איין &השתק הכל Toggle &mutes השתקות החלף &השתק Playback slider מחוון פס קול Capture slider מחוון לכידה Playback switch מתג פס קול Capture switch מתג לכידה %1 (%2) MWdg::Mixer_Sliders_Proxies_Column %1 dB ‎%1 דציבל %1 % MWdg::Mixer_Switches %1 (%2) Playback selection מבחר פס קול Playback switch מתג פס קול Capture selection מבחר לכידה Capture switch מתג לכידה MWdg::Slider_Status_Widget Slider value ערך מחוון Value ערך Max. מקס. Maximum מקסימום Min. מינ. Minimum מינימום Volume עוצמה Current volume עוצמה נוכחית Volume maximum עוצמה מקסימום Volume minimum עוצמה מינימום Decibel דציבל Current Decibel value ערך דציבל נוכחי Decibel maximum דציבל מקסימום Decibel minimum דציבל מינימום Element name שם אלמנט Close slider value display סגור תצוגת ערך מחוון Main_Window &Fullscreen mode &מצב מסך מלא Exit &fullscreen mode בטל &מצב מסך מלא &Quit י&ציאה &Settings &הגדרות Ctrl+s &Refresh &רענן Show &device selection מבחר (של) התקן &הצג מבחר התקנים &Info &מידע &File &קובץ &View &תצוגה &Help &עזרה QSnd::Alsa_Config_Model Key מפתח Value ערך QSnd::Mixer_HCTL Empty device name שם התקן ריק QSnd::Mixer_Simple Empty device name שם התקן ריק Tray_Mixer_Balloon Volume is at %1% עוצמה מצויה ברמה של %1% Show mixer הצג מערבל Volume muted עוצמה מושתקת Tray_Mixer_Icon &Show mixer &הצג מערבל Ctrl+s &Close %1 %1 will be replaced with the program title &סגור את %1 Views::Alsa_Config_View ALSA configuration תצורת ALSA &Expand ה&רחבה Co&llapse &צמצום &Sort &סדר Depth: עומק: Views::Basic_Dialog &Close &סגור Views::Device_Selection_View &Close device selection &סגור מבחר התקנים Plugin תוספת Views::Info_Dialog Info מידע About אודות %1 is a collection of desktop applications for the Linux sound system %2. ‏%1 הינו אוסף של יישומים שולחניים עבור מערכת הצלילים של Linux ‏%2. Internet ‎מרשתת Home page עמוד בית Project page עמוד פרויקט Developers ‎מפתחים Translators ‎מתרגמים Information מידע People אנשים License רשיון Contributors ‎תורמים The license file %1 is not available. קובץ הרשיון %1 אינו זמין. Views::Message_Widget Mixer device couldn't be opened התקן מערבל לא היה ניתן לפתיחה No device selected לא נבחר התקן Function פונקציה Address כתובת Error שגיאה Views::Mixer_Simple Show playback הצג פס קול Show capture הצג לכידה Show playback elements הצג אלמנטים של פס קול Show capture elements הצג אלמנטים של לכידה Views::Settings_Dialog Settings הגדרות Startup הפעלה Sliders מחוונים Appearance מראה Input קלט System tray מגש מערכת Startup mixer device התקן מערבל הפעלה From last session מן סשן קודם Show slider value labels הצג ערך תוויות מחוון Mouse wheel גלגל עכבר Number of turns for a slider change from 0% to 100% מספר של סיבובים לשינוי מחוון מן 0% עד 100% Show tray icon הצג סמל מגש Close to tray סגור אל מגש System tray usage שימוש במגש מערכת Notification balloon בלון התראה Show balloon on a volume change הצג בלון בעת שינוי עוצמה Balloon lifetime תוכלת חיי בלון ms ms - abbreviation for milliseconds מ״ש Mini mixer device מיניאטורי התקן מערבל מוקטן Default משתמט Current (same as in main mixer window) נוכחי (זהה כמו אצל חלון מערבל ראשי) User defined מוגדר משתמש User device: התקן משתמש: e.g. hw:0 לדוגמא hw:0 qastools-v0.22.0/i18n/ts/app_ru.ts000066400000000000000000001544531354534512100167100ustar00rootroot00000000000000 ALSA::CTL_Arg_Name CARD CARD SOCKET SOCKET CTL CTL ALSA::CTL_Elem_IFace_Name CARD CARD HWDEP HWDEP MIXER MIXER PCM PCM RAWMIDI RAWMIDI TIMER TIMER SEQUENCER SEQUENCER Unknown Unknown ALSA::CTL_Elem_Type_Name NONE NONE BOOLEAN BOOLEAN INTEGER INTEGER ENUMERATED ENUMERATED BYTES BYTES IEC958 S/PDIF IEC958 INTEGER64 INTEGER64 Unknown Unknown ALSA::Channel_Name Front Left Фронтальный левый Front Right Фронтальный правый Rear Left Задний левый Rear Right Задний правый Front Center Фронтальный центральный Woofer SubWoofer Сабвуфер Side Left Боковой левый Side Right Боковой правый Rear Center Задний центральный ALSA::Elem_Name Auto Gain Control Auto Gain Control Auto-Mute Mode Auto-Mute Mode Bass Bass Beep Beep Capture Capture Center Center Channel Mode Channel Mode External Amplifier External Amplifier External Mic External Mic Ext Mic Ext Mic Front Front Front Mic Front Mic Front Mic Boost Front Mic Boost Headphone Headphone Headphone LFE Headphone LFE Headphone Center Headphone Center Input Source Input Source Internal Mic Internal Mic Int Mic Int Mic Master Master Mic Микрофон Mic Boost Mic Boost Mic Boost (+20dB) Mic Boost (+20dB) Mic Select Mic Select PC Speaker PC Speaker Phone Phone Side Side Speaker Speaker Surround Surround Treble Treble Video Video ALSA::Enum_Value Enabled Enabled Disabled Disabled 1ch 1ch 2ch 2ch 3ch 3ch 4ch 4ch 5ch 5ch 6ch 6ch 7ch 7ch 8ch 8ch Front Mic Front Mic Internal Mic Internal Mic Mic Микрофон Mic1 Микрофон 1 Mic2 Микрофон 2 Mic3 Микрофон 3 Mic4 Микрофон 4 Video Video Phone Phone ALSA::Flags not readable не доступен на чтение readable доступен на чтение not writable не доступен на запись writable доступен на запись not volatile неизменяющийся volatile изменяющийся not active не активен active активен MWdg::Inputs_Setup s "s" is an abbreviation for "split" or "separate". Something like "j" for "joined" or "c" for "channel" may be appropriate, too. s l "l" is an abbreviation for "level" l m "m" is an abbreviation for "mute" m p "p" is an abbreviation for "playback" p c "c" is an abbreviation for "capture" or "record" c Split &channels Used in the context menu (slider/switch right click menu) Разделить &каналы Join &channels Used in the context menu (slider/switch right click menu) Объединить &каналы &Level channels Used in the context menu (slider/switch right click menu) Выровнять &громкость MWdg::Mixer_HCTL Element name Название элемента Joined Объединить Element index Номер элемента Channel %1 Канал %1 Ch. %1 Канал %1 Index: %1 Номер: %1 Channel: %2 Номер канала: %2 Index: Номер: Device: Устройство: Flags: Флаги: Channels: Количество каналов: Num. id: Числовой идентификатор: Device Устройство Flags Флаги Channel count Количество каналов Numeric Id Числовой идентификатор Subdevice Дочернее устройство No element selected Элемент не выбран MWdg::Mixer_HCTL_Edit_Int minimum минимум maximum максимум Integer range: Целочисленный диапазон: Decibel range: Диапазон (дБ): Channel %1 Канал %1 Index %1 Номер %1 MWdg::Mixer_HCTL_Edit_Unsupported Elements of the type %1 are not supported Элемент типа %1 не поддерживается MWdg::Mixer_HCTL_Int_Proxy_Column %1 dB Decibel value string template %1 дБ %1 % Percent value string template %1 % MWdg::Mixer_HCTL_Table_Model %1,%2 %1,%2 Name Название Element name Название элемента Idx Idx - abbreviation for Index Номер Element index Номер элемента Device Устройство Type Тип Element type Тип элемента Ch. Ch. - abbreviation for Channel Ch. Channel count Количество каналов Flags Флаги Id Id Numeric Id Числовой идентификатор MWdg::Mixer_Sliders &Mute &Выключить звук &Mute all &Выключить звук у всех каналов Un&mute &Включить звук Un&mute all &Включить звук у всех каналов Toggle &mutes &Включить/выключить звук Playback slider Регулятор громкости воспроизведения Capture slider Регулятор громкости записи Playback switch Выключатель воспроизведения Capture switch Выключатель записи %1 (%2) %1 (%2) MWdg::Mixer_Sliders_Proxies_Column %1 dB %1 дБ %1 % %1 % MWdg::Mixer_Switches %1 (%2) %1 (%2) Playback selection Playback selection Playback switch Выключатель воспроизведения Capture selection Capture selection Capture switch Выключатель записи MWdg::Slider_Status_Widget Slider value Состояние канала Value Значение Max. Макс. Maximum Максимальное Min. Мин. Minimum Минимальное Volume Громкость Current volume Текущая громкость Volume maximum Максимальная громкость Volume minimum Минимальная громкость Decibel Громкость (дБ) Current Decibel value Текущая громкость (дБ) Decibel maximum Максимальная громкость (дБ) Decibel minimum Минимальная громкость (дБ) Element name Название элемента Close slider value display Закрыть Main_Window &Fullscreen mode П&олноэкранный режим Exit &fullscreen mode Выйти из п&олноэкранного режима &Quit &Выход &Settings &Настройки Ctrl+s Ctrl+s &Refresh &Обновить Show &device selection Отображать панель выбора &устройства &Info &Информация &File &Файл &View &Вид &Help &Помощь QSnd::Alsa_Config_Model Key Ключ Value Значение QSnd::Mixer_HCTL Empty device name Имя устройства пусто QSnd::Mixer_Simple Empty device name Имя устройства пусто Tray_Mixer_Balloon Volume is at %1% Текущая громкость %1% Show mixer Отображать микшер Volume muted Звук выключен Tray_Mixer_Icon &Show mixer &Отображать микшер Ctrl+s Ctrl+s &Close %1 %1 will be replaced with the program title &Закрыть %1 Views::Alsa_Config_View ALSA configuration Конфигурация ALSA &Expand &Раскрыть Co&llapse &Свернуть &Sort &Упорядочить Depth: Глубина: Views::Basic_Dialog &Close &Закрыть Views::Device_Selection_View &Close device selection Закрыть панель выбора у&стройства Mixer device Устройство Views::Info_Dialog Info Информация About О программе Internet Интернет Home page Домашняя страница Project page Страница проекта Developers Программирование Translators Перевод Information Информация People Авторы License Лицензия %1 is a collection of desktop applications for the Linux sound system %2. %1 — это набор приложений для работы со звуковой системой %2. Contributors Участники The license file %1 is not available. Файл лицензии %1 не доступен. Views::Message_Widget Mixer device couldn't be opened Не удалось открыть микшер No device selected Устройство не выбрано Function Функция Address Адрес Error Ошибка Views::Mixer_Simple Show playback Отображать элементы востроизведения Show capture Отображать элементы записи Show playback elements Отображать элементы воспроизведения Show capture elements Отображать элементы записи Views::Settings_Dialog Settings Настройки Startup Запуск Sliders Регуляторы громкости Appearance Внешний вид Input Управление System tray Трей Startup mixer device Устройство используемое после запуска From last session Из предыдущей сессии Show slider value labels Отображать текущее значение громкости числом Mouse wheel Колесико мыши Number of turns for a slider change from 0% to 100% Количество оборотов колесика мыши, чтобы изменить громкость от 0% до 100% Show tray icon Отображать значок в трее Close to tray Закрываться в трей System tray usage Использование системного трея Notification balloon Всплывающая подсказка Show balloon on a volume change Отображать всплывающую подсказку при изменении громкости Balloon lifetime Длительность всплывающей подсказки ms ms - abbreviation for milliseconds мс Mini mixer device Устройство для минимикшера Default Устройство по умолчанию Current (same as in main mixer window) Текущее (то же устройство, что и в главном окне) User defined Другое User device: Устройство: e.g. hw:0 Например: hw:0 qastools-v0.22.0/qasconfig/000077500000000000000000000000001354534512100156035ustar00rootroot00000000000000qastools-v0.22.0/qasconfig/CMakeLists.txt000066400000000000000000000011551354534512100203450ustar00rootroot00000000000000# Program name IF ( NOT PROGRAM_TITLE ) SET ( PROGRAM_TITLE "QasConfig" ) ENDIF ( NOT PROGRAM_TITLE ) IF ( NOT PROGRAM_NAME ) SET ( PROGRAM_NAME "qasconfig${PROGRAM_SUFFIX}" ) ENDIF ( NOT PROGRAM_NAME ) string ( TOUPPER ${PROGRAM_NAME} PROGRAM_NAME_UCASE ) # Program version SET ( VERSION_MAJOR ${PACKAGE_VERSION_MAJOR} ) SET ( VERSION_MINOR ${PACKAGE_VERSION_MINOR} ) SET ( VERSION_PATCH ${PACKAGE_VERSION_PATCH} ) SET ( VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}${VERSION_SUFFIX}" ) # Process subdirectories ADD_SUBDIRECTORY ( src ) ADD_SUBDIRECTORY ( graphics ) ADD_SUBDIRECTORY ( share ) qastools-v0.22.0/qasconfig/graphics/000077500000000000000000000000001354534512100174035ustar00rootroot00000000000000qastools-v0.22.0/qasconfig/graphics/CMakeLists.txt000066400000000000000000000011031354534512100221360ustar00rootroot00000000000000# Install application icons INSTALL( FILES icons/app-icon-16x16.png DESTINATION ${INSTALL_DIR_ICONS_PNG_16} RENAME ${PROGRAM_NAME}.png ) INSTALL( FILES icons/app-icon-32x32.png DESTINATION ${INSTALL_DIR_ICONS_PNG_32} RENAME ${PROGRAM_NAME}.png ) INSTALL( FILES icons/app-icon-48x48.png DESTINATION ${INSTALL_DIR_ICONS_PNG_48} RENAME ${PROGRAM_NAME}.png ) INSTALL( FILES icons/app-icon-64x64.png DESTINATION ${INSTALL_DIR_ICONS_PNG_64} RENAME ${PROGRAM_NAME}.png ) INSTALL( FILES icons/app-icon.svg DESTINATION ${INSTALL_DIR_ICONS_SVG} RENAME ${PROGRAM_NAME}.svg ) qastools-v0.22.0/qasconfig/graphics/icons/000077500000000000000000000000001354534512100205165ustar00rootroot00000000000000qastools-v0.22.0/qasconfig/graphics/icons/app-icon-16x16.png000066400000000000000000000023541354534512100235210ustar00rootroot00000000000000PNG  IHDROc#" vpAg\ƭbKGDC pHYsHHFk>wIDATHǭkLW8#Q-"`S."AE.BVhPłyb-ҐmZK_XҦ"`pg4~?ܓs=sv Yp̆w=-]zl%>+אy)*A^cL*{bbwK&h{z:7<%hh`Cz9#a_)ꙝ;;0g_`v`ޑN-,r7 Rl>!/ ,{1^\u9-JJa= <݁i mO|+0艷A.PYq. X r Wz_W:!Vs)! zgNƍ"~jxM-2TIPe-{Q.unChmZl(nbzNoRՖNs8"$ L.ҘAJ:&5BoVe"ӂ?h2prGEx։wej.Tbt# Ȯ $ I&I'!Z73ݹL!fum3r2tk=ڡȐB{18x[1bj/sycl_w\'#t':qQ??/Z[W#%آ5}ASb4$ W@AS+O-"4MmnsD~@|y|_Hf𤠥Q\{X&g_%@vI=ߘʉJU[wb%5mM% ~)7#$& v Pu*]<[2Pc歏sVtt:,Lg Jl@g@H mƚզ]ۜ'LOO60~/~>nip郒pπ_@0%MH(=<. ڭZVwFU;RV4ٷp~> !!qܙM$$cڮaiDXU*Iפ"4e@,d BtJM /'h#) G<^K9~@H;ڒ*fqYIENDB`qastools-v0.22.0/qasconfig/graphics/icons/app-icon-32x32.png000066400000000000000000000036451354534512100235210ustar00rootroot00000000000000PNG  IHDR #ꦷ vpAg bKGDC pHYsHHFk>0IDATh{PTU7Y,`Q>42KlHpYey,CY)4PAF9 DsȢS|4F2Pv>swfIͽ3{.*؄5*z%iu&I˨_*&J?>6Sb5|PPш~i]9^Ei,ͬl7?86/о:^\< =:^0 =vʏȜ'Vs'yrIJ4MU %P&Gs*·b]yS^DW~Fu#V+8uBeV#UI9g5ϐ]$D2g[}s3읓 ğ`aΫi;Q9 Pf 5aJZ[6Z-Y>nc֩M{&-֘*I2 _| p'TN 55`5`` ps[Upaݑ"Xٱ]7~lJ8P9.bgD-fcTrXc#G?}_cP'@o = pYοd3m\ ayV'U7@zy!-k̷`~0ko L$a]p^LV=sduՇl ,&Nhu/y~U*IENDB`qastools-v0.22.0/qasconfig/graphics/icons/app-icon-48x48.png000066400000000000000000000063201354534512100235300ustar00rootroot00000000000000PNG  IHDR00% vpAg00WbKGDC pHYsHHFk> [IDATxy\TwWEdw-#E &DqwPT 3.V̧-!Xb ZkT,SVAS,1Qp 7ėss~0`-vQNR&L <¼_@cchzMgiZ4L̸[̐Shj[^HUo?\wRﳴc-Y즫Ji=-[S,u4nKsW75l1;rK ->K;9r7v_u_s nۙQ}uc7k; ~!١#R2w~Nn@'L \;Yso*Bジ~5>7֯{Rɝzp_vyrӉ@ޭ$m#_Jt~6*j4i/5d^4^Yڹ^W]^l3~XC%NvUܵ' =+w7xE^+S6qzHf8+y\%RʦY㷉;ZUiuK=}Ν{=p/B%gp''0sgƪq˽!p7N5qs/r\nŞ-bgz,\ԳwOpS_Ɓ.<s(2O7?,181[p}6n>K =Z}5g k{9짾m:e7q﹜=Eg\V} LC#E}?~;+x\kǍKC.?{ z̢:~3{yn`35< w6nŏxTh N]=U)mOswĀ?'x84~3KEsq/l犸GGa{[Da;F\t}GqMwU7Ul7_0l Dܾ؟/.,Py7p7v{ͷ'[^ߣ™鋛55&lJ5U;buC> üuK;Nw J>ֿkx0EGYC.@8!@vЌnC4MdI"B0%qll chmG;x#{?/|@{ Z?K6S[n6j Qap#n_ˀv=uNT]aYhp.ВEW93[hTN3Oq'.Чѥ]g"VJ0v h1>|)*Jי TRT-Nͤ5 X1C4x\*o,W827鯭܈y32(;˒9duҷ4+i`r̃R%&L2{~FaYk.p\(mn ę| Hcwv7cxH:OS {~b<On!#$Oī9@4|/ݽ2Yr{=0@B'P U@1 &Sr,P^W쓈3&LeL6e۝?gK^z&{.C/'.M`xO h/ifrѕl5-:ny:7lV mmVh?]Tv_ftଚLHPE2=o?MCw:ԴBZL/MR\ÿR:=q͘stE PD\Z+Ǵqj!YC@CIK>#ǀ3+T ۄlb[@Dkqn4xu+lzt ,6k>ڏYJ̤=;Ǒ.ЉerFM,LoNF@>@h.? `jLj@CngDUSp܄[cTYr];m~u lNX(&JiN-h6MLT0wd-ҘSm^! L79a*X a4(@:l5PYP{ @n5hIq)A дG pƊ1,iL%`iΆM]Y=2 h⥺bl󤤡5ehϦ|g]z‘h4Dzɯbrsɖad.G4Fd }:IReY,%LDzC72*2(V8c "*wbmNubc|`= `= `= Y;PsՑ;Atp . JfK ֳGd: mGn+p[\#3ɴ}=` {c= K E7ܢr@!>)R2ԆT SY@p7{ KuymmKT=xݥ X>Yui.ːˆpܳa@y0xrZ(M,n{[@g ?{(|fDU bW !<|NQY`߯ y oM<"@s =i-V[ςgAֳ Y#tfZhC xh43m]Ӟl _ഞQD%x`;.$m@“V_SyLS `D59z-$Y;P,aHbŸqOyPЭ+jހAd~h̿  @^ 8GkDg^]7 O5r%'o&3u_>0#H V.=k?7Ǔy|8NoDٜ K5_ ޕ3O I\:`fW Zz`ZUxIIENDB`qastools-v0.22.0/qasconfig/graphics/icons/app-icon-64x64.png000066400000000000000000000022761354534512100235320ustar00rootroot00000000000000PNG  IHDR@@ vpAg@@`bKGDC pHYsHHFk>IIDATx\]HQ4vk ~ 0В@m1)( J0(DZwv!1q"!ž*` YAD-hGmvipؽ}޹svwf Kc.WF{pU߹u%ş~`IiZֻBvRE!Wz_lǚ(NkH%!#=stzsy[ZeK 0x{79vMwuunqqfW9~yw6lc.}y`cc 6[}Hn%$!-+3m|\SSY7j>im_!SmHz$75v\2%ݴI_;:,[ `v&wϞO!9Uײc˭ظ ҆t.yw7r\pʆb7a9΂[@xo q F">F(lkDi\%9 >ѱp 2 :roȞl udA@sC!AEIT=~of `]ʫBQ%A7@hҦ Ӷ1` @iIWH0@章&#4jhUMZkk3E @, F6 De F `tX0j&( !D 2<oB.E᳁p;LLIAUMTm;y6l0 s+``Pm{A+a6xOIENDB`qastools-v0.22.0/qasconfig/graphics/icons/app-icon-source.svg000066400000000000000000000445561354534512100242610ustar00rootroot00000000000000 image/svg+xml qastools-v0.22.0/qasconfig/graphics/icons/app-icon.svg000066400000000000000000000227231354534512100227530ustar00rootroot00000000000000 qastools-v0.22.0/qasconfig/share/000077500000000000000000000000001354534512100167055ustar00rootroot00000000000000qastools-v0.22.0/qasconfig/share/CMakeLists.txt000066400000000000000000000005211354534512100214430ustar00rootroot00000000000000# Desktop file SET ( desktop_file_src ${CMAKE_CURRENT_SOURCE_DIR}/application.desktop ) SET ( desktop_file ${CMAKE_CURRENT_BINARY_DIR}/${PROGRAM_NAME}.desktop ) CONFIGURE_FILE ( ${desktop_file_src} ${desktop_file} ) INSTALL( FILES ${desktop_file} DESTINATION ${INSTALL_DIR_DESKTOP} ) # Subdirectories ADD_SUBDIRECTORY ( man ) qastools-v0.22.0/qasconfig/share/application.desktop000066400000000000000000000012471354534512100226070ustar00rootroot00000000000000[Desktop Entry] Type=Application Name=${PROGRAM_TITLE} GenericName=ALSA configuration GenericName[de]=ALSA-Konfiguration GenericName[he]=תצורת ALSA GenericName[it]=Configurazione ALSA GenericName[ru]=Конфигурация ALSA Exec=${PROGRAM_NAME} Icon=${PROGRAM_NAME} StartupNotify=false Terminal=false Categories=AudioVideo;Audio;Mixer;Qt; Keywords=ALSA;Audio;Configuration;Qt; Comment=ALSA configuration browser Comment[cs]=Prohlížeč nastavení ALSA Comment[de]=ALSA-Konfigurationsbetrachter Comment[he]=סייר תצורת ALSA Comment[it]=Configuratore sistema ALSA Comment[ru]=Просмотрщик конфигурации звуковой системы ALSA qastools-v0.22.0/qasconfig/share/man/000077500000000000000000000000001354534512100174605ustar00rootroot00000000000000qastools-v0.22.0/qasconfig/share/man/CMakeLists.txt000066400000000000000000000013401354534512100222160ustar00rootroot00000000000000# Find gzip FIND_PACKAGE ( UnixCommands REQUIRED ) IF ( NOT GZIP ) MESSAGE ( FATAL_ERROR "Unable to find 'gzip' program" ) ENDIF ( NOT GZIP ) # Configure manpages SET ( man_src ${CMAKE_CURRENT_SOURCE_DIR}/manpage.1.cmake ) SET ( man_plain ${CMAKE_CURRENT_BINARY_DIR}/manpage.1 ) SET ( man_gz ${CMAKE_CURRENT_BINARY_DIR}/manpage.1.gz ) CONFIGURE_FILE ( ${man_src} ${man_plain} ) # Compress manpages ADD_CUSTOM_COMMAND ( OUTPUT ${man_gz} COMMAND ${GZIP} -c -9 ${man_plain} > ${man_gz} DEPENDS ${man_plain} COMMENT "Building ${man_gz}" ) ADD_CUSTOM_TARGET ( qasconfig_manpage ALL DEPENDS ${man_gz} ) # Installation of the manpage INSTALL ( FILES ${man_gz} DESTINATION ${INSTALL_DIR_MAN} RENAME ${PROGRAM_NAME}.1.gz ) qastools-v0.22.0/qasconfig/share/man/manpage.1.cmake000066400000000000000000000014731354534512100222360ustar00rootroot00000000000000.TH ${PROGRAM_NAME_UCASE} "1" "2011-12-30" "Linux" "QasTools Manuals" .SH NAME ${PROGRAM_NAME} \- ALSA configuration tree browser .SH SYNOPSIS .B ${PROGRAM_NAME} [OPTION]... .SH DESCRIPTION ALSA's configuration resides in a tree structure which gets built from the contents of the files \fI/etc/asound.conf\fP and \fI~/.asoundrc\fP. \fB${PROGRAM_TITLE}\fP is a graphical browser for this configuration tree and can help to analyze and debug an ALSA setup. .SH OPTIONS .TP \fB\-h\fR, \fB\-\-help\fR prints a help text. .TP \fB\-c\fR, \fB\-\-copying\fR prints copying information. .TP \fB\-v\fR, \fB\-\-version\fR prints the program version. .SH NOTES \fB${PROGRAM_TITLE}\fP is part of the \fBQasTools\fP applications collection. It is written in C++ using the Qt GUI libraries. .SH SEE ALSO .B qashctl(1), qasmixer(1) qastools-v0.22.0/qasconfig/src/000077500000000000000000000000001354534512100163725ustar00rootroot00000000000000qastools-v0.22.0/qasconfig/src/CMakeLists.txt000066400000000000000000000033101354534512100211270ustar00rootroot00000000000000# --- Find modules FIND_PACKAGE ( Qt5Widgets ) FIND_PACKAGE ( ALSA REQUIRED ) # --- Configure files INCLUDE ( CheckIncludeFiles ) CONFIGURE_FILE ( ${SHARED_SRC_DIR}/qastools_config.hpp.cmake ${CMAKE_CURRENT_BINARY_DIR}/qastools_config.hpp ) # --- Sources SET ( SRC_GUI ${SHARED_SRC_DIR}/qsnd/alsa.cpp ${SHARED_SRC_DIR}/qsnd/alsa_config_watcher.cpp ${SHARED_SRC_DIR}/wdg/scroll_area_vertical.cpp ${SHARED_SRC_DIR}/wdg/text_browser.cpp ${SHARED_SRC_DIR}/wdg/tree_view_kv.cpp ${SHARED_SRC_DIR}/views/view_utility.cpp ${SHARED_SRC_DIR}/views/basic_dialog.cpp ${SHARED_SRC_DIR}/views/multi_page_dialog.cpp ${SHARED_SRC_DIR}/views/info_dialog.cpp ${SHARED_SRC_DIR}/license_texts.cpp qsnd/alsa_config_model.cpp views/alsa_config_view.cpp info_texts.cpp static_tree.cpp static_tree_model.cpp main_window.cpp desktop_items.cpp main.cpp ) # --- Compiler flags SET ( CMAKE_CXX_STANDARD 17 ) SET ( CMAKE_CXX_STANDARD_REQUIRED OFF ) SET ( CMAKE_CXX_EXTENSIONS OFF ) SET ( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wextra -Wunused -Wall" ) SET ( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 -g -fno-inline" ) SET ( CMAKE_CXX_FLAGS_RELEASE "-O2 ${CMAKE_CXX_FLAGS_RELEASE}" ) # --- Include directories INCLUDE_DIRECTORIES ( ${CMAKE_CURRENT_SOURCE_DIR} ) INCLUDE_DIRECTORIES ( ${CMAKE_CURRENT_BINARY_DIR} ) INCLUDE_DIRECTORIES ( ${SHARED_INC_DIR} ) INCLUDE_DIRECTORIES ( ${ALSA_INCLUDE_DIRS} ) # --- Executable ADD_EXECUTABLE ( ${PROGRAM_NAME} ${SRC_GUI} ${SRC_GUI_MOC} ) SET_TARGET_PROPERTIES ( ${PROGRAM_NAME} PROPERTIES AUTOMOC ON ) TARGET_LINK_LIBRARIES ( ${PROGRAM_NAME} Qt5::Widgets ${ALSA_LIBRARIES} ) # --- Installation INSTALL ( TARGETS ${PROGRAM_NAME} RUNTIME DESTINATION ${INSTALL_DIR_BIN} ) qastools-v0.22.0/qasconfig/src/desktop_items.cpp000066400000000000000000000046331354534512100217560ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "desktop_items.hpp" #include "qastools_config.hpp" #include "info_texts.hpp" #include #include #include Desktop_Items::Desktop_Items ( ) { } Desktop_Items::~Desktop_Items ( ) { } int Desktop_Items::init_settings ( int argc, char * argv[] ) { //_dsetup.read_from_storage(); return parse_cmd_options ( argc, argv ); } int Desktop_Items::parse_cmd_options ( int argc, char * argv[] ) { // Suppresses error messages by getopt_long opterr = 0; QString card_idx; QString ctl_address; bool flag_print_version ( false ); bool flag_print_help ( false ); bool flag_print_copy_info ( false ); bool scan_further ( true ); while ( scan_further ) { static struct option long_opts[] = { { "help", no_argument, 0, 'h' }, { "copying", no_argument, 0, 'i' }, { "version", no_argument, 0, 'v' }, {0, 0, 0, 0} }; // getopt_long stores the option index here. int long_opts_idx ( 0 ); int opt_char = getopt_long ( argc, argv, "hc:D:tniv", long_opts, &long_opts_idx ); // Leave loop if ( opt_char < 0 ) { break; } switch ( opt_char ) { case 0: break; case 'h': flag_print_help = true; scan_further = false; break; case 'i': flag_print_copy_info = true; break; case 'v': flag_print_version = true; break; default: // Dont't break, as the option may be for QT break; } } if ( flag_print_help ) { { ::std::stringstream msg; msg << "Usage:" << ::std::endl; msg << " " << PROGRAM_NAME << " [OPTION]..." << ::std::endl; msg << ::std::endl; msg << info_text_options; msg << ::std::endl; ::std::cout << msg.str() << ::std::flush; } return -1; } if ( flag_print_version ) { { ::std::stringstream msg; msg << PROGRAM_NAME << " " << VERSION << ::std::endl; ::std::cout << msg.str() << ::std::flush; } return -1; } if ( flag_print_copy_info ) { { ::std::stringstream msg; msg << PROGRAM_TITLE; msg << " - configuration browser for the Linux sound system ALSA."; msg << ::std::endl; msg << ::std::endl; msg << license_text_short; msg << ::std::endl; ::std::cout << msg.str() << ::std::flush; } return -1; } return 0; } void Desktop_Items::start ( bool ) { _mwin.reset ( new Main_Window ); _mwin->restore_state(); _mwin->show(); } qastools-v0.22.0/qasconfig/src/desktop_items.hpp000066400000000000000000000015471354534512100217640ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_desktop_items_hpp__ #define __INC_desktop_items_hpp__ #include "main_window.hpp" #include /// @brief Manages all items that appear on the desktop /// class Desktop_Items { // Public methods public: Desktop_Items ( ); ~Desktop_Items ( ); /// @brief Reads options from storage and command line /// /// @return A negative value on an error int init_settings ( int argc, char * argv[] ); /// @brief Start the mixer window and/or tray icon /// void start ( bool restore_session_n = false ); /// @brief Command line option parser /// /// @return A negative value on an error int parse_cmd_options ( int argc, char * argv[] ); // Private attributes private: QScopedPointer < Main_Window > _mwin; }; #endif qastools-v0.22.0/qasconfig/src/info_texts.cpp000066400000000000000000000005011354534512100212540ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "info_texts.hpp" const char info_text_options[] = "\ Options:\n\ -h, --help prints this help\n\ -i, --copying prints copying information\n\ -v, --version prints the program version\n\ "; qastools-v0.22.0/qasconfig/src/info_texts.hpp000066400000000000000000000003551354534512100212700ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_info_texts_hpp__ #define __INC_info_texts_hpp__ #include "license_texts.hpp" extern const char info_text_options[]; #endif qastools-v0.22.0/qasconfig/src/main.cpp000066400000000000000000000016541354534512100200300ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "qastools_config.hpp" #include "desktop_items.hpp" #include "views/view_utility.hpp" #include #include #include /// @brief The main function /// int main ( int argc, char * argv[] ) { // Qt Application QApplication app ( argc, argv ); app.setOrganizationName ( QString ( PACKAGE_NAME ).toLower() ); app.setApplicationName ( QString ( PROGRAM_NAME ).toLower() ); app.setAttribute ( Qt::AA_DontShowIconsInMenus, false ); Desktop_Items ditems; { int res ( ditems.init_settings ( argc, argv ) ); if ( res < ditems.init_settings ( argc, argv ) ) { return res; } } // Load application icon, translators ::Views::load_application_icon ( &app, "multimedia-volume-control" ); ::Views::load_translators ( &app ); ditems.start ( app.isSessionRestored() ); return app.exec(); } qastools-v0.22.0/qasconfig/src/main_window.cpp000066400000000000000000000073311354534512100214150ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "main_window.hpp" #include "qastools_config.hpp" #include "qsnd/alsa_config_watcher.hpp" #include "views/info_dialog.hpp" #include "views/view_utility.hpp" #include #include #include #include #include #include Main_Window::Main_Window ( ) { setWindowTitle ( PROGRAM_TITLE ); setObjectName ( PROGRAM_TITLE ); setContextMenuPolicy ( Qt::NoContextMenu ); init_menu_bar(); { ::QSnd::ALSA_Config_Watcher * watcher ( new ::QSnd::ALSA_Config_Watcher ( this ) ); connect ( watcher, SIGNAL ( sig_change() ), this, SLOT ( refresh() ) ); } _alsa_cfg_view.set_model ( &_alsa_cfg_model ); setCentralWidget ( &_alsa_cfg_view ); } QSize Main_Window::sizeHint ( ) const { QSize res ( QMainWindow::sizeHint() ); ::Views::win_default_size ( res ); return res; } void Main_Window::restore_state ( ) { QSettings settings; QByteArray mwin_state; QByteArray mwin_geom; bool cfg_sorted; // Main window state { settings.beginGroup ( "main_window" ); mwin_state = settings.value ( "window_state", QByteArray() ).toByteArray(); mwin_geom = settings.value ( "window_geometry", QByteArray() ).toByteArray(); settings.endGroup(); } // Configuration view { settings.beginGroup ( "alsa_config" ); cfg_sorted = settings.value ( "sorting_enabled", true ).toBool(); settings.endGroup(); } // Apply settings restoreState ( mwin_state ); if ( !restoreGeometry ( mwin_geom ) ) { ::Views::resize_to_default ( this ); } _alsa_cfg_view.set_sorting_enabled ( cfg_sorted ); } void Main_Window::save_state ( ) { QSettings settings; settings.beginGroup ( "main_window" ); settings.setValue ( "window_state", saveState() ); settings.setValue ( "window_geometry", saveGeometry() ); settings.endGroup(); settings.beginGroup ( "alsa_config" ); settings.setValue ( "sorting_enabled", _alsa_cfg_view.sorting_enabled() ); settings.endGroup(); } void Main_Window::show_info_dialog ( ) { if ( _info_dialog == 0 ) { ::Views::Info_Dialog * dlg ( new ::Views::Info_Dialog ( this ) ); dlg->setAttribute ( Qt::WA_DeleteOnClose ); _info_dialog = dlg; } _info_dialog->show(); } void Main_Window::init_menu_bar ( ) { // Action: Quit QAction * act_quit ( new QAction ( tr ( "&Quit" ), this ) ); act_quit->setShortcut ( QKeySequence ( QKeySequence::Quit ) ); act_quit->setIcon ( QIcon::fromTheme ( "application-exit" ) ); // Action: Refresh QAction * act_refresh ( new QAction ( tr ( "&Refresh" ), this ) ); act_refresh->setShortcut ( QKeySequence ( QKeySequence::Refresh ) ); act_refresh->setIcon ( QIcon::fromTheme ( "view-refresh" ) ); // Action: Info QAction * act_info = new QAction ( tr ( "&Info" ), this ); act_info->setShortcut ( QKeySequence ( QKeySequence::HelpContents ) ); act_info->setIcon ( QIcon::fromTheme ( "help-about" ) ); // Menu: File { QMenu * cmenu ( menuBar()->addMenu ( tr ( "&File" ) ) ); cmenu->addAction ( act_quit ); } // Menu: View { QMenu * cmenu = menuBar()->addMenu ( tr ( "&View" ) ); cmenu->addAction ( act_refresh ); } // Menu: Help { QMenu * cmenu = menuBar()->addMenu ( tr ( "&Help" ) ); cmenu->addAction ( act_info ); } // Connect actions connect ( act_quit, SIGNAL ( triggered() ), this, SLOT ( close() ) ); connect ( act_refresh, SIGNAL ( triggered() ), this, SLOT ( refresh() ) ); connect ( act_info, SIGNAL ( triggered() ), this, SLOT ( show_info_dialog() ) ); } void Main_Window::refresh ( ) { //::std::cout << "Refresh" << "\n"; _alsa_cfg_view.reload_config(); } void Main_Window::closeEvent ( QCloseEvent * event_n ) { save_state(); QMainWindow::closeEvent ( event_n ); } qastools-v0.22.0/qasconfig/src/main_window.hpp000066400000000000000000000016641354534512100214250ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_main_window_hpp__ #define __INC_main_window_hpp__ #include #include #include #include "qsnd/alsa_config_model.hpp" #include "views/alsa_config_view.hpp" /// @brief Main_Window /// class Main_Window : public QMainWindow { Q_OBJECT // Public methods public: Main_Window ( ); QSize sizeHint ( ) const; void restore_state ( ); void save_state ( ); // Public slots private slots: void refresh ( ); // Protected methods protected: void closeEvent ( QCloseEvent * event_n ); // Private slots private slots: void show_info_dialog ( ); // Private methods private: void init_menu_bar ( ); // Private attributes private: ::QSnd::Alsa_Config_Model _alsa_cfg_model; ::Views::Alsa_Config_View _alsa_cfg_view; QPointer < QDialog > _info_dialog; }; #endif qastools-v0.22.0/qasconfig/src/qsnd/000077500000000000000000000000001354534512100173375ustar00rootroot00000000000000qastools-v0.22.0/qasconfig/src/qsnd/alsa_config_model.cpp000066400000000000000000000142171354534512100234750ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "alsa_config_model.hpp" #include #include #include #include #include namespace QSnd { Alsa_Config_Model::Alsa_Config_Model ( ) : _snd_cfg_root ( 0 ) { reload(); } Alsa_Config_Model::~Alsa_Config_Model ( ) { clear_config(); } void Alsa_Config_Model::clear_config ( ) { const int rows ( rowCount() ); if ( rows > 0 ) { beginRemoveRows ( QModelIndex(), 0, rows - 1 ); } stree().reset(); if ( _snd_cfg_root != 0 ) { snd_config_delete ( _snd_cfg_root ); _snd_cfg_root = 0; } if ( rows > 0 ) { endRemoveRows(); } } int Alsa_Config_Model::load_config ( ) { int err; { snd_config_update_t * snd_cfg_upd = 0; err = snd_config_update_r ( &_snd_cfg_root, &snd_cfg_upd, 0 ); if ( snd_cfg_upd != 0 ) { snd_config_update_free ( snd_cfg_upd ); snd_cfg_upd = 0; } } if ( ( err < 0 ) || ( _snd_cfg_root == 0 ) ) { { ::std::stringstream msg; msg << "[EE] Alsa configuration reading failed" << ::std::endl; ::std::cerr << msg.str(); } ::QSnd::print_alsa_error ( "snd_config_update_r()", err ); } else { add_children_recursively ( stree().root_node(), _snd_cfg_root ); const int rows ( rowCount() ); if ( rows > 0 ) { beginInsertRows ( QModelIndex(), 0, rows - 1 ); endInsertRows(); } } return err; } int Alsa_Config_Model::reload ( ) { int res ( 0 ); beginResetModel(); clear_config(); res = load_config(); endResetModel(); return res; } int Alsa_Config_Model::add_children_recursively ( Node * node_n, snd_config_t * cfg_n ) { if ( ( node_n == 0 ) || ( cfg_n == 0 ) ) { return -1; } const int num_children = cfg_count_children ( cfg_n ); if ( num_children > 0 ) { stree().append_children ( node_n, num_children ); snd_config_iterator_t iter; snd_config_iterator_t iter_end; iter = snd_config_iterator_first ( cfg_n ); iter_end = snd_config_iterator_end ( cfg_n ); int count ( 0 ); while ( ( iter != iter_end ) && ( count < num_children ) ) { Node * node_child = stree().child_node ( node_n, count ); snd_config_t * cfg_child = snd_config_iterator_entry ( iter ); add_children_recursively ( node_child, cfg_child ); iter = snd_config_iterator_next ( iter ); ++count; } } return 0; } snd_config_t * Alsa_Config_Model::cfg_struct ( const Node * node_n ) const { snd_config_t * res ( 0 ); QList < unsigned int > rl; stree().rootline ( node_n, rl ); res = _snd_cfg_root; for ( int ii=rl.size()-1; ii >= 0; --ii ) { res = cfg_child ( res, rl[ii] ); } return res; } snd_config_t * Alsa_Config_Model::cfg_struct ( const QModelIndex & index_n ) const { snd_config_t * res ( 0 ); const Node * node = get_node ( index_n ); if ( node != 0 ) { res = cfg_struct ( node ); } return res; } int Alsa_Config_Model::cfg_count_children ( snd_config_t * cfg_n ) const { int count ( 0 ); if ( cfg_n != 0 ) { if ( snd_config_get_type ( cfg_n ) == SND_CONFIG_TYPE_COMPOUND ) { snd_config_iterator_t iter; snd_config_iterator_t iter_end; iter = snd_config_iterator_first ( cfg_n ); iter_end = snd_config_iterator_end ( cfg_n ); while ( iter != iter_end ) { ++count; iter = snd_config_iterator_next ( iter ); } } } return count; } snd_config_t * Alsa_Config_Model::cfg_child ( snd_config_t * cfg_n, unsigned int index_n ) const { snd_config_t * res ( 0 ); if ( cfg_n != 0 ) { if ( snd_config_get_type ( cfg_n ) == SND_CONFIG_TYPE_COMPOUND ) { snd_config_iterator_t iter; snd_config_iterator_t iter_end; iter = snd_config_iterator_first ( cfg_n ); iter_end = snd_config_iterator_end ( cfg_n ); unsigned int count ( 0 ); while ( iter != iter_end ) { if ( count == index_n ) { res = snd_config_iterator_entry ( iter ); break; } iter = snd_config_iterator_next ( iter ); ++count; } } } return res; } QString Alsa_Config_Model::cfg_id_string ( snd_config_t * cfg_n ) const { QString res; const char * char_ptr ( 0 ); int err = snd_config_get_id ( cfg_n, &char_ptr ); if ( ( err == 0 ) && ( char_ptr != 0 ) ) { res = char_ptr; } return res; } QString Alsa_Config_Model::cfg_value_string ( snd_config_t * cfg_n ) const { QString res; char * char_ptr ( 0 ); int err = snd_config_get_ascii ( cfg_n, &char_ptr ); if ( ( err == 0 ) && ( char_ptr != 0 ) ) { res = char_ptr; free ( char_ptr ); } return res; } QVariant Alsa_Config_Model::headerData ( int section, Qt::Orientation orientation, int role ) const { if ( orientation == Qt::Horizontal ) { if ( role == Qt::DisplayRole ) { if ( section == 0 ) { return tr ( "Key" ) ; } else if ( section == 1 ) { return tr ( "Value" ) ; } } } return QVariant(); } Qt::ItemFlags Alsa_Config_Model::flags ( const QModelIndex & ) const { Qt::ItemFlags ff ( Qt::ItemIsEnabled | Qt::ItemIsSelectable ); return ff; } QVariant Alsa_Config_Model::data ( const QModelIndex & index_n, int role_n ) const { QVariant res; snd_config_t * cfg ( cfg_struct ( index_n ) ); if ( cfg != 0 ) { if ( role_n == Qt::DisplayRole ) { if ( index_n.column() == 0 ) { res = cfg_id_string ( cfg ); } else if ( index_n.column() == 1 ) { res = cfg_value_string ( cfg ); } } } return res; } QString Alsa_Config_Model::index_address_str ( const QModelIndex & index_n ) { QString res; QModelIndex idx ( index_n ); while ( idx.isValid() ) { if ( !res.isEmpty() ) { res.prepend ( "." ); } res.prepend ( data ( idx, Qt::DisplayRole ).toString() ); idx = idx.parent(); } return res; } QModelIndex Alsa_Config_Model::index_from_address ( const QString & addr_n ) { QModelIndex res; const QStringList lst ( addr_n.split ( "." ) ); QModelIndex idx_base; for ( int depth=0; depth < lst.size(); ++depth ) { unsigned int num_rows ( rowCount ( idx_base ) ); for ( unsigned int row=0; row < num_rows; ++row ) { const QModelIndex idx ( index ( row, 0, idx_base ) ); if ( data ( idx, Qt::DisplayRole ).toString() == lst[depth] ) { if ( depth == ( lst.size() - 1 ) ) { res = idx; } else { idx_base = idx; } break; } } } return res; } } // End of namespace qastools-v0.22.0/qasconfig/src/qsnd/alsa_config_model.hpp000066400000000000000000000030321354534512100234730ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_qsnd_alsa_config_model_hpp__ #define __INC_qsnd_alsa_config_model_hpp__ #include "static_tree_model.hpp" #include "qsnd/alsa.hpp" namespace QSnd { /// @brief Alsa_Config_Model /// class Alsa_Config_Model : public Static_Tree_Model { Q_OBJECT // Public methods public: Alsa_Config_Model ( ); ~Alsa_Config_Model ( ); // Model methods QVariant headerData ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const; Qt::ItemFlags flags ( const QModelIndex & index_n ) const; QVariant data ( const QModelIndex & index_n, int role = Qt::DisplayRole ) const; QString index_address_str ( const QModelIndex & index_n ); QModelIndex index_from_address ( const QString & addr_n ); // Public slots public slots: int reload ( ); // Private methods private: void clear_config ( ); int load_config ( ); int add_children_recursively ( Node * node_n, snd_config_t * cfg_n ); snd_config_t * cfg_struct ( const Node * node_n ) const; snd_config_t * cfg_struct ( const QModelIndex & index_n ) const; int cfg_count_children ( snd_config_t * cfg_n ) const; snd_config_t * cfg_child ( snd_config_t * cfg_n, unsigned int index_n ) const; QString cfg_id_string ( snd_config_t * cfg_n ) const; QString cfg_value_string ( snd_config_t * cfg_n ) const; // Private attributes private: snd_config_t * _snd_cfg_root; }; } // End of namespace #endif qastools-v0.22.0/qasconfig/src/static_tree.cpp000066400000000000000000000054201354534512100214050ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "static_tree.hpp" Static_Tree_Node::Static_Tree_Node ( ) : parent_idx ( 0 ), self_idx ( 0 ), children_idx ( 0 ) { } Static_Tree::Static_Tree ( ) { reset(); } void Static_Tree::reset ( ) { clear(); Node nn_root; nn_root.parent_idx = 0; nn_root.self_idx = 0; nn_root.children_idx = 0; append ( nn_root ); } const Static_Tree::Node * Static_Tree::parent_node ( const Node * node_n ) const { if ( node_n != 0 ) { if ( !is_root ( node_n ) ) { return node ( node_n->parent_idx ); } } return 0; } Static_Tree::Node * Static_Tree::parent_node ( const Node * node_n ) { if ( node_n != 0 ) { if ( !is_root ( node_n ) ) { return node ( node_n->parent_idx ); } } return 0; } const Static_Tree::Node * Static_Tree::child_node ( const Node * node_n, Index_Type child_n ) const { if ( node_n != 0 ) { if ( node_n->children_idx > 0 ) { return node ( node_n->children_idx + child_n ); } } return 0; } Static_Tree::Node * Static_Tree::child_node ( const Node * node_n, Index_Type child_n ) { if ( node_n != 0 ) { if ( node_n->children_idx > 0 ) { return node ( node_n->children_idx + child_n ); } } return 0; } Static_Tree::Index_Type Static_Tree::depth ( const Node * node_n ) const { Index_Type res ( 0 ); if ( node_n != 0 ) { while ( !is_root ( node_n ) ) { node_n = parent_node ( node_n ); ++res; } } return res; } Static_Tree::Index_Type Static_Tree::row ( const Node * node_n ) const { Index_Type idx ( 0 ); if ( node_n != 0 ) { idx = node_n->self_idx; while ( idx > 0 ) { const Node * nn ( node ( idx ) ); if ( nn->parent_idx != node_n->parent_idx ) { break; } --idx; } return ( node_n->self_idx - idx ) - 1; } return idx; } Static_Tree::Index_Type Static_Tree::num_children ( const Node * node_n ) const { Index_Type res ( 0 ); if ( node_n != 0 ) { if ( node_n->children_idx > 0 ) { const Index_Type idx_lim ( size() ); Index_Type idx ( node_n->children_idx ); while ( idx < idx_lim ) { const Node * node_c = node ( idx ); if ( node_c->parent_idx != node_n->self_idx ) { break; } ++res; ++idx; } } } return res; } void Static_Tree::rootline ( const Node * node_n, QList < unsigned int > & rows_n ) const { rows_n.clear(); if ( node_n != 0 ) { while ( !is_root ( node_n ) ) { rows_n.append ( row ( node_n ) ); node_n = parent_node ( node_n ); } } } void Static_Tree::append_children ( Node * node_n, Index_Type num_n ) { if ( ( node_n == 0 ) || ( num_n <= 0 ) ) { return; } node_n->children_idx = size(); for ( Index_Type ii=0; ii < num_n; ++ii ) { Node nn; nn.parent_idx = node_n->self_idx; nn.self_idx = size(); append ( nn ); } } qastools-v0.22.0/qasconfig/src/static_tree.hpp000066400000000000000000000042201354534512100214070ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_static_tree_hpp__ #define __INC_static_tree_hpp__ #include #include #include class Static_Tree_Node { // Public typedefs public: typedef unsigned long Index_Type; // Public methods public: Static_Tree_Node ( ); unsigned long parent_idx; unsigned long self_idx; unsigned long children_idx; }; class Static_Tree : public QList < Static_Tree_Node > { public: typedef Static_Tree_Node Node; typedef Static_Tree_Node::Index_Type Index_Type; public: Static_Tree ( ); void reset(); Node * node ( Index_Type idx_n ); const Node * node ( Index_Type idx_n ) const; bool is_root ( const Node * node_n ) const; const Node * root_node ( ) const; Node * root_node ( ); const Node * parent_node ( const Node * node_n ) const; Node * parent_node ( const Node * node_n ); const Node * child_node ( const Node * node_n, Index_Type child_n ) const; Node * child_node ( const Node * node_n, Index_Type child_n ); Index_Type depth ( const Node * node_n ) const; Index_Type row ( const Node * node_n ) const; Index_Type num_children ( const Node * node_n ) const; /// @brief Calculates the rootline starting from the node downwards void rootline ( const Node * node_n, QList < unsigned int > & rows_n ) const; /// @brief Sets the number of children for a node and appends the children void append_children ( Node * node_n, Index_Type num_n ); }; inline bool Static_Tree::is_root ( const Node * node_n ) const { return ( node_n->self_idx == 0 ); } inline const Static_Tree::Node * Static_Tree::root_node ( ) const { return node ( 0 ); } inline Static_Tree::Node * Static_Tree::root_node ( ) { return node ( 0 ); } inline Static_Tree::Node * Static_Tree::node ( Index_Type idx_n ) { if ( idx_n < Index_Type ( size() ) ) { return &operator[] ( idx_n ); } return 0; } inline const Static_Tree::Node * Static_Tree::node ( Index_Type idx_n ) const { if ( idx_n < Index_Type ( size() ) ) { return &operator[] ( idx_n ); } return 0; } #endif qastools-v0.22.0/qasconfig/src/static_tree_model.cpp000066400000000000000000000041501354534512100225640ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "static_tree_model.hpp" Static_Tree_Model::Static_Tree_Model ( ) : _num_columns ( 2 ) { } Static_Tree_Model::~Static_Tree_Model ( ) { } void Static_Tree_Model::set_num_columns ( int num_n ) { _num_columns = num_n; } const Static_Tree_Model::Node * Static_Tree_Model::get_node ( const QModelIndex & index_n ) const { int idx ( 0 ); if ( index_n.isValid() ) { idx = index_n.internalId(); } return stree().node ( idx ); } QModelIndex Static_Tree_Model::index ( const Node * node_n ) const { if ( node_n != 0 ) { const Node_Index node_row ( stree().row ( node_n ) ); return createIndex ( node_row, 0, quint32 ( node_n->self_idx ) ); } return QModelIndex(); } QModelIndex Static_Tree_Model::index ( int row, int column, const QModelIndex & parent_n ) const { if ( ( parent_n.column() > 0 ) ) { return QModelIndex(); } const Node * node_p ( get_node ( parent_n ) ); if ( node_p != 0 ) { if ( Node_Index ( row ) < stree().num_children ( node_p ) ) { quint32 idx = node_p->children_idx + row; return createIndex ( row, column, idx ); } } return QModelIndex(); } QModelIndex Static_Tree_Model::parent ( const QModelIndex & index_n ) const { const long idx ( index_n.internalId() ); if ( index_n.isValid() && ( idx > 0 ) ) { const Node * node ( stree().node ( idx ) ); if ( node != 0 ) { const int ndepth ( stree().depth ( node ) ); if ( ndepth > 1 ) { node = stree().parent_node ( node ); return index ( node ); } } } return QModelIndex(); } int Static_Tree_Model::rowCount ( const QModelIndex & parent_n ) const { int res ( 0 ); const Node * node ( 0 ); if ( parent_n.isValid() ) { if ( parent_n.column() == 0 ) { node = stree().node ( parent_n.internalId() ); } } else { node = stree().node ( 0 ); } if ( node != 0 ) { res = stree().num_children ( node ); } return res; } int Static_Tree_Model::columnCount ( const QModelIndex & index_n ) const { int res ( 0 ); if ( rowCount ( index_n ) > 0 ) { res = _num_columns; } return res; } qastools-v0.22.0/qasconfig/src/static_tree_model.hpp000066400000000000000000000026731354534512100226010ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_static_tree_model_hpp__ #define __INC_static_tree_model_hpp__ #include #include "static_tree.hpp" /// @brief Static_Tree_Model /// class Static_Tree_Model : public QAbstractItemModel { // Public typedefs public: typedef Static_Tree::Index_Type Node_Index; typedef Static_Tree::Node Node; // Public methods public: Static_Tree_Model ( ); ~Static_Tree_Model ( ); int num_columns ( ) const; void set_num_columns ( int num_n ); const Node * get_node ( const QModelIndex & index_n ) const; QModelIndex index ( const Node * node_n ) const; // Model methods QModelIndex index ( int row, int column = 0, const QModelIndex & parent = QModelIndex() ) const; QModelIndex parent ( const QModelIndex & index ) const; int rowCount ( const QModelIndex & parent = QModelIndex() ) const; int columnCount ( const QModelIndex & parent = QModelIndex() ) const; // Protected methods protected: Static_Tree & stree ( ); const Static_Tree & stree ( ) const; // Private attributes private: Static_Tree _stree; int _num_columns; }; inline int Static_Tree_Model::num_columns ( ) const { return _num_columns; } inline Static_Tree & Static_Tree_Model::stree ( ) { return _stree; } inline const Static_Tree & Static_Tree_Model::stree ( ) const { return _stree; } #endif qastools-v0.22.0/qasconfig/src/views/000077500000000000000000000000001354534512100175275ustar00rootroot00000000000000qastools-v0.22.0/qasconfig/src/views/alsa_config_view.cpp000066400000000000000000000115561354534512100235420ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "alsa_config_view.hpp" #include "qsnd/alsa_config_model.hpp" #include "wdg/tree_view_kv.hpp" #include #include #include #include #include #include namespace Views { Alsa_Config_View::Alsa_Config_View ( QWidget * parent_n ) : QWidget ( parent_n ), _alsa_cfg ( 0 ) { QLabel * title_label ( new QLabel ); { QString txt ( "

%1

" ); txt = txt.arg ( tr ( "ALSA configuration" ) ); title_label->setText ( txt ); } _btn_expand.setText ( tr ( "&Expand" ) ); _btn_collapse.setText ( tr ( "Co&llapse" ) ); _btn_sort.setText ( tr ( "&Sort" ) ); QLabel * expand_depth_label ( new QLabel ( tr ( "Depth:" ) ) ); _expand_depth.setRange ( 0, 999 ); _expand_depth.setValue ( 2 ); connect ( &_btn_collapse, SIGNAL ( clicked() ), this, SLOT ( collapse_to_level() ) ); connect ( &_btn_expand, SIGNAL ( clicked() ), this, SLOT ( expand_to_level() ) ); connect ( &_btn_sort, SIGNAL ( toggled ( bool ) ), this, SLOT ( set_sorting_enabled ( bool ) ) ); _tree_view = new ::Wdg::Tree_View_KV ( this ); _sort_model = new QSortFilterProxyModel ( this ); _tree_view->setSelectionMode ( QAbstractItemView::ExtendedSelection ); _tree_view->setModel ( _sort_model ); if ( _tree_view->selectionModel() != 0 ) { connect ( _tree_view->selectionModel(), SIGNAL ( selectionChanged ( const QItemSelection &, const QItemSelection & ) ), this, SLOT ( items_selected ( const QItemSelection &, const QItemSelection & ) ) ); } QHBoxLayout * lay_btn ( new QHBoxLayout ); lay_btn->addWidget ( &_btn_collapse ); lay_btn->addWidget ( &_btn_expand ); lay_btn->addWidget ( expand_depth_label ); lay_btn->addWidget ( &_expand_depth ); lay_btn->addStretch ( 1 ); lay_btn->addWidget ( &_btn_sort ); QVBoxLayout * lay_vbox ( new QVBoxLayout ); lay_vbox->addWidget ( title_label ); lay_vbox->addWidget ( _tree_view ); lay_vbox->addLayout ( lay_btn ); setLayout ( lay_vbox ); } Alsa_Config_View::~Alsa_Config_View ( ) { } void Alsa_Config_View::set_model ( ::QSnd::Alsa_Config_Model * model_n ) { _alsa_cfg = model_n; _sort_model->setSourceModel ( _alsa_cfg ); } bool Alsa_Config_View::sorting_enabled ( ) const { return _sort_model->dynamicSortFilter(); } void Alsa_Config_View::set_sorting_enabled ( bool flag_n ) { if ( flag_n != sorting_enabled() ) { QStringList lst; collect_expanded ( lst ); _sort_model->setDynamicSortFilter ( flag_n ); _sort_model->sort ( flag_n ? 0 : -1 ); set_expanded ( lst ); _btn_sort.setChecked ( flag_n ); update_button_state(); } } void Alsa_Config_View::reload_config ( ) { if ( model() != 0 ) { if ( _expanded_items.isEmpty() ) { collect_expanded ( _expanded_items ); } if ( model()->reload() >= 0 ) { set_expanded ( _expanded_items ); _expanded_items.clear(); } } } void Alsa_Config_View::collect_expanded ( QStringList & lst_n, const QModelIndex & idx_base_n ) { if ( model() == 0 ) { return; } const int rows ( _alsa_cfg->rowCount ( idx_base_n ) ); for ( int row=0; row < rows; ++row ) { const QModelIndex & idx_src ( _alsa_cfg->index ( row, 0, idx_base_n ) ); const QModelIndex & idx ( _sort_model->mapFromSource ( idx_src ) ); if ( idx.isValid() ) { if ( _tree_view->isExpanded ( idx ) ) { lst_n.append ( _alsa_cfg->index_address_str ( idx_src ) ); collect_expanded ( lst_n, idx_src ); } } } } void Alsa_Config_View::set_expanded ( QStringList & lst_n ) { if ( model() == 0 ) { return; } for ( int ii=0; ii < lst_n.size(); ++ii ) { const QModelIndex & idx_src ( _alsa_cfg->index_from_address ( lst_n[ii] ) ); const QModelIndex & idx ( _sort_model->mapFromSource ( idx_src ) ); if ( idx.isValid() ) { _tree_view->setExpanded ( idx, true ); } } } void Alsa_Config_View::expand_to_level ( bool expanded_n ) { int depth ( _expand_depth.value() ); if ( ( _tree_view->selectionModel() != 0 ) && ( depth >= 0 ) ) { QModelIndexList indices ( _tree_view->selectionModel()->selectedRows() ); for ( int ii=0; ii < indices.size(); ++ii ) { const QModelIndex & idx ( indices[ii] ); if ( idx.isValid() ) { _tree_view->set_expanded_recursive ( idx, depth, expanded_n ); } } } } void Alsa_Config_View::expand_to_level ( ) { expand_to_level ( true ); } void Alsa_Config_View::collapse_to_level ( ) { expand_to_level ( false ); } void Alsa_Config_View::items_selected ( const QItemSelection &, const QItemSelection & ) { update_button_state(); } void Alsa_Config_View::update_button_state ( ) { bool is_enabled ( false ); if ( _tree_view->selectionModel() != 0 ) { is_enabled = _tree_view->selectionModel()->hasSelection(); } _btn_expand.setEnabled ( is_enabled ); _btn_collapse.setEnabled ( is_enabled ); _expand_depth.setEnabled ( is_enabled ); } } // End of namespace qastools-v0.22.0/qasconfig/src/views/alsa_config_view.hpp000066400000000000000000000033651354534512100235460ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_views_alsa_config_view_hpp__ #define __INC_views_alsa_config_view_hpp__ #include #include #include #include #include // Forward declaration class QAbstractItemModel; class QSortFilterProxyModel; class QItemSelection; namespace QSnd { class Alsa_Config_Model; } namespace Wdg { class Tree_View_KV; } namespace Views { class Alsa_Config_View : public QWidget { Q_OBJECT // Public methods public: Alsa_Config_View ( QWidget * parent_n = 0 ); ~Alsa_Config_View ( ); ::QSnd::Alsa_Config_Model * model ( ) const; void set_model ( ::QSnd::Alsa_Config_Model * model_n ); bool sorting_enabled ( ) const; // Public slots public slots: void reload_config ( ); void expand_to_level ( bool expanded_n ); void expand_to_level ( ); void collapse_to_level ( ); void set_sorting_enabled ( bool flag_n ); // Protected slots protected slots: void items_selected ( const QItemSelection & sel0_n, const QItemSelection & sel1_n ); // Protected methods protected: void collect_expanded ( QStringList & lst_n, const QModelIndex & = QModelIndex() ); void set_expanded ( QStringList & lst_n ); void update_button_state ( ); // Private attributes private: ::QSnd::Alsa_Config_Model * _alsa_cfg; QSortFilterProxyModel * _sort_model; // Widgets ::Wdg::Tree_View_KV * _tree_view; QPushButton _btn_expand; QPushButton _btn_collapse; QCheckBox _btn_sort; QSpinBox _expand_depth; QStringList _expanded_items; }; inline ::QSnd::Alsa_Config_Model * Alsa_Config_View::model ( ) const { return _alsa_cfg; } } // End of namespace #endif qastools-v0.22.0/qashctl/000077500000000000000000000000001354534512100152705ustar00rootroot00000000000000qastools-v0.22.0/qashctl/CMakeLists.txt000066400000000000000000000011511354534512100200260ustar00rootroot00000000000000# Program name IF ( NOT PROGRAM_TITLE ) SET ( PROGRAM_TITLE "QasHctl" ) ENDIF ( NOT PROGRAM_TITLE ) IF ( NOT PROGRAM_NAME ) SET ( PROGRAM_NAME "qashctl${PROGRAM_SUFFIX}" ) ENDIF ( NOT PROGRAM_NAME ) string ( TOUPPER ${PROGRAM_NAME} PROGRAM_NAME_UCASE ) # Program version SET ( VERSION_MAJOR ${PACKAGE_VERSION_MAJOR} ) SET ( VERSION_MINOR ${PACKAGE_VERSION_MINOR} ) SET ( VERSION_PATCH ${PACKAGE_VERSION_PATCH} ) SET ( VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}${VERSION_SUFFIX}" ) # Process subdirectories ADD_SUBDIRECTORY ( src ) ADD_SUBDIRECTORY ( graphics ) ADD_SUBDIRECTORY ( share ) qastools-v0.22.0/qashctl/graphics/000077500000000000000000000000001354534512100170705ustar00rootroot00000000000000qastools-v0.22.0/qashctl/graphics/CMakeLists.txt000066400000000000000000000011031354534512100216230ustar00rootroot00000000000000# Install application icons INSTALL( FILES icons/app-icon-16x16.png DESTINATION ${INSTALL_DIR_ICONS_PNG_16} RENAME ${PROGRAM_NAME}.png ) INSTALL( FILES icons/app-icon-32x32.png DESTINATION ${INSTALL_DIR_ICONS_PNG_32} RENAME ${PROGRAM_NAME}.png ) INSTALL( FILES icons/app-icon-48x48.png DESTINATION ${INSTALL_DIR_ICONS_PNG_48} RENAME ${PROGRAM_NAME}.png ) INSTALL( FILES icons/app-icon-64x64.png DESTINATION ${INSTALL_DIR_ICONS_PNG_64} RENAME ${PROGRAM_NAME}.png ) INSTALL( FILES icons/app-icon.svg DESTINATION ${INSTALL_DIR_ICONS_SVG} RENAME ${PROGRAM_NAME}.svg ) qastools-v0.22.0/qashctl/graphics/icons/000077500000000000000000000000001354534512100202035ustar00rootroot00000000000000qastools-v0.22.0/qashctl/graphics/icons/app-icon-16x16.png000066400000000000000000000023541354534512100232060ustar00rootroot00000000000000PNG  IHDROc#" vpAg\ƭbKGDC pHYsHHFk>wIDATHǭkLW8#Q-"`S."AE.BVhPłyb-ҐmZK_XҦ"`pg4~?ܓs=sv Yp̆w=-]zl%>+אy)*A^cL*{bbwK&h{z:7<%hh`Cz9#a_)ꙝ;;0g_`v`ޑN-,r7 Rl>!/ ,{1^\u9-JJa= <݁i mO|+0艷A.PYq. X r Wz_W:!Vs)! zgNƍ"~jxM-2TIPe-{Q.unChmZl(nbzNoRՖNs8"$ L.ҘAJ:&5BoVe"ӂ?h2prGEx։wej.Tbt# Ȯ $ I&I'!Z73ݹL!fum3r2tk=ڡȐB{18x[1bj/sycl_w\'#t':qQ??/Z[W#%آ5}ASb4$ W@AS+O-"4MmnsD~@|y|_Hf𤠥Q\{X&g_%@vI=ߘʉJU[wb%5mM% ~)7#$& v Pu*]<[2Pc歏sVtt:,Lg Jl@g@H mƚզ]ۜ'LOO60~/~>nip郒pπ_@0%MH(=<. ڭZVwFU;RV4ٷp~> !!qܙM$$cڮaiDXU*Iפ"4e@,d BtJM /'h#) G<^K9~@H;ڒ*fqYIENDB`qastools-v0.22.0/qashctl/graphics/icons/app-icon-32x32.png000066400000000000000000000036451354534512100232060ustar00rootroot00000000000000PNG  IHDR #ꦷ vpAg bKGDC pHYsHHFk>0IDATh{PTU7Y,`Q>42KlHpYey,CY)4PAF9 DsȢS|4F2Pv>swfIͽ3{.*؄5*z%iu&I˨_*&J?>6Sb5|PPш~i]9^Ei,ͬl7?86/о:^\< =:^0 =vʏȜ'Vs'yrIJ4MU %P&Gs*·b]yS^DW~Fu#V+8uBeV#UI9g5ϐ]$D2g[}s3읓 ğ`aΫi;Q9 Pf 5aJZ[6Z-Y>nc֩M{&-֘*I2 _| p'TN 55`5`` ps[Upaݑ"Xٱ]7~lJ8P9.bgD-fcTrXc#G?}_cP'@o = pYοd3m\ ayV'U7@zy!-k̷`~0ko L$a]p^LV=sduՇl ,&Nhu/y~U*IENDB`qastools-v0.22.0/qashctl/graphics/icons/app-icon-48x48.png000066400000000000000000000063201354534512100232150ustar00rootroot00000000000000PNG  IHDR00% vpAg00WbKGDC pHYsHHFk> [IDATxy\TwWEdw-#E &DqwPT 3.V̧-!Xb ZkT,SVAS,1Qp 7ėss~0`-vQNR&L <¼_@cchzMgiZ4L̸[̐Shj[^HUo?\wRﳴc-Y즫Ji=-[S,u4nKsW75l1;rK ->K;9r7v_u_s nۙQ}uc7k; ~!١#R2w~Nn@'L \;Yso*Bジ~5>7֯{Rɝzp_vyrӉ@ޭ$m#_Jt~6*j4i/5d^4^Yڹ^W]^l3~XC%NvUܵ' =+w7xE^+S6qzHf8+y\%RʦY㷉;ZUiuK=}Ν{=p/B%gp''0sgƪq˽!p7N5qs/r\nŞ-bgz,\ԳwOpS_Ɓ.<s(2O7?,181[p}6n>K =Z}5g k{9짾m:e7q﹜=Eg\V} LC#E}?~;+x\kǍKC.?{ z̢:~3{yn`35< w6nŏxTh N]=U)mOswĀ?'x84~3KEsq/l犸GGa{[Da;F\t}GqMwU7Ul7_0l Dܾ؟/.,Py7p7v{ͷ'[^ߣ™鋛55&lJ5U;buC> üuK;Nw J>ֿkx0EGYC.@8!@vЌnC4MdI"B0%qll chmG;x#{?/|@{ Z?K6S[n6j Qap#n_ˀv=uNT]aYhp.ВEW93[hTN3Oq'.Чѥ]g"VJ0v h1>|)*Jי TRT-Nͤ5 X1C4x\*o,W827鯭܈y32(;˒9duҷ4+i`r̃R%&L2{~FaYk.p\(mn ę| Hcwv7cxH:OS {~b<On!#$Oī9@4|/ݽ2Yr{=0@B'P U@1 &Sr,P^W쓈3&LeL6e۝?gK^z&{.C/'.M`xO h/ifrѕl5-:ny:7lV mmVh?]Tv_ftଚLHPE2=o?MCw:ԴBZL/MR\ÿR:=q͘stE PD\Z+Ǵqj!YC@CIK>#ǀ3+T ۄlb[@Dkqn4xu+lzt ,6k>ڏYJ̤=;Ǒ.ЉerFM,LoNF@>@h.? `jLj@CngDUSp܄[cTYr];m~u lNX(&JiN-h6MLT0wd-ҘSm^! L79a*X a4(@:l5PYP{ @n5hIq)A дG pƊ1,iL%`iΆM]Y=2 h⥺bl󤤡5ehϦ|g]z‘h4Dzɯbrsɖad.G4Fd }:IReY,%LDzC72*2(V8c "*wbmNubc|`= `= `= Y;PsՑ;Atp . JfK ֳGd: mGn+p[\#3ɴ}=` {c= K E7ܢr@!>)R2ԆT SY@p7{ KuymmKT=xݥ X>Yui.ːˆpܳa@y0xrZ(M,n{[@g ?{(|fDU bW !<|NQY`߯ y oM<"@s =i-V[ςgAֳ Y#tfZhC xh43m]Ӟl _ഞQD%x`;.$m@“V_SyLS `D59z-$Y;P,aHbŸqOyPЭ+jހAd~h̿  @^ 8GkDg^]7 O5r%'o&3u_>0#H V.=k?7Ǔy|8NoDٜ K5_ ޕ3O I\:`fW Zz`ZUxIIENDB`qastools-v0.22.0/qashctl/graphics/icons/app-icon-64x64.png000066400000000000000000000022761354534512100232170ustar00rootroot00000000000000PNG  IHDR@@ vpAg@@`bKGDC pHYsHHFk>IIDATx\]HQ4vk ~ 0В@m1)( J0(DZwv!1q"!ž*` YAD-hGmvipؽ}޹svwf Kc.WF{pU߹u%ş~`IiZֻBvRE!Wz_lǚ(NkH%!#=stzsy[ZeK 0x{79vMwuunqqfW9~yw6lc.}y`cc 6[}Hn%$!-+3m|\SSY7j>im_!SmHz$75v\2%ݴI_;:,[ `v&wϞO!9Uײc˭ظ ҆t.yw7r\pʆb7a9΂[@xo q F">F(lkDi\%9 >ѱp 2 :roȞl udA@sC!AEIT=~of `]ʫBQ%A7@hҦ Ӷ1` @iIWH0@章&#4jhUMZkk3E @, F6 De F `tX0j&( !D 2<oB.E᳁p;LLIAUMTm;y6l0 s+``Pm{A+a6xOIENDB`qastools-v0.22.0/qashctl/graphics/icons/app-icon-source.svg000066400000000000000000000445561354534512100237460ustar00rootroot00000000000000 image/svg+xml qastools-v0.22.0/qashctl/graphics/icons/app-icon.svg000066400000000000000000000227231354534512100224400ustar00rootroot00000000000000 qastools-v0.22.0/qashctl/share/000077500000000000000000000000001354534512100163725ustar00rootroot00000000000000qastools-v0.22.0/qashctl/share/CMakeLists.txt000066400000000000000000000005211354534512100211300ustar00rootroot00000000000000# Desktop file SET ( desktop_file_src ${CMAKE_CURRENT_SOURCE_DIR}/application.desktop ) SET ( desktop_file ${CMAKE_CURRENT_BINARY_DIR}/${PROGRAM_NAME}.desktop ) CONFIGURE_FILE ( ${desktop_file_src} ${desktop_file} ) INSTALL( FILES ${desktop_file} DESTINATION ${INSTALL_DIR_DESKTOP} ) # Subdirectories ADD_SUBDIRECTORY ( man ) qastools-v0.22.0/qashctl/share/application.desktop000066400000000000000000000010041354534512100222630ustar00rootroot00000000000000[Desktop Entry] Type=Application Name=${PROGRAM_TITLE} GenericName=ALSA HCTL mixer GenericName[de]=ALSA HCTL mixer GenericName[he]=מערבל ALSA HCTL GenericName[it]=ALSA HCTL mixer GenericName[ru]=ALSA HCTL микшер Exec=${PROGRAM_NAME} Icon=${PROGRAM_NAME} StartupNotify=false Terminal=false Categories=AudioVideo;Audio;Mixer;Qt; Keywords=ALSA;Audio;Mixer;Qt; Comment=ALSA HCTL mixer Comment[de]=ALSA HCTL mixer Comment[he]=מערבל ALSA HCTL Comment[it]=ALSA HCTL mixer Comment[ru]=ALSA HCTL микшер qastools-v0.22.0/qashctl/share/man/000077500000000000000000000000001354534512100171455ustar00rootroot00000000000000qastools-v0.22.0/qashctl/share/man/CMakeLists.txt000066400000000000000000000013361354534512100217100ustar00rootroot00000000000000# Find gzip FIND_PACKAGE ( UnixCommands REQUIRED ) IF ( NOT GZIP ) MESSAGE ( FATAL_ERROR "Unable to find 'gzip' program" ) ENDIF ( NOT GZIP ) # Configure manpages SET ( man_src ${CMAKE_CURRENT_SOURCE_DIR}/manpage.1.cmake ) SET ( man_plain ${CMAKE_CURRENT_BINARY_DIR}/manpage.1 ) SET ( man_gz ${CMAKE_CURRENT_BINARY_DIR}/manpage.1.gz ) CONFIGURE_FILE ( ${man_src} ${man_plain} ) # Compress manpages ADD_CUSTOM_COMMAND ( OUTPUT ${man_gz} COMMAND ${GZIP} -c -9 ${man_plain} > ${man_gz} DEPENDS ${man_plain} COMMENT "Building ${man_gz}" ) ADD_CUSTOM_TARGET ( qashctl_manpage ALL DEPENDS ${man_gz} ) # Installation of the manpage INSTALL ( FILES ${man_gz} DESTINATION ${INSTALL_DIR_MAN} RENAME ${PROGRAM_NAME}.1.gz ) qastools-v0.22.0/qashctl/share/man/manpage.1.cmake000066400000000000000000000012571354534512100217230ustar00rootroot00000000000000.TH ${PROGRAM_NAME_UCASE} "1" "2011-12-30" "Linux" "QasTools Manuals" .SH NAME ${PROGRAM_NAME} \- Desktop mixer for ALSA's "High level Control Interface" .SH SYNOPSIS .B ${PROGRAM_NAME} [OPTION]... .SH DESCRIPTION .B ${PROGRAM_TITLE} is a desktop mixer application for ALSA's "High level Control Interface" (HCTL). .SH OPTIONS .TP \fB\-h\fR, \fB\-\-help\fR prints a help text. .TP \fB\-c\fR, \fB\-\-copying\fR prints copying information. .TP \fB\-v\fR, \fB\-\-version\fR prints the program version. .SH NOTES \fB${PROGRAM_TITLE}\fP is part of the \fBQasTools\fP applications collection. It is written in C++ using the Qt GUI libraries. .SH SEE ALSO .B qasconfig(1), qasmixer(1) qastools-v0.22.0/qashctl/src/000077500000000000000000000000001354534512100160575ustar00rootroot00000000000000qastools-v0.22.0/qashctl/src/CMakeLists.txt000066400000000000000000000132731354534512100206250ustar00rootroot00000000000000# --- Find modules FIND_PACKAGE ( Qt5Widgets ) FIND_PACKAGE ( Qt5Svg ) FIND_PACKAGE ( ALSA REQUIRED ) # TODO: FIND_PACKAGE SET ( UDEV_LIBRARIES udev ) # --- Configure files INCLUDE ( CheckIncludeFiles ) CONFIGURE_FILE ( ${SHARED_SRC_DIR}/qastools_config.hpp.cmake ${CMAKE_CURRENT_BINARY_DIR}/qastools_config.hpp ) # --- Sources SET ( SRC_GUI ${SHARED_SRC_DIR}/qsnd/alsa.cpp ${SHARED_SRC_DIR}/qsnd/alsa_config_watcher.cpp ${SHARED_SRC_DIR}/qsnd/event_types.cpp ${SHARED_SRC_DIR}/qsnd/ctl_address_argument.cpp ${SHARED_SRC_DIR}/qsnd/ctl_address.cpp ${SHARED_SRC_DIR}/qsnd/ctl_format_argument.cpp ${SHARED_SRC_DIR}/qsnd/ctl_format.cpp ${SHARED_SRC_DIR}/qsnd/card_info.cpp ${SHARED_SRC_DIR}/qsnd/cards_model.cpp ${SHARED_SRC_DIR}/qsnd/controls_database.cpp ${SHARED_SRC_DIR}/qsnd/controls_model.cpp ${SHARED_SRC_DIR}/qsnd/mixer_hctl.cpp ${SHARED_SRC_DIR}/qsnd/mixer_hctl_elem.cpp ${SHARED_SRC_DIR}/qsnd/mixer_hctl_elem_group.cpp ${SHARED_SRC_DIR}/qsnd/mixer_hctl_info_db.cpp ${SHARED_SRC_DIR}/qsnd/udev_device_lookout.cpp ${SHARED_SRC_DIR}/dpe/image_allocator.cpp ${SHARED_SRC_DIR}/dpe/image.cpp ${SHARED_SRC_DIR}/dpe/image_request.cpp ${SHARED_SRC_DIR}/dpe/image_set.cpp ${SHARED_SRC_DIR}/dpe/image_set_group.cpp ${SHARED_SRC_DIR}/dpe/image_set_meta.cpp ${SHARED_SRC_DIR}/dpe/image_set_state.cpp ${SHARED_SRC_DIR}/dpe/is_buffer.cpp ${SHARED_SRC_DIR}/dpe/is_buffer_handle.cpp ${SHARED_SRC_DIR}/dpe/painter.cpp ${SHARED_SRC_DIR}/dpe/painter_simple.cpp ${SHARED_SRC_DIR}/dpe/painter_thread.cpp ${SHARED_SRC_DIR}/dpe/painter_thread_shared.cpp ${SHARED_SRC_DIR}/dpe/paint_job.cpp ${SHARED_SRC_DIR}/wdg/label_width.cpp ${SHARED_SRC_DIR}/wdg/label_elide.cpp ${SHARED_SRC_DIR}/wdg/tree_view_kv.cpp ${SHARED_SRC_DIR}/wdg/text_browser.cpp ${SHARED_SRC_DIR}/wdg/scroll_area_horizontal.cpp ${SHARED_SRC_DIR}/wdg/scroll_area_vertical.cpp ${SHARED_SRC_DIR}/wdg/color_methods.cpp ${SHARED_SRC_DIR}/wdg/cubic_curve.cpp ${SHARED_SRC_DIR}/wdg/uint_mapper.cpp ${SHARED_SRC_DIR}/wdg/ds_widget_painter.cpp ${SHARED_SRC_DIR}/wdg/ds_widget_style_db.cpp ${SHARED_SRC_DIR}/wdg/ds_imaging.cpp ${SHARED_SRC_DIR}/wdg/ds_switch.cpp ${SHARED_SRC_DIR}/wdg/ds_switch_painter_circle.cpp ${SHARED_SRC_DIR}/wdg/ds_switch_painter_svg.cpp ${SHARED_SRC_DIR}/wdg/ds_slider.cpp ${SHARED_SRC_DIR}/wdg/ds_slider_meta_bg.cpp ${SHARED_SRC_DIR}/wdg/ds_slider_painter_bevelled.cpp ${SHARED_SRC_DIR}/wdg/event_types.cpp ${SHARED_SRC_DIR}/wdg/pass_events.cpp ${SHARED_SRC_DIR}/wdg/pad_proxies_column.cpp ${SHARED_SRC_DIR}/wdg/pad_proxies_group.cpp ${SHARED_SRC_DIR}/wdg/pad_proxy.cpp ${SHARED_SRC_DIR}/wdg/pad_proxy_enum.cpp ${SHARED_SRC_DIR}/wdg/pad_proxy_slider.cpp ${SHARED_SRC_DIR}/wdg/pad_proxy_style.cpp ${SHARED_SRC_DIR}/wdg/pad_proxy_switch.cpp ${SHARED_SRC_DIR}/wdg/pad_focus_info.cpp ${SHARED_SRC_DIR}/wdg/layout_weights.cpp ${SHARED_SRC_DIR}/wdg/equal_columns_layout_group.cpp ${SHARED_SRC_DIR}/wdg/equal_columns_layout.cpp ${SHARED_SRC_DIR}/wdg/sliders_pad.cpp ${SHARED_SRC_DIR}/wdg/sliders_pad_data.cpp ${SHARED_SRC_DIR}/wdg/sliders_pad_footer.cpp ${SHARED_SRC_DIR}/wdg/sliders_pad_header.cpp ${SHARED_SRC_DIR}/wdg/sliders_pad_header_data.cpp ${SHARED_SRC_DIR}/wdg/sliders_pad_layout.cpp ${SHARED_SRC_DIR}/wdg/sliders_pad_style.cpp ${SHARED_SRC_DIR}/mwdg/event_types.cpp ${SHARED_SRC_DIR}/mwdg/slider_status_widget.cpp ${SHARED_SRC_DIR}/mwdg/controls_view.cpp ${SHARED_SRC_DIR}/mwdg/controls_delegate.cpp ${SHARED_SRC_DIR}/mwdg/ctl_arg_view.cpp ${SHARED_SRC_DIR}/mwdg/ctl_arg_view_integer.cpp ${SHARED_SRC_DIR}/mwdg/ctl_arg_view_string.cpp ${SHARED_SRC_DIR}/mwdg/ctl_arg_view_card.cpp ${SHARED_SRC_DIR}/mwdg/inputs_setup.cpp ${SHARED_SRC_DIR}/mwdg/mixer_device_setup.cpp ${SHARED_SRC_DIR}/mwdg/mixer_style.cpp ${SHARED_SRC_DIR}/views/view_utility.cpp ${SHARED_SRC_DIR}/views/message_widget.cpp ${SHARED_SRC_DIR}/views/view_base_setup.cpp ${SHARED_SRC_DIR}/views/view_base.cpp ${SHARED_SRC_DIR}/views/device_selection_view_setup.cpp ${SHARED_SRC_DIR}/views/device_selection_view.cpp ${SHARED_SRC_DIR}/views/basic_dialog.cpp ${SHARED_SRC_DIR}/views/multi_page_dialog.cpp ${SHARED_SRC_DIR}/views/info_dialog.cpp ${SHARED_SRC_DIR}/license_texts.cpp mwdg/mixer_hctl.cpp mwdg/mixer_hctl_edit_bool.cpp mwdg/mixer_hctl_edit_enum.cpp mwdg/mixer_hctl_edit_int.cpp mwdg/mixer_hctl_editor.cpp mwdg/mixer_hctl_editor_data.cpp mwdg/mixer_hctl_edit_unsupported.cpp mwdg/mixer_hctl_int_proxies_group.cpp mwdg/mixer_hctl_int_proxy_column.cpp mwdg/mixer_hctl_int_proxy_slider.cpp mwdg/mixer_hctl_proxies_group.cpp mwdg/mixer_hctl_proxy.cpp mwdg/mixer_hctl_proxy_enum.cpp mwdg/mixer_hctl_proxy_switch.cpp mwdg/mixer_hctl_slider_status_widget.cpp mwdg/mixer_hctl_table_model.cpp mwdg/mixer_hctl_tree_model.cpp views/mixer_hctl_setup.cpp views/mixer_hctl.cpp info_texts.cpp main_window_setup.cpp main_window.cpp desktop_items.cpp main.cpp ) # --- Compiler flags SET ( CMAKE_CXX_STANDARD 17 ) SET ( CMAKE_CXX_STANDARD_REQUIRED OFF ) SET ( CMAKE_CXX_EXTENSIONS OFF ) SET ( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wextra -Wunused -Wall" ) SET ( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 -g -fno-inline" ) SET ( CMAKE_CXX_FLAGS_RELEASE "-O2 ${CMAKE_CXX_FLAGS_RELEASE}" ) # --- Include directories INCLUDE_DIRECTORIES ( ${CMAKE_CURRENT_SOURCE_DIR} ) INCLUDE_DIRECTORIES ( ${CMAKE_CURRENT_BINARY_DIR} ) INCLUDE_DIRECTORIES ( ${SHARED_INC_DIR} ) INCLUDE_DIRECTORIES ( ${ALSA_INCLUDE_DIRS} ) # --- Executable ADD_EXECUTABLE ( ${PROGRAM_NAME} ${SRC_GUI} ${SRC_GUI_MOC} ) SET_TARGET_PROPERTIES ( ${PROGRAM_NAME} PROPERTIES AUTOMOC ON ) TARGET_LINK_LIBRARIES ( ${PROGRAM_NAME} Qt5::Widgets Qt5::Svg ${ALSA_LIBRARIES} ${UDEV_LIBRARIES} ) # --- Installation INSTALL ( TARGETS ${PROGRAM_NAME} RUNTIME DESTINATION ${INSTALL_DIR_BIN} ) qastools-v0.22.0/qashctl/src/desktop_items.cpp000066400000000000000000000046331354534512100214430ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "desktop_items.hpp" #include "qastools_config.hpp" #include "info_texts.hpp" #include #include #include Desktop_Items::Desktop_Items ( ) { } Desktop_Items::~Desktop_Items ( ) { } int Desktop_Items::init_settings ( int argc, char * argv[] ) { //_dsetup.read_from_storage(); return parse_cmd_options ( argc, argv ); } int Desktop_Items::parse_cmd_options ( int argc, char * argv[] ) { // Suppresses error messages by getopt_long opterr = 0; QString card_idx; QString ctl_address; bool flag_print_version ( false ); bool flag_print_help ( false ); bool flag_print_copy_info ( false ); bool scan_further ( true ); while ( scan_further ) { static struct option long_opts[] = { { "help", no_argument, 0, 'h' }, { "copying", no_argument, 0, 'i' }, { "version", no_argument, 0, 'v' }, {0, 0, 0, 0} }; // getopt_long stores the option index here. int long_opts_idx ( 0 ); int opt_char = getopt_long ( argc, argv, "hc:D:tniv", long_opts, &long_opts_idx ); // Leave loop if ( opt_char < 0 ) { break; } switch ( opt_char ) { case 0: break; case 'h': flag_print_help = true; scan_further = false; break; case 'i': flag_print_copy_info = true; break; case 'v': flag_print_version = true; break; default: // Dont't break, as the option may be for QT break; } } if ( flag_print_help ) { { ::std::stringstream msg; msg << "Usage:" << ::std::endl; msg << " " << PROGRAM_NAME << " [OPTION]..." << ::std::endl; msg << ::std::endl; msg << info_text_options; msg << ::std::endl; ::std::cout << msg.str() << ::std::flush; } return -1; } if ( flag_print_version ) { { ::std::stringstream msg; msg << PROGRAM_NAME << " " << VERSION << ::std::endl; ::std::cout << msg.str() << ::std::flush; } return -1; } if ( flag_print_copy_info ) { { ::std::stringstream msg; msg << PROGRAM_TITLE; msg << " - desktop mixer for ALSA's High level Control Interface."; msg << ::std::endl; msg << ::std::endl; msg << license_text_short; msg << ::std::endl; ::std::cout << msg.str() << ::std::flush; } return -1; } return 0; } void Desktop_Items::start ( bool ) { _mwin.reset ( new Main_Window ); _mwin->restore_state(); _mwin->show(); } qastools-v0.22.0/qashctl/src/desktop_items.hpp000066400000000000000000000015471354534512100214510ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_desktop_items_hpp__ #define __INC_desktop_items_hpp__ #include "main_window.hpp" #include /// @brief Manages all items that appear on the desktop /// class Desktop_Items { // Public methods public: Desktop_Items ( ); ~Desktop_Items ( ); /// @brief Reads options from storage and command line /// /// @return A negative value on an error int init_settings ( int argc, char * argv[] ); /// @brief Start the mixer window and/or tray icon /// void start ( bool restore_session_n = false ); /// @brief Command line option parser /// /// @return A negative value on an error int parse_cmd_options ( int argc, char * argv[] ); // Private attributes private: QScopedPointer < Main_Window > _mwin; }; #endif qastools-v0.22.0/qashctl/src/info_texts.cpp000066400000000000000000000005011354534512100207410ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "info_texts.hpp" const char info_text_options[] = "\ Options:\n\ -h, --help prints this help\n\ -i, --copying prints copying information\n\ -v, --version prints the program version\n\ "; qastools-v0.22.0/qashctl/src/info_texts.hpp000066400000000000000000000003551354534512100207550ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_info_texts_hpp__ #define __INC_info_texts_hpp__ #include "license_texts.hpp" extern const char info_text_options[]; #endif qastools-v0.22.0/qashctl/src/main.cpp000066400000000000000000000016551354534512100175160ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include #include "qastools_config.hpp" #include "views/view_utility.hpp" #include "desktop_items.hpp" #include #include /// @brief The main function /// int main ( int argc, char * argv[] ) { // Qt Application QApplication app ( argc, argv ); app.setOrganizationName ( QString ( PACKAGE_NAME ).toLower() ); app.setApplicationName ( QString ( PROGRAM_NAME ).toLower() ); app.setAttribute ( Qt::AA_DontShowIconsInMenus, false ); Desktop_Items ditems; { int res ( ditems.init_settings ( argc, argv ) ); if ( res < ditems.init_settings ( argc, argv ) ) { return res; } } // Load application icon, translators ::Views::load_application_icon ( &app, "multimedia-volume-control" ); ::Views::load_translators ( &app ); ditems.start ( app.isSessionRestored() ); return app.exec(); } qastools-v0.22.0/qashctl/src/main_window.cpp000066400000000000000000000253531354534512100211060ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "main_window.hpp" #include "qastools_config.hpp" #include "qsnd/alsa_config_watcher.hpp" #include "wdg/ds_switch_painter_circle.hpp" #include "wdg/ds_switch_painter_svg.hpp" #include "wdg/ds_slider_painter_bevelled.hpp" #include "mwdg/mixer_style.hpp" #include "views/info_dialog.hpp" #include "views/device_selection_view.hpp" #include "views/view_utility.hpp" #include #include #include #include #include #include #include Main_Window::Main_Window ( ) { setWindowTitle ( PROGRAM_TITLE ); setObjectName ( PROGRAM_TITLE ); setContextMenuPolicy ( Qt::NoContextMenu ); // Strings and icons _str_fscreen_enable = tr ( "&Fullscreen mode" ); _str_fscreen_disable = tr ( "Exit &fullscreen mode" ); _icon_fscreen_enable = QIcon::fromTheme ( "view-fullscreen" ); _icon_fscreen_disable = QIcon::fromTheme ( "view-restore" ); // File watcher { ::QSnd::ALSA_Config_Watcher * watcher ( new ::QSnd::ALSA_Config_Watcher ( this ) ); connect ( watcher, SIGNAL ( sig_change() ), this, SLOT ( refresh() ) ); } // Slider painter bevelled { ::Wdg::Painter::DS_Slider_Painter_Bevelled * pnt ( new ::Wdg::Painter::DS_Slider_Painter_Bevelled ); pnt->set_wdg_style_db ( &_wdg_style_db ); _image_alloc.install_painter ( pnt ); } // Switch painter circle { ::Wdg::Painter::DS_Switch_Painter_Circle * pnt ( new ::Wdg::Painter::DS_Switch_Painter_Circle ); pnt->set_group_variant ( ::Wdg::DS_CIRCLE ); pnt->set_wdg_style_db ( &_wdg_style_db ); _image_alloc.install_painter ( pnt ); } // Switch painter SVG { QScopedPointer < ::Wdg::Painter::DS_Switch_Painter_SVG > pnt ( new ::Wdg::Painter::DS_Switch_Painter_SVG ); pnt->set_group_variant ( ::Wdg::DS_SVG_JOINED ); pnt->set_wdg_style_db ( &_wdg_style_db ); pnt->set_base_dir ( INSTALL_DIR_WIDGETS_GRAPHICS ); pnt->set_file_prefix_bg ( "sw_joined_bg_" ); pnt->set_file_prefix_handle ( "sw_joined_handle_" ); if ( pnt->ready() ) { _image_alloc.install_painter ( pnt.take() ); } } // Init widget style database { ::MWdg::Mixer_Style mstyle; ::MWdg::Mixer_Style::Style_Type stype; stype = ::MWdg::Mixer_Style::PLAYBACK ; _wdg_style_db.palettes.insert ( stype, mstyle.style_palette ( stype ) ); stype = ::MWdg::Mixer_Style::CAPTURE; _wdg_style_db.palettes.insert ( stype, mstyle.style_palette ( stype ) ); } // Init setup { _setup.hctl.wdg_style_db = &_wdg_style_db; _setup.hctl.image_alloc = &_image_alloc; } // Widgets and docks init_widgets(); init_menu_bar(); update_fullscreen_action(); } void Main_Window::init_widgets ( ) { // Device selection { // QueuedConnection to update the GUI before loading the mixer _dev_select = new ::Views::Device_Selection_View; _dev_select->hide(); connect ( _dev_select, SIGNAL ( sig_control_selected() ), this, SLOT ( select_ctl_from_side_iface() ) ); connect ( _dev_select, SIGNAL ( sig_close() ), this, SLOT ( toggle_device_selection() ) ); } // Central mixer { _mixer_hctl = new ::Views::Mixer_HCTL; } // Central splitter { _splitter.reset ( new QSplitter ); _splitter->addWidget ( _mixer_hctl ); _splitter->addWidget ( _dev_select ); _splitter->setStretchFactor ( 0, 1 ); _splitter->setStretchFactor ( 1, 0 ); _splitter->setCollapsible ( 0, false ); _splitter->setCollapsible ( 1, false ); setCentralWidget ( _splitter.data() ); } } void Main_Window::init_menu_bar ( ) { // Action: Quit QAction * act_quit ( new QAction ( tr ( "&Quit" ), this ) ); act_quit->setShortcut ( QKeySequence ( QKeySequence::Quit ) ); act_quit->setIcon ( QIcon::fromTheme ( "application-exit" ) ); // Action: Device selection _act_show_dev_select = new QAction ( this ); _act_show_dev_select->setText ( tr ( "Show &device selection" ) ); _act_show_dev_select->setCheckable ( true ); _act_show_dev_select->setShortcut ( _setup.dev_select.kseq_toggle_vis ); // Action: Fullscreen _act_fullscreen = new QAction ( this ); _act_fullscreen->setShortcut ( QKeySequence ( Qt::Key_F11 ) ); _act_fullscreen->setCheckable ( true ); // Action: Refresh QAction * act_refresh ( new QAction ( tr ( "&Refresh" ), this ) ); act_refresh->setShortcut ( QKeySequence ( QKeySequence::Refresh ) ); act_refresh->setIcon ( QIcon::fromTheme ( "view-refresh" ) ); // Action: Info QAction * act_info = new QAction ( tr ( "&Info" ), this ); act_info->setShortcut ( QKeySequence ( QKeySequence::HelpContents ) ); act_info->setIcon ( QIcon::fromTheme ( "help-about" ) ); // Menu: File { QMenu * cmenu ( menuBar()->addMenu ( tr ( "&File" ) ) ); cmenu->addAction ( act_quit ); } // Menu: View { QMenu * cmenu = menuBar()->addMenu ( tr ( "&View" ) ); cmenu->addAction ( _act_show_dev_select ); cmenu->addAction ( _act_fullscreen ); cmenu->addSeparator(); cmenu->addAction ( act_refresh ); } // Menu: Help { QMenu * menu = menuBar()->addMenu ( tr ( "&Help" ) ); menu->addAction ( act_info ); } // Connect actions connect ( act_quit, SIGNAL ( triggered() ), this, SLOT ( close() ) ); connect ( _act_show_dev_select, SIGNAL ( toggled ( bool ) ), this, SLOT ( show_device_selection ( bool ) ) ); connect ( _act_fullscreen, SIGNAL ( toggled ( bool ) ), this, SLOT ( set_fullscreen ( bool ) ) ); connect ( act_refresh, SIGNAL ( triggered() ), this, SLOT ( refresh() ) ); connect ( act_info, SIGNAL ( triggered() ), this, SLOT ( show_info_dialog() ) ); } QSize Main_Window::sizeHint ( ) const { QSize res ( QMainWindow::sizeHint() ); ::Views::win_default_size ( res ); return res; } void Main_Window::restore_state ( ) { QSettings settings; QByteArray mwin_state; QByteArray mwin_geom; QByteArray mwin_splitter; // Main window state { settings.beginGroup ( "main_window" ); { mwin_state = settings.value ( "window_state", QByteArray() ).toByteArray(); mwin_geom = settings.value ( "window_geometry", QByteArray() ).toByteArray(); mwin_splitter = settings.value ( "splitter_state", QByteArray() ).toByteArray(); } _setup.show_dev_select = settings.value ( "show_device_selection", _setup.show_dev_select ).toBool(); settings.endGroup(); } // General { _setup.mixer_dev.ctl_addr = settings.value ( "current_device", _setup.mixer_dev.ctl_addr ).toString(); _setup.inputs.wheel_degrees = settings.value ( "wheel_degrees", _setup.inputs.wheel_degrees ).toUInt(); } // CTL mixer { settings.beginGroup ( "element_mixer" ); _setup.hctl.iface_name = settings.value ( "iface_name", _setup.hctl.iface_name ).toString(); _setup.hctl.elem_grp_name = settings.value ( "elem_grp_name", _setup.hctl.elem_grp_name ).toString(); _setup.hctl.elem_grp_index = settings.value ( "elem_grp_index", _setup.hctl.elem_grp_index ).toUInt(); settings.endGroup(); } // Device selection { settings.beginGroup ( "device_selection" ); _setup.dev_select.selection_db_set ( settings.value ( "selection_db", _setup.dev_select.selection_db_get() ).toStringList() ); settings.endGroup(); } // Sanitize values if ( _setup.mixer_dev.ctl_addr.isEmpty() ) { _setup.mixer_dev.ctl_addr = "default"; } if ( _setup.inputs.wheel_degrees == 0 ) { _setup.inputs.wheel_degrees = 720; } _setup.inputs.update_translation(); // Apply values restoreState ( mwin_state ); if ( !restoreGeometry ( mwin_geom ) ) { ::Views::resize_to_default ( this ); } _splitter->restoreState ( mwin_splitter ); update_fullscreen_action(); show_device_selection ( _setup.show_dev_select ); _dev_select->set_view_setup ( &_setup.dev_select ); _dev_select->silent_select_ctl ( _setup.mixer_dev.ctl_addr ); _mixer_hctl->set_inputs_setup ( &_setup.inputs ); _mixer_hctl->set_mdev_setup ( &_setup.mixer_dev ); _mixer_hctl->set_view_setup ( &_setup.hctl ); } void Main_Window::save_state ( ) { QSettings settings; // Main window state { settings.beginGroup ( "main_window" ); settings.setValue ( "window_state", saveState() ); settings.setValue ( "window_geometry", saveGeometry() ); settings.setValue ( "splitter_state", _splitter->saveState() ); settings.setValue ( "show_device_selection", _setup.show_dev_select ); settings.endGroup(); } settings.setValue ( "current_device", _setup.mixer_dev.ctl_addr ); settings.setValue ( "wheel_degrees", _setup.inputs.wheel_degrees ); // CTL mixer { settings.beginGroup ( "element_mixer" ); settings.setValue ( "iface_name", _setup.hctl.iface_name ); settings.setValue ( "elem_grp_name", _setup.hctl.elem_grp_name ); settings.setValue ( "elem_grp_index", _setup.hctl.elem_grp_index ); settings.endGroup(); } // Device selection { settings.beginGroup ( "device_selection" ); settings.setValue ( "selection_db", _setup.dev_select.selection_db_get() ); settings.endGroup(); } } void Main_Window::refresh ( ) { //::std::cout << "Refresh" << "\n"; _mixer_hctl->set_mdev_setup ( 0 ); _mixer_hctl->set_mdev_setup ( &_setup.mixer_dev ); } void Main_Window::select_snd_ctl ( const QString & ctl_n ) { if ( ctl_n != _setup.mixer_dev.ctl_addr ) { _mixer_hctl->set_mdev_setup ( 0 ); _setup.mixer_dev.ctl_addr = ctl_n; _mixer_hctl->set_mdev_setup ( &_setup.mixer_dev ); } } void Main_Window::select_ctl_from_side_iface ( ) { select_snd_ctl ( _dev_select->selected_ctl().addr_str() ); } void Main_Window::set_fullscreen ( bool flag_n ) { if ( flag_n != isFullScreen() ) { if ( flag_n ) { showFullScreen(); } else { showNormal(); } update_fullscreen_action(); } } void Main_Window::show_device_selection ( bool flag_n ) { if ( _setup.show_dev_select != flag_n ) { _setup.show_dev_select = flag_n; } _act_show_dev_select->setChecked ( flag_n ); _dev_select->setVisible ( flag_n ); } void Main_Window::toggle_device_selection ( ) { _act_show_dev_select->setChecked ( !_act_show_dev_select->isChecked() ); } void Main_Window::update_fullscreen_action ( ) { QString * txt; QIcon * icon; bool checked; if ( isFullScreen() ) { txt = &_str_fscreen_disable; icon = &_icon_fscreen_disable; checked = true; } else { txt = &_str_fscreen_enable; icon = &_icon_fscreen_enable; checked = false; } _act_fullscreen->setText ( *txt ); _act_fullscreen->setIcon ( *icon ); _act_fullscreen->setChecked ( checked ); } void Main_Window::show_info_dialog ( ) { if ( _info_dialog == 0 ) { ::Views::Info_Dialog * dlg ( new ::Views::Info_Dialog ( this ) ); dlg->setAttribute ( Qt::WA_DeleteOnClose ); _info_dialog = dlg; } _info_dialog->show(); } void Main_Window::changeEvent ( QEvent * event_n ) { QMainWindow::changeEvent ( event_n ); if ( event_n->type() == QEvent::WindowStateChange ) { update_fullscreen_action(); } } void Main_Window::closeEvent ( QCloseEvent * event_n ) { save_state(); QMainWindow::closeEvent ( event_n ); } qastools-v0.22.0/qashctl/src/main_window.hpp000066400000000000000000000037201354534512100211050ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_main_window_hpp__ #define __INC_main_window_hpp__ #include "dpe/image_allocator.hpp" #include "wdg/ds_widget_style_db.hpp" #include "views/mixer_hctl.hpp" #include "main_window_setup.hpp" #include #include #include #include #include #include // Forward declaration namespace Views { class Mixer_HCTL; } namespace Views { class Device_Selection_View; } /// @brief Main_Window /// class Main_Window : public QMainWindow { Q_OBJECT // Public methods public: Main_Window ( ); QSize sizeHint ( ) const; void restore_state ( ); void save_state ( ); // Public slots public slots: void select_snd_ctl ( const QString & ctl_n ); void refresh ( ); void set_fullscreen ( bool flag_n ); // Device selection void show_device_selection ( bool flag_n ); void toggle_device_selection ( ); // Protected methods protected: void changeEvent ( QEvent * event_n ); void closeEvent ( QCloseEvent * event_n ); // Private slots private slots: void select_ctl_from_side_iface ( ); void show_info_dialog ( ); // Private methods private: void init_widgets ( ); void init_menu_bar ( ); void update_fullscreen_action ( ); // Private attributes private: // Shared storages and settings ::Wdg::DS_Widget_Style_Db _wdg_style_db; ::dpe::Image_Allocator _image_alloc; // Widgets settings Main_Window_Setup _setup; // Widgets QScopedPointer < QSplitter > _splitter; ::Views::Mixer_HCTL * _mixer_hctl; ::Views::Device_Selection_View * _dev_select; QPointer < QDialog > _info_dialog; // Menubar QMenu * _menu_mixer; QAction * _act_show_dev_select; QAction * _act_fullscreen; // Strings and icons QString _str_fscreen_enable; QString _str_fscreen_disable; QIcon _icon_fscreen_enable; QIcon _icon_fscreen_disable; }; #endif qastools-v0.22.0/qashctl/src/main_window_setup.cpp000066400000000000000000000003141354534512100223140ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "main_window_setup.hpp" Main_Window_Setup::Main_Window_Setup ( ) : show_dev_select ( true ) { } qastools-v0.22.0/qashctl/src/main_window_setup.hpp000066400000000000000000000013151354534512100223230ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_main_window_setup_hpp__ #define __INC_main_window_setup_hpp__ #include "mwdg/mixer_device_setup.hpp" #include "mwdg/inputs_setup.hpp" #include "views/mixer_hctl_setup.hpp" #include "views/device_selection_view_setup.hpp" #include #include /// @brief Main_Window_Setup /// class Main_Window_Setup { // Public methods public: Main_Window_Setup ( ); // Public attributes public: bool show_dev_select; ::MWdg::Mixer_Device_Setup mixer_dev; ::MWdg::Inputs_Setup inputs; ::Views::Mixer_HCTL_Setup hctl; ::Views::Device_Selection_View_Setup dev_select; }; #endif qastools-v0.22.0/qashctl/src/mwdg/000077500000000000000000000000001354534512100170155ustar00rootroot00000000000000qastools-v0.22.0/qashctl/src/mwdg/mixer_hctl.cpp000066400000000000000000000233741354534512100216700ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "mixer_hctl.hpp" #include #include #include #include "qsnd/mixer_hctl_elem.hpp" #include "qsnd/mixer_hctl_elem_group.hpp" #include "mwdg/mixer_hctl_editor_data.hpp" #include "mwdg/mixer_hctl_proxy.hpp" #include "mwdg/mixer_hctl_edit_bool.hpp" #include "mwdg/mixer_hctl_edit_enum.hpp" #include "mwdg/mixer_hctl_edit_int.hpp" #include "mwdg/mixer_hctl_edit_unsupported.hpp" #include namespace MWdg { Mixer_HCTL::Mixer_HCTL ( QWidget * parent_n ) : QWidget ( parent_n ), _editor_pad ( 0 ) { _editor_data.reset ( new ::MWdg::Mixer_HCTL_Editor_Data ); { const QString dmask ( "
%1
\n
(%2)
" ); _ttip_name_lbl_mask = dmask.arg ( tr ( "Element name" ) ); } // Localized shared strings _editor_data->str_joined = tr ( "Joined" ); _editor_data->ttip_grid_lbl_elem = tr ( "Element index" ); _editor_data->ttip_grid_lbl_channel = tr ( "Channel %1" ); _editor_data->str_list_channel = tr ( "Ch. %1" ); _editor_data->ttip_list_channel = tr ( "Channel %1" ); { const QString dmask ( "
%1
" ); QString txt[2]; txt[0] = tr ( "Index: %1" ); txt[1] = tr ( "Channel: %2" ); _editor_data->ttip_grid_widget += dmask.arg ( txt[0] ); _editor_data->ttip_grid_widget += "\n"; _editor_data->ttip_grid_widget += dmask.arg ( txt[1] ); } // Pad widget layout { QVBoxLayout * lay_pad_wdg ( new QVBoxLayout ); lay_pad_wdg->setContentsMargins ( 0, 0, 0, 0 ); _pad_wdg.setLayout ( lay_pad_wdg ); } // Info widget 1 layout { QHBoxLayout * lay_elem_name ( new QHBoxLayout ); lay_elem_name->setContentsMargins ( 0, 0, 0, 0 ); lay_elem_name->addWidget ( &_info_lbl_name ); lay_elem_name->addStretch(); QHBoxLayout * lay_info_items_1 ( new QHBoxLayout ); lay_info_items_1->setContentsMargins ( 0, 0, 0, 0 ); { QGridLayout * lay_items ( new QGridLayout ); lay_items->setContentsMargins ( 0, 0, 0, 0 ); unsigned int row ( 0 ); unsigned int col ( 0 ); lay_items->addWidget ( &_info_lbl_count.name, row, col++ ); lay_items->addWidget ( &_info_lbl_count.value, row, col++ ); lay_items->addWidget ( &_info_lbl_flags.name, row, col++ ); lay_items->addWidget ( &_info_lbl_flags.value, row, col++ ); ++row; col = 0; lay_items->addWidget ( &_info_lbl_index.name, row, col++ ); lay_items->addWidget ( &_info_lbl_index.value, row, col++ ); lay_items->addWidget ( &_info_lbl_dev.name, row, col++ ); lay_items->addWidget ( &_info_lbl_dev.value, row, col++ ); lay_items->addWidget ( &_info_lbl_numid.name, row, col++ ); lay_items->addWidget ( &_info_lbl_numid.value, row, col++ ); lay_info_items_1->addLayout ( lay_items ); lay_info_items_1->addStretch(); } QVBoxLayout * lay_info_wdg ( new QVBoxLayout ); lay_info_wdg->setContentsMargins ( 0, 0, 0, 0 ); lay_info_wdg->addLayout ( lay_elem_name ); lay_info_wdg->addLayout ( lay_info_items_1 ); _info_wdg.setLayout ( lay_info_wdg ); } // Item name labels _info_lbl_index.name.setText ( tr ( "Index:" ) ); _info_lbl_dev.name.setText ( tr ( "Device:" ) ); _info_lbl_flags.name.setText ( tr ( "Flags:" ) ); _info_lbl_count.name.setText ( tr ( "Channels:" ) ); _info_lbl_numid.name.setText ( tr ( "Num. id:" ) ); // Item name tooltips _info_lbl_index.name.setToolTip ( tr ( "Element index" ) ); _info_lbl_dev.name.setToolTip ( tr ( "Device" ) ); _info_lbl_flags.name.setToolTip ( tr ( "Flags" ) ); _info_lbl_count.name.setToolTip ( tr ( "Channel count" ) ); _info_lbl_numid.name.setToolTip ( tr ( "Numeric Id" ) ); // Item values _info_dev_mask = "%1,%2"; _info_lbl_index.value.set_min_text ( "1000" ); _info_lbl_dev.value.set_min_text ( "99,99" ); _info_lbl_flags.value.set_min_text ( "MMMM" ); _info_lbl_count.value.set_min_text ( "1000" ); _info_lbl_numid.value.set_min_text ( "1000" ); // Item value tooltips { QString ttip_dev ( _info_dev_mask ); ttip_dev = ttip_dev.arg ( tr ( "Device" ) ); ttip_dev = ttip_dev.arg ( tr ( "Subdevice" ) ); _info_lbl_index.value.setToolTip ( _info_lbl_index.name.toolTip() ); _info_lbl_dev.value.setToolTip ( ttip_dev ); _info_lbl_count.value.setToolTip ( _info_lbl_count.name.toolTip() ); _info_lbl_numid.value.setToolTip ( _info_lbl_numid.name.toolTip() ); } // Item alignment { const Qt::Alignment align_cc ( Qt::AlignHCenter | Qt::AlignVCenter ); //const Qt::Alignment align_lc ( Qt::AlignLeft | Qt::AlignVCenter ); _info_lbl_index.value.setAlignment ( align_cc ); _info_lbl_dev.value.setAlignment ( align_cc ); _info_lbl_flags.value.setAlignment ( align_cc ); _info_lbl_count.value.setAlignment ( align_cc ); _info_lbl_numid.value.setAlignment ( align_cc ); } // Set final layout { QVBoxLayout * lay_vbox ( new QVBoxLayout ); lay_vbox->addWidget ( &_info_wdg, 0 ); lay_vbox->addWidget ( &_pad_wdg, 1 ); setLayout ( lay_vbox ); } update_info(); } Mixer_HCTL::~Mixer_HCTL ( ) { clear(); } ::QSnd::Mixer_HCTL_Elem_Group * Mixer_HCTL::snd_elem_group ( ) const { return _editor_data->snd_elem_group; } unsigned int Mixer_HCTL::elem_idx ( ) const { return _editor_data->elem_idx; } const ::QSnd::Mixer_HCTL_Info_Db * Mixer_HCTL::ctl_info_db ( ) const { return _editor_data->ctl_info_db; } void Mixer_HCTL::set_ctl_info_db ( const ::QSnd::Mixer_HCTL_Info_Db * info_db_n ) { _editor_data->ctl_info_db = info_db_n; } void Mixer_HCTL::set_inputs_setup ( const ::MWdg::Inputs_Setup * setup_n ) { if ( _editor_pad != 0 ) { _editor_pad->set_inputs_setup ( 0 ); } _inputs_setup = setup_n; if ( inputs_setup() != 0 ) { if ( _editor_pad != 0 ) { _editor_pad->set_inputs_setup ( inputs_setup() ); } } } const ::Wdg::DS_Widget_Style_Db * Mixer_HCTL::wdg_style_db ( ) const { return _editor_data->wdg_style_db; } void Mixer_HCTL::set_wdg_style_db ( const ::Wdg::DS_Widget_Style_Db * style_db_n ) { _editor_data->wdg_style_db = style_db_n; } ::dpe::Image_Allocator * Mixer_HCTL::image_alloc ( ) const { return _editor_data->image_alloc; } void Mixer_HCTL::set_image_alloc ( ::dpe::Image_Allocator * alloc_n ) { _editor_data->image_alloc = alloc_n; } void Mixer_HCTL::clear ( ) { _editor_pad.reset(); _editor_data->snd_elem_group = 0; } void Mixer_HCTL::set_snd_elem_group ( ::QSnd::Mixer_HCTL_Elem_Group * elem_group_n, unsigned int index_n ) { if ( ( snd_elem_group() == elem_group_n ) && ( elem_idx() == index_n ) ) { return; } clear(); _editor_data->snd_elem_group = elem_group_n; _editor_data->elem_idx = index_n; if ( snd_elem_group() != 0 ) { setup_widgets(); } update_info(); } void Mixer_HCTL::setup_widgets ( ) { if ( snd_elem_group() == 0 ) { return; } if ( snd_elem_group()->num_elems() == 0 ) { return; } ::QSnd::Mixer_HCTL_Elem * elem0 ( snd_elem_group()->elem ( 0 ) ); if ( elem0->is_boolean() ) { _editor_pad.reset ( new Mixer_HCTL_Edit_Bool ( _editor_data.data(), this ) ); } else if ( elem0->is_enumerated() ) { _editor_pad.reset ( new Mixer_HCTL_Edit_Enum ( _editor_data.data(), this ) ); } else if ( elem0->is_integer() ) { _editor_pad.reset ( new Mixer_HCTL_Edit_Int ( _editor_data.data(), this ) ); } else { _editor_pad.reset ( new Mixer_HCTL_Edit_Unsupported ( _editor_data.data(), this ) ); } if ( _editor_pad != 0 ) { _pad_wdg.layout()->addWidget ( _editor_pad.data() ); _editor_pad->set_inputs_setup ( inputs_setup() ); } } void Mixer_HCTL::update_info ( ) { QFont name_fnt ( font() ); QString name_val; QString name_ttip; _info_wdg.setEnabled ( ( snd_elem_group() != 0 ) ); // Clear { QString clear_txt ( "" ); _info_lbl_name.setText ( clear_txt ); _info_lbl_index.value.setText ( clear_txt ); _info_lbl_dev.value.setText ( clear_txt ); _info_lbl_flags.value.setText ( clear_txt ); _info_lbl_count.value.setText ( clear_txt ); _info_lbl_numid.value.setText ( clear_txt ); } if ( snd_elem_group() == 0 ) { name_fnt.setItalic ( true ); name_val = tr ( "No element selected" ); } else { const ::QSnd::Mixer_HCTL_Elem * elem_first ( snd_elem_group()->elem ( 0 ) ); const QString dname ( elem_first->display_name() ); name_val = "

%1

"; name_val = name_val.arg ( dname ); // Tooltip name_ttip = _ttip_name_lbl_mask.arg ( elem_first->elem_name() ); if ( elem_idx() < snd_elem_group()->num_elems() ) { const QString val ( "%1" ); QString valc; ::QSnd::Mixer_HCTL_Elem * elem ( snd_elem_group()->elem ( elem_idx() ) ); valc = val.arg ( elem->elem_index() ); _info_lbl_index.value.setText ( valc ); valc = _info_dev_mask; valc = valc.arg ( elem->device() ); valc = valc.arg ( elem->subdevice() ); _info_lbl_dev.value.setText ( valc ); if ( ctl_info_db() != 0 ) { const QString wrap ( "
%1
" ); QString txt; QString accu; accu = ctl_info_db()->flag_readable_char ( elem->is_readable() ); accu += ctl_info_db()->flag_writable_char ( elem->is_writable() ); accu += ctl_info_db()->flag_active_char ( elem->is_active() ); accu += ctl_info_db()->flag_volatile_char ( elem->is_volatile() ); _info_lbl_flags.value.setText ( accu ); txt = ctl_info_db()->flag_readable_text ( elem->is_readable() ); accu = wrap.arg ( txt ); txt = ctl_info_db()->flag_writable_text ( elem->is_writable() ); accu += wrap.arg ( txt ); txt = ctl_info_db()->flag_active_text ( elem->is_active() ); accu += wrap.arg ( txt ); txt = ctl_info_db()->flag_volatile_text ( elem->is_volatile() ); accu += wrap.arg ( txt ); _info_lbl_flags.value.setToolTip ( accu ); } valc = val.arg ( elem->count() ); _info_lbl_count.value.setText ( valc ); valc = val.arg ( elem->elem_numid() ); _info_lbl_numid.value.setText ( valc ); } } _info_lbl_name.setText ( name_val ); _info_lbl_name.setToolTip ( name_ttip ); _info_lbl_name.setFont ( name_fnt ); } } // End of namespace qastools-v0.22.0/qashctl/src/mwdg/mixer_hctl.hpp000066400000000000000000000050421354534512100216650ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_mwdg_mixer_hctl_hpp__ #define __INC_mwdg_mixer_hctl_hpp__ #include "wdg/label_width.hpp" #include #include #include #include #include // Forward declaration namespace QSnd { class Mixer_HCTL_Elem_Group; class Mixer_HCTL_Info_Db; } namespace dpe { class Image_Allocator; } namespace Wdg { class DS_Widget_Style_Db; } namespace MWdg { class Mixer_HCTL_Editor; class Mixer_HCTL_Editor_Data; class Mixer_HCTL_Info_Db; class Mixer_HCTL_Elem_Group; class Inputs_Setup; } namespace MWdg { /// @brief Mixer_HCTL /// /// This widgets shows the appropriate Mixer_HCTL_Editor widget /// for a given ::QSnd::Mixer_HCTL_Elem_Group /// class Mixer_HCTL : public QWidget { Q_OBJECT // Public typedefs public: struct Label_Pair { ::Wdg::Label_Width name; ::Wdg::Label_Width value; }; // Public methods public: Mixer_HCTL ( QWidget * parent_n = 0 ); ~Mixer_HCTL ( ); // Shared data void set_ctl_info_db ( const ::QSnd::Mixer_HCTL_Info_Db * info_db_n ); const ::QSnd::Mixer_HCTL_Info_Db * ctl_info_db ( ) const; // Element ::QSnd::Mixer_HCTL_Elem_Group * snd_elem_group ( ) const; unsigned int elem_idx ( ) const; void set_snd_elem_group ( ::QSnd::Mixer_HCTL_Elem_Group * elem_group_n, unsigned int index_n = 0 ); // Image allocator ::dpe::Image_Allocator * image_alloc ( ) const; void set_image_alloc ( ::dpe::Image_Allocator * alloc_n ); // Widget style db const ::Wdg::DS_Widget_Style_Db * wdg_style_db ( ) const; void set_wdg_style_db ( const ::Wdg::DS_Widget_Style_Db * style_db_n ); // Inputs setup const ::MWdg::Inputs_Setup * inputs_setup ( ) const; void set_inputs_setup ( const ::MWdg::Inputs_Setup * setup_n ); // Protected methods protected: void clear ( ); void update_info ( ); void setup_widgets ( ); // Private attributes private: QScopedPointer < ::MWdg::Mixer_HCTL_Editor_Data > _editor_data; const ::MWdg::Inputs_Setup * _inputs_setup; // Widgets QFrame _info_wdg; QWidget _pad_wdg; QScopedPointer < ::MWdg::Mixer_HCTL_Editor > _editor_pad; QLabel _info_lbl_name; Label_Pair _info_lbl_index; Label_Pair _info_lbl_dev; Label_Pair _info_lbl_flags; Label_Pair _info_lbl_count; Label_Pair _info_lbl_numid; QString _info_dev_mask; QString _ttip_name_lbl_mask; }; inline const ::MWdg::Inputs_Setup * Mixer_HCTL::inputs_setup ( ) const { return _inputs_setup; } } // End of namespace #endif qastools-v0.22.0/qashctl/src/mwdg/mixer_hctl_edit_bool.cpp000066400000000000000000000172741354534512100237120ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "mixer_hctl_edit_bool.hpp" #include "qsnd/mixer_hctl_elem.hpp" #include "qsnd/mixer_hctl_elem_group.hpp" #include "wdg/ds_switch.hpp" #include "wdg/label_width.hpp" #include "mwdg/mixer_hctl_proxy_switch.hpp" #include "mwdg/mixer_hctl_proxies_group.hpp" #include "mwdg/mixer_hctl_editor_data.hpp" #include #include #include #include #include #include namespace MWdg { Mixer_HCTL_Edit_Bool::Mixer_HCTL_Edit_Bool ( Mixer_HCTL_Editor_Data * data_n, QWidget * parent_n ) : Mixer_HCTL_Editor ( data_n, parent_n ) { if ( editor_data()->elem_idx < editor_data()->snd_elem_group->num_elems() ) { setup_single(); } else { setup_multi(); } update_proxies_values(); } Mixer_HCTL_Edit_Bool::~Mixer_HCTL_Edit_Bool ( ) { } Mixer_HCTL_Proxies_Group * Mixer_HCTL_Edit_Bool::create_proxies_group ( ::QSnd::Mixer_HCTL_Elem * elem_n ) { Mixer_HCTL_Proxies_Group * pgroup ( new Mixer_HCTL_Proxies_Group ( this ) ); const unsigned int num_channels ( elem_n->count() ); for ( unsigned int ii=0; ii < num_channels; ++ii ) { Mixer_HCTL_Proxy_Switch * mcps ( new Mixer_HCTL_Proxy_Switch ( pgroup ) ); mcps->set_snd_elem ( elem_n ); mcps->set_elem_idx ( ii ); mcps->set_enabled ( elem_n->is_writable() ); pgroup->append_proxy ( mcps ); } pgroup->set_joined ( elem_n->switches_equal() ); return pgroup; } void Mixer_HCTL_Edit_Bool::setup_single ( ) { ::QSnd::Mixer_HCTL_Elem * elem ( editor_data()->snd_elem_group->elem ( editor_data()->elem_idx ) ); const bool is_enabled ( elem->is_writable() ); Mixer_HCTL_Proxies_Group * pgroup ( create_proxies_group ( elem ) ); _proxies_groups.append ( pgroup ); QHBoxLayout * lay_checks ( new QHBoxLayout ); lay_checks->setContentsMargins ( 0, 0, 0, 0 ); { QList < QWidget * > widgets; for ( unsigned int ii=0; ii < pgroup->num_proxies(); ++ii ) { Mixer_HCTL_Proxy_Switch * mcps ( static_cast < Mixer_HCTL_Proxy_Switch * > ( pgroup->proxy ( ii ) ) ); ::Wdg::DS_Switch * wdg_sw ( new ::Wdg::DS_Switch ( 0, editor_data()->image_alloc ) ); wdg_sw->installEventFilter ( mcps ); wdg_sw->setEnabled ( mcps->is_enabled() ); wdg_sw->set_style_id ( elem_style_id ( elem ) ); connect ( mcps, SIGNAL ( sig_enabled_changed ( bool ) ), wdg_sw, SLOT ( setEnabled ( bool ) ) ); connect ( mcps, SIGNAL ( sig_switch_state_changed ( bool ) ), wdg_sw, SLOT ( setChecked ( bool ) ) ); connect ( wdg_sw, SIGNAL ( toggled ( bool ) ), mcps, SLOT ( set_switch_state ( bool ) ) ); widgets.append ( wdg_sw ); } QLayout * lay_grid ( create_channel_grid ( widgets, false ) ); lay_checks->addLayout ( lay_grid, 0 ); lay_checks->addStretch ( 1 ); } // Mass checking buttons QVBoxLayout * lay_extra ( new QVBoxLayout ); lay_extra->setContentsMargins ( 0, 0, 0, 0 ); // Joined button if ( ( pgroup->num_proxies() > 1 ) && is_enabled ) { QCheckBox * btn ( new QCheckBox ); btn->setText ( editor_data()->str_joined ); btn->setChecked ( elem->switches_equal() ); connect ( btn, SIGNAL ( toggled ( bool ) ), pgroup, SLOT ( set_joined ( bool ) ) ); QHBoxLayout * lay_hor ( new QHBoxLayout ); lay_hor->setContentsMargins ( 0, 0, 0, 0 ); lay_hor->addWidget ( btn, 0 ); lay_hor->addStretch ( 1 ); lay_extra->addLayout ( lay_hor ); } QVBoxLayout * lay_vbox ( new QVBoxLayout ); lay_vbox->setContentsMargins ( 0, 0, 0, 0 ); lay_vbox->addLayout ( lay_checks ); lay_vbox->addLayout ( lay_extra ); lay_vbox->addStretch ( 1 ); setLayout ( lay_vbox ); } void Mixer_HCTL_Edit_Bool::setup_multi ( ) { // Create proxies const unsigned int num_elems ( editor_data()->snd_elem_group->num_elems() ); for ( unsigned int eii=0; eii < num_elems; ++eii ) { ::QSnd::Mixer_HCTL_Elem * elem ( editor_data()->snd_elem_group->elem ( eii ) ); Mixer_HCTL_Proxies_Group * pgroup ( create_proxies_group ( elem ) ); _proxies_groups.append ( pgroup ); } QVBoxLayout * lay_switches_pad ( new QVBoxLayout ); lay_switches_pad->setContentsMargins ( 0, 0, 0, 0 ); { QGridLayout * lay_grid ( new QGridLayout ); lay_grid->setContentsMargins ( 0, 0, 0, 0 ); //const Qt::Alignment align_rc ( Qt::AlignRight | Qt::AlignVCenter ); const Qt::Alignment align_cc ( Qt::AlignHCenter | Qt::AlignVCenter ); const QString val ( "%1" ); unsigned int max_channels ( 0 ); unsigned int num_groups ( _proxies_groups.size() ); for ( unsigned int gii=0; gii < num_groups; ++gii ) { ::QSnd::Mixer_HCTL_Elem * elem ( editor_data()->snd_elem_group->elem ( gii ) ); Mixer_HCTL_Proxies_Group * pgroup ( _proxies_groups[gii] ); // Element index label { ::Wdg::Label_Width * wdg_lbl ( new ::Wdg::Label_Width ); wdg_lbl->setAlignment ( align_cc ); wdg_lbl->set_min_text ( "999" ); wdg_lbl->setText ( val.arg ( elem->elem_index() ) ); wdg_lbl->setToolTip ( editor_data()->ttip_grid_lbl_elem ); lay_grid->addWidget ( wdg_lbl, 0, 1 + gii, align_cc ); } if ( max_channels < pgroup->num_proxies() ) { max_channels = pgroup->num_proxies(); } for ( unsigned int pii=0; pii < pgroup->num_proxies(); ++pii ) { Mixer_HCTL_Proxy_Switch * mcps ( static_cast < Mixer_HCTL_Proxy_Switch * > ( pgroup->proxy ( pii ) ) ); // Switch widget ::Wdg::DS_Switch * wdg_sw ( new ::Wdg::DS_Switch ( 0, editor_data()->image_alloc ) ); wdg_sw->installEventFilter ( mcps ); wdg_sw->setEnabled ( mcps->is_enabled() ); wdg_sw->setToolTip ( editor_data()->ttip_grid_widget.arg ( gii ).arg ( pii ) ); wdg_sw->set_style_id ( elem_style_id ( elem ) ); connect ( mcps, SIGNAL ( sig_enabled_changed ( bool ) ), wdg_sw, SLOT ( setEnabled ( bool ) ) ); connect ( mcps, SIGNAL ( sig_switch_state_changed ( bool ) ), wdg_sw, SLOT ( setChecked ( bool ) ) ); connect ( wdg_sw, SIGNAL ( toggled ( bool ) ), mcps, SLOT ( set_switch_state ( bool ) ) ); lay_grid->addWidget ( wdg_sw, 1 + pii, 1 + gii, align_cc ); } } // Joined buttons if ( max_channels > 1 ) { for ( unsigned int cii=0; cii < max_channels; ++cii ) { QLabel * lbl ( new QLabel ); lbl->setText ( editor_data()->str_list_channel.arg ( cii ) ); lbl->setToolTip ( editor_data()->ttip_list_channel.arg ( cii ) ); lay_grid->addWidget ( lbl, 1 + cii, 0 ); } { QLabel * lbl ( new QLabel ( editor_data()->str_joined ) ); lay_grid->addWidget ( lbl, 1 + max_channels, 0 ); } for ( unsigned int gii=0; gii < num_groups; ++gii ) { ::QSnd::Mixer_HCTL_Elem * elem ( editor_data()->snd_elem_group->elem ( gii ) ); Mixer_HCTL_Proxies_Group * pgroup ( _proxies_groups[gii] ); QWidget * btn ( create_small_joined_switch ( pgroup, elem ) ); lay_grid->addWidget ( btn, 1 + max_channels, 1 + gii ); } } // Wrap into stretching layout { QHBoxLayout * lay_switches_grid ( new QHBoxLayout ); lay_switches_grid->setContentsMargins ( 0, 0, 0, 0 ); lay_switches_grid->addLayout ( lay_grid ); lay_switches_grid->addStretch ( 1 ); lay_switches_pad->addLayout ( lay_switches_grid ); lay_switches_pad->addStretch ( 1 ); } } // Scroll area QScrollArea * scroll_area ( new QScrollArea ); { QWidget * switches_pad ( new QWidget ); switches_pad->setLayout ( lay_switches_pad ); scroll_area->setFrameStyle ( QFrame::NoFrame ); scroll_area->setWidget ( switches_pad ); } // Pad layout { QVBoxLayout * lay_pad ( new QVBoxLayout ); lay_pad->setContentsMargins ( 0, 0, 0, 0 ); lay_pad->addWidget ( scroll_area ); setLayout ( lay_pad ); } } void Mixer_HCTL_Edit_Bool::update_proxies_values ( ) { for ( int gii=0; gii < _proxies_groups.size(); ++gii ) { _proxies_groups[gii]->update_values(); } } } // End of namespace qastools-v0.22.0/qashctl/src/mwdg/mixer_hctl_edit_bool.hpp000066400000000000000000000016121354534512100237040ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_mixer_hctl_editor_bool_hpp__ #define __INC_mixer_hctl_editor_bool_hpp__ #include "mwdg/mixer_hctl_editor.hpp" #include namespace MWdg { // Forward declaration class Mixer_HCTL_Proxies_Group; /// @brief Mixer_HCTL_Edit_Bool /// class Mixer_HCTL_Edit_Bool : public Mixer_HCTL_Editor { Q_OBJECT // Public methods public: Mixer_HCTL_Edit_Bool ( Mixer_HCTL_Editor_Data * data_n, QWidget * parent_n = 0 ); ~Mixer_HCTL_Edit_Bool ( ); void setup_single ( ); void setup_multi ( ); Mixer_HCTL_Proxies_Group * create_proxies_group ( ::QSnd::Mixer_HCTL_Elem * elem_n ); // Public slots public slots: void update_proxies_values ( ); // Private attributes private: QList < Mixer_HCTL_Proxies_Group * > _proxies_groups; }; } // End of namespace #endif qastools-v0.22.0/qashctl/src/mwdg/mixer_hctl_edit_enum.cpp000066400000000000000000000175741354534512100237260ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "mixer_hctl_edit_enum.hpp" #include "qsnd/mixer_hctl_elem.hpp" #include "qsnd/mixer_hctl_elem_group.hpp" #include "mwdg/mixer_hctl_editor_data.hpp" #include "mwdg/mixer_hctl_proxy_enum.hpp" #include "mwdg/mixer_hctl_proxies_group.hpp" #include "wdg/label_width.hpp" #include #include #include #include #include #include #include namespace MWdg { Mixer_HCTL_Edit_Enum::Mixer_HCTL_Edit_Enum ( Mixer_HCTL_Editor_Data * data_n, QWidget * parent_n ) : Mixer_HCTL_Editor ( data_n, parent_n ) { if ( editor_data()->elem_idx < editor_data()->snd_elem_group->num_elems() ) { setup_single(); } else { setup_multi(); } update_proxies_values(); } Mixer_HCTL_Edit_Enum::~Mixer_HCTL_Edit_Enum ( ) { } Mixer_HCTL_Proxies_Group * Mixer_HCTL_Edit_Enum::create_proxies_group ( ::QSnd::Mixer_HCTL_Elem * elem_n ) { Mixer_HCTL_Proxies_Group * pgroup ( new Mixer_HCTL_Proxies_Group ( this ) ); const unsigned int num_channels ( elem_n->count() ); for ( unsigned int ii=0; ii < num_channels; ++ii ) { Mixer_HCTL_Proxy_Enum * mcpe ( new Mixer_HCTL_Proxy_Enum ( pgroup ) ); mcpe->set_snd_elem ( elem_n ); mcpe->set_elem_idx ( ii ); mcpe->set_enabled ( elem_n->is_writable() ); pgroup->append_proxy ( mcpe ); } pgroup->set_joined ( elem_n->switches_equal() ); return pgroup; } void Mixer_HCTL_Edit_Enum::setup_single ( ) { ::QSnd::Mixer_HCTL_Elem * elem ( editor_data()->snd_elem_group->elem ( editor_data()->elem_idx ) ); const bool is_enabled ( elem->is_writable() ); Mixer_HCTL_Proxies_Group * pgroup ( create_proxies_group ( elem ) ); _proxies_groups.append ( pgroup ); // // ComboBox area // QHBoxLayout * lay_items ( new QHBoxLayout ); lay_items->setContentsMargins ( 0, 0, 0, 0 ); { QList < QWidget * > wdg_items; QStringList item_names; { unsigned int num_items ( elem->enum_num_items() ); for ( unsigned int ii=0; ii < num_items; ++ii ) { item_names.append ( elem->enum_item_display_name ( ii ) ); } } for ( unsigned int pii=0; pii < pgroup->num_proxies(); ++pii ) { Mixer_HCTL_Proxy_Enum * mcpe ( static_cast < Mixer_HCTL_Proxy_Enum * > ( pgroup->proxy ( pii ) ) ); QComboBox * wdg_sel ( new QComboBox ); wdg_sel->setEnabled ( mcpe->is_enabled() ); wdg_sel->addItems ( item_names ); wdg_sel->installEventFilter ( mcpe ); connect ( mcpe, SIGNAL ( sig_enabled_changed ( bool ) ), wdg_sel, SLOT ( setEnabled ( bool ) ) ); connect ( mcpe, SIGNAL ( sig_enum_index_changed ( int ) ), wdg_sel, SLOT ( setCurrentIndex ( int ) ) ); connect ( wdg_sel, SIGNAL ( currentIndexChanged ( int ) ), mcpe, SLOT ( set_enum_index ( int ) ) ); wdg_items.append ( wdg_sel ); } QLayout * lay_grid ( create_channel_grid ( wdg_items, false ) ); lay_items->addLayout ( lay_grid, 0 ); lay_items->addStretch ( 1 ); } // Extra buttons/labels layout QHBoxLayout * lay_extra ( new QHBoxLayout ); lay_extra->setContentsMargins ( 0, 0, 0, 0 ); if ( ( pgroup->num_proxies() > 1 ) && is_enabled ) { QCheckBox * btn ( new QCheckBox ); btn->setText ( editor_data()->str_joined ); btn->setChecked ( elem->enum_idices_equal() ); connect ( btn, SIGNAL ( toggled ( bool ) ), pgroup, SLOT ( set_joined ( bool ) ) ); lay_extra->addWidget ( btn ); lay_extra->addStretch ( 1 ); } // Pad layout { QVBoxLayout * lay_pad ( new QVBoxLayout ); lay_pad->setContentsMargins ( 0, 0, 0, 0 ); lay_pad->addLayout ( lay_items, 0 ); lay_pad->addSpacing ( fontMetrics().height() ); lay_pad->addLayout ( lay_extra, 0 ); lay_pad->addStretch ( 1 ); setLayout ( lay_pad ); } } void Mixer_HCTL_Edit_Enum::setup_multi ( ) { // Create proxies const unsigned int num_elems ( editor_data()->snd_elem_group->num_elems() ); for ( unsigned int eii=0; eii < num_elems; ++eii ) { ::QSnd::Mixer_HCTL_Elem * elem ( editor_data()->snd_elem_group->elem ( eii ) ); Mixer_HCTL_Proxies_Group * pgroup ( create_proxies_group ( elem ) ); _proxies_groups.append ( pgroup ); } QVBoxLayout * lay_enums_pad ( new QVBoxLayout ); lay_enums_pad->setContentsMargins ( 0, 0, 0, 0 ); { QGridLayout * lay_grid ( new QGridLayout ); lay_grid->setContentsMargins ( 0, 0, 0, 0 ); QStringList item_names; //const Qt::Alignment align_rc ( Qt::AlignRight | Qt::AlignVCenter ); const Qt::Alignment align_cc ( Qt::AlignHCenter | Qt::AlignVCenter ); const QString val ( "%1" ); unsigned int max_channels ( 0 ); const unsigned int num_groups ( _proxies_groups.size() ); for ( unsigned int gii=0; gii < num_groups; ++gii ) { ::QSnd::Mixer_HCTL_Elem * elem ( editor_data()->snd_elem_group->elem ( gii ) ); Mixer_HCTL_Proxies_Group * pgroup ( _proxies_groups[gii] ); // Acquire item names { item_names.clear(); unsigned int num_items ( elem->enum_num_items() ); for ( unsigned int ii=0; ii < num_items; ++ii ) { item_names.append ( elem->enum_item_display_name ( ii ) ); } } // Element index label { ::Wdg::Label_Width * wdg_lbl ( new ::Wdg::Label_Width ); wdg_lbl->setAlignment ( align_cc ); wdg_lbl->set_min_text ( "999" ); wdg_lbl->setText ( val.arg ( elem->elem_index() ) ); wdg_lbl->setToolTip ( editor_data()->ttip_grid_lbl_elem ); lay_grid->addWidget ( wdg_lbl, 0, 1 + gii, align_cc ); } if ( max_channels < pgroup->num_proxies() ) { max_channels = pgroup->num_proxies(); } for ( unsigned int pii=0; pii< pgroup->num_proxies(); ++pii ) { Mixer_HCTL_Proxy_Enum * mcpe ( static_cast < Mixer_HCTL_Proxy_Enum * > ( pgroup->proxy ( pii ) ) ); // Selection widget QComboBox * wdg_sel ( new QComboBox ); wdg_sel->setEnabled ( mcpe->is_enabled() ); wdg_sel->setToolTip ( editor_data()->ttip_grid_widget.arg ( gii ).arg ( pii ) ); wdg_sel->installEventFilter ( mcpe ); wdg_sel->addItems ( item_names ); connect ( mcpe, SIGNAL ( sig_enum_index_changed ( int ) ), wdg_sel, SLOT ( setCurrentIndex ( int ) ) ); connect ( wdg_sel, SIGNAL ( currentIndexChanged ( int ) ), mcpe, SLOT ( set_enum_index ( int ) ) ); lay_grid->addWidget ( wdg_sel, 1 + pii, 1 + gii, align_cc ); } } // Joined buttons if ( max_channels > 1 ) { for ( unsigned int cii=0; cii < max_channels; ++cii ) { QLabel * lbl ( new QLabel ); lbl->setText ( editor_data()->str_list_channel.arg ( cii ) ); lbl->setToolTip ( editor_data()->ttip_list_channel.arg ( cii ) ); lay_grid->addWidget ( lbl, 1 + cii, 0 ); } { QLabel * lbl ( new QLabel ( editor_data()->str_joined ) ); lay_grid->addWidget ( lbl, 1 + max_channels, 0 ); } for ( unsigned int gii=0; gii < num_groups; ++gii ) { ::QSnd::Mixer_HCTL_Elem * elem ( editor_data()->snd_elem_group->elem ( gii ) ); Mixer_HCTL_Proxies_Group * pgroup ( _proxies_groups[gii] ); QWidget * btn ( create_small_joined_switch ( pgroup, elem ) ); lay_grid->addWidget ( btn, 1 + max_channels, 1 + gii ); } } // Wrap into stretching layout { QHBoxLayout * lay_enums_grid ( new QHBoxLayout ); lay_enums_grid->setContentsMargins ( 0, 0, 0, 0 ); lay_enums_grid->addLayout ( lay_grid ); lay_enums_grid->addStretch ( 1 ); lay_enums_pad->addLayout ( lay_enums_grid ); lay_enums_pad->addStretch ( 1 ); } } // Scroll area QScrollArea * scroll_area ( new QScrollArea ); { QWidget * enums_pad ( new QWidget ); enums_pad->setLayout ( lay_enums_pad ); scroll_area->setFrameStyle ( QFrame::NoFrame ); scroll_area->setWidget ( enums_pad ); } // Pad layout { QVBoxLayout * lay_pad ( new QVBoxLayout ); lay_pad->setContentsMargins ( 0, 0, 0, 0 ); lay_pad->addWidget ( scroll_area ); setLayout ( lay_pad ); } } void Mixer_HCTL_Edit_Enum::update_proxies_values ( ) { for ( int gii=0; gii < _proxies_groups.size(); ++gii ) { _proxies_groups[gii]->update_values(); } } } // End of namespace qastools-v0.22.0/qashctl/src/mwdg/mixer_hctl_edit_enum.hpp000066400000000000000000000016101354534512100237130ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_mixer_hctl_editor_enum_hpp__ #define __INC_mixer_hctl_editor_enum_hpp__ #include "mwdg/mixer_hctl_editor.hpp" #include namespace MWdg { // Forward declaration class Mixer_HCTL_Proxies_Group; /// @brief Mixer_HCTL_Edit_Enum /// class Mixer_HCTL_Edit_Enum : public Mixer_HCTL_Editor { Q_OBJECT // Public methods public: Mixer_HCTL_Edit_Enum ( Mixer_HCTL_Editor_Data * data_n, QWidget * parent_n = 0 ); ~Mixer_HCTL_Edit_Enum ( ); void setup_single ( ); void setup_multi ( ); Mixer_HCTL_Proxies_Group * create_proxies_group ( ::QSnd::Mixer_HCTL_Elem * elem_n ); // Public slots public slots: void update_proxies_values ( ); // Private attributes private: QList < Mixer_HCTL_Proxies_Group * > _proxies_groups; }; } // End of namespace #endif qastools-v0.22.0/qashctl/src/mwdg/mixer_hctl_edit_int.cpp000066400000000000000000000337261354534512100235510ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "mixer_hctl_edit_int.hpp" #include "qsnd/mixer_hctl_elem.hpp" #include "qsnd/mixer_hctl_elem_group.hpp" #include "wdg/label_width.hpp" #include "wdg/ds_widget_types.hpp" #include "wdg/pad_proxy_switch.hpp" #include "wdg/pad_proxy_style.hpp" #include "mwdg/event_types.hpp" #include "mwdg/inputs_setup.hpp" #include "mwdg/mixer_hctl_editor_data.hpp" #include "mwdg/mixer_hctl_int_proxies_group.hpp" #include "mwdg/mixer_hctl_int_proxy_column.hpp" #include "mwdg/mixer_hctl_int_proxy_slider.hpp" #include "mwdg/mixer_hctl_slider_status_widget.hpp" #include #include #include #include #include #include #include namespace MWdg { Mixer_HCTL_Edit_Int::Mixer_HCTL_Edit_Int ( ::MWdg::Mixer_HCTL_Editor_Data * data_n, QWidget * parent_n ) : Mixer_HCTL_Editor ( data_n, parent_n ), _act_toggle_joined ( this ), _act_level_channels ( this ) { _range_mask = "%1 / %2"; _range_ttip = _range_mask.arg ( tr ( "minimum" ), tr ( "maximum" ) ); _str_int_range = tr ( "Integer range:" ); _str_dB_range = tr ( "Decibel range:" ); // Actions _act_toggle_joined.setIcon ( QIcon::fromTheme ( "object-flip-horizontal" ) ); _act_level_channels.setIcon ( QIcon::fromTheme ( "object-flip-vertical" ) ); connect ( &_act_toggle_joined, SIGNAL ( triggered ( bool ) ), this, SLOT ( action_toggle_joined() ) ); connect ( &_act_level_channels, SIGNAL ( triggered ( bool ) ), this, SLOT ( action_level_volumes() ) ); // Context menu _cmenu.addAction ( &_act_toggle_joined ); _cmenu.addAction ( &_act_level_channels ); connect ( &_cmenu, SIGNAL ( aboutToHide() ), this, SLOT ( context_menu_cleanup_behind() ) ); rebuild(); } Mixer_HCTL_Edit_Int::~Mixer_HCTL_Edit_Int ( ) { clear(); } void Mixer_HCTL_Edit_Int::set_inputs_setup ( const ::MWdg::Inputs_Setup * setup_n ) { ::MWdg::Mixer_HCTL_Editor::set_inputs_setup ( setup_n ); if ( inputs_setup() != 0 ) { _act_toggle_joined.setShortcut ( inputs_setup()->ks_toggle_joined ); _act_level_channels.setShortcut ( inputs_setup()->ks_level_channels ); _act_level_channels.setText ( inputs_setup()->ts_level_channels ); if ( _sliders_pad != 0 ) { _sliders_pad->set_wheel_degrees ( inputs_setup()->wheel_degrees ); } } } void Mixer_HCTL_Edit_Int::clear ( ) { _sliders_pad.reset(); _scroll_area.reset(); for ( int pii=0; pii < _proxies_groups.size(); ++pii ) { delete _proxies_groups[pii]; } _proxies_groups.clear(); _proxies_slider.clear(); } void Mixer_HCTL_Edit_Int::rebuild ( ) { clear(); if ( editor_data()->snd_elem_group != 0 ) { if ( editor_data()->snd_elem_group->num_elems() > 0 ) { if ( editor_data()->elem_idx < editor_data()->snd_elem_group->num_elems() ) { setup_single(); } else { setup_multi(); } update_proxies_values(); } } } Wdg::Pad_Proxies_Group * Mixer_HCTL_Edit_Int::create_proxies_group ( ::QSnd::Mixer_HCTL_Elem * elem_n, bool multi_n ) { Mixer_HCTL_Int_Proxies_Group * sppg ( new Mixer_HCTL_Int_Proxies_Group ( elem_n, this ) ); const QString str_ch ( tr ( "Channel %1" ) ); const QString str_idx ( tr ( "Index %1" ) ); const unsigned int style_id ( elem_style_id ( elem_n ) ); sppg->set_group_name ( str_idx.arg ( elem_n->elem_index() ) ); sppg->set_style_id ( style_id ); const bool int_equal ( elem_n->integers_equal() ); const unsigned int num_channels ( elem_n->count() ); for ( unsigned int ii=0; ii < num_channels; ++ii ) { Mixer_HCTL_Int_Proxy_Column * pcol ( new Mixer_HCTL_Int_Proxy_Column ); // Slider proxy { Mixer_HCTL_Int_Proxy_Slider * pslider ( new Mixer_HCTL_Int_Proxy_Slider ( elem_n, ii ) ); if ( editor_data()->wdg_style_db != 0 ) { if ( multi_n ) { QString gname ( "%1 (%2)" ); gname = gname.arg ( elem_n->display_name() ); gname = gname.arg ( elem_n->elem_index() ); pslider->set_group_name ( gname ); } else { pslider->set_group_name ( elem_n->display_name() ); } pslider->set_item_name ( str_ch.arg ( ii ) ); pslider->set_style_id ( style_id ); // Decible minimum long db_min; long db_max; if ( elem_n->dB_range ( &db_min, &db_max ) == 0 ) { ::Wdg::Pad_Proxy_Style * pstyle ( new ::Wdg::Pad_Proxy_Style ); pslider->set_style ( pstyle ); if ( ( db_min < 0 ) && ( db_max > 0 ) ) { pstyle->slider_has_minimum = true; pstyle->slider_minimum_idx = pslider->integer_to_index ( elem_n->ask_int_from_dB ( 0 ) ); } else { if ( db_max <= 0 ) { pstyle->slider_has_minimum = true; pstyle->slider_minimum_idx = pslider->slider_index_max(); } else if ( db_min >= 0 ) { pstyle->slider_has_minimum = true; pstyle->slider_minimum_idx = 0; } } } } pslider->set_tool_tip ( str_ch.arg ( ii ) ); pcol->set_slider_proxy ( pslider ); _proxies_slider.append ( pslider ); } // Switch proxy (joined switch) if ( ( ii == 0 ) && ( num_channels > 1 ) ) { ::Wdg::Pad_Proxy_Switch * pswitch ( new ::Wdg::Pad_Proxy_Switch ); pswitch->set_tool_tip ( editor_data()->str_joined ); pswitch->set_switch_state ( int_equal ); pswitch->set_variant_id ( ::Wdg::DS_SVG_JOINED ); pswitch->set_style_id ( elem_style_id ( elem_n ) ); pcol->set_switch_proxy ( pswitch ); connect ( pswitch, SIGNAL ( sig_switch_state_changed ( bool ) ), sppg, SLOT ( set_joined ( bool ) ) ); } sppg->append_column ( pcol ); sppg->set_joined ( int_equal ); } return sppg; } void Mixer_HCTL_Edit_Int::setup_single ( ) { ::QSnd::Mixer_HCTL_Elem * elem ( editor_data()->snd_elem_group->elem ( editor_data()->elem_idx ) ); _proxies_groups.append ( create_proxies_group ( elem, false ) ); setup_widgets(); } void Mixer_HCTL_Edit_Int::setup_multi ( ) { // Create proxies const unsigned int num_elems ( editor_data()->snd_elem_group->num_elems() ); for ( unsigned int eii=0; eii < num_elems; ++eii ) { ::QSnd::Mixer_HCTL_Elem * elem ( editor_data()->snd_elem_group->elem ( eii ) ); _proxies_groups.append ( create_proxies_group ( elem, true ) ); } setup_widgets(); } void Mixer_HCTL_Edit_Int::setup_widgets ( ) { _sliders_pad.reset ( new ::Wdg::Sliders_Pad ( this, editor_data()->image_alloc ) ); _sliders_pad->set_wdg_style_db ( editor_data()->wdg_style_db ); if ( inputs_setup() != 0 ) { _sliders_pad->set_wheel_degrees ( inputs_setup()->wheel_degrees ); } _sliders_pad->set_proxies_groups ( _proxies_groups ); _sliders_pad->installEventFilter ( this ); connect ( _sliders_pad.data(), SIGNAL ( sig_focus_changed() ), this, SLOT ( update_focus_proxies() ) ); connect ( _sliders_pad.data(), SIGNAL ( sig_footer_label_selected ( unsigned int, unsigned int ) ), this, SLOT ( footer_label_selected ( unsigned int, unsigned int ) ) ); // Scroll area _scroll_area.reset ( new ::Wdg::Scroll_Area_Horizontal ); _scroll_area->setFrameStyle ( QFrame::NoFrame ); _scroll_area->setWidget ( _sliders_pad.data() ); // Editor pad layout { QVBoxLayout * lay_pad ( new QVBoxLayout ); lay_pad->setContentsMargins ( 0, 0, 0, 0 ); lay_pad->addWidget ( _scroll_area.data(), 1 ); lay_pad->addLayout ( create_range_label() ); setLayout ( lay_pad ); } } QString Mixer_HCTL_Edit_Int::integer_string ( long value_n ) const { return editor_data()->loc.toString ( (int)value_n ); } QString Mixer_HCTL_Edit_Int::dB_string ( double value_n ) const { return editor_data()->loc.toString ( value_n, 'f', 2 ); } QLayout * Mixer_HCTL_Edit_Int::create_range_label ( ) { ::QSnd::Mixer_HCTL_Elem * elem ( editor_data()->snd_elem_group->elem ( 0 ) ); QLabel * lbl_int_range ( new QLabel ); ::Wdg::Label_Width * lbl_int_rval ( new ::Wdg::Label_Width ); QLabel * lbl_dB_range ( new QLabel ); ::Wdg::Label_Width * lbl_dB_rval ( new ::Wdg::Label_Width ); lbl_int_range->setText ( _str_int_range ); lbl_dB_range->setText ( _str_dB_range ); const Qt::Alignment align_cc ( Qt::AlignHCenter | Qt::AlignVCenter ); //const Qt::Alignment align_lc ( Qt::AlignLeft | Qt::AlignVCenter ); { { const QString mstr ( integer_string ( -99999 ) ); lbl_int_rval->set_min_text ( _range_mask.arg ( mstr, mstr ) ); } lbl_int_rval->setAlignment ( align_cc ); lbl_int_rval->setToolTip ( _range_ttip ); { const QString mstr ( dB_string ( -99.99 ) ); lbl_dB_rval->set_min_text ( _range_mask.arg ( mstr, mstr ) ); } lbl_dB_rval->setAlignment ( align_cc ); lbl_dB_rval->setToolTip ( _range_ttip ); { const QString min_str ( integer_string ( elem->integer_min() ) ); const QString max_str ( integer_string ( elem->integer_max() ) ); lbl_int_rval->setText ( _range_mask.arg ( min_str, max_str ) ); } long db_range[2]; if ( elem->dB_range ( &db_range[0], &db_range[1] ) == 0 ) { const QString min_str ( dB_string ( db_range[0] / 100.0 ) ); const QString max_str ( dB_string ( db_range[1] / 100.0 ) ); lbl_dB_rval->setText ( _range_mask.arg ( min_str, max_str ) ); } else { lbl_dB_range->setEnabled ( false ); lbl_dB_rval->setEnabled ( false ); } } QGridLayout * lay_res ( new QGridLayout ); lay_res->setContentsMargins ( 0, 0, 0, 0 ); lay_res->addWidget ( lbl_int_range, 0, 0 ); lay_res->addWidget ( lbl_int_rval, 0, 1, align_cc ); lay_res->addWidget ( lbl_dB_range, 1, 0 ); lay_res->addWidget ( lbl_dB_rval, 1, 1, align_cc ); QHBoxLayout * lay_hbox ( new QHBoxLayout ); lay_hbox->setContentsMargins ( 0, 0, 0, 0 ); lay_hbox->addLayout ( lay_res ); lay_hbox->addStretch ( 1 ); return lay_hbox; } void Mixer_HCTL_Edit_Int::update_proxies_values ( ) { for ( int ii=0; ii < _proxies_slider.size(); ++ii ) { _proxies_slider[ii]->update_value_from_source(); } } void Mixer_HCTL_Edit_Int::update_focus_proxies ( ) { _focus_proxies_group = 0; _focus_proxy_column = 0; if ( _sliders_pad != 0 ) { if ( _sliders_pad->focus_info().has_focus ) { // Find focus proxies_group const int idx ( _sliders_pad->focus_info().group_idx ); if ( idx < _proxies_groups.size() ) { _focus_proxies_group = static_cast < Mixer_HCTL_Int_Proxies_Group * > ( _proxies_groups[idx] ); _focus_proxy_column = _sliders_pad->focus_info().column_idx; } } } if ( _focus_proxies_group != 0 ) { _act_proxies_group = _focus_proxies_group; _act_proxy_column = _focus_proxy_column; } } bool Mixer_HCTL_Edit_Int::context_menu_start ( const QPoint & pos_n ) { bool res ( false ); if ( !_cmenu.isVisible() && ( _focus_proxies_group != 0 ) && ( _act_proxies_group != 0 ) ) { if ( context_menu_update() > 0 ) { _act_proxies_group->set_notify_value_change ( true ); _cmenu.setTitle ( _act_proxies_group->group_name() ); _cmenu.popup ( pos_n ); res = true; } } return res; } unsigned int Mixer_HCTL_Edit_Int::context_menu_update ( ) { //::std::cout << "Mixer_HCTL_Edit_Int::context_menu_update\n"; unsigned int act_vis ( 0 ); Mixer_HCTL_Int_Proxies_Group * mspg ( _act_proxies_group ); if ( mspg == 0 ) { _cmenu.close(); return act_vis; } // Update split/join and level channels actions { const bool vis_joined ( mspg->num_sliders() > 1 ); _act_toggle_joined.setVisible ( vis_joined ); _act_level_channels.setVisible ( vis_joined ); if ( vis_joined ) { if ( inputs_setup() != 0 ) { const QString * str; if ( mspg->is_joined() ) { str = &inputs_setup()->ts_split_channels; } else { str = &inputs_setup()->ts_join_channels; } _act_toggle_joined.setText ( *str ); } _act_level_channels.setEnabled ( !mspg->volumes_equal() ); act_vis += 2; } } if ( act_vis == 0 ) { _cmenu.close(); } return act_vis; } void Mixer_HCTL_Edit_Int::context_menu_cleanup_behind ( ) { if ( _act_proxies_group != 0 ) { _act_proxies_group->set_notify_value_change ( false ); } } void Mixer_HCTL_Edit_Int::action_toggle_joined ( ) { if ( _act_proxies_group != 0 ) { _act_proxies_group->set_joined ( !_act_proxies_group->is_joined() ); } } void Mixer_HCTL_Edit_Int::action_level_volumes ( ) { if ( _act_proxies_group != 0 ) { _act_proxies_group->level_volumes ( _act_proxy_column ); } } void Mixer_HCTL_Edit_Int::footer_label_selected ( unsigned int group_idx_n, unsigned int column_idx_n ) { //::std::cout << "Footer label selected " << group_idx_n << " " << column_idx_n << "\n"; bool keep_indices ( true ); if ( _status_wdg == 0 ) { // Create new status widget if ( _sliders_pad != 0 ) { ::MWdg::Mixer_HCTL_Slider_Status_Widget * swdg ( new ::MWdg::Mixer_HCTL_Slider_Status_Widget ( this ) ); swdg->setAttribute ( Qt::WA_DeleteOnClose ); swdg->set_sliders_pad ( _sliders_pad.data() ); swdg->slider_focus_changed(); _status_wdg = swdg; _status_wdg->show(); } } else { if ( ( group_idx_n == _status_group_idx ) && ( column_idx_n == _status_column_idx ) ) { _status_group_idx = ~0; _status_column_idx = ~0; _status_wdg->close(); keep_indices = false; } } if ( keep_indices ) { _status_group_idx = group_idx_n; _status_column_idx = column_idx_n; } } bool Mixer_HCTL_Edit_Int::event ( QEvent * event_n ) { bool res ( true ); if ( event_n->type() == ::MWdg::evt_values_changed ) { context_menu_update(); } else { res = Mixer_HCTL_Editor::event ( event_n ); } return res; } bool Mixer_HCTL_Edit_Int::eventFilter ( QObject * watched_n, QEvent * event_n ) { bool filtered ( false ); if ( watched_n == _sliders_pad.data() ) { if ( event_n->type() == QEvent::KeyPress ) { QKeyEvent * ev_key ( static_cast < QKeyEvent * > ( event_n ) ); filtered = true; // Trigger actions const QKeySequence key_seq ( ev_key->key() ); if ( _act_toggle_joined.shortcut() == key_seq ) { _act_toggle_joined.trigger(); } else if ( _act_level_channels.shortcut() == key_seq ) { _act_level_channels.trigger(); } else { filtered = false; } } else if ( event_n->type() == QEvent::ContextMenu ) { QContextMenuEvent * ev_cmenu ( static_cast < QContextMenuEvent * > ( event_n ) ); if ( context_menu_start ( ev_cmenu->globalPos() ) ) { filtered = true; } } } return filtered; } } // End of namespace qastools-v0.22.0/qashctl/src/mwdg/mixer_hctl_edit_int.hpp000066400000000000000000000052361354534512100235510ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_mixer_hctl_editor_int_hpp__ #define __INC_mixer_hctl_editor_int_hpp__ #include "mwdg/mixer_hctl_editor.hpp" #include "wdg/scroll_area_horizontal.hpp" #include "wdg/sliders_pad.hpp" #include #include #include #include #include namespace MWdg { // Forward declaration class Mixer_HCTL_Int_Proxy_Slider; class Mixer_HCTL_Int_Proxies_Group; class Mixer_HCTL_Slider_Status_Widget; /// @brief Mixer_HCTL_Edit_Int /// class Mixer_HCTL_Edit_Int : public Mixer_HCTL_Editor { Q_OBJECT // Public methods public: Mixer_HCTL_Edit_Int ( ::MWdg::Mixer_HCTL_Editor_Data * data_n, QWidget * parent_n = 0 ); ~Mixer_HCTL_Edit_Int ( ); void clear ( ); void rebuild ( ); void set_inputs_setup ( const ::MWdg::Inputs_Setup * setup_n ); void update_proxies_values ( ); QString integer_string ( long value_n ) const; QString dB_string ( double value_n ) const; bool event ( QEvent * event_n ); bool eventFilter ( QObject * watched_n, QEvent * event_n ); // Protected slots protected slots: void update_focus_proxies ( ); void context_menu_cleanup_behind ( ); void action_toggle_joined ( ); void action_level_volumes ( ); void footer_label_selected ( unsigned int group_idx_n, unsigned int column_idx_n ); // Private methods private: void setup_single ( ); void setup_multi ( ); void setup_widgets ( ); QLayout * create_range_label ( ); ::Wdg::Pad_Proxies_Group * create_proxies_group ( ::QSnd::Mixer_HCTL_Elem * elem_n, bool multi_n = false ); // Context menu bool context_menu_start ( const QPoint & pos_n ); /// @return The number of visible actions unsigned int context_menu_update ( ); // Private attributes private: QList < ::MWdg::Mixer_HCTL_Int_Proxy_Slider * > _proxies_slider; QList < ::Wdg::Pad_Proxies_Group * > _proxies_groups; QScopedPointer < ::Wdg::Sliders_Pad > _sliders_pad; QScopedPointer < ::Wdg::Scroll_Area_Horizontal > _scroll_area; // Slider status widget QPointer < ::MWdg::Mixer_HCTL_Slider_Status_Widget > _status_wdg; unsigned int _status_group_idx; unsigned int _status_column_idx; // Context menu QPointer < ::MWdg::Mixer_HCTL_Int_Proxies_Group > _focus_proxies_group; unsigned int _focus_proxy_column; QPointer < ::MWdg::Mixer_HCTL_Int_Proxies_Group > _act_proxies_group; unsigned int _act_proxy_column; QMenu _cmenu; QAction _act_toggle_joined; QAction _act_level_channels; QString _range_mask; QString _range_ttip; QString _str_int_range; QString _str_dB_range; }; } // End of namespace #endif qastools-v0.22.0/qashctl/src/mwdg/mixer_hctl_edit_unsupported.cpp000066400000000000000000000025321354534512100253360ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "mixer_hctl_edit_unsupported.hpp" #include "qsnd/mixer_hctl_elem.hpp" #include "qsnd/mixer_hctl_elem_group.hpp" #include "mwdg/mixer_hctl_editor_data.hpp" #include #include #include #include namespace MWdg { Mixer_HCTL_Edit_Unsupported::Mixer_HCTL_Edit_Unsupported ( Mixer_HCTL_Editor_Data * data_n, QWidget * parent_n ) : Mixer_HCTL_Editor ( data_n, parent_n ) { _str_unsupported = tr ( "Elements of the type %1 are not supported" ); setup_single(); } Mixer_HCTL_Edit_Unsupported::~Mixer_HCTL_Edit_Unsupported ( ) { } void Mixer_HCTL_Edit_Unsupported::setup_single ( ) { QLabel * lbl_head ( new QLabel ); { ::QSnd::Mixer_HCTL_Elem * elem ( editor_data()->snd_elem_group->elem ( 0 ) ); QString val ( elem->elem_type_display_name() ); val = _str_unsupported.arg ( val ); val = QString ( "

%1

" ).arg ( val ); lbl_head->setText ( val ); } // Pad layout { const unsigned int vspace ( qMax ( 0, fontMetrics().height() / 2 ) ); QVBoxLayout * lay_pad ( new QVBoxLayout ); lay_pad->setContentsMargins ( 0, 0, 0, 0 ); lay_pad->addSpacing ( vspace ); lay_pad->addWidget ( lbl_head, 0 ); lay_pad->addStretch ( 1 ); setLayout ( lay_pad ); } } } // End of namespace qastools-v0.22.0/qashctl/src/mwdg/mixer_hctl_edit_unsupported.hpp000066400000000000000000000012231354534512100253370ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_mixer_hctl_editor_unsupported_hpp__ #define __INC_mixer_hctl_editor_unsupported_hpp__ #include "mwdg/mixer_hctl_editor.hpp" namespace MWdg { /// @brief Mixer_HCTL_Edit_Unsupported /// class Mixer_HCTL_Edit_Unsupported : public Mixer_HCTL_Editor { Q_OBJECT // Public methods public: Mixer_HCTL_Edit_Unsupported ( Mixer_HCTL_Editor_Data * data_n, QWidget * parent_n = 0 ); ~Mixer_HCTL_Edit_Unsupported ( ); void setup_single ( ); // Private attributes private: QString _str_unsupported; }; } // End of namespace #endif qastools-v0.22.0/qashctl/src/mwdg/mixer_hctl_editor.cpp000066400000000000000000000065341354534512100232350ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "mwdg/mixer_hctl_editor.hpp" #include "qsnd/mixer_hctl_elem.hpp" #include "wdg/ds_switch.hpp" #include "wdg/ds_widget_types.hpp" #include "wdg/label_width.hpp" #include "mwdg/mixer_style.hpp" #include "mwdg/mixer_hctl_editor_data.hpp" #include "mwdg/mixer_hctl_proxies_group.hpp" #include #include namespace MWdg { Mixer_HCTL_Editor::Mixer_HCTL_Editor ( Mixer_HCTL_Editor_Data * data_n, QWidget * parent_n ) : QWidget ( parent_n ), _editor_data ( data_n ), _inputs_setup ( 0 ) { } Mixer_HCTL_Editor::~Mixer_HCTL_Editor ( ) { } void Mixer_HCTL_Editor::set_inputs_setup ( const ::MWdg::Inputs_Setup * setup_n ) { _inputs_setup = setup_n; } void Mixer_HCTL_Editor::update_proxies_values ( ) { // Dummy } QGridLayout * Mixer_HCTL_Editor::create_channel_grid ( const QList < QWidget * > & items_n, bool bold_labels_n ) { QGridLayout * lay_grid ( new QGridLayout() ); lay_grid->setContentsMargins ( 0, 0, 0, 0 ); if ( items_n.size() == 0 ) { return lay_grid; } const Qt::Alignment align_cc ( Qt::AlignHCenter | Qt::AlignVCenter ); unsigned int num ( items_n.size() ); unsigned int lay_cols ( 1 ); for ( unsigned int ii=1; ii <= num; ii*=2 ) { if ( ii*ii >= num ) { lay_cols = ii; break; } } const QString val ( "%1" ); for ( unsigned int cii=0; cii < num; ++cii ) { QWidget * wdg_input ( items_n[cii] ); const QString str_idx ( val.arg ( cii ) ); ::Wdg::Label_Width * wdg_label ( new ::Wdg::Label_Width ); wdg_label->set_min_text ( val.arg ( 999 ) ); wdg_label->setText ( str_idx ); wdg_label->setToolTip ( editor_data()->ttip_grid_lbl_channel.arg ( str_idx ) ); wdg_label->setAlignment ( align_cc ); wdg_label->setEnabled ( wdg_input->isEnabled() ); if ( bold_labels_n ) { QFont fnt ( wdg_label->font() ); fnt.setBold ( true ); wdg_label->setFont ( fnt ); } unsigned int lay_row = ( cii / lay_cols ); unsigned int lay_col = ( cii % lay_cols ); lay_grid->addWidget ( wdg_label, lay_row * 2, lay_col, align_cc ); lay_grid->addWidget ( wdg_input, lay_row * 2 + 1, lay_col, align_cc ); } return lay_grid; } unsigned int Mixer_HCTL_Editor::elem_style_id ( const ::QSnd::Mixer_HCTL_Elem * elem_n ) const { unsigned int style_id ( 0 ); { const QString ename ( elem_n->elem_name() ); if ( ename.contains ( "playback", Qt::CaseInsensitive ) ) { style_id = ::MWdg::Mixer_Style::PLAYBACK; } else if ( ename.contains ( "capture", Qt::CaseInsensitive ) ) { style_id = ::MWdg::Mixer_Style::CAPTURE; } else if ( ename.contains ( "input", Qt::CaseInsensitive ) ) { style_id = ::MWdg::Mixer_Style::CAPTURE; } else if ( ename.contains ( "mic", Qt::CaseInsensitive ) ) { style_id = ::MWdg::Mixer_Style::CAPTURE; } else { style_id = ::MWdg::Mixer_Style::PLAYBACK; } } return style_id; } QWidget * Mixer_HCTL_Editor::create_small_joined_switch ( ::MWdg::Mixer_HCTL_Proxies_Group * pgroup_n, ::QSnd::Mixer_HCTL_Elem * elem_n ) { ::Wdg::DS_Switch * btn ( new ::Wdg::DS_Switch ( 0, editor_data()->image_alloc ) ); btn->setChecked ( elem_n->values_equal() ); btn->setToolTip ( editor_data()->str_joined ); btn->set_variant_id ( ::Wdg::DS_SVG_JOINED ); connect ( btn, SIGNAL ( toggled ( bool ) ), pgroup_n, SLOT ( set_joined ( bool ) ) ); return btn; } } // End of namespace qastools-v0.22.0/qashctl/src/mwdg/mixer_hctl_editor.hpp000066400000000000000000000036011354534512100232320ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_mixer_hctl_editor_hpp__ #define __INC_mixer_hctl_editor_hpp__ #include #include #include #include #include #include // Forward declaration namespace QSnd { class Mixer_HCTL_Elem; class Mixer_HCTL_Elem_Group; } namespace MWdg { class Mixer_HCTL_Editor_Data; class Mixer_HCTL_Proxies_Group; class Inputs_Setup; } namespace MWdg { /// @brief Mixer_HCTL_Editor /// class Mixer_HCTL_Editor : public QWidget { Q_OBJECT // Public typedefs public: // Public methods public: Mixer_HCTL_Editor ( Mixer_HCTL_Editor_Data * data_n, QWidget * parent_n = 0 ); ~Mixer_HCTL_Editor ( ); // Editor data const Mixer_HCTL_Editor_Data * editor_data ( ) const; Mixer_HCTL_Editor_Data * editor_data ( ); // Inputs setup const ::MWdg::Inputs_Setup * inputs_setup ( ) const; virtual void set_inputs_setup ( const ::MWdg::Inputs_Setup * setup_n ); virtual void update_proxies_values ( ); QWidget * create_small_joined_switch ( ::MWdg::Mixer_HCTL_Proxies_Group * pgroup_n, ::QSnd::Mixer_HCTL_Elem * elem_n ); // Protected methods protected: unsigned int elem_style_id ( const ::QSnd::Mixer_HCTL_Elem * elem_n ) const; QGridLayout * create_channel_grid ( const QList < QWidget * > & items_n, bool bold_labels_n = false ); // Private attributes private: Mixer_HCTL_Editor_Data * _editor_data; const ::MWdg::Inputs_Setup * _inputs_setup; }; inline const Mixer_HCTL_Editor_Data * Mixer_HCTL_Editor::editor_data ( ) const { return _editor_data; } inline Mixer_HCTL_Editor_Data * Mixer_HCTL_Editor::editor_data ( ) { return _editor_data; } inline const ::MWdg::Inputs_Setup * Mixer_HCTL_Editor::inputs_setup ( ) const { return _inputs_setup; } } // End of namespace #endif qastools-v0.22.0/qashctl/src/mwdg/mixer_hctl_editor_data.cpp000066400000000000000000000007461354534512100242250ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "mixer_hctl_editor_data.hpp" #include "qastools_config.hpp" //#include "wdg/ds_switch_painter_svg.hpp" #include namespace MWdg { Mixer_HCTL_Editor_Data::Mixer_HCTL_Editor_Data ( ) : ctl_info_db ( 0 ), wdg_style_db ( 0 ), snd_elem_group ( 0 ), elem_idx ( 0 ), image_alloc ( 0 ) { } Mixer_HCTL_Editor_Data::~Mixer_HCTL_Editor_Data ( ) { } } // End of namespace qastools-v0.22.0/qashctl/src/mwdg/mixer_hctl_editor_data.hpp000066400000000000000000000021401354534512100242200ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_mixer_hctl_editor_data_hpp__ #define __INC_mixer_hctl_editor_data_hpp__ #include #include // Forward declaration namespace QSnd { class Mixer_HCTL_Info_Db; class Mixer_HCTL_Elem; class Mixer_HCTL_Elem_Group; } namespace dpe { class Image_Allocator; } namespace Wdg { class DS_Widget_Style_Db; } namespace MWdg { /// @brief Mixer_HCTL_Editor_Data /// class Mixer_HCTL_Editor_Data { // Public methods public: Mixer_HCTL_Editor_Data ( ); ~Mixer_HCTL_Editor_Data ( ); // Public attributes public: const ::QSnd::Mixer_HCTL_Info_Db * ctl_info_db; const ::Wdg::DS_Widget_Style_Db * wdg_style_db; // Group and element selection ::QSnd::Mixer_HCTL_Elem_Group * snd_elem_group; unsigned int elem_idx; ::dpe::Image_Allocator * image_alloc; // Strings QLocale loc; QString str_joined; QString ttip_grid_lbl_elem; QString ttip_grid_lbl_channel; QString ttip_grid_widget; QString str_list_channel; QString ttip_list_channel; }; } // End of namespace #endif qastools-v0.22.0/qashctl/src/mwdg/mixer_hctl_int_proxies_group.cpp000066400000000000000000000060011354534512100255130ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "mixer_hctl_int_proxies_group.hpp" #include "qsnd/mixer_hctl_elem.hpp" #include "wdg/pad_proxy_switch.hpp" #include "mwdg/mixer_hctl_int_proxy_slider.hpp" #include "mwdg/mixer_hctl_int_proxy_column.hpp" #include "mwdg/event_types.hpp" #include #include #include #include namespace MWdg { Mixer_HCTL_Int_Proxies_Group::Mixer_HCTL_Int_Proxies_Group ( ::QSnd::Mixer_HCTL_Elem * snd_elem_n, QObject * parent_n ) : ::Wdg::Pad_Proxies_Group ( parent_n ), _snd_elem ( snd_elem_n ), _notify_value_change ( false ) { assert ( _snd_elem != 0 ); connect ( _snd_elem, SIGNAL ( sig_values_changed() ), this, SLOT ( update_values() ) ); } Mixer_HCTL_Int_Proxies_Group::~Mixer_HCTL_Int_Proxies_Group ( ) { } bool Mixer_HCTL_Int_Proxies_Group::is_joined ( ) const { bool res ( false ); if ( num_columns() > 0 ) { Mixer_HCTL_Int_Proxy_Column * col ( mcolumn ( 0 ) ); if ( col->has_slider() ) { res = col->mslider_proxy()->is_joined(); } } return res; } inline Mixer_HCTL_Int_Proxy_Column * Mixer_HCTL_Int_Proxies_Group::mcolumn ( unsigned int idx_n ) const { return static_cast < ::MWdg::Mixer_HCTL_Int_Proxy_Column * > ( column ( idx_n ) ); } void Mixer_HCTL_Int_Proxies_Group::set_joined ( bool flag_n ) { if ( num_columns() < 2 ) { return; } for ( unsigned int cii=0; cii < num_columns(); ++cii ) { ::MWdg::Mixer_HCTL_Int_Proxy_Column * col ( mcolumn ( cii ) ); if ( col->has_slider() ) { ::MWdg::Mixer_HCTL_Int_Proxy_Slider * pslider ( col->mslider_proxy() ); pslider->set_joined ( flag_n ); pslider->set_enabled ( ( cii == 0 ) || !flag_n ); if ( flag_n && ( cii == 0 ) ) { pslider->snd_elem()->level_integers(); } } } { ::MWdg::Mixer_HCTL_Int_Proxy_Column * col ( mcolumn ( 0 ) ); if ( col->has_switch() ) { col->switch_proxy()->set_switch_state ( flag_n ); } } } bool Mixer_HCTL_Int_Proxies_Group::volumes_equal ( ) const { return _snd_elem->integers_equal();; } void Mixer_HCTL_Int_Proxies_Group::level_volumes ( unsigned int column_n ) { if ( num_columns() < 2 ) { return; } if ( column_n >= num_columns() ) { column_n = 0; } Mixer_HCTL_Int_Proxy_Column * col ( mcolumn ( column_n ) ); if ( col->has_slider() ) { Mixer_HCTL_Int_Proxy_Slider * psl ( col->mslider_proxy() ); psl->snd_elem()->set_integer_all ( psl->integer_value() ); } } void Mixer_HCTL_Int_Proxies_Group::set_notify_value_change ( bool flag_n ) { _notify_value_change = flag_n; } void Mixer_HCTL_Int_Proxies_Group::update_values ( ) { for ( unsigned int cii=0; cii < num_columns(); ++cii ) { Mixer_HCTL_Int_Proxy_Column * col ( mcolumn ( cii ) ); if ( col->has_slider() ) { col->slider_proxy()->update_value_from_source(); } } // Notify parent on demand if ( notify_value_change() && ( parent() != 0 ) ) { QEvent ev_req ( ::MWdg::evt_values_changed ); QCoreApplication::sendEvent ( parent(), &ev_req ); } } } // End of namespace qastools-v0.22.0/qashctl/src/mwdg/mixer_hctl_int_proxies_group.hpp000066400000000000000000000024601354534512100255250ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_mixer_hctl_int_proxies_group_hpp__ #define __INC_mixer_hctl_int_proxies_group_hpp__ #include "wdg/pad_proxies_group.hpp" // Forward declaration namespace QSnd { class Mixer_HCTL_Elem; } namespace MWdg { class Mixer_HCTL_Int_Proxy_Column; } namespace MWdg { /// @brief Mixer_HCTL_Int_Proxies_Group /// class Mixer_HCTL_Int_Proxies_Group : public ::Wdg::Pad_Proxies_Group { Q_OBJECT // Public methods public: Mixer_HCTL_Int_Proxies_Group ( ::QSnd::Mixer_HCTL_Elem * snd_elem_n, QObject * parent_n ); ~Mixer_HCTL_Int_Proxies_Group ( ); // Notify parent on value change bool notify_value_change ( ) const; void set_notify_value_change ( bool flag_n ); bool is_joined ( ) const; bool volumes_equal ( ) const; Mixer_HCTL_Int_Proxy_Column * mcolumn ( unsigned int idx_n ) const; // Public slots public slots: void set_joined ( bool flag_n ); void level_volumes ( unsigned int column_n = 0 ); void update_values ( ); // Private attributes private: ::QSnd::Mixer_HCTL_Elem * _snd_elem; bool _notify_value_change; }; inline bool Mixer_HCTL_Int_Proxies_Group::notify_value_change ( ) const { return _notify_value_change; } } // End of namespace #endif qastools-v0.22.0/qashctl/src/mwdg/mixer_hctl_int_proxy_column.cpp000066400000000000000000000054521354534512100253550ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "mixer_hctl_int_proxy_column.hpp" #include namespace MWdg { Mixer_HCTL_Int_Proxy_Column::Mixer_HCTL_Int_Proxy_Column ( ) { //: Decibel value string template _str_value_dB = tr ( "%1 dB" ); //: Percent value string template _str_value_pc = tr ( "%1 %" ); } Mixer_HCTL_Int_Proxy_Column::~Mixer_HCTL_Int_Proxy_Column ( ) { } void Mixer_HCTL_Int_Proxy_Column::slider_proxy_changed ( ) { update_connections(); } void Mixer_HCTL_Int_Proxy_Column::show_value_string_changed ( ) { update_connections(); } void Mixer_HCTL_Int_Proxy_Column::update_connections ( ) { if ( slider_proxy() != 0 ) { Mixer_HCTL_Int_Proxy_Slider * msps ( mslider_proxy() ); disconnect ( msps, 0, this, 0 ); if ( show_value_string() ) { //if ( msps->has_dB() ) { // connect ( // msps, SIGNAL ( sig_dB_value_changed ( long ) ), // this, SIGNAL ( sig_value_string_changed() ) ); //} else { connect ( msps, SIGNAL ( sig_slider_index_changed ( unsigned long ) ), this, SIGNAL ( sig_value_string_changed() ) ); //} } } } // Value string QString Mixer_HCTL_Int_Proxy_Column::value_string ( ) const { QString res; if ( has_slider() && show_value_string() ) { Mixer_HCTL_Int_Proxy_Slider * msps ( mslider_proxy() ); //if ( msps->has_dB() ) { // dB_string ( res, msps->dB_value() ); //} else { // percent_string ( res, msps->volume_permille() ); //} integer_string ( res, msps->integer_value() ); } return res; } QString Mixer_HCTL_Int_Proxy_Column::value_min_string ( ) const { QString res; if ( has_slider() && show_value_string() ) { Mixer_HCTL_Int_Proxy_Slider * msps ( mslider_proxy() ); //if ( msps->has_dB() ) { // dB_string ( res, msps->dB_max() ); //} else { // percent_string ( res, -1000 ); //} integer_string ( res, msps->integer_min() ); } return res; } QString Mixer_HCTL_Int_Proxy_Column::value_max_string ( ) const { QString res; if ( has_slider() && show_value_string() ) { Mixer_HCTL_Int_Proxy_Slider * msps ( mslider_proxy() ); //if ( msps->has_dB() ) { // dB_string ( res, msps->dB_min() ); //} else { // percent_string ( res, 1000 ); //} integer_string ( res, msps->integer_max() ); } return res; } void Mixer_HCTL_Int_Proxy_Column::integer_string ( QString & str_n, long value_n ) const { str_n = _loc.toString ( (int)value_n ); } void Mixer_HCTL_Int_Proxy_Column::dB_string ( QString & str_n, long dB_value_n ) const { str_n = _loc.toString ( dB_value_n / 100.0, 'f', 2 ); str_n = _str_value_dB.arg ( str_n ); } void Mixer_HCTL_Int_Proxy_Column::percent_string ( QString & str_n, int permille_n ) const { str_n = _loc.toString ( permille_n / 10.0, 'f', 1 ); str_n = _str_value_pc.arg ( str_n ); } } // End of namespace qastools-v0.22.0/qashctl/src/mwdg/mixer_hctl_int_proxy_column.hpp000066400000000000000000000026261354534512100253620ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_mixer_hctl_int_proxy_column_hpp__ #define __INC_mixer_hctl_int_proxy_column_hpp__ #include #include #include "wdg/pad_proxies_column.hpp" #include "mixer_hctl_int_proxy_slider.hpp" namespace MWdg { /// /// @brief Mixer_HCTL_Int_Proxy_Column /// class Mixer_HCTL_Int_Proxy_Column : public ::Wdg::Pad_Proxies_Column { Q_OBJECT // Public methods public: Mixer_HCTL_Int_Proxy_Column ( ); ~Mixer_HCTL_Int_Proxy_Column ( ); ::MWdg::Mixer_HCTL_Int_Proxy_Slider * mslider_proxy ( ) const; // Value string QString value_string ( ) const; QString value_min_string ( ) const; QString value_max_string ( ) const; // Protected methods protected: void slider_proxy_changed ( ); void show_value_string_changed ( ); void update_connections ( ); void integer_string ( QString & str_n, long value_n ) const; void dB_string ( QString & str_n, long dB_value_n ) const; void percent_string ( QString & str_n, int permille_n ) const; // Private attributes private: QString _str_value_dB; QString _str_value_pc; QLocale _loc; }; inline ::MWdg::Mixer_HCTL_Int_Proxy_Slider * Mixer_HCTL_Int_Proxy_Column::mslider_proxy ( ) const { return static_cast < ::MWdg::Mixer_HCTL_Int_Proxy_Slider * > ( slider_proxy() ); } } // End of namespace #endif qastools-v0.22.0/qashctl/src/mwdg/mixer_hctl_int_proxy_slider.cpp000066400000000000000000000050601354534512100253350ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "mixer_hctl_int_proxy_slider.hpp" #include "qsnd/mixer_hctl_elem.hpp" #include #include #include namespace MWdg { Mixer_HCTL_Int_Proxy_Slider::Mixer_HCTL_Int_Proxy_Slider ( ::QSnd::Mixer_HCTL_Elem * elem_n, unsigned int elem_idx_n ) : _integer_value ( 0 ), _is_joined ( false ), _updating_state ( false ) { _snd_elem = elem_n; _elem_idx = elem_idx_n; assert ( _snd_elem != 0 ); set_slider_index_max ( ::Wdg::integer_distance ( integer_min(), integer_max() ) ); } Mixer_HCTL_Int_Proxy_Slider::~Mixer_HCTL_Int_Proxy_Slider ( ) { } long Mixer_HCTL_Int_Proxy_Slider::integer_min ( ) const { return snd_elem()->integer_min(); } long Mixer_HCTL_Int_Proxy_Slider::integer_max ( ) const { return snd_elem()->integer_max(); } void Mixer_HCTL_Int_Proxy_Slider::set_joined ( bool flag_n ) { _is_joined = flag_n; } void Mixer_HCTL_Int_Proxy_Slider::set_integer_value ( long value_n ) { if ( integer_value() != value_n ) { _integer_value = value_n; this->integer_value_changed(); emit sig_integer_value_changed ( integer_value() ); emit sig_integer_value_changed ( int ( integer_value() ) ); } } void Mixer_HCTL_Int_Proxy_Slider::set_integer_value ( int value_n ) { set_integer_value ( long ( value_n ) ); } void Mixer_HCTL_Int_Proxy_Slider::integer_value_changed ( ) { //::std::cout << "Mixer_HCTL_Int_Proxy_Slider::integer_value_changed " << integer_value() << "\n"; if ( snd_elem() != 0 ) { set_slider_index ( integer_to_index ( integer_value() ) ); } if ( ( snd_elem() != 0 ) && !_updating_state ) { if ( is_joined() || joined_by_key() ) { snd_elem()->set_integer_all ( integer_value() ); } else { snd_elem()->set_integer ( elem_idx(), integer_value() ); } } } void Mixer_HCTL_Int_Proxy_Slider::slider_index_changed ( ) { //::std::cout << "Mixer_HCTL_Int_Proxy_Slider::slider_index_changed " << integer_index() << "\n"; if ( snd_elem() != 0 ) { set_integer_value ( index_to_integer ( slider_index() ) ); } } void Mixer_HCTL_Int_Proxy_Slider::update_value_from_source ( ) { if ( ( snd_elem() != 0 ) && !_updating_state ) { _updating_state = true; set_integer_value ( snd_elem()->integer_value ( elem_idx() ) ); _updating_state = false; } } bool Mixer_HCTL_Int_Proxy_Slider::joined_by_key ( ) const { bool res ( true ); if ( ( QApplication::keyboardModifiers() & Qt::ControlModifier ) == 0 ) { res = false; } res = ( res && has_focus() ); return res; } } // End of namespace qastools-v0.22.0/qashctl/src/mwdg/mixer_hctl_int_proxy_slider.hpp000066400000000000000000000046021354534512100253430ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_mixer_hctl_int_proxy_slider_hpp__ #define __INC_mixer_hctl_int_proxy_slider_hpp__ #include #include "wdg/pad_proxy_slider.hpp" #include "wdg/uint_mapper.hpp" // Forward declaration namespace QSnd { class Mixer_HCTL_Elem; } namespace MWdg { /// @brief Mixer_HCTL_Int_Proxy_Slider /// class Mixer_HCTL_Int_Proxy_Slider : public ::Wdg::Pad_Proxy_Slider { Q_OBJECT // Public methods public: Mixer_HCTL_Int_Proxy_Slider ( ::QSnd::Mixer_HCTL_Elem * elem_n, unsigned int elem_idx_n ); ~Mixer_HCTL_Int_Proxy_Slider ( ); // Snd element ::QSnd::Mixer_HCTL_Elem * snd_elem ( ) const; unsigned int elem_idx ( ) const; // Joined bool is_joined ( ) const; void set_joined ( bool flag_n ); bool joined_by_key ( ) const; // Integer value long integer_min ( ) const; long integer_max ( ) const; long integer_value ( ) const; unsigned long integer_to_index ( long integer_n ) const; long index_to_integer ( unsigned long index_n ) const; // Signals signals: void sig_integer_value_changed ( long value_n ); void sig_integer_value_changed ( int value_n ); // Public slots public slots: void set_integer_value ( long value_n ); void set_integer_value ( int value_n ); void update_value_from_source ( ); // Protected methods protected: void integer_value_changed ( ); void slider_index_changed ( ); // Private attributes private: ::QSnd::Mixer_HCTL_Elem * _snd_elem; unsigned int _elem_idx; long _integer_value; bool _is_joined; bool _updating_state; }; inline ::QSnd::Mixer_HCTL_Elem * Mixer_HCTL_Int_Proxy_Slider::snd_elem ( ) const { return _snd_elem; } inline unsigned int Mixer_HCTL_Int_Proxy_Slider::elem_idx ( ) const { return _elem_idx; } inline bool Mixer_HCTL_Int_Proxy_Slider::is_joined ( ) const { return _is_joined; } inline long Mixer_HCTL_Int_Proxy_Slider::integer_value ( ) const { return _integer_value; } inline unsigned long Mixer_HCTL_Int_Proxy_Slider::integer_to_index ( long integer_n ) const { unsigned long res ( ::Wdg::integer_distance ( integer_min(), integer_n ) ); return res; } inline long Mixer_HCTL_Int_Proxy_Slider::index_to_integer ( unsigned long index_n ) const { long res ( integer_min() ); res += index_n; return res; } } // End of namespace #endif qastools-v0.22.0/qashctl/src/mwdg/mixer_hctl_proxies_group.cpp000066400000000000000000000017141354534512100246470ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "mixer_hctl_proxies_group.hpp" #include "qsnd/mixer_hctl_elem.hpp" #include namespace MWdg { Mixer_HCTL_Proxies_Group::Mixer_HCTL_Proxies_Group ( QObject * parent_n ) : QObject ( parent_n ) { } Mixer_HCTL_Proxies_Group::~Mixer_HCTL_Proxies_Group ( ) { } void Mixer_HCTL_Proxies_Group::update_values ( ) { for ( unsigned int pii=0; pii < num_proxies(); ++pii ) { proxy ( pii )->update_value_from_source(); } } void Mixer_HCTL_Proxies_Group::set_joined ( bool flag_n ) { for ( unsigned int pii=0; pii < num_proxies(); ++pii ) { Mixer_HCTL_Proxy * pro ( proxy ( pii ) ); pro->set_joined ( flag_n ); pro->set_enabled ( ( pii == 0 ) || !flag_n ); } if ( flag_n && ( num_proxies() > 1 ) ) { Mixer_HCTL_Proxy * pro ( proxy ( 0 ) ); if ( pro->snd_elem() != 0 ) { pro->snd_elem()->level_values(); } } } } // End of namespace qastools-v0.22.0/qashctl/src/mwdg/mixer_hctl_proxies_group.hpp000066400000000000000000000023311354534512100246500ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_mixer_hctl_proxies_group_hpp__ #define __INC_mixer_hctl_proxies_group_hpp__ #include #include "mixer_hctl_proxy.hpp" namespace MWdg { /// /// @brief Mixer_HCTL_Proxies_Group /// class Mixer_HCTL_Proxies_Group : public QObject { Q_OBJECT // Public methods public: Mixer_HCTL_Proxies_Group ( QObject * parent_n ); ~Mixer_HCTL_Proxies_Group ( ); unsigned int num_proxies ( ) const; Mixer_HCTL_Proxy * proxy ( unsigned int idx_n ) const; void append_proxy ( Mixer_HCTL_Proxy * proxy_n ); // Public slots public slots: void update_values ( ); void set_joined ( bool flag_n ); // Private attributes private: QList < Mixer_HCTL_Proxy * > _proxies; }; inline unsigned int Mixer_HCTL_Proxies_Group::num_proxies ( ) const { return _proxies.size(); } inline Mixer_HCTL_Proxy * Mixer_HCTL_Proxies_Group::proxy ( unsigned int idx_n ) const { return _proxies[idx_n]; } inline void Mixer_HCTL_Proxies_Group::append_proxy ( Mixer_HCTL_Proxy * proxy_n ) { if ( proxy_n != 0 ) { _proxies.append ( proxy_n ); proxy_n->setParent ( this ); } } } // End of namespace #endif qastools-v0.22.0/qashctl/src/mwdg/mixer_hctl_proxy.cpp000066400000000000000000000033041354534512100231200ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "mixer_hctl_proxy.hpp" #include "qsnd/mixer_hctl_elem.hpp" #include #include namespace MWdg { Mixer_HCTL_Proxy::Mixer_HCTL_Proxy ( QObject * parent_n ) : QObject ( parent_n ), _snd_elem ( 0 ), _elem_idx ( 0 ), _is_enabled ( true ), _is_joined ( false ), _has_focus ( false ) { } Mixer_HCTL_Proxy::~Mixer_HCTL_Proxy ( ) { } void Mixer_HCTL_Proxy::set_snd_elem ( ::QSnd::Mixer_HCTL_Elem * elem_n ) { if ( _snd_elem != 0 ) { disconnect ( _snd_elem, 0, this, 0 ); } _snd_elem = elem_n; if ( _snd_elem != 0 ) { connect ( _snd_elem, SIGNAL ( sig_values_changed() ), this, SLOT ( update_value_from_source() ) ); } } void Mixer_HCTL_Proxy::set_elem_idx ( unsigned int idx_n ) { _elem_idx = idx_n; } void Mixer_HCTL_Proxy::set_joined ( bool flag_n ) { _is_joined = flag_n; } void Mixer_HCTL_Proxy::set_enabled ( bool flag_n ) { if ( flag_n != is_enabled() ) { _is_enabled = flag_n; emit sig_enabled_changed ( is_enabled() ); } } void Mixer_HCTL_Proxy::update_value_from_source ( ) { // Dummy implementation } bool Mixer_HCTL_Proxy::joined_by_key ( ) const { bool res ( true ); if ( ( QApplication::keyboardModifiers() & Qt::ControlModifier ) == 0 ) { res = false; } res = ( res && has_focus() ); return res; } bool Mixer_HCTL_Proxy::eventFilter ( QObject * obj_n, QEvent * event_n ) { bool res ( QObject::eventFilter ( obj_n, event_n ) ); if ( !res ) { if ( event_n->type() == QEvent::FocusIn ) { _has_focus = true; } else if ( event_n->type() == QEvent::FocusOut ) { _has_focus = false; } } return res; } } // End of namespace qastools-v0.22.0/qashctl/src/mwdg/mixer_hctl_proxy.hpp000066400000000000000000000033371354534512100231330ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_mixer_hctl_proxy_hpp__ #define __INC_mixer_hctl_proxy_hpp__ #include // Forward declaration namespace QSnd { class Mixer_HCTL_Elem; } namespace MWdg { /// @brief Mixer_HCTL_Proxy /// class Mixer_HCTL_Proxy : public QObject { Q_OBJECT // Public methods public: Mixer_HCTL_Proxy ( QObject * parent_n = 0 ); virtual ~Mixer_HCTL_Proxy ( ); // Snd element ::QSnd::Mixer_HCTL_Elem * snd_elem ( ) const; void set_snd_elem ( ::QSnd::Mixer_HCTL_Elem * elem_n ); // Snd element index unsigned int elem_idx ( ) const; void set_elem_idx ( unsigned int idx_n ); // Enabled bool is_enabled ( ) const; void set_enabled ( bool flag_n ); // Joined bool is_joined ( ) const; void set_joined ( bool flag_n ); bool joined_by_key ( ) const; // Focus bool has_focus ( ) const; bool eventFilter ( QObject * obj_n, QEvent * event_n ); // Signals signals: void sig_enabled_changed ( bool flag_n ); // Public slots public: virtual void update_value_from_source ( ); // Private attributes private: ::QSnd::Mixer_HCTL_Elem * _snd_elem; unsigned int _elem_idx; bool _is_enabled; bool _is_joined; bool _has_focus; }; inline ::QSnd::Mixer_HCTL_Elem * Mixer_HCTL_Proxy::snd_elem ( ) const { return _snd_elem; } inline unsigned int Mixer_HCTL_Proxy::elem_idx ( ) const { return _elem_idx; } inline bool Mixer_HCTL_Proxy::is_joined ( ) const { return _is_joined; } inline bool Mixer_HCTL_Proxy::is_enabled ( ) const { return _is_enabled; } inline bool Mixer_HCTL_Proxy::has_focus ( ) const { return _has_focus; } } // End of namespace #endif qastools-v0.22.0/qashctl/src/mwdg/mixer_hctl_proxy_enum.cpp000066400000000000000000000030441354534512100241450ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "mixer_hctl_proxy_enum.hpp" #include "qsnd/mixer_hctl_elem.hpp" #include namespace MWdg { Mixer_HCTL_Proxy_Enum::Mixer_HCTL_Proxy_Enum ( QObject * parent_n ) : Mixer_HCTL_Proxy ( parent_n ), _enum_index ( 0 ), _updating_state ( false ) { } unsigned int Mixer_HCTL_Proxy_Enum::enum_num_items ( ) const { return snd_elem()->enum_num_items(); } const char * Mixer_HCTL_Proxy_Enum::enum_item_name ( unsigned int index_n ) { return snd_elem()->enum_item_name ( index_n ); } void Mixer_HCTL_Proxy_Enum::set_enum_index ( unsigned int index_n ) { if ( enum_index() != index_n ) { _enum_index = index_n; this->enum_index_changed(); emit sig_enum_index_changed ( enum_index() ); emit sig_enum_index_changed ( static_cast < int > ( enum_index() ) ); } } void Mixer_HCTL_Proxy_Enum::set_enum_index ( int index_n ) { if ( index_n >= 0 ) { set_enum_index ( static_cast < unsigned int > ( index_n ) ); } } void Mixer_HCTL_Proxy_Enum::enum_index_changed ( ) { if ( ( snd_elem() != 0 ) && !_updating_state ) { if ( is_joined() || joined_by_key() ) { snd_elem()->set_enum_index_all ( enum_index() ); } else { snd_elem()->set_enum_index ( elem_idx(), enum_index() ); } } } void Mixer_HCTL_Proxy_Enum::update_value_from_source ( ) { if ( ( snd_elem() != 0 ) && !_updating_state ) { _updating_state = true; set_enum_index ( snd_elem()->enum_index ( elem_idx() ) ); _updating_state = false; } } } // End of namespace qastools-v0.22.0/qashctl/src/mwdg/mixer_hctl_proxy_enum.hpp000066400000000000000000000022111354534512100241450ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_mixer_hctl_proxy_enum_hpp__ #define __INC_mixer_hctl_proxy_enum_hpp__ #include #include "mixer_hctl_proxy.hpp" namespace MWdg { /// /// @brief Mixer_HCTL_Proxy_Enum /// class Mixer_HCTL_Proxy_Enum : public Mixer_HCTL_Proxy { Q_OBJECT // Public methods public: Mixer_HCTL_Proxy_Enum ( QObject * parent_n ); unsigned int enum_index ( ) const; unsigned int enum_num_items ( ) const; const char * enum_item_name ( unsigned int index_n ); // Signals signals: void sig_enum_index_changed ( unsigned int index_n ); void sig_enum_index_changed ( int index_n ); // Public slots public slots: void set_enum_index ( unsigned int index_n ); void set_enum_index ( int index_n ); void update_value_from_source ( ); // Protected methods protected: void enum_index_changed ( ); // Private attributes private: unsigned int _enum_index; bool _updating_state; }; inline unsigned int Mixer_HCTL_Proxy_Enum::enum_index ( ) const { return _enum_index; } } // End of namespace #endif qastools-v0.22.0/qashctl/src/mwdg/mixer_hctl_proxy_switch.cpp000066400000000000000000000021641354534512100245040ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "mixer_hctl_proxy_switch.hpp" #include "qsnd/mixer_hctl_elem.hpp" #include namespace MWdg { Mixer_HCTL_Proxy_Switch::Mixer_HCTL_Proxy_Switch ( QObject * parent_n ) : Mixer_HCTL_Proxy ( parent_n ), _switch_state ( false ), _updating_state ( false ) { } void Mixer_HCTL_Proxy_Switch::set_switch_state ( bool state_n ) { if ( switch_state() != state_n ) { _switch_state = state_n; this->switch_state_changed(); emit sig_switch_state_changed ( switch_state() ); } } void Mixer_HCTL_Proxy_Switch::switch_state_changed ( ) { if ( ( snd_elem() != 0 ) && !_updating_state ) { if ( is_joined() || joined_by_key() ) { snd_elem()->set_switch_all ( switch_state() ); } else { snd_elem()->set_switch_state ( elem_idx(), switch_state() ); } } } void Mixer_HCTL_Proxy_Switch::update_value_from_source ( ) { if ( ( snd_elem() != 0 ) && !_updating_state ) { _updating_state = true; set_switch_state ( snd_elem()->switch_state ( elem_idx() ) ); _updating_state = false; } } } // End of namespace qastools-v0.22.0/qashctl/src/mwdg/mixer_hctl_proxy_switch.hpp000066400000000000000000000016651354534512100245160ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_mixer_hctl_proxy_switch_hpp__ #define __INC_mixer_hctl_proxy_switch_hpp__ #include #include "mixer_hctl_proxy.hpp" namespace MWdg { /// @brief Mixer_HCTL_Proxy_Switch /// class Mixer_HCTL_Proxy_Switch : public Mixer_HCTL_Proxy { Q_OBJECT // Public methods public: Mixer_HCTL_Proxy_Switch ( QObject * parent_n ); bool switch_state ( ) const; // Signals signals: void sig_switch_state_changed ( bool state_n ); // Public slots public slots: void set_switch_state ( bool state_n ); void update_value_from_source ( ); // Protected methods protected: void switch_state_changed ( ); // Private attributes private: bool _switch_state; bool _updating_state; }; inline bool Mixer_HCTL_Proxy_Switch::switch_state ( ) const { return _switch_state; } } // End of namespace #endif qastools-v0.22.0/qashctl/src/mwdg/mixer_hctl_slider_status_widget.cpp000066400000000000000000000100661354534512100261720ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "mixer_hctl_slider_status_widget.hpp" #include "qsnd/mixer_hctl_elem.hpp" #include "wdg/pad_proxies_column.hpp" #include "wdg/pad_proxies_group.hpp" #include "wdg/sliders_pad.hpp" #include namespace MWdg { Mixer_HCTL_Slider_Status_Widget::Mixer_HCTL_Slider_Status_Widget ( QWidget * parent_n ) : Slider_Status_Widget ( parent_n ), _proxy_slider ( 0 ) { } Mixer_HCTL_Slider_Status_Widget::~Mixer_HCTL_Slider_Status_Widget ( ) { } void Mixer_HCTL_Slider_Status_Widget::select_slider ( unsigned int grp_idx_n, unsigned int col_idx_n ) { if ( sliders_pad() != 0 ) { ::MWdg::Mixer_HCTL_Int_Proxy_Slider * proxy_new ( _proxy_slider ); if ( grp_idx_n < sliders_pad()->num_proxies_groups() ) { ::Wdg::Pad_Proxies_Group * pgroup ( sliders_pad()->proxies_group ( grp_idx_n ) ); if ( col_idx_n < pgroup->num_sliders() ) { proxy_new = dynamic_cast < ::MWdg::Mixer_HCTL_Int_Proxy_Slider * > ( pgroup->column ( col_idx_n )->slider_proxy() ); } } set_slider_proxy ( proxy_new ); } } void Mixer_HCTL_Slider_Status_Widget::proxy_destroyed ( ) { set_slider_proxy ( 0 ); } void Mixer_HCTL_Slider_Status_Widget::set_slider_proxy ( Mixer_HCTL_Int_Proxy_Slider * proxy_n ) { //::std::cout << "Mixer_HCTL_Slider_Status_Widget::set_slider_proxy " << proxy_n << "\n"; if ( _proxy_slider != proxy_n ) { // Disconnect previous proxy if ( _proxy_slider != 0 ) { if ( _proxy_slider->snd_elem() != 0 ) { disconnect ( _proxy_slider->snd_elem(), 0, this, 0 ); } disconnect ( _proxy_slider, 0, this, 0 ); } _proxy_slider = proxy_n; setup_values(); if ( _proxy_slider != 0 ) { if ( _proxy_slider->snd_elem() != 0 ) { connect ( _proxy_slider->snd_elem(), SIGNAL ( sig_values_changed() ), this, SLOT ( update_values() ) ); } connect ( _proxy_slider, SIGNAL ( destroyed ( QObject * ) ), this, SLOT ( proxy_destroyed() ) ); update_values(); } } } QString Mixer_HCTL_Slider_Status_Widget::elem_name ( ) const { QString res; if ( _proxy_slider != 0 ) { res = _proxy_slider->group_name(); if ( res != _proxy_slider->item_name() ) { res += " - "; res += _proxy_slider->item_name(); } } return res; } bool Mixer_HCTL_Slider_Status_Widget::elem_has_volume ( ) const { return ( _proxy_slider != 0 ); } bool Mixer_HCTL_Slider_Status_Widget::elem_has_dB ( ) const { bool res ( false ); if ( _proxy_slider != 0 ) { res = _proxy_slider->snd_elem()->has_dB(); } return res; } long Mixer_HCTL_Slider_Status_Widget::elem_volume_value ( ) const { long res ( 0 ); if ( _proxy_slider != 0 ) { res = _proxy_slider->integer_value(); } return res; } void Mixer_HCTL_Slider_Status_Widget::elem_set_volume ( long value_n ) const { if ( _proxy_slider != 0 ) { _proxy_slider->set_integer_value ( value_n ); } } long Mixer_HCTL_Slider_Status_Widget::elem_volume_min ( ) const { long res ( 0 ); if ( _proxy_slider != 0 ) { res = _proxy_slider->integer_min(); } return res; } long Mixer_HCTL_Slider_Status_Widget::elem_volume_max ( ) const { long res ( 0 ); if ( _proxy_slider != 0 ) { res = _proxy_slider->integer_max(); } return res; } long Mixer_HCTL_Slider_Status_Widget::elem_dB_value ( ) const { long res ( 0 ); if ( _proxy_slider != 0 ) { res = _proxy_slider->snd_elem()->dB_value ( _proxy_slider->elem_idx() ); } return res; } void Mixer_HCTL_Slider_Status_Widget::elem_set_nearest_dB ( long dB_value_n ) const { if ( _proxy_slider != 0 ) { const long vol_near ( _proxy_slider->snd_elem()->ask_int_from_dB ( dB_value_n ) ); _proxy_slider->set_integer_value ( vol_near ); } } long Mixer_HCTL_Slider_Status_Widget::elem_dB_min ( ) const { long res ( 0 ); if ( _proxy_slider != 0 ) { long dummy; _proxy_slider->snd_elem()->dB_range ( &res, &dummy ); } return res; } long Mixer_HCTL_Slider_Status_Widget::elem_dB_max ( ) const { long res ( 0 ); if ( _proxy_slider != 0 ) { long dummy; _proxy_slider->snd_elem()->dB_range ( &dummy, &res ); } return res; } } // End of namespace qastools-v0.22.0/qashctl/src/mwdg/mixer_hctl_slider_status_widget.hpp000066400000000000000000000030471354534512100262000ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_mixer_hctl_slider_status_widget_hpp__ #define __INC_mixer_hctl_slider_status_widget_hpp__ #include "mixer_hctl_int_proxy_slider.hpp" #include "mwdg/slider_status_widget.hpp" namespace MWdg { /// /// @brief Mixer_HCTL_Slider_Status_Widget /// class Mixer_HCTL_Slider_Status_Widget : public Slider_Status_Widget { Q_OBJECT // Public methods public: Mixer_HCTL_Slider_Status_Widget ( QWidget * parent_n = 0 ); ~Mixer_HCTL_Slider_Status_Widget ( ); Mixer_HCTL_Int_Proxy_Slider * proxy_slider ( ) const; // Element info QString elem_name ( ) const; bool elem_has_volume ( ) const; bool elem_has_dB ( ) const; long elem_volume_value ( ) const; void elem_set_volume ( long value_n ) const; long elem_volume_min ( ) const; long elem_volume_max ( ) const; long elem_dB_value ( ) const; void elem_set_nearest_dB ( long dB_value_n ) const; long elem_dB_min ( ) const; long elem_dB_max ( ) const; // Slider selection void select_slider ( unsigned int grp_idx_n, unsigned int col_idx_n ); // Protected slots protected slots: void proxy_destroyed ( ); // Protected methods protected: void set_slider_proxy ( Mixer_HCTL_Int_Proxy_Slider * proxy_n ); // Private attributes private: Mixer_HCTL_Int_Proxy_Slider * _proxy_slider; }; inline Mixer_HCTL_Int_Proxy_Slider * Mixer_HCTL_Slider_Status_Widget::proxy_slider ( ) const { return _proxy_slider; } } // End of namespace #endif qastools-v0.22.0/qashctl/src/mwdg/mixer_hctl_table_model.cpp000066400000000000000000000153151354534512100242130ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "mixer_hctl_table_model.hpp" #include "qsnd/mixer_hctl.hpp" #include "qsnd/mixer_hctl_elem.hpp" #include #include namespace MWdg { Mixer_HCTL_Table_Model::Mixer_HCTL_Table_Model ( QObject * parent_n ) : QAbstractTableModel ( parent_n ), _snd_mixer ( 0 ), _iface_type_idx ( 0 ), _num_columns ( 7 ), _align_cc ( Qt::AlignHCenter | Qt::AlignVCenter ), _align_lc ( Qt::AlignLeft | Qt::AlignVCenter ) { _str_dev_mask = tr ( "%1,%2" ); _ttip_dev = _str_dev_mask; _ttip_dev = _ttip_dev.arg ( "Device" ); _ttip_dev = _ttip_dev.arg ( "Subdevice" ); _ttip_name_mask = "
%1
\n
(%2)
"; _col_names[0] = tr ( "Name" ); _col_ttips[0] = tr ( "Element name" ); //: Idx - abbreviation for Index _col_names[1] = tr ( "Idx" ); _col_ttips[1] = tr ( "Element index" ); _col_names[2] = tr ( "Device" ); _col_ttips[2] = tr ( "Device" ); _col_names[3] = tr ( "Type" ); _col_ttips[3] = tr ( "Element type" ); //: Ch. - abbreviation for Channel _col_names[4] = tr ( "Ch." ); _col_ttips[4] = tr ( "Channel count" ); _col_names[5] = tr ( "Flags" ); _col_ttips[5] = tr ( "Flags" ); _col_names[6] = tr ( "Id" ); _col_ttips[6] = tr ( "Numeric Id" ); } Mixer_HCTL_Table_Model::~Mixer_HCTL_Table_Model ( ) { set_snd_mixer ( 0 ); } int Mixer_HCTL_Table_Model::rowCount ( const QModelIndex & parent_n ) const { int res ( 0 ); if ( !parent_n.isValid() ) { res = _elems.size(); } return res; } int Mixer_HCTL_Table_Model::columnCount ( const QModelIndex & parent_n ) const { int res ( 0 ); if ( !parent_n.isValid() ) { res = _num_columns; } return res; } QVariant Mixer_HCTL_Table_Model::data ( const QModelIndex & index_n, int role_n ) const { QVariant res; const int row ( index_n.row() ); const int col ( index_n.column() ); if ( !index_n.isValid() || index_n.parent().isValid() || ( row < 0 ) || ( row >= _elems.size() ) || ( col < 0 ) || ( col >= (int)_num_columns ) ) { return res; } const ::QSnd::Mixer_HCTL_Elem * elem ( _elems[row] ); const QString val ( "%1" ); if ( col == 0 ) { // Element name if ( role_n == Qt::DisplayRole ) { QString valc ( elem->display_name() ); res = valc; } else if ( role_n == Qt::ToolTipRole ) { QString valc ( elem->display_name() ); if ( valc != elem->elem_name() ) { valc = _ttip_name_mask.arg ( valc ); valc = valc.arg ( elem->elem_name() ); } res = valc; } } else if ( col == 1 ) { // Element index if ( role_n == Qt::DisplayRole ) { res = val.arg ( elem->elem_index() ); } else if ( role_n == Qt::TextAlignmentRole ) { res = QVariant ( _align_cc ); } } else if ( col == 2 ) { // Element device if ( role_n == Qt::DisplayRole ) { QString valc ( _str_dev_mask ); valc = valc.arg ( elem->device() ); valc = valc.arg ( elem->subdevice() ); res = valc; } else if ( role_n == Qt::ToolTipRole ) { res = _ttip_dev; } else if ( role_n == Qt::TextAlignmentRole ) { res = QVariant ( _align_cc ); } } else if ( col == 3 ) { // Element type if ( role_n == Qt::DisplayRole ) { res = elem->elem_type_display_name(); } else if ( role_n == Qt::ToolTipRole ) { res = elem->elem_type_display_name(); } } else if ( col == 4 ) { // Element channel count if ( role_n == Qt::DisplayRole ) { res = val.arg ( elem->count() ); } else if ( role_n == Qt::TextAlignmentRole ) { res = QVariant ( _align_cc ); } } else if ( col == 5 ) { const ::QSnd::Mixer_HCTL_Info_Db * idb ( _snd_mixer->info_db() ); // Element is readable if ( role_n == Qt::DisplayRole ) { QString txt; txt += idb->flag_readable_char ( elem->is_readable() ); txt += idb->flag_writable_char ( elem->is_writable() ); txt += idb->flag_active_char ( elem->is_active() ); txt += idb->flag_volatile_char ( elem->is_volatile() ); res = txt; } else if ( role_n == Qt::ToolTipRole ) { const QString wrap ( "
%1
" ); QString txt_res; QString tmp; tmp = idb->flag_readable_text ( elem->is_readable() ); txt_res += wrap.arg ( tmp ); tmp = idb->flag_writable_text ( elem->is_writable() ); txt_res += wrap.arg ( tmp ); tmp = idb->flag_active_text ( elem->is_active() ); txt_res += wrap.arg ( tmp ); tmp = idb->flag_volatile_text ( elem->is_volatile() ); txt_res += wrap.arg ( tmp ); res = txt_res; } else if ( role_n == Qt::TextAlignmentRole ) { res = QVariant ( _align_cc ); } } else if ( col == 6 ) { // Element numeric id if ( role_n == Qt::DisplayRole ) { res = val.arg ( elem->elem_numid() ); } else if ( role_n == Qt::TextAlignmentRole ) { res = QVariant ( _align_cc ); } } return res; } QVariant Mixer_HCTL_Table_Model::headerData ( int section_n, Qt::Orientation orientation_n, int role_n ) const { QVariant res; if ( ( orientation_n == Qt::Vertical ) || ( section_n < 0 ) || ( section_n >= (int)_num_columns ) ) { return res; } if ( role_n == Qt::DisplayRole ) { res = _col_names[section_n]; } else if ( role_n == Qt::ToolTipRole ) { res = _col_ttips[section_n]; } return res; } ::QSnd::Mixer_HCTL_Elem * Mixer_HCTL_Table_Model::elem ( const QModelIndex & idx_n ) const { ::QSnd::Mixer_HCTL_Elem * res ( 0 ); if ( !idx_n.isValid() || ( idx_n.column() < 0 ) || ( idx_n.column() >= columnCount() ) || ( idx_n.row() < 0 ) || ( idx_n.column() >= rowCount() ) ) { return res; } if ( !idx_n.parent().isValid() ) { if ( idx_n.row() < _elems.size() ) { res = _elems[idx_n.row()]; } } return res; } void Mixer_HCTL_Table_Model::set_snd_mixer ( ::QSnd::Mixer_HCTL * snd_mixer_n ) { if ( _snd_mixer != snd_mixer_n ) { clear(); _snd_mixer = snd_mixer_n; load(); } } void Mixer_HCTL_Table_Model::set_iface_type_idx ( unsigned int type_n ) { if ( _iface_type_idx != type_n ) { beginResetModel(); clear(); _iface_type_idx = type_n; load(); endResetModel(); } } void Mixer_HCTL_Table_Model::clear ( ) { if ( _elems.size() > 0 ) { beginRemoveRows ( QModelIndex(), 0, _elems.size() - 1 ); _elems.clear(); endRemoveRows(); } } void Mixer_HCTL_Table_Model::load ( ) { if ( snd_mixer() == 0 ) { return; } if ( snd_mixer()->iface_type_count ( iface_type_idx() ) == 0 ) { return; } QList < ::QSnd::Mixer_HCTL_Elem * > new_elems; // // Filter elements // const unsigned int num_elems ( snd_mixer()->num_elems() ); for ( unsigned int ii=0; ii < num_elems; ++ii ) { ::QSnd::Mixer_HCTL_Elem * elem ( snd_mixer()->elem ( ii ) ); if ( elem->iface_type_idx() == iface_type_idx() ) { new_elems.append ( elem ); } } if ( new_elems.size() > 0 ) { beginInsertRows ( QModelIndex(), 0, new_elems.size() - 1 ); _elems = new_elems; endInsertRows(); } } } // End of namespace qastools-v0.22.0/qashctl/src/mwdg/mixer_hctl_table_model.hpp000066400000000000000000000036641354534512100242240ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_mixer_hctl_table_model_hpp__ #define __INC_mixer_hctl_table_model_hpp__ #include #include #include // Forward declaration namespace QSnd { class Mixer_HCTL; class Mixer_HCTL_Elem; class Mixer_HCTL_Elem_Group; } namespace MWdg { /// @brief Mixer_HCTL_Table_Model /// class Mixer_HCTL_Table_Model : public QAbstractTableModel { Q_OBJECT; // Public methods public: Mixer_HCTL_Table_Model ( QObject * parent_n = 0 ); ~Mixer_HCTL_Table_Model ( ); // Mixer class ::QSnd::Mixer_HCTL * snd_mixer ( ) const; void set_snd_mixer ( ::QSnd::Mixer_HCTL * snd_mixer_n ); // Interface type index unsigned int iface_type_idx ( ) const; void set_iface_type_idx ( unsigned int type_n ); ::QSnd::Mixer_HCTL_Elem * elem ( const QModelIndex & idx_n ) const; int rowCount ( const QModelIndex & parent_n = QModelIndex() ) const; int columnCount ( const QModelIndex & parent_n = QModelIndex() ) const; QVariant data ( const QModelIndex & index_n, int role_n = Qt::DisplayRole ) const; QVariant headerData ( int section_n, Qt::Orientation orientation_n, int role_n = Qt::DisplayRole ) const; // Protected methods protected: void clear ( ); void load ( ); // Private attributes private: ::QSnd::Mixer_HCTL * _snd_mixer; QList < ::QSnd::Mixer_HCTL_Elem * > _elems; unsigned int _iface_type_idx; QString _str_dev_mask; QString _ttip_dev; QString _ttip_name_mask; QString _col_names[7]; QString _col_ttips[7]; const unsigned int _num_columns; const Qt::Alignment _align_cc; const Qt::Alignment _align_lc; }; inline ::QSnd::Mixer_HCTL * Mixer_HCTL_Table_Model::snd_mixer ( ) const { return _snd_mixer; } inline unsigned int Mixer_HCTL_Table_Model::iface_type_idx ( ) const { return _iface_type_idx; } } // End of namespace #endif qastools-v0.22.0/qashctl/src/mwdg/mixer_hctl_tree_model.cpp000066400000000000000000000247531354534512100240710ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "mixer_hctl_tree_model.hpp" #include "qsnd/mixer_hctl.hpp" #include "qsnd/mixer_hctl_elem.hpp" #include "qsnd/mixer_hctl_elem_group.hpp" #include #include namespace MWdg { Mixer_HCTL_Tree_Model::Mixer_HCTL_Tree_Model ( QObject * parent_n ) : QStandardItemModel ( parent_n ), _snd_mixer ( 0 ) { } Mixer_HCTL_Tree_Model::~Mixer_HCTL_Tree_Model ( ) { set_snd_mixer ( 0 ); } void Mixer_HCTL_Tree_Model::set_snd_dir_foreground ( unsigned int dir_n, const QBrush & brush_n ) { _brush_snd_dir[dir_n] = brush_n; } unsigned int Mixer_HCTL_Tree_Model::index_data ( const QModelIndex & idx_n, ::QSnd::Mixer_HCTL_Elem_Group * * grp_n, unsigned int * elem_index_n, unsigned int * iface_type_n ) const { unsigned int res ( 0 ); if ( grp_n == 0 ) { return res; } if ( !idx_n.isValid() || ( idx_n.column() != 0 ) || ( idx_n.row() < 0 ) ) { return res; } const QModelIndex idx_base ( invisibleRootItem()->index() ); if ( idx_n == idx_base ) { return res; } const unsigned int invalid_val ( ~0 ); unsigned int type_grp ( _type_groups.size() ); unsigned int type_row ( invalid_val ); unsigned int elem_idx ( invalid_val ); { const QModelIndex idx_p0 ( idx_n.parent() ); if ( idx_p0 == idx_base ) { res = 1; type_grp = idx_n.row(); } else { const QModelIndex idx_p1 ( idx_p0.parent() ); if ( idx_p1 == idx_base ) { res = 2; type_grp = idx_p0.row(); type_row = idx_n.row(); } else { const QModelIndex idx_p2 ( idx_p1.parent() ); if ( idx_p2 == idx_base ) { res = 3; type_grp = idx_p1.row(); type_row = idx_p0.row(); elem_idx = idx_n.row(); } } } } const Type_Group * tgrp ( 0 ); ::QSnd::Mixer_HCTL_Elem_Group * grp ( 0 ); if ( res >= 1 ) { if ( (int)type_grp < _type_groups.size() ) { tgrp = _type_groups[type_grp]; } else { res = 0; } } if ( res >= 2 ) { if ( (int)type_row < tgrp->list.size() ) { grp = tgrp->list[type_row]; } else { res = 0; } } if ( res == 3 ) { if ( elem_idx >= grp->num_elems() ) { res = 0; } } if ( res == 2 ) { elem_idx = grp->num_elems(); if ( elem_idx == 1 ) { --elem_idx; } } if ( ( grp_n != 0 ) && ( grp != 0 ) ) { *grp_n = grp; } if ( ( iface_type_n != 0 ) && ( tgrp != 0 ) ) { *iface_type_n = tgrp->iface_type_idx; } if ( elem_index_n != 0 ) { *elem_index_n = elem_idx; } return res; } QModelIndex Mixer_HCTL_Tree_Model::elem_index ( ::QSnd::Mixer_HCTL_Elem * elem_n ) const { QModelIndex res; if ( ( elem_n != 0 ) && ( _type_groups.size() > 0 ) ) { bool found ( false ); unsigned int tidx ( 0 ); unsigned int gidx ( 0 ); unsigned int eidx ( 0 ); ::QSnd::Mixer_HCTL_Elem_Group * grp ( 0 ); const unsigned int num_types ( _type_groups.size() ); for ( unsigned int tgii=0; tgii < num_types; ++tgii ) { const Type_Group * tgrp ( _type_groups[tgii] ); const unsigned int num_grps ( tgrp->list.size() ); for ( unsigned int gii=0; gii < num_grps; ++gii ) { grp = tgrp->list[gii]; for ( unsigned int eii=0; eii < grp->num_elems(); ++eii ) { if ( grp->elem ( eii ) == elem_n ) { tidx = tgii; gidx = gii; eidx = eii; found = true; goto loop_break; } } } } loop_break: if ( found ) { res = index ( tidx, 0, invisibleRootItem()->index() ); res = index ( gidx, 0, res ); if ( grp->num_elems() > 1 ) { res = index ( eidx, 0, res ); } } } return res; } QModelIndex Mixer_HCTL_Tree_Model::elem_desc_index ( const QString & iface_name_n, const QString & elem_name_n, unsigned int elem_idx_n ) const { QModelIndex res; if ( iface_name_n.isEmpty() || ( _snd_mixer == 0 ) ) { return res; } const ::QSnd::Mixer_HCTL_Info_Db * idb ( _snd_mixer->info_db() ); Type_Group * tgrp ( 0 ); for ( int ii=0; ii < _type_groups.size(); ++ii ) { Type_Group * tgrp_cur ( _type_groups[ii] ); if ( iface_name_n == idb->iface_name ( tgrp_cur->iface_type_idx ) ) { tgrp = tgrp_cur; res = index ( ii, 0 ); break; } } if ( ( tgrp == 0 ) || ( elem_name_n.isEmpty() ) ) { return res; } const ::QSnd::Mixer_HCTL_Elem_Group * grp ( 0 ); for ( int ii=0; ii < tgrp->list.size(); ++ii ) { const ::QSnd::Mixer_HCTL_Elem_Group * grp_cur ( tgrp->list[ii] ); if ( elem_name_n == grp_cur->elem ( 0 )->elem_name() ) { grp = grp_cur; res = index ( ii, 0, res ); break; } } if ( grp != 0 ) { if ( ( grp->num_elems() > 1 ) && ( elem_idx_n < grp->num_elems() ) ) { res = index ( elem_idx_n, 0, res ); } } return res; } void Mixer_HCTL_Tree_Model::set_snd_mixer ( ::QSnd::Mixer_HCTL * snd_mixer_n ) { if ( _snd_mixer != snd_mixer_n ) { clear(); _snd_mixer = snd_mixer_n; load(); } } void Mixer_HCTL_Tree_Model::clear ( ) { invisibleRootItem()->removeRows ( 0, invisibleRootItem()->rowCount() ); for ( int ii=0; ii < _type_groups.size(); ++ii ) { Type_Group * tgrp ( _type_groups[ii] ); for ( int jj=0; jj < tgrp->list.size(); ++jj ) { delete tgrp->list[jj]; } delete tgrp; } _type_groups.clear(); } void Mixer_HCTL_Tree_Model::load ( ) { if ( snd_mixer() == 0 ) { return; } const unsigned int num_types ( snd_mixer()->iface_types_avail() ); const unsigned int num_elems ( snd_mixer()->num_elems() ); if ( num_types == 0 ) { return; } for ( unsigned int tii=0; tii < num_types; ++tii ) { Type_Group * tgrp ( new Type_Group ); tgrp->iface_type_idx = snd_mixer()->iface_avail_type( tii ); _type_groups.append ( tgrp ); } // Find groups for each interface type for ( unsigned int ii=0; ii < num_elems; ++ii ) { ::QSnd::Mixer_HCTL_Elem * elem ( snd_mixer()->elem ( ii ) ); Type_Group * tgrp ( 0 ); for ( unsigned int tii=0; tii < num_types; ++tii ) { tgrp = _type_groups[tii]; if ( elem->iface_type_idx() == tgrp->iface_type_idx ) { break; } tgrp = 0; } if ( tgrp != 0 ) { ::QSnd::Mixer_HCTL_Elem_Group * grp ( new ::QSnd::Mixer_HCTL_Elem_Group ); grp->append_elem ( elem ); tgrp->list.append ( grp ); } } // Moves all items with the same name into a single group for ( unsigned int tii=0; tii < num_types; ++tii ) { compress_group_list ( _type_groups[tii]->list ); } // // Create model items // const QString val ( "%1" ); const QString ttip_suff ( "(%1)" ); const QString num_suff ( " [%1]" ); const QString idx_suff ( ", %1" ); const QString dmask ( "
%1
" ); QFont fnt_default; for ( unsigned int tii=0; tii < num_types; ++tii ) { const Type_Group * tgrp ( _type_groups[tii] ); QStandardItem * type_item ( new QStandardItem ); type_item->setSelectable ( true ); type_item->setEditable ( false ); type_item->setText ( snd_mixer()->info_db()->iface_display_name ( snd_mixer()->iface_avail_type ( tii ) ) ); { QFont fnt ( fnt_default ); fnt.setBold ( true ); type_item->setFont ( fnt ); } for ( int gii=0; gii < tgrp->list.size(); ++gii ) { const ::QSnd::Mixer_HCTL_Elem_Group * grp ( tgrp->list[gii] ); const ::QSnd::Mixer_HCTL_Elem * elem_first ( grp->elem ( 0 ) ); QStandardItem * grp_item ( new QStandardItem ); grp_item->setSelectable ( true ); grp_item->setEditable ( false ); QString elm_name ( elem_first->elem_name() ); QString elm_disp_name ( elem_first->display_name() ); QString it_text ( elm_disp_name ); QString it_ttip ( dmask.arg ( elm_disp_name ) ); QFont fnt ( fnt_default ); QBrush fg_brush ( get_foreground ( elm_name ) ); if ( elm_name != elm_disp_name ) { // Append untranslated real name to tooltip it_ttip.append ( "\n" ); it_ttip.append ( dmask.arg ( ttip_suff.arg ( elm_name ) ) ); } const unsigned int num_grp_elms ( grp->num_elems() ); if ( num_grp_elms > 1 ) { fnt.setItalic ( true ); for ( unsigned int jj=0; jj < num_grp_elms; ++jj ) { const ::QSnd::Mixer_HCTL_Elem * elem ( grp->elem ( jj ) ); QStandardItem * elm_item ( new QStandardItem ); { QString txt ( elm_disp_name ); txt += idx_suff.arg ( elem->elem_index() ); elm_item->setText ( txt ); } elm_item->setToolTip ( it_ttip ); elm_item->setSelectable ( true ); elm_item->setEditable ( false ); elm_item->setForeground ( fg_brush ); grp_item->appendRow ( elm_item ); } elm_disp_name += num_suff.arg ( num_grp_elms ); } grp_item->setFont ( fnt ); grp_item->setText ( elm_disp_name ); grp_item->setToolTip ( it_ttip ); grp_item->setForeground ( fg_brush ); type_item->appendRow ( grp_item ); } invisibleRootItem()->appendRow ( type_item ); } } void Mixer_HCTL_Tree_Model::compress_group_list ( QList < ::QSnd::Mixer_HCTL_Elem_Group * > & lst_n ) { QString span_name; ::QSnd::Mixer_HCTL_Elem_Group * span_grp ( 0 ); ::QSnd::Mixer_HCTL_Elem * span_elem ( 0 ); unsigned int span_start ( 0 ); unsigned int span ( 0 ); for ( int gii=0; gii < lst_n.size(); ++gii ) { ::QSnd::Mixer_HCTL_Elem_Group * grp ( lst_n[gii] ); ::QSnd::Mixer_HCTL_Elem * elem ( grp->elem ( 0 ) ); bool match ( false ); if ( span_grp != 0 ) { match = ( elem->elem_name() == span_name ) && ( elem->elem_type() == span_elem->elem_type() ) && ( elem->iface() == span_elem->iface() ) && ( elem->elem_index() != span_elem->elem_index() ); } if ( match ) { ++span; } if ( !match || ( gii == ( lst_n.size() - 1 ) ) ) { if ( span > 0 ) { for ( unsigned int jj=0; jj < span; ++jj ) { ::QSnd::Mixer_HCTL_Elem_Group * grp_cur ( lst_n[span_start + 1 + jj] ); span_grp->append_elem ( grp_cur->elem ( 0 ) ); grp_cur->clear(); } } span_name = elem->elem_name(); span_grp = grp; span_elem = elem; span_start = gii; span = 0; } } // Remove empty groups int gii ( 0 ); while ( gii < lst_n.size() ) { ::QSnd::Mixer_HCTL_Elem_Group * grp ( lst_n[gii] ); if ( grp->num_elems() == 0 ) { lst_n.removeAt ( gii ); delete grp; } else { ++gii; } } } QBrush Mixer_HCTL_Tree_Model::get_foreground ( const QString & name_n ) { QBrush res; { QBrush * br_snd ( 0 ); const QString & ename ( name_n ); if ( ename.contains ( "playback", Qt::CaseInsensitive ) ) { br_snd = &_brush_snd_dir[0]; } else if ( ename.contains ( "capture", Qt::CaseInsensitive ) ) { br_snd = &_brush_snd_dir[1]; } else if ( ename.contains ( "input", Qt::CaseInsensitive ) ) { br_snd = &_brush_snd_dir[1]; } else if ( ename.contains ( "mic", Qt::CaseInsensitive ) ) { br_snd = &_brush_snd_dir[1]; } if ( br_snd != 0 ) { res = *br_snd; } } return res; } } // End of namespace qastools-v0.22.0/qashctl/src/mwdg/mixer_hctl_tree_model.hpp000066400000000000000000000036111354534512100240640ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_mixer_hctl_tree_model_hpp__ #define __INC_mixer_hctl_tree_model_hpp__ #include #include #include #include // Forward declaration namespace QSnd { class Mixer_HCTL; class Mixer_HCTL_Elem; class Mixer_HCTL_Elem_Group; } namespace MWdg { /// @brief Mixer_HCTL_Tree_Model /// class Mixer_HCTL_Tree_Model : public QStandardItemModel { Q_OBJECT; // Public methods public: Mixer_HCTL_Tree_Model ( QObject * parent_n = 0 ); ~Mixer_HCTL_Tree_Model ( ); // Mixer class ::QSnd::Mixer_HCTL * snd_mixer ( ) const; void set_snd_mixer ( ::QSnd::Mixer_HCTL * snd_mixer_n ); void set_snd_dir_foreground ( unsigned int dir_n, const QBrush & brush_n ); /// @return 0 - nothing; 1 - iface_type; 2 - group/element; 3 - group/element unsigned int index_data ( const QModelIndex & idx_n, ::QSnd::Mixer_HCTL_Elem_Group * * grp_n, unsigned int * elem_index_n, unsigned int * iface_type_n = 0 ) const; QModelIndex elem_index ( ::QSnd::Mixer_HCTL_Elem * elem_n ) const; QModelIndex elem_desc_index ( const QString & iface_name_n, const QString & elem_name_n, unsigned int elem_idx_n ) const; // Protected typedefs protected: struct Type_Group { unsigned int iface_type_idx; QList < ::QSnd::Mixer_HCTL_Elem_Group * > list; }; // Private methods private: void clear ( ); void load ( ); void compress_group_list ( QList < ::QSnd::Mixer_HCTL_Elem_Group * > & lst_n ); QBrush get_foreground ( const QString & name_n ); // Private attributes private: ::QSnd::Mixer_HCTL * _snd_mixer; QList < Type_Group * > _type_groups; QBrush _brush_snd_dir[2]; }; inline ::QSnd::Mixer_HCTL * Mixer_HCTL_Tree_Model::snd_mixer ( ) const { return _snd_mixer; } } // End of namespace #endif qastools-v0.22.0/qashctl/src/views/000077500000000000000000000000001354534512100172145ustar00rootroot00000000000000qastools-v0.22.0/qashctl/src/views/mixer_hctl.cpp000066400000000000000000000207041354534512100220610ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "mixer_hctl.hpp" #include "qsnd/mixer_hctl.hpp" #include "qsnd/mixer_hctl_info_db.hpp" #include "qsnd/mixer_hctl_elem.hpp" #include "qsnd/mixer_hctl_elem_group.hpp" #include "wdg/tree_view_kv.hpp" #include "mwdg/mixer_style.hpp" #include "mwdg/mixer_device_setup.hpp" #include "mwdg/mixer_hctl.hpp" #include "mwdg/mixer_hctl_tree_model.hpp" #include "mwdg/mixer_hctl_table_model.hpp" #include "views/mixer_hctl_setup.hpp" #include "views/message_widget.hpp" #include #include #include #include namespace Views { Mixer_HCTL::Mixer_HCTL ( QWidget * parent_n ) : ::Views::View_Base ( parent_n ), _view_setup ( 0 ) { // Snd hctl mixer _snd_mixer = new ::QSnd::Mixer_HCTL ( this ); connect ( _snd_mixer, SIGNAL ( sig_mixer_reload_request() ), this, SIGNAL ( sig_mdev_reload_request() ) ); _default_iface_type_idx = _snd_mixer->info_db()->iface_type_idx ( SND_CTL_ELEM_IFACE_MIXER ); // Mixer widget _mixer_hctl = new ::MWdg::Mixer_HCTL; _mixer_hctl->set_ctl_info_db ( _snd_mixer->info_db() ); // Tree model _tree_model = new ::MWdg::Mixer_HCTL_Tree_Model ( this ); // Tree view _tree_view = new ::Wdg::Tree_View_KV; _tree_view->setHeaderHidden ( true ); _tree_view->setTextElideMode ( Qt::ElideMiddle ); _tree_view->setModel ( _tree_model ); connect ( _tree_view, SIGNAL ( activated ( const QModelIndex & ) ), this, SLOT ( tree_element_selected ( const QModelIndex & ) ) ); // Tree view container widget { QVBoxLayout * lay_wdg_tree ( new QVBoxLayout ); lay_wdg_tree->setContentsMargins ( 0, 0, 0, 0 ); lay_wdg_tree->addWidget ( _tree_view ); _wdg_side.setLayout ( lay_wdg_tree ); } // Table model _table_model = new ::MWdg::Mixer_HCTL_Table_Model ( this ); // Table view { _table_view = new QTableView; _table_view->setModel ( _table_model ); { QHeaderView * vhv ( _table_view->verticalHeader() ); if ( vhv != 0 ) { vhv->hide(); } } _table_view->setSelectionMode ( QAbstractItemView::SingleSelection ); _table_view->setSelectionBehavior ( QAbstractItemView::SelectRows ); connect ( _table_view, SIGNAL ( activated ( const QModelIndex & ) ), this, SLOT ( table_element_selected ( const QModelIndex & ) ) ); } // Central widget with stacked layout { QVBoxLayout * lay_center ( new QVBoxLayout ); _wdg_center.setLayout ( lay_center ); _lay_center_stack = new QStackedLayout; lay_center->addLayout ( _lay_center_stack ); _lay_center_stack->setContentsMargins ( 0, 0, 0, 0 ); _lay_center_stack->addWidget ( _table_view ); _lay_center_stack->addWidget ( _mixer_hctl ); } // Horizontal splitter { QSplitter * hsplit ( new QSplitter ); hsplit->setOrientation ( Qt::Horizontal ); hsplit->addWidget ( &_wdg_side ); hsplit->addWidget ( &_wdg_center ); hsplit->setCollapsible ( 0, false ); hsplit->setCollapsible ( 1, false ); hsplit->setStretchFactor ( 1, 8 ); lay_stack()->addWidget ( hsplit ); } // Adjust margins { QLayout * lay; lay = _wdg_center.layout(); if ( lay != 0 ) { QMargins mgs ( lay->contentsMargins() ); mgs.setRight ( 0 ); mgs.setTop ( 0 ); mgs.setBottom ( 0 ); lay->setContentsMargins ( mgs ); } lay = _mixer_hctl->layout(); if ( lay != 0 ) { lay->setContentsMargins ( 0, 0, 0, 0 ); } } } Mixer_HCTL::~Mixer_HCTL ( ) { set_mdev_setup ( 0 ); set_inputs_setup ( 0 ); set_view_setup ( 0 ); } void Mixer_HCTL::set_mdev_setup ( const ::MWdg::Mixer_Device_Setup * setup_n ) { if ( mdev_setup() != 0 ) { if ( _snd_mixer->is_open() ) { // Close mixer _mixer_hctl->set_snd_elem_group ( 0 ); _tree_model->set_snd_mixer ( 0 ); _table_model->set_snd_mixer ( 0 ); _snd_mixer->close(); } } ::Views::View_Base::set_mdev_setup ( setup_n ); if ( mdev_setup() != 0 ) { if ( !mdev_setup()->ctl_addr.isEmpty() ) { // Open mixer _snd_mixer->open ( mdev_setup()->ctl_addr ); if ( _snd_mixer->is_open() ) { setup_view(); restore_state(); } } } } void Mixer_HCTL::set_inputs_setup ( const ::MWdg::Inputs_Setup * setup_n ) { if ( inputs_setup() != 0 ) { _mixer_hctl->set_inputs_setup ( 0 ); } ::Views::View_Base::set_inputs_setup ( setup_n ); if ( inputs_setup() != 0 ) { _mixer_hctl->set_inputs_setup ( inputs_setup() ); } } void Mixer_HCTL::set_view_setup ( ::Views::View_Base_Setup * setup_n ) { if ( _view_setup != 0 ) { _mixer_hctl->set_image_alloc ( 0 ); _mixer_hctl->set_wdg_style_db ( 0 ); } _view_setup = dynamic_cast < ::Views::Mixer_HCTL_Setup * > ( setup_n ); if ( _view_setup != 0 ) { _mixer_hctl->set_wdg_style_db ( _view_setup->wdg_style_db ); _mixer_hctl->set_image_alloc ( _view_setup->image_alloc ); if ( _view_setup->wdg_style_db != 0 ) { // Get playback / capture colors { const unsigned int style_id ( ::MWdg::Mixer_Style::PLAYBACK ); const QPalette & pal ( _view_setup->wdg_style_db->palette ( style_id ) ); _tree_model->set_snd_dir_foreground ( 0, pal.color ( QPalette::WindowText ) ); } { const unsigned int style_id ( ::MWdg::Mixer_Style::CAPTURE ); const QPalette & pal ( _view_setup->wdg_style_db->palette ( style_id ) ); _tree_model->set_snd_dir_foreground ( 1, pal.color ( QPalette::WindowText ) ); } } setup_view(); restore_state(); } } void Mixer_HCTL::setup_view ( ) { if ( ( mdev_setup() == 0 ) || ( _view_setup == 0 ) ) { return; } int lay_stack_idx ( 0 ); // Open mixer if ( !mdev_setup()->ctl_addr.isEmpty() ) { if ( _snd_mixer->is_open() ) { _tree_model->set_snd_mixer ( _snd_mixer ); _table_model->set_snd_mixer ( _snd_mixer ); lay_stack_idx = 1; } else { message_wdg()->set_mixer_open_fail ( mdev_setup()->ctl_addr, _snd_mixer->err_message(), _snd_mixer->err_func() ); } } else { message_wdg()->set_no_device(); } expand_tree_items(); adjust_table_columns(); lay_stack()->setCurrentIndex ( lay_stack_idx ); } void Mixer_HCTL::restore_state ( ) { if ( ( mdev_setup() == 0 ) || ( _view_setup == 0 ) ) { return; } QModelIndex idx ( _tree_model->elem_desc_index ( _view_setup->iface_name, _view_setup->elem_grp_name, _view_setup->elem_grp_index ) ); if ( !idx.isValid() ) { idx = _tree_model->index ( 0, 0 ); } if ( idx.isValid() ) { _tree_view->setCurrentIndex ( idx ); } } void Mixer_HCTL::expand_tree_items ( ) { const QModelIndex base_idx ( _tree_model->invisibleRootItem()->index() ); _tree_view->expand ( base_idx ); const unsigned int num_rows ( _tree_model->rowCount ( base_idx ) ); if ( num_rows == 1 ) { for ( unsigned int ii=0; ii < num_rows; ++ii ) { QModelIndex mod_idx ( _tree_model->index ( ii, 0, base_idx ) ); _tree_view->expand ( mod_idx ); } } } void Mixer_HCTL::adjust_table_columns ( ) { _table_view->resizeColumnsToContents(); _table_view->resizeRowsToContents(); } void Mixer_HCTL::tree_element_selected ( const QModelIndex & idx_n ) { if ( !idx_n.isValid() ) { return; } ::QSnd::Mixer_HCTL_Elem_Group * elem_grp ( 0 ); unsigned int elem_grp_index ( 0 ); unsigned int iface_type_index ( 0 ); unsigned int found_type = _tree_model->index_data ( idx_n, &elem_grp, &elem_grp_index, &iface_type_index ); if ( found_type == 1 ) { //::std::cout << "Element type selected\n"; _table_model->set_iface_type_idx ( iface_type_index ); _lay_center_stack->setCurrentIndex ( 0 ); adjust_table_columns(); } else if ( found_type == 2 ) { //::std::cout << "Element group selected\n"; _mixer_hctl->set_snd_elem_group ( elem_grp, elem_grp_index ); _lay_center_stack->setCurrentIndex ( 1 ); } else if ( found_type == 3 ) { //::std::cout << "Element selected\n"; _mixer_hctl->set_snd_elem_group ( elem_grp, elem_grp_index ); _lay_center_stack->setCurrentIndex ( 1 ); } // Save selected state in the setup class if ( _view_setup != 0 ) { if ( found_type > 0 ) { _view_setup->iface_name = _snd_mixer->info_db()->iface_name ( iface_type_index ); if ( found_type == 1 ) { _view_setup->elem_grp_name.clear(); } else { _view_setup->elem_grp_name = elem_grp->elem ( 0 )->elem_name(); _view_setup->elem_grp_index = elem_grp_index; } } } } void Mixer_HCTL::table_element_selected ( const QModelIndex & idx_n ) { ::QSnd::Mixer_HCTL_Elem * elem ( _table_model->elem ( idx_n ) ); if ( elem != 0 ) { QModelIndex tree_idx ( _tree_model->elem_index ( elem ) ); if ( tree_idx.isValid() ) { _tree_view->setCurrentIndex ( tree_idx ); } } } } // End of namespace qastools-v0.22.0/qashctl/src/views/mixer_hctl.hpp000066400000000000000000000033161354534512100220660ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_views_mixer_hctl_hpp__ #define __INC_views_mixer_hctl_hpp__ #include "views/view_base.hpp" #include #include // Forward declaration namespace QSnd { class Mixer_HCTL; } namespace Wdg { class Tree_View_KV; } namespace MWdg { class Mixer_HCTL_Tree_Model; class Mixer_HCTL_Table_Model; class Mixer_HCTL; } namespace Views { class Mixer_HCTL_Setup; } namespace Views { class Mixer_HCTL : public ::Views::View_Base { Q_OBJECT // Public methods public: Mixer_HCTL ( QWidget * parent_n = 0 ); ~Mixer_HCTL ( ); // Mixer device and view setup void set_mdev_setup ( const ::MWdg::Mixer_Device_Setup * setup_n ); void set_inputs_setup ( const ::MWdg::Inputs_Setup * setup_n ); void set_view_setup ( ::Views::View_Base_Setup * setup_n ); // Protected slots protected slots: void tree_element_selected ( const QModelIndex & idx_n ); void table_element_selected ( const QModelIndex & idx_n ); // Protected methods protected: void setup_view ( ); void expand_tree_items ( ); void adjust_table_columns ( ); void restore_state ( ); // Private attributes private: ::Views::Mixer_HCTL_Setup * _view_setup; // Databases ::QSnd::Mixer_HCTL * _snd_mixer; ::MWdg::Mixer_HCTL_Tree_Model * _tree_model; ::MWdg::Mixer_HCTL_Table_Model * _table_model; // Side widgets QWidget _wdg_side; ::Wdg::Tree_View_KV * _tree_view; // Central widgets QWidget _wdg_center; QStackedLayout * _lay_center_stack; QTableView * _table_view; ::MWdg::Mixer_HCTL * _mixer_hctl; unsigned int _default_iface_type_idx; }; } // End of namespace #endif qastools-v0.22.0/qashctl/src/views/mixer_hctl_setup.cpp000066400000000000000000000003641354534512100233010ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "mixer_hctl_setup.hpp" namespace Views { Mixer_HCTL_Setup::Mixer_HCTL_Setup ( ) : elem_grp_index ( 9999 ) { } } // End of namespace qastools-v0.22.0/qashctl/src/views/mixer_hctl_setup.hpp000066400000000000000000000010271354534512100233030ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_mv_mixer_hctl_setup_hpp__ #define __INC_mv_mixer_hctl_setup_hpp__ #include "views/view_base_setup.hpp" #include namespace Views { class Mixer_HCTL_Setup : public ::Views::View_Base_Setup { // Public methods public: Mixer_HCTL_Setup ( ); // Public attributes public: // Public attributes QString iface_name; QString elem_grp_name; unsigned int elem_grp_index; }; } // End of namespace #endif qastools-v0.22.0/qasmixer/000077500000000000000000000000001354534512100154625ustar00rootroot00000000000000qastools-v0.22.0/qasmixer/CMakeLists.txt000066400000000000000000000011531354534512100202220ustar00rootroot00000000000000# Program name IF ( NOT PROGRAM_TITLE ) SET ( PROGRAM_TITLE "QasMixer" ) ENDIF ( NOT PROGRAM_TITLE ) IF ( NOT PROGRAM_NAME ) SET ( PROGRAM_NAME "qasmixer${PROGRAM_SUFFIX}" ) ENDIF ( NOT PROGRAM_NAME ) string ( TOUPPER ${PROGRAM_NAME} PROGRAM_NAME_UCASE ) # Program version SET ( VERSION_MAJOR ${PACKAGE_VERSION_MAJOR} ) SET ( VERSION_MINOR ${PACKAGE_VERSION_MINOR} ) SET ( VERSION_PATCH ${PACKAGE_VERSION_PATCH} ) SET ( VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}${VERSION_SUFFIX}" ) # Process subdirectories ADD_SUBDIRECTORY ( src ) ADD_SUBDIRECTORY ( graphics ) ADD_SUBDIRECTORY ( share ) qastools-v0.22.0/qasmixer/doc/000077500000000000000000000000001354534512100162275ustar00rootroot00000000000000qastools-v0.22.0/qasmixer/doc/Bevel_01.svg000066400000000000000000000242601354534512100203110ustar00rootroot00000000000000 image/svg+xml b b 22.5° 67.5° qastools-v0.22.0/qasmixer/doc/Bevel_types.svg000066400000000000000000000132101354534512100212260ustar00rootroot00000000000000 image/svg+xml qastools-v0.22.0/qasmixer/doc/Labels.svg000066400000000000000000000563561354534512100201710ustar00rootroot00000000000000 image/svg+xml φ φ φ l l h φ w l + l * sin ( φ )= h l * ( 1+ sin ( φ ) ) = h qastools-v0.22.0/qasmixer/doc/Sliders_Pad.svg000066400000000000000000000121011354534512100211340ustar00rootroot00000000000000 image/svg+xml Header Footer Input area qastools-v0.22.0/qasmixer/graphics/000077500000000000000000000000001354534512100172625ustar00rootroot00000000000000qastools-v0.22.0/qasmixer/graphics/CMakeLists.txt000066400000000000000000000014051354534512100220220ustar00rootroot00000000000000# Install application icons INSTALL( FILES icons/app-icon-16x16.png DESTINATION ${INSTALL_DIR_ICONS_PNG_16} RENAME ${PROGRAM_NAME}.png ) INSTALL( FILES icons/app-icon-32x32.png DESTINATION ${INSTALL_DIR_ICONS_PNG_32} RENAME ${PROGRAM_NAME}.png ) INSTALL( FILES icons/app-icon-48x48.png DESTINATION ${INSTALL_DIR_ICONS_PNG_48} RENAME ${PROGRAM_NAME}.png ) INSTALL( FILES icons/app-icon-64x64.png DESTINATION ${INSTALL_DIR_ICONS_PNG_64} RENAME ${PROGRAM_NAME}.png ) INSTALL( FILES icons/app-icon.svg DESTINATION ${INSTALL_DIR_ICONS_SVG} RENAME ${PROGRAM_NAME}.svg ) # Install simple mixer icons INSTALL ( FILES icons/show-playback.svg DESTINATION ${INSTALL_DIR_APP_ICONS} ) INSTALL ( FILES icons/show-capture.svg DESTINATION ${INSTALL_DIR_APP_ICONS} ) qastools-v0.22.0/qasmixer/graphics/icons/000077500000000000000000000000001354534512100203755ustar00rootroot00000000000000qastools-v0.22.0/qasmixer/graphics/icons/app-icon-16x16.png000066400000000000000000000020101354534512100233650ustar00rootroot00000000000000PNG  IHDRjbKGD#2 pHYsHHFk>IDAT8][Lu˥KZdCH6X lf ɔ,:8Q7q@xX" a &CȀ -0-P4p9'z2-떾hWG҂j(=o>5{~ +_b\FzeeK()~TPj_Y cI sla#z? %i(9Uu3ZO5s">glLd"vXaZ tkY 6-zLR1a*C,3<, &lg&Oshr0T,GTv>WVU hUoky*\cݿ 6J/Ƨ+4^sda޴\v=-;P S.);+Ӽ K"vS "Z)i+Y'-̢GXdž_7^{"OE #g',ҥj>GC MHa:>%óҾk _zOuf緻1~фui_ނ}߮.JT 7Vv\;7dٯȲ$o{.Ĭh(hXW] u9mE-.zPArMwy }ȧZ|>\ZZ:cfw"=ݞ͹>f uᖝ{Ǘ O>v 7xIwq XΝ1rda 78@ OVˎ8ki|RWjz]8!ßa+̓Δ]?=\ L Q?MhQ=wNֆ)TNĹ(64u::Ҟzv}OaB5&V[7˰ܽږ0q Oĺ_:7mqa+ٚ c367aJ<7͕BjIENDB`qastools-v0.22.0/qasmixer/graphics/icons/app-icon-32x32.png000066400000000000000000000047311354534512100233750ustar00rootroot00000000000000PNG  IHDR n<bKGD#2 pHYsHHFk> }IDATXíyxW?ݒ{I$)%"VB-UmաEL; ZF[T;CflPJR[kR$$"3GU:Os;~y# NPErɩg+]#+ejEP;lHޚo8wsSJ ^QdEi5WݦE:ή˜]CQE/1qteTZeVMkZ_}.cw1qnGU%_.SNso4WhDXnbO&DZAD/Nֵ԰"ֆ0AIT"I/#UXh!mDZ[G!-, L7pNv@S4Q\FP@q]=2lZ1Nx"NQj9f@caH >{F͎,0 7?K ԓ!GhvfD)jam(ORU4l@VTYMq$Fu3T/O6rc)hd|amL`76GL6LuKrJ..%oJ0ښ[aY-Ƭo>?3c-Z'Ҫ7>728Jnr|у,vM0/5<'iYV ӈ2_7lOjQjYizJ;b$ b[=f6G}B)G=]%f  V}T:.][/Y 2.'|"By|XW4= b*ڀx zg$9/U `< Z<n] L˴"@wt@/Q ^(kZ!3 ̀! dg0'ʹ/5cDƂ}tHZA4}H|5,k{`nH<1d{L ևAfWWZGVS80"6 ,:>x& i;'k"P@z+"/a")0{h45GdҮhqt}gK|,HɻPc55?z_wУl1‚j|YnÝ'-Ks NXs;WZ}ԭV}cH볷D%-{=Q6jc[TU;F7ZÂ$ f%Vj-U*85WL7`KERt/,pD1Tޗ ZO5C!-X\JSibP"R5E 7΋ov㼠Rq*!g ^v:7V-,<| 1c(Atځ bsi=꤂J4zuAD Lm4Po@u?aʳ[D.^LPwj? A9_iX`=#R䅊Co飭m1Rb[7~v+UjXf=EuMS^{ T`Fm8j۶5N닪c?6kía}n?=|HM>WS{Q5Iax^YD܊Oڗ^]ig"CGDT):JUl=EJ,gKb+5yl,J}(4R1L1I0fPƽ x#j% #~wLaF/ G]]5HR,q@+}qsV8h-EZ:sEwNf"kHR:MHA2wB7I3i\SW5AtEL߳K;2%P$%F>P}d#՞xg4F02};zU " 3cB@4M{ L4~vz\y|D0F6 ?"RIENDB`qastools-v0.22.0/qasmixer/graphics/icons/app-icon-48x48.png000066400000000000000000000100041354534512100234010ustar00rootroot00000000000000PNG  IHDR00ObKGD#2 pHYsHHFk>IDAThՙiչ3=C< (#(QQdQ A`\ DfF>M3Wr݅V+OSw޽}9Z]EpPP քN&{){=;<|w;ϯف_>˃R B!)x#TLpAhRf+m&=C=זOgyU-ZM䤿;fF __.TS93ZQ+o =]C])ok8 D!v ޙjJz/E 5ιXSm;zB.8ף\=Wy{H^E,i/ g\p@mfJAgt?{4䝘Ix}/hp/& 5bG~.S" q(|(u3lP/:83蔢8Pz +@1JILQ@b (!j!5SƷ5% r'\ ·fULH!Oqb1rXHX6R!8J b(R/mV> v,jsdͱ_F}okt?i;²CC[ѴAߢMKbН5Unܟom;=&3YRR^85{ܼܶ?Le3mc/}5H RȊI};ΣZY_G)q\tIxP2P~i;hHDҞ~ yb< 2CSz^"DLJBfuDT 4ӛ'aGp;'qHzl h"rab07t\ &&8ICg<)c$'L 儩C44 pLמN4${i2 ?*]vF9hcljx[kRwpeR)4ߙiZiTCN|ty|K:jwFj'ϻRm4hODV6VnPAjkw t~etC4Dmfzms #? n ݀߼?"3U9MYT \Kg"TwTQXd(d͠oD2D pU663Y m \,I7Eo\Aew i-&H Ŵ+G򆚋getėn v (HS^+Q 2`f@ߦaul66 559ޚ22؍h)3ej}/j#l(ڃ,p^4neMM(p8 fa'P 8lf* 8hQIe  `#0PEmRj 1'",p{З6U엜UMv bF0]P7E0({`bN9Hl!%`=F"r:`_^ K@|  c])~X;)M%օ" !.1҆Pj`sb57^up3\fH#5ƌKw.Գ!q},G=s:a,aBt撆5_^j41ŚW42Rz!2!~\ħQh~VaW_ jpLyu_:!G$2z_xtU؉oOϭ~XdfwRlMj'e+;[ ]ӂ2Pm%ʧdN<QU-V0Luãf✣Qq @҉L6?>1viYPz4bD#f1Sj\x$>31m fo.ռ.uWR=,K;agl5oU$_h[4}׈З*xUQ*@#jAG*`+tE3tE$z+R|=aY,-}OȂ*8>s=O1a k!pcqܿ}1v%++hdAm<&bY̷SbH/;-~rӮ.W֨5kZ<f0b=mAhHfڲ;ȝ,$(50 !k2X.&[wVapCJ ۲w-;*6վJh-- %Oj^ѿHp>MV@zVi@ @+`P<1*`w5Pj/Zmg!lqv 4c⿲0H6dž:^5"J+ڻ8x@ g7c` jP6wwì?=Y276>CUӚU醆Hskݣrʎu%إ>~`(]3_Nm!̇Ȫ[o9wSUV=u\4n & 1A%S}'q ld 9$Ey,6T;uUtjqCшN#*38iċYNo?v1r4@\Tn6\UN^k|Dfm@ PF8RjzcB7i2iT'N, fROd5B588#ijGqKcIU:7Ulo6,69VRU*]x rZ:ϱ@@yOߋ>3egPk[;̍%.f@fՆ55pDsC2A֓mލh]6 !)w!BhZ\>fZSȵϚ(OЀެpzkí0`\Zhq-0 E{) Y(i J΂֠h@EW>h A;&ĕP@d CT&YE?܍  ]P|F6cوЈF\VbKFHr8GOP x=ދ!HS;pܑF+6Du,fVR"t+& èklG7zf Tƶhyxht!drbi<ѰxS=HiEefIENDB`qastools-v0.22.0/qasmixer/graphics/icons/app-icon-64x64.png000066400000000000000000000126611354534512100234100ustar00rootroot00000000000000PNG  IHDR@@PebKGD#2 pHYsHHFk>UIDATxyU*I%ffW6QDQeiQsDQqE GEAEEwwDUA@^غٺ;$Uu?r=378~p{NNJrO=܊( tho^v_ʸ9\17:?:R/%a2wꁮK?U?n.s s8m]Ss<OC-gL\?4ҘdNp%x>Tcƣ% 6B]2|g6Rr[u{M'#Ek#"GgRO4nj:t=VŘz9͸2WjQP}krak iqD9PoIc$G7d-)o@V|I/w:){&ڻ:Qxvd8ޤC>=HMP,SSSwMYK8tzOJa*ݗuOs3չ \cxʰ盃H>hjfZ g;QMT$G%v :cWdjp.$QrLC} WH9)k@ A7*$HJ)w"ylV JGr!p:S #"e930w@ 7,% ) A'5H!6L#4FӨ\+/ qԼWWH Џk0: 2N;rE0`}K ?|ڳ9{tSHzȰH:.Ǣ ݳ;qSQrZυ6g:ƳER[\ Ӎ- 1'-K*_9˱y+q\ۻ.PRc#$q1G7Dzgپ{%Ar##t1<=i\aI]nygL:Al&aQ,faleƱ 2JlG10U*arqͧcA1B|Y+~`/;.$[U@'7j΍<`&f;3NYYw~d־h,TqCDYTbvRdNY#>q=EB8N Ba#DBb<_"{"qH-:+-+(*r Mb?yH}"ieX.wW[O,G/ܗ$T_,fKg'ا)z~$RUq##9\9@Ѻź8?˸ИZLm+CȾw^9exyȳ5Ak6BC{a 9i8잯J\LDˏ%;Vha/h\e;ZKptDޚb<7h7s>UܪMꑔQ BtCOvA9d9@ܫ/lDOdE5,~9hA_1I(ӋY_'8.-[@N}VmR F[f#yz[ky H$<Ԯwl9JcD]&^;2{?>ήW1[ G.tR&0#d~ ZǪț{O槛!1mm[~Nozڤ5t;@i*nحA-/ 7/͖r3˾808O$'y֏6 >/ߵK5}Mnc#̱Z{|_jPg Лkv[/w:T!)#ō9߆H/}hqȩ:x}挜i2V \WV?f}}KdhEJedkkI*xNq܄CѬ?[l¹b ؐHsg5yƈ<ժ%^Ux. .1O}&O[f_>l˥e{yĀRj;I|bMt=*6AHvc)v"{9lߩ Z*zlK+K"y9o X+Y.hD'j&>/^tZnٟv)kH1m^bhth5yf'f;N1p̾[2 8{Zޕs4b7)b[Ve_mm7bе;b5E/hPI##ӷ0ؖ)R9 %Y2x4Ѓ>t6PY÷|oxwOrO pM6:0^<8]TID*gݴ'^p iXQ +NUh -P|6`K+׉r8Tsm+s1JKWJH)RM.ϳ㕜 Ϋ[ߎ"Y`>蠮|; վ(!/WsȞW9vx+K$Su'#|t21.p΃dMݻ )oDK?`vjkNc-'եON燓AV3|-zQ ITmkh|lB<'rِ\ԣ4%M UF|ᢟRs~s1w1ղ;9' FFh]N4OGj{&^nWQa %4 xbwB '# w+4J}CR=ZրbIÀرOkUE.@ܤܤ4*Plp=ga|1%4Av b{M{V͟8f7IO,i)y=d9üUF2 Q-4&Y55#ގ޶fDq3sƺZ5?9ˤ/ m-2{ӬUZiC3Ɔd1v+O, Gq1I|I1d"qc?ґU|CBb!{ 9Spo.᠃3-F «zLUS) ^5UIc3'u53l`O=` f6ŴEOyoY z G0c.B6±Ž%-? Vu̫w$P+/t&2*fmYXQ}ۻ“3ʼؚS'Nm·DVVpߢ=k?v]xjqKU 0"]jWPn rj+mßۆQbѰW+mosPxTSjگE$kHwҕQ\.G08.,niTneoq-8]'bRDC2E_ PJ'|Pj>Xm4A#@)vH?~EPdkي&N;hAC=H"EO\*}@! zab6`H1Z$D!"Bz?4q*R|{BG0p90G!RGF#59ڋ//^ ݈.jh/Hc.4\S#c|-& w(}t.R/X+ڴ6d;x/S_i24ZҘ-zvZwt$5TOM, F;-Ӊ5I]p4P="y$fXeySW2a+Kh)IENDB`qastools-v0.22.0/qasmixer/graphics/icons/app-icon-source.svg000066400000000000000000000473261354534512100241360ustar00rootroot00000000000000 image/svg+xml qastools-v0.22.0/qasmixer/graphics/icons/app-icon.svg000066400000000000000000000352611354534512100226330ustar00rootroot00000000000000 image/svg+xml qastools-v0.22.0/qasmixer/graphics/icons/show-capture.svg000066400000000000000000000127711354534512100235470ustar00rootroot00000000000000 qastools-v0.22.0/qasmixer/graphics/icons/show-playback.svg000066400000000000000000000126571354534512100236750ustar00rootroot00000000000000 qastools-v0.22.0/qasmixer/graphics/misc/000077500000000000000000000000001354534512100202155ustar00rootroot00000000000000qastools-v0.22.0/qasmixer/graphics/misc/microphone-source.svg000066400000000000000000000271261354534512100244070ustar00rootroot00000000000000 image/svg+xml qastools-v0.22.0/qasmixer/graphics/misc/speaker-source.svg000066400000000000000000000300411354534512100236640ustar00rootroot00000000000000 image/svg+xml qastools-v0.22.0/qasmixer/share/000077500000000000000000000000001354534512100165645ustar00rootroot00000000000000qastools-v0.22.0/qasmixer/share/CMakeLists.txt000066400000000000000000000005211354534512100213220ustar00rootroot00000000000000# Desktop file SET ( desktop_file_src ${CMAKE_CURRENT_SOURCE_DIR}/application.desktop ) SET ( desktop_file ${CMAKE_CURRENT_BINARY_DIR}/${PROGRAM_NAME}.desktop ) CONFIGURE_FILE ( ${desktop_file_src} ${desktop_file} ) INSTALL( FILES ${desktop_file} DESTINATION ${INSTALL_DIR_DESKTOP} ) # Subdirectories ADD_SUBDIRECTORY ( man ) qastools-v0.22.0/qasmixer/share/application.desktop000066400000000000000000000014331354534512100224630ustar00rootroot00000000000000[Desktop Entry] Type=Application Name=${PROGRAM_TITLE} GenericName=Sound volume mixer GenericName[de]=Klanglautstärkenregler GenericName[he]=מערבל צלילי עוצמת שמע GenericName[it]=Mixer volume audio GenericName[ru]=Микшер для звуковой системы Exec=${PROGRAM_NAME} Icon=${PROGRAM_NAME} StartupNotify=false Terminal=false Categories=AudioVideo;Audio;Mixer;Qt; Keywords=ALSA;Audio;Mixer;Qt; Comment=Graphical mixer application for the ALSA Comment[cs]=Grafický směšovač pro ALSA Comment[de]=Graphische Mixeranwendung für ALSA Comment[es]=Mezclador gráfico para ALSA Comment[he]=יישום מערבל גרפי עבור ALSA Comment[it]=Mixer grafico per ALSA Comment[ru]=Графический микшер для звуковой системы ALSA qastools-v0.22.0/qasmixer/share/man/000077500000000000000000000000001354534512100173375ustar00rootroot00000000000000qastools-v0.22.0/qasmixer/share/man/CMakeLists.txt000066400000000000000000000013371354534512100221030ustar00rootroot00000000000000# Find gzip FIND_PACKAGE ( UnixCommands REQUIRED ) IF ( NOT GZIP ) MESSAGE ( FATAL_ERROR "Unable to find 'gzip' program" ) ENDIF ( NOT GZIP ) # Configure manpages SET ( man_src ${CMAKE_CURRENT_SOURCE_DIR}/manpage.1.cmake ) SET ( man_plain ${CMAKE_CURRENT_BINARY_DIR}/manpage.1 ) SET ( man_gz ${CMAKE_CURRENT_BINARY_DIR}/manpage.1.gz ) CONFIGURE_FILE ( ${man_src} ${man_plain} ) # Compress manpages ADD_CUSTOM_COMMAND ( OUTPUT ${man_gz} COMMAND ${GZIP} -c -9 ${man_plain} > ${man_gz} DEPENDS ${man_plain} COMMENT "Building ${man_gz}" ) ADD_CUSTOM_TARGET ( qasmixer_manpage ALL DEPENDS ${man_gz} ) # Installation of the manpage INSTALL ( FILES ${man_gz} DESTINATION ${INSTALL_DIR_MAN} RENAME ${PROGRAM_NAME}.1.gz ) qastools-v0.22.0/qasmixer/share/man/manpage.1.cmake000066400000000000000000000016141354534512100221120ustar00rootroot00000000000000.TH ${PROGRAM_NAME_UCASE} "1" "2011-12-14" "Linux" "QasTools Manuals" .SH NAME ${PROGRAM_NAME} \- Desktop sound mixer for ALSA .SH SYNOPSIS .B ${PROGRAM_NAME} [OPTION]... .SH DESCRIPTION .B ${PROGRAM_TITLE} is a desktop mixer application for the Linux sound system ALSA. .SH OPTIONS .TP \fB\-h\fR, \fB\-\-help\fR prints a help text. .TP \fB\-c\fR, \fB\-\-card=NUMBER\fR selects a sound card. .TP \fB\-D\fR, \fB\-\-device=NAME\fR selects a mixer device (e.g. hw:1). .TP \fB\-t\fR, \fB\-\-tray\fR start minimized in tray. .TP \fB\-n\fR, \fB\-\-no-single\fR allow multiple instances. .TP \fB\-c\fR, \fB\-\-copying\fR prints copying information. .TP \fB\-v\fR, \fB\-\-version\fR prints the program version. .SH NOTES \fB${PROGRAM_TITLE}\fP is part of the \fBQasTools\fP applications collection. It is written in C++ using the Qt GUI libraries. .SH SEE ALSO .B alsamixer(1), qasconfig(1), qashctl(1) qastools-v0.22.0/qasmixer/src/000077500000000000000000000000001354534512100162515ustar00rootroot00000000000000qastools-v0.22.0/qasmixer/src/CMakeLists.txt000066400000000000000000000143241354534512100210150ustar00rootroot00000000000000# --- Find modules FIND_PACKAGE ( Qt5Core REQUIRED ) FIND_PACKAGE ( Qt5Widgets REQUIRED ) FIND_PACKAGE ( Qt5Svg REQUIRED ) FIND_PACKAGE ( Qt5Network REQUIRED ) FIND_PACKAGE ( ALSA REQUIRED ) # TODO: FIND_PACKAGE SET ( UDEV_LIBRARIES udev ) # --- Configure files INCLUDE ( CheckIncludeFiles ) CONFIGURE_FILE ( ${SHARED_SRC_DIR}/qastools_config.hpp.cmake ${CMAKE_CURRENT_BINARY_DIR}/qastools_config.hpp ) # --- Sources SET ( SRC_GUI ${SHARED_SRC_DIR}/qsnd/alsa.cpp ${SHARED_SRC_DIR}/qsnd/event_types.cpp ${SHARED_SRC_DIR}/qsnd/ctl_format_argument.cpp ${SHARED_SRC_DIR}/qsnd/ctl_format.cpp ${SHARED_SRC_DIR}/qsnd/ctl_address_argument.cpp ${SHARED_SRC_DIR}/qsnd/ctl_address.cpp ${SHARED_SRC_DIR}/qsnd/controls_database.cpp ${SHARED_SRC_DIR}/qsnd/controls_model.cpp ${SHARED_SRC_DIR}/qsnd/cards_model.cpp ${SHARED_SRC_DIR}/qsnd/card_info.cpp ${SHARED_SRC_DIR}/qsnd/mixer_simple_elem.cpp ${SHARED_SRC_DIR}/qsnd/mixer_simple_filter.cpp ${SHARED_SRC_DIR}/qsnd/mixer_simple_filter_name.cpp ${SHARED_SRC_DIR}/qsnd/mixer_simple.cpp ${SHARED_SRC_DIR}/qsnd/udev_device_lookout.cpp ${SHARED_SRC_DIR}/dpe/image.cpp ${SHARED_SRC_DIR}/dpe/image_set_meta.cpp ${SHARED_SRC_DIR}/dpe/image_set.cpp ${SHARED_SRC_DIR}/dpe/image_set_group.cpp ${SHARED_SRC_DIR}/dpe/image_set_state.cpp ${SHARED_SRC_DIR}/dpe/image_request.cpp ${SHARED_SRC_DIR}/dpe/image_allocator.cpp ${SHARED_SRC_DIR}/dpe/is_buffer_handle.cpp ${SHARED_SRC_DIR}/dpe/is_buffer.cpp ${SHARED_SRC_DIR}/dpe/paint_job.cpp ${SHARED_SRC_DIR}/dpe/painter.cpp ${SHARED_SRC_DIR}/dpe/painter_simple.cpp ${SHARED_SRC_DIR}/dpe/painter_thread.cpp ${SHARED_SRC_DIR}/dpe/painter_thread_shared.cpp ${SHARED_SRC_DIR}/wdg/label_elide.cpp ${SHARED_SRC_DIR}/wdg/label_width.cpp ${SHARED_SRC_DIR}/wdg/text_browser.cpp ${SHARED_SRC_DIR}/wdg/scroll_area_horizontal.cpp ${SHARED_SRC_DIR}/wdg/scroll_area_vertical.cpp ${SHARED_SRC_DIR}/wdg/balloon_widget.cpp ${SHARED_SRC_DIR}/wdg/color_methods.cpp ${SHARED_SRC_DIR}/wdg/ds_widget_style_db.cpp ${SHARED_SRC_DIR}/wdg/ds_widget_painter.cpp ${SHARED_SRC_DIR}/wdg/ds_imaging.cpp ${SHARED_SRC_DIR}/wdg/ds_switch_painter_circle.cpp ${SHARED_SRC_DIR}/wdg/ds_switch_painter_close.cpp ${SHARED_SRC_DIR}/wdg/ds_switch_painter_svg.cpp ${SHARED_SRC_DIR}/wdg/ds_switch.cpp ${SHARED_SRC_DIR}/wdg/uint_mapper.cpp ${SHARED_SRC_DIR}/wdg/cubic_curve.cpp ${SHARED_SRC_DIR}/wdg/ds_slider_meta_bg.cpp ${SHARED_SRC_DIR}/wdg/ds_slider_painter_bevelled.cpp ${SHARED_SRC_DIR}/wdg/ds_slider.cpp ${SHARED_SRC_DIR}/wdg/event_types.cpp ${SHARED_SRC_DIR}/wdg/pass_events.cpp ${SHARED_SRC_DIR}/wdg/pad_focus_info.cpp ${SHARED_SRC_DIR}/wdg/pad_proxy.cpp ${SHARED_SRC_DIR}/wdg/pad_proxy_style.cpp ${SHARED_SRC_DIR}/wdg/pad_proxy_slider.cpp ${SHARED_SRC_DIR}/wdg/pad_proxy_switch.cpp ${SHARED_SRC_DIR}/wdg/pad_proxy_enum.cpp ${SHARED_SRC_DIR}/wdg/pad_proxies_column.cpp ${SHARED_SRC_DIR}/wdg/pad_proxies_group.cpp ${SHARED_SRC_DIR}/wdg/layout_weights.cpp ${SHARED_SRC_DIR}/wdg/equal_columns_layout_group.cpp ${SHARED_SRC_DIR}/wdg/equal_columns_layout.cpp ${SHARED_SRC_DIR}/wdg/fill_columns_layout.cpp ${SHARED_SRC_DIR}/wdg/sliders_pad_layout.cpp ${SHARED_SRC_DIR}/wdg/sliders_pad_style.cpp ${SHARED_SRC_DIR}/wdg/sliders_pad_data.cpp ${SHARED_SRC_DIR}/wdg/sliders_pad_header_data.cpp ${SHARED_SRC_DIR}/wdg/sliders_pad_header.cpp ${SHARED_SRC_DIR}/wdg/sliders_pad_footer.cpp ${SHARED_SRC_DIR}/wdg/sliders_pad.cpp ${SHARED_SRC_DIR}/wdg/switches_pad_widgets.cpp ${SHARED_SRC_DIR}/wdg/switches_pad_widgets_group.cpp ${SHARED_SRC_DIR}/wdg/switches_pad.cpp ${SHARED_SRC_DIR}/wdg/switches_area.cpp ${SHARED_SRC_DIR}/mwdg/event_types.cpp ${SHARED_SRC_DIR}/mwdg/ctl_arg_view.cpp ${SHARED_SRC_DIR}/mwdg/ctl_arg_view_string.cpp ${SHARED_SRC_DIR}/mwdg/ctl_arg_view_integer.cpp ${SHARED_SRC_DIR}/mwdg/ctl_arg_view_card.cpp ${SHARED_SRC_DIR}/mwdg/controls_delegate.cpp ${SHARED_SRC_DIR}/mwdg/controls_view.cpp ${SHARED_SRC_DIR}/mwdg/slider_status_widget.cpp ${SHARED_SRC_DIR}/mwdg/inputs_setup.cpp ${SHARED_SRC_DIR}/mwdg/mixer_device_setup.cpp ${SHARED_SRC_DIR}/mwdg/mixer_style.cpp ${SHARED_SRC_DIR}/views/view_utility.cpp ${SHARED_SRC_DIR}/views/message_widget.cpp ${SHARED_SRC_DIR}/views/view_base_setup.cpp ${SHARED_SRC_DIR}/views/view_base.cpp ${SHARED_SRC_DIR}/views/device_selection_view_setup.cpp ${SHARED_SRC_DIR}/views/device_selection_view.cpp ${SHARED_SRC_DIR}/views/basic_dialog.cpp ${SHARED_SRC_DIR}/views/multi_page_dialog.cpp ${SHARED_SRC_DIR}/views/info_dialog.cpp ${SHARED_SRC_DIR}/unix_signal_handler.cpp ${SHARED_SRC_DIR}/single_application.cpp ${SHARED_SRC_DIR}/license_texts.cpp mwdg/mixer_gui_state.cpp mwdg/mixer_simple_setup.cpp mwdg/mixer_separation_info.cpp mwdg/mixer_sliders_proxy_slider.cpp mwdg/mixer_sliders_proxy_switch.cpp mwdg/mixer_sliders_proxies_column.cpp mwdg/mixer_sliders_proxies_group.cpp mwdg/mixer_sliders_status_widget.cpp mwdg/mixer_sliders.cpp mwdg/mixer_switches_proxy_enum.cpp mwdg/mixer_switches_proxy_switch.cpp mwdg/mixer_switches_proxies_group.cpp mwdg/mixer_switches.cpp views/mixer_simple_setup.cpp views/mixer_simple.cpp views/settings_dialog_setup.cpp views/settings_dialog.cpp tray_mixer_mdev_setup.cpp tray_mixer_view_setup.cpp tray_mixer_icon.cpp tray_mixer_balloon.cpp tray_mixer.cpp cmd_options.cpp main_window_setup.cpp main_window.cpp desktop_items_setup.cpp desktop_items.cpp init_globals.cpp info_texts.cpp main.cpp ) # --- Compiler flags SET ( CMAKE_CXX_STANDARD 17 ) SET ( CMAKE_CXX_STANDARD_REQUIRED OFF ) SET ( CMAKE_CXX_EXTENSIONS OFF ) SET ( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wextra -Wunused -Wall" ) SET ( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 -g -fno-inline" ) SET ( CMAKE_CXX_FLAGS_RELEASE "-O2 ${CMAKE_CXX_FLAGS_RELEASE}" ) # --- Include directories INCLUDE_DIRECTORIES ( ${CMAKE_CURRENT_SOURCE_DIR} ) INCLUDE_DIRECTORIES ( ${CMAKE_CURRENT_BINARY_DIR} ) INCLUDE_DIRECTORIES ( ${SHARED_INC_DIR} ) INCLUDE_DIRECTORIES ( ${ALSA_INCLUDE_DIRS} ) # --- Executable ADD_EXECUTABLE ( ${PROGRAM_NAME} ${SRC_GUI} ) SET_TARGET_PROPERTIES ( ${PROGRAM_NAME} PROPERTIES AUTOMOC ON ) TARGET_LINK_LIBRARIES ( ${PROGRAM_NAME} Qt5::Widgets Qt5::Svg Qt5::Network ${ALSA_LIBRARIES} ${UDEV_LIBRARIES} ) # --- Installation INSTALL ( TARGETS ${PROGRAM_NAME} RUNTIME DESTINATION ${INSTALL_DIR_BIN} ) qastools-v0.22.0/qasmixer/src/cmd_options.cpp000066400000000000000000000003401354534512100212700ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "cmd_options.hpp" CMD_Options::CMD_Options ( ) : start_tray_minimized ( false ), start_single_instance ( true ) { } qastools-v0.22.0/qasmixer/src/cmd_options.hpp000066400000000000000000000007461354534512100213070ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_cmd_options_hpp__ #define __INC_cmd_options_hpp__ #include /// @brief Command (line) options /// /// These can come from the command line or from a second instance class CMD_Options { // Public methods public: CMD_Options ( ); // Public attributes public: bool start_tray_minimized; bool start_single_instance; QString start_ctl_address; }; #endif qastools-v0.22.0/qasmixer/src/desktop_items.cpp000066400000000000000000000341311354534512100216310ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "desktop_items.hpp" #include "qastools_config.hpp" #include "info_texts.hpp" #include "tray_mixer.hpp" #include "main_window.hpp" #include "wdg/ds_slider_painter_bevelled.hpp" #include "wdg/ds_switch_painter_circle.hpp" #include "wdg/ds_switch_painter_close.hpp" #include "wdg/ds_switch_painter_svg.hpp" #include "wdg/ds_widget_types.hpp" #include "views/info_dialog.hpp" #include "views/settings_dialog.hpp" #include #include #include #include #include #include #include Desktop_Items::Desktop_Items ( QObject * parent_n ) : QObject ( parent_n ), _tray_mixer ( 0 ), _main_mixer ( 0 ), _started ( false ), _shutdown ( false ) { // Init widget style database { ::MWdg::Mixer_Style mstyle; ::MWdg::Mixer_Style::Style_Type stype; stype = ::MWdg::Mixer_Style::PLAYBACK ; _wdg_style_db.palettes.insert ( stype, mstyle.style_palette ( stype ) ); stype = ::MWdg::Mixer_Style::CAPTURE; _wdg_style_db.palettes.insert ( stype, mstyle.style_palette ( stype ) ); } { _dsetup.main_window.mixer_simple.wdg_style_db = &_wdg_style_db; _dsetup.main_window.mixer_simple.image_alloc = &_image_alloc; } _dsetup.tray_view.image_alloc = &_image_alloc; _evt_mixer_closed = QEvent::registerEventType(); } Desktop_Items::~Desktop_Items ( ) { if ( _started ) { shutdown(); _dsetup.write_to_storage(); } } int Desktop_Items::init_settings ( int argc, char * argv[] ) { _dsetup.read_from_storage(); return parse_cmd_options ( argc, argv ); } int Desktop_Items::parse_cmd_options ( int argc, char * argv[] ) { // Suppresses error messages by getopt_long opterr = 0; QString card_idx; QString ctl_address; bool flag_print_version ( false ); bool flag_print_help ( false ); bool flag_print_copy_info ( false ); bool scan_further ( true ); while ( scan_further ) { static struct option long_opts[] = { { "help", no_argument, 0, 'h' }, { "card", required_argument, 0, 'c' }, { "device", required_argument, 0, 'D' }, { "tray", no_argument, 0, 't' }, { "no-single", no_argument, 0, 'n' }, { "copying", no_argument, 0, 'i' }, { "version", no_argument, 0, 'v' }, {0, 0, 0, 0} }; // getopt_long stores the option index here. int long_opts_idx ( 0 ); int opt_char = getopt_long ( argc, argv, "hc:D:tniv", long_opts, &long_opts_idx ); // Leave loop if ( opt_char < 0 ) { break; } switch ( opt_char ) { case 0: break; case 'h': flag_print_help = true; scan_further = false; break; case 'c': card_idx = optarg; break; case 'D': ctl_address = optarg; break; case 't': _cmd_opts.start_tray_minimized = true; break; case 'n': _cmd_opts.start_single_instance = false; break; case 'i': flag_print_copy_info = true; break; case 'v': flag_print_version = true; break; default: // Dont't break, as the option may be for QT break; } } if ( flag_print_help ) { { ::std::stringstream msg; msg << "Usage:" << ::std::endl; msg << " " << PROGRAM_NAME << " [OPTION]..." << ::std::endl; msg << ::std::endl; msg << info_text_options; msg << ::std::endl; ::std::cout << msg.str() << ::std::flush; } return -1; } if ( flag_print_version ) { { ::std::stringstream msg; msg << PROGRAM_NAME << " " << VERSION << ::std::endl; ::std::cout << msg.str() << ::std::flush; } return -1; } if ( flag_print_copy_info ) { { ::std::stringstream msg; msg << PROGRAM_TITLE; msg << " - desktop mixer for the Linux sound system ALSA."; msg << ::std::endl; msg << ::std::endl; msg << license_text_short; msg << ::std::endl; ::std::cout << msg.str() << ::std::flush; } return -1; } if ( ctl_address.isEmpty() && !card_idx.isEmpty() ) { bool is_numeric; int card_idx_int ( card_idx.toInt ( &is_numeric ) ); if ( is_numeric ) { if ( card_idx_int < 0 ) { card_idx_int = 0; } ctl_address = QString ( "hw:%1" ).arg ( card_idx_int ); } } if ( !ctl_address.isEmpty() ) { _cmd_opts.start_ctl_address = ctl_address; _dsetup.main_window.mixer_dev.ctl_addr = ctl_address; } return 0; } void Desktop_Items::parse_message ( QString msg_n ) { //::std::cout << "Desktop_Items::parse_message " << "\n"; QStringList rows ( msg_n.split ( "\n", QString::SkipEmptyParts ) ); for ( int ii=0; ii < rows.size(); ++ii ) { const QString & row ( rows[ii] ); //::std::cout << "row[" << ii << "]: " << row.toLocal8Bit().constData() << "\n"; if ( row.contains ( "raise", Qt::CaseInsensitive ) ) { main_mixer_raise(); } else if ( row.contains ( "ctl_address=", Qt::CaseInsensitive ) ) { QString ctl_str; { const int idx ( row.indexOf ( "=" ) + 1 ); ctl_str = ( row.mid ( idx ).trimmed() ); } if ( !ctl_str.isEmpty() ) { if ( _main_mixer == 0 ) { _dsetup.main_window.mixer_dev.ctl_addr = ctl_str; tray_mixer_reload_current_mdev(); } else { _main_mixer->select_ctl ( ctl_str ); } } } } } QString Desktop_Items::message_to_other_instance ( ) const { // The message that gets sent to the other instance QString msg ( "new_instance\n" ); // Append ALSA ctl address command if ( !cmd_opts().start_ctl_address.isEmpty() ) { msg.append ( "ctl_address=" ); msg.append ( cmd_opts().start_ctl_address ); msg.append ( "\n" ); } // Append raise main window command if ( !cmd_opts().start_tray_minimized ) { msg.append ( "raise\n" ); } return msg; } void Desktop_Items::start ( bool restore_session_n ) { _started = true; // Translation _dsetup.main_window.inputs.update_translation(); // Startup mixer device { QString & ctl_addr ( _dsetup.main_window.mixer_dev.ctl_addr ); if ( _cmd_opts.start_ctl_address.isEmpty() ) { bool use_default ( true ); switch ( _dsetup.start_device_mode ) { case 1: // Device should've been set during configuration reading use_default = ctl_addr.isEmpty(); break; case 2: ctl_addr = _dsetup.start_user_device; use_default = false; break; default: break; } if ( use_default ) { ctl_addr = "default"; } } else { ctl_addr = _cmd_opts.start_ctl_address; } } // Slider painter bevelled { ::Wdg::Painter::DS_Slider_Painter_Bevelled * pnt ( new ::Wdg::Painter::DS_Slider_Painter_Bevelled ); pnt->set_wdg_style_db ( &_wdg_style_db ); _image_alloc.install_painter ( pnt ); } // Switch painter circle { ::Wdg::Painter::DS_Switch_Painter_Circle * pnt ( new ::Wdg::Painter::DS_Switch_Painter_Circle ); pnt->set_group_variant ( ::Wdg::DS_CIRCLE ); pnt->set_wdg_style_db ( &_wdg_style_db ); _image_alloc.install_painter ( pnt ); } // Switch painter close { ::Wdg::Painter::DS_Switch_Painter_Close * pnt ( new ::Wdg::Painter::DS_Switch_Painter_Close ); pnt->set_group_variant ( ::Wdg::DS_CLOSE ); pnt->set_wdg_style_db ( &_wdg_style_db ); _image_alloc.install_painter ( pnt ); } // Switch painter SVG { QScopedPointer < ::Wdg::Painter::DS_Switch_Painter_SVG > pnt ( new ::Wdg::Painter::DS_Switch_Painter_SVG ); pnt->set_group_variant ( ::Wdg::DS_SVG_JOINED ); pnt->set_wdg_style_db ( &_wdg_style_db ); pnt->set_base_dir ( INSTALL_DIR_WIDGETS_GRAPHICS ); pnt->set_file_prefix_bg ( "sw_joined_bg_" ); pnt->set_file_prefix_handle ( "sw_joined_handle_" ); if ( pnt->ready() ) { _image_alloc.install_painter ( pnt.take() ); } } if ( restore_session_n ) { // Restore minimized session if ( _dsetup.tray_is_minimized ) { _cmd_opts.start_tray_minimized = true; } } if ( _dsetup.tray_show_icon || ( _cmd_opts.start_tray_minimized && _dsetup.tray_on_close ) ) { tray_mixer_create(); } // Raise the main mixer only on demand if ( !( _cmd_opts.start_tray_minimized && tray_mixer_visible() ) ) { main_mixer_raise(); } } void Desktop_Items::main_mixer_create ( ) { if ( _main_mixer != 0 ) { return; } _main_mixer = new Main_Window; _main_mixer->installEventFilter ( this ); connect ( _main_mixer, SIGNAL ( sig_quit() ), this, SLOT ( quit() ), Qt::QueuedConnection ); connect ( _main_mixer, SIGNAL ( sig_control_changed() ), this, SLOT ( tray_mixer_reload_current_mdev() ), Qt::QueuedConnection ); connect ( _main_mixer, SIGNAL ( sig_show_settings() ), this, SLOT ( show_dialog_settings() ) ); connect ( _main_mixer, SIGNAL ( sig_show_info() ), this, SLOT ( show_dialog_info() ) ); _main_mixer->set_window_setup ( &_dsetup.main_window ); _main_mixer->show(); } void Desktop_Items::main_mixer_destroy ( ) { if ( _main_mixer != 0 ) { delete _main_mixer; _main_mixer = 0; //::std::cout << "Main mixer destroyed\n"; } } bool Desktop_Items::main_mixer_visible ( ) { bool res ( false ); if ( _main_mixer != 0 ) { res = !_main_mixer->isHidden(); } return res; } void Desktop_Items::main_mixer_close ( ) { if ( _main_mixer != 0 ) { _main_mixer->close(); } } void Desktop_Items::main_mixer_raise ( ) { if ( _main_mixer == 0 ) { main_mixer_create(); } _main_mixer->show(); if ( _main_mixer->isMinimized() ) { _main_mixer->showNormal(); } _main_mixer->raise(); _dsetup.tray_is_minimized = false; tray_mixer_update_visibility(); } void Desktop_Items::main_mixer_toggle_by_tray ( ) { bool raise_main ( true ); if ( _main_mixer != 0 ) { if ( _main_mixer->isActiveWindow() ) { raise_main = false; } } if ( raise_main ) { main_mixer_raise(); } else { if ( _dsetup.tray_show_icon || _dsetup.tray_on_close ) { if ( tray_mixer_visible() ) { _dsetup.tray_is_minimized = true; main_mixer_close(); } } } } void Desktop_Items::main_mixer_closed ( ) { // Destroy main mixer to be sure main_mixer_destroy(); tray_mixer_update_visibility(); if ( tray_mixer_visible() && _dsetup.tray_on_close ) { _dsetup.tray_is_minimized = true; } if ( !_dsetup.tray_is_minimized ) { quit(); } } void Desktop_Items::main_mixer_reload_view ( ) { if ( _main_mixer != 0 ) { _main_mixer->reload_mixer_view(); } } void Desktop_Items::tray_mixer_create ( ) { if ( _tray_mixer != 0 ) { return; } _tray_mixer = new Tray_Mixer ( this ); connect ( _tray_mixer, SIGNAL ( sig_toggle_mixer() ), this, SLOT ( main_mixer_toggle_by_tray() ) ); connect ( _tray_mixer, SIGNAL ( sig_quit() ), this, SLOT ( quit() ), Qt::QueuedConnection ); // Initialize setup tree values _dsetup.tray_view.wheel_degrees = _dsetup.main_window.inputs.wheel_degrees; _dsetup.tray_mdev.current_device = _dsetup.main_window.mixer_dev.ctl_addr; // Install setup tree _tray_mixer->set_mdev_setup ( &_dsetup.tray_mdev ); _tray_mixer->set_view_setup ( &_dsetup.tray_view ); } void Desktop_Items::tray_mixer_destroy ( ) { if ( _tray_mixer != 0 ) { delete _tray_mixer; _tray_mixer = 0; } } void Desktop_Items::tray_mixer_update_visibility ( ) { bool tray_vis ( false ); if ( !_shutdown ) { if ( _dsetup.tray_show_icon ) { tray_vis = true; } else if ( _dsetup.tray_on_close ) { tray_vis = !main_mixer_visible(); } } if ( tray_vis ) { tray_mixer_create(); } else { tray_mixer_destroy(); } } bool Desktop_Items::tray_mixer_visible ( ) { bool res ( false ); if ( _tray_mixer != 0 ) { res = _tray_mixer->is_visible(); } return res; } void Desktop_Items::tray_mixer_reload_mdev ( ) { if ( _tray_mixer != 0 ) { _tray_mixer->set_mdev_setup ( 0 ); _tray_mixer->set_mdev_setup ( &_dsetup.tray_mdev ); } } void Desktop_Items::tray_mixer_reload_current_mdev ( ) { const QString & ctl_main ( _dsetup.main_window.mixer_dev.ctl_addr ); if ( _dsetup.tray_mdev.current_device != ctl_main ) { _dsetup.tray_mdev.current_device = ctl_main; if ( _dsetup.tray_mdev.device_mode == ::Tray_Mixer_MDev_Setup::MIXER_DEV_CURRENT ) { tray_mixer_reload_mdev(); } } } void Desktop_Items::tray_mixer_update_balloon_setup ( ) { if ( _tray_mixer != 0 ) { _tray_mixer->update_balloon_setup(); } } void Desktop_Items::reload_inputs_setup ( ) { // Main mixer if ( _main_mixer != 0) { _main_mixer->reload_mixer_inputs(); } // Tray mixer _dsetup.tray_view.wheel_degrees = _dsetup.main_window.inputs.wheel_degrees; if ( _tray_mixer != 0 ) { _tray_mixer->update_balloon_setup(); } } void Desktop_Items::show_dialog_settings ( ) { if ( _main_mixer == 0 ) { return; } if ( _dialog_settings == 0 ) { ::Views::Settings_Dialog * dlg ( new ::Views::Settings_Dialog ( _main_mixer ) ); dlg->setAttribute ( Qt::WA_DeleteOnClose ); dlg->set_setup ( &_dsetup ); connect ( dlg, SIGNAL ( sig_change_mixer_view() ), this, SLOT ( main_mixer_reload_view() ) ); connect ( dlg, SIGNAL ( sig_change_input() ), this, SLOT ( reload_inputs_setup() ) ); connect ( dlg, SIGNAL ( sig_change_tray_view() ), this, SLOT ( tray_mixer_update_visibility() ) ); connect ( dlg, SIGNAL ( sig_change_tray_mdev() ), this, SLOT ( tray_mixer_reload_mdev() ) ); connect ( dlg, SIGNAL ( sig_change_tray_balloon() ), this, SLOT ( tray_mixer_update_balloon_setup() ) ); _dialog_settings = dlg; } _dialog_settings->show(); } void Desktop_Items::show_dialog_info ( ) { if ( _main_mixer == 0 ) { return; } if ( _dialog_info == 0 ) { ::Views::Info_Dialog * dlg ( new ::Views::Info_Dialog ( _main_mixer ) ); dlg->setAttribute ( Qt::WA_DeleteOnClose ); _dialog_info = dlg; } _dialog_info->show(); } void Desktop_Items::shutdown ( ) { if ( !_shutdown ) { _shutdown = true; main_mixer_close(); main_mixer_destroy(); tray_mixer_destroy(); } } void Desktop_Items::quit ( ) { shutdown(); emit sig_quit(); } bool Desktop_Items::event ( QEvent * event_n ) { bool res ( false ); if ( event_n->type() == _evt_mixer_closed ) { main_mixer_closed(); res = true; } else { res = QObject::event ( event_n ); } return res; } bool Desktop_Items::eventFilter ( QObject * obj_n, QEvent * event_n ) { bool filtered ( false ); if ( obj_n == _main_mixer ) { if ( event_n->type() == QEvent::Close ) { //::std::cout << "Close event catched\n"; _main_mixer->save_state(); if ( !_shutdown ) { QEvent * ev_req ( new QEvent ( QEvent::Type ( _evt_mixer_closed ) ) ); QCoreApplication::postEvent ( this, ev_req ); } } } return filtered; } qastools-v0.22.0/qasmixer/src/desktop_items.hpp000066400000000000000000000072361354534512100216440ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_desktop_items_hpp__ #define __INC_desktop_items_hpp__ #include "cmd_options.hpp" #include "desktop_items_setup.hpp" #include "dpe/image_allocator.hpp" #include "mwdg/mixer_style.hpp" #include #include #include // Forward declaration class Tray_Mixer; class Main_Window; class Dialog_Settings; /// @brief Manages all items that appear on the desktop /// /// The managed window items are /// - Main_Mixer /// - Tray_Mixer ( with tray icon ) /// /// All settings are always present in the setup tree. /// The setup tree gets initialized in the constructor /// and on calling init_settings(). /// On destruction it gets written to the storage (disk). class Desktop_Items : public QObject { Q_OBJECT // Public methods public: Desktop_Items ( QObject * parent_n = 0 ); ~Desktop_Items ( ); /// @brief Options that came from the command line or a second instance /// const CMD_Options & cmd_opts ( ) const; /// @brief Reads options from storage and command line /// /// @return A negative value on an error int init_settings ( int argc, char * argv[] ); /// @brief Message to be sent to an other instance /// /// @return The message QString message_to_other_instance ( ) const; /// @brief Start the mixer window and/or tray icon /// void start ( bool restore_session_n = false ); // Event handling bool event ( QEvent * event_n ); bool eventFilter ( QObject * obj_n, QEvent * event_n ); // Signals signals: void sig_quit ( ); // Public slots public slots: /// @brief Reads messages from other instances /// void parse_message ( QString msg_n ); // Main mixer minimize / raise void main_mixer_raise ( ); void main_mixer_close ( ); void main_mixer_toggle_by_tray ( ); // Dialogs void show_dialog_info ( ); void show_dialog_settings ( ); /// @brief Closes and destroy all widgets void shutdown ( ); /// @brief Shuts down and emits sig_quit() void quit ( ); // Protected slots protected slots: void main_mixer_reload_view ( ); /// @brief Lets widgets reload the inputs setup from the setup tree /// void reload_inputs_setup(); /// @return true if the tray icon is visible /// void tray_mixer_update_visibility ( ); void tray_mixer_reload_mdev ( ); void tray_mixer_reload_current_mdev ( ); void tray_mixer_update_balloon_setup ( ); // Private methods private: /// @brief Creates a new main mixer window /// void main_mixer_create ( ); /// @brief Destroys the main mixer window /// void main_mixer_destroy ( ); /// @brief True if the main mixer exists and is visible /// bool main_mixer_visible ( ); /// @brief Will be called shortly after the mixer window was closed /// void main_mixer_closed ( ); /// @brief Creates a tray mixer instance /// void tray_mixer_create ( ); void tray_mixer_destroy ( ); bool tray_mixer_visible ( ); /// @brief Command line option parser /// /// @return A negative value on an error int parse_cmd_options ( int argc, char * argv[] ); // Private attributes private: Desktop_Items_Setup _dsetup; QPointer < Tray_Mixer > _tray_mixer; QPointer < Main_Window > _main_mixer; // Shared storages and settings ::MWdg::Mixer_Style _mixer_style; ::Wdg::DS_Widget_Style_Db _wdg_style_db; ::dpe::Image_Allocator _image_alloc; // Dialogs QPointer < QDialog > _dialog_settings; QPointer < QDialog > _dialog_info; CMD_Options _cmd_opts; int _evt_mixer_closed; bool _started; bool _shutdown; }; inline const CMD_Options & Desktop_Items::cmd_opts ( ) const { return _cmd_opts; } #endif qastools-v0.22.0/qasmixer/src/desktop_items_setup.cpp000066400000000000000000000140121354534512100230450ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "desktop_items_setup.hpp" #include #include Desktop_Items_Setup::Desktop_Items_Setup ( ) : start_device_mode ( ::Desktop_Items_Setup::MIXER_DEV_DEFAULT ), start_user_device ( "hw:0" ), tray_on_close ( true ), tray_show_icon ( true ), tray_is_minimized ( false ) { } void Desktop_Items_Setup::read_from_storage ( ) { Main_Window_Setup & mwin ( main_window ); QSettings settings; start_device_mode = settings.value ( "start_device_mode", start_device_mode ).toUInt(); start_user_device = settings.value ( "start_user_device", start_user_device ).toString(); mwin.mixer_dev.ctl_addr = settings.value ( "current_device", mwin.mixer_dev.ctl_addr ).toString(); mwin.inputs.wheel_degrees = settings.value ( "wheel_degrees", mwin.inputs.wheel_degrees ).toUInt(); tray_on_close = settings.value ( "tray_on_close", tray_on_close ).toBool(); tray_show_icon = settings.value ( "tray_show_icon", tray_show_icon ).toBool(); tray_is_minimized = settings.value ( "tray_is_minimized", tray_is_minimized ).toBool(); // Main window state { settings.beginGroup ( "main_window" ); mwin.window_state = settings.value ( "window_state", mwin.window_state ).toByteArray(); mwin.window_geometry = settings.value ( "window_geometry", mwin.window_geometry ).toByteArray(); mwin.splitter_state = settings.value ( "splitter_state", mwin.splitter_state ).toByteArray(); mwin.show_dev_select = settings.value ( "show_device_selection", mwin.show_dev_select ).toBool(); settings.endGroup(); } // Device selection { ::Views::Device_Selection_View_Setup & vsetup ( main_window.dev_select ); settings.beginGroup ( "device_selection" ); vsetup.selection_db_set ( settings.value ( "selection_db", vsetup.selection_db_get() ).toStringList() ); settings.endGroup(); } // Simple mixer { ::Views::Mixer_Simple_Setup & vsetup ( main_window.mixer_simple ); settings.beginGroup ( "simple_mixer" ); vsetup.show_stream[0] = settings.value ( "show_stream_playback", vsetup.show_stream[0] ).toBool(); vsetup.show_stream[1] = settings.value ( "show_stream_capture", vsetup.show_stream[1] ).toBool(); vsetup.show_slider_value_labels = settings.value ( "show_slider_value_labels", vsetup.show_slider_value_labels ).toBool(); settings.endGroup(); } // Tray mixer { settings.beginGroup ( "tray_mixer" ); Tray_Mixer_MDev_Setup & dsetup ( tray_mdev ); dsetup.device_mode = settings.value ( "device_mode", dsetup.device_mode ).toInt(); dsetup.user_device = settings.value ( "user_device", dsetup.user_device ).toString(); Tray_Mixer_View_Setup & vsetup ( tray_view ); vsetup.show_balloon = settings.value ( "show_balloon", vsetup.show_balloon ).toBool(); vsetup.balloon_lifetime = settings.value ( "balloon_lifetime", vsetup.balloon_lifetime ).toUInt(); settings.endGroup(); } // Settings view { settings.beginGroup ( "settings_dialog" ); settings_dialog.page = settings.value ( "page", settings_dialog.page ).toUInt(); settings.endGroup(); } // Sanitize values if ( main_window.inputs.wheel_degrees == 0 ) { main_window.inputs.wheel_degrees = 720; } tray_view.wheel_degrees = main_window.inputs.wheel_degrees; if ( start_device_mode > ::Desktop_Items_Setup::MIXER_DEV_LAST ) { start_device_mode = ::Desktop_Items_Setup::MIXER_DEV_DEFAULT; } if ( tray_mdev.device_mode > ::Tray_Mixer_MDev_Setup::MIXER_DEV_LAST ) { tray_mdev.device_mode = ::Tray_Mixer_MDev_Setup::MIXER_DEV_DEFAULT; } { ::Views::Mixer_Simple_Setup & vsetup ( main_window.mixer_simple ); if ( !( vsetup.show_stream[0] || vsetup.show_stream[1] ) ) { vsetup.show_stream[0] = true; } } } void Desktop_Items_Setup::write_to_storage ( ) { //::std::cout << "Desktop_Items_Setup::write_to_storage" << "\n"; QSettings settings; // General settings.setValue ( "start_device_mode", start_device_mode ); settings.setValue ( "start_user_device", start_user_device ); settings.setValue ( "current_device", main_window.mixer_dev.ctl_addr ); settings.setValue ( "wheel_degrees", main_window.inputs.wheel_degrees ); settings.setValue ( "tray_on_close", tray_on_close ); settings.setValue ( "tray_show_icon", tray_show_icon ); settings.setValue ( "tray_is_minimized", tray_is_minimized ); // Main window state { settings.beginGroup ( "main_window" ); settings.setValue ( "window_state", main_window.window_state ); settings.setValue ( "window_geometry", main_window.window_geometry ); settings.setValue ( "splitter_state", main_window.splitter_state ); settings.setValue ( "show_device_selection", main_window.show_dev_select ); settings.endGroup(); } // Device selection { const ::Views::Device_Selection_View_Setup & vsetup ( main_window.dev_select ); settings.beginGroup ( "device_selection" ); settings.setValue ( "selection_db", vsetup.selection_db_get() ); settings.endGroup(); } // Simple mixer { const ::Views::Mixer_Simple_Setup & vsetup ( main_window.mixer_simple ); settings.beginGroup ( "simple_mixer" ); settings.setValue ( "show_stream_playback", vsetup.show_stream[0] ); settings.setValue ( "show_stream_capture", vsetup.show_stream[1] ); settings.setValue ( "show_slider_value_labels", vsetup.show_slider_value_labels ); settings.endGroup(); } // Mini mixer { settings.beginGroup ( "tray_mixer" ); const Tray_Mixer_MDev_Setup & dsetup ( tray_mdev ); settings.setValue ( "device_mode", dsetup.device_mode ); settings.setValue ( "user_device", dsetup.user_device ); const Tray_Mixer_View_Setup & vsetup ( tray_view ); settings.setValue ( "show_balloon", vsetup.show_balloon ); settings.setValue ( "balloon_lifetime", vsetup.balloon_lifetime ); settings.endGroup(); } // Settings view { settings.beginGroup ( "settings_dialog" ); settings.setValue ( "page", settings_dialog.page ); settings.endGroup(); } } qastools-v0.22.0/qasmixer/src/desktop_items_setup.hpp000066400000000000000000000022201354534512100230500ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_desktop_items_setup_hpp__ #define __INC_desktop_items_setup_hpp__ #include "views/device_selection_view.hpp" #include "views/settings_dialog_setup.hpp" #include "tray_mixer_mdev_setup.hpp" #include "tray_mixer_view_setup.hpp" #include "main_window_setup.hpp" #include /// @brief Desktop_Items_Setup /// class Desktop_Items_Setup { // Public typedefs public: enum Mixer_Device { MIXER_DEV_DEFAULT = 0, MIXER_DEV_PREVIOUS = 1, MIXER_DEV_USER = 2, MIXER_DEV_LAST = MIXER_DEV_USER }; // Public methods public: Desktop_Items_Setup ( ); void read_from_storage ( ); void write_to_storage ( ); // Public attributes public: // Device to load on startup unsigned int start_device_mode; QString start_user_device; ::Tray_Mixer_MDev_Setup tray_mdev; ::Tray_Mixer_View_Setup tray_view; ::Main_Window_Setup main_window; ::Views::Device_Selection_View_Setup device_selection_view; ::Views::Settings_Dialog_Setup settings_dialog; bool tray_on_close; bool tray_show_icon; bool tray_is_minimized; }; #endif qastools-v0.22.0/qasmixer/src/info_texts.cpp000066400000000000000000000010201354534512100211300ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "info_texts.hpp" const char info_text_options[] = "\ Options:\n\ -h, --help prints this help\n\ -c, --card=NUMBER selects a card\n\ -D, --device=NAME selects a mixer device (e.g. hw:1)\n\ \n\ -t, --tray start minimized in tray\n\ -n, --no-single allow multiple instances\n\ \n\ -i, --copying prints copying information\n\ -v, --version prints the program version\n\ "; qastools-v0.22.0/qasmixer/src/info_texts.hpp000066400000000000000000000003551354534512100211470ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_info_texts_hpp__ #define __INC_info_texts_hpp__ #include "license_texts.hpp" extern const char info_text_options[]; #endif qastools-v0.22.0/qasmixer/src/init_globals.cpp000066400000000000000000000005321354534512100214230ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "init_globals.hpp" #include "qsnd/event_types.hpp" #include "wdg/event_types.hpp" #include "mwdg/event_types.hpp" int init_globals ( ) { ::QSnd::init_event_types(); ::Wdg::init_event_types(); ::MWdg::init_event_types(); return 0; } qastools-v0.22.0/qasmixer/src/init_globals.hpp000066400000000000000000000004011354534512100214230ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_init_globals_hpp__ #define __INC_init_globals_hpp__ /// @brief Initializes program wide used variables one time int init_globals ( ); #endif qastools-v0.22.0/qasmixer/src/main.cpp000066400000000000000000000035541354534512100177100ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "qastools_config.hpp" #include "init_globals.hpp" #include "single_application.hpp" #include "desktop_items.hpp" #include "views/view_utility.hpp" #include #include #include #include #include #include #include /// @brief The main function /// int main ( int argc, char * argv[] ) { init_globals(); // Qt Application Single_Application app ( argc, argv ); app.setOrganizationName ( QString ( PACKAGE_NAME ).toLower() ); app.setApplicationName ( QString ( PROGRAM_NAME ).toLower() ); app.setQuitOnLastWindowClosed ( false ); app.setAttribute ( Qt::AA_DontShowIconsInMenus, false ); Desktop_Items ditems; // Parse remaining command line options { const int res ( ditems.init_settings ( argc, argv ) ); if ( res < 0 ) { return res; } } // If an other instance is running send a message to it and quit if ( ditems.cmd_opts().start_single_instance ) { app.set_unique_key ( SINGLE_APPLICATION_KEY ); if ( app.is_running() ) { if ( app.send_message ( ditems.message_to_other_instance() ) ) { return 0; } } } // Connect single instance signals with desktop item manager { QObject::connect ( &app, SIGNAL ( sig_message_available ( QString ) ), &ditems, SLOT ( parse_message ( QString ) ) ); QObject::connect ( &app, SIGNAL ( commitDataRequest ( QSessionManager & ) ), &ditems, SLOT ( shutdown() ) ); QObject::connect ( &ditems, SIGNAL ( sig_quit() ), &app, SLOT ( quit() ), Qt::QueuedConnection ); } // Load application icon, translators ::Views::load_application_icon ( &app, "multimedia-volume-control" ); ::Views::load_translators ( &app ); // Start and restore session (on demand) ditems.start ( app.isSessionRestored() ); return app.exec(); } qastools-v0.22.0/qasmixer/src/main_window.cpp000066400000000000000000000206731354534512100213000ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "main_window.hpp" #include "views/mixer_simple.hpp" #include "views/device_selection_view.hpp" #include "views/view_utility.hpp" #include #include #include #include #include #include #include #include Main_Window::Main_Window ( QWidget * parent_n, Qt::WindowFlags flags_n ) : QMainWindow ( parent_n, flags_n ), _win_setup ( 0 ), _mixer_simple ( 0 ), _dev_select ( 0 ) { setWindowTitle ( PROGRAM_TITLE ); setObjectName ( PROGRAM_TITLE ); setContextMenuPolicy ( Qt::NoContextMenu ); _str_fscreen_enable = tr ( "&Fullscreen mode" ); _str_fscreen_disable = tr ( "Exit &fullscreen mode" ); _icon_fscreen_enable = QIcon::fromTheme ( "view-fullscreen" ); _icon_fscreen_disable = QIcon::fromTheme ( "view-restore" ); // Init menus init_menus(); init_widgets(); update_fullscreen_action(); } Main_Window::~Main_Window ( ) { } void Main_Window::init_menus ( ) { // Action: Exit / Quit QAction * act_quit = new QAction ( tr ( "&Quit" ), this ); act_quit->setShortcut ( QKeySequence ( QKeySequence::Quit ) ); act_quit->setIcon ( QIcon::fromTheme ( "application-exit" ) ); // Action: Settings QAction * act_settings = new QAction ( tr ( "&Settings" ), this ); act_settings->setShortcut ( QKeySequence ( tr ( "Ctrl+s" ) ) ); act_settings->setIcon ( QIcon::fromTheme ( "preferences-desktop" ) ); // Action: Refresh QAction * act_refresh = new QAction ( tr ( "&Refresh" ), this ); act_refresh->setShortcut ( QKeySequence ( QKeySequence::Refresh ) ); act_refresh->setIcon ( QIcon::fromTheme ( "view-refresh" ) ); // Action: Device selection _act_show_dev_select = new QAction ( this ); _act_show_dev_select->setText ( tr ( "Show &device selection" ) ); _act_show_dev_select->setCheckable ( true ); // Action: Fullscreen _act_fullscreen = new QAction ( this ); _act_fullscreen->setShortcut ( QKeySequence ( Qt::Key_F11 ) ); _act_fullscreen->setCheckable ( true ); // Action: Info QAction * act_info = new QAction ( tr ( "&Info" ), this ); act_info->setShortcut ( QKeySequence ( QKeySequence::HelpContents ) ); act_info->setIcon ( QIcon::fromTheme ( "help-about" ) ); // Menus { QMenu * cmenu = menuBar()->addMenu ( tr ( "&File" ) ); cmenu->addAction ( act_settings ); cmenu->addSeparator(); cmenu->addAction ( act_quit ); } { QMenu * cmenu = menuBar()->addMenu ( tr ( "&View" ) ); cmenu->addAction ( _act_show_dev_select ); cmenu->addAction ( _act_fullscreen ); cmenu->addSeparator(); cmenu->addAction ( act_refresh ); } { QMenu * cmenu = menuBar()->addMenu ( tr ( "&Help" ) ); cmenu->addAction ( act_info ); } // Connect actions connect ( act_quit, SIGNAL ( triggered() ), this, SIGNAL ( sig_quit() ) ); // View actions connect ( _act_show_dev_select, SIGNAL ( toggled ( bool ) ), this, SLOT ( show_device_selection ( bool ) ) ); connect ( act_refresh, SIGNAL ( triggered() ), this, SLOT ( refresh_views() ) ); connect ( _act_fullscreen, SIGNAL ( toggled ( bool ) ), this, SLOT ( set_fullscreen ( bool ) ) ); // Info action connect ( act_settings, SIGNAL ( triggered() ), this, SIGNAL ( sig_show_settings() ) ); connect ( act_info, SIGNAL ( triggered() ), this, SIGNAL ( sig_show_info() ) ); } void Main_Window::init_widgets ( ) { // Device selection { _dev_select = new ::Views::Device_Selection_View; _dev_select->hide(); // QueuedConnection to update the GUI before loading the mixer connect ( _dev_select, SIGNAL ( sig_control_selected() ), this, SLOT ( select_ctl_from_side_iface() ), Qt::QueuedConnection ); connect ( _dev_select, SIGNAL ( sig_control_reload() ), this, SLOT ( reload_mixer_device() ), Qt::QueuedConnection ); connect ( _dev_select, SIGNAL ( sig_close() ), this, SLOT ( toggle_device_selection() ) ); } // Central mixer { _mixer_simple = new ::Views::Mixer_Simple; } // Central splitter { _splitter.reset ( new QSplitter ); _splitter->addWidget ( _mixer_simple ); _splitter->addWidget ( _dev_select ); _splitter->setStretchFactor ( 0, 1 ); _splitter->setStretchFactor ( 1, 0 ); _splitter->setCollapsible ( 0, false ); _splitter->setCollapsible ( 1, false ); setCentralWidget ( _splitter.data() ); } } QSize Main_Window::sizeHint ( ) const { QSize res ( QMainWindow::sizeHint() ); ::Views::win_default_size ( res ); return res; } void Main_Window::set_window_setup ( Main_Window_Setup * setup_n ) { if ( _win_setup != 0 ) { _mixer_simple->set_mdev_setup ( 0 ); _mixer_simple->set_inputs_setup ( 0 ); _mixer_simple->set_view_setup ( 0 ); _dev_select->set_view_setup ( 0 ); } _win_setup = setup_n; if ( _win_setup != 0 ) { // Restore mixer window state restoreState ( _win_setup->window_state ); if ( !restoreGeometry ( _win_setup->window_geometry ) ) { ::Views::resize_to_default ( this ); } _splitter->restoreState ( _win_setup->splitter_state ); // Actions _act_show_dev_select->setShortcut ( _win_setup->dev_select.kseq_toggle_vis ); _act_show_dev_select->setChecked ( _win_setup->show_dev_select ); // Pass setup tree to child classes _dev_select->set_view_setup ( &_win_setup->dev_select ); _dev_select->silent_select_ctl ( _win_setup->mixer_dev.ctl_addr ); _mixer_simple->set_view_setup ( &_win_setup->mixer_simple ); _mixer_simple->set_inputs_setup ( &_win_setup->inputs ); _mixer_simple->set_mdev_setup ( &_win_setup->mixer_dev ); } } void Main_Window::update_fullscreen_action ( ) { QString * txt; QIcon * icon; bool checked; if ( isFullScreen() ) { txt = &_str_fscreen_disable; icon = &_icon_fscreen_disable; checked = true; } else { txt = &_str_fscreen_enable; icon = &_icon_fscreen_enable; checked = false; } _act_fullscreen->setText ( *txt ); _act_fullscreen->setIcon ( *icon ); _act_fullscreen->setChecked ( checked ); } void Main_Window::select_ctl ( const QString & ctl_n ) { //::std::cout << "Main_Window::select_ctl " << ctl_n.toLocal8Bit().data() << "\n"; _dev_select->silent_select_ctl ( ctl_n ); if ( _win_setup != 0 ) { if ( _win_setup->mixer_dev.ctl_addr != ctl_n ) { // Remove _mixer_simple->set_mdev_setup ( 0 ); // Change _win_setup->mixer_dev.ctl_addr = ctl_n; // Reinstall _mixer_simple->set_mdev_setup ( &_win_setup->mixer_dev ); } } emit sig_control_changed(); } void Main_Window::select_ctl_from_side_iface ( ) { //::std::cout << "Main_Window::select_ctl_from_side_iface " << "\n"; select_ctl ( _dev_select->selected_ctl().addr_str() ); emit sig_control_changed(); } void Main_Window::reload_mixer_device ( ) { //::std::cout << "Main_Window::reload_mixer_device" << "\n"; _mixer_simple->set_mdev_setup ( 0 ); _mixer_simple->set_mdev_setup ( &_win_setup->mixer_dev ); } void Main_Window::reload_mixer_inputs ( ) { //::std::cout << "Main_Window::reload_mixer_inputs" << "\n"; _mixer_simple->set_inputs_setup ( 0 ); _mixer_simple->set_inputs_setup ( &_win_setup->inputs ); } void Main_Window::refresh_views ( ) { _dev_select->reload_database(); reload_mixer_device(); } void Main_Window::reload_mixer_view ( ) { //::std::cout << "Main_Window::reload_mixer_view" << "\n"; _mixer_simple->set_view_setup ( 0 ); _mixer_simple->set_view_setup ( &_win_setup->mixer_simple ); } void Main_Window::set_fullscreen ( bool flag_n ) { if ( flag_n != isFullScreen() ) { if ( flag_n ) { showFullScreen(); } else { showNormal(); } update_fullscreen_action(); } } void Main_Window::show_device_selection ( bool flag_n ) { if ( _win_setup != 0 ) { if ( _win_setup->show_dev_select != flag_n ) { _win_setup->show_dev_select = flag_n; } } _dev_select->setVisible ( flag_n ); } void Main_Window::toggle_device_selection ( ) { _act_show_dev_select->setChecked ( !_act_show_dev_select->isChecked() ); } void Main_Window::save_state ( ) { if ( _win_setup != 0 ) { _win_setup->window_state = saveState(); _win_setup->window_geometry = saveGeometry(); _win_setup->splitter_state = _splitter->saveState(); } } void Main_Window::changeEvent ( QEvent * event_n ) { QMainWindow::changeEvent ( event_n ); if ( event_n->type() == QEvent::WindowStateChange ) { update_fullscreen_action(); } } void Main_Window::keyPressEvent ( QKeyEvent * event_n ) { QMainWindow::keyPressEvent ( event_n ); if ( _win_setup != 0 ) { const QKeySequence kseq ( event_n->key() ); if ( kseq == _win_setup->dev_select.kseq_toggle_vis ) { toggle_device_selection(); } } } qastools-v0.22.0/qasmixer/src/main_window.hpp000066400000000000000000000040461354534512100213010ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_main_window_hpp__ #define __INC_main_window_hpp__ #include "qastools_config.hpp" #include "main_window_setup.hpp" #include #include #include #include #include // Forward declaration namespace Views { class Mixer_Simple; class Device_Selection_View; } class Main_Window : public QMainWindow { Q_OBJECT // Public methods public: Main_Window ( QWidget * parent_n = 0, Qt::WindowFlags flags_n = 0 ); ~Main_Window ( ); QSize sizeHint ( ) const; void set_window_setup ( Main_Window_Setup * setup_n ); void select_ctl ( const QString & ctl_n ); // Signals signals: void sig_show_settings ( ); void sig_show_info ( ); void sig_control_changed ( ); void sig_quit ( ); // Public slots public slots: // Snd control selection void select_ctl_from_side_iface ( ); void reload_mixer_device ( ); void reload_mixer_inputs ( ); void reload_mixer_view ( ); void refresh_views ( ); /// @brief Sets/unsets fullscreen mode /// void set_fullscreen ( bool flag_n ); // Device selection void show_device_selection ( bool flag_n ); void toggle_device_selection ( ); /// @brief Save state to the setup tree /// void save_state ( ); // Protected methods protected: void update_fullscreen_action ( ); // Event handlers void changeEvent ( QEvent * event_n ); void keyPressEvent ( QKeyEvent * event_n ); void init_menus ( ); void init_widgets ( ); // Private attributes private: Main_Window_Setup * _win_setup; // Base widgets QScopedPointer < QSplitter > _splitter; ::Views::Mixer_Simple * _mixer_simple; ::Views::Device_Selection_View * _dev_select; // Menubar QMenu * _menu_mixer; QAction * _act_show_dev_select; QAction * _act_fullscreen; // Strings and icons QString _str_fscreen_enable; QString _str_fscreen_disable; QIcon _icon_fscreen_enable; QIcon _icon_fscreen_disable; }; #endif qastools-v0.22.0/qasmixer/src/main_window_setup.cpp000066400000000000000000000003151354534512100225070ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "main_window_setup.hpp" Main_Window_Setup::Main_Window_Setup ( ) : show_dev_select ( false ) { } qastools-v0.22.0/qasmixer/src/main_window_setup.hpp000066400000000000000000000014531354534512100225200ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_main_window_setup_hpp__ #define __INC_main_window_setup_hpp__ #include "mwdg/mixer_device_setup.hpp" #include "mwdg/inputs_setup.hpp" #include "views/mixer_simple_setup.hpp" #include "views/device_selection_view_setup.hpp" #include #include /// @brief Main_Window_Setup /// class Main_Window_Setup { // Public methods public: Main_Window_Setup ( ); // Public attributes public: bool show_dev_select; QByteArray window_state; QByteArray window_geometry; QByteArray splitter_state; ::MWdg::Mixer_Device_Setup mixer_dev; ::MWdg::Inputs_Setup inputs; ::Views::Mixer_Simple_Setup mixer_simple; ::Views::Device_Selection_View_Setup dev_select; }; #endif qastools-v0.22.0/qasmixer/src/mwdg/000077500000000000000000000000001354534512100172075ustar00rootroot00000000000000qastools-v0.22.0/qasmixer/src/mwdg/mixer_gui_state.cpp000066400000000000000000000005561354534512100231110ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "mixer_gui_state.hpp" namespace MWdg { Mixer_GUI_State_Proxy::Mixer_GUI_State_Proxy ( ) { clear(); } void Mixer_GUI_State_Proxy::clear ( ) { group_name.clear(); snd_dir = 0; column_idx = 0; row_idx = 0; has_focus = false; } } // End of namespace qastools-v0.22.0/qasmixer/src/mwdg/mixer_gui_state.hpp000066400000000000000000000012231354534512100231060ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_mixer_gui_state_hpp__ #define __INC_mixer_gui_state_hpp__ #include namespace MWdg { /// @brief Identifies a proxy element /// class Mixer_GUI_State_Proxy { // Public methods public: Mixer_GUI_State_Proxy ( ); void clear ( ); bool is_clear ( ) const; // Public attributes public: QString group_name; unsigned char snd_dir; unsigned char column_idx; unsigned char row_idx; bool has_focus; }; inline bool Mixer_GUI_State_Proxy::is_clear ( ) const { return group_name.isEmpty(); } } // End of namespace #endif qastools-v0.22.0/qasmixer/src/mwdg/mixer_separation_info.cpp000066400000000000000000000004231354534512100242760ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "mixer_separation_info.hpp" namespace MWdg { Mixer_Separation_Info::Mixer_Separation_Info ( ) : _requested ( false ), _do_it ( false ) { } } // End of namespace qastools-v0.22.0/qasmixer/src/mwdg/mixer_separation_info.hpp000066400000000000000000000022661354534512100243120ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_mixer_separation_info_hpp__ #define __INC_mixer_separation_info_hpp__ #include namespace MWdg { /// /// @brief Mixer_Separation_Info /// class Mixer_Separation_Info { // Public methods public: Mixer_Separation_Info ( ); // Separation bool requested ( ) const; void set_requested ( bool flag_n ); bool do_it ( ) const; void set_do_it ( bool flag_n ); const QTime & time ( ) const; void set_time ( const QTime & time_n ); // Private attributes private: QTime _time; bool _requested; bool _do_it; }; inline bool Mixer_Separation_Info::requested ( ) const { return _requested; } inline void Mixer_Separation_Info::set_requested ( bool flag_n ) { _requested = flag_n; } inline bool Mixer_Separation_Info::do_it ( ) const { return _do_it; } inline void Mixer_Separation_Info::set_do_it ( bool flag_n ) { _do_it = flag_n; } inline const QTime & Mixer_Separation_Info::time ( ) const { return _time; } inline void Mixer_Separation_Info::set_time ( const QTime & time_n ) { _time = time_n; } } // End of namespace #endif qastools-v0.22.0/qasmixer/src/mwdg/mixer_simple_setup.cpp000066400000000000000000000005531354534512100236330ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "mixer_simple_setup.hpp" namespace MWdg { Mixer_Simple_Setup::Mixer_Simple_Setup ( ) { show_slider_value_labels = true; show_stream[0] = true; show_stream[1] = false; mixer_simple = 0; wdg_style_db = 0; image_alloc = 0; } } // End of namespace qastools-v0.22.0/qasmixer/src/mwdg/mixer_simple_setup.hpp000066400000000000000000000013221354534512100236330ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_mwdg_mixer_simple_setup_hpp__ #define __INC_mwdg_mixer_simple_setup_hpp__ // Forward declaration namespace QSnd { class Mixer_Simple; } namespace dpe { class Image_Allocator; } namespace Wdg { class DS_Widget_Style_Db; } namespace MWdg { /// @brief Mixer_Simple_Setup /// class Mixer_Simple_Setup { // Public methods public: Mixer_Simple_Setup ( ); // Public attributes public: bool show_slider_value_labels; bool show_stream[2]; ::QSnd::Mixer_Simple * mixer_simple; const ::Wdg::DS_Widget_Style_Db * wdg_style_db; ::dpe::Image_Allocator * image_alloc; }; } // End of namespace #endif qastools-v0.22.0/qasmixer/src/mwdg/mixer_sliders.cpp000066400000000000000000000501401354534512100225640ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "mixer_sliders.hpp" #include "wdg/pass_events.hpp" #include "wdg/scroll_area_horizontal.hpp" #include "wdg/pad_proxy_style.hpp" #include "wdg/sliders_pad.hpp" #include "mwdg/inputs_setup.hpp" #include "mwdg/mixer_simple_setup.hpp" #include "mwdg/event_types.hpp" #include "mwdg/mixer_style.hpp" #include "mwdg/mixer_gui_state.hpp" #include "mwdg/mixer_sliders_proxies_group.hpp" #include "qsnd/mixer_simple.hpp" #include #include #include #include #include #include #include namespace MWdg { Mixer_Sliders::Mixer_Sliders ( QWidget * parent_n ) : QWidget ( parent_n ), _mixer_setup ( 0 ), _separation_requested ( false ), _act_proxies_column ( 0 ), _cmenu ( this ), _act_toggle_joined ( this ), _act_level_channels ( this ), _act_separator_channels ( this ), _act_toggle_mute ( this ) { // Sliders pad _sliders_pad = new ::Wdg::Sliders_Pad; connect ( _sliders_pad, SIGNAL ( sig_focus_changed() ), this, SLOT ( update_focus_proxies() ) ); connect ( _sliders_pad, SIGNAL ( sig_footer_label_selected ( unsigned int, unsigned int ) ), this, SIGNAL ( sig_footer_label_selected ( unsigned int, unsigned int ) ) ); _sliders_pad->installEventFilter ( this ); // Sliders area _sliders_area = new ::Wdg::Scroll_Area_Horizontal; _sliders_area->setFrameStyle ( QFrame::NoFrame ); _sliders_area->set_widget ( _sliders_pad ); // Actions _act_toggle_joined.setIcon ( QIcon::fromTheme ( "object-flip-horizontal" ) ); _act_level_channels.setIcon ( QIcon::fromTheme ( "object-flip-vertical" ) ); _act_separator_channels.setSeparator ( true ); _act_str_mute[0] = tr ( "&Mute" ); _act_str_mute[1] = tr ( "&Mute all" ); _act_str_unmute[0] = tr ( "Un&mute" ); _act_str_unmute[1] = tr ( "Un&mute all" ); _act_str_toggle_mute = tr ( "Toggle &mutes" ); _icon_vol_high = QIcon::fromTheme ( "audio-volume-high" ); _icon_vol_med = QIcon::fromTheme ( "audio-volume-medium" ); _icon_muted = QIcon::fromTheme ( "audio-volume-muted" ); connect ( &_act_toggle_joined, SIGNAL ( triggered ( bool ) ), this, SLOT ( action_toggle_joined() ) ); connect ( &_act_level_channels, SIGNAL ( triggered ( bool ) ), this, SLOT ( action_level_volumes() ) ); connect ( &_act_toggle_mute, SIGNAL ( triggered ( bool ) ), this, SLOT ( action_toggle_mute() ) ); // Context menu _cmenu.addAction ( &_act_toggle_joined ); _cmenu.addAction ( &_act_level_channels ); _cmenu.addAction ( &_act_separator_channels ); _cmenu.addAction ( &_act_toggle_mute ); connect ( &_cmenu, SIGNAL ( aboutToHide() ), this, SLOT ( context_menu_cleanup_behind() ) ); // Proxies vars _ttip_slider[0] = tr ( "Playback slider" ); _ttip_slider[1] = tr ( "Capture slider" ); _ttip_switch[0] = tr ( "Playback switch" ); _ttip_switch[1] = tr ( "Capture switch" ); // Layout QVBoxLayout * lay_vbox ( new QVBoxLayout() ); lay_vbox->addWidget ( _sliders_area, 1 ); setLayout ( lay_vbox ); // Adjust margins and spacings { int space ( qMax ( fontMetrics().height(), lay_vbox->spacing() ) ); lay_vbox->setSpacing ( space ); } } Mixer_Sliders::~Mixer_Sliders ( ) { set_mixer_setup ( 0 ); delete _sliders_pad; } void Mixer_Sliders::set_mixer_setup ( const ::MWdg::Mixer_Simple_Setup * setup_n ) { _cmenu.close(); if ( mixer_setup() != 0 ) { if ( mixer_setup()->mixer_simple != 0 ) { disconnect ( mixer_setup()->mixer_simple, 0, this, 0 ); show_visible_proxies_sets ( false ); clear_proxies_groups(); _sliders_pad->set_wdg_style_db ( 0 ); _sliders_pad->set_image_alloc ( 0 ); _sliders_pad->set_footer_visible ( 0 ); } } _mixer_setup = setup_n; if ( mixer_setup() != 0 ) { if ( mixer_setup()->mixer_simple != 0 ) { _sliders_pad->set_wdg_style_db ( mixer_setup()->wdg_style_db ); _sliders_pad->set_image_alloc ( mixer_setup()->image_alloc ); _sliders_pad->set_footer_visible ( mixer_setup()->show_slider_value_labels ); create_proxies_groups(); rebuild_visible_proxies_list(); show_visible_proxies_sets ( true ); } } } void Mixer_Sliders::set_inputs_setup ( const ::MWdg::Inputs_Setup * setup_n ) { _inputs_setup = setup_n; if ( inputs_setup() != 0 ) { _act_toggle_joined.setShortcut ( inputs_setup()->ks_toggle_joined ); _act_level_channels.setShortcut ( inputs_setup()->ks_level_channels ); _act_toggle_mute.setShortcut ( inputs_setup()->ks_mute_volumes ); _act_level_channels.setText ( inputs_setup()->ts_level_channels ); _sliders_pad->set_wheel_degrees ( inputs_setup()->wheel_degrees ); } } void Mixer_Sliders::clear_proxies_groups ( ) { for ( int ii=0; ii < _proxies_groups.size(); ++ii ) { delete _proxies_groups[ii]; } _proxies_groups.clear(); _proxies_groups_vis.clear(); _proxies_groups_pass.clear(); } void Mixer_Sliders::create_proxies_groups ( ) { ::QSnd::Mixer_Simple * snd_mixer ( 0 ); if ( mixer_setup() != 0 ) { snd_mixer = mixer_setup()->mixer_simple; } if ( snd_mixer == 0 ) { return; } for ( unsigned int ii=0; ii < snd_mixer->num_elems(); ++ii ) { ::QSnd::Mixer_Simple_Elem * qsme ( snd_mixer->elem ( ii ) ); for ( unsigned int snd_dir = 0; snd_dir < 2; ++snd_dir ) { if ( qsme->has_volume ( snd_dir ) ) { Mixer_Sliders_Proxies_Group * mspg ( new Mixer_Sliders_Proxies_Group ( this ) ); mspg->set_snd_dir ( snd_dir ); mspg->set_mixer_simple_elem ( qsme ); mspg->set_group_name ( qsme->display_name() ); mspg->set_style_id ( ::MWdg::Mixer_Style::PLAYBACK + snd_dir ); if ( mspg->should_be_separated() ) { setup_proxies_group_separate ( mspg ); } else { setup_proxies_group_joined ( mspg ); } if ( mspg->num_columns() > 0 ) { _proxies_groups.append ( mspg ); } else { delete mspg; } } } } } void Mixer_Sliders::setup_proxies_group_joined ( Mixer_Sliders_Proxies_Group * mspg_n ) { mspg_n->clear_columns(); mspg_n->set_is_joined ( true ); { QString ttip; ttip = mspg_n->group_name(); mspg_n->set_tool_tip ( ttip ); } create_proxies_group ( mspg_n, 0 ); mspg_n->update_mixer_values(); } void Mixer_Sliders::setup_proxies_group_separate ( Mixer_Sliders_Proxies_Group * mspg_n ) { const unsigned int num_channels ( mspg_n->mixer_simple_elem()->num_channels ( mspg_n->snd_dir() ) ); mspg_n->clear_columns(); mspg_n->set_is_joined ( false ); { QString ttip; ttip = mspg_n->group_name(); mspg_n->set_tool_tip ( ttip ); } for ( unsigned int ii=0; ii < num_channels; ++ii ) { create_proxies_group ( mspg_n, ii ); } mspg_n->update_mixer_values(); } bool Mixer_Sliders::create_proxies_group ( Mixer_Sliders_Proxies_Group * mspg_n, unsigned int channel_idx_n ) { bool res ( false ); ::QSnd::Mixer_Simple_Elem * qsme ( mspg_n->mixer_simple_elem() ); const unsigned int snd_dir ( mspg_n->snd_dir() ); Mixer_Sliders_Proxies_Column * mspc ( new Mixer_Sliders_Proxies_Column ); // Item name QString iname; if ( mspg_n->is_joined() ) { iname = mspg_n->group_name(); } else { iname = tr ( "%1 (%2)" ); iname = iname.arg ( QCoreApplication::translate ( "ALSA::Channel_Name", qsme->channel_name ( snd_dir, channel_idx_n ) ) ); iname = iname.arg ( qsme->channel ( snd_dir, channel_idx_n ) ); } // Tool tip QString ttip_name; QString ttip_channel; ttip_name += "
"; ttip_name += mspg_n->group_name(); ttip_name += "
\n"; if ( !mspg_n->is_joined() ) { ttip_channel += "
"; ttip_channel += iname; ttip_channel += "
\n"; } // Create volume proxy if ( qsme->has_volume ( snd_dir ) && ( channel_idx_n < qsme->num_volume_channels ( snd_dir ) ) ) { Mixer_Sliders_Proxy_Slider * msps ( new Mixer_Sliders_Proxy_Slider ); msps->set_snd_dir ( snd_dir ); msps->set_channel_idx ( channel_idx_n ); msps->set_is_joined ( mspg_n->is_joined() ); msps->set_mixer_simple_elem ( qsme ); msps->set_item_name ( iname ); msps->set_group_name ( mspg_n->group_name() ); msps->set_style_id ( ::MWdg::Mixer_Style::PLAYBACK + snd_dir ); { QString ttip ( ttip_name ); { QString ttip_type; ttip_type += "
"; ttip_type += _ttip_slider[snd_dir]; ttip_type += "
"; ttip += ttip_type; } ttip += ttip_channel; msps->set_tool_tip ( ttip ); } // Proxy Style if ( msps->has_dB() ) { ::Wdg::Pad_Proxy_Style * pstyle ( new ::Wdg::Pad_Proxy_Style ); if ( ( msps->dB_max() > 0 ) && ( msps->dB_min() < 0 ) ) { pstyle->slider_has_minimum = true; pstyle->slider_minimum_idx = msps->ask_dB_vol_nearest ( 0 ); } else { if ( msps->dB_max() <= 0 ) { pstyle->slider_has_minimum = true; pstyle->slider_minimum_idx = msps->slider_index_max(); } else if ( msps->dB_min() >= 0 ) { pstyle->slider_has_minimum = true; pstyle->slider_minimum_idx = 0; } } msps->set_style ( pstyle ); } mspc->set_slider_proxy ( msps ); } // Create switch proxy if ( qsme->has_switch ( snd_dir ) && ( channel_idx_n < qsme->num_switch_channels ( snd_dir ) ) ) { Mixer_Sliders_Proxy_Switch * msps ( new Mixer_Sliders_Proxy_Switch ); msps->set_snd_dir ( snd_dir ); msps->set_channel_idx ( channel_idx_n ); msps->set_is_joined ( mspg_n->is_joined() ); msps->set_mixer_simple_elem ( qsme ); msps->set_item_name ( iname ); msps->set_group_name ( mspg_n->group_name() ); msps->set_style_id ( ::MWdg::Mixer_Style::PLAYBACK + snd_dir ); { QString ttip ( ttip_name ); { QString ttip_type; ttip_type += "
"; ttip_type += _ttip_switch[snd_dir]; ttip_type += "
"; ttip += ttip_type; } ttip += ttip_channel; msps->set_tool_tip ( ttip ); } mspc->set_switch_proxy ( msps ); } if ( mspc->has_slider() || mspc->has_switch() ) { mspg_n->append_column ( mspc ); } else { delete mspc; res = true; } return res; } bool Mixer_Sliders::should_be_visible ( const Mixer_Sliders_Proxies_Group * mspg_n ) const { const ::QSnd::Mixer_Simple_Elem * qsme ( mspg_n->mixer_simple_elem() ); unsigned int snd_dir ( mspg_n->snd_dir() % 2 ); return ( qsme->is_active() && mixer_setup()->show_stream[snd_dir] ); } void Mixer_Sliders::rebuild_visible_proxies_list ( ) { _proxies_groups_vis.clear(); _proxies_groups_pass.clear(); for ( int ii=0; ii < _proxies_groups.size(); ++ii ) { Mixer_Sliders_Proxies_Group * mspg ( _proxies_groups[ii] ); mspg->set_is_visible ( should_be_visible ( mspg ) ); if ( mspg->is_visible() ) { if ( mspg->needs_separation() ) { separate_proxies_group ( mspg ); } _proxies_groups_vis.append ( mspg ); _proxies_groups_pass.append ( mspg ); } } } void Mixer_Sliders::action_level_volumes ( ) { //::std::cout << "Mixer_Sliders::action_level_volumes" << "\n"; ::MWdg::Mixer_Sliders_Proxies_Group * mspg ( _act_proxies_group ); if ( mspg != 0 ) { ::MWdg::Mixer_Sliders_Proxies_Column * mspc ( 0 ); { unsigned int col_idx ( 0 ); if ( _act_proxies_column < mspg->num_columns() ) { col_idx = _act_proxies_column; } mspc = static_cast < ::MWdg::Mixer_Sliders_Proxies_Column * > ( mspg->column ( col_idx ) ); } ::MWdg::Mixer_Sliders_Proxy_Slider * msps ( 0 ); if ( mspc != 0 ) { msps = static_cast < ::MWdg::Mixer_Sliders_Proxy_Slider * > ( mspc->slider_proxy() ); } if ( msps != 0 ) { mspg->mixer_simple_elem()->set_volume_all ( mspg->snd_dir(), msps->volume_value() ); } else { mspg->mixer_simple_elem()->level_volumes ( mspg->snd_dir() ); } } } void Mixer_Sliders::action_toggle_joined ( ) { //::std::cout << "Mixer_Sliders::action_toggle_joined" << "\n"; Mixer_Sliders_Proxies_Group * mspg ( _act_proxies_group ); if ( mspg != 0 ) { toggle_joined_separated ( mspg ); } } void Mixer_Sliders::action_toggle_mute ( ) { //::std::cout << "Mixer_Sliders::action_toggle_mute" << "\n"; Mixer_Sliders_Proxies_Group * mspg ( _act_proxies_group ); if ( mspg != 0 ) { mspg->mixer_simple_elem()->invert_switches ( mspg->snd_dir() ); } } void Mixer_Sliders::update_focus_proxies ( ) { if ( _sliders_pad->focus_info().has_focus ) { // Find focus proxies_group const int idx ( _sliders_pad->focus_info().group_idx ); if ( idx < _proxies_groups_vis.size() ) { _act_proxies_group = _proxies_groups_vis[idx]; _act_proxies_column = _sliders_pad->focus_info().column_idx; } } } void Mixer_Sliders::acquire_gui_state ( ::MWdg::Mixer_GUI_State_Proxy & state_n ) { if ( _act_proxies_group != 0 ) { ::MWdg::Mixer_Sliders_Proxies_Group * mspg ( _act_proxies_group ); state_n.group_name = mspg->group_name(); state_n.snd_dir = mspg->snd_dir(); state_n.column_idx = mspg->focus_column(); state_n.row_idx = mspg->focus_row(); state_n.has_focus = _sliders_pad->focus_info().has_focus; } } void Mixer_Sliders::restore_gui_state ( const ::MWdg::Mixer_GUI_State_Proxy & state_n ) { { _act_proxies_group = find_visible_proxy ( state_n ); _act_proxies_column = state_n.column_idx; } // Restore focus if ( state_n.has_focus && ( _act_proxies_group != 0 ) ) { _sliders_pad->set_focus_proxy ( _act_proxies_group->group_index(), state_n.column_idx, state_n.row_idx ); } if ( _cmenu.isVisible() ) { context_menu_update(); } } ::MWdg::Mixer_Sliders_Proxies_Group * Mixer_Sliders::find_visible_proxy ( const ::MWdg::Mixer_GUI_State_Proxy & prox_id_n ) { ::MWdg::Mixer_Sliders_Proxies_Group * mspg_res ( 0 ); if ( !prox_id_n.is_clear() ) { for ( int ii=0; ii < _proxies_groups_vis.size(); ++ii ) { ::MWdg::Mixer_Sliders_Proxies_Group * mspg ( _proxies_groups_vis[ii] ); if ( ( mspg->group_name() == prox_id_n.group_name ) && ( mspg->snd_dir() == prox_id_n.snd_dir ) ) { mspg_res = mspg; break; } } } return mspg_res; } void Mixer_Sliders::toggle_joined_separated ( ::MWdg::Mixer_Sliders_Proxies_Group * mspg_n ) { if ( mspg_n != 0 ) { if ( !mspg_n->can_be_separated() ) { return; } ::MWdg::Mixer_GUI_State_Proxy proxy_state; acquire_gui_state ( proxy_state ); show_visible_proxies_sets ( false ); if ( mspg_n->is_joined() ) { separate_proxies_group ( mspg_n ); } else { join_proxies_group ( mspg_n ); } show_visible_proxies_sets ( true ); restore_gui_state ( proxy_state ); } } void Mixer_Sliders::join_proxies_group ( ::MWdg::Mixer_Sliders_Proxies_Group * mspg_n ) { if ( !mspg_n->is_joined() ) { ::QSnd::Mixer_Simple_Elem * qsme ( mspg_n->mixer_simple_elem() ); qsme->level_volumes ( mspg_n->snd_dir() ); qsme->level_switches ( mspg_n->snd_dir() ); setup_proxies_group_joined ( mspg_n ); if ( _cmenu.isVisible() ) { context_menu_update(); } } } void Mixer_Sliders::separate_proxies_group ( Mixer_Sliders_Proxies_Group * mspg_n ) { if ( mspg_n->can_be_separated() ) { setup_proxies_group_separate ( mspg_n ); if ( _cmenu.isVisible() ) { context_menu_update(); } } } void Mixer_Sliders::show_visible_proxies_sets ( bool flag_n ) { if ( flag_n ) { if ( _proxies_groups_vis.size() > 0 ) { _sliders_pad->set_proxies_groups ( _proxies_groups_pass ); _sliders_area->set_widget ( _sliders_pad ); _sliders_pad->setAutoFillBackground ( false ); _sliders_pad->show(); } updateGeometry(); } else { _sliders_pad->hide(); _sliders_area->take_widget(); _sliders_pad->clear_proxies_groups(); } } void Mixer_Sliders::separate_where_requested ( ) { //::std::cout << "Mixer_Sliders::separate_where_requested" << "\n"; bool visible_request ( false ); for ( int ii=0; ii < _proxies_groups_vis.size(); ++ii ) { ::MWdg::Mixer_Sliders_Proxies_Group * mspg ( _proxies_groups_vis[ii] ); if ( mspg->separation_request() ) { visible_request = true; break; } } if ( visible_request ) { ::MWdg::Mixer_GUI_State_Proxy proxy_state; acquire_gui_state ( proxy_state ); show_visible_proxies_sets ( false ); for ( int ii=0; ii < _proxies_groups_vis.size(); ++ii ) { Mixer_Sliders_Proxies_Group * mspg ( _proxies_groups_vis[ii] ); if ( mspg->separation_request() ) { mspg->set_separation_request ( false ); separate_proxies_group ( mspg ); } } show_visible_proxies_sets ( true ); restore_gui_state ( proxy_state ); } //::std::cout << "Mixer_Sliders::separate_where_requested done" << "\n"; } bool Mixer_Sliders::context_menu_start ( const QPoint & pos_n ) { bool res ( false ); if ( !_cmenu.isVisible() && ( _sliders_pad->focus_info().has_focus ) && ( _act_proxies_group != 0 ) ) { if ( context_menu_update() > 0 ) { // Tells the proxy that any changes should be notified _act_proxies_group->set_notify_value_change ( true ); _cmenu.setTitle ( _act_proxies_group->group_name() ); _cmenu.popup ( pos_n ); res = true; } } return res; } void Mixer_Sliders::context_menu_cleanup_behind ( ) { //::std::cout << "Mixer_Sliders::context_cleanup_behind\n"; if ( _act_proxies_group != 0 ) { // Tells the proxy that changes must not be notified _act_proxies_group->set_notify_value_change ( false ); } } unsigned int Mixer_Sliders::context_menu_update ( ) { //::std::cout << "Mixer_Sliders::context_menu_update\n"; unsigned int act_vis ( 0 ); Mixer_Sliders_Proxies_Group * mspg ( _act_proxies_group ); if ( mspg == 0 ) { _cmenu.close(); return act_vis; } const ::QSnd::Mixer_Simple_Elem * qsme ( mspg->mixer_simple_elem() ); const unsigned int snd_dir ( mspg->snd_dir() ); // Update split/join and level channels actions { const bool vis_joined ( mspg->can_be_separated() ); _act_toggle_joined.setVisible ( vis_joined ); if ( vis_joined ) { ++act_vis; if ( inputs_setup() != 0 ) { const QString * str; if ( mspg->is_joined() ) { str = &inputs_setup()->ts_split_channels; } else { str = &inputs_setup()->ts_join_channels; } _act_toggle_joined.setText ( *str ); } } const bool vis_level ( ( mspg->num_sliders() > 1 ) && !qsme->volumes_equal ( snd_dir ) ); _act_level_channels.setVisible ( vis_level ); if ( vis_level ) { ++act_vis; } } // Update mute / unmute channels actions { unsigned int num_sw ( mspg->num_switches() ); if ( num_sw > 0 ) { ++act_vis; QString * act_txt = &_act_str_toggle_mute; QIcon * act_icon = &_icon_vol_med; const bool is_on ( qsme->switch_state ( snd_dir, 0 ) ); if ( is_on ) { act_icon = &_icon_muted; } else { act_icon = &_icon_vol_high; } if ( num_sw == 1 ) { if ( is_on ) { act_txt = &_act_str_mute[0]; } else { act_txt = &_act_str_unmute[0]; } } else { if ( qsme->switches_equal ( snd_dir ) ) { if ( is_on ) { act_txt = &_act_str_mute[1]; } else { act_txt = &_act_str_unmute[1]; } } } _act_toggle_mute.setText ( *act_txt ); _act_toggle_mute.setIcon ( *act_icon ); } _act_toggle_mute.setVisible ( num_sw > 0 ); } if ( act_vis == 0 ) { _cmenu.close(); } return act_vis; } bool Mixer_Sliders::eventFilter ( QObject * watched_n, QEvent * event_n ) { bool filtered ( false ); if ( watched_n == _sliders_pad ) { if ( event_n->type() == QEvent::KeyPress ) { if ( inputs_setup() != 0 ) { filtered = true; const QKeySequence kseq ( static_cast < QKeyEvent * > ( event_n )->key() ); // Trigger actions on a key press if ( kseq == inputs_setup()->ks_toggle_joined ) { _act_toggle_joined.trigger(); } else if ( kseq == inputs_setup()->ks_level_channels ) { _act_level_channels.trigger(); } else if ( kseq == inputs_setup()->ks_mute_volumes ) { _act_toggle_mute.trigger(); } else { filtered = false; } } } else if ( event_n->type() == QEvent::ContextMenu ) { QContextMenuEvent * ev_cmenu ( static_cast < QContextMenuEvent * > ( event_n ) ); if ( context_menu_start ( ev_cmenu->globalPos() ) ) { filtered = true; } } } return filtered; } bool Mixer_Sliders::event ( QEvent * event_n ) { bool res ( true ); if ( event_n->type() == ::MWdg::evt_separation_request ) { if ( !_separation_requested ) { _separation_requested = true; QCoreApplication::postEvent ( this, new QEvent ( ::MWdg::evt_separation ) ); } } else if ( event_n->type() == ::MWdg::evt_separation ) { _separation_requested = false; separate_where_requested(); } else if ( event_n->type() == ::MWdg::evt_values_changed ) { context_menu_update(); } else { res = QWidget::event ( event_n ); } return res; } } // End of namespace qastools-v0.22.0/qasmixer/src/mwdg/mixer_sliders.hpp000066400000000000000000000105021354534512100225670ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_mwdg_mixer_sliders_hpp__ #define __INC_mwdg_mixer_sliders_hpp__ #include #include #include #include // Forward declaration namespace MWdg { class Inputs_Setup; class Mixer_Simple_Setup; class Mixer_Sliders_Proxies_Group; class Mixer_GUI_State; class Mixer_GUI_State_Proxy; } namespace Wdg { class Sliders_Pad; class Pad_Proxies_Group; class Scroll_Area_Horizontal; } namespace MWdg { /// @brief Mixer_Sliders /// class Mixer_Sliders : public QWidget { Q_OBJECT // Public methods public: Mixer_Sliders ( QWidget * parent_n = 0 ); ~Mixer_Sliders ( ); // Mixer setup const ::MWdg::Mixer_Simple_Setup * mixer_setup ( ) const; void set_mixer_setup ( const ::MWdg::Mixer_Simple_Setup * setup_n ); // Inputs setup const ::MWdg::Inputs_Setup * inputs_setup ( ) const; void set_inputs_setup ( const ::MWdg::Inputs_Setup * setup_n ); /// @brief Number of visualized proxies groups /// unsigned int num_visible ( ) const; ::Wdg::Sliders_Pad * sliders_pad ( ); // Event handling bool event ( QEvent * event_n ); bool eventFilter ( QObject * watched, QEvent * event ); // Signals signals: void sig_footer_label_selected ( unsigned int group_idx_n, unsigned int column_idx_n ); // Protected slots protected slots: void action_toggle_joined ( ); void action_level_volumes ( ); void action_toggle_mute ( ); void update_focus_proxies ( ); void context_menu_cleanup_behind ( ); // Protected methods protected: // Proxy group creation / deletion void clear_proxies_groups ( ); void create_proxies_groups ( ); void setup_proxies_group_joined ( ::MWdg::Mixer_Sliders_Proxies_Group * mspg_n ); void setup_proxies_group_separate ( ::MWdg::Mixer_Sliders_Proxies_Group * mspg_n ); bool create_proxies_group ( ::MWdg::Mixer_Sliders_Proxies_Group * mspg_n, unsigned int channel_idx_n ); // Proxy group manipulation bool should_be_visible ( const ::MWdg::Mixer_Sliders_Proxies_Group * mspg_n ) const; void toggle_joined_separated ( ::MWdg::Mixer_Sliders_Proxies_Group * mspg_n ); void join_proxies_group ( ::MWdg::Mixer_Sliders_Proxies_Group * mspg_n ); void separate_proxies_group ( ::MWdg::Mixer_Sliders_Proxies_Group * mspg_n ); // Proxy group showing hiding void show_visible_proxies_sets ( bool flag_n ); // Proxy group updating void separate_where_requested ( ); void rebuild_visible_proxies_list ( ); // Focus proxy void acquire_gui_state ( ::MWdg::Mixer_GUI_State_Proxy & state_n ); void restore_gui_state ( const ::MWdg::Mixer_GUI_State_Proxy & state_n ); Mixer_Sliders_Proxies_Group * find_visible_proxy ( const ::MWdg::Mixer_GUI_State_Proxy & prox_id_n ); // Context menu bool context_menu_start ( const QPoint & pos_n ); /// @return The number of visible actions unsigned int context_menu_update ( ); // Private attributes private: const ::MWdg::Mixer_Simple_Setup * _mixer_setup; const ::MWdg::Inputs_Setup * _inputs_setup; QList < ::MWdg::Mixer_Sliders_Proxies_Group * > _proxies_groups; QList < ::MWdg::Mixer_Sliders_Proxies_Group * > _proxies_groups_vis; QList < ::Wdg::Pad_Proxies_Group * > _proxies_groups_pass; ::Wdg::Scroll_Area_Horizontal * _sliders_area; ::Wdg::Sliders_Pad * _sliders_pad; // Flags bool _separation_requested; // Action focus proxy QPointer < Mixer_Sliders_Proxies_Group > _act_proxies_group; unsigned int _act_proxies_column; // Context menu QMenu _cmenu; QAction _act_toggle_joined; QAction _act_level_channels; QAction _act_separator_channels; QAction _act_toggle_mute; // Strings and Icons QString _act_str_mute[2]; QString _act_str_unmute[2]; QString _act_str_toggle_mute; QString _ttip_slider[2]; QString _ttip_switch[2]; QIcon _icon_vol_high; QIcon _icon_vol_med; QIcon _icon_muted; }; inline const Mixer_Simple_Setup * Mixer_Sliders::mixer_setup ( ) const { return _mixer_setup; } inline const ::MWdg::Inputs_Setup * Mixer_Sliders::inputs_setup ( ) const { return _inputs_setup; } inline unsigned int Mixer_Sliders::num_visible ( ) const { return _proxies_groups_vis.size(); } inline ::Wdg::Sliders_Pad * Mixer_Sliders::sliders_pad ( ) { return _sliders_pad; } } // End of namespace #endif qastools-v0.22.0/qasmixer/src/mwdg/mixer_sliders_proxies_column.cpp000066400000000000000000000063711354534512100257210ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "mixer_sliders_proxies_column.hpp" #include "wdg/event_types.hpp" #include "wdg/pass_events.hpp" #include #include namespace MWdg { Mixer_Sliders_Proxies_Column::Mixer_Sliders_Proxies_Column ( ) { _str_value_dB = tr ( "%1 dB" ); _str_value_pc = tr ( "%1 %" ); } Mixer_Sliders_Proxies_Column::~Mixer_Sliders_Proxies_Column ( ) { } void Mixer_Sliders_Proxies_Column::update_mixer_values ( ) { if ( slider_proxy() != 0 ) { mslider_proxy()->update_value_from_source(); } if ( switch_proxy() != 0 ) { mswitch_proxy()->update_value_from_source(); } } void Mixer_Sliders_Proxies_Column::slider_proxy_changed ( ) { update_connections(); } void Mixer_Sliders_Proxies_Column::switch_proxy_changed ( ) { update_connections(); } void Mixer_Sliders_Proxies_Column::show_value_string_changed ( ) { update_connections(); } void Mixer_Sliders_Proxies_Column::update_connections ( ) { if ( slider_proxy() != 0 ) { ::MWdg::Mixer_Sliders_Proxy_Slider * msps ( mslider_proxy() ); disconnect ( msps, 0, this, 0 ); if ( show_value_string() ) { if ( msps->has_dB() ) { connect ( msps, SIGNAL ( sig_dB_value_changed ( long ) ), this, SIGNAL ( sig_value_string_changed() ) ); } else { connect ( msps, SIGNAL ( sig_slider_index_changed ( unsigned long ) ), this, SIGNAL ( sig_value_string_changed() ) ); } } } } // Value string QString Mixer_Sliders_Proxies_Column::value_string ( ) const { QString res; if ( has_slider() && show_value_string() ) { ::MWdg::Mixer_Sliders_Proxy_Slider * msps ( mslider_proxy() ); if ( msps->has_dB() ) { dB_string ( res, msps->dB_value() ); } else { percent_string ( res, msps->volume_permille() ); } } return res; } QString Mixer_Sliders_Proxies_Column::value_min_string ( ) const { QString res; if ( has_slider() && show_value_string() ) { ::MWdg::Mixer_Sliders_Proxy_Slider * msps ( mslider_proxy() ); if ( msps->has_dB() ) { dB_string ( res, msps->dB_max() ); } else { percent_string ( res, -1000 ); } } return res; } QString Mixer_Sliders_Proxies_Column::value_max_string ( ) const { QString res; if ( has_slider() && show_value_string() ) { ::MWdg::Mixer_Sliders_Proxy_Slider * msps ( mslider_proxy() ); if ( msps->has_dB() ) { dB_string ( res, msps->dB_min() ); } else { percent_string ( res, 1000 ); } } return res; } void Mixer_Sliders_Proxies_Column::dB_string ( QString & str_n, long dB_value_n ) const { str_n = _loc.toString ( dB_value_n / 100.0, 'f', 2 ); str_n = _str_value_dB.arg ( str_n ); } void Mixer_Sliders_Proxies_Column::percent_string ( QString & str_n, int permille_n ) const { str_n = _loc.toString ( permille_n / 10.0, 'f', 1 ); str_n = _str_value_pc.arg ( str_n ); } bool Mixer_Sliders_Proxies_Column::event ( QEvent * event_n ) { if ( event_n->type() == ::Wdg::evt_pass_event_key ) { ::Wdg::Pass_Event_Key * ev_kp ( static_cast < ::Wdg::Pass_Event_Key * > ( event_n ) ); if ( parent() != 0 ) { ev_kp->column_idx = column_index(); QCoreApplication::sendEvent ( parent(), event_n ); } return true; } return ::Wdg::Pad_Proxies_Column::event ( event_n ); } } // End of namespace qastools-v0.22.0/qasmixer/src/mwdg/mixer_sliders_proxies_column.hpp000066400000000000000000000033161354534512100257220ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_mixer_sliders_proxies_column_hpp__ #define __INC_mixer_sliders_proxies_column_hpp__ #include #include "wdg/pad_proxies_column.hpp" #include "mixer_sliders_proxy_slider.hpp" #include "mixer_sliders_proxy_switch.hpp" namespace MWdg { /// @brief Mixer_Sliders_Proxies_Column /// class Mixer_Sliders_Proxies_Column : public ::Wdg::Pad_Proxies_Column { Q_OBJECT // Public methods public: Mixer_Sliders_Proxies_Column ( ); ~Mixer_Sliders_Proxies_Column ( ); ::MWdg::Mixer_Sliders_Proxy_Slider * mslider_proxy ( ) const; ::MWdg::Mixer_Sliders_Proxy_Switch * mswitch_proxy ( ) const; void update_mixer_values ( ); // Value string QString value_string ( ) const; QString value_min_string ( ) const; QString value_max_string ( ) const; bool event ( QEvent * event_n ); // Protected methods protected: void slider_proxy_changed ( ); void switch_proxy_changed ( ); void show_value_string_changed ( ); void update_connections ( ); void dB_string ( QString & str_n, long dB_value_n ) const; void percent_string ( QString & str_n, int permille_n ) const; // Private atributes private: QString _str_value_dB; QString _str_value_pc; QLocale _loc; }; inline ::MWdg::Mixer_Sliders_Proxy_Slider * Mixer_Sliders_Proxies_Column::mslider_proxy ( ) const { return static_cast < ::MWdg::Mixer_Sliders_Proxy_Slider * > ( slider_proxy() ); } inline ::MWdg::Mixer_Sliders_Proxy_Switch * Mixer_Sliders_Proxies_Column::mswitch_proxy ( ) const { return static_cast < ::MWdg::Mixer_Sliders_Proxy_Switch * > ( switch_proxy() ); } } // End of namespace #endif qastools-v0.22.0/qasmixer/src/mwdg/mixer_sliders_proxies_group.cpp000066400000000000000000000112021354534512100255450ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "mixer_sliders_proxies_group.hpp" #include "wdg/event_types.hpp" #include "wdg/pass_events.hpp" #include "mwdg/event_types.hpp" #include #include namespace MWdg { Mixer_Sliders_Proxies_Group::Mixer_Sliders_Proxies_Group ( QObject * parent_n ) : Wdg::Pad_Proxies_Group ( parent_n ), _mixer_simple_elem ( 0 ), _snd_dir ( 0 ), _is_joined ( false ), _is_visible ( false ), _notify_value_change ( false ), _separation_request ( false ) { // Separation timer _separation_timer.setSingleShot ( true ); _separation_timer.setInterval ( 550 ); connect ( &_separation_timer, SIGNAL ( timeout() ), this, SLOT ( timer_separation_check() ) ); } void Mixer_Sliders_Proxies_Group::set_mixer_simple_elem ( ::QSnd::Mixer_Simple_Elem * selem_n ) { if ( mixer_simple_elem() != 0 ) { disconnect ( mixer_simple_elem(), 0, this, 0 ); } _mixer_simple_elem = selem_n; if ( mixer_simple_elem() != 0 ) { connect ( mixer_simple_elem(), SIGNAL ( sig_values_changed() ), this, SLOT ( update_mixer_values() ) ); } } void Mixer_Sliders_Proxies_Group::set_snd_dir ( unsigned char dir_n ) { _snd_dir = dir_n; } void Mixer_Sliders_Proxies_Group::set_is_joined ( bool flag_n ) { _is_joined = flag_n; } void Mixer_Sliders_Proxies_Group::set_is_visible ( bool flag_n ) { _is_visible = flag_n; } void Mixer_Sliders_Proxies_Group::set_notify_value_change ( bool flag_n ) { _notify_value_change = flag_n; } void Mixer_Sliders_Proxies_Group::set_separation_request ( bool flag_n ) { _separation_request = flag_n; } bool Mixer_Sliders_Proxies_Group::can_be_separated ( ) const { if ( mixer_simple_elem() != 0 ) { return ( mixer_simple_elem()->num_channels ( snd_dir() ) > 1 ); } return false; } bool Mixer_Sliders_Proxies_Group::should_be_separated ( ) const { bool res ( false ); ::QSnd::Mixer_Simple_Elem * sme ( mixer_simple_elem() ); if ( sme != 0 ) { res = ( ( sme->num_volume_channels ( snd_dir() ) > 1 ) && !sme->volumes_equal ( snd_dir() ) ) || ( ( sme->num_switch_channels ( snd_dir() ) > 1 ) && !sme->switches_equal ( snd_dir() ) ); } return res; } bool Mixer_Sliders_Proxies_Group::needs_separation ( ) const { bool res ( false ); ::QSnd::Mixer_Simple_Elem * sme ( mixer_simple_elem() ); if ( sme != 0 ) { res = is_joined() && ( ( ( sme->num_volume_channels ( snd_dir() ) > 1 ) && !sme->volumes_equal ( snd_dir() ) ) || ( ( sme->num_switch_channels ( snd_dir() ) > 1 ) && !sme->switches_equal ( snd_dir() ) ) ); } return res; } void Mixer_Sliders_Proxies_Group::update_mixer_values ( ) { for ( unsigned int ii=0; ii < num_columns(); ++ii ) { static_cast < Mixer_Sliders_Proxies_Column * > ( column ( ii ) )->update_mixer_values(); } // Check for needed separation if ( needs_separation() ) { if ( !_separation_timer.isActive() ) { _separation_timer.start(); } } else { if ( _separation_timer.isActive() ) { _separation_timer.stop(); } } // Notify parent on demand if ( notify_value_change() && ( parent() != 0 ) ) { QEvent ev_req ( ::MWdg::evt_values_changed ); QCoreApplication::sendEvent ( parent(), &ev_req ); } } void Mixer_Sliders_Proxies_Group::timer_separation_check ( ) { //::std::cout << "Mixer_Sliders_Proxies_Group::timer_separation_check\n"; if ( parent() != 0 ) { if ( needs_separation() ) { set_separation_request ( true ); // Notify parent QEvent ev_req ( ::MWdg::evt_separation_request ); QCoreApplication::sendEvent ( parent(), &ev_req ); } } } bool Mixer_Sliders_Proxies_Group::event ( QEvent * event_n ) { if ( event_n->type() == ::Wdg::evt_pass_event_key ) { ::Wdg::Pass_Event_Key * ev_kp ( static_cast < ::Wdg::Pass_Event_Key * > ( event_n ) ); if ( ev_kp->column_idx < num_columns() ) { ::Wdg::Pad_Proxies_Column * col ( column ( ev_kp->column_idx ) ); // Pass the key event to the switch widget ::Wdg::Pad_Proxy_Slider * spp_sl ( col->slider_proxy() ); if ( spp_sl != 0 ) { ::Wdg::Pad_Proxy_Switch * spp_sw ( col->switch_proxy() ); // Use joined switch on demand if ( spp_sw == 0 ) { ::Wdg::Pad_Proxies_Column * col0 ( column ( 0 ) ); spp_sw = col0->switch_proxy(); } if ( spp_sw != 0 ) { // Pass event to switch widget if ( spp_sw->widget() != 0 ) { const bool old_focus ( spp_sw->has_focus() ); spp_sw->set_has_focus ( spp_sl->has_focus() ); QCoreApplication::sendEvent ( spp_sw->widget(), &ev_kp->ev_key ); spp_sw->set_has_focus ( old_focus ); } } } } return true; } return ::Wdg::Pad_Proxies_Group::event ( event_n ); } } // End of namespace qastools-v0.22.0/qasmixer/src/mwdg/mixer_sliders_proxies_group.hpp000066400000000000000000000046351354534512100255660ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_mixer_sliders_proxies_group_hpp__ #define __INC_mixer_sliders_proxies_group_hpp__ #include #include #include "wdg/pad_proxies_group.hpp" #include "mixer_sliders_proxies_column.hpp" namespace MWdg { /// @brief Mixer_Sliders_Proxies_Group /// class Mixer_Sliders_Proxies_Group : public ::Wdg::Pad_Proxies_Group { Q_OBJECT // Public methods public: Mixer_Sliders_Proxies_Group ( QObject * parent_n = 0 ); // Mixer_Simple_Elem ::QSnd::Mixer_Simple_Elem * mixer_simple_elem ( ) const; virtual void set_mixer_simple_elem ( ::QSnd::Mixer_Simple_Elem * selem_n ); // Snd dir unsigned char snd_dir ( ) const; void set_snd_dir ( unsigned char dir_n ); // Joined flag bool is_joined ( ) const; void set_is_joined ( bool flag_n ); // If true then the corresponding widget is visible bool is_visible ( ) const; void set_is_visible ( bool flag_n ); // Notify parent on value change bool notify_value_change ( ) const; void set_notify_value_change ( bool flag_n ); // Separation info bool can_be_separated ( ) const; bool should_be_separated ( ) const; bool needs_separation ( ) const; bool separation_request ( ) const; void set_separation_request ( bool flag_n ); // Public slots public slots: void update_mixer_values ( ); // Protected slots protected slots: void timer_separation_check ( ); // Protected methods protected: bool event ( QEvent * event_n ); // Private attributes private: ::QSnd::Mixer_Simple_Elem * _mixer_simple_elem; unsigned char _snd_dir; bool _is_joined; bool _is_visible; bool _notify_value_change; bool _separation_request; QTimer _separation_timer; }; inline ::QSnd::Mixer_Simple_Elem * Mixer_Sliders_Proxies_Group::mixer_simple_elem ( ) const { return _mixer_simple_elem; } inline unsigned char Mixer_Sliders_Proxies_Group::snd_dir ( ) const { return _snd_dir; } inline bool Mixer_Sliders_Proxies_Group::is_joined ( ) const { return _is_joined; } inline bool Mixer_Sliders_Proxies_Group::is_visible ( ) const { return _is_visible; } inline bool Mixer_Sliders_Proxies_Group::notify_value_change ( ) const { return _notify_value_change; } inline bool Mixer_Sliders_Proxies_Group::separation_request ( ) const { return _separation_request; } } // End of namespace #endif qastools-v0.22.0/qasmixer/src/mwdg/mixer_sliders_proxy_slider.cpp000066400000000000000000000111361354534512100253710ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "mixer_sliders_proxy_slider.hpp" #include "wdg/pass_events.hpp" #include "wdg/uint_mapper.hpp" #include #include namespace MWdg { Mixer_Sliders_Proxy_Slider::Mixer_Sliders_Proxy_Slider ( ) : _mixer_simple_elem ( 0 ), _volume_val ( 0 ), _volume_min ( 0 ), _volume_max ( 0 ), _dB_val ( 0 ), _channel_idx ( 0 ), _snd_dir ( 0 ), _alsa_updating ( false ) { update_limits(); } void Mixer_Sliders_Proxy_Slider::set_snd_dir ( unsigned char dir_n ) { _snd_dir = dir_n; update_limits(); } void Mixer_Sliders_Proxy_Slider::set_channel_idx ( unsigned int idx_n ) { _channel_idx = idx_n; } void Mixer_Sliders_Proxy_Slider::set_mixer_simple_elem ( ::QSnd::Mixer_Simple_Elem * selem_n ) { _mixer_simple_elem = selem_n; update_limits(); } void Mixer_Sliders_Proxy_Slider::set_is_joined ( bool flag_n ) { _is_joined = flag_n; } void Mixer_Sliders_Proxy_Slider::set_dB_value ( long dB_val_n ) { if ( has_dB() ) { if ( _dB_val != dB_val_n ) { _dB_val = dB_val_n; this->dB_value_changed(); emit sig_dB_value_changed ( _dB_val ); } } } void Mixer_Sliders_Proxy_Slider::update_limits ( ) { unsigned long idx_max ( 0 ); if ( mixer_simple_elem() == 0 ) { _volume_min = 0; _volume_max = 0; } else { _volume_min = mixer_simple_elem()->volume_min ( snd_dir() ); _volume_max = mixer_simple_elem()->volume_max ( snd_dir() ); idx_max = ::Wdg::integer_distance ( _volume_min, _volume_max ); } set_slider_index_max ( idx_max ); } void Mixer_Sliders_Proxy_Slider::set_volume_value ( long value_n ) { if ( _volume_val != value_n ) { _volume_val = value_n; this->volume_value_changed(); } } int Mixer_Sliders_Proxy_Slider::volume_permille ( ) const { int res; unsigned long val; unsigned long max; if ( _volume_val >= 0 ) { val = _volume_val; max = _volume_max; } else { val = -_volume_val; max = -_volume_min; } if ( _volume_max >= ( 1000*1000 ) ) { max /= 1000; } else { val *= 1000; } res = val / max; if ( _volume_val < 0 ) { res = -res; } return res; } void Mixer_Sliders_Proxy_Slider::dB_value_changed ( ) { //::std::cout << "Mixer_Sliders_Proxy_Slider::dB_value_changed " << slider_value() << "\n"; if ( ( mixer_simple_elem() != 0 ) && ( !_alsa_updating ) ) { if ( is_joined() ) { mixer_simple_elem()->set_dB_all ( snd_dir(), dB_value() ); } else { mixer_simple_elem()->set_dB ( snd_dir(), channel_idx(), dB_value() ); } } //::std::cout << "Mixer_Sliders_Proxy_Slider::dB_value_changed " << "done" << "\n"; } void Mixer_Sliders_Proxy_Slider::volume_value_changed ( ) { //::std::cout << "Mixer_Sliders_Proxy_Slider::volume_value_changed " << volume_value() << "\n"; { unsigned long idx ( ::Wdg::integer_distance ( volume_min(), volume_value() ) ); set_slider_index ( idx ); } if ( ( mixer_simple_elem() != 0 ) && ( !_alsa_updating ) ) { bool key_mod ( ( QApplication::keyboardModifiers() & Qt::ControlModifier ) != 0 ); key_mod = ( key_mod && has_focus() ); if ( is_joined() || key_mod ) { mixer_simple_elem()->set_volume_all ( snd_dir(), volume_value() ); } else { mixer_simple_elem()->set_volume ( snd_dir(), channel_idx(), volume_value() ); } } } void Mixer_Sliders_Proxy_Slider::slider_index_changed ( ) { //::std::cout << "Mixer_Sliders_Proxy_Slider::slider_index_changed " << slider_index() << "\n"; { long vol ( _volume_min ); vol += slider_index(); set_volume_value ( vol ); } } void Mixer_Sliders_Proxy_Slider::update_value_from_source ( ) { if ( ( mixer_simple_elem() != 0 ) && ( !_alsa_updating ) ) { _alsa_updating = true; if ( has_dB() ) { set_dB_value ( mixer_simple_elem()->dB_value ( snd_dir(), channel_idx() ) ); } set_volume_value ( mixer_simple_elem()->volume ( snd_dir(), channel_idx() ) ); _alsa_updating = false; } } bool Mixer_Sliders_Proxy_Slider::eventFilter ( QObject * obj_n, QEvent * event_n ) { bool res ( Pad_Proxy_Slider::eventFilter ( obj_n, event_n ) ); if ( !res ) { if ( ( event_n->type() == QEvent::KeyPress ) || ( event_n->type() == QEvent::KeyRelease ) || ( event_n->type() == QEvent::ShortcutOverride ) ) { QKeyEvent * ev_kev ( static_cast < QKeyEvent * > ( event_n ) ); // Pass certain key events to the parent proxy if ( parent() != 0 ) { switch ( ev_kev->key() ) { case Qt::Key_Space: case Qt::Key_VolumeMute: { ::Wdg::Pass_Event_Key ev_pass ( *ev_kev, 0 ); QCoreApplication::sendEvent ( parent(), &ev_pass ); } break; default: break; } } } } return res; } } // End of namespace qastools-v0.22.0/qasmixer/src/mwdg/mixer_sliders_proxy_slider.hpp000066400000000000000000000072111354534512100253750ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_mixer_sliders_proxy_slider_hpp__ #define __INC_mixer_sliders_proxy_slider_hpp__ #include #include "wdg/pad_proxy_slider.hpp" #include "qsnd/mixer_simple_elem.hpp" namespace MWdg { /// @brief Mixer_Sliders_Proxy_Slider /// class Mixer_Sliders_Proxy_Slider : public ::Wdg::Pad_Proxy_Slider { Q_OBJECT // Public methods public: Mixer_Sliders_Proxy_Slider ( ); // Mixer simple elem ::QSnd::Mixer_Simple_Elem * mixer_simple_elem ( ) const; void set_mixer_simple_elem ( ::QSnd::Mixer_Simple_Elem * selem_n ); // Snd dir unsigned char snd_dir ( ) const; void set_snd_dir ( unsigned char dir_n ); // Channel idx unsigned int channel_idx ( ) const; void set_channel_idx ( unsigned int idx_n ); // Is joined flag bool is_joined ( ) const; void set_is_joined ( bool flag_n ); // Volume long volume_max ( ) const; long volume_min ( ) const; long volume_value ( ) const; int volume_permille ( ) const; // Decibel bool has_dB ( ) const; long ask_dB_vol ( long dB_value_n, int dir_n = -1 ); long ask_dB_vol_nearest ( long dB_value_n ); long ask_vol_dB ( long volume_n ); long dB_value ( ) const; void set_dB_value ( long dB_val_n ); long dB_max ( ) const; long dB_min ( ) const; bool eventFilter ( QObject * obj_n, QEvent * event_n ); // Public signals signals: void sig_dB_value_changed ( long dB_value_n ); // Public slots public slots: void set_volume_value ( long value_n ); void update_value_from_source ( ); // Protected methods protected: void update_limits ( ); void dB_value_changed ( ); void volume_value_changed ( ); void slider_index_changed ( ); // Private attributes private: ::QSnd::Mixer_Simple_Elem * _mixer_simple_elem; long _volume_val; long _volume_min; long _volume_max; long _dB_val; unsigned int _channel_idx; unsigned char _snd_dir; bool _is_joined; bool _alsa_updating; }; inline ::QSnd::Mixer_Simple_Elem * Mixer_Sliders_Proxy_Slider::mixer_simple_elem ( ) const { return _mixer_simple_elem; } inline unsigned char Mixer_Sliders_Proxy_Slider::snd_dir ( ) const { return _snd_dir; } inline unsigned int Mixer_Sliders_Proxy_Slider::channel_idx ( ) const { return _channel_idx; } inline bool Mixer_Sliders_Proxy_Slider::is_joined ( ) const { return _is_joined; } inline long Mixer_Sliders_Proxy_Slider::volume_min ( ) const { return _volume_min; } inline long Mixer_Sliders_Proxy_Slider::volume_value ( ) const { return _volume_val; } inline long Mixer_Sliders_Proxy_Slider::volume_max ( ) const { return _volume_max; } inline bool Mixer_Sliders_Proxy_Slider::has_dB ( ) const { if ( mixer_simple_elem() == 0 ) { return false; } return mixer_simple_elem()->has_dB ( snd_dir() ); } inline long Mixer_Sliders_Proxy_Slider::ask_dB_vol ( long dB_value_n, int dir_n ) { return mixer_simple_elem()->ask_dB_vol ( snd_dir(), dB_value_n, dir_n ); } inline long Mixer_Sliders_Proxy_Slider::ask_dB_vol_nearest ( long dB_value_n ) { return mixer_simple_elem()->ask_dB_vol_nearest ( snd_dir(), dB_value_n ); } inline long Mixer_Sliders_Proxy_Slider::ask_vol_dB ( long volume_n ) { return mixer_simple_elem()->ask_vol_dB ( snd_dir(), volume_n ); } inline long Mixer_Sliders_Proxy_Slider::dB_value ( ) const { return _dB_val; } inline long Mixer_Sliders_Proxy_Slider::dB_min ( ) const { return mixer_simple_elem()->dB_min ( snd_dir() ); } inline long Mixer_Sliders_Proxy_Slider::dB_max ( ) const { return mixer_simple_elem()->dB_max ( snd_dir() ); } } // End of namespace #endif qastools-v0.22.0/qasmixer/src/mwdg/mixer_sliders_proxy_switch.cpp000066400000000000000000000041251354534512100254100ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "mixer_sliders_proxy_switch.hpp" #include #include #include namespace MWdg { Mixer_Sliders_Proxy_Switch::Mixer_Sliders_Proxy_Switch ( ) : _mixer_simple_elem ( 0 ), _channel_idx ( 0 ), _snd_dir ( 0 ), _alsa_updating ( false ) { } void Mixer_Sliders_Proxy_Switch::set_snd_dir ( unsigned char dir_n ) { _snd_dir = dir_n; } void Mixer_Sliders_Proxy_Switch::set_channel_idx ( unsigned int idx_n ) { _channel_idx = idx_n; } void Mixer_Sliders_Proxy_Switch::set_mixer_simple_elem ( ::QSnd::Mixer_Simple_Elem * selem_n ) { _mixer_simple_elem = selem_n; } void Mixer_Sliders_Proxy_Switch::set_is_joined ( bool flag_n ) { _is_joined = flag_n; } void Mixer_Sliders_Proxy_Switch::switch_state_changed ( ) { //::std::cout << "Mixer_Sliders_Proxy_Switch::switch_state_changed " << switch_state() << "\n"; if ( ( mixer_simple_elem() != 0 ) && ( !_alsa_updating ) ) { bool key_mod ( ( QApplication::keyboardModifiers() & Qt::ControlModifier ) != 0 ); key_mod = ( key_mod && has_focus() ); if ( is_joined() || key_mod ) { mixer_simple_elem()->set_switch_all ( snd_dir(), switch_state() ); } else { mixer_simple_elem()->set_switch ( snd_dir(), channel_idx(), switch_state() ); } } //::std::cout << "Mixer_Sliders_Proxy_Switch::switch_state_changed " << "done" << "\n"; } void Mixer_Sliders_Proxy_Switch::update_value_from_source ( ) { if ( ( mixer_simple_elem() != 0 ) && ( !_alsa_updating ) ) { _alsa_updating = true; set_switch_state ( mixer_simple_elem()->switch_state ( snd_dir(), channel_idx() ) ); _alsa_updating = false; } } bool Mixer_Sliders_Proxy_Switch::eventFilter ( QObject * obj_n, QEvent * event_n ) { bool res ( Pad_Proxy_Switch::eventFilter ( obj_n, event_n ) ); if ( !res ) { if ( event_n->type() == QEvent::KeyPress ) { QKeyEvent * kev ( static_cast < QKeyEvent * > ( event_n ) ); if ( kev->key() == Qt::Key_VolumeMute ) { toggle_switch_state(); res = true; } } } return res; } } // End of namespace qastools-v0.22.0/qasmixer/src/mwdg/mixer_sliders_proxy_switch.hpp000066400000000000000000000032101354534512100254070ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_mixer_sliders_proxy_switch_hpp__ #define __INC_mixer_sliders_proxy_switch_hpp__ #include "wdg/pad_proxy_switch.hpp" #include "qsnd/mixer_simple_elem.hpp" namespace MWdg { /// @brief Mixer_Sliders_Proxy_Switch /// class Mixer_Sliders_Proxy_Switch : public ::Wdg::Pad_Proxy_Switch { Q_OBJECT // Public methods public: Mixer_Sliders_Proxy_Switch ( ); ::QSnd::Mixer_Simple_Elem * mixer_simple_elem ( ) const; void set_mixer_simple_elem ( ::QSnd::Mixer_Simple_Elem * selem_n ); unsigned char snd_dir ( ) const; void set_snd_dir ( unsigned char dir_n ); unsigned int channel_idx ( ) const; void set_channel_idx ( unsigned int idx_n ); bool is_joined ( ) const; void set_is_joined ( bool flag_n ); bool eventFilter ( QObject * obj_n, QEvent * event_n ); // Public slots public slots: void update_value_from_source ( ); // Protected methods protected: void switch_state_changed ( ); // Private attributes private: ::QSnd::Mixer_Simple_Elem * _mixer_simple_elem; unsigned int _channel_idx; unsigned char _snd_dir; bool _is_joined; bool _alsa_updating; }; inline ::QSnd::Mixer_Simple_Elem * Mixer_Sliders_Proxy_Switch::mixer_simple_elem ( ) const { return _mixer_simple_elem; } inline unsigned char Mixer_Sliders_Proxy_Switch::snd_dir ( ) const { return _snd_dir; } inline unsigned int Mixer_Sliders_Proxy_Switch::channel_idx ( ) const { return _channel_idx; } inline bool Mixer_Sliders_Proxy_Switch::is_joined ( ) const { return _is_joined; } } // End of namespace #endif qastools-v0.22.0/qasmixer/src/mwdg/mixer_sliders_status_widget.cpp000066400000000000000000000074241354534512100255410ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "mixer_sliders_status_widget.hpp" #include "wdg/sliders_pad.hpp" #include namespace MWdg { Mixer_Sliders_Status_Widget::Mixer_Sliders_Status_Widget ( QWidget * parent_n ) : Slider_Status_Widget ( parent_n ), _proxy_slider ( 0 ) { } Mixer_Sliders_Status_Widget::~Mixer_Sliders_Status_Widget ( ) { } void Mixer_Sliders_Status_Widget::select_slider ( unsigned int grp_idx_n, unsigned int col_idx_n ) { if ( sliders_pad() != 0 ) { ::MWdg::Mixer_Sliders_Proxy_Slider * proxy_new ( _proxy_slider ); if ( grp_idx_n < sliders_pad()->num_proxies_groups() ) { ::Wdg::Pad_Proxies_Group * pgroup ( sliders_pad()->proxies_group ( grp_idx_n ) ); if ( col_idx_n < pgroup->num_sliders() ) { proxy_new = dynamic_cast < ::MWdg::Mixer_Sliders_Proxy_Slider * > ( pgroup->column ( col_idx_n )->slider_proxy() ); } } set_slider_proxy ( proxy_new ); } } void Mixer_Sliders_Status_Widget::proxy_destroyed ( ) { set_slider_proxy ( 0 ); } void Mixer_Sliders_Status_Widget::set_slider_proxy ( ::MWdg::Mixer_Sliders_Proxy_Slider * proxy_n ) { //::std::cout << "Mixer_Sliders_Status_Widget::set_slider_proxy " << proxy_n << "\n"; if ( _proxy_slider != proxy_n ) { // Disconnect previous proxy if ( _proxy_slider != 0 ) { if ( _proxy_slider->mixer_simple_elem() != 0 ) { disconnect ( _proxy_slider->mixer_simple_elem(), 0, this, 0 ); } disconnect ( _proxy_slider, 0, this, 0 ); } _proxy_slider = proxy_n; setup_values(); if ( _proxy_slider != 0 ) { if ( _proxy_slider->mixer_simple_elem() != 0 ) { connect ( _proxy_slider->mixer_simple_elem(), SIGNAL ( sig_values_changed() ), this, SLOT ( update_values() ) ); } connect ( _proxy_slider, SIGNAL ( destroyed ( QObject * ) ), this, SLOT ( proxy_destroyed() ) ); update_values(); } } } QString Mixer_Sliders_Status_Widget::elem_name ( ) const { QString res; if ( _proxy_slider != 0 ) { res = _proxy_slider->group_name(); if ( res != _proxy_slider->item_name() ) { res += " - "; res += _proxy_slider->item_name(); } } return res; } bool Mixer_Sliders_Status_Widget::elem_has_volume ( ) const { return ( _proxy_slider != 0 ); } bool Mixer_Sliders_Status_Widget::elem_has_dB ( ) const { bool res ( false ); if ( _proxy_slider != 0 ) { res = _proxy_slider->has_dB(); } return res; } long Mixer_Sliders_Status_Widget::elem_volume_value ( ) const { long res ( 0 ); if ( _proxy_slider != 0 ) { res = _proxy_slider->volume_value(); } return res; } void Mixer_Sliders_Status_Widget::elem_set_volume ( long value_n ) const { if ( _proxy_slider != 0 ) { _proxy_slider->set_volume_value ( value_n ); } } long Mixer_Sliders_Status_Widget::elem_volume_min ( ) const { long res ( 0 ); if ( _proxy_slider != 0 ) { res = _proxy_slider->volume_min(); } return res; } long Mixer_Sliders_Status_Widget::elem_volume_max ( ) const { long res ( 0 ); if ( _proxy_slider != 0 ) { res = _proxy_slider->volume_max(); } return res; } long Mixer_Sliders_Status_Widget::elem_dB_value ( ) const { long res ( 0 ); if ( _proxy_slider != 0 ) { res = _proxy_slider->dB_value(); } return res; } void Mixer_Sliders_Status_Widget::elem_set_nearest_dB ( long dB_value_n ) const { if ( _proxy_slider != 0 ) { const long vol_near ( _proxy_slider->ask_dB_vol_nearest ( dB_value_n ) ); _proxy_slider->set_volume_value ( vol_near ); } } long Mixer_Sliders_Status_Widget::elem_dB_min ( ) const { long res ( 0 ); if ( _proxy_slider != 0 ) { res = _proxy_slider->dB_min(); } return res; } long Mixer_Sliders_Status_Widget::elem_dB_max ( ) const { long res ( 0 ); if ( _proxy_slider != 0 ) { res = _proxy_slider->dB_max(); } return res; } } // End of namespace qastools-v0.22.0/qasmixer/src/mwdg/mixer_sliders_status_widget.hpp000066400000000000000000000030501354534512100255350ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_mixer_sliders_status_widget_hpp__ #define __INC_mixer_sliders_status_widget_hpp__ #include "mwdg/mixer_sliders_proxies_group.hpp" #include "mwdg/slider_status_widget.hpp" namespace MWdg { /// @brief Mixer_Sliders_Status_Widget /// class Mixer_Sliders_Status_Widget : public Slider_Status_Widget { Q_OBJECT // Public methods public: Mixer_Sliders_Status_Widget ( QWidget * parent_n = 0 ); ~Mixer_Sliders_Status_Widget ( ); ::MWdg::Mixer_Sliders_Proxy_Slider * proxy_slider ( ) const; // Element info QString elem_name ( ) const; bool elem_has_volume ( ) const; bool elem_has_dB ( ) const; long elem_volume_value ( ) const; void elem_set_volume ( long value_n ) const; long elem_volume_min ( ) const; long elem_volume_max ( ) const; long elem_dB_value ( ) const; void elem_set_nearest_dB ( long dB_value_n ) const; long elem_dB_min ( ) const; long elem_dB_max ( ) const; // Slider selection void select_slider ( unsigned int grp_idx_n, unsigned int col_idx_n ); // Protected slots protected slots: void proxy_destroyed ( ); // Protected methods protected: void set_slider_proxy ( ::MWdg::Mixer_Sliders_Proxy_Slider * proxy_n ); // Private attributes private: ::MWdg::Mixer_Sliders_Proxy_Slider * _proxy_slider; }; inline ::MWdg::Mixer_Sliders_Proxy_Slider * Mixer_Sliders_Status_Widget::proxy_slider ( ) const { return _proxy_slider; } } // End of namespace #endif qastools-v0.22.0/qasmixer/src/mwdg/mixer_switches.cpp000066400000000000000000000361271354534512100227610ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "mixer_switches.hpp" #include #include #include #include #include #include #include "qsnd/mixer_simple.hpp" #include "wdg/switches_area.hpp" #include "wdg/switches_pad.hpp" #include "wdg/pad_proxies_group.hpp" #include "wdg/pad_proxies_column.hpp" #include "mwdg/inputs_setup.hpp" #include "mwdg/mixer_simple_setup.hpp" #include "mwdg/event_types.hpp" #include "mwdg/mixer_switches_proxies_group.hpp" #include "mwdg/mixer_gui_state.hpp" #include namespace MWdg { Mixer_Switches::Mixer_Switches ( QWidget * parent_n ) : QWidget ( parent_n ), _mixer_setup ( 0 ), _inputs_setup ( 0 ), _separation_requested ( false ), _act_toggle_joined ( this ) { _switches_area = new ::Wdg::Switches_Area; _switches_area->setFrameStyle ( QFrame::NoFrame ); _switches_pad = new ::Wdg::Switches_Pad; _switches_pad->hide(); _switches_pad->installEventFilter ( this ); connect ( _switches_pad, SIGNAL ( sig_focus_changed() ), this, SLOT ( update_focus_proxies() ) ); // Actions _act_toggle_joined.setIcon ( QIcon::fromTheme ( "object-flip-horizontal" ) ); connect ( &_act_toggle_joined, SIGNAL ( triggered ( bool ) ), this, SLOT ( action_toggle_joined() ) ); // Context menu _cmenu.addAction ( &_act_toggle_joined ); // Center widget layout { QVBoxLayout * lay_vbox = new QVBoxLayout(); lay_vbox->setContentsMargins ( 0, 0, 0, 0 ); lay_vbox->addWidget ( _switches_area ); setLayout ( lay_vbox ); } } Mixer_Switches::~Mixer_Switches ( ) { set_mixer_setup ( 0 ); delete _switches_pad; delete _switches_area; } void Mixer_Switches::set_mixer_setup ( const Mixer_Simple_Setup * setup_n ) { _cmenu.close(); if ( mixer_setup() != 0 ) { if ( mixer_setup()->mixer_simple != 0 ) { disconnect ( mixer_setup()->mixer_simple, 0, this, 0 ); show_visible_proxies_sets ( false ); clear_proxies_groups(); } } _mixer_setup = setup_n; if ( mixer_setup() != 0 ) { if ( mixer_setup()->mixer_simple != 0 ) { create_proxies_groups(); rebuild_visible_proxies_list(); show_visible_proxies_sets ( true ); } } } void Mixer_Switches::set_inputs_setup ( const ::MWdg::Inputs_Setup * setup_n ) { _inputs_setup = setup_n; if ( inputs_setup() != 0 ) { _act_toggle_joined.setShortcut ( inputs_setup()->ks_toggle_joined ); } } void Mixer_Switches::show_visible_proxies_sets ( bool flag_n ) { if ( flag_n ) { if ( _proxies_groups_vis.size() > 0 ) { _switches_pad->set_proxies_groups ( _proxies_groups_pass ); _switches_area->set_widget ( _switches_pad ); _switches_pad->setAutoFillBackground ( false ); _switches_pad->show(); } updateGeometry(); } else { if ( _proxies_groups_vis.size() > 0 ) { _switches_pad->hide(); _switches_area->take_widget(); _switches_pad->clear_proxies_groups(); } } } void Mixer_Switches::clear_proxies_groups ( ) { for ( int ii=0; ii < _proxies_groups.size(); ++ii ) { delete _proxies_groups[ii]; } _proxies_groups.clear(); _proxies_groups_vis.clear(); _proxies_groups_pass.clear(); } void Mixer_Switches::create_proxies_groups ( ) { ::QSnd::Mixer_Simple * snd_mixer ( 0 ); if ( mixer_setup() != 0 ) { snd_mixer = mixer_setup()->mixer_simple; } if ( snd_mixer == 0 ) { return; } //::std::cout << "Mixer_Switches::init_widgets\n"; QString ttip; for ( unsigned int ii=0; ii < snd_mixer->num_elems(); ++ii ) { ::QSnd::Mixer_Simple_Elem * qsme ( snd_mixer->elem ( ii ) ); // Types means either enum or switch for ( unsigned int itype=0; itype < 2; ++itype ) { for ( unsigned int snd_dir=0; snd_dir < 2; ++snd_dir ) { if ( qsme->has_volume( snd_dir ) ) { continue; } bool cr_enum ( itype == 0 ); bool cr_switch ( itype == 1 ); if ( ( cr_enum && qsme->has_enum ( snd_dir ) ) || ( cr_switch && qsme->has_switch ( snd_dir ) ) ) { ::MWdg::Mixer_Switches_Proxies_Group * mspg ( new ::MWdg::Mixer_Switches_Proxies_Group ( this ) ); mspg->set_mixer_simple_elem ( qsme ); mspg->set_snd_dir ( snd_dir ); mspg->set_group_name ( qsme->display_name() ); { ttip = "
"; ttip += mspg->group_name(); ttip += "
\n"; mspg->set_tool_tip ( ttip ); } if ( mspg->should_be_separated() ) { setup_proxies_group_separate ( mspg ); } else { setup_proxies_group_joined ( mspg ); } if ( mspg->num_columns() > 0 ) { _proxies_groups.append ( mspg ); } else { delete mspg; } } } } } } void Mixer_Switches::setup_proxies_group_joined ( ::MWdg::Mixer_Switches_Proxies_Group * mspg_n ) { const ::QSnd::Mixer_Simple_Elem * qsme ( mspg_n->mixer_simple_elem() ); const unsigned int snd_dir ( mspg_n->snd_dir() ); mspg_n->clear_columns(); mspg_n->set_is_joined ( true ); unsigned int num_channels ( 0 ); if ( qsme->has_switch ( snd_dir ) ) { num_channels = qsme->num_switch_channels ( snd_dir ); } else if ( qsme->has_enum ( snd_dir ) ) { num_channels = qsme->num_enum_channels ( snd_dir ); } if ( num_channels > 0 ) { create_proxy ( mspg_n, 0 ); } mspg_n->update_mixer_values(); } void Mixer_Switches::setup_proxies_group_separate ( ::MWdg::Mixer_Switches_Proxies_Group * mspg_n ) { const ::QSnd::Mixer_Simple_Elem * qsme ( mspg_n->mixer_simple_elem() ); const unsigned int snd_dir ( mspg_n->snd_dir() ); mspg_n->clear_columns(); mspg_n->set_is_joined ( false ); unsigned int num_channels ( 0 ); if ( qsme->has_switch ( snd_dir ) ) { num_channels = qsme->num_switch_channels ( snd_dir ); } else if ( qsme->has_enum ( snd_dir ) ) { num_channels = qsme->num_enum_channels ( snd_dir ); } for ( unsigned int ii=0; ii < num_channels; ++ii ) { create_proxy ( mspg_n, ii ); } mspg_n->update_mixer_values(); } void Mixer_Switches::create_proxy ( ::MWdg::Mixer_Switches_Proxies_Group * mspg_n, int channel_idx_n ) { ::QSnd::Mixer_Simple_Elem * qsme ( mspg_n->mixer_simple_elem() ); const unsigned int snd_dir ( mspg_n->snd_dir() ); QString iname; if ( mspg_n->is_joined() ) { iname = mspg_n->group_name(); } else { iname = tr ( "%1 (%2)" ); iname = iname.arg ( QCoreApplication::translate ( "ALSA::Channel_Name", qsme->channel_name ( snd_dir, channel_idx_n ) ) ); iname = iname.arg ( qsme->channel ( snd_dir, channel_idx_n ) ); } QString ttip; ttip += "
"; ttip += mspg_n->group_name(); ttip += "
\n"; ttip += "
"; if ( snd_dir == 0 ) { if ( qsme->has_enum ( snd_dir ) ) { ttip += tr ( "Playback selection" ); } else { ttip += tr ( "Playback switch" ); } } else { if ( qsme->has_enum ( snd_dir ) ) { ttip += tr ( "Capture selection" ); } else { ttip += tr ( "Capture switch" ); } } ttip += "
\n"; if ( !mspg_n->is_joined() ) { ttip += "
"; ttip += iname; ttip += "
"; } ::Wdg::Pad_Proxies_Column * sppc ( new ::Wdg::Pad_Proxies_Column ); if ( qsme->has_enum ( snd_dir ) ) { ::MWdg::Mixer_Switches_Proxy_Enum * msp ( new ::MWdg::Mixer_Switches_Proxy_Enum ); msp->set_mixer_simple_elem ( qsme ); msp->set_snd_dir ( snd_dir ); msp->set_is_joined ( mspg_n->is_joined() ); msp->set_channel_idx ( channel_idx_n ); msp->set_enum_num_items ( qsme->enum_item_names().size() ); msp->set_item_name ( iname ); msp->set_tool_tip ( ttip ); sppc->set_enum_proxy ( msp ); } else if ( qsme->has_switch ( snd_dir ) ) { ::MWdg::Mixer_Switches_Proxy_Switch * msp ( new ::MWdg::Mixer_Switches_Proxy_Switch ); msp->set_mixer_simple_elem ( qsme ); msp->set_snd_dir ( snd_dir ); msp->set_is_joined ( mspg_n->is_joined() ); msp->set_channel_idx ( channel_idx_n ); msp->set_item_name ( iname ); msp->set_tool_tip ( ttip ); sppc->set_switch_proxy ( msp ); } else { delete sppc; sppc = 0; } if ( sppc != 0 ) { mspg_n->append_column ( sppc ); } } bool Mixer_Switches::should_be_visible ( const ::MWdg::Mixer_Switches_Proxies_Group * mspg_n ) const { const ::QSnd::Mixer_Simple_Elem * qsme ( mspg_n->mixer_simple_elem() ); const unsigned int snd_dir ( mspg_n->snd_dir() % 2 ); return ( qsme->is_active() && mixer_setup()->show_stream[snd_dir] ); } void Mixer_Switches::rebuild_visible_proxies_list ( ) { _proxies_groups_vis.clear(); _proxies_groups_pass.clear(); for ( int ii=0; ii < _proxies_groups.size(); ++ii ) { ::MWdg::Mixer_Switches_Proxies_Group * mspg ( _proxies_groups[ii] ); mspg->set_is_visible ( should_be_visible ( mspg ) ); if ( mspg->is_visible() ) { // Separate on demand if ( mspg->needs_separation() ) { separate_proxies_group ( mspg ); } _proxies_groups_vis.append ( mspg ); _proxies_groups_pass.append ( mspg ); } } } void Mixer_Switches::update_focus_proxies ( ) { if ( _switches_pad->focus_info().has_focus ) { // Find focus proxies_group const int idx ( _switches_pad->focus_info().group_idx ); if ( idx < _proxies_groups_vis.size() ) { _act_proxies_group = _proxies_groups_vis[idx]; _act_proxies_column = _switches_pad->focus_info().column_idx; } } } void Mixer_Switches::acquire_gui_state ( ::MWdg::Mixer_GUI_State_Proxy & state_n ) { if ( _act_proxies_group != 0 ) { ::MWdg::Mixer_Switches_Proxies_Group * mspg ( _act_proxies_group ); state_n.group_name = mspg->group_name(); state_n.snd_dir = mspg->snd_dir(); state_n.column_idx = mspg->focus_column(); state_n.has_focus = _switches_pad->focus_info().has_focus; } } void Mixer_Switches::restore_gui_state ( const ::MWdg::Mixer_GUI_State_Proxy & state_n ) { { _act_proxies_group = find_visible_proxy ( state_n ); _act_proxies_column = state_n.column_idx; } // Restore focus if ( state_n.has_focus ) { if ( _act_proxies_group != 0 ) { _switches_pad->set_focus_proxy ( _act_proxies_group->group_index(), state_n.column_idx ); } } if ( _cmenu.isVisible() ) { context_menu_update(); } } Mixer_Switches_Proxies_Group * Mixer_Switches::find_visible_proxy ( const Mixer_GUI_State_Proxy & prox_id_n ) { ::MWdg::Mixer_Switches_Proxies_Group * mspg_res ( 0 ); if ( !prox_id_n.is_clear() ) { for ( int ii=0; ii < _proxies_groups_vis.size(); ++ii ) { ::MWdg::Mixer_Switches_Proxies_Group * mspg ( _proxies_groups_vis[ii] ); if ( ( mspg->group_name() == prox_id_n.group_name ) && ( mspg->snd_dir() == prox_id_n.snd_dir ) ) { mspg_res = mspg; break; } } } return mspg_res; } void Mixer_Switches::action_toggle_joined ( ) { //::std::cout << "Mixer_Switches::action_toggle_joined" << "\n"; if ( _act_proxies_group != 0 ) { toggle_joined_separated ( _act_proxies_group ); } } void Mixer_Switches::toggle_joined_separated ( ::MWdg::Mixer_Switches_Proxies_Group * mspg_n ) { if ( mspg_n == 0 ) { return; } if ( !mspg_n->can_be_separated() ) { return; } ::MWdg::Mixer_GUI_State_Proxy proxy_state; acquire_gui_state ( proxy_state ); show_visible_proxies_sets ( false ); if ( mspg_n->is_joined() ) { separate_proxies_group ( mspg_n ); } else { join_proxies_group ( mspg_n ); } show_visible_proxies_sets ( true ); restore_gui_state ( proxy_state ); } void Mixer_Switches::join_proxies_group ( ::MWdg::Mixer_Switches_Proxies_Group * mspg_n ) { if ( !mspg_n->is_joined() ) { ::QSnd::Mixer_Simple_Elem * qsme ( mspg_n->mixer_simple_elem() ); qsme->level_switches ( mspg_n->snd_dir() ); setup_proxies_group_joined ( mspg_n ); if ( _cmenu.isVisible() ) { context_menu_update(); } } } void Mixer_Switches::separate_proxies_group ( ::MWdg::Mixer_Switches_Proxies_Group * mspg_n ) { if ( mspg_n->is_joined() && mspg_n->can_be_separated() ) { setup_proxies_group_separate ( mspg_n ); if ( _cmenu.isVisible() ) { context_menu_update(); } } } void Mixer_Switches::separate_where_requested ( ) { bool visible_request ( false ); for ( int ii=0; ii < _proxies_groups_vis.size(); ++ii ) { ::MWdg::Mixer_Switches_Proxies_Group * mspg ( _proxies_groups_vis[ii] ); if ( mspg->separation_request() ) { visible_request = true; break; } } if ( visible_request ) { ::MWdg::Mixer_GUI_State_Proxy proxy_state; acquire_gui_state ( proxy_state ); show_visible_proxies_sets ( false ); for ( int ii=0; ii < _proxies_groups_vis.size(); ++ii ) { ::MWdg::Mixer_Switches_Proxies_Group * mspg ( _proxies_groups_vis[ii] ); if ( mspg->separation_request() ) { mspg->set_separation_request ( false ); separate_proxies_group ( mspg ); } } show_visible_proxies_sets ( true ); restore_gui_state ( proxy_state ); } } bool Mixer_Switches::context_menu_start ( const QPoint & pos_n ) { bool res ( false ); if ( !_cmenu.isVisible() && ( _switches_pad->focus_info().has_focus ) && ( _act_proxies_group != 0 ) ) { if ( context_menu_update() > 0 ) { _act_proxies_group->set_notify_value_change ( true ); _cmenu.setTitle ( _act_proxies_group->group_name() ); _cmenu.popup ( pos_n ); res = true; } } return res; } void Mixer_Switches::context_menu_cleanup_behind ( ) { if ( _act_proxies_group != 0 ) { _act_proxies_group->set_notify_value_change ( false ); } } unsigned int Mixer_Switches::context_menu_update ( ) { unsigned int act_vis ( 0 ); ::MWdg::Mixer_Switches_Proxies_Group * mspg ( _act_proxies_group ); if ( mspg == 0 ) { _cmenu.close(); return act_vis; } const ::QSnd::Mixer_Simple_Elem * qsme ( mspg->mixer_simple_elem() ); // Split/Join and level channels { const bool vis_separate ( qsme->num_channels ( mspg->snd_dir() ) > 1 ); _act_toggle_joined.setVisible ( vis_separate ); if ( vis_separate ) { if ( inputs_setup() != 0 ) { const QString * str; if ( mspg->num_columns() <= 1 ) { str = &inputs_setup()->ts_split_channels; } else { str = &inputs_setup()->ts_join_channels; } _act_toggle_joined.setText ( *str ); } ++act_vis; } } if ( act_vis == 0 ) { _cmenu.close(); } return act_vis; } bool Mixer_Switches::eventFilter ( QObject * watched_n, QEvent * event_n ) { bool filtered ( false ); if ( watched_n == _switches_pad ) { if ( event_n->type() == QEvent::KeyPress ) { if ( inputs_setup() != 0 ) { filtered = true; const QKeySequence kseq ( static_cast < QKeyEvent * > ( event_n )->key() ); if ( kseq == inputs_setup()->ks_toggle_joined ) { _act_toggle_joined.trigger(); } else { filtered = false; } } } else if ( event_n->type() == QEvent::ContextMenu ) { //::std::cout << "Mixer_Switches::eventFilter: QContextMenuEvent\n"; QContextMenuEvent * ev_cmenu ( static_cast < QContextMenuEvent * > ( event_n ) ); if ( context_menu_start ( ev_cmenu->globalPos() ) ) { filtered = true; } } } return filtered; } bool Mixer_Switches::event ( QEvent * event_n ) { bool res ( true ); if ( event_n->type() == ::MWdg::evt_separation_request ) { if ( !_separation_requested ) { _separation_requested = true; QCoreApplication::postEvent ( this, new QEvent ( ::MWdg::evt_separation ) ); } } else if ( event_n->type() == ::MWdg::evt_separation ) { _separation_requested = false; separate_where_requested(); } else if ( event_n->type() == ::MWdg::evt_values_changed ) { context_menu_update(); } else { res = QWidget::event ( event_n ); } return res; } } // End of namespace qastools-v0.22.0/qasmixer/src/mwdg/mixer_switches.hpp000066400000000000000000000077671354534512100227760ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_mwdg_mixer_switches_hpp__ #define __INC_mwdg_mixer_switches_hpp__ #include #include #include #include // Forward declaration namespace MWdg { class Inputs_Setup; class Mixer_Simple_Setup; class Mixer_Switches_Proxies_Group; class Mixer_GUI_State_Proxy; } namespace Wdg { class Switches_Pad; class Pad_Proxy; class Pad_Proxies_Column; class Pad_Proxies_Group; class Switches_Area; } namespace MWdg { /// @brief Mixer_Switches /// class Mixer_Switches : public QWidget { Q_OBJECT // Public methods public: Mixer_Switches ( QWidget * parent_n = 0 ); ~Mixer_Switches ( ); // Mixer setup const Mixer_Simple_Setup * mixer_setup ( ) const; void set_mixer_setup ( const Mixer_Simple_Setup * setup_n ); // Inputs setup const ::MWdg::Inputs_Setup * inputs_setup ( ) const; void set_inputs_setup ( const ::MWdg::Inputs_Setup * setup_n ); unsigned int num_visible ( ) const; // Event handling bool event ( QEvent * event_n ); // Protected slots protected slots: void action_toggle_joined ( ); void update_focus_proxies ( ); void context_menu_cleanup_behind ( ); // Protected methods protected: // Proxy group creation / deletion void clear_proxies_groups ( ); void create_proxies_groups ( ); void setup_proxies_group_joined ( ::MWdg::Mixer_Switches_Proxies_Group * mspg_n ); void setup_proxies_group_separate ( ::MWdg::Mixer_Switches_Proxies_Group * mspg_n ); void create_proxy ( ::MWdg::Mixer_Switches_Proxies_Group * mspg_n, int channel_idx_n ); // Proxy group manipulation bool should_be_visible ( const ::MWdg::Mixer_Switches_Proxies_Group * mspg_n ) const; void toggle_joined_separated ( ::MWdg::Mixer_Switches_Proxies_Group * mspg_n ); void join_proxies_group ( ::MWdg::Mixer_Switches_Proxies_Group * mspg_n ); void separate_proxies_group ( ::MWdg::Mixer_Switches_Proxies_Group * mspg_n ); // Proxy group showing hiding void show_visible_proxies_sets ( bool flag_n ); // Proxy group updating void separate_where_requested ( ); void rebuild_visible_proxies_list ( ); // Focus proxy void acquire_gui_state ( ::MWdg::Mixer_GUI_State_Proxy & state_n ); void restore_gui_state ( const ::MWdg::Mixer_GUI_State_Proxy & state_n ); ::MWdg::Mixer_Switches_Proxies_Group * find_visible_proxy ( const ::MWdg::Mixer_GUI_State_Proxy & prox_id_n ); // Context menu bool context_menu_start ( const QPoint & pos_n ); unsigned int context_menu_update ( ); // Event callbacks bool eventFilter ( QObject * watched, QEvent * event ); /// @brief Switches pad getter /// const ::Wdg::Switches_Pad * switches_pad ( ) const; /// @brief Switches pad getter /// ::Wdg::Switches_Pad * switches_pad ( ); // Private attributes private: const ::MWdg::Mixer_Simple_Setup * _mixer_setup; const ::MWdg::Inputs_Setup * _inputs_setup; QList < ::MWdg::Mixer_Switches_Proxies_Group * > _proxies_groups; QList < ::MWdg::Mixer_Switches_Proxies_Group * > _proxies_groups_vis; QList < ::Wdg::Pad_Proxies_Group * > _proxies_groups_pass; ::Wdg::Switches_Area * _switches_area; ::Wdg::Switches_Pad * _switches_pad; // Flags bool _separation_requested; // Action focus proxy QPointer < ::MWdg::Mixer_Switches_Proxies_Group > _act_proxies_group; unsigned int _act_proxies_column; // Context menu QMenu _cmenu; QAction _act_toggle_joined; }; inline const Mixer_Simple_Setup * Mixer_Switches::mixer_setup ( ) const { return _mixer_setup; } inline const ::MWdg::Inputs_Setup * Mixer_Switches::inputs_setup ( ) const { return _inputs_setup; } inline unsigned int Mixer_Switches::num_visible ( ) const { return _proxies_groups_vis.size(); } inline const ::Wdg::Switches_Pad * Mixer_Switches::switches_pad ( ) const { return _switches_pad; } inline Wdg::Switches_Pad * Mixer_Switches::switches_pad ( ) { return _switches_pad; } } // End of namespace #endif qastools-v0.22.0/qasmixer/src/mwdg/mixer_switches_proxies_group.cpp000066400000000000000000000072611354534512100257430ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "mixer_switches_proxies_group.hpp" #include "wdg/pad_proxies_column.hpp" #include "mwdg/event_types.hpp" #include #include namespace MWdg { Mixer_Switches_Proxies_Group::Mixer_Switches_Proxies_Group ( QObject * parent_n ) : Wdg::Pad_Proxies_Group ( parent_n ), _mixer_simple_elem ( 0 ), _snd_dir ( 0 ), _is_joined ( false ), _is_visible ( false ), _notify_value_change ( false ), _separation_request ( false ) { // Separation timer _separation_timer.setSingleShot ( true ); _separation_timer.setInterval ( 550 ); connect ( &_separation_timer, SIGNAL ( timeout() ), this, SLOT ( timer_separation_check() ) ); } void Mixer_Switches_Proxies_Group::set_mixer_simple_elem ( ::QSnd::Mixer_Simple_Elem * selem_n ) { if ( mixer_simple_elem() != 0 ) { disconnect ( mixer_simple_elem(), 0, this, 0 ); } _mixer_simple_elem = selem_n; if ( mixer_simple_elem() != 0 ) { connect ( mixer_simple_elem(), SIGNAL ( sig_values_changed() ), this, SLOT ( update_mixer_values() ) ); } } void Mixer_Switches_Proxies_Group::set_snd_dir ( unsigned char dir_n ) { _snd_dir = dir_n; } void Mixer_Switches_Proxies_Group::set_is_joined ( bool flag_n ) { _is_joined = flag_n; } void Mixer_Switches_Proxies_Group::set_is_visible ( bool flag_n ) { _is_visible = flag_n; } void Mixer_Switches_Proxies_Group::set_notify_value_change ( bool flag_n ) { _notify_value_change = flag_n; } void Mixer_Switches_Proxies_Group::set_separation_request ( bool flag_n ) { _separation_request = flag_n; } bool Mixer_Switches_Proxies_Group::can_be_separated ( ) const { if ( mixer_simple_elem() != 0 ) { return ( mixer_simple_elem()->num_channels ( snd_dir() ) > 1 ); } return false; } bool Mixer_Switches_Proxies_Group::should_be_separated ( ) const { bool res ( false ); ::QSnd::Mixer_Simple_Elem * sme ( mixer_simple_elem() ); if ( sme != 0 ) { res = ( ( sme->num_switch_channels ( snd_dir() ) > 1 ) && !sme->switches_equal ( snd_dir() ) ) || ( ( sme->num_enum_channels ( snd_dir() ) > 1 ) && !sme->enums_equal ( snd_dir() ) ); } return res; } bool Mixer_Switches_Proxies_Group::needs_separation ( ) const { bool res ( false ); ::QSnd::Mixer_Simple_Elem * sme ( mixer_simple_elem() ); if ( sme != 0 ) { res = is_joined() && ( ( ( sme->num_switch_channels ( snd_dir() ) > 1 ) && !sme->switches_equal ( snd_dir() ) ) || ( ( sme->num_enum_channels ( snd_dir() ) > 1 ) && !sme->enums_equal ( snd_dir() ) ) ); } return res; } void Mixer_Switches_Proxies_Group::update_mixer_values ( ) { for ( unsigned int ii=0; ii < num_columns(); ++ii ) { ::Wdg::Pad_Proxies_Column * col ( column ( ii ) ); if ( col->enum_proxy() != 0 ) { col->enum_proxy()->update_value_from_source(); } if ( col->switch_proxy() != 0 ) { col->switch_proxy()->update_value_from_source(); } } // Check for needed separation if ( needs_separation() ) { if ( !_separation_timer.isActive() ) { _separation_timer.start(); } } else { if ( _separation_timer.isActive() ) { _separation_timer.stop(); } } // Notify parent on demand if ( notify_value_change() && ( parent() != 0 ) ) { QEvent ev_req ( ::MWdg::evt_values_changed ); QCoreApplication::sendEvent ( parent(), &ev_req ); } } void Mixer_Switches_Proxies_Group::timer_separation_check ( ) { //::std::cout << "Mixer_Switches_Proxies_Group::timer_separation_check\n"; if ( parent() != 0 ) { if ( needs_separation() ) { set_separation_request ( true ); // Notify parent QEvent ev_req ( ::MWdg::evt_separation_request ); QCoreApplication::sendEvent ( parent(), &ev_req ); } } } } // End of namespace qastools-v0.22.0/qasmixer/src/mwdg/mixer_switches_proxies_group.hpp000066400000000000000000000046541354534512100257530ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_mixer_switches_proxy_group_hpp__ #define __INC_mixer_switches_proxy_group_hpp__ #include #include #include #include #include "wdg/pad_proxies_group.hpp" #include "mixer_switches_proxy_enum.hpp" #include "mixer_switches_proxy_switch.hpp" #include "mixer_separation_info.hpp" namespace MWdg { /// @brief Mixer_Switches_Proxies_Group /// class Mixer_Switches_Proxies_Group : public ::Wdg::Pad_Proxies_Group { Q_OBJECT // Public methods public: Mixer_Switches_Proxies_Group ( QObject * parent_n = 0 ); // Mixer_Simple_Elem ::QSnd::Mixer_Simple_Elem * mixer_simple_elem ( ) const; virtual void set_mixer_simple_elem ( ::QSnd::Mixer_Simple_Elem * selem_n ); // Snd direction unsigned char snd_dir ( ) const; void set_snd_dir ( unsigned char dir_n ); // Is joined flag bool is_joined ( ) const; void set_is_joined ( bool flag_n ); // Is visible flag bool is_visible ( ) const; void set_is_visible ( bool flag_n ); // Notify value change bool notify_value_change ( ) const; void set_notify_value_change ( bool flag_n ); // Separation info bool can_be_separated ( ) const; bool should_be_separated ( ) const; bool needs_separation ( ) const; bool separation_request ( ) const; void set_separation_request ( bool flag_n ); // Public slots public slots: void update_mixer_values ( ); // Protected slots protected slots: void timer_separation_check ( ); // Private attributes private: ::QSnd::Mixer_Simple_Elem * _mixer_simple_elem; unsigned char _snd_dir; bool _is_joined; bool _is_visible; bool _notify_value_change; bool _separation_request; QTimer _separation_timer; }; inline ::QSnd::Mixer_Simple_Elem * Mixer_Switches_Proxies_Group::mixer_simple_elem ( ) const { return _mixer_simple_elem; } inline unsigned char Mixer_Switches_Proxies_Group::snd_dir ( ) const { return _snd_dir; } inline bool Mixer_Switches_Proxies_Group::is_joined ( ) const { return _is_joined; } inline bool Mixer_Switches_Proxies_Group::is_visible ( ) const { return _is_visible; } inline bool Mixer_Switches_Proxies_Group::notify_value_change ( ) const { return _notify_value_change; } inline bool Mixer_Switches_Proxies_Group::separation_request ( ) const { return _separation_request; } } // End of namespace #endif qastools-v0.22.0/qasmixer/src/mwdg/mixer_switches_proxy_enum.cpp000066400000000000000000000035061354534512100252410ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "mixer_switches_proxy_enum.hpp" #include namespace MWdg { Mixer_Switches_Proxy_Enum::Mixer_Switches_Proxy_Enum ( ) : _mixer_simple_elem ( 0 ), _channel_idx ( 0 ), _snd_dir ( 0 ), _is_joined ( false ), _alsa_updating ( false ) { } void Mixer_Switches_Proxy_Enum::set_snd_dir ( unsigned char dir_n ) { _snd_dir = dir_n; } void Mixer_Switches_Proxy_Enum::set_channel_idx ( unsigned int idx_n ) { _channel_idx = idx_n; } void Mixer_Switches_Proxy_Enum::set_mixer_simple_elem ( ::QSnd::Mixer_Simple_Elem * selem_n ) { _mixer_simple_elem = selem_n; } void Mixer_Switches_Proxy_Enum::set_is_joined ( bool flag_n ) { _is_joined = flag_n; } QString Mixer_Switches_Proxy_Enum::enum_item_name ( int idx_n ) { QString res; if ( mixer_simple_elem() != 0 ) { if ( static_cast < unsigned int > ( idx_n ) < mixer_simple_elem()->enum_item_names().size() ) { res = mixer_simple_elem()->enum_item_names()[idx_n]; } } return res; } void Mixer_Switches_Proxy_Enum::enum_index_changed ( ) { if ( ( mixer_simple_elem() != 0 ) && ( !_alsa_updating ) ) { //::std::cout << "Mixer_Switches_Proxy_Enum::enum_index_changed " << enum_index() << "\n"; if ( is_joined() ) { mixer_simple_elem()->set_enum_index_all ( snd_dir(), enum_index() ); } else { mixer_simple_elem()->set_enum_index ( snd_dir(), channel_idx(), enum_index() ); } //::std::cout << "Mixer_Switches_Proxy_Enum::enum_index_changed " << "done" << "\n"; } } void Mixer_Switches_Proxy_Enum::update_value_from_source ( ) { if ( ( mixer_simple_elem() != 0 ) && ( !_alsa_updating ) ) { _alsa_updating = true; set_enum_index ( mixer_simple_elem()->enum_index ( snd_dir() , channel_idx() ) ); _alsa_updating = false; } } } // End of namespace qastools-v0.22.0/qasmixer/src/mwdg/mixer_switches_proxy_enum.hpp000066400000000000000000000031701354534512100252430ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_mixer_switches_proxy_enum_hpp__ #define __INC_mixer_switches_proxy_enum_hpp__ #include "wdg/pad_proxy_enum.hpp" #include "qsnd/mixer_simple_elem.hpp" namespace MWdg { /// @brief Mixer_Switches_Proxy_Enum /// class Mixer_Switches_Proxy_Enum : public ::Wdg::Pad_Proxy_Enum { Q_OBJECT // Public methods public: Mixer_Switches_Proxy_Enum ( ); ::QSnd::Mixer_Simple_Elem * mixer_simple_elem ( ) const; void set_mixer_simple_elem ( ::QSnd::Mixer_Simple_Elem * selem_n ); unsigned char snd_dir ( ) const; void set_snd_dir ( unsigned char dir_n ); unsigned int channel_idx ( ) const; void set_channel_idx ( unsigned int idx_n ); // Is joined flag bool is_joined ( ) const; void set_is_joined ( bool flag_n ); QString enum_item_name ( int idx_n ); // Public slots public slots: void update_value_from_source ( ); // Protected methods protected: void enum_index_changed ( ); // Private attributes private: ::QSnd::Mixer_Simple_Elem * _mixer_simple_elem; unsigned int _channel_idx; unsigned char _snd_dir; bool _is_joined; bool _alsa_updating; }; inline ::QSnd::Mixer_Simple_Elem * Mixer_Switches_Proxy_Enum::mixer_simple_elem ( ) const { return _mixer_simple_elem; } inline unsigned char Mixer_Switches_Proxy_Enum::snd_dir ( ) const { return _snd_dir; } inline unsigned int Mixer_Switches_Proxy_Enum::channel_idx ( ) const { return _channel_idx; } inline bool Mixer_Switches_Proxy_Enum::is_joined ( ) const { return _is_joined; } } // End of namespace #endif qastools-v0.22.0/qasmixer/src/mwdg/mixer_switches_proxy_switch.cpp000066400000000000000000000037311354534512100255760ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "mixer_switches_proxy_switch.hpp" #include #include namespace MWdg { Mixer_Switches_Proxy_Switch::Mixer_Switches_Proxy_Switch ( ) : _mixer_simple_elem ( 0 ), _channel_idx ( 0 ), _snd_dir ( 0 ), _is_joined ( false ), _alsa_updating ( false ) { } void Mixer_Switches_Proxy_Switch::set_snd_dir ( unsigned char dir_n ) { _snd_dir = dir_n; } void Mixer_Switches_Proxy_Switch::set_channel_idx ( unsigned int idx_n ) { _channel_idx = idx_n; } void Mixer_Switches_Proxy_Switch::set_mixer_simple_elem ( ::QSnd::Mixer_Simple_Elem * selem_n ) { _mixer_simple_elem = selem_n; } void Mixer_Switches_Proxy_Switch::set_is_joined ( bool flag_n ) { _is_joined = flag_n; } void Mixer_Switches_Proxy_Switch::switch_state_changed ( ) { if ( ( mixer_simple_elem() != 0 ) && ( !_alsa_updating ) ) { //::std::cout << "Mixer_Switches_Proxy_Switch::switch_state_changed " << switch_state() << "\n"; if ( is_joined() ) { mixer_simple_elem()->set_switch_all ( snd_dir(), switch_state() ); } else { mixer_simple_elem()->set_switch ( snd_dir(), channel_idx(), switch_state() ); } //::std::cout << "Mixer_Switches_Proxy_Switch::switch_state_changed " << "done" << "\n"; } } void Mixer_Switches_Proxy_Switch::update_value_from_source ( ) { if ( ( mixer_simple_elem() != 0 ) && ( !_alsa_updating ) ) { _alsa_updating = true; set_switch_state ( mixer_simple_elem()->switch_state ( snd_dir(), channel_idx() ) ); _alsa_updating = false; } } bool Mixer_Switches_Proxy_Switch::eventFilter ( QObject * obj_n, QEvent * event_n ) { bool res ( Pad_Proxy_Switch::eventFilter ( obj_n, event_n ) ); if ( !res ) { if ( event_n->type() == QEvent::KeyPress ) { QKeyEvent * kev ( static_cast < QKeyEvent * > ( event_n ) ); if ( kev->key() == Qt::Key_VolumeMute ) { toggle_switch_state(); res = true; } } } return res; } } // End of namespace qastools-v0.22.0/qasmixer/src/mwdg/mixer_switches_proxy_switch.hpp000066400000000000000000000032471354534512100256050ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_mixer_switches_proxy_switch_hpp__ #define __INC_mixer_switches_proxy_switch_hpp__ #include "wdg/pad_proxy_switch.hpp" #include "qsnd/mixer_simple_elem.hpp" namespace MWdg { /// @brief Mixer_Switches_Proxy_Switch /// class Mixer_Switches_Proxy_Switch : public ::Wdg::Pad_Proxy_Switch { Q_OBJECT // Public methods public: Mixer_Switches_Proxy_Switch ( ); ::QSnd::Mixer_Simple_Elem * mixer_simple_elem ( ) const; void set_mixer_simple_elem ( ::QSnd::Mixer_Simple_Elem * selem_n ); unsigned char snd_dir ( ) const; void set_snd_dir ( unsigned char dir_n ); unsigned int channel_idx ( ) const; void set_channel_idx ( unsigned int idx_n ); // Is joined flag bool is_joined ( ) const; void set_is_joined ( bool flag_n ); bool eventFilter ( QObject * obj_n, QEvent * event_n ); // Public slots public slots: void update_value_from_source ( ); // Protected methods protected: void switch_state_changed ( ); // Private attributes private: ::QSnd::Mixer_Simple_Elem * _mixer_simple_elem; unsigned int _channel_idx; unsigned char _snd_dir; bool _is_joined; bool _alsa_updating; }; inline ::QSnd::Mixer_Simple_Elem * Mixer_Switches_Proxy_Switch::mixer_simple_elem ( ) const { return _mixer_simple_elem; } inline unsigned char Mixer_Switches_Proxy_Switch::snd_dir ( ) const { return _snd_dir; } inline unsigned int Mixer_Switches_Proxy_Switch::channel_idx ( ) const { return _channel_idx; } inline bool Mixer_Switches_Proxy_Switch::is_joined ( ) const { return _is_joined; } } // End of namespace #endif qastools-v0.22.0/qasmixer/src/tray_mixer.cpp000066400000000000000000000207101354534512100211400ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "tray_mixer.hpp" #include "qastools_config.hpp" #include "tray_mixer_mdev_setup.hpp" #include "tray_mixer_view_setup.hpp" #include "tray_mixer_icon.hpp" #include "tray_mixer_balloon.hpp" #include "qsnd/event_types.hpp" #include "qsnd/mixer_simple.hpp" #include "qsnd/mixer_simple_elem.hpp" #include "qsnd/mixer_simple_filter_name.hpp" #include "wdg/uint_mapper.hpp" #include #include #include #include #include Tray_Mixer::Tray_Mixer ( QObject * parent_n ) : QObject ( parent_n ), _mdev_setup ( 0 ), _view_setup ( 0 ), _mx_elem ( 0 ), _volume_permille ( 0 ), _icon_idx ( 9999 ), _volume_muted ( false ), _updating_scheduled ( false ), _tray_icon ( 0 ), _balloon ( 0 ) { _snd_mixer = new ::QSnd::Mixer_Simple ( this ); { ::QSnd::Mixer_Simple_Filter_Name * filter ( new ::QSnd::Mixer_Simple_Filter_Name ); filter->set_blacklist ( false ); filter->append_name ( "master" ); _snd_mixer->append_elem_filter ( filter ); } // Tray icon { _tray_icon = new Tray_Mixer_Icon ( this ); connect ( _tray_icon, SIGNAL ( sig_quit() ), this, SIGNAL ( sig_quit() ) ); connect ( _tray_icon, SIGNAL ( sig_hover() ), this, SLOT ( raise_balloon() ) ); connect ( _tray_icon, SIGNAL ( sig_activated() ), this, SIGNAL ( sig_toggle_mixer() ) ); connect ( _tray_icon, SIGNAL ( sig_wheel_delta ( int ) ), this, SLOT ( mouse_wheel_delta ( int ) ) ); connect ( _tray_icon, SIGNAL ( sig_middle_click() ), this, SLOT ( mixer_toggle_switch() ) ); } init_icons(); update_tray_icon(); _tray_icon->show(); } Tray_Mixer::~Tray_Mixer ( ) { close_balloon(); } void Tray_Mixer::init_icons ( ) { QIcon icon_def; { const char * def_str ( 0 ); if ( QIcon::hasThemeIcon ( "multimedia-volume-control" ) ) { def_str = "multimedia-volume-control"; } else if ( QIcon::hasThemeIcon ( "audio-volume-high" ) ) { def_str = "audio-volume-high"; } if ( def_str != 0 ) { icon_def = QIcon::fromTheme ( def_str ); } else { QString icon_path ( INSTALL_DIR_ICONS_SVG ); icon_path += "/"; icon_path += PROGRAM_NAME; icon_path += ".svg"; QFileInfo finfo ( icon_path ); if ( finfo.exists() && finfo.isReadable() ) { icon_def = QIcon ( icon_path ); } } } for ( unsigned int ii=0; ii < 5; ++ii ) { _icons_volume.append ( icon_def ); } _icons_volume[2] = QIcon::fromTheme ( "audio-volume-low", icon_def ); _icons_volume[3] = QIcon::fromTheme ( "audio-volume-medium", icon_def ); _icons_volume[4] = QIcon::fromTheme ( "audio-volume-high", icon_def ); // Default and muted _icons_volume[0] = _icons_volume[3]; _icons_volume[1] = QIcon::fromTheme ( "audio-volume-muted", _icons_volume[2] ); } void Tray_Mixer::set_mdev_setup ( Tray_Mixer_MDev_Setup * setup_n ) { if ( _mdev_setup != 0 ) { close_mixer(); } _mdev_setup = setup_n; if ( _mdev_setup != 0 ) { load_mixer(); } } void Tray_Mixer::set_view_setup ( Tray_Mixer_View_Setup * setup_n ) { if ( _view_setup != 0 ) { close_balloon(); } _view_setup = setup_n; } void Tray_Mixer::update_balloon_setup ( ) { bool do_close ( false ); if ( _view_setup == 0 ) { do_close = true; } else if ( !_view_setup->show_balloon ) { do_close = true; } if ( do_close ) { close_balloon(); } if ( ( _balloon != 0 ) && ( _view_setup != 0 ) ) { _balloon->set_duration_ms ( _view_setup->balloon_lifetime ); } } bool Tray_Mixer::is_visible ( ) const { return ( QSystemTrayIcon::isSystemTrayAvailable() && _tray_icon->isVisible() ); } void Tray_Mixer::close_mixer ( ) { close_balloon(); // Clear mixer element if ( _mx_elem != 0 ) { disconnect ( _mx_elem, 0, this, 0 ); } _mx_elem = 0; _volume_permille = 0; _volume_muted = false; _snd_mixer->close(); update_tray_icon(); } void Tray_Mixer::load_mixer ( ) { if ( _mdev_setup == 0 ) { return; } QString mdev; switch ( _mdev_setup->device_mode ) { case ::Tray_Mixer_MDev_Setup::MIXER_DEV_CURRENT: mdev = _mdev_setup->current_device; break; case ::Tray_Mixer_MDev_Setup::MIXER_DEV_USER: mdev = _mdev_setup->user_device; break; default: break; } if ( mdev.isEmpty() ) { mdev = "default"; } if ( !_snd_mixer->open ( mdev ) ) { // Update mixer element for ( unsigned int ii=0; ii < _snd_mixer->num_elems(); ++ii ) { if ( _snd_mixer->elem ( ii )->has_volume ( 0 ) ) { _mx_elem = _snd_mixer->elem ( ii ); break; } } if ( _mx_elem != 0 ) { connect ( _mx_elem, SIGNAL ( sig_values_changed() ), this, SLOT ( mixer_values_changed() ) ); } update_volume_permille(); } update_tray_icon(); } void Tray_Mixer::raise_balloon ( ) { if ( _view_setup == 0 ) { return; } if ( ( _balloon == 0 ) && QSystemTrayIcon::isSystemTrayAvailable() && _tray_icon->isVisible() && _view_setup->show_balloon ) { _balloon.reset ( new Tray_Mixer_Balloon ( _view_setup->image_alloc ) ); _balloon->set_tray_icon_geometry ( _tray_icon->geometry() ); _balloon->set_duration_ms ( _view_setup->balloon_lifetime ); _balloon->set_icon ( _icons_volume[3] ); connect ( _balloon.data(), SIGNAL ( sig_activated() ), this, SIGNAL ( sig_toggle_mixer() ) ); connect ( _balloon.data(), SIGNAL ( sig_middle_click() ), this, SLOT ( mixer_toggle_switch() ) ); connect ( _balloon.data(), SIGNAL ( sig_wheel_delta ( int ) ), this, SLOT ( mouse_wheel_delta ( int ) ) ); connect ( _balloon.data(), SIGNAL ( sig_close() ), this, SLOT ( close_balloon() ) ); } if ( _balloon != 0 ) { _balloon->set_muted ( _volume_muted ); _balloon->set_permille ( _volume_permille ); _balloon->start_show(); } } void Tray_Mixer::close_balloon ( ) { if ( _balloon != 0 ) { _balloon.reset(); } } void Tray_Mixer::update_tray_icon ( ) { unsigned int icon_idx ( 0 ); if ( _mx_elem != 0 ) { if ( _volume_muted ) { icon_idx = 1; } else { if ( _volume_permille < 333 ) { icon_idx = 2; } else if ( _volume_permille < 750 ) { icon_idx = 3; } else { icon_idx = 4; } } } if ( _icon_idx != icon_idx ) { _icon_idx = icon_idx; _tray_icon->setIcon ( _icons_volume[_icon_idx] ); } } bool Tray_Mixer::update_volume_permille ( ) { bool res ( false ); bool muted ( _volume_muted ); unsigned int perm ( _volume_permille ); if ( _mx_elem != 0 ) { unsigned long dist_current ( ::Wdg::integer_distance ( _mx_elem->volume_min ( 0 ), _mx_elem->volume ( 0, 0 ) ) ); unsigned long dist_total ( ::Wdg::integer_distance ( _mx_elem->volume_min ( 0 ), _mx_elem->volume_max ( 0 ) ) ); perm = ::Wdg::permille ( dist_current, dist_total ); if ( _mx_elem->has_switch ( 0 ) ) { muted = !_mx_elem->switch_state ( 0, 0 ); } } if ( ( perm != _volume_permille ) || ( muted != _volume_muted ) ) { _volume_muted = muted; _volume_permille = perm; res = true; } return res; } void Tray_Mixer::update_volume_widgets ( ) { if ( update_volume_permille() ) { raise_balloon(); } update_tray_icon(); } void Tray_Mixer::mixer_values_changed ( ) { if ( !_updating_scheduled ) { _updating_scheduled = true; QEvent * ev_req ( new QEvent ( ::QSnd::evt_update_values ) ); QCoreApplication::postEvent ( this, ev_req ); } } void Tray_Mixer::mixer_toggle_switch ( ) { if ( _mx_elem != 0 ) { if ( _mx_elem->has_switch ( 0 ) ) { _mx_elem->invert_switches ( 0 ); } } } void Tray_Mixer::mouse_wheel_delta ( int wheel_delta_n ) { if ( ( _view_setup == 0 ) || ( _mx_elem == 0 ) ) { return; } const long vol_min ( _mx_elem->volume_min ( 0 ) ); const long vol_max ( _mx_elem->volume_max ( 0 ) ); long vol_old ( _mx_elem->volume ( 0, 0 ) ); long delta; { const double range ( double ( vol_max ) - double ( vol_min ) ); double amount ( range / double ( _view_setup->wheel_degrees ) ); amount *= ( wheel_delta_n / 8.0 ); if ( amount > 0 ) { delta = std::ceil ( amount ); } else { delta = std::floor ( amount ); } } if ( delta == 0 ) { if ( wheel_delta_n > 0 ) { delta = 1; } else { delta = -1; } } long vol ( vol_old ); if ( delta > 0 ) { if ( ( vol_max - vol ) > delta ) { vol += delta; } else { vol = vol_max; } } else { if ( ( vol_min - vol ) < delta ) { vol += delta; } else { vol = vol_min; } } if ( vol != vol_old ) { _mx_elem->set_volume_all ( 0, vol ); } } bool Tray_Mixer::event ( QEvent * event_n ) { if ( event_n->type() == ::QSnd::evt_update_values ) { _updating_scheduled = false; update_volume_widgets(); return true; } return QObject::event ( event_n ); } qastools-v0.22.0/qasmixer/src/tray_mixer.hpp000066400000000000000000000034541354534512100211530ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_tray_mixer_hpp__ #define __INC_tray_mixer_hpp__ #include #include #include // Forward declaration class Tray_Mixer_MDev_Setup; class Tray_Mixer_View_Setup; class Tray_Mixer_Balloon; class Tray_Mixer_Icon; namespace QSnd { class Mixer_Simple; class Mixer_Simple_Elem; } /// @brief Tray_Mixer /// class Tray_Mixer : public QObject { Q_OBJECT // Public methods public: Tray_Mixer ( QObject * parent_n = 0 ); ~Tray_Mixer ( ); void set_mdev_setup ( Tray_Mixer_MDev_Setup * setup_n ); void set_view_setup ( Tray_Mixer_View_Setup * setup_n ); void update_balloon_setup ( ); bool is_visible ( ) const; bool event ( QEvent * event_n ); // Public signals signals: void sig_toggle_mixer ( ); void sig_quit ( ); // Protected slots protected slots: void mixer_values_changed ( ); void mixer_toggle_switch ( ); void mouse_wheel_delta ( int wheel_delta_n ); void raise_balloon ( ); void close_balloon ( ); // Private methods private: void init_icons ( ); void update_tray_icon ( ); bool update_volume_permille ( ); void update_volume_widgets ( ); void load_mixer ( ); void close_mixer ( ); // Private attributes private: Tray_Mixer_MDev_Setup * _mdev_setup; Tray_Mixer_View_Setup * _view_setup; // Mixer ::QSnd::Mixer_Simple * _snd_mixer; ::QSnd::Mixer_Simple_Elem * _mx_elem; unsigned int _volume_permille; // Icons and pixmaps /// 0: default /// 1: muted /// 2...: volumes unsigned int _icon_idx; QList < QIcon > _icons_volume; // State flags bool _volume_muted; bool _updating_scheduled; Tray_Mixer_Icon * _tray_icon; QScopedPointer < Tray_Mixer_Balloon > _balloon; }; #endif qastools-v0.22.0/qasmixer/src/tray_mixer_balloon.cpp000066400000000000000000000073021354534512100226500ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "tray_mixer_balloon.hpp" #include "wdg/ds_switch.hpp" #include "wdg/ds_widget_types.hpp" #include #include #include #include #include #include #include #include Tray_Mixer_Balloon::Tray_Mixer_Balloon ( ::dpe::Image_Allocator * image_alloc_n, QWidget * parent_n ) : ::Wdg::Balloon_Widget ( parent_n ), _image_alloc ( image_alloc_n ) { _value_mask = tr ( "Volume is at %1%" ); { _lbl_icon = new QLabel; _lbl_icon->setMinimumSize ( pixmap_size() ); _lbl_icon->setCursor ( Qt::PointingHandCursor ); _lbl_icon->setToolTip ( tr ( "Show mixer" ) ); _lbl_icon->installEventFilter ( this ); } QAbstractButton * btn_close ( 0 ); if ( image_alloc_n != 0 ) { ::Wdg::DS_Switch * btn ( new ::Wdg::DS_Switch ( 0, image_alloc_n ) ); btn->setCheckable ( false ); btn->set_variant_id ( ::Wdg::DS_CLOSE ); { int btn_size ( fontMetrics().height() ); btn->setIconSize ( QSize ( btn_size, btn_size ) ); btn->setSizePolicy ( QSizePolicy::Fixed, QSizePolicy::Fixed ); btn->setFixedSize ( btn_size, btn_size ); } connect ( btn, SIGNAL ( clicked() ), this, SLOT ( close() ) ); btn_close = btn; } { _lbl_volume_value = new ::Wdg::Label_Width ( ); _lbl_volume_value->set_min_text ( _value_mask.arg ( 100 ) ); _lbl_volume_muted = new QLabel; _lbl_volume_muted->setText ( tr ( "Volume muted" ) ); } { int hspace ( fontMetrics().averageCharWidth() * 3 / 2 ); QWidget * wdg_balloon ( new QWidget ); QHBoxLayout * lay_txt ( new QHBoxLayout ); _lay_volume_stack = new QStackedLayout; lay_txt->setContentsMargins ( 0, 0, 0, 0 ); lay_txt->addWidget ( _lbl_icon ); lay_txt->addSpacing ( hspace ); lay_txt->addLayout ( _lay_volume_stack ); lay_txt->addSpacing ( hspace ); lay_txt->addWidget ( btn_close ); wdg_balloon->setLayout ( lay_txt ); _lay_volume_stack->addWidget ( _lbl_volume_value ); _lay_volume_stack->addWidget ( _lbl_volume_muted ); _lay_volume_stack->setCurrentIndex ( 0 ); add_widget ( wdg_balloon ); } } QSize Tray_Mixer_Balloon::pixmap_size ( ) const { unsigned int len ( fontMetrics().height() * 5 / 2 ); return QSize ( len, len ); } void Tray_Mixer_Balloon::set_muted ( bool flag_n ) { _lay_volume_stack->setCurrentIndex ( ( flag_n ? 1 : 0 ) ); } void Tray_Mixer_Balloon::set_permille ( unsigned int value_n ) { _lbl_volume_value->setText ( _value_mask.arg ( value_n / 10 ) ); } void Tray_Mixer_Balloon::set_icon ( const QIcon & icon_n ) { set_pixmap ( icon_n.pixmap ( pixmap_size() ) ); } void Tray_Mixer_Balloon::set_pixmap ( const QPixmap & pixmap_n ) { _lbl_icon->setPixmap ( pixmap_n ); } void Tray_Mixer_Balloon::mousePressEvent ( QMouseEvent * event_n ) { ::Wdg::Balloon_Widget::mousePressEvent ( event_n ); if ( event_n->button() == Qt::LeftButton ) { close(); } } bool Tray_Mixer_Balloon::eventFilter ( QObject * obj_n, QEvent * event_n ) { bool res ( ::Wdg::Balloon_Widget::eventFilter ( obj_n, event_n ) ); if ( obj_n == _lbl_icon ) { if ( event_n->type() == QEvent::Wheel ) { QWheelEvent * ev_wheel ( static_cast < QWheelEvent * > ( event_n ) ); emit sig_wheel_delta ( ev_wheel->delta() ); res = true; } else if ( ( event_n->type() == QEvent::MouseButtonPress ) || ( event_n->type() == QEvent::MouseButtonDblClick ) ) { res = true; QMouseEvent * ev_mouse ( static_cast < QMouseEvent * > ( event_n ) ); switch ( ev_mouse->button() ) { case Qt::LeftButton: emit sig_activated(); break; case Qt::MidButton: emit sig_middle_click(); break; default: break; } } } return res; } qastools-v0.22.0/qasmixer/src/tray_mixer_balloon.hpp000066400000000000000000000026131354534512100226550ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_tray_mixer_balloon_hpp__ #define __INC_tray_mixer_balloon_hpp__ #include "dpe/image_allocator.hpp" #include "wdg/label_width.hpp" #include "wdg/balloon_widget.hpp" #include #include #include #include /// @brief Tray_Mixer_Balloon /// class Tray_Mixer_Balloon : public ::Wdg::Balloon_Widget { Q_OBJECT // Public methods public: Tray_Mixer_Balloon ( ::dpe::Image_Allocator * image_alloc_n, QWidget * parent_n = 0 ); QSize pixmap_size ( ) const; void set_image_alloc ( ::dpe::Image_Allocator * image_alloc_n ); // Volume value void set_muted ( bool flag_n ); void set_permille ( unsigned int value_n ); void set_icon ( const QIcon & icon_n ); void set_pixmap ( const QPixmap & pixmap_n ); bool eventFilter ( QObject * obj_n, QEvent * event_n ); // Signals signals: void sig_activated ( ); void sig_middle_click ( ); void sig_wheel_delta ( int delta_n ); // Protected methods protected: void mousePressEvent ( QMouseEvent * event_n ); // Private attributes private: QLabel * _lbl_icon; QStackedLayout * _lay_volume_stack; ::Wdg::Label_Width * _lbl_volume_value; QLabel * _lbl_volume_muted; ::dpe::Image_Allocator * _image_alloc; // Strings QString _value_mask; }; #endif qastools-v0.22.0/qasmixer/src/tray_mixer_icon.cpp000066400000000000000000000040601354534512100221500ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "tray_mixer_icon.hpp" #include "qastools_config.hpp" #include #include #include #include #include Tray_Mixer_Icon::Tray_Mixer_Icon ( QObject * parent_n ) : QSystemTrayIcon ( parent_n ) { connect ( this, SIGNAL ( activated ( QSystemTrayIcon::ActivationReason ) ), this, SLOT ( activation ( QSystemTrayIcon::ActivationReason ) ) ); // Context menu { QAction * act_show ( new QAction ( this ) ); act_show->setText ( tr ( "&Show mixer" ) ); act_show->setShortcut ( QKeySequence ( tr ( "Ctrl+s" ) ) ); act_show->setIcon ( QIcon::fromTheme ( "view-fullscreen" ) ); QAction * act_quit ( new QAction ( this ) ); //: %1 will be replaced with the program title act_quit->setText ( tr ( "&Close %1" ).arg ( PROGRAM_TITLE ) ); act_quit->setShortcut ( QKeySequence ( QKeySequence::Quit ) ); act_quit->setIcon ( QIcon::fromTheme ( "application-exit" ) ); connect ( act_show, SIGNAL ( triggered() ), this, SIGNAL ( sig_activated() ) ); connect ( act_quit, SIGNAL ( triggered() ), this, SIGNAL ( sig_quit() ) ); _cmenu.addAction ( act_show ); _cmenu.addAction ( act_quit ); setContextMenu ( &_cmenu ); } } void Tray_Mixer_Icon::activation ( QSystemTrayIcon::ActivationReason reason_n ) { //::std::cout << "Tray_Mixer::activation " << reason_n << "\n"; if ( reason_n == QSystemTrayIcon::Context ) { return; } else if ( reason_n == QSystemTrayIcon::MiddleClick ) { emit sig_middle_click(); } else { emit sig_activated(); } } bool Tray_Mixer_Icon::event ( QEvent * event_n ) { //::std::cout << "Tray_Mixer_Icon::event: " << event_n->type() << "\n"; bool res ( QSystemTrayIcon::event ( event_n ) ); switch ( event_n->type() ) { case QEvent::Wheel: { QWheelEvent * wev ( static_cast < QWheelEvent * > ( event_n ) ); emit sig_wheel_delta ( wev->delta() ); res = true; } break; case QEvent::ToolTip: emit sig_hover(); break; default: break; } return res; } qastools-v0.22.0/qasmixer/src/tray_mixer_icon.hpp000066400000000000000000000014731354534512100221620ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_tray_mixer_icon_hpp__ #define __INC_tray_mixer_icon_hpp__ #include #include #include /// @brief Tray_Mixer_Icon /// class Tray_Mixer_Icon : public QSystemTrayIcon { Q_OBJECT // Public methods public: Tray_Mixer_Icon ( QObject * parent_n = 0 ); bool event ( QEvent * event_n ); // Public signals signals: void sig_hover ( ); void sig_activated ( ); void sig_middle_click ( ); void sig_wheel_delta ( int delta_n ); void sig_quit ( ); // Protected slots protected slots: void activation ( QSystemTrayIcon::ActivationReason reason_n ); // Protected methods protected: // Private attributes private: QMenu _cmenu; }; #endif qastools-v0.22.0/qasmixer/src/tray_mixer_mdev_setup.cpp000066400000000000000000000004221354534512100233710ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "tray_mixer_mdev_setup.hpp" Tray_Mixer_MDev_Setup::Tray_Mixer_MDev_Setup ( ) : device_mode ( ::Tray_Mixer_MDev_Setup::MIXER_DEV_DEFAULT ), user_device ( "hw:0" ) { } qastools-v0.22.0/qasmixer/src/tray_mixer_mdev_setup.hpp000066400000000000000000000013641354534512100234040ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_tray_mixer_mdev_setup_hpp__ #define __INC_tray_mixer_mdev_setup_hpp__ #include /// @brief Tray_Mixer_MDev_Setup /// class Tray_Mixer_MDev_Setup { // Public typedefs public: enum Mixer_Device { MIXER_DEV_DEFAULT = 0, MIXER_DEV_CURRENT = 1, MIXER_DEV_USER = 2, MIXER_DEV_LAST = MIXER_DEV_USER }; // Public methods public: Tray_Mixer_MDev_Setup ( ); // Public attributes public: /// @brief Which device to use for the mixer unsigned int device_mode; /// @brief Mixer device of the main mixer window QString current_device; /// @brief User defined mixer device QString user_device; }; #endif qastools-v0.22.0/qasmixer/src/tray_mixer_view_setup.cpp000066400000000000000000000004321354534512100234110ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "tray_mixer_view_setup.hpp" Tray_Mixer_View_Setup::Tray_Mixer_View_Setup ( ) : balloon_lifetime ( 4000 ), wheel_degrees ( 720 ), show_balloon ( true ), image_alloc ( 0 ) { } qastools-v0.22.0/qasmixer/src/tray_mixer_view_setup.hpp000066400000000000000000000011621354534512100234170ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_tray_mixer_setup_hpp__ #define __INC_tray_mixer_setup_hpp__ #include "dpe/image_allocator.hpp" /// @brief Tray_Mixer_View_Setup /// class Tray_Mixer_View_Setup { // Public methods public: Tray_Mixer_View_Setup ( ); // Public attributes public: /// @brief Balloon lifetime in ms unsigned int balloon_lifetime; /// @brief Mouse wheel degrees for slider widgets unsigned int wheel_degrees; /// @brief Whether to show the balloon bool show_balloon; ::dpe::Image_Allocator * image_alloc; }; #endif qastools-v0.22.0/qasmixer/src/views/000077500000000000000000000000001354534512100174065ustar00rootroot00000000000000qastools-v0.22.0/qasmixer/src/views/mixer_simple.cpp000066400000000000000000000300651354534512100226130ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "mixer_simple.hpp" #include "qastools_config.hpp" #include "qsnd/mixer_simple.hpp" #include "mwdg/inputs_setup.hpp" #include "mwdg/mixer_sliders.hpp" #include "mwdg/mixer_switches.hpp" #include "mwdg/mixer_style.hpp" #include "mwdg/mixer_device_setup.hpp" #include "mwdg/mixer_sliders_status_widget.hpp" #include "views/mixer_simple_setup.hpp" #include "views/message_widget.hpp" #include #include #include #include #include #include #include #include #include #include namespace Views { Mixer_Simple::Mixer_Simple ( QWidget * parent_n ) : ::Views::View_Base ( parent_n ), _view_setup ( 0 ), _status_group_idx ( ~0 ), _status_column_idx ( ~0 ), _qsnd_mixer ( 0 ) { // Strings and icons _act_stream_text[0] = tr ( "Show playback" ); _act_stream_text[1] = tr ( "Show capture" ); _act_stream_ttip[0] = tr ( "Show playback elements" ); _act_stream_ttip[1] = tr ( "Show capture elements" ); { const char * fd_app[3] = { "show-playback", "show-capture" }; const char * fd_def[3] = { "media-playback-start", "media-record" }; QString icon_path_base ( INSTALL_DIR_APP_ICONS ); icon_path_base.append ( "/" ); for ( unsigned int ii=0; ii < 2; ++ii ) { QIcon icon; { QString icon_path ( icon_path_base ); icon_path.append ( fd_app[ii] ); icon_path.append ( ".svg" ); QFileInfo finfo ( icon_path ); if ( finfo.exists() && finfo.isReadable() ) { icon = QIcon ( icon_path ); } else { icon = QIcon::fromTheme ( fd_def[ii] ); } } _act_stream_icon[ii] = icon; } } // Mixer object { _qsnd_mixer = new ::QSnd::Mixer_Simple ( this ); connect ( _qsnd_mixer, SIGNAL ( sig_mixer_reload_request() ), this, SIGNAL ( sig_mdev_reload_request() ) ); } // Mixer sliders { _mixer_sliders = new ::MWdg::Mixer_Sliders; connect ( _mixer_sliders, SIGNAL ( sig_footer_label_selected ( unsigned int, unsigned int ) ), this, SLOT ( footer_label_selected ( unsigned int, unsigned int ) ) ); } // Mixer switches { _switches_area = new QWidget; _mixer_switches = new ::MWdg::Mixer_Switches ( _switches_area ); // Stream buttons for ( unsigned int ii=0; ii < 2; ++ii ) { _btn_stream[ii] = new QPushButton ( _switches_area ); _btn_stream[ii]->setCheckable ( true ); if ( _act_stream_icon[ii].isNull() ) { _btn_stream[ii]->setText ( _act_stream_text[ii] ); } else { _btn_stream[ii]->setIcon ( _act_stream_icon[ii] ); } _btn_stream[ii]->setToolTip ( _act_stream_ttip[ii] ); } connect ( _btn_stream[0], SIGNAL ( toggled ( bool ) ), this, SLOT ( show_playback ( bool ) ), Qt::QueuedConnection ); connect ( _btn_stream[1], SIGNAL ( toggled ( bool ) ), this, SLOT ( show_capture ( bool ) ), Qt::QueuedConnection ); } // Vertical splitter { _mixer_split.setOrientation ( Qt::Vertical ); _mixer_split.addWidget ( _mixer_sliders ); _mixer_split.addWidget ( _switches_area ); QVBoxLayout * lay_vbox ( new QVBoxLayout ); lay_vbox->setContentsMargins ( 0, 0, 0, 0 ); lay_vbox->addWidget ( &_mixer_split ); _wdg_areas.setLayout ( lay_vbox ); lay_stack()->addWidget ( &_wdg_areas ); } // Adjust layout margins { QMargins mgs ( _mixer_sliders->contentsMargins() ); mgs.setTop ( 0 ); _mixer_sliders->setContentsMargins ( mgs ); } if ( _mixer_sliders->layout() != 0 ) { QMargins mgs ( _mixer_sliders->layout()->contentsMargins() ); mgs.setTop ( 0 ); _mixer_sliders->layout()->setContentsMargins ( mgs ); } } Mixer_Simple::~Mixer_Simple ( ) { set_mdev_setup ( 0 ); set_view_setup ( 0 ); } void Mixer_Simple::set_mdev_setup ( const ::MWdg::Mixer_Device_Setup * setup_n ) { if ( mdev_setup() != 0 ) { clear_view(); _qsnd_mixer->close(); } ::Views::View_Base::set_mdev_setup ( setup_n ); if ( mdev_setup() != 0 ) { _qsnd_mixer->open ( mdev_setup()->ctl_addr ); setup_view(); } } void Mixer_Simple::set_inputs_setup ( const ::MWdg::Inputs_Setup * setup_n ) { ::Views::View_Base::set_inputs_setup ( setup_n ); _mixer_sliders->set_inputs_setup ( setup_n ); _mixer_switches->set_inputs_setup ( setup_n ); if ( inputs_setup() != 0 ) { // Append key sequence texts to the tooltip const QString & mask ( "%1 (%2)" ); for ( unsigned int ii=0; ii < 2; ++ii ) { const QKeySequence & kseq ( inputs_setup()->ks_toggle_vis_stream[ii] ); const QString & kstr ( kseq.toString ( QKeySequence::NativeText ) ); if ( !kstr.isEmpty() ) { _btn_stream[ii]->setToolTip ( mask.arg ( _act_stream_ttip[ii], kstr ) ); } } } } void Mixer_Simple::set_view_setup ( ::Views::View_Base_Setup * setup_n ) { clear_view(); _view_setup = dynamic_cast < ::Views::Mixer_Simple_Setup * > ( setup_n ); setup_view(); } void Mixer_Simple::clear_view ( ) { if ( ( mdev_setup() == 0 ) || ( _view_setup == 0 ) ) { return; } if ( _status_wdg != 0 ) { delete _status_wdg; _status_wdg = 0; } if ( _qsnd_mixer->is_open() ) { _mixer_sliders->set_mixer_setup ( 0 ); _mixer_switches->set_mixer_setup ( 0 ); } } void Mixer_Simple::setup_view ( ) { if ( ( mdev_setup() == 0 ) || ( _view_setup == 0 ) ) { return; } // Fix show stream flags on demand if ( ! ( _view_setup->show_stream[0] || _view_setup->show_stream[1] ) ) { _view_setup->show_stream[0] = true; } _btn_stream[0]->setChecked ( _view_setup->show_stream[0] ); _btn_stream[1]->setChecked ( _view_setup->show_stream[1] ); // The stream dirs shown are temporarily overridden for // devices with only one stream direction type bool show_stream[2]; show_stream[0] = _view_setup->show_stream[0]; show_stream[1] = _view_setup->show_stream[1]; if ( ( _qsnd_mixer->num_elems_stream ( 0 ) == 0 ) || ( _qsnd_mixer->num_elems_stream ( 1 ) == 0 ) ) { show_stream[0] = ( _qsnd_mixer->num_elems_stream(0) > 0 ); show_stream[1] = ( _qsnd_mixer->num_elems_stream(1) > 0 ); } _smixer_setup.show_stream[0] = show_stream[0]; _smixer_setup.show_stream[1] = show_stream[1]; _smixer_setup.show_slider_value_labels = _view_setup->show_slider_value_labels; _smixer_setup.mixer_simple = _qsnd_mixer; _smixer_setup.wdg_style_db = _view_setup->wdg_style_db; _smixer_setup.image_alloc = _view_setup->image_alloc; unsigned int lay_stack_idx ( 0 ); if ( mdev_setup()->ctl_addr.isEmpty() ) { message_wdg()->set_no_device(); } else { if ( _qsnd_mixer->is_open() ) { lay_stack_idx = 1; } else { message_wdg()->set_mixer_open_fail ( mdev_setup()->ctl_addr, _qsnd_mixer->err_message(), _qsnd_mixer->err_func() ); } } // Show simple mixer if ( lay_stack_idx == 1 ) { unsigned int num_vis_sliders ( 0 ); unsigned int num_vis_switches ( 0 ); for ( unsigned int ii=0; ii < 2; ++ii ) { if ( _smixer_setup.show_stream[ii] ) { num_vis_sliders += _qsnd_mixer->num_elems_volume ( ii ); num_vis_switches += _qsnd_mixer->num_elems_no_volume ( ii ); } } bool vis_stream_select ( ( _qsnd_mixer->num_elems_stream ( 0 ) > 0 ) && ( _qsnd_mixer->num_elems_stream ( 1 ) > 0 ) ); bool vis_switches_area ( vis_stream_select || ( num_vis_switches > 0 ) ); bool vis_splitter ( ( num_vis_sliders > 0 ) && vis_switches_area ); // Hide areas before installing changes _mixer_split.hide(); _mixer_sliders->hide(); _switches_area->hide(); // Install mixer setup if ( num_vis_sliders > 0 ) { _mixer_sliders->set_mixer_setup ( &_smixer_setup ); } if ( vis_switches_area ) { _mixer_switches->set_mixer_setup ( &_smixer_setup ); } // Switches area layout if ( vis_switches_area ) { QHBoxLayout * lay_hbox ( new QHBoxLayout ); if ( num_vis_switches > 0 ) { lay_hbox->addWidget ( _mixer_switches ); } // Stream select buttons layout if ( vis_stream_select ) { QBoxLayout * lay_btns; if ( num_vis_switches > 1 ) { lay_btns = new QVBoxLayout; } else { lay_btns = new QHBoxLayout; } lay_btns->setContentsMargins ( 0, 0, 0, 0 ); lay_btns->setAlignment ( Qt::AlignRight | Qt::AlignBottom ); lay_btns->addWidget ( _btn_stream[0] ); lay_btns->addWidget ( _btn_stream[1] ); lay_hbox->addLayout ( lay_btns ); } if ( _switches_area->layout() != 0 ) { delete _switches_area->layout(); } _switches_area->setLayout ( lay_hbox ); // Switches area items visiblity _mixer_switches->setVisible ( num_vis_switches > 0 ); _btn_stream[0]->setVisible ( vis_stream_select ); _btn_stream[1]->setVisible ( vis_stream_select ); } // Update splitter layout if ( vis_splitter ) { _mixer_split.addWidget ( _mixer_sliders ); _mixer_split.addWidget ( _switches_area ); _mixer_split.setCollapsible ( 0, false ); _mixer_split.setCollapsible ( 1, false ); _mixer_split.setStretchFactor ( 0, 1 ); _mixer_split.setStretchFactor ( 1, 0 ); _mixer_sliders->show(); _switches_area->show(); { // Shrink switches area to minimum size QList < int > sizes; sizes.append ( height() ); // A value way too big sizes.append ( 1 ); // A value way too small _mixer_split.setSizes ( sizes ); } _mixer_split.show(); } else { if ( num_vis_sliders > 0 ) { _wdg_areas.layout()->addWidget ( _mixer_sliders ); } else { _wdg_areas.layout()->addWidget ( _switches_area ); } _mixer_sliders->setVisible ( num_vis_sliders > 0 ); _switches_area->setVisible ( vis_switches_area ); } } lay_stack()->setCurrentIndex ( lay_stack_idx ); } void Mixer_Simple::show_playback ( bool flag_n ) { if ( _view_setup == 0 ) { return; } if ( flag_n != _view_setup->show_stream[0] ) { clear_view(); _view_setup->show_stream[0] = flag_n; if ( !_view_setup->show_stream[0] && !_view_setup->show_stream[1] ) { _view_setup->show_stream[1] = true; } setup_view(); setFocus(); } } void Mixer_Simple::show_capture ( bool flag_n ) { if ( _view_setup == 0 ) { return; } if ( flag_n != _view_setup->show_stream[1] ) { clear_view(); _view_setup->show_stream[1] = flag_n; if ( !_view_setup->show_stream[0] && !_view_setup->show_stream[1] ) { _view_setup->show_stream[0] = true; } setup_view(); setFocus(); } } void Mixer_Simple::toggle_show_playback ( ) { if ( _view_setup != 0 ) { show_playback ( !_view_setup->show_stream[0] ); } } void Mixer_Simple::toggle_show_capture ( ) { if ( _view_setup != 0 ) { show_capture ( !_view_setup->show_stream[1] ); } } void Mixer_Simple::show_slider_value_widget ( ) { if ( _status_wdg == 0 ) { ::MWdg::Mixer_Sliders_Status_Widget * swdg ( new ::MWdg::Mixer_Sliders_Status_Widget ( this ) ); swdg->setAttribute ( Qt::WA_DeleteOnClose ); swdg->set_sliders_pad ( _mixer_sliders->sliders_pad() ); swdg->slider_focus_changed(); _status_wdg = swdg; _status_wdg->show(); } } void Mixer_Simple::footer_label_selected ( unsigned int group_idx_n, unsigned int column_idx_n ) { //::std::cout << "Footer label selected " << group_idx_n << " " << column_idx_n << "\n"; bool keep_indices ( true ); if ( _status_wdg == 0 ) { show_slider_value_widget(); } else { if ( ( group_idx_n == _status_group_idx ) && ( column_idx_n == _status_column_idx ) ) { _status_group_idx = ~0; _status_column_idx = ~0; _status_wdg->close(); keep_indices = false; } } if ( keep_indices ) { _status_group_idx = group_idx_n; _status_column_idx = column_idx_n; } } void Mixer_Simple::keyPressEvent ( QKeyEvent * event_n ) { bool handled ( false ); if ( inputs_setup() != 0 ) { handled = true; const QKeySequence kseq ( event_n->key() ); if ( kseq == inputs_setup()->ks_toggle_vis_stream[0] ) { toggle_show_playback(); } else if ( kseq == inputs_setup()->ks_toggle_vis_stream[1] ) { toggle_show_capture(); } else { handled = false; } } if ( !handled ) { ::Views::View_Base::keyPressEvent ( event_n ); } } void Mixer_Simple::showEvent ( QShowEvent * event_n ) { View_Base::showEvent ( event_n ); if ( _status_wdg != 0 ) { _status_wdg->show(); } } void Mixer_Simple::hideEvent ( QHideEvent * event_n ) { View_Base::hideEvent ( event_n ); if ( _status_wdg != 0 ) { _status_wdg->hide(); } } } // End of namespace qastools-v0.22.0/qasmixer/src/views/mixer_simple.hpp000066400000000000000000000042411354534512100226150ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_mv_mixer_simple_hpp__ #define __INC_mv_mixer_simple_hpp__ #include #include #include #include "mwdg/mixer_simple_setup.hpp" #include "views/view_base.hpp" // Forward declaration namespace QSnd { class Mixer_Simple; } namespace MWdg { class Mixer_Sliders; class Mixer_Sliders_Status_Widget; class Mixer_Switches; } namespace Views { class Mixer_Simple_Setup; } namespace Views { class Mixer_Simple : public ::Views::View_Base { Q_OBJECT // Public methods public: Mixer_Simple ( QWidget * parent_n = 0 ); ~Mixer_Simple ( ); // Mixer device and view setup void set_mdev_setup ( const ::MWdg::Mixer_Device_Setup * setup_n ); void set_inputs_setup ( const ::MWdg::Inputs_Setup * setup_n ); void set_view_setup ( ::Views::View_Base_Setup * setup_n ); // Public slots public slots: void show_playback ( bool flag_n ); void show_capture ( bool flag_n ); void toggle_show_playback ( ); void toggle_show_capture ( ); void show_slider_value_widget ( ); // Protected slots protected slots: void footer_label_selected ( unsigned int group_idx_n, unsigned int column_idx_n ); // Protected methods protected: void keyPressEvent ( QKeyEvent * event_n ); void showEvent ( QShowEvent * event_n ); void hideEvent ( QHideEvent * event_n ); // Private methods private: void clear_view ( ); void setup_view ( ); // Private attributes private: ::Views::Mixer_Simple_Setup * _view_setup; ::MWdg::Mixer_Simple_Setup _smixer_setup; // widgets QWidget _wdg_areas; QSplitter _mixer_split; ::MWdg::Mixer_Sliders * _mixer_sliders; QWidget * _switches_area; QPushButton * _btn_stream[2]; ::MWdg::Mixer_Switches * _mixer_switches; QPointer < ::MWdg::Mixer_Sliders_Status_Widget > _status_wdg; unsigned int _status_group_idx; unsigned int _status_column_idx; /// @brief Mixer object ::QSnd::Mixer_Simple * _qsnd_mixer; // Strings and Icons QString _act_stream_text[2]; QString _act_stream_ttip[2]; QIcon _act_stream_icon[2]; }; } // End of namespace #endif qastools-v0.22.0/qasmixer/src/views/mixer_simple_setup.cpp000066400000000000000000000004631354534512100240320ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "mixer_simple_setup.hpp" namespace Views { Mixer_Simple_Setup::Mixer_Simple_Setup ( ) { show_slider_value_labels = true; show_stream[0] = true; show_stream[1] = false; } } // End of namespace qastools-v0.22.0/qasmixer/src/views/mixer_simple_setup.hpp000066400000000000000000000007401354534512100240350ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_mv_mixer_simple_setup_hpp__ #define __INC_mv_mixer_simple_setup_hpp__ #include "views/view_base_setup.hpp" namespace Views { class Mixer_Simple_Setup : public ::Views::View_Base_Setup { // Public methods public: Mixer_Simple_Setup ( ); // Public attributes public: bool show_slider_value_labels; bool show_stream[2]; }; } // End of namespace #endif qastools-v0.22.0/qasmixer/src/views/settings_dialog.cpp000066400000000000000000000375341354534512100233050ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "settings_dialog.hpp" #include "qastools_config.hpp" #include "desktop_items_setup.hpp" #include "wdg/scroll_area_vertical.hpp" #include #include #include #include #include #include #include #include namespace Views { Settings_Dialog::Settings_Dialog ( QWidget * parent_n, Qt::WindowFlags flags_n ) : ::Views::Multi_Page_Dialog ( parent_n, flags_n ), _dsetup ( 0 ), _updating_values ( false ) { { 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 ); init_page_startup(); init_page_appearance(); init_page_input(); init_page_sys_tray(); // Update states update_inputs_vis_state(); } Settings_Dialog::~Settings_Dialog ( ) { set_setup ( 0 ); } 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 ( int ) ), 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_smixer ( new QGroupBox ); box_smixer->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_smixer ( new QVBoxLayout ); lay_smixer->addWidget ( _btn_show_sliders_labels ); box_smixer->setLayout ( lay_smixer ); } // Container widget QWidget * wdg_all ( new QWidget ); { QVBoxLayout * lay_wdg ( new QVBoxLayout ); lay_wdg->setContentsMargins ( 0, 0, 0, 0 ); lay_wdg->addWidget ( box_smixer ); 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_input->setButtonSymbols ( QAbstractSpinBox::NoButtons ); _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, SIGNAL ( valueChanged ( int ) ), this, SLOT ( wheel_turns_changed ( int ) ) ); connect ( _mwheel_turns_input, SIGNAL ( valueChanged ( double ) ), this, SLOT ( wheel_turns_changed ( double ) ) ); connect ( _mwheel_turns_input, SIGNAL ( valueChanged ( double ) ), this, SLOT ( 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" ) ); connect ( _tray_btn_show_icon, SIGNAL ( toggled ( bool ) ), this, SLOT ( change_tray_view() ) ); connect ( _tray_btn_on_close, SIGNAL ( toggled ( bool ) ), this, SLOT ( change_tray_view() ) ); 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_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 ( int ) ), this, SLOT ( change_tray_mdev() ) ); connect ( _tray_dev_user_edit, SIGNAL ( editingFinished() ), this, SLOT ( change_tray_mdev() ) ); 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 ); } _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->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 ) { if ( _dsetup != 0 ) { _dsetup->settings_dialog.page = current_page_idx(); } _dsetup = setup_n; if ( _dsetup != 0 ) { update_inputs_values(); if ( _dsetup->settings_dialog.page >= num_pages() ) { _dsetup->settings_dialog.page = 0; } set_current_page_idx ( _dsetup->settings_dialog.page ); } } void Settings_Dialog::update_inputs_values ( ) { if ( _dsetup == 0 ) { 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_simple.show_slider_value_labels ); // 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_balloon_show->setChecked ( _dsetup->tray_view.show_balloon ); _tray_balloon_time_input->setValue ( _dsetup->tray_view.balloon_lifetime ); { unsigned int idx ( _dsetup->tray_mdev.device_mode ); if ( idx > ::Tray_Mixer_MDev_Setup::MIXER_DEV_LAST ) { idx = 0; } _tray_btn_device[idx]->setChecked ( true ); } _tray_dev_user_edit->setText ( _dsetup->tray_mdev.user_device ); update_inputs_vis_state(); _updating_values = false; } void Settings_Dialog::update_inputs_vis_state ( ) { const bool has_setup ( _dsetup != 0 ); _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_view.show_balloon ); _tray_dev_user->setEnabled ( ( _dsetup->tray_mdev.device_mode == ::Tray_Mixer_MDev_Setup::MIXER_DEV_USER ) ); } void Settings_Dialog::wheel_turns_changed ( int value_n ) { _mwheel_turns_input->setValue ( value_n / 10.0 ); } void Settings_Dialog::wheel_turns_changed ( double value_n ) { _mwheel_turns_slider->setValue ( value_n * 10.0 ); } void Settings_Dialog::change_startup ( ) { if ( ( _dsetup == 0 ) || _updating_values ) { return; } bool changed ( false ); int idx = _start_btn_grp_device->checkedId(); if ( ( idx >= 0 ) && ( idx <= ::Desktop_Items_Setup::MIXER_DEV_LAST ) ) { if ( idx != (int)_dsetup->start_device_mode ) { _dsetup->start_device_mode = idx; changed = true; } } if ( _start_dev_user_edit->text() != _dsetup->start_user_device ) { _dsetup->start_user_device = _start_dev_user_edit->text(); changed = true; } if ( changed ) { update_inputs_vis_state(); } } void Settings_Dialog::change_appearance ( ) { if ( ( _dsetup == 0 ) || _updating_values ) { return; } bool changed ( false ); { bool & sflag ( _dsetup->main_window.mixer_simple.show_slider_value_labels ); if ( _btn_show_sliders_labels->isChecked() != sflag ) { sflag = _btn_show_sliders_labels->isChecked(); changed = true; } } if ( changed ) { //::std::cout << "sig_change_mixer_view()\n"; emit sig_change_mixer_view(); } } void Settings_Dialog::change_input ( ) { if ( ( _dsetup == 0 ) || _updating_values ) { return; } bool changed ( false ); int value = _mwheel_turns_input->value() * 360.0; if ( value >= 0 ) { if ( _dsetup->main_window.inputs.wheel_degrees != (unsigned int)value ) { _dsetup->main_window.inputs.wheel_degrees = (unsigned int)value; changed = true; } } if ( changed ) { //::std::cout << "sig_change_input()\n"; emit sig_change_input(); } } void Settings_Dialog::change_tray_view ( ) { if ( ( _dsetup == 0 ) || _updating_values ) { return; } bool changed ( false ); if ( _tray_btn_on_close->isChecked() != _dsetup->tray_on_close ) { _dsetup->tray_on_close = _tray_btn_on_close->isChecked(); changed = true; } if ( _tray_btn_show_icon->isChecked() != _dsetup->tray_show_icon ) { _dsetup->tray_show_icon = _tray_btn_show_icon->isChecked(); changed = true; } if ( changed ) { //::std::cout << "sig_change_tray_view()\n"; update_inputs_vis_state(); emit sig_change_tray_view(); } } void Settings_Dialog::change_tray_balloon ( ) { if ( ( _dsetup == 0 ) || _updating_values ) { return; } bool changed ( false ); if ( _tray_btn_balloon_show->isChecked() != _dsetup->tray_view.show_balloon ) { _dsetup->tray_view.show_balloon = _tray_btn_balloon_show->isChecked(); changed = true; } if ( _tray_balloon_time_input->value() >= 0 ) { const unsigned int lifetime ( _tray_balloon_time_input->value() ); if ( lifetime != _dsetup->tray_view.balloon_lifetime ) { _dsetup->tray_view.balloon_lifetime = lifetime; changed = true; } } if ( changed ) { //::std::cout << "sig_change_tray_balloon()\n"; update_inputs_vis_state(); emit sig_change_tray_balloon(); } } void Settings_Dialog::change_tray_mdev ( ) { if ( ( _dsetup == 0 ) || _updating_values ) { return; } bool changed ( false ); int idx = _tray_btn_grp_device->checkedId(); if ( ( idx >= 0 ) && ( idx <= ::Tray_Mixer_MDev_Setup::MIXER_DEV_LAST ) ) { if ( idx != (int)_dsetup->tray_mdev.device_mode ) { _dsetup->tray_mdev.device_mode = idx; changed = true; } } if ( _tray_dev_user_edit->text() != _dsetup->tray_mdev.user_device ) { _dsetup->tray_mdev.user_device = _tray_dev_user_edit->text(); changed = true; } if ( changed ) { //::std::cout << "sig_change_tray_mdev()\n"; update_inputs_vis_state(); emit sig_change_tray_mdev(); } } } // End of namespace qastools-v0.22.0/qasmixer/src/views/settings_dialog.hpp000066400000000000000000000052431354534512100233020ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_views_settings_dialog_hpp__ #define __INC_views_settings_dialog_hpp__ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "views/multi_page_dialog.hpp" // Forward declaration class Desktop_Items_Setup; namespace Views { /// @brief Settings_Dialog /// class Settings_Dialog : public ::Views::Multi_Page_Dialog { Q_OBJECT // Public methods public: Settings_Dialog ( QWidget * parent_n = 0, Qt::WindowFlags flags_n = 0 ); ~Settings_Dialog ( ); void set_setup ( ::Desktop_Items_Setup * setup_n ); // Signals signals: void sig_change_mixer_view ( ); void sig_change_input ( ); void sig_change_tray_view ( ); void sig_change_tray_mdev ( ); void sig_change_tray_balloon ( ); void sig_close ( ); // Protected slots protected slots: void change_startup ( ); void change_appearance ( ); void change_input ( ); void change_tray_view ( ); void change_tray_mdev ( ); void change_tray_balloon ( ); void wheel_turns_changed ( int value_n ); void wheel_turns_changed ( double value_n ); // Protected methods protected: void init_page_startup ( ); void init_page_appearance ( ); void init_page_input ( ); void init_page_sys_tray ( ); void update_inputs_values ( ); void update_inputs_vis_state ( ); // Private attributes private: ::Desktop_Items_Setup * _dsetup; // Pages QWidget * _page_startup; QWidget * _page_appearance; QWidget * _page_input; QWidget * _page_sys_tray; // Page: Startup QButtonGroup * _start_btn_grp_device; QRadioButton * _start_btn_device[3]; QWidget * _start_dev_user; QLineEdit * _start_dev_user_edit; // Page: Appearance QCheckBox * _btn_show_sliders_labels; // Page: Input QString _mwheel_degrees_mask; QDoubleSpinBox * _mwheel_turns_input; QSlider * _mwheel_turns_slider; // Page: System tray usage QWidget * _tray_minimize; QCheckBox * _tray_btn_on_close; QCheckBox * _tray_btn_show_icon; QWidget * _tray_wdg_grp_ballon; QCheckBox * _tray_btn_balloon_show; QWidget * _tray_balloon_time; QSpinBox * _tray_balloon_time_input; QWidget * _tray_wdg_grp_device; QButtonGroup * _tray_btn_grp_device; QRadioButton * _tray_btn_device[3]; QWidget * _tray_dev_user; QLineEdit * _tray_dev_user_edit; // Layout & Styling QLocale loc; bool _updating_values; unsigned int _vspace; }; } // End of namespace #endif qastools-v0.22.0/qasmixer/src/views/settings_dialog_setup.cpp000066400000000000000000000003661354534512100245160ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "settings_dialog_setup.hpp" namespace Views { Settings_Dialog_Setup::Settings_Dialog_Setup ( ) : page ( 0 ) { } } // End of namespace qastools-v0.22.0/qasmixer/src/views/settings_dialog_setup.hpp000066400000000000000000000006541354534512100245230ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_views_settings_dialog_setup_hpp__ #define __INC_views_settings_dialog_setup_hpp__ namespace Views { /// @brief Settings_Dialog_Setup /// class Settings_Dialog_Setup { // Public methods public: Settings_Dialog_Setup ( ); // Public attributes public: unsigned int page; }; } // End of namespace #endif qastools-v0.22.0/scripts/000077500000000000000000000000001354534512100153205ustar00rootroot00000000000000qastools-v0.22.0/scripts/create_pro_file.py000077500000000000000000000024661354534512100210270ustar00rootroot00000000000000#!/usr/bin/python # -*- coding: utf-8 -*- import os script_dir = os.path.dirname(__file__) pro_file_name = 'app.pro' pro_file_dir = script_dir + '/../i18n' pro_file = pro_file_dir + '/' + pro_file_name src_dirs = [ script_dir + "/../shared/src", script_dir + "/../qasconfig/src", script_dir + "/../qashctl/src", script_dir + "/../qasmixer/src", ] hpp_list = [] cpp_list = [] pro_text = "" # Find header and source files for src_dir in src_dirs: for root, dirs, files in os.walk ( src_dir ): for fl in files: fl_full = root + "/" + fl fl_rel = os.path.relpath ( fl_full, pro_file_dir ) if ( fl.endswith ( ".hpp" ) ): hpp_list.append ( fl_rel ) if ( fl.endswith ( ".cpp" ) ): cpp_list.append ( fl_rel ) # Headers hpp_list.sort() if ( len ( hpp_list ) > 0 ): pro_text += "\n" pro_text += "HEADERS = \\\n" for hpp in hpp_list: pro_text += "\t" pro_text += hpp if ( hpp != hpp_list[-1] ): pro_text += " \\\n" pro_text += "\n" # Sources cpp_list.sort() if ( len ( cpp_list ) > 0 ): pro_text += "\n" pro_text += "SOURCES = \\\n" for cpp in cpp_list: pro_text += "\t" pro_text += cpp if ( cpp != cpp_list[-1] ): pro_text += " \\\n" pro_text += "\n" # Write qastools.pro file print ( "Writing " + pro_file ) with open ( pro_file, 'w' ) as fl: fl.write ( pro_text ) fl.close() qastools-v0.22.0/scripts/fix_header.py000077500000000000000000000047521354534512100200030ustar00rootroot00000000000000#!/usr/bin/python # -*- coding: utf-8 -*- import os import re import sys import shutil script_dir = os.path.dirname ( __file__ ) src_dirs = [ script_dir + "/../shared/src", script_dir + "/../qasconfig/src", script_dir + "/../qashctl/src", script_dir + "/../qasmixer/src", ] cmd_arg_error = True do_list_files = False do_list_files_inverted = False seriously_do_it = False if ( len ( sys.argv ) > 1 ): if ( len ( sys.argv ) > 2 ): print "Too many arguments" else: cmd_arg_error = False if ( sys.argv[1] == '--help' ): print '''\ Options: --help - Print a help text --list - List matching files --list-invert - List not matching files --do-it - Actually change file headers\ ''' elif ( sys.argv[1] == '--list' ): do_list_files = True elif ( sys.argv[1] == '--list-invert' ): do_list_files_inverted = True elif ( sys.argv[1] == '--do-it' ): seriously_do_it = True else: print ( "Unknown argument: " + sys.argv[1] ) print ( "Try --help" ) cmd_arg_error = True exit ( -1 ) if ( cmd_arg_error ): print ( "Try --help" ) exit ( -1 ) file_list = [] # Find files in the source directories for src_dir in src_dirs: for root, dirs, files in os.walk ( src_dir ): for fl in files: fl_full = root + "/" + fl fl_rel = os.path.relpath ( fl_full, script_dir ) file_list.append ( fl_rel ) file_list.sort() # Source file name filter filter_regs = [ re.compile ( ".*\.hpp$" ), re.compile ( ".*\.cpp$" ) ] file_list_filtered = [] for fname in file_list: #print fname for fl in filter_regs: if ( fl.match ( fname ) ): file_list_filtered.append ( fname ) hrepl_in = '''\ /// QasTools: Dektop toolset for the Linux sound system ALSA. /// \\\\copyright See COPYING file.\ ''' hrepl_out = '''\ /// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file.\ ''' hrepl_in = hrepl_in.replace ( '/', '\/' ) hrepl_in = hrepl_in.replace ( '(', '\(' ) hrepl_in = hrepl_in.replace ( ')', '\)' ) hrepl_in = hrepl_in.replace ( '+', '\+' ) #print hrepl_in re_repl = re.compile ( hrepl_in ) tmp_file = "/tmp/header_fix.txt" for fname in file_list_filtered: with open ( fname, 'r' ) as fhandle: fdata = fhandle.read() if ( re_repl.match ( fdata ) ): if ( do_list_files ): print fname if ( seriously_do_it ): print fname fdata_fixed = re_repl.sub ( hrepl_out, fdata ) with open ( tmp_file, 'w' ) as fhandle: fhandle.write ( fdata_fixed ) shutil.move ( tmp_file, fname ) else: if ( do_list_files_inverted ): print fname qastools-v0.22.0/scripts/render_png.sh000077500000000000000000000007351354534512100200070ustar00rootroot00000000000000#!/bin/sh PNGCRUSH="pngcrush -l 9" convert -background transparent app-icon.svg -resize 16x16 temp.png $PNGCRUSH temp.png app-icon-16x16.png convert -background transparent app-icon.svg -resize 32x32 temp.png $PNGCRUSH temp.png app-icon-32x32.png convert -background transparent app-icon.svg -resize 48x48 temp.png $PNGCRUSH temp.png app-icon-48x48.png convert -background transparent app-icon.svg -resize 64x64 temp.png $PNGCRUSH temp.png app-icon-64x64.png rm temp.png qastools-v0.22.0/shared/000077500000000000000000000000001354534512100150775ustar00rootroot00000000000000qastools-v0.22.0/shared/CMakeLists.txt000066400000000000000000000000701354534512100176340ustar00rootroot00000000000000# Process subdirectories ADD_SUBDIRECTORY ( graphics ) qastools-v0.22.0/shared/graphics/000077500000000000000000000000001354534512100166775ustar00rootroot00000000000000qastools-v0.22.0/shared/graphics/CMakeLists.txt000066400000000000000000000006671354534512100214500ustar00rootroot00000000000000# Install widgets graphics FILE ( GLOB switch_icons "widgets/sw_joined_bg_*.svg" ) FOREACH ( switch_icon ${switch_icons} ) INSTALL ( FILES ${switch_icon} DESTINATION ${INSTALL_DIR_WIDGETS_GRAPHICS} ) ENDFOREACH( switch_icon ) FILE ( GLOB switch_icons "widgets/sw_joined_handle_*.svg" ) FOREACH ( switch_icon ${switch_icons} ) INSTALL ( FILES ${switch_icon} DESTINATION ${INSTALL_DIR_WIDGETS_GRAPHICS} ) ENDFOREACH( switch_icon ) qastools-v0.22.0/shared/graphics/widgets/000077500000000000000000000000001354534512100203455ustar00rootroot00000000000000qastools-v0.22.0/shared/graphics/widgets/sw_joined_bg_focus.svg000077700000000000000000000000001354534512100310602sw_joined_bg_idle.svgustar00rootroot00000000000000qastools-v0.22.0/shared/graphics/widgets/sw_joined_bg_hover_focus.svg000077700000000000000000000000001354534512100322632sw_joined_bg_idle.svgustar00rootroot00000000000000qastools-v0.22.0/shared/graphics/widgets/sw_joined_bg_hover_idle.svg000077700000000000000000000000001354534512100320612sw_joined_bg_idle.svgustar00rootroot00000000000000qastools-v0.22.0/shared/graphics/widgets/sw_joined_bg_idle.svg000066400000000000000000000107411354534512100245170ustar00rootroot00000000000000 qastools-v0.22.0/shared/graphics/widgets/sw_joined_handle_checked_focus.svg000066400000000000000000000240411354534512100272300ustar00rootroot00000000000000 qastools-v0.22.0/shared/graphics/widgets/sw_joined_handle_checked_hover_focus.svg000066400000000000000000000240401354534512100304320ustar00rootroot00000000000000 qastools-v0.22.0/shared/graphics/widgets/sw_joined_handle_checked_hover_idle.svg000066400000000000000000000240411354534512100302310ustar00rootroot00000000000000 qastools-v0.22.0/shared/graphics/widgets/sw_joined_handle_checked_idle.svg000066400000000000000000000240411354534512100270260ustar00rootroot00000000000000 qastools-v0.22.0/shared/graphics/widgets/sw_joined_handle_half_checked_focus.svg000066400000000000000000000240411354534512100302220ustar00rootroot00000000000000 qastools-v0.22.0/shared/graphics/widgets/sw_joined_handle_half_checked_hover_focus.svg000066400000000000000000000240411354534512100314250ustar00rootroot00000000000000 qastools-v0.22.0/shared/graphics/widgets/sw_joined_handle_unchecked_focus.svg000066400000000000000000000240371354534512100276000ustar00rootroot00000000000000 qastools-v0.22.0/shared/graphics/widgets/sw_joined_handle_unchecked_hover_focus.svg000066400000000000000000000240371354534512100310030ustar00rootroot00000000000000 qastools-v0.22.0/shared/graphics/widgets/sw_joined_handle_unchecked_hover_idle.svg000066400000000000000000000240371354534512100306010ustar00rootroot00000000000000 qastools-v0.22.0/shared/graphics/widgets/sw_joined_handle_unchecked_idle.svg000066400000000000000000000240371354534512100273760ustar00rootroot00000000000000 qastools-v0.22.0/shared/graphics/widgets/sw_joined_source_bg.svg000066400000000000000000000161251354534512100251040ustar00rootroot00000000000000 image/svg+xml qastools-v0.22.0/shared/graphics/widgets/sw_joined_source_handle.svg000066400000000000000000000474441354534512100257570ustar00rootroot00000000000000 image/svg+xml qastools-v0.22.0/shared/src/000077500000000000000000000000001354534512100156665ustar00rootroot00000000000000qastools-v0.22.0/shared/src/dpe/000077500000000000000000000000001354534512100164365ustar00rootroot00000000000000qastools-v0.22.0/shared/src/dpe/image.cpp000066400000000000000000000014611354534512100202260ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "image.hpp" #include namespace dpe { Image::Image ( ) : _width ( 0 ), _height ( 0 ), _stride ( 0 ) { } Image::~Image ( ) { } void Image::clear ( ) { _pixmap.reset(); _width = 0; _height = 0; _stride = 0; } void Image::set_size ( unsigned int width_n, unsigned int height_n, unsigned int stride_n ) { clear(); _width = width_n; _height = height_n; _stride = stride_n; _qimage = QImage ( _width, _height, QImage::Format_ARGB32_Premultiplied ); } QPixmap * Image::convert_to_pixmap ( ) { if ( ( pixmap() == 0 ) || ( !qimage().isNull() ) ) { _pixmap.reset ( new QPixmap ( QPixmap::fromImage ( _qimage ) ) ); _qimage = QImage(); } return pixmap(); } } // End of namespace qastools-v0.22.0/shared/src/dpe/image.hpp000066400000000000000000000025301354534512100202310ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_dpe_image_hpp__ #define __INC_dpe_image_hpp__ #include #include namespace dpe { /// @brief Image /// /// An image set that can be shared by multiple users. /// Right after creation the user count is always 0. /// class Image { // Public methods public: Image ( ); ~Image ( ); void clear ( ); void set_size ( unsigned int width_n, unsigned int height_n, unsigned int stride_n ); unsigned int width ( ) const; unsigned int height ( ) const; unsigned int stride ( ) const; unsigned int byte_count ( ) const; QPixmap * convert_to_pixmap ( ); QPixmap * pixmap ( ) const; QImage & qimage ( ); // Private attributes private: QScopedPointer < QPixmap > _pixmap; QImage _qimage; unsigned int _width; unsigned int _height; unsigned int _stride; }; inline unsigned int Image::width ( ) const { return _width; } inline unsigned int Image::height ( ) const { return _height; } inline unsigned int Image::stride ( ) const { return _stride; } inline unsigned int Image::byte_count ( ) const { return height()*stride(); } inline QPixmap * Image::pixmap ( ) const { return _pixmap.data(); } inline QImage & Image::qimage ( ) { return _qimage; } } // End of namespace #endif qastools-v0.22.0/shared/src/dpe/image_allocator.cpp000066400000000000000000000105461354534512100222720ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "image_allocator.hpp" #include "image_set.hpp" #include "image_set_meta.hpp" #include "image_set_group.hpp" #include "image_request.hpp" #include "image_set_state.hpp" #include "painter.hpp" #include "paint_job.hpp" #include "painter_thread.hpp" #include "painter_thread_shared.hpp" #include #include namespace dpe { Image_Allocator::Image_Allocator ( ) { _shared = new ::dpe::Painter_Thread_Shared; _multithread = multithreading_is_safe(); _stop_timer.setInterval ( 1500 ); _stop_timer.setSingleShot ( true ); connect ( &_stop_timer, SIGNAL ( timeout() ), this, SLOT ( stop_timeout() ) ); } Image_Allocator::~Image_Allocator ( ) { stop_threads(); delete _shared; } void Image_Allocator::install_painter ( ::dpe::Painter * painter_n ) { _shared->painters.append ( painter_n ); } bool Image_Allocator::multithreading_is_safe ( ) const { bool res ( true ); // https://bugreports.qt.nokia.com/browse/QTBUG-14614 if ( QT_VERSION < QT_VERSION_CHECK(4, 7, 2) ) { res = false; } return res; } void Image_Allocator::set_multithread ( bool flag_n ) { flag_n = ( flag_n && multithreading_is_safe() ); if ( flag_n != _multithread ) { if ( _multithread ) { _shared->wait_for_finish(); } _multithread = flag_n; } } void Image_Allocator::start_threads ( ) { int num_threads ( QThread::idealThreadCount() ); if ( num_threads <= 0 ) { num_threads = 1; } for ( int ii = 0; ii < num_threads; ++ii ) { _threads.append ( new Painter_Thread ( *_shared ) ); } for ( int ii = 0; ii < num_threads; ++ii ) { _threads[ii]->start(); } } void Image_Allocator::stop_threads ( ) { if ( _threads.size() > 0 ) { // Send abort signal _shared->abort_threads ( _threads.size() ); for ( int ii = 0; ii < _threads.size(); ++ii ) { _threads[ii]->wait(); delete _threads[ii]; } _threads.clear(); } } void Image_Allocator::stop_timeout ( ) { _shared->num_rendering.ref(); if ( !_shared->num_rendering.deref() ) { stop_threads(); } else { _stop_timer.start(); } } void Image_Allocator::send_request ( ::dpe::Image_Request * request_n ) { if ( request_n == 0 ) { return; } for ( unsigned int ii=0; ii < request_n->group->img_sets.size(); ++ii ) { ::dpe::IS_Buffer_Handle * handle; handle = _buffer.acquire_return_handle ( request_n->meta[ii], request_n->group->img_sets[ii] ); if ( handle == 0 ) { // No matching image set found! // Create new handle and image set // and enqueue for rendering ::dpe::IS_Buffer_Handle * hnew ( new ::dpe::IS_Buffer_Handle ); hnew->meta = request_n->meta[ii]->new_copy(); hnew->img_set = new ::dpe::Image_Set ( hnew->meta->num_images ); _buffer.append_handle ( hnew ); process_handle ( hnew ); handle = hnew; } request_n->group->img_sets[ii] = handle->img_set; request_n->states[ii] = handle->state; } } void Image_Allocator::process_handle ( ::dpe::IS_Buffer_Handle * handle_n ) { if ( _multithread ) { if ( _threads.size() <= 0 ) { start_threads(); } _stop_timer.start(); enqueue_handle ( handle_n ); } else { render_handle ( handle_n ); } } void Image_Allocator::render_handle ( ::dpe::IS_Buffer_Handle * handle_n ) { handle_n->state->init_todo ( 0 ); // Create paint jobs unsigned int num ( handle_n->img_set->num_images() ); for ( unsigned int ii=0; ii < num; ++ii ) { ::dpe::Paint_Job pjob; pjob.meta = handle_n->meta; pjob.img_set = handle_n->img_set; pjob.img_idx = ii; pjob.state = handle_n->state; _shared->paint_job ( &pjob ); } } void Image_Allocator::enqueue_handle ( ::dpe::IS_Buffer_Handle * handle_n ) { // Increment todo counters handle_n->state->init_todo ( handle_n->img_set->num_images() ); _shared->num_rendering.ref(); // Create paint jobs and enqueue unsigned int num ( handle_n->img_set->num_images() ); for ( unsigned int ii=0; ii < num; ++ii ) { ::dpe::Paint_Job * pjob ( new ::dpe::Paint_Job ); pjob->meta = handle_n->meta; pjob->img_set = handle_n->img_set; pjob->img_idx = ii; pjob->state = handle_n->state; _shared->enqueue_job ( pjob ); } } void Image_Allocator::return_group ( ::dpe::Image_Set_Group * group_n ) { for ( unsigned int ii=0; ii < group_n->img_sets.size(); ++ii ) { _buffer.return_img_set ( group_n->img_sets[ii] ); group_n->img_sets[ii] = 0; } } } // End of namespace qastools-v0.22.0/shared/src/dpe/image_allocator.hpp000066400000000000000000000027751354534512100223040ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_dpe_image_allocator_hpp__ #define __INC_dpe_image_allocator_hpp__ #include "is_buffer.hpp" #include // Forward declaration namespace dpe { class Image_Set_Group; class Image_Request; class Painter; class Painter_Thread; class Painter_Thread_Shared; } namespace dpe { /// @brief Image_Set_Group allocator /// class Image_Allocator : public QObject { Q_OBJECT // Public methods public: Image_Allocator ( ); ~Image_Allocator ( ); void install_painter ( ::dpe::Painter * painter_n ); // Multithreading bool multithreading_is_safe ( ) const; bool multithread ( ) const; void set_multithread ( bool flag_n ); void send_request ( ::dpe::Image_Request * request_n ); void return_group ( ::dpe::Image_Set_Group * group_n ); // Private slots private slots: void stop_timeout ( ); // Private methods private: void start_threads ( ); void stop_threads ( ); void process_handle ( ::dpe::IS_Buffer_Handle * handle_n ); void render_handle ( ::dpe::IS_Buffer_Handle * handle_n ); void enqueue_handle ( ::dpe::IS_Buffer_Handle * handle_n ); // Private attributes private: ::dpe::IS_Buffer _buffer; ::dpe::Painter_Thread_Shared * _shared; QList < ::dpe::Painter_Thread * > _threads; bool _multithread; QTimer _stop_timer; }; inline bool Image_Allocator::multithread ( ) const { return _multithread; } } // End of namespace #endif qastools-v0.22.0/shared/src/dpe/image_request.cpp000066400000000000000000000012501354534512100217720ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "image_request.hpp" #include "image_set_group.hpp" #include "image_set_meta.hpp" #include "image_set_state.hpp" namespace dpe { Image_Request::Image_Request ( ::dpe::Image_Set_Group * group_n ) : group ( group_n ), meta ( group_n->img_sets.size(), 0 ), states ( group_n->img_sets.size(), 0 ) { } Image_Request::~Image_Request ( ) { } void Image_Request::wait_for_finish ( ) { for ( unsigned int ii=0; ii < states.size(); ++ii ) { ::dpe::Image_Set_State * state ( states[ii] ); if ( state != 0 ) { state->wait_for_finish(); } } } } // End of namespace qastools-v0.22.0/shared/src/dpe/image_request.hpp000066400000000000000000000015611354534512100220040ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_dpe_image_request_hpp__ #define __INC_dpe_image_request_hpp__ #include // Forward declaration namespace dpe { class Image_Set_Meta; class Image_Set_Group; class Image_Set_State; } namespace dpe { /// @brief Image_Request request /// class Image_Request { // Public methods public: Image_Request ( ::dpe::Image_Set_Group * group_n ); ~Image_Request ( ); /// @brief To be called by the requesting thread /// /// This method must be called at some point after /// sending this request to an Image_Allocator. void wait_for_finish ( ); // Public attributes public: ::dpe::Image_Set_Group * group; ::std::vector < ::dpe::Image_Set_Meta * > meta; ::std::vector < ::dpe::Image_Set_State * > states; }; } // End of namespace #endif qastools-v0.22.0/shared/src/dpe/image_set.cpp000066400000000000000000000012101354534512100210710ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "image_set.hpp" namespace dpe { Image_Set::Image_Set ( unsigned int num_images_n ) : _num_images ( num_images_n ), _images ( new ::dpe::Image[num_images_n] ) { } Image_Set::~Image_Set ( ) { } unsigned int Image_Set::byte_count ( ) const { unsigned int cnt ( 0 ); for ( unsigned int ii=0; ii < num_images(); ++ii ) { cnt += image ( ii ).byte_count(); } return cnt; } void Image_Set::convert_to_pixmap ( ) { for ( unsigned int ii=0; ii < num_images(); ++ii ) { image ( ii ).convert_to_pixmap(); } } } // End of namespace qastools-v0.22.0/shared/src/dpe/image_set.hpp000066400000000000000000000027211354534512100211060ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_dpe_image_set_hpp__ #define __INC_dpe_image_set_hpp__ #include "image.hpp" #include namespace dpe { /// @brief Image_Set /// /// An image set that can be shared by multiple users. /// Right after creation the user count is always 0. /// class Image_Set { // Public methods public: Image_Set ( unsigned int num_images_n ); virtual ~Image_Set ( ); void convert_to_pixmap ( ); QPixmap * convert_to_pixmap ( unsigned int idx_n ); // Number of images unsigned int num_images ( ) const; unsigned int byte_count ( ) const; const ::dpe::Image & image ( unsigned int index_n ) const; ::dpe::Image & image ( unsigned int index_n ); QPixmap * pixmap ( unsigned int index_n ); // Private attributes private: unsigned int _num_images; QScopedArrayPointer < ::dpe::Image > _images; }; inline unsigned int Image_Set::num_images ( ) const { return _num_images; } inline const ::dpe::Image & Image_Set::image ( unsigned int index_n ) const { return _images[index_n]; } inline ::dpe::Image & Image_Set::image ( unsigned int index_n ) { return _images[index_n]; } inline QPixmap * Image_Set::pixmap ( unsigned int index_n ) { return image ( index_n ).pixmap(); } inline QPixmap * Image_Set::convert_to_pixmap ( unsigned int idx_n ) { return image ( idx_n ).convert_to_pixmap(); } } // End of namespace #endif qastools-v0.22.0/shared/src/dpe/image_set_group.cpp000066400000000000000000000006701354534512100223160ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "image_set_group.hpp" #include "image_set.hpp" namespace dpe { Image_Set_Group::Image_Set_Group ( unsigned int num_sets_n ) : img_sets ( num_sets_n, 0 ) { } void Image_Set_Group::convert_to_pixmap ( ) { for ( unsigned int ii=0; ii < img_sets.size(); ++ii ) { img_sets[ii]->convert_to_pixmap(); } } } // End of namespace qastools-v0.22.0/shared/src/dpe/image_set_group.hpp000066400000000000000000000013711354534512100223220ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_dpe_image_set_group_hpp__ #define __INC_dpe_image_set_group_hpp__ #include // Forward declaration namespace dpe { class Image_Set; } namespace dpe { /// @brief Image_Set_Group /// class Image_Set_Group { // Public methods public: Image_Set_Group ( unsigned int num_sets_n = 0 ); bool ready ( ) const; void convert_to_pixmap ( ); // Public attributes public: ::std::vector < ::dpe::Image_Set * > img_sets; }; inline bool Image_Set_Group::ready ( ) const { for ( unsigned int ii=0; ii < img_sets.size(); ++ii ) { if ( img_sets[ii] == 0 ) { return false; } } return true; } } // End of namespace #endif qastools-v0.22.0/shared/src/dpe/image_set_meta.cpp000066400000000000000000000017111354534512100221050ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "image_set_meta.hpp" namespace dpe { Image_Set_Meta::Image_Set_Meta ( unsigned int num_images_n, unsigned int group_type_n, unsigned int type_id_n ) : type_id ( type_id_n ), style_id ( 0 ), style_sub_id ( 0 ), group_type ( group_type_n ), group_variant ( 0 ), num_images ( num_images_n ) { } Image_Set_Meta::~Image_Set_Meta ( ) { } bool Image_Set_Meta::matches ( const Image_Set_Meta * meta_n ) const { return ( ( meta_n->type_id == type_id ) && ( meta_n->style_id == style_id ) && ( meta_n->style_sub_id == style_sub_id ) && ( meta_n->size == size ) && ( meta_n->group_type == group_type ) && ( meta_n->group_variant == group_variant ) && ( meta_n->num_images == num_images ) ); } Image_Set_Meta * Image_Set_Meta::new_copy ( ) const { Image_Set_Meta * res ( new Image_Set_Meta ( *this ) ); return res; } } // End of namespace qastools-v0.22.0/shared/src/dpe/image_set_meta.hpp000066400000000000000000000034301354534512100221120ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_dpe_image_set_meta_hpp__ #define __INC_dpe_image_set_meta_hpp__ #include namespace dpe { /// @brief Image_Set_Meta /// class Image_Set_Meta { // Public methods public: Image_Set_Meta ( unsigned int num_images_n, unsigned int group_type_n, unsigned int type_id_n ); virtual ~Image_Set_Meta ( ); /// @brief Tests if an other meta information set matches this one /// /// @return true on match virtual bool matches ( const Image_Set_Meta * cfg_n ) const; /// @brief Creates an exact copy of this meta information /// /// @return pointer to the new copy virtual Image_Set_Meta * new_copy ( ) const; // Attributes /// @brief Image set type /// /// Used to specify the sub element of an image group. /// E.g. slider handle images have a different type_id /// than slider background images. unsigned int type_id; /// @brief Style selection code /// /// Used to specify a widget color scheme. unsigned int style_id; /// @brief Style selection sub code /// /// Used to specify a widget's normal/disabled/inactive state unsigned int style_sub_id; /// @brief Image size QSize size; /// @brief Type of the group this set belongs to /// /// Used to determine the widget type (slider, switch, etc.) /// This one must match the group_id value of the respective ::dpe::Painter unsigned int group_type; /// @brief Variant of the group this set belongs to /// /// Used to switch to a different style/painter of the same widget /// This one must match the group_variant value of the respective ::dpe::Painter unsigned int group_variant; /// @brief Number of images in the set const unsigned int num_images; }; } // End of namespace #endif qastools-v0.22.0/shared/src/dpe/image_set_state.cpp000066400000000000000000000012501354534512100222750ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "image_set_state.hpp" namespace dpe { Image_Set_State::Image_Set_State ( ) : _num_todo ( 0 ), _finished ( false ) { } void Image_Set_State::wait_for_finish ( ) { _mutex.lock(); while ( !_finished ) { _cond.wait ( &_mutex ); } _mutex.unlock(); } void Image_Set_State::init_todo ( unsigned int num_n ) { _num_todo = num_n; _finished = ( _num_todo == 0 ); } bool Image_Set_State::one_done ( ) { bool res = _num_todo.deref(); if ( !res ) { _mutex.lock(); _finished = true; _mutex.unlock(); _cond.wakeAll(); } return res; } } // End of namespace qastools-v0.22.0/shared/src/dpe/image_set_state.hpp000066400000000000000000000014521354534512100223060ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_dpe_is_state_hpp__ #define __INC_dpe_is_state_hpp__ #include #include #include #include namespace dpe { /// @brief Image_Set_State /// class Image_Set_State { // Public methods public: Image_Set_State ( ); void wait_for_finish ( ); void init_todo ( unsigned int num_n ); /// @brief To be called by render threads ( thread safe ) /// /// This method is called by render threads after finishing an /// image paint. /// /// @return True if there's more to do bool one_done ( ); // Private attributes private: QAtomicInt _num_todo; QMutex _mutex; QWaitCondition _cond; bool _finished; }; } // End of namespace #endif qastools-v0.22.0/shared/src/dpe/is_buffer.cpp000066400000000000000000000074721354534512100211200ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "is_buffer.hpp" #include "image_set_meta.hpp" #include "image_set.hpp" #include #include #include namespace dpe { IS_Buffer::IS_Buffer ( ) : _storage_limit ( 4*1024*1024 ) { _remove_poll_timer.setInterval ( 1000 / 3 ); connect ( &_remove_poll_timer, SIGNAL ( timeout() ), this, SLOT ( remove_poll() ) ); } IS_Buffer::~IS_Buffer ( ) { clear(); } unsigned int IS_Buffer::byte_count ( ) const { unsigned int res ( 0 ); for ( int ii=0; ii < _handles.size(); ++ii ) { res += _handles[ii]->img_set->byte_count(); } return res; } void IS_Buffer::clear ( ) { //::std::cout << "IS_Buffer::clear byte count " << byte_count() << "\n"; if ( _handles.size() > 0 ) { for ( int ii=0; ii < _handles.size(); ++ii ) { destroy_handle ( _handles[ii] ); } _handles.clear(); } } void IS_Buffer::destroy_handle ( ::dpe::IS_Buffer_Handle * handle_n ) { assert ( handle_n->num_users == 0 ); delete handle_n->img_set; delete handle_n->meta; delete handle_n; } ::dpe::IS_Buffer_Handle * IS_Buffer::acquire_return_handle ( const ::dpe::Image_Set_Meta * meta_n, ::dpe::Image_Set * cur_set_n ) { ::dpe::IS_Buffer_Handle * res ( 0 ); // Try to find an image set with matching meta information for ( int ii=0; ii < _handles.size(); ++ii ) { ::dpe::IS_Buffer_Handle * handle ( _handles[ii] ); if ( meta_n->matches ( handle->meta ) ) { res = handle; break; } } bool no_match ( true ); if ( res != 0 ) { // Increment user count of the set found // if the argument set is not the found set no_match = ( res->img_set != cur_set_n ); if ( no_match ) { ++res->num_users; } } if ( ( cur_set_n != 0 ) && no_match ) { return_img_set ( cur_set_n ); } return res; } void IS_Buffer::append_handle ( ::dpe::IS_Buffer_Handle * handle_n ) { ++handle_n->num_users; _handles.append ( handle_n ); } void IS_Buffer::return_img_set ( ::dpe::Image_Set * img_set_n ) { if ( img_set_n == 0 ) { return; } int list_idx ( _handles.size() ); for ( int ii=0; ii < _handles.size(); ++ii ) { ::dpe::Image_Set * img_set ( _handles[ii]->img_set ); if ( img_set == img_set_n ) { list_idx = ii; break; } } if ( list_idx < _handles.size() ) { // Image set found in list ::dpe::IS_Buffer_Handle * handle ( _handles[list_idx] ); //::std::cout << "IS_Buffer::return_img_set users " << handle->num_users << "\n"; if ( handle->num_users > 0 ) { --handle->num_users; } if ( handle->num_users == 0 ) { //::std::cout << "IS_Buffer::return_img_set bytes " << byte_count() << "\n"; if ( byte_count() <= _storage_limit ) { // Delete later handle->remove_time.start(); handle->remove_time = handle->remove_time.addMSecs ( 1000 ); if ( !_remove_poll_timer.isActive() ) { _remove_poll_timer.start(); } } else { destroy_handle ( handle ); _handles.removeAt ( list_idx ); } } } //::std::cout << "::dpe::IS_Buffer::return_img_set: "; //::std::cout << "List size " << _handles.size() << "\n"; } void IS_Buffer::remove_poll ( ) { unsigned int pending ( 0 ); QTime time_now; time_now.start(); int idx ( 0 ); while ( idx < _handles.size() ) { ::dpe::IS_Buffer_Handle * handle ( _handles[idx] ); bool do_remove ( false ); if ( handle->num_users == 0 ) { QTime & remove_time ( handle->remove_time ); if ( remove_time.isValid() ) { if ( remove_time <= time_now ) { do_remove = true; } else { ++pending; } } } if ( do_remove ) { destroy_handle ( handle ); _handles.removeAt ( idx ); } else { ++idx; } } if ( pending == 0 ) { _remove_poll_timer.stop(); } //::std::cout << "::dpe::IS_Buffer::remove_poll: "; //::std::cout << "List size " << _handles.size() << "\n"; } } // End of namespace qastools-v0.22.0/shared/src/dpe/is_buffer.hpp000066400000000000000000000023131354534512100211120ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_dpe_image_set_buffer_hpp__ #define __INC_dpe_image_set_buffer_hpp__ #include #include #include "is_buffer_handle.hpp" namespace dpe { /// @brief IS_Buffer /// class IS_Buffer : public QObject { Q_OBJECT // Public methods public: IS_Buffer ( ); ~IS_Buffer ( ); void clear ( ); // Buffer info unsigned int num_sets ( ) const; unsigned int byte_count ( ) const; // Image set accquiring an returning ::dpe::IS_Buffer_Handle * acquire_return_handle ( const ::dpe::Image_Set_Meta * meta_n, ::dpe::Image_Set * cur_set_n = 0 ); void append_handle ( ::dpe::IS_Buffer_Handle * handle_n ); void return_img_set ( ::dpe::Image_Set * img_set_n ); // Private slots private slots: void remove_poll ( ); // Private methods private: void destroy_handle ( ::dpe::IS_Buffer_Handle * handle_n ); // Private attributes private: QList < ::dpe::IS_Buffer_Handle * > _handles; QTimer _remove_poll_timer; unsigned int _storage_limit; }; inline unsigned int IS_Buffer::num_sets ( ) const { return _handles.size(); } } // End of namespace #endif qastools-v0.22.0/shared/src/dpe/is_buffer_handle.cpp000066400000000000000000000005551354534512100224260ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "is_buffer_handle.hpp" #include "image_set_state.hpp" namespace dpe { IS_Buffer_Handle::IS_Buffer_Handle ( ) : num_users ( 0 ), state ( new ::dpe::Image_Set_State ) { } IS_Buffer_Handle::~IS_Buffer_Handle ( ) { delete state; } } // End of namespace qastools-v0.22.0/shared/src/dpe/is_buffer_handle.hpp000066400000000000000000000011741354534512100224310ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_dpe_is_buffer_handle_hpp__ #define __INC_dpe_is_buffer_handle_hpp__ #include // Forward declaration namespace dpe { class Image_Set; class Image_Set_Meta; class Image_Set_State; } namespace dpe { /// @brief IS_Buffer_Handle /// class IS_Buffer_Handle { // Public methods public: IS_Buffer_Handle ( ); ~IS_Buffer_Handle ( ); ::dpe::Image_Set * img_set; ::dpe::Image_Set_Meta * meta; unsigned int num_users; QTime remove_time; ::dpe::Image_Set_State * state; }; } // End of namespace #endif qastools-v0.22.0/shared/src/dpe/paint_job.cpp000066400000000000000000000003021354534512100211020ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "paint_job.hpp" namespace dpe { Paint_Job::Paint_Job ( ) { } } // End of namespace qastools-v0.22.0/shared/src/dpe/paint_job.hpp000066400000000000000000000011161354534512100211130ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_dpe_paint_job_hpp__ #define __INC_dpe_paint_job_hpp__ // Forward declaration namespace dpe { class Image_Request; class Image_Set; class Image_Set_Meta; class Image_Set_State; } namespace dpe { /// @brief Paint_Job /// class Paint_Job { // Public methods public: Paint_Job ( ); // Public attributes public: ::dpe::Image_Set_Meta * meta; ::dpe::Image_Set * img_set; unsigned int img_idx; ::dpe::Image_Set_State * state; }; } // End of namespace #endif qastools-v0.22.0/shared/src/dpe/painter.cpp000066400000000000000000000014451354534512100206100ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "painter.hpp" #include "paint_job.hpp" #include "image_set_meta.hpp" namespace dpe { Painter::Painter ( unsigned int group_type_n, unsigned int group_variant_n ) : _group_type ( group_type_n ), _group_variant ( group_variant_n ) { } Painter::~Painter ( ) { } void Painter::set_group_variant ( unsigned int variant_n ) { _group_variant = variant_n; } int Painter::check_and_paint ( ::dpe::Paint_Job * pjob_n ) { int res ( -1 ); if ( pjob_n->meta == 0 ) { return res; } { const QSize & isize ( pjob_n->meta->size ); if ( ( isize.width() <= 0 ) || ( isize.height() <= 0 ) ) { return res; } } res = this->paint_image ( pjob_n ); return res; } } // End of namespace qastools-v0.22.0/shared/src/dpe/painter.hpp000066400000000000000000000022751354534512100206170ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_dpe_painter_hpp__ #define __INC_dpe_painter_hpp__ // Forward declaration namespace dpe { class Image_Set; class Image_Set_Meta; class Paint_Job; } namespace dpe { /// @brief Painter /// class Painter { // Public methods public: Painter ( unsigned int group_type_n, unsigned int group_variant_n = 0 ); virtual ~Painter ( ); unsigned int group_type ( ) const; unsigned int group_variant ( ) const; void set_group_variant ( unsigned int variant_n ); int check_and_paint ( ::dpe::Paint_Job * pjob_n ); // Protected methods protected: /// @brief Single image painting method /// /// @return 0 on success ( no error ) virtual int paint_image ( ::dpe::Paint_Job * pjob_n ) = 0; // Private attributes private: /// @brief Type of the group this painter knows how to paint unsigned int _group_type; /// @brief Group variant id unsigned int _group_variant; }; inline unsigned int Painter::group_type ( ) const { return _group_type; } inline unsigned int Painter::group_variant ( ) const { return _group_variant; } } // End of namespace #endif qastools-v0.22.0/shared/src/dpe/painter_simple.cpp000066400000000000000000000016661354534512100221660ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "painter_simple.hpp" #include "paint_job.hpp" #include "image_set.hpp" #include "image_set_meta.hpp" #include #include namespace dpe { Painter_Simple::Painter_Simple ( ) : ::dpe::Painter ( 0 ) { } Painter_Simple::~Painter_Simple ( ) { } int Painter_Simple::paint_image ( ::dpe::Paint_Job * pjob_n ) { int res ( 0 ); ::dpe::Image & img ( pjob_n->img_set->image ( pjob_n->img_idx ) ); ::dpe::Image_Set_Meta * meta ( pjob_n->meta ); img.set_size ( meta->size.width(), meta->size.height(), meta->size.width() * 4 ); { QColor col; { unsigned int seed ( pjob_n->img_set->num_images() + pjob_n->img_idx * 10 ); seed += time(0); qsrand ( seed ); col.setRgb ( qrand() % 256, qrand() % 256, qrand() % 256, 128 ); } img.qimage().fill ( col.rgba() ); } return res; } } // End of namespace qastools-v0.22.0/shared/src/dpe/painter_simple.hpp000066400000000000000000000007551354534512100221710ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_dpe_painter_simple_hpp__ #define __INC_dpe_painter_simple_hpp__ #include "painter.hpp" namespace dpe { /// @brief Painter_Simple /// class Painter_Simple : public ::dpe::Painter { // Public methods public: Painter_Simple ( ); ~Painter_Simple ( ); int paint_image ( ::dpe::Paint_Job * pjob_n ); // Private attributes private: }; } // End of namespace #endif qastools-v0.22.0/shared/src/dpe/painter_thread.cpp000066400000000000000000000010741354534512100221350ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "painter_thread.hpp" #include "painter_thread_shared.hpp" #include namespace dpe { Painter_Thread::Painter_Thread ( ::dpe::Painter_Thread_Shared & shared_n ) : _shared ( shared_n ) { } void Painter_Thread::run ( ) { while ( true ) { ::dpe::Paint_Job * pjob ( _shared.fetch_job() ); if ( pjob == 0 ) { // Exit loop on invalid job break; } _shared.paint_job ( pjob ); _shared.job_finished ( pjob ); } } } // End of namespace qastools-v0.22.0/shared/src/dpe/painter_thread.hpp000066400000000000000000000011671354534512100221450ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_dpe_paint_thread_hpp__ #define __INC_dpe_paint_thread_hpp__ #include // Forward declaration namespace dpe { class Painter_Thread_Shared; class Paint_Job; } namespace dpe { /// @brief Painter_Thread /// class Painter_Thread : public QThread { // Public methods public: Painter_Thread ( ::dpe::Painter_Thread_Shared & shared_n ); // Protected methods protected: void run ( ); // Private attributes private: ::dpe::Painter_Thread_Shared & _shared; }; } // End of namespace #endif qastools-v0.22.0/shared/src/dpe/painter_thread_shared.cpp000066400000000000000000000053761354534512100234740ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "painter_thread_shared.hpp" #include "painter.hpp" #include "painter_simple.hpp" #include "image_set_meta.hpp" #include "image_set_state.hpp" #include "paint_job.hpp" #include namespace dpe { Painter_Thread_Shared::Painter_Thread_Shared ( ) { painter_def = new ::dpe::Painter_Simple; num_rendering = 0; _finished = false; } Painter_Thread_Shared::~Painter_Thread_Shared ( ) { for ( int ii=0; ii < painters.size(); ++ii ) { delete painters[ii]; } delete painter_def; painters.clear(); } void Painter_Thread_Shared::enqueue_job ( ::dpe::Paint_Job * pjob_n ) { _queue_mutex.lock(); _finished = false; _queue.enqueue ( pjob_n ); _queue_mutex.unlock(); _queue_cond.wakeOne(); } ::dpe::Paint_Job * Painter_Thread_Shared::fetch_job ( ) { ::dpe::Paint_Job * pjob; _queue_mutex.lock(); while ( _queue.size() == 0 ) { _queue_cond.wait ( &_queue_mutex ); } pjob = _queue.dequeue(); _queue_mutex.unlock(); return pjob; } void Painter_Thread_Shared::job_finished ( ::dpe::Paint_Job * pjob_n ) { if ( !pjob_n->state->one_done() ) { if ( !num_rendering.deref() ) { bool do_wake ( false ); _queue_mutex.lock(); if ( _queue.size() == 0 ) { _finished = true; do_wake = true; } _queue_mutex.unlock(); if ( do_wake ) { _finished_cond.wakeAll(); } } } delete pjob_n; } void Painter_Thread_Shared::wait_for_finish ( ) { _queue_mutex.lock(); while ( !_finished ) { _finished_cond.wait ( &_queue_mutex ); } _queue_mutex.unlock(); } int Painter_Thread_Shared::paint_job ( ::dpe::Paint_Job * pjob_n ) { // Find painter and paint ::dpe::Painter * pnt ( find_painter ( pjob_n->meta ) ); return pnt->check_and_paint ( pjob_n ); } ::dpe::Painter * Painter_Thread_Shared::find_painter ( ::dpe::Image_Set_Meta * meta_n ) { ::dpe::Painter * pnt ( 0 ); { const unsigned int group_type ( meta_n->group_type ); unsigned int group_variant ( meta_n->group_variant ); while ( true ) { // Search painter for ( int ii=0; ii < painters.size(); ++ii ) { ::dpe::Painter * pcur ( painters[ii] ); if ( ( pcur->group_type() == group_type ) && ( pcur->group_variant() == group_variant ) ) { pnt = pcur; break; } } if ( pnt != 0 ) { break; } else { // Search again with default variant on demand if ( group_variant == 0 ) { pnt = painter_def; break; } else { group_variant = 0; } } } } return pnt; } void Painter_Thread_Shared::abort_threads ( unsigned int num_n ) { _queue_mutex.lock(); for ( unsigned int ii = 0; ii < num_n; ++ii ) { _queue.append ( 0 ); } _queue_mutex.unlock(); _queue_cond.wakeAll(); } } // End of namespace qastools-v0.22.0/shared/src/dpe/painter_thread_shared.hpp000066400000000000000000000024711354534512100234720ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_dpe_paint_thread_shared_hpp__ #define __INC_dpe_paint_thread_shared_hpp__ #include #include #include #include // Forward declaration namespace dpe { class Paint_Job; class Painter; class Image_Set_Meta; } namespace dpe { /// @brief Painter_Thread_Shared /// class Painter_Thread_Shared { // Public methods public: Painter_Thread_Shared ( ); ~Painter_Thread_Shared ( ); ::dpe::Painter * find_painter ( ::dpe::Image_Set_Meta * meta_n ); int paint_job ( ::dpe::Paint_Job * pjob_n ); // Threading void enqueue_job ( ::dpe::Paint_Job * pjob_n ); ::dpe::Paint_Job * fetch_job ( ); void job_finished ( ::dpe::Paint_Job * pjob_n ); void wait_for_finish ( ); /// @brief sends and abort signal to all threads void abort_threads ( unsigned int num_n ); // Public attributes public: QList < ::dpe::Painter * > painters; /// @brief Fallback painter ::dpe::Painter * painter_def; // Statistics QAtomicInt num_rendering; // Private attributes; private: QMutex _queue_mutex; QQueue < ::dpe::Paint_Job * > _queue; QWaitCondition _queue_cond; bool _finished; QWaitCondition _finished_cond; }; } // End of namespace #endif qastools-v0.22.0/shared/src/license_texts.cpp000066400000000000000000000024101354534512100212400ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "license_texts.hpp" const char license_text_short[] = "\ Copyright QasTools Contributors.\n\ \n\ Permission is hereby granted, free of charge, to any person obtaining\n\ a copy of this software and associated documentation files (the\n\ \"Software\"), to deal in the Software without restriction, including\n\ without limitation the rights to use, copy, modify, merge, publish,\n\ distribute, sublicense, and/or sell copies of the Software, and to\n\ permit persons to whom the Software is furnished to do so, subject to\n\ the following conditions:\n\ \n\ The above copyright notice and this permission notice shall be\n\ included in all copies or substantial portions of the Software.\n\ \n\ THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\n\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\n\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\ "; qastools-v0.22.0/shared/src/license_texts.hpp000066400000000000000000000003261354534512100212510ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_license_texts_hpp__ #define __INC_license_texts_hpp__ extern const char license_text_short[]; #endif qastools-v0.22.0/shared/src/mwdg/000077500000000000000000000000001354534512100166245ustar00rootroot00000000000000qastools-v0.22.0/shared/src/mwdg/controls_delegate.cpp000066400000000000000000000137271354534512100230370ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "controls_delegate.hpp" #include "qsnd/model_keys.hpp" #include #include #include namespace MWdg { Controls_Delegate::Controls_Delegate ( QObject * parent_n ) : QStyledItemDelegate ( parent_n ) { _hmargin = 4; _vmargin = 3; _vspace = 1; } QSize Controls_Delegate::sizeHint ( const QStyleOptionViewItem & option_n, const QModelIndex & index_n ) const { QSize res ( 0, 0 ); QStyleOptionViewItemV4 opt ( option_n ); initStyleOption ( &opt, index_n ); const QFontMetrics & fmet ( opt.fontMetrics ); res.setWidth ( fmet.averageCharWidth()*12 ); res.rheight() += 2*_vmargin; if ( index_n.data ( ::QSnd::MKEY_CARD_INDEX ).isValid() ) { // Is Card res.rheight() += fmet.height()*2; res.rheight() += _vspace; } else { // Is Control res.rheight() += fmet.height(); } return res; } void Controls_Delegate::paint ( QPainter * painter_n, const QStyleOptionViewItem & option_n, const QModelIndex & index_n ) const { Q_ASSERT ( index_n.isValid() ); QStyleOptionViewItemV4 opt ( option_n ); initStyleOption ( &opt, index_n ); const QFontMetrics & fmet ( opt.fontMetrics ); opt.text = QString(); QStyle * style ( 0 ); if ( opt.widget != 0 ) { style = opt.widget->style(); } if ( style == 0 ) { style = QApplication::style(); } QFont fnt ( opt.font ); QColor col_fg; double rrad ( qMin ( _hmargin, _vmargin ) ); { // Color group from state QPalette::ColorGroup col_grp ( QPalette::Active ); if ( opt.state & QStyle::State_Enabled ) { if ( !( opt.state & QStyle::State_Active ) ) { col_grp = QPalette::Inactive; } } else { col_grp = QPalette::Disabled; } // Adjust background brush and foreground color from state QPalette::ColorRole col_role ( QPalette::Text ); if ( opt.state & QStyle::State_Selected ) { col_role = QPalette::HighlightedText; QBrush & br ( opt.backgroundBrush ); br.setStyle ( Qt::SolidPattern ); br.setColor ( opt.palette.color ( col_grp, QPalette::Highlight ) ); } col_fg = opt.palette.color ( col_grp, col_role ); } // Save and setup painter painter_n->save(); painter_n->setRenderHints ( QPainter::TextAntialiasing | QPainter::Antialiasing ); // Paint background { // Paint solid area { painter_n->setBrush ( opt.backgroundBrush ); painter_n->setPen ( Qt::NoPen ); painter_n->drawRoundedRect ( opt.rect, rrad, rrad ); } // Paint frame if ( ( opt.state & QStyle::State_Selected ) ) { painter_n->setBrush ( Qt::NoBrush ); { QPen pen; pen.setWidth ( 1 ); { QColor pcol ( col_fg ); if ( ( opt.state & QStyle::State_Active ) ) { pcol.setAlpha ( 128 ); } else { pcol.setAlpha ( 32 ); } pen.setColor ( pcol ); } { Qt::PenStyle pstyle; if ( ( opt.state & QStyle::State_Active ) ) { pstyle = Qt::DotLine; } else { pstyle = Qt::SolidLine; } pen.setStyle ( pstyle ); } painter_n->setPen ( pen ); } QRectF re_frame ( opt.rect ); re_frame.adjust ( 0.5, 0.5, -0.5, -0.5 ); painter_n->drawRoundedRect ( re_frame, rrad, rrad ); } } if ( index_n.data ( ::QSnd::MKEY_CARD_INDEX ).isValid() ) { // Is card QRect re_t0; QRect re_t1; QRect re_t2; { int hspace ( fmet.averageCharWidth() * 3 / 4 ); re_t0.setWidth ( fmet.width ( "9:" ) ); re_t0.setHeight ( fmet.height() ); re_t0.moveLeft ( opt.rect.left() + _hmargin ); re_t0.moveTop ( opt.rect.top() + _vmargin ); re_t1.setWidth ( opt.rect.width() - re_t0.width() - hspace - 2*_hmargin ); re_t1.setHeight ( fmet.height() ); re_t1.moveLeft ( re_t0.left() + re_t0.width() + hspace ); re_t1.moveTop ( re_t0.top() ); re_t2.setWidth ( re_t1.width() ); re_t2.setHeight ( re_t1.height() ); re_t2.moveLeft ( re_t1.left() ); re_t2.moveTop ( re_t1.top() + re_t1.height() + _vspace ); } // Paint foreground painter_n->setPen ( QPen ( col_fg ) ); painter_n->setBrush ( Qt::NoBrush ); painter_n->setFont ( fnt ); // Index string QString txt; txt.setNum ( index_n.data ( ::QSnd::MKEY_CARD_INDEX ).toInt() ); txt.append ( ":" ); painter_n->drawText ( re_t0, Qt::AlignRight | Qt::AlignVCenter, txt ); // Name string txt = index_n.data ( ::QSnd::MKEY_CARD_NAME ).toString(); txt = fmet.elidedText ( txt, opt.textElideMode, re_t1.width() ); painter_n->drawText ( re_t1, Qt::AlignLeft | Qt::AlignVCenter, txt ); // Bottom string fnt.setItalic ( true ); painter_n->setFont ( fnt ); col_fg.setAlpha ( 160 ); painter_n->setPen ( QPen ( col_fg ) ); txt = index_n.data ( ::QSnd::MKEY_CARD_MIXER_NAME ).toString(); txt = fmet.elidedText ( txt, opt.textElideMode, re_t2.width() ); painter_n->drawText ( re_t2, Qt::AlignLeft | Qt::AlignVCenter, txt ); } else { // Is control QRect re_t0; { re_t0.setWidth ( opt.rect.width() - 2*_hmargin ); re_t0.setHeight ( fmet.height() ); re_t0.moveLeft ( opt.rect.left() + _hmargin ); re_t0.moveTop ( opt.rect.top() + _vmargin ); } // Paint text painter_n->setPen ( QPen ( col_fg ) ); painter_n->setBrush ( Qt::NoBrush ); painter_n->setFont ( fnt ); // Name string QRect brect; { QString txt ( index_n.data ( Qt::DisplayRole ).toString() ); txt = fmet.elidedText ( txt, opt.textElideMode, re_t0.width() ); painter_n->drawText ( re_t0, Qt::AlignLeft | Qt::AlignVCenter, txt, &brect ); } { const QStringList & arg_lst ( index_n.data ( ::QSnd::MKEY_L10N_ARGS ).toStringList() ); if ( arg_lst.size() > 0 ) { col_fg.setAlpha ( 160 ); painter_n->setPen ( QPen ( col_fg ) ); fnt.setItalic ( true ); painter_n->setFont ( fnt ); QString txt ( " : " ); txt.append ( arg_lst.join ( "," ) ); re_t0.setLeft ( brect.left() + brect.width() ); txt = fmet.elidedText ( txt, opt.textElideMode, re_t0.width() ); painter_n->drawText ( re_t0, Qt::AlignLeft | Qt::AlignVCenter, txt ); } } } // Restore painter painter_n->restore(); } } // End of namespace qastools-v0.22.0/shared/src/mwdg/controls_delegate.hpp000066400000000000000000000014131354534512100230310ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_mwdg_controls_delegate_hpp__ #define __INC_mwdg_controls_delegate_hpp__ #include namespace MWdg { /// @brief Controls_Delegate /// class Controls_Delegate : public QStyledItemDelegate { Q_OBJECT // Public methods public: Controls_Delegate ( QObject * parent_n = 0 ); QSize sizeHint ( const QStyleOptionViewItem & option_n, const QModelIndex & index_n ) const; void paint ( QPainter * painter_n, const QStyleOptionViewItem & option_n, const QModelIndex & index_n ) const; // Private attributes private: unsigned int _hmargin; unsigned int _vmargin; unsigned int _vspace; }; } // End of namespace #endif qastools-v0.22.0/shared/src/mwdg/controls_view.cpp000066400000000000000000000105231354534512100222260ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "controls_view.hpp" #include "mwdg/event_types.hpp" #include "mwdg/controls_delegate.hpp" #include #include #include namespace MWdg { Controls_View::Controls_View ( QWidget * parent_n ) : QListView ( parent_n ), _show_rows_min ( 3 ), _show_rows_avrg ( 10 ), _min_chars_vis ( 12 ), _maximum_update_requested ( false ) { setHorizontalScrollBarPolicy ( Qt::ScrollBarAlwaysOff ); { QSizePolicy policy ( sizePolicy() ); policy.setVerticalPolicy ( QSizePolicy::Expanding ); setSizePolicy ( policy ); } setSelectionMode ( QAbstractItemView::SingleSelection ); setItemDelegate ( new ::MWdg::Controls_Delegate ( this ) ); } Controls_View::~Controls_View ( ) { } QSize Controls_View::minimumSizeHint ( ) const { ensurePolished(); QSize res; int & ww ( res.rwidth() ); int & hh ( res.rheight() ); QSize vsb_msh ( verticalScrollBar()->minimumSizeHint() ); QSize vsb_sh ( verticalScrollBar()->sizeHint() ); // Width { ww = fontMetrics().averageCharWidth() * _min_chars_vis; ww = qMax ( 16, ww ); if ( spacing() > 0 ) { ww += spacing()*2; } if ( vsb_msh.width() > 0 ) { ww += vsb_msh.width(); } else if ( vsb_sh.width() > 0 ) { ww += vsb_sh.width(); } } // Height { int rh0 ( sizeHintForRow ( 0 ) ); rh0 = qMax ( rh0, itemDelegate()->sizeHint ( viewOptions(), QModelIndex() ).height() ); if ( spacing() > 0 ) { rh0 += spacing()*2; } hh = rh0 * _show_rows_min; hh = qMax ( vsb_msh.height(), hh ); } QMargins mg ( contentsMargins() ); ww += mg.left() + mg.right(); hh += mg.top() + mg.bottom(); return res; } QSize Controls_View::sizeHint ( ) const { ensurePolished(); QSize res; int & ww ( res.rwidth() ); int & hh ( res.rheight() ); QSize vsb_sh ( verticalScrollBar()->sizeHint() ); // Width { ww = fontMetrics().averageCharWidth() * ( _min_chars_vis * 3 / 2 ); if ( spacing() > 0 ) { ww += spacing()*2; } if ( vsb_sh.width() > 0 ) { ww += vsb_sh.width(); } } // Height { int rh0 ( sizeHintForRow ( 0 ) ); rh0 = qMax ( rh0, itemDelegate()->sizeHint ( viewOptions(), QModelIndex() ).height() ); if ( spacing() > 0 ) { rh0 += spacing()*2; } hh = rh0 * _show_rows_avrg; hh = qMax ( vsb_sh.height(), hh ); } QMargins mg ( contentsMargins() ); ww += mg.left() + mg.right(); hh += mg.top() + mg.bottom(); return res; } void Controls_View::setModel ( QAbstractItemModel * model_n ) { if ( model() != 0 ) { disconnect ( model(), 0, this, 0 ); } QListView::setModel ( model_n ); if ( model() != 0 ) { maximum_height_update_request(); connect ( model(), SIGNAL ( modelReset() ), this, SLOT ( maximum_height_update_request() ) ); connect ( model(), SIGNAL ( layoutChanged() ), this, SLOT ( maximum_height_update_request() ) ); connect ( model(), SIGNAL ( rowsInserted ( const QModelIndex &, int , int ) ), this, SLOT ( maximum_height_update_request() ) ); connect ( model(), SIGNAL ( rowsRemoved ( const QModelIndex &, int , int ) ), this, SLOT ( maximum_height_update_request() ) ); } } void Controls_View::maximum_height_update_request ( ) { if ( !_maximum_update_requested ) { _maximum_update_requested = true; QCoreApplication::postEvent ( this, new QEvent ( ::MWdg::evt_refresh_data ) ); } } bool Controls_View::event ( QEvent * event_n ) { bool res ( false ); if ( event_n->type() == ::MWdg::evt_refresh_data ) { _maximum_update_requested = false; maximum_height_update(); res = true; } else { res = QListView::event ( event_n ); } return res; } void Controls_View::changeEvent ( QEvent * event_n ) { maximum_height_update_request(); QListView::changeEvent ( event_n ); } void Controls_View::maximum_height_update ( ) { unsigned int hsum ( 16000 ); unsigned int vspace ( 0 ); if ( spacing() > 0 ) { vspace = spacing()*2; } if ( model() != 0 ) { hsum = 0; hsum += frameWidth()*2; for ( int ii=0; ii < model()->rowCount(); ++ii ) { int hrow ( sizeHintForRow ( ii ) ); if ( hrow <= 0 ) { hrow = sizeHintForRow ( 0 ); } hrow += vspace; if ( hrow > 0 ) { hsum += hrow; } } } //::std::cout << "Controls_View::maximum_height_update " << hsum << "\n"; if ( maximumHeight() != (int)hsum ) { setMaximumHeight ( hsum ); } } } // End of namespace qastools-v0.22.0/shared/src/mwdg/controls_view.hpp000066400000000000000000000016341354534512100222360ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_mwdg_controls_view_hpp__ #define __INC_mwdg_controls_view_hpp__ #include namespace MWdg { /// @brief Controls_View /// class Controls_View : public QListView { Q_OBJECT // Public methods public: Controls_View ( QWidget * parent_n = 0 ); ~Controls_View ( ); QSize minimumSizeHint ( ) const; QSize sizeHint ( ) const; void setModel ( QAbstractItemModel * model_n ); bool event ( QEvent * event_n ); // Protected slots protected slots: void maximum_height_update_request ( ); // Protected methods protected: void changeEvent ( QEvent * event_n ); void maximum_height_update ( ); // Private attributes private: int _show_rows_min; int _show_rows_avrg; int _min_chars_vis; bool _maximum_update_requested; }; } // End of namespace #endif qastools-v0.22.0/shared/src/mwdg/ctl_arg_view.cpp000066400000000000000000000042661354534512100220050ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "ctl_arg_view.hpp" #include "qsnd/ctl_format_argument.hpp" #include namespace MWdg { CTL_Arg_View::CTL_Arg_View ( QWidget * parent_n ) : QWidget ( parent_n ), _ctl_db ( 0 ), _cards_model ( 0 ), _ctl_arg ( 0 ) { _wdg_title = new QLabel; { QFont fnt ( _wdg_title->font() ); fnt.setBold ( true ); _wdg_title->setFont ( fnt ); } QVBoxLayout * lay_vbox ( new QVBoxLayout ); lay_vbox->setContentsMargins ( 0, 0, 0, 0 ); _lay_content = new QVBoxLayout; lay_vbox->addWidget ( _wdg_title, 0 ); lay_vbox->addLayout ( _lay_content, 1 ); setLayout ( lay_vbox ); } void CTL_Arg_View::set_ctl_db ( const ::QSnd::Controls_Database * ctl_db_n ) { if ( _ctl_db != ctl_db_n ) { _ctl_db = ctl_db_n; this->ctl_db_changed(); } } void CTL_Arg_View::set_cards_model ( ::QSnd::Cards_Model * cards_model_n ) { if ( _cards_model != cards_model_n ) { _cards_model = cards_model_n; this->cards_model_changed(); } } void CTL_Arg_View::set_ctl_arg ( const ::QSnd::CTL_Format_Argument & ctl_arg_n ) { if ( _ctl_arg != ctl_arg_n ) { _ctl_arg = ctl_arg_n; this->ctl_arg_changed(); } } void CTL_Arg_View::set_arg_string ( const QString & str_n ) { if ( _arg_string != str_n ) { _arg_string = str_n; emit sig_arg_changed(); } } bool CTL_Arg_View::set_arg_string_private ( const QString & str_n ) { if ( _arg_string != str_n ) { _arg_string = str_n; return true; } return false; } void CTL_Arg_View::ctl_db_changed ( ) { // Does nothing by default } void CTL_Arg_View::cards_model_changed ( ) { // Does nothing by default } void CTL_Arg_View::ctl_arg_changed ( ) { if ( _ctl_arg.is_valid() ) { // Text { const QString name_l10n ( QCoreApplication::translate ( "ALSA::CTL_Arg_Name", _ctl_arg.arg_name.toUtf8().constData() ) ); QString txt; //txt.append ( QChar ( 0x2192 ) ); txt.append ( name_l10n ); _wdg_title->setText ( txt ); } // Tooltip { QString ttip ( _ctl_arg.arg_name ); ttip.append ( " (" ); ttip.append ( _ctl_arg.arg_type ); ttip.append ( ")" ); _wdg_title->setToolTip ( ttip ); } } } } // End of namespace qastools-v0.22.0/shared/src/mwdg/ctl_arg_view.hpp000066400000000000000000000040521354534512100220030ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_mwdg_ctl_arg_view_hpp__ #define __INC_mwdg_ctl_arg_view_hpp__ #include #include #include #include // Forward declaration namespace QSnd { class Controls_Database; class Cards_Model; } namespace MWdg { /// @brief CTL_Arg_View /// class CTL_Arg_View : public QWidget { Q_OBJECT // Public methods public: CTL_Arg_View ( QWidget * parent_n = 0 ); // Controls database const ::QSnd::Controls_Database * ctl_db ( ) const; void set_ctl_db ( const ::QSnd::Controls_Database * ctl_db_n ); // Cards database ::QSnd::Cards_Model * cards_model ( ) const; void set_cards_model ( ::QSnd::Cards_Model * cards_model_n ); // Control argument const ::QSnd::CTL_Format_Argument & ctl_arg ( ) const; void set_ctl_arg ( const ::QSnd::CTL_Format_Argument & ctl_arg_n ); const QString & arg_string ( ) const; virtual void set_arg_string ( const QString & str_n ); // Signals signals: void sig_arg_changed ( ); // Protected methods protected: bool set_arg_string_private ( const QString & str_n ); virtual void ctl_db_changed ( ); virtual void cards_model_changed ( ); virtual void ctl_arg_changed ( ); QVBoxLayout * lay_content ( ); // Private attributes private: const ::QSnd::Controls_Database * _ctl_db; ::QSnd::Cards_Model * _cards_model; ::QSnd::CTL_Format_Argument _ctl_arg; QString _arg_string; QLabel * _wdg_title; QVBoxLayout * _lay_content; }; inline const ::QSnd::Controls_Database * CTL_Arg_View::ctl_db ( ) const { return _ctl_db; } inline ::QSnd::Cards_Model * CTL_Arg_View::cards_model ( ) const { return _cards_model; } inline const ::QSnd::CTL_Format_Argument & CTL_Arg_View::ctl_arg ( ) const { return _ctl_arg; } inline const QString & CTL_Arg_View::arg_string ( ) const { return _arg_string; } inline QVBoxLayout * CTL_Arg_View::lay_content ( ) { return _lay_content; } } // End of namespace #endif qastools-v0.22.0/shared/src/mwdg/ctl_arg_view_card.cpp000066400000000000000000000041071354534512100227700ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "ctl_arg_view_card.hpp" #include "qsnd/card_info.hpp" #include "qsnd/cards_model.hpp" #include "mwdg/controls_view.hpp" #include #include namespace MWdg { CTL_Arg_View_Card::CTL_Arg_View_Card ( QWidget * parent_n ) : ::MWdg::CTL_Arg_View ( parent_n ) { _ctl_view = new ::MWdg::Controls_View ( this ); lay_content()->addWidget ( _ctl_view ); } void CTL_Arg_View_Card::set_arg_string ( const QString & str_n ) { if ( set_arg_string_private ( str_n ) ) { // Update view if ( cards_model() != 0 ) { QModelIndex midx ( cards_model()->model_index_by_card_id ( arg_string() ) ); if ( midx.isValid() ) { _ctl_view->setCurrentIndex ( midx ); } } emit sig_arg_changed(); } } void CTL_Arg_View_Card::read_view_selection ( ) { // Update arg string if selected index is valid if ( cards_model() != 0 ) { QModelIndex midx ( _ctl_view->currentIndex() ); const ::QSnd::Card_Info * cinfo ( cards_model()->card_info_by_model_index ( midx ) ); if ( cinfo != 0 ) { QString str; str.setNum ( cinfo->card_index() ); set_arg_string ( str ); } } } void CTL_Arg_View_Card::cards_model_changed ( ) { if ( _ctl_view->model() != 0 ) { disconnect ( _ctl_view, 0, this, 0 ); } _ctl_view->setModel ( cards_model() ); if ( cards_model() != 0 ) { connect ( _ctl_view->selectionModel(), SIGNAL ( currentChanged ( const QModelIndex &, const QModelIndex & ) ), this, SLOT ( read_view_selection() ) ); connect ( cards_model(), SIGNAL ( layoutChanged() ), this, SLOT ( read_view_selection() ) ); connect ( cards_model(), SIGNAL ( rowsRemoved ( const QModelIndex &, int, int ) ), this, SLOT ( read_view_selection() ) ); connect ( cards_model(), SIGNAL ( rowsInserted ( const QModelIndex &, int, int ) ), this, SLOT ( read_view_selection() ) ); connect ( cards_model(), SIGNAL ( rowsMoved ( const QModelIndex &, int, int, const QModelIndex &, int ) ), this, SLOT ( read_view_selection() ) ); } } } // End of namespace qastools-v0.22.0/shared/src/mwdg/ctl_arg_view_card.hpp000066400000000000000000000014521354534512100227750ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_mwdg_ctl_arg_view_card_hpp__ #define __INC_mwdg_ctl_arg_view_card_hpp__ #include "mwdg/ctl_arg_view.hpp" #include // Forward declaration namespace MWdg { class Controls_View; } namespace MWdg { /// @brief CTL_Arg_View_Card /// class CTL_Arg_View_Card : public ::MWdg::CTL_Arg_View { Q_OBJECT // Public methods public: CTL_Arg_View_Card ( QWidget * parent_n = 0 ); void set_arg_string ( const QString & str_n ); // Protected methods protected: void cards_model_changed ( ); // Protected methods protected slots: void read_view_selection ( ); // Private attributes private: ::MWdg::Controls_View * _ctl_view; }; } // End of namespace #endif qastools-v0.22.0/shared/src/mwdg/ctl_arg_view_integer.cpp000066400000000000000000000017221354534512100235140ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "ctl_arg_view_integer.hpp" #include #include namespace MWdg { CTL_Arg_View_Integer::CTL_Arg_View_Integer ( QWidget * parent_n ) : ::MWdg::CTL_Arg_View ( parent_n ) { _ledit = new QLineEdit; _ledit_signal_block = false; QIntValidator * vali ( new QIntValidator ( _ledit ) ); _ledit->setValidator ( vali ); connect ( _ledit, SIGNAL ( editingFinished() ), this, SIGNAL ( sig_arg_changed() ) ); lay_content()->addWidget ( _ledit ); } void CTL_Arg_View_Integer::set_arg_string ( const QString & str_n ) { if ( set_arg_string_private ( str_n ) ) { { _ledit_signal_block = true; _ledit->setText ( str_n ); _ledit_signal_block = false; } emit sig_arg_changed(); } } void CTL_Arg_View_Integer::input_string_changed ( ) { if ( !_ledit_signal_block ) { set_arg_string ( _ledit->text() ); } } } // End of namespace qastools-v0.22.0/shared/src/mwdg/ctl_arg_view_integer.hpp000066400000000000000000000012751354534512100235240ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_mwdg_ctl_arg_view_integer_hpp__ #define __INC_mwdg_ctl_arg_view_integer_hpp__ #include "mwdg/ctl_arg_view.hpp" #include namespace MWdg { /// @brief CTL_Arg_View_Integer /// class CTL_Arg_View_Integer : public ::MWdg::CTL_Arg_View { Q_OBJECT // Public methods public: CTL_Arg_View_Integer ( QWidget * parent_n = 0 ); void set_arg_string ( const QString & str_n ); // Protected slots protected slots: void input_string_changed ( ); // Private attributes private: QLineEdit * _ledit; bool _ledit_signal_block; }; } // End of namespace #endif qastools-v0.22.0/shared/src/mwdg/ctl_arg_view_string.cpp000066400000000000000000000015351354534512100233670ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "ctl_arg_view_string.hpp" #include namespace MWdg { CTL_Arg_View_String::CTL_Arg_View_String ( QWidget * parent_n ) : ::MWdg::CTL_Arg_View ( parent_n ) { _ledit = new QLineEdit; _ledit_signal_block = false; connect ( _ledit, SIGNAL ( editingFinished() ), this, SLOT ( input_string_changed() ) ); lay_content()->addWidget ( _ledit ); } void CTL_Arg_View_String::set_arg_string ( const QString & str_n ) { if ( set_arg_string_private ( str_n ) ) { { _ledit_signal_block = true; _ledit->setText ( str_n ); _ledit_signal_block = false; } emit sig_arg_changed(); } } void CTL_Arg_View_String::input_string_changed ( ) { if ( !_ledit_signal_block ) { set_arg_string ( _ledit->text() ); } } } // End of namespace qastools-v0.22.0/shared/src/mwdg/ctl_arg_view_string.hpp000066400000000000000000000012701354534512100233700ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_mwdg_ctl_arg_view_string_hpp__ #define __INC_mwdg_ctl_arg_view_string_hpp__ #include "mwdg/ctl_arg_view.hpp" #include namespace MWdg { /// @brief CTL_Arg_View_String /// class CTL_Arg_View_String : public ::MWdg::CTL_Arg_View { Q_OBJECT // Public methods public: CTL_Arg_View_String ( QWidget * parent_n = 0 ); void set_arg_string ( const QString & str_n ); // Protected slots protected slots: void input_string_changed ( ); // Private attributes private: QLineEdit * _ledit; bool _ledit_signal_block; }; } // End of namespace #endif qastools-v0.22.0/shared/src/mwdg/event_types.cpp000066400000000000000000000012541354534512100216770ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "event_types.hpp" namespace MWdg { ::QEvent::Type evt_separation_request; ::QEvent::Type evt_separation; ::QEvent::Type evt_values_changed; ::QEvent::Type evt_refresh_data; void init_event_types ( ) { evt_separation_request = static_cast < QEvent::Type > ( QEvent::registerEventType() ); evt_separation = static_cast < QEvent::Type > ( QEvent::registerEventType() ); evt_values_changed = static_cast < QEvent::Type > ( QEvent::registerEventType() ); evt_refresh_data = static_cast < QEvent::Type > ( QEvent::registerEventType() ); } } // End of namespace qastools-v0.22.0/shared/src/mwdg/event_types.hpp000066400000000000000000000006671354534512100217130ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_mwdg_event_types_hpp__ #define __INC_mwdg_event_types_hpp__ #include namespace MWdg { extern ::QEvent::Type evt_separation_request; extern ::QEvent::Type evt_separation; extern ::QEvent::Type evt_values_changed; extern ::QEvent::Type evt_refresh_data; void init_event_types ( ); } // End of namespace #endif qastools-v0.22.0/shared/src/mwdg/inputs_setup.cpp000066400000000000000000000030561354534512100220760ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "inputs_setup.hpp" #include namespace MWdg { Inputs_Setup::Inputs_Setup ( ) { wheel_degrees = 720; } void Inputs_Setup::update_translation ( ) { // These key sequence should be all different! //: "s" is an abbreviation for "split" or "separate". //: Something like "j" for "joined" or "c" for "channel" may be appropriate, too. ks_toggle_joined = QCoreApplication::translate ( "MWdg::Inputs_Setup", "s" ); //: "l" is an abbreviation for "level" ks_level_channels = QCoreApplication::translate ( "MWdg::Inputs_Setup", "l" ); //: "m" is an abbreviation for "mute" ks_mute_volumes = QCoreApplication::translate ( "MWdg::Inputs_Setup", "m" ); //: "p" is an abbreviation for "playback" ks_toggle_vis_stream[0] = QCoreApplication::translate ( "MWdg::Inputs_Setup", "p" ); //: "c" is an abbreviation for "capture" or "record" ks_toggle_vis_stream[1] = QCoreApplication::translate ( "MWdg::Inputs_Setup", "c" ); // Strings //: Used in the context menu (slider/switch right click menu) ts_split_channels = QCoreApplication::translate ( "MWdg::Inputs_Setup", "Split &channels" ); //: Used in the context menu (slider/switch right click menu) ts_join_channels = QCoreApplication::translate ( "MWdg::Inputs_Setup", "Join &channels" ); //: Used in the context menu (slider/switch right click menu) ts_level_channels = QCoreApplication::translate ( "MWdg::Inputs_Setup", "&Level channels" ); } } // End of namespace qastools-v0.22.0/shared/src/mwdg/inputs_setup.hpp000066400000000000000000000012221354534512100220740ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_mwdg_inputs_setup_hpp__ #define __INC_mwdg_inputs_setup_hpp__ #include #include namespace MWdg { class Inputs_Setup { // Public methods public: Inputs_Setup ( ); void update_translation ( ); // Public attributes public: unsigned int wheel_degrees; QKeySequence ks_toggle_joined; QKeySequence ks_level_channels; QKeySequence ks_mute_volumes; QKeySequence ks_toggle_vis_stream[2]; QString ts_split_channels; QString ts_join_channels; QString ts_level_channels; }; } // End of namespace #endif qastools-v0.22.0/shared/src/mwdg/mixer_device_setup.cpp000066400000000000000000000003371354534512100232160ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "mixer_device_setup.hpp" namespace MWdg { Mixer_Device_Setup::Mixer_Device_Setup ( ) { } } // End of namespace qastools-v0.22.0/shared/src/mwdg/mixer_device_setup.hpp000066400000000000000000000006561354534512100232270ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_mwdg_mixer_device_setup_hpp__ #define __INC_mwdg_mixer_device_setup_hpp__ #include namespace MWdg { /// @brief Mixer_Device_Setup /// class Mixer_Device_Setup { // Public methods public: Mixer_Device_Setup ( ); // Public attributes public: QString ctl_addr; }; } // End of namespace #endif qastools-v0.22.0/shared/src/mwdg/mixer_style.cpp000066400000000000000000000025651354534512100217040ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "mixer_style.hpp" namespace MWdg { QPalette Mixer_Style::style_palette ( ::MWdg::Mixer_Style::Style_Type style_n ) { QPalette pal; const QPalette::ColorGroup grp_act ( QPalette::Active ); const QPalette::ColorGroup grp_iact ( QPalette::Inactive ); QColor col; if ( style_n == ::MWdg::Mixer_Style::PLAYBACK ) { // Playback palette col = QColor ( 15, 15, 242 ); pal.setColor ( grp_act, QPalette::Window, col ); pal.setColor ( grp_iact, QPalette::Window, col ); col = QColor ( 0, 0, 60 ); pal.setColor ( grp_act, QPalette::WindowText, col ); pal.setColor ( grp_iact, QPalette::WindowText, col ); col = QColor ( 255, 255, 180 ); pal.setColor ( grp_act, QPalette::Light, col ); pal.setColor ( grp_iact, QPalette::Light, col ); } else if ( style_n == ::MWdg::Mixer_Style::CAPTURE ) { // Capture palette col = QColor ( 225, 15, 15 ); pal.setColor ( grp_act, QPalette::Window, col ); pal.setColor ( grp_iact, QPalette::Window, col ); col = QColor ( 80, 0, 0 ); pal.setColor ( grp_act, QPalette::WindowText, col ); pal.setColor ( grp_iact, QPalette::WindowText, col ); col = QColor ( 255, 255, 180 ); pal.setColor ( grp_act, QPalette::Light, col ); pal.setColor ( grp_iact, QPalette::Light, col ); } return pal; } } // End of namespace qastools-v0.22.0/shared/src/mwdg/mixer_style.hpp000066400000000000000000000010311354534512100216740ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_mwdg_mixer_style_hpp__ #define __INC_mwdg_mixer_style_hpp__ #include "wdg/ds_widget_style_db.hpp" namespace MWdg { class Mixer_Style { // Public typedefs public: enum Style_Type { CUSTOM = ::Wdg::DS_Widget_Style_Db::ST_USER, PLAYBACK = CUSTOM, CAPTURE = CUSTOM + 1 }; // Public methods public: QPalette style_palette ( ::MWdg::Mixer_Style::Style_Type style_n ); }; } // End of namespace #endif qastools-v0.22.0/shared/src/mwdg/slider_status_widget.cpp000066400000000000000000000206311354534512100235620ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "slider_status_widget.hpp" #include "wdg/sliders_pad.hpp" #include #include #include #include #include #include #include #include #include namespace MWdg { Slider_Status_Widget::Slider_Status_Widget ( QWidget * parent_n ) : QWidget ( parent_n, Qt::Tool ), _sliders_pad ( 0 ) { setWindowTitle ( tr ( "Slider value" ) ); QFont fnt_title ( _volume_title.font() ); fnt_title.setWeight ( QFont::Bold ); //const Qt::Alignment align_lc ( Qt::AlignLeft | Qt::AlignVCenter ); const Qt::Alignment align_rc ( Qt::AlignRight | Qt::AlignVCenter ); const Qt::Alignment align_cc ( Qt::AlignHCenter | Qt::AlignVCenter ); _lbl_value.setText ( tr ( "Value" ) ); _lbl_value.setFont ( fnt_title ); _lbl_max.setText ( tr ( "Max." ) ); _lbl_max.setToolTip ( tr ( "Maximum" ) ); _lbl_max.setFont ( fnt_title ); _lbl_min.setText ( tr ( "Min." ) ); _lbl_min.setFont ( fnt_title ); _lbl_min.setToolTip ( tr ( "Minimum" ) ); // Volume // Volume label _volume_title.setFont ( fnt_title ); _volume_title.setText ( tr ( "Volume" ) ); _volume_value.setSingleStep ( 1 ); _volume_value.setKeyboardTracking ( false ); // Volume value _volume_value.setToolTip ( tr ( "Current volume" ) ); connect ( &_volume_value, SIGNAL ( valueChanged ( int ) ), this, SLOT ( volume_value_changed ( int ) ) ); // Volume range _volume_max.setAlignment ( align_cc ); _volume_max.setToolTip ( tr ( "Volume maximum" ) ); _volume_max.setTextInteractionFlags ( Qt::TextSelectableByMouse ); _volume_max.set_min_text ( volume_string ( -65000 ) ); _volume_min.setAlignment ( align_cc ); _volume_min.setToolTip ( tr ( "Volume minimum" ) ); _volume_min.setTextInteractionFlags ( Qt::TextSelectableByMouse ); _volume_min.set_min_text ( volume_string ( -65000 ) ); // Decibel // Decibel label _db_title.setFont ( fnt_title ); _db_title.setText ( tr ( "Decibel" ) ); // Decibel value _db_value.setButtonSymbols ( QAbstractSpinBox::NoButtons ); _db_value.setSingleStep ( 0 ); _db_value.setKeyboardTracking ( false ); _db_value.setToolTip ( tr ( "Current Decibel value" ) ); connect ( &_db_value, SIGNAL ( valueChanged ( double ) ), this, SLOT ( db_value_changed ( double ) ) ); // Decibel range _db_max.setAlignment ( align_rc ); _db_max.set_min_text ( db_string ( -99.99 ) ); _db_max.setToolTip ( tr ( "Decibel maximum" ) ); _db_max.setTextInteractionFlags ( Qt::TextSelectableByMouse ); _db_min.setAlignment ( align_rc ); _db_min.set_min_text ( db_string ( -99.99 ) ); _db_min.setToolTip ( tr ( "Decibel minimum" ) ); _db_min.setTextInteractionFlags ( Qt::TextSelectableByMouse ); // Element name _elem_name.setFont ( fnt_title ); _elem_name.setToolTip ( tr ( "Element name" ) ); // Layout { QVBoxLayout * lay_vbox ( new QVBoxLayout ); lay_vbox->addWidget ( &_elem_name ); { QGridLayout * lay_grid ( new QGridLayout ); lay_grid->setContentsMargins ( 0, 0, 0, 0 ); const int fnt_w ( fontMetrics().averageCharWidth() ); const int fnt_h ( fontMetrics().height() ); QSpacerItem * spacer[8]; for ( unsigned int ii=0; ii < 8; ++ii ) { spacer[ii] = new QSpacerItem ( fnt_w, fnt_h ); } unsigned int sp_idx ( 0 ); unsigned int row ( 0 ); unsigned int col ( 0 ); ++col; lay_grid->addItem ( spacer[sp_idx++], row, col++ ); lay_grid->addWidget ( &_volume_title, row, col++ ); lay_grid->addItem ( spacer[sp_idx++], row, col++ ); lay_grid->addWidget ( &_db_title, row, col++ ); ++row; col = 0; lay_grid->addWidget ( &_lbl_value, row, col++ ); lay_grid->addItem ( spacer[sp_idx++], row, col++ ); lay_grid->addWidget ( &_volume_value, row, col++ ); lay_grid->addItem ( spacer[sp_idx++], row, col++ ); lay_grid->addWidget ( &_db_value, row, col++ ); ++row; col = 0; lay_grid->addWidget ( &_lbl_max, row, col++ ); lay_grid->addItem ( spacer[sp_idx++], row, col++ ); lay_grid->addWidget ( &_volume_max, row, col++ ); lay_grid->addItem ( spacer[sp_idx++], row, col++ ); lay_grid->addWidget ( &_db_max, row, col++ ); ++row; col = 0; lay_grid->addWidget ( &_lbl_min, row, col++ ); lay_grid->addItem ( spacer[sp_idx++], row, col++ ); lay_grid->addWidget ( &_volume_min, row, col++ ); lay_grid->addItem ( spacer[sp_idx++], row, col++ ); lay_grid->addWidget ( &_db_min, row, col++ ); QBoxLayout * lay_hbox ( new QHBoxLayout() ); lay_hbox->setContentsMargins ( 0, 0, 0, 0 ); lay_hbox->addLayout ( lay_grid ); lay_hbox->addStretch ( 1 ); lay_vbox->addLayout ( lay_hbox ); } lay_vbox->addStretch ( 1 ); setLayout ( lay_vbox ); } } Slider_Status_Widget::~Slider_Status_Widget ( ) { } void Slider_Status_Widget::set_sliders_pad ( ::Wdg::Sliders_Pad * pad_n ) { if ( sliders_pad() != 0 ) { disconnect ( sliders_pad(), 0, this, 0 ); } _sliders_pad = pad_n; if ( sliders_pad() != 0 ) { connect ( sliders_pad(), SIGNAL ( sig_focus_changed() ), this, SLOT ( slider_focus_changed() ) ); } } void Slider_Status_Widget::slider_focus_changed ( ) { //::std::cout << "Slider_Status_Widget::slider_focus_changed" << "\n"; if ( sliders_pad() != 0 ) { if ( sliders_pad()->focus_info().has_focus ) { this->select_slider ( sliders_pad()->focus_info().group_idx, sliders_pad()->focus_info().column_idx ); } } } void Slider_Status_Widget::volume_value_changed ( int value_n ) { this->elem_set_volume ( value_n ); } void Slider_Status_Widget::db_value_changed ( double value_n ) { const long dB_long ( value_n * 100.0 ); this->elem_set_nearest_dB ( dB_long ); update_values(); } void Slider_Status_Widget::mixer_values_changed ( ) { update_values(); } void Slider_Status_Widget::update_values ( ) { QString txt ( "%1" ); { const long val ( this->elem_volume_value() ); _volume_value.blockSignals ( true ); _volume_value.setValue ( val ); _volume_value.blockSignals ( false ); } if ( this->elem_has_dB() ) { const double val ( this->elem_dB_value() / 100.0 ); _db_value.blockSignals ( true ); _db_value.setValue ( val ); _db_value.blockSignals ( false ); } } void Slider_Status_Widget::setup_values ( ) { QString txt_special; QString txt_max; QString txt_min; long vol_min; long vol_max; bool has_vol ( this->elem_has_volume() ); bool has_db ( this->elem_has_dB() ); _elem_name.setText ( this->elem_name() ); // Volume _volume_title.setEnabled ( has_vol ); _volume_value.setEnabled ( has_vol ); _volume_max.setEnabled ( has_vol ); _volume_min.setEnabled ( has_vol ); if ( has_vol ) { vol_min = this->elem_volume_min(); vol_max = this->elem_volume_max(); txt_special = QString(); txt_max = volume_string ( vol_max ); txt_min = volume_string ( vol_min ); } else { vol_min = 0; vol_max = 0; txt_special = " "; txt_max = ""; txt_min = ""; } _volume_value.blockSignals ( true ); _volume_value.setSpecialValueText ( txt_special ); _volume_value.setRange ( vol_min, vol_max ); _volume_value.setValue ( vol_min ); // To show the special text on demand _volume_value.blockSignals ( false ); _volume_max.setText ( txt_max ); _volume_min.setText ( txt_min ); // Decibel _db_title.setEnabled ( has_db ); _db_value.setEnabled ( has_db ); _db_max.setEnabled ( has_db ); _db_min.setEnabled ( has_db ); if ( has_db ) { vol_min = this->elem_dB_min(); vol_max = this->elem_dB_max(); txt_special = QString(); txt_max = db_string ( vol_max / 100.0 ); txt_min = db_string ( vol_min / 100.0 ); } else { vol_min = -9900; vol_max = 0; txt_special = " "; txt_max = ""; txt_min = ""; } _db_value.blockSignals ( true ); _db_value.setSpecialValueText ( txt_special ); _db_value.setRange ( vol_min / 100.0, vol_max / 100.0 ); _db_value.setValue ( vol_min / 100.0 ); // To show the special text on demand _db_value.blockSignals ( false ); _db_max.setText ( txt_max ); _db_min.setText ( txt_min ); updateGeometry(); } void Slider_Status_Widget::contextMenuEvent ( QContextMenuEvent * event_n ) { QMenu cmenu ( this ); QAction * act_close ( cmenu.addAction ( tr ( "Close slider value display" ) ) ); if ( QIcon::hasThemeIcon ( "window-close" ) ) { act_close->setIcon ( QIcon::fromTheme ( "window-close" ) ); } connect ( act_close, SIGNAL ( triggered ( bool ) ), this, SLOT ( close() ) ); cmenu.exec ( event_n->globalPos() ); } } // End of namespace qastools-v0.22.0/shared/src/mwdg/slider_status_widget.hpp000066400000000000000000000052761354534512100235770ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_slider_status_widget_hpp__ #define __INC_slider_status_widget_hpp__ #include "wdg/label_elide.hpp" #include "wdg/label_width.hpp" #include #include #include #include #include // Forward declaration namespace Wdg { class Sliders_Pad; } namespace MWdg { /// @brief Slider_Status_Widget /// class Slider_Status_Widget : public QWidget { Q_OBJECT // Public methods public: Slider_Status_Widget ( QWidget * parent_n = 0 ); ~Slider_Status_Widget ( ); // Sliders pad ::Wdg::Sliders_Pad * sliders_pad ( ) const; void set_sliders_pad ( ::Wdg::Sliders_Pad * pad_n ); // Value string generators QString volume_string ( long volume_n ) const; QString db_string ( double db_val_n ) const; // Element info virtual QString elem_name ( ) const = 0; virtual bool elem_has_volume ( ) const = 0; virtual bool elem_has_dB ( ) const = 0; virtual long elem_volume_value ( ) const = 0; virtual void elem_set_volume ( long value_n ) const = 0; virtual long elem_volume_min ( ) const = 0; virtual long elem_volume_max ( ) const = 0; virtual long elem_dB_value ( ) const = 0; virtual void elem_set_nearest_dB ( long dB_value_n ) const = 0; virtual long elem_dB_min ( ) const = 0; virtual long elem_dB_max ( ) const = 0; // Slider selection virtual void select_slider ( unsigned int grp_idx_n, unsigned int col_idx_n ) = 0; // Public slots public slots: void mixer_values_changed ( ); void slider_focus_changed ( ); // Protected slots protected slots: void update_values ( ); void volume_value_changed ( int value_n ); void db_value_changed ( double value_n ); // Protected methods protected: void setup_values ( ); void contextMenuEvent ( QContextMenuEvent * event_n ); // Private attributes private: ::Wdg::Sliders_Pad * _sliders_pad; // Widgets ::Wdg::Label_Elide _elem_name; QLabel _lbl_value; QLabel _lbl_max; QLabel _lbl_min; QLabel _volume_title; QSpinBox _volume_value; ::Wdg::Label_Width _volume_max; ::Wdg::Label_Width _volume_min; QLabel _db_title; QDoubleSpinBox _db_value; ::Wdg::Label_Width _db_max; ::Wdg::Label_Width _db_min; QLocale _loc; }; inline Wdg::Sliders_Pad * Slider_Status_Widget::sliders_pad ( ) const { return _sliders_pad; } inline QString Slider_Status_Widget::volume_string ( long volume_n ) const { return _loc.toString ( (int)volume_n ); } inline QString Slider_Status_Widget::db_string ( double db_val_n ) const { return _loc.toString ( db_val_n, 'f', 2 ); } } // End of namespace #endif qastools-v0.22.0/shared/src/qastools_config.hpp.cmake000066400000000000000000000022021354534512100226440ustar00rootroot00000000000000 #ifndef __INC_qas_config_hpp__ #define __INC_qas_config_hpp__ #define PACKAGE_NAME "${PACKAGE_NAME}" #define PACKAGE_TITLE "${PACKAGE_TITLE}" #define PACKAGE_VERSION "${PACKAGE_VERSION}" #define PROGRAM_NAME "${PROGRAM_NAME}" #define PROGRAM_TITLE "${PROGRAM_TITLE}" #define VERSION "${VERSION}" #define L10N_PREFIX "${L10N_PREFIX}" #define SINGLE_APPLICATION_KEY "${PROGRAM_NAME}-${VERSION}" #define INSTALL_DIR_DATA "${CMAKE_INSTALL_PREFIX}/${INSTALL_DIR_DATA}" #define INSTALL_DIR_L10N "${CMAKE_INSTALL_PREFIX}/${INSTALL_DIR_L10N}" #define INSTALL_DIR_APP_ICONS "${CMAKE_INSTALL_PREFIX}/${INSTALL_DIR_APP_ICONS}" #define INSTALL_DIR_WIDGETS_GRAPHICS "${CMAKE_INSTALL_PREFIX}/${INSTALL_DIR_WIDGETS_GRAPHICS}" #define INSTALL_DIR_ICONS_PNG_16 "${CMAKE_INSTALL_PREFIX}/${INSTALL_DIR_ICONS_PNG_16}" #define INSTALL_DIR_ICONS_PNG_32 "${CMAKE_INSTALL_PREFIX}/${INSTALL_DIR_ICONS_PNG_32}" #define INSTALL_DIR_ICONS_PNG_48 "${CMAKE_INSTALL_PREFIX}/${INSTALL_DIR_ICONS_PNG_48}" #define INSTALL_DIR_ICONS_PNG_64 "${CMAKE_INSTALL_PREFIX}/${INSTALL_DIR_ICONS_PNG_64}" #define INSTALL_DIR_ICONS_SVG "${CMAKE_INSTALL_PREFIX}/${INSTALL_DIR_ICONS_SVG}" #endif qastools-v0.22.0/shared/src/qsnd/000077500000000000000000000000001354534512100166335ustar00rootroot00000000000000qastools-v0.22.0/shared/src/qsnd/alsa.cpp000066400000000000000000000010331354534512100202540ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "alsa.hpp" #include #include #include namespace QSnd { void print_alsa_error ( const std::string & prefix, int err_n ) { ::std::stringstream msg; msg << "[EE] "; msg << prefix << ": "; msg << snd_strerror ( err_n ) << ::std::endl; ::std::cerr << msg.str(); } QString snd_error_qstring ( int err_n ) { return QString::fromLocal8Bit ( snd_strerror ( err_n ) ); } } // End of namespace qastools-v0.22.0/shared/src/qsnd/alsa.hpp000066400000000000000000000006021354534512100202620ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_qsnd_alsa_hpp__ #define __INC_qsnd_alsa_hpp__ #include #include #include namespace QSnd { void print_alsa_error ( const ::std::string & prefix, int err ); QString snd_error_qstring ( int err ); } // End of namespace #endif qastools-v0.22.0/shared/src/qsnd/alsa_config_watcher.cpp000066400000000000000000000035731354534512100233310ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "alsa_config_watcher.hpp" #include namespace QSnd { ALSA_Config_Watcher::ALSA_Config_Watcher ( ::QObject * parent_n ) : QObject ( parent_n ) { _cfg_system_dir = "/etc"; _cfg_system_file = _cfg_system_dir + "/asound.conf"; _cfg_home_dir = QDir::homePath(); _cfg_home_file = _cfg_home_dir + "/.asoundrc"; // File system watcher looks for changes in ALSA cfg files _fwatch.addPath ( _cfg_system_dir ); if ( QFile::exists ( _cfg_system_file ) ) { _fwatch.addPath ( _cfg_system_file ); } _fwatch.addPath ( _cfg_home_dir ); if ( QFile::exists ( _cfg_home_file ) ) { _fwatch.addPath ( _cfg_home_file ); } connect ( &_fwatch, SIGNAL ( fileChanged ( const QString & ) ), this, SLOT ( change_in_file ( const QString & ) ) ); connect ( &_fwatch, SIGNAL ( directoryChanged ( const QString & ) ), this, SLOT ( change_in_dir ( const QString & ) ) ); } void ALSA_Config_Watcher::change_in_file ( const QString & fl_n ) { //::std::cout << "Change in file " << fl_n.toLocal8Bit().data() << "\n"; if ( ( fl_n == _cfg_system_file ) || ( fl_n == _cfg_home_file ) ) { emit sig_change(); } } void ALSA_Config_Watcher::change_in_dir ( const QString & fl_n ) { if ( fl_n == _cfg_system_dir ) { if ( !_fwatch.files().contains ( _cfg_system_file ) ) { if ( QFile::exists ( _cfg_system_file ) ) { //::std::cout << "Change in dir " << _cfg_system_file.toLocal8Bit().data() << "\n"; _fwatch.addPath ( _cfg_system_file ); emit sig_change(); } } } if ( fl_n == _cfg_home_dir ) { if ( !_fwatch.files().contains ( _cfg_home_file ) ) { if ( QFile::exists ( _cfg_home_file ) ) { //::std::cout << "Change in dir " << _cfg_home_file.toLocal8Bit().data() << "\n"; _fwatch.addPath ( _cfg_home_file ); emit sig_change(); } } } } } // End of namespace qastools-v0.22.0/shared/src/qsnd/alsa_config_watcher.hpp000066400000000000000000000014751354534512100233350ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_qsnd_alsa_config_watcher_hpp__ #define __INC_qsnd_alsa_config_watcher_hpp__ #include #include #include namespace QSnd { /// @brief Main_Window /// class ALSA_Config_Watcher : public QObject { Q_OBJECT // Public methods public: ALSA_Config_Watcher ( ::QObject * parent_n = 0 ); // Signals signals: void sig_change ( ); // Private slots private slots: void change_in_file ( const QString & fl_n ); void change_in_dir ( const QString & fl_n ); // Private attributes private: QFileSystemWatcher _fwatch; QString _cfg_system_dir; QString _cfg_system_file; QString _cfg_home_dir; QString _cfg_home_file; }; } // End of namespace #endif qastools-v0.22.0/shared/src/qsnd/alsa_i18n.hpp000066400000000000000000000110551354534512100211250ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_alsa_i18n_hpp__ #define __INC_alsa_i18n_hpp__ /* This file is not meant to be included but serves as a library for the Qt lupdate utility to translate ALSA strings. */ static const char *alsa_i18n_strings[] = { QT_TRANSLATE_NOOP ( "ALSA::Elem_Name", "Auto Gain Control" ), QT_TRANSLATE_NOOP ( "ALSA::Elem_Name", "Auto-Mute Mode" ), QT_TRANSLATE_NOOP ( "ALSA::Elem_Name", "Bass" ), QT_TRANSLATE_NOOP ( "ALSA::Elem_Name", "Beep" ), QT_TRANSLATE_NOOP ( "ALSA::Elem_Name", "Capture" ), QT_TRANSLATE_NOOP ( "ALSA::Elem_Name", "Center" ), QT_TRANSLATE_NOOP ( "ALSA::Elem_Name", "Channel Mode" ), QT_TRANSLATE_NOOP ( "ALSA::Elem_Name", "External Amplifier" ), QT_TRANSLATE_NOOP ( "ALSA::Elem_Name", "External Mic" ), QT_TRANSLATE_NOOP ( "ALSA::Elem_Name", "Ext Mic" ), QT_TRANSLATE_NOOP ( "ALSA::Elem_Name", "Front" ), QT_TRANSLATE_NOOP ( "ALSA::Elem_Name", "Front Mic" ), QT_TRANSLATE_NOOP ( "ALSA::Elem_Name", "Front Mic Boost" ), QT_TRANSLATE_NOOP ( "ALSA::Elem_Name", "Headphone" ), QT_TRANSLATE_NOOP ( "ALSA::Elem_Name", "Headphone LFE" ), QT_TRANSLATE_NOOP ( "ALSA::Elem_Name", "Headphone Center" ), QT_TRANSLATE_NOOP ( "ALSA::Elem_Name", "Input Source" ), QT_TRANSLATE_NOOP ( "ALSA::Elem_Name", "Internal Mic" ), QT_TRANSLATE_NOOP ( "ALSA::Elem_Name", "Int Mic" ), QT_TRANSLATE_NOOP ( "ALSA::Elem_Name", "Master" ), QT_TRANSLATE_NOOP ( "ALSA::Elem_Name", "Mic" ), QT_TRANSLATE_NOOP ( "ALSA::Elem_Name", "Mic Boost" ), QT_TRANSLATE_NOOP ( "ALSA::Elem_Name", "Mic Boost (+20dB)" ), QT_TRANSLATE_NOOP ( "ALSA::Elem_Name", "Mic Select" ), QT_TRANSLATE_NOOP ( "ALSA::Elem_Name", "PC Speaker" ), QT_TRANSLATE_NOOP ( "ALSA::Elem_Name", "Phone" ), QT_TRANSLATE_NOOP ( "ALSA::Elem_Name", "Side" ), QT_TRANSLATE_NOOP ( "ALSA::Elem_Name", "Speaker" ), QT_TRANSLATE_NOOP ( "ALSA::Elem_Name", "Surround" ), QT_TRANSLATE_NOOP ( "ALSA::Elem_Name", "Treble" ), QT_TRANSLATE_NOOP ( "ALSA::Elem_Name", "Video" ), QT_TRANSLATE_NOOP ( "ALSA::Enum_Value", "Enabled" ), QT_TRANSLATE_NOOP ( "ALSA::Enum_Value", "Disabled" ), QT_TRANSLATE_NOOP ( "ALSA::Enum_Value", "1ch" ), QT_TRANSLATE_NOOP ( "ALSA::Enum_Value", "2ch" ), QT_TRANSLATE_NOOP ( "ALSA::Enum_Value", "3ch" ), QT_TRANSLATE_NOOP ( "ALSA::Enum_Value", "4ch" ), QT_TRANSLATE_NOOP ( "ALSA::Enum_Value", "5ch" ), QT_TRANSLATE_NOOP ( "ALSA::Enum_Value", "6ch" ), QT_TRANSLATE_NOOP ( "ALSA::Enum_Value", "7ch" ), QT_TRANSLATE_NOOP ( "ALSA::Enum_Value", "8ch" ), QT_TRANSLATE_NOOP ( "ALSA::Enum_Value", "Front Mic" ), QT_TRANSLATE_NOOP ( "ALSA::Enum_Value", "Internal Mic" ), QT_TRANSLATE_NOOP ( "ALSA::Enum_Value", "Mic" ), QT_TRANSLATE_NOOP ( "ALSA::Enum_Value", "Mic1" ), QT_TRANSLATE_NOOP ( "ALSA::Enum_Value", "Mic2" ), QT_TRANSLATE_NOOP ( "ALSA::Enum_Value", "Mic3" ), QT_TRANSLATE_NOOP ( "ALSA::Enum_Value", "Mic4" ), QT_TRANSLATE_NOOP ( "ALSA::Enum_Value", "Video" ), QT_TRANSLATE_NOOP ( "ALSA::Enum_Value", "Phone" ), QT_TRANSLATE_NOOP ( "ALSA::Channel_Name", "Front Left" ), QT_TRANSLATE_NOOP ( "ALSA::Channel_Name", "Front Right" ), QT_TRANSLATE_NOOP ( "ALSA::Channel_Name", "Rear Left" ), QT_TRANSLATE_NOOP ( "ALSA::Channel_Name", "Rear Right" ), QT_TRANSLATE_NOOP ( "ALSA::Channel_Name", "Front Center" ), QT_TRANSLATE_NOOP ( "ALSA::Channel_Name", "Woofer" ), QT_TRANSLATE_NOOP ( "ALSA::Channel_Name", "Side Left" ), QT_TRANSLATE_NOOP ( "ALSA::Channel_Name", "Side Right" ), QT_TRANSLATE_NOOP ( "ALSA::Channel_Name", "Rear Center" ), QT_TRANSLATE_NOOP ( "ALSA::CTL_Elem_IFace_Name", "CARD" ), QT_TRANSLATE_NOOP ( "ALSA::CTL_Elem_IFace_Name", "HWDEP" ), QT_TRANSLATE_NOOP ( "ALSA::CTL_Elem_IFace_Name", "MIXER" ), QT_TRANSLATE_NOOP ( "ALSA::CTL_Elem_IFace_Name", "PCM" ), QT_TRANSLATE_NOOP ( "ALSA::CTL_Elem_IFace_Name", "RAWMIDI" ), QT_TRANSLATE_NOOP ( "ALSA::CTL_Elem_IFace_Name", "TIMER" ), QT_TRANSLATE_NOOP ( "ALSA::CTL_Elem_IFace_Name", "SEQUENCER" ), QT_TRANSLATE_NOOP ( "ALSA::CTL_Elem_IFace_Name", "Unknown" ), QT_TRANSLATE_NOOP ( "ALSA::CTL_Elem_Type_Name", "NONE" ), QT_TRANSLATE_NOOP ( "ALSA::CTL_Elem_Type_Name", "BOOLEAN" ), QT_TRANSLATE_NOOP ( "ALSA::CTL_Elem_Type_Name", "INTEGER" ), QT_TRANSLATE_NOOP ( "ALSA::CTL_Elem_Type_Name", "ENUMERATED" ), QT_TRANSLATE_NOOP ( "ALSA::CTL_Elem_Type_Name", "BYTES" ), QT_TRANSLATE_NOOP ( "ALSA::CTL_Elem_Type_Name", "IEC958" ), QT_TRANSLATE_NOOP ( "ALSA::CTL_Elem_Type_Name", "INTEGER64" ), QT_TRANSLATE_NOOP ( "ALSA::CTL_Elem_Type_Name", "Unknown" ), QT_TRANSLATE_NOOP ( "ALSA::CTL_Arg_Name", "CARD" ), QT_TRANSLATE_NOOP ( "ALSA::CTL_Arg_Name", "SOCKET" ), QT_TRANSLATE_NOOP ( "ALSA::CTL_Arg_Name", "CTL" ), }; #endif qastools-v0.22.0/shared/src/qsnd/card_info.cpp000066400000000000000000000052241354534512100212660ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "card_info.hpp" #include namespace QSnd { Card_Info::Card_Info ( ) : _card_index ( -1 ) { } Card_Info::Card_Info ( const int hw_idx_n ) : _card_index ( -1 ) { acquire_info ( hw_idx_n ); } Card_Info::Card_Info ( const QString & dev_str_n ) : _card_index ( -1 ) { acquire_info ( dev_str_n ); } void Card_Info::clear ( ) { _card_index = -1; for ( int ii=0; ii < 6; ++ii ) { _strings[ii].clear(); } } bool Card_Info::is_clear ( ) const { return ( _card_index < 0 ); } int Card_Info::acquire_info ( const int hw_idx_n ) { QString dev_str ( "hw:%1" ); dev_str = dev_str.arg ( hw_idx_n ); return acquire_info ( dev_str ); } int Card_Info::acquire_info ( const QString & dev_str_n ) { // Open control handle int err; snd_hctl_t * snd_hctl; err = snd_hctl_open ( &snd_hctl, dev_str_n.toLocal8Bit().constData(), SND_CTL_NONBLOCK ); if ( err >= 0 ) { err = acquire_info ( snd_hctl ); snd_hctl_close ( snd_hctl ); } return err; } int Card_Info::acquire_info ( snd_hctl_t * snd_hctl_n ) { int err; snd_ctl_t * snd_card_ctl ( 0 ); snd_ctl_card_info_t * snd_card_info ( 0 ); snd_ctl_card_info_alloca ( &snd_card_info ); snd_card_ctl = snd_hctl_ctl ( snd_hctl_n ); // Get card information err = snd_ctl_card_info ( snd_card_ctl, snd_card_info ); if ( err >= 0 ) { _card_index = snd_ctl_card_info_get_card ( snd_card_info ); _strings[0] = snd_ctl_card_info_get_id ( snd_card_info ); _strings[1] = snd_ctl_card_info_get_driver ( snd_card_info ); _strings[2] = snd_ctl_card_info_get_name ( snd_card_info ); _strings[3] = snd_ctl_card_info_get_longname ( snd_card_info ); _strings[4] = snd_ctl_card_info_get_mixername ( snd_card_info ); _strings[5] = snd_ctl_card_info_get_components ( snd_card_info ); } else { clear(); } return err; } bool Card_Info::operator== ( const ::QSnd::Card_Info & cinfo_n ) const { bool res ( card_index() == cinfo_n.card_index() ); if ( res ) { const unsigned int num_strings ( sizeof ( _strings ) / sizeof ( QString ) ); for ( unsigned int ii=0; ii != num_strings; ++ii ) { if ( _strings[ii] != cinfo_n._strings[ii] ) { res = false; break; } } } return res; } bool Card_Info::operator!= ( const ::QSnd::Card_Info & cinfo_n ) const { bool res ( card_index() != cinfo_n.card_index() ); if ( !res ) { const unsigned int num_strings ( sizeof ( _strings ) / sizeof ( QString ) ); for ( unsigned int ii=0; ii != num_strings; ++ii ) { if ( _strings[ii] != cinfo_n._strings[ii] ) { res = true; break; } } } return res; } } // End of namespace qastools-v0.22.0/shared/src/qsnd/card_info.hpp000066400000000000000000000032661354534512100212770ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_qsnd_qsnd_card_info_hpp__ #define __INC_qsnd_qsnd_card_info_hpp__ #include #include "qsnd/alsa.hpp" namespace QSnd { /// @brief Card_Info /// class Card_Info { // Public methods public: Card_Info ( ); Card_Info ( const int hw_idx_n ); Card_Info ( const QString & dev_str_n ); void clear ( ); bool is_clear ( ) const; int acquire_info ( const int hw_idx_n ); int acquire_info ( const QString & dev_str_n ); int acquire_info ( snd_hctl_t * snd_hctl_n ); int card_index ( ) const; const QString & card_id ( ) const; const QString & card_driver ( ) const; const QString & card_name ( ) const; const QString & card_long_name ( ) const; const QString & card_mixer_name ( ) const; const QString & card_components ( ) const; bool operator== ( const ::QSnd::Card_Info & cinfo_n ) const; bool operator!= ( const ::QSnd::Card_Info & cinfo_n ) const; // Private attributes private: int _card_index; QString _strings[6]; }; inline int Card_Info::card_index ( ) const { return _card_index; } inline const QString & Card_Info::card_id ( ) const { return _strings[0]; } inline const QString & Card_Info::card_driver ( ) const { return _strings[1]; } inline const QString & Card_Info::card_name ( ) const { return _strings[2]; } inline const QString & Card_Info::card_long_name ( ) const { return _strings[3]; } inline const QString & Card_Info::card_mixer_name ( ) const { return _strings[4]; } inline const QString & Card_Info::card_components ( ) const { return _strings[5]; } } // End of namespace #endif qastools-v0.22.0/shared/src/qsnd/cards_model.cpp000066400000000000000000000101111354534512100216050ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "cards_model.hpp" #include "qsnd/alsa.hpp" #include "qsnd/udev_device_lookout.hpp" #include "qsnd/model_keys.hpp" #include namespace QSnd { Cards_Model::Cards_Model ( QObject * parent_n ) : QStandardItemModel ( parent_n ) { reload(); // Device lookout { ::QSnd::UDev_Device_Lookout * lookout ( new ::QSnd::UDev_Device_Lookout ( this ) ); connect ( lookout, SIGNAL ( sig_change() ), this, SLOT ( reload() ) ); } } Cards_Model::~Cards_Model ( ) { } const ::QSnd::Card_Info * Cards_Model::card_info_by_card_id ( unsigned int id_n ) { const ::QSnd::Card_Info * res ( 0 ); { const unsigned int num ( _card_infos.size() ); for ( unsigned int ii=0; ii != num; ++ii ) { const ::QSnd::Card_Info & cinfo ( _card_infos[ii] ); if ( (unsigned int)cinfo.card_index() == id_n ) { res = &cinfo; break; } } } return res; } const ::QSnd::Card_Info * Cards_Model::card_info_by_model_index ( const QModelIndex & idx_n ) const { const ::QSnd::Card_Info * res ( 0 ); if ( idx_n.isValid() && !idx_n.parent().isValid() ) { if ( ( idx_n.column() == 0 ) && ( idx_n.row() < _card_infos.size() ) ) { res = &_card_infos[idx_n.row()]; } } return res; } QModelIndex Cards_Model::model_index_by_card_id ( const QString & id_str_n ) const { QModelIndex res; bool found ( false ); bool is_int ( false ); int int_val ( id_str_n.toInt ( &is_int) ); for ( int ii=0; ii != _card_infos.size(); ++ii ) { const ::QSnd::Card_Info & cinfo ( _card_infos[ii] ); if ( is_int ) { if ( cinfo.card_index() == int_val ) { found = true; } } else { if ( cinfo.card_id() == id_str_n ) { found = true; } } if ( found ) { res = QModelIndex ( index ( ii, 0 ) ); break; } } return res; } void Cards_Model::reload ( ) { Card_Infos cards; load_cards ( cards ); unsigned int index_src ( 0 ); unsigned int index_dst ( 0 ); while ( ( index_src != (unsigned int)cards.size() ) || ( index_dst != (unsigned int)_card_infos.size() ) ) { bool dst_item_remove ( false ); bool src_item_insert ( false ); bool src_dst_matching ( false ); if ( index_src == (unsigned int)cards.size() ) { dst_item_remove = true; } else { if ( index_dst == (unsigned int)_card_infos.size() ) { src_item_insert = true; } else { const ::QSnd::Card_Info & cinfo_src ( cards[index_src] ); const ::QSnd::Card_Info & cinfo_dst ( _card_infos[index_dst] ); if ( cinfo_src.card_index() == cinfo_dst.card_index() ) { if ( cinfo_src == cinfo_dst ) { src_dst_matching = true; } else { dst_item_remove = true; src_item_insert = true; } } else { if ( cinfo_src.card_index() > cinfo_dst.card_index() ) { dst_item_remove = true; } else { src_item_insert = true; } } } } if ( src_dst_matching ) { ++index_src; ++index_dst; } else { if ( dst_item_remove ) { _card_infos.removeAt ( index_dst ); QList < QStandardItem * > lst ( takeRow ( index_dst ) ); for ( int ii=0; ii != lst.size(); ++ii ) { delete lst[ii]; } } if ( src_item_insert ) { const ::QSnd::Card_Info & cinfo ( cards[index_src] ); _card_infos.insert ( index_dst, cinfo ); { // Create standard item and append QStandardItem * sitem ( new QStandardItem ); sitem->setText ( cinfo.card_name() ); sitem->setEditable ( false ); sitem->setSelectable ( true ); sitem->setData ( QVariant ( cinfo.card_index() ), MKEY_CARD_INDEX ); sitem->setData ( QVariant ( cinfo.card_name() ), MKEY_CARD_NAME ); sitem->setData ( QVariant ( cinfo.card_mixer_name() ), MKEY_CARD_MIXER_NAME ); insertRow ( index_dst, sitem ); } ++index_src; ++index_dst; } } } } void Cards_Model::load_cards ( Card_Infos & card_infos_n ) { card_infos_n.clear(); int card_idx = -1; while ( true ) { if ( ::snd_card_next ( &card_idx ) != 0 ) { break; } if ( card_idx < 0 ) { break; } card_infos_n.append ( ::QSnd::Card_Info ( card_idx ) ); } } } // End of namespace qastools-v0.22.0/shared/src/qsnd/cards_model.hpp000066400000000000000000000025021354534512100216170ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_qsnd_cards_model_hpp__ #define __INC_qsnd_cards_model_hpp__ #include "qsnd/card_info.hpp" #include namespace QSnd { /// @brief Cards_Model /// class Cards_Model : public QStandardItemModel { Q_OBJECT; // Public types public: typedef QList < ::QSnd::Card_Info > Card_Infos; // Public methods public: Cards_Model ( QObject * parent_n = 0 ); ~Cards_Model ( ); unsigned int num_cards ( ) const; const ::QSnd::Card_Info & card_info ( unsigned int index_n ) const; const ::QSnd::Card_Info * card_info_by_card_id ( unsigned int id_n ); // Control definition access const ::QSnd::Card_Info * card_info_by_model_index ( const QModelIndex & idx_n ) const; QModelIndex model_index_by_card_id ( const QString & id_str_n ) const; // Public slots public slots: void reload ( ); // Protected methods protected: void load_cards ( Card_Infos & card_infos_n ); // Private attributes private: Card_Infos _card_infos; }; inline unsigned int Cards_Model::num_cards ( ) const { return _card_infos.size(); } inline const ::QSnd::Card_Info & Cards_Model::card_info ( unsigned int index_n ) const { return _card_infos[index_n]; } } // End of namespace #endif qastools-v0.22.0/shared/src/qsnd/controls_database.cpp000066400000000000000000000111341354534512100230260ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "controls_database.hpp" #include "qsnd/alsa.hpp" #include #include namespace QSnd { // Local functions bool setup_ctl_format ( ::QSnd::CTL_Format & ctl_format_n, snd_config_t * scfg_n ); void setup_ctl_format_args ( ::QSnd::CTL_Format & ctl_format_n, snd_config_t * scfg_n ); void setup_ctl_format_arg ( ::QSnd::CTL_Format_Argument & ctl_arg_n, snd_config_t * scfg_n ); // Controls_Database Controls_Database::Controls_Database ( ) { reload_silent(); } Controls_Database::~Controls_Database ( ) { clear_silent(); } const ::QSnd::CTL_Format * Controls_Database::find_control_format ( const QString & ctl_name_n ) const { const ::QSnd::CTL_Format * res ( 0 ); for ( int ii=0; ii != _ctl_formats.size(); ++ii ) { const ::QSnd::CTL_Format & ctl_format ( _ctl_formats[ii] ); if ( ctl_format.ctl_name() == ctl_name_n ) { res = &ctl_format; break; } } return res; } void Controls_Database::clear ( ) { emit sig_change_coming(); clear_silent(); emit sig_change_done(); } void Controls_Database::clear_silent ( ) { _ctl_formats.clear(); } void Controls_Database::reload ( ) { emit sig_change_coming(); reload_silent(); emit sig_change_done(); } void Controls_Database::reload_silent ( ) { clear_silent(); load_plugins(); } void Controls_Database::load_plugins ( ) { // Load ALSA configuration tree and read ctl entries { snd_config_t * snd_cfg = 0; // Read ALSA config from disk { snd_config_update_t * snd_cfg_update = 0; snd_config_update_r ( &snd_cfg, &snd_cfg_update, 0 ); snd_config_update_free ( snd_cfg_update ); } if ( snd_cfg != 0 ) { snd_config_t * snd_cfg_ctl = 0; snd_config_search ( snd_cfg, "ctl", &snd_cfg_ctl ); if ( snd_cfg_ctl != 0 ) { snd_config_iterator_t iter = snd_config_iterator_first ( snd_cfg_ctl ); snd_config_iterator_t iter_end = snd_config_iterator_end ( snd_cfg_ctl ); while ( iter != iter_end ) { snd_config_t * scfg = snd_config_iterator_entry ( iter ); { ::QSnd::CTL_Format ctl_format; if ( setup_ctl_format ( ctl_format, scfg ) ) { _ctl_formats.append ( ctl_format ); } } iter = snd_config_iterator_next ( iter ); } } snd_config_delete ( snd_cfg ); } } } bool setup_ctl_format ( ::QSnd::CTL_Format & ctl_format_n, snd_config_t * scfg_n ) { if ( scfg_n != 0 ) { const char * char_ptr ( 0 ); int err = snd_config_get_id ( scfg_n, &char_ptr ); if ( ( err == 0 ) && ( char_ptr != 0 ) ) { QString ctl_id ( char_ptr ); ctl_format_n.set_ctl_name ( ctl_id ); setup_ctl_format_args ( ctl_format_n, scfg_n ); } return true; } return false; } inline void setup_ctl_format_args ( ::QSnd::CTL_Format & ctl_format_n, snd_config_t * scfg_n ) { snd_config_t * scfg_args ( 0 ); snd_config_search ( scfg_n, "@args", &scfg_args ); if ( scfg_args != 0 ) { QStringList arg_names; { QString str_num; for ( unsigned int ii=0; ii < 9; ++ii ) { str_num.setNum ( ii ); snd_config_t * scfg_arg ( 0 ); snd_config_search ( scfg_args, str_num.toLatin1().constData(), &scfg_arg ); if ( scfg_arg != 0 ) { if ( snd_config_get_type ( scfg_arg ) == SND_CONFIG_TYPE_STRING ) { const char * char_ptr ( 0 ); int err = snd_config_get_string ( scfg_arg, &char_ptr ); if ( ( err == 0 ) && ( char_ptr != 0 ) ) { arg_names.append ( char_ptr ); } } } } } for ( int ii=0; ii < arg_names.size(); ++ii ) { ::QSnd::CTL_Format_Argument ctl_arg; ctl_arg.arg_name = arg_names[ii]; setup_ctl_format_arg ( ctl_arg, scfg_args ); ctl_format_n.append_arg ( ctl_arg ); } } } inline void setup_ctl_format_arg ( ::QSnd::CTL_Format_Argument & ctl_arg_n, snd_config_t * scfg_n ) { snd_config_t * scfg_arg_com ( 0 ); { int err = snd_config_search ( scfg_n, ctl_arg_n.arg_name.toUtf8().constData(), &scfg_arg_com ); if ( ( err != 0 ) || ( scfg_arg_com == 0 ) ) { return; } if ( snd_config_get_type ( scfg_arg_com ) != SND_CONFIG_TYPE_COMPOUND ) { return; } } { snd_config_t * scfg_arg_type ( 0 ); int err = snd_config_search ( scfg_arg_com, "type", &scfg_arg_type ); if ( ( err == 0 ) && ( scfg_arg_type != 0 ) ) { if ( snd_config_get_type ( scfg_arg_type ) == SND_CONFIG_TYPE_STRING ) { const char * char_ptr ( 0 ); err = snd_config_get_string ( scfg_arg_type, &char_ptr ); if ( ( err == 0 ) && ( char_ptr != 0 ) ) { //::std::cout << "Found ctl arg type: " << char_ptr << "\n"; ctl_arg_n.arg_type = char_ptr; } } } } } } // End of namespace qastools-v0.22.0/shared/src/qsnd/controls_database.hpp000066400000000000000000000024541354534512100230400ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_qsnd_controls_database_hpp__ #define __INC_qsnd_controls_database_hpp__ #include "qsnd/ctl_format.hpp" #include #include namespace QSnd { /// @brief Controls_Database /// class Controls_Database : public QObject { Q_OBJECT; // Public methods public: Controls_Database ( ); ~Controls_Database ( ); // Control plugins unsigned int num_controls ( ) const; const ::QSnd::CTL_Format & control_format ( unsigned int index_n ) const; const ::QSnd::CTL_Format * find_control_format ( const QString & ctl_name_n ) const; // Signals signals: void sig_change_coming ( ); void sig_change_done ( ); void sig_reload_required ( ); // Public slots public slots: void clear ( ); void clear_silent ( ); void reload ( ); void reload_silent ( ); // Protected methods protected: void load_plugins ( ); // Private attributes private: QList < ::QSnd::CTL_Format > _ctl_formats; }; inline unsigned int Controls_Database::num_controls ( ) const { return _ctl_formats.size(); } inline const ::QSnd::CTL_Format & Controls_Database::control_format ( unsigned int index_n ) const { return _ctl_formats[index_n]; } } // End of namespace #endif qastools-v0.22.0/shared/src/qsnd/controls_model.cpp000066400000000000000000000070721354534512100223700ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "controls_model.hpp" #include "qsnd/alsa.hpp" #include "qsnd/model_keys.hpp" #include "qsnd/ctl_format.hpp" #include "qsnd/controls_database.hpp" #include #include #include namespace QSnd { Controls_Model::Controls_Model ( QObject * parent_n ) : QStandardItemModel ( parent_n ), _ctl_db ( 0 ) { } Controls_Model::~Controls_Model ( ) { } void Controls_Model::set_controls_db ( ::QSnd::Controls_Database * ctl_db_n ) { if ( _ctl_db == ctl_db_n ) { return; } reload_begin(); if ( _ctl_db != 0 ) { disconnect ( _ctl_db, 0, this, 0 ); } _ctl_db = ctl_db_n; if ( _ctl_db != 0 ) { connect ( _ctl_db, SIGNAL ( sig_change_coming() ), this, SLOT ( reload_begin() ) ); connect ( _ctl_db, SIGNAL ( sig_change_done() ), this, SLOT ( reload_finish() ) ); } reload_finish(); } const ::QSnd::CTL_Format * Controls_Model::ctl_format ( const QModelIndex & idx_n ) const { const ::QSnd::CTL_Format * res ( 0 ); if ( ( _ctl_db != 0 ) && ( idx_n.isValid() ) ) { const QVariant & idata ( data ( idx_n, MKEY_DB_INDEX ) ); if ( idata.type() == QVariant::UInt ) { const unsigned int ctl_idx ( idata.toUInt() ); if ( ctl_idx < _ctl_db->num_controls() ) { res = &_ctl_db->control_format ( ctl_idx ); } } } return res; } void Controls_Model::ctl_format ( ::QSnd::CTL_Format & ctl_format_n, const QModelIndex & idx_n ) const { const ::QSnd::CTL_Format * format ( ctl_format ( idx_n ) ); if ( format != 0 ) { ctl_format_n = *format; } else { ctl_format_n.clear(); } } QModelIndex Controls_Model::ctl_format_index ( const QString & ctl_addr_n ) const { QModelIndex res; if ( _ctl_db != 0 ) { const int num_rows ( rowCount() ); for ( int row=0; row < num_rows; ++row ) { QModelIndex midx ( index ( row, 0 ) ); const QVariant & idata ( data ( midx, MKEY_DB_INDEX ) ); const unsigned int ctl_idx ( idata.toUInt() ); if ( ctl_idx < _ctl_db->num_controls() ) { if ( _ctl_db->control_format ( ctl_idx ).match ( ctl_addr_n ) ) { res = midx; break; } } } } return res; } void Controls_Model::reload ( ) { reload_begin(); reload_finish(); } void Controls_Model::reload_begin ( ) { beginResetModel(); removeRows ( 0, rowCount() ); } void Controls_Model::reload_finish ( ) { load_data(); endResetModel(); } void Controls_Model::load_data ( ) { if ( _ctl_db == 0 ) { return; } if ( _ctl_db->num_controls() == 0 ) { return; } for ( unsigned int ii=0; ii != _ctl_db->num_controls(); ++ii ) { const ::QSnd::CTL_Format & ctl_format ( _ctl_db->control_format ( ii ) ); // Create standard item and append QStandardItem * sitem ( new QStandardItem ); sitem->setText ( ctl_format.ctl_name() ); sitem->setEditable ( false ); sitem->setSelectable ( true ); sitem->setData ( QVariant ( ii ), MKEY_DB_INDEX ); QString ttip ( ctl_format.ctl_name() ); QStringList args_l10n; if ( ctl_format.num_args() != 0 ) { ttip.append ( ":" ); for ( unsigned int jj=0; jj != ctl_format.num_args(); ++jj ) { const ::QSnd::CTL_Format_Argument & arg ( ctl_format.arg ( jj ) ); if ( jj > 0 ) { ttip.append ( "," ); } ttip.append ( arg.arg_name ); QString str_l10n ( QCoreApplication::translate ( "ALSA::CTL_Arg_Name", arg.arg_name.toUtf8().constData() ) ); args_l10n.append ( str_l10n ); } } sitem->setData ( QVariant ( args_l10n ), MKEY_L10N_ARGS ); sitem->setToolTip ( ttip ); appendRow ( sitem ); } // Sort items sort ( 0 ); } } // End of namespace qastools-v0.22.0/shared/src/qsnd/controls_model.hpp000066400000000000000000000025041354534512100223700ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_qsnd_controls_model_hpp__ #define __INC_qsnd_controls_model_hpp__ #include // Forward declaration namespace QSnd { class CTL_Format; class Controls_Database; } namespace QSnd { /// @brief Controls_Model /// class Controls_Model : public QStandardItemModel { Q_OBJECT; // Public methods public: Controls_Model ( QObject * parent_n = 0 ); ~Controls_Model ( ); // Controls database ::QSnd::Controls_Database * controls_db ( ) const; void set_controls_db ( ::QSnd::Controls_Database * ctl_db_n ); // Control definition access const ::QSnd::CTL_Format * ctl_format ( const QModelIndex & idx_n ) const; void ctl_format ( ::QSnd::CTL_Format & ctl_format_n, const QModelIndex & idx_n ) const; QModelIndex ctl_format_index ( const QString & ctl_addr_n ) const; // Public slots public slots: void reload ( ); // Protected slots protected slots: void reload_begin ( ); void reload_finish ( ); // Protected methods protected: void load_data ( ); // Private attributes private: ::QSnd::Controls_Database * _ctl_db; }; inline ::QSnd::Controls_Database * Controls_Model::controls_db ( ) const { return _ctl_db; } } // End of namespace #endif qastools-v0.22.0/shared/src/qsnd/ctl_address.cpp000066400000000000000000000063001354534512100216250ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "ctl_address.hpp" namespace QSnd { CTL_Address::CTL_Address ( const char * addr_str_n ) { if ( addr_str_n != 0 ) { set_addr_str ( QString ( addr_str_n ) ); } } CTL_Address::CTL_Address ( const QString & addr_str_n ) { if ( !addr_str_n.isEmpty() ) { set_addr_str ( addr_str_n ); } } CTL_Address::CTL_Address ( const CTL_Address & ctl_addr_n ) { clone_addr ( ctl_addr_n ); } CTL_Address::~CTL_Address ( ) { clear(); } void CTL_Address::clear ( ) { _addr_str.clear(); _ctl_name.clear(); _args.clear(); } void CTL_Address::set_ctl_name ( const QString & name_n ) { _ctl_name = name_n; update_addr_str(); } void CTL_Address::set_addr_str ( const QString & addr_str_n ) { clear(); QString pstr ( addr_str_n ); int idx; idx = pstr.indexOf ( ':' ); if ( idx < 0 ) { _ctl_name = addr_str_n; } else if ( idx > 1 ) { _ctl_name = pstr.left ( idx ); pstr = pstr.mid ( idx + 1 ); QString arg_str; while ( !pstr.isEmpty() ) { idx = pstr.indexOf ( ',' ); if ( idx < 0 ) { arg_str = pstr; pstr.clear(); } else { arg_str = pstr.left ( idx ); pstr = pstr.mid ( idx + 1 ); } ::QSnd::CTL_Address_Argument argm; idx = arg_str.indexOf ( '=' ); if ( idx < 0 ) { argm.arg_value = arg_str; } else { argm.arg_name = arg_str.left ( idx ); argm.arg_value = arg_str.mid ( idx + 1 ); } if ( !argm.arg_value.isEmpty() ) { _args.append ( argm ); } } } update_addr_str(); } void CTL_Address::append_arg ( const ::QSnd::CTL_Address_Argument & arg_n ) { _args.append ( arg_n ); update_addr_str(); } bool CTL_Address::match ( const ::QSnd::CTL_Address & ctl_addr_n ) const { bool res = ( _ctl_name == ctl_addr_n.ctl_name() ); res = res && ( num_args() == ctl_addr_n.num_args() ); if ( res ) { for ( unsigned int ii=0; ii < ctl_addr_n.num_args(); ++ii ) { const ::QSnd::CTL_Address_Argument & arg1 ( arg ( ii ) ); const ::QSnd::CTL_Address_Argument & arg2 ( ctl_addr_n.arg ( ii ) ); if ( arg1.arg_value == arg2.arg_value ) { if ( ( !arg1.arg_name.isEmpty() ) && ( !arg2.arg_name.isEmpty() ) ) { if ( arg1.arg_name != arg2.arg_name ) { res = false; break; } } } else { res = false; break; } } } return res; } ::QSnd::CTL_Address & CTL_Address::operator = ( const ::QSnd::CTL_Address & ctl_addr_n ) { clear(); clone_addr ( ctl_addr_n ); return *this; } void CTL_Address::update_addr_str ( ) { _addr_str = _ctl_name; if ( _args.size() > 0 ) { _addr_str.append ( ":" ); for ( int ii=0; ii < _args.size(); ++ii ) { const ::QSnd::CTL_Address_Argument & argm ( arg ( ii ) ); if ( ii > 0 ) { _addr_str.append ( "," ); } if ( !argm.arg_name.isEmpty() ) { _addr_str.append ( argm.arg_name ); _addr_str.append ( "=" ); } _addr_str.append ( argm.arg_value ); } } } void CTL_Address::clone_addr ( const ::QSnd::CTL_Address & ctl_addr_n ) { _addr_str = ctl_addr_n.addr_str(); _ctl_name = ctl_addr_n.ctl_name(); for ( unsigned int ii=0; ii < ctl_addr_n.num_args(); ++ii ) { _args.append ( ctl_addr_n.arg ( ii ) ); } } } // End of namespace qastools-v0.22.0/shared/src/qsnd/ctl_address.hpp000066400000000000000000000035631354534512100216420ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_qsnd_control_address_hpp__ #define __INC_qsnd_control_address_hpp__ #include "qsnd/ctl_address_argument.hpp" #include #include namespace QSnd { /// @brief CTL_Address /// class CTL_Address { // Public methods public: CTL_Address ( const char * ctl_str_n = 0 ); CTL_Address ( const QString & ctl_str_n ); CTL_Address ( const CTL_Address & ctl_addr_n ); ~CTL_Address ( ); // Clear void clear ( ); bool is_valid ( ) const; // Control name const QString & ctl_name ( ) const; void set_ctl_name ( const QString & name_n ); // Address string const QString & addr_str ( ) const; void set_addr_str ( const QString & id_n ); // Control arguments unsigned int num_args ( ) const; const ::QSnd::CTL_Address_Argument & arg ( unsigned int idx_n ) const; void append_arg ( const ::QSnd::CTL_Address_Argument & arg_n ); // Comparison bool match ( const ::QSnd::CTL_Address & ctl_addr_n ) const; // Operators ::QSnd::CTL_Address & operator = ( const ::QSnd::CTL_Address & ctl_addr_n ); // Private methods private: void clone_addr ( const ::QSnd::CTL_Address & ctl_addr_n ); void update_addr_str ( ); // Private attributes private: QString _addr_str; QString _ctl_name; QList < ::QSnd::CTL_Address_Argument > _args; }; inline bool CTL_Address::is_valid ( ) const { return !_ctl_name.isEmpty(); } inline const QString & CTL_Address::ctl_name ( ) const { return _ctl_name; } inline unsigned int CTL_Address::num_args ( ) const { return _args.size(); } inline const ::QSnd::CTL_Address_Argument & CTL_Address::arg ( unsigned int idx_n ) const { return _args[idx_n]; } inline const QString & CTL_Address::addr_str ( ) const { return _addr_str; } } // End of namespace #endif qastools-v0.22.0/shared/src/qsnd/ctl_address_argument.cpp000066400000000000000000000007131354534512100235310ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "ctl_address_argument.hpp" namespace QSnd { CTL_Address_Argument::CTL_Address_Argument ( ) { } CTL_Address_Argument::CTL_Address_Argument ( const QString & name_n, const QString & value_n ) : arg_name ( name_n ), arg_value ( value_n ) { } void CTL_Address_Argument::clear ( ) { arg_name.clear(); arg_value.clear(); } } // End of namespace qastools-v0.22.0/shared/src/qsnd/ctl_address_argument.hpp000066400000000000000000000010721354534512100235350ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_qsnd_control_address_argument_hpp__ #define __INC_qsnd_control_address_argument_hpp__ #include namespace QSnd { /// @brief CTL_Address_Argument /// class CTL_Address_Argument { // Public methods public: CTL_Address_Argument ( ); CTL_Address_Argument ( const QString & name_n, const QString & value_n = QString() ); void clear ( ); // Public attributes QString arg_name; QString arg_value; }; } // End of namespace #endif qastools-v0.22.0/shared/src/qsnd/ctl_format.cpp000066400000000000000000000046661354534512100215050ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "ctl_format.hpp" namespace QSnd { CTL_Format::CTL_Format ( const char * addr_str_n ) { if ( addr_str_n != 0 ) { _ctl_name = addr_str_n; } } CTL_Format::CTL_Format ( const QString & addr_str_n ) : _ctl_name ( addr_str_n ) { } CTL_Format::CTL_Format ( const CTL_Format & ctl_format_n ) { clone_def ( ctl_format_n ); } CTL_Format::~CTL_Format ( ) { clear(); } void CTL_Format::clear ( ) { _ctl_name.clear(); _args.clear(); } void CTL_Format::set_ctl_name ( const QString & name_n ) { _ctl_name = name_n; } void CTL_Format::append_arg ( const ::QSnd::CTL_Format_Argument & arg_n ) { _args.append ( arg_n ); } bool CTL_Format::match ( const ::QSnd::CTL_Address & ctl_addr_n ) const { bool res ( true ); if ( ctl_addr_n.ctl_name().isEmpty() ) { res = false; } if ( res && ( ctl_addr_n.ctl_name() != ctl_name() ) ) { res = false; } if ( res && ( ctl_addr_n.num_args() > num_args() ) ) { res = false; } if ( res ) { for ( unsigned int ii=0; ii < ctl_addr_n.num_args(); ++ii ) { const ::QSnd::CTL_Address_Argument & arga ( ctl_addr_n.arg ( ii ) ); if ( !arga.arg_name.isEmpty() ) { const ::QSnd::CTL_Format_Argument & argd ( arg ( ii ) ); if ( arga.arg_name != argd.arg_name ) { res = false; break; } } } } return res; } CTL_Format & CTL_Format::operator = ( const ::QSnd::CTL_Format & ctl_format_n ) { clear(); clone_def ( ctl_format_n ); return *this; } bool CTL_Format::operator == ( const ::QSnd::CTL_Format & ctl_format_n ) const { bool res; res = ( _ctl_name == ctl_format_n.ctl_name() ); res = res && ( num_args() == ctl_format_n.num_args() ); if ( res ) { for ( unsigned int ii=0; ii < ctl_format_n.num_args(); ++ii ) { const ::QSnd::CTL_Format_Argument & arg1 ( arg ( ii ) ); const ::QSnd::CTL_Format_Argument & arg2 ( ctl_format_n.arg ( ii ) ); if ( ( arg1.arg_name != arg2.arg_name ) || ( arg1.arg_type != arg2.arg_type ) ) { res = false; break; } } } return res; } bool CTL_Format::operator != ( const ::QSnd::CTL_Format & ctl_format_n ) const { return !operator== ( ctl_format_n ); } void CTL_Format::clone_def ( const ::QSnd::CTL_Format & ctl_format_n ) { _ctl_name = ctl_format_n.ctl_name(); for ( unsigned int ii=0; ii < ctl_format_n.num_args(); ++ii ) { _args.append ( ctl_format_n.arg ( ii ) ); } } } // End of namespace qastools-v0.22.0/shared/src/qsnd/ctl_format.hpp000066400000000000000000000034371354534512100215050ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_qsnd_control_format_hpp__ #define __INC_qsnd_control_format_hpp__ #include "qsnd/ctl_address.hpp" #include "qsnd/ctl_format_argument.hpp" #include #include namespace QSnd { /// @brief CTL_Format /// class CTL_Format { // Public methods public: CTL_Format ( const char * ctl_str_n = 0 ); CTL_Format ( const QString & ctl_str_n ); CTL_Format ( const CTL_Format & ctl_format_n ); ~CTL_Format ( ); // Clear void clear ( ); bool is_valid ( ) const; // Control name const QString & ctl_name ( ) const; void set_ctl_name ( const QString & name_n ); // Control arguments unsigned int num_args ( ) const; const ::QSnd::CTL_Format_Argument & arg ( unsigned int idx_n ) const; void append_arg ( const ::QSnd::CTL_Format_Argument & arg_n ); // Comparison bool match ( const ::QSnd::CTL_Address & ctl_addr_n ) const; // Operators CTL_Format & operator = ( const ::QSnd::CTL_Format & ctl_format_n ); bool operator == ( const ::QSnd::CTL_Format & ctl_format_n ) const; bool operator != ( const ::QSnd::CTL_Format & ctl_format_n ) const; // Private methods private: void clone_def ( const ::QSnd::CTL_Format & ctl_format_n ); // Private attributes private: QString _ctl_name; QList < ::QSnd::CTL_Format_Argument > _args; }; inline bool CTL_Format::is_valid ( ) const { return !_ctl_name.isEmpty(); } inline const QString & CTL_Format::ctl_name ( ) const { return _ctl_name; } inline unsigned int CTL_Format::num_args ( ) const { return _args.size(); } inline const ::QSnd::CTL_Format_Argument & CTL_Format::arg ( unsigned int idx_n ) const { return _args[idx_n]; } } // End of namespace #endif qastools-v0.22.0/shared/src/qsnd/ctl_format_argument.cpp000066400000000000000000000020101354534512100233640ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "ctl_format_argument.hpp" namespace QSnd { CTL_Format_Argument::CTL_Format_Argument ( ) : arg_type ( "string" ) { } CTL_Format_Argument::CTL_Format_Argument ( const QString & name_n, const QString & type_n ) : arg_name ( name_n ), arg_type ( type_n ) { } void CTL_Format_Argument::clear ( ) { arg_name.clear(); arg_type.clear(); } bool CTL_Format_Argument::is_valid ( ) const { bool res ( true ); if ( arg_name.isEmpty() ) { res = false; } else if ( arg_type.isEmpty() ) { res = false; } return res; } bool CTL_Format_Argument::operator == ( const ::QSnd::CTL_Format_Argument & ctl_arg_n ) const { return ( ( arg_name == ctl_arg_n.arg_name ) && ( arg_type == ctl_arg_n.arg_type ) ); } bool CTL_Format_Argument::operator != ( const ::QSnd::CTL_Format_Argument & ctl_arg_n ) const { return ( ( arg_name != ctl_arg_n.arg_name ) || ( arg_type != ctl_arg_n.arg_type ) ); } } // End of namespace qastools-v0.22.0/shared/src/qsnd/ctl_format_argument.hpp000066400000000000000000000014011354534512100233740ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_qsnd_control_format_argument_hpp__ #define __INC_qsnd_control_format_argument_hpp__ #include namespace QSnd { /// @brief CTL_Format_Argument /// class CTL_Format_Argument { // Public methods public: CTL_Format_Argument ( ); CTL_Format_Argument ( const QString & name_n, const QString & type_n = QString ( "string" ) ); void clear ( ); bool is_valid ( ) const; bool operator == ( const ::QSnd::CTL_Format_Argument & ctl_arg_n ) const; bool operator != ( const ::QSnd::CTL_Format_Argument & ctl_arg_n ) const; // Public attributes public: QString arg_name; QString arg_type; }; } // End of namespace #endif qastools-v0.22.0/shared/src/qsnd/event_types.cpp000066400000000000000000000012611354534512100217040ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "qsnd/event_types.hpp" namespace QSnd { ::QEvent::Type evt_update_values_request; ::QEvent::Type evt_update_values; ::QEvent::Type evt_reload_request; ::QEvent::Type evt_reload; void init_event_types ( ) { evt_update_values_request = static_cast < QEvent::Type > ( QEvent::registerEventType() ); evt_update_values = static_cast < QEvent::Type > ( QEvent::registerEventType() ); evt_reload_request = static_cast < QEvent::Type > ( QEvent::registerEventType() ); evt_reload = static_cast < QEvent::Type > ( QEvent::registerEventType() ); } } // End of namespace qastools-v0.22.0/shared/src/qsnd/event_types.hpp000066400000000000000000000006601354534512100217130ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_qsnd_event_types_hpp__ #define __INC_qsnd_event_types_hpp__ #include namespace QSnd { extern QEvent::Type evt_update_values_request; extern QEvent::Type evt_update_values; extern QEvent::Type evt_reload_request; extern QEvent::Type evt_reload; void init_event_types ( ); } // End of namespace #endif qastools-v0.22.0/shared/src/qsnd/mixer_hctl.cpp000066400000000000000000000161631354534512100215040ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "mixer_hctl.hpp" #include "qsnd/mixer_hctl_elem.hpp" #include "qsnd/mixer_hctl_info_db.hpp" #include #include #include #include namespace QSnd { Mixer_HCTL::Mixer_HCTL ( QObject * parent_n ) : QObject ( parent_n ), _snd_hctl ( 0 ), _iface_num_types ( 0 ), _update_requested ( false ), _reload_requested ( false ) { _info_db = new ::QSnd::Mixer_HCTL_Info_Db; for ( unsigned int ii=0; ii < info_db()->num_iface_types(); ++ii ) { _iface_avail_types[ii] = 0; } for ( unsigned int ii=0; ii < info_db()->num_iface_types(); ++ii ) { _iface_type_count[ii] = 0; } } Mixer_HCTL::~Mixer_HCTL ( ) { close(); delete _info_db; } void Mixer_HCTL::close ( ) { // Destroy socket notifiers if ( _socket_notifiers.size() > 0 ) { for ( int ii=0; ii < _socket_notifiers.size(); ++ii ) { delete _socket_notifiers[ii]; } _socket_notifiers.clear(); _pollfds.clear(); } if ( _mixer_elems.size() > 0 ) { // Disconnect mixer elements for ( int ii=0; ii < _mixer_elems.size(); ++ii ) { snd_hctl_elem_t * elem ( _mixer_elems[ii]->snd_hctl_elem() ); snd_hctl_elem_set_callback ( elem, 0 ); snd_hctl_elem_set_callback_private ( elem, 0 ); } // Destroy mixer elements for ( int ii=0; ii < _mixer_elems.size(); ++ii ) { delete _mixer_elems[ii]; } _mixer_elems.clear(); } if ( snd_hctl() != 0 ) { snd_hctl_set_callback ( snd_hctl(), 0 ); snd_hctl_set_callback_private ( snd_hctl(), 0 ); snd_hctl_close ( snd_hctl() ); _snd_hctl = 0; } // Clear statistics _iface_num_types = 0; for ( unsigned int ii=0; ii < info_db()->num_iface_types(); ++ii ) { _iface_avail_types[ii] = 0; } for ( unsigned int ii=0; ii < info_db()->num_iface_types(); ++ii ) { _iface_type_count[ii] = 0; } } int Mixer_HCTL::open ( const QString & dev_name_n ) { close(); _err_func.clear(); _err_message.clear(); if ( dev_name_n.isEmpty() ) { _err_func = "open"; _err_message = tr ( "Empty device name" ); return -1; } // Open control handle int err; err = snd_hctl_open ( &_snd_hctl, dev_name_n.toLocal8Bit().constData(), SND_CTL_NONBLOCK ); if ( err < 0 ) { _err_func = "snd_hctl_open"; _err_message = snd_error_qstring ( err ); close(); return err; } // Load mixer err = snd_hctl_load ( snd_hctl() ); if ( err < 0 ) { _err_func = "snd_hctl_load"; _err_message = snd_error_qstring ( err ); close(); return err; } snd_hctl_set_callback ( snd_hctl(), &Mixer_HCTL::alsa_callback_hctl ); snd_hctl_set_callback_private ( snd_hctl(), this ); // Create mixer elements err = create_mixer_elems(); if ( err < 0 ) { close(); return err; } // Create socket notifiers err = create_socket_notifiers(); if ( err < 0 ) { close(); return err; } // Update statistics for ( unsigned int ii=0; ii < num_elems(); ++ii ) { Mixer_HCTL_Elem * snd_elem ( elem ( ii ) ); unsigned int type_idx ( info_db()->iface_type_idx ( snd_elem->iface() ) ); _iface_type_count[type_idx] += 1; } _iface_num_types = 0; for ( unsigned int ii=0; ii < info_db()->num_iface_types(); ++ii ) { if ( _iface_type_count[ii] > 0 ) { _iface_avail_types[_iface_num_types] = ii; ++_iface_num_types; } } return 0; } int Mixer_HCTL::create_mixer_elems ( ) { // Create and connect Mixer_HCTL_Elem items snd_hctl_elem_t * hctl_elem; hctl_elem = snd_hctl_first_elem ( snd_hctl() ); while ( hctl_elem != 0 ) { Mixer_HCTL_Elem * smce = new Mixer_HCTL_Elem ( *info_db(), this, snd_hctl(), hctl_elem ); snd_hctl_elem_set_callback_private ( hctl_elem, smce ); snd_hctl_elem_set_callback ( hctl_elem, &Mixer_HCTL_Elem::alsa_callback_hctl_elem ); _mixer_elems.append ( smce ); hctl_elem = snd_hctl_elem_next ( hctl_elem ); } return 0; } int Mixer_HCTL::create_socket_notifiers ( ) { //::std::cout << "Mixer_HCTL::create_socket_notifiers" << "\n"; // Setup socket notifiers const int num_fds ( snd_hctl_poll_descriptors_count ( snd_hctl() ) ); if ( num_fds <= 0 ) { _err_func = "snd_hctl_poll_descriptors_count"; _err_message = snd_error_qstring ( num_fds ); return num_fds; } _pollfds.resize ( num_fds ); memset ( &_pollfds[0], 0, num_fds*sizeof ( pollfd ) ); int err = snd_hctl_poll_descriptors ( snd_hctl(), &_pollfds[0], num_fds ); if ( err < 0 ) { _err_func = "snd_hctl_poll_descriptors"; _err_message = snd_error_qstring ( err ); return err; } for ( int ii=0; ii < num_fds; ++ii ) { const int fd ( _pollfds[ii].fd ); if ( fd != 0 ) { QSocketNotifier * snot ( new QSocketNotifier ( fd, QSocketNotifier::Read, this ) ); connect ( snot, SIGNAL ( activated ( int ) ), this, SLOT ( socket_event ( int ) ) ); _socket_notifiers.append ( snot ); } } return 0; } void Mixer_HCTL::set_socked_notifiers_enabled ( bool flag_n ) { for ( int ii=0; ii < _socket_notifiers.size(); ++ii ) { _socket_notifiers[ii]->setEnabled ( flag_n ); } } void Mixer_HCTL::signalize_all_changes ( ) { for ( int ii=0; ii < _mixer_elems.size(); ++ii ) { _mixer_elems[ii]->signalize_changes(); } } bool Mixer_HCTL::event ( QEvent * event_n ) { bool res ( true ); if ( event_n->type() == ::QSnd::evt_update_values_request ) { if ( !_update_requested ) { _update_requested = true; QCoreApplication::postEvent ( this, new QEvent ( ::QSnd::evt_update_values ) ); } } else if ( event_n->type() == ::QSnd::evt_update_values ) { _update_requested = false; signalize_all_changes(); } else if ( event_n->type() == ::QSnd::evt_reload_request ) { if ( !_reload_requested ) { _reload_requested = true; QCoreApplication::postEvent ( this, new QEvent ( ::QSnd::evt_reload ) ); } } else if ( event_n->type() == ::QSnd::evt_reload ) { _reload_requested = false; emit sig_mixer_reload_request(); } else { res = QObject::event ( event_n ); } return res; } void Mixer_HCTL::socket_event ( int ) { if ( snd_hctl() != 0 ) { int num_ev ( snd_hctl_handle_events ( snd_hctl() ) ); if ( num_ev < 0 ) { // Error. Disable socket notifiers set_socked_notifiers_enabled ( false ); print_alsa_error ( "snd_hctl_handle_events ", num_ev ); } signalize_all_changes(); } } void Mixer_HCTL::request_reload ( ) { QCoreApplication::postEvent ( this, new QEvent ( ::QSnd::evt_reload_request ) ); } // Alsa callbacks int Mixer_HCTL::alsa_callback_hctl ( snd_hctl_t * snd_hctl_n, unsigned int mask_n, snd_hctl_elem_t * ) { int res ( 0 ); Mixer_HCTL * qsnd_mixer; { void * priv ( snd_hctl_get_callback_private ( snd_hctl_n ) ); qsnd_mixer = reinterpret_cast < Mixer_HCTL * > ( priv ); } if ( qsnd_mixer != 0 ) { const unsigned int change_mask ( SND_CTL_EVENT_MASK_VALUE | SND_CTL_EVENT_MASK_INFO | SND_CTL_EVENT_MASK_ADD | SND_CTL_EVENT_MASK_TLV ); if ( ( mask_n == SND_CTL_EVENT_MASK_REMOVE ) || ( ( mask_n & change_mask ) != 0 ) ) { qsnd_mixer->request_reload(); } else { { ::std::stringstream msg; msg << "Mixer_HCTL::alsa_callback_hctl: "; msg << "Unknown mask ( " << mask_n << " )" << ::std::endl; ::std::cerr << msg.str(); } res = -1; } } return res; } } // End of namespace qastools-v0.22.0/shared/src/qsnd/mixer_hctl.hpp000066400000000000000000000067611354534512100215140ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_qsnd_mixer_hctl_hpp__ #define __INC_qsnd_mixer_hctl_hpp__ #include "qsnd/alsa.hpp" #include "qsnd/event_types.hpp" #include #include #include #include // Forward declaration namespace QSnd { class Mixer_HCTL_Info_Db; class Mixer_HCTL_Elem; class Mixer_HCTL_Elem_Group; } namespace QSnd { /// @brief Mixer_HCTL /// /// Brings Qt and ALSA objects together but without /// any GUI objects /// class Mixer_HCTL : public QObject { Q_OBJECT // Public methods public: Mixer_HCTL ( QObject * parent_n = 0 ); ~Mixer_HCTL ( ); const Mixer_HCTL_Info_Db * info_db ( ) const; snd_hctl_t * snd_hctl ( ); // Init / close /// @return On an error a negative error code int open ( const QString & dev_name_n ); void close ( ); bool is_open ( ) const; // Error strings / codes const QString & err_func ( ) const; const QString & err_message ( ) const; // Elements unsigned int num_elems ( ) const; const Mixer_HCTL_Elem * elem ( unsigned int idx_n ) const; Mixer_HCTL_Elem * elem ( unsigned int idx_n ); // Interface types unsigned int iface_type_count ( unsigned int type_idx_n ) const; unsigned int iface_types_avail ( ) const; unsigned int iface_avail_type ( unsigned int type_idx_n ) const; // Alsa callbacks static int alsa_callback_hctl ( snd_hctl_t * snd_hctl_n, unsigned int mask_n, snd_hctl_elem_t * elem_n ); // Signals signals: void sig_mixer_reload_request ( ); // Public slots public slots: void request_reload ( ); // Protected slots protected slots: void socket_event ( int socket_id ); // Protected methods protected: int create_mixer_elems ( ); // Socket notifiers int create_socket_notifiers ( ); void set_socked_notifiers_enabled ( bool flag_n ); void signalize_all_changes ( ); bool event ( QEvent * event_n ); // Private attributes private: ::QSnd::Mixer_HCTL_Info_Db * _info_db; snd_hctl_t * _snd_hctl; QList < Mixer_HCTL_Elem * > _mixer_elems; std::vector < pollfd > _pollfds; QList < QSocketNotifier * > _socket_notifiers; unsigned int _iface_num_types; unsigned int _iface_avail_types[7]; unsigned int _iface_type_count[7]; bool _update_requested; bool _reload_requested; QString _err_func; QString _err_message; }; inline const Mixer_HCTL_Info_Db * Mixer_HCTL::info_db ( ) const { return _info_db; } inline snd_hctl_t * Mixer_HCTL::snd_hctl ( ) { return _snd_hctl; } inline bool Mixer_HCTL::is_open ( ) const { return ( _snd_hctl != 0 ); } inline const QString & Mixer_HCTL::err_func ( ) const { return _err_func; } inline const QString & Mixer_HCTL::err_message ( ) const { return _err_message; } // Elements inline unsigned int Mixer_HCTL::num_elems ( ) const { return _mixer_elems.size(); } inline const Mixer_HCTL_Elem * Mixer_HCTL::elem ( unsigned int idx_n ) const { return _mixer_elems[idx_n]; } inline Mixer_HCTL_Elem * Mixer_HCTL::elem ( unsigned int idx_n ) { return _mixer_elems[idx_n]; } // Interface types inline unsigned int Mixer_HCTL::iface_type_count ( unsigned int type_idx_n ) const { return _iface_type_count[type_idx_n]; } inline unsigned int Mixer_HCTL::iface_types_avail ( ) const { return _iface_num_types; } inline unsigned int Mixer_HCTL::iface_avail_type ( unsigned int type_idx_n ) const { return _iface_avail_types[type_idx_n]; } } // End of namespace #endif qastools-v0.22.0/shared/src/qsnd/mixer_hctl_elem.cpp000066400000000000000000000230341354534512100225010ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "mixer_hctl_elem.hpp" #include "qsnd/event_types.hpp" #include #include #include #include namespace QSnd { Mixer_HCTL_Elem::Mixer_HCTL_Elem ( const Mixer_HCTL_Info_Db & info_db_n, QObject * parent_n, snd_hctl_t * hctl_n, snd_hctl_elem_t * hctl_elem_n ) : QObject ( parent_n ), _info_db ( info_db_n ), _snd_hctl ( hctl_n ), _values_changed ( false ) { snd_ctl_elem_info_malloc ( &_snd_ctl_elem_info ); snd_ctl_elem_value_malloc ( &_snd_ctl_elem_value ); snd_ctl_elem_info_clear ( _snd_ctl_elem_info ); snd_ctl_elem_value_clear ( _snd_ctl_elem_value ); set_snd_hctl_elem ( hctl_elem_n ); } Mixer_HCTL_Elem::~Mixer_HCTL_Elem ( ) { snd_ctl_elem_info_free ( _snd_ctl_elem_info ); snd_ctl_elem_value_free ( _snd_ctl_elem_value ); } QString Mixer_HCTL_Elem::enum_item_display_name ( unsigned int enum_idx_n ) const { return QCoreApplication::translate ( "ALSA::Enum_Value", enum_item_name ( enum_idx_n ) ); } void Mixer_HCTL_Elem::clear ( ) { _enum_item_names.clear(); } void Mixer_HCTL_Elem::set_snd_hctl ( snd_hctl_t * hctl_n ) { clear(); _snd_hctl = hctl_n; } void Mixer_HCTL_Elem::set_display_name ( const QString & name_n ) { _display_name = name_n; } void Mixer_HCTL_Elem::set_snd_hctl_elem ( snd_hctl_elem_t * hctl_elem_n ) { clear(); if ( hctl_elem_n == 0 ) { return; } _snd_hctl_elem = hctl_elem_n; if ( snd_hctl_elem() == 0 ) { return; } // Load info snd_hctl_elem_info ( snd_hctl_elem(), _snd_ctl_elem_info ); _display_name = QCoreApplication::translate ( "ALSA::Elem_Name", snd_hctl_elem_get_name ( snd_hctl_elem() ) ); update_value_mark(); } // Boolean type bool Mixer_HCTL_Elem::switches_equal ( ) const { bool res ( true ); const unsigned int num ( count() ); if ( num > 1 ) { long state0 ( switch_state ( 0 ) ); for ( unsigned int ii=1; ii < num; ++ii ) { if ( switch_state ( ii ) != state0 ) { res = false; break; } } } return res; } void Mixer_HCTL_Elem::set_switch_state ( unsigned int idx_n, bool state_n ) { snd_ctl_elem_value_set_boolean ( _snd_ctl_elem_value, idx_n, state_n ); value_was_set(); } void Mixer_HCTL_Elem::set_switch_all ( bool state_n ) { unsigned int num ( count() ); for ( unsigned int ii=0; ii < num; ++ii ) { snd_ctl_elem_value_set_boolean ( _snd_ctl_elem_value, ii, state_n ); } value_was_set(); } void Mixer_HCTL_Elem::invert_switch_state ( unsigned int idx_n ) { bool state ( !switch_state ( idx_n ) ); snd_ctl_elem_value_set_boolean ( _snd_ctl_elem_value, idx_n, state ); value_was_set(); } void Mixer_HCTL_Elem::invert_switch_all ( ) { unsigned int num ( count() ); for ( unsigned int ii=0; ii < num; ++ii ) { bool state ( !switch_state ( ii ) ); snd_ctl_elem_value_set_boolean ( _snd_ctl_elem_value, ii, state ); } value_was_set(); } void Mixer_HCTL_Elem::level_switches ( ) { const unsigned int num_switches ( count() ); unsigned int num_on ( 0 ); unsigned int num_off ( 0 ); for ( unsigned int ii=0; ii < num_switches; ++ii ) { if ( switch_state ( ii ) ) { ++num_on; } else { ++num_off; } } set_switch_all ( ( num_on >= num_off ) ); } // Integer type bool Mixer_HCTL_Elem::integers_equal ( ) const { bool res ( true ); const unsigned int num ( count() ); if ( num > 1 ) { long val0 ( integer_value ( 0 ) ); for ( unsigned int ii=1; ii < num; ++ii ) { if ( integer_value ( ii ) != val0 ) { res = false; break; } } } return res; } void Mixer_HCTL_Elem::set_integer ( unsigned int idx_n, long value_n ) { //::std::cout << "Mixer_HCTL_Elem::set_integer " << idx_n << " value " << value_n << "\n"; snd_ctl_elem_value_set_integer ( _snd_ctl_elem_value, idx_n, value_n ); value_was_set(); } void Mixer_HCTL_Elem::set_integer_all ( long value_n ) { unsigned int num ( count() ); for ( unsigned int ii=0; ii < num; ++ii ) { snd_ctl_elem_value_set_integer ( _snd_ctl_elem_value, ii, value_n ); } value_was_set(); } void Mixer_HCTL_Elem::level_integers ( ) { const unsigned int num ( count() ); if ( num < 2 ) { return; } const long num_int ( num ); long vol_avrg_accu ( 0 ); long vol_mod_accu ( 0 ); for ( unsigned int ii=0; ii < num; ++ii ) { const long val ( integer_value ( ii ) ); long vol_mod; if ( ( val >= num_int ) || ( val <= (-num_int ) ) ) { const long vol_avrg ( val / num_int ); vol_avrg_accu += vol_avrg; vol_mod = val; // Subtraction performed in two steps to prevent and overflow vol_mod -= vol_avrg * ( num_int - 1 ); vol_mod -= vol_avrg; } else { vol_mod = val; } vol_mod_accu += vol_mod; if ( ( vol_mod_accu >= num_int ) || ( vol_mod_accu <= (-num_int) ) ) { const long vol_avrg ( vol_mod_accu / num_int ); vol_avrg_accu += vol_avrg; vol_mod_accu -= ( vol_avrg * num_int ); } } set_integer_all ( vol_avrg_accu ); } // Decibel bool Mixer_HCTL_Elem::has_dB ( ) const { long tmp[2]; return ( dB_range ( &tmp[0], &tmp[1] ) == 0 ); } int Mixer_HCTL_Elem::dB_range ( long * min_n, long * max_n ) const { snd_ctl_elem_id_t * elem_id; snd_ctl_elem_id_alloca ( &elem_id ); snd_ctl_elem_info_get_id ( _snd_ctl_elem_info, elem_id ); return snd_ctl_get_dB_range ( snd_hctl_ctl ( _snd_hctl ), elem_id, min_n, max_n ); } long Mixer_HCTL_Elem::dB_value ( unsigned int idx_n ) const { return ask_dB_from_int ( integer_value ( idx_n ) ); } long Mixer_HCTL_Elem::ask_dB_from_int ( long int_value_n ) const { long res ( 0 ); snd_ctl_elem_id_t * elem_id; snd_ctl_elem_id_alloca ( &elem_id ); snd_ctl_elem_info_get_id ( _snd_ctl_elem_info, elem_id ); snd_ctl_convert_to_dB ( snd_hctl_ctl ( _snd_hctl ), elem_id, int_value_n, &res ); return res; } long Mixer_HCTL_Elem::ask_int_from_dB ( long db_value_n, int round_dir_n ) const { long res ( 0 ); snd_ctl_elem_id_t * elem_id; snd_ctl_elem_id_alloca ( &elem_id ); snd_ctl_elem_info_get_id ( _snd_ctl_elem_info, elem_id ); snd_ctl_convert_from_dB ( snd_hctl_ctl ( _snd_hctl ), elem_id, db_value_n, &res, round_dir_n ); return res; } // Enum type bool Mixer_HCTL_Elem::enum_idices_equal ( ) const { bool res ( true ); const unsigned int num ( count() ); if ( num > 1 ) { unsigned int idx0 ( enum_index ( 0 ) ); for ( unsigned int ii=1; ii < num; ++ii ) { if ( enum_index ( ii ) != idx0 ) { res = false; break; } } } return res; } void Mixer_HCTL_Elem::set_enum_index ( unsigned int channel_idx_n, unsigned int enum_idx_n ) { snd_ctl_elem_value_set_enumerated ( _snd_ctl_elem_value, channel_idx_n, enum_idx_n ); value_was_set(); } void Mixer_HCTL_Elem::set_enum_index_all ( unsigned int enum_idx_n ) { unsigned int num ( count() ); for ( unsigned int ii=0; ii < num; ++ii ) { snd_ctl_elem_value_set_enumerated ( _snd_ctl_elem_value, ii, enum_idx_n ); } value_was_set(); } void Mixer_HCTL_Elem::level_enums ( ) { unsigned int idx ( 0 ); if ( count() > 0 ) { idx = enum_index ( 0 ); } set_enum_index_all ( idx ); } // General bool Mixer_HCTL_Elem::values_equal ( ) const { bool res ( true ); if ( is_boolean() ) { res = switches_equal(); } else if ( is_integer() ) { res = integers_equal(); } else if ( is_enumerated() ) { res = enum_idices_equal(); } return res; } void Mixer_HCTL_Elem::level_values ( ) { if ( is_boolean() ) { level_switches(); } else if ( is_integer() ) { level_integers(); } else if ( is_enumerated() ) { level_enums(); } } void Mixer_HCTL_Elem::value_was_set ( ) { snd_hctl_elem_t * hctl_elem ( snd_hctl_elem() ); if ( hctl_elem != 0 ) { int err = snd_hctl_elem_write ( hctl_elem, _snd_ctl_elem_value ); if ( err >= 0 ) { // Read values back update_value_mark(); if ( parent() != 0 ) { QEvent ev_req ( ::QSnd::evt_update_values_request ); QCoreApplication::sendEvent ( parent(), &ev_req ); } } else { print_alsa_error ( "snd_hctl_elem_write", err ); } } } void Mixer_HCTL_Elem::update_value ( ) { snd_hctl_elem_t * hctl_elem ( snd_hctl_elem() ); if ( hctl_elem != 0 ) { int err = snd_hctl_elem_read ( hctl_elem, _snd_ctl_elem_value ); if ( err < 0 ) { print_alsa_error ( "snd_hctl_elem_read", err ); } } } void Mixer_HCTL_Elem::update_value_mark ( ) { _values_changed = true; update_value(); } void Mixer_HCTL_Elem::signalize_changes ( ) { if ( _values_changed ) { _values_changed = false; emit sig_values_changed(); } } void Mixer_HCTL_Elem::signalize_element_changed ( ) { if ( snd_hctl_elem() != 0 ) { snd_hctl_elem_info ( snd_hctl_elem(), _snd_ctl_elem_info ); } if ( parent() != 0 ) { QEvent ev_req ( ::QSnd::evt_reload_request ); QCoreApplication::sendEvent ( parent(), &ev_req ); } } // Alsa callbacks int Mixer_HCTL_Elem::alsa_callback_hctl_elem ( snd_hctl_elem_t * elem_n, unsigned int mask_n ) { int res ( 0 ); Mixer_HCTL_Elem * smce; { void * priv ( snd_hctl_elem_get_callback_private ( elem_n ) ); smce = reinterpret_cast < Mixer_HCTL_Elem * > ( priv ); } if ( smce != 0 ) { const unsigned int change_mask ( SND_CTL_EVENT_MASK_INFO | SND_CTL_EVENT_MASK_ADD | SND_CTL_EVENT_MASK_TLV ); if ( ( mask_n == SND_CTL_EVENT_MASK_REMOVE ) || ( ( mask_n & change_mask ) != 0 ) ) { smce->signalize_element_changed(); } else if ( ( mask_n & SND_CTL_EVENT_MASK_VALUE ) != 0 ) { smce->update_value_mark(); } else { // Unusual mask { ::std::stringstream msg; msg << "Mixer_HCTL_Elem::alsa_callback_hctl_elem: "; msg << "Unknown mask ( " << mask_n << " )" << ::std::endl; ::std::cerr << msg.str(); } res = -1; } } return res; } } // End of namespace qastools-v0.22.0/shared/src/qsnd/mixer_hctl_elem.hpp000066400000000000000000000212661354534512100225130ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_qsnd_mixer_hctl_elem_hpp__ #define __INC_qsnd_mixer_hctl_elem_hpp__ #include "qsnd/alsa.hpp" #include "qsnd/mixer_hctl_info_db.hpp" #include #include #include namespace QSnd { /// @brief Mixer_HCTL_Elem /// /// Brings Qt and ALSA objects together but without /// any GUI objects /// class Mixer_HCTL_Elem : public QObject { Q_OBJECT // Public typedefs public: typedef ::std::vector < QString > Enum_Names_Buffer; // Public methods public: Mixer_HCTL_Elem ( const Mixer_HCTL_Info_Db & info_db_n, QObject * parent_n = 0, snd_hctl_t * hctl_n = 0, snd_hctl_elem_t * hctl_elem_n = 0 ); ~Mixer_HCTL_Elem ( ); void clear ( ); // Alsa hctl snd_hctl_t * snd_hctl ( ) const; void set_snd_hctl ( snd_hctl_t * hctl_n ); // Alsa hctl elem void set_snd_hctl_elem ( snd_hctl_elem_t * hctl_elem_n ); snd_hctl_elem_t * snd_hctl_elem ( ) const; // Alsa snd_ctl_elem_info_t const snd_ctl_elem_info_t * snd_ctl_info ( ) const; const QString & display_name ( ) const; void set_display_name ( const QString & name_n ); const char * elem_name ( ) const; unsigned int elem_numid ( ) const; unsigned int elem_index ( ) const; unsigned int device ( ) const; unsigned int subdevice ( ) const; snd_ctl_elem_iface_t iface ( ) const; unsigned int iface_type_idx ( ) const; const QString & iface_name ( ) const; const QString & iface_display_name ( ) const; unsigned int count ( ) const; // Type snd_ctl_elem_type_t elem_type ( ) const; const QString & elem_type_name ( ) const; const QString & elem_type_display_name ( ) const; bool is_boolean ( ) const; bool is_integer ( ) const; bool is_enumerated ( ) const; bool is_bytes ( ) const; bool is_IEC958 ( ) const; bool is_integer64 ( ) const; // State flags bool is_volatile ( ) const; bool is_readable ( ) const; bool is_writable ( ) const; bool is_active ( ) const; // Boolean type bool switch_state ( unsigned int idx_n ) const; bool switches_equal ( ) const; void set_switch_state ( unsigned int idx_n, bool state_n ); void set_switch_all ( bool state_n ); void invert_switch_state ( unsigned int idx_n ); void invert_switch_all ( ); void level_switches ( ); // Integer type long integer_min ( ) const; long integer_max ( ) const; long integer_value ( unsigned int idx_n ) const; bool integers_equal ( ) const; void set_integer ( unsigned int idx_n, long value_n ); void set_integer_all ( long value_n ); void level_integers ( ); // Decibel bool has_dB ( ) const; /// @return < 0 on error int dB_range ( long * min_n, long * max_n ) const; long dB_value ( unsigned int idx_n ) const; long ask_dB_from_int ( long int_value_n ) const; long ask_int_from_dB ( long value_n, int round_dir_n = 0 ) const; // Enum type unsigned int enum_num_items ( ) const; const char * enum_item_name ( unsigned int enum_idx_n ) const; QString enum_item_display_name ( unsigned int enum_idx_n ) const; unsigned int enum_index ( unsigned int channel_idx_n ) const; bool enum_idices_equal ( ) const; void set_enum_index ( unsigned int channel_idx_n, unsigned int enum_idx_n ); void set_enum_index_all ( unsigned int enum_idx_n ); void level_enums ( ); // General bool values_equal ( ) const; void level_values ( ); bool values_changed ( ) const; /// @brief Reads all value from alsa void update_value ( ); // Callback methods /// @brief Reads all value from alsa and flags a change void update_value_mark ( ); void signalize_changes ( ); /// @brief Signalizes the parent that this element changed void signalize_element_changed ( ); // Alsa callbacks static int alsa_callback_hctl_elem ( snd_hctl_elem_t * elem_n, unsigned int mask_n ); // Signals signals: /// @brief Gets emitted when a value was set void sig_values_changed ( ); // Protected methods protected: void value_was_set ( ); // Private attributes private: const Mixer_HCTL_Info_Db & _info_db; snd_hctl_t * _snd_hctl; snd_hctl_elem_t * _snd_hctl_elem; snd_ctl_elem_info_t * _snd_ctl_elem_info; snd_ctl_elem_value_t * _snd_ctl_elem_value; bool _values_changed; QString _display_name; Enum_Names_Buffer _enum_item_names; }; inline snd_hctl_t * Mixer_HCTL_Elem::snd_hctl ( ) const { return _snd_hctl; } inline snd_hctl_elem_t * Mixer_HCTL_Elem::snd_hctl_elem ( ) const { return _snd_hctl_elem; } inline const snd_ctl_elem_info_t * Mixer_HCTL_Elem::snd_ctl_info ( ) const { return _snd_ctl_elem_info; } inline const QString & Mixer_HCTL_Elem::display_name ( ) const { return _display_name; } inline const char * Mixer_HCTL_Elem::elem_name ( ) const { return snd_ctl_elem_info_get_name ( _snd_ctl_elem_info ); } inline unsigned int Mixer_HCTL_Elem::elem_numid ( ) const { return snd_ctl_elem_info_get_numid ( _snd_ctl_elem_info ); } inline unsigned int Mixer_HCTL_Elem::elem_index ( ) const { return snd_ctl_elem_info_get_index ( _snd_ctl_elem_info ); } inline unsigned int Mixer_HCTL_Elem::device ( ) const { return snd_ctl_elem_info_get_device ( _snd_ctl_elem_info ); } inline unsigned int Mixer_HCTL_Elem::subdevice ( ) const { return snd_ctl_elem_info_get_subdevice ( _snd_ctl_elem_info ); } inline snd_ctl_elem_iface_t Mixer_HCTL_Elem::iface ( ) const { return snd_ctl_elem_info_get_interface ( _snd_ctl_elem_info ); } inline unsigned int Mixer_HCTL_Elem::iface_type_idx ( ) const { return _info_db.iface_type_idx ( iface() ); } inline const QString & Mixer_HCTL_Elem::iface_name ( ) const { return _info_db.iface_name ( iface() ); } inline const QString & Mixer_HCTL_Elem::iface_display_name ( ) const { return _info_db.iface_display_name ( iface() ); } inline unsigned int Mixer_HCTL_Elem::count ( ) const { return snd_ctl_elem_info_get_count ( _snd_ctl_elem_info ); } // Type inline snd_ctl_elem_type_t Mixer_HCTL_Elem::elem_type ( ) const { return snd_ctl_elem_info_get_type ( _snd_ctl_elem_info ); } inline const QString & Mixer_HCTL_Elem::elem_type_name ( ) const { return _info_db.elem_type_name ( elem_type() ); } inline const QString & Mixer_HCTL_Elem::elem_type_display_name ( ) const { return _info_db.elem_type_display_name ( elem_type() ); } inline bool Mixer_HCTL_Elem::is_boolean ( ) const { return ( elem_type() == SND_CTL_ELEM_TYPE_BOOLEAN ); } inline bool Mixer_HCTL_Elem::is_integer ( ) const { return ( elem_type() == SND_CTL_ELEM_TYPE_INTEGER ); } inline bool Mixer_HCTL_Elem::is_enumerated ( ) const { return ( elem_type() == SND_CTL_ELEM_TYPE_ENUMERATED ); } inline bool Mixer_HCTL_Elem::is_bytes ( ) const { return ( elem_type() == SND_CTL_ELEM_TYPE_BYTES ); } inline bool Mixer_HCTL_Elem::is_IEC958 ( ) const { return ( elem_type() == SND_CTL_ELEM_TYPE_IEC958 ); } inline bool Mixer_HCTL_Elem::is_integer64 ( ) const { return ( elem_type() == SND_CTL_ELEM_TYPE_INTEGER64 ); } inline bool Mixer_HCTL_Elem::is_volatile ( ) const { return snd_ctl_elem_info_is_volatile ( _snd_ctl_elem_info ); } inline bool Mixer_HCTL_Elem::is_readable ( ) const { return snd_ctl_elem_info_is_readable ( _snd_ctl_elem_info ); } inline bool Mixer_HCTL_Elem::is_writable ( ) const { return snd_ctl_elem_info_is_writable ( _snd_ctl_elem_info ); } inline bool Mixer_HCTL_Elem::is_active ( ) const { return ( snd_ctl_elem_info_is_inactive ( _snd_ctl_elem_info ) == 0 ); } // Integer type inline long Mixer_HCTL_Elem::integer_min ( ) const { return snd_ctl_elem_info_get_min ( _snd_ctl_elem_info ); } inline long Mixer_HCTL_Elem::integer_max ( ) const { return snd_ctl_elem_info_get_max ( _snd_ctl_elem_info ); } inline long Mixer_HCTL_Elem::integer_value ( unsigned int idx_n ) const { return snd_ctl_elem_value_get_integer ( _snd_ctl_elem_value, idx_n ); } // Switch value inline bool Mixer_HCTL_Elem::switch_state ( unsigned int idx_n ) const { return snd_ctl_elem_value_get_boolean ( _snd_ctl_elem_value, idx_n ); } inline unsigned int Mixer_HCTL_Elem::enum_num_items ( ) const { return snd_ctl_elem_info_get_items ( _snd_ctl_elem_info ); } inline const char * Mixer_HCTL_Elem::enum_item_name ( unsigned int enum_idx_n ) const { snd_ctl_elem_info_set_item ( _snd_ctl_elem_info, enum_idx_n ); snd_hctl_elem_info ( snd_hctl_elem(), _snd_ctl_elem_info ); return snd_ctl_elem_info_get_item_name ( _snd_ctl_elem_info ); } inline unsigned int Mixer_HCTL_Elem::enum_index ( unsigned int channel_idx_n ) const { return snd_ctl_elem_value_get_enumerated ( _snd_ctl_elem_value, channel_idx_n ); } inline bool Mixer_HCTL_Elem::values_changed ( ) const { return _values_changed; } } // End of namespace #endif qastools-v0.22.0/shared/src/qsnd/mixer_hctl_elem_group.cpp000066400000000000000000000003621354534512100237140ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "mixer_hctl_elem_group.hpp" namespace QSnd { void Mixer_HCTL_Elem_Group::clear ( ) { _snd_elems.clear(); } } // End of namespace qastools-v0.22.0/shared/src/qsnd/mixer_hctl_elem_group.hpp000066400000000000000000000017461354534512100237300ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_qsnd_mixer_hctl_elem_group_hpp__ #define __INC_qsnd_mixer_hctl_elem_group_hpp__ #include // Forward declaration namespace QSnd { class Mixer_HCTL_Elem; } namespace QSnd { /// @brief Mixer_HCTL_Elem_Group /// class Mixer_HCTL_Elem_Group { // Public methods public: void clear ( ); unsigned int num_elems ( ) const; void append_elem ( Mixer_HCTL_Elem * elem_n ); Mixer_HCTL_Elem * elem ( unsigned int idx_n ) const; // Private attributes private: QList < Mixer_HCTL_Elem * > _snd_elems; }; inline unsigned int Mixer_HCTL_Elem_Group::num_elems ( ) const { return _snd_elems.size(); } inline void Mixer_HCTL_Elem_Group::append_elem ( Mixer_HCTL_Elem * elem_n ) { _snd_elems.append ( elem_n ); } inline Mixer_HCTL_Elem * Mixer_HCTL_Elem_Group::elem ( unsigned int idx_n ) const { return _snd_elems[idx_n]; } } // End of namespace #endif qastools-v0.22.0/shared/src/qsnd/mixer_hctl_info_db.cpp000066400000000000000000000075171354534512100231670ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "mixer_hctl_info_db.hpp" #include #include #include namespace QSnd { Mixer_HCTL_Info_Db::Mixer_HCTL_Info_Db ( ) { // Element type names for ( unsigned int ii=0; ii < num_iface_types(); ++ii ) { const char * if_name ( snd_ctl_elem_type_name ( element_idx_type ( ii ) ) ); _etype_names[ii] = if_name; _etype_display_names[ii] = QCoreApplication::translate ( "ALSA::CTL_Elem_Type_Name", if_name ); // Fix untranslated names if ( _etype_names[ii] == _etype_display_names[ii] ) { QString & idn ( _etype_display_names[ii] ); if ( idn == "NONE" ) { idn = "None"; } else if ( idn == "BOOLEAN" ) { idn = "Boolean"; } else if ( idn == "INTEGER" ) { idn = "Integer"; } else if ( idn == "ENUMERATED" ) { idn = "Enumerated"; } else if ( idn == "BYTES" ) { idn = "Bytes"; } else if ( idn == "IEC958" ) { idn = "IEC958"; } else if ( idn == "INTEGER64" ) { idn = "Integer64"; } } } { const unsigned int idx ( num_element_types() ); _etype_names[idx] = QCoreApplication::translate ( "ALSA::CTL_Elem_Type_Name", "Unknown" ); _etype_display_names[idx] = _etype_names[idx]; } // Interface names for ( unsigned int ii=0; ii < num_iface_types(); ++ii ) { const char * if_name = snd_ctl_elem_iface_name ( iface_idx_type ( ii ) ); _iface_names[ii] = if_name; _iface_display_names[ii] = QCoreApplication::translate ( "ALSA::CTL_Elem_IFace_Name", if_name ); // Fix untranslated names if ( _iface_names[ii] == _iface_display_names[ii] ) { QString & idn ( _iface_display_names[ii] ); if ( idn == "CARD" ) { idn = "Card"; } else if ( idn == "HWDEP" ) { idn = "Hw dep."; } else if ( idn == "MIXER" ) { idn = "Mixer"; } else if ( idn == "PCM" ) { idn = "PCM"; } else if ( idn == "RAWMIDI" ) { idn = "Raw midi"; } else if ( idn == "TIMER" ) { idn = "Timer"; } else if ( idn == "SEQUENCER" ) { idn = "Sequencer"; } } } { const unsigned int idx ( num_iface_types() ); _iface_names[idx] = QCoreApplication::translate ( "ALSA::CTL_Elem_IFace_Name", "Unknown" ); _iface_display_names[idx] = _iface_names[idx]; } // Flag names _flag_readable_text[0] = QCoreApplication::translate ( "ALSA::Flags", "not readable" ); _flag_readable_text[1] = QCoreApplication::translate ( "ALSA::Flags", "readable" ); _flag_readable_char[0] = "-"; _flag_readable_char[1] = "r"; _flag_writable_text[0] = QCoreApplication::translate ( "ALSA::Flags", "not writable" ); _flag_writable_text[1] = QCoreApplication::translate ( "ALSA::Flags", "writable" ); _flag_writable_char[0] = "-"; _flag_writable_char[1] = "w"; _flag_volatile_text[0] = QCoreApplication::translate ( "ALSA::Flags", "not volatile" ); _flag_volatile_text[1] = QCoreApplication::translate ( "ALSA::Flags", "volatile" ); _flag_volatile_char[0] = "-"; _flag_volatile_char[1] = "v"; _flag_active_text[0] = QCoreApplication::translate ( "ALSA::Flags", "not active" ); _flag_active_text[1] = QCoreApplication::translate ( "ALSA::Flags", "active" ); _flag_active_char[0] = "-"; _flag_active_char[1] = "a"; } const QString & Mixer_HCTL_Info_Db::elem_type_name ( snd_ctl_elem_type_t type_n ) const { return elem_type_name ( element_type_idx ( type_n ) ); } const QString & Mixer_HCTL_Info_Db::elem_type_display_name ( snd_ctl_elem_type_t type_n ) const { return elem_type_display_name ( element_type_idx ( type_n ) ); } const QString & Mixer_HCTL_Info_Db::iface_name ( snd_ctl_elem_iface_t type_n ) const { return iface_name ( iface_type_idx ( type_n ) ); } const QString & Mixer_HCTL_Info_Db::iface_display_name ( snd_ctl_elem_iface_t type_n ) const { return iface_display_name ( iface_type_idx ( type_n ) ); } } // End of namespace qastools-v0.22.0/shared/src/qsnd/mixer_hctl_info_db.hpp000066400000000000000000000160541354534512100231700ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_qsnd_mixer_hctl_info_db_hpp__ #define __INC_qsnd_mixer_hctl_info_db_hpp__ #include "qsnd/alsa.hpp" #include #include namespace QSnd { /// @brief Mixer_HCTL_Info_Db /// /// Offers localized strings and translation tables /// for Alsa objects class Mixer_HCTL_Info_Db { // Public methods public: Mixer_HCTL_Info_Db ( ); // Element types unsigned int num_element_types ( ) const; unsigned int element_type_idx ( snd_ctl_elem_type_t type_n ) const; snd_ctl_elem_type_t element_idx_type ( unsigned int idx_n ) const; const QString & elem_type_name ( snd_ctl_elem_type_t type_n ) const; const QString & elem_type_name ( unsigned int type_idx_n ) const; const QString & elem_type_display_name ( snd_ctl_elem_type_t type_n ) const; const QString & elem_type_display_name ( unsigned int type_idx_n ) const; // Interface types unsigned int num_iface_types ( ) const; unsigned int iface_type_idx ( snd_ctl_elem_iface_t type_n ) const; snd_ctl_elem_iface_t iface_idx_type ( unsigned int idx_n ) const; const QString & iface_name ( snd_ctl_elem_iface_t type_n ) const; const QString & iface_name ( unsigned int type_idx_n ) const; const QString & iface_display_name ( snd_ctl_elem_iface_t type_n ) const; const QString & iface_display_name ( unsigned int type_idx_n ) const; const QString & flag_readable_text ( bool flag_n = true ) const; const QString & flag_readable_char ( bool flag_n = true ) const; const QString & flag_writable_text ( bool flag_n = true ) const; const QString & flag_writable_char ( bool flag_n = true ) const; const QString & flag_active_text ( bool flag_n = true ) const; const QString & flag_active_char ( bool flag_n = true ) const; const QString & flag_volatile_text ( bool flag_n = true ) const; const QString & flag_volatile_char ( bool flag_n = true ) const; // Private attributes private: static const unsigned int _num_iface_types = 7; static const unsigned int _num_elem_types = 7; QString _etype_names[ _num_elem_types + 1 ]; QString _etype_display_names[ _num_elem_types + 1 ]; QString _iface_names[ _num_iface_types + 1 ]; QString _iface_display_names[ _num_iface_types + 1 ]; QString _flag_readable_text[2]; QString _flag_readable_char[2]; QString _flag_writable_text[2]; QString _flag_writable_char[2]; QString _flag_volatile_text[2]; QString _flag_volatile_char[2]; QString _flag_active_text[2]; QString _flag_active_char[2]; }; // Element types inline unsigned int Mixer_HCTL_Info_Db::num_element_types ( ) const { return _num_elem_types; } inline unsigned int Mixer_HCTL_Info_Db::element_type_idx ( snd_ctl_elem_type_t type_n ) const { unsigned int res ( 0 ); switch ( type_n ) { case SND_CTL_ELEM_TYPE_NONE: res = 0; break; case SND_CTL_ELEM_TYPE_BOOLEAN: res = 1; break; case SND_CTL_ELEM_TYPE_INTEGER: res = 2; break; case SND_CTL_ELEM_TYPE_ENUMERATED: res = 3; break; case SND_CTL_ELEM_TYPE_BYTES: res = 4; break; case SND_CTL_ELEM_TYPE_IEC958: res = 5; break; case SND_CTL_ELEM_TYPE_INTEGER64: res = 6; break; default: break; } return res; } inline snd_ctl_elem_type_t Mixer_HCTL_Info_Db::element_idx_type ( unsigned int idx_n ) const { snd_ctl_elem_type_t res ( SND_CTL_ELEM_TYPE_NONE ); switch ( idx_n ) { case 0: res = SND_CTL_ELEM_TYPE_NONE; break; case 1: res = SND_CTL_ELEM_TYPE_BOOLEAN; break; case 2: res = SND_CTL_ELEM_TYPE_INTEGER; break; case 3: res = SND_CTL_ELEM_TYPE_ENUMERATED; break; case 4: res = SND_CTL_ELEM_TYPE_BYTES; break; case 5: res = SND_CTL_ELEM_TYPE_IEC958; break; case 6: res = SND_CTL_ELEM_TYPE_INTEGER64; break; default: break; } return res; } inline const QString & Mixer_HCTL_Info_Db::elem_type_name ( unsigned int type_idx_n ) const { if ( type_idx_n > num_element_types() ) { type_idx_n = num_element_types(); } return _etype_names[type_idx_n]; } inline const QString & Mixer_HCTL_Info_Db::elem_type_display_name ( unsigned int type_idx_n ) const { if ( type_idx_n > num_element_types() ) { type_idx_n = num_element_types(); } return _etype_display_names[type_idx_n]; } // Interface types inline unsigned int Mixer_HCTL_Info_Db::num_iface_types ( ) const { return _num_iface_types; } inline unsigned int Mixer_HCTL_Info_Db::iface_type_idx ( snd_ctl_elem_iface_t type_n ) const { unsigned int res ( 2 ); switch ( type_n ) { case SND_CTL_ELEM_IFACE_CARD: res = 0; break; case SND_CTL_ELEM_IFACE_HWDEP: res = 1; break; case SND_CTL_ELEM_IFACE_MIXER: res = 2; break; case SND_CTL_ELEM_IFACE_PCM: res = 3; break; case SND_CTL_ELEM_IFACE_RAWMIDI: res = 4; break; case SND_CTL_ELEM_IFACE_TIMER: res = 5; break; case SND_CTL_ELEM_IFACE_SEQUENCER: res = 6; break; default: break; } return res; } inline snd_ctl_elem_iface_t Mixer_HCTL_Info_Db::iface_idx_type ( unsigned int idx_n ) const { snd_ctl_elem_iface_t res ( SND_CTL_ELEM_IFACE_CARD ); switch ( idx_n ) { case 0: res = SND_CTL_ELEM_IFACE_CARD; break; case 1: res = SND_CTL_ELEM_IFACE_HWDEP; break; case 2: res = SND_CTL_ELEM_IFACE_MIXER; break; case 3: res = SND_CTL_ELEM_IFACE_PCM; break; case 4: res = SND_CTL_ELEM_IFACE_RAWMIDI; break; case 5: res = SND_CTL_ELEM_IFACE_TIMER; break; case 6: res = SND_CTL_ELEM_IFACE_SEQUENCER; break; default: break; } return res; } inline const QString & Mixer_HCTL_Info_Db::iface_name ( unsigned int type_idx_n ) const { if ( type_idx_n > num_iface_types() ) { type_idx_n = num_iface_types(); } return _iface_names[type_idx_n]; } inline const QString & Mixer_HCTL_Info_Db::iface_display_name ( unsigned int type_idx_n ) const { if ( type_idx_n > num_iface_types() ) { type_idx_n = num_iface_types(); } return _iface_display_names[type_idx_n]; } inline const QString & Mixer_HCTL_Info_Db::flag_readable_text ( bool flag_n ) const { return _flag_readable_text[ ( flag_n ? 1 : 0 ) ]; } inline const QString & Mixer_HCTL_Info_Db::flag_readable_char ( bool flag_n ) const { return _flag_readable_char[ ( flag_n ? 1 : 0 ) ]; } inline const QString & Mixer_HCTL_Info_Db::flag_writable_text ( bool flag_n ) const { return _flag_writable_text[ ( flag_n ? 1 : 0 ) ]; } inline const QString & Mixer_HCTL_Info_Db::flag_writable_char ( bool flag_n ) const { return _flag_writable_char[ ( flag_n ? 1 : 0 ) ]; } inline const QString & Mixer_HCTL_Info_Db::flag_volatile_text ( bool flag_n ) const { return _flag_volatile_text[ ( flag_n ? 1 : 0 ) ]; } inline const QString & Mixer_HCTL_Info_Db::flag_volatile_char ( bool flag_n ) const { return _flag_volatile_char[ ( flag_n ? 1 : 0 ) ]; } inline const QString & Mixer_HCTL_Info_Db::flag_active_text ( bool flag_n ) const { return _flag_active_text[ ( flag_n ? 1 : 0 ) ]; } inline const QString & Mixer_HCTL_Info_Db::flag_active_char ( bool flag_n ) const { return _flag_active_char[ ( flag_n ? 1 : 0 ) ]; } } // End of namespace #endif qastools-v0.22.0/shared/src/qsnd/mixer_simple.cpp000066400000000000000000000242141354534512100220370ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "mixer_simple.hpp" #include "qsnd/mixer_simple_elem.hpp" #include "qsnd/mixer_simple_filter.hpp" #include "qsnd/event_types.hpp" #include #include #include #include namespace QSnd { Mixer_Simple::Mixer_Simple ( QObject * parent_n ) : QObject ( parent_n ), _snd_hctl ( 0 ), _snd_mixer ( 0 ), _update_requested ( false ), _reload_requested ( false ) { _num_elems_stream[0] = 0; _num_elems_stream[1] = 0; _num_elems_volume[0] = 0; _num_elems_volume[1] = 0; _num_elems_no_volume[0] = 0; _num_elems_no_volume[1] = 0; } Mixer_Simple::~Mixer_Simple ( ) { close(); clear_elem_filters(); } void Mixer_Simple::clear_elem_filters ( ) { for ( int ii=0; ii < _elem_filters.size(); ++ii ) { delete _elem_filters[ii]; } _elem_filters.clear(); } void Mixer_Simple::append_elem_filter ( ::QSnd::Mixer_Simple_Filter * filter_n ) { if ( filter_n != 0 ) { _elem_filters.append ( filter_n ); } } void Mixer_Simple::close ( ) { // Destroy socket notifiers for ( int ii=0; ii < _socket_notifiers.size(); ++ii ) { delete _socket_notifiers[ii]; } _socket_notifiers.clear(); _pollfds.clear(); clear_mixer_elems(); if ( snd_mixer() != 0 ) { snd_mixer_set_callback ( snd_mixer(), 0 ); snd_mixer_set_callback_private ( snd_mixer(), 0 ); if ( _snd_hctl != 0 ) { snd_mixer_detach_hctl ( snd_mixer(), _snd_hctl ); } snd_mixer_close ( snd_mixer() ); _snd_mixer = 0; } if ( _snd_hctl != 0 ) { snd_hctl_close ( _snd_hctl ); _snd_hctl = 0; } _num_elems_stream[0] = 0; _num_elems_stream[1] = 0; _num_elems_volume[0] = 0; _num_elems_volume[1] = 0; _num_elems_no_volume[0] = 0; _num_elems_no_volume[1] = 0; } int Mixer_Simple::open ( const QString & dev_name_n ) { //::std::cout << "Mixer_Simple::open " << dev_name_n.toLocal8Bit().constData() << "\n"; close(); _err_func.clear(); _err_message.clear(); if ( dev_name_n.isEmpty() ) { _err_func = "open"; _err_message = tr ( "Empty device name" ); return -1; } int err; err = snd_mixer_open ( &_snd_mixer, 0 ); if ( err < 0 ) { _err_func = "snd_mixer_open"; _err_message = snd_error_qstring ( err ); return err; } err = snd_mixer_selem_register ( _snd_mixer, NULL, NULL ); if ( err < 0 ) { _err_func = "snd_mixer_selem_register"; _err_message = snd_error_qstring ( err ); close(); return err; } // Open control handle err = snd_hctl_open ( &_snd_hctl, dev_name_n.toLocal8Bit().constData(), SND_CTL_NONBLOCK ); if ( err < 0 ) { _err_func = "snd_hctl_open"; _err_message = snd_error_qstring ( err ); close(); return err; } // Attach hctl handle to mixer err = snd_mixer_attach_hctl ( _snd_mixer, _snd_hctl ); if ( err < 0 ) { _snd_hctl = 0; _err_func = "snd_mixer_attach_hctl"; _err_message = snd_error_qstring ( err ); close(); return err; } // Load mixer err = snd_mixer_load ( _snd_mixer ); if ( err < 0 ) { _err_func = "snd_mixer_load"; _err_message = snd_error_qstring ( err ); close(); return err; } // Install alsa callback snd_mixer_set_callback_private ( snd_mixer(), this ); snd_mixer_set_callback ( snd_mixer(), &::QSnd::Mixer_Simple::alsa_callback_mixer ); // Create mixer elements err = create_mixer_elems(); if ( err < 0 ) { close(); return err; } // Create socket notifiers err = create_socket_notifiers(); if ( err < 0 ) { close(); return err; } return 0; } void Mixer_Simple::clear_mixer_elems ( ) { if ( _mixer_elems.size() > 0 ) { // Disconnect mixer elements for ( int ii=0; ii < _mixer_elems.size(); ++ii ) { destroy_mixer_elem ( _mixer_elems[ii] ); } _mixer_elems.clear(); } } int Mixer_Simple::create_mixer_elems ( ) { // Create and Mixer_Simple_Elem objects { snd_mixer_elem_t * elem; elem = snd_mixer_first_elem ( snd_mixer() ); while ( elem != 0 ) { { Mixer_Simple_Elem * mx_elem ( create_mixer_elem ( elem ) ); _mixer_elems.append ( mx_elem ); } elem = snd_mixer_elem_next ( elem ); } } // Filter Mixer_Simple_Elem objects if ( _elem_filters.size() > 0 ) { // List for dropped (filtered) elements QList < Mixer_Simple_Elem * > elems_dropped; for ( int ii=0; ii < _elem_filters.size(); ++ ii ) { _elem_filters[ii]->filter ( _mixer_elems, elems_dropped ); } // Destroy dropped elements for ( int ii=0; ii < elems_dropped.size(); ++ ii ) { destroy_mixer_elem ( elems_dropped[ii] ); } } // Handle names that occur multiple times const QString str_new ( "%1, %2" ); for ( int ii=0; ii < _mixer_elems.size(); ++ii ) { Mixer_Simple_Elem * mx_elem ( _mixer_elems[ii] ); QString str_cur ( mx_elem->display_name() ); bool dbl ( false ); // Detect if there're doubles at all for ( int jj=ii+1; jj < _mixer_elems.size(); ++jj ) { Mixer_Simple_Elem * mx_elem2 ( _mixer_elems[jj] ); if ( mx_elem2->display_name() == str_cur ) { dbl = true; break; } } // Rename doubles if ( dbl ) { for ( int jj=ii; jj < _mixer_elems.size(); ++jj ) { Mixer_Simple_Elem * mx_elem2 ( _mixer_elems[jj] ); if ( mx_elem2->display_name() == str_cur ) { QString nname ( str_new ); nname = nname.arg ( str_cur ); nname = nname.arg ( mx_elem2->elem_index() ); mx_elem2->set_display_name ( nname ); } } } } // Acquire some statistics for ( int ii=0; ii < _mixer_elems.size(); ++ii ) { Mixer_Simple_Elem * mx_elem ( _mixer_elems[ii] ); for ( unsigned int sdir = 0; sdir < 2; ++ sdir ) { bool has_vol ( mx_elem->has_volume ( sdir ) ); bool has_switch ( mx_elem->has_switch ( sdir ) ); bool has_enum ( mx_elem->has_enum ( sdir ) ); if ( has_vol ) { ++_num_elems_volume[sdir]; } else { if ( has_switch || has_enum ) { ++_num_elems_no_volume[sdir]; } } if ( has_vol || has_switch || has_enum ) { ++_num_elems_stream[sdir]; } } } return 0; } void Mixer_Simple::destroy_mixer_elem ( Mixer_Simple_Elem * elem_n ) { snd_mixer_elem_t * snd_elem ( elem_n->snd_mixer_elem() ); snd_mixer_elem_set_callback ( snd_elem, 0 ); snd_mixer_elem_set_callback_private ( snd_elem, 0 ); delete elem_n; } Mixer_Simple_Elem * Mixer_Simple::create_mixer_elem ( snd_mixer_elem_t * elem_n ) { snd_mixer_selem_id_t * elem_id; snd_mixer_selem_id_alloca ( &elem_id ); snd_mixer_selem_get_id ( elem_n, elem_id ); Mixer_Simple_Elem * mx_elem ( new Mixer_Simple_Elem ( this, snd_mixer(), elem_id ) ); mx_elem->set_display_name ( QCoreApplication::translate ( "ALSA::Elem_Name", mx_elem->elem_name() ) ); // Install alsa callbacks snd_mixer_elem_set_callback_private ( elem_n, mx_elem ); snd_mixer_elem_set_callback ( elem_n, &::QSnd::Mixer_Simple_Elem::alsa_callback_mixer_elem ); return mx_elem; } int Mixer_Simple::create_socket_notifiers ( ) { //::std::cout << "Mixer_Simple::create_socket_notifiers" << "\n"; // Setup socket notifiers { int num_fds = snd_mixer_poll_descriptors_count ( _snd_mixer ); if ( num_fds >= 0 ) { _pollfds.resize ( num_fds ); } else { _err_func = "snd_mixer_poll_descriptors_count"; _err_message = snd_error_qstring ( num_fds ); return num_fds; } } if ( _pollfds.size() > 0 ) { memset ( _pollfds.data(), 0, _pollfds.size()*sizeof ( pollfd ) ); int err = snd_mixer_poll_descriptors ( _snd_mixer, _pollfds.data(), _pollfds.size() ); if ( err < 0 ) { _err_func = "snd_mixer_poll_descriptors"; _err_message = snd_error_qstring ( err ); return err; } } for ( unsigned int ii=0; ii < _pollfds.size(); ++ii ) { int fd ( _pollfds[ii].fd ); if ( fd != 0 ) { QSocketNotifier * sn ( new QSocketNotifier ( fd, QSocketNotifier::Read, this ) ); connect ( sn, SIGNAL ( activated ( int ) ), this, SLOT ( socket_event ( int ) ) ); _socket_notifiers.append ( sn ); } } return 0; } void Mixer_Simple::set_socked_notifiers_enabled ( bool flag_n ) { for ( int ii=0; ii < _socket_notifiers.size(); ++ii ) { _socket_notifiers[ii]->setEnabled ( flag_n ); } } void Mixer_Simple::signalize_all_changes ( ) { for ( int ii=0; ii < _mixer_elems.size(); ++ii ) { _mixer_elems[ii]->signalize_changes(); } } bool Mixer_Simple::event ( QEvent * event_n ) { bool res ( true ); if ( event_n->type() == ::QSnd::evt_update_values_request ) { if ( !_update_requested ) { _update_requested = true; QCoreApplication::postEvent ( this, new QEvent ( ::QSnd::evt_update_values ) ); } } else if ( event_n->type() == ::QSnd::evt_update_values ) { _update_requested = false; signalize_all_changes(); } else if ( event_n->type() == ::QSnd::evt_reload_request ) { if ( !_reload_requested ) { _reload_requested = true; QCoreApplication::postEvent ( this, new QEvent ( ::QSnd::evt_reload ) ); } } else if ( event_n->type() == ::QSnd::evt_reload ) { _reload_requested = false; emit sig_mixer_reload_request(); } else { res = QObject::event ( event_n ); } return res; } void Mixer_Simple::socket_event ( int ) { if ( snd_mixer() != 0 ) { int num_ev ( snd_mixer_handle_events ( _snd_mixer ) ); if ( num_ev < 0 ) { // Error. Disable socket notifiers set_socked_notifiers_enabled ( false ); print_alsa_error ( "snd_mixer_handle_events ", num_ev ); } signalize_all_changes(); } } void Mixer_Simple::request_reload ( ) { QCoreApplication::postEvent ( this, new QEvent ( ::QSnd::evt_reload_request ) ); } // Alsa callbacks int Mixer_Simple::alsa_callback_mixer ( snd_mixer_t * snd_mixer_n, unsigned int mask_n, snd_mixer_elem_t * ) { int res ( 0 ); Mixer_Simple * qsnd_mixer; { void * priv ( snd_mixer_get_callback_private ( snd_mixer_n ) ); qsnd_mixer = reinterpret_cast < Mixer_Simple * > ( priv ); } if ( qsnd_mixer != 0 ) { const unsigned int change_mask ( SND_CTL_EVENT_MASK_VALUE | SND_CTL_EVENT_MASK_INFO | SND_CTL_EVENT_MASK_ADD | SND_CTL_EVENT_MASK_TLV ); if ( ( mask_n == SND_CTL_EVENT_MASK_REMOVE ) || ( ( mask_n & change_mask ) != 0 ) ) { qsnd_mixer->request_reload(); } else { { ::std::stringstream msg; msg << "Mixer_Simple::alsa_callback_mixer: "; msg << "Unknown mask ( " << mask_n << " )" << ::std::endl; ::std::cerr << msg.str(); } res = -1; } } return res; } } // End of namespace qastools-v0.22.0/shared/src/qsnd/mixer_simple.hpp000066400000000000000000000102661354534512100220460ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_qsnd_mixer_simple_hpp__ #define __INC_qsnd_mixer_simple_hpp__ #include "qsnd/alsa.hpp" #include #include #include #include // Forward declaration namespace QSnd { class Mixer_Simple_Elem; class Mixer_Simple_Filter; } namespace QSnd { /// @brief Mixer_Simple /// /// Connects ALSA simple mixer objects with Qt objects /// class Mixer_Simple : public QObject { Q_OBJECT // Public methods public: Mixer_Simple ( QObject * parent_n = 0 ); ~Mixer_Simple ( ); snd_hctl_t * snd_hctl ( ); snd_mixer_t * snd_mixer ( ); // Elements unsigned int num_elems ( ) const; /// @brief Number of elements in playback (0) or capture (1) unsigned int num_elems_stream ( unsigned int stream_dir_n ) const; /// @brief Elements with a volume unsigned int num_elems_volume ( unsigned int stream_dir_n ) const; /// @brief Elements with no volume unsigned int num_elems_no_volume ( unsigned int stream_dir_n ) const; const Mixer_Simple_Elem * elem ( unsigned int idx_n ) const; Mixer_Simple_Elem * elem ( unsigned int idx_n ); // Element filters void clear_elem_filters ( ); /// @brief Appends a new element filter /// /// The ownership of the filter is passed to the mixer. void append_elem_filter ( ::QSnd::Mixer_Simple_Filter * filter_n ); // open / close /// @brief Opens a simple mixer /// /// @return On an error a negative error code int open ( const QString & dev_name_n ); void close ( ); bool is_open ( ) const; // Error strings / codes const QString & err_func ( ) const; const QString & err_message ( ) const; // Event handling bool event ( QEvent * event_n ); // Alsa callbacks static int alsa_callback_mixer ( snd_mixer_t * snd_mixer_n, unsigned int mask_n, snd_mixer_elem_t * ); // Signals signals: void sig_mixer_reload_request ( ); // Public slots public slots: void request_reload ( ); // Private slots private slots: void socket_event ( int socket_id ); // Private methods private: // Mixer elements void clear_mixer_elems ( ); int create_mixer_elems ( ); void destroy_mixer_elem ( Mixer_Simple_Elem * elem_n ); Mixer_Simple_Elem * create_mixer_elem ( snd_mixer_elem_t * elem_n ); // Socket notifiers int create_socket_notifiers ( ); void set_socked_notifiers_enabled ( bool flag_n ); void signalize_all_changes ( ); // Private attributes private: snd_hctl_t * _snd_hctl; snd_mixer_t * _snd_mixer; QList < ::QSnd::Mixer_Simple_Elem * > _mixer_elems; ::std::vector < pollfd > _pollfds; QList < QSocketNotifier * > _socket_notifiers; // Statistics unsigned int _num_elems_stream[2]; unsigned int _num_elems_volume[2]; // Elements with a volume unsigned int _num_elems_no_volume[2]; // Elements without a volume bool _update_requested; bool _reload_requested; QString _err_func; QString _err_message; QList < ::QSnd::Mixer_Simple_Filter * > _elem_filters; }; inline bool Mixer_Simple::is_open ( ) const { return ( _snd_mixer != 0 ); } inline const QString & Mixer_Simple::err_func ( ) const { return _err_func; } inline const QString & Mixer_Simple::err_message ( ) const { return _err_message; } inline snd_hctl_t * Mixer_Simple::snd_hctl ( ) { return _snd_hctl; } inline snd_mixer_t * Mixer_Simple::snd_mixer ( ) { return _snd_mixer; } // Elements inline unsigned int Mixer_Simple::num_elems ( ) const { return _mixer_elems.size(); } inline unsigned int Mixer_Simple::num_elems_stream ( unsigned int stream_dir_n ) const { return _num_elems_stream[stream_dir_n]; } inline unsigned int Mixer_Simple::num_elems_volume ( unsigned int stream_dir_n ) const { return _num_elems_volume[stream_dir_n]; } inline unsigned int Mixer_Simple::num_elems_no_volume ( unsigned int stream_dir_n ) const { return _num_elems_no_volume[stream_dir_n]; } inline const Mixer_Simple_Elem * Mixer_Simple::elem ( unsigned int idx_n ) const { return _mixer_elems[idx_n]; } inline Mixer_Simple_Elem * Mixer_Simple::elem ( unsigned int idx_n ) { return _mixer_elems[idx_n]; } } // End of namespace #endif qastools-v0.22.0/shared/src/qsnd/mixer_simple_elem.cpp000066400000000000000000000574421354534512100230520ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "mixer_simple_elem.hpp" #include "event_types.hpp" #include #include #include #include namespace QSnd { Mixer_Simple_Elem::Mixer_Simple_Elem ( QObject * parent_n, snd_mixer_t * mixer_n, snd_mixer_selem_id_t * elem_id_n ) : QObject ( parent_n ), _snd_mixer ( mixer_n ), _values_changed ( false ) { snd_mixer_selem_id_malloc ( &_snd_mixer_selem_id ); set_snd_mixer_selem_id ( elem_id_n ); } Mixer_Simple_Elem::~Mixer_Simple_Elem ( ) { snd_mixer_selem_id_free ( _snd_mixer_selem_id ); } void Mixer_Simple_Elem::clear ( ) { _volumes_equal[0] = true; _volumes_equal[1] = true; _switches_equal[0] = true; _switches_equal[1] = true; _enums_equal[0] = true; _enums_equal[1] = true; _num_volume_channels[0] = 0; _num_volume_channels[1] = 0; _num_switch_channels[0] = 0; _num_switch_channels[1] = 0; _num_enum_channels[0] = 0; _num_enum_channels[1] = 0; _channels[0].clear(); _channels[1].clear(); _volume_min[0] = 0; _volume_min[1] = 0; _volume_max[0] = 0; _volume_max[1] = 0; _dB_min[0] = 0; _dB_min[1] = 0; _dB_max[0] = 0; _dB_max[1] = 0; _enum_num_items = 0; _enum_item_names.clear(); } unsigned int Mixer_Simple_Elem::elem_index ( ) const { unsigned int res ( 0 ); if ( snd_mixer_elem() != 0 ) { res = snd_mixer_selem_get_index ( snd_mixer_elem() ); } return res; } const char * Mixer_Simple_Elem::channel_name ( unsigned int snd_dir_n, unsigned int channel_idx_n ) const { const char * res ( 0 ); if ( channel_idx_n < _channels[snd_dir_n].size() ) { res = snd_mixer_selem_channel_name ( _channels[snd_dir_n][channel_idx_n] ); } return res; } void Mixer_Simple_Elem::set_display_name ( const QString & name_n ) { _display_name = name_n; } void Mixer_Simple_Elem::set_snd_mixer_selem_id ( snd_mixer_selem_id_t * selem_id_n ) { clear(); if ( selem_id_n == 0 ) { return; } snd_mixer_selem_id_copy ( _snd_mixer_selem_id, selem_id_n ); snd_mixer_elem_t * snd_elem = snd_mixer_elem(); if ( snd_elem == 0 ) { return; } for ( int ii=0; ii <= SND_MIXER_SCHN_LAST; ++ii ) { snd_mixer_selem_channel_id_t ch_id ( static_cast < snd_mixer_selem_channel_id_t > ( ii ) ); if ( snd_mixer_selem_has_playback_channel ( snd_elem, ch_id ) ) { _channels[0].push_back ( ch_id ); } if ( snd_mixer_selem_has_capture_channel ( snd_elem, ch_id ) ) { _channels[1].push_back ( ch_id ); } } if ( snd_mixer_selem_has_playback_volume ( snd_elem ) > 0 ) { const int snd_dir ( 0 ); if ( _channels[snd_dir].size() > 0 ) { if ( snd_mixer_selem_has_playback_volume_joined ( snd_elem ) ) { _num_volume_channels[snd_dir] = 1; } else { _num_volume_channels[snd_dir] = _channels[snd_dir].size(); } snd_mixer_selem_get_playback_volume_range ( snd_elem, &_volume_min[snd_dir], &_volume_max[snd_dir] ); int err = snd_mixer_selem_get_playback_dB_range ( snd_elem, &_dB_min[snd_dir], &_dB_max[snd_dir] ); if ( err < 0 ) { _dB_min[snd_dir] = 0; _dB_max[snd_dir] = 0; } } else { QString msg ( "[WW] %1 has a playback volume but no playback channels\n" ); msg = msg.arg ( elem_name() ); ::std::cerr << msg.toLocal8Bit().constData(); } } if ( snd_mixer_selem_has_capture_volume ( snd_elem ) > 0 ) { const int snd_dir ( 1 ); if ( _channels[snd_dir].size() > 0 ) { if ( snd_mixer_selem_has_capture_volume_joined ( snd_elem ) ) { _num_volume_channels[snd_dir] = 1; } else { _num_volume_channels[snd_dir] = _channels[snd_dir].size(); } snd_mixer_selem_get_capture_volume_range ( snd_elem, &_volume_min[snd_dir], &_volume_max[snd_dir] ); int err = snd_mixer_selem_get_capture_dB_range ( snd_elem, &_dB_min[snd_dir], &_dB_max[snd_dir] ); if ( err < 0 ) { _dB_min[snd_dir] = 0; _dB_max[snd_dir] = 0; } } else { QString msg ( "[WW] %1 has a capture volume but no capture channels\n" ); msg = msg.arg ( elem_name() ); ::std::cerr << msg.toLocal8Bit().constData(); } } if ( snd_mixer_selem_has_playback_switch ( snd_elem ) > 0 ) { const int snd_dir ( 0 ); if ( _channels[snd_dir].size() > 0 ) { if ( snd_mixer_selem_has_playback_switch_joined ( snd_elem ) ) { _num_switch_channels[snd_dir] = 1; } else { _num_switch_channels[snd_dir] = _channels[snd_dir].size(); } } else { QString msg ( "[WW] %1 has a playback switch but no playback channels\n" ); msg = msg.arg ( elem_name() ); ::std::cerr << msg.toLocal8Bit().constData(); } } if ( snd_mixer_selem_has_capture_switch ( snd_elem ) > 0 ) { const int snd_dir ( 1 ); if ( _channels[snd_dir].size() > 0 ) { if ( snd_mixer_selem_has_capture_switch_joined ( snd_elem ) ) { _num_switch_channels[snd_dir] = 1; } else { _num_switch_channels[snd_dir] = _channels[snd_dir].size(); } } else { QString msg ( "[WW] %1 has a capture switch but no capture channels\n" ); msg = msg.arg ( elem_name() ); ::std::cerr << msg.toLocal8Bit().constData(); } } // Enumerated if ( snd_mixer_selem_is_enumerated ( snd_elem ) ) { bool is_play ( snd_mixer_selem_is_enum_playback ( snd_elem ) > 0 ); bool is_cap ( snd_mixer_selem_is_enum_capture ( snd_elem ) > 0 ); if ( !( is_play || is_cap ) ) { // Workaround // Try to determine the direction from the name QString fstr ( elem_name() ); fstr = fstr.toLower(); int fidx ( fstr.indexOf ( "mic" ) ); if ( fidx < 0 ) { fidx = fstr.indexOf ( "adc " ); } if ( fidx < 0 ) { fidx = fstr.indexOf ( "capture" ); } if ( fidx < 0 ) { fidx = fstr.indexOf ( "input source" ); } if ( fidx >= 0 ) { is_cap = true; } if ( !is_cap ) { if ( _channels[0].size() > 0 ) { is_play = true; } else if ( _channels[0].size() > 0 ) { is_cap = true; } else { is_play = true; } } } // Changing the channels for broken alsa implementations if ( is_play ) { _num_enum_channels[0] = 1; _channels[0].resize ( 1, SND_MIXER_SCHN_MONO ); } if ( is_cap ) { _num_enum_channels[1] = 1; _channels[1].resize ( 1, SND_MIXER_SCHN_MONO ); } // Read enum item names const int num_items ( snd_mixer_selem_get_enum_items ( snd_elem ) ); if ( num_items > 0 ) { _enum_num_items = num_items; _enum_item_names.resize ( _enum_num_items ); const unsigned int buff_size ( 256 ); char buff[buff_size]; for ( int ii=0; ii < num_items; ++ii ) { int err = snd_mixer_selem_get_enum_item_name ( snd_elem, ii, buff_size, buff ); if ( err >= 0 ) { _enum_item_names[ii] = QCoreApplication::translate ( "ALSA::Enum_Value", buff ); } else { print_alsa_error ( "snd_mixer_selem_get_enum_item_name", err ); } } } } update_values_mark(); } // State flags bool Mixer_Simple_Elem::is_active ( ) const { return ( snd_mixer_selem_is_active ( snd_mixer_elem() ) != 0 ); } // Joined feature bool Mixer_Simple_Elem::volume_joined ( unsigned int snd_dir_n ) const { bool res ( false ); snd_mixer_elem_t * snd_elem ( snd_mixer_elem() ); if ( snd_dir_n == 0 ) { res = ( snd_mixer_selem_has_playback_volume_joined ( snd_elem ) != 0 ); } else { res = ( snd_mixer_selem_has_capture_volume_joined ( snd_elem ) != 0 ); } return res; } bool Mixer_Simple_Elem::switch_joined ( unsigned int snd_dir_n ) const { bool res ( false ); snd_mixer_elem_t * snd_elem ( snd_mixer_elem() ); if ( snd_dir_n == 0 ) { res = ( snd_mixer_selem_has_playback_switch_joined ( snd_elem ) != 0 ); } else { res = ( snd_mixer_selem_has_capture_switch_joined ( snd_elem ) != 0 ); } return res; } bool Mixer_Simple_Elem::enum_joined ( unsigned int ) const { return true; } unsigned int Mixer_Simple_Elem::num_volume_channels ( unsigned int snd_dir_n ) const { return _num_volume_channels[snd_dir_n]; } long Mixer_Simple_Elem::volume ( unsigned int snd_dir_n, unsigned int channel_idx_n ) const { long val ( 0 ); snd_mixer_elem_t * snd_elem ( snd_mixer_elem() ); if ( snd_dir_n == 0 ) { int err ( snd_mixer_selem_get_playback_volume ( snd_elem, _channels[0][channel_idx_n], &val ) ); if ( err < 0 ) { print_alsa_error ( "snd_mixer_selem_get_playback_volume", err ); } } else { int err ( snd_mixer_selem_get_capture_volume ( snd_elem, _channels[1][channel_idx_n], &val ) ); if ( err < 0 ) { print_alsa_error ( "snd_mixer_selem_get_capture_volume", err ); } } return val; } void Mixer_Simple_Elem::set_volume ( unsigned int snd_dir_n, int channel_idx_n, long volume_n ) { int err; snd_mixer_elem_t * snd_elem ( snd_mixer_elem() ); //::std::cout << "Mixer_Simple_Elem::set_volume " << volume_n << "\n"; if ( snd_dir_n == 0 ) { err = snd_mixer_selem_set_playback_volume ( snd_elem, _channels[0][channel_idx_n], volume_n ); if ( err < 0 ) { print_alsa_error ( "snd_mixer_selem_set_playback_volume", err ); } } else { err = snd_mixer_selem_set_capture_volume ( snd_elem, _channels[1][channel_idx_n], volume_n ); if ( err < 0 ) { print_alsa_error ( "snd_mixer_selem_set_capture_volume", err ); } } value_was_set(); } void Mixer_Simple_Elem::set_volume_all ( unsigned int snd_dir_n, long volume_n ) { int err; snd_mixer_elem_t * snd_elem ( snd_mixer_elem() ); //::std::cout << "Mixer_Simple_Elem::set_volume_all " << volume_n << "\n"; if ( snd_dir_n == 0 ) { err = snd_mixer_selem_set_playback_volume_all ( snd_elem, volume_n ); if ( err < 0 ) { print_alsa_error ( "snd_mixer_selem_set_playback_volume_all", err ); } } else { err = snd_mixer_selem_set_capture_volume_all ( snd_elem, volume_n ); if ( err < 0 ) { print_alsa_error ( "snd_mixer_selem_set_capture_volume_all", err ); } } value_was_set(); } void Mixer_Simple_Elem::level_volumes ( unsigned int snd_dir_n ) { const long num_volumes ( _num_volume_channels[snd_dir_n] ); if ( volumes_equal ( snd_dir_n ) || ( num_volumes < 2 ) ) { return; } snd_mixer_elem_t * snd_elem ( snd_mixer_elem() ); int ( *vol_func ) ( snd_mixer_elem_t *, snd_mixer_selem_channel_id_t, long * ); if ( snd_dir_n == 0 ) { vol_func = &snd_mixer_selem_get_playback_volume; } else { vol_func = &snd_mixer_selem_get_capture_volume; } long vol_avrg_accu ( 0 ); long vol_mod_accu ( 0 ); for ( int ii=0; ii < num_volumes; ++ii ) { long val ( 0 ); vol_func ( snd_elem, _channels[snd_dir_n][ii], &val ); long vol_mod; if ( ( val >= num_volumes ) || ( val <= (-num_volumes) ) ) { const long vol_avrg ( val / num_volumes ); vol_avrg_accu += vol_avrg; vol_mod = val; vol_mod -= vol_avrg * ( num_volumes - 1 ); // To prevent an overflow vol_mod -= vol_avrg; } else { vol_mod = val; } vol_mod_accu += vol_mod; if ( ( vol_mod_accu >= num_volumes ) || ( vol_mod_accu <= (-num_volumes) ) ) { const long vol_avrg ( vol_mod_accu / num_volumes ); vol_avrg_accu += vol_avrg; vol_mod_accu -= ( vol_avrg * num_volumes ); } } set_volume_all ( snd_dir_n, vol_avrg_accu ); } long Mixer_Simple_Elem::ask_dB_vol_nearest ( unsigned int snd_dir_n, long dB_value_n ) { long res ( 0 ); const long vol_above ( ask_dB_vol ( snd_dir_n, dB_value_n, 1 ) ); const long vol_below ( ask_dB_vol ( snd_dir_n, dB_value_n, -1 ) ); long db_above ( ask_vol_dB ( snd_dir_n, vol_above ) ); long db_below ( ask_vol_dB ( snd_dir_n, vol_below ) ); db_above = ::std::abs ( db_above - dB_value_n ); db_below = ::std::abs ( dB_value_n - db_below ); if ( db_above > db_below ) { res = vol_below; } else { res = vol_above; } return res; } long Mixer_Simple_Elem::dB_value ( unsigned int snd_dir_n, unsigned int channel_idx_n ) const { long val ( 0 ); snd_mixer_elem_t * snd_elem ( snd_mixer_elem() ); if ( snd_dir_n == 0 ) { int err ( snd_mixer_selem_get_playback_dB ( snd_elem, _channels[0][channel_idx_n], &val ) ); if ( err < 0 ) { print_alsa_error ( "snd_mixer_selem_get_playback_dB", err ); } } else { int err ( snd_mixer_selem_get_capture_dB ( snd_elem, _channels[1][channel_idx_n], &val ) ); if ( err < 0 ) { print_alsa_error ( "snd_mixer_selem_get_capture_dB", err ); } } return val; } void Mixer_Simple_Elem::set_dB ( unsigned int snd_dir_n, int channel_idx_n, long dB_val_n, int dir_n ) { snd_mixer_elem_t * snd_elem ( snd_mixer_elem() ); //::std::cout << "Mixer_Simple_Elem::set_dB " << dB_val_n << "\n"; if ( snd_dir_n == 0 ) { int err = snd_mixer_selem_set_playback_dB ( snd_elem, _channels[0][channel_idx_n], dB_val_n, dir_n ); if ( err < 0 ) { print_alsa_error ( "snd_mixer_selem_set_playback_dB", err ); } } else { int err = snd_mixer_selem_set_capture_dB ( snd_elem, _channels[1][channel_idx_n], dB_val_n, dir_n ); if ( err < 0 ) { print_alsa_error ( "snd_mixer_selem_set_capture_dB", err ); } } value_was_set(); } void Mixer_Simple_Elem::set_dB_all ( unsigned int snd_dir_n, long dB_val_n, int dir_n ) { snd_mixer_elem_t * snd_elem ( snd_mixer_elem() ); //::std::cout << "Mixer_Simple_Elem::set_dB_all " << dB_val_n << "\n"; if ( snd_dir_n == 0 ) { int err = snd_mixer_selem_set_playback_dB_all ( snd_elem, dB_val_n, dir_n ); if ( err < 0 ) { print_alsa_error ( "snd_mixer_selem_set_playback_dB_all", err ); } } else { int err = snd_mixer_selem_set_capture_dB_all ( snd_elem, dB_val_n, dir_n ); if ( err < 0 ) { print_alsa_error ( "snd_mixer_selem_set_capture_dB_all", err ); } } value_was_set(); } unsigned int Mixer_Simple_Elem::num_switch_channels ( unsigned int snd_dir_n ) const { return _num_switch_channels[snd_dir_n]; } bool Mixer_Simple_Elem::switch_state ( unsigned int snd_dir_n, unsigned int channel_idx_n ) const { int val ( 0 ); snd_mixer_elem_t * snd_elem ( snd_mixer_elem() ); if ( snd_dir_n == 0 ) { int err ( snd_mixer_selem_get_playback_switch ( snd_elem, _channels[0][channel_idx_n], &val ) ); if ( err < 0 ) { print_alsa_error ( "snd_mixer_selem_get_playback_switch", err ); } } else { int err ( snd_mixer_selem_get_capture_switch ( snd_elem, _channels[1][channel_idx_n], &val ) ); if ( err < 0 ) { print_alsa_error ( "snd_mixer_selem_get_capture_switch", err ); } } return ( val != 0 ); } void Mixer_Simple_Elem::set_switch ( unsigned int snd_dir_n, int channel_idx_n, bool state_n ) { snd_mixer_elem_t * snd_elem ( snd_mixer_elem() ); //::std::cout << "Mixer_Simple_Elem::set_switch " << state_n << "\n"; if ( snd_dir_n == 0 ) { int err = snd_mixer_selem_set_playback_switch ( snd_elem, _channels[0][channel_idx_n], state_n ); if ( err < 0 ) { print_alsa_error ( "snd_mixer_selem_set_playback_switch", err ); } } else { int err = snd_mixer_selem_set_capture_switch ( snd_elem, _channels[1][channel_idx_n], state_n ); if ( err < 0 ) { print_alsa_error ( "snd_mixer_selem_set_capture_switch", err ); } } value_was_set(); } void Mixer_Simple_Elem::set_switch_all ( unsigned int snd_dir_n, bool state_n ) { snd_mixer_elem_t * snd_elem ( snd_mixer_elem() ); //::std::cout << "Mixer_Simple_Elem::set_switch_all " << state_n << "\n"; if ( snd_dir_n == 0 ) { int err = snd_mixer_selem_set_playback_switch_all ( snd_elem, state_n ); if ( err < 0 ) { print_alsa_error ( "snd_mixer_selem_set_playback_switch_all", err ); } } else { int err = snd_mixer_selem_set_capture_switch_all ( snd_elem, state_n ); if ( err < 0 ) { print_alsa_error ( "snd_mixer_selem_set_capture_switch_all", err ); } } value_was_set(); } void Mixer_Simple_Elem::invert_switches ( unsigned int snd_dir_n ) { snd_mixer_elem_t * snd_elem ( snd_mixer_elem() ); if ( snd_dir_n == 0 ) { for ( unsigned int cii=0; cii < _num_switch_channels[0]; ++cii ) { int err = snd_mixer_selem_set_playback_switch ( snd_elem, _channels[0][cii], !switch_state ( 0, cii ) ); if ( err < 0 ) { print_alsa_error ( "snd_mixer_selem_set_playback_switch", err ); } } } else { for ( unsigned int cii=0; cii < _num_switch_channels[1]; ++cii ) { int err = snd_mixer_selem_set_capture_switch ( snd_elem, _channels[1][cii], !switch_state ( 1, cii ) ); if ( err < 0 ) { print_alsa_error ( "snd_mixer_selem_set_capture_switch", err ); } } } value_was_set(); } void Mixer_Simple_Elem::level_switches ( unsigned int snd_dir_n ) { const unsigned int num_switches ( _num_switch_channels[snd_dir_n] ); if ( switches_equal ( snd_dir_n ) || ( num_switches < 2 ) ) { return; } unsigned int num_on ( 0 ); unsigned int num_off ( 0 ); { snd_mixer_elem_t * snd_elem ( snd_mixer_elem() ); int ( *state_func ) ( snd_mixer_elem_t *, snd_mixer_selem_channel_id_t, int * ); if ( snd_dir_n == 0 ) { state_func = &snd_mixer_selem_get_playback_switch; } else { state_func = &snd_mixer_selem_get_capture_switch; } for ( unsigned int ii=0; ii < num_switches; ++ii ) { int val ( 0 ); state_func ( snd_elem, _channels[snd_dir_n][ii], &val ); if ( val != 0 ) { ++num_on; } else { ++num_off; } } } set_switch_all ( snd_dir_n, ( num_on >= num_off ) ); } unsigned int Mixer_Simple_Elem::num_enum_channels ( unsigned int snd_dir_n ) const { return _num_enum_channels[snd_dir_n]; } unsigned int Mixer_Simple_Elem::enum_index ( unsigned int snd_dir_n, unsigned int channel_idx_n ) const { unsigned int val ( 0 ); snd_mixer_elem_t * snd_elem ( snd_mixer_elem() ); int err ( snd_mixer_selem_get_enum_item ( snd_elem, _channels[snd_dir_n][channel_idx_n], &val ) ); if ( err < 0 ) { print_alsa_error ( "snd_mixer_selem_get_enum_item", err ); } return val; } void Mixer_Simple_Elem::set_enum_index ( unsigned int snd_dir_n, int channel_idx_n, unsigned int index_n ) { snd_mixer_elem_t * snd_elem ( snd_mixer_elem() ); //::std::cout << "Mixer_Simple_Elem::set_enum_index " << index_n << "\n"; int err = snd_mixer_selem_set_enum_item ( snd_elem, _channels[snd_dir_n][channel_idx_n], index_n ); if ( err < 0 ) { print_alsa_error ( "snd_mixer_selem_set_enum_item", err ); } value_was_set(); } void Mixer_Simple_Elem::set_enum_index_all ( unsigned int snd_dir_n, unsigned int index_n ) { snd_mixer_elem_t * snd_elem ( snd_mixer_elem() ); //::std::cout << "Mixer_Simple_Elem::set_enum_index_all " << index_n << "\n"; for ( unsigned int ii=0; ii < _num_enum_channels[snd_dir_n]; ++ii ) { int err = snd_mixer_selem_set_enum_item ( snd_elem, _channels[snd_dir_n][ii], index_n ); if ( err < 0 ) { print_alsa_error ( "snd_mixer_selem_set_enum_item", err ); } } value_was_set(); } void Mixer_Simple_Elem::value_was_set ( ) { // Read values back update_values_mark(); if ( parent() != 0 ) { QEvent ev_req ( ::QSnd::evt_update_values_request ); QCoreApplication::sendEvent ( parent(), &ev_req ); } } void Mixer_Simple_Elem::update_values ( ) { snd_mixer_elem_t * snd_elem = snd_mixer_elem(); if ( snd_elem == 0 ) { return; } //::std::cout << "Mixer_Simple_Elem::update_mixer_values" << "\n"; // Playback volume equality if ( _num_volume_channels[0] > 1 ) { const Channel_Buffer & chs ( _channels[0] ); bool vols_equal ( false ); long val_first ( 0 ); int err ( snd_mixer_selem_get_playback_volume ( snd_elem, chs[0], &val_first ) ); if ( err == 0 ) { vols_equal = true; const unsigned int num_ch ( _num_volume_channels[0] ); for ( unsigned int ii=1; ii < num_ch; ++ii ) { long val ( 0 ); err = snd_mixer_selem_get_playback_volume ( snd_elem, chs[ii], &val ); if ( ( err < 0 ) || ( val != val_first ) ) { vols_equal = false; break; } } } _volumes_equal[0] = vols_equal; } // Capture volume equality if ( _num_volume_channels[1] > 1 ) { const Channel_Buffer & chs ( _channels[1] ); bool vols_equal ( false ); long val_first ( 0 ); int err ( snd_mixer_selem_get_capture_volume ( snd_elem, chs[0], &val_first ) ); if ( err == 0 ) { vols_equal = true; const unsigned int num_ch ( _num_volume_channels[1] ); for ( unsigned int ii=1; ii < num_ch; ++ii ) { long val ( 0 ); err = snd_mixer_selem_get_capture_volume ( snd_elem, chs[ii], &val ); if ( ( err < 0 ) || ( val != val_first ) ) { vols_equal = false; break; } } } _volumes_equal[1] = vols_equal; } // Playback switch equality if ( _num_switch_channels[0] > 1 ) { const Channel_Buffer & chs ( _channels[0] ); bool states_equal ( false ); int state_first ( 0 ); int err ( snd_mixer_selem_get_playback_switch ( snd_elem, chs[0], &state_first ) ); if ( err == 0 ) { states_equal = true; const unsigned int num_ch ( _num_switch_channels[0] ); for ( unsigned int ii=1; ii < num_ch; ++ii ) { int state ( 0 ); err = snd_mixer_selem_get_playback_switch ( snd_elem, chs[ii], &state ); if ( ( err < 0 ) || ( state != state_first ) ) { states_equal = false; break; } } } _switches_equal[0] = states_equal; } // Capture switch equality if ( _num_switch_channels[1] > 1 ) { const Channel_Buffer & chs ( _channels[1] ); bool states_equal ( false ); int state_first ( 0 ); int err ( snd_mixer_selem_get_capture_switch ( snd_elem, chs[0], &state_first ) ); if ( err == 0 ) { states_equal = true; const unsigned int num_ch ( _num_switch_channels[1] ); for ( unsigned int ii=1; ii < num_ch; ++ii ) { int state ( 0 ); err = snd_mixer_selem_get_capture_switch ( snd_elem, chs[ii], &state ); if ( ( err < 0 ) || ( state != state_first ) ) { states_equal = false; break; } } } _switches_equal[1] = states_equal; } // Playback enum equality if ( _num_enum_channels[0] > 1 ) { const Channel_Buffer & chs ( _channels[0] ); bool indices_equal ( false ); unsigned int idx_first ( 0 ); int err ( snd_mixer_selem_get_enum_item ( snd_elem, chs[0], &idx_first ) ); if ( err == 0 ) { indices_equal = true; const unsigned int num_ch ( _num_enum_channels[0] ); for ( unsigned int ii=1; ii < num_ch; ++ii ) { unsigned int idx ( 0 ); err = snd_mixer_selem_get_enum_item ( snd_elem, chs[ii], &idx ); if ( ( err < 0 ) || ( idx != idx_first ) ) { indices_equal = false; break; } } } _enums_equal[0] = indices_equal; } // Capture enum equality if ( _num_enum_channels[1] > 1 ) { const Channel_Buffer & chs ( _channels[1] ); bool indices_equal ( false ); unsigned int idx_first ( 0 ); int err ( snd_mixer_selem_get_enum_item ( snd_elem, chs[0], &idx_first ) ); if ( err == 0 ) { indices_equal = true; const unsigned int num_ch ( _num_enum_channels[1] ); for ( unsigned int ii=1; ii < num_ch; ++ii ) { unsigned int idx ( 0 ); err = snd_mixer_selem_get_enum_item ( snd_elem, chs[ii], &idx ); if ( ( err < 0 ) || ( idx != idx_first ) ) { indices_equal = false; break; } } } _enums_equal[1] = indices_equal; } } void Mixer_Simple_Elem::update_values_mark ( ) { _values_changed = true; update_values(); } void Mixer_Simple_Elem::signalize_changes ( ) { if ( _values_changed ) { _values_changed = false; emit sig_values_changed(); } } void Mixer_Simple_Elem::signalize_element_changed ( ) { if ( parent() != 0 ) { QEvent ev_req ( ::QSnd::evt_reload_request ); QCoreApplication::sendEvent ( parent(), &ev_req ); } } // Alsa callbacks int Mixer_Simple_Elem::alsa_callback_mixer_elem ( snd_mixer_elem_t * elem_n, unsigned int mask_n ) { int res ( 0 ); Mixer_Simple_Elem * smse; { void * priv ( snd_mixer_elem_get_callback_private ( elem_n ) ); smse = reinterpret_cast < Mixer_Simple_Elem * > ( priv ); } if ( smse != 0 ) { const unsigned int change_mask ( SND_CTL_EVENT_MASK_INFO | SND_CTL_EVENT_MASK_ADD | SND_CTL_EVENT_MASK_TLV ); if ( ( mask_n == SND_CTL_EVENT_MASK_REMOVE ) || ( ( mask_n & change_mask ) != 0 ) ) { smse->signalize_element_changed(); } else if ( ( mask_n & SND_CTL_EVENT_MASK_VALUE ) != 0 ) { smse->update_values_mark(); } else { // Unusual mask { ::std::stringstream msg; msg << "Mixer_Simple_Elem::alsa_callback_mixer_elem: "; msg << "Unknown mask ( " << mask_n << " )" << ::std::endl; ::std::cerr << msg.str(); } res = -1; } } return res; } } // End of namespace qastools-v0.22.0/shared/src/qsnd/mixer_simple_elem.hpp000066400000000000000000000207321354534512100230470ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_qsnd_mixer_simple_elem_hpp__ #define __INC_qsnd_mixer_simple_elem_hpp__ #include "qsnd/alsa.hpp" #include #include #include namespace QSnd { /// @brief Mixer_Simple_Elem /// /// Connects an ALSA simple mixer element with Qt /// class Mixer_Simple_Elem : public QObject { Q_OBJECT // Public typedefs public: typedef std::vector < snd_mixer_selem_channel_id_t > Channel_Buffer; typedef std::vector < QString > Enum_Names_Buffer; // Public methods public: Mixer_Simple_Elem ( QObject * parent_n = 0, snd_mixer_t * mixer_n = 0, snd_mixer_selem_id_t * elem_id_n = 0 ); ~Mixer_Simple_Elem ( ); void clear ( ); // Alsa snd_mixer snd_mixer_t * snd_mixer ( ) const; void set_snd_mixer ( snd_mixer_t * mixer_n ); // Alsa set_snd_mixer_selem_id void set_snd_mixer_selem_id ( snd_mixer_selem_id_t * selem_id_n ); snd_mixer_selem_id_t * snd_mixer_selem_id ( ) const; // Alsa snd_mixer_elem_t snd_mixer_elem_t * snd_mixer_elem ( ) const; const QString & display_name ( ) const; void set_display_name ( const QString & name_n ); const char * elem_name ( ) const; unsigned int elem_index ( ) const; unsigned int num_channels ( unsigned int snd_dir_n ) const; snd_mixer_selem_channel_id_t channel ( unsigned int snd_dir_n, unsigned int channel_idx_n ) const; const char * channel_name ( unsigned int snd_dir_n, unsigned int channel_idx_n ) const; // Availability bool has_volume ( unsigned int snd_dir_n ) const; bool has_dB ( unsigned int snd_dir_n ) const; bool has_switch ( unsigned int snd_dir_n ) const; bool has_enum ( unsigned int snd_dir_n ) const; // State flags bool is_active ( ) const; // Joined feature bool volume_joined ( unsigned int snd_dir_n ) const; bool switch_joined ( unsigned int snd_dir_n ) const; bool enum_joined ( unsigned int snd_dir_n ) const; // Equality bool volumes_equal ( unsigned int snd_dir_n ) const; bool switches_equal ( unsigned int snd_dir_n ) const; bool enums_equal ( unsigned int snd_dir_n ) const; // Volume unsigned int num_volume_channels ( unsigned int snd_dir_n ) const; long volume ( unsigned int snd_dir_n, unsigned int channel_idx_n ) const; long volume_min ( unsigned int snd_dir_n ) const; long volume_max ( unsigned int snd_dir_n ) const; // Decibel long dB_value ( unsigned int snd_dir_n, unsigned int channel_idx_n ) const; long dB_min ( unsigned int snd_dir_n ) const; long dB_max ( unsigned int snd_dir_n ) const; long ask_dB_vol ( unsigned int snd_dir_n, long dB_value_n, int dir_n = -1 ); long ask_vol_dB ( unsigned int snd_dir_n, long volume_n ); long ask_dB_vol_nearest ( unsigned int snd_dir_n, long dB_value_n ); // Switch unsigned int num_switch_channels ( unsigned int snd_dir_n ) const; bool switch_state ( unsigned int snd_dir_n, unsigned int channel_idx_n ) const; // Enumerated unsigned int num_enum_channels ( unsigned int snd_dir_n ) const; unsigned int enum_index ( unsigned int snd_dir_n, unsigned int channel_idx_n ) const; unsigned int enum_num_items ( ) const; const Enum_Names_Buffer & enum_item_names ( ) const; // Volume setting void set_volume ( unsigned int snd_dir_n, int channel_idx_n, long volume_n ); void set_volume_all ( unsigned int snd_dir_n, long volume_n ); void level_volumes ( unsigned int snd_dir_n ); // Decibel setting void set_dB ( unsigned int snd_dir_n, int channel_idx_n, long dB_val_n, int dir_n = -1 ); void set_dB_all ( unsigned int snd_dir_n, long dB_val_n, int dir_n = -1 ); // Switch setting void set_switch ( unsigned int snd_dir_n, int channel_idx_n, bool index_n ); void set_switch_all ( unsigned int snd_dir_n, bool index_n ); void invert_switches ( unsigned int snd_dir_n ); void level_switches ( unsigned int snd_dir_n ); // Enum setting void set_enum_index ( unsigned int snd_dir_n, int channel_idx_n, unsigned int index_n ); void set_enum_index_all ( unsigned int snd_dir_n, unsigned int index_n ); /// @brief Reads all values from alsa void update_values ( ); // Callback methods /// @brief Reads all values from alsa and marks a change void update_values_mark ( ); void signalize_changes ( ); /// @brief Signalizes the parent that this element changed void signalize_element_changed ( ); // Alsa callbacks static int alsa_callback_mixer_elem ( snd_mixer_elem_t * elem_n, unsigned int mask_n ); // Signals signals: /// @brief Gets emitted when values changed void sig_values_changed ( ); // Protected methods protected: void value_was_set ( ); // Private attributes private: snd_mixer_t * _snd_mixer; snd_mixer_selem_id_t * _snd_mixer_selem_id; QString _display_name; bool _values_changed; bool _volumes_equal[2]; bool _switches_equal[2]; bool _enums_equal[2]; unsigned int _num_volume_channels[2]; unsigned int _num_switch_channels[2]; unsigned int _num_enum_channels[2]; Channel_Buffer _channels[2]; long _volume_min[2]; long _volume_max[2]; long _dB_min[2]; long _dB_max[2]; unsigned int _enum_num_items; Enum_Names_Buffer _enum_item_names; }; inline snd_mixer_t * Mixer_Simple_Elem::snd_mixer ( ) const { return _snd_mixer; } inline snd_mixer_selem_id_t * Mixer_Simple_Elem::snd_mixer_selem_id ( ) const { return _snd_mixer_selem_id; } inline snd_mixer_elem_t * Mixer_Simple_Elem::snd_mixer_elem ( ) const { return snd_mixer_find_selem ( snd_mixer(), snd_mixer_selem_id() ); } inline void Mixer_Simple_Elem::set_snd_mixer ( snd_mixer_t * mixer_n ) { _snd_mixer = mixer_n; } inline const QString & Mixer_Simple_Elem::display_name ( ) const { return _display_name; } inline const char * Mixer_Simple_Elem::elem_name ( ) const { return snd_mixer_selem_get_name ( snd_mixer_elem() ); } inline snd_mixer_selem_channel_id_t Mixer_Simple_Elem::channel ( unsigned int snd_dir_n, unsigned int channel_idx_n ) const { return _channels[snd_dir_n][channel_idx_n]; } inline unsigned int Mixer_Simple_Elem::num_channels ( unsigned int snd_dir_n ) const { return _channels[snd_dir_n].size(); } // Availability inline bool Mixer_Simple_Elem::has_volume ( unsigned int snd_dir_n ) const { return ( _num_volume_channels[snd_dir_n] > 0 ); } inline bool Mixer_Simple_Elem::has_dB ( unsigned int snd_dir_n ) const { return ( _dB_min[snd_dir_n] != _dB_max[snd_dir_n] ); } inline bool Mixer_Simple_Elem::has_switch ( unsigned int snd_dir_n ) const { return ( _num_switch_channels[snd_dir_n] > 0 ); } inline bool Mixer_Simple_Elem::has_enum ( unsigned int snd_dir_n ) const { return ( _num_enum_channels[snd_dir_n] > 0 ); } // Equality inline bool Mixer_Simple_Elem::volumes_equal ( unsigned int snd_dir_n ) const { return _volumes_equal[snd_dir_n]; } inline bool Mixer_Simple_Elem::switches_equal ( unsigned int snd_dir_n ) const { return _switches_equal[snd_dir_n]; } inline bool Mixer_Simple_Elem::enums_equal ( unsigned int snd_dir_n ) const { return _enums_equal[snd_dir_n]; } inline long Mixer_Simple_Elem::volume_min ( unsigned int snd_dir_n ) const { return _volume_min[snd_dir_n]; } inline long Mixer_Simple_Elem::volume_max ( unsigned int snd_dir_n ) const { return _volume_max[snd_dir_n]; } inline long Mixer_Simple_Elem::dB_min ( unsigned int snd_dir_n ) const { return _dB_min[snd_dir_n]; } inline long Mixer_Simple_Elem::dB_max ( unsigned int snd_dir_n ) const { return _dB_max[snd_dir_n]; } inline long Mixer_Simple_Elem::ask_dB_vol ( unsigned int snd_dir_n, long dB_value_n, int dir_n ) { long res ( 0 ); if ( snd_dir_n == 0 ) { snd_mixer_selem_ask_playback_dB_vol ( snd_mixer_elem(), dB_value_n, dir_n, &res ); } else { snd_mixer_selem_ask_capture_dB_vol ( snd_mixer_elem(), dB_value_n, dir_n, &res ); } return res; } inline long Mixer_Simple_Elem::ask_vol_dB ( unsigned int snd_dir_n, long volume_n ) { long res ( 0 ); if ( snd_dir_n == 0 ) { snd_mixer_selem_ask_playback_vol_dB ( snd_mixer_elem(), volume_n, &res ); } else { snd_mixer_selem_ask_capture_vol_dB ( snd_mixer_elem(), volume_n, &res ); } return res; } inline unsigned int Mixer_Simple_Elem::enum_num_items ( ) const { return _enum_num_items; } inline const Mixer_Simple_Elem::Enum_Names_Buffer & Mixer_Simple_Elem::enum_item_names ( ) const { return _enum_item_names; } } // End of namespace #endif qastools-v0.22.0/shared/src/qsnd/mixer_simple_filter.cpp000066400000000000000000000004271354534512100234040ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "mixer_simple_filter.hpp" namespace QSnd { Mixer_Simple_Filter::Mixer_Simple_Filter ( ) { } Mixer_Simple_Filter::~Mixer_Simple_Filter ( ) { } } // End of namespace qastools-v0.22.0/shared/src/qsnd/mixer_simple_filter.hpp000066400000000000000000000014041354534512100234050ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_mixer_simple_filter_hpp__ #define __INC_mixer_simple_filter_hpp__ #include // Forward declaration namespace QSnd { class Mixer_Simple_Elem; } namespace QSnd { /// @brief Mixer_Simple_Filter /// /// Filters mixer elements from a list /// class Mixer_Simple_Filter { // Public methods public: Mixer_Simple_Filter ( ); virtual ~Mixer_Simple_Filter ( ); /// @brief Filters certain elements from accent_n to drop_n /// /// @return The number of dropped elements virtual unsigned int filter ( QList < ::QSnd::Mixer_Simple_Elem * > & accept_n, QList < ::QSnd::Mixer_Simple_Elem * > & drop_n ) = 0; }; } // End of namespace #endif qastools-v0.22.0/shared/src/qsnd/mixer_simple_filter_name.cpp000066400000000000000000000032341354534512100244030ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "mixer_simple_filter_name.hpp" #include "qsnd/mixer_simple_elem.hpp" #include namespace QSnd { Mixer_Simple_Filter_Name::Mixer_Simple_Filter_Name ( bool blacklist_n ) : _blacklist ( blacklist_n ) { } Mixer_Simple_Filter_Name::~Mixer_Simple_Filter_Name ( ) { } void Mixer_Simple_Filter_Name::set_blacklist ( bool flag_n ) { _blacklist = flag_n; } void Mixer_Simple_Filter_Name::append_name ( const QString & name_n ) { _names.append ( name_n ); } void Mixer_Simple_Filter_Name::append_names ( const QList < QString > & names_n ) { _names.append ( names_n ); } unsigned int Mixer_Simple_Filter_Name::filter ( QList < ::QSnd::Mixer_Simple_Elem * > & accept_n, QList < ::QSnd::Mixer_Simple_Elem * > & drop_n ) { unsigned int cnt ( 0 ); if ( _names.size() > 0 ) { int aii ( 0 ); while ( aii < accept_n.size() ) { bool match ( false ); ::QSnd::Mixer_Simple_Elem * elem ( accept_n[aii] ); if ( elem != 0 ) { // Compare all names for ( int dii=0; dii < _names.size(); ++dii ) { const QString & cmp_str ( _names[dii] ); if ( ::QString::compare ( cmp_str, elem->elem_name(), Qt::CaseInsensitive ) == 0 ) { match = true; } else if ( ::QString::compare ( cmp_str, elem->display_name(), Qt::CaseInsensitive ) == 0 ) { match = true; } if ( match ) { break; } } } if ( match == blacklist() ) { // Drop element accept_n.removeAt ( aii ); drop_n.append ( elem ); ++cnt; } else { ++aii ; } } } return cnt; } } // End of namespace qastools-v0.22.0/shared/src/qsnd/mixer_simple_filter_name.hpp000066400000000000000000000021631354534512100244100ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_qsnd_mixer_simple_filter_name_hpp__ #define __INC_qsnd_mixer_simple_filter_name_hpp__ #include "qsnd/mixer_simple_filter.hpp" namespace QSnd { /// @brief Mixer_Simple_Filter /// /// Filters mixer elements from a list by their name /// class Mixer_Simple_Filter_Name : public ::QSnd::Mixer_Simple_Filter { // Public methods public: Mixer_Simple_Filter_Name ( bool blacklist_n = true ); virtual ~Mixer_Simple_Filter_Name ( ); /// @brief true if this is a blacklist. false if it is a whitelist. /// bool blacklist ( ) const; void set_blacklist ( bool flag_n ); void append_name ( const QString & name_n ); void append_names ( const QList < QString > & names_n ); unsigned int filter ( QList < ::QSnd::Mixer_Simple_Elem * > & accept_n, QList < ::QSnd::Mixer_Simple_Elem * > & drop_n ); // Private attributes private: QList < QString > _names; bool _blacklist; }; inline bool Mixer_Simple_Filter_Name::blacklist ( ) const { return _blacklist; } } // End of namespace #endif qastools-v0.22.0/shared/src/qsnd/model_keys.hpp000066400000000000000000000011011354534512100214700ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_qsnd_model_keys_hpp__ #define __INC_qsnd_model_keys_hpp__ #include namespace QSnd { static const unsigned int MKEY_DB_INDEX ( Qt::UserRole + 1 ); static const unsigned int MKEY_L10N_ARGS ( Qt::UserRole + 3 ); static const unsigned int MKEY_CARD_INDEX ( Qt::UserRole + 10 ); static const unsigned int MKEY_CARD_NAME ( Qt::UserRole + 11 ); static const unsigned int MKEY_CARD_MIXER_NAME ( Qt::UserRole + 12 ); } // End of namespace #endif qastools-v0.22.0/shared/src/qsnd/pcm_device_info.cpp000066400000000000000000000026301354534512100224510ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "pcm_device_info.hpp" #include namespace QSnd { PCM_Device_Info::PCM_Device_Info ( ) { clear(); } void PCM_Device_Info::clear ( ) { _dev_index = -1; _dev_id.clear(); _dev_name.clear(); _sdevs_info[0].clear(); _sdevs_info[1].clear(); } int PCM_Device_Info::acquire_device_info ( snd_ctl_t * snd_ctl_handle_n, int device_idx_n ) { int err ( 0 ); clear(); if ( snd_ctl_handle_n == 0 ) { return -1; } _dev_index = device_idx_n; snd_pcm_info_t * pcm_info; snd_pcm_info_alloca ( &pcm_info ); // Read Playback info snd_pcm_info_set_device ( pcm_info, _dev_index ); snd_pcm_info_set_subdevice ( pcm_info, 0 ); snd_pcm_info_set_stream ( pcm_info, SND_PCM_STREAM_PLAYBACK ); err = snd_ctl_pcm_info ( snd_ctl_handle_n, pcm_info ); if ( err < 0 ) { snd_pcm_info_set_device ( pcm_info, _dev_index ); snd_pcm_info_set_subdevice ( pcm_info, 0 ); snd_pcm_info_set_stream ( pcm_info, SND_PCM_STREAM_CAPTURE ); } err = snd_ctl_pcm_info ( snd_ctl_handle_n, pcm_info ); if ( err >= 0 ) { _dev_id = snd_pcm_info_get_id ( pcm_info ); _dev_name = snd_pcm_info_get_name ( pcm_info ); for ( unsigned int ii=0; ii < 2; ++ii ) { _sdevs_info[ii].acquire_subdevices ( snd_ctl_handle_n, _dev_index, ii ); } } if ( err < 0 ) { clear(); } return err; } } // End of namespace qastools-v0.22.0/shared/src/qsnd/pcm_device_info.hpp000066400000000000000000000023641354534512100224620ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_qsnd_pcm_device_info_hpp__ #define __INC_qsnd_pcm_device_info_hpp__ #include "qsnd/alsa.hpp" #include "qsnd/pcm_subdevices_info.hpp" #include #include namespace QSnd { /// @brief PCM_Device_Info /// class PCM_Device_Info { // Public methods public: PCM_Device_Info ( ); int dev_index ( ) const; const QString & dev_id ( ) const; const QString & dev_name ( ) const; const ::QSnd::PCM_Subdevices_Info & subdevices_info ( unsigned int idx_n ) const; void clear ( ); int acquire_device_info ( snd_ctl_t * snd_ctl_handle, int device_idx_n ); // Private attributes private: int _dev_index; QString _dev_id; QString _dev_name; ::QSnd::PCM_Subdevices_Info _sdevs_info[2]; }; inline int PCM_Device_Info::dev_index ( ) const { return _dev_index; } inline const QString & PCM_Device_Info::dev_id ( ) const { return _dev_id; } inline const QString & PCM_Device_Info::dev_name ( ) const { return _dev_name; } inline const ::QSnd::PCM_Subdevices_Info & PCM_Device_Info::subdevices_info ( unsigned int stream_dir_n ) const { return _sdevs_info[stream_dir_n]; } } // End of namespace #endif qastools-v0.22.0/shared/src/qsnd/pcm_subdevice_info.cpp000066400000000000000000000011151354534512100231600ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "pcm_subdevice_info.hpp" #include namespace QSnd { PCM_Subdevice_Info::PCM_Subdevice_Info ( snd_pcm_info_t * pcm_info_n ) { acquire_info ( pcm_info_n ); } int PCM_Subdevice_Info::acquire_info ( snd_pcm_info_t * pcm_info_n ) { if ( pcm_info_n != 0 ) { _dev_index = snd_pcm_info_get_subdevice ( pcm_info_n ); _dev_name = snd_pcm_info_get_subdevice_name ( pcm_info_n ); } else { _dev_index = 0; _dev_name.clear(); } return 0; } } // End of namespace qastools-v0.22.0/shared/src/qsnd/pcm_subdevice_info.hpp000066400000000000000000000014271354534512100231730ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_qsnd_pcm_subdevice_info_hpp__ #define __INC_qsnd_pcm_subdevice_info_hpp__ #include "qsnd/alsa.hpp" #include namespace QSnd { /// @brief PCM_Subdevice_Info /// class PCM_Subdevice_Info { // Public methods public: PCM_Subdevice_Info ( snd_pcm_info_t * pcm_info_n = 0 ); int dev_idx ( ) const; const QString & dev_name ( ) const; int acquire_info ( snd_pcm_info_t * pcm_info_n ); // Private attributes private: int _dev_index; QString _dev_name; }; inline int PCM_Subdevice_Info::dev_idx ( ) const { return _dev_index; } inline const QString & PCM_Subdevice_Info::dev_name ( ) const { return _dev_name; } } // End of namespace #endif qastools-v0.22.0/shared/src/qsnd/pcm_subdevices_info.cpp000066400000000000000000000034451354534512100233530ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "pcm_subdevices_info.hpp" #include namespace QSnd { PCM_Subdevices_Info::PCM_Subdevices_Info ( ) : _stream_dir ( 0 ), _num_sdevs ( 0 ), _num_sdevs_avail ( 0 ) { } PCM_Subdevices_Info::~PCM_Subdevices_Info ( ) { clear(); } void PCM_Subdevices_Info::clear ( ) { _stream_dir = 0; _num_sdevs = 0; _num_sdevs_avail = 0; if ( _sdevs_info.size() > 0 ) { for ( int ii = 0; ii < _sdevs_info.size(); ++ii ) { delete _sdevs_info[ii]; } _sdevs_info.clear(); } } int PCM_Subdevices_Info::acquire_subdevices ( snd_ctl_t * snd_ctl_handle_n, int dev_idx_n, unsigned int stream_dir_n ) { int err ( 0 ); clear(); _stream_dir = stream_dir_n; snd_pcm_stream_t pcm_stream ( SND_PCM_STREAM_PLAYBACK ); if ( _stream_dir > 0 ) { pcm_stream = SND_PCM_STREAM_CAPTURE; } snd_pcm_info_t * pcm_info; snd_pcm_info_alloca ( &pcm_info ); snd_pcm_info_set_device ( pcm_info, dev_idx_n ); snd_pcm_info_set_subdevice ( pcm_info, 0 ); snd_pcm_info_set_stream ( pcm_info, pcm_stream ); err = snd_ctl_pcm_info ( snd_ctl_handle_n, pcm_info ); if ( err >= 0 ) { _num_sdevs = snd_pcm_info_get_subdevices_count ( pcm_info ); _num_sdevs_avail = snd_pcm_info_get_subdevices_avail ( pcm_info ); // Read subdevices info for ( unsigned int ii=0; ii < _num_sdevs; ++ii ) { snd_pcm_info_set_device ( pcm_info, dev_idx_n ); snd_pcm_info_set_subdevice ( pcm_info, ii ); snd_pcm_info_set_stream ( pcm_info, pcm_stream ); PCM_Subdevice_Info * sdev_info ( new PCM_Subdevice_Info ); err = snd_ctl_pcm_info ( snd_ctl_handle_n, pcm_info ); if ( err >= 0 ) { sdev_info->acquire_info ( pcm_info ); } _sdevs_info.append ( sdev_info ); } } return err; } } // End of namespace qastools-v0.22.0/shared/src/qsnd/pcm_subdevices_info.hpp000066400000000000000000000026231354534512100233550ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_qsnd_pcm_subdevices_info_hpp__ #define __INC_qsnd_pcm_subdevices_info_hpp__ #include "qsnd/alsa.hpp" #include "qsnd/pcm_subdevice_info.hpp" #include #include namespace QSnd { /// @brief PCM_Subdevices_Info /// class PCM_Subdevices_Info { // Public methods public: PCM_Subdevices_Info ( ); ~PCM_Subdevices_Info ( ); unsigned int stream_dir ( ) const; unsigned int num_subdevices ( ) const; unsigned int num_subdevices_avail ( ) const; const PCM_Subdevice_Info * subdevice_info ( unsigned int idx_n ) const; void clear ( ); int acquire_subdevices ( snd_ctl_t * snd_ctl_handle_n, int dev_idx_n, unsigned int stream_dir_n ); // Private attributes private: unsigned int _stream_dir; unsigned int _num_sdevs; unsigned int _num_sdevs_avail; QList < ::QSnd::PCM_Subdevice_Info * > _sdevs_info; }; inline unsigned int PCM_Subdevices_Info::stream_dir ( ) const { return _stream_dir; } inline unsigned int PCM_Subdevices_Info::num_subdevices ( ) const { return _num_sdevs; } inline unsigned int PCM_Subdevices_Info::num_subdevices_avail ( ) const { return _num_sdevs_avail; } inline const ::QSnd::PCM_Subdevice_Info * PCM_Subdevices_Info::subdevice_info ( unsigned int idx_n ) const { return _sdevs_info[idx_n]; } } // End of namespace #endif qastools-v0.22.0/shared/src/qsnd/udev_device_lookout.cpp000066400000000000000000000056701354534512100234050ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "udev_device_lookout.hpp" #include #include #include namespace QSnd { UDev_Device_Lookout::UDev_Device_Lookout ( QObject * parent_n ) : QObject ( parent_n ), _udev ( 0 ), _udev_mon ( 0 ) { udev_init(); } UDev_Device_Lookout::~UDev_Device_Lookout ( ) { udev_close(); } void UDev_Device_Lookout::udev_init ( ) { // Init udev if ( _udev == 0 ) { _udev = ::udev_new(); if ( _udev == 0 ) { { ::std::stringstream msg; msg << "Could not create udev object" << ::std::endl; ::std::cout << msg.str() << ::std::flush; } } else { _udev_mon = ::udev_monitor_new_from_netlink ( _udev, "udev" ); if ( _udev_mon == 0 ) { { ::std::stringstream msg; msg << "Could not create udev monitor object"; msg << ::std::endl; ::std::cout << msg.str() << ::std::flush; } udev_close(); } else { ::udev_monitor_filter_add_match_subsystem_devtype ( _udev_mon, "sound", 0 ); ::udev_monitor_enable_receiving ( _udev_mon ); // Socket notifier { QSocketNotifier * socknot ( new QSocketNotifier ( ::udev_monitor_get_fd ( _udev_mon ), QSocketNotifier::Read, this ) ); connect ( socknot, SIGNAL ( activated ( int ) ), this, SLOT ( udev_process() ) ); } } } } } void UDev_Device_Lookout::udev_close ( ) { if ( _udev != 0 ) { if ( _udev_mon != 0 ) { ::udev_monitor_unref ( _udev_mon ); _udev_mon = 0; } ::udev_unref ( _udev ); _udev = 0; } } void UDev_Device_Lookout::udev_process ( ) { bool any_change ( false ); while ( true ) { // Read all device device changes from udev ::udev_device * dev ( ::udev_monitor_receive_device ( _udev_mon ) ); if ( dev != 0 ) { #ifdef QASTOOLS_UDEV_DEBUG { ::std::string devnode; ::std::string subsystem; ::std::string devtype; ::std::string action; { const char * nullstr ( "(null)" ); const char * cstr ( 0 ); cstr = ::udev_device_get_devnode ( dev ); devnode = ( ( cstr != 0 ) ? cstr : nullstr ); cstr = ::udev_device_get_subsystem ( dev ); subsystem = ( ( cstr != 0 ) ? cstr : nullstr ); cstr = ::udev_device_get_devtype ( dev ); devtype = ( ( cstr != 0 ) ? cstr : nullstr ); cstr = ::udev_device_get_action ( dev ); action = ( ( cstr != 0 ) ? cstr : nullstr ); } { ::std::stringstream msg; msg << "UDev action" << ::std::endl; msg << " Node: " << devnode << ::std::endl; msg << " Subsystem: " << subsystem << ::std::endl; msg << " Devtype: " << devtype << ::std::endl; msg << " Action: " << action << ::std::endl; ::std::cout << msg.str() << ::std::flush; } } #endif ::udev_device_unref ( dev ); any_change = true; } else { break; } } if ( any_change ) { emit sig_change(); } } } // End of namespace qastools-v0.22.0/shared/src/qsnd/udev_device_lookout.hpp000066400000000000000000000014421354534512100234030ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_qsnd_udev_device_lookout_hpp__ #define __INC_qsnd_udev_device_lookout_hpp__ #include #include #include namespace QSnd { /// @brief UDev_Device_Lookout /// class UDev_Device_Lookout : public QObject { Q_OBJECT // Public methods public: UDev_Device_Lookout ( QObject * parent_n = 0 ); ~UDev_Device_Lookout ( ); // Signals signals: void sig_change ( ); // Protected slots protected slots: void udev_process ( ); // Private methods private: void udev_init ( ); void udev_close ( ); // Private attributes private: // udev device detection ::udev * _udev; ::udev_monitor * _udev_mon; }; } // End of namespace #endif qastools-v0.22.0/shared/src/single_application.cpp000066400000000000000000000150511354534512100222400ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "single_application.hpp" #include #include #include #include #include #include #include #include #include #include "unix_signal_handler.hpp" Single_Application::Single_Application ( int & argc, char *argv[], const QString & unique_key_n ) : QApplication ( argc, argv ), _is_running ( false ), _local_server ( 0 ), _timeout ( 2000 ) { // Unix signal handling { Unix_Signal_Handler::init_unix_signal_handlers(); Unix_Signal_Handler * usigh ( new Unix_Signal_Handler ( this ) ); QObject::connect ( usigh, SIGNAL ( sig_int() ), this, SLOT ( quit() ) ); QObject::connect ( usigh, SIGNAL ( sig_hup() ), this, SLOT ( quit() ) ); QObject::connect ( usigh, SIGNAL ( sig_term() ), this, SLOT ( quit() ) ); } if ( !unique_key_n.isEmpty() ) { set_unique_key ( unique_key_n ); } } Single_Application::~Single_Application ( ) { } void Single_Application::commitData ( QSessionManager & manager_n ) { //::std::cout << "Single_Application::commitData\n"; emit commitDataRequest ( manager_n ); } void Single_Application::saveState ( QSessionManager & manager_n ) { //::std::cout << "Single_Application::saveState\n"; manager_n.setRestartHint ( QSessionManager::RestartIfRunning ); emit saveStateRequest ( manager_n ); } bool Single_Application::set_unique_key ( const QString & unique_key_n ) { if ( _unique_key == unique_key_n ) { return false; } // Clear { if ( _local_server != 0 ) { delete _local_server; _local_server = 0; } _is_running = false; } _unique_key = unique_key_n; _com_key = unique_key_n; if ( _com_key.isEmpty() ) { return _is_running; } // Adjust com key _com_key.replace ( "-", "_" ); _com_key.replace ( ".", "_" ); _com_key.replace ( QRegExp ( "[^A-Za-z0-9_]" ), QString() ); { QString com_suff ( "_" ); uid_t uid ( getuid() ); struct passwd * pwd ( getpwuid ( uid ) ); if ( pwd != 0 ) { com_suff.append ( QString::fromLocal8Bit ( pwd->pw_name ) ); } else { com_suff.append ( "%1" ); com_suff = com_suff.arg ( uid ); } _com_key.append ( com_suff ) ; } // Com socket file _com_file = "/tmp/"; _com_file.append ( _com_key ); { QFile com_fl ( _com_file ); if ( com_fl.exists() ) { { // Try to connect QLocalSocket lsocket; lsocket.connectToServer ( _com_file, QIODevice::WriteOnly ); _is_running = lsocket.waitForConnected ( _timeout ); } if ( !_is_running ) { // Connection failed { ::std::stringstream msg; msg << "[WW] SApp: Existing socket does not reply."; msg << ::std::endl; msg << "[WW] SApp: Removing broken socket: "; msg << _com_file.toLocal8Bit().constData(); msg << ::std::endl; ::std::cerr << msg.str(); } // Remove dead socket file if ( !com_fl.remove() ) { _is_running = true; { ::std::stringstream msg; msg << "[WW] Removing socket failed" << ::std::endl; ::std::cerr << msg.str(); } } } } } if ( !_is_running ) { // Create a local server and listen to incomming messages from other instances _local_server = new QLocalServer ( this ); if ( _local_server->listen ( _com_file ) ) { connect ( _local_server, SIGNAL ( newConnection() ), this, SLOT ( new_client() ) ); } else { QString err ( _local_server->errorString() ); if ( !err.isEmpty() ) { { ::std::stringstream msg; msg << "[EE] SApp: QLocalServer::listen" << ::std::endl; msg << "[EE] " << err.toLocal8Bit().constData(); msg << ::std::endl; ::std::cerr << msg.str(); } } delete _local_server; _local_server = 0; _is_running = true; } } return _is_running; } void Single_Application::clear_dead_clients ( ) { //::std::cout << "Single_Application::clear_dead_clients\n"; QLinkedList < Client >::iterator iter ( _clients.begin() ); while ( iter != _clients.end() ) { bool remove ( false ); Client & cln ( *iter ); if ( cln.socket != 0 ) { if ( cln.socket->state() == QLocalSocket::UnconnectedState ) { delete cln.socket; publish_message ( cln.data ); remove = true; } } if ( remove ) { //::std::cout << "Single_Application::clear_dead_clients - removing\n"; iter = _clients.erase ( iter ); } else { ++iter; } } } void Single_Application::read_clients_data ( ) { //::std::cout << "Single_Application::read_clients_data\n"; QLinkedList < Client >::iterator iter ( _clients.begin() ); while ( iter != _clients.end() ) { Client & cln ( *iter ); if ( cln.socket != 0 ) { if ( cln.socket->bytesAvailable() > 0 ) { const int limit ( 1024*4 ); cln.data.append ( cln.socket->read ( limit ) ); if ( cln.data.size() >= limit ) { // Publish to avoid buffer size explosion publish_message ( cln.data ); } } } ++iter; } } void Single_Application::new_client ( ) { QLocalSocket * lsocket ( _local_server->nextPendingConnection() ); if ( lsocket != 0 ) { connect ( lsocket, SIGNAL ( readyRead() ), this, SLOT ( read_clients_data() ) ); connect ( lsocket, SIGNAL ( disconnected() ), this, SLOT ( clear_dead_clients() ), Qt::QueuedConnection ); { Client cln; cln.socket = lsocket; _clients.append ( cln ); } read_clients_data(); } } void Single_Application::publish_message ( QByteArray & data_n ) { if ( data_n.size() > 0 ) { _latest_message = data_n.constData(); emit sig_message_available ( _latest_message ); data_n.clear(); } } bool Single_Application::send_message ( const QString & msg_n ) { if ( !_is_running || _com_file.isEmpty() ) { return false; } bool res ( false ); QLocalSocket lsocket ( this ); lsocket.connectToServer ( _com_file, QIODevice::WriteOnly ); if ( lsocket.waitForConnected ( _timeout ) ) { lsocket.write ( msg_n.toUtf8() ); if ( lsocket.waitForBytesWritten ( _timeout ) ) { res = true; } else { QString err ( lsocket.errorString() ); if ( !err.isEmpty() ) { { ::std::stringstream msg; msg << "[EE] SApp: send_message" << ::std::endl; msg << "[EE] " << err.toLocal8Bit().constData(); msg << ::std::endl; ::std::cerr << msg.str(); } } } lsocket.disconnectFromServer(); } else { QString err ( lsocket.errorString() ); if ( !err.isEmpty() ) { { ::std::stringstream msg; msg << "[EE] SApp: send_message" << ::std::endl; msg << "[EE] " << err.toLocal8Bit().constData(); msg << ::std::endl; ::std::cerr << msg.str(); } } } return res; } qastools-v0.22.0/shared/src/single_application.hpp000066400000000000000000000033361354534512100222500ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_single_application_hpp__ #define __INC_single_application_hpp__ #include #include #include #include class Single_Application : public QApplication { Q_OBJECT // Public methods public: Single_Application ( int & argc, char *argv[], const QString & unique_key_n = QString() ); ~Single_Application ( ); // Unique key const QString & unique_key ( ) const; bool set_unique_key ( const QString & unique_key_n ); bool is_running ( ) const; // Message bool send_message ( const QString & msg_n ); const QString latest_message ( ) const; // Session management void commitData ( QSessionManager & manager_n ); void saveState ( QSessionManager & manager_n ); // Signals signals: void sig_message_available ( QString mesg_n ); // Protected slots protected slots: void new_client ( ); void read_clients_data ( ); void clear_dead_clients ( ); // Protected methods protected: void publish_message ( QByteArray & data_n ); // Private attributes private: bool _is_running; QString _unique_key; QString _com_key; QString _com_file; QString _latest_message; QLocalServer * _local_server; struct Client { QPointer < QLocalSocket > socket; QByteArray data; }; QLinkedList < Client > _clients; const unsigned int _timeout; }; inline bool Single_Application::is_running ( ) const { return _is_running; } inline const QString & Single_Application::unique_key ( ) const { return _unique_key; } inline const QString Single_Application::latest_message ( ) const { return _latest_message; } #endif qastools-v0.22.0/shared/src/unix_signal_handler.cpp000066400000000000000000000077431354534512100224220ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "unix_signal_handler.hpp" #include #include #include #include #include int Unix_Signal_Handler::_sig_int_fds[2]; int Unix_Signal_Handler::_sig_hup_fds[2]; int Unix_Signal_Handler::_sig_term_fds[2]; Unix_Signal_Handler::Unix_Signal_Handler ( QObject * parent_n ) : QObject ( parent_n ) { if ( ::socketpair ( AF_UNIX, SOCK_STREAM, 0, _sig_int_fds ) ) { qFatal ( "Couldn't create SIGINT socketpair" ); } if ( ::socketpair ( AF_UNIX, SOCK_STREAM, 0, _sig_hup_fds ) ) { qFatal ( "Couldn't create SIGHUP socketpair" ); } if ( ::socketpair ( AF_UNIX, SOCK_STREAM, 0, _sig_term_fds ) ) { qFatal ( "Couldn't create SIGTERM socketpair" ); } _sn_int.reset ( new QSocketNotifier ( _sig_int_fds[1], QSocketNotifier::Read, this ) ); _sn_hup.reset ( new QSocketNotifier ( _sig_hup_fds[1], QSocketNotifier::Read, this ) ); _sn_term.reset ( new QSocketNotifier ( _sig_term_fds[1], QSocketNotifier::Read, this ) ); connect ( _sn_int.get(), SIGNAL ( activated ( int ) ), this, SLOT ( sev_handle_sig_int() ) ); connect ( _sn_hup.get(), SIGNAL ( activated ( int ) ), this, SLOT ( sev_handle_sig_hup() ) ); connect ( _sn_term.get(), SIGNAL ( activated ( int ) ), this, SLOT ( sev_handle_sig_term() ) ); } Unix_Signal_Handler::~Unix_Signal_Handler ( ) { } int Unix_Signal_Handler::init_unix_signal_handlers ( ) { { struct sigaction act; act.sa_handler = Unix_Signal_Handler::signal_handler_int; sigemptyset ( &act.sa_mask ); act.sa_flags = 0; act.sa_flags |= SA_RESTART; if ( sigaction ( SIGINT, &act, 0 ) > 0 ) { return 1; } } { struct sigaction act; act.sa_handler = Unix_Signal_Handler::signal_handler_hup; sigemptyset ( &act.sa_mask ); act.sa_flags = 0; act.sa_flags |= SA_RESTART; if ( sigaction ( SIGHUP, &act, 0 ) > 0 ) { return 2; } } { struct sigaction act; act.sa_handler = Unix_Signal_Handler::signal_handler_term; sigemptyset ( &act.sa_mask ); act.sa_flags = 0; act.sa_flags |= SA_RESTART; if ( sigaction ( SIGTERM, &act, 0 ) > 0 ) { return 3; } } return 0; } void Unix_Signal_Handler::signal_handler_int ( int ) { char dat ( 1 ); int size ( sizeof ( dat ) ); if ( ::write ( _sig_int_fds[0], &dat, size ) != size ) { qFatal ( "Unix_Signal_Handler: Writing to SIGINT socket failed" ); } } void Unix_Signal_Handler::signal_handler_hup ( int ) { char dat ( 1 ); int size ( sizeof ( dat ) ); if ( ::write ( _sig_hup_fds[0], &dat, size ) != size ) { qFatal ( "Unix_Signal_Handler: Writing to SIGHUP socket failed" ); } } void Unix_Signal_Handler::signal_handler_term ( int ) { char dat ( 1 ); int size ( sizeof ( dat ) ); if ( ::write ( _sig_term_fds[0], &dat, size ) != size ) { qFatal ( "Unix_Signal_Handler: Writing to SIGTERM socket failed" ); } } void Unix_Signal_Handler::sev_handle_sig_int ( ) { //::std::cout << "Unix_Signal_Handler::sev_handle_sig_int\n"; _sn_int->setEnabled ( false ); char tmp; int size ( sizeof ( tmp ) ); if ( ::read ( _sig_int_fds[1], &tmp, size ) == -1 ) { qFatal ( "Unix_Signal_Handler: Reading from SIGINT socket failed" ); } emit sig_int(); _sn_int->setEnabled ( true ); } void Unix_Signal_Handler::sev_handle_sig_hup ( ) { //::std::cout << "Unix_Signal_Handler::sev_handle_sig_hup\n"; _sn_hup->setEnabled ( false ); char tmp; int size ( sizeof ( tmp ) ); if ( ::read ( _sig_hup_fds[1], &tmp, size ) == -1 ) { qFatal ( "Unix_Signal_Handler: Reading from SIGHUP socket failed" ); } emit sig_hup(); _sn_hup->setEnabled ( true ); } void Unix_Signal_Handler::sev_handle_sig_term ( ) { //::std::cout << "Unix_Signal_Handler::sev_handle_sig_term\n"; _sn_term->setEnabled ( false ); char tmp; int size ( sizeof ( tmp ) ); if ( ::read ( _sig_term_fds[1], &tmp, size ) == -1 ) { qFatal ( "Unix_Signal_Handler: Reading from SIGTERM socket failed" ); } emit sig_term(); _sn_term->setEnabled ( true ); } qastools-v0.22.0/shared/src/unix_signal_handler.hpp000066400000000000000000000022201354534512100224100ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_unix_signal_handler_hpp__ #define __INC_unix_signal_handler_hpp__ #include #include // Forward declaration class QSocketNotifier; class Unix_Signal_Handler : public QObject { Q_OBJECT // Public methods public: Unix_Signal_Handler ( QObject * parent_n ); ~Unix_Signal_Handler ( ); static int init_unix_signal_handlers ( ); // Unix signal handlers. static void signal_handler_int ( int unused_n ); static void signal_handler_hup ( int unused_n ); static void signal_handler_term ( int unused_n ); // Signals signals: void sig_int ( ); void sig_hup ( ); void sig_term ( ); // Public slots public slots: void sev_handle_sig_int ( ); void sev_handle_sig_hup ( ); void sev_handle_sig_term ( ); // Private attributes private: static int _sig_int_fds[2]; static int _sig_hup_fds[2]; static int _sig_term_fds[2]; ::std::unique_ptr < QSocketNotifier > _sn_int; ::std::unique_ptr < QSocketNotifier > _sn_hup; ::std::unique_ptr < QSocketNotifier > _sn_term; }; #endif qastools-v0.22.0/shared/src/views/000077500000000000000000000000001354534512100170235ustar00rootroot00000000000000qastools-v0.22.0/shared/src/views/basic_dialog.cpp000066400000000000000000000034311354534512100221300ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "basic_dialog.hpp" #include namespace Views { Basic_Dialog::Basic_Dialog ( QWidget * parent_n, Qt::WindowFlags flags_n ) : QDialog ( parent_n, flags_n ) { _lay_main = new QVBoxLayout; setLayout ( _lay_main ); _lbl_title = create_title_widget ( QString() ); _lay_main->addWidget ( _lbl_title, 0, Qt::AlignTop ); } Basic_Dialog::~Basic_Dialog ( ) { } void Basic_Dialog::set_title_str ( const QString & str_n ) { _lbl_title->setText ( str_n ); } void Basic_Dialog::set_central_widget ( QWidget * wdg_n ) { _lay_main->addWidget ( wdg_n, 1 ); } QLabel * Basic_Dialog::create_title_widget ( const QString & txt_n ) { QLabel * lbl ( new QLabel ( txt_n ) ); { QMargins marg ( lbl->contentsMargins() ); marg.setTop ( lbl->fontMetrics().height() * 1 / 4 ); marg.setBottom ( lbl->fontMetrics().height() * 3 / 4 ); lbl->setContentsMargins ( marg ); } { QSizePolicy policy ( lbl->sizePolicy() ); policy.setHorizontalPolicy ( QSizePolicy::Expanding ); policy.setVerticalPolicy ( QSizePolicy::Fixed ); lbl->setSizePolicy ( policy ); } { QFont fnt ( lbl->font() ); fnt.setBold ( true ); double scale ( 1.8 ); if ( fnt.pixelSize() > 0 ) { fnt.setPixelSize ( fnt.pixelSize() * scale ); } else { fnt.setPointSizeF ( fnt.pointSizeF() * scale ); } lbl->setFont ( fnt ); } return lbl; } QPushButton * Basic_Dialog::create_close_button ( ) { QPushButton * btn ( new QPushButton ( tr ( "&Close" ) ) ); const char * icon_name ( "window-close" ); if ( QIcon::hasThemeIcon ( icon_name ) ) { btn->setIcon ( QIcon::fromTheme ( icon_name ) ); } connect ( btn, SIGNAL ( clicked() ), this, SLOT ( close() ) ); return btn; } } // End of namespace qastools-v0.22.0/shared/src/views/basic_dialog.hpp000066400000000000000000000014611354534512100221360ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_views_basic_dialog_hpp__ #define __INC_views_basic_dialog_hpp__ #include #include #include #include namespace Views { /// @brief Basic_Dialog /// class Basic_Dialog : public QDialog { Q_OBJECT // Public methods public: Basic_Dialog ( QWidget * parent_n = 0, Qt::WindowFlags flags_n = 0 ); ~Basic_Dialog ( ); void set_title_str ( const QString & str_n ); void set_central_widget ( QWidget * wdg_n ); QLabel * create_title_widget ( const QString & txt_n ); QPushButton * create_close_button ( ); // Private attributes private: // Pages QLabel * _lbl_title; QVBoxLayout * _lay_main; }; } // End of namespace #endif qastools-v0.22.0/shared/src/views/device_selection_view.cpp000066400000000000000000000273161354534512100240760ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "device_selection_view.hpp" #include "qsnd/ctl_address.hpp" #include "qsnd/ctl_format.hpp" #include "qsnd/controls_model.hpp" #include "mwdg/controls_view.hpp" #include "mwdg/ctl_arg_view.hpp" #include "mwdg/ctl_arg_view_string.hpp" #include "mwdg/ctl_arg_view_integer.hpp" #include "mwdg/ctl_arg_view_card.hpp" #include "views/device_selection_view_setup.hpp" #include #include #include #include namespace Views { Device_Selection_View::Device_Selection_View ( QWidget * parent_n ) : QWidget ( parent_n ), _view_setup ( 0 ), _lay_arg_views ( 0 ), _selected_ctl_checks_good ( false ), _silent_ctl_change ( false ), _silent_arg_change ( false ) { // Strings _str_type_card = "card"; _str_type_string = "string"; _str_type_integer = "integer"; // View close action _act_close = new QAction ( this ); _act_close->setText ( tr ( "&Close device selection" ) ); if ( QIcon::hasThemeIcon ( "window-close" ) ) { _act_close->setIcon ( QIcon::fromTheme ( "window-close" ) ); } connect ( _act_close, SIGNAL ( triggered ( bool ) ), this, SIGNAL ( sig_close() ) ); // Controls database connect ( &_controls_db, SIGNAL ( sig_reload_required() ), this, SLOT ( reload_database() ) ); // Control selection model and view { _controls_model = new ::QSnd::Controls_Model ( this ); _controls_model->set_controls_db ( &_controls_db ); _controls_view = new ::MWdg::Controls_View ( this ); _controls_view->setModel ( _controls_model ); connect ( _controls_view->selectionModel(), SIGNAL ( currentChanged ( const QModelIndex &, const QModelIndex & ) ), this, SLOT ( control_changed ( const QModelIndex &, const QModelIndex & ) ) ); } { QSizePolicy policy ( sizePolicy() ); policy.setHorizontalPolicy ( QSizePolicy::Preferred ); policy.setVerticalPolicy ( QSizePolicy::Expanding ); setSizePolicy ( policy ); } QLabel * controls_label = new QLabel; controls_label->setText ( tr ( "Mixer device" ) ); { QFont fnt ( controls_label->font() ); fnt.setBold ( true ); controls_label->setFont ( fnt ); } _lay_arg_views = new QVBoxLayout; { QVBoxLayout * lay_args ( new QVBoxLayout ); int vspace ( fontMetrics().height() * 2 / 3 ); lay_args->setContentsMargins ( 0, vspace, 0, 0 ); lay_args->addLayout ( _lay_arg_views, 0 ); lay_args->addStretch ( 1 ); QVBoxLayout * lay_vbox ( new QVBoxLayout ); lay_vbox->addWidget ( controls_label, 0 ); lay_vbox->addWidget ( _controls_view, 1 ); lay_vbox->addLayout ( lay_args, 0 ); setLayout ( lay_vbox ); } } Device_Selection_View::~Device_Selection_View ( ) { clear_arg_views(); } void Device_Selection_View::set_view_setup ( ::Views::Device_Selection_View_Setup * setup_n ) { _view_setup = setup_n; if ( _view_setup != 0 ) { selection_db_sanitize(); } } void Device_Selection_View::compile_ctl_address ( ::QSnd::CTL_Address & ctl_addr_n ) { //::std::cout << "Device_Selection_View::compile_ctl_address: " << ctl_addr_n.addr_str().toLocal8Bit().data() << "\n"; const QModelIndex & cidx ( _controls_view->currentIndex() ); const ::QSnd::CTL_Format * ctl_format ( _controls_model->ctl_format ( cidx ) ); if ( ctl_format != 0 ) { // Control name ctl_addr_n.set_ctl_name ( ctl_format->ctl_name() ); // Control arguments for ( int ii=0; ii < _arg_views.size(); ++ii ) { const QString & arg_name ( _arg_views[ii]->ctl_arg().arg_name ); const QString & arg_str ( _arg_views[ii]->arg_string() ); if ( !arg_str.isEmpty() ) { ctl_addr_n.append_arg ( ::QSnd::CTL_Address_Argument ( arg_name, arg_str ) ); } } } else { ctl_addr_n.clear(); } } void Device_Selection_View::silent_select_ctl ( const ::QSnd::CTL_Address & ctl_addr_n ) { if ( !_selected_ctl.match ( ctl_addr_n ) ) { _silent_ctl_change = true; // Clear previous selection clear_arg_views(); _selected_ctl_format.clear(); _selected_ctl.clear(); _controls_view->clearSelection(); // Find control format model index from name const QModelIndex midx ( _controls_model->ctl_format_index ( ctl_addr_n.ctl_name() ) ); // It's safer to set a current index even if it is invalid. // Otherwise Qt may pick the first index just to have one selected. _controls_view->setCurrentIndex ( midx ); if ( midx.isValid() ) { // The address in the database will be used by the arg view restore selection_db_commit ( ctl_addr_n ); { ::QSnd::CTL_Format format; _controls_model->ctl_format ( format, midx ); if ( format.is_valid() ) { _selected_ctl_format = format; } } // Create and update argument inputs _silent_arg_change = true; create_arg_views(); restore_arg_views(); _silent_arg_change = false; compile_ctl_address ( _selected_ctl ); update_selected_ctl_checks(); } _silent_ctl_change = false; } } void Device_Selection_View::reload_database ( ) { //::std::cout << "Device_Selection_View::reload_database" << "\n"; if ( _view_setup != 0 ) { // Remember selection const ::QSnd::CTL_Address ctl_addr ( _selected_ctl ); const bool ctl_check_good ( _selected_ctl_checks_good ); // Clear selection _selected_ctl.clear(); _selected_ctl_format.clear(); // Silent reload _silent_ctl_change = true; _controls_db.reload(); selection_db_sanitize(); _silent_ctl_change = false; // Non silent selection restore silent_select_ctl ( ctl_addr ); // Look for changes if ( !_selected_ctl.match ( ctl_addr ) ) { emit sig_control_selected(); } else if ( _selected_ctl_checks_good != ctl_check_good ) { emit sig_control_reload(); } } } void Device_Selection_View::control_changed ( const QModelIndex & cur_idx_n, const QModelIndex & ) { control_changed ( cur_idx_n ); } void Device_Selection_View::control_changed ( const QModelIndex & idx_n ) { //::std::cout << "Device_Selection_View::control_changed " << "\n"; if ( !_silent_ctl_change ) { { ::QSnd::CTL_Format ctl_format; _controls_model->ctl_format ( ctl_format, idx_n ); if ( _selected_ctl_format != ctl_format ) { // Clear argument inputs clear_arg_views(); // Update format _selected_ctl_format = ctl_format; // Create new argument inputs on demand if ( _selected_ctl_format.is_valid() ) { _silent_arg_change = true; create_arg_views(); restore_arg_views(); _silent_arg_change = false; } } } update_selected_ctl(); } } void Device_Selection_View::control_arg_changed ( ) { //::std::cout << "Device_Selection_View::control_arg_changed " << "\n"; if ( !( _silent_ctl_change || _silent_arg_change ) ) { if ( update_selected_ctl() ) { // Remember _selected_ctl for a later visit selection_db_commit ( _selected_ctl ); } } } void Device_Selection_View::update_selected_ctl_checks ( ) { _selected_ctl_checks_good = false; if ( _selected_ctl.is_valid() ) { _selected_ctl_checks_good = true; const unsigned int num_args ( _selected_ctl.num_args() ); if ( num_args <= _selected_ctl_format.num_args() ) { for ( unsigned int ii=0; ii != num_args; ++ii ) { const ::QSnd::CTL_Address_Argument & arg ( _selected_ctl.arg ( ii ) ); if ( arg.arg_value.isEmpty() ) { // Empty arguments are bad _selected_ctl_checks_good = false; } else { const ::QSnd::CTL_Format_Argument & arg_format ( _selected_ctl_format.arg ( ii ) ); if ( arg_format.arg_name.compare ( _str_type_card, Qt::CaseInsensitive ) == 0 ) { unsigned int card_id ( arg.arg_value.toUInt() ); if ( _cards_model.card_info_by_card_id ( card_id ) == 0 ) { _selected_ctl_checks_good = false; } } } } } else { _selected_ctl_checks_good = false; } } } bool Device_Selection_View::update_selected_ctl ( ) { //::std::cout << "Device_Selection_View::update_selected_ctl " << "\n"; bool res ( false ); { ::QSnd::CTL_Address ctl_addr; compile_ctl_address ( ctl_addr ); if ( !_selected_ctl.match ( ctl_addr ) ) { _selected_ctl = ctl_addr; emit sig_control_selected(); res = true; } } update_selected_ctl_checks(); return res; } const ::QSnd::CTL_Address * Device_Selection_View::selection_db_find ( const QString & ctl_name_n ) const { const ::QSnd::CTL_Address * res ( 0 ); if ( _view_setup != 0 ) { for ( int ii=0; ii < _view_setup->selection_db.size(); ++ii ) { const ::QSnd::CTL_Address & addr ( _view_setup->selection_db[ii] ); if ( addr.ctl_name() == ctl_name_n ) { res = &addr; break; } } } return res; } void Device_Selection_View::selection_db_commit ( const ::QSnd::CTL_Address & ctl_addr_n ) { if ( ( _view_setup != 0 ) && ctl_addr_n.is_valid() ) { bool found ( false ); for ( int ii=0; ii < _view_setup->selection_db.size(); ++ii ) { ::QSnd::CTL_Address & addr ( _view_setup->selection_db[ii] ); if ( addr.ctl_name() == ctl_addr_n.ctl_name() ) { addr = ctl_addr_n; found = true; break; } } if ( !found ) { _view_setup->selection_db.append ( ctl_addr_n ); } } } void Device_Selection_View::selection_db_sanitize ( ) { if ( _view_setup != 0 ) { // Remove entries from selection db that don't exist in the // available controls database typedef Device_Selection_View_Setup::Selection_DB::iterator Iterator; Iterator itc ( _view_setup->selection_db.begin() ); while ( itc != _view_setup->selection_db.end() ) { if ( _controls_db.find_control_format ( itc->ctl_name() ) == 0 ) { itc = _view_setup->selection_db.erase ( itc ); } else { ++itc; } } } } void Device_Selection_View::clear_arg_views ( ) { for ( int ii=0; ii < _arg_views.size(); ++ii ) { delete _arg_views[ii]; } _arg_views.clear(); } void Device_Selection_View::create_arg_views ( ) { //::std::cout << "Device_Selection_View::create_arg_views"\n"; if ( _selected_ctl_format.is_valid() ) { const unsigned int num_args ( _selected_ctl_format.num_args() ); for ( unsigned int ii=0; ii != num_args; ++ii ) { const ::QSnd::CTL_Format_Argument & ctl_arg ( _selected_ctl_format.arg ( ii ) ); ::MWdg::CTL_Arg_View * arg_view ( 0 ); if ( ctl_arg.arg_name.compare ( _str_type_card, Qt::CaseInsensitive ) == 0 ) { arg_view = new ::MWdg::CTL_Arg_View_Card; } else if ( ctl_arg.arg_type.compare ( _str_type_string, Qt::CaseInsensitive ) == 0 ) { arg_view = new ::MWdg::CTL_Arg_View_String; } else if ( ctl_arg.arg_type.compare ( _str_type_integer, Qt::CaseInsensitive ) == 0 ) { arg_view = new ::MWdg::CTL_Arg_View_Integer; } if ( arg_view != 0 ) { arg_view->set_ctl_db ( &_controls_db ); arg_view->set_cards_model ( &_cards_model ); arg_view->set_ctl_arg ( ctl_arg ); connect ( arg_view, SIGNAL ( sig_arg_changed() ), this, SLOT ( control_arg_changed() ) ); _arg_views.append ( arg_view ); _lay_arg_views->addWidget ( arg_view ); } } } } void Device_Selection_View::restore_arg_views ( ) { if ( _selected_ctl_format.is_valid() && ( _selected_ctl_format.num_args() != 0 ) ) { const ::QSnd::CTL_Address * ctl_addr ( selection_db_find ( _selected_ctl_format.ctl_name() ) ); if ( ctl_addr != 0 ) { const unsigned int num_args ( ::std::min ( ctl_addr->num_args(), _selected_ctl_format.num_args() ) ); for ( unsigned int ii=0; ii != num_args; ++ii ) { const ::QSnd::CTL_Address_Argument & ctl_arg ( ctl_addr->arg ( ii ) ); ::MWdg::CTL_Arg_View * arg_view ( _arg_views[ii] ); bool name_match ( true ); if ( !ctl_arg.arg_name.isEmpty() ) { name_match = ( arg_view->ctl_arg().arg_name == ctl_arg.arg_name ); } if ( name_match ) { arg_view->set_arg_string ( ctl_arg.arg_value ); } } } } } void Device_Selection_View::contextMenuEvent ( QContextMenuEvent * event_n ) { QMenu cmenu ( this ); cmenu.addAction ( _act_close ); cmenu.exec ( event_n->globalPos() ); } } // End of namespace qastools-v0.22.0/shared/src/views/device_selection_view.hpp000066400000000000000000000056211354534512100240760ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_views_device_selection_view_hpp__ #define __INC_views_device_selection_view_hpp__ #include "qsnd/ctl_address.hpp" #include "qsnd/controls_database.hpp" #include "qsnd/cards_model.hpp" #include "mwdg/ctl_arg_view.hpp" #include #include // Forward declaration class QModelIndex; namespace QSnd { class Controls_Model; } namespace MWdg { class Controls_View; } namespace Views { class Device_Selection_View_Setup; } namespace Views { /// @brief Device_Selection_View /// /// Mixer device selection view class Device_Selection_View : public QWidget { Q_OBJECT // Public methods public: Device_Selection_View ( QWidget * parent_n = 0 ); ~Device_Selection_View ( ); void set_view_setup ( ::Views::Device_Selection_View_Setup * setup_n ); const ::QSnd::CTL_Address & default_ctl ( ) const; const ::QSnd::CTL_Address & selected_ctl ( ) const; void silent_select_ctl ( const ::QSnd::CTL_Address & ctl_addr_n ); // Signals signals: void sig_close ( ); void sig_control_selected ( ); /// @brief Gets emitted e.g. when the card of the selected ctl appears/disappears void sig_control_reload ( ); // Public slots public slots: void reload_database ( ); // Protected methods protected: void contextMenuEvent ( QContextMenuEvent * event_n ); // Private slots private slots: void control_changed ( const QModelIndex & cur_idx_n, const QModelIndex & prev_idx_n ); void control_changed ( const QModelIndex & idx_n ); void control_arg_changed ( ); // Private methods private: void clear_arg_views ( ); void create_arg_views ( ); void restore_arg_views ( ); void compile_ctl_address ( ::QSnd::CTL_Address & ctl_addr_n ); void update_selected_ctl_checks ( ); bool update_selected_ctl ( ); const ::QSnd::CTL_Address * selection_db_find ( const QString & ctl_name_n ) const; void selection_db_commit ( const ::QSnd::CTL_Address & ctl_addr_n ); /// @brief Removes non existing CTL addresses /// void selection_db_sanitize ( ); // Private attributes private: ::Views::Device_Selection_View_Setup * _view_setup; ::QSnd::Controls_Database _controls_db; ::QSnd::Cards_Model _cards_model; ::QSnd::Controls_Model * _controls_model; ::MWdg::Controls_View * _controls_view; QList < ::MWdg::CTL_Arg_View * > _arg_views; QVBoxLayout * _lay_arg_views; // Selection state ::QSnd::CTL_Address _selected_ctl; ::QSnd::CTL_Format _selected_ctl_format; bool _selected_ctl_checks_good; bool _silent_ctl_change; bool _silent_arg_change; // Strings QString _str_type_card; QString _str_type_string; QString _str_type_integer; // Context menu QAction * _act_close; }; inline const ::QSnd::CTL_Address & Device_Selection_View::selected_ctl ( ) const { return _selected_ctl; } } // End of namespace #endif qastools-v0.22.0/shared/src/views/device_selection_view_setup.cpp000066400000000000000000000017111354534512100253050ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "device_selection_view_setup.hpp" #include "qsnd/ctl_address.hpp" namespace Views { Device_Selection_View_Setup::Device_Selection_View_Setup ( ) : kseq_toggle_vis ( Qt::Key_F6 ) { } Device_Selection_View_Setup::~Device_Selection_View_Setup ( ) { selection_db_clear(); } void Device_Selection_View_Setup::selection_db_clear ( ) { selection_db.clear(); } QStringList Device_Selection_View_Setup::selection_db_get ( ) const { QStringList lst; for ( int ii=0; ii < selection_db.size(); ++ii ) { lst.append ( selection_db[ii].addr_str() ); } return lst; } void Device_Selection_View_Setup::selection_db_set ( const QStringList & sel_db_n ) { selection_db_clear(); for ( int ii=0; ii < sel_db_n.size(); ++ii ) { if ( !sel_db_n[ii].isEmpty() ) { selection_db.append ( ::QSnd::CTL_Address ( sel_db_n[ii] ) ); } } } } // End of namespace qastools-v0.22.0/shared/src/views/device_selection_view_setup.hpp000066400000000000000000000015451354534512100253170ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_device_selection_view_setup_hpp__ #define __INC_device_selection_view_setup_hpp__ #include #include #include // Forward declaration namespace QSnd { class CTL_Address; } namespace Views { /// @brief Device_Selection_View_Setup /// class Device_Selection_View_Setup { // Public types public: typedef QList < ::QSnd::CTL_Address > Selection_DB; // Public methods public: Device_Selection_View_Setup ( ); ~Device_Selection_View_Setup ( ); void selection_db_clear ( ); QStringList selection_db_get ( ) const; void selection_db_set ( const QStringList & sel_db_n ); // Public attributes public: QKeySequence kseq_toggle_vis; Selection_DB selection_db; }; } // End of namespace #endif qastools-v0.22.0/shared/src/views/info_dialog.cpp000066400000000000000000000121211354534512100217760ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "info_dialog.hpp" #include "qastools_config.hpp" #include "wdg/text_browser.hpp" #include #include #include #include #include #include namespace Views { Info_Dialog::Info_Dialog ( QWidget * parent_n, Qt::WindowFlags flags_n ) : ::Views::Multi_Page_Dialog ( parent_n, flags_n ) { // Window title { QString txt ( "%1 - %2" ); txt = txt.arg ( PROGRAM_TITLE ); txt = txt.arg ( tr ( "Info" ) ); setWindowTitle ( txt ); } // Title label { QString txt ( "%1 - %2" ); txt = txt.arg ( PACKAGE_TITLE ); txt = txt.arg ( PACKAGE_VERSION ); set_title_str ( txt ); } ::Wdg::Text_Browser * _txt_info ( 0 ); ::Wdg::Text_Browser * _txt_people ( 0 ); ::Wdg::Text_Browser * _txt_license ( 0 ); const QString hmask ( "

%1

\n" ); // Description text { const QString amask ( "%1" ); QString txt; txt += hmask.arg ( tr ( "About" ) ); txt += "

"; { QString val ( tr ( "%1 is a collection of desktop applications for the Linux sound system %2." ) ); val = val.arg ( PACKAGE_TITLE ); val = val.arg ( "ALSA" ); txt += val; } txt += "

"; // Internet txt += hmask.arg ( tr ( "Internet" ) ); txt += "

"; txt += amask.arg ( "https://gitlab.com/sebholt/qastools", tr ( "Project page" ) ); txt += "

"; _txt_info = new ::Wdg::Text_Browser; _txt_info->setAlignment ( Qt::AlignLeft | Qt::AlignTop ); _txt_info->setWordWrapMode ( QTextOption::NoWrap ); _txt_info->setOpenLinks ( true ); _txt_info->setOpenExternalLinks ( true ); _txt_info->setHtml ( txt ); } // People text { const QString pemask ( "%1 <%2>" ); QString trmask; QString pdivmask; { const QString pdiv ( "
%1
" ); trmask.append ( pemask ); trmask.append ( " [%3]" ); trmask = pdiv.arg ( trmask ); pdivmask = pdiv.arg ( pemask ); } QString txt; // Developers { txt += hmask.arg ( tr ( "Developers" ) ); const char * names[] = { "Sebastian Holtermann", "sebholt@web.de", 0, 0 }; for ( const char ** ptr ( &names[0] ); *ptr != 0; ptr += 2 ) { txt += pdivmask.arg ( ptr[0], ptr[1] ); } } // Contributors { txt += hmask.arg ( tr ( "Contributors" ) ); const char * names[] = { "Jose Lencioni", "elcorreodelcoco@gmail.com", "Ivan Sorokin", "vanyacpp@gmail.com", "Fernando Auil ", "auil@usp.br", 0, 0 }; for ( const char ** ptr ( &names[0] ); *ptr != 0; ptr += 2 ) { txt += pdivmask.arg ( ptr[0], ptr[1] ); } } // Translators { txt += hmask.arg ( tr ( "Translators" ) ); const char * names[] = { "Pavel Fric", "pavelfric@seznam.cz", "cs", "Sebastian Holtermann", "sebholt@web.de", "de", "Jose Lencioni", "elcorreodelcoco@gmail.com", "es", "Ivan Sorokin", "vanyacpp@gmail.com", "ru", 0, 0, 0 }; for ( const char ** ptr ( &names[0] ); *ptr != 0; ptr += 3 ) { txt += trmask.arg ( ptr[0], ptr[1], ptr[2] ); } } _txt_people = new ::Wdg::Text_Browser; _txt_people->setAlignment ( Qt::AlignLeft | Qt::AlignTop ); _txt_people->setWordWrapMode ( QTextOption::NoWrap ); _txt_people->setOpenLinks ( true ); _txt_people->setOpenExternalLinks ( true ); _txt_people->setHtml ( txt ); } // License text { QString txt; { const unsigned int num_search ( 2 ); QString fl_abs[num_search]; fl_abs[0] = INSTALL_DIR_DATA; fl_abs[0] += "/COPYING"; fl_abs[1] = "/usr/share/common-licenses/GPL-3"; bool found ( false ); for ( unsigned int ii=0; ii < num_search; ++ii ) { if ( read_utf8_file ( fl_abs[ii], txt ) ) { found = true; break; } } if ( found ) { _txt_license = new ::Wdg::Text_Browser; } else { txt = tr ( "The license file %1 is not available." ); txt = txt.arg ( fl_abs[0] ); } } if ( _txt_license != 0 ) { //_txt_license->setFrameStyle ( QFrame::NoFrame ); _txt_license->setAlignment ( Qt::AlignLeft | Qt::AlignTop ); _txt_license->setWordWrapMode ( QTextOption::NoWrap ); _txt_license->setOpenLinks ( true ); _txt_license->setOpenExternalLinks ( true ); { QFont fnt ( _txt_license->document()->defaultFont() ); fnt.setFamily ( "courier" ); fnt.setFixedPitch ( true ); _txt_license->document()->setDefaultFont ( fnt ); } _txt_license->setPlainText ( txt ); } } add_page ( tr ( "Information" ), _txt_info ); add_page ( tr ( "People" ), _txt_people ); add_page ( tr ( "License" ), _txt_license ); set_current_page_idx ( 0 ); } bool Info_Dialog::read_utf8_file ( const QString & filename_n, QString & txt_n ) const { bool res ( false ); QFile file ( filename_n ); file.open ( QIODevice::ReadOnly ); if ( file.isOpen() ) { QByteArray ba ( file.readAll() ); txt_n = QString::fromUtf8 ( ba.data(), ba.size() ); file.close(); res = true; } return res; } } // End of namespace qastools-v0.22.0/shared/src/views/info_dialog.hpp000066400000000000000000000011541354534512100220070ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_views_info_dialog_hpp__ #define __INC_views_info_dialog_hpp__ #include "views/multi_page_dialog.hpp" namespace Views { /// @brief Info_Dialog /// class Info_Dialog : public ::Views::Multi_Page_Dialog { Q_OBJECT // Public methods public: Info_Dialog ( QWidget * parent_n = 0, Qt::WindowFlags flags_n = 0 ); // Protected methods protected: bool read_utf8_file ( const QString & filename_n, QString & txt_n ) const; // Private attributes private: }; } // End of namespace #endif qastools-v0.22.0/shared/src/views/message_widget.cpp000066400000000000000000000040051354534512100225150ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "message_widget.hpp" #include namespace Views { Message_Widget::Message_Widget ( QWidget * parent_n ) : QWidget ( parent_n ), _title_mask ( "

%1

" ) { { QString cstyle ( "style=\"padding-left: 0px; padding-right: %1px; padding-top: 0px; padding-bottom: %2px;\" align=\"left\"" ); cstyle = cstyle.arg ( fontMetrics().averageCharWidth() * 2 ); cstyle = cstyle.arg ( fontMetrics().height() * 1 / 2 ); _table_row_mask.append ( "" ); _table_row_mask.append ( "%1" ); _table_row_mask.append ( "%2" ); _table_row_mask.append ( "" ); } _title_open_mixer_fail = tr ( "Mixer device couldn't be opened" ); _title_no_device = tr ( "No device selected" ); // Layout { QVBoxLayout * lay_vbox ( new QVBoxLayout ); lay_vbox->addWidget ( &_title ); lay_vbox->addSpacing ( fontMetrics().height() / 2 ); lay_vbox->addWidget ( &_text ); lay_vbox->addStretch(); setLayout ( lay_vbox ); } } void Message_Widget::set_title ( const QString & txt_n ) { _title.setText ( _title_mask.arg ( txt_n ) ); } void Message_Widget::set_text ( const QString & txt_n ) { _text.setText ( txt_n ); } void Message_Widget::set_mixer_open_fail ( const QString & device_n, const QString & error_n, const QString & func_n ) { set_title ( _title_open_mixer_fail ); { QString txt; txt += ""; txt += _table_row_mask.arg ( tr ( "Function" ) + ":" ).arg ( func_n ); txt += _table_row_mask.arg ( tr ( "Address" ) + ":" ).arg ( device_n ); txt += _table_row_mask.arg ( tr ( "Error" ) + ":" ).arg ( error_n ); txt += "
"; set_text ( txt ); } } void Message_Widget::set_no_device ( ) { set_title ( _title_no_device ); set_text ( QString() ); } } // End of namespace qastools-v0.22.0/shared/src/views/message_widget.hpp000066400000000000000000000015711354534512100225270ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_views_message_widget_hpp__ #define __INC_views_message_widget_hpp__ #include #include namespace Views { /// @brief (Error) message display widget /// class Message_Widget : public QWidget { Q_OBJECT // Public methods public: Message_Widget ( QWidget * parent_n = 0 ); void set_title ( const QString & txt_n ); void set_text ( const QString & txt_n ); void set_mixer_open_fail ( const QString & device_n, const QString & error_n, const QString & func_n ); void set_no_device ( ); // Private attributes private: QLabel _title; QLabel _text; // Masks QString _title_mask; QString _table_row_mask; // Default titles QString _title_open_mixer_fail; QString _title_no_device; }; } // End of namespace #endif qastools-v0.22.0/shared/src/views/multi_page_dialog.cpp000066400000000000000000000073341354534512100232030ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "multi_page_dialog.hpp" #include #include #include #include #include #include #include #include "wdg/scroll_area_vertical.hpp" namespace Views { Multi_Page_Dialog::Multi_Page_Dialog ( QWidget * parent_n, Qt::WindowFlags flags_n ) : ::Views::Basic_Dialog ( parent_n, flags_n ) { { _pages_model = new QStandardItemModel ( this ); _page_selection = new QListView; _page_selection->setModel ( _pages_model ); // QueuedConnection to paint update the tree view before // painting heavy new widgets connect ( _page_selection->selectionModel(), SIGNAL ( currentChanged ( const QModelIndex &, const QModelIndex & ) ), this, SLOT ( page_changed ( const QModelIndex &, const QModelIndex & ) ), Qt::QueuedConnection ); } // Close button layout QHBoxLayout * lay_close ( new QHBoxLayout ); { QPushButton * btn_close ( create_close_button() ); lay_close->setContentsMargins ( 0, 0, 0, 0 ); lay_close->addStretch ( 1 ); lay_close->addWidget ( btn_close, 0 ); lay_close->addStretch ( 1 ); } // Page selection widget QWidget * navi_wdg ( new QWidget ); { QVBoxLayout * lay_vbox ( new QVBoxLayout ); lay_vbox->setContentsMargins ( 0, 0, 0, 0 ); lay_vbox->addWidget ( _page_selection, 1 ); lay_vbox->addLayout ( lay_close, 0 ); navi_wdg->setLayout ( lay_vbox ); } // Page display widget QWidget * pages_wdg ( new QWidget ); { QHBoxLayout * lay_pages ( new QHBoxLayout ); lay_pages->setContentsMargins ( 0, 0, 0, 0 ); pages_wdg->setLayout ( lay_pages ); _lay_pages_stack = new QStackedLayout; _lay_pages_stack->setContentsMargins ( 0, 0, 0, 0 ); lay_pages->addSpacing ( fontMetrics().averageCharWidth() * 3 / 2 ); lay_pages->addLayout ( _lay_pages_stack ); } // Main splitter and layout { QSplitter * hsplit ( new QSplitter ); hsplit->setChildrenCollapsible ( false ); hsplit->addWidget ( navi_wdg ); hsplit->addWidget ( pages_wdg ); hsplit->setStretchFactor ( 0, 2 ); hsplit->setStretchFactor ( 1, 5 ); set_central_widget ( hsplit ); } } Multi_Page_Dialog::~Multi_Page_Dialog ( ) { } void Multi_Page_Dialog::add_page_vscroll ( const QString & name_n, QWidget * wdg_n ) { if ( wdg_n == 0 ) { return; } // Add widget { ::Wdg::Scroll_Area_Vertical * vscroll ( new ::Wdg::Scroll_Area_Vertical ); vscroll->setFrameStyle ( QFrame::NoFrame ); vscroll->set_widget ( wdg_n ); add_page ( name_n, vscroll ); } } void Multi_Page_Dialog::add_page ( const QString & name_n, QWidget * wdg_n ) { if ( wdg_n == 0 ) { return; } // Add widget _lay_pages_stack->addWidget ( wdg_n ); // Add selection entry { QStandardItem * sitem ( new QStandardItem ); sitem->setText ( name_n ); sitem->setToolTip ( name_n ); sitem->setSelectable ( true ); sitem->setEditable ( false ); _pages_model->appendRow ( sitem ); } } unsigned int Multi_Page_Dialog::num_pages ( ) const { return _lay_pages_stack->count(); } int Multi_Page_Dialog::current_page_idx ( ) const { return _lay_pages_stack->currentIndex(); } void Multi_Page_Dialog::set_current_page_idx ( int idx_n ) { _page_selection->setCurrentIndex ( _pages_model->index ( idx_n, 0, QModelIndex() ) ); } void Multi_Page_Dialog::page_changed ( const QModelIndex & cur_n, const QModelIndex & ) { page_selected ( cur_n ); } void Multi_Page_Dialog::page_selected ( const QModelIndex & index_n ) { QModelIndex root_idx; for ( int ii=0; ii < _pages_model->rowCount ( root_idx ); ++ii ) { if ( _pages_model->index ( ii, 0, root_idx ) == index_n ) { _lay_pages_stack->setCurrentIndex ( ii ); break; } } } } // End of namespace qastools-v0.22.0/shared/src/views/multi_page_dialog.hpp000066400000000000000000000023711354534512100232040ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_views_multi_page_dialog_hpp__ #define __INC_views_multi_page_dialog_hpp__ #include #include #include #include #include #include #include "basic_dialog.hpp" namespace Views { /// @brief Multi_Page_Dialog /// class Multi_Page_Dialog : public ::Views::Basic_Dialog { Q_OBJECT // Public methods public: Multi_Page_Dialog ( QWidget * parent_n = 0, Qt::WindowFlags flags_n = 0 ); ~Multi_Page_Dialog ( ); void add_page_vscroll ( const QString & name_n, QWidget * wdg_n ); void add_page ( const QString & name_n, QWidget * wdg_n ); unsigned int num_pages ( ) const; int current_page_idx ( ) const; void set_current_page_idx ( int idx_n ); // Protected slots protected slots: void page_changed ( const QModelIndex & cur_n, const QModelIndex & prev_n ); void page_selected ( const QModelIndex & index_n ); // Protected methods protected: // Private attributes private: // Pages QListView * _page_selection; QStackedLayout * _lay_pages_stack; QStandardItemModel * _pages_model; }; } // End of namespace #endif qastools-v0.22.0/shared/src/views/view_base.cpp000066400000000000000000000020521354534512100214720ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "view_base.hpp" #include "mwdg/mixer_device_setup.hpp" #include "views/message_widget.hpp" #include #include namespace Views { View_Base::View_Base ( QWidget * parent_n ) : QWidget ( parent_n ), _mdev_setup ( 0 ), _inputs_setup ( 0 ), _message_wdg ( 0 ) { _message_wdg = new ::Views::Message_Widget ( this ); _message_wdg->hide(); _lay_stack = new QStackedLayout; _lay_stack->addWidget ( _message_wdg ); QVBoxLayout * lay_vbox ( new QVBoxLayout ); lay_vbox->addLayout ( _lay_stack ); setLayout ( lay_vbox ); } View_Base::~View_Base ( ) { } void View_Base::set_mdev_setup ( const ::MWdg::Mixer_Device_Setup * setup_n ) { //::std::cout << "View_Base::set_mdev_setup: " << setup_n << "\n"; _mdev_setup = setup_n; } void View_Base::set_inputs_setup ( const ::MWdg::Inputs_Setup * setup_n ) { //::std::cout << "View_Base::set_inputs_setup: " << setup_n << "\n"; _inputs_setup = setup_n; } } // End of namespace qastools-v0.22.0/shared/src/views/view_base.hpp000066400000000000000000000040271354534512100215030ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_view_view_base_hpp__ #define __INC_view_view_base_hpp__ #include #include // Forward declaration namespace MWdg { class Mixer_Device_Setup; class Inputs_Setup; } namespace Views { class Message_Widget; class View_Base_Setup; } namespace Views { class View_Base : public QWidget { Q_OBJECT // Public methods public: View_Base ( QWidget * parent_n = 0 ); virtual ~View_Base ( ); /// The stacked layout holds the actual view widget and a /// (most times) hidden message widget that can be used for /// displaying error or info texts. QStackedLayout * lay_stack ( ) const; /// @brief The message widget is mostly used for error messages /// Message_Widget * message_wdg ( ); // Mixer device setup /// @brief Mixer device setup /// /// @return The setup const ::MWdg::Mixer_Device_Setup * mdev_setup ( ); virtual void set_mdev_setup ( const ::MWdg::Mixer_Device_Setup * setup_n ); // Input setup (keyboard/mouse) /// @brief Inputs (keyboard/mouse) setup /// /// @return The setup const ::MWdg::Inputs_Setup * inputs_setup ( ); virtual void set_inputs_setup ( const ::MWdg::Inputs_Setup * setup_n ); // View setup (colors, element selection, etc.) virtual void set_view_setup ( ::Views::View_Base_Setup * setup_n ) = 0; // Signals signals: void sig_mdev_reload_request ( ); // Private attributes private: const ::MWdg::Mixer_Device_Setup * _mdev_setup; const ::MWdg::Inputs_Setup * _inputs_setup; ::Views::Message_Widget * _message_wdg; QStackedLayout * _lay_stack; }; inline const ::MWdg::Mixer_Device_Setup * View_Base::mdev_setup ( ) { return _mdev_setup; } inline const ::MWdg::Inputs_Setup * View_Base::inputs_setup ( ) { return _inputs_setup; } inline QStackedLayout * View_Base::lay_stack ( ) const { return _lay_stack; } inline Message_Widget * View_Base::message_wdg ( ) { return _message_wdg; } } // End of namespace #endif qastools-v0.22.0/shared/src/views/view_base_setup.cpp000066400000000000000000000004531354534512100227150ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "view_base_setup.hpp" namespace Views { View_Base_Setup::View_Base_Setup ( ) : wdg_style_db ( 0 ), image_alloc ( 0 ) { } View_Base_Setup::~View_Base_Setup ( ) { } } // End of namespace qastools-v0.22.0/shared/src/views/view_base_setup.hpp000066400000000000000000000011721354534512100227210ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_views_view_base_setup_hpp__ #define __INC_views_view_base_setup_hpp__ // Forward declaration namespace dpe { class Image_Allocator; } namespace Wdg { class DS_Widget_Style_Db; } namespace Views { /// @brief View_Base general static setup variables /// class View_Base_Setup { // Public methods public: View_Base_Setup ( ); virtual ~View_Base_Setup ( ); // Public attributes public: const ::Wdg::DS_Widget_Style_Db * wdg_style_db; ::dpe::Image_Allocator * image_alloc; }; } // End of namespace #endif qastools-v0.22.0/shared/src/views/view_utility.cpp000066400000000000000000000065701354534512100222740ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "view_utility.hpp" #include "qastools_config.hpp" #include #include #include #include #include #include #include namespace Views { void load_translators ( QApplication * app_n ) { // Application translators setup { QTranslator * trans_qt ( new QTranslator ( app_n ) ); QTranslator * trans_default ( new QTranslator ( app_n ) ); QTranslator * trans_local ( new QTranslator ( app_n ) ); { QString l10n_db ( "qt_" ); l10n_db.append ( QLocale::system().name() ); trans_qt->load ( l10n_db, QLibraryInfo::location ( QLibraryInfo::TranslationsPath ) ); } { QString l10n_db ( L10N_PREFIX ); l10n_db.append ( "default" ); trans_default->load ( l10n_db, INSTALL_DIR_L10N ); } { QString l10n_db ( L10N_PREFIX ); l10n_db.append ( QLocale::system().name() ); trans_local->load ( l10n_db, INSTALL_DIR_L10N ); } app_n->installTranslator ( trans_qt ); app_n->installTranslator ( trans_default ); app_n->installTranslator ( trans_local ); } } void load_application_icon ( QApplication * app_n, const QString & fallback_n ) { QIcon icon; { // Try application icon QString icon_path ( INSTALL_DIR_ICONS_SVG ); icon_path += "/"; icon_path += PROGRAM_NAME; icon_path += ".svg"; QFileInfo finfo ( icon_path ); if ( finfo.exists() && finfo.isReadable() ) { icon = QIcon ( icon_path ); } } if ( icon.isNull() ) { // Try system theme icon if ( QIcon::hasThemeIcon ( fallback_n ) ) { icon = QIcon::fromTheme ( fallback_n ); } } if ( !icon.isNull() ) { app_n->setWindowIcon ( icon ); } } bool win_default_geometry ( QRect & rect_n ) { const unsigned int aspect[2] = { 16, 9 }; const QRect ravail ( QApplication::desktop()->availableGeometry() ); const bool res ( ravail.isValid() ); if ( res ) { QSize rsize; { // Calculate window size from available screen area unsigned int rel_width[2]; if ( ravail.width() > 1024 ) { // Larger screens rel_width[0] = 2; rel_width[1] = 3; } else { // Small screens - occupy more relative space rel_width[0] = 3; rel_width[1] = 4; } rsize.setWidth ( ( ravail.width() * rel_width[0] ) / rel_width[1] ); rsize.setHeight ( ( rsize.width() * aspect[1] ) / aspect[0] ); if ( rsize.width() > ravail.width() ) { rsize.setWidth ( ravail.width() ); } if ( rsize.height() > ravail.height() ) { rsize.setHeight ( ravail.height() ); } } rect_n.setSize ( rsize ); rect_n.moveTop ( ( ravail.height() - rect_n.height() ) / 2 ); rect_n.moveLeft ( ( ravail.width() - rect_n.width() ) / 2 ); } else { const QSize default_size ( 800, 450 ); rect_n.setSize ( default_size ); } return res; } bool win_default_size ( QSize & size_n ) { QRect rhint; if ( ::Views::win_default_geometry ( rhint ) ) { if ( size_n.width() < rhint.width() ) { size_n.setWidth ( rhint.width() ); } if ( size_n.height() < rhint.height() ) { size_n.setHeight ( rhint.height() ); } return true; } return false; } void resize_to_default ( QMainWindow * mwin_n ) { QRect wrect; if ( win_default_geometry ( wrect ) ) { mwin_n->resize ( wrect.size() ); mwin_n->move ( wrect.topLeft() ); } else { mwin_n->resize ( wrect.size() ); } } } // End of namespace qastools-v0.22.0/shared/src/views/view_utility.hpp000066400000000000000000000012071354534512100222710ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_views_view_utility_hpp__ #define __INC_views_view_utility_hpp__ #include #include namespace Views { void load_translators ( QApplication * app_n ); void load_application_icon ( QApplication * app_n, const QString & fallback_n ); /// @return true on successful size determination bool win_default_geometry ( QRect & rect_n ); /// @return true on successful size determination bool win_default_size ( QSize & size_n ); void resize_to_default ( QMainWindow * mwin_n ); } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/000077500000000000000000000000001354534512100164475ustar00rootroot00000000000000qastools-v0.22.0/shared/src/wdg/balloon_widget.cpp000066400000000000000000000104561354534512100221520ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "balloon_widget.hpp" #include #include #include #include #include #include #include #include namespace Wdg { Balloon_Widget::Balloon_Widget ( QWidget * parent_n ) : QWidget ( parent_n, Qt::ToolTip ), _update_pxmap ( true ), _stay_on_hover ( true ), _remains_on_hover ( false ) { setFocusPolicy ( Qt::NoFocus ); _close_timer.setInterval ( 6000 ); _close_timer.setSingleShot ( true ); connect ( &_close_timer, SIGNAL ( timeout() ), this, SLOT ( close_timeout() ) ); hide(); { int mg_h ( fontMetrics().height() ); int mg_v ( mg_h * 3 / 4 ); setContentsMargins ( mg_h, mg_v, mg_h, mg_v ); } { QVBoxLayout * lay_vbox ( new QVBoxLayout ); lay_vbox->setContentsMargins ( 0, 0, 0, 0 ); setLayout ( lay_vbox ); } } void Balloon_Widget::add_widget ( QWidget * wdg_n ) { layout()->addWidget ( wdg_n ); } unsigned int Balloon_Widget::duration_ms ( ) const { return qMax ( 0, _close_timer.interval() ); } void Balloon_Widget::set_duration_ms ( unsigned int ms_n ) { _close_timer.setInterval ( ms_n ); } void Balloon_Widget::set_stay_on_hover ( bool flag_n ) { _stay_on_hover = flag_n; } void Balloon_Widget::set_tray_icon_geometry ( const QRect & geom_n ) { if ( _tray_icon_geom != geom_n ) { _tray_icon_geom = geom_n; update_geometry(); } } void Balloon_Widget::update_geometry ( ) { if ( !_tray_icon_geom.isValid() ) { return; } const QPoint ti_tl ( _tray_icon_geom.topLeft() ); QRect srect; QRect arect; { QDesktopWidget * desk_wdg ( QApplication::desktop() ); srect = desk_wdg->screenGeometry ( ti_tl ); arect = desk_wdg->availableGeometry ( ti_tl ); } QSize nsize ( minimumSizeHint() ); QPoint npos; unsigned int mg_hor ( fontMetrics().averageCharWidth() ); unsigned int mg_vert ( fontMetrics().height() / 2 ); // Find corner if ( ti_tl.x() < ( srect.left() + srect.width() - ti_tl.x() ) ) { // Left npos.setX ( arect.left() + mg_hor ); } else { // Right npos.setX ( arect.left() + arect.width() - nsize.width() - mg_hor ); } if ( ti_tl.y() < ( srect.top() + srect.height() - ti_tl.y() ) ) { // Top npos.setY ( arect.top() + mg_vert); } else { // Bottom npos.setY ( arect.top() + arect.height() - nsize.height() - mg_vert ); } move ( npos ); resize ( nsize ); } void Balloon_Widget::update_mask ( ) { QBitmap mask ( size() ); mask.fill ( Qt::color0 ); { QPainter pnt ( &mask ); pnt.setRenderHints ( QPainter::Antialiasing | QPainter::SmoothPixmapTransform ); pnt.setPen ( Qt::NoPen ); pnt.setBrush ( QBrush ( Qt::color1 ) ); { QRectF rectf ( rect() ); pnt.drawRoundedRect ( rectf, _corner_rad, _corner_rad ); } } setMask ( mask ); } void Balloon_Widget::update_pixmap ( ) { QImage img ( size(), QImage::Format_ARGB32_Premultiplied ); img.fill ( 0 ); { QPainter pnt ( &img ); pnt.setRenderHints ( QPainter::Antialiasing | QPainter::SmoothPixmapTransform ); { QPen pen ( palette().color ( QPalette::WindowText ), _border_width ); pnt.setPen ( pen ); QBrush brush ( palette().color ( QPalette::Window ) ); pnt.setBrush ( brush ); } { QRectF rectf ( rect() ); const double adj ( _border_width / 2.0 ); rectf.adjust ( adj, adj, -adj, -adj ); pnt.drawRoundedRect ( rectf, _corner_rad, _corner_rad ); } } _pxmap = QPixmap::fromImage ( img ); } void Balloon_Widget::start_show ( ) { if ( _tray_icon_geom.isValid() ) { _remains_on_hover = false; show(); _close_timer.start(); } } void Balloon_Widget::close_timeout ( ) { if ( _stay_on_hover ) { if ( underMouse() ) { _remains_on_hover = true; } } if ( !_remains_on_hover ) { emit sig_close(); } } void Balloon_Widget::leaveEvent ( QEvent * event_n ) { QWidget::leaveEvent ( event_n ); if ( _remains_on_hover ) { _remains_on_hover = false; emit sig_close(); } } void Balloon_Widget::resizeEvent ( QResizeEvent * event_n ) { _update_pxmap = true; QWidget::resizeEvent ( event_n ); } void Balloon_Widget::paintEvent ( QPaintEvent * ) { if ( _update_pxmap ) { _update_pxmap = false; update_mask(); update_pixmap(); } { QPainter pnt ( this ); pnt.drawPixmap ( QPoint ( 0, 0 ), _pxmap ); } } } // End of namespace qastools-v0.22.0/shared/src/wdg/balloon_widget.hpp000066400000000000000000000033701354534512100221540ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_balloon_widget_hpp__ #define __INC_balloon_widget_hpp__ #include #include namespace Wdg { /// @brief Balloon_Widget /// class Balloon_Widget : public QWidget { Q_OBJECT // Public methods public: Balloon_Widget ( QWidget * parent_n = 0 ); // Duration unsigned int duration_ms ( ) const; void set_duration_ms ( unsigned int ms_n ); /// @brief Stay visible if widget is under mouse /// /// @return The flag - true by default bool stay_on_hover ( ) const; void set_stay_on_hover ( bool flag_n ); // Tray icon geometry const QRect & tray_icon_geometry ( ) const; void set_tray_icon_geometry ( const QRect & geom_n ); // Widgets void add_widget ( QWidget * wdg_n ); // Public signals signals: void sig_close ( ); // Public slots public slots: void start_show ( ); // Protected methods protected: void leaveEvent ( QEvent * event_n ); void resizeEvent ( QResizeEvent * event_n ); void paintEvent ( QPaintEvent * event_n ); // Private slots private slots: void close_timeout ( ); // Private methods private: void update_mask ( ); void update_pixmap ( ); void update_geometry ( ); // Private attributes private: QPixmap _pxmap; QRect _tray_icon_geom; QTimer _close_timer; static const unsigned int _border_width = 1; static const unsigned int _corner_rad = 6; bool _update_pxmap; bool _stay_on_hover; bool _remains_on_hover; }; inline bool Balloon_Widget::stay_on_hover ( ) const { return _stay_on_hover; } inline const QRect & Balloon_Widget::tray_icon_geometry ( ) const { return _tray_icon_geom; } } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/color_methods.cpp000066400000000000000000000015451354534512100220210ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "color_methods.hpp" namespace Wdg { QColor col_mix ( const QColor & col_1, const QColor & col_2, int w_1, int w_2 ) { const int wsum ( w_1 + w_2 ); unsigned int com1[4]; com1[0] = col_1.alpha(); com1[1] = col_1.red(); com1[2] = col_1.green(); com1[3] = col_1.blue(); for ( int ii=0; ii<4; ++ii ) { com1[ii] *= w_1; } { unsigned int com2[4]; com2[0] = col_2.alpha(); com2[1] = col_2.red(); com2[2] = col_2.green(); com2[3] = col_2.blue(); for ( int ii=0; ii<4; ++ii ) { com2[ii] *= w_2; } // Mix for ( int ii=0; ii<4; ++ii ) { com1[ii] += com2[ii]; } } // Rescale for ( int ii=0; ii<4; ++ii ) { com1[ii] /= wsum; } QColor res ( com1[1], com1[2], com1[3], com1[0] ); return res; } } // End of namespace qastools-v0.22.0/shared/src/wdg/color_methods.hpp000066400000000000000000000005121354534512100220170ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_wdg_color_methods_hpp__ #define __INC_wdg_color_methods_hpp__ #include namespace Wdg { QColor col_mix ( const QColor & col_1, const QColor & col_2, int w_1, int w_2 ); } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/cubic_curve.cpp000066400000000000000000000017371354534512100214540ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "cubic_curve.hpp" #include namespace Wdg { Cubic_Curve::Cubic_Curve ( ) { for ( int ii=0; ii < 4; ++ii ) { _coeff[ii] = 0.0; } } void Cubic_Curve::set_params ( double x0_n, double v0_n, double x1_n, double time_n ) { double xdiff ( x1_n - x0_n ); double tt ( time_n ); double tt2 ( tt*tt ); double tt3 ( tt*tt*tt ); _coeff[0] = x0_n; _coeff[1] = v0_n; _coeff[2] = ( 3.0 * xdiff / tt2 ) - ( 2.0 * v0_n / tt ); _coeff[3] = ( v0_n / tt2 ) - ( 2.0 * xdiff / tt3 ); } double Cubic_Curve::eval ( double pos_n ) const { double res ( _coeff[0] ); res += _coeff[1]*(pos_n); res += _coeff[2]*(pos_n*pos_n); res += _coeff[3]*(pos_n*pos_n*pos_n); return res; } double Cubic_Curve::eval_speed ( double pos_n ) const { double res ( _coeff[1] ); res += 2.0*_coeff[2]*(pos_n); res += 3.0*_coeff[3]*(pos_n*pos_n); return res; } } // End of namespace qastools-v0.22.0/shared/src/wdg/cubic_curve.hpp000066400000000000000000000010001354534512100214400ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_cubic_curve_hpp__ #define __INC_cubic_curve_hpp__ namespace Wdg { class Cubic_Curve { // Public methods public: Cubic_Curve ( ); double eval ( double pos_n ) const; double eval_speed ( double pos_n ) const; void set_params ( double x0_n, double v0_n, double x1_n, double time_n ); // Private attributes private: double _coeff[4]; }; } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/ds_imaging.cpp000066400000000000000000000033411354534512100212550ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "ds_imaging.hpp" #include "dpe/image_set_meta.hpp" #include "dpe/image_request.hpp" #include "dpe/image_allocator.hpp" #include "wdg/ds_widget_types.hpp" #include namespace Wdg { DS_Imaging::DS_Imaging ( unsigned int num_image_groups_n, ::dpe::Image_Allocator * alloc_n ) : _images ( num_image_groups_n ), _image_request ( 0 ), _image_alloc ( alloc_n ), _request_sent ( false ) { _image_request = new ::dpe::Image_Request ( &_images ); } DS_Imaging::~DS_Imaging ( ) { set_image_alloc ( 0 ); delete _image_request; } void DS_Imaging::set_image_alloc ( ::dpe::Image_Allocator * alloc_n ) { if ( _image_alloc == alloc_n ) { return; } if ( _image_alloc != 0 ) { wait_for_request(); _image_alloc->return_group ( &_images ); } _image_alloc = alloc_n; } void DS_Imaging::set_images_variant_id ( unsigned int variant_n ) { for ( unsigned int ii=0; ii < image_request()->meta.size() ; ++ii ) { image_request()->meta[ii]->group_variant = variant_n; } } void DS_Imaging::set_images_style_id ( unsigned int style_n ) { for ( unsigned int ii=0; ii < image_request()->meta.size() ; ++ii ) { image_request()->meta[ii]->style_id = style_n; } } void DS_Imaging::set_images_style_sub_id ( unsigned int style_n ) { for ( unsigned int ii=0; ii < image_request()->meta.size() ; ++ii ) { image_request()->meta[ii]->style_sub_id = style_n; } } unsigned int DS_Imaging::style_sub_id ( QWidget * wdg_n ) { unsigned int res ( ::Wdg::ST_NORMAL ); if ( !wdg_n->isEnabled() ) { res = ::Wdg::ST_DISABLED; } else if ( !wdg_n->isActiveWindow() ) { res = ::Wdg::ST_INACTIVE; } return res; } } // End of namespace qastools-v0.22.0/shared/src/wdg/ds_imaging.hpp000066400000000000000000000034231354534512100212630ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_wdg_ds_imaging_hpp__ #define __INC_wdg_ds_imaging_hpp__ #include "dpe/image_set_group.hpp" #include "dpe/image_allocator.hpp" #include "dpe/image_request.hpp" // Forward declaration class QWidget; namespace Wdg { /// @brief DS_Imaging /// class DS_Imaging { // Public methods public: DS_Imaging ( unsigned int num_image_groups_n, ::dpe::Image_Allocator * alloc_n = 0 ); ~DS_Imaging ( ); // Image set group allocation ::dpe::Image_Allocator * image_alloc ( ) const; void set_image_alloc ( ::dpe::Image_Allocator * alloc_n ); ::dpe::Image_Set_Group & images ( ); ::dpe::Image_Request * image_request ( ) const; void send_request ( ); void wait_for_request ( ); void set_images_variant_id ( unsigned int variant_n ); void set_images_style_id ( unsigned int style_n ); void set_images_style_sub_id ( unsigned int style_n ); static unsigned int style_sub_id ( QWidget * wdg_n ); // Private attributes private: // Image allocation sets ::dpe::Image_Set_Group _images; ::dpe::Image_Request * _image_request; ::dpe::Image_Allocator * _image_alloc; bool _request_sent; }; inline ::dpe::Image_Set_Group & DS_Imaging::images ( ) { return _images; } inline ::dpe::Image_Request * DS_Imaging::image_request ( ) const { return _image_request; } inline ::dpe::Image_Allocator * DS_Imaging::image_alloc ( ) const { return _image_alloc; } inline void DS_Imaging::send_request ( ) { _request_sent = true; _image_alloc->send_request ( image_request() ); } inline void DS_Imaging::wait_for_request ( ) { if ( _request_sent ) { _request_sent = false; image_request()->wait_for_finish(); } } } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/ds_slider.cpp000066400000000000000000000555201354534512100211320ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "ds_slider.hpp" #include "dpe/image_set.hpp" #include "dpe/image_request.hpp" #include "dpe/image_allocator.hpp" #include "wdg/ds_widget_types.hpp" #include "wdg/ds_widget_style_db.hpp" #include "wdg/color_methods.hpp" #include #include #include #include #include #include #include namespace Wdg { DS_Slider::DS_Slider ( QWidget * parent_n, ::dpe::Image_Allocator * alloc_n ) : QWidget ( parent_n ), _dsi ( 4, alloc_n ), _current_index ( 0 ), _maximum_index ( 0 ), _wheel_degrees ( 720 ), _step_single ( 0 ), _step_page ( 0 ), _handle_pos ( 0 ), _handle_pos_index ( 0 ), _handle_pos_hint ( 0 ), _handle_pos_max ( 0 ), _map_hp_idx ( 0 ), _map_idx_hp ( 0 ), _slider_down ( false ), _update_pixmaps_pending ( false ), _update_painter_pending ( false ), _cursor_select_allowed ( false ), _cursor_over_handle ( false ), _cursor_value_hinting ( false ), _anim_run_snap ( false ), _meta_bg ( num_images_bg, ::Wdg::DS_SLIDER, 0 ), _meta_marker ( num_images_marker, ::Wdg::DS_SLIDER, 1 ), _meta_frame ( num_images_frame, ::Wdg::DS_SLIDER, 2 ), _meta_handle ( num_images_handle, ::Wdg::DS_SLIDER, 3 ), _wdg_style_db ( 0 ) { _dsi.image_request()->meta[0] = &_meta_bg; _dsi.image_request()->meta[1] = &_meta_marker; _dsi.image_request()->meta[2] = &_meta_frame; _dsi.image_request()->meta[3] = &_meta_handle; { QSizePolicy policy ( sizePolicy() ); policy.setHorizontalPolicy ( QSizePolicy::Expanding ); policy.setVerticalPolicy ( QSizePolicy::Expanding ); setSizePolicy ( policy ); } setFocusPolicy ( Qt::StrongFocus ); setMouseTracking ( true ); // Animation timer { const unsigned int fps ( 60 ); _anim_timer.setInterval ( 1000 / fps ); connect ( &_anim_timer, SIGNAL ( timeout() ), this, SLOT ( anim_tick() ) ); } update_index_mappers(); _update_painter_pending = true; } DS_Slider::~DS_Slider ( ) { _dsi.set_image_alloc ( 0 ); clear_index_mappers(); } QSize DS_Slider::sizeHint ( ) const { const int def_len ( fontMetrics().height() ); return QSize ( def_len, def_len*10 ); } QSize DS_Slider::minimumSizeHint ( ) const { const int def_len ( fontMetrics().height() ); return QSize ( def_len, def_len*4 ); } void DS_Slider::set_image_alloc ( ::dpe::Image_Allocator * alloc_n ) { _dsi.set_image_alloc ( alloc_n ); } void DS_Slider::set_wdg_style_db ( const ::Wdg::DS_Widget_Style_Db * db_n ) { if ( _wdg_style_db != db_n ) { _wdg_style_db = db_n; _update_painter_pending = true; } } void DS_Slider::set_style_id ( unsigned int id_n ) { if ( style_id() != id_n ) { _dsi.set_images_style_id ( id_n ); _update_painter_pending = true; } } void DS_Slider::set_wheel_degrees ( unsigned int degrees_n ) { _wheel_degrees = ( degrees_n > 0 ) ? degrees_n : 1; } void DS_Slider::set_current_index ( unsigned long idx_n ) { if ( idx_n > maximum_index() ) { idx_n = maximum_index(); } if ( current_index() != idx_n ) { _current_index = idx_n; this->current_index_changed(); emit sig_current_index_changed ( idx_n ); } } void DS_Slider::adjust_current_index ( long idx_delta_n ) { unsigned long idx ( current_index() ); if ( idx_delta_n >= 0 ) { unsigned long dplus ( idx_delta_n ); if ( dplus >= maximum_index() ) { idx = maximum_index(); } else { if ( ( maximum_index() - dplus ) <= idx ) { idx = maximum_index(); } else { idx += dplus; } } } else { unsigned long dplus ( -idx_delta_n ); if ( dplus > idx ) { idx = 0; } else { idx -= dplus; } } set_current_index ( idx ); } void DS_Slider::set_maximum_index ( unsigned long idx_n ) { if ( maximum_index() != idx_n ) { _maximum_index = idx_n; this->maximum_index_changed(); emit sig_maximum_index_changed ( idx_n ); } } void DS_Slider::set_slider_down ( bool down_n ) { _slider_down = down_n; } void DS_Slider::current_index_changed ( ) { _handle_pos_index = map_index_to_handle_pos ( current_index() ); if ( !slider_down() ) { anim_snap_start(); } update(); } void DS_Slider::maximum_index_changed ( ) { update_index_mappers(); if ( current_index() > maximum_index() ) { set_current_index ( maximum_index() ); } unsigned long delta ( maximum_index() ); unsigned long div; unsigned long val; unsigned long mod; // Single step div = 100; val = delta / div; mod = delta % div; if ( mod > ( div / 2 ) ) { ++val; } if ( val == 0 ) { ++val; } _step_single = val; // Page step div = 12; val = delta / div; mod = delta % div; if ( mod > ( div / 2 ) ) { ++val; } if ( val == 0 ) { ++val; } _step_page = val; // Update pixmap config _meta_bg.ticks_max_idx = delta; update_pixmaps(); } unsigned long DS_Slider::map_handle_pos_to_index ( int handle_pos_n ) { unsigned long res ( 0 ); if ( handle_pos_n <= 0 ) { res = maximum_index(); } else { unsigned int hpos ( handle_pos_n ); if ( hpos <= _handle_pos_max ) { hpos = _handle_pos_max - hpos; res = _map_hp_idx->map ( hpos ); } } return res; } unsigned int DS_Slider::map_index_to_handle_pos ( unsigned long idx_n ) { unsigned int res ( _handle_pos_max ); if ( idx_n <= maximum_index() ) { res = _map_idx_hp->map ( idx_n ); if ( res > _handle_pos_max ) { res = 0; } else { res = _handle_pos_max - res; } } return res; } unsigned int DS_Slider::map_tick_pos_to_handle_pos ( int tick_pos_n ) { unsigned int res ( 0 ); const int delta ( _handle_rect.height() / 2 ); if ( tick_pos_n > delta ) { res = ( tick_pos_n - delta ); if ( res > _handle_pos_max ) { res = _handle_pos_max; } } return res; } unsigned int DS_Slider::map_handle_pos_to_tick_pos ( int handle_pos_n ) { unsigned int res ( 0 ); if ( handle_pos_n > 0 ) { res = handle_pos_n; if ( res > _handle_pos_max ) { res = _handle_pos_max; } } res += ( _handle_rect.height() / 2 ); return res; } unsigned int DS_Slider::map_index_to_tick_pos ( unsigned long idx_n ) { unsigned int res = map_index_to_handle_pos ( idx_n ); res = map_handle_pos_to_tick_pos ( res ); return res; } unsigned long DS_Slider::map_tick_pos_to_index ( int tick_pos_n ) { unsigned long res = map_tick_pos_to_handle_pos ( tick_pos_n ); res = map_handle_pos_to_index ( res ); return res; } void DS_Slider::clear_index_mappers ( ) { if ( _map_idx_hp != 0 ) { delete _map_idx_hp; _map_idx_hp = 0; } if ( _map_hp_idx != 0 ) { delete _map_hp_idx; _map_hp_idx = 0; } } void DS_Slider::update_index_mappers ( ) { clear_index_mappers(); if ( maximum_index() > _handle_pos_max ) { _map_idx_hp = new UInt_Mapper_Down ( maximum_index(), _handle_pos_max ); _map_hp_idx = new UInt_Mapper_Up ( _handle_pos_max, maximum_index() ); } else { _map_idx_hp = new UInt_Mapper_Up ( maximum_index(), _handle_pos_max ); _map_hp_idx = new UInt_Mapper_Down ( _handle_pos_max, maximum_index() ); } } bool DS_Slider::update_cursor_mode ( ) { //::std::cout << "DS_Slider::update_cursor_mode " << "\n"; bool res ( false ); // Indicates a cursor mode change const QPoint cur_pos ( mapFromGlobal ( QCursor::pos() ) ); { // Check if the cursor is over the handle const bool over_handle ( _handle_rect.contains ( cur_pos ) ); if ( over_handle != _cursor_over_handle ) { _cursor_over_handle = over_handle; res = true; } } { // Update cursor value hinting const bool show_hint ( _cursor_select_allowed && rect().contains ( cur_pos ) && !_cursor_over_handle && !slider_down() ); if ( show_hint ) { unsigned long hpos; hpos = map_tick_pos_to_index ( cur_pos.y() ); hpos = map_index_to_handle_pos ( hpos ); if ( _handle_pos_hint != hpos ) { _handle_pos_hint = hpos; res = true; } } if ( _cursor_value_hinting != show_hint ) { _cursor_value_hinting = show_hint; res = true; } } { // Update cursor shape Qt::CursorShape cshape ( Qt::ArrowCursor ); if ( slider_down() ) { cshape = Qt::ClosedHandCursor; } else if ( _cursor_over_handle ) { cshape = Qt::OpenHandCursor; } else if ( _cursor_value_hinting ) { cshape = Qt::CrossCursor; } QCursor curs ( cursor() ); if ( curs.shape() != cshape ) { curs.setShape ( cshape ); setCursor ( curs ); res = true; } } return res; } bool DS_Slider::set_handle_pos ( unsigned int pos_n ) { //::std::cout << "DS_Slider::set_handle_pos " << pos_n << "\n"; if ( pos_n > _handle_pos_max ) { pos_n = _handle_pos_max; } if ( _handle_pos != pos_n ) { _handle_pos = pos_n; _handle_rect.moveTop ( _handle_pos ); return true; } return false; } void DS_Slider::update_value_from_handle_pos ( ) { unsigned long idx = map_handle_pos_to_index ( _handle_pos ); set_current_index ( idx ); } void DS_Slider::finish_handle_manipulation ( ) { set_slider_down ( false ); _handle_pos_index = map_index_to_handle_pos ( current_index() ); anim_snap_start(); update_cursor_mode(); } void DS_Slider::changeEvent ( QEvent * event_n ) { QWidget::changeEvent ( event_n ); bool upd_painter ( false ); bool upd_pixmaps ( false ); switch ( event_n->type() ) { case QEvent::ActivationChange: case QEvent::EnabledChange: upd_pixmaps = true; case QEvent::StyleChange: case QEvent::PaletteChange: case QEvent::LayoutDirectionChange: upd_painter = true; break; default: break; } if ( upd_painter ) { _update_painter_pending = true; } if ( upd_pixmaps ) { update_pixmaps(); } } // Focus events void DS_Slider::focusInEvent ( QFocusEvent * event_n ) { //::std::cout << "DS_Slider::focusInEvent " << "\n"; QWidget::focusInEvent ( event_n ); switch ( event_n->reason() ) { case Qt::MouseFocusReason: case Qt::ActiveWindowFocusReason: _cursor_select_allowed = false; break; default: _cursor_select_allowed = true; break; } update_cursor_mode(); update(); } void DS_Slider::focusOutEvent ( QFocusEvent * event_n ) { //::std::cout << "DS_Slider::focusOutEvent " << "\n"; QWidget::focusOutEvent ( event_n ); _cursor_select_allowed = false; _cursor_value_hinting = false; finish_handle_manipulation(); update(); } void DS_Slider::enterEvent ( QEvent * event_n ) { //::std::cout << "DS_Slider::enterEvent" << "\n"; QWidget::enterEvent ( event_n ); update_cursor_mode(); update(); } void DS_Slider::leaveEvent ( QEvent * event_n ) { //::std::cout << "DS_Slider::leaveEvent" << "\n"; QWidget::leaveEvent ( event_n ); update_cursor_mode(); update(); } // Mouse events void DS_Slider::mousePressEvent ( QMouseEvent * event_n ) { //::std::cout << "DS_Slider::mousePressEvent" << "\n"; QWidget::mousePressEvent ( event_n ); if ( event_n->button() == Qt::LeftButton ) { if ( _cursor_over_handle ) { // Start slider drag set_slider_down ( true ); } else { // Select a value on the slider range if ( _cursor_select_allowed ) { set_slider_down ( true ); const unsigned int hpos ( map_tick_pos_to_handle_pos ( event_n->pos().y() ) ); if ( set_handle_pos ( hpos ) ) { update_value_from_handle_pos(); } } } if ( slider_down() ) { anim_stop(); } // After a click selection should be allowed if ( hasFocus() ) { _cursor_select_allowed = true; } update_cursor_mode(); update(); } } void DS_Slider::mouseReleaseEvent ( QMouseEvent * event_n ) { //::std::cout << "DS_Slider::mouseReleaseEvent" << "\n"; QWidget::mouseReleaseEvent ( event_n ); if ( event_n->button() == Qt::LeftButton ) { if ( slider_down() ) { finish_handle_manipulation(); update(); } } } void DS_Slider::mouseMoveEvent ( QMouseEvent * event_n ) { //::std::cout << "DS_Slider::mouseMoveEvent" << "\n"; QWidget::mouseMoveEvent ( event_n ); bool do_update ( false ); if ( slider_down() ) { int delta ( 0 ); { int p_now ( event_n->pos().y() ); int p_prev ( _mouse_last.y() ); if ( p_now != p_prev ) { int p_min; int p_max; if ( p_now > p_prev ) { // For moving downwards the cursor positions must be in this range p_min = _tick_min; p_max = height() - 1; } else { // For moving upwards the cursor positions must be in this range p_min = 0; p_max = _tick_max; } p_now = qBound ( p_min, p_now, p_max ); p_prev = qBound ( p_min, p_prev, p_max ); delta = ( p_now - p_prev ); } } //::std::cout << "DS_Slider::mouseMoveEvent: Delta " << delta << "\n"; unsigned int hpos ( _handle_pos ); if ( delta < 0 ) { delta = -delta; if ( (unsigned int)delta < hpos ) { hpos -= delta; } else { hpos = 0; } } else { hpos += delta; } if ( set_handle_pos ( hpos ) ) { update_value_from_handle_pos(); do_update = true; } } _mouse_last = event_n->pos(); // Test if the cursor is over the handle if ( update_cursor_mode() ) { do_update = true; } if ( do_update ) { update(); } } void DS_Slider::wheelEvent ( QWheelEvent * event_n ) { QWidget::wheelEvent ( event_n ); if ( rect().contains ( event_n->pos() ) ) { event_n->accept(); setFocus(); long delta; { double amount ( maximum_index() / double ( _wheel_degrees ) ); amount *= ( event_n->delta() / 8.0 ); if ( amount > 0 ) { delta = ::std::ceil ( amount ); } else { delta = ::std::floor ( amount ); } } if ( delta == 0 ) { if ( event_n->delta() > 0 ) { delta = 1; } else { delta = -1; } } adjust_current_index ( delta ); } else { event_n->ignore(); } } void DS_Slider::keyPressEvent ( QKeyEvent * event_n ) { QWidget::keyPressEvent ( event_n ); long idx_adjust ( 0 ); switch ( event_n->key() ) { case Qt::Key_Left: idx_adjust = -_step_single; break; case Qt::Key_Up: idx_adjust = _step_single; break; case Qt::Key_Right: idx_adjust = _step_single; break; case Qt::Key_Down: idx_adjust = -_step_single; break; case Qt::Key_VolumeDown: idx_adjust = -_step_single; break; case Qt::Key_VolumeUp: idx_adjust = _step_single; break; case Qt::Key_PageUp: idx_adjust = _step_page; break; case Qt::Key_PageDown: idx_adjust = -_step_page; break; default: break; } if ( idx_adjust != 0 ) { adjust_current_index ( idx_adjust ); } } void DS_Slider::keyReleaseEvent ( QKeyEvent * event_n ) { QWidget::keyReleaseEvent ( event_n ); } // Window events void DS_Slider::resizeEvent ( QResizeEvent * event_n ) { //::std::cout << "DS_Slider::resizeEvent " << this << "\n"; QWidget::resizeEvent ( event_n ); anim_stop(); if ( ( width() <= 0 ) || ( height() <= 0 ) ) { return; } // Handle rect unsigned int handle_height ( width() ); handle_height += ( handle_height + 1 ) % 2; // Make odd _handle_rect.setRect ( 0, _handle_pos, width(), handle_height ); // Handle range _handle_pos_max = 0; if ( (unsigned int)height() > handle_height ) { _handle_pos_max = ( height() - handle_height ); } update_index_mappers(); _tick_min = handle_height / 2; _tick_max = _tick_min + ( _handle_pos_max + 1 ); // Update pixmap config _meta_bg.ticks_range_max_idx = _handle_pos_max; _meta_bg.ticks_range_start = handle_height / 2; // Marker size { int mww ( _handle_rect.height() / 5 ); int mhh ( _handle_rect.width() / 7 ); mww = qMin ( mww, mhh ); if ( mww < 6 ) { mww = 6; } if ( ( ( _handle_rect.width() - mww ) % 2 ) != 0 ) { --mww; } mhh = mww; if ( ( mhh % 2 ) == 0 ) { --mhh; // height should be odd } _marker_size.setWidth ( mww ); _marker_size.setHeight ( mhh ); } // Update value marker painting position offset { int off_x ( _handle_rect.width() ); int off_y ( _handle_rect.height() / 2 ); off_x -= _marker_size.width(); off_y -= _marker_size.height() / 2; off_x /= 2; _marker_offset[0] = off_x; _marker_offset[1] = off_y; } // Update handle position _handle_pos_index = map_index_to_handle_pos ( current_index() ); set_handle_pos ( _handle_pos_index ); update_cursor_mode(); update_pixmaps(); } void DS_Slider::paintEvent ( QPaintEvent * ) { if ( _update_pixmaps_pending ) { update_pixmaps(); } if ( _update_painter_pending ) { update_painter_utils(); } _dsi.wait_for_request(); if ( !_dsi.images().ready() ) { return; } QPixmap * pixmap_handle ( 0 ); QPixmap * pixmap_frame ( 0 ); QPixmap * pixmap_marker_2 ( 0 ); QPixmap * pixmap_marker_1 ( 0 ); bool draw_snap_line ( false ); QPixmap * pixmap_bg_2 ( 0 ); QPixmap * pixmap_bg_1 ( 0 ); // Items setup { // Local state buffer const bool loc_under_mouse ( underMouse() ); const bool loc_is_enabled ( isEnabled() ); const bool loc_has_focus ( hasFocus() ); const bool loc_slider_down ( slider_down() ); // Slider background setup { // Top half of the background ::dpe::Image & img ( _dsi.images().img_sets[0]->image ( 0 ) ); pixmap_bg_1 = img.convert_to_pixmap(); } { // Bottom half of the background ::dpe::Image & img ( _dsi.images().img_sets[0]->image ( 1 ) ); pixmap_bg_2 = img.convert_to_pixmap(); } // Value marker and snap line setup if ( loc_slider_down || _anim_run_snap ) { draw_snap_line = true; ::dpe::Image & img ( _dsi.images().img_sets[1]->image ( 0 ) ); pixmap_marker_1 = img.convert_to_pixmap(); } // Value hint marker setup if ( _cursor_value_hinting ) { ::dpe::Image & img ( _dsi.images().img_sets[1]->image ( 1 ) ); pixmap_marker_2 = img.convert_to_pixmap(); } // Frame setup { int idx ( -1 ); if ( loc_has_focus ) { idx = 0; } else if ( loc_under_mouse && loc_is_enabled ) { idx = 1; } if ( idx >= 0 ) { ::dpe::Image & img ( _dsi.images().img_sets[2]->image ( idx ) ); pixmap_frame = img.convert_to_pixmap(); } } // Handle setup { unsigned int idx; if ( loc_slider_down ) { idx = 4; } else { idx = loc_has_focus ? 1 : 0; if ( loc_under_mouse && loc_is_enabled ) { idx += 2; } } ::dpe::Image & img ( _dsi.images().img_sets[3]->image ( idx ) ); pixmap_handle = img.convert_to_pixmap(); } } // Painting QPainter painter ( this ); painter.setRenderHint ( QPainter::Antialiasing ); if ( ( pixmap_bg_1 != 0 ) && ( pixmap_bg_2 != 0 ) ) { const int mid_pos ( _handle_pos_index + _handle_rect.height() / 2 ); { const QRect re_img ( 0, 0, width(), mid_pos ); painter.drawPixmap ( re_img, *pixmap_bg_1, re_img ); } { const QRect re_img ( 0, mid_pos, width(), height() - mid_pos ); painter.drawPixmap ( re_img, *pixmap_bg_2, re_img ); } } if ( draw_snap_line ) { unsigned int pos_diff; if ( _handle_pos > _handle_pos_index ) { pos_diff = _handle_pos - _handle_pos_index; } else { pos_diff = _handle_pos_index - _handle_pos; } if ( pos_diff > 5 ) { const double x_mid ( width() / 2.0 ); double dx1 ( _marker_size.width() / 5.0 ); dx1 = qMax ( dx1, 1.5 ); double yy1 ( map_handle_pos_to_tick_pos ( _handle_pos ) ); double yy2 ( map_handle_pos_to_tick_pos ( _handle_pos_index ) ); yy1 += 0.5; yy2 += 0.5; const double yym ( ( yy1 + yy2 ) / 2.0 ); const int num_pts ( 6 ); QPointF pts[num_pts] = { QPointF ( x_mid + dx1, yy1 ), QPointF ( x_mid , yym ), QPointF ( x_mid + dx1, yy2 ), QPointF ( x_mid - dx1, yy2 ), QPointF ( x_mid , yym ), QPointF ( x_mid - dx1, yy1 ) }; painter.setPen ( _snap_pen ); painter.setBrush ( _snap_brush ); painter.drawPolygon ( pts, num_pts ); } } if ( pixmap_marker_1 != 0 ) { const QPointF pp ( _marker_offset[0], _marker_offset[1] + _handle_pos_index ); painter.drawPixmap ( pp, *pixmap_marker_1 ); } if ( pixmap_marker_2 != 0 ) { const QPointF pp ( _marker_offset[0], _marker_offset[1] + _handle_pos_hint ); painter.drawPixmap ( pp, *pixmap_marker_2 ); } if ( pixmap_frame != 0 ) { const QPointF pp ( 0, 0 ); painter.drawPixmap ( pp, *pixmap_frame ); } if ( pixmap_handle != 0 ) { painter.drawPixmap ( _handle_rect.topLeft(), *pixmap_handle ); } } void DS_Slider::update_pixmaps ( ) { if ( _dsi.image_alloc() != 0 ) { if ( isVisible() ) { //::std::cout << "DS_Slider::update_pixmaps " << this << "\n"; _update_pixmaps_pending = false; _dsi.wait_for_request(); _meta_bg.size = size(); _meta_marker.size = _marker_size; _meta_frame.size = size(); _meta_handle.size = _handle_rect.size(); _dsi.set_images_style_sub_id ( _dsi.style_sub_id ( this ) ); _dsi.send_request(); update(); } else { _update_pixmaps_pending = true; } } } void DS_Slider::update_painter_utils ( ) { QColor col; { if ( wdg_style_db() != 0 ) { setPalette ( wdg_style_db()->palette ( style_id() ) ); } QColor col_bg ( palette().color ( QPalette::Window ) ); QColor col_fg ( palette().color ( QPalette::WindowText ) ); col = ::Wdg::col_mix ( col_bg, col_fg, 1, 2 ); } col.setAlpha ( 70 ); _snap_pen.setStyle ( Qt::NoPen ); _snap_pen.setColor ( col ); _snap_brush.setStyle ( Qt::SolidPattern ); _snap_brush.setColor ( col ); } void DS_Slider::anim_stop ( ) { _anim_run_snap = false; _anim_timer.stop(); } void DS_Slider::anim_tick ( ) { bool do_update ( false ); if ( _anim_run_snap ) { // Passed seconds since the animation start unsigned int msec ( ::std::abs ( _anim_snap_time.elapsed() ) ); if ( msec >= _anim_snap_msec_max ) { msec = _anim_snap_msec_max; _anim_run_snap = false; } if ( anim_snap_tick ( msec ) ) { do_update = true; } if ( _handle_pos == _handle_pos_index ) { _anim_run_snap = false; do_update = true; } } if ( !_anim_run_snap ) { anim_stop(); } if ( do_update ) { update_cursor_mode(); update(); } } void DS_Slider::anim_snap_start ( ) { if ( ( _handle_pos != _handle_pos_index ) ) { // Current speed double v_x0 ( 0.0 ); if ( _anim_run_snap ) { // A snapping annimation is already running. unsigned int msec ( ::std::abs ( _anim_snap_time.elapsed() ) ); if ( msec < _anim_snap_msec_max ) { // Acquire the current speed v_x0 = double ( msec ) / 1000.0; v_x0 = _cubic_curve.eval_speed ( v_x0 ); } else { msec = _anim_snap_msec_max; } // Do a anim tick anim_snap_tick ( msec ); } else { _anim_run_snap = true; } _anim_snap_time.start(); if ( !_anim_timer.isActive() ) { _anim_timer.start(); } if ( _handle_pos_max > 0 ) { unsigned int pos_diff; if ( _handle_pos > _handle_pos_index ) { pos_diff = _handle_pos - _handle_pos_index; } else { pos_diff = _handle_pos_index - _handle_pos; } _anim_snap_msec_max = ( 800 * pos_diff ) / _handle_pos_max; } else { _anim_snap_msec_max = 500; } _anim_snap_msec_max = qBound ( 100, (int)_anim_snap_msec_max, 600 ); _cubic_curve.set_params ( _handle_pos, v_x0, _handle_pos_index, _anim_snap_msec_max / 1000.0 ); } } bool DS_Slider::anim_snap_tick ( unsigned int msec_n ) { unsigned int hpos ( _handle_pos_index ); if ( msec_n <= _anim_snap_msec_max ) { // Calculate the position from the easing curve double dpos ( double ( msec_n ) / 1000.0 ); dpos = _cubic_curve.eval ( dpos ); dpos = std::floor ( dpos + 0.5 ); // Round if ( dpos > 0.0 ) { hpos = static_cast < unsigned int > ( dpos ); } else { hpos = 0; } } return set_handle_pos ( hpos ); } } // End of namespace qastools-v0.22.0/shared/src/wdg/ds_slider.hpp000066400000000000000000000141401354534512100211300ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_ds_slider_hpp__ #define __INC_ds_slider_hpp__ #include "dpe/image_set_meta.hpp" #include "wdg/ds_slider_meta_bg.hpp" #include "wdg/ds_imaging.hpp" #include "wdg/uint_mapper.hpp" #include "wdg/cubic_curve.hpp" #include #include #include #include #include // Forward declaration namespace dpe { class Image_Request; class Image_Allocator; } namespace Wdg { class DS_Widget_Style_Db; } namespace Wdg { /// @brief Dynamic sized slider /// /// Background images: /// 0 - non_active area /// 1 - active area /// /// Frame images: /// 0 - focus /// 1 - weak focus /// /// Handle images: /// 0 - idle /// 1 - focus /// 2 - idle + hover /// 3 - focus + hover /// 4 - isDown() /// /// Marker images: /// 0 - Current value marker /// 1 - Value hint marker /// class DS_Slider : public QWidget { Q_OBJECT // Public methods public: DS_Slider ( QWidget * parent_n = 0, ::dpe::Image_Allocator * alloc_n = 0 ); ~DS_Slider ( ); // Size hints QSize sizeHint ( ) const; QSize minimumSizeHint ( ) const; // Value index unsigned long current_index ( ) const; unsigned long maximum_index ( ) const; bool slider_down ( ) const; // Image allocator and style id ::dpe::Image_Allocator * image_alloc ( ) const; void set_image_alloc ( ::dpe::Image_Allocator * alloc_n ); // Style database const ::Wdg::DS_Widget_Style_Db * wdg_style_db ( ) const; void set_wdg_style_db ( const ::Wdg::DS_Widget_Style_Db * db_n ); // Style id unsigned int style_id ( ) const; void set_style_id ( unsigned int id_n ); // Additional config ::Wdg::DS_Slider_Meta_Bg & meta_bg ( ); // Mouse wheel degrees void set_wheel_degrees ( unsigned int degrees_n ); unsigned int wheel_degrees ( ) const; // Public slots public slots: void set_current_index ( unsigned long idx_n ); void adjust_current_index ( long idx_delta_n ); void set_maximum_index ( unsigned long idx_n ); // Signals signals: void sig_current_index_changed ( unsigned long idx_n ); void sig_maximum_index_changed ( unsigned long idx_n ); // Protected methods protected: void set_slider_down ( bool down_n ); virtual void current_index_changed ( ); virtual void maximum_index_changed ( ); // Mapping: Pixel <=> Value unsigned long map_handle_pos_to_index ( int handle_pos_n ); unsigned int map_index_to_handle_pos ( unsigned long idx_n ); unsigned int map_tick_pos_to_handle_pos ( int tick_pos_n ); unsigned int map_handle_pos_to_tick_pos ( int handle_pos_n ); unsigned long map_tick_pos_to_index ( int tick_pos_n ); unsigned int map_index_to_tick_pos ( unsigned long idx_n ); void clear_index_mappers ( ); void update_index_mappers ( ); // Cursor mode bool update_cursor_mode ( ); // Handle position /// @return true if the handle position was changed bool set_handle_pos ( unsigned int pos_n ); void update_value_from_handle_pos ( ); void finish_handle_manipulation ( ); // Change events void changeEvent ( QEvent * event_n ); // Focus events void focusInEvent ( QFocusEvent * event_n ); void focusOutEvent ( QFocusEvent * event_n ); // Enter events void enterEvent ( QEvent * event_n ); void leaveEvent ( QEvent * event_n ); // Mouse events void mousePressEvent ( QMouseEvent * event_n ); void mouseReleaseEvent ( QMouseEvent * event_n ); void mouseMoveEvent ( QMouseEvent * event_n ); void wheelEvent ( QWheelEvent * event_n ); // Keyboard events void keyPressEvent ( QKeyEvent * event_n ); void keyReleaseEvent ( QKeyEvent * event_n ); // Window events void resizeEvent ( QResizeEvent * event_n ); void paintEvent ( QPaintEvent * event_n ); /// @brief Fetches new pixmaps from the image buffers void update_pixmaps ( ); void update_painter_utils ( ); // Private slots private slots: void anim_tick ( ); // Private methods private: void anim_stop ( ); void anim_snap_start ( ); bool anim_snap_tick ( unsigned int msec_n ); // Private attributes private: static const unsigned int num_images_bg = 2; static const unsigned int num_images_marker = 2; static const unsigned int num_images_frame = 2; static const unsigned int num_images_handle = 5; ::Wdg::DS_Imaging _dsi; unsigned long _current_index; unsigned long _maximum_index; unsigned int _wheel_degrees; long _step_single; long _step_page; QRect _handle_rect; QPen _snap_pen; QBrush _snap_brush; unsigned int _handle_pos; unsigned int _handle_pos_index; unsigned int _handle_pos_hint; unsigned int _handle_pos_max; int _marker_offset[2]; int _tick_min; int _tick_max; QPoint _mouse_last; UInt_Mapper * _map_hp_idx; UInt_Mapper * _map_idx_hp; bool _slider_down; bool _update_pixmaps_pending; bool _update_painter_pending; bool _cursor_select_allowed; bool _cursor_over_handle; bool _cursor_value_hinting; bool _anim_run_snap; // Animation QTimer _anim_timer; QTime _anim_snap_time; unsigned int _anim_snap_msec_max; ::Wdg::Cubic_Curve _cubic_curve; // Graphics creation QSize _marker_size; // Pixmap buffers ::Wdg::DS_Slider_Meta_Bg _meta_bg; ::dpe::Image_Set_Meta _meta_marker; ::dpe::Image_Set_Meta _meta_frame; ::dpe::Image_Set_Meta _meta_handle; const ::Wdg::DS_Widget_Style_Db * _wdg_style_db; }; inline unsigned long DS_Slider::current_index ( ) const { return _current_index; } inline unsigned long DS_Slider::maximum_index ( ) const { return _maximum_index; } inline bool DS_Slider::slider_down ( ) const { return _slider_down; } inline unsigned int DS_Slider::wheel_degrees ( ) const { return _wheel_degrees; } inline ::dpe::Image_Allocator * DS_Slider::image_alloc ( ) const { return _dsi.image_alloc(); } inline const ::Wdg::DS_Widget_Style_Db * DS_Slider::wdg_style_db ( ) const { return _wdg_style_db; } inline unsigned int DS_Slider::style_id ( ) const { return _meta_bg.style_id; } inline ::Wdg::DS_Slider_Meta_Bg & DS_Slider::meta_bg ( ) { return _meta_bg; } } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/ds_slider_meta_bg.cpp000066400000000000000000000024351354534512100226050ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "ds_slider_meta_bg.hpp" #include "wdg/ds_widget_types.hpp" namespace Wdg { DS_Slider_Meta_Bg::DS_Slider_Meta_Bg ( unsigned int num_images_n, unsigned int group_type_n, unsigned int type_id_n ) : ::dpe::Image_Set_Meta ( num_images_n, group_type_n, type_id_n ), ticks_max_idx ( 0 ), ticks_range_max_idx ( 0 ), ticks_range_start ( 0 ), bg_show_image ( 0 ), bg_tick_min_idx ( 0 ) { } DS_Slider_Meta_Bg::~DS_Slider_Meta_Bg ( ) { } bool DS_Slider_Meta_Bg::matches ( const ::dpe::Image_Set_Meta * meta_n ) const { bool res ( false ); const ::Wdg::DS_Slider_Meta_Bg * meta_c ( dynamic_cast < const ::Wdg::DS_Slider_Meta_Bg * > ( meta_n ) ); if ( meta_c != 0 ) { res = ::dpe::Image_Set_Meta::matches ( meta_n ); res = res && ( meta_c->ticks_max_idx == ticks_max_idx ); res = res && ( meta_c->ticks_range_max_idx == ticks_range_max_idx ); res = res && ( meta_c->ticks_range_start == ticks_range_start ); res = res && ( meta_c->bg_show_image == bg_show_image ); res = res && ( meta_c->bg_tick_min_idx == bg_tick_min_idx ); } return res; } ::dpe::Image_Set_Meta * DS_Slider_Meta_Bg::new_copy ( ) const { return new ::Wdg::DS_Slider_Meta_Bg ( *this ); } } // End of namespace qastools-v0.22.0/shared/src/wdg/ds_slider_meta_bg.hpp000066400000000000000000000014771354534512100226170ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_ds_slider_meta_bg_hpp__ #define __INC_ds_slider_meta_bg_hpp__ #include "dpe/image_set_meta.hpp" namespace Wdg { /// @brief DS_Slider_Meta_Bg /// class DS_Slider_Meta_Bg : public ::dpe::Image_Set_Meta { // Public methods public: DS_Slider_Meta_Bg ( unsigned int num_images_n, unsigned int group_type_n, unsigned int type_id_n ); ~DS_Slider_Meta_Bg ( ); bool matches ( const ::dpe::Image_Set_Meta * meta_n ) const; ::dpe::Image_Set_Meta * new_copy ( ) const; // Public attributes unsigned int ticks_max_idx; int ticks_range_max_idx; int ticks_range_start; // Style int bg_show_image; unsigned int bg_tick_min_idx; // Which tick has the minimum width }; } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/ds_slider_painter_bevelled.cpp000066400000000000000000000703221354534512100245130ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "ds_slider_painter_bevelled.hpp" #include "dpe/paint_job.hpp" #include "dpe/image_set.hpp" #include "dpe/image_set_meta.hpp" #include "wdg/ds_slider_meta_bg.hpp" #include "wdg/ds_widget_style_db.hpp" #include "wdg/ds_widget_types.hpp" #include "wdg/color_methods.hpp" #include "wdg/uint_mapper.hpp" #include #include #include #include #include #include #include namespace Wdg { namespace Painter { struct DS_Slider_Painter_Bevelled::PData { inline QSize & size ( ) { return meta->size; } inline int width ( ) { return meta->size.width(); } inline int height ( ) { return meta->size.height(); } ::dpe::Image_Set_Meta * meta; QPalette pal; QPainter qpnt; int ew; // Edge width int bw; // Border width x,y int bevel; int tick_width[3]; int tick_min_dist; QRectF rectf; bool has_focus; bool has_weak_focus; bool mouse_over; bool is_down; ::dpe::Image * img; ::Wdg::DS_Slider_Meta_Bg * meta_bg; }; DS_Slider_Painter_Bevelled::DS_Slider_Painter_Bevelled ( ) : ::Wdg::Painter::DS_Widget_Painter ( ::Wdg::DS_SLIDER ) { } int DS_Slider_Painter_Bevelled::paint_image ( ::dpe::Paint_Job * pjob_n ) { int res ( 0 ); // Init paint data PData pd; pd.meta = pjob_n->meta; pd.img = &pjob_n->img_set->image ( pjob_n->img_idx ); res = create_image_data ( pd.img, pd.meta ); if ( res == 0 ) { // Init general painting setup if ( wdg_style_db() != 0 ) { pd.pal = wdg_style_db()->palettes[pd.meta->style_id]; pd.pal.setCurrentColorGroup ( wdg_style_db()->color_group ( pd.meta->style_sub_id ) ); } pd.bw = pd.meta->size.width() / 24; if ( pd.bw < 2 ) { pd.bw = 2; } pd.ew = ( pd.bw / 4 ); if ( pd.ew < 1 ) { pd.ew = 1; } pd.bevel = pd.bw; pd.rectf = QRectF ( 0.0, 0.0, pd.width(), pd.height() ); // Init painter pd.qpnt.begin ( &pd.img->qimage() ); pd.qpnt.setRenderHints ( QPainter::Antialiasing | QPainter::SmoothPixmapTransform ); // Paint type switch ( pd.meta->type_id ) { case 0: res = paint_bg ( pjob_n, pd ); break; case 1: res = paint_marker ( pjob_n, pd ); break; case 2: res = paint_frame ( pjob_n, pd ); break; case 3: res = paint_handle ( pjob_n, pd ); break; } } return res; } // Background painting int DS_Slider_Painter_Bevelled::paint_bg ( ::dpe::Paint_Job * pjob_n, PData & pd ) { //::std::cout << "DS_Slider_Painter_Bevelled::paint_bg " << "\n"; pd.meta_bg = dynamic_cast < ::Wdg::DS_Slider_Meta_Bg * > ( pjob_n->meta ); if ( pd.meta_bg == 0 ) { return -1; } // Calculate tick sizes { int in_width ( pd.meta->size.width() - 2*pd.bw ); pd.tick_width[0] = in_width * 1 / 2; pd.tick_width[1] = in_width * 1 / 4; pd.tick_width[2] = in_width * 1 / 16; pd.tick_width[0] = ::std::max ( pd.tick_width[0], 6 ); pd.tick_width[1] = ::std::max ( pd.tick_width[1], 4 ); pd.tick_width[2] = ::std::max ( pd.tick_width[2], 2 ); if ( ( pd.meta->size.width() % 2 ) == 0 ) { for ( int ii=0; ii < 3; ++ii ) { if ( ( pd.tick_width[ii] % 2 ) != 0 ) { ++( pd.tick_width[ii] ); } } } else { for ( int ii=0; ii < 3; ++ii ) { if ( ( pd.tick_width[ii] % 2 ) == 0 ) { ++( pd.tick_width[ii] ); } } } pd.tick_min_dist = 8; } // State flags { pd.is_down = ( pjob_n->img_idx == 1 ); } // Painting { paint_bg_area ( pd ); paint_bg_frame ( pd ); paint_bg_area_deco ( pd ); paint_bg_ticks ( pd ); } return 0; } void DS_Slider_Painter_Bevelled::paint_bg_area ( PData & pd ) { QColor col_li ( pd.pal.color ( QPalette::Button ) ); QColor col_mid ( pd.pal.color ( QPalette::Button ) ); QColor col_dk ( pd.pal.color ( QPalette::Mid ) ); col_li.setAlpha ( 55 ); col_dk.setAlpha ( 190 ); const double inner_width ( pd.width() - 2*pd.bw ); const double x_start = pd.bw; const double x_end = pd.width() - pd.bw; const double x_mid = x_start + inner_width / 3.0; QPainterPath area_path; papp_bevel_area ( area_path, pd.rectf, pd.bevel, pd.bw / 2.0 ); // Base color { pd.qpnt.setPen ( Qt::NoPen ); pd.qpnt.setBrush ( col_mid ); } pd.qpnt.drawPath ( area_path ); // Fake 3D gradient { QLinearGradient lgrad ( QPointF ( x_start, 0.0 ), QPointF ( x_end, 0.0 ) ); lgrad.setColorAt ( 0.0, col_li ); lgrad.setColorAt ( x_mid / ( x_end - x_start ), col_mid ); lgrad.setColorAt ( 1.0, col_dk ); pd.qpnt.setPen ( Qt::NoPen ); pd.qpnt.setBrush ( lgrad ); } pd.qpnt.drawPath ( area_path ); // Sound color overlay { QColor c0 ( pd.pal.color ( QPalette::Window ) ); QColor c1 ( c0 ); c0.setAlpha ( 30 ); c1.setAlpha ( 0 ); QLinearGradient lgrad ( QPointF ( x_start, 0.0 ), QPointF ( x_start + inner_width / 7.0, 0.0 ) ); lgrad.setColorAt ( 0.0, c0 ); lgrad.setColorAt ( 1.0, c1 ); pd.qpnt.setPen ( Qt::NoPen ); pd.qpnt.setBrush ( lgrad ); } pd.qpnt.drawPath ( area_path ); } void DS_Slider_Painter_Bevelled::paint_bg_frame ( PData & pd ) { QColor fcol; { QColor col_btn ( pd.pal.color ( QPalette::Button ) ); QColor col_mid ( pd.pal.color ( QPalette::Mid ) ); if ( col_mid == col_btn ) { col_mid = pd.pal.color ( QPalette::WindowText ); fcol = col_mix ( col_btn, col_mid, 1, 1 ); } else { fcol = col_mix ( col_btn, col_mid, 1, 2 ); } //fcol = col_mid; } paint_bevel_raised_frame ( pd, pd.rectf, pd.bevel, pd.bw, pd.ew, fcol ); } void DS_Slider_Painter_Bevelled::paint_bg_area_deco ( PData & pd ) { QPainterPath ppath; const int range_max_idx ( pd.meta_bg->ticks_range_max_idx ); int y_min; int y_bottom; int y_top; bool has_minimum ( pd.meta_bg->bg_show_image ); bool has_zero_split ( false ); y_bottom = pd.height() - 1; y_bottom -= pd.meta_bg->ticks_range_start; y_top = y_bottom - range_max_idx; y_min = y_bottom; if ( has_minimum ) { Wdg::UInt_Mapper_Auto mapper ( range_max_idx, pd.meta_bg->ticks_max_idx ); y_min -= mapper.v2_to_v1 ( pd.meta_bg->bg_tick_min_idx ); } has_zero_split = ( ( y_min > y_top ) && ( y_min < y_bottom ) ); const double w_tick ( ( pd.tick_width[0] + pd.tick_width[1] ) / 2.0 ); const double w_out ( w_tick * 2.0 / 3.0 ); const double w_neck ( 1 ); double x_out_l ( ( pd.width() - w_tick ) / 2.0 ); double x_neck_l ( x_out_l ); double x_out_r; double x_neck_r; x_neck_l = std::floor ( x_neck_l ); x_neck_r = x_neck_l + w_neck; x_out_l = std::floor ( x_out_l ); x_out_r = x_out_l + w_out; if ( has_minimum ) { if ( has_zero_split ) { double x_out_rt ( x_out_r ); double x_out_rb ( x_out_r ); const int dt ( y_min - y_top ); const int db ( y_bottom - y_min ); if ( dt > db ) { int ww = ( db * w_out ) / dt; x_out_rb = x_out_l + ww; } else { int ww = ( dt * w_out ) / db; x_out_rt = x_out_l + ww; } ppath.moveTo ( x_out_l, y_top + 0.5 ); ppath.lineTo ( x_out_rt, y_top + 0.5 ); ppath.lineTo ( x_neck_r, y_min + 0.5 ); ppath.lineTo ( x_out_rb, y_bottom + 0.5 ); ppath.lineTo ( x_out_l, y_bottom + 0.5 ); ppath.lineTo ( x_neck_l, y_min + 0.5 ); ppath.closeSubpath(); } else { double x_rt; double x_rb; if ( y_min < y_bottom ) { x_rt = x_neck_r; x_rb = x_out_r; } else { x_rt = x_out_r; x_rb = x_neck_r; } ppath.moveTo ( x_neck_l, y_top + 0.5 ); ppath.lineTo ( x_rt, y_top + 0.5 ); ppath.lineTo ( x_rb, y_bottom + 0.5 ); ppath.lineTo ( x_out_l, y_bottom + 0.5 ); ppath.closeSubpath(); } } else { x_out_r = x_out_l + w_out / 2.0; ppath.moveTo ( x_out_l, y_top + 0.5 ); ppath.lineTo ( x_out_r, y_top + 0.5 ); ppath.lineTo ( x_out_r, y_bottom + 0.5 ); ppath.lineTo ( x_out_l, y_bottom + 0.5 ); ppath.closeSubpath(); } { QColor col_fill ( pd.pal.color ( QPalette::Window ) ); QColor col_pen ( pd.pal.color ( QPalette::WindowText ) ); if ( pd.is_down ) { col_fill.setAlpha ( 40 ); col_pen.setAlpha ( 40 ); } else { col_fill.setAlpha ( 16 ); col_pen.setAlpha ( 18 ); } { QPen pen; pen.setColor ( col_pen ); pen.setWidth ( 1.0 ); pd.qpnt.setPen ( pen ); } pd.qpnt.setBrush ( col_fill ); } pd.qpnt.drawPath ( ppath ); } void DS_Slider_Painter_Bevelled::paint_bg_ticks ( PData & pd ) { const int range_max_idx ( pd.meta_bg->ticks_range_max_idx ); unsigned int ticks_max_idx; int idx_delta ( 1 ); int y_off; y_off = pd.height() - 1; y_off -= pd.meta_bg->ticks_range_start; const int y_bottom = y_off; const int y_top = y_off - range_max_idx; // Setup main tick position mapper ticks_max_idx = pd.meta_bg->ticks_max_idx; if ( ticks_max_idx > 0 ) { if ( ( range_max_idx / ticks_max_idx ) < 2 ) { ticks_max_idx = range_max_idx / pd.tick_min_dist; } } ::Wdg::UInt_Mapper_Up mapper ( ticks_max_idx, range_max_idx ); if ( ticks_max_idx > 0 ) { const int tmd ( mapper.min_dist() ); while ( ( idx_delta * tmd ) < pd.tick_min_dist ) { ++idx_delta; } } // Paint { QColor tick_col ( pd.pal.color ( QPalette::WindowText ) ); tick_col = col_mix ( tick_col, pd.pal.color ( QPalette::Button ), 3, 1 ); const int idx_start = idx_delta; for ( unsigned int ii=idx_start; ii < ticks_max_idx; ii += idx_delta ) { int yy = y_bottom - mapper.map ( ii ); if ( ( yy - y_top ) < pd.tick_min_dist ) { break; } paint_bg_tick ( pd, yy, pd.tick_width[1], tick_col ); } } { QColor tick_col ( pd.pal.color ( QPalette::WindowText ) ); tick_col = col_mix ( tick_col, pd.pal.color ( QPalette::Button ), 4, 1 ); // Bottom and top ticks if ( ticks_max_idx > 0 ) { paint_bg_tick ( pd, y_top, pd.tick_width[0], tick_col ); } paint_bg_tick ( pd, y_bottom, pd.tick_width[0], tick_col ); } } void DS_Slider_Painter_Bevelled::paint_bg_tick ( PData & pd, double tick_pos_n, double tick_width_n, const QColor & col_n ) { const double tick_start ( ( pd.width() - tick_width_n ) / 2.0 ); QColor col ( col_n ); // Glow below solid line { col.setAlpha ( 32 ); pd.qpnt.setPen ( Qt::NoPen ); pd.qpnt.setBrush ( col ); const unsigned int num_pts ( 9 ); double xl ( tick_start - 0.5 ); double xr ( tick_start + tick_width_n + 0.5 ); const QPointF points[num_pts] = { QPointF ( xl, tick_pos_n - 1 ), QPointF ( xr, tick_pos_n - 1 ), QPointF ( xr + 1, tick_pos_n ), QPointF ( xr + 1, tick_pos_n + 1 ), QPointF ( xr, tick_pos_n + 2 ), QPointF ( xl, tick_pos_n + 2 ), QPointF ( xl - 1, tick_pos_n + 1 ), QPointF ( xl - 1, tick_pos_n ), QPointF ( xl, tick_pos_n - 1 ) }; pd.qpnt.drawPolygon ( points, num_pts ); } // Solid line { col.setAlpha ( 200 ); pd.qpnt.setPen ( Qt::NoPen ); pd.qpnt.setBrush ( col ); pd.qpnt.drawRect ( tick_start, tick_pos_n, tick_width_n, 1.0 ); } } // Marker painting int DS_Slider_Painter_Bevelled::paint_marker ( ::dpe::Paint_Job * pjob_n, PData & pd ) { int res ( 0 ); //::std::cout << "DS_Slider_Painter_Bevelled::paint_marker\n"; switch ( pjob_n->img_idx ) { case 0: paint_marker_current ( pd ); break; case 1: paint_marker_hint ( pd ); break; default: res = -1; break; } return res; } void DS_Slider_Painter_Bevelled::paint_marker_current ( PData & pd ) { int bevel ( pd.width() / 3 ); bevel = qMax ( bevel, 2 ); { // Background const unsigned int num_pts ( 9 ); const double x0 ( 0.0 ); const double x1 ( bevel ); const double x2 ( pd.width() - bevel ); const double x3 ( pd.width() ); const double y0 ( 0.0 ); const double y1 ( bevel ); const double y2 ( pd.height() - bevel ); const double y3 ( pd.height() ); const QPointF points[num_pts] = { QPointF ( x0, y1 ), QPointF ( x1, y0 ), QPointF ( x2, y0 ), QPointF ( x3, y1 ), QPointF ( x3, y2 ), QPointF ( x2, y3 ), QPointF ( x1, y3 ), QPointF ( x0, y2 ), QPointF ( x0, y1 ) }; { QColor col ( pd.pal.color ( QPalette::WindowText ) ); col.setAlpha ( 64 ); pd.qpnt.setPen ( Qt::NoPen ); pd.qpnt.setBrush ( col ); } pd.qpnt.drawPolygon ( points, num_pts ); } { // Foreground const unsigned int num_pts ( 9 ); double delta ( pd.width() / 6.0 ); if ( delta < 1.0 ) { delta = 1.0; } double delta_sq ( delta * ( ::std::sqrt ( 2.0 ) - 1.0 ) ); const double x0 ( delta ); const double x1 ( bevel + delta_sq ); const double x2 ( pd.width() - x1 ); const double x3 ( pd.width() - x0 ); const double y0 ( delta ); const double y1 ( bevel + delta_sq ); const double y2 ( pd.height() - y1 ); const double y3 ( pd.height() - y0 ); const QPointF points[num_pts] = { QPointF ( x0, y1 ), QPointF ( x1, y0 ), QPointF ( x2, y0 ), QPointF ( x3, y1 ), QPointF ( x3, y2 ), QPointF ( x2, y3 ), QPointF ( x1, y3 ), QPointF ( x0, y2 ), QPointF ( x0, y1 ) }; { const QColor & col ( pd.pal.color ( QPalette::WindowText ) ); pd.qpnt.setPen ( Qt::NoPen ); pd.qpnt.setBrush ( col ); } pd.qpnt.drawPolygon ( points, num_pts ); } } void DS_Slider_Painter_Bevelled::paint_marker_hint ( PData & pd ) { int bevel ( pd.width() / 3 ); bevel = qMax ( bevel, 2 ); { const unsigned int num_pts ( 9 ); const double x0 ( 0.0 ); const double x1 ( bevel ); const double x2 ( pd.width() - bevel ); const double x3 ( pd.width() ); const double y0 ( 0.0 ); const double y1 ( bevel ); const double y2 ( pd.height() - bevel ); const double y3 ( pd.height() ); const QPointF points[num_pts] = { QPointF ( x0, y1 ), QPointF ( x1, y0 ), QPointF ( x2, y0 ), QPointF ( x3, y1 ), QPointF ( x3, y2 ), QPointF ( x2, y3 ), QPointF ( x1, y3 ), QPointF ( x0, y2 ), QPointF ( x0, y1 ), }; { QColor col ( pd.pal.color ( QPalette::WindowText ) ); col.setAlpha ( 100 ); pd.qpnt.setPen ( Qt::NoPen ); pd.qpnt.setBrush ( col ); } pd.qpnt.drawPolygon ( points, num_pts ); } } // Frame painting int DS_Slider_Painter_Bevelled::paint_frame ( ::dpe::Paint_Job * pjob_n, PData & pd ) { //::std::cout << "DS_Slider_Painter_Bevelled::paint_frame " << pjob_n->img_idx << "\n"; // Calculate state flags { pd.has_focus = ( pjob_n->img_idx == 0 ); pd.has_weak_focus = ( pjob_n->img_idx == 1 ); } // Paint paint_frame_deco ( pd ); return 0; } void DS_Slider_Painter_Bevelled::paint_frame_deco ( PData & pd ) { const QColor col_norm ( pd.pal.color ( QPalette::Button ) ); const QColor col_text ( pd.pal.color ( QPalette::ButtonText ) ); const QColor col_text2 ( pd.pal.color ( QPalette::WindowText ) ); const QColor col_high ( pd.pal.color ( QPalette::Highlight ) ); { QColor col; if ( pd.has_weak_focus ) { col = col_high; } else { col = ::Wdg::col_mix ( col_text, col_text2, 2, 1 ); col = ::Wdg::col_mix ( col, col_norm, 3, 1 ); } int frw ( qMax ( 1, pd.bw - 2*pd.ew ) ); double shrink ( pd.ew ); if ( frw < 2 ) { if ( !pd.has_weak_focus ) { if ( pd.bw > 2 ) { frw = qMin ( 2, pd.bw ); } else { //shrink = false; } } } // Fill pd.qpnt.setPen ( Qt::NoPen ); pd.qpnt.setBrush ( col ); pd.qpnt.drawPath ( path_bevel_frame ( pd.rectf, pd.bevel, frw, shrink ) ); } } // Handle painting int DS_Slider_Painter_Bevelled::paint_handle ( ::dpe::Paint_Job * pjob_n, PData & pd ) { pd.bw = pd.width() / 24; pd.bw = qMax ( 2, pd.bw ); pd.ew = qMax ( 1, ( pd.bw / 4 ) ); { pd.has_focus = ( ( pjob_n->img_idx == 1 ) || ( pjob_n->img_idx == 3 ) ); pd.mouse_over = ( pjob_n->img_idx >= 2 ); pd.is_down = ( pjob_n->img_idx == 4 ); } // Painting { paint_handle_area ( pd ); paint_handle_frame ( pd ); paint_handle_items ( pd ); } return 0; } void DS_Slider_Painter_Bevelled::paint_handle_area ( PData & pd ) { const int iw ( pd.width() - 2*pd.bw ); const int ih ( pd.height() - 2*pd.bw ); QPainterPath area_path; papp_bevel_area ( area_path, pd.rectf, pd.bevel, pd.bw / 2.0 ); // Background { const double grw ( iw / 3.0 ); const double grwn ( grw / double ( iw ) ); QColor col_base ( pd.pal.color ( QPalette::Window ) ); if ( pd.pal.currentColorGroup() == QPalette::Disabled ) { QColor col_btn ( pd.pal.color ( QPalette::Button ) ); col_base = col_mix ( col_base, col_btn, 2, 1 ); } QColor col_edge ( col_base ); QColor col_center ( col_base ); col_edge.setAlpha ( 170 ); col_center.setAlpha ( 145 ); QLinearGradient lgrad ( QPointF ( pd.bw, 0.0 ), QPointF ( pd.width() - pd.bw, 0.0 ) ); lgrad.setColorAt ( 0.0, col_edge ); lgrad.setColorAt ( grwn, col_center ); lgrad.setColorAt ( 1.0 - grwn, col_center ); lgrad.setColorAt ( 1.0, col_edge ); pd.qpnt.setPen ( Qt::NoPen ); pd.qpnt.setBrush ( lgrad ); } pd.qpnt.drawPath ( area_path ); // Highlight { QColor col_edge ( pd.pal.color ( QPalette::Light ) ); QColor col_trans ( pd.pal.color ( QPalette::Light ) ); col_edge.setAlpha ( 128 ); col_trans.setAlpha ( 30 ); const double hl_dy ( ih / 8.0 ); const double y_top ( pd.bw ); const double y_bottom ( pd.height() - pd.bw ); QLinearGradient lgrad; if ( pd.is_down ) { lgrad.setStart ( 0.0, y_bottom - hl_dy ); lgrad.setFinalStop ( 0.0, y_top ); } else { lgrad.setStart ( 0.0, y_top + hl_dy ); lgrad.setFinalStop ( 0.0, y_bottom ); if ( pd.mouse_over ) { col_edge.setAlpha ( 150 ); } } // Adjust gradient pattern lgrad.setColorAt ( 0.0, col_edge ); lgrad.setColorAt ( 1.0, col_trans ); lgrad.setSpread ( QGradient::ReflectSpread ); pd.qpnt.setPen ( Qt::NoPen ); pd.qpnt.setBrush ( lgrad ); } pd.qpnt.drawPath ( area_path ); } void DS_Slider_Painter_Bevelled::paint_handle_frame ( PData & pd ) { QColor col; { //const QColor col_btn ( pd.pal.color ( QPalette::Button ) ); const QColor col_bg ( pd.pal.color ( QPalette::Window ) ); const QColor col_fg ( pd.pal.color ( QPalette::WindowText ) ); col = ::Wdg::col_mix ( col_bg, col_fg, 1, 1 ); } paint_bevel_raised_frame ( pd, pd.rectf, pd.bevel, pd.bw, pd.ew, col ); } void DS_Slider_Painter_Bevelled::paint_handle_items ( PData & pd ) { // Colors QColor col_bg ( pd.pal.color ( QPalette::Window ) ); QColor col_light ( pd.pal.color ( QPalette::Light ) ); col_light = ::Wdg::col_mix ( col_light, col_bg, 3, 2 ); QColor col_dark ( pd.pal.color ( QPalette::WindowText ) ); col_dark = ::Wdg::col_mix ( col_dark, col_bg, 5, 1 ); // Transforms const QTransform trans_hmirror ( -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, pd.width(), 0.0, 1.0 ); // Variables const double center_v ( pd.height() / 2.0 ); const double height_sub ( pd.bevel + pd.bw * ( sqrt ( 2.0 ) - 1.0 ) ); const double line_width_long ( 1.3333 ); // Width of the bright border const double line_width_small ( 1.25 ); // Width of the bright border const double line_width_fine ( 1.0 ); // Width of the bright border double tri_height_base; double tri_width; { const double in_w ( pd.width() - 2*pd.bw ); const double in_h ( pd.height() - 2*pd.bw ); const double tri_len_h ( in_w / 6.0f ); const double tri_len_v ( in_h / 6.0f ); const double tri_len ( qMin ( tri_len_v, tri_len_h ) ); tri_height_base = tri_len; tri_width = tri_len; tri_width += 1; } if ( pd.is_down ) { const double down_scale ( 3.0 / 4.0 ); tri_width *= down_scale; } // Round tri_width = ::std::floor ( tri_width + 0.5 ); // Install clipping region { QPainterPath area_path; papp_bevel_area ( area_path, pd.rectf, pd.bevel, pd.bw ); pd.qpnt.setClipPath ( area_path ); } { // Paint long piece QPainterPath ppath; { const double bb_w_loc ( line_width_long / 2.0 ); const double xoff ( pd.bw ); double pp_w ( tri_width - bb_w_loc ); double pp_h ( pd.height() / 2.0 - height_sub - bb_w_loc ); const QPointF ptop ( xoff, center_v - pp_h ); const QPointF pbot ( xoff, center_v + pp_h ); const QPointF pmid_top ( xoff + pp_w, center_v - 0.5 ); const QPointF pmid_bot ( xoff + pp_w, center_v + 0.5 ); const double sl_dk_x1 ( pp_w / 2.25 ); const double sl_dk_y1 ( pp_w / 2.5 ); const double sl_dk_y2 ( pp_h / 4.0 ); // Create path ppath.moveTo ( 0.0, ptop.y() ); ppath.lineTo ( ptop.x(), ptop.y() ); ppath.cubicTo ( QPointF ( ptop.x() + sl_dk_x1, ptop.y() + sl_dk_y1 ), QPointF ( pmid_top.x(), pmid_top.y() - sl_dk_y2 ), QPointF ( pmid_top.x(), pmid_top.y() ) ); ppath.lineTo ( pmid_bot.x(), pmid_bot.y() ); ppath.cubicTo ( QPointF ( pmid_bot.x(), pmid_bot.y() + sl_dk_y2 ), QPointF ( pbot.x() + sl_dk_x1, pbot.y() - sl_dk_y1 ), QPointF ( pbot.x(), pbot.y() ) ); ppath.lineTo ( 0.0, pbot.y() ); ppath.closeSubpath(); } { QPen pen; pen.setWidthF ( line_width_long ); pen.setColor ( col_light ); pd.qpnt.setPen ( pen ); } pd.qpnt.setBrush ( col_dark ); pd.qpnt.drawPath ( ppath ); ppath = trans_hmirror.map ( ppath ); pd.qpnt.drawPath ( ppath ); } { // Paint small triangle QPainterPath ppath; { double tri_height ( tri_height_base ); tri_height = std::floor ( tri_height ) + 0.5; const double xoff ( pd.bw ); const double pp_w ( tri_width ); const double pp_h ( tri_height ); // Create path ppath.moveTo ( 0, center_v - pp_h ); ppath.lineTo ( xoff, center_v - pp_h ); ppath.lineTo ( xoff, center_v - pp_h ); ppath.lineTo ( xoff + pp_w, center_v ); ppath.lineTo ( xoff, center_v + pp_h ); ppath.lineTo ( 0, center_v + pp_h ); ppath.closeSubpath(); } { QPen pen; pen.setWidthF ( line_width_small ); pen.setColor ( col_light ); pd.qpnt.setPen ( pen ); } pd.qpnt.setBrush ( col_dark ); pd.qpnt.drawPath ( ppath ); ppath = trans_hmirror.map ( ppath ); pd.qpnt.drawPath ( ppath ); } { // Center line const double xoff ( pd.bw + tri_width ); // Bright background pd.qpnt.setPen ( Qt::NoPen ); pd.qpnt.setBrush ( col_light ); pd.qpnt.drawRect ( xoff, center_v - 0.5 - line_width_fine, pd.width() - 2*xoff, 1.0 + line_width_fine*2 ); // Dark foreground pd.qpnt.setPen ( Qt::NoPen ); pd.qpnt.setBrush ( col_dark ); pd.qpnt.drawRect ( pd.bw, center_v - 0.5f, pd.width() - 2*pd.bw, 1.0 ); } // Remove clipping region pd.qpnt.setClipping ( false ); } void DS_Slider_Painter_Bevelled::papp_bevel_area ( QPainterPath & ppath_n, const QRectF & area_n, double bevel_n, double indent_n ) { const double angle_tan ( ::std::tan ( 22.5 / 180.0 * M_PI ) ); double ds ( indent_n ); double db ( bevel_n + angle_tan * indent_n ); double xl[2] = { area_n.left(), area_n.left() + area_n.width() }; double yl[2] = { area_n.top(), area_n.top() + area_n.height() }; ppath_n.moveTo ( xl[0] + ds, yl[0] + db ), ppath_n.lineTo ( xl[0] + db, yl[0] + ds ), ppath_n.lineTo ( xl[1] - db, yl[0] + ds ), ppath_n.lineTo ( xl[1] - ds, yl[0] + db ), ppath_n.lineTo ( xl[1] - ds, yl[1] - db ), ppath_n.lineTo ( xl[1] - db, yl[1] - ds ), ppath_n.lineTo ( xl[0] + db, yl[1] - ds ), ppath_n.lineTo ( xl[0] + ds, yl[1] - db ), ppath_n.closeSubpath(); } void DS_Slider_Painter_Bevelled::paint_bevel_raised_frame ( PData & pd, const QRectF & area_n, double bevel_n, double frame_width_n, double edge_width_n, const QColor & col_n ) { QColor col_light ( pd.pal.color ( QPalette::Light ) ); QColor col_shadow ( pd.pal.color ( QPalette::Shadow ) ); QColor col_mid ( col_n ); QColor col_br ( ::Wdg::col_mix ( col_n, col_light, 5, 4 ) ); QColor col_dk ( ::Wdg::col_mix ( col_n, col_shadow, 5, 4 ) ); const double shrink_out ( 0.0 ); const double shrink_in ( frame_width_n - edge_width_n ); // Bright area { QPainterPath pp; papp_bevel_frame_edge ( pp, area_n, 3, bevel_n, edge_width_n, shrink_out ); papp_bevel_frame_corner ( pp, area_n, 0, bevel_n, edge_width_n, shrink_out ); papp_bevel_frame_edge ( pp, area_n, 0, bevel_n, edge_width_n, shrink_out ); papp_bevel_frame_edge ( pp, area_n, 1, bevel_n, edge_width_n, shrink_in ); papp_bevel_frame_corner ( pp, area_n, 2, bevel_n, edge_width_n, shrink_in ); papp_bevel_frame_edge ( pp, area_n, 2, bevel_n, edge_width_n, shrink_in ); pd.qpnt.setPen ( Qt::NoPen ); pd.qpnt.setBrush ( col_br ); pd.qpnt.drawPath ( pp ); } // Mid area { QPainterPath pp; papp_bevel_frame_corner ( pp, area_n, 1, bevel_n, edge_width_n, shrink_out ); papp_bevel_frame_corner ( pp, area_n, 1, bevel_n, edge_width_n, shrink_in ); papp_bevel_frame_corner ( pp, area_n, 3, bevel_n, edge_width_n, shrink_out ); papp_bevel_frame_corner ( pp, area_n, 3, bevel_n, edge_width_n, shrink_in ); pd.qpnt.setPen ( Qt::NoPen ); pd.qpnt.setBrush ( col_mid ); pd.qpnt.drawPath ( pp ); } // Dark area { QPainterPath pp; papp_bevel_frame_edge ( pp, area_n, 3, bevel_n, edge_width_n, shrink_in ); papp_bevel_frame_corner ( pp, area_n, 0, bevel_n, edge_width_n, shrink_in ); papp_bevel_frame_edge ( pp, area_n, 0, bevel_n, edge_width_n, shrink_in ); papp_bevel_frame_edge ( pp, area_n, 1, bevel_n, edge_width_n, shrink_out ); papp_bevel_frame_corner ( pp, area_n, 2, bevel_n, edge_width_n, shrink_out ); papp_bevel_frame_edge ( pp, area_n, 2, bevel_n, edge_width_n, shrink_out ); pd.qpnt.setPen ( Qt::NoPen ); pd.qpnt.setBrush ( col_dk ); pd.qpnt.drawPath ( pp ); } // Frame center line area const double mid_width ( frame_width_n - 2.0*edge_width_n ); if ( mid_width > 0.0 ) { pd.qpnt.setPen ( Qt::NoPen ); pd.qpnt.setBrush ( col_mid ); pd.qpnt.drawPath ( path_bevel_frame ( area_n, bevel_n, mid_width, edge_width_n ) ); } } QPainterPath DS_Slider_Painter_Bevelled::path_bevel_frame ( const QRectF & area_n, double bevel_n, double frame_width_n, double indent_n ) { QPainterPath ppath; papp_bevel_area ( ppath, area_n, bevel_n, indent_n ); papp_bevel_area ( ppath, area_n, bevel_n, indent_n + frame_width_n ); return ppath; } void DS_Slider_Painter_Bevelled::papp_bevel_frame_corner ( QPainterPath & ppath_n, const QRectF & area_n, unsigned int edge_n, double bevel_n, double width_n, double indent_n ) { double xx[4]; double yy[4]; { const double angle_tan ( ::std::tan ( 22.5 / 180.0 * M_PI ) ); double ds1 ( indent_n ); double db1 ( bevel_n + angle_tan * ds1 ); double ds2 ( indent_n + width_n ); double db2 ( bevel_n + angle_tan * ds2 ); xx[0] = ds1; xx[1] = db1; xx[2] = db2; xx[3] = ds2; yy[0] = db1; yy[1] = ds1; yy[2] = ds2; yy[3] = db2; } { double x_off ( area_n.left() ); double y_off ( area_n.top() ); double x_scale ( 1.0 ); double y_scale ( 1.0 ); if ( edge_n == 0 ) { // pass } else if ( edge_n == 1 ) { x_off += area_n.width(); x_scale = -1; } else if ( edge_n == 2 ) { x_off += area_n.width(); y_off += area_n.height(); x_scale = -1; y_scale = -1; } else { y_off += area_n.height(); y_scale = -1; } for ( unsigned int ii=0; ii < 4; ++ii ) { xx[ii] *= x_scale; } for ( unsigned int ii=0; ii < 4; ++ii ) { yy[ii] *= y_scale; } for ( unsigned int ii=0; ii < 4; ++ii ) { xx[ii] += x_off; } for ( unsigned int ii=0; ii < 4; ++ii ) { yy[ii] += y_off; } } ppath_n.moveTo ( xx[0], yy[0] ); ppath_n.lineTo ( xx[1], yy[1] ); ppath_n.lineTo ( xx[2], yy[2] ); ppath_n.lineTo ( xx[3], yy[3] ); ppath_n.closeSubpath(); } void DS_Slider_Painter_Bevelled::papp_bevel_frame_edge ( QPainterPath & ppath_n, const QRectF & area_n, unsigned int edge_n, double bevel_n, double width_n, double indent_n ) { double xx[4]; double yy[4]; { const double angle_tan ( ::std::tan ( 22.5 / 180.0 * M_PI ) ); double ds1 ( indent_n ); double db1 ( bevel_n + angle_tan * ds1 ); double ds2 ( indent_n + width_n ); double db2 ( bevel_n + angle_tan * ds2 ); if ( ( edge_n % 2 ) == 0 ) { // top / bottom xx[0] = area_n.left() + db1; xx[1] = area_n.left() + area_n.width() - db1; xx[2] = area_n.left() + area_n.width() - db2; xx[3] = area_n.left() + db2; yy[0] = ds1; yy[1] = ds1; yy[2] = ds2; yy[3] = ds2; } else { // left / right xx[0] = ds1; xx[1] = ds1; xx[2] = ds2; xx[3] = ds2; yy[0] = area_n.top() + area_n.height() - db1; yy[1] = area_n.top() + db1; yy[2] = area_n.top() + db2; yy[3] = area_n.top() + area_n.height() - db2; } } // Flip sides if ( edge_n == 1 ) { // flip left to right for ( unsigned int ii=0; ii < 4; ++ii ) { xx[ii] *= -1; } const double x_off ( area_n.left() + area_n.width() ); for ( unsigned int ii=0; ii < 4; ++ii ) { xx[ii] += x_off; } } else if ( edge_n == 2 ) { // flip top to bottom for ( unsigned int ii=0; ii < 4; ++ii ) { yy[ii] *= -1; } const double y_off ( area_n.top() + area_n.height() ); for ( unsigned int ii=0; ii < 4; ++ii ) { yy[ii] += y_off; } } ppath_n.moveTo ( xx[0], yy[0] ); ppath_n.lineTo ( xx[1], yy[1] ); ppath_n.lineTo ( xx[2], yy[2] ); ppath_n.lineTo ( xx[3], yy[3] ); ppath_n.closeSubpath(); } } // End of namespace } // End of namespace qastools-v0.22.0/shared/src/wdg/ds_slider_painter_bevelled.hpp000066400000000000000000000044501354534512100245170ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_ds_slider_painter_bevelled_hpp__ #define __INC_ds_slider_painter_bevelled_hpp__ #include "wdg/ds_widget_painter.hpp" // Forward declaration class QColor; class QRectF; class QPainterPath; namespace Wdg { namespace Painter { class DS_Slider_Painter_Bevelled : public ::Wdg::Painter::DS_Widget_Painter { // Public methods public: DS_Slider_Painter_Bevelled ( ); // Protected methods protected: int paint_image ( ::dpe::Paint_Job * pjob_n ); // Private methods private: // Declaration struct PData; // Backgournd painting int paint_bg ( ::dpe::Paint_Job * pjob_n, PData & pd ); void paint_bg_area ( PData & pd ); void paint_bg_frame ( PData & pd ); void paint_bg_area_deco ( PData & pd ); void paint_bg_ticks ( PData & pd ); void paint_bg_tick ( PData & pd, double tick_pos_n, double tick_width_n, const QColor & col_n ); // Marker painting int paint_marker ( ::dpe::Paint_Job * pjob_n, PData & pd ); void paint_marker_current ( PData & pd ); void paint_marker_hint ( PData & pd ); // Frame painting int paint_frame ( ::dpe::Paint_Job * pjob_n, PData & pd ); void paint_frame_deco ( PData & pd ); // Handle painting int paint_handle ( ::dpe::Paint_Job * pjob_n, PData & pd ); void paint_handle_area ( PData & pd ); void paint_handle_frame ( PData & pd ); void paint_handle_items ( PData & pd ); // Shared / Utility void papp_bevel_area ( QPainterPath & ppath_n, const QRectF & area_n, double bevel_n, double indent_n = 0.0 ); QPainterPath path_bevel_frame ( const QRectF & area_n, double bevel_n, double width_n, double indent_n = 0.0 ); void paint_bevel_raised_frame ( PData & pd, const QRectF & area_n, double bevel_n, double width_n, double edge_n, const QColor & col_n ); void papp_bevel_frame_corner ( QPainterPath & ppath_n, const QRectF & area_n, unsigned int edge_n, double bevel_n, double width_n, double indent_n ); void papp_bevel_frame_edge ( QPainterPath & ppath_n, const QRectF & area_n, unsigned int edge_n, double bevel_n, double width_n, double indent_n ); }; } // End of namespace } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/ds_slider_test.cpp000066400000000000000000000022211354534512100221570ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "slider_test.hpp" #include namespace Wdg { DS_Slider_Test::DS_Slider_Test ( QWidget * parent_n ) : QWidget ( parent_n ) { connect ( slider(), SIGNAL ( valueChanged ( int ) ), this, SLOT ( value_changed ( int ) ) ); connect ( slider(), SIGNAL ( rangeChanged ( int, int ) ), this, SLOT ( range_changed ( int, int ) ) ); QVBoxLayout * lay_vbox ( new QVBoxLayout() ); lay_vbox->addWidget ( slider() ); lay_vbox->addWidget ( &_value ); lay_vbox->addWidget ( &_range ); setLayout ( lay_vbox ); value_changed ( 0 ); } DS_Slider_Test::~DS_Slider_Test ( ) { } void DS_Slider_Test::value_changed ( int value_n ) { //::std::cout << "DS_Slider_Test::value_changed " << value_n << "\n"; _value.setText ( QString ( "Value
\n%1" ).arg ( value_n ) ); } void DS_Slider_Test::range_changed ( int min_n, int max_n ) { //::std::cout << "DS_Slider_Test::range_changed " << min_n << " - " << max_n << "\n"; _range.setText ( QString ( "Range
%1
\n%2" ).arg ( max_n ).arg ( min_n ) ); } } // End of namespace qastools-v0.22.0/shared/src/wdg/ds_slider_test.hpp000066400000000000000000000013541354534512100221720ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_ds_slider_test_hpp__ #define __INC_ds_slider_test_hpp__ #include #include "namespace_wdg.hpp" #include "qslider.hpp" #include namespace Wdg { class DS_Slider_Test : public QWidget { Q_OBJECT public: DS_Slider_Test ( QWidget * parent_n = 0 ); ~DS_Slider_Test ( ); DS_Slider * slider ( ); protected slots: void value_changed ( int value_n ); void range_changed ( int min_n, int max_n ); // Private attributes private: DS_Slider _slider; QLabel _value; QLabel _range; }; inline DS_Slider * DS_Slider_Test::slider ( ) { return &_slider; } } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/ds_slider_test_dialog.cpp000066400000000000000000000043231354534512100235030ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "ds_slider_test_dialog.hpp" #include #include namespace Wdg { DS_Slider_Test_Dialog::DS_Slider_Test_Dialog ( QWidget * parent_n ) : QDialog ( parent_n ) { const int num_blocks = 7; const int num_sliders = 3*num_blocks; Slider_Test * sliders[num_sliders]; for ( int ii=0; ii < num_sliders; ++ii ) { sliders[ii] = new Slider_Test ( this ); sliders[ii]->slider()->set_px_buffers ( _widget_hub.slider_buffers() ); } int int_max ( INT_MAX ); int int_min ( INT_MIN ); int sli ( 0 ); sliders[sli++]->slider()->setRange ( 0, 0 ); sliders[sli++]->slider()->setRange ( 1, 1 ); sliders[sli++]->slider()->setRange ( int_max, int_max ); sliders[sli++]->slider()->setRange ( 0, 1 ); sliders[sli++]->slider()->setRange ( int_max - 1, int_max ); sliders[sli++]->slider()->setRange ( -1, 0 ); sliders[sli++]->slider()->setRange ( 0, 5 ); sliders[sli++]->slider()->setRange ( 1, 6 ); sliders[sli++]->slider()->setRange ( -5, 0 ); sliders[sli++]->slider()->setRange ( 0, 31 ); sliders[sli++]->slider()->setRange ( 1, 32 ); sliders[sli++]->slider()->setRange ( int_max - 31, int_max ); sliders[sli++]->slider()->setRange ( 0, 127 ); sliders[sli++]->slider()->setRange ( 1, 128 ); sliders[sli++]->slider()->setRange ( int_max - 127, int_max ); sliders[sli++]->slider()->setRange ( -127, 0 ); sliders[sli++]->slider()->setRange ( -127, -16 ); sliders[sli++]->slider()->setRange ( -256, 256 ); sliders[sli++]->slider()->setRange ( 0, int_max ); sliders[sli++]->slider()->setRange ( int_min, 0 ); sliders[sli++]->slider()->setRange ( int_min, int_max ); QHBoxLayout * lay_hbox ( new QHBoxLayout() ); sli = 0; for ( int jj=0; jj 0 ) { lay_hbox->addWidget ( new_vline() ); } for ( int ii=0; ii < 3; ++ii ) { lay_hbox->addWidget ( sliders[sli] ); ++sli; } } lay_hbox->addStretch(); setLayout ( lay_hbox ); } QWidget * DS_Slider_Test_Dialog::new_vline ( ) { QFrame * fr ( new QFrame ( this ) ); fr->setFrameStyle ( QFrame::VLine | QFrame::Plain ); return fr; } DS_Slider_Test_Dialog::~DS_Slider_Test_Dialog ( ) { } } // End of namespace qastools-v0.22.0/shared/src/wdg/ds_slider_test_dialog.hpp000066400000000000000000000012261354534512100235070ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_ds_slider_test_dialog_hpp__ #define __INC_ds_slider_test_dialog_hpp__ #include #include #include #include "namespace_wdg.hpp" #include "slider_test.hpp" #include "mixer_style.hpp" namespace Wdg { class DS_Slider_Test_Dialog : public QDialog { Q_OBJECT public: DS_Slider_Test_Dialog ( QWidget * parent_n = 0 ); ~DS_Slider_Test_Dialog ( ); QWidget * new_vline ( ); // Protected slots protected slots: // Private attributes private: Mixer_Style _widget_hub; }; } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/ds_switch.cpp000066400000000000000000000103251354534512100211430ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "ds_switch.hpp" #include "dpe/image_set.hpp" #include "dpe/image_request.hpp" #include "dpe/image_allocator.hpp" #include "wdg/ds_widget_types.hpp" #include #include #include namespace Wdg { DS_Switch::DS_Switch ( QWidget * parent_n, ::dpe::Image_Allocator * alloc_n ) : QAbstractButton ( parent_n ), _dsi ( 2, alloc_n ), _update_pixmaps_pending ( false ), _meta_bg ( num_images_bg, ::Wdg::DS_SWITCH, 0 ), _meta_handle ( num_images_handle, ::Wdg::DS_SWITCH, 1 ) { _dsi.image_request()->meta[0] = &_meta_bg; _dsi.image_request()->meta[1] = &_meta_handle; setCheckable ( true ); { QSizePolicy policy ( sizePolicy() ); policy.setHorizontalPolicy ( QSizePolicy::Preferred ); policy.setVerticalPolicy ( QSizePolicy::Preferred ); setSizePolicy ( policy ); } } DS_Switch::~DS_Switch ( ) { _dsi.set_image_alloc ( 0 ); } QSize DS_Switch::sizeHint ( ) const { ensurePolished(); const QFontMetrics fmet ( fontMetrics() ); return QSize ( fmet.height(), fmet.height() ); } QSize DS_Switch::minimumSizeHint ( ) const { ensurePolished(); const QFontMetrics fmet ( fontMetrics() ); return QSize ( fmet.height(), fmet.height() ); } void DS_Switch::set_image_alloc ( ::dpe::Image_Allocator * alloc_n ) { _dsi.set_image_alloc ( alloc_n ); } void DS_Switch::set_variant_id ( unsigned int id_n ) { _dsi.set_images_variant_id ( id_n ); } void DS_Switch::set_style_id ( unsigned int id_n ) { _dsi.set_images_style_id ( id_n ); } // Events void DS_Switch::changeEvent ( QEvent * event_n ) { QWidget::changeEvent ( event_n ); if ( ( event_n->type() == QEvent::ActivationChange ) || ( event_n->type() == QEvent::EnabledChange ) || ( event_n->type() == QEvent::StyleChange ) || ( event_n->type() == QEvent::PaletteChange ) || ( event_n->type() == QEvent::LayoutDirectionChange ) ) { update_pixmaps(); } } void DS_Switch::enterEvent ( QEvent * event_n ) { QAbstractButton::enterEvent ( event_n ); update(); } void DS_Switch::leaveEvent ( QEvent * event_n ) { QAbstractButton::leaveEvent ( event_n ); update(); } void DS_Switch::resizeEvent ( QResizeEvent * event_n ) { QAbstractButton::resizeEvent ( event_n ); QRect ren ( contentsRect() ); if ( ren.width() != ren.height() ) { const int delta ( ren.width() - ren.height() ); if ( delta > 0 ) { ren.setWidth ( ren.height() ); ren.moveLeft ( ren.left() + delta / 2 ); } else { ren.setHeight ( ren.width() ); ren.moveTop ( ren.top() - delta / 2 ); } } _pxmap_rect = ren; update_pixmaps(); } void DS_Switch::paintEvent ( QPaintEvent * ) { if ( _update_pixmaps_pending ) { update_pixmaps(); } _dsi.wait_for_request(); if ( !_dsi.images().ready() ) { return; } QPixmap * pixmap_handle ( 0 ); QPixmap * pixmap_bg ( 0 ); // Background setup { unsigned int img_idx ( 0 ); if ( hasFocus() ) { img_idx = 1; } if ( underMouse() && isEnabled() ) { img_idx += 2; } ::dpe::Image & img ( _dsi.images().img_sets[0]->image ( img_idx ) ); pixmap_bg = img.convert_to_pixmap(); } // Handle setup { unsigned int img_idx ( 0 ); if ( isDown() ) { img_idx = 8; if ( underMouse() ) { ++img_idx; } } else { if ( isChecked() ) { img_idx = 4; } if ( underMouse() && isEnabled() ) { img_idx += 2; } if ( hasFocus() ) { ++img_idx; } } ::dpe::Image & img ( _dsi.images().img_sets[1]->image ( img_idx ) ); pixmap_handle = img.convert_to_pixmap(); } // Painting QPainter painter ( this ); if ( pixmap_bg != 0 ) { painter.drawPixmap ( _pxmap_rect.topLeft(), *pixmap_bg ); } if ( pixmap_handle != 0 ) { painter.drawPixmap ( _pxmap_rect.topLeft(), *pixmap_handle ); } } void DS_Switch::update_pixmaps ( ) { if ( _dsi.image_alloc() != 0 ) { if ( isVisible() ) { _update_pixmaps_pending = false; //::std::cout << "DS_Slider::update_pixmaps " << this << "\n"; _dsi.wait_for_request(); _meta_bg.size = _pxmap_rect.size(); _meta_handle.size = _pxmap_rect.size(); _dsi.set_images_style_sub_id ( _dsi.style_sub_id ( this ) ); _dsi.send_request(); update(); } else { _update_pixmaps_pending = true; } } } } // End of namespace qastools-v0.22.0/shared/src/wdg/ds_switch.hpp000066400000000000000000000035321354534512100211520ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_wdg_ds_switch_hpp__ #define __INC_wdg_ds_switch_hpp__ #include "dpe/image_set_meta.hpp" #include "wdg/ds_imaging.hpp" #include namespace Wdg { /// @brief Dynamic sized switch /// /// Background images: /// 0 - idle /// 1 - focus /// 2 - hover idle /// 3 - hover focus /// /// Handle images: /// 0 - unchecked idle /// 1 - unchecked focus /// 2 - unchecked hover /// 3 - unchecked hover & focus /// /// 4 - checked idle /// 5 - checked focus /// 6 - checked hover /// 7 - checked hover & focus /// /// 8 - half checked focus /// 9 - half checked hover & focus /// /// It is possible to use this switch widget as a push button /// by setting setCheckable ( false ). /// Push buttons don't require the images 4-7. /// class DS_Switch : public QAbstractButton { Q_OBJECT // Public methods public: DS_Switch ( QWidget * parent_n = 0, ::dpe::Image_Allocator * alloc_n = 0 ); ~DS_Switch ( ); QSize sizeHint ( ) const; QSize minimumSizeHint ( ) const; // Image allocator and style id void set_image_alloc ( ::dpe::Image_Allocator * alloc_n ); void set_variant_id ( unsigned int id_n ); void set_style_id ( unsigned int id_n ); // Protected methods protected: void changeEvent ( QEvent * event_n ); void enterEvent ( QEvent * ); void leaveEvent ( QEvent * ); void resizeEvent ( QResizeEvent * event ); void paintEvent ( QPaintEvent * event ); void update_pixmaps ( ); // Private attributes private: static const unsigned int num_images_bg = 4; static const unsigned int num_images_handle = 10; ::Wdg::DS_Imaging _dsi; QRect _pxmap_rect; bool _update_pixmaps_pending; ::dpe::Image_Set_Meta _meta_bg; ::dpe::Image_Set_Meta _meta_handle; }; } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/ds_switch_painter_circle.cpp000066400000000000000000000176461354534512100242230ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "ds_switch_painter_circle.hpp" #include "dpe/paint_job.hpp" #include "dpe/image_set.hpp" #include "dpe/image_set_meta.hpp" #include "wdg/ds_widget_style_db.hpp" #include "wdg/ds_widget_types.hpp" #include "wdg/color_methods.hpp" #include #include #include #include #define _USE_MATH_DEFINES #include #include namespace Wdg { namespace Painter { struct DS_Switch_Painter_Circle::PData { inline QSize & size ( ) { return meta->size; } inline int width ( ) { return meta->size.width(); } inline int height ( ) { return meta->size.height(); } ::dpe::Image_Set_Meta * meta; QPalette pal; QPainter qpnt; int max_len; int min_len; int border_width; int gap_width; double center_x; double center_y; bool checked; bool half_checked; bool has_focus; bool mouse_over; QColor col_border; QColor col_focus; QRectF rectf; ::dpe::Image * img; }; DS_Switch_Painter_Circle::DS_Switch_Painter_Circle ( ) : ::Wdg::Painter::DS_Widget_Painter ( ::Wdg::DS_SWITCH ) { } int DS_Switch_Painter_Circle::paint_image ( ::dpe::Paint_Job * pjob_n ) { int res ( 0 ); // Init paint data PData pd; pd.meta = pjob_n->meta; pd.img = &pjob_n->img_set->image ( pjob_n->img_idx ); res = create_image_data ( pd.img, pd.meta ); if ( res == 0 ) { if ( wdg_style_db() != 0 ) { pd.pal = wdg_style_db()->palettes[pd.meta->style_id]; pd.pal.setCurrentColorGroup ( wdg_style_db()->color_group ( pd.meta->style_sub_id ) ); } pd.rectf.setRect ( 0.0, 0.0, pd.width(), pd.height() ); pd.min_len = qMin ( pd.width(), pd.height() ); pd.max_len = qMax ( pd.width(), pd.height() ); pd.border_width = qMax ( pd.min_len / 16, 1 ); pd.gap_width = qMax ( pd.min_len / 8, 2 ); pd.center_x = pd.width() / 2.0; pd.center_y = pd.height() / 2.0; switch ( pd.meta->type_id ) { case 0: res = paint_bg ( pjob_n, pd ); break; case 1: res = paint_handle ( pjob_n, pd ); break; default: break; } } return res; } int DS_Switch_Painter_Circle::paint_bg ( ::dpe::Paint_Job * pjob_n, PData & pd ) { { const QColor col_bg ( pd.pal.color ( QPalette::Button ) ); const QColor col_fg ( pd.pal.color ( QPalette::ButtonText ) ); pd.col_border = ::Wdg::col_mix ( col_bg, col_fg, 1, 1 ); } { const QColor col_bg ( pd.pal.color ( QPalette::Button ) ); const QColor col_fg ( pd.pal.color ( QPalette::ButtonText ) ); pd.col_focus = ::Wdg::col_mix ( col_bg, col_fg, 1, 2 ); } // Calc state flags { unsigned int state_mod ( pjob_n->img_idx % 2 ); unsigned int state_div ( pjob_n->img_idx / 2 ); pd.has_focus = ( state_mod != 0 ); pd.mouse_over = ( state_div != 0 ); } { // Init painter pd.qpnt.begin ( &pd.img->qimage() ); pd.qpnt.setRenderHints ( QPainter::Antialiasing | QPainter::SmoothPixmapTransform ); // Painting paint_bg_area ( pd ); paint_bg_deco ( pd ); paint_bg_border ( pd ); } return 0; } void DS_Switch_Painter_Circle::paint_bg_area ( PData & pd ) { { double rad ( ( pd.min_len - pd.border_width ) / 2.0 ); QRadialGradient rgrad ( QPointF ( pd.center_x, pd.center_y ), rad ); { // Color mixing int w_dk ( 40 ); if ( pd.mouse_over ) { w_dk = 45; } QColor col_dk ( pd.pal.color ( QPalette::Window ) ); QColor col_win ( pd.pal.color ( QPalette::Button ) ); QColor col_mix ( ::Wdg::col_mix ( col_dk, col_win, w_dk, 255 - w_dk ) ); rgrad.setColorAt ( 0.0, col_win ); rgrad.setColorAt ( 1.0, col_mix ); pd.qpnt.setPen ( Qt::NoPen ); pd.qpnt.setBrush ( rgrad ); } pd.qpnt.drawEllipse ( QPointF ( pd.center_x, pd.center_y ), rad, rad ); } } void DS_Switch_Painter_Circle::paint_bg_deco ( PData & pd ) { // Mouse over if ( pd.mouse_over ) { paint_highlight ( pd ); } } void DS_Switch_Painter_Circle::paint_bg_border ( PData & pd ) { // Border { double rad ( ( pd.min_len - pd.border_width ) / 2.0 ); { QPen pen; pen.setWidthF ( pd.border_width ); pen.setColor ( pd.col_border ); pd.qpnt.setBrush ( Qt::NoBrush ); pd.qpnt.setPen ( pen ); } pd.qpnt.drawEllipse ( QPointF ( pd.center_x, pd.center_y ), rad, rad ); } if ( pd.has_focus ) { paint_focus_path ( pd ); } } // Handle int DS_Switch_Painter_Circle::paint_handle ( ::dpe::Paint_Job * pjob_n, PData & pd ) { // Calc state flags { unsigned int state_mod ( pjob_n->img_idx % 2 ); pd.has_focus = ( state_mod != 0 ); pd.mouse_over = ( ( pjob_n->img_idx == 2 ) || ( pjob_n->img_idx == 3 ) || ( pjob_n->img_idx == 6 ) || ( pjob_n->img_idx == 7 ) ); pd.half_checked = ( pjob_n->img_idx > 7 ); } // Painting { if ( pjob_n->img_idx < 4 ) { // Empty images for the first variants pd.img->clear(); } else { // Init painter pd.qpnt.begin ( &pd.img->qimage() ); pd.qpnt.setRenderHints ( QPainter::Antialiasing | QPainter::SmoothPixmapTransform ); // Painting paint_handle_area ( pd ); paint_handle_deco ( pd ); } } return 0; } void DS_Switch_Painter_Circle::paint_handle_area ( PData & pd ) { double rad ( pd.min_len / 2.0 - pd.border_width - pd.gap_width ); double fade_offset ( 0.2 ); QColor col_full ( pd.pal.color ( QPalette::WindowText ) ); if ( pd.half_checked ) { // Gradient color circle QColor col_trans ( col_full ); col_trans.setAlpha ( 64 ); QRadialGradient rgrad ( QPointF ( pd.center_x, pd.center_y ), rad ); rgrad.setColorAt ( 0.0, col_full ); rgrad.setColorAt ( fade_offset, col_full ); rgrad.setColorAt ( 1.0, col_trans ); pd.qpnt.setPen ( Qt::NoPen ); pd.qpnt.setBrush ( rgrad ); } else { // Full color circle pd.qpnt.setPen ( Qt::NoPen ); pd.qpnt.setBrush ( col_full ); } pd.qpnt.drawEllipse ( QPointF ( pd.center_x, pd.center_y ), rad, rad ); } void DS_Switch_Painter_Circle::paint_handle_deco ( PData & pd ) { if ( pd.mouse_over ) { paint_highlight ( pd ); } } void DS_Switch_Painter_Circle::paint_highlight ( PData & pd ) { const double rad ( pd.min_len / 2.0 - pd.border_width ); { const double diam0 ( pd.min_len - pd.border_width ); const double diam1 ( pd.min_len - pd.border_width - pd.gap_width ); const double diam2 ( qMax ( ( diam1 - pd.gap_width * 6.0 ), pd.gap_width * 3.0 ) ); QColor cf ( pd.pal.color ( QPalette::Highlight ) ); QColor ca ( cf ); cf.setAlpha ( 180 ); ca.setAlpha ( 0 ); double w0 = 0.0; double w1 = diam2 / diam0; double w2 = diam1 / diam0; double w3 = 1.0; QRadialGradient rgrad ( QPointF ( pd.center_x, pd.center_y ), rad ); rgrad.setColorAt ( w0, ca ); rgrad.setColorAt ( w1, ca ); rgrad.setColorAt ( w2, cf ); rgrad.setColorAt ( w3, cf ); pd.qpnt.setPen ( Qt::NoPen ); pd.qpnt.setBrush ( rgrad ); } pd.qpnt.drawEllipse ( QPointF ( pd.center_x, pd.center_y ), rad, rad ); } void DS_Switch_Painter_Circle::paint_focus_path ( PData & pd ) { QPainterPath ppath[4]; { const QPointF center ( pd.center_x, pd.center_y ); const double rad ( pd.min_len / 2.0 ); const double big_rad ( rad - pd.border_width ); const double rscale ( M_PI / 180.0 ); const double ang_delta ( 90.0 * rscale ); double angle ( ( 90.0 / 2.0 ) * rscale ); double crad ( rad - big_rad*::std::cos ( angle ) ); crad *= 2.0 / 3.0; for ( unsigned int ii=0; ii < 4; ++ii ) { QPointF ccen ( ::std::cos ( angle ), ::std::sin ( angle ) ); ccen *= big_rad; ccen += center; ppath[ii].addEllipse ( ccen, crad, crad ); angle += ang_delta; } } // Subtract inner circle { QPainterPath ppathc; QRectF brect ( pd.rectf ); const double adj ( pd.border_width / 2.0 ); brect.adjust ( adj, adj, -adj, -adj ); ppathc.addEllipse ( brect ); for ( unsigned int ii=0; ii < 4; ++ii ) { ppath[ii] = ppath[ii].subtracted ( ppathc ); } } pd.qpnt.setPen ( Qt::NoPen ); pd.qpnt.setBrush ( pd.col_focus ); for ( unsigned int ii=0; ii < 4; ++ii ) { pd.qpnt.drawPath ( ppath[ii] ); } } } // End of namespace } // End of namespace qastools-v0.22.0/shared/src/wdg/ds_switch_painter_circle.hpp000066400000000000000000000020711354534512100242120ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_ds_switch_painter_circle_hpp__ #define __INC_ds_switch_painter_circle_hpp__ #include "wdg/ds_widget_painter.hpp" namespace Wdg { namespace Painter { class DS_Switch_Painter_Circle : public ::Wdg::Painter::DS_Widget_Painter { // Public methods public: DS_Switch_Painter_Circle ( ); // Protected methods protected: int paint_image ( ::dpe::Paint_Job * pjob_n ); // Private methods private: // Declaration struct PData; // Background int paint_bg ( ::dpe::Paint_Job * pjob_n, PData & pd ); void paint_bg_area ( PData & pd ); void paint_bg_deco ( PData & pd ); void paint_bg_border ( PData & pd ); // Handle int paint_handle ( ::dpe::Paint_Job * pjob_n, PData & pd ); void paint_handle_area ( PData & pd ); void paint_handle_deco ( PData & pd ); // Shared void paint_highlight ( PData & pd ); void paint_focus_path ( PData & pd ); }; } // End of namespace } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/ds_switch_painter_close.cpp000066400000000000000000000160441354534512100240560ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "ds_switch_painter_close.hpp" #include "dpe/paint_job.hpp" #include "dpe/image_set.hpp" #include "dpe/image_set_meta.hpp" #include "wdg/ds_widget_style_db.hpp" #include "wdg/ds_widget_types.hpp" #include "wdg/color_methods.hpp" #include #include #include #include #define _USE_MATH_DEFINES #include #include namespace Wdg { namespace Painter { struct DS_Switch_Painter_Close::PData { inline QSize & size ( ) { return meta->size; } inline int width ( ) { return meta->size.width(); } inline int height ( ) { return meta->size.height(); } ::dpe::Image_Set_Meta * meta; QPalette pal; QPainter qpnt; int max_len; int min_len; int border_width; double center_x; double center_y; bool checked; bool half_checked; bool has_focus; bool mouse_over; ::dpe::Image * img; }; DS_Switch_Painter_Close::DS_Switch_Painter_Close ( ) : ::Wdg::Painter::DS_Widget_Painter ( ::Wdg::DS_SWITCH ) { } int DS_Switch_Painter_Close::paint_image ( ::dpe::Paint_Job * pjob_n ) { int res ( 0 ); // Init paint data PData pd; pd.meta = pjob_n->meta; pd.img = &pjob_n->img_set->image ( pjob_n->img_idx ); res = create_image_data ( pd.img, pd.meta ); if ( res == 0 ) { if ( wdg_style_db() != 0 ) { pd.pal = wdg_style_db()->palettes[pd.meta->style_id]; pd.pal.setCurrentColorGroup ( wdg_style_db()->color_group ( pd.meta->style_sub_id ) ); } pd.min_len = qMin ( pd.width(), pd.height() ); pd.max_len = qMax ( pd.width(), pd.height() ); pd.border_width = qMax ( pd.min_len / 16, 1 ); pd.center_x = pd.width() / 2.0; pd.center_y = pd.height() / 2.0; switch ( pd.meta->type_id ) { case 0: res = paint_bg ( pjob_n, pd ); break; case 1: res = paint_handle ( pjob_n, pd ); break; default: break; } } return res; } int DS_Switch_Painter_Close::paint_bg ( ::dpe::Paint_Job * pjob_n, PData & pd ) { // Calc state flags { unsigned int state_mod ( pjob_n->img_idx % 2 ); unsigned int state_div ( pjob_n->img_idx / 2 ); pd.has_focus = ( state_mod != 0 ); pd.mouse_over = ( state_div != 0 ); } { // Init painter pd.qpnt.begin ( &pd.img->qimage() ); pd.qpnt.setRenderHints ( QPainter::Antialiasing | QPainter::SmoothPixmapTransform ); // Painting paint_bg_area ( pd ); paint_bg_border ( pd ); } return 0; } void DS_Switch_Painter_Close::paint_bg_area ( PData & pd ) { { double rad ( ( pd.min_len - pd.border_width ) / 2.0 ); if ( pd.mouse_over ) { QColor col0 ( pd.pal.color ( QPalette::Button ) ); QColor col1 ( pd.pal.color ( QPalette::Highlight ) ); QRadialGradient rgrad ( QPointF ( pd.center_x, pd.center_y ), rad ); rgrad.setColorAt ( 0.0, col0 ); rgrad.setColorAt ( 0.75, col1 ); rgrad.setColorAt ( 1.0, col1 ); pd.qpnt.setPen ( Qt::NoPen ); pd.qpnt.setBrush ( rgrad ); } else { QColor col ( pd.pal.color ( QPalette::Button ) ); pd.qpnt.setPen ( Qt::NoPen ); pd.qpnt.setBrush ( col ); } pd.qpnt.drawEllipse ( QPointF ( pd.center_x, pd.center_y ), rad, rad ); } } void DS_Switch_Painter_Close::paint_bg_border ( PData & pd ) { // Border { double rad ( ( pd.min_len - pd.border_width ) / 2.0 ); { QPen pen; pen.setWidthF ( pd.border_width ); { QColor col_bg ( pd.pal.color ( QPalette::Button ) ); QColor col_fg ( pd.pal.color ( QPalette::ButtonText ) ); pen.setColor ( ::Wdg::col_mix ( col_bg, col_fg, 1, 2 ) ); } pd.qpnt.setBrush ( Qt::NoBrush ); pd.qpnt.setPen ( pen ); } pd.qpnt.drawEllipse ( QPointF ( pd.center_x, pd.center_y ), rad, rad ); } if ( pd.has_focus ) { paint_focus_path ( pd ); } } // Handle int DS_Switch_Painter_Close::paint_handle ( ::dpe::Paint_Job * pjob_n, PData & pd ) { // Calc state flags { unsigned int state_mod ( pjob_n->img_idx % 2 ); pd.has_focus = ( state_mod != 0 ); pd.mouse_over = ( ( pjob_n->img_idx == 2 ) || ( pjob_n->img_idx == 3 ) || ( pjob_n->img_idx == 6 ) || ( pjob_n->img_idx == 7 ) ); pd.half_checked = ( pjob_n->img_idx > 7 ); } // Painting { if ( ( pjob_n->img_idx > 3 ) && ( pjob_n->img_idx < 8 ) ) { // Empty images for the first variants pd.img->clear(); } else { // Init painter pd.qpnt.begin ( &pd.img->qimage() ); pd.qpnt.setRenderHints ( QPainter::Antialiasing | QPainter::SmoothPixmapTransform ); // Paint paint_handle_area ( pd ); } } return 0; } void DS_Switch_Painter_Close::paint_handle_area ( PData & pd ) { QColor col_full; if ( pd.half_checked || pd.mouse_over ) { col_full = pd.pal.color ( QPalette::HighlightedText ); } else { const QColor col_bg ( pd.pal.color ( QPalette::Button ) ); const QColor col_fg ( pd.pal.color ( QPalette::ButtonText ) ); col_full = ::Wdg::col_mix ( col_bg, col_fg, 1, 3 ); } double gap_width = qMax ( pd.min_len / 4, 4 ); if ( pd.half_checked ) { QColor col_trans ( col_full ); col_trans.setAlpha ( 128 ); double rad ( pd.min_len / 2.0 - pd.border_width - gap_width ); QRadialGradient rgrad ( QPointF ( 0, 0 ), rad ); rgrad.setColorAt ( 0.0, col_full ); rgrad.setColorAt ( 1.0, col_trans ); pd.qpnt.setPen ( Qt::NoPen ); pd.qpnt.setBrush ( rgrad ); } else { pd.qpnt.setPen ( Qt::NoPen ); pd.qpnt.setBrush ( col_full ); } double rwidth ( pd.min_len - pd.border_width - gap_width ); double rheight ( 1.5 ); if ( rheight < pd.border_width ) { rheight = pd.border_width; } // Paths pd.qpnt.translate ( pd.center_x, pd.center_y ); pd.qpnt.rotate ( 45 ); pd.qpnt.drawRect ( QRectF ( -rwidth / 2.0, -rheight / 2.0, rwidth, rheight ) ); pd.qpnt.drawRect ( QRectF ( -rheight / 2.0, -rwidth / 2.0, rheight, rwidth ) ); pd.qpnt.resetTransform(); } void DS_Switch_Painter_Close::paint_focus_path ( PData & pd ) { QPainterPath ppath[4]; { const QPointF center ( pd.center_x, pd.center_y ); const double rad ( pd.min_len / 2.0 ); const double big_rad ( rad - pd.border_width ); const double rscale ( M_PI / 180.0 ); const double ang_delta ( 90.0 * rscale ); double angle ( ( 90.0 / 2.0 ) * rscale ); double crad ( rad - big_rad*::std::cos ( angle ) ); crad *= 2.0 / 3.0; for ( unsigned int ii=0; ii < 4; ++ii ) { QPointF ccen ( ::std::cos ( angle ), ::std::sin ( angle ) ); ccen *= big_rad; ccen += center; ppath[ii].addEllipse ( ccen, crad, crad ); angle += ang_delta; } } // Subtract inner circle { QPainterPath ppathc; QRectF brect ( QPointF ( 0, 0 ), pd.size() ); const double adj ( pd.border_width / 2.0 ); brect.adjust ( adj, adj, -adj, -adj ); ppathc.addEllipse ( brect ); for ( unsigned int ii=0; ii < 4; ++ii ) { ppath[ii] = ppath[ii].subtracted ( ppathc ); } } pd.qpnt.setPen ( Qt::NoPen ); { const QColor col_bg ( pd.pal.color ( QPalette::Button ) ); const QColor col_fg ( pd.pal.color ( QPalette::ButtonText ) ); pd.qpnt.setBrush ( ::Wdg::col_mix ( col_bg, col_fg, 1, 3 ) ); } for ( unsigned int ii=0; ii < 4; ++ii ) { pd.qpnt.drawPath ( ppath[ii] ); } } } // End of namespace } // End of namespace qastools-v0.22.0/shared/src/wdg/ds_switch_painter_close.hpp000066400000000000000000000016671354534512100240700ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_ds_switch_painter_close_hpp__ #define __INC_ds_switch_painter_close_hpp__ #include "wdg/ds_widget_painter.hpp" namespace Wdg { namespace Painter { class DS_Switch_Painter_Close : public ::Wdg::Painter::DS_Widget_Painter { // Public methods public: DS_Switch_Painter_Close ( ); // Protected methods protected: int paint_image ( ::dpe::Paint_Job * pjob_n ); // Private methods private: // Declaration struct PData; // Background int paint_bg ( ::dpe::Paint_Job * pjob_n, PData & pd ); void paint_bg_area ( PData & pd ); void paint_bg_border ( PData & pd ); // Handle int paint_handle ( ::dpe::Paint_Job * pjob_n, PData & pd ); void paint_handle_area ( PData & pd ); // Shared void paint_focus_path ( PData & pd ); }; } // End of namespace } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/ds_switch_painter_svg.cpp000066400000000000000000000075101354534512100235460ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "ds_switch_painter_svg.hpp" #include "dpe/paint_job.hpp" #include "dpe/image_set.hpp" #include "dpe/image_set_meta.hpp" #include "wdg/ds_widget_types.hpp" #include #include #include #include #include #include #include namespace Wdg { namespace Painter { DS_Switch_Painter_SVG::DS_Switch_Painter_SVG ( ) : ::Wdg::Painter::DS_Widget_Painter ( ::Wdg::DS_SWITCH ) { _suffix_bg[0] = "idle"; _suffix_bg[1] = "focus"; _suffix_bg[2] = "hover_idle"; _suffix_bg[3] = "hover_focus"; _suffix_handle[0] = "unchecked_idle"; _suffix_handle[1] = "unchecked_focus"; _suffix_handle[2] = "unchecked_hover_idle"; _suffix_handle[3] = "unchecked_hover_focus"; _suffix_handle[4] = "checked_idle"; _suffix_handle[5] = "checked_focus"; _suffix_handle[6] = "checked_hover_idle"; _suffix_handle[7] = "checked_hover_focus"; _suffix_handle[8] = "half_checked_focus"; _suffix_handle[9] = "half_checked_hover_focus"; } void DS_Switch_Painter_SVG::set_base_dir ( const QString & dir_n ) { _base_dir = dir_n; } void DS_Switch_Painter_SVG::set_file_prefix_bg ( const QString & file_prefix_n ) { _prefix_bg = file_prefix_n; } void DS_Switch_Painter_SVG::set_file_prefix_handle ( const QString & file_prefix_n ) { _prefix_handle = file_prefix_n; } bool DS_Switch_Painter_SVG::ready ( ) const { for ( unsigned int ii=0; ii < num_bg; ++ii ) { QString fname ( file_name ( _prefix_bg, _suffix_bg[ii] ) ); if ( !file_ready ( fname ) ) { return false; } } for ( unsigned int ii=0; ii < num_handle; ++ii ) { QString fname ( file_name ( _prefix_handle, _suffix_handle[ii] ) ); if ( !file_ready ( fname ) ) { return false; } } return true; } bool DS_Switch_Painter_SVG::file_ready ( const QString & file_name_n ) const { QFileInfo finfo ( file_name_n ); if ( !finfo.exists() ) { return false; } if ( !finfo.isFile() ) { return false; } if ( !finfo.isReadable() ) { return false; } return true; } int DS_Switch_Painter_SVG::paint_image ( ::dpe::Paint_Job * pjob_n ) { int res ( 0 ); res = create_image_data ( &pjob_n->img_set->image ( pjob_n->img_idx ), pjob_n->meta ); if ( res == 0 ) { switch ( pjob_n->meta->type_id ) { case 0: res = paint_bg ( pjob_n ); break; case 1: res = paint_handle ( pjob_n ); break; } } return res; } int DS_Switch_Painter_SVG::paint_bg ( ::dpe::Paint_Job * pjob_n ) const { const QString fname ( file_name ( _prefix_bg, _suffix_bg[pjob_n->img_idx] ) ); return render_svg ( pjob_n->img_set->image ( pjob_n->img_idx ), fname ); } int DS_Switch_Painter_SVG::paint_handle ( ::dpe::Paint_Job * pjob_n ) const { const QString fname ( file_name ( _prefix_handle, _suffix_handle[pjob_n->img_idx] ) ); return render_svg ( pjob_n->img_set->image ( pjob_n->img_idx ), fname ); } QString DS_Switch_Painter_SVG::file_name ( const QString & prefix_n, const QString & suffix_n ) const { QString res ( base_dir() ); if ( res[res.size() - 1] != '/' ) { res.append ( '/' ); } res.append ( prefix_n ); res.append ( suffix_n ); res.append ( ".svg" ); return res; } int DS_Switch_Painter_SVG::render_svg ( ::dpe::Image & img_n, const QString & svg_file_n ) const { int res ( 0 ); { QSvgRenderer svg_render; if ( svg_render.load ( svg_file_n ) ) { QPainter pnt ( &img_n.qimage() ); pnt.setRenderHints ( QPainter::Antialiasing | QPainter::SmoothPixmapTransform ); svg_render.render ( &pnt ); } else { img_n.clear(); { ::std::stringstream msg; msg << "SVG image loading failed for " << ::std::endl; msg << svg_file_n.toLocal8Bit().data() << ::std::endl; ::std::cerr << msg.str(); } res = -1; } } return res; } } // End of namespace } // End of namespace qastools-v0.22.0/shared/src/wdg/ds_switch_painter_svg.hpp000066400000000000000000000036041354534512100235530ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_ds_switch_painter_svg_hpp__ #define __INC_ds_switch_painter_svg_hpp__ #include "wdg/ds_widget_painter.hpp" #include #include namespace Wdg { namespace Painter { class DS_Switch_Painter_SVG : public ::Wdg::Painter::DS_Widget_Painter { // Public methods public: DS_Switch_Painter_SVG ( ); const QString & base_dir ( ) const; void set_base_dir ( const QString & dir_n ); const QString & file_prefix_bg ( ) const; const QString & file_prefix_handle ( ) const; void set_file_prefix_bg ( const QString & file_prefix_n ); void set_file_prefix_handle ( const QString & file_prefix_n ); /// @brief Checks if all required SVG images exist bool ready ( ) const; // Protected methods protected: int paint_image ( ::dpe::Paint_Job * pjob_n ); // Private methods private: int paint_bg ( ::dpe::Paint_Job * pjob_n ) const; int paint_handle ( ::dpe::Paint_Job * pjob_n ) const; QString file_name ( const QString & prefix_n, const QString & suffix_n ) const; bool file_ready ( const QString & file_name_n ) const; /// @return 0 on success (no error) int render_svg ( ::dpe::Image & img_n, const QString & svg_file_n ) const; // Private attributes private: static const unsigned int num_bg = 4; static const unsigned int num_handle = 10; QString _suffix_bg[num_bg]; QString _suffix_handle[num_handle]; QString _base_dir; QString _prefix_bg; QString _prefix_handle; }; inline const QString & DS_Switch_Painter_SVG::base_dir ( ) const { return _base_dir; } inline const QString & DS_Switch_Painter_SVG::file_prefix_bg ( ) const { return _prefix_bg; } inline const QString & DS_Switch_Painter_SVG::file_prefix_handle ( ) const { return _prefix_handle; } } // End of namespace } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/ds_widget_painter.cpp000066400000000000000000000015751354534512100226560ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "ds_widget_painter.hpp" #include "dpe/image.hpp" #include "dpe/image_set_meta.hpp" #include namespace Wdg { namespace Painter { DS_Widget_Painter::DS_Widget_Painter ( unsigned int group_type_n, unsigned int group_variant_n ) : ::dpe::Painter ( group_type_n, group_variant_n ), _wdg_style_db ( 0 ) { } void DS_Widget_Painter::set_wdg_style_db ( ::Wdg::DS_Widget_Style_Db * style_db_n ) { _wdg_style_db = style_db_n; } int DS_Widget_Painter::create_image_data ( ::dpe::Image * img_n, const ::dpe::Image_Set_Meta * meta_n ) { if ( !meta_n->size.isValid() ) { return -1; } img_n->set_size ( meta_n->size.width(), meta_n->size.height(), meta_n->size.width() * 4 ); img_n->qimage().fill ( 0 ); return 0; } } // End of namespace } // End of namespace qastools-v0.22.0/shared/src/wdg/ds_widget_painter.hpp000066400000000000000000000020521354534512100226520ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_wdg_ds_widget_painter_hpp__ #define __INC_wdg_ds_widget_painter_hpp__ #include "dpe/painter.hpp" // Forward declaration namespace dpe { class Image; class Image_Set_Meta; } namespace Wdg { class DS_Widget_Style_Db; } namespace Wdg { namespace Painter { class DS_Widget_Painter : public ::dpe::Painter { // Public methods public: DS_Widget_Painter ( unsigned int group_type_n, unsigned int group_variant_n = 0 ); // Widget style database ::Wdg::DS_Widget_Style_Db * wdg_style_db ( ) const; void set_wdg_style_db ( ::Wdg::DS_Widget_Style_Db * style_db_n ); // Protected methods protected: int create_image_data ( ::dpe::Image * img_n, const ::dpe::Image_Set_Meta * meta_n ); // Private methods private: ::Wdg::DS_Widget_Style_Db * _wdg_style_db; }; inline ::Wdg::DS_Widget_Style_Db * DS_Widget_Painter::wdg_style_db ( ) const { return _wdg_style_db; } } // End of namespace } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/ds_widget_style_db.cpp000066400000000000000000000004231354534512100230100ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "ds_widget_style_db.hpp" namespace Wdg { DS_Widget_Style_Db::DS_Widget_Style_Db ( ) { QPalette pal; palettes.insert ( ST_NORMAL, pal ); } } // End of namespace qastools-v0.22.0/shared/src/wdg/ds_widget_style_db.hpp000066400000000000000000000037311354534512100230220ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_wdg_ds_imaging_style_hpp__ #define __INC_wdg_ds_imaging_style_hpp__ #include #include #include "wdg/ds_widget_types.hpp" namespace Wdg { class DS_Widget_Style_Db { // Public typedefs public: enum STYLES { ST_NORMAL = 0, ST_USER = 32 // User defined style should start here }; // Public methods public: DS_Widget_Style_Db ( ); QPalette palette ( unsigned int style_id_n ) const; const QColor & color ( unsigned int style_id_n, QPalette::ColorRole role_n ) const; const QColor & color ( unsigned int style_id_n, QPalette::ColorGroup group_n, QPalette::ColorRole role_n ) const; QPalette::ColorGroup color_group ( ::Wdg::DS_Widget_State state_n ) const; QPalette::ColorGroup color_group ( unsigned int state_n ) const; // Public attributes public: QHash < unsigned int, QPalette > palettes; }; inline QPalette DS_Widget_Style_Db::palette ( unsigned int style_id_n ) const { return palettes.value ( style_id_n ); } inline const QColor & DS_Widget_Style_Db::color ( unsigned int style_id_n, QPalette::ColorRole role_n ) const { return palette ( style_id_n ).color ( role_n ); } inline const QColor & DS_Widget_Style_Db::color ( unsigned int style_id_n, QPalette::ColorGroup group_n, QPalette::ColorRole role_n ) const { return palette ( style_id_n ).color ( group_n, role_n ); } inline QPalette::ColorGroup DS_Widget_Style_Db::color_group ( ::Wdg::DS_Widget_State state_n ) const { QPalette::ColorGroup res; switch ( state_n ) { case ::Wdg::ST_DISABLED: res = QPalette::Disabled; break; case ::Wdg::ST_INACTIVE: res = QPalette::Inactive; break; default: res = QPalette::Normal; } return res; } inline QPalette::ColorGroup DS_Widget_Style_Db::color_group ( unsigned int state_n ) const { return color_group ( (::Wdg::DS_Widget_State) state_n ); } } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/ds_widget_types.hpp000066400000000000000000000007071354534512100223610ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_ds_widget_types_hpp__ #define __INC_ds_widget_types_hpp__ namespace Wdg { enum DS_Widget_Type { DS_UNKNOWN = 0, DS_SWITCH = 1, DS_SLIDER = 2 }; enum DS_Widget_State { ST_NORMAL = 0, ST_DISABLED = 1, ST_INACTIVE = 2 }; enum DS_Switch_Variants { DS_CIRCLE = 0, DS_SVG_JOINED = 1, DS_CLOSE = 2 }; } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/equal_columns_layout.cpp000066400000000000000000000527211354534512100234260ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "equal_columns_layout.hpp" #include "equal_columns_layout_group.hpp" #include #include "layout_weights.hpp" #include namespace Wdg { /// /// @brief Equal_Columns_Layout_Index /// class Equal_Columns_Layout_Index { // Public methods public: Equal_Columns_Layout_Index ( ); // Attributes QLayoutItem * item; Equal_Columns_Layout_Group * group; Equal_Columns_Layout_Column * column; Equal_Columns_Layout_Row * row; }; Equal_Columns_Layout_Index::Equal_Columns_Layout_Index ( ) : item ( 0 ), group ( 0 ), column ( 0 ), row ( 0 ) { } // // Equal_Columns_Layout // Equal_Columns_Layout::Equal_Columns_Layout ( QWidget * parent_n ) : QLayout ( parent_n ), _smallest_group_dist ( 0 ), _smallest_column_dist ( 0 ), _spacing_vertical ( 7 ), _cache_dirty ( true ) { _col_type_min_widths[0] = 3; // Horizontal spacing minor _col_type_min_widths[1] = 6; // Horizontal spacing major _col_type_min_widths[2] = 0; // Content column minor _col_type_min_widths[3] = 0; // Content column major _col_type_weights[0] = 4; // Horizontal spacing minor _col_type_weights[1] = 9; // Horizontal spacing major _col_type_weights[2] = _col_type_weights[1] * 5 / 3; // Content column minor _col_type_weights[3] = _col_type_weights[1] * 8 / 3; // Content column major update_cache(); } Equal_Columns_Layout::~Equal_Columns_Layout ( ) { if ( _groups.size() > 0 ) { for ( int ii=0; ii < _groups.size(); ++ii ) { delete _groups[ii]; } _groups.clear(); } if ( _indices.size() > 0 ) { for ( int ii=0; ii < _indices.size(); ++ii ) { if ( _indices[ii]->item != 0 ) { delete _indices[ii]->item; } delete _indices[ii]; } _indices.clear(); } } // // QLayout methods // int Equal_Columns_Layout::add_group_item ( QLayoutItem * item_n, unsigned int group_idx_n, unsigned int column_idx_n, unsigned int row_idx_n ) { bool res ( -1 ); if ( item_n == 0 ) { return res; } // Create new groups on demand while ( (int)group_idx_n >= _groups.size() ) { unsigned int idx ( _groups.size() ); _groups.append ( new ::Wdg::Equal_Columns_Layout_Group ( idx ) ); } Equal_Columns_Layout_Group * grp ( _groups[group_idx_n] ); // Create a new columns on demand while ( column_idx_n >= grp->num_columns() ) { unsigned int idx ( grp->num_columns() ); grp->append_column ( new ::Wdg::Equal_Columns_Layout_Column ( idx ) ); } ::Wdg::Equal_Columns_Layout_Column * col ( grp->column ( column_idx_n ) ); // Create a new rows on demand while ( row_idx_n >= col->num_rows() ) { unsigned int idx ( col->num_rows() ); col->append_row ( new ::Wdg::Equal_Columns_Layout_Row ( idx ) ); } ::Wdg::Equal_Columns_Layout_Row * row ( col->row ( row_idx_n ) ); // Add item if ( row->item() == 0 ) { row->set_item ( item_n ); ::Wdg::Equal_Columns_Layout_Index * lindex ( new Equal_Columns_Layout_Index ); lindex->item = item_n; lindex->group = grp; lindex->column = col; lindex->row = row; _indices.append ( lindex ); invalidate(); res = 0; } else { //::std::cout << "Shouldn't happen " << row->item() << "\n"; } return res; } int Equal_Columns_Layout::add_group_widget ( QWidget * wdg_n, unsigned int group_idx, unsigned int column_idx, unsigned int row_idx_n ) { int res ( -1 ); if ( wdg_n != 0 ) { addChildWidget ( wdg_n ); QWidgetItem * item ( new QWidgetItem ( wdg_n ) ); res = add_group_item ( item, group_idx, column_idx, row_idx_n ); if ( res != 0 ) { delete item; } } return res; } void Equal_Columns_Layout::addItem ( QLayoutItem * item_n ) { if ( item_n != 0 ) { add_group_item ( item_n, _groups.size(), 0, 0 ); } } QLayoutItem * Equal_Columns_Layout::itemAt ( int idx_n ) const { QLayoutItem * res ( 0 ); if ( ( idx_n >= 0 ) && ( idx_n < _indices.size() ) ) { res = _indices[idx_n]->item; } return res; } QLayoutItem * Equal_Columns_Layout::takeAt ( int idx_n ) { QLayoutItem * res ( 0 ); //::std::cout << "Equal_Columns_Layout::takeAt " << idx_n << "\n"; if ( ( idx_n >= 0 ) && ( idx_n < _indices.size() ) ) { Equal_Columns_Layout_Index * lindex ( _indices[idx_n] ); _indices.removeAt ( idx_n ); if ( lindex->row != 0 ) { lindex->row->set_item ( 0 ); } if ( lindex->column != 0 ) { lindex->column->remove_empty_rows_at_back(); } if ( lindex->group != 0 ) { lindex->group->remove_empty_columns_at_back(); } remove_empty_groups_at_back ( ); res = lindex->item; delete lindex; _groups_active.clear(); invalidate(); } return res; } int Equal_Columns_Layout::count ( ) const { return _indices.size(); } void Equal_Columns_Layout::remove_empty_groups_at_back ( ) { unsigned int idx ( _groups.size() ); while ( idx > 0 ) { --idx; Equal_Columns_Layout_Group * grp ( _groups[idx] ); bool remove ( true ); if ( grp != 0 ) { if ( grp->num_columns() > 0 ) { remove = false; } } if ( remove ) { if ( grp != 0 ) { delete grp; } _groups.removeLast(); } else { break; } } } QSize Equal_Columns_Layout::minimumSize ( ) const { update_cache_const(); QSize res ( 0, 0 ); int & ww ( res.rwidth() ); int & hh ( res.rheight() ); { // Margins const QMargins mgs ( contentsMargins() ); ww += mgs.left() + mgs.right(); hh += mgs.top() + mgs.bottom(); } // Width for ( unsigned int ii=0; ii < 4; ++ii ) { ww += _col_type_count[ii]*_col_type_min_widths[ii]; } // Height for ( int ii=0; ii < _row_min_heights.size(); ++ii ) { hh += _row_min_heights[ii]; } if ( _rows_active > 0 ) { hh += ( _rows_active - 1 )*_spacing_vertical; } //::std::cout << "Equal_Columns_Layout::minimumSize " << res.width() << ":" << res.height() << "\n"; return res; } QSize Equal_Columns_Layout::sizeHint ( ) const { return minimumSize(); } void Equal_Columns_Layout::invalidate ( ) { //::std::cout << "Equal_Columns_Layout::invalidate" << "\n"; _cache_dirty = true; QLayout::invalidate(); } unsigned int Equal_Columns_Layout::all_rows_height ( ) const { unsigned int res ( 0 ); for ( unsigned int ii=0; ii < num_rows(); ++ii ) { res += row_height ( ii ); } if ( _rows_active > 0 ) { res += ( _rows_active - 1 ) * spacing_vertical(); } return res; } void Equal_Columns_Layout::set_row_height ( unsigned int row_idx_n, unsigned int height_n ) { _row_heights[row_idx_n] = height_n; } void Equal_Columns_Layout::update_cache_const ( ) const { const_cast < Equal_Columns_Layout * > ( this )->update_cache(); } unsigned int Equal_Columns_Layout::minor_spacing_max_width ( unsigned int major_sp_width_n ) const { unsigned int res; unsigned int min_width ( major_sp_width_n * _col_type_weights[0] ); res = min_width / _col_type_weights[1]; if ( ( min_width % _col_type_weights[1] ) > 0 ) { ++res; } return res; } void Equal_Columns_Layout::update_cache ( ) { if ( !_cache_dirty ) { return; } _cache_dirty = false; //::std::cout << "Equal_Columns_Layout::update_cache" << "\n"; // Reset buffers _groups_active.clear(); for ( int ii=0; ii < 4; ++ii ) { _col_type_count[ii] = 0; } _col_type_min_widths[2] = 0; _col_type_min_widths[3] = 0; _row_min_heights.clear(); _row_heights.clear(); _row_stretch.clear(); _rows_active = 0; for ( int gii=0; gii < _groups.size(); ++gii ) { Equal_Columns_Layout_Group * grp ( _groups[gii] ); if ( grp == 0) { continue; } grp->row_stats().clear(); if ( grp->num_columns() == 0) { continue; } unsigned int active_cols ( 0 ); unsigned int cmin_width ( 0 ); for ( unsigned int cii=0; cii < grp->num_columns(); ++cii ) { Equal_Columns_Layout_Column * col ( grp->column ( cii ) ); if ( col == 0 ) { continue; } if ( col->num_rows() == 0 ) { continue; } // Adjust row heights buffer on demand while ( _row_min_heights.size() < (int)col->num_rows() ) { _row_min_heights.append ( 0 ); _row_heights.append ( 0 ); _row_stretch.append ( 0 ); } // Adjust row statistics buffer size while ( grp->row_stats().size() < (int)col->num_rows() ) { grp->row_stats().append ( 0 ); } unsigned int active_rows ( 0 ); for ( unsigned int rii=0; rii < col->num_rows(); ++rii ) { const Equal_Columns_Layout_Row * row ( col->row ( rii ) ); if ( row == 0 ) { continue; } if ( row->item() == 0 ) { continue; } if ( row->item()->isEmpty() ) { continue; } grp->row_stats()[rii] += 1; ++active_rows; { Qt::Orientations ori ( row->item()->expandingDirections() ); if ( ( ori & Qt::Vertical ) != 0 ) { _row_stretch[rii] = 1; } } const QSize msize ( row->item()->minimumSize() ); if ( msize.height() > (int)_row_min_heights[rii] ) { _row_min_heights[rii] = msize.height(); } if ( msize.width() > (int)cmin_width ) { cmin_width = msize.width(); } } col->set_active_rows ( active_rows ); if ( col->active_rows() > 0 ) { ++active_cols; } } grp->set_active_columns ( active_cols ); if ( active_cols > 0 ) { _groups_active.append ( grp ); _col_type_count[1] += 1; // Spacing major if ( active_cols == 1 ) { // Single major content column _col_type_count[3] += 1; if ( cmin_width > _col_type_min_widths[3] ) { _col_type_min_widths[3] = cmin_width; } } else { // More than one minor content columns _col_type_count[0] += ( active_cols - 1 ); _col_type_count[2] += active_cols; if ( cmin_width > _col_type_min_widths[2] ) { _col_type_min_widths[2] = cmin_width; } } } } // Remove on major spacing if ( _col_type_count[1] > 0 ) { --_col_type_count[1]; } for ( int ii=0; ii < _row_min_heights.size(); ++ii ) { if ( _row_min_heights[ii] > 0 ) { ++_rows_active; } } } void Equal_Columns_Layout::calc_columns_sizes ( unsigned int area_width_n, unsigned int area_height_n ) { calc_row_heights ( area_height_n ); calc_column_widths ( area_width_n ); } void Equal_Columns_Layout::calc_row_heights ( unsigned int height_n ) { //::std::cout << "Equal_Columns_Layout::calc_row_heights " << height_n << "\n"; unsigned int avail_space ( height_n ); if ( _rows_active > 0 ) { avail_space -= ( _rows_active - 1 ) * _spacing_vertical; } unsigned int expanding_rows ( 0 ); for ( int ii=0; ii < _row_stretch.size(); ++ii ) { if ( _row_stretch[ii] == 0 ) { _row_heights[ii] = _row_min_heights[ii]; if ( avail_space >= _row_min_heights[ii] ) { avail_space -= _row_min_heights[ii]; } else { avail_space = 0; } } else { ++expanding_rows; } } // Share available space between expanding rows equally if ( ( expanding_rows > 0 ) && ( avail_space > 0 ) ) { unsigned int def_height ( avail_space / expanding_rows ); unsigned int height_mod ( avail_space % expanding_rows ); unsigned int exp_row ( 0 ); for ( int ii=0; ii < _row_stretch.size(); ++ii ) { if ( _row_stretch[ii] != 0 ) { unsigned int rheight ( def_height ); if ( exp_row < height_mod ) { ++rheight; } _row_heights[ii] = rheight; ++exp_row; } } } // Calculate maximum column width { unsigned int max_width ( 0 ); for ( int ii=0; ii < _row_heights.size(); ++ii ) { if ( _row_heights[ii] > max_width ) { max_width = _row_heights[ii]; } } max_width = ( max_width / 5 ); { unsigned int max_width_font ( 0 ); { QFont fnt; QFontMetrics fmet ( fnt ); max_width_font = fmet.height() * 3; } if ( max_width > max_width_font ) { max_width = max_width_font; } } for ( int ii=0; ii < 4; ++ii ) { _col_max_widths[ii] = max_width; } _col_max_widths[0] = minor_spacing_max_width ( max_width ); // Crop to limits for ( int ii=0; ii < 4; ++ii ) { if ( _col_type_count[ii] > 0 ) { if ( _col_max_widths[ii] < _col_type_min_widths[ii] ) { _col_max_widths[ii] = _col_type_min_widths[ii]; } } else { _col_max_widths[ii] = 0; } } } } void Equal_Columns_Layout::calc_column_widths ( unsigned int width_n ) { //::std::cout << "Equal_Columns_Layout::calc_column_widths " << width_n << "\n"; _smallest_group_dist = 0; _smallest_column_dist = 0; if ( num_active_groups() == 0 ) { return; } if ( ( _col_type_count[2] == 0 ) && ( _col_type_count[3] == 0 ) ) { return; } const unsigned long avail_space ( width_n ); for ( unsigned int ii=0; ii < 4; ++ii ) { _col_widths[ii] = 0; } // Calculate a first estimate for the column widths { Layout_Weights weights_all; for ( unsigned int ii=0; ii < 4; ++ii ) { weights_all[ii] = _col_type_weights[ii] * _col_type_count[ii]; } const unsigned long wsum ( weights_all.sum() ); // Calculate first estimate for the column widths for ( unsigned int ii=0; ii < 4; ++ii ) { if ( _col_type_count[ii] > 0 ) { _col_widths[ii] = ( weights_all[ii] * avail_space ) / ( wsum * _col_type_count[ii] ); _col_widths[ii] = qMax ( _col_widths[ii], _col_type_min_widths[ii] ); } } } // Crop estimates to allowed range for ( unsigned int ii=0; ii < 4; ++ii ) { if ( _col_type_count[ii] > 0 ) { if ( _col_widths[ii] < _col_type_min_widths[ii] ) { _col_widths[ii] = _col_type_min_widths[ii]; } if ( _col_widths[ii] > _col_max_widths[ii] ) { _col_widths[ii] = _col_max_widths[ii]; } } } // Calculate used space unsigned int used_space ( 0 ); for ( unsigned int ii=0; ii < 4; ++ii ) { used_space += _col_widths[ii] * _col_type_count[ii]; } // Take from all if too much space has been taken for ( unsigned int ii=0; ii < 100; ++ii ) { if ( used_space <= avail_space ) { break; } // The estimate is too big bool changed ( false ); for ( unsigned int tii=0; tii < 4; ++tii ) { if ( ( _col_widths[tii] > _col_type_min_widths[tii] ) && ( used_space >= _col_type_count[tii] ) ) { _col_widths[tii] -= 1; used_space -= _col_type_count[tii]; changed = true; } } if ( !changed ) { break; } } // If now not all space is used after shrinking try to expand if ( used_space < avail_space ) { unsigned int space_delta ( avail_space - used_space ); unsigned int min_sp_max ( minor_spacing_max_width ( _col_widths[1] ) ); // Normalize single weights for comparison Layout_Weights col_weights_norm ( _col_type_weights ); for ( int ii=0; ii < 4; ++ii ) { if ( _col_type_count[ii] == 0 ) { col_weights_norm[ii] = 0; } } col_weights_norm.normalize(); const unsigned int invalid_type ( ~0 ); while ( space_delta > 0 ) { // Find maximum delta unsigned int increment_type ( invalid_type ); unsigned int num_less; unsigned int weight_delta_order[4]; { Layout_Weights col_widths_norm ( _col_widths ); col_widths_norm.normalize(); num_less = calc_weights_delta_order ( weight_delta_order, col_weights_norm, col_widths_norm ); } for ( unsigned int ii=0; ii < num_less; ++ii ) { unsigned int idx ( weight_delta_order[ii] ); if ( ( _col_type_count[idx] > 0 ) && ( _col_type_count[idx] <= space_delta ) && ( _col_widths[idx] < _col_max_widths[idx] ) ) { increment_type = idx; break; } } // Add to spacing as a fallback if ( increment_type == invalid_type ) { for ( unsigned int ii=0; ii < 4; ++ii ) { unsigned int idx ( weight_delta_order[ii] ); if ( idx < 2 ) { if ( ( _col_type_count[idx] > 0 ) && ( _col_type_count[idx] <= space_delta ) && ( _col_widths[idx] < _col_max_widths[idx] ) ) { if ( ( idx == 1 ) || ( _col_widths[0] < min_sp_max ) ) { increment_type = idx; break; } } } } } if ( increment_type != invalid_type ) { _col_widths[increment_type] += 1; used_space += _col_type_count[increment_type]; space_delta = avail_space - used_space; if ( increment_type == 1 ) { // Major spacing grew min_sp_max = minor_spacing_max_width ( _col_widths[1] ); } } else { break; } } } // // Set position and with for every active group / column // if ( _groups_active.size() == 0 ) { return; } // Write columns positioning data unsigned int spare_space ( avail_space - used_space ); unsigned int smallest_group_width ( width_n ); bool extra_space_major ( ( spare_space > 0 ) && ( _col_type_count[1] > 0 ) && ( _col_widths[1] < _col_max_widths[1] ) ); bool extra_space_minor ( ( spare_space > 0 ) && ( _col_type_count[0] > 0 ) && ( _col_type_count[1] == 0 ) && ( _col_widths[0] < _col_max_widths[0] ) ); // extra_space_start indicates the group or column index from which on // a single pixel horizontal space can be added to distribute the spare_space unsigned int extra_space_start ( ~0 ); if ( extra_space_major ) { extra_space_start = _groups_active.size() - 1; } else if ( extra_space_minor ) { if ( _groups_active[0]->num_columns() > 0 ) { extra_space_start = _groups_active[0]->num_columns() - 1; } } if ( spare_space > 0 ) { if ( extra_space_start > spare_space ) { extra_space_start -= spare_space; } else { extra_space_start = 0; } } unsigned int pos ( 0 ); unsigned int num_act_grps ( _groups_active.size() ); for ( unsigned int gii=0; gii < num_act_grps; ++gii ) { Equal_Columns_Layout_Group * grp ( _groups_active[gii] ); unsigned long col_width_cur; if ( grp->active_columns() == 1 ) { col_width_cur = _col_widths[3]; // Major slider } else { col_width_cur = _col_widths[2]; // Minor slider } unsigned int group_pos ( pos ); { const unsigned int num_cols ( grp->num_columns() ); unsigned int act_col_idx ( 0 ); for ( unsigned int cii=0; cii < num_cols; ++cii ) { Equal_Columns_Layout_Column * col ( grp->column ( cii ) ); if ( col->active_rows() > 0 ) { if ( act_col_idx > 0 ) { pos += _col_widths[0]; // Spacing minor if ( extra_space_minor && ( act_col_idx > extra_space_start ) ) { ++pos; } } col->set_column_pos ( pos ); col->set_column_width ( col_width_cur ); pos += col_width_cur; ++act_col_idx; } } } unsigned int group_width ( pos - group_pos ); grp->set_group_pos ( group_pos ); grp->set_group_width ( group_width ); pos += _col_widths[1]; // Spacing major if ( extra_space_major && ( gii >= extra_space_start ) ) { ++pos; } if ( ( group_width > 0 ) && ( group_width < smallest_group_width ) ) { smallest_group_width = group_width; } } for ( unsigned int ii=0; ii < 4; ++ii ) { _col_widths[ii] = _col_widths[ii]; } _smallest_group_dist = smallest_group_width + _col_widths[1]; if ( _col_type_count[ 0 ] > 0 ) { _smallest_column_dist = _col_widths[0] + _col_widths[2]; } else { _smallest_column_dist = _smallest_group_dist; } } void Equal_Columns_Layout::setGeometry ( const QRect & rect_n ) { QLayout::setGeometry ( rect_n ); if ( rect_n.isValid() ) { QRect crect ( rect_n ); { const QMargins & mgs ( contentsMargins() ); crect.adjust ( mgs.left(), mgs.top(), -mgs.right(), -mgs.bottom() ); } if ( crect.isValid() ) { update_cache(); if ( _rows_active > 0 ) { calc_columns_sizes ( crect.width(), crect.height() ); set_geometries ( crect ); } } } } void Equal_Columns_Layout::set_geometries ( const QRect & crect_n ) { // Set widgets geometries int y_pos ( crect_n.top() ); unsigned int num_rows ( _row_heights.size() ); for ( unsigned int rii=0; rii < num_rows; ++rii ) { if ( _row_heights[rii] == 0 ) { continue; } unsigned int items_set ( 0 ); QRect row_rect ( crect_n.left(), y_pos, crect_n.width(), _row_heights[rii] ); unsigned int num_act_grps ( _groups_active.size() ); for ( unsigned int gii=0; gii < num_act_grps; ++gii ) { const Equal_Columns_Layout_Group * grp ( _groups_active[gii] ); if ( grp == 0 ) { continue; } // Place items normally const unsigned int num_cols ( grp->num_columns() ); for ( unsigned int cii=0; cii < num_cols; ++cii ) { const Equal_Columns_Layout_Column * col ( grp->column ( cii ) ); if ( col == 0 ) { continue; } if ( col->num_rows() <= rii ) { continue; } const Equal_Columns_Layout_Row * row ( col->row ( rii ) ); if ( row == 0 ) { continue; } if ( row->item() == 0 ) { continue; } if ( row->item()->isEmpty() ) { continue; } set_geometry_row ( row_rect, grp, col, row ); ++items_set; } } if ( items_set > 0 ) { y_pos += row_rect.height(); y_pos += _spacing_vertical; } } } void Equal_Columns_Layout::set_geometry_row ( const QRect & row_rect_n, const Equal_Columns_Layout_Group * grp_n, const Equal_Columns_Layout_Column * col_n, const Equal_Columns_Layout_Row * row_n ) { QRect re_wdg ( row_rect_n.left() + col_n->column_pos(), row_rect_n.top(), col_n->column_width(), row_rect_n.height() ); // Count type numbers unsigned int num_sliders ( 0 ); unsigned int num_switches ( 0 ); if ( grp_n->num_rows() > 0 ) { num_sliders = grp_n->row_stat ( 0 ); if ( grp_n->num_rows() > 1 ) { num_switches = grp_n->row_stat ( 1 ); } } bool center_widget ( false ); if ( row_n->row_index() == 0 ) { // Center slider on demand if ( ( num_sliders == 1 ) && ( num_switches > 1 ) ) { center_widget = true; } } else if ( row_n->row_index() == 1 ) { // Center switch on demand if ( ( num_sliders > 1 ) && ( num_switches == 1 ) ) { center_widget = true; } } if ( center_widget ) { // Center widget horizontally in group int xx ( grp_n->group_pos() ); xx += ( grp_n->group_width() - re_wdg.width() ) / 2; re_wdg.moveLeft ( xx ); } //::std::cout << "re_wdg " << re_wdg.left() << " " << re_wdg.top() << " " << re_wdg.width() << " " << re_wdg.height() << "\n"; row_n->item()->setGeometry ( re_wdg ); } } // End of namespace qastools-v0.22.0/shared/src/wdg/equal_columns_layout.hpp000066400000000000000000000116551354534512100234340ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_equal_columns_layout_hpp__ #define __INC_equal_columns_layout_hpp__ #include #include #include #include #include #include namespace Wdg { // Forward declaration class Equal_Columns_Layout_Group; class Equal_Columns_Layout_Column; class Equal_Columns_Layout_Row; class Equal_Columns_Layout_Index; /// /// @brief Equal_Columns_Layout /// class Equal_Columns_Layout : public QLayout { // Public methods public: Equal_Columns_Layout ( QWidget * parent_n = 0 ); ~Equal_Columns_Layout ( ); // // Size hints // QSize minimumSize ( ) const; QSize sizeHint ( ) const; // // Variable reader // unsigned int num_groups ( ) const; const Equal_Columns_Layout_Group * group ( unsigned int idx_n ) const; unsigned int num_active_groups ( ) const; const Equal_Columns_Layout_Group * active_group ( unsigned int idx_n ) const; int spacing_vertical ( ) const; unsigned int smallest_group_dist ( ) const; unsigned int smallest_column_dist ( ) const; unsigned int num_rows ( ) const; unsigned int row_min_height ( unsigned int idx_n ) const; unsigned int row_height ( unsigned int idx_n ) const; unsigned int all_rows_height ( ) const; unsigned int row_pos ( unsigned int idx_n ) const; unsigned int col_type_width ( unsigned int type_n ); // // QLayout methods // int add_group_item ( QLayoutItem * item_n, unsigned int group_idx_n, unsigned int column_idx_n, unsigned int row_idx_n ); int add_group_widget ( QWidget * wdg_n, unsigned int group_idx, unsigned int column_idx, unsigned int row_idx_n ); void addItem ( QLayoutItem * item_n ); QLayoutItem * itemAt ( int index_n ) const; QLayoutItem * takeAt ( int index_n ); int count ( ) const; void invalidate ( ); void setGeometry ( const QRect & rect_n ); // Implementation methods // Direct use is not recommended void update_cache_const ( ) const; void update_cache ( ); /// update_cache should be called before this once void calc_columns_sizes ( unsigned int area_width_n, unsigned int area_height_n ); void calc_row_heights ( unsigned int height_n ); void calc_column_widths ( unsigned int width_n ); void set_row_height ( unsigned int row_idx_n, unsigned int height_n ); void set_geometries ( const QRect & crect_n ); void set_geometry_row ( const QRect & row_rect_n, const Equal_Columns_Layout_Group * grp_n, const Equal_Columns_Layout_Column * col_n, const Equal_Columns_Layout_Row * row_n ); // Protected methods protected: // Utility void remove_empty_groups_at_back ( ); unsigned int minor_spacing_max_width ( unsigned int major_sp_width_n ) const; // Private attributes; private: QList < Equal_Columns_Layout_Index * > _indices; QList < Equal_Columns_Layout_Group * > _groups; QList < Equal_Columns_Layout_Group * > _groups_active; unsigned int _smallest_group_dist; unsigned int _smallest_column_dist; unsigned int _col_type_count[4]; unsigned int _col_type_weights[4]; unsigned int _col_type_min_widths[4]; unsigned int _col_max_widths[4]; unsigned int _col_widths[4]; QList < unsigned int > _row_min_heights; QList < unsigned int > _row_heights; QList < unsigned int > _row_stretch; unsigned int _rows_active; int _spacing_vertical; bool _cache_dirty; }; inline unsigned int Equal_Columns_Layout::num_groups ( ) const { return _groups.size(); } inline const Equal_Columns_Layout_Group * Equal_Columns_Layout::group ( unsigned int idx_n ) const { return _groups[idx_n]; } inline unsigned int Equal_Columns_Layout::num_active_groups ( ) const { return _groups_active.size(); } inline const Equal_Columns_Layout_Group * Equal_Columns_Layout::active_group ( unsigned int idx_n ) const { return _groups_active[idx_n]; } inline unsigned int Equal_Columns_Layout::num_rows ( ) const { return _row_heights.size(); } inline unsigned int Equal_Columns_Layout::row_height ( unsigned int idx_n ) const { return _row_heights[idx_n]; } inline unsigned int Equal_Columns_Layout::row_min_height ( unsigned int idx_n ) const { return _row_min_heights[idx_n]; } inline unsigned int Equal_Columns_Layout::row_pos ( unsigned int idx_n ) const { unsigned int res ( 0 ); if ( idx_n > 0 ) { for ( unsigned int ii=0; ii <= idx_n; ++ii ) { res += _row_heights[ii]; res += spacing_vertical(); } } return res; } inline unsigned int Equal_Columns_Layout::col_type_width ( unsigned int type_n ) { return _col_widths[type_n]; } inline int Equal_Columns_Layout::spacing_vertical ( ) const { return _spacing_vertical; } inline unsigned int Equal_Columns_Layout::smallest_group_dist ( ) const { return _smallest_group_dist; } inline unsigned int Equal_Columns_Layout::smallest_column_dist ( ) const { return _smallest_column_dist; } } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/equal_columns_layout_group.cpp000066400000000000000000000055331354534512100246410ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "equal_columns_layout_group.hpp" namespace Wdg { // // Equal_Columns_Layout_Row // Equal_Columns_Layout_Row::Equal_Columns_Layout_Row ( unsigned int row_idx_n ) : _row_index ( row_idx_n ), _item ( 0 ) { } // // Equal_Columns_Layout_Column // Equal_Columns_Layout_Column::Equal_Columns_Layout_Column ( unsigned int column_index_n ) : _column_index ( column_index_n ), _active_rows ( 0 ), _column_pos ( 0 ), _column_width ( 0 ) { } Equal_Columns_Layout_Column::~Equal_Columns_Layout_Column ( ) { clear_rows(); } void Equal_Columns_Layout_Column::set_column_pos ( unsigned int pos_n ) { _column_pos = pos_n; } void Equal_Columns_Layout_Column::set_column_width ( unsigned int width_n ) { _column_width = width_n; } void Equal_Columns_Layout_Column::clear_rows ( ) { unsigned int rows ( num_rows() ); if ( rows > 0 ) { for ( unsigned int ii=0; ii < rows; ++ii ) { Equal_Columns_Layout_Row * row ( _rows[ii] ); if ( row != 0 ) { delete row; } } _rows.clear(); } } void Equal_Columns_Layout_Column::append_row ( Equal_Columns_Layout_Row * item_n ) { _rows.append ( item_n ); } void Equal_Columns_Layout_Column::remove_empty_rows_at_back ( ) { unsigned int idx ( num_rows() ); while ( idx > 0 ) { --idx; Equal_Columns_Layout_Row * row ( _rows[idx] ); bool remove ( true ); if ( row != 0 ) { if ( row->item() != 0 ) { remove = false; } } if ( remove ) { if ( row != 0 ) { delete row; } _rows.removeLast(); } else { break; } } } // // Equal_Columns_Layout_Column // Equal_Columns_Layout_Group::Equal_Columns_Layout_Group ( unsigned int group_idx_n ) : _group_index ( group_idx_n ), _active_columns ( 0 ), _group_pos ( 0 ), _group_width ( 0 ) { } Equal_Columns_Layout_Group::~Equal_Columns_Layout_Group ( ) { clear_columns(); } void Equal_Columns_Layout_Group::set_group_pos ( unsigned int pos_n ) { _group_pos = pos_n; } void Equal_Columns_Layout_Group::set_group_width ( unsigned int width_n ) { _group_width = width_n; } void Equal_Columns_Layout_Group::clear_columns ( ) { if ( num_columns() > 0 ) { for ( int ii=0; ii < _columns.size(); ++ii ) { delete _columns[ii]; } _columns.clear(); } } void Equal_Columns_Layout_Group::append_column ( Equal_Columns_Layout_Column * column_n ) { if ( column_n != 0 ) { _columns.append ( column_n ); } } void Equal_Columns_Layout_Group::remove_empty_columns_at_back ( ) { unsigned int idx ( num_columns() ); while ( idx > 0 ) { --idx; Equal_Columns_Layout_Column * col ( _columns[idx] ); bool remove ( true ); if ( col != 0 ) { if ( col->num_rows() != 0 ) { remove = false; } } if ( remove ) { if ( col != 0 ) { delete col; } _columns.removeLast(); } else { break; } } } } // End of namespace qastools-v0.22.0/shared/src/wdg/equal_columns_layout_group.hpp000066400000000000000000000134361354534512100246470ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_equal_columns_layout_group_hpp__ #define __INC_equal_columns_layout_group_hpp__ #include namespace Wdg { /// /// @brief Equal_Columns_Layout_Column /// class Equal_Columns_Layout_Row { // Public methods public: Equal_Columns_Layout_Row ( unsigned int row_idx_n ); // Row index unsigned int row_index ( ) const; void set_row_index ( unsigned int row_idx_n ); // Layout item QLayoutItem * item ( ) const; void set_item ( QLayoutItem * item_n ); // Private attributes private: unsigned int _row_index; QLayoutItem * _item; }; inline unsigned int Equal_Columns_Layout_Row::row_index ( ) const { return _row_index; } inline void Equal_Columns_Layout_Row::set_row_index ( unsigned int row_idx_n ) { _row_index = row_idx_n; } inline QLayoutItem * Equal_Columns_Layout_Row::item ( ) const { return _item; } inline void Equal_Columns_Layout_Row::set_item ( QLayoutItem * item_n ) { _item = item_n; } /// /// @brief Equal_Columns_Layout_Column /// class Equal_Columns_Layout_Column { // Public methods public: Equal_Columns_Layout_Column ( unsigned int column_idx_n ); virtual ~Equal_Columns_Layout_Column ( ); // Column index unsigned int column_index ( ) const; void set_column_index ( unsigned int idx_n ); // Active rows unsigned int active_rows ( ) const; void set_active_rows ( unsigned int num_n ); // Column position unsigned int column_pos ( ) const; void set_column_pos ( unsigned int pos_n ); // Column width unsigned int column_width ( ) const; void set_column_width ( unsigned int pos_n ); // Rows void clear_rows ( ); void append_row ( Equal_Columns_Layout_Row * item_n ); void remove_empty_rows_at_back ( ); unsigned int num_rows ( ) const; const Equal_Columns_Layout_Row * row ( unsigned int idx_n ) const; Equal_Columns_Layout_Row * row ( unsigned int idx_n ); // Private attributes private: unsigned int _column_index; unsigned int _active_rows; unsigned int _column_pos; unsigned int _column_width; QList < Equal_Columns_Layout_Row * > _rows; }; inline unsigned int Equal_Columns_Layout_Column::column_index ( ) const { return _column_index; } inline void Equal_Columns_Layout_Column::set_column_index ( unsigned int idx_n ) { _column_index = idx_n; } inline unsigned int Equal_Columns_Layout_Column::active_rows ( ) const { return _active_rows; } inline void Equal_Columns_Layout_Column::set_active_rows ( unsigned int num_n ) { _active_rows = num_n; } inline unsigned int Equal_Columns_Layout_Column::column_pos ( ) const { return _column_pos; } inline unsigned int Equal_Columns_Layout_Column::column_width ( ) const { return _column_width; } inline unsigned int Equal_Columns_Layout_Column::num_rows ( ) const { return _rows.size(); } inline const Equal_Columns_Layout_Row * Equal_Columns_Layout_Column::row ( unsigned int idx_n ) const { return _rows[idx_n]; } inline Equal_Columns_Layout_Row * Equal_Columns_Layout_Column::row ( unsigned int idx_n ) { return _rows[idx_n]; } /// /// @brief Equal_Columns_Layout_Group /// class Equal_Columns_Layout_Group { // Public methods public: Equal_Columns_Layout_Group ( unsigned int group_idx_n ); virtual ~Equal_Columns_Layout_Group ( ); // Group index unsigned int group_index ( ) const; void set_group_index ( unsigned int idx_n ); // Active columns unsigned int active_columns ( ) const; void set_active_columns ( unsigned int num_n ); // Group pos unsigned int group_pos ( ) const; void set_group_pos ( unsigned int pos_n ); // Group width unsigned int group_width ( ) const; void set_group_width ( unsigned int pos_n ); // Columns void clear_columns ( ); void append_column ( Equal_Columns_Layout_Column * column_n ); void remove_empty_columns_at_back ( ); unsigned int num_columns ( ) const; const Equal_Columns_Layout_Column * column ( unsigned int idx_n ) const; Equal_Columns_Layout_Column * column ( unsigned int idx_n ); // Row statistics QList < unsigned int > & row_stats ( ); unsigned int num_rows ( ) const; unsigned int row_stat ( unsigned int idx_n ) const; // Private attributes private: unsigned int _group_index; unsigned int _active_columns; unsigned int _group_pos; unsigned int _group_width; QList < Equal_Columns_Layout_Column * > _columns; QList < unsigned int > _row_stats; }; inline unsigned int Equal_Columns_Layout_Group::group_index ( ) const { return _group_index; } inline void Equal_Columns_Layout_Group::set_group_index ( unsigned int idx_n ) { _group_index = idx_n; } inline unsigned int Equal_Columns_Layout_Group::active_columns ( ) const { return _active_columns; } inline void Equal_Columns_Layout_Group::set_active_columns ( unsigned int num_n ) { _active_columns = num_n; } inline unsigned int Equal_Columns_Layout_Group::group_pos ( ) const { return _group_pos; } inline unsigned int Equal_Columns_Layout_Group::group_width ( ) const { return _group_width; } inline unsigned int Equal_Columns_Layout_Group::num_columns ( ) const { return _columns.size(); } inline const Equal_Columns_Layout_Column * Equal_Columns_Layout_Group::column ( unsigned int idx_n ) const { return _columns[idx_n]; } inline Equal_Columns_Layout_Column * Equal_Columns_Layout_Group::column ( unsigned int idx_n ) { return _columns[idx_n]; } inline QList < unsigned int > & Equal_Columns_Layout_Group::row_stats ( ) { return _row_stats; } inline unsigned int Equal_Columns_Layout_Group::num_rows ( ) const { return _row_stats.size(); } inline unsigned int Equal_Columns_Layout_Group::row_stat ( unsigned int idx_n ) const { return _row_stats[idx_n]; } } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/event_types.cpp000066400000000000000000000006771354534512100215320ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "event_types.hpp" namespace Wdg { ::QEvent::Type evt_pass_event_focus; ::QEvent::Type evt_pass_event_key; void init_event_types ( ) { evt_pass_event_focus = static_cast < QEvent::Type > ( QEvent::registerEventType() ); evt_pass_event_key = static_cast < QEvent::Type > ( QEvent::registerEventType() ); } } // End of namespace qastools-v0.22.0/shared/src/wdg/event_types.hpp000066400000000000000000000005431354534512100215270ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_wdg_event_types_hpp__ #define __INC_wdg_event_types_hpp__ #include namespace Wdg { extern ::QEvent::Type evt_pass_event_focus; extern ::QEvent::Type evt_pass_event_key; void init_event_types ( ); } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/fill_columns_layout.cpp000066400000000000000000000220421354534512100232360ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "fill_columns_layout.hpp" #include #include #include namespace Wdg { Fill_Columns_Layout::Fill_Columns_Layout ( QWidget * parent_n ) : QLayout ( parent_n ), _hspace ( -1 ), _vspace ( -1 ), _cache_dirty ( true ) { } Fill_Columns_Layout::~Fill_Columns_Layout ( ) { for ( int ii=0; ii < _items.size(); ++ii ) { delete _items[ii].item; } } QSize Fill_Columns_Layout::minimumSize ( ) const { update_cache_const(); QSize res ( 0, 0 ); const unsigned int num_items ( _items.size() ); for ( unsigned int ii=0; ii < num_items; ++ii ) { const QSize & ish ( _items[ii].min_size ); res.rwidth() = qMax ( ish.width(), res.width() ); res.rheight() = qMax ( ish.height(), res.height() ); } { const QMargins mgs ( contentsMargins() ); res.rwidth() += mgs.left() + mgs.right(); res.rheight() += mgs.top() + mgs.bottom(); } return res; } QSize Fill_Columns_Layout::sizeHint ( ) const { return minimumSize(); } bool Fill_Columns_Layout::hasHeightForWidth ( ) const { return true; } int Fill_Columns_Layout::heightForWidth ( int width ) const { QSize nsz ( 0, 0 ); if ( width > 0 ) { unsigned int aheight ( 65536 ); if ( _viewport.height() > 0 ) { aheight = _viewport.height(); } nsz = const_cast < Fill_Columns_Layout * > ( this )->calc_columns ( width, aheight ); } return ( nsz.height() ); } int Fill_Columns_Layout::horizontal_spacing ( ) const { int res ( -1 ); if ( _hspace >= 0 ) { res = _hspace; } else { QObject * pobj ( parent() ); if ( pobj != 0 ) { QStyle * style ( 0 ); QWidget * pwdg ( dynamic_cast < QWidget * > ( pobj ) ); if ( pwdg != 0 ) { style = pwdg->style(); } if ( style != 0 ) { res = pwdg->style()->pixelMetric ( QStyle::PM_LayoutHorizontalSpacing, 0, pwdg ); } else { res = static_cast < QLayout * > ( pobj )->spacing(); } } } return res; } int Fill_Columns_Layout::vertical_spacing ( ) const { int res ( -1 ); if ( _vspace >= 0 ) { res = _vspace; } else { QObject * pobj ( parent() ); if ( pobj != 0 ) { QStyle * style ( 0 ); QWidget * pwdg ( dynamic_cast < QWidget * > ( pobj ) ); if ( pwdg != 0 ) { style = pwdg->style(); } if ( style != 0 ) { res = style->pixelMetric ( QStyle::PM_LayoutVerticalSpacing, 0, pwdg ); } else { res = static_cast < QLayout * > ( pobj )->spacing(); } } } return res; } unsigned int Fill_Columns_Layout::horizontal_spacing_default ( ) const { int hspace ( horizontal_spacing() ); if ( hspace < 0 ) { hspace = spacing_default ( Qt::Horizontal ); } return hspace; } unsigned int Fill_Columns_Layout::vertical_spacing_default ( ) const { int vspace ( vertical_spacing() ); if ( vspace < 0 ) { vspace = spacing_default ( Qt::Vertical ); } return vspace; } unsigned int Fill_Columns_Layout::spacing_default ( Qt::Orientation orient_n ) const { int res ( 0 ); QWidget * pwdg ( parentWidget() ); if ( pwdg != 0 ) { QStyle * style ( pwdg->style() ); if ( style != 0 ) { res = style->combinedLayoutSpacing ( QSizePolicy::DefaultType, QSizePolicy::DefaultType, orient_n, 0, pwdg ); if ( res < 0 ) { res = 0; } } } return res; } QLayoutItem * Fill_Columns_Layout::itemAt ( int index ) const { QLayoutItem * res ( 0 ); if ( ( index >= 0 ) && ( index < _items.size() ) ) { res = _items[index].item; } return res; } int Fill_Columns_Layout::count ( ) const { return _items.size(); } void Fill_Columns_Layout::addItem ( QLayoutItem * item_n ) { if ( item_n != 0 ) { Fill_Columns_Layout_Item fitem; fitem.item = item_n; _items.push_back ( fitem ); } } QLayoutItem * Fill_Columns_Layout::takeAt ( int index_n ) { QLayoutItem * res ( 0 ); if ( ( index_n >= 0 ) && ( index_n < _items.size() ) ) { res = _items[index_n].item; _items.removeAt ( index_n ); } return res; } void Fill_Columns_Layout::invalidate ( ) { _cache_dirty = true; QLayout::invalidate(); } void Fill_Columns_Layout::set_viewport_geometry ( const QRect & rect_n ) { if ( _viewport != rect_n ) { _viewport = rect_n; invalidate(); } } void Fill_Columns_Layout::setGeometry ( const QRect & rect_n ) { QLayout::setGeometry ( rect_n ); if ( !rect_n.isValid() ) { return; } unsigned int aheight ( 65536 ); if ( _viewport.isValid() ) { int hh ( _viewport.top() + _viewport.height() - rect_n.top() ); if ( hh > 0 ) { aheight = hh; } } calc_columns ( rect_n.width(), aheight ); const unsigned int num_items ( _items.size() ); for ( unsigned int ii=0; ii < num_items; ++ii ) { Fill_Columns_Layout_Item & fitem ( _items[ii] ); if ( !fitem.item->isEmpty() ) { QRect irect ( fitem.rect ); irect.moveTop ( irect.top() + rect_n.top() ); irect.moveLeft ( irect.left() + rect_n.left() ); fitem.item->setGeometry ( irect ); } } } QSize Fill_Columns_Layout::calc_columns ( unsigned int width_n, unsigned int height_n ) { update_cache(); //::std::cout << "Fill_Columns_Layout::calc_columns " << width_n << "\n"; QSize res; unsigned int x_left ( 0 ); unsigned int x_limit ( width_n ); unsigned int y_top ( 0 ); unsigned int y_limit ( height_n ); // Adjust start points and limits { QMargins mgs ( contentsMargins() ); if ( mgs.left() > 0 ) { x_left = mgs.left(); } if ( mgs.right() > 0 ) { if ( (int)x_limit > mgs.right() ) { x_limit -= mgs.right(); } else { x_limit = 0; } } if ( mgs.top() > 0 ) { y_top += mgs.top(); } if ( mgs.bottom() > 0 ) { if ( (int)y_limit > mgs.bottom() ) { y_limit -= mgs.bottom(); } else { y_limit = 0; } } res.setWidth ( mgs.right() ); res.setHeight ( mgs.bottom() ); } //::std::cout << "Viewport " << _viewport.width() << ":" << _viewport.height() << "\n"; //::std::cout << "y_top " << y_top << "\n"; //::std::cout << "y_max " << y_max << "\n"; const unsigned int fixed_hspace ( horizontal_spacing() ); const unsigned int fixed_vspace ( vertical_spacing() ); QStyle * style ( 0 ); QWidget * pwdg ( parentWidget() ); if ( pwdg != 0 ) { style = pwdg->style(); } QSizePolicy::ControlTypes ctl_types1; QSizePolicy::ControlTypes ctl_types2; unsigned int x_pos ( x_left ); unsigned int x_pos_max ( x_left ); unsigned int y_pos ( y_top ); unsigned int y_pos_max ( y_top ); unsigned int row_idx ( 0 ); const unsigned int num_items ( _items.size() ); for ( unsigned int ii=0; ii < num_items; ++ii ) { Fill_Columns_Layout_Item & fitem ( _items[ii] ); if ( fitem.item->isEmpty() ) { continue; } ctl_types1 = ctl_types2; ctl_types2 = fitem.item->controlTypes(); // Add vertical spacing if ( row_idx > 0 ) { int vspace ( fixed_vspace ); if ( ( vspace < 0 ) && ( style != 0 ) ) { vspace = style->combinedLayoutSpacing ( ctl_types1, ctl_types2, Qt::Vertical, 0, pwdg ); } if ( vspace < 0 ) { vspace = 0; } y_pos += vspace; } const unsigned int iwidth ( qMax ( 0, fitem.min_size.width() ) ); const unsigned int iheight ( qMax ( 0, fitem.min_size.height() ) ); unsigned int y_bot ( y_pos + iheight ); // Start new column on demand if ( ( y_bot > y_limit ) && ( row_idx > 0 ) ) { // Find broadest following widget unsigned int wmax ( 0 ); for ( unsigned int jj=ii; jj < num_items; ++jj ) { if ( !_items[jj].item->isEmpty() ) { int iww ( _items[jj].min_size.width() ); if ( ( iww > 0 ) && ( iww > (int)wmax ) ) { wmax = iww; } } } int hspace ( fixed_hspace ); if ( ( hspace < 0 ) && ( style != 0 ) ) { hspace = style->combinedLayoutSpacing ( ctl_types1, ctl_types2, Qt::Horizontal, 0, pwdg ); } if ( hspace < 0 ) { hspace = 0; } // Start new column if it fits into the give width if ( ( x_pos_max + hspace + wmax ) <= x_limit ) { // New column x_pos = x_pos_max + hspace; x_pos_max = x_pos; y_pos = y_top; row_idx = 0; } } fitem.rect.moveLeft ( x_pos ); fitem.rect.moveTop ( y_pos ); fitem.rect.setWidth ( iwidth ); fitem.rect.setHeight ( iheight ); y_pos += iheight; // Update maxima storages { unsigned int tmp ( x_pos + iwidth ); if ( x_pos_max < tmp ) { x_pos_max = tmp; } if ( y_pos_max < y_pos ) { y_pos_max = y_pos; } } ++row_idx; } // Adjust vertical align if ( y_pos_max < y_limit ) { unsigned int delta ( ( y_limit - y_pos_max ) / 2 ); y_pos_max += delta; for ( unsigned int ii=0; ii < num_items; ++ii ) { Fill_Columns_Layout_Item & fitem ( _items[ii] ); fitem.rect.moveTop ( fitem.rect.top() + delta ); } } res.rwidth() += qMax ( 0, (int)x_pos_max - 1 ); res.rheight() += qMax ( 0, (int)y_pos_max - 1 ); return res; } void Fill_Columns_Layout::update_cache_const ( ) const { const_cast < Fill_Columns_Layout * > ( this )->update_cache(); } void Fill_Columns_Layout::update_cache ( ) { if ( !_cache_dirty ) { return; } _cache_dirty = false; const unsigned int num_items ( _items.size() ); for ( unsigned int ii=0; ii < num_items; ++ii ) { _items[ii].min_size = _items[ii].item->minimumSize(); } } } // End of namespace qastools-v0.22.0/shared/src/wdg/fill_columns_layout.hpp000066400000000000000000000035321354534512100232460ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_fill_columns_layout_hpp__ #define __INC_fill_columns_layout_hpp__ #include #include #include namespace Wdg { class Fill_Columns_Layout_Item { public: Fill_Columns_Layout_Item ( ); QLayoutItem * item; QSize min_size; QRect rect; }; inline Fill_Columns_Layout_Item::Fill_Columns_Layout_Item ( ) : item ( 0 ) { } class Fill_Columns_Layout : public QLayout { // Public methods public: Fill_Columns_Layout ( QWidget * parent_n = 0 ); ~Fill_Columns_Layout ( ); // Size hints QSize sizeHint ( ) const; QSize minimumSize ( ) const; bool hasHeightForWidth ( ) const; int heightForWidth ( int width ) const; // Spacings int horizontal_spacing ( ) const; int vertical_spacing ( ) const; unsigned int horizontal_spacing_default ( ) const; unsigned int vertical_spacing_default ( ) const; unsigned int spacing_default ( Qt::Orientation orient_n ) const; // Viewport geometry const QRect & viewport_geometry ( ) const; void set_viewport_geometry ( const QRect & rect_n ); // Layout methods QLayoutItem * itemAt ( int index_n ) const; int count ( ) const; void addItem ( QLayoutItem * item_n ); QLayoutItem * takeAt ( int index_n ); void invalidate ( ); void setGeometry ( const QRect & rect_n ); // Protected methods protected: void update_cache_const ( ) const; void update_cache ( ); QSize calc_columns ( unsigned int width_n, unsigned int height_n ); // Private attributes private: QList < Fill_Columns_Layout_Item > _items; QRect _viewport; int _hspace; int _vspace; bool _cache_dirty; }; inline const QRect & Fill_Columns_Layout::viewport_geometry ( ) const { return _viewport; } } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/label_elide.cpp000066400000000000000000000027171354534512100214030ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "label_elide.hpp" #include namespace Wdg { Label_Elide::Label_Elide ( QWidget * parent_n ) : QWidget ( parent_n ), _alignment ( Qt::AlignLeft | Qt::AlignVCenter ), _elide_mode ( Qt::ElideMiddle ) { } QSize Label_Elide::minimumSizeHint ( ) const { return QSize ( 0, fontMetrics().height() ); } QSize Label_Elide::sizeHint ( ) const { QSize res ( fontMetrics().width ( text() ), fontMetrics().height() ); return res; } void Label_Elide::setText ( const QString txt_n ) { if ( txt_n != _text ) { _text = txt_n; update_text_elided(); updateGeometry(); update(); } } void Label_Elide::setAlignment ( Qt::Alignment align_n ) { if ( align_n != _alignment ) { _alignment = align_n; update_text_elided(); update(); } } void Label_Elide::setElideMode ( Qt::TextElideMode mode_n ) { if ( mode_n != _elide_mode ) { _elide_mode = mode_n; update_text_elided(); update(); } } void Label_Elide::update_text_elided ( ) { _text_elided = fontMetrics().elidedText ( _text, _elide_mode, width() ); } void Label_Elide::resizeEvent ( QResizeEvent * event_n ) { QWidget::resizeEvent ( event_n ); update_text_elided(); } void Label_Elide::paintEvent ( QPaintEvent * event_n ) { QWidget::paintEvent ( event_n ); QPainter painter ( this ); painter.drawText ( contentsRect(), _alignment, _text_elided ); } } // End of namespace qastools-v0.22.0/shared/src/wdg/label_elide.hpp000066400000000000000000000023221354534512100214000ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_label_elide_hpp__ #define __INC_label_elide_hpp__ #include #include namespace Wdg { class Label_Elide : public QWidget { // Public methods public: Label_Elide ( QWidget * parent = 0 ); const QString & text ( ) const; void setText ( const QString txt_n ); Qt::Alignment alignment ( ) const; void setAlignment ( Qt::Alignment align_n ); Qt::TextElideMode elideMode ( ) const; void setElideMode ( Qt::TextElideMode mode_n ); QSize minimumSizeHint ( ) const; QSize sizeHint ( ) const; // Protected methods protected: void update_text_elided ( ); void resizeEvent ( QResizeEvent * event_n ); void paintEvent ( QPaintEvent * event_n ); // Private attributes private: QString _text; QString _text_elided; Qt::Alignment _alignment; Qt::TextElideMode _elide_mode; }; inline const QString & Label_Elide::text ( ) const { return _text; } inline Qt::Alignment Label_Elide::alignment ( ) const { return _alignment; } inline Qt::TextElideMode Label_Elide::elideMode ( ) const { return _elide_mode; } } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/label_width.cpp000066400000000000000000000015611354534512100214340ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "label_width.hpp" namespace Wdg { Label_Width::Label_Width ( QWidget * parent_n ) : QLabel ( parent_n ) { } QSize Label_Width::minimumSizeHint ( ) const { QSize res ( QLabel::minimumSizeHint() ); int w_min ( fontMetrics().width ( _min_text ) ); res.setWidth ( qMax ( res.width(), w_min ) ); return res; } QSize Label_Width::sizeHint ( ) const { QSize res ( QLabel::sizeHint() ); int w_min ( fontMetrics().width ( _min_text ) ); { QMargins mg ( contentsMargins() ); w_min += mg.left(); w_min += mg.right(); } res.setWidth ( qMax ( res.width(), w_min ) ); return res; } void Label_Width::set_min_text ( const QString txt_n ) { if ( txt_n != _min_text ) { _min_text = txt_n; updateGeometry(); adjustSize(); } } } // End of namespace qastools-v0.22.0/shared/src/wdg/label_width.hpp000066400000000000000000000012141354534512100214340ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_label_width_hpp__ #define __INC_label_width_hpp__ #include #include namespace Wdg { class Label_Width : public QLabel { // Public methods public: Label_Width ( QWidget * parent = 0 ); const QString & min_text ( ) const; void set_min_text ( const QString txt_n ); QSize minimumSizeHint ( ) const; QSize sizeHint ( ) const; // Private attributes private: QString _min_text; }; inline const QString & Label_Width::min_text ( ) const { return _min_text; } } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/layout_weights.cpp000066400000000000000000000047011354534512100222240ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "layout_weights.hpp" #include #include namespace Wdg { void Layout_Weights::normalize ( unsigned long weight_normal_n ) { unsigned long wsum ( sum() ); if ( wsum == weight_normal_n ) { return; } if ( wsum == 0 ) { set_all ( weight_normal_n / 4 ); wsum = sum(); } Layout_Weights weights_cur; Layout_Weights weights_cur_mod; for ( unsigned int ii=0; ii < 4; ++ii ) { weights_cur[ii] = ( _weights[ii] * weight_normal_n ); } for ( unsigned int ii=0; ii < 4; ++ii ) { weights_cur_mod[ii] = ( weights_cur[ii] % wsum ); } for ( unsigned int ii=0; ii < 4; ++ii ) { weights_cur[ii] = ( weights_cur[ii] / wsum ); } wsum = weights_cur.sum(); while ( wsum < weight_normal_n ) { // Find largest modulo (division rest) value unsigned int max_mod_idx ( 0 ); { unsigned long max_mod ( 0 ); for ( int ii=0; ii < 4; ++ii ) { const unsigned long & cur_mod ( weights_cur_mod[ii] ); if ( cur_mod > max_mod ) { max_mod = cur_mod; max_mod_idx = ii; } } } // Increase weight with largest division rest weights_cur[max_mod_idx] += 1; weights_cur_mod[max_mod_idx] = 0; wsum = weights_cur.sum(); } *this = weights_cur; } unsigned int calc_weights_delta_order ( unsigned int * order_n, const Layout_Weights & wnorm_req_n, const Layout_Weights & wnorm_cur_n ) { unsigned int res ( 0 ); // Use weight values as indices for ( unsigned int ii=0; ii < 4; ++ii ) { order_n[ii] = ii; } for ( unsigned int ii=0; ii < 4; ++ii ) { unsigned int min_idx ( ii ); unsigned long min_delta_minus ( 0 ); unsigned long min_delta_plus ( 0 ); // Find minimum value in remaining values for ( unsigned int jj=ii; jj < 4; ++jj ) { unsigned int idx ( order_n[jj] ); unsigned long delta_minus ( 0 ); unsigned long delta_plus ( 0 ); if ( wnorm_req_n[idx] > wnorm_cur_n[idx] ) { delta_minus = wnorm_req_n[idx] - wnorm_cur_n[idx]; } else { delta_plus = wnorm_cur_n[idx] - wnorm_req_n[idx]; } if ( ( delta_minus > min_delta_minus ) || ( delta_plus < min_delta_plus ) ) { min_delta_minus = delta_minus; min_delta_plus = delta_plus; min_idx = jj; } } if ( min_delta_minus > 0 ) { ++res; } // Swap the minimum index to the front if ( min_idx != ii ) { std::swap ( order_n[ii], order_n[min_idx] ); } } return res; } } // End of namespace qastools-v0.22.0/shared/src/wdg/layout_weights.hpp000066400000000000000000000036761354534512100222430ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_layout_weights_hpp__ #define __INC_layout_weights_hpp__ namespace Wdg { /// /// @brief Layout_Weights /// class Layout_Weights { // Public methods public: Layout_Weights ( ); Layout_Weights ( unsigned int * values_n ); Layout_Weights ( unsigned long * values_n ); Layout_Weights ( unsigned long value_all_n ); unsigned long sum ( ) const; void set_all ( unsigned long value_n ); void normalize ( unsigned long weight_normal_n = 4096 ); unsigned long operator[] ( unsigned int idx_n ) const; unsigned long & operator[] ( unsigned int idx_n ); // Private attributes private: unsigned long _weights[4]; }; unsigned int calc_weights_delta_order ( unsigned int * order_n, const Layout_Weights & wnorm_req_n, const Layout_Weights & wnorm_cur_n ); // // Definitions // inline Layout_Weights::Layout_Weights ( ) { } inline Layout_Weights::Layout_Weights ( unsigned int * values_n ) { for ( unsigned int ii=0; ii < 4; ++ii ) { _weights[ii] = values_n[ii]; } } inline Layout_Weights::Layout_Weights ( unsigned long * values_n ) { for ( unsigned int ii=0; ii < 4; ++ii ) { _weights[ii] = values_n[ii]; } } inline Layout_Weights::Layout_Weights ( unsigned long value_all_n ) { for ( unsigned int ii=0; ii < 4; ++ii ) { _weights[ii] = value_all_n; } } inline unsigned long Layout_Weights::operator[] ( unsigned int idx_n ) const { return _weights[idx_n]; } inline unsigned long & Layout_Weights::operator[] ( unsigned int idx_n ) { return _weights[idx_n]; } inline void Layout_Weights::set_all ( unsigned long value_n ) { for ( unsigned int ii=0; ii < 4; ++ii ) { _weights[ii] = value_n; } } inline unsigned long Layout_Weights::sum ( ) const { unsigned long res ( 0 ); for ( unsigned int ii=0; ii < 4; ++ii ) { res += _weights[ii]; } return res; } } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/pad_focus_info.cpp000066400000000000000000000005051354534512100221310ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "pad_focus_info.hpp" namespace Wdg { Pad_Focus_Info::Pad_Focus_Info ( ) { clear(); } void Pad_Focus_Info::clear ( ) { has_focus = false; group_idx = 0; column_idx = 0; row_idx = 0; } } // End of namespace qastools-v0.22.0/shared/src/wdg/pad_focus_info.hpp000066400000000000000000000007751354534512100221470ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_pad_focus_info_hpp__ #define __INC_pad_focus_info_hpp__ namespace Wdg { /// @brief Specifies which element of a slider/switches pad has the focus /// class Pad_Focus_Info { // Public methods public: Pad_Focus_Info ( ); void clear ( ); // Public attributes bool has_focus; unsigned int group_idx; unsigned int column_idx; unsigned int row_idx; }; } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/pad_proxies_column.cpp000066400000000000000000000070011354534512100230430ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "pad_proxies_column.hpp" #include "wdg/pad_proxies_group.hpp" #include "wdg/pad_proxy_slider.hpp" #include "wdg/pad_proxy_switch.hpp" #include "wdg/pad_proxy_enum.hpp" #include "wdg/event_types.hpp" #include "wdg/pass_events.hpp" #include #include #include namespace Wdg { Pad_Proxies_Column::Pad_Proxies_Column ( unsigned int col_idx_n ) : _column_index ( col_idx_n ), _proxy_slider ( 0 ), _proxy_switch ( 0 ), _proxy_enum ( 0 ), _has_focus ( false ), _show_value_string ( true ) { } Pad_Proxies_Column::~Pad_Proxies_Column ( ) { clear_proxies(); } ::Wdg::Pad_Proxies_Group * Pad_Proxies_Column::group ( ) const { ::Wdg::Pad_Proxies_Group * res ( 0 ); QObject * par ( parent() ); if ( par != 0 ) { res = dynamic_cast < ::Wdg::Pad_Proxies_Group * > ( par ); } return res; } void Pad_Proxies_Column::set_column_index ( unsigned int idx_n ) { _column_index = idx_n; } void Pad_Proxies_Column::clear_proxies ( ) { if ( _proxy_slider != 0 ) { delete _proxy_slider; _proxy_slider = 0; } if ( _proxy_switch != 0 ) { delete _proxy_switch; _proxy_switch = 0; } if ( _proxy_enum != 0 ) { delete _proxy_enum; _proxy_enum = 0; } } void Pad_Proxies_Column::set_slider_proxy ( ::Wdg::Pad_Proxy_Slider * proxy_n ) { if ( proxy_n != _proxy_slider ) { if ( proxy_n != 0 ) { proxy_n->setParent ( this ); } _proxy_slider = proxy_n; this->slider_proxy_changed(); } } void Pad_Proxies_Column::set_switch_proxy ( ::Wdg::Pad_Proxy_Switch * proxy_n ) { if ( proxy_n != _proxy_switch ) { if ( proxy_n != 0 ) { proxy_n->setParent ( this ); } _proxy_switch = proxy_n; this->switch_proxy_changed(); } } void Pad_Proxies_Column::set_enum_proxy ( ::Wdg::Pad_Proxy_Enum * proxy_n ) { if ( proxy_n != _proxy_enum ) { if ( proxy_n != 0 ) { proxy_n->setParent ( this ); } _proxy_enum = proxy_n; this->enum_proxy_changed(); } } void Pad_Proxies_Column::set_show_value_string ( bool flag_n ) { if ( flag_n != _show_value_string ) { _show_value_string = flag_n; this->show_value_string_changed(); } } QString Pad_Proxies_Column::value_string ( ) const { QString res; if ( slider_proxy() != 0 ) { const QString mask ( "%1" ); res = mask.arg ( slider_proxy()->slider_index() ); } return res; } QString Pad_Proxies_Column::value_min_string ( ) const { QString res; if ( slider_proxy() != 0 ) { const QString mask ( "%1" ); res = mask.arg ( 0 ); } return res; } QString Pad_Proxies_Column::value_max_string ( ) const { QString res; if ( slider_proxy() != 0 ) { const QString mask ( "%1" ); res = mask.arg ( slider_proxy()->slider_index_max() ); } return res; } void Pad_Proxies_Column::slider_proxy_changed ( ) { // Dummy implementation } void Pad_Proxies_Column::switch_proxy_changed ( ) { // Dummy implementation } void Pad_Proxies_Column::enum_proxy_changed ( ) { // Dummy implementation } void Pad_Proxies_Column::show_value_string_changed ( ) { // Dummy implementation } bool Pad_Proxies_Column::event ( QEvent * event_n ) { if ( event_n->type() == ::Wdg::evt_pass_event_focus ) { ::Wdg::Pass_Event_Focus * ev_fp ( static_cast < ::Wdg::Pass_Event_Focus * > ( event_n ) ); _has_focus = ev_fp->ev_focus.gotFocus(); if ( parent() != 0 ) { ev_fp->column_idx = column_index(); QCoreApplication::sendEvent ( parent(), event_n ); } return true; } return QObject::event ( event_n ); } } // End of namespace qastools-v0.22.0/shared/src/wdg/pad_proxies_column.hpp000066400000000000000000000055601354534512100230600ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_wdg_pad_proxies_column_hpp__ #define __INC_wdg_pad_proxies_column_hpp__ #include #include "wdg/pad_proxy.hpp" // Forward declaration namespace Wdg { class Pad_Proxies_Group; class Pad_Proxy_Slider; class Pad_Proxy_Switch; class Pad_Proxy_Enum; } namespace Wdg { class Pad_Proxies_Column : public QObject { Q_OBJECT // Public methods public: Pad_Proxies_Column ( unsigned int col_idx_n = 0 ); virtual ~Pad_Proxies_Column ( ); ::Wdg::Pad_Proxies_Group * group ( ) const; // Column index unsigned int column_index ( ) const; void set_column_index ( unsigned int idx_n ); void clear_proxies ( ); // Slider proxy ::Wdg::Pad_Proxy_Slider * slider_proxy ( ) const; void set_slider_proxy ( ::Wdg::Pad_Proxy_Slider * proxy_n ); // Switch proxy ::Wdg::Pad_Proxy_Switch * switch_proxy ( ) const; void set_switch_proxy ( ::Wdg::Pad_Proxy_Switch * proxy_n ); // Enum proxy ::Wdg::Pad_Proxy_Enum * enum_proxy ( ) const; void set_enum_proxy ( ::Wdg::Pad_Proxy_Enum * proxy_n ); // Show value string void set_show_value_string ( bool flag_n ); bool show_value_string ( ) const; // State info bool has_slider ( ) const; bool has_switch ( ) const; bool has_enum ( ) const; bool has_focus ( ) const; // Value string virtual QString value_string ( ) const; virtual QString value_min_string ( ) const; virtual QString value_max_string ( ) const; // Event handling bool event ( QEvent * event_n ); // Signals signals: void sig_value_string_changed ( ); // Protected methods protected: virtual void slider_proxy_changed ( ); virtual void switch_proxy_changed ( ); virtual void enum_proxy_changed ( ); virtual void show_value_string_changed ( ); // Private attributes private: unsigned int _column_index; ::Wdg::Pad_Proxy_Slider * _proxy_slider; ::Wdg::Pad_Proxy_Switch * _proxy_switch; ::Wdg::Pad_Proxy_Enum * _proxy_enum; bool _has_focus; bool _show_value_string; }; inline unsigned int Pad_Proxies_Column::column_index ( ) const { return _column_index; } inline ::Wdg::Pad_Proxy_Slider * Pad_Proxies_Column::slider_proxy ( ) const { return _proxy_slider; } inline ::Wdg::Pad_Proxy_Switch * Pad_Proxies_Column::switch_proxy ( ) const { return _proxy_switch; } inline ::Wdg::Pad_Proxy_Enum * Pad_Proxies_Column::enum_proxy ( ) const { return _proxy_enum; } inline bool Pad_Proxies_Column::has_slider ( ) const { return ( _proxy_slider != 0 ); } inline bool Pad_Proxies_Column::has_switch ( ) const { return ( _proxy_switch != 0 ); } inline bool Pad_Proxies_Column::has_enum ( ) const { return ( _proxy_enum != 0 ); } inline bool Pad_Proxies_Column::show_value_string ( ) const { return _show_value_string; } } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/pad_proxies_group.cpp000066400000000000000000000055251354534512100227130ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "pad_proxies_group.hpp" #include "wdg/pad_proxy_slider.hpp" #include "wdg/pad_proxy_switch.hpp" #include "wdg/pad_proxies_column.hpp" #include "wdg/event_types.hpp" #include "wdg/pass_events.hpp" #include #include namespace Wdg { Pad_Proxies_Group::Pad_Proxies_Group ( QObject * parent_n ) : QObject ( parent_n ), _pad ( 0 ), _group_index ( 0 ), _style_id ( 0 ), _num_sliders ( 0 ), _num_switches ( 0 ), _focus_column ( 0 ), _focus_row ( 0 ), _has_focus ( false ) { } Pad_Proxies_Group::~Pad_Proxies_Group ( ) { clear_columns(); } void Pad_Proxies_Group::set_pad ( QObject * pad_n ) { _pad = pad_n; } void Pad_Proxies_Group::set_group_index ( unsigned int idx_n ) { _group_index = idx_n; } void Pad_Proxies_Group::clear_columns ( ) { if ( _columns.size() > 0 ) { for ( int ii=0; ii < _columns.size(); ++ii ) { delete _columns[ii]; } _columns.clear(); _num_sliders = 0; _num_switches = 0; } } void Pad_Proxies_Group::append_column ( ::Wdg::Pad_Proxies_Column * column_n ) { if ( column_n != 0 ) { column_n->setParent ( this ); column_n->set_column_index ( _columns.size() ); _columns.append ( column_n ); if ( column_n->has_slider() != 0 ) { ++_num_sliders; } if ( column_n->has_switch() != 0 ) { ++_num_switches; } } } void Pad_Proxies_Group::set_group_name ( const QString & name_n ) { _group_name = name_n; } void Pad_Proxies_Group::set_tool_tip ( const QString & tip_n ) { _tool_tip = tip_n; } void Pad_Proxies_Group::set_style_id ( unsigned int style_id_n ) { _style_id = style_id_n; } bool Pad_Proxies_Group::take_focus ( unsigned int column_n, unsigned int row_n ) { bool success ( false ); if ( column_n >= num_columns() ) { // Use first column as fallback column_n = 0; } if ( column_n < num_columns() ) { ::Wdg::Pad_Proxies_Column * col ( column ( column_n ) ); ::Wdg::Pad_Proxy * proxy ( 0 ); if ( row_n == 0 ) { proxy = col->slider_proxy(); } else { proxy = col->switch_proxy(); if ( proxy == 0 ) { proxy = col->slider_proxy(); } } if ( proxy != 0 ) { QWidget * wdg ( proxy->widget() ); if ( wdg != 0 ) { if ( wdg->isEnabled() ) { wdg->setFocus(); success = true; } } } } return success; } bool Pad_Proxies_Group::event ( QEvent * event_n ) { if ( event_n->type() == ::Wdg::evt_pass_event_focus ) { ::Wdg::Pass_Event_Focus * ev_fp ( static_cast < ::Wdg::Pass_Event_Focus * > ( event_n ) ); _focus_column = ev_fp->column_idx; _focus_row = ev_fp->row_idx; _has_focus = ev_fp->ev_focus.gotFocus(); if ( pad() != 0 ) { ev_fp->group_idx = group_index(); QCoreApplication::sendEvent ( pad(), event_n ); } return true; } return QObject::event ( event_n ); } } // End of namespace qastools-v0.22.0/shared/src/wdg/pad_proxies_group.hpp000066400000000000000000000062661354534512100227230ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_wdg_pad_proxies_group_hpp__ #define __INC_wdg_pad_proxies_group_hpp__ #include #include // Forward declaration namespace Wdg { class Pad_Proxies_Column; } namespace Wdg { class Pad_Proxies_Group : public QObject { Q_OBJECT // Public methods public: Pad_Proxies_Group ( QObject * parent_n = 0 ); virtual ~Pad_Proxies_Group ( ); /// @brief The pad object /// Gets set by the pad and shouldn't be set manually QObject * pad ( ) const; void set_pad ( QObject * pad_n ); // Group index /// @brief The group index /// Gets set by the sliders pad and shouldn't be set manually unsigned int group_index ( ) const; void set_group_index ( unsigned int idx_n ); // Group name const QString & group_name ( ) const; void set_group_name ( const QString & name_n ); // Tool tip const QString & tool_tip ( ) const; void set_tool_tip ( const QString & tip_n ); // Style id unsigned int style_id ( ) const; void set_style_id ( unsigned int style_id_n ); // Proxies columns unsigned int num_columns ( ) const; void append_column ( ::Wdg::Pad_Proxies_Column * column_n ); void clear_columns ( ); ::Wdg::Pad_Proxies_Column * column ( unsigned int idx_n ) const; // Statistics unsigned int num_sliders ( ) const; unsigned int num_switches ( ) const; // Focus unsigned char focus_column ( ) const; unsigned char focus_row ( ) const; bool has_focus ( ) const; /// @return true when the focus was taken - false when already has focus or invalid column bool take_focus ( unsigned int column_n, unsigned int row_n ); // Protected methods protected: bool event ( QEvent * event_n ); // Private attributes private: QObject * _pad; unsigned int _group_index; unsigned int _style_id; QList < ::Wdg::Pad_Proxies_Column * > _columns; QString _group_name; QString _tool_tip; unsigned int _num_sliders; unsigned int _num_switches; unsigned char _focus_column; unsigned char _focus_row; bool _has_focus; }; inline QObject * Pad_Proxies_Group::pad ( ) const { return _pad; } inline unsigned int Pad_Proxies_Group::group_index ( ) const { return _group_index; } inline unsigned int Pad_Proxies_Group::num_columns ( ) const { return _columns.size(); } inline ::Wdg::Pad_Proxies_Column * Pad_Proxies_Group::column ( unsigned int idx_n ) const { return _columns[idx_n]; } inline const QString & Pad_Proxies_Group::group_name ( ) const { return _group_name; } inline const QString & Pad_Proxies_Group::tool_tip ( ) const { return _tool_tip; } inline unsigned int Pad_Proxies_Group::style_id ( ) const { return _style_id; } inline unsigned int Pad_Proxies_Group::num_sliders ( ) const { return _num_sliders; } inline unsigned int Pad_Proxies_Group::num_switches ( ) const { return _num_switches; } inline unsigned char Pad_Proxies_Group::focus_column ( ) const { return _focus_column; } inline unsigned char Pad_Proxies_Group::focus_row ( ) const { return _focus_row; } inline bool Pad_Proxies_Group::has_focus ( ) const { return _has_focus; } } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/pad_proxy.cpp000066400000000000000000000052101354534512100211560ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "pad_proxy.hpp" #include "wdg/pad_proxies_column.hpp" #include "wdg/pad_proxy_style.hpp" #include "wdg/pass_events.hpp" #include #include #include namespace Wdg { Pad_Proxy::Pad_Proxy ( unsigned char index_n ) : _index ( index_n ), _has_focus ( false ), _is_enabled ( true ), _variant_id ( 0 ), _style_id ( 0 ), _widget ( 0 ), _style ( 0 ) { } Pad_Proxy::~Pad_Proxy ( ) { if ( _style != 0 ) { delete _style; } } ::Wdg::Pad_Proxies_Column * Pad_Proxy::column ( ) const { ::Wdg::Pad_Proxies_Column * res ( 0 ); QObject * par ( parent() ); if ( par != 0 ) { res = dynamic_cast < ::Wdg::Pad_Proxies_Column * > ( par ); } return res; } ::Wdg::Pad_Proxies_Group * Pad_Proxy::group ( ) const { Pad_Proxies_Group * res ( 0 ); Pad_Proxies_Column * sp_col ( column() ); if ( sp_col != 0 ) { res = sp_col->group(); } return res; } void Pad_Proxy::set_index ( unsigned char idx_n ) { _index = idx_n; } void Pad_Proxy::set_has_focus ( bool flag_n ) { _has_focus = flag_n; } void Pad_Proxy::set_enabled ( bool flag_n ) { if ( flag_n != is_enabled() ) { _is_enabled = flag_n; emit sig_enabled_changed ( is_enabled() ); } } void Pad_Proxy::set_widget ( QWidget * wdg_n ) { if ( _widget != 0 ) { _widget->removeEventFilter ( this ); } _widget = wdg_n; if ( _widget != 0 ) { _widget->installEventFilter ( this ); } } void Pad_Proxy::set_item_name ( const QString & name_n ) { _item_name = name_n; } void Pad_Proxy::set_group_name ( const QString & name_n ) { _group_name = name_n; } void Pad_Proxy::set_tool_tip ( const QString & tip_n ) { _tool_tip = tip_n; } void Pad_Proxy::set_variant_id ( unsigned int id_n ) { _variant_id = id_n; } void Pad_Proxy::set_style_id ( unsigned int id_n ) { _style_id = id_n; } void Pad_Proxy::set_style ( ::Wdg::Pad_Proxy_Style * style_n ) { if ( _style != 0 ) { delete _style; } _style = style_n; } void Pad_Proxy::update_value_from_source ( ) { // Dummy implementation does nothing } bool Pad_Proxy::eventFilter ( QObject * obj_n, QEvent * event_n ) { bool res ( QObject::eventFilter ( obj_n, event_n ) ); if ( !res && ( ( event_n->type() == QEvent::FocusIn ) || ( event_n->type() == QEvent::FocusOut ) ) ) { QFocusEvent * ev_foc ( static_cast < QFocusEvent * > ( event_n ) ); _has_focus = ev_foc->gotFocus(); if ( parent() != 0 ) { ::Wdg::Pass_Event_Focus ev_pass ( *ev_foc ); ev_pass.row_idx = index(); QCoreApplication::sendEvent ( parent(), &ev_pass ); } } return res; } } // End of namespace qastools-v0.22.0/shared/src/wdg/pad_proxy.hpp000066400000000000000000000056141354534512100211730ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_wdg_pad_proxy_hpp__ #define __INC_wdg_pad_proxy_hpp__ #include #include #include // Forward declaration namespace Wdg { class Pad_Proxy_Style; class Pad_Proxies_Column; class Pad_Proxies_Group; } namespace Wdg { /// @brief Pad_Proxy /// class Pad_Proxy : public QObject { Q_OBJECT; // Public methods public: Pad_Proxy ( unsigned char index_n = 0 ); virtual ~Pad_Proxy ( ); ::Wdg::Pad_Proxies_Column * column ( ) const; ::Wdg::Pad_Proxies_Group * group ( ) const; // Position index /// @brief The position index in the parent column /// unsigned char index ( ) const; void set_index ( unsigned char idx_n ); // Focus flag bool has_focus ( ) const; void set_has_focus ( bool flag_n ); // Enabled flag bool is_enabled ( ) const; void set_enabled ( bool flag_n ); // Widget QWidget * widget ( ) const; void set_widget ( QWidget * wdg_n ); // Item name const QString & item_name ( ) const; void set_item_name ( const QString & name_n ); // Group name const QString & group_name ( ) const; void set_group_name ( const QString & name_n ); // Tool tip const QString & tool_tip ( ) const; void set_tool_tip ( const QString & tip_n ); // Style information unsigned int variant_id ( ) const; void set_variant_id ( unsigned int id_n ); unsigned int style_id ( ) const; void set_style_id ( unsigned int id_n ); const ::Wdg::Pad_Proxy_Style * style ( ) const; void set_style ( ::Wdg::Pad_Proxy_Style * style_n ); bool eventFilter ( QObject * obj_n, QEvent * event_n ); // Signals signals: void sig_enabled_changed ( bool flag_n ); // Public slots public slots: virtual void update_value_from_source ( ); // Private attributes private: unsigned char _index; bool _has_focus; bool _is_enabled; QString _item_name; QString _group_name; QString _tool_tip; unsigned int _variant_id; unsigned int _style_id; QWidget * _widget; ::Wdg::Pad_Proxy_Style * _style; }; inline unsigned char Pad_Proxy::index ( ) const { return _index; } inline bool Pad_Proxy::has_focus ( ) const { return _has_focus; } inline bool Pad_Proxy::is_enabled ( ) const { return _is_enabled; } inline QWidget * Pad_Proxy::widget ( ) const { return _widget; } inline const QString & Pad_Proxy::item_name ( ) const { return _item_name; } inline const QString & Pad_Proxy::group_name ( ) const { return _group_name; } inline const QString & Pad_Proxy::tool_tip ( ) const { return _tool_tip; } inline unsigned int Pad_Proxy::variant_id ( ) const { return _variant_id; } inline unsigned int Pad_Proxy::style_id ( ) const { return _style_id; } inline const ::Wdg::Pad_Proxy_Style * Pad_Proxy::style ( ) const { return _style; } } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/pad_proxy_enum.cpp000066400000000000000000000013031354534512100222010ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "pad_proxy_enum.hpp" namespace Wdg { Pad_Proxy_Enum::Pad_Proxy_Enum ( ) : _enum_num_items ( 0 ), _enum_index ( 0 ) { } void Pad_Proxy_Enum::set_enum_num_items ( int num_n ) { _enum_num_items = num_n; } QString Pad_Proxy_Enum::enum_item_name ( int ) { // Dummy implementation return QString(); } void Pad_Proxy_Enum::set_enum_index ( int idx_n ) { if ( idx_n != enum_index() ) { _enum_index = idx_n; this->enum_index_changed(); emit sig_enum_index_changed ( enum_index() ); } } void Pad_Proxy_Enum::enum_index_changed ( ) { // Dummy implementation } } // End of namespace qastools-v0.22.0/shared/src/wdg/pad_proxy_enum.hpp000066400000000000000000000017751354534512100222230ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_wdg_pad_proxy_enum_hpp__ #define __INC_wdg_pad_proxy_enum_hpp__ #include "wdg/pad_proxy.hpp" namespace Wdg { /// @brief Pad_Proxy_Enum /// class Pad_Proxy_Enum : public ::Wdg::Pad_Proxy { Q_OBJECT // Public methods public: Pad_Proxy_Enum ( ); int enum_num_items ( ) const; void set_enum_num_items ( int num_n ); virtual QString enum_item_name ( int idx_n ); int enum_index ( ) const; // Public slots public slots: void set_enum_index ( int idx_n ); // Signals signals: void sig_enum_index_changed ( int value_n ); // Protected methods protected: virtual void enum_index_changed ( ); // Private attributes private: int _enum_num_items; int _enum_index; }; inline int Pad_Proxy_Enum::enum_num_items ( ) const { return _enum_num_items; } inline int Pad_Proxy_Enum::enum_index ( ) const { return _enum_index; } } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/pad_proxy_slider.cpp000066400000000000000000000021561354534512100225260ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "pad_proxy_slider.hpp" namespace Wdg { Pad_Proxy_Slider::Pad_Proxy_Slider ( ) : ::Wdg::Pad_Proxy ( 0 ), _slider_index ( 0 ), _slider_index_max ( 0 ) { } Pad_Proxy_Slider::~Pad_Proxy_Slider ( ) { } void Pad_Proxy_Slider::set_slider_index ( unsigned long index_n ) { if ( index_n > slider_index_max() ) { index_n = slider_index_max(); } if ( slider_index() != index_n ) { _slider_index = index_n; this->slider_index_changed(); emit sig_slider_index_changed ( slider_index() ); } } void Pad_Proxy_Slider::set_slider_index_max ( unsigned long index_n ) { if ( slider_index_max() != index_n ) { _slider_index_max = index_n; if ( slider_index() > slider_index_max() ) { set_slider_index ( slider_index_max() ); } this->slider_index_max_changed(); emit sig_slider_index_max_changed ( slider_index_max() ); } } void Pad_Proxy_Slider::slider_index_changed ( ) { // Dummy implementation } void Pad_Proxy_Slider::slider_index_max_changed ( ) { // Dummy implementation } } // End of namespace qastools-v0.22.0/shared/src/wdg/pad_proxy_slider.hpp000066400000000000000000000023171354534512100225320ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_wdg_pad_proxy_slider_hpp__ #define __INC_wdg_pad_proxy_slider_hpp__ #include "wdg/pad_proxy.hpp" namespace Wdg { /// @brief Pad_Proxy_Slider /// class Pad_Proxy_Slider : public ::Wdg::Pad_Proxy { Q_OBJECT; // Public methods public: Pad_Proxy_Slider ( ); ~Pad_Proxy_Slider ( ); unsigned long slider_index ( ) const; unsigned long slider_index_max ( ) const; // Signals signals: void sig_slider_index_changed ( unsigned long idx_n ); void sig_slider_index_max_changed ( unsigned long idx_n ); // Public slots public slots: void set_slider_index ( unsigned long idx_n ); void set_slider_index_max ( unsigned long idx_n ); // Protected methods protected: virtual void slider_index_changed ( ); virtual void slider_index_max_changed ( ); // Private attributes private: unsigned long _slider_index; unsigned long _slider_index_max; }; inline unsigned long Pad_Proxy_Slider::slider_index ( ) const { return _slider_index; } inline unsigned long Pad_Proxy_Slider::slider_index_max ( ) const { return _slider_index_max; } } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/pad_proxy_style.cpp000066400000000000000000000004161354534512100224010ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "pad_proxy_style.hpp" namespace Wdg { Pad_Proxy_Style::Pad_Proxy_Style ( ) : slider_minimum_idx ( 0 ), slider_has_minimum ( false ) { } } // End of namespace qastools-v0.22.0/shared/src/wdg/pad_proxy_style.hpp000066400000000000000000000006461354534512100224130ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_wdg_pad_proxy_style_hpp__ #define __INC_wdg_pad_proxy_style_hpp__ namespace Wdg { /// @brief Pad_Proxy_Style /// class Pad_Proxy_Style { // Public methods public: Pad_Proxy_Style ( ); // Public attributes unsigned int slider_minimum_idx; bool slider_has_minimum; }; } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/pad_proxy_switch.cpp000066400000000000000000000012741354534512100225450ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "pad_proxy_switch.hpp" namespace Wdg { Pad_Proxy_Switch::Pad_Proxy_Switch ( ) : ::Wdg::Pad_Proxy ( 1 ), _switch_state ( false ) { } Pad_Proxy_Switch::~Pad_Proxy_Switch ( ) { } void Pad_Proxy_Switch::set_switch_state ( bool state_n ) { if ( state_n != _switch_state ) { _switch_state = state_n; this->switch_state_changed(); emit sig_switch_state_changed ( switch_state() ); } } void Pad_Proxy_Switch::toggle_switch_state ( ) { this->set_switch_state ( !switch_state() ); } void Pad_Proxy_Switch::switch_state_changed ( ) { // Dummy implementation } } // End of namespace qastools-v0.22.0/shared/src/wdg/pad_proxy_switch.hpp000066400000000000000000000015571354534512100225560ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_wdg_pad_proxy_switch_hpp__ #define __INC_wdg_pad_proxy_switch_hpp__ #include "wdg/pad_proxy.hpp" namespace Wdg { /// @brief Pad_Proxy_Switch /// class Pad_Proxy_Switch : public ::Wdg::Pad_Proxy { Q_OBJECT; // Public methods public: Pad_Proxy_Switch ( ); ~Pad_Proxy_Switch ( ); bool switch_state ( ) const; // Signals signals: void sig_switch_state_changed ( bool state_n ); // Public slots public slots: void set_switch_state ( bool state_n ); void toggle_switch_state ( ); // Protected methods protected: virtual void switch_state_changed ( ); // Private attributes private: bool _switch_state; }; inline bool Pad_Proxy_Switch::switch_state ( ) const { return _switch_state; } } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/pass_events.cpp000066400000000000000000000017011354534512100215040ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "pass_events.hpp" #include "wdg/event_types.hpp" namespace Wdg { Pass_Event::Pass_Event ( QEvent::Type type_n, unsigned int group_idx_n, unsigned int column_idx_n, unsigned int row_idx_n ) : QEvent ( type_n ), group_idx ( group_idx_n ), column_idx ( column_idx_n ), row_idx ( row_idx_n ) { } Pass_Event_Focus::Pass_Event_Focus ( const QFocusEvent & event_n, unsigned int group_idx_n, unsigned int column_idx_n, unsigned int row_idx_n ) : ::Wdg::Pass_Event ( ::Wdg::evt_pass_event_focus, group_idx_n, column_idx_n, row_idx_n ), ev_focus ( event_n ) { } Pass_Event_Key::Pass_Event_Key ( const QKeyEvent & event_n, unsigned int group_idx_n, unsigned int column_idx_n, unsigned int row_idx_n ) : ::Wdg::Pass_Event ( ::Wdg::evt_pass_event_key, group_idx_n, column_idx_n, row_idx_n ), ev_key ( event_n ) { } } // End of namespace qastools-v0.22.0/shared/src/wdg/pass_events.hpp000066400000000000000000000021761354534512100215200ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_pass_events_hpp__ #define __INC_pass_events_hpp__ #include #include #include namespace Wdg { /// @brief Pass_Event /// class Pass_Event : public QEvent { // Public methods public: Pass_Event ( QEvent::Type type_n, unsigned int group_idx_n = 0, unsigned int column_idx_n = 0, unsigned int row_idx_n = 0 ); unsigned int group_idx; unsigned int column_idx; unsigned int row_idx; }; /// @brief Pass_Event_Focus /// class Pass_Event_Focus : public ::Wdg::Pass_Event { // Public methods public: Pass_Event_Focus ( const QFocusEvent & event_n, unsigned int group_idx_n = 0, unsigned int column_idx_n = 0, unsigned int row_idx_n = 0 ); QFocusEvent ev_focus; }; /// @brief Pass_Event_Key /// class Pass_Event_Key : public ::Wdg::Pass_Event { // Public methods public: Pass_Event_Key ( const QKeyEvent & event_n, unsigned int group_idx_n = 0, unsigned int column_idx_n = 0, unsigned int row_idx_n = 0 ); QKeyEvent ev_key; }; } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/scroll_area_horizontal.cpp000066400000000000000000000034141354534512100237140ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "scroll_area_horizontal.hpp" #include #include #include #include namespace Wdg { Scroll_Area_Horizontal::Scroll_Area_Horizontal ( QWidget * parent_n ) : QScrollArea ( parent_n ) { setVerticalScrollBarPolicy ( Qt::ScrollBarAlwaysOff ); setWidgetResizable ( true ); } QSize Scroll_Area_Horizontal::minimumSizeHint ( ) const { QSize res = ( QScrollArea::minimumSizeHint() ); if ( widget() != 0 ) { res.setHeight ( 0 ); { const QSize wmsh ( widget()->minimumSizeHint() ); if ( wmsh.height() > 0 ) { res.rheight() += wmsh.height(); } } if ( horizontalScrollBar() != 0 ) { QSize sb_msh ( horizontalScrollBar()->minimumSizeHint() ); if ( sb_msh.height() <= 0 ) { sb_msh = horizontalScrollBar()->sizeHint(); } if ( sb_msh.height() > 0 ) { res.rheight() += sb_msh.height(); } } { const QMargins mgs ( contentsMargins() ); res.rheight() += ( mgs.top() + mgs.bottom() ); } } return res; } void Scroll_Area_Horizontal::set_widget ( QWidget * wdg_n ) { if ( widget() != 0 ) { widget()->removeEventFilter ( this ); } setWidget ( wdg_n ); if ( widget() != 0 ) { widget()->installEventFilter ( this ); } updateGeometry(); } QWidget * Scroll_Area_Horizontal::take_widget ( ) { if ( widget() != 0 ) { widget()->removeEventFilter ( this ); } return takeWidget(); } bool Scroll_Area_Horizontal::eventFilter ( QObject * watched_n, QEvent * event_n ) { if ( watched_n == widget() ) { //::std::cout << "Event type: " << event_n->type() << "\n"; if ( event_n->type() == QEvent::LayoutRequest ) { updateGeometry(); } } return false; } } // End of namespace qastools-v0.22.0/shared/src/wdg/scroll_area_horizontal.hpp000066400000000000000000000012111354534512100237120ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_scroll_area_horizontal_hpp__ #define __INC_scroll_area_horizontal_hpp__ #include namespace Wdg { /// @brief Scroll_Area_Horizontal /// class Scroll_Area_Horizontal : public QScrollArea { // Public methods public: Scroll_Area_Horizontal ( QWidget * parent_n = 0 ); QSize minimumSizeHint ( ) const; void set_widget ( QWidget * wdg_n ); QWidget * take_widget ( ); // Protected methods protected: bool eventFilter ( QObject * watched_n, QEvent * event_n ); }; } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/scroll_area_vertical.cpp000066400000000000000000000033621354534512100233360ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "scroll_area_vertical.hpp" #include #include #include #include namespace Wdg { Scroll_Area_Vertical::Scroll_Area_Vertical ( QWidget * parent_n ) : QScrollArea ( parent_n ) { setHorizontalScrollBarPolicy ( Qt::ScrollBarAlwaysOff ); setWidgetResizable ( true ); } QSize Scroll_Area_Vertical::minimumSizeHint ( ) const { QSize res = ( QScrollArea::minimumSizeHint() ); if ( widget() != 0 ) { res.setHeight ( 0 ); { const QSize wmsh ( widget()->minimumSizeHint() ); if ( wmsh.width() > 0 ) { res.rwidth() += wmsh.width(); } } if ( verticalScrollBar() != 0 ) { QSize sb_msh ( verticalScrollBar()->minimumSizeHint() ); if ( sb_msh.width() <= 0 ) { sb_msh = verticalScrollBar()->sizeHint(); } if ( sb_msh.width() > 0 ) { res.rwidth() += sb_msh.width(); } } { const QMargins mgs ( contentsMargins() ); res.rwidth() += ( mgs.left() + mgs.right() ); } } return res; } void Scroll_Area_Vertical::set_widget ( QWidget * wdg_n ) { if ( widget() != 0 ) { widget()->removeEventFilter ( this ); } setWidget ( wdg_n ); if ( widget() != 0 ) { widget()->installEventFilter ( this ); } updateGeometry(); } QWidget * Scroll_Area_Vertical::take_widget ( ) { if ( widget() != 0 ) { widget()->removeEventFilter ( this ); } return takeWidget(); } bool Scroll_Area_Vertical::eventFilter ( QObject * watched_n, QEvent * event_n ) { if ( watched_n == widget() ) { //::std::cout << "Event type: " << event_n->type() << "\n"; if ( event_n->type() == QEvent::LayoutRequest ) { updateGeometry(); } } return false; } } // End of namespace qastools-v0.22.0/shared/src/wdg/scroll_area_vertical.hpp000066400000000000000000000011771354534512100233450ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_scroll_area_vertical_hpp__ #define __INC_scroll_area_vertical_hpp__ #include namespace Wdg { /// @brief Scroll_Area_Vertical /// class Scroll_Area_Vertical : public QScrollArea { // Public methods public: Scroll_Area_Vertical ( QWidget * parent_n = 0 ); QSize minimumSizeHint ( ) const; void set_widget ( QWidget * wdg_n ); QWidget * take_widget ( ); // Protected methods protected: bool eventFilter ( QObject * watched_n, QEvent * event_n ); }; } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/sliders_pad.cpp000066400000000000000000000350161354534512100214510ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "sliders_pad.hpp" #include "wdg/pad_proxy_style.hpp" #include "wdg/pad_proxy_slider.hpp" #include "wdg/pad_proxy_switch.hpp" #include "wdg/pad_proxies_column.hpp" #include "wdg/pad_proxies_group.hpp" #include "wdg/sliders_pad_data.hpp" #include "wdg/sliders_pad_header.hpp" #include "wdg/sliders_pad_footer.hpp" #include "wdg/sliders_pad_layout.hpp" #include "wdg/sliders_pad_style.hpp" #include "wdg/ds_switch.hpp" #include "wdg/ds_slider.hpp" #include "wdg/ds_widget_style_db.hpp" #include "wdg/color_methods.hpp" #include "wdg/event_types.hpp" #include "wdg/pass_events.hpp" #include #include #include #include #include namespace Wdg { Sliders_Pad::Sliders_Pad ( QWidget * parent_n, ::dpe::Image_Allocator * isg_alloc_n ) : QWidget ( parent_n ), _sp_data ( new Sliders_Pad_Data ( this ) ), _update_decoration ( true ), _wheel_degrees ( 720 ), _sp_style ( new Sliders_Pad_Style ( _sp_data ) ), _wdg_style_db ( 0 ), _image_alloc ( isg_alloc_n ) { setSizePolicy ( QSizePolicy::Expanding, QSizePolicy::Expanding ); { Sliders_Pad_Header * lheader ( new Sliders_Pad_Header ( _sp_data, _sp_style, this ) ); Sliders_Pad_Footer * lfooter ( new Sliders_Pad_Footer ( _sp_data, _sp_style, this ) ); _sp_data->header = lheader; _sp_data->footer = lfooter; _sp_data->header_data = &lheader->hd_data(); _sp_data->footer_data = &lfooter->hd_data(); connect ( lheader, SIGNAL ( sig_label_selected ( unsigned int, unsigned int ) ), this, SLOT ( header_label_selected ( unsigned int, unsigned int ) ) ); connect ( lfooter, SIGNAL ( sig_label_selected ( unsigned int, unsigned int ) ), this, SLOT ( footer_label_selected ( unsigned int, unsigned int ) ) ); } update_colors(); } Sliders_Pad::~Sliders_Pad ( ) { clear_proxies_groups(); delete _sp_style; delete _sp_data; } void Sliders_Pad::set_wdg_style_db ( const ::Wdg::DS_Widget_Style_Db * style_db_n ) { if ( _wdg_style_db == style_db_n ) { return; } _wdg_style_db = style_db_n; } void Sliders_Pad::set_image_alloc ( ::dpe::Image_Allocator * alloc_n ) { _image_alloc = alloc_n; unsigned int num ( num_widgets() ); for ( unsigned int ii=0; ii < num; ++ii ) { QWidget * wdg ( widget ( ii ) ); { ::Wdg::DS_Slider * swdg ( dynamic_cast < ::Wdg::DS_Slider * > ( wdg ) ); if ( swdg != 0 ) { swdg->set_image_alloc ( image_alloc() ); continue; } } { ::Wdg::DS_Switch * swdg ( dynamic_cast < ::Wdg::DS_Switch * > ( wdg ) ); if ( swdg != 0 ) { swdg->set_image_alloc ( image_alloc() ); continue; } } } } QWidget * Sliders_Pad::header ( ) { return _sp_data->header; } QWidget * Sliders_Pad::footer ( ) { return _sp_data->footer; } Sliders_Pad_Header * Sliders_Pad::header_cast ( ) { return _sp_data->header_cast(); } Sliders_Pad_Footer * Sliders_Pad::footer_cast ( ) { return _sp_data->footer_cast(); } Sliders_Pad_Header_Data * Sliders_Pad::header_data ( ) { return _sp_data->header_data; } Sliders_Pad_Header_Data * Sliders_Pad::footer_data ( ) { return _sp_data->footer_data; } // Show footer bool Sliders_Pad::footer_visible ( ) const { return _sp_data->show_value_labels; } void Sliders_Pad::set_footer_visible ( bool flag_n ) { if ( _sp_data->show_value_labels != flag_n ) { _sp_data->show_value_labels = flag_n; _sp_data->footer->setVisible ( flag_n ); } } void Sliders_Pad::set_wheel_degrees ( unsigned int delta_n ) { if ( ( delta_n == 0 ) || ( wheel_degrees() == delta_n ) ) { return; } _wheel_degrees = delta_n; unsigned int num ( num_widgets() ); for ( unsigned int ii=0; ii < num; ++ii ) { ::Wdg::DS_Slider * slider ( dynamic_cast < ::Wdg::DS_Slider * > ( widget ( ii ) ) ); if ( slider != 0 ) { slider->set_wheel_degrees ( wheel_degrees() ); } } } void Sliders_Pad::clear_widgets ( ) { if ( layout() != 0 ) { delete layout(); } for ( int ii=0; ii < _proxies_groups.size(); ++ii ) { ::Wdg::Pad_Proxies_Group * grp ( _proxies_groups[ii] ); grp->set_pad ( 0 ); for ( unsigned int jj=0; jj < grp->num_columns(); ++jj ) { ::Wdg::Pad_Proxies_Column * col ( grp->column ( jj ) ); if ( col->slider_proxy() != 0 ) { col->slider_proxy()->set_widget ( 0 ); } if ( col->switch_proxy() != 0 ) { col->switch_proxy()->set_widget ( 0 ); } } } // Clear widgets if ( _widgets.size() > 0 ) { for ( int ii=0; ii < _widgets.size(); ++ii ) { delete _widgets[ii]; } _widgets.clear(); } header_data()->labels.clear(); footer_data()->labels.clear(); for ( unsigned int ii=0; ii < _sp_data->groups.size(); ++ii ) { Sliders_Pad_Data_Group * sp_grp ( _sp_data->groups[ii] ); for ( unsigned int jj=0; jj < sp_grp->columns.size(); ++jj ) { delete sp_grp->columns[jj]; } sp_grp->columns.clear(); delete sp_grp; } _sp_data->groups.clear(); } void Sliders_Pad::create_widgets ( ) { const unsigned int num_groups ( _proxies_groups.size() ); if ( num_groups == 0 ) { return; } if ( layout() != 0 ) { delete layout(); } // Shared data setup _sp_data->groups.resize ( num_groups ); unsigned int num_columns_total ( 0 ); unsigned int col_total_idx ( 0 ); for ( unsigned int ii=0; ii < num_groups; ++ii ) { ::Wdg::Pad_Proxies_Group * sppg ( proxies_group ( ii ) ); ::Wdg::Sliders_Pad_Data_Group * sp_grp ( new Sliders_Pad_Data_Group ( _sp_data ) ); sp_grp->sppg = sppg; sp_grp->num_sliders = sppg->num_sliders(); sp_grp->num_switches = sppg->num_switches(); const unsigned int num_cols ( sppg->num_columns() ); sp_grp->columns.resize ( num_cols ); for ( unsigned int jj=0; jj < num_cols; ++jj ) { ::Wdg::Pad_Proxies_Column * sppc ( sppg->column ( jj ) ); ::Wdg::Sliders_Pad_Data_Column * sp_col ( new Sliders_Pad_Data_Column ( sp_grp ) ); if ( sppc->show_value_string() && sppc->has_slider() ) { connect ( sppc, SIGNAL ( sig_value_string_changed ( ) ), sp_col, SLOT ( update_footer_label() ) ); } sp_col->col_idx = jj; sp_col->col_total_idx = col_total_idx; sp_col->show_value_label = sppc->show_value_string(); sp_col->sppc = sppc; sp_grp->columns[jj] = sp_col; ++col_total_idx; } _sp_data->groups[ii] = sp_grp; num_columns_total += num_cols; } // Header and footer setup header_data()->labels.resize ( num_groups ); header_data()->update_elided_texts = true; footer_data()->labels.resize ( num_columns_total ); footer_data()->update_elided_texts = true; col_total_idx = 0; for ( unsigned int ii=0; ii < num_groups; ++ii ) { Pad_Proxies_Group * sppg ( proxies_group ( ii ) ); // Setup header labels variables { ::Wdg::Sliders_Pad_Header_Label & lbl ( header_data()->labels[ii] ); lbl.group_idx = ii; lbl.column_idx = 0; lbl.column_total_idx = ii; lbl.text = sppg->group_name(); lbl.tool_tip = sppg->tool_tip(); if ( wdg_style_db() != 0 ) { lbl.col_fg = wdg_style_db()->color ( sppg->style_id(), QPalette::WindowText ); } else { lbl.col_fg = palette().color ( QPalette::WindowText ); } lbl.label_length_max = header_cast()->label_str_length_px_max ( sppg->group_name() ); } // Setup footer labels variables const unsigned int num_cols ( sppg->num_columns() ); for ( unsigned int jj=0; jj < num_cols; ++jj ) { ::Wdg::Pad_Proxies_Column * sppc ( sppg->column ( jj ) ); ::Wdg::Sliders_Pad_Header_Label & lbl ( footer_data()->labels[col_total_idx] ); lbl.group_idx = ii; lbl.column_idx = jj; lbl.column_total_idx = col_total_idx; lbl.tool_tip = sppg->tool_tip(); if ( wdg_style_db() != 0 ) { lbl.col_fg = wdg_style_db()->color ( sppg->style_id(), QPalette::WindowText ); } else { lbl.col_fg = palette().color ( QPalette::WindowText ); } { unsigned int llength[2] = { 0, 0 }; llength[0] = footer_cast()->label_str_length_px_max ( sppc->value_min_string() ); llength[1] = footer_cast()->label_str_length_px_max ( sppc->value_max_string() ); lbl.label_length_max = qMax ( llength[0], llength[1] ); } if ( sppc->show_value_string() ) { lbl.text = sppc->value_string(); } ++col_total_idx; } } // Inputs area layout and widget creation ::Wdg::Sliders_Pad_Layout * sp_layout ( new Sliders_Pad_Layout ( _sp_data ) ); sp_layout->setContentsMargins ( 0, 0, 0, 0 ); sp_layout->set_header_widget ( header() ); sp_layout->set_footer_widget ( footer() ); for ( unsigned int gii=0; gii < num_groups; ++gii ) { ::Wdg::Pad_Proxies_Group * sppg ( proxies_group ( gii ) ); sppg->set_pad ( this ); sppg->set_group_index ( gii ); // Add widgets to the widgets groups for ( unsigned int cii=0; cii < sppg->num_columns(); ++cii ) { ::Wdg::Pad_Proxies_Column * sppc ( sppg->column ( cii ) ); // Slider widget if ( sppc->has_slider() ) { ::Wdg::Pad_Proxy_Slider * spps ( sppc->slider_proxy() ); ::Wdg::DS_Slider * sl_wdg ( new ::Wdg::DS_Slider ( 0, _image_alloc ) ); sl_wdg->set_maximum_index ( spps->slider_index_max() ); sl_wdg->set_current_index ( spps->slider_index() ); sl_wdg->setToolTip ( spps->tool_tip() ); sl_wdg->setEnabled ( spps->is_enabled() ); sl_wdg->set_wheel_degrees ( wheel_degrees() ); sl_wdg->set_wdg_style_db ( wdg_style_db() ); sl_wdg->set_style_id ( spps->style_id() ); if ( spps->style() != 0 ) { ::Wdg::DS_Slider_Meta_Bg & meta_bg ( sl_wdg->meta_bg() ); meta_bg.bg_show_image = spps->style()->slider_has_minimum; meta_bg.bg_tick_min_idx = spps->style()->slider_minimum_idx; } connect ( spps, SIGNAL ( sig_enabled_changed ( bool ) ), sl_wdg, SLOT ( setEnabled ( bool ) ) ); connect ( sl_wdg, SIGNAL ( sig_current_index_changed ( unsigned long ) ), spps, SLOT ( set_slider_index ( unsigned long ) ) ); connect ( spps, SIGNAL ( sig_slider_index_changed ( unsigned long ) ), sl_wdg, SLOT ( set_current_index ( unsigned long ) ) ); connect ( spps, SIGNAL ( sig_slider_index_max_changed ( unsigned long ) ), sl_wdg, SLOT ( set_maximum_index ( unsigned long ) ) ); spps->set_widget ( sl_wdg ); _widgets.append ( sl_wdg ); sp_layout->add_group_widget ( sl_wdg, gii, cii, 0 ); } // Switch widget if ( sppc->has_switch() ) { ::Wdg::Pad_Proxy_Switch * spps ( sppc->switch_proxy() ); ::Wdg::DS_Switch * sw_wdg ( new ::Wdg::DS_Switch ( 0, _image_alloc ) ); sw_wdg->setChecked ( spps->switch_state() ); sw_wdg->setToolTip ( spps->tool_tip() ); sw_wdg->setEnabled ( spps->is_enabled() ); sw_wdg->set_variant_id ( spps->variant_id() ); sw_wdg->set_style_id ( spps->style_id() ); connect ( spps, SIGNAL ( sig_enabled_changed ( bool ) ), sw_wdg, SLOT ( setEnabled ( bool ) ) ); connect ( sw_wdg, SIGNAL ( toggled ( bool ) ), spps, SLOT ( set_switch_state ( bool ) ) ); connect ( spps, SIGNAL ( sig_switch_state_changed ( bool ) ), sw_wdg, SLOT ( setChecked ( bool ) ) ); spps->set_widget ( sw_wdg ); _widgets.append ( sw_wdg ); sp_layout->add_group_widget ( sw_wdg, gii, cii, 1 ); } } } setLayout ( sp_layout ); } void Sliders_Pad::set_proxies_groups ( const QList < ::Wdg::Pad_Proxies_Group * > & list_n ) { bool do_update ( false ); if ( _proxies_groups.size() > 0 ) { clear_widgets(); do_update = true; } _proxies_groups = list_n; if ( _proxies_groups.size() > 0 ) { create_widgets(); do_update = true; } if ( do_update ) { _update_decoration = true; header_data()->update_decoration = true; footer_data()->update_decoration = true; update(); } } void Sliders_Pad::clear_proxies_groups ( ) { if ( _proxies_groups.size() > 0 ) { set_proxies_groups ( QList < Pad_Proxies_Group * >() ); } } void Sliders_Pad::update_colors ( ) { { const QPalette & pal ( palette() ); const QColor col_bg ( pal.color ( QPalette::Button ) ); const QColor col_fg ( pal.color ( QPalette::ButtonText ) ); QColor col = ::Wdg::col_mix ( col_bg, col_fg, 1, 1 ); _sp_style->stem_pen.setColor ( col ); } } bool Sliders_Pad::set_focus_proxy ( unsigned int group_idx_n ) { return set_focus_proxy ( group_idx_n, 0, 0 ); } bool Sliders_Pad::set_focus_proxy ( unsigned int group_idx_n, unsigned int column_idx_n, unsigned int row_idx_n ) { bool success ( false ); const unsigned int num_groups ( _proxies_groups.size() ); if ( group_idx_n < num_groups ) { ::Wdg::Pad_Proxies_Group * sppg ( proxies_group ( group_idx_n ) ); success = sppg->take_focus ( column_idx_n, row_idx_n ); } return success; } void Sliders_Pad::header_label_selected ( unsigned int group_idx_n, unsigned int column_idx_n ) { set_focus_proxy ( group_idx_n, column_idx_n, 0 ); } void Sliders_Pad::footer_label_selected ( unsigned int group_idx_n, unsigned int column_idx_n ) { if ( set_focus_proxy ( group_idx_n, column_idx_n, 0 ) ) { emit sig_footer_label_selected ( group_idx_n, column_idx_n ); } } bool Sliders_Pad::event ( QEvent * event_n ) { if ( event_n->type() == ::Wdg::evt_pass_event_focus ) { ::Wdg::Pass_Event_Focus * ev_fp ( static_cast < ::Wdg::Pass_Event_Focus * > ( event_n ) ); _focus_info.clear(); if ( ev_fp->ev_focus.gotFocus() && ( ev_fp->group_idx < num_proxies_groups() ) ) { _focus_info.has_focus = true; _focus_info.group_idx = ev_fp->group_idx; _focus_info.column_idx = ev_fp->column_idx; _focus_info.row_idx = ev_fp->row_idx; } { // Update header focus unsigned int group_idx ( ~0 ); unsigned int col_idx ( ~0 ); if ( _focus_info.has_focus ) { group_idx = _focus_info.group_idx; col_idx = _focus_info.column_idx; } header_cast()->set_focus_idx ( group_idx, col_idx ); footer_cast()->set_focus_idx ( group_idx, col_idx ); } emit sig_focus_changed(); update(); return true; } return QWidget::event ( event_n ); } void Sliders_Pad::resizeEvent ( QResizeEvent * event ) { //::std::cout << "Resize event " << width() << ":" << height() << "\n"; QWidget::resizeEvent ( event ); _update_decoration = true; header_data()->update_decoration = true; footer_data()->update_decoration = true; } void Sliders_Pad::paintEvent ( QPaintEvent * event ) { QWidget::paintEvent ( event ); if ( _update_decoration ) { _update_decoration = false; _sp_style->paint_base_decoration(); } { QPainter painter ( this ); painter.setRenderHints ( QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform ); // Debug area painting //painter.setBrush ( Qt::yellow ); //painter.setPen ( Qt::NoPen ); //painter.drawRect ( rect() ); for ( unsigned int gii=0; gii < _sp_data->groups.size(); ++gii ) { painter.drawPicture ( 0, 0, _sp_data->groups[gii]->center_pic ); } } } } // End of namespace qastools-v0.22.0/shared/src/wdg/sliders_pad.hpp000066400000000000000000000104161354534512100214530ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_wdg_sliders_pad_hpp__ #define __INC_wdg_sliders_pad_hpp__ #include "wdg/pad_focus_info.hpp" #include #include // Forward declaration namespace dpe { class Image_Allocator; } namespace Wdg { class Sliders_Pad_Data; class Sliders_Pad_Data_Group; class Sliders_Pad_Data_Column; class Sliders_Pad_Header_Data; class Sliders_Pad_Header; class Sliders_Pad_Footer; class Sliders_Pad_Style; class Pad_Proxies_Group; class DS_Widget_Style_Db; } namespace Wdg { /// @brief Sliders_Pad /// class Sliders_Pad : public QWidget { Q_OBJECT // Public methods public: Sliders_Pad ( QWidget * parent_n = 0, ::dpe::Image_Allocator * isg_alloc_n = 0 ); ~Sliders_Pad ( ); // Proxies groups list const QList < Pad_Proxies_Group * > & proxies_groups ( ) const; void set_proxies_groups ( const QList < Pad_Proxies_Group * > & list_n ); void clear_proxies_groups ( ); // Proxies group access unsigned int num_proxies_groups ( ) const; Pad_Proxies_Group * proxies_group ( unsigned int idx_n ); // Widget style database const ::Wdg::DS_Widget_Style_Db * wdg_style_db ( ) const; void set_wdg_style_db ( const ::Wdg::DS_Widget_Style_Db * style_db_n ); // Image_Set_Group allocator void set_image_alloc ( ::dpe::Image_Allocator * alloc_n ); ::dpe::Image_Allocator * image_alloc ( ) const; // Show footer bool footer_visible ( ) const; void set_footer_visible ( bool flag_n ); // Wheel degrees void set_wheel_degrees ( unsigned int delta_n ); unsigned int wheel_degrees ( ) const; // Widgets QWidget * header ( ); QWidget * footer ( ); ::Wdg::Sliders_Pad_Header * header_cast ( ); ::Wdg::Sliders_Pad_Footer * footer_cast ( ); ::Wdg::Sliders_Pad_Header_Data * header_data ( ); ::Wdg::Sliders_Pad_Header_Data * footer_data ( ); unsigned int num_widgets ( ) const; QWidget * widget ( unsigned int idx_n ); // Focus info const Pad_Focus_Info & focus_info ( ) const; /// @brief Event handler reimplementation bool event ( QEvent * event_n ); // Public signals signals: void sig_focus_changed ( ); void sig_footer_label_selected ( unsigned int group_idx_n, unsigned int column_idx_n ); // Public slots public slots: bool set_focus_proxy ( unsigned int group_idx_n ); bool set_focus_proxy ( unsigned int group_idx_n, unsigned int column_idx_n, unsigned int row_idx_n ); // Protected methods protected: void clear_widgets ( ); void create_widgets ( ); // Event methods void resizeEvent ( QResizeEvent * event ); void paintEvent ( QPaintEvent * event ); // Protected slots protected slots: void header_label_selected ( unsigned int group_idx_n, unsigned int column_idx_n ); void footer_label_selected ( unsigned int group_idx_n, unsigned int column_idx_n ); // Private methods private: void update_colors ( ); // Private attributes private: QList < ::Wdg::Pad_Proxies_Group * > _proxies_groups; ::Wdg::Sliders_Pad_Data * _sp_data; QList < QWidget * > _widgets; ::Wdg::Pad_Focus_Info _focus_info; bool _update_decoration; unsigned int _wheel_degrees; ::Wdg::Sliders_Pad_Style * _sp_style; // Paints decoration graphics const ::Wdg::DS_Widget_Style_Db * _wdg_style_db; ::dpe::Image_Allocator * _image_alloc; }; inline unsigned int Sliders_Pad::wheel_degrees ( ) const { return _wheel_degrees; } inline const QList < ::Wdg::Pad_Proxies_Group * > & Sliders_Pad::proxies_groups ( ) const { return _proxies_groups; } inline unsigned int Sliders_Pad::num_proxies_groups ( ) const { return _proxies_groups.size(); } inline Pad_Proxies_Group * Sliders_Pad::proxies_group ( unsigned int idx_n ) { return _proxies_groups[idx_n]; } inline const ::Wdg::DS_Widget_Style_Db * Sliders_Pad::wdg_style_db ( ) const { return _wdg_style_db; } inline ::dpe::Image_Allocator * Sliders_Pad::image_alloc ( ) const { return _image_alloc; } inline unsigned int Sliders_Pad::num_widgets ( ) const { return _widgets.size(); } inline QWidget * Sliders_Pad::widget ( unsigned int idx_n ) { return _widgets[idx_n]; } inline const Pad_Focus_Info & Sliders_Pad::focus_info ( ) const { return _focus_info; } } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/sliders_pad_data.cpp000066400000000000000000000024131354534512100224350ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "sliders_pad_data.hpp" #include "pad_proxies_column.hpp" #include "sliders_pad_header.hpp" #include "sliders_pad_footer.hpp" #include namespace Wdg { Sliders_Pad_Data_Column::Sliders_Pad_Data_Column ( QObject * parent_n ) : QObject ( parent_n ), col_idx ( 0 ), col_total_idx ( 0 ), col_pos ( 0 ), col_width ( 0 ), show_value_label ( true ), sppc ( 0 ) { } void Sliders_Pad_Data_Column::update_footer_label ( ) { if ( show_value_label ) { const QString & txt ( sppc->value_string() ); sp_data()->footer_cast()->set_label_text ( col_total_idx, txt ); } } Sliders_Pad_Data_Group::Sliders_Pad_Data_Group ( QObject * parent_n ) : QObject ( parent_n ), group_idx ( 0 ), group_pos ( 0 ), group_width ( 0 ), num_sliders ( 0 ), num_switches ( 0 ), sppg ( 0 ) { } Sliders_Pad_Data::Sliders_Pad_Data ( QObject * parent_n ) : QObject ( parent_n ), header ( 0 ), footer ( 0 ), show_value_labels ( true ) { } Sliders_Pad_Header * Sliders_Pad_Data::header_cast ( ) { return static_cast < Sliders_Pad_Header * > ( header ); } Sliders_Pad_Footer * Sliders_Pad_Data::footer_cast ( ) { return static_cast < Sliders_Pad_Footer * > ( footer ); } } // End of namespace qastools-v0.22.0/shared/src/wdg/sliders_pad_data.hpp000066400000000000000000000052411354534512100224440ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_sliders_pad_data_hpp__ #define __INC_sliders_pad_data_hpp__ #include #include #include #include // Forward declarations namespace Wdg { class Pad_Proxies_Group; class Pad_Proxies_Column; class Sliders_Pad_Data; class Sliders_Pad_Data_Group; class Sliders_Pad_Data_Column; class Sliders_Pad_Header_Data; class Sliders_Pad_Header; class Sliders_Pad_Footer; } namespace Wdg { class Sliders_Pad_Data_Column : public QObject { Q_OBJECT // Public methods public: Sliders_Pad_Data_Column ( QObject * parent_n = 0 ); Sliders_Pad_Data_Group * sp_group ( ); Sliders_Pad_Data * sp_data ( ); // Public slots public slots: void update_footer_label ( ); // Public attributes public: unsigned int col_idx; unsigned int col_total_idx; unsigned int col_pos; unsigned int col_width; QPicture hd_pics[2]; // Header/footer pictures bool show_value_label; Pad_Proxies_Column * sppc; }; class Sliders_Pad_Data_Group : public QObject { Q_OBJECT // Public methods public: Sliders_Pad_Data_Group ( QObject * parent_n = 0 ); Sliders_Pad_Data * sp_data ( ); // Public attributes public: unsigned int group_idx; unsigned int group_pos; unsigned int group_width; unsigned int num_sliders; unsigned int num_switches; ::std::vector < Sliders_Pad_Data_Column * > columns; QPicture center_pic; // Center picture QPicture hd_pics[2]; // Header/footer pictures Pad_Proxies_Group * sppg; }; /// @brief Sliders_Pad_Data /// class Sliders_Pad_Data : public QObject { Q_OBJECT // Public methods public: Sliders_Pad_Data ( QObject * parent_n = 0 ); Sliders_Pad_Header * header_cast ( ); Sliders_Pad_Footer * footer_cast ( ); // Public attributes ::std::vector < Sliders_Pad_Data_Group * > groups; // Areas QRect header_area; QRect inputs_area; // Contains sliders_area and switches_area int sliders_area_y; int sliders_area_height; int sub_slider_area_y; int sub_slider_area_height; int switches_area_y; int switches_area_height; QRect footer_area; Sliders_Pad_Header_Data * header_data; Sliders_Pad_Header_Data * footer_data; QWidget * header; QWidget * footer; bool show_value_labels; }; inline Sliders_Pad_Data_Group * Sliders_Pad_Data_Column::sp_group ( ) { return static_cast < Sliders_Pad_Data_Group * > ( parent() ); } inline Sliders_Pad_Data * Sliders_Pad_Data_Column::sp_data ( ) { return sp_group()->sp_data(); } inline Sliders_Pad_Data * Sliders_Pad_Data_Group::sp_data ( ) { return static_cast < Sliders_Pad_Data * > ( parent() ); } } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/sliders_pad_footer.cpp000066400000000000000000000010611354534512100230200ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "sliders_pad_footer.hpp" #include "sliders_pad_data.hpp" #include #include namespace Wdg { Sliders_Pad_Footer::Sliders_Pad_Footer ( Sliders_Pad_Data * sp_data_n, Sliders_Pad_Style * sp_style_n, QWidget * parent_n ) : Sliders_Pad_Header ( sp_data_n, sp_style_n, parent_n ) { hd_data().upside_down = true; hd_data().column_labels = true; hd_data().label_sliding = false; update_painter_states(); } } // End of namespace qastools-v0.22.0/shared/src/wdg/sliders_pad_footer.hpp000066400000000000000000000010051354534512100230230ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_sliders_pad_footer_hpp__ #define __INC_sliders_pad_footer_hpp__ #include "sliders_pad_header.hpp" namespace Wdg { /// /// @brief Sliders_Pad_Footer /// class Sliders_Pad_Footer : public Sliders_Pad_Header { Q_OBJECT // Public methods public: Sliders_Pad_Footer ( Sliders_Pad_Data * sp_data_n, Sliders_Pad_Style * sp_style_n, QWidget * parent_n = 0 ); }; } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/sliders_pad_header.cpp000066400000000000000000000246501354534512100227630ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "sliders_pad_header.hpp" #include "wdg/sliders_pad_data.hpp" #include "wdg/sliders_pad_style.hpp" #include #include #include #include #include namespace Wdg { Sliders_Pad_Header::Sliders_Pad_Header ( Sliders_Pad_Data * sp_data_n, Sliders_Pad_Style * sp_style_n, QWidget * parent_n ) : QWidget ( parent_n ), _sp_data ( sp_data_n ), _sp_style ( sp_style_n ), _focus_idx ( ~0 ), _weak_focus_idx ( ~0 ), _invalid_idx ( ~0 ) { hd_data().max_str_length_px = fontMetrics().averageCharWidth() * 18; hd_data().widget = this; setMouseTracking ( true ); int max_h ( hd_data().spacing_vertical ); max_h += hd_data().pad_left; max_h += hd_data().pad_right; max_h += hd_data().max_str_length_px; setMaximumHeight ( max_h ); update_painter_states(); } Sliders_Pad_Header::~Sliders_Pad_Header ( ) { } QSize Sliders_Pad_Header::minimumSizeHint ( ) const { QSize res ( 64, 0 ); res.rheight() += hd_data().spacing_vertical; res.rheight() += fontMetrics().height() * 5 / 2; return res; } QSize Sliders_Pad_Header::sizeHint ( ) const { return minimumSizeHint(); } unsigned int Sliders_Pad_Header::label_str_length_px_max ( const QString & str_n ) const { unsigned int res; res = ::std::ceil ( fontMetrics().width ( str_n ) ); res = qMin ( res, hd_data().max_str_length_px ); return res; } void Sliders_Pad_Header::set_focus_idx ( unsigned int group_idx_n, unsigned int column_idx_n ) { unsigned int idx ( _invalid_idx ); if ( group_idx_n < sp_data()->groups.size() ) { const Sliders_Pad_Data_Group * sp_grp ( sp_data()->groups[group_idx_n] ); if ( hd_data().column_labels ) { if ( column_idx_n < sp_grp->columns.size() ) { const Sliders_Pad_Data_Column * sp_col ( sp_grp->columns[column_idx_n] ); idx = sp_col->col_total_idx; } } else { idx = group_idx_n; } if ( idx >= hd_data().labels.size() ) { idx = _invalid_idx; } } _focus_idx = idx; } void Sliders_Pad_Header::set_label_text ( unsigned int lbl_idx_n, const QString & txt_n ) { if ( lbl_idx_n < hd_data().labels.size() ) { Sliders_Pad_Header_Label & lbl ( hd_data().labels[lbl_idx_n] ); lbl.text = txt_n; elided_label_text ( lbl ); update ( lbl.label_txt_bbox ); } } void Sliders_Pad_Header::enterEvent ( QEvent * ) { if ( _weak_focus_idx < hd_data().labels.size() ) { _weak_focus_idx = _invalid_idx; update(); } } void Sliders_Pad_Header::leaveEvent ( QEvent * ) { if ( _weak_focus_idx < hd_data().labels.size() ) { _weak_focus_idx = _invalid_idx; update(); } } void Sliders_Pad_Header::mousePressEvent ( QMouseEvent * event_n ) { const Sliders_Pad_Header_Label * lbl ( find_label ( event_n->pos() ) ); if ( lbl != 0 ) { emit sig_label_selected ( lbl->group_idx, lbl->column_idx ); } } void Sliders_Pad_Header::mouseMoveEvent ( QMouseEvent * event_n ) { const Sliders_Pad_Header_Label * lbl ( find_label ( event_n->pos() ) ); bool changed ( false ); { unsigned int idx ( _invalid_idx ); if ( lbl != 0 ) { idx = lbl->column_total_idx; } if ( idx != _weak_focus_idx ) { _weak_focus_idx = idx; changed = true; } } if ( changed ) { Qt::CursorShape cursor_shape ( Qt::ArrowCursor ); if ( lbl == 0 ) { setToolTip ( QString() ); } else { setToolTip ( lbl->tool_tip ); if ( ( event_n->buttons() & Qt::LeftButton ) != 0 ) { if ( hd_data().label_sliding ) { emit sig_label_selected ( lbl->group_idx, lbl->column_idx ); } } cursor_shape = Qt::PointingHandCursor; } { // Adjust the cursor QCursor cursor_new ( cursor() ); if ( cursor_new.shape() != cursor_shape ) { cursor_new.setShape ( cursor_shape ); setCursor ( cursor_new ); } } update(); } } void Sliders_Pad_Header::changeEvent ( QEvent * event_n ) { QWidget::changeEvent ( event_n ); update_painter_states(); } void Sliders_Pad_Header::paintEvent ( QPaintEvent * event_n ) { //::std::cout << "Sliders_Pad_Header::paintEvent" << "\n"; QWidget::paintEvent ( event_n ); // Update elided text strings on demand if ( hd_data().update_elided_texts ) { hd_data().update_elided_texts = false; update_elided_texts(); } if ( hd_data().update_decoration ) { hd_data().update_decoration = false; if ( hd_data().upside_down ) { sp_style()->paint_footer_decoration(); } else { sp_style()->paint_header_decoration(); } } QPainter pnt ( this ); pnt.setRenderHints ( QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform ); // Draw debug area { //painter.setBrush ( hd_data().upside_down ? Qt::cyan : Qt::yellow ); //painter.setPen ( Qt::NoPen ); //painter.drawRect ( rect() ); } if ( hd_data().labels.size() > 0 ) { paint_label_rects ( pnt ); paint_label_decos ( pnt ); paint_label_texts ( pnt ); } } void Sliders_Pad_Header::paint_label_rects ( QPainter & pnt_n ) { pnt_n.setPen ( Qt::NoPen ); if ( _lbl_rect_brush[0].style() != Qt::NoBrush ) { pnt_n.setBrush ( _lbl_rect_brush[0] ); for ( unsigned int lii=0; lii < hd_data().labels.size(); ++lii ) { // Draw focus items later if ( ( lii != _focus_idx ) && ( lii != _weak_focus_idx ) ) { const Sliders_Pad_Header_Label & lbl ( hd_data().labels[lii] ); pnt_n.setTransform ( lbl.label_trans ); pnt_n.drawRect ( lbl.label_rect ); } } } if ( ( _focus_idx < hd_data().labels.size() ) && ( _lbl_rect_brush[1].style() != Qt::NoBrush ) ) { pnt_n.setBrush ( _lbl_rect_brush[1] ); const Sliders_Pad_Header_Label & lbl ( hd_data().labels[_focus_idx] ); pnt_n.setTransform ( lbl.label_trans ); pnt_n.drawRect ( lbl.label_rect ); } if ( ( _weak_focus_idx < hd_data().labels.size() ) && ( _lbl_rect_brush[2].style() != Qt::NoBrush ) ) { pnt_n.setBrush ( _lbl_rect_brush[2] ); const Sliders_Pad_Header_Label & lbl ( hd_data().labels[_weak_focus_idx] ); pnt_n.setTransform ( lbl.label_trans ); pnt_n.drawRect ( lbl.label_rect ); } } void Sliders_Pad_Header::paint_label_decos ( QPainter & pnt_n ) { pnt_n.setPen ( Qt::NoPen ); pnt_n.setBrush ( Qt::NoBrush ); pnt_n.resetTransform(); // Draw groups/columns decoration graphics const unsigned int pic_idx ( hd_data().upside_down ? 1 : 0 ); for ( unsigned int gii=0; gii < sp_data()->groups.size(); ++gii ) { // Group picture const Sliders_Pad_Data_Group * sp_grp ( sp_data()->groups[gii] ); pnt_n.drawPicture ( 0, 0, sp_grp->hd_pics[pic_idx] ); // Columns pictures for ( unsigned int cii=0; cii < sp_grp->columns.size(); ++cii ) { const Sliders_Pad_Data_Column * sp_col ( sp_grp->columns[cii] ); pnt_n.drawPicture ( 0, 0, sp_col->hd_pics[pic_idx] ); } } } void Sliders_Pad_Header::paint_label_texts ( QPainter & pnt_n ) { Qt::Alignment txt_align ( Qt::AlignLeft | Qt::AlignVCenter ); if ( hd_data().upside_down ) { txt_align = Qt::AlignRight | Qt::AlignVCenter; } pnt_n.setPen ( _lbl_txt_pen[0] ); pnt_n.setBrush ( Qt::NoBrush ); pnt_n.setFont ( _lbl_txt_font[0] ); for ( unsigned int lii=0; lii < hd_data().labels.size(); ++lii ) { // Draw focus items later if ( ( lii != _focus_idx ) && ( lii != _weak_focus_idx ) ) { const Sliders_Pad_Header_Label & lbl ( hd_data().labels[lii] ); { // Pen color const QPen & ppen ( pnt_n.pen() ); if ( lbl.col_fg != ppen.color() ) { QPen npen ( ppen ); npen.setColor ( lbl.col_fg ); pnt_n.setPen ( npen ); } } // Draw text pnt_n.setTransform ( lbl.label_trans ); pnt_n.drawText ( lbl.text_rect, txt_align, lbl.text_elided ); } } if ( _weak_focus_idx != _focus_idx ) { paint_label_text ( pnt_n, txt_align, _focus_idx, 1 ); paint_label_text ( pnt_n, txt_align, _weak_focus_idx, 2 ); } else { paint_label_text ( pnt_n, txt_align, _focus_idx, 3 ); } } void Sliders_Pad_Header::paint_label_text ( QPainter & pnt_n, Qt::Alignment txt_align_n, unsigned int lbl_idx_n, unsigned int state_idx_n ) { if ( lbl_idx_n < hd_data().labels.size() ) { pnt_n.setFont ( _lbl_txt_font[state_idx_n] ); pnt_n.setPen ( _lbl_txt_pen[state_idx_n] ); const Sliders_Pad_Header_Label & lbl ( hd_data().labels[lbl_idx_n] ); pnt_n.setTransform ( lbl.label_trans ); pnt_n.drawText ( lbl.text_rect, txt_align_n, lbl.text_elided ); } } void Sliders_Pad_Header::update_painter_states ( ) { _lbl_rect_brush[0].setStyle ( Qt::NoBrush ); _lbl_rect_brush[1].setStyle ( Qt::SolidPattern ); if ( hd_data().upside_down ) { _lbl_rect_brush[1].setColor ( palette().color ( QPalette::Button ) ); } else { _lbl_rect_brush[1].setColor ( palette().color ( QPalette::Highlight ) ); } _lbl_rect_brush[2].setStyle ( Qt::NoBrush ); const QFont fnt ( font() ); _lbl_txt_font[0] = fnt; _lbl_txt_font[1] = fnt; _lbl_txt_font[2] = fnt; _lbl_txt_font[2].setUnderline ( !fnt.underline() ); _lbl_txt_font[3] = _lbl_txt_font[2]; const QPen pen; _lbl_txt_pen[0] = pen; _lbl_txt_pen[1] = pen; if ( hd_data().upside_down ) { _lbl_txt_pen[1].setColor ( palette().color ( QPalette::ButtonText ) ); } else { _lbl_txt_pen[1].setColor ( palette().color ( QPalette::HighlightedText ) ); } _lbl_txt_pen[2] = pen; _lbl_txt_pen[3] = _lbl_txt_pen[1]; } const Sliders_Pad_Header_Label * Sliders_Pad_Header::find_label ( const QPoint & pos_n ) { const Sliders_Pad_Header_Label * res ( 0 ); const QPointF pos_f ( pos_n ); const unsigned int num_lbl ( hd_data().labels.size() ); unsigned int lbl_idx ( num_lbl ); for ( unsigned int lii = 0; lii < num_lbl; ++lii ) { --lbl_idx; const Sliders_Pad_Header_Label & lbl ( hd_data().labels[lbl_idx] ); const Sliders_Pad_Data_Group * sp_grp ( sp_data()->groups[lbl.group_idx] ); if ( pos_n.x() >= (int)sp_grp->group_pos ) { const QPointF pos_map ( lbl.label_trans_inv.map ( pos_f ) ); QRectF rect_f ( lbl.label_rect ); rect_f.adjust ( 0, -1.5, 0, 3.0 ); if ( rect_f.contains ( pos_map ) ) { res = &lbl; break; } } } return res; } void Sliders_Pad_Header::elided_label_text ( Sliders_Pad_Header_Label & lbl_n ) { const QFontMetrics & fmet ( fontMetrics() ); lbl_n.text_elided = fmet.elidedText ( lbl_n.text, Qt::ElideRight, lbl_n.text_area.width() ); // Update text rectangle lbl_n.text_rect = lbl_n.text_area; if ( lbl_n.text_rect.width() > lbl_n.label_length_max ) { lbl_n.text_rect.setWidth ( lbl_n.label_length_max ); } } void Sliders_Pad_Header::update_elided_texts ( ) { for ( unsigned int ii=0; ii < hd_data().labels.size(); ++ii ) { elided_label_text ( hd_data().labels[ii] ); } } } // End of namespace qastools-v0.22.0/shared/src/wdg/sliders_pad_header.hpp000066400000000000000000000057441354534512100227730ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_sliders_pad_header_hpp__ #define __INC_sliders_pad_header_hpp__ #include "sliders_pad_header_data.hpp" #include #include #include #include namespace Wdg { // Forward declaration class Sliders_Pad_Data; class Sliders_Pad_Data_Group; class Sliders_Pad_Data_Column; class Sliders_Pad_Style; /// /// @brief Sliders_Pad_Header /// class Sliders_Pad_Header : public QWidget { Q_OBJECT // Public methods public: Sliders_Pad_Header ( Sliders_Pad_Data * sp_data_n, Sliders_Pad_Style * sp_style_n, QWidget * parent_n = 0 ); ~Sliders_Pad_Header ( ); QSize minimumSizeHint ( ) const; QSize sizeHint ( ) const; // Header variables const Sliders_Pad_Header_Data & hd_data ( ) const; Sliders_Pad_Header_Data & hd_data ( ); Sliders_Pad_Data * sp_data ( ) const; Sliders_Pad_Style * sp_style ( ) const; // Decoration graphics /// @brief Sets the index of the label/group with the focus void set_focus_idx ( unsigned int group_idx_n, unsigned int column_idx_n ); unsigned int label_str_length_px_max ( const QString & str_n ) const; // Public slots public slots: void set_label_text ( unsigned int lbl_idx_n, const QString & txt_n ); // Signals signals: void sig_label_selected ( unsigned int group_idx_n, unsigned int column_idx_n ); // Protected methods protected: void enterEvent ( QEvent * event_n ); void leaveEvent ( QEvent * event_n ); void mousePressEvent ( QMouseEvent * event_n ); void mouseMoveEvent ( QMouseEvent * event_n ); void changeEvent ( QEvent * event_n ); void paintEvent ( QPaintEvent * event_n ); void paint_label_rects ( QPainter & pnt_n ); void paint_label_decos ( QPainter & pnt_n ); void paint_label_texts ( QPainter & pnt_n ); void paint_label_text ( QPainter & pnt_n, Qt::Alignment txt_align_n, unsigned int lbl_idx_n, unsigned int state_idx_n ); const Sliders_Pad_Header_Label * find_label ( const QPoint & pos_n ); void elided_label_text ( Sliders_Pad_Header_Label & lbl_n ); void update_elided_texts ( ); void update_painter_states ( ); // Private attributes private: Sliders_Pad_Header_Data _data; Sliders_Pad_Data * _sp_data; Sliders_Pad_Style * _sp_style; unsigned int _focus_idx; unsigned int _weak_focus_idx; const unsigned int _invalid_idx; // 0 - default // 1 - focus only // 2 - weak focus only // 3 - focus and weak focus QBrush _lbl_rect_brush[3]; QPen _lbl_txt_pen[4]; QFont _lbl_txt_font[4]; }; inline const Sliders_Pad_Header_Data & Sliders_Pad_Header::hd_data ( ) const { return _data; } inline Sliders_Pad_Header_Data & Sliders_Pad_Header::hd_data ( ) { return _data; } inline Sliders_Pad_Data * Sliders_Pad_Header::sp_data ( ) const { return _sp_data; } inline Sliders_Pad_Style * Sliders_Pad_Header::sp_style ( ) const { return _sp_style; } } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/sliders_pad_header_data.cpp000066400000000000000000000013451354534512100237500ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "sliders_pad_header_data.hpp" namespace Wdg { // // Sliders_Pad_Header_Label // Sliders_Pad_Header_Label::Sliders_Pad_Header_Label ( ) : label_length_max ( 0 ), group_idx ( 0 ), column_idx ( 0 ), column_total_idx ( 0 ) { } // // Sliders_Pad_Header_Data // Sliders_Pad_Header_Data::Sliders_Pad_Header_Data ( ) : update_elided_texts ( false ), update_decoration ( false ), upside_down ( false ), column_labels ( false ), label_sliding ( true ), angle ( 0.0 ), angle_sin ( 0.0 ), angle_cos ( 1.0 ), max_str_length_px ( 100 ), pad_left ( 2 ), pad_right ( 1 ), spacing_inter ( 3 ), spacing_vertical ( 3 ) { } } // End of namespace qastools-v0.22.0/shared/src/wdg/sliders_pad_header_data.hpp000066400000000000000000000024521354534512100237550ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_sliders_pad_header_data_hpp__ #define __INC_sliders_pad_header_data_hpp__ #include #include #include namespace Wdg { class Sliders_Pad_Header_Label { // Public methods public: Sliders_Pad_Header_Label ( ); // Public attributes public: unsigned int label_length_max; QTransform label_trans; QTransform label_trans_inv; QRectF label_rect; QRectF text_area; QRectF text_rect; QRect label_txt_bbox; unsigned int group_idx; unsigned int column_idx; unsigned int column_total_idx; QString text; QString text_elided; QString tool_tip; QColor col_fg; }; /// /// @brief Sliders_Pad_Header_Data /// class Sliders_Pad_Header_Data { // Public methods public: Sliders_Pad_Header_Data ( ); bool update_elided_texts; bool update_decoration; bool upside_down; bool column_labels; bool label_sliding; std::vector < Sliders_Pad_Header_Label > labels; double angle; double angle_sin; double angle_cos; double center_x; double center_y; unsigned int max_str_length_px; unsigned int pad_left; unsigned int pad_right; unsigned int spacing_inter; unsigned int spacing_vertical; QPointer < QWidget > widget; }; } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/sliders_pad_layout.cpp000066400000000000000000000470241354534512100230500ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "sliders_pad_layout.hpp" #include "sliders_pad_header.hpp" #include "equal_columns_layout_group.hpp" #include "equal_columns_layout.hpp" #define _USE_MATH_DEFINES #include #include #include namespace Wdg { Sliders_Pad_Layout::Sliders_Pad_Layout ( Sliders_Pad_Data * sp_data_n, QWidget * parent_n ) : QLayout ( parent_n ), _num_items ( 0 ), _header_data ( 0 ), _footer_data ( 0 ), _sp_data ( sp_data_n ) { _lay_eqc.reset ( new ::Wdg::Equal_Columns_Layout ); _lay_eqc->setContentsMargins ( 0, 0, 0, 0 ); _items[0] = _lay_eqc.data(); ++_num_items; } Sliders_Pad_Layout::~Sliders_Pad_Layout ( ) { } // QLayout methods void Sliders_Pad_Layout::set_header_item ( QLayoutItem * item_n ) { if ( _header_item != 0 ) { QScopedPointer < QLayoutItem > item ( _header_item.data() ); removeItem ( item.data() ); _header_data = 0; } if ( item_n != 0 ) { _header_item.reset ( item_n ); _items[_num_items] = item_n; ++_num_items; invalidate(); } } void Sliders_Pad_Layout::set_header_widget ( QWidget * wdg_n ) { if ( wdg_n != 0 ) { ::Wdg::Sliders_Pad_Header * header ( dynamic_cast < ::Wdg::Sliders_Pad_Header * > ( wdg_n ) ); if ( header != 0 ) { set_header_item ( new QWidgetItem ( wdg_n ) ); _header_data = &header->hd_data(); } } } void Sliders_Pad_Layout::set_footer_item ( QLayoutItem * item_n ) { if ( _footer_item != 0 ) { QScopedPointer < QLayoutItem > item ( _footer_item.data() ); removeItem ( item.data() ); _footer_data = 0; } if ( item_n != 0 ) { _footer_item.reset ( item_n ); _items[_num_items] = item_n; ++_num_items; invalidate(); } } void Sliders_Pad_Layout::set_footer_widget ( QWidget * wdg_n ) { if ( wdg_n != 0 ) { ::Wdg::Sliders_Pad_Header * header ( dynamic_cast < ::Wdg::Sliders_Pad_Header * > ( wdg_n ) ); if ( header != 0 ) { set_footer_item ( new QWidgetItem ( wdg_n ) ); _footer_data = &header->hd_data(); } } } int Sliders_Pad_Layout::add_group_widget ( QWidget * wdg_n, unsigned int group_idx, unsigned int column_idx, unsigned int row_idx_n ) { return _lay_eqc->add_group_widget ( wdg_n, group_idx, column_idx, row_idx_n ); } void Sliders_Pad_Layout::addItem ( QLayoutItem * item_n ) { _lay_eqc->addItem ( item_n ); } QLayoutItem * Sliders_Pad_Layout::itemAt ( int idx_n ) const { QLayoutItem * res ( 0 ); if ( ( idx_n >= 0 ) && ( idx_n < (int)_num_items ) ) { res = _items[idx_n]; } return res; } QLayoutItem * Sliders_Pad_Layout::takeAt ( int idx_n ) { QLayoutItem * res ( 0 ); if ( ( idx_n >= 0 ) && ( idx_n < (int)_num_items ) ) { res = _items[idx_n]; --_num_items; const unsigned int num ( _num_items - idx_n ); for ( unsigned int ii=0; ii < num; ++ii ) { const unsigned int idx ( idx_n + ii ); _items[idx] = _items[idx + 1]; } if ( res == _header_item.data() ) { _header_item.take(); } else if ( res == _lay_eqc.data() ) { _lay_eqc.take(); } else if ( res == _footer_item.data() ) { _footer_item.take(); } invalidate(); } return res; } int Sliders_Pad_Layout::count ( ) const { return _num_items; } QSize Sliders_Pad_Layout::minimumSize ( ) const { QSize res ( _lay_eqc->minimumSize() ); if ( _header_item != 0 ) { const QSize hms ( _header_item->minimumSize() ); res.rwidth() = qMax ( hms.width(), res.width() ); res.rheight() += hms.height(); } if ( _footer_item != 0 ) { const QSize fms ( _footer_item->minimumSize() ); res.rwidth() = qMax ( fms.width(), res.width() ); res.rheight() += fms.height(); } if ( extra_sub_slider_spacing() ) { // Sub slider area when no buttons are present res.rheight() += _lay_eqc->spacing_vertical(); } { const QMargins & mgs ( contentsMargins() ); res.rwidth() += mgs.left() + mgs.right(); res.rheight() += mgs.top() + mgs.bottom(); } //::std::cout << "Sliders_Pad_Layout::minimumSize " << res.width() << ":" << res.height() << "\n"; return res; } QSize Sliders_Pad_Layout::sizeHint ( ) const { QSize res ( minimumSize() ); int & ww ( res.rwidth() ); int & hh ( res.rheight() ); int mg_hor ( 0 ); int mg_vert ( 0 ); { const QMargins mgs ( contentsMargins() ); mg_hor = mgs.left() + mgs.right(); mg_vert = mgs.top() + mgs.bottom(); } ww -= mg_hor; hh -= mg_vert; ww *= 3; hh *= 3; ww /= 2; hh /= 2; ww += mg_hor; hh += mg_vert; return res; } bool Sliders_Pad_Layout::extra_sub_slider_spacing ( ) const { return ( _lay_eqc->num_rows() == 1 ); } unsigned int Sliders_Pad_Layout::header_height_hint ( const QLayoutItem * item_n, const Sliders_Pad_Header_Data * hdata_n ) const { unsigned int res ( 0 ); if ( ( item_n == 0 ) || ( hdata_n == 0 ) ) { return res; } if ( !item_n->isEmpty() ) { unsigned int fnt_height ( 16 ); if ( hdata_n->widget != 0 ) { fnt_height = hdata_n->widget->fontMetrics().height(); } unsigned int max_label_len ( 0 ); { unsigned int num_lbl ( hdata_n->labels.size() ); if ( num_lbl > 0 ) { for ( unsigned int ii=0; ii < num_lbl; ++ii ) { unsigned int len ( hdata_n->labels[ii].label_length_max ); if ( max_label_len < len ) { max_label_len = len; } } } else { max_label_len = hdata_n->max_str_length_px; } } max_label_len += hdata_n->pad_left; max_label_len += hdata_n->pad_right; const double angle_sin ( ::std::abs ( hdata_n->angle_sin ) ); const double angle_cos ( ::std::abs ( hdata_n->angle_cos ) ); double h_hint ( hdata_n->spacing_vertical ); h_hint += max_label_len * angle_sin; h_hint += fnt_height * angle_cos; res = ::std::ceil ( h_hint ); } return res; } void Sliders_Pad_Layout::calc_column_widths_sync ( unsigned int width_n ) { _lay_eqc->calc_column_widths ( width_n ); // Synchronize sliders pad data const unsigned int num_grps ( _lay_eqc->num_active_groups() ); if ( num_grps == _sp_data->groups.size() ) { for ( unsigned int gii=0; gii < num_grps; ++gii ) { const Equal_Columns_Layout_Group * eq_grp ( _lay_eqc->group ( gii ) ); Sliders_Pad_Data_Group * sp_grp ( _sp_data->groups[gii] ); sp_grp->group_pos = eq_grp->group_pos(); sp_grp->group_width = eq_grp->group_width(); const unsigned int num_cols ( eq_grp->num_columns() ); if ( num_cols == sp_grp->columns.size() ) { for ( unsigned int cii=0; cii < num_cols; ++cii ) { const Equal_Columns_Layout_Column * eq_col ( eq_grp->column ( cii ) ); Sliders_Pad_Data_Column * sp_col ( sp_grp->columns[cii] ); sp_col->col_pos = eq_col->column_pos(); sp_col->col_width = eq_col->column_width(); } } } } } void Sliders_Pad_Layout::calc_label_angle ( Sliders_Pad_Header_Data * hdata_n, unsigned int lbl_hor_dist_n, bool min_angle_n ) { if ( hdata_n == 0 ) { return; } unsigned int fnt_height ( 16 ); if ( hdata_n->widget != 0 ) { fnt_height = hdata_n->widget->fontMetrics().height(); } double angle_sin; const unsigned int lbl_v_dist ( fnt_height + hdata_n->spacing_inter ); const unsigned int col_h_dist ( qMax ( (unsigned int)1, lbl_hor_dist_n ) ); //::std::cout << "lbl_v_dist " << lbl_v_dist << "\n"; //::std::cout << "col_h_dist " << col_h_dist << "\n"; if ( col_h_dist >= lbl_v_dist ) { angle_sin = double ( lbl_v_dist ) / double ( col_h_dist ); if ( min_angle_n && ( angle_sin > 0.7 ) ) { angle_sin = 1.0; } } else { angle_sin = 1.0; } if ( hdata_n->upside_down ) { angle_sin = -angle_sin; } angle_sin = ::std::asin ( angle_sin ); hdata_n->angle = angle_sin; hdata_n->angle_sin = ::std::sin ( angle_sin ); hdata_n->angle_cos = ::std::cos ( angle_sin ); const double fh2 ( fnt_height / 2.0 ); hdata_n->center_x = hdata_n->angle_sin * fh2; hdata_n->center_y = hdata_n->angle_cos * fh2; const double limit_min ( 0.001 ); if ( ::std::abs ( hdata_n->center_x ) < limit_min ) { hdata_n->center_x = 0.0; } if ( ::std::abs ( hdata_n->center_y ) < limit_min ) { hdata_n->center_y = 0.0; } hdata_n->update_elided_texts = true; } double Sliders_Pad_Layout::calc_label_x_center ( const Sliders_Pad_Header_Data * hdata_n, const Sliders_Pad_Data_Group * sp_grp_n, const Sliders_Pad_Data_Column * sp_col_n ) { double x_center; if ( hdata_n->column_labels ) { x_center = sp_col_n->col_pos; x_center += sp_col_n->col_width / 2.0; } else { x_center = sp_grp_n->group_pos; x_center += sp_grp_n->group_width / 2.0; } return x_center; } unsigned int Sliders_Pad_Layout::calc_labels_max_x ( const Sliders_Pad_Header_Data * hdata_n ) { unsigned int res ( 0 ); if ( hdata_n != 0 ) { const double fnt_height ( hdata_n->widget->fontMetrics().height() ); const double angle_sin_abs ( ::std::abs ( hdata_n->angle_sin ) ); const double angle_cos_abs ( ::std::abs ( hdata_n->angle_cos ) ); const double height_off ( fnt_height * angle_sin_abs / 2.0 ); const unsigned int x_padding ( hdata_n->pad_left + hdata_n->pad_right ); unsigned int lbl_idx ( hdata_n->labels.size() ); unsigned int lim_num ( 4 ); // Check these number of labels if ( lbl_idx < lim_num ) { lim_num = lbl_idx; } for ( unsigned int ii=0; ii < lim_num; ++ii ) { --lbl_idx; const Sliders_Pad_Header_Label & lbl ( hdata_n->labels[lbl_idx] ); const Sliders_Pad_Data_Group * sp_grp ( _sp_data->groups[lbl.group_idx] ); const Sliders_Pad_Data_Column * sp_col ( sp_grp->columns[lbl.column_idx] ); unsigned int x_max; { double x_center ( calc_label_x_center ( hdata_n, sp_grp, sp_col ) ); double label_len ( lbl.label_length_max + x_padding ); double x_max_dbl ( x_center + height_off + label_len * angle_cos_abs ); x_max = ::std::ceil ( x_max_dbl ); } if ( x_max > res ) { res = x_max; } } } return res; } void Sliders_Pad_Layout::calc_columns_sizes ( unsigned int area_width_n, unsigned int area_height_n ) { //::std::cout << "Sliders_Pad_Layout::calc_columns_sizes " << area_width_n << ":" << area_height_n << "\n"; if ( _header_data == 0 ) { return; } // Require synchronized label storage sizes if ( _header_data->labels.size() != _lay_eqc->num_groups() ) { return; } // Minimum size of the sliders block const QSize inputs_min_size ( _lay_eqc->minimumSize() ); bool header_vis ( false ); bool footer_vis ( false ); unsigned int h_header = 0; unsigned int h_inputs = 0; unsigned int h_footer = 0; unsigned int h_sub_slider = 0; if ( extra_sub_slider_spacing() ) { h_sub_slider = _lay_eqc->spacing_vertical(); } if ( _header_item != 0 ) { if ( !_header_item->isEmpty() ) { header_vis = true; h_header = _header_item->minimumSize().height(); } } if ( _footer_item != 0 ) { if ( !_footer_item->isEmpty() ) { footer_vis = true; h_footer = _footer_item->minimumSize().height(); } } h_inputs = area_height_n - h_header - h_footer - h_sub_slider; // Calculate a first estimate for the row heights _lay_eqc->calc_row_heights ( h_inputs ); // Shrink columns widths so that the last labels fit into the given frame // The column widths are fixed after this step if ( header_vis || footer_vis ) { const unsigned int min_width ( qMax ( 0, inputs_min_size.width() ) ); const unsigned int max_width ( area_width_n ); unsigned int w_min ( ( area_width_n * 4 ) / 5 ); if ( w_min < min_width ) { w_min = inputs_min_size.width(); } unsigned int w_test ( max_width ); while ( ( w_test >= w_min ) && ( w_test > 0 ) ) { calc_column_widths_sync ( w_test ); const bool min_angle ( w_test <= min_width ); calc_label_angle ( _header_data, _lay_eqc->smallest_group_dist(), min_angle ); calc_label_angle ( _footer_data, _lay_eqc->smallest_column_dist(), min_angle ); unsigned int max_x_header ( calc_labels_max_x ( _header_data ) ); unsigned int max_x_footer ( calc_labels_max_x ( _footer_data ) ); if ( ( max_x_header < max_width ) && ( max_x_footer < max_width ) ) { break; } --w_test; } //::std::cout << "Iterations min_width " << min_width << "\n"; //::std::cout << "Iterations max_width " << max_width << "\n"; //::std::cout << "Iterations w_test " << w_test << "\n"; //::std::cout << "Iterations " << max_width - w_test << "\n"; } // // Adjust header and sliders block heights // const unsigned int h_header_hint ( header_height_hint ( _header_item.data(), _header_data ) ); const unsigned int h_footer_hint ( header_height_hint ( _footer_item.data(), _footer_data ) ); h_header = h_header_hint; h_inputs = _lay_eqc->all_rows_height(); h_footer = h_footer_hint; // Header and footer should always be smaller than the inputs block if ( ( h_header * 3 ) > area_height_n ) { h_header = area_height_n / 3; if ( h_header > h_header_hint ) { h_header = h_header_hint; } } if ( ( h_footer * 4 ) > area_height_n ) { h_footer = area_height_n / 4; if ( h_footer > h_footer_hint ) { h_footer = h_footer_hint; } } h_inputs = area_height_n - h_header - h_footer - h_sub_slider; // Check inputs area minimum size and shrink the header and footer on demand if ( (int)h_inputs < inputs_min_size.height() ) { h_inputs = inputs_min_size.height(); if ( h_inputs < area_height_n ) { unsigned int delta ( area_height_n - h_inputs - h_sub_slider ); h_footer = delta / 2; h_header = delta - h_footer; } else { h_header = 0; h_footer = 0; } } _lay_eqc->calc_row_heights ( h_inputs ); post_adjust_row_heights(); // Store calculated area sizes _sp_data->header_area.setHeight ( h_header ); _sp_data->inputs_area.setHeight ( h_inputs ); _sp_data->footer_area.setHeight ( h_footer ); { unsigned int aheight ( 0 ); if ( _lay_eqc->num_rows() > 0 ) { aheight = _lay_eqc->row_height ( 0 ); } _sp_data->sliders_area_height = aheight; } { unsigned int aheight ( 0 ); if ( _lay_eqc->num_rows() > 1 ) { aheight = _lay_eqc->row_height ( 1 ); } _sp_data->switches_area_height = aheight; } } void Sliders_Pad_Layout::post_adjust_row_heights ( ) { if ( _lay_eqc->num_rows() < 2 ) { return; } if ( _lay_eqc->row_height ( 0 ) <= _lay_eqc->row_min_height ( 0 ) ) { return; } unsigned int sw_height ( _lay_eqc->row_height ( 0 ) / 16 ); // Switch row should not be higher than broad for ( unsigned int ii=2; ii <=3; ++ii ) { const unsigned int twidth ( _lay_eqc->col_type_width ( ii ) ); if ( ( twidth > 0 ) && ( sw_height > twidth ) ) { sw_height = twidth; } } if ( sw_height <= _lay_eqc->row_height ( 1 ) ) { return; } unsigned int delta ( sw_height - _lay_eqc->row_height ( 1 ) ); const unsigned int max_delta ( _lay_eqc->row_height ( 0 ) - _lay_eqc->row_min_height ( 0 ) ); if ( delta > max_delta ) { delta = max_delta; } _lay_eqc->set_row_height ( 0, _lay_eqc->row_height ( 0 ) - delta ); _lay_eqc->set_row_height ( 1, _lay_eqc->row_height ( 1 ) + delta ); } void Sliders_Pad_Layout::setGeometry ( const QRect & rect_n ) { QRect crect ( rect_n ); { const QMargins & mgs ( contentsMargins() ); crect.adjust ( mgs.left(), mgs.top(), -mgs.right(), -mgs.bottom() ); } if ( crect.isValid() ) { set_geometries ( crect ); } } void Sliders_Pad_Layout::set_geometries ( const QRect & crect_n ) { _lay_eqc->update_cache(); calc_columns_sizes ( crect_n.width(), crect_n.height() ); // Header area _sp_data->header_area.moveLeft ( crect_n.left() ); _sp_data->header_area.moveTop ( crect_n.top() ); _sp_data->header_area.setWidth ( crect_n.width() ); // Inputs area _sp_data->inputs_area.moveLeft ( crect_n.left() ); _sp_data->inputs_area.moveTop ( _sp_data->header_area.top() + _sp_data->header_area.height() ); _sp_data->inputs_area.setWidth ( crect_n.width() ); // Sliders area _sp_data->sliders_area_y = _sp_data->inputs_area.top(); // Sub sliders area _sp_data->sub_slider_area_y = _sp_data->sliders_area_y; _sp_data->sub_slider_area_y += _sp_data->sliders_area_height; _sp_data->sub_slider_area_height = _lay_eqc->spacing_vertical(); // Switches area _sp_data->switches_area_y = _sp_data->sub_slider_area_y; _sp_data->switches_area_y += _sp_data->sub_slider_area_height; // Footer area _sp_data->footer_area.moveLeft ( crect_n.left() ); _sp_data->footer_area.moveTop ( _sp_data->switches_area_y + _sp_data->switches_area_height ); _sp_data->footer_area.setWidth ( crect_n.width() ); // Apply geometries to widgets if ( _header_item != 0 ) { if ( !_header_item->isEmpty() ) { _header_item->setGeometry ( _sp_data->header_area ); update_labels_transforms ( _header_data, _sp_data->header_area ); } } _lay_eqc->set_geometries ( _sp_data->inputs_area ); if ( _footer_item != 0 ) { if ( !_footer_item->isEmpty() ) { _footer_item->setGeometry ( _sp_data->footer_area ); update_labels_transforms ( _footer_data, _sp_data->footer_area ); } } } void Sliders_Pad_Layout::update_labels_transforms ( Sliders_Pad_Header_Data * hdata_n, const QRect & hrect_n ) { //::std::cout << "Sliders_Pad_Layout::update_labels_transforms\n"; if ( !hrect_n.isValid() || ( hdata_n == 0 ) ) { return; } if ( hdata_n->widget == 0 ) { return; } const double fnt_height ( hdata_n->widget->fontMetrics().height() ); double lbl_area_height ( hrect_n.height() - hdata_n->spacing_vertical ); double x_right ( hrect_n.width() ); double y_base; if ( !hdata_n->upside_down ) { y_base = lbl_area_height; } else { y_base = 0.0; y_base += hdata_n->spacing_vertical; y_base += double ( fnt_height ) * hdata_n->angle_cos; } const unsigned int num_lbl ( hdata_n->labels.size() ); for ( unsigned int ii=0; ii < num_lbl; ++ii ) { Sliders_Pad_Header_Label & lbl ( hdata_n->labels[ii] ); if ( lbl.group_idx >= _sp_data->groups.size() ) { continue; } const Sliders_Pad_Data_Group * sp_grp ( _sp_data->groups[lbl.group_idx] ); if ( lbl.column_idx >= sp_grp->columns.size() ) { continue; } const Sliders_Pad_Data_Column * sp_col ( sp_grp->columns[lbl.column_idx] ); // Find horizontal center double x_center ( calc_label_x_center ( hdata_n, sp_grp, sp_col ) ); double x_base ( x_center + hdata_n->center_x ); // Label transformation and inverse { const QTransform trans ( hdata_n->angle_cos, -hdata_n->angle_sin, 0.0, hdata_n->angle_sin, hdata_n->angle_cos, 0.0, x_base, y_base, 1.0 ); lbl.label_trans = trans; lbl.label_trans_inv = trans.inverted(); } // Label rectangle const double limit_min ( 0.002 ); const double angle_sin_abs ( ::std::abs ( hdata_n->angle_sin ) ); const double angle_cos_abs ( ::std::abs ( hdata_n->angle_cos ) ); double lbl_width; // Label width including left and right padding if ( angle_sin_abs > limit_min ) { double h_avail ( lbl_area_height ); h_avail -= double ( fnt_height ) * angle_cos_abs; lbl_width = h_avail / angle_sin_abs; } else { lbl_width = hdata_n->max_str_length_px * 2; } // Shorten the length if the label is too near to the right edge if ( angle_cos_abs > limit_min ) { double xdist ( x_right - x_center ); double height_offset ( fnt_height * angle_sin_abs / 2.0 ); double x_center_dist ( lbl_width * angle_cos_abs + height_offset ); if ( xdist < x_center_dist ) { xdist -= height_offset; lbl_width = xdist / angle_cos_abs; if ( lbl_width < 0.0 ) { lbl_width = 0.0; } } } lbl.label_rect = QRectF ( 0, -fnt_height, lbl_width, fnt_height ); lbl.text_area = lbl.label_rect; lbl.text_area.moveLeft ( lbl.text_area.left() + hdata_n->pad_left ); lbl.text_area.setWidth ( lbl.text_area.width() - hdata_n->pad_left - hdata_n->pad_right ); { QRectF bbox ( lbl.label_rect ); bbox = lbl.label_trans.mapRect ( bbox ); lbl.label_txt_bbox.setRect ( ::std::floor ( bbox.left() ), ::std::floor ( bbox.top() ), ::std::ceil ( bbox.width() ), ::std::ceil ( bbox.height() ) ); // Make a bit wider just to be sure lbl.label_txt_bbox.adjust ( -1, -1, 1, 1 ); } } } } // End of namespace qastools-v0.22.0/shared/src/wdg/sliders_pad_layout.hpp000066400000000000000000000061061354534512100230510ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_sliders_pad_layout_hpp__ #define __INC_sliders_pad_layout_hpp__ #include #include #include #include #include #include #include "sliders_pad_data.hpp" #include "sliders_pad_header_data.hpp" namespace Wdg { // Forward declarations class Equal_Columns_Layout; /// /// @brief Sliders_Pad_Layout /// class Sliders_Pad_Layout : public QLayout { // Public methods public: Sliders_Pad_Layout ( Sliders_Pad_Data * sp_data_n, QWidget * parent_n = 0 ); ~Sliders_Pad_Layout ( ); // // Size hints // QSize minimumSize ( ) const; QSize sizeHint ( ) const; // Header specific Sliders_Pad_Header_Data * header_data ( ) const; Sliders_Pad_Header_Data * footer_data ( ) const; // Header labels unsigned int num_header_labels ( ) const; const Sliders_Pad_Header_Label & header_label ( unsigned int idx_n ) const; Sliders_Pad_Header_Label & header_label ( unsigned int idx_n ); // // QLayout methods // void set_header_item ( QLayoutItem * item_n ); void set_header_widget ( QWidget * wdg_n ); void set_footer_item ( QLayoutItem * item_n ); void set_footer_widget ( QWidget * wdg_n ); int add_group_widget ( QWidget * wdg_n, unsigned int group_idx, unsigned int column_idx, unsigned int row_idx_n ); void addItem ( QLayoutItem * item_n ); QLayoutItem * itemAt ( int index_n ) const; QLayoutItem * takeAt ( int index_n ); int count ( ) const; void setGeometry ( const QRect & rect_n ); // Protected methods protected: bool extra_sub_slider_spacing ( ) const; unsigned int header_height_hint ( const QLayoutItem * item_n, const Sliders_Pad_Header_Data * hdata_n ) const; void calc_column_widths_sync ( unsigned int width_n ); void calc_label_angle ( Sliders_Pad_Header_Data * hdata_n, unsigned int lbl_hor_dist_n, bool min_angle_n ); double calc_label_x_center ( const Sliders_Pad_Header_Data * hdata_n, const Sliders_Pad_Data_Group * sp_grp_n, const Sliders_Pad_Data_Column * sp_col_n ); unsigned int calc_labels_max_x ( const Sliders_Pad_Header_Data * hdata_n ); void calc_columns_sizes ( unsigned int area_width_n, unsigned int area_height_n ); void post_adjust_row_heights ( ); void set_geometries ( const QRect & crect_n ); void update_labels_transforms ( Sliders_Pad_Header_Data * hdata_n, const QRect & hrect_n ); // Private attributes; private: QScopedPointer < QLayoutItem > _header_item; QScopedPointer < Equal_Columns_Layout > _lay_eqc; QScopedPointer < QLayoutItem > _footer_item; unsigned int _num_items; QLayoutItem * _items[3]; Sliders_Pad_Header_Data * _header_data; Sliders_Pad_Header_Data * _footer_data; Sliders_Pad_Data * _sp_data; }; inline Sliders_Pad_Header_Data * Sliders_Pad_Layout::header_data ( ) const { return _header_data; } inline Sliders_Pad_Header_Data * Sliders_Pad_Layout::footer_data ( ) const { return _footer_data; } } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/sliders_pad_style.cpp000066400000000000000000000361301354534512100226670ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "sliders_pad_style.hpp" #include "sliders_pad_data.hpp" #include "sliders_pad_header_data.hpp" #include #define _USE_MATH_DEFINES #include #include #include namespace Wdg { Sliders_Pad_Style::Sliders_Pad_Style ( Sliders_Pad_Data * data_n ) : _sp_data ( data_n ) { stem_corner_indent = 1.0; stem_pen.setWidthF ( 1 ); stem_pen.setCapStyle ( Qt::FlatCap ); stem_pen.setJoinStyle ( Qt::BevelJoin ); } Sliders_Pad_Style::~Sliders_Pad_Style ( ) { } double Sliders_Pad_Style::calc_col_center ( unsigned int col_width_n, unsigned int col_idx_n , unsigned int num_cols_n ) const { unsigned int div_val ( col_width_n ); if ( col_width_n > 0 ) { if ( ( col_width_n % 2 ) == 0 ) { if ( col_idx_n >= ( num_cols_n / 2 ) ) { ++div_val; } else { --div_val; } } } return ( double ( div_val ) / 2.0 ); } QPainterPath Sliders_Pad_Style::bridge_path ( Sliders_Pad_Data_Group * sp_grp_n, double y_top_n ) const { QPainterPath ppath; if ( sp_grp_n->columns.size() < 2 ) { return ppath; } const unsigned int num_cols ( sp_grp_n->columns.size() ); const unsigned int col_idx_max ( num_cols - 1 ); const double y_bottom ( 0.0 ); // Draw bridge line from the leftmost column rightmost { const Sliders_Pad_Data_Column * sp_col_b ( sp_grp_n->columns[0] ); const Sliders_Pad_Data_Column * sp_col_e ( sp_grp_n->columns[col_idx_max] ); double cx_mid_min ( sp_col_b->col_pos ); double cx_mid_max ( sp_col_e->col_pos ); cx_mid_min += calc_col_center ( sp_col_b->col_width, 0, num_cols ); cx_mid_max += calc_col_center ( sp_col_e->col_width, col_idx_max, num_cols ); const double c_off ( stem_corner_indent ); // Corner offset ppath.moveTo ( cx_mid_min, y_bottom ); ppath.lineTo ( cx_mid_min, y_top_n - c_off ); ppath.lineTo ( cx_mid_min + c_off, y_top_n ); ppath.lineTo ( cx_mid_max - c_off, y_top_n ); ppath.lineTo ( cx_mid_max, y_top_n - c_off ); ppath.lineTo ( cx_mid_max, y_bottom ); } // Draw vertical lines from the bridge line down to the bottom for ( unsigned int cii=1; cii < col_idx_max; ++cii ) { const Sliders_Pad_Data_Column * sp_col ( sp_grp_n->columns[cii] ); double cx_mid ( sp_col->col_pos ); cx_mid += calc_col_center ( sp_col->col_width, cii, num_cols ); ppath.moveTo ( cx_mid, y_top_n ); ppath.lineTo ( cx_mid, y_bottom ); } return ppath; } QPainterPath Sliders_Pad_Style::inclined_bridge_path ( Sliders_Pad_Data_Group * sp_grp_n, double y_top_n ) const { QPainterPath ppath; if ( sp_grp_n->columns.size() < 2 ) { return ppath; } const unsigned int num_cols ( sp_grp_n->columns.size() ); const unsigned int col_idx_max ( num_cols - 1 ); const double y_bottom ( 0.0 ); // Draw bridge line from the leftmost column rightmost { const Sliders_Pad_Data_Column * sp_col_b ( sp_grp_n->columns[0] ); const Sliders_Pad_Data_Column * sp_col_e ( sp_grp_n->columns[col_idx_max] ); double cx_mid_min ( sp_col_b->col_pos ); double cx_mid_max ( sp_col_e->col_pos ); cx_mid_min += calc_col_center ( sp_col_b->col_width, 0, num_cols ); cx_mid_max += calc_col_center ( sp_col_e->col_width, col_idx_max, num_cols ); const double x_off ( y_top_n - 0.5 ); // Corner offset ppath.moveTo ( cx_mid_min, y_bottom ); ppath.lineTo ( cx_mid_min, y_bottom + 0.5 ); ppath.lineTo ( cx_mid_min + x_off, y_top_n ); ppath.lineTo ( cx_mid_max - x_off, y_top_n ); ppath.lineTo ( cx_mid_max, y_bottom + 0.5 ); ppath.lineTo ( cx_mid_max, y_bottom ); } // Draw vertical lines from the bridge line down to the bottom for ( unsigned int cii=1; cii < col_idx_max; ++cii ) { const Sliders_Pad_Data_Column * sp_col ( sp_grp_n->columns[cii] ); double cx_mid ( sp_col->col_pos ); cx_mid += calc_col_center ( sp_col->col_width, cii, num_cols ); ppath.moveTo ( cx_mid, y_top_n ); ppath.lineTo ( cx_mid, y_bottom ); } return ppath; } QPainterPath Sliders_Pad_Style::inclined_multi_bridge_path ( Sliders_Pad_Data_Group * sp_grp_n, double y_top_n ) const { QPainterPath ppath; if ( sp_grp_n->columns.size() < 2 ) { return ppath; } const unsigned int num_cols ( sp_grp_n->columns.size() ); const unsigned int col_idx_max ( num_cols - 1 ); const double y_bottom ( 0.0 ); // Draw vertical lines from the bridge line down to the bottom for ( unsigned int cii=0; cii < col_idx_max; ++cii ) { const Sliders_Pad_Data_Column * sp_col_b ( sp_grp_n->columns[cii] ); const Sliders_Pad_Data_Column * sp_col_e ( sp_grp_n->columns[cii+1] ); double cx_mid_1 ( sp_col_b->col_pos ); double cx_mid_2 ( sp_col_e->col_pos ); cx_mid_1 += calc_col_center ( sp_col_b->col_width, 0, num_cols ); cx_mid_2 += calc_col_center ( sp_col_e->col_width, col_idx_max, num_cols ); const double x_off ( y_top_n - 0.5 ); // Corner offset ppath.moveTo ( cx_mid_1, y_bottom ); ppath.lineTo ( cx_mid_1, y_bottom + 0.5 ); ppath.lineTo ( cx_mid_1 + x_off, y_top_n ); ppath.lineTo ( cx_mid_2 - x_off, y_top_n ); ppath.lineTo ( cx_mid_2, y_bottom + 0.5 ); ppath.lineTo ( cx_mid_2, y_bottom ); } return ppath; } void Sliders_Pad_Style::paint_base_decoration ( ) { if ( sp_data() != 0 ) { this->draw_base(); } } void Sliders_Pad_Style::paint_header_decoration ( ) { if ( sp_data() != 0 ) { if ( ( sp_data()->header != 0 ) && ( sp_data()->header_data != 0 ) ) { this->draw_header(); } } } void Sliders_Pad_Style::paint_footer_decoration ( ) { if ( sp_data() != 0 ) { if ( ( sp_data()->footer != 0 ) && ( sp_data()->footer_data != 0 ) ) { this->draw_footer(); } } } // Base painting void Sliders_Pad_Style::draw_base ( ) { _area_left = qMax ( 0, sp_data()->inputs_area.left() ); _area_height = sp_data()->sub_slider_area_height; _y_top = sp_data()->sub_slider_area_y; _y_bottom = sp_data()->switches_area_y; _y_mid = _area_height; if ( ( _area_height % 2 ) == 0 ) { _y_mid -= 1; } _y_mid = _y_mid / 2.0; const unsigned int num_grps ( sp_data()->groups.size() ); for ( unsigned int ii=0; ii < num_grps; ++ii ) { Sliders_Pad_Data_Group * sp_grp ( sp_data()->groups[ii] ); sp_grp->center_pic = QPicture(); const unsigned int num_sliders ( sp_grp->num_sliders ); const unsigned int num_switches ( sp_grp->num_switches ); _x_mid = sp_grp->group_width; if ( ( sp_grp->group_width % 2 ) == 0 ) { _x_mid -= 1.0; } _x_mid = _x_mid / 2.0; _x_mid += double ( _area_left ) + sp_grp->group_pos; QPainter pnt ( &sp_grp->center_pic ); if ( num_sliders > 1 ) { dbase_sliders_bridge ( pnt, sp_grp ); } if ( num_switches > 0 ) { if ( num_switches == 1 ) { dbase_single_switch_stem ( pnt, sp_grp ); } else { if ( num_sliders == num_switches ) { dbase_multi_switch_stems ( pnt, sp_grp ); } else { dbase_switches_bridge ( pnt, sp_grp ); if ( num_sliders == 1 ) { dbase_single_slider_stem ( pnt, sp_grp ); } } } } if ( ( num_sliders > 0 ) && ( num_switches < num_sliders ) ) { dbase_labels_connectors ( pnt, sp_grp ); } } } void Sliders_Pad_Style::dbase_sliders_bridge ( QPainter & pnt_n, Sliders_Pad_Data_Group * sp_grp_n ) { QPainterPath ppath; ppath = inclined_multi_bridge_path ( sp_grp_n, _y_mid ); ppath.translate ( _area_left, _y_top ); pnt_n.setBrush ( Qt::NoBrush ); pnt_n.setPen ( stem_pen ); pnt_n.drawPath ( ppath ); } void Sliders_Pad_Style::dbase_switches_bridge ( QPainter & pnt_n, Sliders_Pad_Data_Group * sp_grp_n ) { QPainterPath ppath; ppath = bridge_path ( sp_grp_n, double ( _area_height ) - _y_mid ); { // Invert and translate const QTransform trans ( 1.0, 0.0, 0.0, 0.0, -1.0, 0.0, _area_left, _y_bottom, 1.0 ); ppath = trans.map ( ppath ); } pnt_n.setBrush ( Qt::NoBrush ); pnt_n.setPen ( stem_pen ); pnt_n.drawPath ( ppath ); } void Sliders_Pad_Style::dbase_single_switch_stem ( QPainter & pnt_n, Sliders_Pad_Data_Group * sp_grp_n ) { double y_top ( _y_top ); if ( sp_grp_n->num_sliders > 1 ) { y_top += _y_mid; } QPainterPath ppath; ppath.moveTo ( _x_mid, y_top ); ppath.lineTo ( _x_mid, _y_bottom ); pnt_n.setBrush ( Qt::NoBrush ); pnt_n.setPen ( stem_pen ); pnt_n.drawPath ( ppath ); } void Sliders_Pad_Style::dbase_single_slider_stem ( QPainter & pnt_n, Sliders_Pad_Data_Group * ) { QPainterPath ppath; ppath.moveTo ( _x_mid, _y_top ); ppath.lineTo ( _x_mid, _y_mid ); pnt_n.setBrush ( Qt::NoBrush ); pnt_n.setPen ( stem_pen ); pnt_n.drawPath ( ppath ); } void Sliders_Pad_Style::dbase_multi_switch_stems ( QPainter & pnt_n, Sliders_Pad_Data_Group * sp_grp_n ) { QPainterPath ppath; const unsigned int num_cols ( sp_grp_n->num_switches ); for ( unsigned int cii=0; cii < num_cols; ++cii ) { const Sliders_Pad_Data_Column * sp_col ( sp_grp_n->columns[cii] ); double cx_mid ( _area_left ); cx_mid += sp_col->col_pos; cx_mid += calc_col_center ( sp_col->col_width, cii, num_cols ); ppath.moveTo ( cx_mid, _y_top ); ppath.lineTo ( cx_mid, _y_bottom ); } pnt_n.setBrush ( Qt::NoBrush ); pnt_n.setPen ( stem_pen ); pnt_n.drawPath ( ppath ); } void Sliders_Pad_Style::dbase_labels_connectors ( QPainter & pnt_n, Sliders_Pad_Data_Group * sp_grp_n ) { if ( sp_data()->show_value_labels ) { QPainterPath ppath; const unsigned int num_cols ( sp_grp_n->num_sliders ); for ( unsigned int cii=0; cii < num_cols; ++cii ) { const Sliders_Pad_Data_Column * sp_col ( sp_grp_n->columns[cii] ); if ( sp_col->show_value_label ) { double cx_mid ( _area_left ); cx_mid += sp_col->col_pos; cx_mid += calc_col_center ( sp_col->col_width, cii, num_cols ); double y_bottom ( _y_bottom ); y_bottom += sp_data()->switches_area_height; ppath.moveTo ( cx_mid, _y_top ); ppath.lineTo ( cx_mid, y_bottom ); } } pnt_n.setBrush ( Qt::NoBrush ); pnt_n.setPen ( stem_pen ); pnt_n.drawPath ( ppath ); } } // Header painting void Sliders_Pad_Style::draw_header ( ) { const unsigned int pic_idx ( 0 ); for ( unsigned int ii=0; ii < sp_data()->groups.size(); ++ii ) { Sliders_Pad_Data_Group * sp_grp ( sp_data()->groups[ii] ); if ( sp_grp->num_sliders > 0 ) { sp_grp->hd_pics[pic_idx] = QPicture(); QPainter pnt ( &sp_grp->hd_pics[pic_idx] ); dheader_stem ( pnt, sp_grp ); if ( sp_grp->num_sliders > 1 ) { dheader_bridge ( pnt, sp_grp ); } } } } void Sliders_Pad_Style::dheader_stem ( QPainter & pnt_n, Sliders_Pad_Data_Group * sp_grp_n ) { QPainterPath ppath; const Sliders_Pad_Header_Data & hdata ( *sp_data()->header_data ); const QFontMetrics & fmet ( sp_data()->header->fontMetrics() ); { const unsigned int hheight ( sp_data()->header_area.height() ); const double fnt_hhalf ( fmet.height() / 2.0 ); const double x_left ( 0.0 ); const double y_bottom ( hheight ); const double y_mid ( ( hheight - hdata.spacing_inter ) + 0.5 ); double stem_height ( hdata.angle_cos * fnt_hhalf ); double stem_bottom; if ( sp_grp_n->num_sliders == 1 ) { stem_height += hdata.spacing_vertical; stem_bottom = y_bottom; } else { stem_height += 0.5; stem_bottom = y_mid; } if ( stem_height > 0.5 ) { double stem_l1 ( stem_height / ( 1.0 + hdata.angle_sin ) ); double stem_dx ( stem_l1 * hdata.angle_cos ); stem_dx = std::floor ( stem_dx ); if ( ( sp_grp_n->group_width % 2 ) == 0 ) { stem_dx += 0.5; } double stem_h2 ( 0.0 ); if ( hdata.angle_cos > 0.002 ) { stem_h2 = stem_dx * hdata.angle_sin / hdata.angle_cos; } double grp_x_mid ( x_left + sp_grp_n->group_pos ); grp_x_mid += double ( sp_grp_n->group_width ) / double ( 2.0 ); double stem_x1 = grp_x_mid - stem_dx; double stem_h1 ( stem_height - stem_h2 ); QPointF pts[3] = { QPointF ( grp_x_mid, stem_bottom - stem_height ), QPointF ( stem_x1, stem_bottom - stem_h1 ), QPointF ( stem_x1, stem_bottom ) }; QPointF pmid[2]; pmid[0] = ( pts[0] * 1.0 + pts[1] * 2.0 ) / 3.0; pmid[1] = ( pts[1] * 2.0 + pts[2] * 1.0 ) / 3.0; ppath.moveTo ( pts[0] ); ppath.lineTo ( pmid[0] ); //ppath.lineTo ( pts[1] ); ppath.lineTo ( pmid[1] ); ppath.lineTo ( pts[2] ); } } pnt_n.setBrush ( Qt::NoBrush ); pnt_n.setPen ( stem_pen ); pnt_n.drawPath ( ppath ); } void Sliders_Pad_Style::dheader_bridge ( QPainter & pnt_n, Sliders_Pad_Data_Group * sp_grp_n ) { if ( sp_grp_n->columns.size() < 2 ) { return; } QPainterPath ppath; { // Acquire bridge path double bheight ( sp_data()->header_data->spacing_inter ); bheight -= 0.5; ppath = inclined_bridge_path ( sp_grp_n, bheight ); } { // Invert and translate const double yoff ( sp_data()->header_area.height() ); const QTransform trans ( 1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, yoff, 1.0 ); ppath = trans.map ( ppath ); } pnt_n.setBrush ( Qt::NoBrush ); pnt_n.setPen ( stem_pen ); pnt_n.drawPath ( ppath ); } // Footer painting void Sliders_Pad_Style::draw_footer ( ) { if ( sp_data()->show_value_labels ) { const unsigned int pic_idx ( 1 ); Sliders_Pad_Header_Data & hdata ( *sp_data()->footer_data ); for ( unsigned int ii=0; ii < hdata.labels.size(); ++ii ) { const Sliders_Pad_Header_Label & lbl ( hdata.labels[ii] ); Sliders_Pad_Data_Group * sp_grp ( sp_data()->groups[lbl.group_idx] ); Sliders_Pad_Data_Column * sp_col ( sp_grp->columns[lbl.column_idx] ); sp_col->hd_pics[pic_idx] = QPicture(); if ( sp_col->show_value_label ) { QPainter pnt ( &sp_col->hd_pics[pic_idx] ); dfooter_stem ( pnt, sp_grp, sp_col ); } } } } void Sliders_Pad_Style::dfooter_stem ( QPainter & pnt_n, Sliders_Pad_Data_Group * sp_grp_n, Sliders_Pad_Data_Column * sp_col_n ) { const Sliders_Pad_Header_Data & hdata ( *sp_data()->footer_data ); QPainterPath ppath_line; QPainterPath ppath_solid; const double fnt_height ( sp_data()->footer->fontMetrics().height() ); const double fheight_yoff ( ::std::abs ( hdata.angle_cos ) * fnt_height / 2.0 ); const double lbl_y_center ( fheight_yoff + hdata.spacing_vertical ); double x_center; if ( hdata.column_labels ) { x_center = sp_col_n->col_pos; x_center += calc_col_center ( sp_col_n->col_width, sp_col_n->col_idx, sp_grp_n->columns.size() ); } else { x_center = sp_grp_n->group_pos; x_center += calc_col_center ( sp_grp_n->group_width, 0, 0 ); } const double rad ( qMin ( fnt_height / 6.0, lbl_y_center ) ); const QTransform rot_trans ( hdata.angle_cos, -hdata.angle_sin, 0.0, hdata.angle_sin, hdata.angle_cos, 0.0, 0.0, 0.0, 1.0 ); { ppath_line.moveTo ( x_center, 0.0 ); ppath_line.lineTo ( x_center, 0.5 ); QPointF pnt ( rot_trans.map ( QPointF ( -rad / 2.0, 0.0 ) ) ); pnt += QPointF ( x_center, lbl_y_center ); ppath_line.lineTo ( pnt ); } ppath_solid.addEllipse ( QPointF ( 0, 0 ), rad, rad ); { QPainterPath ppd; ppd.addRect ( -fnt_height, -fnt_height, fnt_height, 2*fnt_height ); ppath_solid = ppath_solid.intersected ( ppd ); } ppath_solid = rot_trans.map ( ppath_solid ); ppath_solid.translate ( x_center, lbl_y_center ); // Paint pnt_n.setBrush ( Qt::NoBrush ); pnt_n.setPen ( stem_pen ); pnt_n.drawPath ( ppath_line ); pnt_n.setBrush ( stem_pen.color() ); pnt_n.setPen ( Qt::NoPen ); pnt_n.drawPath ( ppath_solid ); } } // End of namespace qastools-v0.22.0/shared/src/wdg/sliders_pad_style.hpp000066400000000000000000000051171354534512100226750ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_sliders_pad_style_hpp__ #define __INC_sliders_pad_style_hpp__ #include #include #include // Forward declaration namespace Wdg { class Sliders_Pad_Style_BData; class Sliders_Pad_Data; class Sliders_Pad_Data_Group; class Sliders_Pad_Data_Column; } namespace Wdg { /// @brief Sliders_Pad_Header /// class Sliders_Pad_Style { // Public methods public: Sliders_Pad_Style ( Sliders_Pad_Data * data_n ); virtual ~Sliders_Pad_Style ( ); Sliders_Pad_Data * sp_data ( ) const; void paint_base_decoration ( ); void paint_header_decoration ( ); void paint_footer_decoration ( ); // Protected methods protected: // Utility double calc_col_center ( unsigned int col_width_n, unsigned int col_idx_n , unsigned int num_cols_n ) const; QPainterPath bridge_path ( Sliders_Pad_Data_Group * sp_grp_n, double y_top_n ) const; QPainterPath inclined_bridge_path ( Sliders_Pad_Data_Group * sp_grp_n, double y_top_n ) const; QPainterPath inclined_multi_bridge_path ( Sliders_Pad_Data_Group * sp_grp_n, double y_top_n ) const; // Base drawing virtual void draw_base ( ); void dbase_sliders_bridge ( QPainter & pnt_n, Sliders_Pad_Data_Group * sp_grp_n ); void dbase_switches_bridge ( QPainter & pnt_n, Sliders_Pad_Data_Group * sp_grp_n ); void dbase_single_slider_stem ( QPainter & pnt_n, Sliders_Pad_Data_Group * sp_grp_n ); void dbase_single_switch_stem ( QPainter & pnt_n, Sliders_Pad_Data_Group * sp_grp_n ); void dbase_multi_switch_stems ( QPainter & pnt_n, Sliders_Pad_Data_Group * sp_grp_n ); void dbase_labels_connectors ( QPainter & pnt_n, Sliders_Pad_Data_Group * sp_grp_n ); // Header drawing virtual void draw_header ( ); void dheader_stem ( QPainter & pnt_n, Sliders_Pad_Data_Group * sp_grp_n ); void dheader_bridge ( QPainter & pnt_n, Sliders_Pad_Data_Group * sp_grp_n ); // Footer drawing virtual void draw_footer ( ); void dfooter_stem ( QPainter & pnt_n, Sliders_Pad_Data_Group * sp_grp_n, Sliders_Pad_Data_Column * sp_col_n ); // Public attributes public: QPen stem_pen; double stem_corner_indent; // Private attributes private: Sliders_Pad_Data * _sp_data; // Painting variables unsigned int _area_left; unsigned int _area_height; unsigned int _y_top; unsigned int _y_bottom; double _x_mid; double _y_mid; }; inline Sliders_Pad_Data * Sliders_Pad_Style::sp_data ( ) const { return _sp_data; } } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/switches_area.cpp000066400000000000000000000060351354534512100220000ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "switches_area.hpp" #include "wdg/switches_pad.hpp" #include "wdg/fill_columns_layout.hpp" #include #include #include namespace Wdg { Switches_Area::Switches_Area ( QWidget * parent_n ) : QScrollArea ( parent_n ) { setHorizontalScrollBarPolicy ( Qt::ScrollBarAlwaysOff ); setWidgetResizable ( true ); } QSize Switches_Area::minimumSizeHint ( ) const { ensurePolished(); if ( widget() == 0 ) { return QScrollArea::minimumSizeHint(); } QSize res ( 0, 0 ); // Height { ::Wdg::Switches_Pad * sw_pad ( dynamic_cast < ::Wdg::Switches_Pad * > ( widget() ) ); const ::Wdg::Fill_Columns_Layout * lay_cols ( dynamic_cast < const ::Wdg::Fill_Columns_Layout * > ( widget()->layout() ) ); { // Number of visible rows unsigned int num_vis ( 4 ); if ( sw_pad != 0 ) { num_vis = sw_pad->num_proxies_groups(); } // Number of minimum visible rows unsigned int min_rows ( 4 ); if ( num_vis < 6 ) { min_rows = 3; } if ( num_vis < 2 ) { min_rows = 2; } res.rheight() += widget()->fontMetrics().height() * min_rows; if ( lay_cols != 0 ) { res.rheight() += lay_cols->vertical_spacing_default() * ( min_rows - 1 ); } } if ( lay_cols != 0 ) { QMargins mgs ( lay_cols->contentsMargins() ); res.rheight() += mgs.top() + mgs.bottom(); } } // Widget width { QSize wdg_msh ( widget()->minimumSizeHint() ); if ( wdg_msh.width() > 0 ) { res.rwidth() += wdg_msh.width(); } } // Scrollbar if ( verticalScrollBar() != 0 ) { QSize sb_msh ( verticalScrollBar()->minimumSizeHint() ); if ( sb_msh.width() <= 0 ) { sb_msh = verticalScrollBar()->sizeHint(); } if ( sb_msh.width() > 0 ) { res.rwidth() += sb_msh.width(); } } // Contents margins { QMargins mgs ( contentsMargins() ); res.rwidth() += mgs.left() + mgs.right(); res.rheight() += mgs.top() + mgs.bottom(); } return res; } QSize Switches_Area::sizeHint ( ) const { return minimumSizeHint(); } void Switches_Area::set_widget ( QWidget * wdg_n ) { if ( widget() != 0 ) { widget()->removeEventFilter ( this ); } setWidget ( wdg_n ); if ( widget() != 0 ) { widget()->installEventFilter ( this ); } updateGeometry(); } QWidget * Switches_Area::take_widget ( ) { if ( widget() != 0 ) { widget()->removeEventFilter ( this ); } return takeWidget(); } void Switches_Area::resizeEvent ( QResizeEvent * event_n ) { if ( widget() != 0 ) { ::Wdg::Switches_Pad * spad ( dynamic_cast < ::Wdg::Switches_Pad * > ( widget() ) ); if ( spad != 0 ) { spad->set_viewport_geometry ( viewport()->contentsRect() ); } } QScrollArea::resizeEvent ( event_n ); } bool Switches_Area::eventFilter ( QObject * watched_n, QEvent * event_n ) { if ( watched_n == widget() ) { if ( event_n->type() == QEvent::LayoutRequest ) { //::std::cout << "Switches_Area::eventFilter: " << event_n->type() << "\n"; updateGeometry(); } } return false; } } // End of namespace qastools-v0.22.0/shared/src/wdg/switches_area.hpp000066400000000000000000000013141354534512100220000ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_switches_scroll_area_hpp__ #define __INC_switches_scroll_area_hpp__ #include #include namespace Wdg { /// @brief Switches_Area /// class Switches_Area : public QScrollArea { // Public methods public: Switches_Area ( QWidget * parent_n = 0 ); QSize minimumSizeHint ( ) const; QSize sizeHint ( ) const; void set_widget ( QWidget * wdg_n ); QWidget * take_widget ( ); // Protected methods protected: void resizeEvent ( QResizeEvent * event_n ); bool eventFilter ( QObject * watched_n, QEvent * event_n ); }; } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/switches_pad.cpp000066400000000000000000000167121354534512100216370ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "switches_pad.hpp" #include "wdg/pad_proxies_group.hpp" #include "wdg/pad_proxies_column.hpp" #include "wdg/pad_proxy_enum.hpp" #include "wdg/pad_proxy_switch.hpp" #include "wdg/switches_pad_widgets_group.hpp" #include "wdg/fill_columns_layout.hpp" #include "wdg/color_methods.hpp" #include "wdg/event_types.hpp" #include "wdg/pass_events.hpp" #include #include #include #include #include #include #include #include namespace Wdg { Switches_Pad::Switches_Pad ( QWidget * parent_n ) : QWidget ( parent_n ) { _stem_pen.setWidth ( 1 ); update_colors(); } Switches_Pad::~Switches_Pad ( ) { clear_proxies_groups(); } void Switches_Pad::set_viewport_geometry ( const QRect & rect_n ) { //::std::cout << "Switches_Pad::set_viewport_geometry\n"; if ( _viewport != rect_n ) { _viewport = rect_n; if ( layout() != 0 ) { ::Wdg::Fill_Columns_Layout * lay_cols ( static_cast < ::Wdg::Fill_Columns_Layout * > ( layout() ) ); lay_cols->set_viewport_geometry ( _viewport ); } } } void Switches_Pad::set_proxies_groups ( const QList < ::Wdg::Pad_Proxies_Group * > & groups_n ) { if ( _proxies_groups.size() > 0 ) { clear_widgets_groups(); } _proxies_groups = groups_n; if ( _proxies_groups.size() > 0 ) { create_widgets_groups(); } } void Switches_Pad::clear_proxies_groups ( ) { if ( _proxies_groups.size() > 0 ) { set_proxies_groups ( QList < ::Wdg::Pad_Proxies_Group * >() ); } } void Switches_Pad::clear_widgets_groups ( ) { if ( layout() != 0 ) { delete layout(); } for ( int ii=0; ii < _proxies_groups.size(); ++ii ) { ::Wdg::Pad_Proxies_Group * grp ( _proxies_groups[ii] ); grp->set_pad ( 0 ); for ( unsigned int jj=0; jj < grp->num_columns(); ++jj ) { ::Wdg::Pad_Proxies_Column * col ( grp->column ( jj ) ); if ( col->switch_proxy() != 0 ) { col->switch_proxy()->set_widget ( 0 ); } if ( col->enum_proxy() != 0 ) { col->enum_proxy()->set_widget ( 0 ); } } } if ( _widgets_groups.size() > 0 ) { for ( int ii=0; ii < _widgets_groups.size(); ++ii ) { delete _widgets_groups[ii]; } _widgets_groups.clear(); } } void Switches_Pad::create_widgets_groups ( ) { //::std::cout << "Mixer_Switches::create_widgets_groups\n"; if ( _proxies_groups.size() == 0 ) { return; } ::Wdg::Fill_Columns_Layout * lay_cols ( new ::Wdg::Fill_Columns_Layout ); lay_cols->setContentsMargins ( 0, 0, 0, 0 ); lay_cols->set_viewport_geometry ( _viewport ); for ( int ii=0; ii < _proxies_groups.size(); ++ii ) { ::Wdg::Pad_Proxies_Group * sppg ( _proxies_groups[ii] ); sppg->set_pad ( this ); sppg->set_group_index ( ii ); QScopedPointer < ::Wdg::Switches_Pad_Widgets_Group > spwg ( new ::Wdg::Switches_Pad_Widgets_Group ); if ( sppg->num_columns() > 1 ) { QLabel * label ( new QLabel ( spwg.data() ) ); label->setText ( sppg->group_name() ); label->setToolTip ( sppg->tool_tip() ); label->setFocusPolicy ( Qt::ClickFocus ); label->setContextMenuPolicy ( Qt::NoContextMenu ); { QFont fnt ( font() ); fnt.setBold ( true ); label->setFont ( fnt ); } label->installEventFilter ( spwg.data() ); spwg->set_label ( label ); spwg->set_stem_pen ( _stem_pen ); } for ( unsigned int jj=0; jj < sppg->num_columns(); ++jj ) { ::Wdg::Pad_Proxies_Column * sppc ( sppg->column ( jj ) ); if ( sppc->has_enum() ) { // Is enumerated ::Wdg::Pad_Proxy_Enum * spp_enum ( sppc->enum_proxy() ); ::Wdg::Switches_Pad_Widgets * spw ( new Switches_Pad_Widgets ); { // Label QLabel * label ( new QLabel ( spwg.data() ) ); label->setText ( spp_enum->item_name() ); label->setToolTip ( spp_enum->tool_tip() ); spw->set_label_wdg ( label ); } { // Combo box // Setup selectable items QComboBox * cbox ( new QComboBox ( spwg.data() ) ); for ( int ee=0; ee < spp_enum->enum_num_items(); ++ee ) { cbox->addItem ( spp_enum->enum_item_name ( ee ) ); } cbox->setCurrentIndex ( spp_enum->enum_index() ); cbox->setToolTip ( spp_enum->tool_tip() ); connect ( cbox, SIGNAL ( currentIndexChanged ( int ) ), spp_enum, SLOT ( set_enum_index ( int ) ) ); connect ( spp_enum, SIGNAL ( sig_enum_index_changed ( int ) ), cbox, SLOT ( setCurrentIndex ( int ) ) ); spw->set_input_wdg ( cbox ); spp_enum->set_widget ( cbox ); } spwg->append_widgets ( spw ); continue; } if ( sppc->has_switch() ) { // Is switch ::Wdg::Pad_Proxy_Switch * spp_switch ( sppc->switch_proxy() ); Switches_Pad_Widgets * spw ( new Switches_Pad_Widgets ); QCheckBox * switch_wdg ( new QCheckBox ( spwg.data() ) ); if ( sppg->num_columns() > 1 ) { switch_wdg->setText ( spp_switch->item_name() ); } else { switch_wdg->setText ( sppg->group_name() ); } switch_wdg->setChecked ( spp_switch->switch_state() ); switch_wdg->setToolTip ( spp_switch->tool_tip() ); switch_wdg->setPalette ( palette() ); connect ( switch_wdg, SIGNAL ( toggled ( bool ) ), spp_switch, SLOT ( set_switch_state ( bool ) ) ); connect ( spp_switch, SIGNAL ( sig_switch_state_changed ( bool ) ), switch_wdg, SLOT ( setChecked ( bool ) ) ); spw->set_input_wdg ( switch_wdg ); spp_switch->set_widget ( switch_wdg ); spwg->append_widgets ( spw ); continue; } } // Append widgets group to the list if ( spwg->num_widgets() > 0 ) { _widgets_groups.append ( spwg.take() ); } } // Append to layout for ( int ii=0; ii < _widgets_groups.size(); ++ii ) { lay_cols->addWidget ( _widgets_groups[ii] ); } setLayout ( lay_cols ); } void Switches_Pad::set_focus_proxy ( unsigned int proxies_group_idx_n ) { set_focus_proxy ( proxies_group_idx_n, 0 ); } void Switches_Pad::set_focus_proxy ( unsigned int proxies_group_idx_n, unsigned int proxy_idx_n ) { const unsigned int num_groups ( _widgets_groups.size() ); if ( proxies_group_idx_n < num_groups ) { ::Wdg::Switches_Pad_Widgets_Group * spwg ( _widgets_groups[ proxies_group_idx_n ] ); QWidget * wdg ( 0 ); // Select the slider of given widget set if ( proxy_idx_n < spwg->num_widgets() ) { wdg = spwg->widgets ( proxy_idx_n )->input_wdg(); } // No widget found so far - Take first slider then if ( wdg == 0 ) { for ( unsigned int ii=0; ii < spwg->num_widgets(); ++ii ) { ::Wdg::Switches_Pad_Widgets * spw ( spwg->widgets ( ii ) ); if ( spw->input_wdg() != 0 ) { wdg = spw->input_wdg(); break; } } } if ( wdg != 0 ) { wdg->setFocus(); } } } void Switches_Pad::update_colors ( ) { { QPalette pal ( palette() ); const QColor col_bg ( pal.color ( QPalette::Button ) ); const QColor col_fg ( pal.color ( QPalette::ButtonText ) ); QColor col = ::Wdg::col_mix ( col_bg, col_fg, 1, 1 ); _stem_pen.setColor ( col ); } } bool Switches_Pad::event ( QEvent * event_n ) { if ( event_n->type() == ::Wdg::evt_pass_event_focus ) { ::Wdg::Pass_Event_Focus * ev_fp ( static_cast < ::Wdg::Pass_Event_Focus * > ( event_n ) ); _focus_info.clear(); if ( ev_fp->ev_focus.gotFocus() && ( ev_fp->group_idx < num_proxies_groups() ) ) { _focus_info.has_focus = true; _focus_info.group_idx = ev_fp->group_idx; _focus_info.column_idx = ev_fp->column_idx; } emit sig_focus_changed(); return true; } return QWidget::event ( event_n ); } } // End of namespace qastools-v0.22.0/shared/src/wdg/switches_pad.hpp000066400000000000000000000042171354534512100216410ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_wdg_switches_pad_hpp__ #define __INC_wdg_switches_pad_hpp__ #include #include #include #include "wdg/pad_focus_info.hpp" // Forward declaration namespace Wdg { class Pad_Proxies_Group; class Switches_Pad_Widgets_Group; } namespace Wdg { /// @brief Switches_Pad /// class Switches_Pad : public QWidget { Q_OBJECT // Public methods public: Switches_Pad ( QWidget * parent_n = 0 ); ~Switches_Pad ( ); void set_viewport_geometry ( const QRect & rect_n ); // Proxies groups const QList < ::Wdg::Pad_Proxies_Group * > & proxies_groups ( ) const; void set_proxies_groups ( const QList < ::Wdg::Pad_Proxies_Group * > & groups_n ); void clear_proxies_groups ( ); // Proxies groups access unsigned int num_proxies_groups ( ) const; ::Wdg::Pad_Proxies_Group * proxies_group ( unsigned int idx_n ); // Focus item getting / setting const ::Wdg::Pad_Focus_Info & focus_info ( ); // Event handling bool event ( QEvent * event_n ); // Public slots public slots: void set_focus_proxy ( unsigned int proxies_group_idx_n ); void set_focus_proxy ( unsigned int proxies_group_idx_n, unsigned int proxy_idx_n ); // Public signals signals: void sig_focus_changed ( ); // Protected methods protected: void clear_widgets_groups ( ); void create_widgets_groups ( ); void update_colors(); // Private attributes private: QList < ::Wdg::Pad_Proxies_Group * > _proxies_groups; QList < ::Wdg::Switches_Pad_Widgets_Group * > _widgets_groups; QRect _viewport; Pad_Focus_Info _focus_info; QPen _stem_pen; }; inline const QList < ::Wdg::Pad_Proxies_Group * > & Switches_Pad::proxies_groups ( ) const { return _proxies_groups; } inline ::Wdg::Pad_Proxies_Group * Switches_Pad::proxies_group ( unsigned int idx_n ) { return _proxies_groups[idx_n]; } inline unsigned int Switches_Pad::num_proxies_groups ( ) const { return _proxies_groups.size(); } inline const Pad_Focus_Info & Switches_Pad::focus_info ( ) { return _focus_info; } } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/switches_pad_widgets.cpp000066400000000000000000000010731354534512100233570ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "switches_pad_widgets.hpp" namespace Wdg { Switches_Pad_Widgets::Switches_Pad_Widgets ( ) { } Switches_Pad_Widgets::~Switches_Pad_Widgets ( ) { clear_widgets(); } void Switches_Pad_Widgets::clear_widgets ( ) { _label.reset(); _input.reset(); } void Switches_Pad_Widgets::set_input_wdg ( QWidget * wdg_n ) { _input.reset ( wdg_n ); } void Switches_Pad_Widgets::set_label_wdg ( QLabel * wdg_n ) { _label.reset ( wdg_n ); } } // End of namespace qastools-v0.22.0/shared/src/wdg/switches_pad_widgets.hpp000066400000000000000000000016431354534512100233670ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_switches_pad_widgets_hpp__ #define __INC_switches_pad_widgets_hpp__ #include #include #include namespace Wdg { /// @brief Switches_Pad_Widgets /// class Switches_Pad_Widgets { // Public methods public: Switches_Pad_Widgets ( ); ~Switches_Pad_Widgets ( ); void clear_widgets ( ); // Input widget void set_input_wdg ( QWidget * wdg_n ); QWidget * input_wdg ( ); // Label widget QLabel * label_wdg ( ); void set_label_wdg ( QLabel * wdg_n ); // Private attributes private: QScopedPointer < QLabel > _label; QScopedPointer < QWidget > _input; }; inline QWidget * Switches_Pad_Widgets::input_wdg ( ) { return _input.data(); } inline QLabel * Switches_Pad_Widgets::label_wdg ( ) { return _label.data(); } } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/switches_pad_widgets_group.cpp000066400000000000000000000074111354534512100245750ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "switches_pad_widgets_group.hpp" #include #include #include #include namespace Wdg { Switches_Pad_Widgets_Group::Switches_Pad_Widgets_Group ( QWidget * parent_n ) : QWidget ( parent_n ), _label ( 0 ), _lay_grid ( 0 ) { setContextMenuPolicy ( Qt::NoContextMenu ); _stem_pen.setWidth ( 1 ); QVBoxLayout * lay_vbox ( new QVBoxLayout ); lay_vbox->setContentsMargins ( 0, 0, 0, 0 ); setLayout ( lay_vbox ); } Switches_Pad_Widgets_Group::~Switches_Pad_Widgets_Group ( ) { clear_widgets(); } void Switches_Pad_Widgets_Group::clear_widgets ( ) { if ( _widgets.size() > 0 ) { for ( int ii=0; ii < _widgets.size(); ++ ii ) { delete _widgets[ii]; } _widgets.clear(); } if ( _label != 0 ) { delete _label; _label = 0; } if ( _lay_grid != 0 ) { delete _lay_grid; _lay_grid = 0; } } void Switches_Pad_Widgets_Group::set_label ( QLabel * wdg_n ) { if ( _label != 0 ) { delete _label; } _label = wdg_n; if ( _label != 0 ) { if ( _lay_grid == 0 ) { _lay_grid = new QGridLayout; _lay_grid->setContentsMargins ( enum_spacing()*2, 0, 0, 0 ); _lay_grid->setHorizontalSpacing ( enum_spacing() ); } lay_vbox()->addWidget ( _label ); lay_vbox()->addLayout ( _lay_grid ); } else { if ( _lay_grid != 0 ) { delete _lay_grid; _lay_grid = 0; } } } void Switches_Pad_Widgets_Group::append_widgets ( Switches_Pad_Widgets * spw_n ) { if ( spw_n == 0 ) { return; } if ( spw_n->input_wdg() == 0 ) { return; } if ( _lay_grid != 0 ) { // Multiple input widgets const unsigned int row ( _widgets.size() ); if ( spw_n->label_wdg() != 0 ) { // Input widget with separate label _lay_grid->addWidget ( spw_n->input_wdg(), row, 0 ); _lay_grid->addWidget ( spw_n->label_wdg(), row, 1 ); } else { // Single input widget _lay_grid->addWidget ( spw_n->input_wdg(), row, 0 ); } } else { // Single input widget if ( spw_n->label_wdg() != 0 ) { // Input widget with separate label QHBoxLayout * lay_hbox ( new QHBoxLayout ); lay_hbox->setContentsMargins ( 0, 0, 0, 0 ); lay_hbox->setSpacing ( enum_spacing() ); lay_hbox->addWidget ( spw_n->input_wdg() ); lay_hbox->addWidget ( spw_n->label_wdg() ); lay_vbox()->addLayout ( lay_hbox ); } else { // Single input widget lay_vbox()->addWidget ( spw_n->input_wdg() ); } } _widgets.append ( spw_n ); } int Switches_Pad_Widgets_Group::enum_spacing ( ) const { return fontMetrics().averageCharWidth() * 4 / 3; } bool Switches_Pad_Widgets_Group::eventFilter ( QObject * watched_n, QEvent * event_n ) { bool res ( false ); if ( ( watched_n == _label ) && ( _label != 0 ) ) { if ( event_n->type() == QEvent::FocusIn ) { if ( _widgets.size() > 0 ) { _widgets[0]->input_wdg()->setFocus(); res = true; } } } return res; } void Switches_Pad_Widgets_Group::paintEvent ( QPaintEvent * event_n ) { QWidget::paintEvent ( event_n ); if ( ( _lay_grid != 0 ) && ( _label != 0 ) && ( num_widgets() > 0 ) ) { QRect re_lbl ( _label->geometry() ); QRect re_wdg ( _lay_grid->itemAt ( 0 )->geometry() ); int x0 = ( re_lbl.x() * 4 + re_wdg.x() * 3 ) / 7; int x1 = re_wdg.x() - 3; if ( !re_lbl.isValid() || !re_wdg.isValid() || ( x1 <= x0 ) ) { return; } int y0 = re_lbl.y() + re_lbl.height(); int y1 = y0; QPainter pnt ( this ); pnt.setBrush ( Qt::NoBrush ); pnt.setPen ( _stem_pen ); for ( unsigned int ii=0; ii < num_widgets(); ++ii ) { re_wdg = _lay_grid->itemAt ( ii )->geometry(); int yy ( re_wdg.y() + ( re_wdg.height() + 1 ) / 2 ); if ( y1 < yy ) { y1 = yy; } pnt.drawLine ( x0, yy, x1, yy ); } pnt.drawLine ( x0, y0, x0, y1 ); } } } // End of namespace qastools-v0.22.0/shared/src/wdg/switches_pad_widgets_group.hpp000066400000000000000000000043221354534512100246000ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_switches_pad_widgets_group_hpp__ #define __INC_switches_pad_widgets_group_hpp__ #include #include #include #include #include #include #include "wdg/switches_pad_widgets.hpp" #include "wdg/pad_proxies_group.hpp" namespace Wdg { /// @brief Switches_Pad_Widgets_Group /// class Switches_Pad_Widgets_Group : public QWidget { // Public typedefs public: typedef QList < ::Wdg::Switches_Pad_Widgets * > Widgets_List; // Public methods public: Switches_Pad_Widgets_Group ( QWidget * parent_n = 0 ); ~Switches_Pad_Widgets_Group ( ); void clear_widgets ( ); // Label QLabel * label ( ); void set_label ( QLabel * wdg_n ); // Widgets list unsigned int num_widgets ( ) const; void append_widgets ( ::Wdg::Switches_Pad_Widgets * wdgs_n ); const Switches_Pad_Widgets * widgets ( int idx_n ) const; ::Wdg::Switches_Pad_Widgets * widgets ( int idx_n ); // Stem pen void set_stem_pen ( const QPen & pen_n ); // Protected methods private: QVBoxLayout * lay_vbox ( ); int enum_spacing ( ) const; // Event handling bool eventFilter ( QObject * watched_n, QEvent * event_n ); void paintEvent ( QPaintEvent * event_n ); // Private attributes private: Widgets_List _widgets; QLabel * _label; QGridLayout * _lay_grid; QPen _stem_pen; }; inline QLabel * Switches_Pad_Widgets_Group::label ( ) { return _label; } inline unsigned int Switches_Pad_Widgets_Group::num_widgets ( ) const { return _widgets.size(); } inline const ::Wdg::Switches_Pad_Widgets * Switches_Pad_Widgets_Group::widgets ( int idx_n ) const { return _widgets[idx_n]; } inline ::Wdg::Switches_Pad_Widgets * Switches_Pad_Widgets_Group::widgets ( int idx_n ) { return _widgets[idx_n]; } inline QVBoxLayout * Switches_Pad_Widgets_Group::lay_vbox ( ) { return static_cast < QVBoxLayout * > ( layout() ); } inline void Switches_Pad_Widgets_Group::set_stem_pen ( const QPen & pen_n ) { _stem_pen = pen_n; } typedef QList < ::Wdg::Switches_Pad_Widgets_Group * > Switches_Pad_Widgets_Group_List; } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/text_browser.cpp000066400000000000000000000023151354534512100217030ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "text_browser.hpp" #include namespace Wdg { Text_Browser::Text_Browser ( QWidget * parent ) : QTextBrowser ( parent ) { } void Text_Browser::setPlainText ( const QString & txt_n ) { QTextBrowser::setPlainText ( txt_n ); update_size_hint(); } void Text_Browser::setHtml ( const QString & txt_n ) { QTextBrowser::setHtml ( txt_n ); update_size_hint(); } QSize Text_Browser::sizeHint ( ) const { const QSize shint ( _hint_width, _hint_height ); return shint; } void Text_Browser::update_size_hint ( ) { const int max_width ( 800 ); // Adjust main root frame padding QTextFrame * rf ( document()->rootFrame() ); { QTextFrameFormat fformat ( rf->frameFormat() ); fformat.setPadding ( fontMetrics().averageCharWidth() * 4 / 3 ); rf->setFrameFormat ( fformat ); } document()->adjustSize(); _hint_width = document()->size().width() + 0.5; _hint_width += verticalScrollBar()->sizeHint().width(); _hint_width += 2*frameWidth(); if ( _hint_width > max_width ) { _hint_width = max_width; } _hint_height = ( _hint_width * 2 ) / 3; updateGeometry(); } } // End of namespace qastools-v0.22.0/shared/src/wdg/text_browser.hpp000066400000000000000000000012551354534512100217120ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_text_browser_hpp__ #define __INC_text_browser_hpp__ #include #include #include #include namespace Wdg { class Text_Browser : public QTextBrowser { // Public methods public: Text_Browser ( QWidget * parent = 0 ); void setPlainText ( const QString & txt_n ); void setHtml ( const QString & txt_n ); QSize sizeHint ( ) const; // Protected methods protected: void update_size_hint ( ); // Private attributes private: int _hint_width; int _hint_height; }; } // Enf of namespace #endif qastools-v0.22.0/shared/src/wdg/tree_view_kv.cpp000066400000000000000000000041171354534512100216470ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "tree_view_kv.hpp" #include #include #include #include namespace Wdg { Tree_View_KV::Tree_View_KV ( QWidget * parent ) : QTreeView ( parent ), _activate_current ( true ) { header()->setSectionResizeMode ( QHeaderView::Interactive ); } void Tree_View_KV::setModel ( QAbstractItemModel * model_n ) { QTreeView::setModel ( model_n ); QFontMetrics fmet ( fontMetrics() ); const int mss ( 3*indentation() + fmet.averageCharWidth() * 8 ); header()->setMinimumSectionSize ( mss ); header()->resizeSection ( 0, mss ); } void Tree_View_KV::set_activate_current ( bool flag_n ) { _activate_current = flag_n; } void Tree_View_KV::set_expanded_recursive ( const QModelIndex & index_n, int depth_n, bool expanded_n ) { setExpanded ( index_n, expanded_n ); if ( depth_n > 0 ) { const int rows ( model()->rowCount ( index_n ) ); for ( int ii=0; ii < rows; ++ii ) { const QModelIndex mi ( model()->index ( ii, 0, index_n ) ); set_expanded_recursive ( mi, depth_n - 1, expanded_n ); } } else { collapse ( index_n ); } } void Tree_View_KV::expand_recursive ( const QModelIndex & index_n, int depth_n ) { set_expanded_recursive ( index_n, depth_n, true ); } void Tree_View_KV::collapse_recursive ( const QModelIndex & index_n, int depth_n ) { set_expanded_recursive ( index_n, depth_n, false ); } void Tree_View_KV::adjust_first_column_width ( ) { int hspace_free ( contentsRect().width() ); if ( verticalScrollBar() != 0 ) { if ( verticalScrollBar()->isVisible() ) { hspace_free -= verticalScrollBar()->width(); } } QFontMetrics fm ( fontMetrics() ); int ww = sizeHintForColumn ( 0 ) + fm.averageCharWidth(); if ( ww < hspace_free ) { header()->resizeSection ( 0, ww ); } } void Tree_View_KV::currentChanged ( const QModelIndex & current, const QModelIndex & previous ) { QTreeView::currentChanged ( current, previous ); if ( _activate_current ) { emit activated ( current ); } } } // End of namespace qastools-v0.22.0/shared/src/wdg/tree_view_kv.hpp000066400000000000000000000022021354534512100216450ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_tree_view_kv_hpp__ #define __INC_tree_view_kv_hpp__ #include namespace Wdg { /// /// @brief Tree_View_KV /// class Tree_View_KV : public QTreeView { Q_OBJECT // Public methods public: Tree_View_KV ( QWidget * parent = 0 ); void setModel ( QAbstractItemModel * model_n ); // Activate current bool activate_current ( ) const; void set_activate_current ( bool flag_n ); // Public slots public slots: void set_expanded_recursive ( const QModelIndex & index_n, int depth_n, bool expanded_n ); void expand_recursive ( const QModelIndex & index_n, int depth_n ); void collapse_recursive ( const QModelIndex & index_n, int depth_n ); void adjust_first_column_width ( ); // Protected methods protected: void currentChanged ( const QModelIndex & current, const QModelIndex & previous ); // Private attributes private: bool _activate_current; }; inline bool Tree_View_KV::activate_current ( ) const { return _activate_current; } } // End of namespace #endif qastools-v0.22.0/shared/src/wdg/uint_mapper.cpp000066400000000000000000000077571354534512100215160ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #include "uint_mapper.hpp" #include namespace Wdg { // // Utility functions // unsigned int integer_distance ( int int_min_n, int int_max_n ) { unsigned int res ( 0 ); if ( int_min_n > int_max_n ) { int tmp = int_max_n; int_max_n = int_min_n; int_min_n = tmp; } if ( ( int_min_n >= 0 ) || ( int_max_n < 0 ) ) { // No integer overflow possible res = int ( int_max_n - int_min_n ); } else { // Integer overflow possible res = int_max_n; ++int_min_n; res += int ( -int_min_n ); ++res; } return res; } unsigned long integer_distance ( long int_min_n, long int_max_n ) { unsigned long res; if ( int_min_n > int_max_n ) { long tmp = int_max_n; int_max_n = int_min_n; int_min_n = tmp; } if ( ( int_min_n > 0 ) || ( int_max_n < 0 ) ) { // No integer overflow possible res = long ( int_max_n - int_min_n ); } else { // Integer overflow possible res = int_max_n; ++int_min_n; res += long ( -int_min_n ); ++res; } return res; } unsigned int permille ( unsigned long current_n, unsigned long total_n ) { unsigned int res; if ( total_n > 16000 ) { res = current_n / ( total_n / 1000 ); } else { res = ( current_n * 1000 ) / total_n; } return res; } UInt_Mapper::~UInt_Mapper ( ) { } // // UInt_Mapper_Down // UInt_Mapper_Down::UInt_Mapper_Down ( unsigned long max_idx_fine, unsigned long max_idx_coarse ) : _max_idx_fine ( max_idx_fine ), _max_idx_coarse ( max_idx_coarse ), _dist_small ( 0 ), _dist_large ( 0 ), _len_mod ( 0 ) { if ( _max_idx_coarse > 0 ) { _dist_small = _max_idx_fine / _max_idx_coarse; _dist_large = _dist_small; _len_mod = _max_idx_fine % _max_idx_coarse; if ( _len_mod > 0 ) { ++_dist_large; } } _mid_pos = _len_mod * _dist_large; } unsigned long UInt_Mapper_Down::map ( unsigned long val_n ) const { unsigned long res ( 0 ); if ( _dist_small > 0 ) { unsigned long res_mod; unsigned long mod_lim; if ( val_n <= _mid_pos ) { res = val_n / _dist_large; res_mod = val_n % _dist_large; mod_lim = _dist_large / 2; } else { val_n -= _mid_pos; res = _len_mod; res += val_n / _dist_small; res_mod = val_n % _dist_small ; mod_lim = _dist_small / 2; } if ( res_mod > mod_lim ) { ++res; } } return res; } // // UInt_Mapper_Up // UInt_Mapper_Up::UInt_Mapper_Up ( unsigned long max_idx_coarse, unsigned long max_idx_fine ) : _max_idx_coarse ( max_idx_coarse ), _max_idx_fine ( max_idx_fine ), _len_div ( 0 ), _len_mod ( 0 ) { if ( max_idx_coarse > 0 ) { _len_div = _max_idx_fine / _max_idx_coarse; _len_mod = _max_idx_fine % _max_idx_coarse; } } unsigned long UInt_Mapper_Up::map ( unsigned long val_n ) const { unsigned long res ( val_n * _len_div ); if ( val_n >= _len_mod ) { res += _len_mod; } else { res += val_n; } return res; } // // UInt_Mapper_Auto // UInt_Mapper_Auto::UInt_Mapper_Auto ( unsigned long max_idx_1_n, unsigned long max_idx_2_n ) : _max_idx_1 ( 0 ), _max_idx_2 ( 0 ) { set_max_idx_all ( max_idx_1_n, max_idx_2_n ); } void UInt_Mapper_Auto::set_max_idx_all ( unsigned long max_idx_1_n, unsigned long max_idx_2_n ) { _max_idx_1 = max_idx_1_n; _max_idx_2 = max_idx_2_n; unsigned long lfine; unsigned long lcoarse; if ( max_idx_1() > max_idx_2() ) { lfine = max_idx_1(); lcoarse = max_idx_2(); } else { lfine = max_idx_2(); lcoarse = max_idx_1(); } _mapper_down = UInt_Mapper_Down ( lfine, lcoarse ); _mapper_up = UInt_Mapper_Up ( lcoarse, lfine ); } unsigned long UInt_Mapper_Auto::v1_to_v2 ( unsigned long val_n ) const { unsigned long res; if ( max_idx_1() > max_idx_2() ) { res = _mapper_down.map ( val_n ); } else { res = _mapper_up.map ( val_n ); } return res; } unsigned long UInt_Mapper_Auto::v2_to_v1 ( unsigned long val_n ) const { unsigned long res; if ( max_idx_1() > max_idx_2() ) { res = _mapper_up.map ( val_n ); } else { res = _mapper_down.map ( val_n ); } return res; } } // End of namespace qastools-v0.22.0/shared/src/wdg/uint_mapper.hpp000066400000000000000000000054531354534512100215120ustar00rootroot00000000000000/// QasTools: Desktop toolset for the Linux sound system ALSA. /// \copyright See COPYING file. #ifndef __INC_wdg_uint_mapper_hpp__ #define __INC_wdg_uint_mapper_hpp__ namespace Wdg { /// /// @return The distance between the values as unsigned int /// unsigned int integer_distance ( int int_min_n, int int_max_n ); unsigned long integer_distance ( long int_min_n, long int_max_n ); unsigned int permille ( unsigned long current_n, unsigned long total_n ); /// /// @brief ulong to ulong span mapper interface definition class /// class UInt_Mapper { // Public methods public: virtual ~UInt_Mapper ( ); virtual unsigned long map ( unsigned long val_n ) const = 0; }; /// /// @brief Maps down to a coarser range /// class UInt_Mapper_Down : public UInt_Mapper { // Public methods public: /// /// @param max_idx_fine The maximum index of the fine ladder (num_steps - 1). /// @param max_idx_coarse The maximum index of the coarse ladder (num_steps - 1). UInt_Mapper_Down ( unsigned long max_idx_fine = 1, unsigned long max_idx_coarse = 1 ); unsigned long map ( unsigned long val_n ) const; // Private attributes private: unsigned long _max_idx_fine; unsigned long _max_idx_coarse; unsigned long _dist_small; unsigned long _dist_large; unsigned long _len_mod; unsigned long _mid_pos; }; /// /// @brief Maps up to a finer range /// class UInt_Mapper_Up : public UInt_Mapper { // Public methods public: /// /// @param max_idx_coarse The maximum index of the coarse ladder (num_steps - 1). /// @param max_idx_fine The maximum index of the fine ladder (num_steps - 1). UInt_Mapper_Up ( unsigned long max_idx_coarse = 1, unsigned long max_idx_fine = 1 ); unsigned long map ( unsigned long val_n ) const; unsigned long min_dist ( ) const; // Private attributes private: unsigned long _max_idx_coarse; unsigned long _max_idx_fine; unsigned long _len_div; unsigned long _len_mod; }; inline unsigned long UInt_Mapper_Up::min_dist ( ) const { return _len_div; } class UInt_Mapper_Auto { // Public methods public: UInt_Mapper_Auto ( unsigned long max_idx_1_n = 0, unsigned long max_idx_2_n = 0 ); unsigned long max_idx_1 ( ) const; unsigned long max_idx_2 ( ) const; void set_max_idx_all ( unsigned long max_idx_1_n, unsigned long max_idx_2_n ); unsigned long v1_to_v2 ( unsigned long val_n ) const; unsigned long v2_to_v1 ( unsigned long val_n ) const; // Protected methods protected: // Private attributes private: unsigned long _max_idx_1; unsigned long _max_idx_2; UInt_Mapper_Up _mapper_up; UInt_Mapper_Down _mapper_down; }; inline unsigned long UInt_Mapper_Auto::max_idx_1 ( ) const { return _max_idx_1; } inline unsigned long UInt_Mapper_Auto::max_idx_2 ( ) const { return _max_idx_2; } } // End of namespace #endif