diff --git a/LICENSES b/LICENSES index 957e47e8..e4835cc5 100644 --- a/LICENSES +++ b/LICENSES @@ -1,880 +1,875 @@ here the results of a licensing investigation (first done 2007-06-17) LIST OF LICENSES FOUND IN THE SOURCES ===================================== * GPL2 - GNU General Public License, version 2 or newer (abbreviated as GPL2+) - kwave, libgui, libkwave and many others... => this currently is the Kwave "default" license ! => the intention of the authors is to keep Kwave under the GPL2+ * LGPL2 - GNU Library General Public License, version 2 or newer - some icons * Creative Commons Attribution-Share Alike 3.0 License or the GNU Library General Public License 3.0 - Oxygen icons * Creative Commons Attribution-Share Alike 4.0 (CC BY-SA 4.0) http://creativecommons.org/licenses/by-sa/4.0/ - audio samples in samples/... * Creative Commons Zero v1.0 Universal (CC0-1.0) - kwave/kwave.appdata.xml * Kitware (cmake) - cmake/Copyright.txt * FDL - Free Documentation License - documentation in doc - screenshots * BSD - cmake/COPYING-CMAKE-SCRIPTS BSD (3 clause) - plugins/codec_ogg/OpusEncoder.cpp BSD (3 clause) DIRECTLY USED EXTERNAL LIBRARIES ================================ * Qt-5 GPL2 or GPL3 * KDE frameworks 5 LGPL2 * FFTW-3.x GPL2+ * audiofile-0.2.6 LGPL2+ / GPL2+ * id3lib-3.8.3 LGPL2.1 * mad-0.15.1b GPL2+ <= possible patent issue !!! * ogg-1.1.3 ~BSD style * flac-1.2.1 Xiph.Org's BSD-like + GPL2 + LGPL2 * alsa-lib-1.0.16 LGPL2.1 * OSS-3.8 GPL2, CDDL, BSD * libstdc++-v3.3.6 LGPL2.1 * glibc-2.6.1 LGPL2 * libsamplerate-0.1.4 GPL2+ * pulseaudio-4.0 LGPL2.1+ LICENSE ISSUES ============== issue #1: license of the icons ------------------------------ -> maybe most are LGPL, but might depend from case to case !!! (the icons listed here are composed of one or more icons from KDE and/or modified) # doc/en/audio-1.png ??? UNKNOWN ??? -> kdeclassic/32x32/apps/kblackbox.png + kdeclassic/64x64/mimetypes/binary2.png + kdeclassic/32x32/apps/kmix.png + kdeclassic/32x32/actions/forward.png + ??? + ??? # doc/en/audio2signal.png ??? UNKNOWN ??? -> kdeclassic/32x32/apps/kmix.png + kdeclassic/32x32/actions/forward.png + ??? + ??? # doc/en/nonlinear.png ??? UNKNOWN ??? (arrow only) -> arrow is from kdeclassic/32x32/actions/forward.png issue #2: license of some files is unknown or problematic / author known ------------------------------------------------------------------------ - currently none - issue #3: some files have neither license nor author ---------------------------------------------------- - currently none - COMPLETE LIST OF FILES AND THEIR LICENSE ======================================== AUTHORS GPL2+ CHANGES (should be GPL2+) CMakeLists.txt BSD (3 clause) config.h.cmake GPL2+ doxy.cfg.in GPL2+ ExtraDesktop.sh GPL2+ GNU-LICENSE free kwave.ebuild.in GPL2+ / Gentoo kwave.kdev4 GPL2+ kwave.spec.in GPL2+ LICENSES GPL2+ Messages.sh GPL2+ README GPL2+ TODO GPL2+ .krazy GPL2+ bin/import-screenshots.sh GPL2+ bin/make-specfile-changelog.pl GPL2+ bin/menusconfig2pot.pl GPL2+ bin/msgstats.pl GPL2+ bin/svn-update-l10n.sh GPL2+ bin/update-command-xref.pl GPL2+ bin/update-fileinfo-xref.pl GPL2+ bin/update-plugin-xref.pl GPL2+ cmake/CheckIncludeFilesCXX.cmake BSD (3 clause) cmake/COPYING-CMAKE-SCRIPTS BSD (3 clause) cmake/Copyright.txt Kitware (cmake) cmake/FindRequiredProgram.cmake BSD (3 clause) cmake/KwaveALSASupport.cmake BSD (3 clause) cmake/KwaveDEBSupport.cmake BSD (3 clause) cmake/KwaveEbuild.cmake BSD (3 clause) cmake/KwaveHandbook.cmake BSD (3 clause) cmake/KwaveL10N.cmake BSD (3 clause) cmake/KwaveLibaudiofileSupport.cmake BSD (3 clause) cmake/KwaveLibsamplerateSupport.cmake BSD (3 clause) cmake/KwaveOSSSupport.cmake BSD (3 clause) cmake/KwavePulseAudioSupport.cmake BSD (3 clause) cmake/KwaveRPMSupport.cmake BSD (3 clause) cmake/KwaveSysinfo.cmake BSD (3 clause) cmake/uninstall.cmake.in BSD (3 clause) doc/CMakeLists.txt BSD (3 clause) doc/fix-common GPL2+ doc/en/CMakeLists.txt BSD (3 clause) doc/en/README.translators.txt GPL2+ # doc/en/audio-1.png ??? UNKNOWN ??? # doc/en/audio2signal.png ??? UNKNOWN ??? doc/en/krec_record.png LGPL2 (crystal project) [copied from mix_record.png] doc/en/kwave-edit-label.png (should be FDL) doc/en/kwave-gui-mdi.png (should be FDL) doc/en/kwave-gui-sdi.png (should be FDL) doc/en/kwave-gui-tab.png (should be FDL) doc/en/kwave-main.png (should be FDL) doc/en/kwave-plugin-about.png (should be FDL) doc/en/kwave-plugin-amplifyfree.png (should be FDL) doc/en/kwave-plugin-band_pass.png (should be FDL) doc/en/kwave-plugin-codec_mp3.png (should be FDL) doc/en/kwave-plugin-fileinfo.png (should be FDL) doc/en/kwave-plugin-goto.png (should be FDL) doc/en/kwave-plugin-insert_at.png (should be FDL) doc/en/kwave-plugin-lowpass.png (should be FDL) doc/en/kwave-plugin-memory.png (should be FDL) doc/en/kwave-plugin-newsignal.png (should be FDL) doc/en/kwave-plugin-noise.png (should be FDL) doc/en/kwave-plugin-notch_filter.png (should be FDL) doc/en/kwave-plugin-pitch_shift.png (should be FDL) doc/en/kwave-plugin-playback.png (should be FDL) doc/en/kwave-plugin-record.png (should be FDL) doc/en/kwave-plugin-saveblocks.png (should be FDL) doc/en/kwave-plugin-selectrange.png (should be FDL) doc/en/kwave-plugin-sonagram-setup.png (should be FDL) doc/en/kwave-plugin-sonagram-window.png (should be FDL) doc/en/kwave-plugin-stringenter.png (should be FDL) doc/en/kwave-plugin-volume.png (should be FDL) doc/en/light_off.png LGPL2 (crystal project) [derived from greenled.png] doc/en/light_on.png LGPL2 (crystal project) [derived from greenled.png] # doc/en/nonlinear.png ??? UNKNOWN ??? (arrow only) doc/en/record_new.png LGPL2 (crystal project) [copied from document-new.png] doc/en/record_pause.png (should be FDL) doc/en/record_stop.png (should be FDL) doc/en/signal2digital.png (should be FDL) doc/en/signed.png (should be FDL) doc/en/sinus2samples.png (should be FDL) doc/en/under-construction.png LGPL2 (crystal project) [copied from Service\ Manager.png] doc/en/unsigned.png (should be FDL) kwave/CMakeLists.txt BSD (3 clause) kwave/App.cpp GPL2+ kwave/App.h GPL2+ kwave/FileContext.cpp GPL2+ kwave/FileContext.h GPL2+ kwave/kwave.appdata.xml CC0-1.0 kwave/main.cpp GPL2+ / Martin Wilz kwave/MainWidget.cpp GPL2+ / Martin Wilz kwave/MainWidget.h GPL2+ / Martin Wilz kwave/menus.config GPL2+ kwave/org.kde.kwave.desktop.in (should be GPL2+) kwave/ShortcutWrapper.cpp GPL2+ kwave/ShortcutWrapper.h GPL2+ kwave/Splash.cpp GPL2+ / Gilles Caulier kwave/Splash.h GPL2+ / Gilles Caulier kwave/PlayerToolBar.cpp GPL2+ kwave/PlayerToolBar.h GPL2+ kwave/TopWidget.cpp GPL2+ / Martin Wilz kwave/TopWidget.h GPL2+ / Martin Wilz kwave/ZoomToolBar.cpp GPL2+ kwave/ZoomToolBar.h GPL2+ kwave/pics/amplify_free.png (should be GPL2+) kwave/pics/fade_in.png (should be GPL2+) kwave/pics/fade_out.png (should be GPL2+) kwave/pics/knob.xpm LGPL2 (crystal project) [derived from greenled.png] kwave/pics/kwave-splash.png (should be GPL2+ / Thomas Eschenbacher) kwave/pics/kwave.svgz (should be GPL2+ / Thomas Eschenbacher) - kwave/pics/krec_record.xpm LGPL2 (crystal project) [converted from mix_record.png] kwave/pics/light_off.xpm LGPL2 (crystal project) [derived from greenled.png] kwave/pics/light_on.xpm LGPL2 (crystal project) [copied from greenled.png] kwave/pics/logo.xpm (should be GPL2+ / Martin Wilz) kwave/pics/noise.png (should be GPL2+) kwave/pics/selectedknob.xpm LGPL2 (crystal project) [derived from greenled.png] kwave/pics/sound_card.png LGPL2 (crystal project) [copied from kcmpci.png] kwave/pics/sound_device.png LGPL2 (crystal project) [copied from multimedia.png] kwave/pics/sound_note.png LGPL2 (crystal project) [copied from knotify.png] kwave/pics/sound_subdevice.png LGPL2 (crystal project) [copied from kcmsound.png] kwave/toolbar/kwave_player_bg.svgz derived from "Oxygen" icons kwave/toolbar/kwave_player_end.svgz derived from "Oxygen" icons kwave/toolbar/kwave_player_fwd.svgz derived from "Oxygen" icons kwave/toolbar/kwave_player_loop.svgz derived from "Oxygen" icons kwave/toolbar/kwave_player_pause.svgz derived from "Oxygen" icons kwave/toolbar/kwave_player_pause_2.svgz derived from "Oxygen" icons kwave/toolbar/kwave_player_play.svgz derived from "Oxygen" icons kwave/toolbar/kwave_player_record.svgz derived from "Oxygen" icons kwave/toolbar/kwave_player_rew.svgz derived from "Oxygen" icons kwave/toolbar/kwave_player_start.svgz derived from "Oxygen" icons kwave/toolbar/kwave_player_stop.svgz derived from "Oxygen" icons kwave/toolbar/kwave_viewmag.svgz derived from "Oxygen" icons kwave/toolbar/kwave_viewmagfit.svgz derived from "Oxygen" icons kwave/toolbar/kwave_zoom_in.svgz derived from "Oxygen" icons kwave/toolbar/kwave_zoom_original.svgz derived from "Oxygen" icons kwave/toolbar/kwave_zoom_out.svgz derived from "Oxygen" icons libgui/CMakeLists.txt BSD (3 clause) libgui/Colors.cpp GPL2+ libgui/Colors.h GPL2+ libgui/ConfirmCancelProxy.cpp GPL2+ libgui/ConfirmCancelProxy.h GPL2+ libgui/CurveWidget.cpp GPL2+ libgui/CurveWidget.h GPL2+ libgui/FileDialog.cpp GPL2+ libgui/FileDialog.h GPL2+ libgui/FilterPlugin.cpp GPL2+ libgui/FilterPlugin.h GPL2+ libgui/FrequencyResponseWidget.cpp GPL2+ libgui/FrequencyResponseWidget.h GPL2+ libgui/HMSTimeWidgetBase.ui (should be GPL2+) libgui/HMSTimeWidget.cpp GPL2+ libgui/HMSTimeWidget.h GPL2+ libgui/ImageView.cpp GPL2+ / Martin Wilz libgui/ImageView.h GPL2+ / Martin Wilz libgui/InvertableSpinBox.cpp GPL2+ libgui/InvertableSpinBox.h GPL2+ libgui/LabelItem.cpp GPL2+ libgui/LabelItem.h GPL2+ libgui/LabelPropertiesWidget.cpp GPL2+ libgui/LabelPropertiesWidget.h GPL2+ libgui/LabelPropertiesWidgetBase.ui GPL2+ libgui/MenuGroup.cpp GPL2+ libgui/MenuGroup.h GPL2+ libgui/MenuItem.cpp GPL2+ libgui/MenuItem.h GPL2+ libgui/MenuManager.cpp GPL2+ libgui/MenuManager.h GPL2+ libgui/MenuNode.cpp GPL2+ libgui/MenuNode.h GPL2+ libgui/MenuRoot.cpp GPL2+ libgui/MenuRoot.h GPL2+ libgui/MenuSub.cpp GPL2+ libgui/MenuSub.h GPL2+ libgui/MouseMark.cpp GPL2+ libgui/MouseMark.h GPL2+ libgui/MultiStateWidget.cpp GPL2+ libgui/MultiStateWidget.h GPL2+ libgui/OverViewCache.cpp GPL2+ libgui/OverViewCache.h GPL2+ libgui/OverViewWidget.cpp GPL2+ libgui/OverViewWidget.h GPL2+ libgui/ScaleWidget.cpp GPL2+ libgui/ScaleWidget.h GPL2+ libgui/SelectionBorderItem.h GPL2+ libgui/SelectionBorderItem.cpp GPL2+ libgui/SelectionItem.h GPL2+ libgui/SelectionItem.cpp GPL2+ libgui/SelectionTracker.h GPL2+ libgui/SelectionTracker.cpp GPL2+ libgui/SelectTimeWidgetBase.ui (should be GPL2+) libgui/SelectTimeWidget.cpp GPL2+ libgui/SelectTimeWidget.h GPL2+ libgui/SignalWidget.cpp GPL2+ / Martin Wilz libgui/SignalWidget.h GPL2+ libgui/TrackPixmap.cpp GPL2+ libgui/TrackPixmap.h GPL2+ libgui/TrackView.cpp GPL2+ libgui/TrackView.h GPL2+ libgui/TreeWidgetWrapper.cpp GPL2+ libgui/TreeWidgetWrapper.h GPL2+ libgui/UndoModifyLabelAction.cpp GPL2+ libgui/UndoModifyLabelAction.h GPL2+ libgui/ViewItem.cpp GPL2+ libgui/ViewItem.h GPL2+ libgui/Zoomable.h GPL2+ libkwave/BitrateMode.h GPL2+ libkwave/ByteOrder.h GPL2+ libkwave/ClipBoard.cpp GPL2+ libkwave/ClipBoard.h GPL2+ libkwave/CMakeLists.txt BSD (3 clause) libkwave/CodecBase.cpp GPL2+ libkwave/CodecBase.h GPL2+ libkwave/CodecManager.cpp GPL2+ libkwave/CodecManager.h GPL2+ libkwave/CodecPlugin.cpp GPL2+ libkwave/CodecPlugin.h GPL2+ libkwave/CommandHandler.h GPL2+ libkwave/Compression.cpp GPL2+ libkwave/Compression.h GPL2+ libkwave/Connect.cpp GPL2+ libkwave/Connect.h GPL2+ libkwave/cpu_accel.cpp GPL2+ / Aaron Holtzman libkwave/cputest.h GPL2+ libkwave/Curve.cpp GPL2+ libkwave/Curve.h GPL2+ libkwave/Decoder.cpp GPL2+ libkwave/Decoder.h GPL2+ libkwave/Drag.cpp GPL2+ libkwave/Drag.h GPL2+ libkwave/Encoder.cpp GPL2+ libkwave/Encoder.h GPL2+ libkwave/FileDrag.h GPL2+ libkwave/FileInfo.cpp GPL2+ libkwave/FileInfo.h GPL2+ libkwave/FileProgress.cpp GPL2+ libkwave/FileProgress.h GPL2+ libkwave/Filter.cpp GPL2+ libkwave/Filter.h GPL2+ libkwave/FixedPool.h GPL2+ libkwave/Functions.cpp GPL2+ libkwave/Functions.h GPL2+ libkwave/GenreType.cpp GPL2+ libkwave/GenreType.h GPL2+ libkwave/GlobalLock.cpp GPL2+ libkwave/GlobalLock.h GPL2+ libkwave/InsertMode.h GPL2+ libkwave/Interpolation.cpp GPL2+ libkwave/Interpolation.h GPL2+ libkwave/Label.cpp GPL2+ libkwave/Label.h GPL2+ libkwave/LabelList.cpp GPL2+ libkwave/LabelList.h GPL2+ libkwave/Logger.cpp GPL2+ libkwave/Logger.h GPL2+ libkwave/Matrix.h GPL2+ (Martin Hinsch) libkwave/MimeData.cpp GPL2+ libkwave/MimeData.h GPL2+ libkwave/MixerMatrix.cpp GPL2+ libkwave/MixerMatrix.h GPL2+ libkwave/memcpy.c GPL2+ / xine libkwave/memcpy.h GPL2+ libkwave/MemoryManager.cpp GPL2+ libkwave/MemoryManager.h GPL2+ libkwave/MessageBox.h GPL2+ libkwave/MessageBox.cpp GPL2+ libkwave/MetaData.cpp GPL2+ libkwave/MetaData.h GPL2+ libkwave/MetaDataList.cpp GPL2+ libkwave/MetaDataList.h GPL2+ libkwave/MultiPlaybackSink.cpp GPL2+ libkwave/MultiPlaybackSink.h GPL2+ libkwave/MultiStreamWriter.cpp GPL2+ libkwave/MultiStreamWriter.h GPL2+ libkwave/MultiTrackSource.h GPL2+ libkwave/MultiTrackReader.cpp GPL2+ libkwave/MultiTrackReader.h GPL2+ libkwave/MultiTrackSink.h GPL2+ libkwave/MultiTrackWriter.cpp GPL2+ libkwave/MultiTrackWriter.h GPL2+ libkwave/MultiWriter.cpp GPL2+ libkwave/MultiWriter.h GPL2+ libkwave/Parser.cpp GPL2+ libkwave/Parser.h GPL2+ libkwave/PlaybackController.cpp GPL2+ libkwave/PlaybackController.h GPL2+ libkwave/PlaybackDeviceFactory.h GPL2+ libkwave/PlayBackDevice.h GPL2+ libkwave/PlayBackParam.h GPL2+ libkwave/PlaybackSink.cpp GPL2+ libkwave/PlaybackSink.h GPL2+ libkwave/PlayBackTypesMap.cpp GPL2+ libkwave/PlayBackTypesMap.h GPL2+ libkwave/Plugin.cpp GPL2+ libkwave/Plugin.h GPL2+ libkwave/PluginManager.cpp GPL2+ libkwave/PluginManager.h GPL2+ libkwave/PluginSetupDialog.h GPL2+ libkwave/ReaderMode.h GPL2+ libkwave/Runnable.h GPL2+ libkwave/Sample.h GPL2+ libkwave/SampleArray.cpp GPL2+ libkwave/SampleArray.h GPL2+ libkwave/SampleEncoder.h GPL2+ libkwave/SampleEncoderLinear.h GPL2+ libkwave/SampleEncoderLinear.cpp GPL2+ libkwave/SampleFIFO.cpp GPL2+ libkwave/SampleFIFO.h GPL2+ libkwave/SampleFormat.cpp GPL2+ libkwave/SampleFormat.h GPL2+ libkwave/SampleReader.cpp GPL2+ libkwave/SampleReader.h GPL2+ libkwave/SampleSink.cpp GPL2+ libkwave/SampleSink.h GPL2+ libkwave/SampleSource.cpp GPL2+ libkwave/SampleSource.h GPL2+ libkwave/Selection.h GPL2+ libkwave/Selection.cpp GPL2+ libkwave/Signal.cpp GPL2+ libkwave/Signal.h GPL2+ libkwave/SignalManager.cpp GPL2+ libkwave/SignalManager.h GPL2+ libkwave/StandardBitrates.cpp GPL2+ libkwave/StandardBitrates.h GPL2+ libkwave/StreamWriter.cpp GPL2+ libkwave/StreamWriter.h GPL2+ libkwave/String.h GPL2+ libkwave/Stripe.cpp GPL2+ libkwave/Stripe.h GPL2+ libkwave/SwapFile.cpp GPL2+ libkwave/SwapFile.h GPL2+ libkwave/Track.cpp GPL2+ libkwave/Track.h GPL2+ libkwave/TrackWriter.cpp GPL2+ libkwave/TrackWriter.h GPL2+ libkwave/TransmissionFunction.h GPL2+ libkwave/Triple.h GPL2+ libkwave/TypesMap.h GPL2+ libkwave/Utils.h GPL2+ libkwave/Utils.cpp GPL2+ libkwave/VirtualAudioFile.cpp GPL2+ libkwave/VirtualAudioFile.h GPL2+ libkwave/VorbisCommentMap.cpp GPL2+ libkwave/VorbisCommentMap.h GPL2+ libkwave/WindowFunction.cpp GPL2+ libkwave/WindowFunction.h GPL2+ libkwave/WorkerThread.h GPL2+ libkwave/WorkerThread.cpp GPL2+ libkwave/Writer.cpp GPL2+ libkwave/Writer.h GPL2+ libkwave/modules/ChannelMixer.cpp GPL2+ libkwave/modules/ChannelMixer.h GPL2+ libkwave/modules/CurveStreamAdapter.cpp GPL2+ libkwave/modules/CurveStreamAdapter.h GPL2+ libkwave/modules/Delay.cpp GPL2+ libkwave/modules/Delay.h GPL2+ libkwave/modules/Indexer.cpp GPL2+ libkwave/modules/Indexer.h GPL2+ libkwave/modules/Mul.cpp GPL2+ libkwave/modules/Mul.h GPL2+ libkwave/modules/Osc.cpp GPL2+ libkwave/modules/Osc.h GPL2+ libkwave/modules/SampleBuffer.cpp GPL2+ libkwave/modules/SampleBuffer.h GPL2+ libkwave/modules/StreamObject.cpp GPL2+ libkwave/modules/StreamObject.h GPL2+ libkwave/undo/UndoAction.h GPL2+ libkwave/undo/UndoAddMetaDataAction.cpp GPL2+ libkwave/undo/UndoAddMetaDataAction.h GPL2+ libkwave/undo/UndoDeleteAction.cpp GPL2+ libkwave/undo/UndoDeleteAction.h GPL2+ libkwave/undo/UndoDeleteMetaDataAction.cpp GPL2+ libkwave/undo/UndoDeleteMetaDataAction.h GPL2+ libkwave/undo/UndoDeleteTrack.cpp GPL2+ libkwave/undo/UndoDeleteTrack.h GPL2+ libkwave/undo/UndoHandler.h GPL2+ libkwave/undo/UndoInsertAction.cpp GPL2+ libkwave/undo/UndoInsertAction.h GPL2+ libkwave/undo/UndoInsertTrack.cpp GPL2+ libkwave/undo/UndoInsertTrack.h GPL2+ libkwave/undo/UndoManager.cpp GPL2+ libkwave/undo/UndoManager.h GPL2+ libkwave/undo/UndoModifyAction.cpp GPL2+ libkwave/undo/UndoModifyAction.h GPL2+ libkwave/undo/UndoModifyMetaDataAction.cpp GPL2+ libkwave/undo/UndoModifyMetaDataAction.h GPL2+ libkwave/undo/UndoSelection.cpp GPL2+ libkwave/undo/UndoSelection.h GPL2+ libkwave/undo/UndoTransaction.cpp GPL2+ libkwave/undo/UndoTransactionGuard.cpp GPL2+ libkwave/undo/UndoTransactionGuard.h GPL2+ libkwave/undo/UndoTransaction.h GPL2+ plugins/CMakeLists.txt BSD (3 clause) plugins/kwave-plugin.desktop GPL2+ plugins/about/AboutContainer.cpp GPL2+ / Mirko Boehm / Espen Sand plugins/about/AboutContainer.h GPL2+ / Mirko Boehm / Espen Sand plugins/about/AboutDialogBase.ui (should be GPL2+ / Ralf Waspe) plugins/about/AboutDialog.cpp GPL2+ / Ralf Waspe & Gilles Caulier plugins/about/AboutDialog.h GPL2+ / Ralf Waspe plugins/about/AboutPlugin.cpp GPL2+ plugins/about/AboutPlugin.h GPL2+ plugins/about/CMakeLists.txt BSD (3 clause) plugins/about/kwaveplugin_about.desktop.in GPL2+ plugins/about/LogoWidget.cpp GPL2+ / Martin Wilz plugins/about/LogoWidget.h GPL2+ / Martin Wilz plugins/about/logo.xpm GPL2+ / Martin Wilz plugins/amplifyfree/AmplifyFreeDialog.cpp GPL2+ plugins/amplifyfree/AmplifyFreeDialog.h GPL2+ plugins/amplifyfree/AmplifyFreeDlg.ui (should be GPL2+) plugins/amplifyfree/AmplifyFreePlugin.cpp GPL2+ plugins/amplifyfree/AmplifyFreePlugin.h GPL2+ plugins/amplifyfree/CMakeLists.txt BSD (3 clause) plugins/amplifyfree/kwaveplugin_amplifyfree.desktop.in GPL2+ plugins/band_pass/BandPass.cpp GPL2+ / Juhana Sadeharju plugins/band_pass/BandPass.h GPL2+ plugins/band_pass/BandPassDialog.cpp GPL2+ plugins/band_pass/BandPassDialog.h GPL2+ plugins/band_pass/BandPassDlg.ui GPL2+ plugins/band_pass/BandPass.h GPL2+ plugins/band_pass/BandPassPlugin.cpp GPL2+ plugins/band_pass/BandPassPlugin.h GPL2+ plugins/band_pass/CMakeLists.txt BSD (3 clause) plugins/band_pass/kwaveplugin_band_pass.desktop.in GPL2+ plugins/codec_ascii/AsciiCodecPlugin.cpp GPL2+ plugins/codec_ascii/AsciiCodecPlugin.h GPL2+ plugins/codec_ascii/AsciiEncoder.h GPL2+ plugins/codec_ascii/AsciiDecoder.h GPL2+ plugins/codec_ascii/AsciiEncoder.cpp GPL2+ plugins/codec_ascii/AsciiDecoder.cpp GPL2+ plugins/codec_ascii/CMakeLists.txt BSD (3 clause) plugins/codec_ascii/kwaveplugin_codec_ascii.desktop.in GPL2+ plugins/codec_audiofile/AudiofileCodecPlugin.cpp GPL2+ plugins/codec_audiofile/AudiofileCodecPlugin.h GPL2+ plugins/codec_audiofile/AudiofileDecoder.cpp GPL2+ plugins/codec_audiofile/AudiofileDecoder.h GPL2+ plugins/codec_audiofile/CMakeLists.txt BSD (3 clause) plugins/codec_audiofile/kwaveplugin_codec_audiofile.desktop.in GPL2+ plugins/codec_flac/CMakeLists.txt BSD (3 clause) plugins/codec_flac/FlacCodecPlugin.cpp GPL2+ plugins/codec_flac/FlacCodecPlugin.h GPL2+ plugins/codec_flac/FlacDecoder.cpp GPL2+ plugins/codec_flac/FlacDecoder.h GPL2+ plugins/codec_flac/FlacEncoder.cpp GPL2+ plugins/codec_flac/FlacEncoder.h GPL2+ plugins/codec_flac/kwaveplugin_codec_flac.desktop.in GPL2+ plugins/codec_mp3/CMakeLists.txt BSD (3 clause) plugins/codec_mp3/ID3_PropertyMap.cpp GPL2+ plugins/codec_mp3/ID3_PropertyMap.h GPL2+ plugins/codec_mp3/ID3_QIODeviceReader.cpp GPL2+ plugins/codec_mp3/ID3_QIODeviceReader.h GPL2+ plugins/codec_mp3/ID3_QIODeviceWriter.cpp GPL2+ plugins/codec_mp3/ID3_QIODeviceWriter.h GPL2+ plugins/codec_mp3/kwaveplugin_codec_mp3.desktop.in GPL2+ plugins/codec_mp3/MP3CodecPlugin.cpp GPL2+ plugins/codec_mp3/MP3CodecPlugin.h GPL2+ plugins/codec_mp3/MP3Decoder.cpp GPL2+ plugins/codec_mp3/MP3Decoder.h GPL2+ plugins/codec_mp3/MP3Encoder.cpp GPL2+ plugins/codec_mp3/MP3Encoder.h GPL2+ plugins/codec_ogg/CMakeLists.txt BSD (3 clause) plugins/codec_ogg/kwaveplugin_codec_ogg.desktop.in GPL2+ plugins/codec_ogg/OggCodecPlugin.cpp GPL2+ plugins/codec_ogg/OggCodecPlugin.h GPL2+ plugins/codec_ogg/OggDecoder.cpp GPL2+ plugins/codec_ogg/OggDecoder.h GPL2+ plugins/codec_ogg/OggEncoder.cpp GPL2+ plugins/codec_ogg/OggEncoder.h GPL2+ plugins/codec_ogg/OggSubDecoder.h GPL2+ plugins/codec_ogg/OggSubEncoder.h GPL2+ plugins/codec_ogg/OpusCommon.cpp GPL2+ plugins/codec_ogg/OpusCommon.h GPL2+ plugins/codec_ogg/OpusDecoder.cpp GPL2+ plugins/codec_ogg/OpusDecoder.h GPL2+ plugins/codec_ogg/OpusEncoder.cpp GPL2+, parts two clause BSD plugins/codec_ogg/OpusEncoder.h GPL2+ plugins/codec_ogg/OpusHeader.h GPL2+ plugins/codec_ogg/VorbisDecoder.cpp GPL2+ plugins/codec_ogg/VorbisDecoder.h GPL2+ plugins/codec_ogg/VorbisEncoder.cpp GPL2+ plugins/codec_ogg/VorbisEncoder.h GPL2+ plugins/codec_wav/CMakeLists.txt BSD (3 clause) plugins/codec_wav/kwaveplugin_codec_wav.desktop.in GPL2+ plugins/codec_wav/RecoveryBuffer.cpp GPL2+ plugins/codec_wav/RecoveryBuffer.h GPL2+ plugins/codec_wav/RecoveryMapping.cpp GPL2+ plugins/codec_wav/RecoveryMapping.h GPL2+ plugins/codec_wav/RecoverySource.cpp GPL2+ plugins/codec_wav/RecoverySource.h GPL2+ plugins/codec_wav/RepairVirtualAudioFile.cpp GPL2+ plugins/codec_wav/RepairVirtualAudioFile.h GPL2+ plugins/codec_wav/RIFFChunk.cpp GPL2+ plugins/codec_wav/RIFFChunk.h GPL2+ plugins/codec_wav/RIFFParser.cpp GPL2+ plugins/codec_wav/RIFFParser.h GPL2+ plugins/codec_wav/WavCodecPlugin.cpp GPL2+ plugins/codec_wav/WavCodecPlugin.h GPL2+ plugins/codec_wav/WavDecoder.cpp GPL2+ plugins/codec_wav/WavDecoder.h GPL2+ plugins/codec_wav/WavEncoder.cpp GPL2+ plugins/codec_wav/WavEncoder.h GPL2+ plugins/codec_wav/WavFileFormat.h GPL2+ plugins/codec_wav/WavFormatMap.cpp GPL2+ plugins/codec_wav/WavFormatMap.h GPL2+ plugins/codec_wav/WavPropertyMap.cpp GPL2+ plugins/codec_wav/WavPropertyMap.h GPL2+ plugins/common/CMakeLists.txt.template BSD (3 clause) plugins/debug/CMakeLists.txt BSD (3 clause) plugins/debug/DebugPlugin.cpp GPL2+ plugins/debug/DebugPlugin.h GPL2+ plugins/debug/kwaveplugin_debug.desktop.in GPL2+ plugins/export_k3b/CMakeLists.txt BSD (3 clause) plugins/export_k3b/K3BExportDialog.cpp GPL2+ plugins/export_k3b/K3BExportDialog.h GPL2+ plugins/export_k3b/K3BExportPlugin.cpp GPL2+ / Sebastian Trueg , Gustavo Pichorim Boiko Michal Malek plugins/export_k3b/K3BExportPlugin.h GPL2+ plugins/export_k3b/K3BExportWidget.cpp GPL2+ plugins/export_k3b/K3BExportWidget.h GPL2+ plugins/export_k3b/K3BExportWidegetBase.ui GPL2+ plugins/export_k3b/kwaveplugin_export_k3b.desktop.in GPL2+ plugins/goto/CMakeLists.txt BSD (3 clause) plugins/goto/GotoDialog.cpp GPL2+ plugins/goto/GotoDialog.h GPL2+ plugins/goto/GotoDlg.ui (should be GPL2+) plugins/goto/GotoPlugin.cpp GPL2+ plugins/goto/GotoPlugin.h GPL2+ plugins/goto/GotoPluginBase.cpp GPL2+ plugins/goto/GotoPluginBase.h GPL2+ plugins/goto/InsertAtPlugin.cpp GPL2+ plugins/goto/InsertAtPlugin.h GPL2+ plugins/goto/kwaveplugin_goto.desktop.in GPL2+ plugins/goto/kwaveplugin_insert_at.desktop.in GPL2+ plugins/fileinfo/BitrateSpinBox.cpp GPL2+ plugins/fileinfo/BitrateSpinBox.h GPL2+ plugins/fileinfo/BitrateWidgetBase.ui (should be GPL2+) plugins/fileinfo/BitrateWidget.cpp GPL2+ plugins/fileinfo/BitrateWidget.h GPL2+ plugins/fileinfo/CMakeLists.txt BSD (3 clause) plugins/fileinfo/CompressionWidgetBase.ui (should be GPL2+) plugins/fileinfo/CompressionWidget.cpp GPL2+ plugins/fileinfo/CompressionWidget.h GPL2+ plugins/fileinfo/FileInfoDialog.cpp GPL2+ plugins/fileinfo/FileInfoDialog.h GPL2+ plugins/fileinfo/FileInfoDlg.ui (should be GPL2+) plugins/fileinfo/FileInfoPlugin.cpp GPL2+ plugins/fileinfo/FileInfoPlugin.h GPL2+ plugins/fileinfo/KeywordWidgetBase.ui (should be GPL2+) plugins/fileinfo/KeywordWidget.cpp GPL2+ plugins/fileinfo/KeywordWidget.h GPL2+ plugins/fileinfo/kwaveplugin_fileinfo.desktop.in GPL2+ plugins/fileinfo/SelectDateDialog.cpp GPL2+ plugins/fileinfo/SelectDateDialog.h GPL2+ plugins/fileinfo/SelectDateDlg.ui (should be GPL2+) plugins/labeler/LabelerPlugin.cpp GPL2+ plugins/labeler/LabelerPlugin.h GPL2+ plugins/labeler/gui/LabelView.cpp GPL2+ plugins/labeler/gui/LabelView.h GPL2+ plugins/lowpass/CMakeLists.txt BSD (3 clause) plugins/lowpass/kwaveplugin_lowpass.desktop.in GPL2+ plugins/lowpass/LowPassDialog.cpp GPL2+ plugins/lowpass/LowPassDialog.h GPL2+ plugins/lowpass/LowPassDlg.ui (should be GPL2+) plugins/lowpass/LowPassFilter.cpp GPL2+ / Juhana Sadeharju plugins/lowpass/LowPassFilter.h GPL2+ / Juhana Sadeharju plugins/lowpass/LowPassPlugin.cpp GPL2+ plugins/lowpass/LowPassPlugin.h GPL2+ plugins/memory/CMakeLists.txt BSD (3 clause) plugins/memory/kwaveplugin_memory.desktop.in GPL2+ plugins/memory/MemDlg.ui (should be GPL2+) plugins/memory/MemoryDialog.cpp GPL2+ plugins/memory/MemoryDialog.h GPL2+ plugins/memory/MemoryPlugin.cpp GPL2+ plugins/memory/MemoryPlugin.h GPL2+ plugins/newsignal/CMakeLists.txt BSD (3 clause) plugins/newsignal/kwaveplugin_newsignal.desktop.in GPL2+ plugins/newsignal/NewSigDlg.ui (should be GPL2+) plugins/newsignal/NewSignalDialog.cpp GPL2+ plugins/newsignal/NewSignalDialog.h GPL2+ plugins/newsignal/NewSignalPlugin.cpp GPL2+ plugins/newsignal/NewSignalPlugin.h GPL2+ plugins/noise/CMakeLists.txt BSD (3 clause) plugins/noise/kwaveplugin_noise.desktop.in GPL2+ plugins/noise/NoiseDialog.cpp GPL2+ plugins/noise/NoiseDialog.h GPL2+ plugins/noise/NoiseDlg.ui GPL2+ plugins/noise/NoiseGenerator.cpp GPL2+ plugins/noise/NoiseGenerator.h GPL2+ plugins/noise/NoisePlugin.cpp GPL2+ plugins/noise/NoisePlugin.h GPL2+ plugins/normalize/CMakeLists.txt BSD (3 clause) plugins/normalize/kwaveplugin_normalize.desktop.in GPL2+ plugins/normalize/NormalizePlugin.cpp GPL2+ plugins/normalize/NormalizePlugin.h GPL2+ plugins/notch_filter/CMakeLists.txt BSD (3 clause) plugins/notch_filter/kwaveplugin_notch_filter.desktop.in GPL2+ plugins/notch_filter/NotchFilter.cpp GPL2+ / Dave Flogeras / Juhana Sadeharju plugins/notch_filter/NotchFilterDialog.cpp GPL2+ / Dave Flogeras plugins/notch_filter/NotchFilterDialog.h GPL2+ / Dave Flogeras plugins/notch_filter/NotchFilterDlg.ui (should be GPL2+ / Dave Flogeras) plugins/notch_filter/NotchFilter.h GPL2+ / Dave Flogeras plugins/notch_filter/NotchFilterPlugin.cpp GPL2+ / Dave Flogeras plugins/notch_filter/NotchFilterPlugin.h GPL2+ / Dave Flogeras plugins/pitch_shift/CMakeLists.txt BSD (3 clause) plugins/pitch_shift/kwaveplugin_pitch_shift.desktop.in GPL2+ plugins/pitch_shift/PitchShiftDialog.cpp GPL2+ plugins/pitch_shift/PitchShiftDialog.h GPL2+ plugins/pitch_shift/PitchShiftFilter.cpp GPL2+ / Jeff Tranter + Stefan Westerfeld plugins/pitch_shift/PitchShiftFilter.h GPL2+ plugins/pitch_shift/PitchShiftDlg.ui (should be GPL2+) plugins/pitch_shift/PitchShiftPlugin.cpp GPL2+ plugins/pitch_shift/PitchShiftPlugin.h GPL2+ plugins/playback/CMakeLists.txt BSD (3 clause) plugins/playback/kwaveplugin_playback.desktop.in GPL2+ plugins/playback/PlayBack-ALSA.cpp GPL2+ / (parts from) Jaroslav Kysela plugins/playback/PlayBack-ALSA.h GPL2+ plugins/playback/PlayBackDialog.cpp GPL2+ plugins/playback/PlayBackDialog.h GPL2+ plugins/playback/PlayBackDlg.ui (should be GPL2+) plugins/playback/PlayBack-OSS.cpp GPL2+ plugins/playback/PlayBack-OSS.h GPL2+ plugins/playback/PlayBack-PulseAudio.cpp GPL2+ plugins/playback/PlayBack-PulseAudio.h GPL2+ plugins/playback/PlayBack-Qt.cpp GPL2+ plugins/playback/PlayBack-Qt.h GPL2+ plugins/playback/PlayBackPlugin.cpp GPL2+ plugins/playback/PlayBackPlugin.h GPL2+ plugins/record/CMakeLists.txt BSD (3 clause) - plugins/record/krec_record.xpm LGPL2 (crystal project) [converted from mix_record.png] plugins/record/kwaveplugin_record.desktop.in GPL2+ plugins/record/LevelMeter.cpp GPL2+ / Rik Hemsley plugins/record/LevelMeter.h GPL2+ / Rik Hemsley plugins/record/Record-ALSA.cpp GPL2+ plugins/record/Record-ALSA.h GPL2+ plugins/record/Record-OSS.cpp GPL2+ plugins/record/Record-OSS.h GPL2+ plugins/record/Record-PulseAudio.cpp GPL2+ plugins/record/Record-PulseAudio.h GPL2+ plugins/record/Record-Qt.cpp GPL2+ plugins/record/Record-Qt.h GPL2+ plugins/record/RecordController.cpp GPL2+ plugins/record/RecordController.h GPL2+ plugins/record/RecordDevice.h GPL2+ plugins/record/RecordDialog.cpp GPL2+ plugins/record/RecordDialog.h GPL2+ plugins/record/RecordDlg.ui (should be GPL2+) plugins/record/RecordingState.xmi (should be GPL2+) plugins/record/RecordParams.cpp GPL2+ plugins/record/RecordParams.h GPL2+ - plugins/record/record_pause2.xpm (should be GPL2+) - plugins/record/record_pause.xpm (should be GPL2+) plugins/record/RecordPlugin.cpp GPL2+ plugins/record/RecordPlugin.h GPL2+ plugins/record/RecordPlugin.png (should be GPL2+) plugins/record/RecordState.h GPL2+ - plugins/record/record_stop.xpm (should be GPL2+) plugins/record/RecordThread.cpp GPL2+ plugins/record/RecordThread.h GPL2+ plugins/record/RecordTypesMap.cpp GPL2+ plugins/record/RecordTypesMap.h GPL2+ plugins/record/StatusWidget.h GPL2+ plugins/record/StatusWidget.cpp GPL2+ plugins/record/SampleDecoder.h GPL2+ plugins/record/SampleDecoderLinear.cpp GPL2+ plugins/record/SampleDecoderLinear.h GPL2+ plugins/record/stop_hand.xpm free / KDE -> icons/ikons/16x16/actions/stop_hand.png plugins/record/ok.xpm free / KDE -> icons/crystalsvg/16x16/actions/ok.png plugins/record/ledgreen.xpm GPL2 (kdelirc) plugins/record/ledlightgreen.xpm GPL2 (kdelirc) plugins/record/ledred.xpm GPL2 (kdelirc) plugins/record/ledyellow.xpm GPL2 (kdelirc) plugins/record/walk_r1.xpm GPL2 (amor) plugins/record/walk_r2.xpm GPL2 (amor) plugins/record/walk_r3.xpm GPL2 (amor) plugins/record/walk_r4.xpm GPL2 (amor) plugins/record/walk_r5.xpm GPL2 (amor) plugins/record/walk_r6.xpm GPL2 (amor) plugins/record/walk_r7.xpm GPL2 (amor) plugins/record/walk_r8.xpm GPL2 (amor) plugins/reverse/CMakeLists.txt BSD (3 clause) plugins/reverse/kwaveplugin_reverse.desktop.in GPL2+ plugins/reverse/ReversePlugin.h GPL2+ plugins/reverse/ReversePlugin.cpp GPL2+ plugins/samplerate/CMakeLists.txt BSD (3 clause) plugins/samplerate/kwaveplugin_samplerate.desktop.in GPL2+ plugins/samplerate/SampleRatePlugin.cpp GPL2+ plugins/samplerate/SampleRatePlugin.h GPL2+ plugins/saveblocks/CMakeLists.txt BSD (3 clause) plugins/saveblocks/kwaveplugin_saveblocks.desktop.in GPL2+ plugins/saveblocks/SaveBlocksWidgetBase.ui GPL2+ plugins/saveblocks/SaveBlocksDialog.h GPL2+ plugins/saveblocks/SaveBlocksDialog.cpp GPL2+ plugins/saveblocks/SaveBlocksPlugin.cpp GPL2+ plugins/saveblocks/SaveBlocksPlugin.h GPL2+ plugins/saveblocks/SaveBlocksWidget.cpp GPL2+ plugins/saveblocks/SaveBlocksWidget.h GPL2+ plugins/selectrange/CMakeLists.txt BSD (3 clause) plugins/selectrange/kwaveplugin_selectrange.desktop.in GPL2+ plugins/selectrange/SelectRangeDialog.cpp GPL2+ plugins/selectrange/SelectRangeDialog.h GPL2+ plugins/selectrange/SelectRangeDlg.ui (should be GPL2+) plugins/selectrange/SelectRangePlugin.cpp GPL2+ plugins/selectrange/SelectRangePlugin.h GPL2+ plugins/sonagram/CMakeLists.txt BSD (3 clause) plugins/sonagram/kwaveplugin_sonagram.desktop.in GPL2+ plugins/sonagram/SonagramDialog.cpp GPL2+ plugins/sonagram/SonagramDialog.h GPL2+ plugins/sonagram/SonagramDlg.ui (should be GPL2+) plugins/sonagram/SonagramPlugin.cpp GPL2+ plugins/sonagram/SonagramPlugin.h GPL2+ plugins/sonagram/SonagramWindow.cpp GPL2+ plugins/sonagram/SonagramWindow.h GPL2+ plugins/stringenter/CMakeLists.txt BSD (3 clause) plugins/stringenter/kwaveplugin_stringenter.desktop.in GPL2+ plugins/stringenter/StringEnterDialog.cpp GPL2+ plugins/stringenter/StringEnterDialog.h GPL2+ plugins/stringenter/StringEnterDlg.ui (should be GPL2+) plugins/stringenter/StringEnterPlugin.cpp GPL2+ plugins/stringenter/StringEnterPlugin.h GPL2+ plugins/volume/CMakeLists.txt BSD (3 clause) plugins/volume/kwaveplugin_volume.desktop.in GPL2+ plugins/volume/VolumeDialog.cpp GPL2+ plugins/volume/VolumeDialog.h GPL2+ plugins/volume/VolumeDlg.ui (should be GPL2+) plugins/volume/VolumePlugin.cpp GPL2+ plugins/volume/VolumePlugin.h GPL2+ plugins/zero/CMakeLists.txt BSD (3 clause) plugins/zero/kwaveplugin_zero.desktop.in GPL2+ plugins/zero/ZeroPlugin.cpp GPL2+ plugins/zero/ZeroPlugin.h GPL2+ samples/sample.opus CC BY-SA 4.0 scripts/create-testfile.kwave GPL2+ scripts/screenshots.kwave GPL2+ ### EOF ### diff --git a/kwave/CMakeLists.txt b/kwave/CMakeLists.txt index e2d6aef3..6e2fef89 100644 --- a/kwave/CMakeLists.txt +++ b/kwave/CMakeLists.txt @@ -1,146 +1,146 @@ ############################################################################# ## Kwave - kwave/CMakeLists.txt ## ------------------- ## begin : Wed May 09 2007 ## copyright : (C) 2007 by Thomas Eschenbacher ## email : Thomas.Eschenbacher@gmx.de ############################################################################# # ############################################################################# # # # Redistribution and use in source and binary forms, with or without # # modification, are permitted provided that the following conditions # # are met: # # # # 1. Redistributions of source code must retain the above copyright # # notice, this list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright # # notice, this list of conditions and the following disclaimer in the # # documentation and/or other materials provided with the distribution. # # # # For details see the accompanying cmake/COPYING-CMAKE-SCRIPTS file. # # # ############################################################################# INCLUDE(ECMInstallIcons) ############################################################################# SET(kwave_SRCS App.cpp FileContext.cpp main.cpp MainWidget.cpp PlayerToolBar.cpp ShortcutWrapper.cpp Splash.cpp TopWidget.cpp ZoomToolBar.cpp ) ############################################################################# ### some pixmaps to be installed in the data dir ### SET(kwave_PIXMAPS pics/amplify_free.png pics/fade_in.png pics/fade_out.png pics/knob.xpm pics/kwave-splash.png pics/light_off.xpm pics/light_on.xpm pics/logo.xpm pics/noise.png pics/selectedknob.xpm - pics/sound_device.png - pics/sound_subdevice.png pics/sound_card.png + pics/sound_device.png pics/sound_note.png + pics/sound_subdevice.png ) ############################################################################# ### scalable action icons to be installed in the icon dir ### SET(kwave_ACTION_ICONS toolbar/sc-actions-kwave_player_end.svgz toolbar/sc-actions-kwave_player_fwd.svgz toolbar/sc-actions-kwave_player_pause.svgz toolbar/sc-actions-kwave_player_pause_2.svgz toolbar/sc-actions-kwave_player_play.svgz toolbar/sc-actions-kwave_player_loop.svgz toolbar/sc-actions-kwave_player_record.svgz toolbar/sc-actions-kwave_player_rew.svgz toolbar/sc-actions-kwave_player_start.svgz toolbar/sc-actions-kwave_player_stop.svgz toolbar/sc-actions-kwave_viewmagfit.svgz toolbar/sc-actions-kwave_viewmag.svgz toolbar/sc-actions-kwave_zoom_in.svgz toolbar/sc-actions-kwave_zoom_original.svgz toolbar/sc-actions-kwave_zoom_out.svgz ) ############################################################################# ADD_EXECUTABLE(kwave_core ${kwave_SRCS}) ############################################################################# TARGET_LINK_LIBRARIES(kwave_core kwavegui kwave audiofile ${SAMPLERATE_LIBS} Qt5::Core Qt5::Widgets KF5::Completion KF5::ConfigCore KF5::Crash KF5::DBusAddons KF5::I18n KF5::IconThemes KF5::KIOFileWidgets KF5::Service KF5::XmlGui ) ADD_DEPENDENCIES(kwave_core libkwavegui libkwave) SET_TARGET_PROPERTIES(kwave_core PROPERTIES OUTPUT_NAME "kwave" ENABLE_EXPORTS TRUE ) ############################################################################# ### install files ### # the main program INSTALL(TARGETS kwave_core DESTINATION ${BIN_INSTALL_DIR}) # other files INSTALL(FILES menus.config DESTINATION ${DATA_INSTALL_DIR}/kwave) INSTALL(FILES ${kwave_PIXMAPS} DESTINATION ${DATA_INSTALL_DIR}/kwave/pics) INSTALL( FILES ${CMAKE_CURRENT_BINARY_DIR}/org.kde.kwave.desktop DESTINATION ${XDG_APPS_INSTALL_DIR} ) # action icons ECM_INSTALL_ICONS( ICONS ${kwave_ACTION_ICONS} DESTINATION ${ICON_INSTALL_DIR} ) # application icon ECM_INSTALL_ICONS( ICONS ${CMAKE_CURRENT_SOURCE_DIR}/pics/sc-apps-kwave.svgz DESTINATION ${ICON_INSTALL_DIR} ) # AppData file INSTALL( FILES org.kde.kwave.appdata.xml DESTINATION ${KDE_INSTALL_METAINFODIR} ) ############################################################################# ############################################################################# diff --git a/kwave/PlayerToolBar.cpp b/kwave/PlayerToolBar.cpp index 36504ddf..1cd65e9b 100644 --- a/kwave/PlayerToolBar.cpp +++ b/kwave/PlayerToolBar.cpp @@ -1,561 +1,544 @@ /*************************************************************************** PlayerToolBar.cpp - Toolbar with control logic for playback/record ------------------- begin : 2012-04-23 copyright : (C) 2012 by Thomas Eschenbacher email : Thomas Eschenbacher ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "config.h" -#include #include +#include +#include #include -#include #include #include "libkwave/FileInfo.h" #include "libkwave/Parser.h" #include "libkwave/PlaybackController.h" #include "libkwave/SignalManager.h" #include "libgui/MenuManager.h" #include "FileContext.h" #include "PlayerToolBar.h" /** default width to skip when doing a "seek" = 1/10 of visible range */ #define SEEK_LENGTH (m_last_visible / 10) /** shortcut for coupling the "enable" of a menu item to a toolbar action */ #define UPDATE_MENU(__action__,__entry__) \ m_menu_manager.setItemEnabled(_(__entry__), \ m_action_##__action__->isEnabled()) /** useful macro for command parsing */ #define CASE_COMMAND(x) } else if (command == _(x)) { //*************************************************************************** Kwave::PlayerToolBar::PlayerToolBar(KMainWindow *parent, const QString &name, Kwave::MenuManager &menu_manager) :KToolBar(name, parent, true), m_context(Q_NULLPTR), m_action_prev(), m_action_rewind(Q_NULLPTR), m_action_record(Q_NULLPTR), m_action_play(Q_NULLPTR), m_action_loop(Q_NULLPTR), m_action_pause(Q_NULLPTR), m_action_stop(Q_NULLPTR), m_action_forward(Q_NULLPTR), m_action_next(Q_NULLPTR), m_pause_timer(Q_NULLPTR), m_blink_on(false), m_playback(Q_NULLPTR), m_menu_manager(menu_manager), m_labels(), m_last_tracks(0), m_last_offset(0), m_last_visible(0), m_last_length(0) { - KIconLoader icon_loader; - const int max_s = KIconLoader::SizeEnormous; - m_action_prev = addAction( - icon_loader.loadIcon(_("kwave_player_start"), - KIconLoader::Toolbar, max_s), + QIcon::fromTheme(_("kwave_player_start")), i18n("Previous"), this, SLOT(toolbarRewindPrev())); m_action_rewind = addAction( - icon_loader.loadIcon(_("kwave_player_rew"), - KIconLoader::Toolbar, max_s), + QIcon::fromTheme(_("kwave_player_rew")), i18n("Rewind"), this, SLOT(toolbarRewind())); m_action_record = addAction( - icon_loader.loadIcon(_("kwave_player_record"), - KIconLoader::Toolbar, max_s), + QIcon::fromTheme(_("kwave_player_record")), i18n("Record"), this, SLOT(toolbarRecord())); m_action_play = addAction( - icon_loader.loadIcon(_("kwave_player_play"), - KIconLoader::Toolbar, max_s), + QIcon::fromTheme(_("kwave_player_play")), i18n("Start playback"), this, SLOT(toolbarStart())); m_action_loop = addAction( - icon_loader.loadIcon(_("kwave_player_loop"), - KIconLoader::Toolbar, max_s), + QIcon::fromTheme(_("kwave_player_loop")), i18n("Start playback and loop"), this, SLOT(toolbarLoop())); m_action_pause = addAction( - icon_loader.loadIcon(_("kwave_player_pause"), - KIconLoader::Toolbar, max_s), + QIcon::fromTheme(_("kwave_player_pause")), QString(), this, SLOT(toolbarPause())); m_action_stop = addAction( - icon_loader.loadIcon(_("kwave_player_stop"), - KIconLoader::Toolbar, max_s), + QIcon::fromTheme(_("kwave_player_stop")), i18n("Stop playback or loop"), this, SLOT(toolbarStop())); m_action_forward = addAction( - icon_loader.loadIcon(_("kwave_player_fwd"), - KIconLoader::Toolbar, max_s), + QIcon::fromTheme(_("kwave_player_fwd")), i18n("Forward"), this, SLOT(toolbarForward())); m_action_next = addAction( - icon_loader.loadIcon(_("kwave_player_end"), - KIconLoader::Toolbar, max_s), + QIcon::fromTheme(_("kwave_player_end")), i18n("Next"), this, SLOT(toolbarForwardNext())); // initial state update updateState(); } //*************************************************************************** Kwave::PlayerToolBar::~PlayerToolBar() { if (m_pause_timer) delete m_pause_timer; m_pause_timer = Q_NULLPTR; m_context = Q_NULLPTR; } //*************************************************************************** void Kwave::PlayerToolBar::contextSwitched(Kwave::FileContext *context) { if (context == m_context) return; // nothing to do // disconnect the playback controller of the previous context if (m_context && m_playback) { disconnect(m_playback, SIGNAL(sigPlaybackStarted()), this, SLOT(updateState())); disconnect(m_playback, SIGNAL(sigPlaybackPaused()), this, SLOT(playbackPaused())); disconnect(m_playback, SIGNAL(sigPlaybackStopped()), this, SLOT(updateState())); disconnect(m_playback, SIGNAL(sigPlaybackPos(sample_index_t)), this, SLOT(updatePlaybackPos(sample_index_t))); disconnect(m_context, SIGNAL(sigVisibleRangeChanged(sample_index_t, sample_index_t, sample_index_t)), this, SLOT(visibleRangeChanged(sample_index_t, sample_index_t, sample_index_t)) ); } // use the new context m_context = context; Kwave::SignalManager *signal = (m_context) ? m_context->signalManager() : Q_NULLPTR; m_playback = (signal) ? &signal->playbackController() : Q_NULLPTR; // connect the playback controller of the new context if (m_context && m_playback) { connect(m_playback, SIGNAL(sigPlaybackStarted()), this, SLOT(updateState())); connect(m_playback, SIGNAL(sigPlaybackPaused()), this, SLOT(playbackPaused())); connect(m_playback, SIGNAL(sigPlaybackStopped()), this, SLOT(updateState())); connect(m_playback, SIGNAL(sigPlaybackPos(sample_index_t)), this, SLOT(updatePlaybackPos(sample_index_t))); connect(m_context, SIGNAL(sigVisibleRangeChanged(sample_index_t, sample_index_t, sample_index_t)), this, SLOT(visibleRangeChanged(sample_index_t, sample_index_t, sample_index_t)) ); } updateState(); } //*************************************************************************** void Kwave::PlayerToolBar::contextDestroyed(Kwave::FileContext *context) { if (context != m_context) return; // not of interest contextSwitched(Q_NULLPTR); } //*************************************************************************** void Kwave::PlayerToolBar::toolbarRewindPrev() { if (!m_action_prev || !m_action_prev->isEnabled() || !m_playback) return; const bool play = m_playback->running() || m_playback->paused(); if (play) { const sample_index_t first = m_playback->startPos(); sample_index_t prev = m_labels.nextLabelLeft(m_playback->currentPos()); if (!m_labels.isEmpty()) { // go to the start marker of the current block if (prev > first) { // seek back to the start of the previous block prev = m_labels.nextLabelLeft(prev); } else if (m_playback->loop()) { // in loop mode: wrap around to last block prev = m_labels.nextLabelLeft(m_playback->endPos()); } } if (prev < first) prev = first; m_playback->seekTo(prev); } else { emit sigCommand(_("view:scroll_prev_label()")); } } //*************************************************************************** void Kwave::PlayerToolBar::toolbarRewind() { if (!m_action_rewind || !m_action_rewind->isEnabled() || !m_playback) return; const bool play = m_playback->running() || m_playback->paused(); if (play) { sample_index_t first = m_playback->startPos(); sample_index_t last = m_playback->endPos(); sample_index_t pos = m_playback->currentPos(); if (pos < first) pos = first; if (pos > last) pos = last; if ((first + SEEK_LENGTH) <= pos) { // simple case: seek without wraparound pos = pos - SEEK_LENGTH; } else if (m_playback->loop() && ((first + SEEK_LENGTH) <= last)) { // loop mode: wrap around pos = last - (first + SEEK_LENGTH - pos); } else { // normal mode: stick to left border pos = first; } m_playback->seekTo(pos); } else { emit sigCommand(_("view:scroll_left()")); } } //*************************************************************************** void Kwave::PlayerToolBar::toolbarRecord() { if (!m_action_record || !m_action_record->isEnabled()) return; emit sigCommand(_("plugin(record)")); } //*************************************************************************** void Kwave::PlayerToolBar::toolbarStart() { if (m_playback) m_playback->playbackStart(); } //*************************************************************************** void Kwave::PlayerToolBar::toolbarLoop() { if (m_playback) m_playback->playbackLoop(); } //*************************************************************************** void Kwave::PlayerToolBar::playbackPaused() { updateState(); if (!m_pause_timer) { m_pause_timer = new QTimer(this); Q_ASSERT(m_pause_timer); if (!m_pause_timer) return; m_blink_on = true; m_pause_timer->start(500); connect(m_pause_timer, SIGNAL(timeout()), this, SLOT(blinkPause())); blinkPause(); } } //*************************************************************************** void Kwave::PlayerToolBar::toolbarPause() { if (!m_action_pause || !m_action_pause->isEnabled() || !m_playback) return; const bool have_signal = (m_last_length && m_last_tracks); const bool playing = m_playback->running(); if (!have_signal) return; if (playing) { m_playback->playbackPause(); } else { m_playback->playbackContinue(); } } //*************************************************************************** void Kwave::PlayerToolBar::toolbarStop() { if (m_playback) m_playback->playbackStop(); } //*************************************************************************** void Kwave::PlayerToolBar::blinkPause() { - KIconLoader icon_loader; - const int max_s = KIconLoader::SizeEnormous; const bool paused = m_playback && m_playback->paused(); Q_ASSERT(m_action_pause); if (!m_action_pause) return; - m_action_pause->setIcon(icon_loader.loadIcon( - _((paused && m_blink_on) ? - "kwave_player_pause_2" : "kwave_player_pause"), - KIconLoader::Toolbar, max_s) - ); + m_action_pause->setIcon(QIcon::fromTheme(_((paused && m_blink_on) ? + "kwave_player_pause_2" : "kwave_player_pause"))); m_blink_on = !m_blink_on; } //*************************************************************************** void Kwave::PlayerToolBar::toolbarForward() { if (!m_action_forward || !m_action_forward->isEnabled() || !m_playback) return; const bool play = m_playback->running() || m_playback->paused(); if (play) { sample_index_t first = m_playback->startPos(); sample_index_t last = m_playback->endPos(); sample_index_t pos = m_playback->currentPos(); if (pos < first) pos = first; if (pos > last) pos = last; if ((pos + SEEK_LENGTH) <= last) { // simple case: seek without wraparound pos = pos + SEEK_LENGTH; } else if (m_playback->loop() && ((first + SEEK_LENGTH) <= last)) { // loop mode: wrap around pos = first + SEEK_LENGTH - (last - pos); } else { // must be loop mode but selection too small: wrap to left border pos = first; } m_playback->seekTo(pos); } else { emit sigCommand(_("view:scroll_right()")); } } //*************************************************************************** void Kwave::PlayerToolBar::toolbarForwardNext() { if (!m_action_next || !m_action_next->isEnabled() || !m_playback) return; const bool play = m_playback->running() || m_playback->paused(); if (play) { sample_index_t last = m_playback->endPos(); sample_index_t next = m_labels.nextLabelRight(m_playback->currentPos()); if (next >= last) next = m_playback->startPos(); // wrap around to start m_playback->seekTo(next); } else { emit sigCommand(_("view:scroll_next_label()")); } } //*************************************************************************** void Kwave::PlayerToolBar::updateState() { if (!m_playback) return; bool have_signal = (m_last_length && m_last_tracks); bool playing = m_playback->running(); bool paused = m_playback->paused(); bool at_start = (m_last_offset == 0); bool at_end = ((m_last_offset + m_last_visible) >= m_last_length); /* --- seek buttons, depending on mode --- */ if (playing || paused) { // seek buttons in playback mode bool loop = m_playback->loop(); sample_index_t pos = m_playback->currentPos(); sample_index_t first = m_playback->startPos(); sample_index_t last = m_playback->endPos(); sample_index_t prev = m_labels.nextLabelLeft(pos); sample_index_t next = m_labels.nextLabelRight(pos); sample_index_t seek_len = SEEK_LENGTH; bool have_label = (prev > first) || (next < last); m_action_prev->setEnabled( (pos > first)); m_action_rewind->setEnabled( (pos > first) || (pos > prev)); m_action_forward->setEnabled( loop || // wrap around in loop mode ((pos + seek_len) < last) // forward a bit, by range ); m_action_next->setEnabled( (loop && have_label) || // wrap around in loop mode (next < last) // snap to next label ); UPDATE_MENU(prev, "ID_PLAYBACK_PREV"); UPDATE_MENU(rewind, "ID_PLAYBACK_REWIND"); UPDATE_MENU(forward,"ID_PLAYBACK_FORWARD"); UPDATE_MENU(next, "ID_PLAYBACK_NEXT"); // scroll controls per menu m_menu_manager.setItemEnabled(_("ID_SCROLL_START"), false); m_menu_manager.setItemEnabled(_("ID_SCROLL_END"), false); m_menu_manager.setItemEnabled(_("ID_SCROLL_PREV"), false); m_menu_manager.setItemEnabled(_("ID_SCROLL_NEXT"), false); m_menu_manager.setItemEnabled(_("ID_SCROLL_RIGHT"), false); m_menu_manager.setItemEnabled(_("ID_SCROLL_LEFT"), false); } else { // seek buttons in normal mode m_action_prev->setEnabled( have_signal && !at_start); m_action_rewind->setEnabled( have_signal && !at_start); m_action_forward->setEnabled( have_signal && !at_end); m_action_next->setEnabled( have_signal && !at_end); m_menu_manager.setItemEnabled(_("ID_PLAYBACK_PREV"), false); m_menu_manager.setItemEnabled(_("ID_PLAYBACK_REWIND"), false); m_menu_manager.setItemEnabled(_("ID_PLAYBACK_FORWARD"), false); m_menu_manager.setItemEnabled(_("ID_PLAYBACK_NEXT"), false); // scroll controls per menu m_menu_manager.setItemEnabled(_("ID_SCROLL_START"), !at_start); m_menu_manager.setItemEnabled(_("ID_SCROLL_END"), !at_end); m_menu_manager.setItemEnabled(_("ID_SCROLL_PREV"), !at_start); m_menu_manager.setItemEnabled(_("ID_SCROLL_NEXT"), !at_end); m_menu_manager.setItemEnabled(_("ID_SCROLL_RIGHT"), !at_end); m_menu_manager.setItemEnabled(_("ID_SCROLL_LEFT"), !at_start); } /* --- standard record/playback controls --- */ m_action_record->setEnabled( !playing && !paused); m_action_play->setEnabled( have_signal && !playing); m_action_loop->setEnabled( have_signal && !playing); m_action_pause->setEnabled( playing || paused); m_action_stop->setEnabled( playing || paused); UPDATE_MENU(record, "ID_RECORD"); UPDATE_MENU(play, "ID_PLAYBACK_START"); UPDATE_MENU(loop, "ID_PLAYBACK_LOOP"); UPDATE_MENU(stop, "ID_PLAYBACK_STOP"); m_menu_manager.setItemEnabled(_("ID_PLAYBACK_PAUSE"), playing); m_menu_manager.setItemEnabled(_("ID_PLAYBACK_CONTINUE"), paused); /* handling of blink timer */ if (m_pause_timer && !paused) { // stop blinking m_pause_timer->stop(); delete m_pause_timer; m_pause_timer = Q_NULLPTR; m_blink_on = false; blinkPause(); m_blink_on = false; } /* pause button: continue/pause playback */ if (paused) { m_action_pause->setToolTip(i18n("Continue playback")); } else { m_action_pause->setToolTip(i18n("Pause playback")); } } //*************************************************************************** void Kwave::PlayerToolBar::updatePlaybackPos(sample_index_t pos) { Q_UNUSED(pos); updateState(); } //*************************************************************************** int Kwave::PlayerToolBar::executeCommand(const QString &command) { int result = 0; Kwave::Parser parser(command); if (false) { CASE_COMMAND("prev") m_action_prev->activate(QAction::Trigger); CASE_COMMAND("rewind") m_action_rewind->activate(QAction::Trigger); CASE_COMMAND("start") m_action_play->activate(QAction::Trigger); CASE_COMMAND("loop") m_action_loop->activate(QAction::Trigger); CASE_COMMAND("pause") m_action_pause->activate(QAction::Trigger); CASE_COMMAND("continue") m_action_pause->activate(QAction::Trigger); CASE_COMMAND("stop") m_action_stop->activate(QAction::Trigger); CASE_COMMAND("forward") m_action_forward->activate(QAction::Trigger); CASE_COMMAND("next") m_action_next->activate(QAction::Trigger); } else { result = -1; // unknown command ? } return result; } //*************************************************************************** void Kwave::PlayerToolBar::metaDataChanged(Kwave::MetaDataList meta_data) { const Kwave::FileInfo info(meta_data); sample_index_t length = info.length(); unsigned int tracks = info.tracks(); bool playing = m_playback && m_playback->running(); m_labels = LabelList(meta_data); if (!playing && (length == m_last_length) && (tracks == m_last_tracks)) return; // nothing interesting for us changed // transition empty <-> not empty m_last_length = length; m_last_tracks = tracks; updateState(); } //*************************************************************************** void Kwave::PlayerToolBar::visibleRangeChanged(sample_index_t offset, sample_index_t visible, sample_index_t total) { bool changed = (offset != m_last_offset) || (visible != m_last_visible) || (total != m_last_length); if (!changed) return; m_last_offset = offset; m_last_visible = visible; m_last_length = total; updateState(); } //*************************************************************************** //*************************************************************************** diff --git a/kwave/TopWidget.cpp b/kwave/TopWidget.cpp index 93ba90e5..d5b7432f 100644 --- a/kwave/TopWidget.cpp +++ b/kwave/TopWidget.cpp @@ -1,1640 +1,1636 @@ /*************************************************************************** TopWidget.cpp - Toplevel widget of Kwave ------------------- begin : 1999 copyright : (C) 1999 by Martin Wilz email : Martin Wilz ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include -#include #include #include -#include - #include +#include #include "libkwave/ClipBoard.h" #include "libkwave/CodecManager.h" #include "libkwave/FileDrag.h" #include "libkwave/LabelList.h" #include "libkwave/Logger.h" #include "libkwave/MessageBox.h" #include "libkwave/MetaDataList.h" #include "libkwave/Parser.h" #include "libkwave/Plugin.h" // for some helper functions #include "libkwave/PluginManager.h" #include "libkwave/SignalManager.h" #include "libkwave/String.h" #include "libkwave/Utils.h" #include "libgui/FileDialog.h" #include "libgui/MenuManager.h" #include "App.h" #include "FileContext.h" #include "MainWidget.h" #include "PlayerToolBar.h" #include "Splash.h" #include "TopWidget.h" #include "ZoomToolBar.h" /** * useful macro for command parsing */ #define CASE_COMMAND(x) } else if (parser.command() == _(x)) { /** toolbar name: file operations */ #define TOOLBAR_FILE _("MainWidget File") /** toolbar name: edit operations */ #define TOOLBAR_EDIT _("MainWidget Edit") /** toolbar name: record and playback */ #define TOOLBAR_RECORD_PLAY _("MainWidget Record/Playback") /** toolbar name: zoom controls */ #define TOOLBAR_ZOOM _("MainWidget Zoom") //*************************************************************************** //*************************************************************************** Kwave::TopWidget::TopWidget(Kwave::App &app) :KMainWindow(), m_application(app), m_context_map(), m_toolbar_record_playback(Q_NULLPTR), m_toolbar_zoom(Q_NULLPTR), m_menu_manager(Q_NULLPTR), m_mdi_area(Q_NULLPTR), m_action_save(Q_NULLPTR), m_action_save_as(Q_NULLPTR), m_action_close(Q_NULLPTR), m_action_undo(Q_NULLPTR), m_action_redo(Q_NULLPTR), m_action_cut(Q_NULLPTR), m_action_copy(Q_NULLPTR), m_action_erase(Q_NULLPTR), m_action_delete(Q_NULLPTR), m_lbl_status_size(Q_NULLPTR), m_lbl_status_mode(Q_NULLPTR), m_lbl_status_cursor(Q_NULLPTR) { // status bar items QStatusBar *status_bar = statusBar(); Q_ASSERT(status_bar); if (!status_bar) return; QLabel *spacer = new QLabel(this); const int frame_style = QFrame::StyledPanel | QFrame::Sunken; status_bar->addWidget(spacer); spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); spacer->setFrameStyle(frame_style); QSizePolicy policy = spacer->sizePolicy(); policy.setHorizontalStretch(100); spacer->setSizePolicy(policy); policy.setHorizontalStretch(0); m_lbl_status_cursor = new QLabel(this); status_bar->addWidget(m_lbl_status_cursor); m_lbl_status_cursor->setSizePolicy(policy); m_lbl_status_cursor->setFrameStyle(frame_style); m_lbl_status_mode = new QLabel(this); status_bar->addWidget(m_lbl_status_mode); m_lbl_status_mode->setSizePolicy(policy); m_lbl_status_mode->setFrameStyle(frame_style); m_lbl_status_size = new QLabel(this); status_bar->addWidget(m_lbl_status_size); m_lbl_status_size->setSizePolicy(policy); m_lbl_status_size->setFrameStyle(frame_style); // start up iconified if requested const QCommandLineParser *args = m_application.cmdline(); bool iconic = (args && args->isSet(_("iconic"))); if (iconic) { showMinimized(); } setAcceptDrops(true); // enable drag&drop // direct all kind of focus to this window per default setFocusPolicy(Qt::WheelFocus); } //*************************************************************************** void Kwave::TopWidget::connectContext(Kwave::FileContext *context) { // connect the context to the top widget connect(context, SIGNAL(sigMetaDataChanged(Kwave::MetaDataList)), this, SLOT(metaDataChanged(Kwave::MetaDataList))); connect(context, SIGNAL(sigSelectionChanged(sample_index_t,sample_index_t)), this, SLOT(selectionChanged(sample_index_t,sample_index_t))); connect(context, SIGNAL(sigUndoRedoInfo(QString,QString)), this, SLOT(setUndoRedoInfo(QString,QString))); connect(context, SIGNAL(sigModified()), this, SLOT(modifiedChanged())); // connect the zoom toolbar connect(context, SIGNAL(sigZoomChanged(Kwave::FileContext*,double)), m_toolbar_zoom, SLOT(setZoomInfo(Kwave::FileContext*,double))); connect(context, SIGNAL(destroyed(Kwave::FileContext*)), m_toolbar_zoom, SLOT(contextDestroyed(Kwave::FileContext*))); // connect the playback/record toolbar connect(context, SIGNAL(destroyed(Kwave::FileContext*)), m_toolbar_record_playback, SLOT(contextDestroyed(Kwave::FileContext*)) ); connect(context, SIGNAL(sigMetaDataChanged(Kwave::MetaDataList)), m_toolbar_record_playback, SLOT(metaDataChanged(Kwave::MetaDataList))); // connect the status bar connect(context, SIGNAL(sigStatusBarMessage(QString,uint)), this, SLOT(showStatusBarMessage(QString,uint))); } //*************************************************************************** Kwave::FileContext *Kwave::TopWidget::newFileContext() { Q_ASSERT(m_toolbar_zoom); if (!m_toolbar_zoom) return Q_NULLPTR; Kwave::FileContext *context = new(std::nothrow) Kwave::FileContext(m_application); if (!context) return Q_NULLPTR; if (!context->init(this)) { delete context; return Q_NULLPTR; } // if we are in SDI mode, there is a context but no MDI sub window // and in MDI/TAB mode we use this special entry for a context that // has just been created but has no sub window yet m_context_map[Q_NULLPTR] = context; // do all signal/slot connections connectContext(context); // if we reach this point everything was ok, now we can safely switch // to the new context emit sigFileContextSwitched(context); return context; } //*************************************************************************** Kwave::FileContext *Kwave::TopWidget::currentContext() const { if (m_context_map.isEmpty()) return Q_NULLPTR; if (m_context_map.contains(Q_NULLPTR)) { // the "null" entry is special, it has precedence over all // other entries. In SDI mode it is the only one ever and in // MDI/TAB mode it is used for a context that has no sub // window yet. return m_context_map[Q_NULLPTR]; } if (m_mdi_area) { // MDI or TAB mode QMdiSubWindow *current_sub = m_mdi_area->currentSubWindow(); if (!m_context_map.contains(current_sub)) { qWarning("WARNING: unassociated MDI sub window %p?", static_cast(current_sub)); QMapIterator it(m_context_map); Kwave::FileContext *context = Q_NULLPTR; while (it.hasNext()) { it.next(); context = it.value(); } return (m_context_map.count() == 1) ? context : Q_NULLPTR; } return m_context_map[current_sub]; } else { // SDI mode Q_ASSERT(0 && "SDI mode but no context?"); return Q_NULLPTR; } } //*************************************************************************** bool Kwave::TopWidget::init() { - KIconLoader icon_loader; - showInSplashSreen(i18n("Loading main menu...")); QMenuBar *menubar = menuBar(); Q_ASSERT(menubar); if (!menubar) return false; m_menu_manager = new(std::nothrow) Kwave::MenuManager(this, *menubar); Q_ASSERT(m_menu_manager); if (!m_menu_manager) return false; // connect clicked menu entries with main communication channel of kwave connect(m_menu_manager, SIGNAL(sigMenuCommand(QString)), this, SLOT(forwardCommand(QString))); connect(&Kwave::ClipBoard::instance(), SIGNAL(clipboardChanged(bool)), this, SLOT(clipboardChanged(bool))); // --- zoom control toolbar --- m_toolbar_zoom = new(std::nothrow) Kwave::ZoomToolBar(this, TOOLBAR_ZOOM); Q_ASSERT(m_toolbar_zoom); if (!m_toolbar_zoom) return false; connect(this, SIGNAL(sigFileContextSwitched(Kwave::FileContext*)), m_toolbar_zoom, SLOT(contextSwitched(Kwave::FileContext*))); // --- playback control toolbar --- m_toolbar_record_playback = new(std::nothrow) Kwave::PlayerToolBar( this, TOOLBAR_RECORD_PLAY, *m_menu_manager); Q_ASSERT(m_toolbar_record_playback); if (!m_toolbar_record_playback) return false; connect(this, SIGNAL(sigFileContextSwitched(Kwave::FileContext*)), m_toolbar_record_playback, SLOT(contextSwitched(Kwave::FileContext*))); connect(m_toolbar_record_playback, SIGNAL(sigCommand(QString)), this, SLOT(forwardCommand(QString))); // -- create a new file context --- Kwave::FileContext *context = newFileContext(); if (!context) return false; QWidget *central_widget = Q_NULLPTR; switch (m_application.guiType()) { case Kwave::App::GUI_SDI: // create a main widget if (!context->createMainWidget(geometry().size() * 0.85)) return false; central_widget = context->mainWidget(); break; case Kwave::App::GUI_MDI: // create a MDI area if required, MDI mode m_mdi_area = new(std::nothrow) QMdiArea(this); Q_ASSERT(m_mdi_area); if (!m_mdi_area) return false; m_mdi_area->setViewMode(QMdiArea::SubWindowView); break; case Kwave::App::GUI_TAB: // create a MDI area if required, TAB mode m_mdi_area = new(std::nothrow) QMdiArea(this); Q_ASSERT(m_mdi_area); if (!m_mdi_area) return false; m_mdi_area->setViewMode(QMdiArea::TabbedView); m_mdi_area->setTabsClosable(true); m_mdi_area->setTabsMovable(true); break; } if (m_mdi_area) { connect(m_mdi_area, SIGNAL(subWindowActivated(QMdiSubWindow*)), this, SLOT(subWindowActivated(QMdiSubWindow*)) ); central_widget = m_mdi_area; } // --- set up the toolbar --- showInSplashSreen(i18n("Initializing toolbar...")); KToolBar *toolbar_file = toolBar(TOOLBAR_FILE); Q_ASSERT(toolbar_file); if (!toolbar_file) return false; // --- file open and save --- toolbar_file->addAction( - icon_loader.loadIcon(_("document-new"), KIconLoader::Toolbar), + QIcon::fromTheme(_("document-new")), i18n("Create a new empty file"), this, SLOT(toolbarFileNew())); toolbar_file->addAction( - icon_loader.loadIcon(_("document-open"), KIconLoader::Toolbar), + QIcon::fromTheme(_("document-open")), i18n("Open an existing file"), this, SLOT(toolbarFileOpen())); m_action_save = toolbar_file->addAction( - icon_loader.loadIcon(_("document-save"), KIconLoader::Toolbar), + QIcon::fromTheme(_("document-save")), i18n("Save the current file"), this, SLOT(toolbarFileSave())); m_action_save_as = toolbar_file->addAction( - icon_loader.loadIcon(_("document-save-as"), KIconLoader::Toolbar), + QIcon::fromTheme(_("document-save-as")), i18n("Save the current file under a different name or file format..."), this, SLOT(toolbarFileSaveAs())); m_action_close = toolbar_file->addAction( - icon_loader.loadIcon(_("document-close"), KIconLoader::Toolbar), + QIcon::fromTheme(_("document-close")), i18n("Close the current file"), this, SLOT(toolbarFileClose())); // --- edit, cut&paste --- KToolBar *toolbar_edit = toolBar(TOOLBAR_EDIT); Q_ASSERT(toolbar_edit); if (!toolbar_edit) return false; m_action_undo = toolbar_edit->addAction( - icon_loader.loadIcon(_("edit-undo"), KIconLoader::Toolbar), + QIcon::fromTheme(_("edit-undo")), i18n("Undo"), this, SLOT(toolbarEditUndo())); m_action_redo = toolbar_edit->addAction( - icon_loader.loadIcon(_("edit-redo"), KIconLoader::Toolbar), + QIcon::fromTheme(_("edit-redo")), i18n("Redo"), this, SLOT(toolbarEditRedo())); m_action_cut = toolbar_edit->addAction( - icon_loader.loadIcon(_("edit-cut"), KIconLoader::Toolbar), + QIcon::fromTheme(_("edit-cut")), i18n("Cut"), this, SLOT(toolbarEditCut())); m_action_copy = toolbar_edit->addAction( - icon_loader.loadIcon(_("edit-copy"), KIconLoader::Toolbar), + QIcon::fromTheme(_("edit-copy")), i18n("Copy"), this, SLOT(toolbarEditCopy())); QAction *btPaste = toolbar_edit->addAction( - icon_loader.loadIcon(_("edit-paste"), KIconLoader::Toolbar), + QIcon::fromTheme(_("edit-paste")), i18n("Insert"), this, SLOT(toolbarEditPaste())); btPaste->setEnabled(!Kwave::ClipBoard::instance().isEmpty()); connect(&Kwave::ClipBoard::instance(), SIGNAL(clipboardChanged(bool)), btPaste, SLOT(setEnabled(bool))); m_action_erase = toolbar_edit->addAction( - icon_loader.loadIcon(_("draw-eraser"), KIconLoader::Toolbar), + QIcon::fromTheme(_("draw-eraser")), i18n("Mute selection"), this, SLOT(toolbarEditErase())); m_action_delete = toolbar_edit->addAction( - icon_loader.loadIcon(_("edit-delete"), KIconLoader::Toolbar), + QIcon::fromTheme(_("edit-delete")), i18n("Delete selection"), this, SLOT(toolbarEditDelete())); // set up the relationship between top widget / mdi area / main widget Q_ASSERT(central_widget); if (!central_widget) return false; setCentralWidget(central_widget); // set a nice initial size of the toplevel window int w = central_widget->minimumSize().width(); w = qMax(w, central_widget->sizeHint().width()); w = qMax(w, width()); int h = qMax(central_widget->sizeHint().height(), (w * 6) / 10); h = qMax(h, height()); resize(w, h); metaDataChanged(Kwave::MetaDataList()); setUndoRedoInfo(QString(), QString()); selectionChanged(0, 0); updateMenu(); updateToolbar(); updateRecentFiles(); // make sure that everything of our window is visible QRect desk = qApp->desktop()->rect(); QRect g = this->geometry(); if (!desk.contains(g)) { // KDE's stupid geometry management has failed ? // this happens when one passes "-geometry x" without // specifying a target position!? // passing "-geometry x--" works... g = desk.intersected(g); setGeometry(g); } // enable saving of window size and position for next startup setAutoSaveSettings(); // workaround for KDE4: detect first startup and set all toolbars // to "only symbols" mode KConfigGroup cfg = KSharedConfig::openConfig()->group("MainWindow"); QString magic = _("3"); if (cfg.readEntry("toolbars") != magic) { qDebug("toolbar layout changed => resetting toolbars to defaults"); // unlock all toolbars KToolBar::setToolBarsLocked(false); // reset all toolbars to default layout resetToolbarToDefaults(); cfg.writeEntry("toolbars", magic); } // make sure we have the focus, not the zoom combo box setFocus(); // special handling: a null string tells the splash screen to hide showInSplashSreen(QString()); return true; } //*************************************************************************** Kwave::TopWidget::~TopWidget() { // close the current file (no matter what the user wants) closeAllSubWindows(); delete m_toolbar_zoom; m_toolbar_zoom = Q_NULLPTR; delete m_toolbar_record_playback; m_toolbar_record_playback = Q_NULLPTR; delete m_menu_manager; m_menu_manager = Q_NULLPTR; while (!m_context_map.isEmpty()) { Kwave::FileContext *context = m_context_map.values().last(); m_context_map.remove(m_context_map.keys().last()); if (context) delete context; } m_application.toplevelWindowHasClosed(this); } //*************************************************************************** QList Kwave::TopWidget::openFiles() const { QList all_files; foreach (Kwave::FileContext *context, m_context_map.values()) { if (!context) continue; QString name = context->signalName(); if (!name.length()) continue; int instance_nr = context->instanceNr(); all_files.append(Kwave::App::FileAndInstance(name, instance_nr)); } return all_files; } //*************************************************************************** QList Kwave::TopWidget::detachAllContexts() { QList list; QMutableMapIterator i(m_context_map); while (i.hasNext()) { i.next(); QMdiSubWindow *sub = i.key(); Kwave::FileContext *context = i.value(); // remove the entry from the map to prevent damage i.remove(); if (sub) { // leave the "minimized" state before migration Qt::WindowStates state = sub->windowState(); if (state & Qt::WindowMinimized) { state &= ~Qt::WindowMinimized; sub->setWindowState(state); sub->showNormal(); } // detach the main widget from the MDI sub window sub->setWidget(Q_NULLPTR); delete sub; } // detach the context from this parent widget if (context) { context->disconnect(); context->setParent(Q_NULLPTR); if (context->isInUse()) list += context; // in use -> keep else context->release(); // empty -> release } } // get rid of the MDI area, it should be empty now setCentralWidget(Q_NULLPTR); if (m_mdi_area) { delete m_mdi_area; m_mdi_area = Q_NULLPTR; } emit sigFileContextSwitched(Q_NULLPTR); return list; } //*************************************************************************** void Kwave::TopWidget::insertContext(Kwave::FileContext *context) { // if no context was given: create a new empty default context if (!context) { context = newFileContext(); Q_ASSERT(context); if (!context) return; if ( (m_application.guiType() == Kwave::App::GUI_SDI) && !context->mainWidget() ) { context->createMainWidget(geometry().size() * 0.85); } // prevent it from getting removed again m_context_map.remove(Q_NULLPTR); } switch (m_application.guiType()) { case Kwave::App::GUI_SDI: // we may have an empty default context -> get rid of it Q_ASSERT(m_context_map.count() <= 1); if (!m_context_map.isEmpty()) { Kwave::FileContext *ctx = m_context_map[Q_NULLPTR]; m_context_map.remove(Q_NULLPTR); if (ctx) ctx->release(); } // take over the new context m_context_map[Q_NULLPTR] = context; connectContext(context); context->setParent(this); // set the central widget to the new main widget setCentralWidget(context->mainWidget()); break; case Kwave::App::GUI_MDI: if (!m_mdi_area) { // create a MDI area if required, MDI mode m_mdi_area = new(std::nothrow) QMdiArea(this); Q_ASSERT(m_mdi_area); if (!m_mdi_area) return; m_mdi_area->setViewMode(QMdiArea::SubWindowView); } /* FALLTHROUGH */ case Kwave::App::GUI_TAB: { // create a MDI area if required, TAB mode if (!m_mdi_area) { m_mdi_area = new(std::nothrow) QMdiArea(this); Q_ASSERT(m_mdi_area); if (!m_mdi_area) return; m_mdi_area->setViewMode(QMdiArea::TabbedView); m_mdi_area->setTabsClosable(true); m_mdi_area->setTabsMovable(true); } context->setParent(this); setCentralWidget(m_mdi_area); connect(m_mdi_area, SIGNAL(subWindowActivated(QMdiSubWindow*)), this, SLOT(subWindowActivated(QMdiSubWindow*)) ); QWidget *main_widget = context->mainWidget(); if (main_widget) { QMdiSubWindow *sub = m_mdi_area->addSubWindow( main_widget, Qt::SubWindow); Q_ASSERT(sub); if (!sub) return; sub->adjustSize(); if (m_context_map.contains(Q_NULLPTR)) m_context_map.remove(Q_NULLPTR); m_context_map[sub] = context; connect(context->mainWidget(), SIGNAL(destroyed(QObject*)), sub, SLOT(close())); connect(sub, SIGNAL(destroyed(QObject*)), this, SLOT(subWindowDeleted(QObject*))); connectContext(context); if (m_application.guiType() != Kwave::App::GUI_SDI) { // this really sucks... // Qt adds a "Close" entry to the MDI subwindow's system // menu, with the shortcut "Ctrl+W". This collides with // our own shortcut, produces a warning and makes the // shortcut key not work: // QAction::eventFilter: Ambiguous shortcut overload: Ctrl+W QMenu *m = sub->systemMenu(); if (m) { foreach (QAction *act, m->actions()) if (act) act->setShortcut(0); // remove shortcut } } sub->setAttribute(Qt::WA_DeleteOnClose); main_widget->setWindowTitle(context->windowCaption(true)); // workaround for stupid bug in Qt: when having only one // single sub window, switching to tab mode shows a tab + // a sub window with frame and title (not maximized within // the mdi area) Qt::WindowStates state = sub->windowState(); if (m_application.guiType() == Kwave::App::GUI_TAB) { state |= Qt::WindowMaximized; sub->setWindowState(state); sub->show(); } else { state &= ~Qt::WindowMaximized; sub->setWindowState(state); sub->showNormal(); } // NOTE: we have to mark the sub window as "not hidden", // otherwise currentSubWindow() would return a null pointer! sub->setHidden(false); m_mdi_area->setActiveSubWindow(sub); } else { m_context_map[Q_NULLPTR] = context; // set empty default context } break; } } // update the menu bar, toolbar etc. emit sigFileContextSwitched(Q_NULLPTR); emit sigFileContextSwitched(context); updateMenu(); updateToolbar(); updateCaption(); } //*************************************************************************** int Kwave::TopWidget::executeCommand(const QString &line) { int result = 0; QString command = line; // qDebug("TopWidget::executeCommand(%s)", DBG(command)); if (!command.length()) return 0; // empty line -> nothing to do // parse one single command Kwave::Parser parser(command); // playback commands are always possible if ( (parser.command() == _("playback")) && (m_toolbar_record_playback) ) return m_toolbar_record_playback->executeCommand(parser.firstParam()); if ((result = m_application.executeCommand(command)) != ENOSYS) return result; result = 0; if (false) { CASE_COMMAND("about_kde") // Help / About KDE KHelpMenu *dlg = new KHelpMenu(this, _("Kwave")); if (dlg) dlg->aboutKDE(); result = 0; CASE_COMMAND("menu") Q_ASSERT(m_menu_manager); if (m_menu_manager) result = m_menu_manager->executeCommand(command); CASE_COMMAND("newsignal") sample_index_t samples = parser.toSampleIndex(); double rate = parser.toDouble(); unsigned int bits = parser.toUInt(); unsigned int tracks = parser.toUInt(); result = newSignal(samples, rate, bits, tracks); CASE_COMMAND("open") QString filename = parser.nextParam(); if (!filename.isEmpty()) { // open the selected file result = loadFile(QUrl::fromUserInput(filename)); } else { // show file open dialog result = openFile(); } CASE_COMMAND("openrecent") result = openRecent(command); CASE_COMMAND("quit") result = (close()) ? 0 : -1; CASE_COMMAND("reset_toolbars") if ((result = (Kwave::MessageBox::questionYesNo(this, i18n("Reset the toolbar to default settings?")) == KMessageBox::Yes) ? 1 : 0)) { resetToolbarToDefaults(); } result = 0; CASE_COMMAND("select_gui_type") QString gui_type = parser.nextParam(); Kwave::App::GuiType new_type = Kwave::App::GUI_SDI; if (gui_type == _("SDI")) new_type = Kwave::App::GUI_SDI; else if (gui_type == _("MDI")) new_type = Kwave::App::GUI_MDI; else if (gui_type == _("TAB")) new_type = Kwave::App::GUI_TAB; else return -1; KConfigGroup cfg = KSharedConfig::openConfig()->group("Global"); cfg.writeEntry(_("UI Type"), gui_type); m_application.switchGuiType(this, new_type); result = 0; CASE_COMMAND("reenable_dna") if ((result = (Kwave::MessageBox::questionYesNo(this, i18n("Re-enable all disabled notifications?\n" "All messages that you previously turned off by activating " "the \"Do not ask again\" checkbox will then be enabled again." )) == KMessageBox::Yes) ? 1 : 0)) { KMessageBox::enableAllMessages(); } result = 0; CASE_COMMAND("window:minimize") if (m_application.guiType() == Kwave::App::GUI_MDI) { // in case of MDI mode: minimize the current sub window if (m_mdi_area) { QMdiSubWindow *sub = m_mdi_area->activeSubWindow(); if (!sub) return -1; sub->setWindowState(windowState() | Qt::WindowMinimized); } } else { // in case of TAB or SDI mode: minimize the toplevel window setWindowState(windowState() | Qt::WindowMinimized); } result = 0; CASE_COMMAND("window:next_sub") if (m_mdi_area) m_mdi_area->activateNextSubWindow(); result = 0; CASE_COMMAND("window:prev_sub") if (m_mdi_area) m_mdi_area->activatePreviousSubWindow(); result = 0; CASE_COMMAND("window:cascade") if (m_mdi_area) m_mdi_area->cascadeSubWindows(); result = 0; CASE_COMMAND("window:tile") if (m_mdi_area) m_mdi_area->tileSubWindows(); result = 0; CASE_COMMAND("window:tile_vertical") if (!m_mdi_area) return 0; // determine the number of not minimized sub windows int count = 0; foreach (QMdiSubWindow *sub, m_mdi_area->subWindowList()) { if (sub && !(sub->windowState() & Qt::WindowMinimized)) ++count; } if (!count) return 0; int total_height = m_mdi_area->height(); int width = m_mdi_area->width(); int height = total_height / count; int increment = height; int y = 0; foreach (QMdiSubWindow *sub, m_mdi_area->subWindowList()) { if (!sub || (sub->windowState() & Qt::WindowMinimized)) continue; // resize/move the sub window sub->resize(width, height); sub->move(0, y); y += increment; } result = 0; CASE_COMMAND("window:activate") if (m_mdi_area) { QString title = parser.nextParam(); foreach (QMdiSubWindow *sub, m_context_map.keys()) { if (!sub) continue; Kwave::FileContext *context = m_context_map[sub]; if (!context) continue; // identify the window by it's title if (context->windowCaption(false) == title) { // activate the sub window if it is not the active one if (m_mdi_area->activeSubWindow() != sub) m_mdi_area->setActiveSubWindow(sub); // leave the "minimized" state if necessary Qt::WindowStates state = sub->windowState(); if (state & Qt::WindowMinimized) sub->setWindowState(state & ~(Qt::WindowMinimized)); sub->raise(); return 0; } } } else return ENOSYS; return EINVAL; } else { return ENOSYS; // command not implemented (here) } return result; } //*************************************************************************** int Kwave::TopWidget::forwardCommand(const QString &command) { Kwave::FileContext *context = currentContext(); if (!context) return EAGAIN; // execute the command in the current context int retval = context->executeCommand(command); // synchronize after the command Kwave::PluginManager *plugin_manager = context->pluginManager(); if (plugin_manager) plugin_manager->sync(); return retval; } //*************************************************************************** bool Kwave::TopWidget::closeAllSubWindows() { bool allowed = true; QMutableMapIterator it(m_context_map); it.toBack(); while (it.hasPrevious()) { it.previous(); QMdiSubWindow *sub = it.key(); Kwave::FileContext *context = it.value(); if (!sub) { // reached the default context (without sub windows) // or SDI mode with only one context if (context) allowed &= context->closeFile(); break; } if (!context) { // invalid entry? it.remove(); continue; } // try to close the sub window / context if (!sub->close()) { allowed = false; break; } else { it.remove(); if (m_context_map.isEmpty()) { // keep the default context, without a window m_context_map[Q_NULLPTR] = context; break; } } } return allowed; } //*************************************************************************** int Kwave::TopWidget::newWindow(Kwave::FileContext *&context, const QUrl &url) { switch (m_application.guiType()) { case Kwave::App::GUI_SDI: { // SDI mode and already something loaded // -> open a new toplevel window // (except for processing commands per kwave: URL Kwave::SignalManager *signal_manager = (context) ? context->signalManager() : Q_NULLPTR; if ( signal_manager && !signal_manager->isEmpty() && (url.scheme().toLower() != Kwave::urlScheme()) ) return m_application.newWindow(url); // try to close the previous file if (context && !context->closeFile()) return -1; break; } case Kwave::App::GUI_MDI: /* FALLTHROUGH */ case Kwave::App::GUI_TAB: // MDI or TAB mode: open a new sub window Q_ASSERT(m_mdi_area); if (!m_mdi_area) return -1; if (context && context->isEmpty()) { // current context is empty, no main widget etc -> discard it if (m_context_map.contains(Q_NULLPTR)) { // must have been the default context Q_ASSERT(m_context_map[Q_NULLPTR] == context); m_context_map.remove(Q_NULLPTR); } // NOTE: do not handle the following context switch // notification, it might be handled with a // refcount that has already been set to zero disconnect( this, SIGNAL(sigFileContextSwitched(Kwave::FileContext*)), context, SLOT(contextSwitched(Kwave::FileContext*)) ); context->release(); } // create a new file context context = newFileContext(); if (!context) return -1; // create a main widget if (!context->createMainWidget( m_mdi_area->geometry().size() * 0.85)) return -1; // insert the context into this instance insertContext(context); break; } return 1; } //*************************************************************************** int Kwave::TopWidget::loadFile(const QUrl &url) { Kwave::FileContext *context = currentContext(); // special handling for kwave: URLs if (url.scheme().toLower() == Kwave::urlScheme()) { QString cmd = Kwave::Parser::fromUrl(url); Kwave::Logger::log(this, Kwave::Logger::Info, _("CMD: from command line: '") + cmd + _("'")); Kwave::Splash::showMessage(i18n("Executing command '%1'...", cmd)); return (context) ? context->executeCommand(cmd) : executeCommand(cmd); } if (!context) return -1; Kwave::SignalManager *signal_manager = context->signalManager(); Q_ASSERT(signal_manager); // add an entry to the list of recent files m_application.addRecentFile(url.isLocalFile() ? url.toLocalFile() : url.toDisplayString()); // abort if new file not valid and local if (!url.isLocalFile()) return -1; // detect whether it is a macro (batch) file QFileInfo file(url.fileName()); QString suffix = file.suffix(); if (suffix == _("kwave")) { Kwave::Splash::showMessage( i18n("Executing Kwave script file '%1'...", url.toDisplayString()) ); return context->loadBatch(url); } // open a new window (empty in case of MDI/TAB) int retval = newWindow(context, url); if ((retval <= 0) || !context) return retval; Kwave::Splash::showMessage( i18n("Loading file '%1'...", url.toDisplayString()) ); // NOTE: the context may have changed, now we may have a different // signal manager signal_manager = context->signalManager(); int res = -ENOMEM; if (signal_manager && !(res = signal_manager->loadFile(url))) { // succeeded } else { qWarning("TopWidget::loadFile() failed: result=%d", res); QString reason; switch (res) { case -ENOMEM: reason = i18n("Out of memory"); break; case -EIO: reason = i18nc("error message after opening a file failed", "Unable to open '%1'", url.toDisplayString()); break; case -EINVAL: reason = i18nc("error message after opening a file failed", "Invalid or unknown file type: '%1'", url.toDisplayString()); break; default: reason = _(""); } // show an error message box if the reason was known if (reason.length()) { Kwave::MessageBox::error(this, reason); } // load failed context->closeFile(); } updateMenu(); updateToolbar(); return 0; } //*************************************************************************** int Kwave::TopWidget::openRecent(const QString &str) { Kwave::Parser parser(str); return loadFile(QUrl::fromUserInput(parser.firstParam())); } //*************************************************************************** int Kwave::TopWidget::openFile() { QString filter = Kwave::CodecManager::decodingFilter(); QPointer dlg = new (std::nothrow) Kwave::FileDialog( _("kfiledialog:///kwave_open_dir"), Kwave::FileDialog::OpenFile, filter, this ); if (!dlg) return -1; dlg->setWindowTitle(i18n("Open")); if (dlg->exec() == QDialog::Accepted) { QUrl url = dlg->selectedUrl(); delete dlg; return loadFile(url); } else { delete dlg; return -1; } } //*************************************************************************** int Kwave::TopWidget::newSignal(sample_index_t samples, double rate, unsigned int bits, unsigned int tracks) { Kwave::FileContext *context = currentContext(); if (!context) return -1; Kwave::SignalManager *signal_manager = context->signalManager(); if (!signal_manager) return -1; QUrl url = Kwave::Parser::toUrl( _("newsignal(%1,%2,%3,%4)" ).arg(samples).arg(rate).arg(bits).arg(tracks)); int retval = newWindow(context, url); if (retval <= 0) return retval; signal_manager = context->signalManager(); if (!signal_manager) return -1; signal_manager->newSignal(samples, rate, bits, tracks); return 0; } //*************************************************************************** void Kwave::TopWidget::metaDataChanged(Kwave::MetaDataList meta_data) { Q_ASSERT(statusBar()); if (!statusBar() || !m_menu_manager) return; QString txt; const Kwave::FileInfo info(meta_data); sample_index_t length = info.length(); unsigned int tracks = info.tracks(); double rate = info.rate(); unsigned int bits = info.bits(); // length in milliseconds if (length) { double ms = (rate > 0) ? (static_cast(length) / static_cast(rate) * 1E3) : 0; txt = _(" ") + i18nc( "Length, as in total duration of loaded song", "Length: %1 (%2 samples)", Kwave::ms2string(ms), Kwave::samples2string(length) ) + _(" "); } else txt = _(""); m_lbl_status_size->setText(txt); // sample rate and resolution if (bits) { QString khz = _("%0.3f"); khz = khz.sprintf("%0.3f", static_cast(rate) * 1E-3); txt = _(" ") + i18n("Mode: %1 kHz @ %2 Bit", khz, bits) + _(" "); } else txt = _(""); m_lbl_status_mode->setText(txt); // remove selection/position display on file close bool have_signal = (tracks != 0); if (!have_signal) selectionChanged(0, 0); // update the menu updateMenu(); // update the toolbar as well updateToolbar(); // update the window caption updateCaption(); } //*************************************************************************** void Kwave::TopWidget::selectionChanged(sample_index_t offset, sample_index_t length) { const Kwave::FileContext *context = currentContext(); if (!context) return; Kwave::SignalManager *signal_manager = context->signalManager(); Q_ASSERT(signal_manager); if (!signal_manager) return; Q_ASSERT(statusBar()); if (!statusBar()) return; // force sample mode if rate==0 const double rate = signal_manager->rate(); const bool sample_mode = (qFuzzyIsNull(rate)); if (length > 1) { // show offset and length // Selected: 2000...3000 (1000 samples) // Selected: 02:00...05:00 (3 min) sample_index_t last = offset + ((length) ? length-1 : 0); QString txt = _(" "); if (sample_mode) { txt += i18nc( "%1=first sample, %2=last sample, %3=number of samples, "\ "example: 'Selected: 2000...3000 (1000 samples)'", "Selected: %1...%2 (%3 samples)", Kwave::samples2string(offset), Kwave::samples2string(last), Kwave::samples2string(length) ); } else { double ms_first = static_cast(offset) * 1E3 / rate; double ms_last = static_cast(last + 1) * 1E3 / rate; double ms = (ms_last - ms_first); txt += i18nc( "%1=start time, %2=end time, %3=time span, "\ "example: 'Selected: 02:00...05:00 (3 min)'", "Selected: %1...%2 (%3)", Kwave::ms2string(ms_first), Kwave::ms2string(ms_last), Kwave::ms2string(ms) ); } m_lbl_status_cursor->setText(_("")); statusBar()->showMessage(txt, 4000); if (m_menu_manager) m_menu_manager->setItemEnabled(_("@SELECTION"), true); } else { // show cursor position // Position: 02:00 if (sample_mode || !signal_manager->tracks()) { m_lbl_status_cursor->setText(_("")); } else { double ms_first = static_cast(offset) * 1E3 / rate; QString txt = i18n("Position: %1", Kwave::ms2string(ms_first)); m_lbl_status_cursor->setText(txt); } if (m_menu_manager) m_menu_manager->setItemEnabled(_("@SELECTION"), false); } // update the toolbar on selection change, maybe the // button for "zoom selection" has to be enabled/disabled updateToolbar(); } //*************************************************************************** void Kwave::TopWidget::setUndoRedoInfo(const QString &undo, const QString &redo) { QString txt; bool undo_enabled = (undo.length() != 0); bool redo_enabled = (redo.length() != 0); // set the state and tooltip of the undo toolbar button if (m_action_undo) { txt = (undo_enabled) ? i18nc("tooltip of the undo toolbar button if undo enabled", "Undo (%1)", undo) : i18nc("tooltip of the undo toolbar button if undo disabled", "Undo"); m_action_undo->setToolTip(txt); m_action_undo->setEnabled(undo_enabled); } // set the state and tooltip of the redo toolbar button if (m_action_redo) { txt = (redo_enabled) ? i18nc("tooltip of the redo toolbar button, redo enabled", "Redo (%1)", redo) : i18nc("tooltip of the redo toolbar button, redo disabled", "Redo"); m_action_redo->setToolTip(txt); m_action_redo->setEnabled(redo_enabled); } if (!m_menu_manager) return; // set new enable and text of the undo menu entry m_menu_manager->setItemEnabled(_("ID_EDIT_UNDO"), undo_enabled); txt = (undo_enabled) ? i18nc("menu entry for undo if undo enabled", "Undo (%1)", undo) : i18nc("menu entry for undo if undo disabled", "Undo"); m_menu_manager->setItemText(_("ID_EDIT_UNDO"), txt); // set new enable and text of the undo menu entry m_menu_manager->setItemEnabled(_("ID_EDIT_REDO"), redo_enabled); txt = (redo_enabled) ? i18nc("menu entry for redo if redo enabled", "Redo (%1)", redo) : i18nc("menu entry for redo if redo disabled", "Redo"); m_menu_manager->setItemText(_("ID_EDIT_REDO"), txt); } //*************************************************************************** void Kwave::TopWidget::clipboardChanged(bool data_available) { if (!m_menu_manager) return; m_menu_manager->setItemEnabled(_("@CLIPBOARD"), data_available); } //*************************************************************************** void Kwave::TopWidget::updateRecentFiles() { Q_ASSERT(m_menu_manager); if (!m_menu_manager) return; m_menu_manager->clearNumberedMenu(_("ID_FILE_OPEN_RECENT")); foreach (const QString &file, m_application.recentFiles()) m_menu_manager->addNumberedMenuEntry( _("ID_FILE_OPEN_RECENT"), file, QString()); // enable/disable the "clear" menu entry in Files / Open Recent m_menu_manager->setItemEnabled(_("ID_FILE_OPEN_RECENT_CLEAR"), !m_application.recentFiles().isEmpty()); } //*************************************************************************** void Kwave::TopWidget::updateMenu() { const Kwave::FileContext *context = currentContext(); Kwave::SignalManager *signal_manager = (context) ? context->signalManager() : Q_NULLPTR; Q_ASSERT(m_menu_manager); if (!m_menu_manager) return; bool have_window_menu = false; switch (m_application.guiType()) { case Kwave::App::GUI_SDI: m_menu_manager->selectItem(_("@GUI_TYPE"), _("ID_GUI_SDI")); m_menu_manager->setItemVisible(_("ID_WINDOW"), false); m_menu_manager->setItemVisible(_("ID_WINDOW_NEXT"), false); m_menu_manager->setItemVisible(_("ID_WINDOW_PREV"), false); m_menu_manager->setItemVisible(_("ID_WINDOW_CASCADE"), false); m_menu_manager->setItemVisible(_("ID_WINDOW_TILE"), false); m_menu_manager->setItemVisible(_("ID_WINDOW_TILE_VERTICAL"), false); m_menu_manager->setItemVisible(_("ID_FILE_NEW_WINDOW"), true); break; case Kwave::App::GUI_MDI: m_menu_manager->selectItem(_("@GUI_TYPE"), _("ID_GUI_MDI")); m_menu_manager->setItemVisible(_("ID_WINDOW"), true); m_menu_manager->setItemVisible(_("ID_WINDOW_NEXT"), true); m_menu_manager->setItemVisible(_("ID_WINDOW_PREV"), true); m_menu_manager->setItemVisible(_("ID_WINDOW_CASCADE"), true); m_menu_manager->setItemVisible(_("ID_WINDOW_TILE"), true); m_menu_manager->setItemVisible(_("ID_WINDOW_TILE_VERTICAL"), true); m_menu_manager->setItemVisible(_("ID_FILE_NEW_WINDOW"), false); have_window_menu = true; break; case Kwave::App::GUI_TAB: m_menu_manager->selectItem(_("@GUI_TYPE"), _("ID_GUI_TAB")); m_menu_manager->setItemVisible(_("ID_WINDOW"), true); m_menu_manager->setItemVisible(_("ID_WINDOW_NEXT"), true); m_menu_manager->setItemVisible(_("ID_WINDOW_PREV"), true); m_menu_manager->setItemVisible(_("ID_WINDOW_CASCADE"), false); m_menu_manager->setItemVisible(_("ID_WINDOW_TILE"), false); m_menu_manager->setItemVisible(_("ID_WINDOW_TILE_VERTICAL"), false); m_menu_manager->setItemVisible(_("ID_FILE_NEW_WINDOW"), false); have_window_menu = true; break; } if (have_window_menu) { // update the "Windows" menu m_menu_manager->clearNumberedMenu(_("ID_WINDOW_LIST")); unsigned int win_count = 0; foreach (const Kwave::FileContext *ctx, m_context_map.values()) { if (!ctx) continue; QString caption = ctx->windowCaption(false); if (!caption.length()) continue; m_menu_manager->addNumberedMenuEntry(_("ID_WINDOW_LIST"), caption, QString()); ++win_count; } bool on = (win_count > 1); m_menu_manager->setItemEnabled(_("ID_WINDOW_NEXT"), on); m_menu_manager->setItemEnabled(_("ID_WINDOW_PREV"), on); m_menu_manager->setItemEnabled(_("ID_WINDOW_CASCADE"), on); m_menu_manager->setItemEnabled(_("ID_WINDOW_TILE"), on); m_menu_manager->setItemEnabled(_("ID_WINDOW_TILE_VERTICAL"), on); } // enable/disable all items that depend on having a file bool have_file = (context && context->signalName().length()); m_menu_manager->setItemEnabled(_("@NOT_CLOSED"), have_file); // enable/disable all items that depend on having a label // and update the label menu bool have_labels = false; if (signal_manager) { Kwave::LabelList labels(signal_manager->metaData()); have_labels = !labels.isEmpty(); m_menu_manager->clearNumberedMenu(_("ID_LABEL_DELETE")); if (labels.count()) { // add special entry to delete all labels m_menu_manager->addNumberedMenuEntry( _("ID_LABEL_DELETE"), i18nc("special entry in the list of labels to delete all", "(All)"), _("-1")); // iterate over the list of labels unsigned int index = 0; foreach (const Kwave::Label &label, labels) { QString name = label.name(); QString desc = (name.length()) ? i18nc( "list menu entry of a label, %1=index, %2=description/name", "#%1 (%2)", index, name) : i18nc("list menue entry of a label, " "without description, %1=index", "#%1", index); m_menu_manager->addNumberedMenuEntry( _("ID_LABEL_DELETE"), desc, name.setNum(index)); index++; } } } m_menu_manager->setItemEnabled(_("@LABELS"), have_labels); // update the list of deletable tracks unsigned int tracks = (signal_manager) ? signal_manager->tracks() : 0; m_menu_manager->clearNumberedMenu(_("ID_EDIT_TRACK_DELETE")); QString buf; for (unsigned int i = 0; i < tracks; i++) { m_menu_manager->addNumberedMenuEntry( _("ID_EDIT_TRACK_DELETE"), buf.setNum(i), buf.setNum(i)); } // enable/disable all items that depend on having a signal bool have_signal = (tracks != 0); m_menu_manager->setItemEnabled(_("@SIGNAL"), have_signal); // revert is only possible if the signal exists, is modified and there // is a file behind from which we could reload (which is not the case // after File/New...). bool enable_revert = false; if (signal_manager) { bool have_filename = Kwave::FileInfo( signal_manager->metaData() ).contains(Kwave::INF_FILENAME); bool is_modified = signal_manager->isModified(); enable_revert = have_filename && is_modified; } m_menu_manager->setItemEnabled(_("ID_FILE_REVERT"), enable_revert); // enable/disable all items that depend on having something in the // clipboard bool have_clipboard_data = !Kwave::ClipBoard::instance().isEmpty(); clipboardChanged(have_clipboard_data); } //*************************************************************************** void Kwave::TopWidget::resetToolbarToDefaults() { KToolBar *toolbar_file = toolBar(TOOLBAR_FILE); KToolBar *toolbar_edit = toolBar(TOOLBAR_EDIT); KToolBar *toolbar_record_play = toolBar(TOOLBAR_RECORD_PLAY); KToolBar *toolbar_zoom = toolBar(TOOLBAR_ZOOM); int icon_size_def = style()->pixelMetric(QStyle::PM_ToolBarIconSize); int icon_size_big = style()->pixelMetric(QStyle::PM_LargeIconSize); // change style to "symbols only mode" and set standard size foreach(KToolBar *bar, toolBars()) { bar->setToolButtonStyle(Qt::ToolButtonIconOnly); bar->setIconSize( QSize(icon_size_def, icon_size_def) ); } // re-order the tool bars: // ----------------------- // file | edit | // ----------------------- // record/play | zoom // ----------------------- insertToolBar(toolbar_zoom, toolbar_record_play); insertToolBar(toolbar_record_play, toolbar_edit); insertToolBar(toolbar_edit, toolbar_file); // move record/playback into a separate line, below file/edit insertToolBarBreak(toolbar_record_play); // let record/playback and zoom use bigger icons toolbar_record_play->setIconSize(QSize(icon_size_big, icon_size_big)); toolbar_zoom->setIconSize(QSize(icon_size_big, icon_size_big)); foreach(KToolBar *bar, toolBars()) { bar->update(); bar->show(); } } //*************************************************************************** void Kwave::TopWidget::updateToolbar() { const Kwave::FileContext *context = currentContext(); if (!context) return; Kwave::SignalManager *signal_manager = context->signalManager(); Q_ASSERT(signal_manager); if (!signal_manager) return; bool have_signal = signal_manager->tracks(); if (m_action_save) m_action_save->setEnabled(have_signal); if (m_action_save_as) m_action_save_as->setEnabled(have_signal); if (m_action_close) m_action_close->setEnabled(have_signal); bool have_selection = (signal_manager->selection().length() > 1); if (m_action_cut) m_action_cut->setEnabled(have_selection); if (m_action_copy) m_action_copy->setEnabled(have_selection); if (m_action_erase) m_action_erase->setEnabled(have_selection); if (m_action_delete) m_action_delete->setEnabled(have_selection); // update the zoom toolbar if (m_toolbar_zoom) m_toolbar_zoom->updateToolbar(); } //*************************************************************************** void Kwave::TopWidget::modifiedChanged() { updateCaption(); updateMenu(); } //*************************************************************************** void Kwave::TopWidget::updateCaption() { const Kwave::FileContext *context = currentContext(); QString caption = (context) ? context->windowCaption(true) : QString(); setCaption(caption); } //*************************************************************************** void Kwave::TopWidget::closeEvent(QCloseEvent *e) { (closeAllSubWindows()) ? e->accept() : e->ignore(); } //*************************************************************************** void Kwave::TopWidget::showInSplashSreen(const QString &message) { Kwave::Splash::showMessage(message); } //*************************************************************************** void Kwave::TopWidget::showStatusBarMessage(const QString &msg, unsigned int ms) { QStatusBar *status_bar = statusBar(); if (!status_bar) return; if (msg.length()) status_bar->showMessage(msg, ms); else status_bar->clearMessage(); } //*************************************************************************** void Kwave::TopWidget::subWindowActivated(QMdiSubWindow *sub) { if (!sub || !m_context_map.contains(sub)) return; emit sigFileContextSwitched(currentContext()); } //*************************************************************************** void Kwave::TopWidget::subWindowDeleted(QObject *obj) { QMdiSubWindow *sub = static_cast(obj); if (!sub || !m_context_map.contains(sub)) { // sub window is not in the map, maybe it has already been detached return; } Kwave::FileContext *context = m_context_map[sub]; Q_ASSERT(context); if (!context) return; m_context_map.remove(sub); if (m_context_map.isEmpty()) { // keep the default context, without a window m_context_map[Q_NULLPTR] = context; } else { // remove the context context->release(); } } //*************************************************************************** void Kwave::TopWidget::dragEnterEvent(QDragEnterEvent *event) { if (!event) return; if ((event->proposedAction() != Qt::MoveAction) && (event->proposedAction() != Qt::CopyAction)) return; /* unsupported action */ if (Kwave::FileDrag::canDecode(event->mimeData())) event->acceptProposedAction(); } //*************************************************************************** void Kwave::TopWidget::dropEvent(QDropEvent *event) { if (!event) return; if (!event->mimeData()) return; if (event->mimeData()->hasUrls()) { bool first = true; foreach (const QUrl &url, event->mimeData()->urls()) { QString filename = url.toLocalFile(); QString mimetype = Kwave::CodecManager::mimeTypeOf(url); if (Kwave::CodecManager::canDecode(mimetype)) { if (first) { // first dropped URL -> open in this window forwardCommand(_("open(%1)").arg( Kwave::Parser::escape(filename))); first = false; } else { // all others -> open a new window forwardCommand(_("newwindow(%1)").arg( Kwave::Parser::escape(filename))); } } } } } //*************************************************************************** //*************************************************************************** diff --git a/kwave/ZoomToolBar.cpp b/kwave/ZoomToolBar.cpp index 3a9276a3..d47689c6 100644 --- a/kwave/ZoomToolBar.cpp +++ b/kwave/ZoomToolBar.cpp @@ -1,334 +1,326 @@ /*************************************************************************** ZoomToolBar.cpp - Toolbar for zoom control ------------------- begin : 2014-08-12 copyright : (C) 2014 by Thomas Eschenbacher email : Thomas Eschenbacher ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "config.h" #include #include +#include #include #include -#include #include #include "libkwave/Selection.h" #include "libkwave/SignalManager.h" #include "libkwave/Utils.h" #include "libgui/MenuManager.h" #include "libgui/Zoomable.h" #include "FileContext.h" #include "ZoomToolBar.h" /** role value for entries in the zoom combo box, "predefined" flag (bool) */ #define ZOOM_DATA_PREDEFINED (Qt::UserRole + 0) /** role value for entries in the zoom combo box, "time" in ms (double) */ #define ZOOM_DATA_TIME (Qt::UserRole + 1) /** returns the number of elements of an array */ #define ELEMENTS_OF(__x__) (sizeof(__x__) / sizeof(__x__[0])) //*************************************************************************** Kwave::ZoomToolBar::ZoomToolBar(KMainWindow *parent, const QString &name) :KToolBar(name, parent, true), m_context(Q_NULLPTR), m_action_zoomselection(Q_NULLPTR), m_action_zoomin(Q_NULLPTR), m_action_zoomout(Q_NULLPTR), m_action_zoomnormal(Q_NULLPTR), m_action_zoomall(Q_NULLPTR), m_action_zoomselect(Q_NULLPTR), m_zoomselect(Q_NULLPTR) { - KIconLoader icon_loader; - const int max_s = KIconLoader::SizeEnormous; - m_action_zoomselection = addAction( - icon_loader.loadIcon(_("kwave_viewmag"), - KIconLoader::Toolbar, max_s), + QIcon::fromTheme(_("kwave_viewmag")), i18n("Zoom to selection"), this, SLOT(zoomSelection())); m_action_zoomin = addAction( - icon_loader.loadIcon(_("kwave_zoom_in"), - KIconLoader::Toolbar, max_s), + QIcon::fromTheme(_("kwave_zoom_in")), i18n("Zoom in"), this, SLOT(zoomIn())); m_action_zoomout = addAction( - icon_loader.loadIcon(_("kwave_zoom_out"), - KIconLoader::Toolbar, max_s), + QIcon::fromTheme(_("kwave_zoom_out")), i18n("Zoom out"), this, SLOT(zoomOut())); m_action_zoomnormal = addAction( - icon_loader.loadIcon(_("kwave_zoom_original"), - KIconLoader::Toolbar, max_s), + QIcon::fromTheme(_("kwave_zoom_original")), i18n("Zoom to 100%"), this, SLOT(zoomNormal())); m_action_zoomall = addAction( - icon_loader.loadIcon(_("kwave_viewmagfit"), - KIconLoader::Toolbar, max_s), + QIcon::fromTheme(_("kwave_viewmagfit")), i18n("Zoom to all"), this, SLOT(zoomAll())); // zoom selection combo box m_zoomselect = new KComboBox(this); Q_ASSERT(m_zoomselect); if (!m_zoomselect) return; m_zoomselect->setToolTip(i18n("Select zoom factor")); m_zoomselect->setInsertPolicy(QComboBox::InsertAtTop); m_zoomselect->setEditable(false); /** Initialized list of zoom factors */ struct { const QString text; unsigned int ms; } zoom_factors[] = { { i18n("%1 ms", 1), 1L}, { i18n("%1 ms", 10), 10L}, { i18n("%1 ms", 100), 100L}, { i18n("%1 sec", 1), 1000L}, { i18n("%1 sec", 10), 10L*1000L}, { i18n("%1 sec", 30), 30L*1000L}, { i18n("%1 min", 1), 1L*60L*1000L}, { i18n("%1 min", 3), 3L*60L*1000L}, { i18n("%1 min", 5), 5L*60L*1000L}, { i18n("%1 min", 10), 10L*60L*1000L}, { i18n("%1 min", 30), 30L*60L*1000L}, { i18n("%1 min", 60), 60L*60L*1000L}, }; for (unsigned int i = 0; i < ELEMENTS_OF(zoom_factors); i++) { m_zoomselect->addItem(zoom_factors[i].text); int index = m_zoomselect->count() - 1; unsigned int time = zoom_factors[i].ms; m_zoomselect->setItemData(index, QVariant(true), ZOOM_DATA_PREDEFINED); m_zoomselect->setItemData(index, QVariant(time), ZOOM_DATA_TIME); } m_action_zoomselect = addWidget(m_zoomselect); connect(m_zoomselect, SIGNAL(activated(int)), this, SLOT(selectZoom(int))); connect(this, SIGNAL(sigCommand(QString)), parent, SLOT(forwardCommand(QString))); int h = m_zoomselect->sizeHint().height(); m_zoomselect->setMinimumWidth(h * 5); m_zoomselect->setFocusPolicy(Qt::FocusPolicy(Qt::ClickFocus | Qt::TabFocus)); m_zoomselect->clearFocus(); } //*************************************************************************** Kwave::ZoomToolBar::~ZoomToolBar() { } //*************************************************************************** void Kwave::ZoomToolBar::contextSwitched(Kwave::FileContext *context) { if (context == m_context) return; // nothing to do m_context = context; updateToolbar(); } //*************************************************************************** void Kwave::ZoomToolBar::contextDestroyed(Kwave::FileContext *context) { if (context != m_context) return; // not of interest contextSwitched(Q_NULLPTR); } //*************************************************************************** void Kwave::ZoomToolBar::updateToolbar() { bool have_signal = false; bool have_selection = false; bool is_closed = true; if (m_context) { Kwave::SignalManager *signal_manager = m_context->signalManager(); Q_ASSERT(signal_manager); if (!signal_manager) return; have_signal = (signal_manager->tracks() != 0); have_selection = (signal_manager->selection().length() != 0); is_closed = signal_manager->isClosed(); } if (m_action_zoomselection) m_action_zoomselection->setEnabled(have_signal && have_selection); if (m_action_zoomin) m_action_zoomin->setEnabled(have_signal); if (m_action_zoomout) m_action_zoomout->setEnabled(have_signal); if (m_action_zoomnormal) m_action_zoomnormal->setEnabled(have_signal); if (m_action_zoomall) m_action_zoomall->setEnabled(have_signal); if (m_action_zoomselect) m_action_zoomselect->setEnabled(have_signal); if (m_zoomselect && is_closed) { for (int i = 0; i < m_zoomselect->count(); i++) { QVariant v = m_zoomselect->itemData(i, ZOOM_DATA_PREDEFINED); if (!v.isValid() || !v.toBool()) { m_zoomselect->removeItem(i); break; } } m_zoomselect->insertItem(-1, _(" ")); m_zoomselect->setCurrentIndex(0); } } //*************************************************************************** void Kwave::ZoomToolBar::selectZoom(int index) { if (!m_context) return; Kwave::SignalManager *signal_manager = m_context->signalManager(); Q_ASSERT(signal_manager); Q_ASSERT(m_zoomselect); if (!signal_manager) return; if (!m_zoomselect) return; if (index < 0) return; if (index >= m_zoomselect->count()) return; QVariant v = m_zoomselect->itemData(index, ZOOM_DATA_TIME); unsigned int ms = 1; bool ok = false; if (v.isValid()) ms = v.toUInt(&ok); if (!ok) ms = 1; Kwave::Zoomable *zoomable = m_context->zoomable(); Q_ASSERT(zoomable); if (!zoomable) return; const double rate = signal_manager->rate(); unsigned int width = zoomable->visibleWidth(); Q_ASSERT(width > 1); if (width <= 1) width = 2; const double new_zoom = rint(((rate * ms) / 1.0E3) -1 ) / static_cast(width - 1); zoomable->setZoom(new_zoom); // force the zoom factor to be set, maybe the current selection // has been changed/corrected to the previous value so that we // don't get a signal. setZoomInfo(m_context, zoomable->zoom()); } //*************************************************************************** void Kwave::ZoomToolBar::setZoomInfo(Kwave::FileContext *context, double zoom) { if (!m_context || (context != m_context)) return; Kwave::SignalManager *signal_manager = m_context->signalManager(); Kwave::Zoomable *zoomable = m_context->zoomable(); Q_ASSERT(zoom >= 0); Q_ASSERT(m_zoomselect); if (zoom <= 0.0) return; // makes no sense or signal is empty if (!m_zoomselect) return; double rate = (signal_manager) ? signal_manager->rate() : 0.0; double ms = ((rate > 0) && (zoomable)) ? (((zoomable->visibleSamples()) * 1E3) / rate) : 0.0; QString strZoom; if ((signal_manager) && (signal_manager->tracks())) { if (rate > 0) { // time display mode int s = Kwave::toInt(ms) / 1000; int m = s / 60; if (ms >= 60*1000) { strZoom = strZoom.sprintf("%02d:%02d min", m, s % 60); } else if (ms >= 1000) { strZoom = strZoom.sprintf("%d sec", s); } else if (ms >= 1) { strZoom = strZoom.sprintf("%d ms", Kwave::toInt(round(ms))); } else if (ms >= 0.01) { strZoom = strZoom.sprintf("%0.3g ms", ms); } } else { // percent mode double percent = 100.0 / zoom; strZoom = Kwave::zoom2string(percent); } } m_zoomselect->blockSignals(true); // if the text is equal to an entry in the current list -> keep it if (m_zoomselect->contains(strZoom)) { // select existing entry, string match m_zoomselect->setCurrentIndex(m_zoomselect->findText(strZoom)); } else { // remove user defined entries and scan for more or less exact match int i = 0; int match = -1; while (i < m_zoomselect->count()) { QVariant v = m_zoomselect->itemData(i, ZOOM_DATA_PREDEFINED); if (!v.isValid() || !v.toBool()) { m_zoomselect->removeItem(i); } else { QVariant vz = m_zoomselect->itemData(i, ZOOM_DATA_TIME); bool ok = false; double t = vz.toDouble(&ok); if (ok && (t > 0) && fabs(1 - (t / ms)) < (1.0 / 60.0)) { match = i; } i++; } } if (match >= 0) { // use an exact match from the list i = match; } else if (rate > 0) { // time mode: // find the best index where to insert the new user defined value for (i = 0; i < m_zoomselect->count(); ++i) { QVariant v = m_zoomselect->itemData(i, ZOOM_DATA_TIME); bool ok = false; double t = v.toDouble(&ok); if (!ok) continue; if (t > ms) break; } m_zoomselect->insertItem(i, strZoom); m_zoomselect->setItemData(i, QVariant(ms), ZOOM_DATA_TIME); } else { // percent mode -> just insert at top m_zoomselect->insertItem(-1, strZoom); i = 0; } m_zoomselect->setCurrentIndex(i); } m_zoomselect->blockSignals(false); } //*************************************************************************** //*************************************************************************** diff --git a/kwave/menus.config b/kwave/menus.config index a9ade147..84ab9145 100644 --- a/kwave/menus.config +++ b/kwave/menus.config @@ -1,259 +1,259 @@ ############################################################################ # menus.config - Kwave menu command file # ------------------- # begin : Sat Feb 3 2001 # copyright : (C) 2001 by Thomas Eschenbacher # email : Thomas.Eschenbacher@gmx.de ############################################################################ # ############################################################################ # # # This program is free software; you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # # the Free Software Foundation; either version 2 of the License, or # # (at your option) any later version. # # # ############################################################################ menu (plugin(newsignal),File/New.../#icon(document-new),::New) menu (open(),File/Open,CTRL+::Open) menu (open(),File/Open/#icon(document-open)) menu (ignore(),File/Open Recent/#listmenu(ID_FILE_OPEN_RECENT, openrecent(%1))) menu (ignore(),File/Open Recent/#icon(document-open-recent)) menu (ignore(),File/Open Recent/-/#hidden) # workaround to protect the separator menu (ignore(),File/Open Recent/#separator) - menu (openrecent:clear(),File/Open Recent/Clear List,,ID_FILE_OPEN_RECENT_CLEAR) + menu (openrecent:clear(),File/Open Recent/Clear List/#icon(edit-clear-list),,ID_FILE_OPEN_RECENT_CLEAR) menu (ignore(),File/#separator) menu (plugin:setup(record),File/Record/#icon(media-record),F2,ID_RECORD) menu (ignore(),File/#separator) menu (save(),File/&Save/#icon(document-save),::Save,ID_FILE_SAVE_CURRENT) menu (save(),File/&Save/#group(@SIGNAL)) menu (ignore(),File/Save/#group(@SIGNAL),,ID_FILE_SAVE) menu (saveas(),File/Save/As.../#icon(document-save-as),SHIFT+::Save) menu (saveas(),File/Save/As.../#group(@SIGNAL),SHIFT+::Save) menu (saveselect(),File/Save/Selection.../#group(@SELECTION)) menu (plugin:setup(saveblocks),File/Save/Blocks.../#group(@LABELS)) menu (plugin:setup(saveblocks),File/Save/Blocks.../#icon(document-save-all)) menu (close(),File/Close/#group(@NOT_CLOSED),::Close,ID_FILE_CLOSE) menu (close(),File/Close/#icon(document-close)) menu (ignore(),File/#separator) menu (newwindow(),File/New Window/#icon(window-new),SHIFT+CTRL+W,ID_FILE_NEW_WINDOW) menu (ignore(),File/#separator) menu (revert(),File/Revert/#icon(document-revert),CTRL+R,ID_FILE_REVERT) menu (ignore(),File/#separator) menu (quit(),File/Quit/#icon(application-exit),CTRL+Q) menu (ignore(),File,,ID_FILE) menu (ignore(),Edit/#group(@NOT_CLOSED),,ID_EDIT) menu (undo(),Edit/Undo/#icon(edit-undo),::Undo,ID_EDIT_UNDO) menu (undo(),Edit/Undo/#disabled) menu (redo(),Edit/Redo/#icon(edit-redo),::Redo,ID_EDIT_REDO) menu (redo(),Edit/Redo/#disabled) menu (ignore(),Edit/#separator) menu (cut(),Edit/Cut/#icon(edit-cut),::Cut) menu (cut(),Edit/Cut/#group(@SIGNAL,@SELECTION)) menu (copy(),Edit/Copy/#icon(edit-copy),::Copy) menu (copy(),Edit/Copy/#group(@SIGNAL,@SELECTION)) menu (paste(),Edit/Paste/#icon(edit-paste),::Paste) menu (paste(),Edit/Paste/#group(@SIGNAL,@CLIPBOARD)) - menu (crop(),Edit/Crop/#icon(crop),SHIFT+::Cut) + menu (crop(),Edit/Crop/#icon(transform-crop),SHIFT+::Cut) menu (crop(),Edit/Crop/#group(@SIGNAL,@SELECTION)) menu (delete(),Edit/Delete/#icon(edit-delete),::Delete) menu (delete(),Edit/Delete/#group(@SIGNAL,@SELECTION)) menu (ignore(),Edit/#separator) # menu (dialog(stringenter),Edit/Enter Command,CTRL+E) # menu (ignore(),Edit/#separator) menu (selectall(),Edit/Selection/#group(@SIGNAL)) menu (selectall(),Edit/Selection/All,::SelectAll) menu (plugin:setup(selectrange),Edit/Selection/Range,R) menu (selectvisible(),Edit/Selection/Visible Area,V) menu (selectnext(),Edit/Selection/Next,SHIFT++) menu (selectprev(),Edit/Selection/Previous,SHIFT+-) menu (selectnone(),Edit/Selection/Nothing,N) menu (selecttoleft(),Edit/Selection/To Start,::SelectStartOfLine) menu (selecttoright(),Edit/Selection/To End,::SelectEndOfLine) menu (expandtolabel(),Edit/Selection/Expand to Labels/#group(@LABELS),E) menu (selectnextlabels(),Edit/Selection/To Next Labels/#group(@LABELS),SHIFT+CTRL+N) menu (selectprevlabels(),Edit/Selection/To Previous Labels/#group(@LABELS),SHIFT+CTRL+P) menu (ignore(),Edit/#separator) menu (add_track(),Edit/Track/Add/#group(@NOT_CLOSED),SHIFT+A) menu (add_track(),Edit/Track/Add/#icon(list-add)) menu (ignore(),Edit/Track/Delete/#listmenu(ID_EDIT_TRACK_DELETE, delete_track(%1))) menu (ignore(),Edit/Track/Delete/#icon(list-remove)) menu (ignore(),Edit/Track/Delete/#group(@SIGNAL)) # menu (dialog(mix),Edit/Track/Mix/#group(@SIGNAL),SHIFT+M) # menu (ignore,Edit/Track/Mix/#disabled,SHIFT+M) menu (select_track:all(),Edit/Track/Select all/#group(@SIGNAL),SHIFT+::SelectAll) menu (select_track:invert(),Edit/Track/Invert Selection/#group(@SIGNAL),SHIFT+I) menu (ignore(),Edit/#separator) menu (ignore(),Edit/Clipboard/#group(@SIGNAL,@CLIPBOARD)) menu (clipboard_flush(),Edit/Clipboard/Flush/#group(@SIGNAL,@CLIPBOARD)) menu (clipboard_flush(),Edit/Clipboard/Flush/#icon(edit-clear),) # menu (clipboard_tonew(),Edit/Clipboard/To New Window/#disabled,) menu (nomacro:plugin:setup(insert_at),Edit/Clipboard/Insert At.../#group(@SIGNAL,@CLIPBOARD)) # menu (ignore(),Edit/#separator) # menu (mixpaste(),Edit/Mix Paste/#disabled,SHIFT+::Copy) # menu (trim(),Edit/Trim/#disabled,CTRL+T) menu (ignore(),Edit/#separator) menu (plugin:setup(fileinfo),Edit/File Properties.../#group(@SIGNAL),F7) menu (plugin:setup(fileinfo),Edit/File Properties.../#icon(document-properties),F7) menu (ignore(),View/#group(@SIGNAL),,ID_VIEW) menu (nomacro:plugin:setup(goto),View/Go to Position.../#group(@SIGNAL),CTRL+G) menu (view:scroll_start(),View/Begin/#icon(go-first),::MoveToStartOfDocument,ID_SCROLL_START) menu (view:scroll_end(),View/End/#icon(go-last),::MoveToEndOfDocument,ID_SCROLL_END) menu (view:scroll_prev(),View/Previous Page/#icon(kwave_player_start),::MoveToPreviousPage,ID_SCROLL_PREV) menu (view:scroll_next(),View/Next Page/#icon(kwave_player_end),::MoveToNextPage,ID_SCROLL_NEXT) menu (view:scroll_right(),View/Scroll Right/#icon(kwave_player_fwd),::MoveToNextChar,ID_SCROLL_RIGHT) menu (view:scroll_left(),View/Scroll Left/#icon(kwave_player_rew),::MoveToPreviousChar,ID_SCROLL_LEFT) menu (ignore(),View/#separator) menu (view:zoom_in(),View/Zoom In/#icon(kwave_zoom_in),::ZoomIn) menu (view:zoom_out(),View/Zoom Out/#icon(kwave_zoom_out),::ZoomOut) menu (view:zoom_selection(),View/Zoom to Selection/#icon(kwave_viewmag),CTRL+SPACE) menu (view:zoom_selection(),View/Zoom to Selection/#group(@SELECTION)) menu (view:zoom_all(),View/Zoom to Whole Signal/#icon(kwave_viewmagfit)) menu (view:zoom_normal(),View/Zoom to 100%/#icon(kwave_zoom_original)) menu (ignore(),Play/#group(@SIGNAL),,ID_PLAY_MENU) menu (playback(prev),Play/Previous/#icon(kwave_player_start),::MoveToPreviousPage,ID_PLAYBACK_PREV) menu (playback(rewind),Play/Rewind/#icon(kwave_player_rew),::MoveToPreviousChar,ID_PLAYBACK_REWIND) menu (playback(start),Play/Start/#icon(kwave_player_play),P,ID_PLAYBACK_START) menu (playback(loop),Play/Loop/#icon(kwave_player_loop),,ID_PLAYBACK_LOOP) menu (playback(pause),Play/Pause/#icon(kwave_player_pause),SPACE,ID_PLAYBACK_PAUSE) menu (playback(continue),Play/Continue/#icon(kwave_player_pause_2),SPACE,ID_PLAYBACK_CONTINUE) menu (playback(stop),Play/Stop/#icon(kwave_player_stop),ESC,ID_PLAYBACK_STOP) menu (playback(forward),Play/Forward/#icon(kwave_player_fwd),::MoveToNextChar,ID_PLAYBACK_FORWARD) menu (playback(next),Play/Next/#icon(kwave_player_end),::MoveToNextPage,ID_PLAYBACK_NEXT) menu (ignore(),Record) - menu (plugin:setup(record),Record/Prepare...) - menu (plugin:setup(record,start_now),Record/Start Now!) + menu (plugin:setup(record),Record/Prepare.../#icon(configure)) + menu (plugin:setup(record,start_now),Record/Start Now!/#icon(media-record)) menu (ignore(),Labels/#group(@SIGNAL),,ID_LABELS) menu (label:add(),Labels/Add.../#icon(list-add)) menu (label:delete(),Labels/Delete/#listmenu(ID_LABEL_DELETE, label:delete(%1))) menu (label:delete(),Labels/Delete/-/#hidden) # workaround to protect the separator menu (label:delete(),Labels/Delete/#group(@LABELS)) menu (label:delete(),Labels/Delete/#icon(list-remove)) menu (ignore(),Labels/Delete/#separator) menu (label:load(),Labels/Load.../#icon(document-open)) menu (label:save(),Labels/Save.../#group(@LABELS)) menu (label:save(),Labels/Save.../#icon(document-save)) # menu (ignore(),Labels/Generate/#disabled) # menu (label:by_intensity,Labels/Generate/Label by Intensity/#disabled) # menu (label:by_period,Labels/Generate/Label by Period/#disabled) # menu (label:to_pitch(),Labels/Convert Label Distance to Pitch/#disabled) menu (ignore(),Fx/#group(@SIGNAL),,ID_FX) # menu (dialog (distort),Fx/Distort/#disabled,SHIFT+D) menu (plugin(volume),Fx/Volume/#icon(player-volume),SHIFT+V) menu (plugin:execute(normalize),Fx/Normalize) menu (plugin:execute(amplifyfree, fade in, linear, 0.0, 0.0, 1.0, 1.0),Fx/Fade In/#group(@SIGNAL),I) menu (ignore(),Fx/Fade In/#icon(fade_in.png)) menu (ignore(),Fx/Fade In/#group(@SELECTION)) menu (plugin:execute(amplifyfree, fade out, linear, 0.0, 1.0, 1.0, 0.0),Fx/Fade Out/#group(@SIGNAL),O) menu (ignore(),Fx/Fade Out/#icon(fade_out.png)) menu (ignore(),Fx/Fade Out/#group(@SELECTION)) menu (plugin(amplifyfree),Fx/Amplify Free/#group(@SELECTION)) menu (ignore(),Fx/Amplify Free/#icon(amplify_free.png)) # menu (amplifyclip(),Fx/Amplify with Clipboard/#disabled) # this is the first attempt of primitive macro processing: menu (plugin:execute(amplifyfree,fade intro, linear,0,0,1,1);selectprev();selecttoleft();delete();plugin:execute(zero,0,1000);,Fx/Fade Intro/#group(@SIGNAL),SHIFT+CTRL+I) menu (plugin:execute(amplifyfree,fade leadout,linear,0,1,1,0);selectnext();selecttoright();delete();selecttoright();selectnext();plugin:execute(zero,0,1000);,Fx/Fade Leadout/#group(@SIGNAL),SHIFT+CTRL+O) menu (ignore(),Fx/#separator) menu (plugin(lowpass),Fx/Low Pass/#group(@SIGNAL)) menu (plugin(notch_filter),Fx/Notch Filter/#group(@SIGNAL)) menu (plugin(band_pass),Fx/Band Pass/#group(@SIGNAL)) # menu (dialog (movingaverage),Fx/Filter/Moving Average/#disabled) # menu (dialog (filter),Fx/Filter/Create/#disabled) # menu (ignore (),Fx/Filter/Presets/to be done.../#disabled) menu (ignore(),Fx/#separator) menu (plugin(pitch_shift),Fx/Pitch Shift) # menu (dialog (delay),Fx/Delay/#disabled) menu (plugin:execute(reverse),Fx/Reverse/#group(@SIGNAL),SHIFT+CTRL+R) menu (plugin:execute(reverse),Fx/Reverse/#icon(object-flip-horizontal),SHIFT+CTRL+R) # menu (dialog (gap),Fx/Periodic Silence/#disabled) menu (ignore(),Fx/#separator) # menu (dialog(rate),Fx/Change rate/#disabled) # menu (dialog(quantize),Fx/Requantize/#disabled,SHIFT+R) # menu (flip(),Fx/Flip Phase/#group(@SIGNAL)) # menu (flip(),Fx/Flip Phase/#disabled) # menu (center(),Fx/Center Signal/#group(@SIGNAL)) # menu (center(),Fx/Center Signal/#disabled) # menu (resample(),Fx/Resample/#group(@SIGNAL),SHIFT+R) # menu (resample(),Fx/Resample/#disabled) menu (ignore(),Calculate/#group(@SIGNAL),,ID_CALCULATE) menu (plugin(zero),Calculate/Silence/#icon(edit-clear)) menu (plugin(zero),Calculate/Silence/#group(@SELECTION)) menu (plugin(noise),Calculate/Noise) menu (ignore(),Calculate/Noise/#icon(noise.png)) # menu (dialog (addsynth),Calculate/Additive Synthesis/#disabled) # menu (dialog (pulse),Calculate/Pulse Train/#disabled) menu (ignore(),Calculate/#separator) # menu (dialog(envelope),Calculate/Envelope/#disabled) # menu (ignore(),Calculate/#separator) # menu (dialog(fft),Calculate/Spectrum/#disabled,F) # menu (dialog(averagefft),Calculate/Average spectrum/#disabled,SHIFT+F) menu (plugin(sonagram),Calculate/Sonagram,S) #menu (ignore(),Macro) # menu (macro(start),Macro/Start recording/#disabled) # menu (macro(stop),Macro/Stop recording/#disabled) # menu (dialog(macro),Macro/Edit/#disabled) # menu (ignore(),Macro/#separator) # menu (ignore(),Macro/Execute/#listmenu(ID_MACRO_LIST, macro_play(%1)),,ID_MACROS) # menu (ignore(),Macro/Execute/#disabled,,ID_MACROS) menu (ignore(),Window/#group(@NOT_CLOSED),,ID_WINDOW) menu (window:next_sub(),Window/Next Window/#icon(go-next-view),::NextChild,ID_WINDOW_NEXT) menu (window:prev_sub(),Window/Previous Window/#icon(go-previous-view),::PreviousChild,ID_WINDOW_PREV) menu (window:cascade(),Window/Cascade Sub Windows,,ID_WINDOW_CASCADE) menu (window:tile(),Window/Tile Sub Windows,,ID_WINDOW_TILE) menu (window:tile_vertical(),Window/Arrange Sub Windows Vertically,,ID_WINDOW_TILE_VERTICAL) menu (ignore(),Window/-/#hidden) # workaround to protect the separator menu (ignore(),Window/#separator) menu (ignore(),Window/#listmenu(ID_WINDOW_LIST, window:activate(%1))) menu (ignore(),Settings) menu (select_gui_type(SDI),Settings/Show Files in.../Separate Windows (SDI)/#exclusive(@GUI_TYPE),,ID_GUI_SDI) menu (select_gui_type(MDI),Settings/Show Files in.../Same Window (MDI)/#exclusive(@GUI_TYPE),,ID_GUI_MDI) menu (select_gui_type(TAB),Settings/Show Files in.../Tabs/#exclusive(@GUI_TYPE),,ID_GUI_TAB) menu (plugin:setup(playback),Settings/Playback/#icon(speaker)) menu (ignore(),Settings/Record) - menu (plugin:setup(record,format), Settings/Record/Format) - menu (plugin:setup(record,source), Settings/Record/Source) + menu (plugin:setup(record,format), Settings/Record/Format/#icon(configure)) + menu (plugin:setup(record,source), Settings/Record/Source/#icon(audio-input-microphone)) menu (plugin:setup(memory),Settings/Memory/#icon(configure)) menu (reset_toolbars(),Settings/Reset Toolbar/#icon(configure-toolbars)) menu (reenable_dna(),Settings/Re-enable all "Do not ask again" messages) menu (ignore(),#separator) menu (help(),Help/Contents/#icon(help-contents),::HelpContents) menu (plugin(about,kwave),Help/About Kwave/#icon(kwave)) menu (about_kde(),Help/About KDE/#icon(kde)) # # end of file # diff --git a/kwave/pics/krec_record.xpm b/kwave/pics/krec_record.xpm deleted file mode 100644 index ed20d491..00000000 --- a/kwave/pics/krec_record.xpm +++ /dev/null @@ -1,251 +0,0 @@ -/* XPM */ -static const char *xpm_krec_record[] = { -/* columns rows colors chars-per-pixel */ -"22 22 223 2", -" c #9D0000", -". c #A00000", -"X c #A20000", -"o c #A40000", -"O c #AD0000", -"+ c #AF0000", -"@ c #B10000", -"# c #B20000", -"$ c #BF0000", -"% c #B71414", -"& c #C10000", -"* c #D60000", -"= c #DD0505", -"- c #D01212", -"; c #E10000", -": c #E40000", -"> c #E60000", -", c #E40202", -"< c #E90000", -"1 c #EA0000", -"2 c #E80303", -"3 c #EC0000", -"4 c #EF0101", -"5 c #ED0707", -"6 c #EE0E0E", -"7 c #F40000", -"8 c #F50000", -"9 c #F70000", -"0 c #F50505", -"q c #F90000", -"w c #FA0000", -"e c #FC0101", -"r c #FD0101", -"t c #FE0303", -"y c #FE0505", -"u c #F00E0E", -"i c #FF0909", -"p c #FF0A0A", -"a c #FF0D0D", -"s c #E01B1B", -"d c #E21B1B", -"f c #FF1010", -"g c #FF1313", -"h c #FA1616", -"j c #FD1414", -"k c #FF1616", -"l c #FF1818", -"z c #FF1919", -"x c #FF1C1C", -"c c #FF1D1D", -"v c #FC1F1F", -"b c #C12020", -"n c #D12828", -"m c #C63A3A", -"M c #C73A3A", -"N c #F72121", -"B c #F92121", -"V c #FF2020", -"C c #FF2424", -"Z c #FF2727", -"A c #FF2828", -"S c #FF2C2C", -"D c #FF2E2E", -"F c #EB3D3D", -"G c #ED3D3D", -"H c #FE3131", -"J c #FF3232", -"K c #FE3333", -"L c #FF3434", -"P c #FF3535", -"I c #F23D3D", -"U c #F43D3D", -"Y c #FF3838", -"T c #FF3939", -"R c #FF3A3A", -"E c #F83D3D", -"W c #FA3D3D", -"Q c #FF3C3C", -"! c #FF3D3D", -"~ c #FD3E3E", -"^ c #FE3F3F", -"/ c #FF3F3F", -"( c #D64040", -") c #D74040", -"_ c #D54646", -"` c #D64646", -"' c #D24B4B", -"] c #D95C5C", -"[ c #DA5C5C", -"{ c #E74848", -"} c #E14D4D", -"| c #E34D4D", -" . c #E84848", -".. c #EC4848", -"X. c #EE4848", -"o. c #FF4141", -"O. c #FF4343", -"+. c #FF4444", -"@. c #FF4545", -"#. c #FF4747", -"$. c #F24848", -"%. c #F34848", -"&. c #F74848", -"*. c #F84848", -"=. c #FB4848", -"-. c #FC4848", -";. c #FE4949", -":. c #FF4949", -">. c #FE4A4A", -",. c #FF4B4B", -"<. c #FF4C4C", -"1. c #FF4D4D", -"2. c #FF4E4E", -"3. c #FF4F4F", -"4. c #E85252", -"5. c #E95252", -"6. c #EC5252", -"7. c #ED5252", -"8. c #E35D5D", -"9. c #E45D5D", -"0. c #E75D5D", -"q. c #E85D5D", -"w. c #EB5D5D", -"e. c #EC5D5D", -"r. c #EE5D5D", -"t. c #EF5D5D", -"y. c #F05252", -"u. c #F15252", -"i. c #F45252", -"p. c #F55252", -"a. c #F75252", -"s. c #F85252", -"d. c #FA5252", -"f. c #FB5252", -"g. c #FF5050", -"h. c #FF5151", -"j. c #FC5252", -"k. c #FD5252", -"l. c #FF5252", -"z. c #FF5353", -"x. c #FF5454", -"c. c #FF5555", -"v. c #FF5757", -"b. c #F15D5D", -"n. c #F35D5D", -"m. c #F45D5D", -"M. c #F55D5D", -"N. c #FF5858", -"B. c #FF5959", -"V. c #FF5A5A", -"C. c #FF5B5B", -"Z. c #FF5C5C", -"A. c #FF5D5D", -"S. c #FF5E5E", -"D. c #D96464", -"F. c #E36767", -"G. c #E46767", -"H. c #E66767", -"J. c #E76767", -"K. c #E96767", -"L. c #EB6767", -"P. c #EC6767", -"I. c #ED6767", -"U. c #EE6767", -"Y. c #EF6767", -"T. c #FF6161", -"R. c #FF6262", -"E. c #FF6464", -"W. c #FF6565", -"Q. c #FF6666", -"!. c #FF6868", -"~. c #FF6969", -"^. c #FF6A6A", -"/. c #FF6B6B", -"(. c #FF6E6E", -"). c #E27272", -"_. c #E37272", -"`. c #E57272", -"'. c #E67272", -"]. c #E77272", -"[. c #E87272", -"{. c #E97272", -"}. c #EA7272", -"|. c #E37C7C", -" X c #E47C7C", -".X c #E57C7C", -"XX c #FF7373", -"oX c #FF7676", -"OX c #FF7777", -"+X c #FF7878", -"@X c #FF7979", -"#X c #FF7A7A", -"$X c #FF7C7C", -"%X c #FF7D7D", -"&X c #FF8282", -"*X c #FF8383", -"=X c #FF8585", -"-X c #FF8686", -";X c #FF8888", -":X c #FF8989", -">X c #FF8A8A", -",X c #FF8C8C", -".-.*.%.X. .- aX", -"aXs F I E ~ O.:.3.l.x.c.z.g.,.+.^ W U G d aX", -"aX: 6 N H ! @.1.z.N.V.C.B.c.3.#./ K B u > aX", -"aX3 7 r a C T :.z.C.T.R.Z.x.,.Q Z f t 9 4 aX", -"aX1 w i z A P o.,.z.v.v.x.2.+.T S c a e 2 aX", -"aX, y g C L O.h.Z.E.~.^.Q.S.x.#.Y A l p = aX", -"aX; j x D / 3.S./.oX$X%X+X(.R.z.O.J V v * aX", -"aXaX0 D P #.B.^.@X-XX8X7X&X^.3.aXaXaXaXaXaXaX", -"aXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaX", -"aXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaX" -}; diff --git a/libgui/CurveWidget.cpp b/libgui/CurveWidget.cpp index c19b873d..f7c56178 100644 --- a/libgui/CurveWidget.cpp +++ b/libgui/CurveWidget.cpp @@ -1,494 +1,496 @@ /*************************************************************************** CurveWidget.cpp - widget for editing an interpolated curve ------------------- begin : Sep 16 2001 copyright : (C) 2001 by Thomas Eschenbacher email : Thomas Eschenbacher ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "libkwave/Curve.h" #include "libkwave/Interpolation.h" #include "libkwave/Logger.h" #include "libkwave/String.h" #include "libkwave/Utils.h" #include "libgui/CurveWidget.h" #include "libgui/FileDialog.h" //*************************************************************************** Kwave::CurveWidget::CurveWidget(QWidget *parent) :QWidget(parent), m_width(0), m_height(0), m_curve(), m_menu(Q_NULLPTR), m_preset_menu(Q_NULLPTR), m_current(Kwave::Curve::NoPoint), m_last(Kwave::Curve::NoPoint), m_down(false), m_knob(), m_selected_knob() { - KIconLoader icon_loader; + KIconLoader *icon_loader = KIconLoader::global(); // set the default curve m_curve.fromCommand(_("curve(linear,0,0,1,1)")); QPalette pal = palette(); pal.setColor(QPalette::Window, Qt::black); setPalette(pal); // create the pixmaps for the selected and non-selected knob - m_knob = icon_loader.loadIcon(_("knob.xpm"), KIconLoader::Small); - m_selected_knob = icon_loader.loadIcon(_("selectedknob.xpm"), - KIconLoader::Small); + if (icon_loader) { + m_knob = icon_loader->loadIcon(_("knob.xpm"), KIconLoader::Small); + m_selected_knob = icon_loader->loadIcon(_("selectedknob.xpm"), + KIconLoader::Small); + } // set up the context menu for the right mouse button m_menu = new QMenu(this); Q_ASSERT(m_menu); if (!m_menu) return; QMenu *interpolation = m_menu->addMenu(i18n("Interpolation")); Q_ASSERT(interpolation); if (!interpolation) return; m_menu->addSeparator(); QMenu *transform = m_menu->addMenu(i18n("Transform")); Q_ASSERT(transform); if (!transform) return; transform->addAction(i18n("Flip horizontal"), this, SLOT(HFlip())); transform->addAction(i18n("Flip vertical"), this, SLOT(VFlip())); transform->addSeparator(); transform->addAction(i18n("Into first half"), this, SLOT(firstHalf())); transform->addAction(i18n("Into second half"), this, SLOT(secondHalf())); QMenu *del = m_menu->addMenu(i18n("Delete")); Q_ASSERT(del); if (!del) return; m_menu->addAction(i18n("Fit In"), this, SLOT(scaleFit())); m_menu->addSeparator(); /* list of presets */ m_preset_menu = m_menu->addMenu(i18n("Presets")); Q_ASSERT(m_preset_menu); if (!m_preset_menu) return; loadPresetList(); connect(m_preset_menu, SIGNAL(triggered(QAction*)), this, SLOT(loadPreset(QAction*))); m_menu->addAction( QIcon::fromTheme(_("document-export")), i18n("Save Preset"), this, SLOT(savePreset())); del->addAction( QIcon::fromTheme(_("edit-delete")), i18n("Currently Selected Point"), this, SLOT(deleteLast()), QKeySequence::Delete); del->addAction(i18n("Every Second Point"), this, SLOT(deleteSecond())); QStringList types = Kwave::Interpolation::descriptions(true); int id = 0; foreach (const QString &text, types) { QAction *action = new QAction(interpolation); action->setText(text); action->setData(id++); interpolation->addAction(action); } connect(interpolation, SIGNAL(triggered(QAction*)), this, SLOT(selectInterpolationType(QAction*))); setMouseTracking(true); QShortcut *delkey = new QShortcut(this); Q_ASSERT(delkey); if (!delkey) return; delkey->setKey(Qt::Key_Delete); connect(delkey, SIGNAL(activated()), this, SLOT (deleteLast())); } //*************************************************************************** Kwave::CurveWidget::~CurveWidget() { if (m_menu) delete m_menu; } //*************************************************************************** QString Kwave::CurveWidget::getCommand() { return m_curve.getCommand(); } //*************************************************************************** void Kwave::CurveWidget::setCurve(const QString &command) { m_curve.fromCommand(command); repaint(); } //*************************************************************************** void Kwave::CurveWidget::selectInterpolationType(QAction *action) { if (!action) return; QVariant data = action->data(); int index = data.toInt(); m_curve.setInterpolationType(Kwave::Interpolation::findByIndex(index)); repaint(); } //*************************************************************************** void Kwave::CurveWidget::savePreset() { QString presetSubDir = _("presets") + QDir::separator() + _("curves"); QString presetPath = QStandardPaths::writableLocation( QStandardPaths::AppDataLocation) + QDir::separator() + presetSubDir; if (!QDir(presetPath).exists()) { Kwave::Logger::log(this, Logger::Info, _("curve preset directory did not exist, creating '%1'").arg( presetPath)); QDir(presetPath).mkpath(presetPath); } QPointer dlg = new (std::nothrow) Kwave::FileDialog( presetPath, Kwave::FileDialog::SaveFile, _("*.curve *.CURVE|") + i18nc("Filter description for Kwave curve presets, " "for use in a FileDialog", "Kwave curve preset (*.curve)"), this, QUrl(), _("*.curve")); if (!dlg) return; dlg->setWindowTitle(i18n("Save Curve Preset")); if (dlg->exec() != QDialog::Accepted) { delete dlg; return; } QString name = dlg->selectedUrl().toLocalFile(); delete dlg; // append the extension if not given if (!name.endsWith(_(".curve"))) name.append(_(".curve")); QFile out(name); out.open(QIODevice::WriteOnly); QString cmd = m_curve.getCommand(); out.write(DBG(cmd), cmd.length()); // reload the list of known presets loadPresetList(); } //*************************************************************************** void Kwave::CurveWidget::loadPresetList() { const QChar s = QDir::separator(); QString presetSubDir = s + _("kwave") + s + _("presets") + s + _("curves"); QStringList files; QStringList presetPaths = QStandardPaths::standardLocations( QStandardPaths::GenericDataLocation); foreach (const QString &path, presetPaths) { QDir d(path + presetSubDir); QStringList f = d.entryList(QDir::Files, QDir::Name); foreach (const QString &file, f) { QString preset = d.path() + s + file; if (!files.contains(preset)) files.append(preset); } } files.sort(); m_preset_menu->clear(); foreach (const QString &file, files) { QFileInfo fi(file); QString name = fi.baseName(); QAction *action = new (std::nothrow) QAction(name, m_preset_menu); Q_ASSERT(action); if (!action) continue; action->setData(file); m_preset_menu->addAction(action); } } //*************************************************************************** void Kwave::CurveWidget::loadPreset(QAction *action) { Q_ASSERT(m_preset_menu); Q_ASSERT(action); if (!m_preset_menu || !action) return; if (!action->data().isValid()) return; // invalidate the current selection m_current = Kwave::Curve::NoPoint; m_last = Kwave::Curve::NoPoint; // get the path of the file and check whether it (still) exists QString filename = action->data().toString(); QFileInfo fi(filename); if (!fi.exists(filename)) return; // load the file QFile file(filename); if (!file.open(QIODevice::ReadOnly)) { qWarning("CurveWidget::loadPreset('%s') - FAILED", DBG(filename)); return; } QTextStream stream(&file); m_curve.fromCommand(stream.readLine()); file.close(); repaint(); } //*************************************************************************** void Kwave::CurveWidget::secondHalf() { m_curve.secondHalf (); m_last = Kwave::Curve::NoPoint; repaint(); } //*************************************************************************** void Kwave::CurveWidget::firstHalf() { m_curve.firstHalf (); m_last = Kwave::Curve::NoPoint; repaint(); } //**************************************************************************** void Kwave::CurveWidget::deleteSecond() { m_curve.deleteSecondPoint(); m_last = Kwave::Curve::NoPoint; repaint (); } //**************************************************************************** void Kwave::CurveWidget::deleteLast() { if (m_last != Kwave::Curve::NoPoint) { m_curve.deletePoint(m_last, true); m_last = Kwave::Curve::NoPoint; repaint(); } } //*************************************************************************** void Kwave::CurveWidget::HFlip() { m_curve.HFlip(); repaint(); } //*************************************************************************** void Kwave::CurveWidget::VFlip() { m_curve.VFlip(); repaint(); } //*************************************************************************** void Kwave::CurveWidget::scaleFit() { m_curve.scaleFit(); repaint(); } //*************************************************************************** void Kwave::CurveWidget::addPoint(double newx, double newy) { m_curve.insert(newx, newy); m_last = Kwave::Curve::NoPoint; repaint(); } //*************************************************************************** Kwave::Curve::Point Kwave::CurveWidget::findPoint(int sx, int sy) // checks, if given coordinates fit to a control point in the list... { Q_ASSERT(m_width > 1); Q_ASSERT(m_height > 1); if ((m_width <= 1) || (m_height <= 1)) return Kwave::Curve::NoPoint; return m_curve.findPoint((static_cast(sx)) / (m_width - 1), (static_cast(m_height) - sy) / (m_height - 1)); } //*************************************************************************** void Kwave::CurveWidget::mousePressEvent(QMouseEvent *e) { Q_ASSERT(e); Q_ASSERT(m_width > 1); Q_ASSERT(m_height > 1); if (!e || (m_width <= 1) || (m_height <= 1)) return; if (e->buttons() == Qt::RightButton) { // right mouse button -> context menu QPoint popup = QCursor::pos(); if (m_menu) m_menu->popup(popup); } else if (e->buttons() == Qt::LeftButton) { // left mouse button -> select existing or create new point m_down = true; m_current = findPoint(e->pos().x(), e->pos().y()); if (m_current == Kwave::Curve::NoPoint) { // no matching point is found -> generate a new one ! addPoint(static_cast(e->pos().x()) / (m_width - 1), static_cast(m_height - e->pos().y()) / (m_height - 1)); m_current = findPoint(e->pos().x(), e->pos().y()); } repaint(); } } //*************************************************************************** void Kwave::CurveWidget::mouseReleaseEvent(QMouseEvent *) { m_last = m_current; m_current = Kwave::Curve::NoPoint; m_down = false; repaint(); } //*************************************************************************** void Kwave::CurveWidget::mouseMoveEvent(QMouseEvent *e ) { Q_ASSERT(e); Q_ASSERT(m_width > 1); Q_ASSERT(m_height > 1); if (!e || (m_width <= 1) || (m_height <= 1)) return; int x = e->pos().x(); int y = e->pos().y(); // if a point is selected... if (m_current != Kwave::Curve::NoPoint) { if (m_current == m_curve.first()) x = 0; if (m_current == m_curve.last()) x = m_width - 1; m_curve.deletePoint(m_current, false); m_current.setX(static_cast(x) / (m_width - 1)); m_current.setY(static_cast(m_height - y) / (m_height - 1)); if (m_current.x() < 0.0) m_current.setX(0.0); if (m_current.y() < 0.0) m_current.setY(0.0); if (m_current.x() > 1.0) m_current.setX(1.0); if (m_current.y() > 1.0) m_current.setY(1.0); double dx = (1.0 / static_cast(m_width - 1)); do { Kwave::Curve::Point nearest = m_curve.findPoint( m_current.x(), m_current.y(), 1.0); if (qFuzzyCompare(nearest.x(), m_current.x())) { if (nearest == m_curve.last()) m_current.setX(m_current.x() - dx); else m_current.setX(m_current.x() + dx); } else break; } while (true); m_curve.insert(m_current.x(), m_current.y()); repaint (); } else { if (findPoint(x, y) != Kwave::Curve::NoPoint) setCursor(Qt::SizeAllCursor); else setCursor(Qt::ArrowCursor); } } //*************************************************************************** void Kwave::CurveWidget::paintEvent(QPaintEvent *) { // qDebug("CurveWidget::paintEvent (QPaintEvent *)"); QPainter p; int ly; m_height = rect().height(); m_width = rect().width(); if (!m_curve.count()) return; // nothing to draw const int kw = m_knob.width(); const int kh = m_knob.height(); QVector y = m_curve.interpolation(m_width); Q_ASSERT(Kwave::toInt(y.count()) == m_width); if (Kwave::toInt(y.count()) < m_width) { qWarning("CurveWidget: unable to get interpolation !"); return; } p.begin(this); p.fillRect(rect(), QBrush(palette().dark())); p.setPen(palette().text().color()); // draw the lines ly = (m_height-1) - Kwave::toInt(y[0] * (m_height - 1)); for (int i = 1; i < m_width; i++) { int ay = (m_height-1) - Kwave::toInt(y[i] * (m_height - 1)); p.drawLine (i - 1, ly, i, ay); ly = ay; } // draw the points (knobs) foreach (const Kwave::Curve::Point &pt, m_curve) { int lx = Kwave::toInt(pt.x() * (m_width - 1)); ly = (m_height - 1) - Kwave::toInt(pt.y() * (m_height - 1)); if ((pt == m_current) || (!m_down && (pt == m_last)) ) p.drawPixmap(lx - (kw >> 1), ly - (kh >> 1), m_selected_knob); else p.drawPixmap(lx - (kw >> 1), ly - (kh >> 1), m_knob); } p.end(); } //*************************************************************************** //*************************************************************************** diff --git a/libgui/LabelItem.cpp b/libgui/LabelItem.cpp index 6e03efbc..fe4c0d8a 100644 --- a/libgui/LabelItem.cpp +++ b/libgui/LabelItem.cpp @@ -1,197 +1,196 @@ /*************************************************************************** LabelItem.cpp - label item within a SignalView ------------------- begin : Sat Mar 26 2011 copyright : (C) 2011 by Thomas Eschenbacher email : Thomas.Eschenbacher@gmx.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "config.h" #include +#include #include -#include #include #include "libkwave/Label.h" #include "libkwave/SignalManager.h" #include "libkwave/String.h" #include "libkwave/Utils.h" #include "libkwave/undo/UndoModifyMetaDataAction.h" #include "libkwave/undo/UndoTransactionGuard.h" #include "libgui/LabelItem.h" #include "libgui/SignalView.h" //*************************************************************************** Kwave::LabelItem::LabelItem(Kwave::SignalView &view, Kwave::SignalManager &signal_manager, unsigned int index, const Kwave::Label &label) :Kwave::ViewItem(view, signal_manager), m_index(index), m_initial_pos(label.pos()), m_current_pos(label.pos()), m_description(label.name()), m_undo_transaction(Q_NULLPTR) { } //*************************************************************************** Kwave::LabelItem::~LabelItem() { if (m_undo_transaction) { // restore the previous data qDebug("Kwave::LabelItem::~LabelItem() -> aborted -> reverting!"); m_undo_transaction->abort(); delete m_undo_transaction; m_undo_transaction = Q_NULLPTR; } } //*************************************************************************** Kwave::ViewItem::Flags Kwave::LabelItem::flags() const { return Kwave::ViewItem::CanGrabAndMove; } //*************************************************************************** QString Kwave::LabelItem::toolTip(sample_index_t &ofs) { Q_UNUSED(ofs); QString description = (m_description.length()) ? i18nc("tooltip of a label, %1=index, %2=description/name", "Label #%1 (%2)", m_index, m_description) : i18nc("tooltip of a label, without description, %1=index", "Label #%1", m_index); QString hms = Kwave::ms2hms(m_view.samples2ms(m_current_pos)); QString tip = _("%1\n%2\n%3").arg(description).arg(m_current_pos).arg(hms); return tip; } //*************************************************************************** void Kwave::LabelItem::appendContextMenu(QMenu *parent) { Q_ASSERT(parent); if (!parent) return; // locate the "label" menu QMenu *label_menu = Q_NULLPTR; foreach (const QAction *action, parent->actions()) { if (action->text() == i18n("Label")) { label_menu = action->menu(); break; } } // the context menu of a label has been activated if (label_menu) { - KIconLoader icon_loader; // find the "New" action and disable it foreach (QAction *action, label_menu->actions()) { if (action->text() == i18n("New")) { action->setEnabled(false); break; } } QAction *action_label_delete = label_menu->addAction( - icon_loader.loadIcon(_("list-remove"), KIconLoader::Toolbar), + QIcon::fromTheme(_("list-remove")), i18n("&Delete"), this, SLOT(contextMenuLabelDelete())); Q_ASSERT(action_label_delete); if (!action_label_delete) return; QAction *action_label_properties = label_menu->addAction( - icon_loader.loadIcon(_("configure"), KIconLoader::Toolbar), + QIcon::fromTheme(_("configure")), i18n("&Properties..."), this, SLOT(contextMenuLabelProperties())); Q_ASSERT(action_label_properties); if (!action_label_properties) return; } } //*************************************************************************** void Kwave::LabelItem::contextMenuLabelDelete() { emit sigCommand(_("label:delete(%1)").arg(m_index)); } //*************************************************************************** void Kwave::LabelItem::contextMenuLabelProperties() { emit sigCommand(_("nomacro:label:edit(%1)").arg(m_index)); } //*************************************************************************** QCursor Kwave::LabelItem::mouseCursor() const { return Qt::SizeHorCursor; } //*************************************************************************** void Kwave::LabelItem::moveTo(const QPoint &mouse_pos) { const sample_index_t new_pos = m_view.offset() + m_view.pixels2samples(mouse_pos.x()); Kwave::Label label = m_signal_manager.findLabel(new_pos); if (label.isNull()) { // this is the first move ? if (!m_undo_transaction) { // there probably will be something to undo later // create an undo transaction guard m_undo_transaction = new(std::nothrow) Kwave::UndoTransactionGuard( m_signal_manager, i18n("Move Label")); Q_ASSERT(m_undo_transaction); if (!m_undo_transaction) return; // save the previous label data for undo Kwave::Label lbl = m_signal_manager.findLabel(m_initial_pos); if (!m_undo_transaction->registerUndoAction(new(std::nothrow) UndoModifyMetaDataAction(Kwave::MetaDataList(lbl)))) { qWarning("Kwave::LabelItem::done(): saving undo data failed!"); return; } } if (m_signal_manager.modifyLabel(m_index, new_pos, m_description, false)) { Kwave::Label lbl = m_signal_manager.findLabel(new_pos); if (!lbl.isNull()) { m_index = m_signal_manager.labelIndex(lbl); m_current_pos = lbl.pos(); } } } } //*************************************************************************** void Kwave::LabelItem::done() { if (m_undo_transaction) { // close the undo transaction (regularly, with undo action) if (m_current_pos == m_initial_pos) m_undo_transaction->abort(); delete m_undo_transaction; m_undo_transaction = Q_NULLPTR; } } //*************************************************************************** //*************************************************************************** diff --git a/libgui/MenuItem.cpp b/libgui/MenuItem.cpp index d0124792..339523e5 100644 --- a/libgui/MenuItem.cpp +++ b/libgui/MenuItem.cpp @@ -1,164 +1,163 @@ /*************************************************************************** MenuItem.h - description ------------------- begin : Mon Jan 10 2000 copyright : (C) 2000 by Thomas Eschenbacher email : Thomas.Eschenbacher@gmx.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "config.h" #include #include #include -#include #include "libkwave/Parser.h" #include "libkwave/String.h" #include "libgui/MenuGroup.h" #include "libgui/MenuItem.h" #include "libgui/MenuNode.h" //***************************************************************************** Kwave::MenuItem::MenuItem(Kwave::MenuNode *parent, const QString &name, const QString &command, const QKeySequence &shortcut, const QString &uid) :Kwave::MenuNode(parent, name, command, shortcut, uid), m_exclusive_group(), m_action(Q_NULLPTR) { Q_ASSERT(parent); if (!parent) return; m_action.setText(i18nc(UTF8(_("menu: ") + path()), UTF8(name))); if (!shortcut.isEmpty()) m_action.setShortcut(shortcut); connect(&m_action, SIGNAL(triggered(bool)), this, SLOT(actionTriggered(bool))); } //***************************************************************************** Kwave::MenuItem::~MenuItem() { } //***************************************************************************** void Kwave::MenuItem::actionTriggered(bool checked) { Q_UNUSED(checked); actionSelected(); } //***************************************************************************** void Kwave::MenuItem::actionSelected() { if (isCheckable() && !m_exclusive_group.length()) setChecked(true); Kwave::MenuNode::actionSelected(); } //***************************************************************************** bool Kwave::MenuItem::specialCommand(const QString &command) { Kwave::Parser parser(command); if (command == _("#checkable")) { // checking/selecting of the item (non-exclusive) setCheckable(true); } else if (parser.command() == _("#exclusive")) { // join to a list of groups QString group = parser.firstParam(); while (group.length()) { if (!m_exclusive_group.length()) { m_exclusive_group = group; joinGroup(group, Kwave::MenuGroup::EXCLUSIVE); } else if (m_exclusive_group != group) { qWarning("menu item '%s' already member of " "exclusive group '%s'", DBG(name()), DBG(m_exclusive_group)); } group = parser.nextParam(); } // make the item checkable setCheckable(true); return true; } else if (command == _("#hidden")) { setVisible(false); } return (Kwave::MenuNode::specialCommand(command)); } //***************************************************************************** void Kwave::MenuItem::setVisible(bool visible) { m_action.setVisible(visible); } //***************************************************************************** bool Kwave::MenuItem::isEnabled() { if (!m_action.isEnabled()) return false; return Kwave::MenuNode::isEnabled(); } //***************************************************************************** void Kwave::MenuItem::setEnabled(bool enable) { m_action.setEnabled(enable); } //***************************************************************************** bool Kwave::MenuItem::isCheckable() { return m_action.isCheckable(); } //***************************************************************************** void Kwave::MenuItem::setCheckable(bool checkable) { m_action.setCheckable(checkable); } //***************************************************************************** void Kwave::MenuItem::setChecked(bool check) { m_action.setChecked(check); } //***************************************************************************** void Kwave::MenuItem::setText(const QString &text) { m_action.setText(text); } //***************************************************************************** const QIcon Kwave::MenuItem::icon() { return m_action.icon(); } //***************************************************************************** void Kwave::MenuItem::setIcon(const QIcon &icon) { m_action.setIcon(icon); } //*************************************************************************** //***************************************************************************** diff --git a/libgui/MenuNode.cpp b/libgui/MenuNode.cpp index 8ad3bac2..47d5e719 100644 --- a/libgui/MenuNode.cpp +++ b/libgui/MenuNode.cpp @@ -1,494 +1,488 @@ /*************************************************************************** MenuNode.cpp - generic menu node type ------------------- begin : Mon Jan 10 2000 copyright : (C) 2000 by Thomas Eschenbacher email : Thomas.Eschenbacher@gmx.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "config.h" #include #include #include -#include - #include "libkwave/Parser.h" #include "libkwave/String.h" #include "libgui/MenuGroup.h" #include "libgui/MenuList.h" #include "libgui/MenuNode.h" #include "libgui/MenuRoot.h" #include "libgui/MenuSub.h" //***************************************************************************** Kwave::MenuNode::MenuNode(Kwave::MenuNode *parent, const QString &name, const QString &command, const QKeySequence &shortcut, const QString &uid) :QObject(), m_children(), m_groups(), m_uid(uid), m_shortcut(shortcut), m_name(name), m_command(command), m_parentNode(parent) { } //***************************************************************************** Kwave::MenuNode::~MenuNode() { // leave all groups QStringList::iterator group = m_groups.begin(); while (group != m_groups.end()) { leaveGroup(*group); group = m_groups.begin(); } // remove all childs clear(); // de-register from our parent if (m_parentNode) m_parentNode->removeChild(this); } //***************************************************************************** const QString Kwave::MenuNode::path() const { return (m_parentNode) ? (m_parentNode->path() + _("/") + m_name) : QString(); } //***************************************************************************** void Kwave::MenuNode::emitCommand(const QString &command) { Q_ASSERT(command.length()); if (!command.length()) return ; if (!parentNode()) { // no parent -> we are the root node -> we have to emit emit sigCommand(command); } else { // tell the root node to emit Kwave::MenuNode *root = rootNode(); Q_ASSERT(root); if (root) root->emitCommand(command); } } //***************************************************************************** void Kwave::MenuNode::actionSelected() { if (m_command.length()) emitCommand(m_command); } //***************************************************************************** void Kwave::MenuNode::clear() { // remove all children while (!m_children.isEmpty()) { Kwave::MenuNode *child = m_children.takeLast(); delete child; } } //***************************************************************************** Kwave::MenuNode *Kwave::MenuNode::parentNode() const { return m_parentNode; } //***************************************************************************** Kwave::MenuNode *Kwave::MenuNode::rootNode() { return (m_parentNode) ? m_parentNode->rootNode() : this; } //***************************************************************************** const QIcon Kwave::MenuNode::icon() { static QIcon dummy; Q_ASSERT(dummy.isNull()); return dummy; } //***************************************************************************** void Kwave::MenuNode::setIcon(const QIcon &icon) { qWarning("MenuNode(%s)::setIcon(%p)", DBG(name()), reinterpret_cast(&icon)); } //***************************************************************************** bool Kwave::MenuNode::isEnabled() { // evaluate our own (individual) enable and our parent's enable state if (m_parentNode && !m_parentNode->isEnabled()) return false; // find out if all our groups are enabled QHash &groups = groupList(); Kwave::MenuNode *root = rootNode(); if (root) { foreach (const QString &group_name, m_groups) { if (groups.contains(group_name)) { Kwave::MenuGroup *group = groups[group_name]; if (group && !group->isEnabled()) { qDebug("MenuNode(%s).isEnabled(): group %s is disabled", DBG(name()), DBG(group_name)); return false; } } } } // if we get here, everything is enabled return true; } //***************************************************************************** void Kwave::MenuNode::setVisible(bool visible) { Q_UNUSED(visible); } //***************************************************************************** void Kwave::MenuNode::setEnabled(bool enable) { Q_UNUSED(enable); } //***************************************************************************** void Kwave::MenuNode::setChecked(bool check) { Q_UNUSED(check); } //***************************************************************************** void Kwave::MenuNode::setText(const QString &text) { Q_UNUSED(text); } //***************************************************************************** void Kwave::MenuNode::insertChild(Kwave::MenuNode *node, Kwave::MenuNode *before) { if (!node) return; if (before && m_children.contains(before)) m_children.insert(m_children.indexOf(before), node); else m_children.append(node); } //***************************************************************************** void Kwave::MenuNode::setUID(const QString &uid) { m_uid = uid; } //***************************************************************************** Kwave::MenuNode *Kwave::MenuNode::findUID(const QString &uid) { if (m_uid == uid) return this; // found ourself foreach (Kwave::MenuNode *child, m_children) { Kwave::MenuNode *node = (child) ? child->findUID(uid) : Q_NULLPTR; if (node) return node; // found in child } return Q_NULLPTR; // nothing found :-( } //***************************************************************************** Kwave::MenuNode *Kwave::MenuNode::findChild(const QString &name) { Q_ASSERT(name.length()); foreach (Kwave::MenuNode *child, m_children) { if (child && (name == child->name())) return child; } return Q_NULLPTR; } //***************************************************************************** void Kwave::MenuNode::removeChild(Kwave::MenuNode *child) { if (child && !m_children.isEmpty()) m_children.removeAll(child); } //***************************************************************************** Kwave::MenuSub *Kwave::MenuNode::insertBranch(const QString &name, const QString &command, const QKeySequence &shortcut, const QString &uid) { Q_UNUSED(name); Q_UNUSED(command); Q_UNUSED(shortcut); Q_UNUSED(uid); return Q_NULLPTR; } //***************************************************************************** Kwave::MenuNode *Kwave::MenuNode::insertLeaf(const QString &name, const QString &command, const QKeySequence &shortcut, const QString &uid) { Q_UNUSED(name); Q_UNUSED(command); Q_UNUSED(shortcut); Q_UNUSED(uid); return Q_NULLPTR; } //***************************************************************************** void Kwave::MenuNode::insertNode(const QString &name, const QString &position, const QString &command, const QKeySequence &shortcut, const QString &uid) { int pos = 0; if (!position.length()) { qWarning("MenuNode::insertNode: no position!"); return; } // at start of the parsing process ? if (!name.length()) { // split off the first token, separated by a slash pos = position.indexOf(QLatin1Char('/')); if (pos < 0) pos = position.length(); } QString n = position.left(pos); QString p = position; p.remove(0, pos + 1); if ((n.length()) && (specialCommand(n))) { // no new branch, only a special command return; } if ((!p.length()) || (p[0] == QLatin1Char('#'))) { // end of the tree Kwave::MenuNode *sub = findChild(n); if (sub) { // a leaf with this name already exists // -> maybe we want to set new properties if (!shortcut.isEmpty()) sub->setShortcut(shortcut); if (uid.length()) sub->setUID(uid); } else { // insert a new leaf sub = insertLeaf(n, command, shortcut, uid); if (!sub) return; } if (p[0] == QLatin1Char('#')) sub->specialCommand(p); } else { // somewhere in the tree Kwave::MenuNode *sub = findChild(n); if (!sub) { sub = insertBranch(n, command, shortcut, uid); } else if ( !sub->isBranch() && (p[0] != QLatin1Char('#'))) { // remove the "leaf" and insert a branch with // the same properties sub = leafToBranch(sub); } else if (!p.length() || (p[0] == QLatin1Char('#')) ) { // branch already exists and we are at the end of parsing // -> maybe we want to set new properties if (!shortcut.isEmpty()) sub->setShortcut(shortcut); if (uid.length()) sub->setUID(uid); } if (sub) { sub->insertNode(QString(), p, command, shortcut, uid); } else { qDebug("MenuNode::insertNode: branch failed!"); } } } //***************************************************************************** Kwave::MenuNode *Kwave::MenuNode::leafToBranch(Kwave::MenuNode *node) { Q_ASSERT(node); Q_ASSERT(node != this); if (!node || (node == this)) return Q_NULLPTR; // get the old properties bool old_enable = node->isEnabled(); QKeySequence old_shortcut = node->shortcut(); QString old_uid = node->uid(); QIcon old_icon = node->icon(); QString name = node->name(); QString command = node->command(); QStringList old_groups = node->m_groups; // remove the old child node removeChild(node); // insert the new branch Kwave::MenuSub *sub = insertBranch(name, command, old_shortcut, old_uid); if (sub) { // join it to the same groups foreach (const QString &group, old_groups) sub->joinGroup(group, Kwave::MenuGroup::NORMAL); // set the old icon if (!old_icon.isNull()) sub->setIcon(old_icon); // set the "enable" sub->setEnabled(old_enable); } // free the old node later. // IMPORTANT: we must not call "delete node" now, because we get called // through leafToBranch(this) ! Kwave::MenuRoot::deleteLater(node); return sub; } //***************************************************************************** QHash &Kwave::MenuNode::groupList() { static QHash _empty_list; Q_ASSERT(m_parentNode); return (m_parentNode) ? m_parentNode->groupList() : _empty_list; } //***************************************************************************** void Kwave::MenuNode::joinGroup(const QString &group, Kwave::MenuGroup::Mode mode) { if (m_groups.contains(group)) return; // already joined QHash &group_list = groupList(); Kwave::MenuGroup *grp = Q_NULLPTR; if (group_list.contains(group)) { grp = group_list[group]; } else { // group does not already exist, create a new one grp = new(std::nothrow) Kwave::MenuGroup(rootNode(), group, mode); if (grp) group_list.insert(group, grp); } // remember that we now belong to the given group m_groups.append(group); // register this node as a child of the group if (grp) grp->join(this); } //***************************************************************************** void Kwave::MenuNode::leaveGroup(const QString &group) { QHash &group_list = groupList(); Kwave::MenuGroup *grp = (group_list.contains(group)) ? group_list.value(group) : Q_NULLPTR; // remove the group from our list m_groups.removeAll(group); // remove ourself from the group if (grp) { grp->leave(this); // clean up the group if nobody uses it any more if (grp->isEmpty()) delete grp; } } //***************************************************************************** bool Kwave::MenuNode::specialCommand(const QString &command) { Kwave::Parser parser(command); if (parser.command() == _("#icon")) { // --- give the item an icon --- - const QString &filename = parser.firstParam(); - if (filename.length()) { + const QString &icon_name = parser.firstParam(); + if ( icon_name.length()) { // try to load from standard dirs - KIconLoader loader; - QIcon icon = loader.loadIcon(filename, - KIconLoader::Small, 0, KIconLoader::DefaultState, - QStringList(), Q_NULLPTR, true); - + QIcon icon = QIcon::fromTheme( icon_name ); if (!icon.isNull()) { setIcon(icon); } else { qWarning("MenuNode '%s': icon '%s' not found !", - DBG(name()), DBG(filename)); + DBG(name()), DBG( icon_name )); } } return true; } if (parser.command() == _("#listmenu")) { // make sure that the current node is a sub menu Kwave::MenuNode *parent = parentNode(); Kwave::MenuNode *sub = (parent && !isBranch()) ? parent->leafToBranch(this) : this; if (!sub) return false; // append a placeholder for inserting the list // (if it does not already exist) const QString uid = parser.firstParam(); const QString cmd = parser.nextParam(); if (!sub->findUID(uid)) { Kwave::MenuList *placeholder = new(std::nothrow) Kwave::MenuList(sub, cmd, uid); Q_ASSERT(placeholder); if (!placeholder) return false; sub->insertChild(placeholder, Q_NULLPTR); } return true; } if (parser.command() == _("#group")) { QString group = parser.firstParam(); while (group.length()) { joinGroup(group, Kwave::MenuGroup::NORMAL); group = parser.nextParam(); } return true; } if (command == _("#disabled")) { // disable the node setEnabled(false); return true; } if (command == _("#enabled")) { // enable the node setEnabled(true); return true; } return false; } //*************************************************************************** //*************************************************************************** diff --git a/libgui/SignalWidget.cpp b/libgui/SignalWidget.cpp index 8bafc6fb..0807ba9d 100644 --- a/libgui/SignalWidget.cpp +++ b/libgui/SignalWidget.cpp @@ -1,692 +1,690 @@ /*************************************************************************** SignalWidget.cpp - Widget for displaying the signal ------------------- begin : 1999 copyright : (C) 1999 by Martin Wilz email : Martin Wilz ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include +#include #include #include #include #include #include #include #include #include -#include #include "libkwave/ClipBoard.h" #include "libkwave/LabelList.h" #include "libkwave/SignalManager.h" #include "libkwave/String.h" #include "libkwave/Track.h" #include "libkwave/Utils.h" #include "libgui/SignalView.h" #include "libgui/SignalWidget.h" #include "libgui/TrackPixmap.h" #include "libgui/TrackView.h" // #include "libgui/ShortcutWrapper.h" // /** table of keyboard shortcuts 0...9 */ // static const int tbl_keys[10] = { // Qt::Key_1, // Qt::Key_2, // Qt::Key_3, // Qt::Key_4, // Qt::Key_5, // Qt::Key_6, // Qt::Key_7, // Qt::Key_8, // Qt::Key_9, // Qt::Key_0 // }; /** vertical zoom factor: minimum value */ #define VERTICAL_ZOOM_MIN 1.0 /** vertical zoom factor: maximum value */ #define VERTICAL_ZOOM_MAX 100.0 /** vertical zoom factor: increment/decrement factor */ #define VERTICAL_ZOOM_STEP_FACTOR 1.5 /** interval for limiting the number of repaints per second [ms] */ #define REPAINT_INTERVAL 50 //*************************************************************************** Kwave::SignalWidget::SignalWidget(QWidget *parent, Kwave::SignalManager *signal_manager, QVBoxLayout *upper_dock, QVBoxLayout *lower_dock) :QWidget(parent), m_signal_manager(signal_manager), m_views(), m_layout(this), m_upper_dock(upper_dock), m_lower_dock(lower_dock), m_offset(0), m_zoom(0.0), m_vertical_zoom(1.0), m_repaint_timer() { // qDebug("SignalWidget::SignalWidget()"); // connect to the signal manager's signals Kwave::SignalManager *sig = m_signal_manager; connect(sig, SIGNAL(sigTrackInserted(uint,Kwave::Track*)), this, SLOT(slotTrackInserted(uint,Kwave::Track*))); connect(sig, SIGNAL(sigTrackDeleted(uint,Kwave::Track*)), this, SLOT(slotTrackDeleted(uint,Kwave::Track*))); // use a timer for limiting the repaint rate m_repaint_timer.setSingleShot(true); connect(&m_repaint_timer, SIGNAL(timeout()), this, SLOT(repaintTimerElapsed())); // // -- accelerator keys for 1...9 -- // for (int i = 0; i < 10; i++) { // Kwave::ShortcutWrapper *shortcut = // new Kwave::ShortcutWrapper(this, tbl_keys[i], i); // connect(shortcut, SIGNAL(activated(int)), // this, SLOT(parseKey(int))); // } setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); m_layout.setColumnStretch(0, 0); m_layout.setColumnStretch(1, 100); m_layout.setMargin(0); m_layout.setVerticalSpacing(3); setLayout(&m_layout); m_layout.activate(); } //*************************************************************************** Kwave::SignalWidget::~SignalWidget() { } //*************************************************************************** void Kwave::SignalWidget::setZoomAndOffset(double zoom, sample_index_t offset) { Q_ASSERT(zoom >= 0.0); foreach (QPointer view, m_views) view->setZoomAndOffset(zoom, offset); } //*************************************************************************** void Kwave::SignalWidget::forwardCommand(const QString &command) { emit sigCommand(command); } //*************************************************************************** void Kwave::SignalWidget::requestRepaint(Kwave::SignalView *view) { // add the view to the repaint queue (if not already there) if (!m_repaint_queue.contains(view)) m_repaint_queue.enqueue(view); if (!m_repaint_timer.isActive()) { // start the repaint timer m_repaint_timer.start(REPAINT_INTERVAL); } // else: repainting is inhibited -> wait until the // repaint timer is elapsed } //*************************************************************************** void Kwave::SignalWidget::repaintTimerElapsed() { while (!m_repaint_queue.isEmpty()) { Kwave::SignalView *view = m_repaint_queue.dequeue(); if (!view) continue; view->refresh(); } } //*************************************************************************** void Kwave::SignalWidget::contextMenuEvent(QContextMenuEvent *e) { Q_ASSERT(e); bool have_signal = m_signal_manager && !m_signal_manager->isEmpty(); if (!have_signal)return; bool have_selection = (m_signal_manager->selection().length() > 1); bool have_labels = !(Kwave::LabelList(m_signal_manager->metaData()).isEmpty()); QMenu *context_menu = new QMenu(this); Q_ASSERT(context_menu); if (!context_menu) return; - KIconLoader icon_loader; - /* menu items common to all cases */ // undo QAction *action; action = context_menu->addAction( - icon_loader.loadIcon(_("edit-undo"), KIconLoader::Toolbar), + QIcon::fromTheme(_("edit-undo")), i18n("&Undo"), this, SLOT(contextMenuEditUndo()), Qt::CTRL + Qt::Key_Z); Q_ASSERT(action); if (!action) return; if (!m_signal_manager->canUndo()) action->setEnabled(false); // redo action = context_menu->addAction( - icon_loader.loadIcon(_("edit-redo"), KIconLoader::Toolbar), + QIcon::fromTheme(_("edit-redo")), i18n("&Redo"), this, SLOT(contextMenuEditRedo()), Qt::CTRL + Qt::Key_Y); Q_ASSERT(action); if (!action) return; if (!m_signal_manager->canRedo()) action->setEnabled(false); context_menu->addSeparator(); // cut/copy/paste QAction *action_cut = context_menu->addAction( - icon_loader.loadIcon(_("edit-cut"), KIconLoader::Toolbar), + QIcon::fromTheme(_("edit-cut")), i18n("Cu&t"), this, SLOT(contextMenuEditCut()), Qt::CTRL + Qt::Key_X); QAction *action_copy = context_menu->addAction( - icon_loader.loadIcon(_("edit-copy"), KIconLoader::Toolbar), + QIcon::fromTheme(_("edit-copy")), i18n("&Copy"), this, SLOT(contextMenuEditCopy()), Qt::CTRL + Qt::Key_C); QAction *action_paste = context_menu->addAction( - icon_loader.loadIcon(_("edit-paste"), KIconLoader::Toolbar), + QIcon::fromTheme(_("edit-paste")), i18n("&Paste"), this, SLOT(contextMenuEditPaste()), Qt::CTRL + Qt::Key_V); context_menu->addSeparator(); if (action_cut) action_cut->setEnabled(have_selection); if (action_copy) action_copy->setEnabled(have_selection); if (action_paste) action_paste->setEnabled(!Kwave::ClipBoard::instance().isEmpty()); int mouse_x = mapFromGlobal(e->globalPos()).x(); int mouse_y = mapFromGlobal(e->globalPos()).y(); if (mouse_x < 0) mouse_x = 0; if (mouse_y < 0) mouse_y = 0; if (mouse_x >= width()) mouse_x = width() - 1; if (mouse_y >= height()) mouse_y = height() - 1; QMenu *submenu_select = context_menu->addMenu(i18n("Selection")); Q_ASSERT(submenu_select); if (!submenu_select) return; // Selection / &Save QAction *action_select_save = submenu_select->addAction( - icon_loader.loadIcon(_("document-save"), KIconLoader::Toolbar), + QIcon::fromTheme(_("document-save")), i18n("&Save..."), this, SLOT(contextMenuSaveSelection())); Q_ASSERT(action_select_save); if (!action_select_save) return; action_select_save->setEnabled(have_selection); // Selection / &Expand to labels QAction *action_select_expand_to_labels = submenu_select->addAction( i18n("&Expand to Labels"), this, SLOT(contextMenuSelectionExpandToLabels()), Qt::Key_E); Q_ASSERT(action_select_expand_to_labels); if (!action_select_expand_to_labels) return; action_select_expand_to_labels->setEnabled(have_labels); // Selection / to next labels QAction *action_select_next_labels = submenu_select->addAction( i18n("To Next Labels"), this, SLOT(contextMenuSelectionNextLabels()), Qt::SHIFT + Qt::CTRL + Qt::Key_N); Q_ASSERT(action_select_next_labels); if (!action_select_next_labels) return; action_select_next_labels->setEnabled(have_labels); // Selection / to previous labels QAction *action_select_prev_labels = submenu_select->addAction( i18n("To Previous Labels"), this, SLOT(contextMenuSelectionPrevLabels()), Qt::SHIFT + Qt::CTRL + Qt::Key_P); Q_ASSERT(action_select_prev_labels); if (!action_select_prev_labels) return; action_select_prev_labels->setEnabled(have_labels); // find out whether there was a click within a signal view QSharedPointer item(Q_NULLPTR); foreach (QPointer view, m_views) { // map the rect of the view to our coordinate system const QRect view_rect = QRect( view->mapToParent(view->rect().topLeft()), view->mapToParent(view->rect().bottomRight())); // check: mouse click was into that view? if (view_rect.contains(mouse_x, mouse_y)) { // map mouse click position to coordinate system of the view QPoint pos = view->mapFromParent(QPoint(mouse_x, mouse_y)); // give the view the chance to extend the context menu view->handleContextMenu(pos, context_menu); // try to find a view item at these coordinates item = view->findItem(pos); // if found, give the item the chance to extend the context menu if (!item.isNull()) { connect(item.data(), SIGNAL(sigCommand(QString)), this, SLOT(forwardCommand(QString))); item->appendContextMenu(context_menu); } // we process only one view, views cannot overlap! break; } } context_menu->exec(QCursor::pos()); delete context_menu; } //*************************************************************************** void Kwave::SignalWidget::wheelEvent(QWheelEvent *event) { if (!event) return; // we currently are only interested in + if (event->modifiers() != Qt::AltModifier) { event->ignore(); return; } if (event->delta() > 0) { // zoom in setVerticalZoom(m_vertical_zoom * VERTICAL_ZOOM_STEP_FACTOR); event->accept(); } else if (event->delta() < 0) { // zoom out setVerticalZoom(m_vertical_zoom / VERTICAL_ZOOM_STEP_FACTOR); event->accept(); } else { // no change event->ignore(); } } //*************************************************************************** void Kwave::SignalWidget::setVerticalZoom(double zoom) { if (zoom > VERTICAL_ZOOM_MAX) zoom = VERTICAL_ZOOM_MAX; if (zoom < VERTICAL_ZOOM_MIN) zoom = VERTICAL_ZOOM_MIN; if (qFuzzyCompare(zoom, m_vertical_zoom)) return; // no change // take over the zoom factor m_vertical_zoom = zoom; // propagate the zoom to all views foreach (QPointer view, m_views) if (view) view->setVerticalZoom(m_vertical_zoom); // get back the maximum zoom set by the views foreach (QPointer view, m_views) if (view && view->verticalZoom() > m_vertical_zoom) m_vertical_zoom = view->verticalZoom(); } //*************************************************************************** int Kwave::SignalWidget::mapToViewPort(const QPoint &pos) const { if (m_views.isEmpty()) return mapFromGlobal(pos).x(); // if empty return mapFromGlobal(pos).x() - m_layout.cellRect(0, 1).left(); } //*************************************************************************** int Kwave::SignalWidget::visibleWidth() const { if (m_views.isEmpty()) return width(); // if empty return m_layout.cellRect(0, 1).width(); } //*************************************************************************** void Kwave::SignalWidget::insertRow(int index, Kwave::SignalView *view, QWidget *controls) { const int rows = m_layout.rowCount(); const int cols = m_layout.columnCount(); // update the layout: move all items from the index on to the next row for (int row = rows; row > index; row--) { for (int col = 0; col < cols; col++) { QLayoutItem *item = m_layout.itemAtPosition(row - 1, col); if (item) { m_layout.removeItem(item); m_layout.addItem(item, row, col); } } } // add the widget to the layout m_layout.addWidget(view, index, 1); if (controls) { // add the controls to the layout m_layout.addWidget(controls, index, 0); // associate the controls to the view, so that when the view // gets removed/deleted, the controls get removed as well view->addSibling(controls); m_layout.activate(); // NOTE: QLayout::activate() does not really activate the layout // synchronously as expected. Instead it posts an event to // invalidate the layout of it's parent widget. // Unfortunately we need reliable geometry information // already *now*, which forces us to do the event loop // right here. qApp->processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers); } } //*************************************************************************** void Kwave::SignalWidget::deleteRow(int index) { const int rows = m_layout.rowCount(); const int cols = m_layout.columnCount(); if (index >= rows) return; // update the layout: move all items from this row to the previous for (int row = index; row < (rows - 1); row++) { for (int col = 0; col < cols; col++) { QLayoutItem *item = m_layout.itemAtPosition(row + 1, col); if (item) { m_layout.removeItem(item); m_layout.addItem(item, row, col); } } } } //*************************************************************************** void Kwave::SignalWidget::insertView(Kwave::SignalView *view, QWidget *controls) { Q_ASSERT(m_upper_dock); Q_ASSERT(m_lower_dock); Q_ASSERT(view); if (!m_upper_dock || !m_lower_dock) return; if (!view) return; // set initial vertical zoom view->setVerticalZoom(m_vertical_zoom); // find the proper row to insert the track view int index = 0; int track = (view) ? view->track() : -1; const Kwave::SignalView::Location where = view->preferredLocation(); switch (where) { case Kwave::SignalView::UpperDockTop: { // upper dock area, top index = 0; m_upper_dock->insertWidget(0, view); Q_ASSERT(!controls); break; } case Kwave::SignalView::UpperDockBottom: { // upper dock area, bottom index = m_upper_dock->count(); m_upper_dock->addWidget(view); Q_ASSERT(!controls); break; } case Kwave::SignalView::Top: { // central layout, above all others index = m_upper_dock->count(); int row = 0; insertRow(row, view, controls); break; } case Kwave::SignalView::AboveTrackTop: { // above the corresponding track, start of group index = m_upper_dock->count(); int row = 0; for (;index < m_views.count(); ++row, ++index) { if (m_views[index]->track() >= track) break; // reached top if (m_views[index]->preferredLocation() >= Kwave::SignalView::Bottom) break; } insertRow(row, view, controls); break; } case Kwave::SignalView::AboveTrackBottom: { // above the corresponding track, end of group index = m_upper_dock->count(); int row = 0; for (;index < m_views.count(); ++row, ++index) { if (m_views[index]->track() < track) continue; // too early if (m_views[index]->track() != track) break; // next track if (m_views[index]->preferredLocation() != Kwave::SignalView::AboveTrackTop) break; } insertRow(row, view, controls); break; } case Kwave::SignalView::BelowTrackTop: { // below the corresponding track, start of group index = m_upper_dock->count(); int row = 0; for (;index < m_views.count(); ++row, ++index) { if (m_views[index]->track() < track) continue; // too early if (m_views[index]->track() != track) break; // next track if (m_views[index]->preferredLocation() >= Kwave::SignalView::BelowTrackTop) break; } insertRow(row, view, controls); break; } case Kwave::SignalView::BelowTrackBottom: { // below the corresponding track, end of group index = m_upper_dock->count(); int row = 0; for (;index < m_views.count(); ++row, ++index) { if (m_views[index]->track() < track) continue; // too early if (m_views[index]->track() != track) break; // next track if (m_views[index]->preferredLocation() >= Kwave::SignalView::Bottom) break; } insertRow(row, view, controls); break; } case Kwave::SignalView::Bottom: { // below all others int row = m_layout.rowCount(); index = m_upper_dock->count() + row; insertRow(row, view, controls); break; } case Kwave::SignalView::LowerDockTop: { // lower dock area, top index = m_upper_dock->count() + m_layout.rowCount(); m_lower_dock->insertWidget(0, view); Q_ASSERT(!controls); break; } case Kwave::SignalView::LowerDockBottom: // lower dock area, bottom index = m_upper_dock->count() + m_layout.rowCount() + m_lower_dock->count(); m_lower_dock->addWidget(view); Q_ASSERT(!controls); break; } // insert the view into the list of views Q_ASSERT(index >= 0); Q_ASSERT(index < m_upper_dock->count() + m_layout.rowCount() + m_lower_dock->count()); m_views.insert(index, view); // initially set the current view info view->setZoomAndOffset(m_zoom, m_offset); // connect all signals connect(view, SIGNAL(sigCommand(QString)), this, SIGNAL(sigCommand(QString)), Qt::QueuedConnection); connect(view, SIGNAL(sigNeedRepaint(Kwave::SignalView*)), this, SLOT(requestRepaint(Kwave::SignalView*))); connect(view, SIGNAL(contentSizeChanged()), this, SLOT(updateMinimumHeight())); connect(view, SIGNAL(destroyed(QObject*)), this, SLOT(updateMinimumHeight())); connect(view, SIGNAL(sigCursorChanged(sample_index_t)), this, SIGNAL(sigCursorChanged(sample_index_t))); connect(this, SIGNAL(sigCursorChanged(sample_index_t)), view, SLOT(showCursor(sample_index_t))); updateMinimumHeight(); } //*************************************************************************** void Kwave::SignalWidget::slotTrackInserted(unsigned int index, Kwave::Track *track) { Q_ASSERT(track); if (!track) return; // create a container widget for the track controls QWidget *controls = new QWidget(Q_NULLPTR); Q_ASSERT(controls); if (!controls) return; // create a new view for the track's signal Kwave::SignalView *new_view = new Kwave::TrackView( this, controls, m_signal_manager, track); Q_ASSERT(new_view); if (!new_view) { delete controls; return; } // loop over all views and adjust the track index of the following ones foreach (QPointer view, m_views) { if (view->track() >= Kwave::toInt(index)) view->setTrack(view->track() + 1); } // assign the view to the new track new_view->setTrack(index); insertView(new_view, controls); } //*************************************************************************** void Kwave::SignalWidget::slotTrackDeleted(unsigned int index, Kwave::Track *track) { Q_UNUSED(track); // loop over all views, delete those that are bound to this track // and adjust the index of the following ones bool empty = true; QMutableListIterator > it(m_views); while (it.hasNext()) { Kwave::SignalView *view = it.next(); if (view->track() == Kwave::toInt(index)) { it.remove(); delete view; } else if (view->track() > Kwave::toInt(index)) { view->setTrack(view->track() - 1); empty = false; } else if (view->track() != -1) { empty = false; } } // find out if there are any empty rows in the grid now const int rows = m_layout.rowCount(); const int cols = m_layout.columnCount(); for (int row = 0; row < rows; row++) { bool row_is_empty = true; for (int col = 0; col < cols; col++) { QLayoutItem *item = m_layout.itemAtPosition(row, col); if (item) { row_is_empty = false; break; } } if (row_is_empty) deleteRow(row); } // if there are only views with track() == -1, we are empty, // in that case delete the rest (all views) if (empty) { while (!m_views.isEmpty()) delete m_views.takeFirst(); } } //*************************************************************************** void Kwave::SignalWidget::updateMinimumHeight() { int height = 0; const int rows = m_layout.rowCount(); const int cols = m_layout.columnCount(); for (int row = 0; row < rows; row++) { int h = 0; for (int col = 0; col < cols; col++) { QLayoutItem *item = m_layout.itemAtPosition(row, col); QWidget *widget = (item) ? item->widget() : Q_NULLPTR; if (widget) { int min_height = widget->minimumSize().height(); if (min_height > h) h = min_height; } } height += h; } if (rows > 1) height += (rows - 1) * m_layout.verticalSpacing(); setMinimumHeight(height); } //*************************************************************************** // void Kwave::SignalWidget::parseKey(int key) // { // if ((key < 0) || (key >= m_lamps.count())) // return; // if (m_lamps.at(key)) m_lamps.at(key)->nextState(); // } //*************************************************************************** //*************************************************************************** diff --git a/libgui/TrackView.cpp b/libgui/TrackView.cpp index 79db932b..315528fe 100644 --- a/libgui/TrackView.cpp +++ b/libgui/TrackView.cpp @@ -1,530 +1,527 @@ /*************************************************************************** TrackView.cpp - signal views that shows the track in time space ------------------- begin : Sat Jan 30 2010 copyright : (C) 2010 by Thomas Eschenbacher email : Thomas.Eschenbacher@gmx.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "config.h" #include +#include #include #include #include #include #include #include -#include - #include "libkwave/Label.h" #include "libkwave/LabelList.h" #include "libkwave/SignalManager.h" #include "libkwave/String.h" #include "libkwave/Track.h" #include "libkwave/Utils.h" #include "libgui/LabelItem.h" #include "libgui/MultiStateWidget.h" #include "libgui/SelectionBorderItem.h" #include "libgui/SelectionItem.h" #include "libgui/TrackView.h" #include "libgui/ViewItem.h" /** minimum height of the view in pixel */ #define MINIMUM_HEIGHT 100 //*************************************************************************** Kwave::TrackView::TrackView(QWidget *parent, QWidget *controls, Kwave::SignalManager *signal_manager, Kwave::Track *track) :Kwave::SignalView(parent, controls, signal_manager, Kwave::SignalView::AboveTrackTop), m_pixmap(*track), m_last_width(-1), m_last_height(-1), m_image(), m_img_signal(), m_img_selection(), m_img_markers(), m_img_signal_needs_refresh(true), m_img_selection_needs_refresh(true), m_img_markers_needs_refresh(true), m_mouse_click_position(0), m_cursor_pos(SAMPLE_INDEX_MAX) { setMinimumSize(400, MINIMUM_HEIGHT); // trigger a repaint request when the signal has been modified connect(&m_pixmap, SIGNAL(sigModified()), this, SLOT(refreshSignalLayer())); if (controls) { // add the channel controls, for "enabled" / "disabled" QVBoxLayout *layout = new QVBoxLayout(controls); Q_ASSERT(layout); if (!layout) return; Kwave::MultiStateWidget *msw = new(std::nothrow) Kwave::MultiStateWidget(Q_NULLPTR, 0); Q_ASSERT(msw); if (!msw) { delete layout; return; } // add a bitmap for off (0 and on (1) msw->addPixmap(_("light_off.xpm")); msw->addPixmap(_("light_on.xpm")); // connect widget <-> track connect( msw, SIGNAL(clicked(int)), track, SLOT(toggleSelection()) ); connect( track, SIGNAL(sigSelectionChanged(bool)), msw, SLOT(switchState(bool)) ); msw->setMinimumSize(20, 20); msw->switchState(track->selected()); layout->addWidget(msw); } // get informed about meta data changes connect(signal_manager, SIGNAL( sigMetaDataChanged(Kwave::MetaDataList)), this, SLOT(refreshMarkersLayer()), Qt::QueuedConnection); // get informed about selection changes connect(&(signal_manager->selection()), SIGNAL(changed(sample_index_t,sample_index_t)), this, SLOT(refreshSelectionLayer())); // update the playback position connect(&(signal_manager->playbackController()), SIGNAL(sigPlaybackPos(sample_index_t)), this, SLOT(showCursor(sample_index_t))); connect(&(signal_manager->playbackController()), SIGNAL(sigPlaybackStopped()), this, SLOT(showCursor())); // update when the track selection changed connect(track, SIGNAL(sigSelectionChanged(bool)), this, SLOT(refreshSignalLayer())); } //*************************************************************************** Kwave::TrackView::~TrackView() { } //*************************************************************************** void Kwave::TrackView::refresh() { // qDebug("Kwave::TrackView[%d]::refresh()", track()); m_pixmap.repaint(); repaint(); } //*************************************************************************** void Kwave::TrackView::setZoomAndOffset(double zoom, sample_index_t offset) { Q_ASSERT(zoom >= 0.0); Kwave::SignalView::setZoomAndOffset(zoom, offset); m_pixmap.setZoom(zoom); m_pixmap.setOffset(offset); if (m_pixmap.isModified()) { refreshAllLayers(); } } //*************************************************************************** void Kwave::TrackView::setVerticalZoom(double zoom) { const int old_height = this->height(); const double old_zoom = verticalZoom(); if (old_height > MINIMUM_HEIGHT * old_zoom) { // stretched mode zoom *= double(old_height) / (old_zoom * double(MINIMUM_HEIGHT)); } Kwave::SignalView::setVerticalZoom(zoom); setMinimumHeight(Kwave::toInt(MINIMUM_HEIGHT * zoom)); emit contentSizeChanged(); } //*************************************************************************** QSharedPointer Kwave::TrackView::findItem(const QPoint &pos) { QSharedPointer item = QSharedPointer(Q_NULLPTR); Q_ASSERT(m_signal_manager); if (!m_signal_manager) return item; const double offset = m_offset + pixels2samples(pos.x()); // [samples] const double tolerance = m_zoom * selectionTolerance(); // [samples] const double fine_pos = static_cast(m_offset) + (static_cast(pos.x()) * m_zoom); // we support the following items (with this priority): // 1. a label, which can be moved // 2. the border of a selection (left or right), which can be moved // 3. the body of a selection, which can be dragged // find the nearest label Kwave::Label nearest_label; unsigned int nearest_label_index = 0; double d_label = tolerance; { unsigned int index = 0; foreach (const Kwave::Label &label, Kwave::LabelList(m_signal_manager->metaData())) { double d = qAbs(static_cast(label.pos()) - fine_pos); if (d < qMin(d_label, tolerance)) { d_label = d; nearest_label = label; nearest_label_index = index; } index++; } } // get information about the current selection double selection_first = static_cast( m_signal_manager->selection().first()); double selection_last = static_cast( m_signal_manager->selection().last()); bool selection_is_empty = (m_signal_manager->selection().length() == 0); const double d_selection_left = qAbs(selection_first - fine_pos); const double d_selection_right = qAbs(selection_last - fine_pos); // special case: label is near selection left and cursor is left // of selection -> take the label // (or vice versa at the right border) bool prefer_the_label = ((d_selection_left < tolerance) && (fine_pos < selection_first)) || ((d_selection_right < tolerance) && (fine_pos > selection_last)); bool selection_is_nearer = (d_selection_left <= d_label) || (d_selection_right <= d_label); if (selection_is_nearer && !prefer_the_label) { // one of the selection borders is nearer d_label = d_selection_left + d_selection_right; } if ( (d_label <= qMin(d_selection_left, d_selection_right)) && !nearest_label.isNull() ) { // found a label return QSharedPointer(new(std::nothrow) Kwave::LabelItem(*this, *m_signal_manager, nearest_label_index, nearest_label)); } if ( (d_selection_left < qMin(tolerance, d_selection_right)) || ((d_selection_left < tolerance) && selection_is_empty) ) { // found selection border (left) or empty selection return QSharedPointer(new(std::nothrow) Kwave::SelectionBorderItem( *this, *m_signal_manager, m_signal_manager->selection().first())); } if (d_selection_right < qMin(tolerance, d_selection_left)) { // found selection border (right) return QSharedPointer(new(std::nothrow) Kwave::SelectionBorderItem( *this, *m_signal_manager, m_signal_manager->selection().last())); } if ((offset >= selection_first) && (offset <= selection_last)) { // found selection body return QSharedPointer(new(std::nothrow) Kwave::SelectionItem(*this, *m_signal_manager)); } // nothing found return QSharedPointer(Q_NULLPTR); } //*************************************************************************** void Kwave::TrackView::handleContextMenu(const QPoint &pos, QMenu *menu) { - KIconLoader icon_loader; - QMenu *submenu_label = menu->addMenu(i18n("Label")); Q_ASSERT(submenu_label); if (!submenu_label) return; // add label QAction *action_label_new = submenu_label->addAction( - icon_loader.loadIcon(_("list-add"), KIconLoader::Toolbar), + QIcon::fromTheme(_("list-add")), i18n("New"), this, SLOT(contextMenuLabelNew())); Q_ASSERT(action_label_new); if (!action_label_new) return; // store the menu position m_mouse_click_position = m_offset + pixels2samples(pos.x()); } //*************************************************************************** void Kwave::TrackView::contextMenuLabelNew() { emit sigCommand(_("label:add(%1)").arg(m_mouse_click_position)); } //*************************************************************************** void Kwave::TrackView::resizeEvent(QResizeEvent *event) { Kwave::SignalView::resizeEvent(event); if (!event) return; // request a repaint on all size changes, but not on horizontal shrink if ((event->size().width() > m_last_width) || (event->size().height() != m_last_height)) { refreshAllLayers(); } } //*************************************************************************** void Kwave::TrackView::refreshSignalLayer() { m_img_signal_needs_refresh = true; emit sigNeedRepaint(this); } //*************************************************************************** void Kwave::TrackView::refreshSelectionLayer() { m_img_selection_needs_refresh = true; emit sigNeedRepaint(this); } //*************************************************************************** void Kwave::TrackView::refreshMarkersLayer() { m_img_markers_needs_refresh = true; emit sigNeedRepaint(this); } //*************************************************************************** void Kwave::TrackView::refreshAllLayers() { m_img_signal_needs_refresh = true; m_img_selection_needs_refresh = true; m_img_markers_needs_refresh = true; emit sigNeedRepaint(this); } //*************************************************************************** void Kwave::TrackView::paintEvent(QPaintEvent *) { Q_ASSERT(m_signal_manager); if (!m_signal_manager) return; // qDebug("TrackView::paintEvent()"); // #define DEBUG_REPAINT_TIMES #ifdef DEBUG_REPAINT_TIMES QTime time; time.start(); #endif /* DEBUG_REPAINT_TIMES */ QPainter p; const int width = QWidget::width(); const int height = QWidget::height(); // qDebug("TrackView::paintEvent(): width=%d, height=%d", width, height); // --- detect size changes and refresh the whole image --- if ((width > m_last_width) || (height != m_last_height)) { // qDebug("TrackView::paintEvent(): window size changed from " // "%dx%d to %dx%d", m_last_width, m_last_height, width, height); // create new images for the layers const QImage::Format format = QImage::Format_ARGB32_Premultiplied; m_img_signal = QImage(width, height, format); m_img_selection = QImage(width, height, format); m_img_markers = QImage(width, height, format); // create a new target image m_image = QImage(width, height, format); // mark all images as "need refresh" m_img_signal_needs_refresh = true; m_img_selection_needs_refresh = true; m_img_markers_needs_refresh = true; // remember the last width m_last_width = width; m_last_height = height; } // --- repaint of the signal layer --- if (m_img_signal_needs_refresh) { // qDebug("TrackView::paintEvent(): - redraw of signal layer -"); p.begin(&m_img_signal); // fix the width and height of the track pixmap if ((m_pixmap.width() < width) || (m_pixmap.height() != height)) m_pixmap.resize(width, height); // refresh the pixmap if (m_pixmap.isModified()) m_pixmap.repaint(); p.setCompositionMode(QPainter::CompositionMode_Source); p.drawPixmap(0, 0, m_pixmap.pixmap()); p.end(); m_img_signal_needs_refresh = false; } // --- repaint of the markers layer --- if (m_img_markers_needs_refresh) { // qDebug("TrackView::paintEvent(): - redraw of markers layer -"); p.begin(&m_img_markers); p.fillRect(0, 0, width, height, Qt::black); int last_marker = -1; const sample_index_t last_visible = lastVisible(); foreach (const Kwave::Label &label, Kwave::LabelList(m_signal_manager->metaData())) { sample_index_t pos = label.pos(); if (pos < m_offset) continue; // outside left if (pos > last_visible) break; // far outside right, done int x = samples2pixels(pos - m_offset); if (x >= width) break; // outside right, done // position must differ from the last one, otherwise we // would wipe out the last one with XOR mode if (x == last_marker) continue; p.setPen(Qt::cyan); p.setCompositionMode(QPainter::CompositionMode_Exclusion); p.drawLine(x, 0, x, height); last_marker = x; } p.end(); m_img_markers_needs_refresh = false; } // --- repaint of the selection layer --- if (m_img_selection_needs_refresh) { // qDebug("TrackView::paintEvent(): - redraw of selection layer -"); p.begin(&m_img_selection); p.fillRect(0, 0, width, height, Qt::black); sample_index_t left = m_signal_manager->selection().first(); sample_index_t right = m_signal_manager->selection().last(); const sample_index_t visible = pixels2samples(width); if ((right > 0) && (right >= m_offset)) { // shift and clip the selection, relative to m_offset left = (left > m_offset) ? (left - m_offset) : 0; if (left <= visible) { right -= m_offset; if (right > visible) right = visible + 1; // transform to pixel coordinates int l = samples2pixels(left); int r = samples2pixels(right); // clip to the widget's size if (r >= width) r = width - 1; if (l > r) l = r; p.setPen(Qt::yellow); if (l == r) { p.drawLine(l, 0, l, height); } else { p.setBrush(Qt::yellow); p.drawRect(l, 0, r - l + 1, height); } } } p.end(); m_img_selection_needs_refresh = false; } // bitBlt all layers together p.begin(&m_image); p.fillRect(0, 0, width, height, Qt::black); // paint the signal layer (copy mode) p.setCompositionMode(QPainter::CompositionMode_Source); p.drawImage(0, 0, m_img_signal); // paint the selection layer (XOR mode) p.setCompositionMode(QPainter::CompositionMode_Exclusion); p.drawImage(0, 0, m_img_selection); // paint the markers/labels layer (XOR mode) p.setCompositionMode(QPainter::CompositionMode_Exclusion); p.drawImage(0, 0, m_img_markers); // --- show the cursor position --- do { if (m_cursor_pos == SAMPLE_INDEX_MAX) break; if (m_cursor_pos < m_offset) break; const sample_index_t visible = pixels2samples(width); if (m_cursor_pos >= m_offset + visible) break; int x = samples2pixels(m_cursor_pos - m_offset); if (x >= width) break; p.setPen(Qt::yellow); p.setCompositionMode(QPainter::CompositionMode_Exclusion); p.drawLine(x, 0, x, height); } while (0); p.end(); // draw the result p.begin(this); p.drawImage(0, 0, m_image); p.end(); #ifdef DEBUG_REPAINT_TIMES qDebug("TrackView::paintEvent() -- done, t=%d ms --", time.elapsed()); #endif /* DEBUG_REPAINT_TIMES */ } //*************************************************************************** void Kwave::TrackView::showCursor(sample_index_t pos) { m_cursor_pos = pos; emit sigNeedRepaint(this); } //*************************************************************************** //*************************************************************************** diff --git a/plugins/playback/PlayBackDialog.cpp b/plugins/playback/PlayBackDialog.cpp index 5619abdb..39044928 100644 --- a/plugins/playback/PlayBackDialog.cpp +++ b/plugins/playback/PlayBackDialog.cpp @@ -1,665 +1,665 @@ /*************************************************************************** PlayBackDialog.cpp - dialog for configuring the playback ------------------- begin : Sun May 13 2001 copyright : (C) 2001 by Thomas Eschenbacher email : Thomas.Eschenbacher@gmx.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "libkwave/PlayBackDevice.h" #include "libkwave/PlayBackTypesMap.h" #include "libkwave/PlaybackController.h" #include "libkwave/Plugin.h" #include "libkwave/String.h" #include "libgui/FileDialog.h" #include "PlayBackDialog.h" #include "PlayBackPlugin.h" //*************************************************************************** Kwave::PlayBackDialog::PlayBackDialog( Kwave::Plugin &p, Kwave::PlaybackController &playback_controller, const Kwave::PlayBackParam ¶ms ) :QDialog(p.parentWidget()), PlayBackDlg(), m_playback_controller(playback_controller), m_device(Q_NULLPTR), m_playback_params(params), m_methods_map(), m_file_filter(_("")), m_devices_list_map(), m_enable_setDevice(true) { setupUi(this); setModal(true); // fill the combo box with playback methods unsigned int index=0; for (index = 0; index < m_methods_map.count(); index++) { cbMethod->addItem( m_methods_map.description(index, true), static_cast(m_methods_map.data(index)) ); } cbMethod->setEnabled(cbMethod->count() > 1); connect(cbMethod, SIGNAL(activated(int)), SLOT(methodSelected(int))); connect(cbDevice, SIGNAL(editTextChanged(QString)), SLOT(setDevice(QString))); connect(cbDevice, SIGNAL(activated(QString)), SLOT(setDevice(QString))); connect(cbBitsPerSample, SIGNAL(editTextChanged(QString)), SLOT(bitsPerSampleSelected(QString))); connect(cbBitsPerSample, SIGNAL(activated(QString)), SLOT(bitsPerSampleSelected(QString))); connect(sbChannels, SIGNAL(valueChanged(int)), SLOT(setChannels(int))); connect(slBufferSize, SIGNAL(valueChanged(int)), SLOT(setBufferSize(int))); connect(btSelectDevice, SIGNAL(clicked()), SLOT(selectPlaybackDevice())); connect(listDevices, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), SLOT(listEntrySelected(QTreeWidgetItem*,QTreeWidgetItem*))); connect(listDevices, SIGNAL(itemExpanded(QTreeWidgetItem*)), SLOT(listItemExpanded(QTreeWidgetItem*))); connect(listDevices, SIGNAL(focusLost()), SLOT(updateListSelection())); connect(btTest, SIGNAL(clicked()), SIGNAL(sigTestPlayback())); connect(btHelp->button(QDialogButtonBox::Help), SIGNAL(clicked()), this, SLOT(invokeHelp())); // remove the header of the tree view listDevices->headerItem()->setHidden(true); // fix the dialog size setFixedHeight(sizeHint().height()); // update the GUI elements // order is: Method -> Device -> "Select..."-button // -> Channels -> Bits per Sample setMethod(params.method); setDevice(params.device); setBitsPerSample(params.bits_per_sample); setChannels(params.channels); // buffer size is independent setBufferSize(params.bufbase); // set the focus onto the "OK" button buttonBox->button(QDialogButtonBox::Ok)->setFocus(); } //*************************************************************************** Kwave::PlayBackDialog::~PlayBackDialog() { } //*************************************************************************** void Kwave::PlayBackDialog::setMethod(Kwave::playback_method_t method) { Kwave::playback_method_t old_method = m_playback_params.method; m_playback_params.method = method; // update the selection in the combo box if necessary int index = cbMethod->findData(static_cast(method)); if (cbMethod->currentIndex() != index) { cbMethod->setCurrentIndex(index); return; // we will get called again, through "methodSelected(...)" } qDebug("PlayBackDialog::setMethod('%s' [%d])", DBG(m_methods_map.name(m_methods_map.findFromData(method))), static_cast(method) ); // set hourglass cursor QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); // change the playback method (class PlayBackDevice) if (m_device) delete m_device; m_device = Q_NULLPTR; // remember the device selection, just for the GUI // for the next time this method gets selected // change in method -> save the current device and use // the previous one QString device = _(""); QString section = _("plugin playback"); KConfigGroup cfg = KSharedConfig::openConfig()->group(section); // save the current device cfg.writeEntry( QString(_("last_device_%1")).arg(static_cast(old_method)), m_playback_params.device); qDebug("SAVE: '%s' (%d) -> '%s'", DBG(m_methods_map.name(m_methods_map.findFromData(old_method))), static_cast(old_method), DBG(m_playback_params.device.split(_("|")).at(0))); cfg.sync(); // NOTE: the "method" may get modified here if not supported! m_playback_controller.checkMethod(method); if (method != m_playback_params.method) { // method has been modified to some fallback -> start through qDebug(" method has changed: %d -> %d", static_cast(m_playback_params.method), static_cast(method)); setMethod(method); // -> recursion // remove hourglass QApplication::restoreOverrideCursor(); return; } // if we found no playback method if (method == Kwave::PLAYBACK_INVALID) { qWarning("found no valid playback method"); } // create a new playback device (will fail if method is unsupported) m_device = m_playback_controller.createDevice(method); if (!m_device) { // oops, something has failed :-( setSupportedDevices(QStringList()); setDevice(QString()); // remove hourglass QApplication::restoreOverrideCursor(); return; } // restore the previous settings of the new method device = cfg.readEntry( _("last_device_%1").arg(static_cast(method))); qDebug("RESTORE: '%s' (%d) -> '%s'", DBG(m_methods_map.name(m_methods_map.findFromData(method))), static_cast(method), DBG(device.split(_("|")).at(0))); m_playback_params.device = device; // set list of supported devices setSupportedDevices(m_device->supportedDevices()); // set current device, no matter if supported or not, // the dialog will take care of this. setDevice(m_playback_params.device); // check the filter for the "select..." dialog. If it is // empty, the "select" dialog will be disabled setFileFilter(m_device->fileFilter()); // remove hourglass QApplication::restoreOverrideCursor(); } //*************************************************************************** void Kwave::PlayBackDialog::methodSelected(int index) { Kwave::playback_method_t method = static_cast( cbMethod->itemData(index).toInt()); qDebug("PlayBackDialog::methodSelected(%d) -> %s [%d]", index, DBG(m_methods_map.name(m_methods_map.findFromData(method))), static_cast(method) ); if (method <= Kwave::PLAYBACK_NONE) return; if (method >= Kwave::PLAYBACK_INVALID) return; setMethod(method); } //*************************************************************************** void Kwave::PlayBackDialog::setSupportedDevices(QStringList devices) { Q_ASSERT(cbDevice); Q_ASSERT(listDevices); if (!cbDevice || !listDevices) return; QString current_device = m_playback_params.device; // disable all that noisy stuff that comes from modifying the // device controls... m_enable_setDevice = false; // qDebug("PlayBackDialog::setSupportedDevices():"); // foreach (const QString &d, devices) // qDebug(" '%s'", DBG(d)); cbDevice->clearEditText(); cbDevice->clear(); listDevices->clear(); if (devices.contains(_("#EDIT#"))) { devices.removeAll(_("#EDIT#")); cbDevice->setEditable(true); } else { cbDevice->setEditable(false); } if (devices.contains(_("#SELECT#"))) { devices.removeAll(_("#SELECT#")); btSelectDevice->setEnabled(true); btSelectDevice->show(); } else { btSelectDevice->setEnabled(false); btSelectDevice->hide(); } if (devices.contains(_("#TREE#"))) { // treeview mode - KIconLoader icon_loader; + KIconLoader *icon_loader = KIconLoader::global(); devices.removeAll((_("#TREE#"))); listDevices->setEnabled(true); cbDevice->setEnabled(false); cbDevice->hide(); m_devices_list_map.clear(); // build a tree with all nodes in the list foreach (const QString &dev_id, devices) { QTreeWidgetItem *parent = Q_NULLPTR; QStringList list = dev_id.split(_("||"), QString::KeepEmptyParts); foreach (const QString &t, list) { QString token(t); QTreeWidgetItem *item = Q_NULLPTR; // split the icon name from the token QString icon_name; int pos = token.indexOf(QLatin1Char('|')); if (pos > 0) { icon_name = token.mid(pos+1); token = token.left(pos); } // find the first item with the same text // and the same root if (parent) { for (int i = 0; i < parent->childCount(); i++) { QTreeWidgetItem *node = parent->child(i); if (node && node->text(0) == token) { item = node; break; } } } else { QList matches = listDevices->findItems(token, Qt::MatchExactly); if (matches.count()) item = matches.takeFirst(); } if (item) { // already in the list parent = item; } else if (parent) { // new leaf, add to the parent item = new QTreeWidgetItem(parent); Q_ASSERT(item); if (item) { item->setText(0, token); m_devices_list_map.insert(item, dev_id); } parent->setExpanded(true); parent->setFlags(parent->flags() & ~(Qt::ItemIsUserCheckable | Qt::ItemIsSelectable)); if (m_devices_list_map.contains(parent)) { // make the parent not selectable m_devices_list_map.remove(parent); } } else { // new root node item = new QTreeWidgetItem(listDevices); Q_ASSERT(item); if (item) { item->setText(0, token); m_devices_list_map.insert(item, dev_id); } } - if (item && icon_name.length()) { - QIcon icon = icon_loader.loadIcon( + if (item && icon_name.length() && icon_loader) { + QIcon icon = icon_loader->loadIcon( icon_name, KIconLoader::User); item->setIcon(0, icon); } // use the current item as parent for the next pass parent = item; } } } else { // combo box mode cbDevice->addItems(devices); cbDevice->show(); listDevices->setEnabled(false); if (devices.contains(current_device)) { // current device is in the list cbDevice->setCurrentIndex(cbDevice->findText(current_device)); } else { if (cbDevice->isEditable() && current_device.length()) { // user defined device name cbDevice->setEditText(current_device); } else if (devices.count()) { // one or more other possibilities -> take the first one cbDevice->setCurrentIndex(0); } else { // empty list of possibilities cbDevice->clearEditText(); cbDevice->clear(); } } cbDevice->setEnabled(devices.count() > 1); } // enable changes in the device controls again m_enable_setDevice = true; } //*************************************************************************** void Kwave::PlayBackDialog::listEntrySelected(QTreeWidgetItem *current, QTreeWidgetItem *previous) { Q_ASSERT(listDevices); Q_UNUSED(previous); if (!current || !listDevices) return; if (m_devices_list_map.contains(current)) setDevice(m_devices_list_map[current]); } //*************************************************************************** void Kwave::PlayBackDialog::listItemExpanded(QTreeWidgetItem *item) { Q_UNUSED(item); updateListSelection(); } //*************************************************************************** void Kwave::PlayBackDialog::updateListSelection() { // set the current device again, otherwise nothing will be selected setDevice(m_playback_params.device); } //*************************************************************************** void Kwave::PlayBackDialog::setDevice(const QString &device) { Q_ASSERT(cbDevice); Q_ASSERT(listDevices); if (!cbDevice || !listDevices) return; if (!m_enable_setDevice) return; qDebug("PlayBackDialog::setDevice(): '%s' -> '%s'", DBG(m_playback_params.device.split(_("|")).at(0)), DBG(device.split(_("|")).at(0))); if (listDevices->isEnabled()) { // treeview mode QTreeWidgetItem *node = m_devices_list_map.key(device, Q_NULLPTR); if (node) { node->setSelected(true); listDevices->scrollToItem(node); listDevices->setCurrentItem(node); } } else if (cbDevice->isEditable() && device.length()) { // user defined device name if (!device.isEmpty() && (cbDevice->currentText() != device)) { cbDevice->setCurrentIndex(cbDevice->findText(device)); cbDevice->setEditText(device); } } else { // just take one from the list if (cbDevice->findText(device) >= 0) { cbDevice->setCurrentIndex(cbDevice->findText(device)); } else if (cbDevice->count()) { cbDevice->setCurrentIndex(0); } } // select the default device if new one is not supported QString dev = device; if (m_device) { QStringList supported = m_device->supportedDevices(); supported.removeAll(_("#EDIT#")); supported.removeAll(_("#SELECT#")); supported.removeAll(_("#TREE#")); if (!supported.isEmpty() && !supported.contains(device)) { // use the first entry as default dev = supported.first(); qDebug("PlayBackPlugin::setDevice(%s) -> fallback to '%s'", DBG(device.split(_("|")).at(0)), DBG(dev.split(_("|")).at(0))); } } // take over the device, please note that this one might differ from // the device we got as parameter, maybe it is a fallback m_playback_params.device = dev; QList supported_bits; if (m_device) supported_bits = m_device->supportedBits(dev); setSupportedBits(supported_bits); unsigned int min = 0; unsigned int max = 0; if (m_device) m_device->detectChannels(dev, min, max); setSupportedChannels(min, max); } //*************************************************************************** void Kwave::PlayBackDialog::setBufferSize(int exp) { Q_ASSERT(slBufferSize); Q_ASSERT(txtBufferSize); if (!slBufferSize || !txtBufferSize) return; if (exp < 8) exp = 8; if (exp > 18) exp = 18; // update the slider if necessary if (slBufferSize->value() != exp) slBufferSize->setValue(exp); // take the value into our struct m_playback_params.bufbase = exp; // update the text unsigned int buffer_size = (1 << exp); QString text; if (buffer_size < 1024) { text = i18n("%1 Bytes", buffer_size); } else { text = i18n("%1 kB", buffer_size >> 10); } txtBufferSize->setText(text); } //*************************************************************************** void Kwave::PlayBackDialog::setSupportedBits(const QList &bits) { Q_ASSERT(cbBitsPerSample); if (!cbBitsPerSample) return; int current_bits = m_playback_params.bits_per_sample; cbBitsPerSample->clear(); QString txt; foreach (unsigned int b, bits) { txt.setNum(b); cbBitsPerSample->addItem(txt); } // if possibilities are "unknown" -> use last known setting if (!bits.count()) { txt.setNum(current_bits); cbBitsPerSample->addItem(txt); } if (!bits.contains(current_bits) && bits.count()) current_bits = bits.last(); setBitsPerSample(current_bits); cbBitsPerSample->setEnabled(bits.count() > 0); } //*************************************************************************** void Kwave::PlayBackDialog::bitsPerSampleSelected(const QString &text) { bool ok = false; unsigned int bits = text.toUInt(&ok); if (!ok) bits = 0; setBitsPerSample(bits); } //*************************************************************************** void Kwave::PlayBackDialog::setBitsPerSample(unsigned int bits) { Q_ASSERT(cbBitsPerSample); if (!cbBitsPerSample) return; qDebug("PlayBackDialog::setBitsPerSample(): %u -> %u", m_playback_params.bits_per_sample, bits); QString txt; txt.setNum(bits); if (cbBitsPerSample->findText(txt) >= 0) { cbBitsPerSample->setCurrentIndex(cbBitsPerSample->findText(txt)); m_playback_params.bits_per_sample = bits; } } //*************************************************************************** void Kwave::PlayBackDialog::setSupportedChannels(unsigned int min, unsigned int max) { Q_ASSERT(sbChannels); if (!sbChannels) return; int current_channels = m_playback_params.channels; // if possibilities are "unknown" -> use last known setting if (!min && !max && current_channels) min = max = current_channels; sbChannels->setMinimum(min); sbChannels->setMaximum(max); setChannels(current_channels); sbChannels->setEnabled(min != max); } //*************************************************************************** void Kwave::PlayBackDialog::setChannels(int channels) { Q_ASSERT(sbChannels); if (!sbChannels) return; if ((sbChannels->value() != channels) && (sbChannels->minimum() != sbChannels->maximum()) && (sbChannels->maximum() > 0)) { sbChannels->setValue(channels); channels = sbChannels->value(); } qDebug("PlayBackDialog::setChannels(): %d -> %d", m_playback_params.channels, channels); m_playback_params.channels = channels; QString txt; switch (channels) { case 1: txt = i18n("(mono)"); break; case 2: txt = i18n("(stereo)"); break; case 4: txt = i18n("(quadro)"); break; default: txt = _(""); } lblChannels->setText(txt); } //*************************************************************************** const Kwave::PlayBackParam &Kwave::PlayBackDialog::params() { return m_playback_params; } //*************************************************************************** void Kwave::PlayBackDialog::setFileFilter(const QString &filter) { m_file_filter = filter; if (btSelectDevice) btSelectDevice->setEnabled(m_file_filter.length()); } //*************************************************************************** void Kwave::PlayBackDialog::selectPlaybackDevice() { QString filter = m_file_filter; QPointer dlg = new(std::nothrow) Kwave::FileDialog( _("kfiledialog:///kwave_playback_device"), Kwave::FileDialog::OpenFile, filter, this, QUrl(_("file:/dev")) ); if (!dlg) return; dlg->setWindowTitle(i18n("Select Playback Device")); if (!m_playback_params.device.startsWith(_("#"))) dlg->selectUrl(QUrl(_("file:") + m_playback_params.device)); else dlg->selectUrl(QUrl(_("file:/dev/*"))); if (dlg->exec() == QDialog::Accepted) { QString new_device = dlg->selectedUrl().fileName(); // selected new device if (cbDevice) cbDevice->setEditText(new_device); } delete dlg; } //*************************************************************************** void Kwave::PlayBackDialog::invokeHelp() { KHelpClient::invokeHelp(_("playback")); } //*************************************************************************** //*************************************************************************** diff --git a/plugins/record/RecordDialog.cpp b/plugins/record/RecordDialog.cpp index 54afe7a1..63eb9ffc 100644 --- a/plugins/record/RecordDialog.cpp +++ b/plugins/record/RecordDialog.cpp @@ -1,1369 +1,1363 @@ /************************************************************************* RecordDialog.cpp - dialog window for controlling audio recording ------------------- begin : Wed Aug 20 2003 copyright : (C) 2003 by Thomas Eschenbacher email : Thomas.Eschenbacher@gmx.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "libkwave/Compression.h" #include "libkwave/SampleFormat.h" #include "libkwave/String.h" #include "libkwave/Utils.h" #include "libgui/FileDialog.h" #include "libgui/HMSTimeWidget.h" #include "LevelMeter.h" #include "RecordDevice.h" #include "RecordDialog.h" #include "RecordParams.h" #include "RecordState.h" -#include "krec_record.xpm" -#include "record_pause.xpm" -#include "record_stop.xpm" - // status bar icons #include "ledgreen.xpm" #include "ledlightgreen.xpm" #include "ledred.xpm" #include "ledyellow.xpm" #include "ok.xpm" #include "stop_hand.xpm" #include "walk_r1.xpm" #include "walk_r2.xpm" #include "walk_r3.xpm" #include "walk_r4.xpm" #include "walk_r5.xpm" #include "walk_r6.xpm" #include "walk_r7.xpm" #include "walk_r8.xpm" /* some macros, for laziness ;-) */ #define SETUP(enabled,property,check,value) \ check->setChecked(m_params.enabled); \ value->setValue(m_params.property); \ #define STD_SETUP(enabled,property,control) \ SETUP(enabled,property,chk##control,sb##control); \ sb##control->setEnabled(chk##control->isEnabled() && \ chk##control->isChecked()); #define STD_SETUP_SLIDER(enabled,property,control) \ STD_SETUP(enabled,property,control); \ sl##control->setEnabled(sb##control->isEnabled()); //*************************************************************************** Kwave::RecordDialog::RecordDialog(QWidget *parent, QStringList ¶ms, Kwave::RecordController *controller, Kwave::RecordDialog::Mode mode) :QDialog(parent), Ui::RecordDlg(), m_methods_map(), m_file_filter(), m_devices_list_map(), m_state(Kwave::REC_EMPTY), m_params(), m_supported_resolutions(), m_buffer_progress_count(0), m_buffer_progress_total(0), m_buffer_progress_timer(this), m_record_enabled(true), m_samples_recorded(0), m_enable_setDevice(true), m_state_icon_widget(Q_NULLPTR) { m_status_bar.m_state = Q_NULLPTR; m_status_bar.m_time = Q_NULLPTR; m_status_bar.m_sample_rate = Q_NULLPTR; m_status_bar.m_bits_per_sample = Q_NULLPTR; m_status_bar.m_tracks = Q_NULLPTR; setupUi(this); /* get initial parameters */ m_params.fromList(params); /* set the icons of the record control buttons */ - KIconLoader icon_loader; - btNew->setIcon( QIcon(icon_loader.loadIcon(_("document-new"), - KIconLoader::Toolbar))); - btStop->setIcon( QIcon(QPixmap(xpm_stop))); - btPause->setIcon( QIcon(QPixmap(xpm_pause))); - btRecord->setIcon(QIcon(QPixmap(xpm_krec_record))); + btNew->setIcon( QIcon::fromTheme(_("document-new"))); + btStop->setIcon( QIcon::fromTheme(_("kwave_player_stop"))); + btPause->setIcon( QIcon::fromTheme(_("kwave_player_pause"))); + btRecord->setIcon(QIcon::fromTheme(_("kwave_player_record"))); // fill the combo box with playback methods unsigned int index=0; for (index = 0; index < m_methods_map.count(); ++index) { cbMethod->addItem(m_methods_map.description(index, true)); } cbMethod->setEnabled(cbMethod->count() > 1); /* --- set up all controls with their default/startup values --- */ // pre-record STD_SETUP_SLIDER(pre_record_enabled, pre_record_time, RecordPre); connect(chkRecordPre, SIGNAL(toggled(bool)), this, SLOT(preRecordingChecked(bool))); connect(sbRecordPre, SIGNAL(valueChanged(int)), this, SLOT(preRecordingTimeChanged(int))); // record time (duration) STD_SETUP(record_time_limited, record_time, RecordTime); // start time (date & time) chkRecordStartTime->setChecked(m_params.start_time_enabled); startTime->setDateTime(m_params.start_time); // record trigger STD_SETUP_SLIDER(record_trigger_enabled, record_trigger, RecordTrigger); // amplification STD_SETUP_SLIDER(amplification_enabled, amplification, LevelAmplify); // AGC STD_SETUP_SLIDER(agc_enabled, agc_decay, LevelAGC); // fade in STD_SETUP(fade_in_enabled, fade_in_time, LevelFadeIn); // fade out STD_SETUP(fade_out_enabled, fade_out_time, LevelFadeOut); // sample rate, bits per sample, track // -> will be initialized later, by the plugin // number of buffers slSourceBufferCount->setValue(m_params.buffer_count); // power of buffer size slSourceBufferSize->setValue(m_params.buffer_size); sourceBufferSizeChanged(m_params.buffer_size); // after this point all controls have their initial values /* --- connect some missing low level GUI functionality --- */ connect(cbMethod, SIGNAL(activated(int)), this, SLOT(methodSelected(int))); // record buffer size and count slSourceBufferCount->setValue(m_params.buffer_count); slSourceBufferSize->setValue(m_params.buffer_size); connect(slSourceBufferSize, SIGNAL(valueChanged(int)), this, SLOT(sourceBufferSizeChanged(int))); connect(slSourceBufferCount, SIGNAL(valueChanged(int)), this, SLOT(sourceBufferCountChanged(int))); // device treeview connect(listDevices, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), SLOT(listEntrySelected(QTreeWidgetItem*,QTreeWidgetItem*))); connect(listDevices, SIGNAL(itemExpanded(QTreeWidgetItem*)), SLOT(listItemExpanded(QTreeWidgetItem*))); connect(listDevices, SIGNAL(focusLost()), SLOT(updateListSelection())); // "select device..." button connect(btSourceSelect, SIGNAL(clicked()), this, SLOT(selectRecordDevice())); connect(cbDevice, SIGNAL(activated(QString)), this, SLOT(setDevice(QString))); // setup controls connect(chkRecordTime, SIGNAL(toggled(bool)), this, SLOT(recordTimeChecked(bool))); connect(sbRecordTime, SIGNAL(valueChanged(int)), this, SLOT(recordTimeChanged(int))); connect(chkRecordStartTime, SIGNAL(toggled(bool)), this, SLOT(startTimeChecked(bool))); connect(startTime, SIGNAL(dateTimeChanged(QDateTime)), this, SLOT(startTimeChanged(QDateTime))); connect(chkRecordTrigger, SIGNAL(toggled(bool)), this, SLOT(triggerChecked(bool))); connect(sbRecordTrigger, SIGNAL(valueChanged(int)), this, SLOT(triggerChanged(int))); connect(cbFormatSampleRate, SIGNAL(editTextChanged(QString)), this, SLOT(sampleRateChanged(QString))); connect(cbFormatSampleRate, SIGNAL(activated(QString)), this, SLOT(sampleRateChanged(QString))); connect(sbFormatTracks, SIGNAL(valueChanged(int)), this, SLOT(tracksChanged(int))); connect(cbFormatCompression, SIGNAL(activated(int)), this, SLOT(compressionChanged(int))); connect(sbFormatResolution, SIGNAL(valueChanged(int)), this, SLOT(bitsPerSampleChanged(int))); connect(cbFormatSampleFormat, SIGNAL(activated(int)), this, SLOT(sampleFormatChanged(int))); // connect the buttons to the record controller connect(btNew, SIGNAL(clicked()), controller, SLOT(actionReset())); connect(btStop, SIGNAL(clicked()), controller, SLOT(actionStop())); connect(btPause, SIGNAL(clicked()), controller, SLOT(actionPause())); connect(btRecord, SIGNAL(clicked()), controller, SLOT(actionStart())); // stop recording when the window gets closed connect(this, SIGNAL(rejected()), controller, SLOT(actionStop())); connect(this, SIGNAL(accepted()), controller, SLOT(actionStop())); // connect the notifications/commands of the record controller connect(controller, SIGNAL(stateChanged(Kwave::RecordState)), this, SLOT(setState(Kwave::RecordState))); // timer for updating the buffer progress bar connect(&m_buffer_progress_timer, SIGNAL(timeout()), this, SLOT(updateBufferProgressBar())); // help button connect(buttonBox->button(QDialogButtonBox::Help), SIGNAL(clicked()), this, SLOT(invokeHelp())); // status bar m_state_icon_widget = new Kwave::StatusWidget(this); Q_ASSERT(m_state_icon_widget); if (!m_state_icon_widget) return; m_state_icon_widget->setFixedSize(16, 16); lbl_state->addWidget(m_state_icon_widget); m_status_bar.m_state = new (std::nothrow) QLabel(_(" ")); Q_ASSERT(m_status_bar.m_state); if (!m_status_bar.m_state) return; m_status_bar.m_state->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); lbl_state->addWidget(m_status_bar.m_state); m_status_bar.m_time = new (std::nothrow) QLabel(_(" ")); Q_ASSERT(m_status_bar.m_time); if (!m_status_bar.m_time) return; m_status_bar.m_time->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); lbl_state->addWidget(m_status_bar.m_time); m_status_bar.m_sample_rate = new (std::nothrow) QLabel(_(" ")); Q_ASSERT(m_status_bar.m_sample_rate); if (!m_status_bar.m_sample_rate) return; m_status_bar.m_sample_rate->setAlignment(Qt::AlignRight | Qt::AlignVCenter); lbl_state->addWidget(m_status_bar.m_sample_rate); m_status_bar.m_bits_per_sample = new (std::nothrow) QLabel(_(" ")); Q_ASSERT(m_status_bar.m_bits_per_sample); if (!m_status_bar.m_bits_per_sample) return; m_status_bar.m_bits_per_sample->setAlignment(Qt::AlignRight | Qt::AlignVCenter); lbl_state->addWidget(m_status_bar.m_bits_per_sample); m_status_bar.m_tracks = new (std::nothrow) QLabel(_(" ")); Q_ASSERT(m_status_bar.m_tracks); if (!m_status_bar.m_tracks) return; m_status_bar.m_tracks->setAlignment(Qt::AlignRight | Qt::AlignVCenter); lbl_state->addWidget(m_status_bar.m_tracks); m_state_icon_widget->setFixedSize(16, lbl_state->childrenRect().height()); // set the initial state of the dialog to "Reset/Empty" setState(Kwave::REC_EMPTY); // disable the "level" tab, it is not implemented yet tabRecord->setCurrentIndex(1); QWidget *page = tabRecord->currentWidget(); tabRecord->setCurrentIndex(0); if (page) delete page; // add the "Done" button manually, otherwise it would have "Cancel" semantic QPushButton *bt_done = buttonBox->addButton(i18n("&Done"), QDialogButtonBox::AcceptRole); Q_ASSERT(bt_done); if (!bt_done) return; connect(bt_done, SIGNAL(clicked(bool)), this, SLOT(accept())); switch (mode) { case Kwave::RecordDialog::SETTINGS_FORMAT: tabRecord->setCurrentIndex(1); break; case Kwave::RecordDialog::SETTINGS_SOURCE: tabRecord->setCurrentIndex(2); break; case Kwave::RecordDialog::START_RECORDING: /* FALLTHROUGH */ case Kwave::RecordDialog::SETTINGS_DEFAULT: /* FALLTHROUGH */ default: tabRecord->setCurrentIndex(0); // set the focus onto the "Record" button btRecord->setFocus(); break; } } //*************************************************************************** Kwave::RecordDialog::~RecordDialog() { updateBufferState(0,0); } //*************************************************************************** Kwave::RecordParams &Kwave::RecordDialog::params() { return m_params; } //*************************************************************************** void Kwave::RecordDialog::setMethod(Kwave::record_method_t method) { m_params.method = method; cbMethod->setCurrentIndex(m_methods_map.findFromData( m_params.method)); } //*************************************************************************** void Kwave::RecordDialog::methodSelected(int index) { Kwave::record_method_t method = m_methods_map.data(index); // qDebug("RecordDialog::methodSelected(%d) - %d", index, (int)method); Q_ASSERT(method > Kwave::RECORD_NONE); Q_ASSERT(method < Kwave::RECORD_INVALID); if (method <= Kwave::RECORD_NONE) return; if (method >= Kwave::RECORD_INVALID) return; if (method != m_params.method) { setMethod(method); emit sigMethodChanged(method); } } //*************************************************************************** void Kwave::RecordDialog::setSupportedDevices(QStringList devices) { // qDebug("RecordDialog::setSupportedDevices(QStringList devices)"); Q_ASSERT(cbDevice); Q_ASSERT(listDevices); if (!cbDevice || !listDevices) return; QString current_device = m_params.device_name; // disable all that noisy stuff that comes from modifying the // device controls... m_enable_setDevice = false; - KIconLoader icon_loader; + KIconLoader *icon_loader = KIconLoader::global(); cbDevice->clearEditText(); cbDevice->clear(); listDevices->clear(); if (devices.contains(_("#EDIT#"))) { devices.removeAll(_("#EDIT#")); cbDevice->setEditable(true); } else { cbDevice->setEditable(false); } if (devices.contains(_("#SELECT#"))) { devices.removeAll(_("#SELECT#")); btSourceSelect->setEnabled(true); btSourceSelect->show(); } else { btSourceSelect->setEnabled(false); btSourceSelect->hide(); } if (devices.contains(_("#TREE#"))) { // treeview mode devices.removeAll(_("#TREE#")); listDevices->setEnabled(true); cbDevice->setEnabled(false); cbDevice->hide(); m_devices_list_map.clear(); // build a tree with all nodes in the list foreach (QString dev_id, devices) { QTreeWidgetItem *parent = Q_NULLPTR; QStringList list = dev_id.split(_("||"), QString::KeepEmptyParts); foreach (QString token, list) { QTreeWidgetItem *item = Q_NULLPTR; // split the icon name from the token QString icon_name; int pos = token.indexOf(QLatin1Char('|')); if (pos > 0) { icon_name = token.mid(pos+1); token = token.left(pos); } // find the first item with the same text // and the same root if (parent) { for (int i = 0; i < parent->childCount(); i++) { QTreeWidgetItem *node = parent->child(i); if (node && node->text(0) == token) { item = node; break; } } } else { QList matches = listDevices->findItems(token, Qt::MatchExactly); if (matches.count()) item = matches.takeFirst(); } if (item) { // already in the list parent = item; } else if (parent) { // new leaf, add to the parent item = new QTreeWidgetItem(parent); Q_ASSERT(item); if (item) { item->setText(0, token); m_devices_list_map.insert(item, dev_id); } parent->setExpanded(true); parent->setFlags(parent->flags() & ~(Qt::ItemIsUserCheckable | Qt::ItemIsSelectable)); if (m_devices_list_map.contains(parent)) { // make the parent not selectable m_devices_list_map.remove(parent); } } else { // new root node item = new QTreeWidgetItem(listDevices); Q_ASSERT(item); if (item) { item->setText(0, token); m_devices_list_map.insert(item, dev_id); } } - if (item && icon_name.length()) { - QIcon icon = icon_loader.loadIcon( + if (item && icon_name.length() && icon_loader) { + QIcon icon = icon_loader->loadIcon( icon_name, KIconLoader::User); item->setIcon(0, icon); } // use the current item as parent for the next pass parent = item; } } } else { // combo box mode cbDevice->addItems(devices); cbDevice->show(); listDevices->setEnabled(false); if (devices.contains(current_device)) { // current device is in the list cbDevice->setCurrentIndex(cbDevice->findText(current_device)); } else { if (cbDevice->isEditable() && current_device.length()) { // user defined device name cbDevice->setEditText(current_device); } else if (devices.count()) { // one or more other possibilities -> take the first one cbDevice->setCurrentIndex(0); } else { // empty list of possibilities cbDevice->clearEditText(); cbDevice->clear(); } } cbDevice->setEnabled(devices.count() > 1); } // enable changes in the device controls again m_enable_setDevice = true; } //*************************************************************************** void Kwave::RecordDialog::listEntrySelected(QTreeWidgetItem *current, QTreeWidgetItem *previous) { Q_ASSERT(listDevices); Q_UNUSED(previous); if (!current || !listDevices) return; if (m_devices_list_map.contains(current)) setDevice(m_devices_list_map[current]); } //*************************************************************************** void Kwave::RecordDialog::listItemExpanded(QTreeWidgetItem *item) { Q_UNUSED(item); updateListSelection(); } //*************************************************************************** void Kwave::RecordDialog::updateListSelection() { // set the current device again, otherwise nothing will be selected setDevice(m_params.device_name); } //*************************************************************************** void Kwave::RecordDialog::setDevice(const QString &device) { Q_ASSERT(cbDevice); Q_ASSERT(listDevices); if (!cbDevice || !listDevices) return; bool device_changed = (device != m_params.device_name); m_params.device_name = device; // qDebug("RecordDialog::setDevice(%s)", device.local8Bit().data()); if (listDevices->isEnabled()) { // treeview mode QTreeWidgetItem *node = m_devices_list_map.key(device, Q_NULLPTR); if (node) { node->setSelected(true); listDevices->scrollToItem(node); listDevices->setCurrentItem(node); } } else if (cbDevice->isEditable() && device.length()) { // user defined device name if (!device.isEmpty() && (cbDevice->currentText() != device)) { cbDevice->setCurrentIndex(cbDevice->findText(device)); cbDevice->setEditText(device); } } else { // just take one from the list if (cbDevice->findText(device) >= 0) { cbDevice->setCurrentIndex(cbDevice->findText(device)); } else if (cbDevice->count()) { cbDevice->setCurrentIndex(0); } } if (device_changed) emit sigDeviceChanged(device); } //*************************************************************************** void Kwave::RecordDialog::sourceBufferCountChanged(int value) { Q_ASSERT(value >= 4); Q_ASSERT(value <= 64); if (value < 4) value = 4; if (value > 64) value = 64; // take the value into our struct m_params.buffer_count = value; emit sigBuffersChanged(); } //*************************************************************************** void Kwave::RecordDialog::sourceBufferSizeChanged(int value) { Q_ASSERT(value >= 10); Q_ASSERT(value <= 18); if (value < 10) value = 10; if (value > 18) value = 18; // take the value into our struct m_params.buffer_size = value; // update the text unsigned int buffer_size = (1 << value); txtSourceBuffer->setText(i18n("%1 samples", buffer_size)); emit sigBuffersChanged(); } //*************************************************************************** void Kwave::RecordDialog::setFileFilter(const QString &filter) { m_file_filter = filter; if (btSourceSelect) btSourceSelect->setEnabled(m_file_filter.length()); } //*************************************************************************** void Kwave::RecordDialog::selectRecordDevice() { if (!m_enable_setDevice) return; QString filter; filter += _("dsp*|") + i18n("OSS record device (dsp*)"); filter += _("\nadsp*|") + i18n("ALSA record device (adsp*)"); filter += _("\n*|") + i18n("Any device (*)"); QPointer dlg = new(std::nothrow) Kwave::FileDialog( _("kfiledialog:///kwave_record_device"), Kwave::FileDialog::OpenFile, filter, this, QUrl(_("file:/dev")) ); if (!dlg) return; dlg->setWindowTitle(i18n("Select Record Device")); if (!m_params.device_name.startsWith(_("#"))) dlg->selectUrl(QUrl(_("file:") + m_params.device_name)); else dlg->selectUrl(QUrl(_("file:/dev/*"))); if (dlg->exec() == QDialog::Accepted) { // selected new device QString new_device = dlg->selectedUrl().path(); if (new_device != m_params.device_name) emit sigDeviceChanged(new_device); } delete dlg; } //*************************************************************************** QString Kwave::RecordDialog::rate2string(double rate) const { QLocale locale; const QString dot = locale.decimalPoint(); const QString tsep = locale.groupSeparator(); // format number with 3 digits QString s = locale.toString(rate, 'f', 3); // remove thousands separator (looks ugly) s.remove(tsep); // remove trailing zeroes while (s.endsWith(_("0"))) s.remove(s.length()-1, 1); // remove decimal point if necessary if (s.endsWith(dot)) s.remove(s.length()-1, 1); return s; } //*************************************************************************** double Kwave::RecordDialog::string2rate(const QString &rate) const { QLocale locale; const QString s = rate; double r; bool ok; r = locale.toDouble(rate, &ok); Q_ASSERT(ok); if (!ok) return s.toDouble(); return r; } //*************************************************************************** void Kwave::RecordDialog::setSupportedTracks(unsigned int min, unsigned int max) { Q_ASSERT(sbFormatTracks); if (!sbFormatTracks) return; if ((min == max) || (!max)) { sbFormatTracks->setEnabled(false); return; } else sbFormatTracks->setEnabled(true); if (sbFormatTracks->value() < sbFormatTracks->minimum()) { sbFormatTracks->setMaximum(max); sbFormatTracks->setMinimum(min); } else { sbFormatTracks->setMinimum(min); sbFormatTracks->setMaximum(max); } } //*************************************************************************** void Kwave::RecordDialog::setTracks(unsigned int tracks) { // qDebug("+++ RecordDialog::setTracks(%u)", tracks); Q_ASSERT(sbFormatTracks); Q_ASSERT(m_status_bar.m_tracks); if (!sbFormatTracks || !m_status_bar.m_tracks) return; if (!tracks) return; m_params.tracks = tracks; QString tracks_str; switch (tracks) { case 1: tracks_str = i18n("Mono"); break; case 2: tracks_str = i18n("Stereo"); break; case 4: tracks_str = i18n("Quadro"); break; default: tracks_str = _(""); } if (tracks_str.length()) { lblTracksVerbose->setText(_("(") + tracks_str + _(")")); m_status_bar.m_tracks->setText(tracks_str); } else { lblTracksVerbose->setText(_("")); m_status_bar.m_tracks->setText(i18n("%1 tracks", tracks)); } sbFormatTracks->setValue(tracks); } //*************************************************************************** void Kwave::RecordDialog::tracksChanged(int tracks) { if (tracks < 1) return; // no device if (tracks == Kwave::toInt(m_params.tracks)) return; m_params.tracks = tracks; emit sigTracksChanged(tracks); } //*************************************************************************** void Kwave::RecordDialog::setSupportedSampleRates(const QList &rates) { Q_ASSERT(cbFormatSampleRate); if (!cbFormatSampleRate) return; cbFormatSampleRate->clearEditText(); cbFormatSampleRate->setEditable(false); cbFormatSampleRate->clear(); foreach (double r, rates) { QString rate = rate2string(r); Q_ASSERT(rate.length()); if (!rate.length()) continue; // string was zero? cbFormatSampleRate->addItem(rate); } bool have_choice = (cbFormatSampleRate->count() > 1); cbFormatSampleRate->setEnabled(have_choice); } //*************************************************************************** void Kwave::RecordDialog::setSampleRate(double new_rate) { Q_ASSERT(cbFormatSampleRate); Q_ASSERT(m_status_bar.m_sample_rate); if (!cbFormatSampleRate || !m_status_bar.m_sample_rate) return; if (new_rate <= 0) { cbFormatSampleRate->setEnabled(false); return; } else { bool have_choice = (cbFormatSampleRate->count() > 1); cbFormatSampleRate->setEnabled(have_choice); m_params.sample_rate = new_rate; } QString rate; rate = rate2string(new_rate); cbFormatSampleRate->setCurrentItem(rate, true); m_status_bar.m_sample_rate->setText(i18n("%1 Hz", rate)); } //*************************************************************************** void Kwave::RecordDialog::sampleRateChanged(const QString &rate) { if (!rate.length()) return; // no rate selected, combo box clear double sample_rate = string2rate(rate); if (qFuzzyCompare(sample_rate, m_params.sample_rate)) return; m_params.sample_rate = sample_rate; emit sampleRateChanged(sample_rate); } //*************************************************************************** void Kwave::RecordDialog::setSupportedCompressions( const QList &comps ) { Q_ASSERT(cbFormatCompression); if (!cbFormatCompression) return; cbFormatCompression->clear(); if (comps.isEmpty()) { // no compressions -> add "none" manually const Kwave::Compression comp(Kwave::Compression::NONE); cbFormatCompression->addItem(comp.name()); } else { foreach (Kwave::Compression::Type c, comps) { const Kwave::Compression comp(c); cbFormatCompression->addItem(comp.name(), comp.toInt()); } } bool have_choice = (cbFormatCompression->count() > 1); cbFormatCompression->setEnabled(have_choice); } //*************************************************************************** void Kwave::RecordDialog::setCompression(int compression) { Q_ASSERT(cbFormatCompression); if (!cbFormatCompression) return; if (compression < 0) { cbFormatCompression->setEnabled(false); return; } else { bool have_choice = (cbFormatCompression->count() > 1); cbFormatCompression->setEnabled(have_choice); m_params.compression = Kwave::Compression::fromInt(compression); } const Kwave::Compression comp(Kwave::Compression::fromInt(compression)); cbFormatCompression->setCurrentItem(comp.name(), true); } //*************************************************************************** void Kwave::RecordDialog::compressionChanged(int index) { Kwave::Compression::Type compression = Kwave::Compression::fromInt( cbFormatCompression->itemData(index).toInt()); if (compression != m_params.compression) emit sigCompressionChanged(compression); } //*************************************************************************** void Kwave::RecordDialog::setSupportedBits(const QList &bits) { Q_ASSERT(sbFormatResolution); if (!sbFormatResolution) return; m_supported_resolutions = bits; if (bits.count()) { sbFormatResolution->setMinimum(bits.first()); sbFormatResolution->setMaximum(bits.last()); } // enable only if there is a choice sbFormatResolution->setEnabled(bits.count() > 1); } //*************************************************************************** void Kwave::RecordDialog::setBitsPerSample(unsigned int bits) { Q_ASSERT(sbFormatResolution); Q_ASSERT(m_status_bar.m_bits_per_sample); if (!sbFormatResolution || !m_status_bar.m_bits_per_sample) return; if (!bits ) { sbFormatResolution->setEnabled(false); return; } else { sbFormatResolution->setEnabled(m_supported_resolutions.count() > 1); m_params.bits_per_sample = bits; } m_status_bar.m_bits_per_sample->setText(i18n("%1 bit", bits)); sbFormatResolution->setValue(bits); } //*************************************************************************** void Kwave::RecordDialog::bitsPerSampleChanged(int bits) { if (bits < 1) return; // no device int last = m_params.bits_per_sample; if (bits == last) return; // round up or down to the next supported resolution in bits per sample if (!m_supported_resolutions.isEmpty()) { if (bits > last) { // step up to the next supported value QListIterator it(m_supported_resolutions); while (it.hasNext()) { bits = it.next(); if (bits > last) break; } if (bits < last) bits = m_supported_resolutions.last(); } else { // step down to the next supported value QListIterator it(m_supported_resolutions); it.toBack(); while (it.hasPrevious()) { bits = it.previous(); if (bits < last) break; } if (bits > last) bits = m_supported_resolutions.first(); } } m_params.bits_per_sample = bits; if (sbFormatResolution && (bits != sbFormatResolution->value())) sbFormatResolution->setValue(bits); emit sigBitsPerSampleChanged(bits); } //*************************************************************************** void Kwave::RecordDialog::setSupportedSampleFormats( const QList &formats) { Q_ASSERT(cbFormatSampleFormat); if (!cbFormatSampleFormat) return; cbFormatSampleFormat->clear(); Kwave::SampleFormat::Map types; foreach (Kwave::SampleFormat::Format format, formats) { int index = types.findFromData(format); cbFormatSampleFormat->addItem( types.description(index, true), Kwave::SampleFormat(format).toInt() ); } bool have_choice = (cbFormatSampleFormat->count() > 1); cbFormatSampleFormat->setEnabled(have_choice); } //*************************************************************************** void Kwave::RecordDialog::setSampleFormat( Kwave::SampleFormat::Format sample_format) { Q_ASSERT(cbFormatSampleFormat); if (!cbFormatSampleFormat) return; if (sample_format == Kwave::SampleFormat::Unknown) { cbFormatSampleFormat->setEnabled(false); return; } else { bool have_choice = (cbFormatSampleFormat->count() > 1); cbFormatSampleFormat->setEnabled(have_choice); m_params.sample_format = sample_format; } int cb_index = cbFormatSampleFormat->findData( Kwave::SampleFormat(sample_format).toInt()); cbFormatSampleFormat->setCurrentIndex(cb_index); } //*************************************************************************** void Kwave::RecordDialog::sampleFormatChanged(int index) { Q_ASSERT(cbFormatSampleFormat); if (!cbFormatSampleFormat) return; Kwave::SampleFormat format; format.fromInt(cbFormatSampleFormat->itemData(index).toInt()); if (format == m_params.sample_format) return; emit sigSampleFormatChanged(format); } //*************************************************************************** void Kwave::RecordDialog::setState(Kwave::RecordState state) { Q_ASSERT(m_status_bar.m_state); if (!m_status_bar.m_state) return; bool enable_new = false; bool enable_pause = false; bool enable_stop = false; bool enable_record = false; bool enable_settings = false; bool enable_trigger = false; QString state_text = _(""); QVector pixmaps; unsigned int animation_time = 500; m_state = state; switch (state) { case Kwave::REC_UNINITIALIZED: state_text = i18n("Please check the source device settings..."); enable_new = true; enable_pause = false; enable_stop = false; enable_record = false; enable_settings = true; enable_trigger = true; pixmaps.push_back(QPixmap(stop_hand_xpm)); pixmaps.push_back(QPixmap(ledred_xpm)); m_status_bar.m_time->setText(_("")); break; case Kwave::REC_EMPTY: state_text = i18n("(empty)"); enable_new = true; enable_pause = false; enable_stop = false; enable_record = m_params.device_name.length(); enable_settings = true; enable_trigger = true; pixmaps.push_back(QPixmap(ledgreen_xpm)); m_status_bar.m_time->setText(_("")); break; case Kwave::REC_BUFFERING: state_text = i18n("Buffering..."); enable_new = true; /* throw away current FIFO content */ enable_pause = false; enable_stop = true; enable_record = true; /* acts as "trigger now" */ enable_settings = false; enable_trigger = true; pixmaps.push_back(QPixmap(ledgreen_xpm)); pixmaps.push_back(QPixmap(ledlightgreen_xpm)); break; case Kwave::REC_PRERECORDING: state_text = i18n("Prerecording..."); enable_new = false; enable_pause = false; enable_stop = true; enable_record = true; enable_settings = false; enable_trigger = true; pixmaps.push_back(QPixmap(ledgreen_xpm)); pixmaps.push_back(QPixmap(ledlightgreen_xpm)); break; case Kwave::REC_WAITING_FOR_TRIGGER: state_text = i18n("Waiting for trigger..."); enable_new = false; enable_pause = false; enable_stop = true; enable_record = true; /* acts as "trigger now" */ enable_settings = false; enable_trigger = true; pixmaps.push_back(QPixmap(ledgreen_xpm)); pixmaps.push_back(QPixmap(ledlightgreen_xpm)); break; case Kwave::REC_RECORDING: state_text = i18n("Recording..."); enable_new = false; enable_pause = true; enable_stop = true; enable_record = false; enable_settings = false; enable_trigger = false; pixmaps.push_back(QPixmap(walk_r1_xpm)); pixmaps.push_back(QPixmap(walk_r2_xpm)); pixmaps.push_back(QPixmap(walk_r3_xpm)); pixmaps.push_back(QPixmap(walk_r4_xpm)); pixmaps.push_back(QPixmap(walk_r5_xpm)); pixmaps.push_back(QPixmap(walk_r6_xpm)); pixmaps.push_back(QPixmap(walk_r7_xpm)); pixmaps.push_back(QPixmap(walk_r8_xpm)); animation_time = 100; break; case Kwave::REC_PAUSED: state_text = i18n("Paused"); enable_new = true; /* start again */ enable_pause = true; /* used for "continue" */ enable_stop = true; enable_record = true; /* used for "continue" */ enable_settings = false; enable_trigger = false; pixmaps.push_back(QPixmap(ledgreen_xpm)); pixmaps.push_back(QPixmap(ledyellow_xpm)); break; case Kwave::REC_DONE: state_text = i18n("Done"); enable_new = true; enable_pause = false; enable_stop = false; enable_record = true; enable_settings = true; enable_trigger = true; pixmaps.push_back(QPixmap(ok_xpm)); break; } m_status_bar.m_state->setText(state_text); m_state_icon_widget->setPixmaps(pixmaps, animation_time); // enable/disable the record control buttons btNew->setEnabled(enable_new); btPause->setEnabled(enable_pause); btStop->setEnabled(enable_stop); m_record_enabled = enable_record; updateRecordButton(); // enable disable all controls (groups) for setup chkRecordPre->setEnabled(enable_settings); sbRecordPre->setEnabled(enable_settings && chkRecordPre->isChecked()); slRecordPre->setEnabled(enable_settings && chkRecordPre->isChecked()); chkRecordStartTime->setEnabled(enable_settings); chkRecordTime->setEnabled(enable_settings); sbRecordTime->setEnabled(enable_settings && chkRecordTime->isChecked()); chkRecordTrigger->setEnabled(enable_settings); // it is not really necessary to disable these ;-) sbRecordTrigger->setEnabled(enable_trigger && chkRecordTrigger->isChecked()); slRecordTrigger->setEnabled(enable_trigger && chkRecordTrigger->isChecked()); startTime->setEnabled(enable_settings && chkRecordStartTime->isChecked()); grpFormat->setEnabled(enable_settings); grpSource->setEnabled(enable_settings); } //*************************************************************************** void Kwave::RecordDialog::updateBufferState(unsigned int count, unsigned int total) { Q_ASSERT(progress_bar); Q_ASSERT(m_status_bar.m_state); if (!progress_bar || !m_status_bar.m_state) return; if (total == 0) { // we are done: stop update timer and reset buffer percentage m_buffer_progress_timer.stop(); m_buffer_progress_count = 0; m_buffer_progress_total = 0; progress_bar->setTextVisible(false); progress_bar->setMinimum(0); progress_bar->setMaximum(100); progress_bar->setValue(0); progress_bar->reset(); } else { m_buffer_progress_count = count; m_buffer_progress_total = total; if (!m_buffer_progress_timer.isActive()) updateBufferProgressBar(); } // update recording time QString txt; switch (m_state) { case Kwave::REC_UNINITIALIZED: case Kwave::REC_EMPTY: case Kwave::REC_BUFFERING: case Kwave::REC_PRERECORDING: txt = _(""); break; case Kwave::REC_WAITING_FOR_TRIGGER: { txt = _(""); QString state_text; QDateTime now = QDateTime::currentDateTime(); QDateTime t_start = m_params.start_time; if (m_params.start_time_enabled && (now < t_start)) { // waiting for start time to come... int s = Kwave::toInt(now.secsTo(t_start)); int m = s / 60; s %= 60; int h = m / 60; m %= 60; int d = h / 24; h %= 24; QString days = (d) ? i18np("one day ", "%1 days ", d) : _(""); QString hours = (h) ? i18np("one hour ", "%1 hours ", h) : _(""); QString minutes = (m) ? i18np("one minute ", "%1 minutes ", m) : _(""); QString seconds = (d | h | m) ? i18np("and %1 second", "and %1 seconds", s) : i18np("%1 second", "%1 seconds", s); state_text = i18nc( "%1=days; %2=hours; %3=minutes; %4=seconds", "Waiting for start in %1%2%3%4...", days, hours, minutes, seconds); } else { // waiting for trigger... state_text = i18n("Waiting for trigger..."); } m_status_bar.m_state->setText(state_text); break; } case Kwave::REC_RECORDING: case Kwave::REC_PAUSED: case Kwave::REC_DONE: { if (m_samples_recorded > 1) { double rate = m_params.sample_rate; double ms = (rate > 0) ? ((static_cast(m_samples_recorded) / rate) * 1E3) : 0; txt = _(" ") + i18n("Length: %1", Kwave::ms2string(ms)) + _(" ") + i18n("(%1 samples)", Kwave::samples2string(m_samples_recorded)); } else txt = _(""); break; } } m_status_bar.m_time->setText(txt); } //*************************************************************************** void Kwave::RecordDialog::preRecordingChecked(bool enabled) { m_params.pre_record_enabled = enabled; emit sigPreRecordingChanged(enabled); } //*************************************************************************** void Kwave::RecordDialog::preRecordingTimeChanged(int time) { m_params.pre_record_time = time; } //*************************************************************************** void Kwave::RecordDialog::recordTimeChecked(bool limited) { m_params.record_time_limited = limited; emit sigRecordTimeChanged(limited ? sbRecordTime->value() : -1); } //*************************************************************************** void Kwave::RecordDialog::recordTimeChanged(int limit) { m_params.record_time = limit; emit sigRecordTimeChanged(chkRecordTime->isChecked() ? limit : -1); updateRecordButton(); } //*************************************************************************** void Kwave::RecordDialog::startTimeChecked(bool enabled) { m_params.start_time_enabled = enabled; emit sigTriggerChanged(enabled || m_params.record_trigger_enabled); } //*************************************************************************** void Kwave::RecordDialog::startTimeChanged(const QDateTime &datetime) { m_params.start_time = datetime; // force seconds to zero QTime t = m_params.start_time.time(); t.setHMS(t.hour(), t.minute(), 0, 0); m_params.start_time.setTime(t); } //*************************************************************************** void Kwave::RecordDialog::triggerChecked(bool enabled) { m_params.record_trigger_enabled = enabled; emit sigTriggerChanged(enabled || m_params.start_time_enabled); } //*************************************************************************** void Kwave::RecordDialog::triggerChanged(int trigger) { m_params.record_trigger = trigger; } //*************************************************************************** void Kwave::RecordDialog::updateBufferProgressBar() { unsigned int count = m_buffer_progress_count; unsigned int total = m_buffer_progress_total; // qDebug("RecordDialog::updateBufferProgressBar(): %u/%u", // count, total); /* * @note: QProgressBar has a bug when handling small numbers, * therefore we multiply everything by 100 */ progress_bar->setTextVisible(true); progress_bar->setMinimum(0); progress_bar->setMaximum(100 * total); progress_bar->setValue(100 * count); m_buffer_progress_timer.setSingleShot(true); m_buffer_progress_timer.setInterval(100); m_buffer_progress_timer.start(); } //*************************************************************************** void Kwave::RecordDialog::updateEffects(unsigned int track, Kwave::SampleArray &buffer) { if (!buffer.size()) return; if (level_meter) { level_meter->setTracks(m_params.tracks); level_meter->setSampleRate(m_params.sample_rate); level_meter->updateTrack(track, buffer); } } //*************************************************************************** void Kwave::RecordDialog::setRecordedSamples(sample_index_t samples_recorded) { // if (!m_params.record_time_limited) return; // not of interest m_samples_recorded = samples_recorded; updateRecordButton(); } //*************************************************************************** void Kwave::RecordDialog::updateRecordButton() { bool old_enable = btRecord->isEnabled(); bool new_enable; // enabled if not disabled by status and also not limited or // less than the limit has been recorded new_enable = m_record_enabled && (!m_params.record_time_limited || (m_samples_recorded < m_params.record_time * m_params.sample_rate)); if (new_enable != old_enable) btRecord->setEnabled(new_enable); } //*************************************************************************** void Kwave::RecordDialog::invokeHelp() { KHelpClient::invokeHelp(_("recording")); } //*************************************************************************** void Kwave::RecordDialog::message(const QString &message) { if (lbl_state) lbl_state->showMessage(message, 3000); } //*************************************************************************** void Kwave::RecordDialog::showDevicePage() { if (tabRecord) tabRecord->setCurrentIndex(2); } //*************************************************************************** //*************************************************************************** diff --git a/plugins/record/krec_record.xpm b/plugins/record/krec_record.xpm deleted file mode 100644 index ed20d491..00000000 --- a/plugins/record/krec_record.xpm +++ /dev/null @@ -1,251 +0,0 @@ -/* XPM */ -static const char *xpm_krec_record[] = { -/* columns rows colors chars-per-pixel */ -"22 22 223 2", -" c #9D0000", -". c #A00000", -"X c #A20000", -"o c #A40000", -"O c #AD0000", -"+ c #AF0000", -"@ c #B10000", -"# c #B20000", -"$ c #BF0000", -"% c #B71414", -"& c #C10000", -"* c #D60000", -"= c #DD0505", -"- c #D01212", -"; c #E10000", -": c #E40000", -"> c #E60000", -", c #E40202", -"< c #E90000", -"1 c #EA0000", -"2 c #E80303", -"3 c #EC0000", -"4 c #EF0101", -"5 c #ED0707", -"6 c #EE0E0E", -"7 c #F40000", -"8 c #F50000", -"9 c #F70000", -"0 c #F50505", -"q c #F90000", -"w c #FA0000", -"e c #FC0101", -"r c #FD0101", -"t c #FE0303", -"y c #FE0505", -"u c #F00E0E", -"i c #FF0909", -"p c #FF0A0A", -"a c #FF0D0D", -"s c #E01B1B", -"d c #E21B1B", -"f c #FF1010", -"g c #FF1313", -"h c #FA1616", -"j c #FD1414", -"k c #FF1616", -"l c #FF1818", -"z c #FF1919", -"x c #FF1C1C", -"c c #FF1D1D", -"v c #FC1F1F", -"b c #C12020", -"n c #D12828", -"m c #C63A3A", -"M c #C73A3A", -"N c #F72121", -"B c #F92121", -"V c #FF2020", -"C c #FF2424", -"Z c #FF2727", -"A c #FF2828", -"S c #FF2C2C", -"D c #FF2E2E", -"F c #EB3D3D", -"G c #ED3D3D", -"H c #FE3131", -"J c #FF3232", -"K c #FE3333", -"L c #FF3434", -"P c #FF3535", -"I c #F23D3D", -"U c #F43D3D", -"Y c #FF3838", -"T c #FF3939", -"R c #FF3A3A", -"E c #F83D3D", -"W c #FA3D3D", -"Q c #FF3C3C", -"! c #FF3D3D", -"~ c #FD3E3E", -"^ c #FE3F3F", -"/ c #FF3F3F", -"( c #D64040", -") c #D74040", -"_ c #D54646", -"` c #D64646", -"' c #D24B4B", -"] c #D95C5C", -"[ c #DA5C5C", -"{ c #E74848", -"} c #E14D4D", -"| c #E34D4D", -" . c #E84848", -".. c #EC4848", -"X. c #EE4848", -"o. c #FF4141", -"O. c #FF4343", -"+. c #FF4444", -"@. c #FF4545", -"#. c #FF4747", -"$. c #F24848", -"%. c #F34848", -"&. c #F74848", -"*. c #F84848", -"=. c #FB4848", -"-. c #FC4848", -";. c #FE4949", -":. c #FF4949", -">. c #FE4A4A", -",. c #FF4B4B", -"<. c #FF4C4C", -"1. c #FF4D4D", -"2. c #FF4E4E", -"3. c #FF4F4F", -"4. c #E85252", -"5. c #E95252", -"6. c #EC5252", -"7. c #ED5252", -"8. c #E35D5D", -"9. c #E45D5D", -"0. c #E75D5D", -"q. c #E85D5D", -"w. c #EB5D5D", -"e. c #EC5D5D", -"r. c #EE5D5D", -"t. c #EF5D5D", -"y. c #F05252", -"u. c #F15252", -"i. c #F45252", -"p. c #F55252", -"a. c #F75252", -"s. c #F85252", -"d. c #FA5252", -"f. c #FB5252", -"g. c #FF5050", -"h. c #FF5151", -"j. c #FC5252", -"k. c #FD5252", -"l. c #FF5252", -"z. c #FF5353", -"x. c #FF5454", -"c. c #FF5555", -"v. c #FF5757", -"b. c #F15D5D", -"n. c #F35D5D", -"m. c #F45D5D", -"M. c #F55D5D", -"N. c #FF5858", -"B. c #FF5959", -"V. c #FF5A5A", -"C. c #FF5B5B", -"Z. c #FF5C5C", -"A. c #FF5D5D", -"S. c #FF5E5E", -"D. c #D96464", -"F. c #E36767", -"G. c #E46767", -"H. c #E66767", -"J. c #E76767", -"K. c #E96767", -"L. c #EB6767", -"P. c #EC6767", -"I. c #ED6767", -"U. c #EE6767", -"Y. c #EF6767", -"T. c #FF6161", -"R. c #FF6262", -"E. c #FF6464", -"W. c #FF6565", -"Q. c #FF6666", -"!. c #FF6868", -"~. c #FF6969", -"^. c #FF6A6A", -"/. c #FF6B6B", -"(. c #FF6E6E", -"). c #E27272", -"_. c #E37272", -"`. c #E57272", -"'. c #E67272", -"]. c #E77272", -"[. c #E87272", -"{. c #E97272", -"}. c #EA7272", -"|. c #E37C7C", -" X c #E47C7C", -".X c #E57C7C", -"XX c #FF7373", -"oX c #FF7676", -"OX c #FF7777", -"+X c #FF7878", -"@X c #FF7979", -"#X c #FF7A7A", -"$X c #FF7C7C", -"%X c #FF7D7D", -"&X c #FF8282", -"*X c #FF8383", -"=X c #FF8585", -"-X c #FF8686", -";X c #FF8888", -":X c #FF8989", -">X c #FF8A8A", -",X c #FF8C8C", -".-.*.%.X. .- aX", -"aXs F I E ~ O.:.3.l.x.c.z.g.,.+.^ W U G d aX", -"aX: 6 N H ! @.1.z.N.V.C.B.c.3.#./ K B u > aX", -"aX3 7 r a C T :.z.C.T.R.Z.x.,.Q Z f t 9 4 aX", -"aX1 w i z A P o.,.z.v.v.x.2.+.T S c a e 2 aX", -"aX, y g C L O.h.Z.E.~.^.Q.S.x.#.Y A l p = aX", -"aX; j x D / 3.S./.oX$X%X+X(.R.z.O.J V v * aX", -"aXaX0 D P #.B.^.@X-XX8X7X&X^.3.aXaXaXaXaXaXaX", -"aXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaX", -"aXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaX" -}; diff --git a/plugins/record/record_pause.xpm b/plugins/record/record_pause.xpm deleted file mode 100644 index 23c4aa56..00000000 --- a/plugins/record/record_pause.xpm +++ /dev/null @@ -1,27 +0,0 @@ -/* XPM */ -static const char * xpm_pause[] = { -"22 22 2 1", -" c None", -"# c #000000", -" ", -" ", -" ", -" ", -" ", -" ", -" #### #### ", -" #### #### ", -" #### #### ", -" #### #### ", -" #### #### ", -" #### #### ", -" #### #### ", -" #### #### ", -" #### #### ", -" #### #### ", -" ", -" ", -" ", -" ", -" ", -" "}; diff --git a/plugins/record/record_pause2.xpm b/plugins/record/record_pause2.xpm deleted file mode 100644 index b2d0a08a..00000000 --- a/plugins/record/record_pause2.xpm +++ /dev/null @@ -1,28 +0,0 @@ -/* XPM */ -static const char * xpm_pause2[] = { -"22 22 3 1", -" c None", -". c Yellow", -"# c #000000", -" ", -" ", -" ", -" ", -" ", -" ", -" ##### ##### ", -" #...# #...# ", -" #...# #...# ", -" #...# #...# ", -" #...# #...# ", -" #...# #...# ", -" #...# #...# ", -" #...# #...# ", -" #...# #...# ", -" ##### ##### ", -" ", -" ", -" ", -" ", -" ", -" "}; diff --git a/plugins/record/record_stop.xpm b/plugins/record/record_stop.xpm deleted file mode 100644 index d8bc241f..00000000 --- a/plugins/record/record_stop.xpm +++ /dev/null @@ -1,30 +0,0 @@ -/* XPM */ -static const char *xpm_stop[] = { -/* columns rows colors chars-per-pixel */ -"22 22 2 1", -" c None", -"# c #000000", -/* pixels */ -" ", -" ", -" ", -" ", -" ", -" ########## ", -" ########## ", -" ########## ", -" ########## ", -" ########## ", -" ########## ", -" ########## ", -" ########## ", -" ########## ", -" ########## ", -" ########## ", -" ########## ", -" ", -" ", -" ", -" ", -" ", -}; diff --git a/plugins/stringenter/StringEnterPlugin.cpp b/plugins/stringenter/StringEnterPlugin.cpp index b6429d22..97331fd1 100644 --- a/plugins/stringenter/StringEnterPlugin.cpp +++ b/plugins/stringenter/StringEnterPlugin.cpp @@ -1,90 +1,91 @@ /*************************************************************************** StringEnterPlugin.cpp - plugin for entering a text command ------------------- begin : Sat Mar 14 2015 copyright : (C) 2015 by Thomas Eschenbacher email : Thomas.Eschenbacher@gmx.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "config.h" #include "errno.h" #include #include #include #include "libkwave/String.h" #include "libkwave/Utils.h" #include "StringEnterDialog.h" #include "StringEnterPlugin.h" KWAVE_PLUGIN(stringenter, StringEnterPlugin) //*************************************************************************** Kwave::StringEnterPlugin::StringEnterPlugin(QObject *parent, const QVariantList &args) :Kwave::Plugin(parent, args) { } //*************************************************************************** Kwave::StringEnterPlugin::~StringEnterPlugin() { } //*************************************************************************** void Kwave::StringEnterPlugin::load(QStringList ¶ms) { Q_UNUSED(params); - QString entry = _("menu(plugin:setup(stringenter),%1/%2,F12)"); + QString entry = + _("menu(plugin:setup(stringenter),%1/%2/#icon(editor),F12)"); emitCommand(entry.arg(_("Settings")).arg(_(I18N_NOOP2( "menu: /Settings/Enter Command", "Enter Command") ))); } //*************************************************************************** QStringList *Kwave::StringEnterPlugin::setup(QStringList &previous_params) { QString preset; if (previous_params.count() == 1) preset = previous_params[0]; // create the setup dialog QPointer dialog = new Kwave::StringEnterDialog(parentWidget(), preset); Q_ASSERT(dialog); if (!dialog) return Q_NULLPTR; QStringList *list = new QStringList(); Q_ASSERT(list); if (list && dialog->exec()) { // user has pressed "OK" QString command = dialog->command(); emitCommand(command); } else { // user pressed "Cancel" if (list) delete list; list = Q_NULLPTR; } if (dialog) delete dialog; return list; } //*************************************************************************** #include "StringEnterPlugin.moc" //*************************************************************************** //***************************************************************************