Merge pull request #4 from LMMS/master

Master
This commit is contained in:
Lost Robot
2019-04-13 18:59:52 -06:00
committed by GitHub
110 changed files with 1760 additions and 558 deletions

View File

@@ -4,7 +4,7 @@ dist: trusty
sudo: required
cache:
directories:
- apt_mingw_cache
- $HOME/apt_mingw_cache
- $HOME/.ccache
- $HOME/pbuilder-bases
matrix:
@@ -14,9 +14,15 @@ matrix:
- env: TARGET_OS=win32
- env: TARGET_OS=win64
- env: TARGET_OS=debian-sid TARGET_DEPLOY=True
git:
depth: false
- env: TARGET_OS=debian-sid TARGET_ARCH=i386
git:
depth: false
- compiler: clang
env: TARGET_OS=debian-sid
git:
depth: false
- os: osx
osx_image: xcode8.3
install: ${TRAVIS_BUILD_DIR}/.travis/install.sh

View File

@@ -23,4 +23,4 @@ sudo apt-get install -y $PACKAGES
sudo add-apt-repository -y ppa:kxstudio-debian/libs
sudo add-apt-repository -y ppa:kxstudio-debian/apps
sudo apt-get update
sudo apt-get install -y carla-git
sudo apt-get install -y carla

View File

@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
set -e
: "${TARGET_ARCH:=amd64}"
@@ -21,19 +21,50 @@ fi
if [ ! -e "$BASETGZ.stamp" ]
then
mkdir -p "$HOME/pbuilder-bases"
# debootstrap fails to resolve dependencies which are virtual packages
# e.g. perl-openssl-abi-1.1 provided by perl-openssl-defaults, needed for building SWH
# See also: https://bugs.launchpad.net/ubuntu/+source/debootstrap/+bug/86536
sudo pbuilder --create --basetgz "$BASETGZ" --mirror $MIRROR \
--distribution sid --architecture $TARGET_ARCH \
--debootstrapopts --variant=buildd \
--debootstrapopts --keyring=$KEYRING \
--debootstrapopts --include=perl,libxml2-utils,libxml-perl,liblist-moreutils-perl,perl-openssl-defaults
--debootstrapopts --include=perl
touch "$BASETGZ.stamp"
else
sudo pbuilder --update --basetgz "$BASETGZ"
fi
sync_version() {
local VERSION
local MMR
local STAGE
local EXTRA
VERSION=$(git describe --tags --match v[0-9].[0-9].[0-9]*)
VERSION=${VERSION#v}
MMR=${VERSION%%-*}
case $VERSION in
*-*-*-*)
VERSION=${VERSION%-*}
STAGE=${VERSION#*-}
STAGE=${STAGE%-*}
EXTRA=${VERSION##*-}
VERSION=$MMR~$STAGE.$EXTRA
;;
*-*-*)
VERSION=${VERSION%-*}
EXTRA=${VERSION##*-}
VERSION=$MMR.$EXTRA
;;
*-*)
STAGE=${VERSION#*-}
VERSION=$MMR~$STAGE
;;
esac
sed "1 s/@VERSION@/$VERSION/" -i debian/changelog
echo "Set Debian version to $VERSION"
}
sync_version
DIR="$PWD"
cd ..
dpkg-source -b "$DIR"

View File

@@ -2,7 +2,7 @@
set -e
CACHE_DIR=$TRAVIS_BUILD_DIR/apt_mingw_cache/$1
CACHE_DIR=$HOME/apt_mingw_cache/$1
mkdir -p "$CACHE_DIR"
pushd "$CACHE_DIR"

View File

@@ -67,7 +67,8 @@ OPTION(WANT_STK "Include Stk (Synthesis Toolkit) support" ON)
OPTION(WANT_SWH "Include Steve Harris's LADSPA plugins" ON)
OPTION(WANT_TAP "Include Tom's Audio Processing LADSPA plugins" ON)
OPTION(WANT_VST "Include VST support" ON)
OPTION(WANT_VST_NOWINE "Include partial VST support (without wine)" OFF)
OPTION(WANT_VST_32 "Include 32-bit VST support" ON)
OPTION(WANT_VST_64 "Include 64-bit VST support" ON)
OPTION(WANT_WINMM "Include WinMM MIDI support" OFF)
OPTION(WANT_DEBUG_FPE "Debug floating point exceptions" OFF)
@@ -75,6 +76,7 @@ OPTION(WANT_DEBUG_FPE "Debug floating point exceptions" OFF)
IF(LMMS_BUILD_APPLE)
# Fix linking on 10.14+. See issue #4762 on github
LINK_DIRECTORIES(/usr/local/lib)
SET(WANT_SOUNDIO OFF)
SET(WANT_ALSA OFF)
SET(WANT_PULSEAUDIO OFF)
SET(WANT_VST OFF)

View File

@@ -101,6 +101,7 @@ mv "${APPDIR}usr/bin/lmms" "${APPDIR}usr/bin/lmms.real"
cat >"${APPDIR}usr/bin/lmms" <<EOL
#!/usr/bin/env bash
DIR="\$( cd "\$( dirname "\${BASH_SOURCE[0]}" )" && pwd )"
export PATH="$PATH:/sbin"
if which carla > /dev/null 2>&1; then
CARLAPATH="\$(which carla)"
CARLAPREFIX="\${CARLAPATH%/bin*}"
@@ -134,15 +135,15 @@ export LD_LIBRARY_PATH="${APPDIR}usr/lib/lmms/":$LD_LIBRARY_PATH
# Handle wine linking
if [ -d "@WINE_32_LIBRARY_DIR@" ]; then
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$LD_LIBRARY_PATH/wine/:@WINE_32_LIBRARY_DIR@:@WINE_32_LIBRARY_DIR@wine/
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:@WINE_32_LIBRARY_DIRS@
fi
if [ -d "@WINE_64_LIBRARY_DIR@" ]; then
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$LD_LIBRARY_PATH/wine/:@WINE_64_LIBRARY_DIR@:@WINE_64_LIBRARY_DIR@wine/
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:@WINE_64_LIBRARY_DIRS@
fi
# Move executables so linuxdeployqt can find them
ZYNLIB="${APPDIR}usr/lib/lmms/RemoteZynAddSubFx"
VSTLIB32="${APPDIR}usr/lib/lmms/RemoteVstPlugin32.exe.so"
VSTLIB32="${APPDIR}usr/lib/lmms/32/RemoteVstPlugin32.exe.so"
VSTLIB64="${APPDIR}usr/lib/lmms/RemoteVstPlugin64.exe.so"
ZYNBIN="${APPDIR}usr/bin/RemoteZynAddSubFx"
@@ -172,8 +173,10 @@ executables="${executables} -executable=${APPDIR}usr/lib/lmms/ladspa/pitch_scale
# Bundle both qt and non-qt dependencies into appimage format
echo -e "\nBundling and relinking system dependencies..."
echo -e ">>>>> linuxdeployqt" > "$LOGFILE"
# FIXME: -unsupported-allow-new-glibc may result in an AppImage which is unusable on old systems.
# shellcheck disable=SC2086
"$LINUXDEPLOYQT" "$DESKTOPFILE" $executables -bundle-non-qt-libs -verbose=$VERBOSITY $STRIP >> "$LOGFILE" 2>&1
"$LINUXDEPLOYQT" "$DESKTOPFILE" $executables -unsupported-allow-new-glibc -bundle-non-qt-libs -verbose=$VERBOSITY $STRIP >> "$LOGFILE" 2>&1
success "Bundled and relinked dependencies"
# Link to original location so lmms can find them

View File

@@ -0,0 +1,27 @@
INCLUDE(CheckCXXSourceCompiles)
FUNCTION(CheckWineGcc BITNESS WINEGCC_EXECUTABLE RESULT)
FILE(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/winegcc_test.cxx" "
#include <iostream>
#define USE_WS_PREFIX
#include <windows.h>
int main(int argc, const char* argv[]) {
return 0;
}
")
EXECUTE_PROCESS(COMMAND ${WINEGCC_EXECUTABLE} "-m${BITNESS}"
"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/winegcc_test.cxx"
"-o" "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/winegcc_test"
OUTPUT_QUIET ERROR_QUIET
RESULT_VARIABLE WINEGCC_RESULT
)
FILE(REMOVE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/winegcc_test.cxx"
"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/winegcc_test"
"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/winegcc_test.exe.so"
)
IF(WINEGCC_RESULT EQUAL 0)
SET(${RESULT} True PARENT_SCOPE)
ELSE()
SET(${RESULT} False PARENT_SCOPE)
ENDIF()
ENDFUNCTION()

View File

@@ -7,46 +7,89 @@
# WINE_DEFINITIONS - Compiler switches required for using wine
#
MACRO(_findwine_find_flags output expression result)
STRING(REPLACE " " ";" WINEBUILD_FLAGS "${output}")
FOREACH(FLAG ${WINEBUILD_FLAGS})
IF("${FLAG}" MATCHES "${expression}")
SET(${result} "${FLAG}")
ENDIF()
ENDFOREACH()
ENDMACRO()
LIST(APPEND CMAKE_PREFIX_PATH /opt/wine-stable /opt/wine-devel /opt/wine-staging /usr/lib/wine/)
FIND_PATH(WINE_INCLUDE_DIR wine/exception.h PATH_SUFFIXES wine)
FIND_PROGRAM(WINE_CXX
NAMES wineg++ winegcc winegcc64 winegcc32 winegcc-stable
PATHS /usr/lib/wine)
PATHS /usr/lib/wine
)
FIND_PROGRAM(WINE_BUILD NAMES winebuild)
# Detect wine paths and handle linking problems
IF(WINE_CXX)
EXEC_PROGRAM(${WINE_CXX} ARGS "-m32 -v /dev/zero" OUTPUT_VARIABLE WINEBUILD_OUTPUT_32)
EXEC_PROGRAM(${WINE_CXX} ARGS "-m64 -v /dev/zero" OUTPUT_VARIABLE WINEBUILD_OUTPUT_64)
_findwine_find_flags("${WINEBUILD_OUTPUT_32}" "^-isystem/usr/include$" BUGGED_WINEGCC)
_findwine_find_flags("${WINEBUILD_OUTPUT_32}" "^-isystem" WINEGCC_INCLUDE_DIR)
_findwine_find_flags("${WINEBUILD_OUTPUT_32}" "libwinecrt0\\.a.*" WINECRT_32)
_findwine_find_flags("${WINEBUILD_OUTPUT_64}" "libwinecrt0\\.a.*" WINECRT_64)
STRING(REGEX REPLACE "^-isystem" "" WINE_INCLUDE_HINT "${WINEGCC_INCLUDE_DIR}")
STRING(REGEX REPLACE "/wine/windows$" "" WINE_INCLUDE_HINT "${WINE_INCLUDE_HINT}")
STRING(REGEX REPLACE "libwinecrt0\\.a.*" "" WINE_32_LIBRARY_DIR "${WINECRT_32}")
STRING(REGEX REPLACE "libwinecrt0\\.a.*" "" WINE_64_LIBRARY_DIR "${WINECRT_64}")
IF(BUGGED_WINEGCC)
MESSAGE(WARNING "Your winegcc is unusable due to https://bugs.winehq.org/show_bug.cgi?id=46293,\n
Consider either upgrading or downgrading wine.")
RETURN()
ENDIF()
IF(WINE_32_LIBRARY_DIR STREQUAL WINE_64_LIBRARY_DIR)
MESSAGE(STATUS "Old winegcc detected, trying to use workaround linking")
# Fix library search directory according to the target bitness
IF(WINE_32_LIBRARY_DIR MATCHES "/lib/(x86_64|i386)-")
# Debian systems
STRING(REPLACE "/lib/x86_64-" "/lib/i386-" WINE_32_LIBRARY_DIR "${WINE_32_LIBRARY_DIR}")
STRING(REPLACE "/lib/i386-" "/lib/x86_64-" WINE_64_LIBRARY_DIR "${WINE_64_LIBRARY_DIR}")
ELSEIF(WINE_32_LIBRARY_DIR MATCHES "/(lib|lib64)/wine/$")
# WineHQ (/opt/wine-stable, /opt/wine-devel, /opt/wine-staging)
STRING(REGEX REPLACE "/lib64/wine/$" "/lib/wine/" WINE_32_LIBRARY_DIR "${WINE_32_LIBRARY_DIR}")
STRING(REGEX REPLACE "/lib/wine/$" "/lib64/wine/" WINE_64_LIBRARY_DIR "${WINE_64_LIBRARY_DIR}")
ELSEIF(WINE_32_LIBRARY_DIR MATCHES "/lib32/.*/wine/")
# Systems with old multilib layout
STRING(REPLACE "/lib32/" "/lib/" WINE_64_LIBRARY_DIR "${WINE_32_LIBRARY_DIR}")
ELSEIF(WINE_32_LIBRARY_DIR MATCHES "/lib64/.*/wine/")
# We need to test if the corresponding 64bit library directory is lib or lib32
STRING(REPLACE "/lib64/" "/lib32/" WINE_32_LIBRARY_DIR "${WINE_64_LIBRARY_DIR}")
IF(NOT EXISTS "${WINE_32_LIBRARY_DIR}")
STRING(REPLACE "/lib64/" "/lib/" WINE_32_LIBRARY_DIR "${WINE_64_LIBRARY_DIR}")
ENDIF()
ELSEIF(WINE_32_LIBRARY_DIR MATCHES "/lib/.*/wine/")
# Test if this directory is for 32bit or 64bit
STRING(REPLACE "/lib/" "/lib32/" WINE_32_LIBRARY_DIR "${WINE_64_LIBRARY_DIR}")
IF(NOT EXISTS "${WINE_32_LIBRARY_DIR}")
SET(WINE_32_LIBRARY_DIR "${WINE_64_LIBRARY_DIR}")
STRING(REPLACE "/lib/" "/lib64/" WINE_64_LIBRARY_DIR "${WINE_64_LIBRARY_DIR}")
ENDIF()
ELSE()
MESSAGE(WARNING "Can't detect wine installation layout. You may get some build errors.")
ENDIF()
SET(WINE_LIBRARY_FIX "${WINE_32_LIBRARY_DIR} and ${WINE_64_LIBRARY_DIR}")
ENDIF()
ENDIF()
FIND_PATH(WINE_INCLUDE_DIR wine/exception.h
HINTS "${WINE_INCLUDE_HINT}"
)
SET(_ARCHITECTURE ${CMAKE_LIBRARY_ARCHITECTURE})
FIND_LIBRARY(WINE_LIBRARY NAMES wine PATH_SUFFIXES wine i386-linux-gnu/wine)
FIND_LIBRARY(WINE_LIBRARY NAMES wine
PATH_SUFFIXES wine i386-linux-gnu/wine
HINTS "${WINE_32_LIBRARY_DIR}" "${WINE_64_LIBRARY_DIR}"
)
SET(CMAKE_LIBRARY_ARCHITECTURE ${_ARCHITECTURE})
SET(WINE_INCLUDE_DIRS ${WINE_INCLUDE_DIR} )
SET(WINE_LIBRARIES ${WINE_LIBRARY} )
# Handle wine linking problems
EXEC_PROGRAM(${WINE_CXX} ARGS "-v -m32 /dev/zero" OUTPUT_VARIABLE WINEBUILD_OUTPUT)
STRING(REPLACE " " ";" WINEBUILD_FLAGS "${WINEBUILD_OUTPUT}")
FOREACH(FLAG ${WINEBUILD_FLAGS})
IF("${FLAG}" MATCHES "libwinecrt0.a.*")
STRING(REGEX REPLACE "/wine/libwinecrt0.a.*" "" FLAG "${FLAG}")
SET(WINE_64_LIBRARY_DIR "${FLAG}/")
# Debian systems
STRING(REPLACE "/lib/x86_64-" "/lib/i386-" FLAG "${FLAG}")
# Fedora systems
STRING(REPLACE "/lib/lib64" "/lib/i386" FLAG "${FLAG}")
# Gentoo systems
STRING(REPLACE "/lib/wine-" "/lib32/wine-" FLAG "${FLAG}")
# WineHQ (/opt/wine-stable, /opt/wine-devel, /opt/wine-staging)
STRING(REGEX REPLACE "/lib64$" "/lib" FLAG "${FLAG}")
SET(WINE_32_LIBRARY_DIR "${FLAG}/")
ENDIF()
ENDFOREACH()
SET(WINE_LIBRARIES ${WINE_LIBRARY})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Wine DEFAULT_MSG WINE_CXX WINE_LIBRARIES WINE_INCLUDE_DIRS)
@@ -54,7 +97,23 @@ find_package_handle_standard_args(Wine DEFAULT_MSG WINE_CXX WINE_LIBRARIES WINE_
mark_as_advanced(WINE_INCLUDE_DIR WINE_LIBRARY WINE_CXX WINE_BUILD)
IF(WINE_32_LIBRARY_DIR)
SET(WINE_32_FLAGS "-L${WINE_32_LIBRARY_DIR}wine/ -L${WINE_32_LIBRARY_DIR}")
IF(WINE_32_LIBRARY_DIR MATCHES "wine*/lib")
SET(WINE_32_FLAGS "-L${WINE_32_LIBRARY_DIR} -L${WINE_32_LIBRARY_DIR}../")
SET(WINE_32_LIBRARY_DIRS "${WINE_32_LIBRARY_DIR}:${WINE_32_LIBRARY_DIR}/..")
ELSE()
SET(WINE_32_FLAGS "-L${WINE_32_LIBRARY_DIR}")
SET(WINE_32_LIBRARY_DIRS "${WINE_32_LIBRARY_DIR}")
ENDIF()
ENDIF()
IF(WINE_64_LIBRARY_DIR)
IF(WINE_64_LIBRARY_DIR MATCHES "wine*/lib")
SET(WINE_64_FLAGS "-L${WINE_64_LIBRARY_DIR} -L${WINE_64_LIBRARY_DIR}../")
SET(WINE_64_LIBRARY_DIRS "${WINE_64_LIBRARY_DIR}:${WINE_64_LIBRARY_DIR}/..")
ELSE()
SET(WINE_64_FLAGS "-L${WINE_64_LIBRARY_DIR}")
SET(WINE_64_LIBRARY_DIRS "${WINE_64_LIBRARY_DIR}")
ENDIF()
ENDIF()
# Create winegcc wrapper

View File

@@ -22,6 +22,9 @@ while [ $# -gt 0 ]; do
-m32)
win32=true
;;
-m64)
win64=true
;;
*)
;;
@@ -42,11 +45,19 @@ fi
# by FindWine.cmake
extra_args="-I@WINE_INCLUDE_DIR@ -I@WINE_INCLUDE_DIR@/wine/windows"
# Apply manually specified flags
extra_args="$extra_args @WINE_CXX_FLAGS@"
# Apply -m32 library fix if necessary
if [ "$win32" = true ] && [ "$no_link" != true ]; then
extra_args="$extra_args @WINE_32_FLAGS@"
fi
# Apply -m64 library fix if necessary
if [ "$win64" = true ] && [ "$no_link" != true ]; then
extra_args="$extra_args @WINE_64_FLAGS@"
fi
# Run winegcc
export WINEBUILD=@WINE_BUILD@
@WINE_CXX@ $extra_args $args

View File

@@ -1 +0,0 @@
usr/lib/*/lmms/ladspa/calf.so usr/lib/ladspa

2
debian/changelog vendored
View File

@@ -1,4 +1,4 @@
lmms (1.2.0~rc7.1) unstable; urgency=low
lmms (@VERSION@) unstable; urgency=low
* Upstream integration.
* Drop Debian menu entry (policy 9.6).

31
debian/control vendored
View File

@@ -17,6 +17,7 @@ Build-Depends:
libfluidsynth-dev,
libgig-dev,
libjack-jackd2-dev,
liblist-moreutils-perl,
libmp3lame-dev,
libpulse-dev,
libqt5x11extras5-dev,
@@ -29,10 +30,12 @@ Build-Depends:
libvorbis-dev,
libxcb-keysyms1-dev,
libxcb-util0-dev,
libxml-perl,
libxml2-utils,
portaudio19-dev,
qtbase5-private-dev,
qttools5-dev,
wine32-tools [i386]
wine64-tools [amd64] | wine32-tools [i386]
Standards-Version: 4.2.1.4
Homepage: http://lmms.io/
Vcs-Browser: https://salsa.debian.org/debian-edu-pkg-team/lmms.git
@@ -41,8 +44,9 @@ Package: lmms-bin
Architecture: any
Depends: lmms-common (>= ${source:Version}), ${shlibs:Depends}, ${misc:Depends},
stk
Recommends: calf-ladspa, tap-plugins, caps,
lmms-vst-server:i386 (>= ${source:Version})
Recommends: tap-plugins, caps,
lmms-vst-server:i386 (>= ${source:Version}),
lmms-vst-server:amd64 (>= ${source:Version})
Suggests: fil-plugins, mcp-plugins, omins, freepats, fluid-soundfont-gm,
ladspa-plugin
Replaces: lmms-common (<< 1.0.0-1)
@@ -63,7 +67,7 @@ Description: Linux Multimedia Studio - minimal installation
Package: lmms
Architecture: any
Depends: calf-ladspa, lmms-bin, ${misc:Depends}
Depends: lmms-bin, ${misc:Depends}
Description: Linux Multimedia Studio
LMMS aims to be a free alternative to popular (but commercial and closed-
source) programs like FruityLoops, Cubase and Logic giving you the ability of
@@ -96,23 +100,8 @@ Description: Linux Multimedia Studio - common files
and some example projects.
Package: lmms-vst-server
Architecture: i386
# Order matters to avoid wine64
Depends: wine32, wine, ${shlibs:Depends}, ${misc:Depends}
Architecture: amd64 i386
Depends: wine64 [amd64] | wine64-development [amd64] | wine32 [i386] | wine32-development [i386], ${shlibs:Depends}, ${misc:Depends}
Recommends: lmms-bin:any
Description: Linux Multimedia Studio - VST server
This package contains a helper application that loads VST plugins.
Package: calf-ladspa
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Replaces: calf-plugins (<< 0.0.19)
Provides: ladspa-plugin
Description: Linux Multimedia Studio - Calf LADSPA plugins
Calf is a pack of audio plugins - effects and instruments. The goal is to
create a set of plugins using decent algorithms and parameter settings,
available in a form which is compatible with as many open source applications
as possible.
.
These plugins are distributed as part of Linux Multimedia Studio, but may be
used by other applications.

View File

@@ -1,7 +1,4 @@
usr/bin/lmms
usr/lib/*/lmms/ladspa/[a-b]*
usr/lib/*/lmms/ladspa/caps.so
usr/lib/*/lmms/ladspa/c[b-z]*
usr/lib/*/lmms/ladspa/[d-z]*
usr/lib/*/lmms/ladspa/*
usr/lib/*/lmms/lib*
usr/lib/*/lmms/RemoteZynAddSubFx

View File

@@ -1 +1 @@
usr/lib/*/lmms/RemoteVstPlugin*
usr/lib/*/lmms/{32/,}RemoteVstPlugin*

14
debian/rules vendored
View File

@@ -6,6 +6,7 @@ DH_CMAKE_BUILD_DIR=obj -${DEB_BUILD_GNU_TYPE}
DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH)
DEB_HOST_ARCH ?= $(shell dpkg-architecture -qDEB_HOST_ARCH)
DEB_HOST_ARCH_OS ?= $(shell dpkg-architecture -qDEB_HOST_ARCH_OS)
DEB_HOST_ARCH_BIT ?= $(shell dpkg-architecture -qDEB_HOST_ARCH_BITS)
CMAKE_OPTS= -DCONTRIBUTORS=$(CURDIR)/doc/CONTRIBUTORS -DFORCE_VERSION=internal \
-DWANT_QT5=1
@@ -13,13 +14,18 @@ ifneq ($(DEB_HOST_ARCH_OS),linux)
CMAKE_OPTS+= -DWANT_ALSA=0
endif
ifeq ($(DEB_HOST_ARCH),i386)
ifeq ($(DEB_HOST_ARCH),amd64)
export PATH := $(PATH):/usr/lib/wine
WINE_PATH := /usr/lib/$(DEB_HOST_MULTIARCH)/wine
CMAKE_OPTS+= -DWINE_CXX_FLAGS=-Wl,--enable-new-dtags,-rpath=$(WINE_PATH)
CMAKE_OPTS+= -DWANT_VST_32=OFF -DREMOTE_VST_PLUGIN_FILEPATH_32=../../i386-linux-gnu/lmms/32/RemoteVstPlugin32 \
-DWINE_CXX_FLAGS=-Wl,--enable-new-dtags,-rpath=$(WINE_PATH)
else ifeq ($(DEB_HOST_ARCH),i386)
export PATH := $(PATH):/usr/lib/wine
WINE_PATH := /usr/lib/$(DEB_HOST_MULTIARCH)/wine
CMAKE_OPTS+= -DWANT_VST_64=OFF -DREMOTE_VST_PLUGIN_FILEPATH_64=../../x86_64-linux-gnu/lmms/RemoteVstPlugin64 \
-DWINE_CXX_FLAGS=-Wl,--enable-new-dtags,-rpath=$(WINE_PATH)
else
CMAKE_OPTS+= -DWANT_VST_NOWINE=1 \
-DREMOTE_VST_PLUGIN_FILEPATH=../../i386-linux-gnu/lmms/RemoteVstPlugin
CMAKE_OPTS+= -DWANT_VST=OFF
endif
# Define NDEBUG. This helps with reproducible builds.

View File

@@ -47,6 +47,7 @@ protected:
DropToolBar * addDropToolBar(Qt::ToolBarArea whereToAdd, QString const & windowTitle);
DropToolBar * addDropToolBar(QWidget * parent, Qt::ToolBarArea whereToAdd, QString const & windowTitle);
virtual void closeEvent( QCloseEvent * _ce );
protected slots:
virtual void play() {}
virtual void record() {}

View File

@@ -148,11 +148,6 @@ public:
m_noRun = _state;
}
inline const Descriptor::SubPluginFeatures::Key & key() const
{
return m_key;
}
EffectChain * effectChain() const
{
return m_parent;
@@ -201,8 +196,6 @@ private:
sampleFrame * _dst_buf, sample_rate_t _dst_sr,
const f_cnt_t _frames );
Descriptor::SubPluginFeatures::Key m_key;
ch_cnt_t m_processors;
bool m_okay;

View File

@@ -111,6 +111,9 @@ public:
return s_instanceOfMe;
}
static void setDndPluginKey(void* newKey);
static void* pickDndPluginKey();
signals:
void initProgress(const QString &msg);
@@ -137,6 +140,7 @@ private:
static DummyTrackContainer * s_dummyTC;
static Ladspa2LMMS * s_ladspaManager;
static void* s_dndPluginKey;
// even though most methods are static, an instance is needed for Qt slots/signals
static LmmsCore * s_instanceOfMe;

View File

@@ -0,0 +1,53 @@
/*
* FxLineLcdSpinBox.h - a specialization of LcdSpnBox for setting FX channels
*
* Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of LMMS - https://lmms.io
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program (see COPYING); if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
*/
#ifndef FX_LINE_LCD_SPIN_BOX_H
#define FX_LINE_LCD_SPIN_BOX_H
#include "LcdSpinBox.h"
class TrackView;
class FxLineLcdSpinBox : public LcdSpinBox
{
Q_OBJECT
public:
FxLineLcdSpinBox(int numDigits, QWidget * parent, const QString& name, TrackView * tv = NULL) :
LcdSpinBox(numDigits, parent, name), m_tv(tv)
{}
virtual ~FxLineLcdSpinBox() {}
void setTrackView(TrackView * tv);
protected:
virtual void mouseDoubleClickEvent(QMouseEvent* event);
virtual void contextMenuEvent(QContextMenuEvent* event);
private:
TrackView * m_tv;
};
#endif

View File

@@ -55,14 +55,17 @@ public:
Q_DECLARE_FLAGS(Flags, Flag);
Instrument( InstrumentTrack * _instrument_track,
const Descriptor * _descriptor );
Instrument(InstrumentTrack * _instrument_track,
const Descriptor * _descriptor,
const Descriptor::SubPluginFeatures::Key * key = nullptr);
virtual ~Instrument() = default;
// --------------------------------------------------------------------
// functions that can/should be re-implemented:
// --------------------------------------------------------------------
virtual bool hasNoteInput() const { return true; }
// if the plugin doesn't play each note, it can create an instrument-
// play-handle and re-implement this method, so that it mixes its
// output buffer only once per mixer-period
@@ -113,10 +116,12 @@ public:
// provided functions:
// --------------------------------------------------------------------
// instantiate instrument-plugin with given name or return NULL
// on failure
static Instrument * instantiate( const QString & _plugin_name,
InstrumentTrack * _instrument_track );
//! instantiate instrument-plugin with given name or return NULL
//! on failure
static Instrument * instantiate(const QString & _plugin_name,
InstrumentTrack * _instrument_track,
const Plugin::Descriptor::SubPluginFeatures::Key* key,
bool keyFromDnd = false);
virtual bool isFromTrack( const Track * _track ) const;

View File

@@ -36,6 +36,7 @@
#include "Piano.h"
#include "PianoView.h"
#include "Pitch.h"
#include "Plugin.h"
#include "Track.h"
@@ -52,6 +53,7 @@ class InstrumentTrackWindow;
class InstrumentMidiIOView;
class InstrumentMiscView;
class Knob;
class FxLineLcdSpinBox;
class LcdSpinBox;
class LeftRightNav;
class midiPortMenu;
@@ -146,7 +148,9 @@ public:
// load instrument whose name matches given one
Instrument * loadInstrument( const QString & _instrument_name );
Instrument * loadInstrument(const QString & _instrument_name,
const Plugin::Descriptor::SubPluginFeatures::Key* key = nullptr,
bool keyFromDnd = false);
AudioPort * audioPort()
{
@@ -440,7 +444,7 @@ private:
QLabel * m_pitchLabel;
LcdSpinBox* m_pitchRangeSpinBox;
QLabel * m_pitchRangeLabel;
LcdSpinBox * m_effectChannelNumber;
FxLineLcdSpinBox * m_effectChannelNumber;

View File

@@ -74,6 +74,7 @@ class LMMS_EXPORT Knob : public QWidget, public FloatModelView
public:
Knob( knobTypes _knob_num, QWidget * _parent = NULL, const QString & _name = QString() );
Knob( QWidget * _parent = NULL, const QString & _name = QString() ); //!< default ctor
Knob( const Knob& other ) = delete;
virtual ~Knob();
// TODO: remove

View File

@@ -30,6 +30,8 @@
#include "LadspaManager.h"
//! Class responsible for sorting found plugins (by LadspaManager)
//! into categories
class LMMS_EXPORT Ladspa2LMMS : public LadspaManager
{
public:

View File

@@ -41,10 +41,6 @@ public:
m_displayName( _display_name ),
m_defaultConstructed( _default_constructed )
{
#if QT_VERSION < 0x050000
connect( this, SIGNAL( dataChanged() ), this,
SLOT( thisDataChanged() ), Qt::DirectConnection );
#endif
}
virtual ~Model()
@@ -89,19 +85,6 @@ signals:
// emitted if properties of the model (e.g. ranges) have changed
void propertiesChanged();
#if QT_VERSION < 0x050000
// emitted along with dataChanged(), but with this model as an argument
// workaround for when QObject::sender() and Qt5 are unavailable
void dataChanged( Model * );
private slots:
void thisDataChanged()
{
emit dataChanged( this );
}
signals:
#endif
} ;

View File

@@ -40,7 +40,27 @@ class PixmapLoader;
class PluginView;
class AutomatableModel;
/**
Abstract representation of a plugin
Such a plugin can be an Instrument, Effect, Tool plugin etc.
Plugins have descriptors, containing meta info, which is used especially
by PluginFactory and friends.
There are also Plugin keys (class Key, confusingly under
SubPluginFeatures), which contain pointers to the plugin descriptor.
Some plugins have sub plugins, e.g. there is one CALF Plugin and for
each CALF effect, there is a CALF sub plugin. For those plugins, there
are keys for each sub plugin. These keys also link to the superior
Plugin::Descriptor. Additionally, they contain attributes that help the
superior Plugin saving them and recognizing them when loading.
In case of sub plugins, the Descriptor has SubPluginFeatures. Those
are a bit like values to the sub plugins' keys (in terms of a key-value-
map).
*/
class LMMS_EXPORT Plugin : public Model, public JournallingObject
{
MM_OPERATORS
@@ -59,9 +79,9 @@ public:
Undefined = 255
} ;
// descriptor holds information about a plugin - every external plugin
// has to instantiate such a descriptor in an extern "C"-section so that
// the plugin-loader is able to access information about the plugin
//! Descriptor holds information about a plugin - every external plugin
//! has to instantiate such a Descriptor in an extern "C"-section so that
//! the plugin-loader is able to access information about the plugin
struct Descriptor
{
const char * name;
@@ -71,23 +91,49 @@ public:
int version;
PluginTypes type;
const PixmapLoader * logo;
const char * supportedFileTypes;
const char * supportedFileTypes; //!< csv list of extensions
inline bool supportsFileType( const QString& extension ) const
{
return QString( supportedFileTypes ).split( QChar( ',' ) ).contains( extension );
}
/**
Access to non-key-data of a sub plugin
If you consider sub plugin keys as keys in a
key-value-map, this is the lookup for the corresponding
values. In order to have flexibility between different
plugin APIs, this is rather an array of fixed data,
but a bunch of virtual functions taking the key and
returning some values (or modifying objects of other
classes).
*/
class LMMS_EXPORT SubPluginFeatures
{
public:
/**
Key reference a Plugin::Descriptor, and,
if the plugin has sub plugins, also reference
its sub plugin (using the attributes).
When keys are saved, those attributes are
written to XML in order to find the right sub
plugin when realoading.
@note Any data that is not required to reference
the right Plugin or sub plugin should
not be here (but rather in
SubPluginFeatures, which are like values
in a key-value map).
*/
struct Key
{
typedef QMap<QString, QString> AttributeMap;
inline Key( const Plugin::Descriptor * desc = NULL,
const QString & name = QString(),
const AttributeMap & am = AttributeMap() )
const QString & name = QString(),
const AttributeMap & am = AttributeMap()
)
:
desc( desc ),
name( name ),
@@ -101,12 +147,28 @@ public:
inline bool isValid() const
{
return desc != NULL && name.isNull() == false;
return desc != nullptr;
}
//! Key to subplugin: reference to parent descriptor
//! Key to plugin: reference to its descriptor
const Plugin::Descriptor* desc;
//! Descriptive name like "Calf Phaser".
//! Not required for key lookup and not saved
//! only used sometimes to temporary store descriptive names
//! @todo This is a bug, there should be a function
//! in SubPluginFeatures (to get the name) instead
QString name;
//! Attributes that make up the key and identify
//! the sub plugin. They are being loaded and saved
AttributeMap attributes;
// helper functions to retrieve data that is
// not part of the key, but mapped via desc->subPluginFeatures
QString additionalFileExtensions() const;
QString displayName() const;
QString description() const;
const PixmapLoader* logo() const;
} ;
typedef QList<Key> KeyList;
@@ -125,11 +187,40 @@ public:
{
}
//! While PluginFactory only collects the plugins,
//! this function is used by widgets like EffectSelectDialog
//! to find all possible sub plugins
virtual void listSubPluginKeys( const Plugin::Descriptor *, KeyList & ) const
{
}
private:
// You can add values mapped by "Key" below
// The defaults are sane, i.e. redirect to sub plugin's
// supererior descriptor
virtual QString additionalFileExtensions(const Key&) const
{
return QString();
}
virtual QString displayName(const Key& k) const
{
return k.isValid() ? k.name : QString();
}
virtual QString description(const Key& k) const
{
return k.isValid() ? k.desc->description : QString();
}
virtual const PixmapLoader* logo(const Key& k) const
{
Q_ASSERT(k.desc);
return k.desc->logo;
}
protected:
const Plugin::PluginTypes m_type;
} ;
@@ -140,48 +231,66 @@ public:
// typedef a list so we can easily work with list of plugin descriptors
typedef QList<Descriptor*> DescriptorList;
// contructor of a plugin
Plugin( const Descriptor * descriptor, Model * parent );
//! Constructor of a plugin
//! @param key Sub plugins must pass a key here, optional otherwise.
//! See the key() function
Plugin(const Descriptor * descriptor, Model * parent,
const Descriptor::SubPluginFeatures::Key *key = nullptr);
virtual ~Plugin();
// returns display-name out of descriptor
virtual QString displayName() const
{
return Model::displayName().isEmpty()
? m_descriptor->displayName
: Model::displayName();
}
//! Return display-name out of sub plugin or descriptor
virtual QString displayName() const;
// return plugin-type
//! Return logo out of sub plugin or descriptor
const PixmapLoader *logo() const;
//! Return plugin type
inline PluginTypes type( void ) const
{
return m_descriptor->type;
}
// return plugin-descriptor for further information
//! Return plugin Descriptor
inline const Descriptor * descriptor() const
{
return m_descriptor;
}
// can be called if a file matching supportedFileTypes should be
// loaded/processed with the help of this plugin
//! Return the key referencing this plugin. If the Plugin has no
//! sub plugin features, the key is pretty useless. If it has,
//! this key will also contain the sub plugin attributes, and will be
//! a key to those SubPluginFeatures.
inline const Descriptor::SubPluginFeatures::Key & key() const
{
return m_key;
}
//! Can be called if a file matching supportedFileTypes should be
//! loaded/processed with the help of this plugin
virtual void loadFile( const QString & file );
// Called if external source needs to change something but we cannot
// reference the class header. Should return null if not key not found.
//! Called if external source needs to change something but we cannot
//! reference the class header. Should return null if not key not found.
virtual AutomatableModel* childModel( const QString & modelName );
// returns an instance of a plugin whose name matches to given one
// if specified plugin couldn't be loaded, it creates a dummy-plugin
static Plugin * instantiate( const QString& pluginName, Model * parent, void * data );
//! Overload if the argument passed to the plugin is a subPluginKey
//! If you can not pass the key and are aware that it's stored in
//! Engine::pickDndPluginKey(), use this function, too
static Plugin * instantiateWithKey(const QString& pluginName, Model * parent,
const Descriptor::SubPluginFeatures::Key *key,
bool keyFromDnd = false);
// create a view for the model
//! Return an instance of a plugin whose name matches to given one
//! if specified plugin couldn't be loaded, it creates a dummy-plugin
//! @param data Anything the plugin expects. If this is a pointer to a sub plugin key,
//! use instantiateWithKey instead
static Plugin * instantiate(const QString& pluginName, Model * parent, void *data);
//! Create a view for the model
PluginView * createView( QWidget * parent );
protected:
// create a view for the model
//! Create a view for the model
virtual PluginView* instantiateView( QWidget * ) = 0;
void collectErrorForUI( QString errMsg );
@@ -189,6 +298,8 @@ protected:
private:
const Descriptor * m_descriptor;
Descriptor::SubPluginFeatures::Key m_key;
// pointer to instantiation-function in plugin
typedef Plugin * ( * InstantiationHook )( Model * , void * );

View File

@@ -31,6 +31,10 @@
#include "SideBarWidget.h"
#include "Plugin.h"
class QLineEdit;
class QTreeWidget;
class QTreeWidgetItem;
class PluginBrowser : public SideBarWidget
{
@@ -39,18 +43,18 @@ public:
PluginBrowser( QWidget * _parent );
virtual ~PluginBrowser() = default;
private slots:
void onFilterChanged( const QString & filter );
private:
void addPlugins();
void updateRootVisibility( int index );
void updateRootVisibilities();
QWidget * m_view;
};
class PluginDescList : public QWidget
{
Q_OBJECT
public:
PluginDescList(QWidget* parent);
QTreeWidget * m_descTree;
QTreeWidgetItem * m_lmmsRoot;
QTreeWidgetItem * m_lv2Root;
};
@@ -60,7 +64,9 @@ class PluginDescWidget : public QWidget
{
Q_OBJECT
public:
PluginDescWidget( const Plugin::Descriptor & _pd, QWidget * _parent );
typedef Plugin::Descriptor::SubPluginFeatures::Key PluginKey;
PluginDescWidget( const PluginKey & _pk, QWidget * _parent );
QString name() const;
protected:
@@ -72,7 +78,7 @@ protected:
private:
constexpr static int DEFAULT_HEIGHT{24};
const Plugin::Descriptor & m_pluginDescriptor;
PluginKey m_pluginKey;
QPixmap m_logo;
bool m_mouseOver;

View File

@@ -26,10 +26,13 @@
#define PLUGINFACTORY_H
#include <memory>
#include <string>
#include <QtCore/QFileInfo>
#include <QtCore/QHash>
#include <QtCore/QList>
#include <QtCore/QString>
#include <QtCore/QVector>
#include "lmms_export.h"
#include "Plugin.h"
@@ -41,12 +44,10 @@ class LMMS_EXPORT PluginFactory
public:
struct PluginInfo
{
PluginInfo() : library(nullptr), descriptor(nullptr) {}
const QString name() const;
QFileInfo file;
std::shared_ptr<QLibrary> library;
Plugin::Descriptor* descriptor;
std::shared_ptr<QLibrary> library = nullptr;
Plugin::Descriptor* descriptor = nullptr;
bool isNull() const {return ! library;}
};
@@ -56,6 +57,8 @@ public:
PluginFactory();
~PluginFactory();
static void setupSearchPaths();
/// Returns the singleton instance of PluginFactory. You won't need to call
/// this directly, use pluginFactory instead.
static PluginFactory* instance();
@@ -64,10 +67,17 @@ public:
const Plugin::DescriptorList descriptors() const;
const Plugin::DescriptorList descriptors(Plugin::PluginTypes type) const;
struct PluginInfoAndKey
{
PluginInfo info;
Plugin::Descriptor::SubPluginFeatures::Key key;
bool isNull() const { return info.isNull(); }
};
/// Returns a list of all found plugins' PluginFactory::PluginInfo objects.
const PluginInfoList& pluginInfos() const;
/// Returns a plugin that support the given file extension
const PluginInfo pluginSupportingExtension(const QString& ext);
const PluginInfoAndKey pluginSupportingExtension(const QString& ext);
/// Returns the PluginInfo object of the plugin with the given name.
/// If the plugin is not found, an empty PluginInfo is returned (use
@@ -84,7 +94,9 @@ public slots:
private:
DescriptorMap m_descriptors;
PluginInfoList m_pluginInfos;
QMap<QString, PluginInfo> m_pluginByExt;
QMap<QString, PluginInfoAndKey> m_pluginByExt;
QVector<std::string> m_garbage; //!< cleaned up at destruction
QHash<QString, QString> m_errors;

View File

@@ -26,13 +26,19 @@
#define SAMPLE_TRACK_H
#include <QDialog>
#include <QLayout>
#include "AudioPort.h"
#include "FxMixer.h"
#include "FxLineLcdSpinBox.h"
#include "Track.h"
class EffectRackView;
class Knob;
class SampleBuffer;
class SampleTrackWindow;
class TrackLabelButton;
class QLineEdit;
class SampleTCO : public TrackContentObject
@@ -140,6 +146,11 @@ public:
QDomElement & _parent );
virtual void loadTrackSpecificSettings( const QDomElement & _this );
inline IntModel * effectChannelModel()
{
return &m_effectChannelModel;
}
inline AudioPort * audioPort()
{
return &m_audioPort;
@@ -153,15 +164,18 @@ public:
public slots:
void updateTcos();
void setPlayingTcos( bool isPlaying );
void updateEffectChannel();
private:
FloatModel m_volumeModel;
FloatModel m_panningModel;
IntModel m_effectChannelModel;
AudioPort m_audioPort;
friend class SampleTrackView;
friend class SampleTrackWindow;
} ;
@@ -174,6 +188,24 @@ public:
SampleTrackView( SampleTrack* Track, TrackContainerView* tcv );
virtual ~SampleTrackView();
SampleTrackWindow * getSampleTrackWindow()
{
return m_window;
}
SampleTrack * model()
{
return castModel<SampleTrack>();
}
const SampleTrack * model() const
{
return castModel<SampleTrack>();
}
virtual QMenu * createFxMenu( QString title, QString newFxLabel );
public slots:
void showEffects();
@@ -187,12 +219,77 @@ protected:
}
private slots:
void assignFxLine( int channelIndex );
void createFxLine();
private:
EffectRackView * m_effectRack;
QWidget * m_effWindow;
SampleTrackWindow * m_window;
Knob * m_volumeKnob;
Knob * m_panningKnob;
TrackLabelButton * m_tlb;
friend class SampleTrackWindow;
} ;
class SampleTrackWindow : public QWidget, public ModelView, public SerializingObjectHook
{
Q_OBJECT
public:
SampleTrackWindow(SampleTrackView * tv);
virtual ~SampleTrackWindow();
SampleTrack * model()
{
return castModel<SampleTrack>();
}
const SampleTrack * model() const
{
return castModel<SampleTrack>();
}
void setSampleTrackView(SampleTrackView * tv);
SampleTrackView *sampleTrackView()
{
return m_stv;
}
public slots:
void textChanged(const QString & new_name);
void toggleVisibility(bool on);
void updateName();
protected:
// capture close-events for toggling sample-track-button
virtual void closeEvent(QCloseEvent * ce);
virtual void saveSettings(QDomDocument & doc, QDomElement & element);
virtual void loadSettings(const QDomElement & element);
private:
virtual void modelChanged();
SampleTrack * m_track;
SampleTrackView * m_stv;
// widgets on the top of an sample-track-window
QLineEdit * m_nameLineEdit;
Knob * m_volumeKnob;
Knob * m_panningKnob;
FxLineLcdSpinBox * m_effectChannelNumber;
EffectRackView * m_effectRack;
} ;

View File

@@ -122,6 +122,9 @@ private slots:
void toggleDisplayWaveform( bool en );
void toggleDisableAutoquit( bool en );
void vstEmbedMethodChanged();
void toggleVSTAlwaysOnTop( bool en );
void setLanguage( int lang );
@@ -203,6 +206,8 @@ private:
QComboBox* m_vstEmbedComboBox;
QString m_vstEmbedMethod;
LedCheckBox * m_vstAlwaysOnTopCheckBox;
bool m_vstAlwaysOnTop;
} ;

View File

@@ -352,7 +352,7 @@ public:
}
}
bool canPasteSelection( MidiTime tcoPos, const QMimeData * mimeData );
bool canPasteSelection( MidiTime tcoPos, const QDropEvent *de );
bool pasteSelection( MidiTime tcoPos, QDropEvent * de );
MidiTime endPosition( const MidiTime & posStart );
@@ -675,6 +675,10 @@ public:
virtual void update();
// Create a menu for assigning/creating channels for this track
// Currently instrument track and sample track supports it
virtual QMenu * createFxMenu(QString title, QString newFxLabel);
public slots:
virtual bool close();

View File

@@ -41,10 +41,10 @@
struct VstSyncData
{
bool isPlaying;
double ppqPos;
int timeSigNumer;
int timeSigDenom;
bool isPlaying;
bool isCycle;
bool hasSHM;
float cycleStart;

View File

@@ -45,11 +45,11 @@ EqAnalyser::EqAnalyser() :
const float a2 = 0.14128;
const float a3 = 0.01168;
for(int i = 0; i < FFT_BUFFER_SIZE; i++)
for (int i = 0; i < FFT_BUFFER_SIZE; i++)
{
m_fftWindow[i] = ( a0 - a1 * cosf( 2 * F_PI * i / (float)FFT_BUFFER_SIZE - 1 )
+ a2 * cosf( 4 * F_PI * i / (float)FFT_BUFFER_SIZE-1)
- a3 * cos( 6 * F_PI * i / (float)FFT_BUFFER_SIZE - 1.0 ));
m_fftWindow[i] = (a0 - a1 * cos(2 * F_PI * i / ((float)FFT_BUFFER_SIZE - 1.0))
+ a2 * cos(4 * F_PI * i / ((float)FFT_BUFFER_SIZE - 1.0))
- a3 * cos(6 * F_PI * i / ((float)FFT_BUFFER_SIZE - 1.0)));
}
clear();
}

View File

@@ -728,10 +728,10 @@ extern "C"
{
// necessary for getting instance out of shared lib
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * )
{
return( new FreeBoyInstrument(
static_cast<InstrumentTrack *>( _data ) ) );
static_cast<InstrumentTrack *>( m ) ) );
}

View File

@@ -1390,9 +1390,9 @@ extern "C"
{
// necessary for getting instance out of shared lib
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * )
{
return new GigInstrument( static_cast<InstrumentTrack *>( _data ) );
return new GigInstrument( static_cast<InstrumentTrack *>( m ) );
}
}

View File

@@ -153,6 +153,9 @@ void LadspaControls::linkPort( int _port, bool _state )
{
first->unlinkControls( m_controls[proc][_port] );
}
// m_stereoLinkModel.setValue() will call updateLinkStatesFromGlobal()
// m_noLink will make sure that this will not unlink any other ports
m_noLink = true;
m_stereoLinkModel.setValue( false );
}

View File

@@ -44,6 +44,16 @@ LadspaSubPluginFeatures::LadspaSubPluginFeatures( Plugin::PluginTypes _type ) :
QString LadspaSubPluginFeatures::displayName(const Plugin::Descriptor::SubPluginFeatures::Key &k) const
{
const ladspa_key_t & lkey = subPluginKeyToLadspaKey(&k);
Ladspa2LMMS * lm = Engine::getLADSPAManager();
return lm->getName(lkey);
}
void LadspaSubPluginFeatures::fillDescriptionWidget( QWidget * _parent,
const Key * _key ) const
{

View File

@@ -25,8 +25,8 @@
*
*/
#ifndef _LADSPA_SUBPLUGIN_FEATURES_H
#define _LADSPA_SUBPLUGIN_FEATURES_H
#ifndef LADSPA_SUBPLUGIN_FEATURES_H
#define LADSPA_SUBPLUGIN_FEATURES_H
#include "LadspaManager.h"
#include "Plugin.h"
@@ -37,11 +37,13 @@ class LadspaSubPluginFeatures : public Plugin::Descriptor::SubPluginFeatures
public:
LadspaSubPluginFeatures( Plugin::PluginTypes _type );
virtual void fillDescriptionWidget( QWidget * _parent,
const Key * _key ) const;
QString displayName(const Key& k) const override;
void fillDescriptionWidget( QWidget * _parent,
const Key * _key ) const override;
virtual void listSubPluginKeys( const Plugin::Descriptor * _desc,
KeyList & _kl ) const;
KeyList & _kl ) const override;
static ladspa_key_t subPluginKeyToLadspaKey( const Key * _key );

View File

@@ -79,9 +79,9 @@ Plugin::Descriptor PLUGIN_EXPORT opulenz_plugin_descriptor =
};
// necessary for getting instance out of shared lib
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * )
{
return( new OpulenzInstrument( static_cast<InstrumentTrack *>( _data ) ) );
return( new OpulenzInstrument( static_cast<InstrumentTrack *>( m ) ) );
}
}

View File

@@ -90,13 +90,8 @@ void VstEffectControls::loadSettings( const QDomElement & _this )
knobFModel[ i ]->setInitValue(LocaleHelper::toFloat(s_dumpValues.at(2)));
}
#if QT_VERSION < 0x050000
connect( knobFModel[i], SIGNAL( dataChanged( Model * ) ),
this, SLOT( setParameter( Model * ) ), Qt::DirectConnection );
#else
connect( knobFModel[i], &FloatModel::dataChanged, this,
[this, i]() { setParameter( knobFModel[i] ); }, Qt::DirectConnection);
#endif
}
}
@@ -383,13 +378,8 @@ manageVSTEffectView::manageVSTEffectView( VstEffect * _eff, VstEffectControls *
}
FloatModel * model = m_vi->knobFModel[i];
#if QT_VERSION < 0x050000
connect( model, SIGNAL( dataChanged( Model * ) ), this,
SLOT( setParameter( Model * ) ), Qt::DirectConnection );
#else
connect( model, &FloatModel::dataChanged, this,
[this, model]() { setParameter( model ); }, Qt::DirectConnection);
#endif
vstKnobs[ i ] ->setModel( model );
}

View File

@@ -877,8 +877,8 @@ void XpressiveView::helpClicked() {
extern "C" {
// necessary for getting instance out of shared lib
PLUGIN_EXPORT Plugin * lmms_plugin_main(Model *, void * _data) {
return (new Xpressive(static_cast<InstrumentTrack *>(_data)));
PLUGIN_EXPORT Plugin * lmms_plugin_main(Model *m, void *) {
return (new Xpressive(static_cast<InstrumentTrack *>(m)));
}
}

View File

@@ -505,7 +505,7 @@ AudioFileProcessorView::AudioFileProcessorView( Instrument * _instrument,
"loop_pingpong_on" ) );
m_loopPingPongButton->setInactiveGraphic( PLUGIN_NAME::getIconPixmap(
"loop_pingpong_off" ) );
ToolTip::add( m_loopPingPongButton, tr( "Enable loop" ) );
ToolTip::add( m_loopPingPongButton, tr( "Enable ping-pong loop" ) );
m_loopGroup = new automatableButtonGroup( this );
m_loopGroup->addButton( m_loopOffButton );
@@ -753,6 +753,7 @@ AudioFileProcessorWaveView::AudioFileProcessorWaveView( QWidget * _parent, int _
m_graph.fill( Qt::transparent );
update();
updateCursor();
}
@@ -769,7 +770,7 @@ void AudioFileProcessorWaveView::isPlaying( f_cnt_t _current_frame )
void AudioFileProcessorWaveView::enterEvent( QEvent * _e )
{
QApplication::setOverrideCursor( Qt::OpenHandCursor );
updateCursor();
}
@@ -777,10 +778,7 @@ void AudioFileProcessorWaveView::enterEvent( QEvent * _e )
void AudioFileProcessorWaveView::leaveEvent( QEvent * _e )
{
while( QApplication::overrideCursor() )
{
QApplication::restoreOverrideCursor();
}
updateCursor();
}
@@ -808,7 +806,7 @@ void AudioFileProcessorWaveView::mousePressEvent( QMouseEvent * _me )
else
{
m_draggingType = wave;
QApplication::setOverrideCursor( Qt::ClosedHandCursor );
updateCursor(_me);
}
}
@@ -820,7 +818,7 @@ void AudioFileProcessorWaveView::mouseReleaseEvent( QMouseEvent * _me )
m_isDragging = false;
if( m_draggingType == wave )
{
QApplication::restoreOverrideCursor();
updateCursor(_me);
}
}
@@ -831,22 +829,7 @@ void AudioFileProcessorWaveView::mouseMoveEvent( QMouseEvent * _me )
{
if( ! m_isDragging )
{
const bool is_size_cursor =
QApplication::overrideCursor()->shape() == Qt::SizeHorCursor;
if( isCloseTo( _me->x(), m_startFrameX ) ||
isCloseTo( _me->x(), m_endFrameX ) ||
isCloseTo( _me->x(), m_loopFrameX ) )
{
if( ! is_size_cursor )
{
QApplication::setOverrideCursor( Qt::SizeHorCursor );
}
}
else if( is_size_cursor )
{
QApplication::restoreOverrideCursor();
}
updateCursor(_me);
return;
}
@@ -1219,6 +1202,24 @@ void AudioFileProcessorWaveView::reverse()
void AudioFileProcessorWaveView::updateCursor( QMouseEvent * _me )
{
bool const waveIsDragged = m_isDragging && (m_draggingType == wave);
bool const pointerCloseToStartEndOrLoop = (_me != nullptr ) &&
( isCloseTo( _me->x(), m_startFrameX ) ||
isCloseTo( _me->x(), m_endFrameX ) ||
isCloseTo( _me->x(), m_loopFrameX ) );
if( !m_isDragging && pointerCloseToStartEndOrLoop)
setCursor(Qt::SizeHorCursor);
else if( waveIsDragged )
setCursor(Qt::ClosedHandCursor);
else
setCursor(Qt::OpenHandCursor);
}
void AudioFileProcessorWaveView::knob::slideTo( double _v, bool _check_bound )
{
@@ -1277,10 +1278,9 @@ extern "C"
{
// necessary for getting instance out of shared lib
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
PLUGIN_EXPORT Plugin * lmms_plugin_main(Model * model, void *)
{
return new audioFileProcessor(
static_cast<InstrumentTrack *>( _data ) );
return new audioFileProcessor(static_cast<InstrumentTrack *>(model));
}

View File

@@ -211,7 +211,6 @@ public:
private:
bool checkBound( double _v ) const;
} ;
@@ -276,6 +275,7 @@ private:
void updateGraph();
void reverse();
void updateCursor( QMouseEvent * _me = nullptr );
static bool isCloseTo( int _a, int _b )
{

View File

@@ -566,9 +566,9 @@ extern "C"
{
// necessary for getting instance out of shared lib
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * )
{
return( new bitInvader( static_cast<InstrumentTrack *>( _data ) ) );
return( new bitInvader( static_cast<InstrumentTrack *>( m ) ) );
}

View File

@@ -25,6 +25,7 @@
#include "carla.h"
#include "embed.h"
#include "InstrumentTrack.h"
extern "C"
{
@@ -43,9 +44,9 @@ Plugin::Descriptor PLUGIN_EXPORT carlapatchbay_plugin_descriptor =
NULL
} ;
PLUGIN_EXPORT Plugin* lmms_plugin_main(Model*, void* data)
PLUGIN_EXPORT Plugin* lmms_plugin_main(Model* m, void*)
{
return new CarlaInstrument(static_cast<InstrumentTrack*>(data), &carlapatchbay_plugin_descriptor, true);
return new CarlaInstrument(static_cast<InstrumentTrack*>(m), &carlapatchbay_plugin_descriptor, true);
}
}

View File

@@ -25,6 +25,7 @@
#include "carla.h"
#include "embed.h"
#include "InstrumentTrack.h"
extern "C"
{
@@ -43,9 +44,9 @@ Plugin::Descriptor PLUGIN_EXPORT carlarack_plugin_descriptor =
NULL
} ;
PLUGIN_EXPORT Plugin* lmms_plugin_main(Model*, void* data)
PLUGIN_EXPORT Plugin* lmms_plugin_main(Model* m, void*)
{
return new CarlaInstrument(static_cast<InstrumentTrack*>(data), &carlarack_plugin_descriptor, false);
return new CarlaInstrument(static_cast<InstrumentTrack*>(m), &carlarack_plugin_descriptor, false);
}
}

View File

@@ -367,9 +367,9 @@ extern "C"
{
// necessary for getting instance out of shared lib
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model * m, void * )
{
return new kickerInstrument( static_cast<InstrumentTrack *>( _data ) );
return new kickerInstrument( static_cast<InstrumentTrack *>( m ) );
}

View File

@@ -1029,11 +1029,11 @@ extern "C"
{
// necessary for getting instance out of shared lib
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model * m, void * )
{
return( new lb302Synth(
static_cast<InstrumentTrack *>( _data ) ) );
static_cast<InstrumentTrack *>( m ) ) );
}

View File

@@ -1828,9 +1828,9 @@ extern "C"
{
// necessary for getting instance out of shared lib
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * )
{
return new MonstroInstrument( static_cast<InstrumentTrack *>( _data ) );
return new MonstroInstrument( static_cast<InstrumentTrack *>( m ) );
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 522 B

After

Width:  |  Height:  |  Size: 539 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 599 B

After

Width:  |  Height:  |  Size: 498 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 563 B

After

Width:  |  Height:  |  Size: 711 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 520 B

After

Width:  |  Height:  |  Size: 443 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 529 B

After

Width:  |  Height:  |  Size: 489 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 578 B

After

Width:  |  Height:  |  Size: 596 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 468 B

After

Width:  |  Height:  |  Size: 530 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 427 B

After

Width:  |  Height:  |  Size: 345 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 539 B

After

Width:  |  Height:  |  Size: 453 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 602 B

After

Width:  |  Height:  |  Size: 566 B

View File

@@ -918,9 +918,9 @@ extern "C"
{
// necessary for getting instance out of shared lib
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * _data )
{
return( new NesInstrument( static_cast<InstrumentTrack *>( _data ) ) );
return( new NesInstrument( static_cast<InstrumentTrack *>( m ) ) );
}

View File

@@ -636,9 +636,9 @@ extern "C"
{
// necessary for getting instance out of shared lib
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * )
{
return( new organicInstrument( static_cast<InstrumentTrack *>( _data ) ) );
return( new organicInstrument( static_cast<InstrumentTrack *>( m ) ) );
}

View File

@@ -66,9 +66,9 @@ Plugin::Descriptor PLUGIN_EXPORT patman_plugin_descriptor =
// necessary for getting instance out of shared lib
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * )
{
return new patmanInstrument( static_cast<InstrumentTrack *>( _data ) );
return new patmanInstrument( static_cast<InstrumentTrack *>( m ) );
}
}

View File

@@ -1150,9 +1150,9 @@ extern "C"
{
// necessary for getting instance out of shared lib
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * )
{
return new sf2Instrument( static_cast<InstrumentTrack *>( _data ) );
return new sf2Instrument( static_cast<InstrumentTrack *>( m ) );
}

View File

@@ -1122,9 +1122,9 @@ extern "C"
{
// necessary for getting instance out of shared lib
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model*, void* data )
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model* m, void* )
{
return new sfxrInstrument( static_cast<InstrumentTrack *>( data ) );
return new sfxrInstrument( static_cast<InstrumentTrack *>( m ) );
}

View File

@@ -794,10 +794,9 @@ extern "C"
{
// necessary for getting instance out of shared lib
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * )
{
return( new sidInstrument(
static_cast<InstrumentTrack *>( _data ) ) );
return( new sidInstrument( static_cast<InstrumentTrack *>( m ) ) );
}

View File

@@ -756,9 +756,9 @@ extern "C"
{
// necessary for getting instance out of shared lib
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model * m, void * )
{
return new malletsInstrument( static_cast<InstrumentTrack *>( _data ) );
return new malletsInstrument( static_cast<InstrumentTrack *>( m ) );
}

View File

@@ -723,9 +723,9 @@ extern "C"
{
// necessary for getting instance out of shared lib
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model* model, void * )
{
return new TripleOscillator( static_cast<InstrumentTrack *>( _data ) );
return new TripleOscillator( static_cast<InstrumentTrack *>( model ) );
}
}

View File

@@ -186,7 +186,13 @@ vestigeInstrument::~vestigeInstrument()
void vestigeInstrument::loadSettings( const QDomElement & _this )
{
loadFile( _this.attribute( "plugin" ) );
QString plugin = _this.attribute( "plugin" );
if( plugin.isEmpty() )
{
return;
}
loadFile( plugin );
m_pluginMutex.lock();
if( m_plugin != NULL )
{
@@ -217,13 +223,8 @@ void vestigeInstrument::loadSettings( const QDomElement & _this )
knobFModel[ i ]->setInitValue(LocaleHelper::toFloat(s_dumpValues.at(2)));
}
#if QT_VERSION < 0x050000
connect( knobFModel[i], SIGNAL( dataChanged( Model * ) ),
this, SLOT( setParameter( Model * ) ), Qt::DirectConnection );
#else
connect( knobFModel[i], &FloatModel::dataChanged, this,
[this, i]() { setParameter( knobFModel[i] ); }, Qt::DirectConnection);
#endif
}
}
m_pluginMutex.unlock();
@@ -978,13 +979,8 @@ manageVestigeInstrumentView::manageVestigeInstrumentView( Instrument * _instrume
}
FloatModel * model = m_vi->knobFModel[i];
#if QT_VERSION < 0x050000
connect( model, SIGNAL( dataChanged( Model * ) ), this,
SLOT( setParameter( Model * ) ), Qt::DirectConnection );
#else
connect( model, &FloatModel::dataChanged, this,
[this, model]() { setParameter( model ); }, Qt::DirectConnection);
#endif
vstKnobs[i] ->setModel( model );
}
@@ -1180,9 +1176,9 @@ extern "C"
{
// necessary for getting instance out of shared lib
Q_DECL_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
Q_DECL_EXPORT Plugin * lmms_plugin_main( Model *m, void * )
{
return new vestigeInstrument( static_cast<InstrumentTrack *>( _data ) );
return new vestigeInstrument( static_cast<InstrumentTrack *>( m ) );
}

View File

@@ -682,9 +682,9 @@ extern "C"
{
// necessary for getting instance out of shared lib
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * )
{
return( new vibed( static_cast<InstrumentTrack *>( _data ) ) );
return( new vibed( static_cast<InstrumentTrack *>( m ) ) );
}

View File

@@ -5,11 +5,11 @@ ENDIF()
INCLUDE(BuildPlugin)
INCLUDE(ExternalProject)
ADD_SUBDIRECTORY(vstbase)
# These variables are not meant to be used normally, except packaging
SET(REMOTE_VST_PLUGIN_FILEPATH_32 "32/RemoteVstPlugin32" CACHE STRING "Relative file path to RemoteVstPlugin32")
SET(REMOTE_VST_PLUGIN_FILEPATH_64 "RemoteVstPlugin64" CACHE STRING "Relative file path to RemoteVstPlugin64")
IF(LMMS_BUILD_LINUX AND WANT_VST_NOWINE)
RETURN()
ENDIF()
ADD_SUBDIRECTORY(vstbase)
SET(LMMS_BINARY_DIR ${CMAKE_BINARY_DIR})
SET(LMMS_SOURCE_DIR ${CMAKE_SOURCE_DIR})
@@ -29,6 +29,10 @@ SET(EXTERNALPROJECT_CMAKE_ARGS
)
# build 32 bit version of RemoteVstPlugin
INCLUDE("${CMAKE_CURRENT_LIST_DIR}/RemoteVstPlugin32.cmake")
IF(WANT_VST_32)
INCLUDE("${CMAKE_CURRENT_LIST_DIR}/RemoteVstPlugin32.cmake")
ENDIF()
# build 64 bit version of RemoteVstPlugin
INCLUDE("${CMAKE_CURRENT_LIST_DIR}/RemoteVstPlugin64.cmake")
IF(WANT_VST_64)
INCLUDE("${CMAKE_CURRENT_LIST_DIR}/RemoteVstPlugin64.cmake")
ENDIF()

View File

@@ -791,10 +791,6 @@ void RemoteVstPlugin::initEditor()
SWP_NOMOVE | SWP_NOZORDER );
pluginDispatch( effEditTop );
if (! EMBED) {
showEditor();
}
#ifdef LMMS_BUILD_LINUX
m_windowID = (intptr_t) GetProp( m_window, "__wine_x11_whole_window" );
#else

View File

@@ -18,6 +18,7 @@ if(IS_WIN64 OR CMAKE_SIZEOF_VOID_P EQUAL 8)
set(BITNESS 64)
else()
set(BITNESS 32)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/32")
endif()
FOREACH( OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES} )

View File

@@ -8,7 +8,7 @@ IF(LMMS_BUILD_WIN32 AND NOT LMMS_BUILD_WIN64)
INSTALL(FILES "${MINGW_PREFIX}/bin/Qt5Core.dll" DESTINATION "${PLUGIN_DIR}/32")
INSTALL(FILES "${MINGW_PREFIX}/bin/zlib1.dll" DESTINATION "${PLUGIN_DIR}/32")
ENDIF(MSVC)
INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32.exe" DESTINATION "${PLUGIN_DIR}/32")
INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../32/RemoteVstPlugin32.exe" DESTINATION "${PLUGIN_DIR}/32")
ELSEIF(LMMS_BUILD_WIN64 AND MSVC)
SET(MSVC_VER ${CMAKE_CXX_COMPILER_VERSION})
@@ -46,7 +46,7 @@ ELSEIF(LMMS_BUILD_WIN64 AND MSVC)
"-DCMAKE_PREFIX_PATH=${QT_32_PREFIX}"
)
INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32.exe" DESTINATION "${PLUGIN_DIR}/32")
INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../32/RemoteVstPlugin32.exe" DESTINATION "${PLUGIN_DIR}/32")
#TODO: find a solution when not using vcpkg for qt
SET(VCPKG_ROOT_32 "${CMAKE_FIND_ROOT_PATH}/../x86-windows")
@@ -58,6 +58,12 @@ ELSEIF(LMMS_BUILD_WIN64 AND MSVC)
ELSEIF(LMMS_BUILD_LINUX)
# Use winegcc
INCLUDE(CheckWineGcc)
CheckWineGcc(32 "${WINEGCC}" WINEGCC_WORKING)
IF(NOT WINEGCC_WORKING)
MESSAGE(WARNING "winegcc fails to complie 32-bit binaries, please make sure you have 32-bit GCC libraries")
RETURN()
ENDIF()
ExternalProject_Add(RemoteVstPlugin32
"${EXTERNALPROJECT_ARGS}"
CMAKE_ARGS
@@ -66,7 +72,7 @@ ELSEIF(LMMS_BUILD_LINUX)
"-DCMAKE_CXX_FLAGS=-m32"
)
INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32" "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32.exe.so" DESTINATION "${PLUGIN_DIR}/32")
INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../32/RemoteVstPlugin32" "${CMAKE_CURRENT_BINARY_DIR}/../32/RemoteVstPlugin32.exe.so" DESTINATION "${PLUGIN_DIR}/32")
ELSEIF(CMAKE_TOOLCHAIN_FILE_32)
ExternalProject_Add(RemoteVstPlugin32
@@ -78,7 +84,7 @@ ELSEIF(CMAKE_TOOLCHAIN_FILE_32)
)
INSTALL(FILES "${CMAKE_PREFIX_PATH_32}/bin/Qt5Core.dll" DESTINATION "${PLUGIN_DIR}/32")
INSTALL(FILES "${CMAKE_PREFIX_PATH_32}/bin/zlib1.dll" DESTINATION "${PLUGIN_DIR}/32")
INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32.exe" DESTINATION "${PLUGIN_DIR}/32")
INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../32/RemoteVstPlugin32.exe" DESTINATION "${PLUGIN_DIR}/32")
ELSE()
MESSAGE(WARNING "Can't build RemoteVstPlugin32, unknown environment. Please supply CMAKE_TOOLCHAIN_FILE_32 and optionally CMAKE_PREFIX_PATH_32")
RETURN()

View File

@@ -2,6 +2,12 @@ IF(LMMS_BUILD_WIN64)
ADD_SUBDIRECTORY(RemoteVstPlugin)
INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin64.exe" DESTINATION "${PLUGIN_DIR}")
ELSEIF(LMMS_BUILD_LINUX)
INCLUDE(CheckWineGcc)
CheckWineGcc(64 "${WINEGCC}" WINEGCC_WORKING)
IF(NOT WINEGCC_WORKING)
MESSAGE(WARNING "winegcc fails to compile 64-bit binaries, please make sure you have 64-bit GCC libraries")
RETURN()
ENDIF()
ExternalProject_Add(RemoteVstPlugin64
"${EXTERNALPROJECT_ARGS}"
CMAKE_ARGS

View File

@@ -149,10 +149,10 @@ VstPlugin::VstPlugin( const QString & _plugin ) :
switch(machineType)
{
case PE::MachineType::amd64:
tryLoad( "RemoteVstPlugin64" );
tryLoad( REMOTE_VST_PLUGIN_FILEPATH_64 ); // Default: RemoteVstPlugin64
break;
case PE::MachineType::i386:
tryLoad( "32/RemoteVstPlugin32" );
tryLoad( REMOTE_VST_PLUGIN_FILEPATH_32 ); // Default: 32/RemoteVstPlugin32
break;
default:
m_failed = true;
@@ -386,7 +386,9 @@ bool VstPlugin::processMessage( const message & _m )
{
case IdVstPluginWindowID:
m_pluginWindowID = _m.getInt();
if( m_embedMethod == "none" )
if( m_embedMethod == "none"
&& ConfigManager::inst()->value(
"ui", "vstalwaysontop" ).toInt() )
{
#ifdef LMMS_BUILD_WIN32
// We're changing the owner, not the parent,

View File

@@ -1,3 +1,6 @@
ADD_DEFINITIONS(-DREMOTE_VST_PLUGIN_FILEPATH_32="${REMOTE_VST_PLUGIN_FILEPATH_32}")
ADD_DEFINITIONS(-DREMOTE_VST_PLUGIN_FILEPATH_64="${REMOTE_VST_PLUGIN_FILEPATH_64}")
BUILD_PLUGIN(vstbase
../vst_base.cpp ../VstPlugin.cpp ../VstPlugin.h ../communication.h
MOCFILES ../VstPlugin.h

View File

@@ -1279,9 +1279,9 @@ extern "C"
{
// necessary for getting instance out of shared lib
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * )
{
return( new WatsynInstrument( static_cast<InstrumentTrack *>( _data ) ) );
return( new WatsynInstrument( static_cast<InstrumentTrack *>( m ) ) );
}

View File

@@ -27,6 +27,7 @@
#include <QDir>
#include <QDomDocument>
#include <QTemporaryFile>
#include <QtGlobal>
#include <QDropEvent>
#include <QGridLayout>
#include <QPushButton>
@@ -290,6 +291,7 @@ void ZynAddSubFxInstrument::loadSettings( const QDomElement & _this )
emit settingsChanged();
}
emit instrumentTrack()->pitchModel()->dataChanged();
}
@@ -659,10 +661,9 @@ extern "C"
{
// necessary for getting instance out of shared lib
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
PLUGIN_EXPORT Plugin * lmms_plugin_main(Model * m, void *)
{
return new ZynAddSubFxInstrument( static_cast<InstrumentTrack *>( _data ) );
return new ZynAddSubFxInstrument(static_cast<InstrumentTrack *>(m));
}

View File

@@ -45,7 +45,7 @@ INCLUDE(GenQrc)
ADD_GEN_QRC(LMMS_RCC_OUT lmms.qrc
"${CMAKE_SOURCE_DIR}/doc/AUTHORS"
"${CMAKE_SOURCE_DIR}/LICENSE.txt"
"${CMAKE_BINARY_DIR}/CONTRIBUTORS"
"${CONTRIBUTORS}"
)
# Paths relative to lmms executable

View File

@@ -511,8 +511,9 @@ void ConfigManager::loadConfigFile( const QString & configFile )
cfg_file.close();
}
// Plugins are searched recursively, blacklist problematic locations
if( m_vstDir.isEmpty() || m_vstDir == QDir::separator() || m_vstDir == "/" ||
m_vstDir == ensureTrailingSlash( QDir::homePath() ) ||
!QDir( m_vstDir ).exists() )
{
#ifdef LMMS_BUILD_WIN32

View File

@@ -124,7 +124,10 @@ void DrumSynth::GetEnv(int env, const char *sec, const char *key, QString ini)
char en[256], s[8];
int i=0, o=0, ep=0;
GetPrivateProfileString(sec, key, "0,0 100,0", en, sizeof(en), ini);
en[255]=0; //be safe!
//be safe!
en[255]=0;
s[0]=0;
while(en[i]!=0)
{

View File

@@ -36,9 +36,8 @@
Effect::Effect( const Plugin::Descriptor * _desc,
Model * _parent,
const Descriptor::SubPluginFeatures::Key * _key ) :
Plugin( _desc, _parent ),
Plugin( _desc, _parent, _key ),
m_parent( NULL ),
m_key( _key ? *_key : Descriptor::SubPluginFeatures::Key() ),
m_processors( 1 ),
m_okay( true ),
m_noRun( false ),
@@ -117,7 +116,7 @@ Effect * Effect::instantiate( const QString& pluginName,
Model * _parent,
Descriptor::SubPluginFeatures::Key * _key )
{
Plugin * p = Plugin::instantiate( pluginName, _parent, _key );
Plugin * p = Plugin::instantiateWithKey( pluginName, _parent, _key );
// check whether instantiated plugin is an effect
if( dynamic_cast<Effect *>( p ) != NULL )
{

View File

@@ -29,6 +29,7 @@
#include "FxMixer.h"
#include "Ladspa2LMMS.h"
#include "Mixer.h"
#include "Plugin.h"
#include "PresetPreviewPlayHandle.h"
#include "ProjectJournal.h"
#include "Song.h"
@@ -41,6 +42,7 @@ BBTrackContainer * LmmsCore::s_bbTrackContainer = NULL;
Song * LmmsCore::s_song = NULL;
ProjectJournal * LmmsCore::s_projectJournal = NULL;
Ladspa2LMMS * LmmsCore::s_ladspaManager = NULL;
void* LmmsCore::s_dndPluginKey = nullptr;
DummyTrackContainer * LmmsCore::s_dummyTC = NULL;
@@ -112,4 +114,24 @@ void LmmsCore::updateFramesPerTick()
DefaultTicksPerTact / s_song->getTempo();
}
void LmmsCore::setDndPluginKey(void *newKey)
{
Q_ASSERT(static_cast<Plugin::Descriptor::SubPluginFeatures::Key*>(newKey));
s_dndPluginKey = newKey;
}
void *LmmsCore::pickDndPluginKey()
{
return s_dndPluginKey;
}
LmmsCore * LmmsCore::s_instanceOfMe = NULL;

View File

@@ -32,6 +32,7 @@
#include "Song.h"
#include "InstrumentTrack.h"
#include "SampleTrack.h"
#include "BBTrackContainer.h"
FxRoute::FxRoute( FxChannel * from, FxChannel * to, float amount ) :
@@ -305,6 +306,22 @@ void FxMixer::deleteChannel( int index )
inst->effectChannelModel()->setValue(val-1);
}
}
else if( t->type() == Track::SampleTrack )
{
SampleTrack* strk = dynamic_cast<SampleTrack *>( t );
int val = strk->effectChannelModel()->value(0);
if( val == index )
{
// we are deleting this track's fx send
// send to master
strk->effectChannelModel()->setValue(0);
}
else if( val > index )
{
// subtract 1 to make up for the missing channel
strk->effectChannelModel()->setValue(val-1);
}
}
}
FxChannel * ch = m_fxChannels[index];
@@ -379,6 +396,19 @@ void FxMixer::moveChannelLeft( int index )
inst->effectChannelModel()->setValue(a);
}
}
else if( trackList[i]->type() == Track::SampleTrack )
{
SampleTrack * strk = (SampleTrack *) trackList[i];
int val = strk->effectChannelModel()->value(0);
if( val == a )
{
strk->effectChannelModel()->setValue(b);
}
else if( val == b )
{
strk->effectChannelModel()->setValue(a);
}
}
}
}
@@ -780,4 +810,3 @@ void FxMixer::validateChannelName( int index, int oldIndex )
m_fxChannels[index]->m_name = tr( "FX %1" ).arg( index );
}
}

View File

@@ -27,9 +27,10 @@
#include "DummyInstrument.h"
Instrument::Instrument( InstrumentTrack * _instrument_track,
const Descriptor * _descriptor ) :
Plugin( _descriptor, NULL/* _instrument_track*/ ),
Instrument::Instrument(InstrumentTrack * _instrument_track,
const Descriptor * _descriptor,
const Descriptor::SubPluginFeatures::Key *key) :
Plugin(_descriptor, NULL/* _instrument_track*/, key),
m_instrumentTrack( _instrument_track )
{
}
@@ -56,19 +57,15 @@ f_cnt_t Instrument::beatLen( NotePlayHandle * ) const
Instrument * Instrument::instantiate( const QString & _plugin_name,
InstrumentTrack * _instrument_track )
Instrument *Instrument::instantiate(const QString &_plugin_name,
InstrumentTrack *_instrument_track, const Descriptor::SubPluginFeatures::Key *key, bool keyFromDnd)
{
Plugin * p = Plugin::instantiate( _plugin_name, _instrument_track,
_instrument_track );
// check whether instantiated plugin is an instrument
if( dynamic_cast<Instrument *>( p ) != NULL )
{
// everything ok, so return pointer
return dynamic_cast<Instrument *>( p );
}
// not quite... so delete plugin and return dummy instrument
if(keyFromDnd)
Q_ASSERT(!key);
// copy from above // TODO! common cleaner func
Plugin * p = Plugin::instantiateWithKey(_plugin_name, _instrument_track, key, keyFromDnd);
if(dynamic_cast<Instrument *>(p))
return dynamic_cast<Instrument *>(p);
delete p;
return( new DummyInstrument( _instrument_track ) );
}

View File

@@ -40,7 +40,7 @@
LadspaManager::LadspaManager()
{
// Make sure plugin search paths are set up
PluginFactory::instance();
PluginFactory::setupSearchPaths();
QStringList ladspaDirectories = QString( getenv( "LADSPA_PATH" ) ).
split( LADSPA_PATH_SEPERATOR );

View File

@@ -23,6 +23,9 @@
*/
#include "MixHelpers.h"
#include <cstdio>
#include "lmms_math.h"
#include "ValueBuffer.h"

View File

@@ -186,8 +186,8 @@ Mixer::~Mixer()
}
delete m_fifo;
delete m_audioDev;
delete m_midiClient;
delete m_audioDev;
for( int i = 0; i < 3; i++ )
{

View File

@@ -22,12 +22,14 @@
*
*/
#include "Plugin.h"
#include <QtGlobal>
#include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtCore/QLibrary>
#include <QMessageBox>
#include "Plugin.h"
#include "embed.h"
#include "Engine.h"
#include "GuiApplication.h"
@@ -53,10 +55,12 @@ static Plugin::Descriptor dummyPluginDescriptor =
Plugin::Plugin( const Descriptor * descriptor, Model * parent ) :
Model( parent ),
Plugin::Plugin(const Descriptor * descriptor, Model * parent, const
Descriptor::SubPluginFeatures::Key* key) :
Model(parent),
JournallingObject(),
m_descriptor( descriptor )
m_descriptor(descriptor),
m_key(key ? *key : Descriptor::SubPluginFeatures::Key(m_descriptor))
{
if( m_descriptor == NULL )
{
@@ -74,6 +78,97 @@ Plugin::~Plugin()
template<class T>
T use_this_or(T this_param, T or_param)
{
return this_param ? this_param : or_param;
}
QString use_this_or(QString this_param, QString or_param)
{
return this_param.isNull() ? or_param : this_param;
}
QString Plugin::displayName() const
{
return Model::displayName().isEmpty() // currently always empty
? (m_descriptor->subPluginFeatures && m_key.isValid())
// get from sub plugin
? m_key.displayName()
// get from plugin
: m_descriptor->displayName
: Model::displayName();
}
const PixmapLoader* Plugin::logo() const
{
return (m_descriptor->subPluginFeatures && m_key.isValid())
? m_key.logo()
: m_descriptor->logo;
}
QString Plugin::Descriptor::SubPluginFeatures::Key::additionalFileExtensions() const
{
Q_ASSERT(isValid());
return desc->subPluginFeatures
// get from sub plugin
? desc->subPluginFeatures->additionalFileExtensions(*this)
// no sub plugin, so no *additional* file extensions
: QString();
}
QString Plugin::Descriptor::SubPluginFeatures::Key::displayName() const
{
Q_ASSERT(isValid());
return desc->subPluginFeatures
// get from sub plugin
? use_this_or(desc->subPluginFeatures->displayName(*this),
QString::fromUtf8(desc->displayName))
// get from plugin
: desc->displayName;
}
const PixmapLoader* Plugin::Descriptor::SubPluginFeatures::Key::logo() const
{
Q_ASSERT(isValid());
return desc->subPluginFeatures
? use_this_or(desc->subPluginFeatures->logo(*this), desc->logo)
: desc->logo;
}
QString Plugin::Descriptor::SubPluginFeatures::Key::description() const
{
Q_ASSERT(isValid());
return desc->subPluginFeatures
? use_this_or(desc->subPluginFeatures->description(*this),
QString::fromUtf8(desc->description))
: desc->description;
}
void Plugin::loadFile( const QString & )
{
}
@@ -90,10 +185,38 @@ AutomatableModel * Plugin::childModel( const QString & )
#include "PluginFactory.h"
Plugin * Plugin::instantiate( const QString& pluginName, Model * parent,
void * data )
Plugin * Plugin::instantiateWithKey(const QString& pluginName, Model * parent,
const Descriptor::SubPluginFeatures::Key *key,
bool keyFromDnd)
{
if(keyFromDnd)
Q_ASSERT(!key);
const Descriptor::SubPluginFeatures::Key *keyPtr = keyFromDnd
? static_cast<Plugin::Descriptor::SubPluginFeatures::Key*>(Engine::pickDndPluginKey())
: key;
const PluginFactory::PluginInfo& pi = pluginFactory->pluginInfo(pluginName.toUtf8());
if(keyPtr)
{
// descriptor is not yet set when loading - set it now
Descriptor::SubPluginFeatures::Key keyCopy = *keyPtr;
keyCopy.desc = pi.descriptor;
return Plugin::instantiate(pluginName, parent, &keyCopy);
}
else
return Plugin::instantiate(pluginName, parent,
// the keys are never touched anywhere
const_cast<Descriptor::SubPluginFeatures::Key *>(keyPtr));
}
Plugin * Plugin::instantiate(const QString& pluginName, Model * parent,
void *data)
{
const PluginFactory::PluginInfo& pi = pluginFactory->pluginInfo(pluginName.toUtf8());
Plugin* inst;
if( pi.isNull() )
{
if( gui )
@@ -104,23 +227,31 @@ Plugin * Plugin::instantiate( const QString& pluginName, Model * parent,
arg( pluginName ).arg( pluginFactory->errorString(pluginName) ),
QMessageBox::Ok | QMessageBox::Default );
}
return new DummyPlugin();
inst = new DummyPlugin();
}
InstantiationHook instantiationHook = ( InstantiationHook ) pi.library->resolve( "lmms_plugin_main" );
if( instantiationHook == NULL )
else
{
if( gui )
InstantiationHook instantiationHook;
if ((instantiationHook = ( InstantiationHook ) pi.library->resolve( "lmms_plugin_main" )))
{
QMessageBox::information( NULL,
tr( "Error while loading plugin" ),
tr( "Failed to load plugin \"%1\"!").arg( pluginName ),
QMessageBox::Ok | QMessageBox::Default );
inst = instantiationHook(parent, data);
if(!inst) {
inst = new DummyPlugin();
}
}
else
{
if( gui )
{
QMessageBox::information( NULL,
tr( "Error while loading plugin" ),
tr( "Failed to load plugin \"%1\"!").arg( pluginName ),
QMessageBox::Ok | QMessageBox::Default );
}
inst = new DummyPlugin();
}
return new DummyPlugin();
}
Plugin * inst = instantiationHook( parent, data );
return inst;
}

View File

@@ -28,8 +28,11 @@
#include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtCore/QLibrary>
#include "lmmsconfig.h"
#include "ConfigManager.h"
#include "Plugin.h"
#include "embed.h"
#ifdef LMMS_BUILD_WIN32
QStringList nameFilters("*.dll");
@@ -45,6 +48,16 @@ qint64 qHash(const QFileInfo& fi)
std::unique_ptr<PluginFactory> PluginFactory::s_instance;
PluginFactory::PluginFactory()
{
setupSearchPaths();
discoverPlugins();
}
PluginFactory::~PluginFactory()
{
}
void PluginFactory::setupSearchPaths()
{
// Adds a search path relative to the main executable if the path exists.
auto addRelativeIfExists = [](const QString & path) {
@@ -76,12 +89,6 @@ PluginFactory::PluginFactory()
QDir::addSearchPath("plugins", env_path);
QDir::addSearchPath("plugins", ConfigManager::inst()->workingDir() + "plugins");
discoverPlugins();
}
PluginFactory::~PluginFactory()
{
}
PluginFactory* PluginFactory::instance()
@@ -107,9 +114,9 @@ const PluginFactory::PluginInfoList& PluginFactory::pluginInfos() const
return m_pluginInfos;
}
const PluginFactory::PluginInfo PluginFactory::pluginSupportingExtension(const QString& ext)
const PluginFactory::PluginInfoAndKey PluginFactory::pluginSupportingExtension(const QString& ext)
{
return m_pluginByExt.value(ext, PluginInfo());
return m_pluginByExt.value(ext, PluginInfoAndKey());
}
const PluginFactory::PluginInfo PluginFactory::pluginInfo(const char* name) const
@@ -150,42 +157,78 @@ void PluginFactory::discoverPlugins()
for (const QFileInfo& file : files)
{
auto library = std::make_shared<QLibrary>(file.absoluteFilePath());
if (! library->load()) {
m_errors[file.baseName()] = library->errorString();
qWarning("%s", library->errorString().toLocal8Bit().data());
continue;
}
if (library->resolve("lmms_plugin_main") == nullptr) {
continue;
}
QString descriptorName = file.baseName() + "_plugin_descriptor";
if( descriptorName.left(3) == "lib" )
Plugin::Descriptor* pluginDescriptor = nullptr;
if (library->resolve("lmms_plugin_main"))
{
descriptorName = descriptorName.mid(3);
QString descriptorName = file.baseName() + "_plugin_descriptor";
if( descriptorName.left(3) == "lib" )
{
descriptorName = descriptorName.mid(3);
}
pluginDescriptor = reinterpret_cast<Plugin::Descriptor*>(library->resolve(descriptorName.toUtf8().constData()));
if(pluginDescriptor == nullptr)
{
qWarning() << qApp->translate("PluginFactory", "LMMS plugin %1 does not have a plugin descriptor named %2!").
arg(file.absoluteFilePath()).arg(descriptorName);
continue;
}
}
Plugin::Descriptor* pluginDescriptor = reinterpret_cast<Plugin::Descriptor*>(library->resolve(descriptorName.toUtf8().constData()));
if(pluginDescriptor == nullptr)
if(pluginDescriptor)
{
qWarning() << qApp->translate("PluginFactory", "LMMS plugin %1 does not have a plugin descriptor named %2!").
arg(file.absoluteFilePath()).arg(descriptorName);
continue;
PluginInfo info;
info.file = file;
info.library = library;
info.descriptor = pluginDescriptor;
pluginInfos << info;
auto addSupportedFileTypes =
[this](QString supportedFileTypes,
const PluginInfo& info,
const Plugin::Descriptor::SubPluginFeatures::Key* key = nullptr)
{
if(!supportedFileTypes.isNull())
{
for (const QString& ext : supportedFileTypes.split(','))
{
//qDebug() << "Plugin " << info.name()
// << "supports" << ext;
PluginInfoAndKey infoAndKey;
infoAndKey.info = info;
infoAndKey.key = key
? *key
: Plugin::Descriptor::SubPluginFeatures::Key();
m_pluginByExt.insert(ext, infoAndKey);
}
}
};
if (info.descriptor->supportedFileTypes)
addSupportedFileTypes(QString(info.descriptor->supportedFileTypes), info);
if (info.descriptor->subPluginFeatures)
{
Plugin::Descriptor::SubPluginFeatures::KeyList
subPluginKeys;
info.descriptor->subPluginFeatures->listSubPluginKeys(
info.descriptor,
subPluginKeys);
for(const Plugin::Descriptor::SubPluginFeatures::Key& key
: subPluginKeys)
{
addSupportedFileTypes(key.additionalFileExtensions(), info, &key);
}
}
descriptors.insert(info.descriptor->type, info.descriptor);
}
PluginInfo info;
info.file = file;
info.library = library;
info.descriptor = pluginDescriptor;
pluginInfos << info;
for (const QString& ext : QString(info.descriptor->supportedFileTypes).split(','))
{
m_pluginByExt.insert(ext, info);
}
descriptors.insert(info.descriptor->type, info.descriptor);
}
m_pluginInfos = pluginInfos;

View File

@@ -137,8 +137,10 @@ PresetPreviewPlayHandle::PresetPreviewPlayHandle( const QString & _preset_file,
suffix().toLower();
if( i == NULL || !i->descriptor()->supportsFileType( ext ) )
{
const PluginFactory::PluginInfoAndKey& infoAndKey =
pluginFactory->pluginSupportingExtension(ext);
i = s_previewTC->previewInstrumentTrack()->
loadInstrument(pluginFactory->pluginSupportingExtension(ext).name());
loadInstrument(infoAndKey.info.name(), &infoAndKey.key);
}
if( i != NULL )
{

View File

@@ -525,7 +525,7 @@ void TrackContentObjectView::dragEnterEvent( QDragEnterEvent * dee )
{
TrackContentWidget * tcw = getTrackView()->getTrackContentWidget();
MidiTime tcoPos = MidiTime( m_tco->startPosition().getTact(), 0 );
if( tcw->canPasteSelection( tcoPos, dee->mimeData() ) == false )
if( tcw->canPasteSelection( tcoPos, dee ) == false )
{
dee->ignore();
}
@@ -630,9 +630,12 @@ DataFile TrackContentObjectView::createTCODataFiles(
it != tcoViews.end(); ++it )
{
// Insert into the dom under the "tcos" element
int trackIndex = tc->tracks().indexOf( ( *it )->m_trackView->getTrack() );
Track* tcoTrack = ( *it )->m_trackView->getTrack();
int trackIndex = tc->tracks().indexOf( tcoTrack );
QDomElement tcoElement = dataFile.createElement( "tco" );
tcoElement.setAttribute( "trackIndex", trackIndex );
tcoElement.setAttribute( "trackType", tcoTrack->type() );
tcoElement.setAttribute( "trackName", tcoTrack->name() );
( *it )->m_tco->saveState( dataFile, tcoElement );
tcoParent.appendChild( tcoElement );
}
@@ -649,6 +652,7 @@ DataFile TrackContentObjectView::createTCODataFiles(
QDomElement metadata = dataFile.createElement( "copyMetadata" );
// initialTrackIndex is the index of the track that was touched
metadata.setAttribute( "initialTrackIndex", initialTrackIndex );
metadata.setAttribute( "trackContainerId", tc->id() );
// grabbedTCOPos is the pos of the tact containing the TCO we grabbed
metadata.setAttribute( "grabbedTCOPos", m_tco->startPosition() );
@@ -1387,7 +1391,7 @@ MidiTime TrackContentWidget::getPosition( int mouseX )
void TrackContentWidget::dragEnterEvent( QDragEnterEvent * dee )
{
MidiTime tcoPos = MidiTime( getPosition( dee->pos().x() ).getTact(), 0 );
if( canPasteSelection( tcoPos, dee->mimeData() ) == false )
if( canPasteSelection( tcoPos, dee ) == false )
{
dee->ignore();
}
@@ -1406,8 +1410,10 @@ void TrackContentWidget::dragEnterEvent( QDragEnterEvent * dee )
* \param tcoPos the position of the TCO slot being pasted on
* \param de the DropEvent generated
*/
bool TrackContentWidget::canPasteSelection( MidiTime tcoPos, const QMimeData * mimeData )
bool TrackContentWidget::canPasteSelection( MidiTime tcoPos, const QDropEvent* de )
{
const QMimeData * mimeData = de->mimeData();
Track * t = getTrack();
QString type = StringPairDrag::decodeMimeKey( mimeData );
QString value = StringPairDrag::decodeMimeValue( mimeData );
@@ -1437,7 +1443,9 @@ bool TrackContentWidget::canPasteSelection( MidiTime tcoPos, const QMimeData * m
const int currentTrackIndex = tracks.indexOf( t );
// Don't paste if we're on the same tact
if( tcoPos == grabbedTCOTact && currentTrackIndex == initialTrackIndex )
auto sourceTrackContainerId = metadata.attributeNode( "trackContainerId" ).value().toUInt();
if( de->source() && sourceTrackContainerId == t->trackContainer()->id() &&
tcoPos == grabbedTCOTact && currentTrackIndex == initialTrackIndex )
{
return false;
}
@@ -1460,9 +1468,9 @@ bool TrackContentWidget::canPasteSelection( MidiTime tcoPos, const QMimeData * m
}
// Track must be of the same type
Track * startTrack = tracks.at( trackIndex );
auto startTrackType = tcoElement.attributeNode("trackType").value().toInt();
Track * endTrack = tracks.at( finalTrackIndex );
if( startTrack->type() != endTrack->type() )
if( startTrackType != endTrack->type() )
{
return false;
}
@@ -1478,7 +1486,7 @@ bool TrackContentWidget::canPasteSelection( MidiTime tcoPos, const QMimeData * m
*/
bool TrackContentWidget::pasteSelection( MidiTime tcoPos, QDropEvent * de )
{
if( canPasteSelection( tcoPos, de->mimeData() ) == false )
if( canPasteSelection( tcoPos, de ) == false )
{
return false;
}
@@ -1548,7 +1556,8 @@ bool TrackContentWidget::pasteSelection( MidiTime tcoPos, QDropEvent * de )
}
//check tco name, if the same as source track name dont copy
if( tco->name() == tracks[trackIndex]->name() )
QString sourceTrackName = outerTCOElement.attributeNode( "trackName" ).value();
if( tco->name() == sourceTrackName )
{
tco->setName( "" );
}
@@ -1924,13 +1933,15 @@ void TrackOperationsWidget::updateMenu()
{
toMenu->addAction( tr( "Clear this track" ), this, SLOT( clearTrack() ) );
}
if( InstrumentTrackView * trackView = dynamic_cast<InstrumentTrackView *>( m_trackView ) )
if (QMenu *fxMenu = m_trackView->createFxMenu(tr("FX %1: %2"), tr("Assign to new FX Channel")))
{
QMenu *fxMenu = trackView->createFxMenu( tr( "FX %1: %2" ), tr( "Assign to new FX Channel" ));
toMenu->addMenu(fxMenu);
}
if (InstrumentTrackView * trackView = dynamic_cast<InstrumentTrackView *>(m_trackView))
{
toMenu->addSeparator();
toMenu->addMenu( trackView->midiMenu() );
toMenu->addMenu(trackView->midiMenu());
}
if( dynamic_cast<AutomationTrackView *>( m_trackView ) )
{
@@ -2677,6 +2688,19 @@ void TrackView::update()
/*! \brief Create a menu for assigning/creating channels for this track.
*
*/
QMenu * TrackView::createFxMenu(QString title, QString newFxLabel)
{
Q_UNUSED(title)
Q_UNUSED(newFxLabel)
return NULL;
}
/*! \brief Close this track View.
*
*/

View File

@@ -61,6 +61,7 @@ static void JackMidiShutdown(void *arg)
MidiJack::MidiJack() :
MidiClientRaw(),
m_jackClient( nullptr ),
m_input_port( NULL ),
m_output_port( NULL ),
m_quit( false )

View File

@@ -56,6 +56,7 @@ SET(LMMS_SRCS
gui/widgets/FadeButton.cpp
gui/widgets/Fader.cpp
gui/widgets/FxLine.cpp
gui/widgets/FxLineLcdSpinBox.cpp
gui/widgets/Graph.cpp
gui/widgets/GroupBox.cpp
gui/widgets/InstrumentFunctionViews.cpp

View File

@@ -27,6 +27,7 @@
#include "ui_EffectSelectDialog.h"
#include "gui_templates.h"
#include "DummyEffect.h"
#include "embed.h"
#include "PluginFactory.h"
@@ -53,11 +54,6 @@ EffectSelectDialog::EffectSelectDialog( QWidget * _parent ) :
if( desc->subPluginFeatures )
{
desc->subPluginFeatures->listSubPluginKeys(
// as iterators are always stated to be not
// equal with pointers, we dereference the
// iterator and take the address of the item,
// so we're on the safe side and the compiler
// likely will reduce that to just "it"
desc,
subPluginEffectKeys );
}
@@ -79,14 +75,14 @@ EffectSelectDialog::EffectSelectDialog( QWidget * _parent ) :
{
QString name;
QString type;
if( ( *it ).desc->subPluginFeatures )
if( it->desc->subPluginFeatures )
{
name = ( *it ).name;
type = ( *it ).desc->displayName;
name = it->displayName();
type = it->desc->displayName;
}
else
{
name = ( *it ).desc->displayName;
name = it->desc->displayName;
type = "LMMS";
}
m_sourceModel.setItem( row, 0, new QStandardItem( name ) );
@@ -147,12 +143,17 @@ EffectSelectDialog::~EffectSelectDialog()
Effect * EffectSelectDialog::instantiateSelectedPlugin( EffectChain * _parent )
{
if( !m_currentSelection.name.isEmpty() && m_currentSelection.desc )
Effect* result = nullptr;
if(!m_currentSelection.name.isEmpty() && m_currentSelection.desc)
{
return Effect::instantiate( m_currentSelection.desc->name,
_parent, &m_currentSelection );
result = Effect::instantiate(m_currentSelection.desc->name,
_parent, &m_currentSelection);
}
return NULL;
if(!result)
{
result = new DummyEffect(_parent, QDomElement());
}
return result;
}
@@ -184,62 +185,63 @@ void EffectSelectDialog::rowChanged( const QModelIndex & _idx,
{
m_currentSelection = m_effectKeys[m_model.mapToSource( _idx ).row()];
}
if( m_currentSelection.desc )
if( m_currentSelection.desc )
{
m_descriptionWidget = new QWidget;
QHBoxLayout *hbox = new QHBoxLayout( m_descriptionWidget );
QHBoxLayout *hbox = new QHBoxLayout( m_descriptionWidget );
Plugin::Descriptor const & descriptor = *( m_currentSelection.desc );
Plugin::Descriptor const & descriptor = *( m_currentSelection.desc );
if ( descriptor.logo )
{
QLabel *logoLabel = new QLabel( m_descriptionWidget );
logoLabel->setPixmap( descriptor.logo->pixmap() );
logoLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
const PixmapLoader* pixLoa = m_currentSelection.logo();
if (pixLoa)
{
QLabel *logoLabel = new QLabel( m_descriptionWidget );
logoLabel->setPixmap(pixLoa->pixmap());
logoLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
hbox->addWidget( logoLabel );
hbox->setAlignment( logoLabel, Qt::AlignTop);
}
hbox->addWidget( logoLabel );
hbox->setAlignment( logoLabel, Qt::AlignTop);
}
QWidget *textualInfoWidget = new QWidget( m_descriptionWidget );
QWidget *textualInfoWidget = new QWidget( m_descriptionWidget );
hbox->addWidget(textualInfoWidget);
hbox->addWidget(textualInfoWidget);
QVBoxLayout * textWidgetLayout = new QVBoxLayout( textualInfoWidget);
textWidgetLayout->setMargin( 4 );
textWidgetLayout->setSpacing( 0 );
QVBoxLayout * textWidgetLayout = new QVBoxLayout( textualInfoWidget);
textWidgetLayout->setMargin( 4 );
textWidgetLayout->setSpacing( 0 );
if ( m_currentSelection.desc->subPluginFeatures )
{
QWidget *subWidget = new QWidget(textualInfoWidget);
QVBoxLayout * subLayout = new QVBoxLayout( subWidget );
subLayout->setMargin( 4 );
subLayout->setSpacing( 0 );
m_currentSelection.desc->subPluginFeatures->
fillDescriptionWidget( subWidget, &m_currentSelection );
for( QWidget * w : subWidget->findChildren<QWidget *>() )
{
if( w->parent() == subWidget )
{
subLayout->addWidget( w );
}
}
if ( m_currentSelection.desc->subPluginFeatures )
{
QWidget *subWidget = new QWidget(textualInfoWidget);
QVBoxLayout * subLayout = new QVBoxLayout( subWidget );
subLayout->setMargin( 4 );
subLayout->setSpacing( 0 );
m_currentSelection.desc->subPluginFeatures->
fillDescriptionWidget( subWidget, &m_currentSelection );
for( QWidget * w : subWidget->findChildren<QWidget *>() )
{
if( w->parent() == subWidget )
{
subLayout->addWidget( w );
}
}
textWidgetLayout->addWidget(subWidget);
}
else
{
QLabel *label = new QLabel(m_descriptionWidget);
QString labelText = "<p><b>" + tr("Name") + ":</b> " + QString::fromUtf8(descriptor.displayName) + "</p>";
labelText += "<p><b>" + tr("Description") + ":</b> " + qApp->translate( "pluginBrowser", descriptor.description ) + "</p>";
labelText += "<p><b>" + tr("Author") + ":</b> " + QString::fromUtf8(descriptor.author) + "</p>";
textWidgetLayout->addWidget(subWidget);
}
else
{
QLabel *label = new QLabel(m_descriptionWidget);
QString labelText = "<p><b>" + tr("Name") + ":</b> " + QString::fromUtf8(descriptor.displayName) + "</p>";
labelText += "<p><b>" + tr("Description") + ":</b> " + qApp->translate( "pluginBrowser", descriptor.description ) + "</p>";
labelText += "<p><b>" + tr("Author") + ":</b> " + QString::fromUtf8(descriptor.author) + "</p>";
label->setText(labelText);
textWidgetLayout->addWidget(label);
}
label->setText(labelText);
textWidgetLayout->addWidget(label);
}
ui->scrollArea->setWidget( m_descriptionWidget );
ui->scrollArea->setWidget( m_descriptionWidget );
m_descriptionWidget->show();
}
}

View File

@@ -180,7 +180,7 @@ void FileBrowser::reloadTree( void )
void FileBrowser::expandItems( QTreeWidgetItem * item )
{
int numChildren = item ? item->childCount() : m_fileBrowserTreeWidget->topLevelItemCount();
int numChildren = item ? item->childCount() : m_fileBrowserTreeWidget->topLevelItemCount();
for( int i = 0; i < numChildren; ++i )
{
QTreeWidgetItem * it = item ? item->child( i ) : m_fileBrowserTreeWidget->topLevelItem(i);
@@ -241,7 +241,7 @@ void FileBrowser::addItems(const QString & path )
Directory *dd = new Directory( cur_file, path,
m_filter );
m_fileBrowserTreeWidget->insertTopLevelItem( i,dd );
dd->update();
dd->update(); // add files to the directory
orphan = false;
break;
}
@@ -406,7 +406,7 @@ void FileBrowserTreeWidget::mousePressEvent(QMouseEvent * me )
delete tf;
}
else if( ( f->extension ()== "xiz" || f->extension() == "sf2" || f->extension() == "sf3" || f->extension() == "gig" || f->extension() == "pat" ) &&
! pluginFactory->pluginSupportingExtension(f->extension()).isNull() )
! pluginFactory->pluginSupportingExtension(f->extension()).info.isNull() )
{
m_previewPlayHandle = new PresetPreviewPlayHandle( f->fullName(), f->handling() == FileItem::LoadByPlugin );
}
@@ -549,8 +549,9 @@ void FileBrowserTreeWidget::handleFile(FileItem * f, InstrumentTrack * it )
if( i == NULL ||
!i->descriptor()->supportsFileType( e ) )
{
i = it->loadInstrument(
pluginFactory->pluginSupportingExtension(e).name() );
PluginFactory::PluginInfoAndKey piakn =
pluginFactory->pluginSupportingExtension(e);
i = it->loadInstrument(piakn.info.name(), &piakn.key);
}
i->loadFile( f->fullName() );
break;

View File

@@ -47,6 +47,7 @@
#include "Mixer.h"
#include "gui_templates.h"
#include "InstrumentTrack.h"
#include "SampleTrack.h"
#include "Song.h"
#include "BBTrackContainer.h"
@@ -251,6 +252,12 @@ void FxMixerView::updateMaxChannelSelector()
inst->effectChannelModel()->setRange(0,
m_fxChannelViews.size()-1,1);
}
else if( trackList[i]->type() == Track::SampleTrack )
{
SampleTrack * strk = (SampleTrack *) trackList[i];
strk->effectChannelModel()->setRange(0,
m_fxChannelViews.size()-1,1);
}
}
}
}

View File

@@ -57,7 +57,7 @@ void InstrumentView::setModel( Model * _model, bool )
if( dynamic_cast<Instrument *>( _model ) != NULL )
{
ModelView::setModel( _model );
instrumentTrackWindow()->setWindowIcon( model()->descriptor()->logo->pixmap() );
instrumentTrackWindow()->setWindowIcon( model()->logo()->pixmap() );
connect( model(), SIGNAL( destroyed( QObject * ) ), this, SLOT( close() ) );
}
}

View File

@@ -24,13 +24,16 @@
#include "PluginBrowser.h"
#include <QHeaderView>
#include <QLabel>
#include <QPainter>
#include <QLineEdit>
#include <QMouseEvent>
#include <QScrollArea>
#include <QPainter>
#include <QStyleOption>
#include <QTreeWidget>
#include "embed.h"
#include "Engine.h"
#include "templates.h"
#include "gui_templates.h"
#include "StringPairDrag.h"
@@ -59,23 +62,91 @@ PluginBrowser::PluginBrowser( QWidget * _parent ) :
m_view );
hint->setWordWrap( true );
QScrollArea* scrollarea = new QScrollArea( m_view );
PluginDescList* descList = new PluginDescList( m_view );
scrollarea->setWidget(descList);
scrollarea->setWidgetResizable(true);
QLineEdit * searchBar = new QLineEdit( m_view );
searchBar->setPlaceholderText( "Search" );
searchBar->setMaxLength( 64 );
searchBar->setClearButtonEnabled( true );
view_layout->addWidget(hint);
view_layout->addWidget(scrollarea);
m_descTree = new QTreeWidget( m_view );
m_descTree->setColumnCount( 1 );
m_descTree->header()->setVisible( false );
m_descTree->setIndentation( 10 );
m_descTree->setSelectionMode( QAbstractItemView::NoSelection );
connect( searchBar, SIGNAL( textEdited( const QString & ) ),
this, SLOT( onFilterChanged( const QString & ) ) );
view_layout->addWidget( hint );
view_layout->addWidget( searchBar );
view_layout->addWidget( m_descTree );
// Add LMMS root to the tree
m_lmmsRoot = new QTreeWidgetItem();
m_lmmsRoot->setText( 0, "LMMS" );
m_descTree->insertTopLevelItem( 0, m_lmmsRoot );
m_lmmsRoot->setExpanded( true );
// Add LV2 root to the tree
m_lv2Root = new QTreeWidgetItem();
m_lv2Root->setText( 0, "LV2" );
m_descTree->insertTopLevelItem( 1, m_lv2Root );
// Add plugins to the tree roots
addPlugins();
// Resize
m_descTree->header()->setSectionResizeMode( QHeaderView::ResizeToContents );
// Hide empty roots
updateRootVisibilities();
}
PluginDescList::PluginDescList(QWidget *parent) :
QWidget(parent)
void PluginBrowser::updateRootVisibility( int rootIndex )
{
QVBoxLayout* layout = new QVBoxLayout(this);
QTreeWidgetItem * root = m_descTree->topLevelItem( rootIndex );
root->setHidden( !root->childCount() );
}
void PluginBrowser::updateRootVisibilities()
{
int rootCount = m_descTree->topLevelItemCount();
for (int rootIndex = 0; rootIndex < rootCount; ++rootIndex)
{
updateRootVisibility( rootIndex );
}
}
void PluginBrowser::onFilterChanged( const QString & filter )
{
int rootCount = m_descTree->topLevelItemCount();
for (int rootIndex = 0; rootIndex < rootCount; ++rootIndex)
{
QTreeWidgetItem * root = m_descTree->topLevelItem( rootIndex );
int itemCount = root->childCount();
for (int itemIndex = 0; itemIndex < itemCount; ++itemIndex)
{
QTreeWidgetItem * item = root->child( itemIndex );
PluginDescWidget * descWidget = static_cast<PluginDescWidget *>
(m_descTree->itemWidget( item, 0));
if (descWidget->name().contains(filter, Qt::CaseInsensitive))
{
item->setHidden( false );
}
else
{
item->setHidden( true );
}
}
}
}
void PluginBrowser::addPlugins()
{
QList<Plugin::Descriptor*> descs = pluginFactory->descriptors(Plugin::Instrument);
std::sort(
descs.begin(),
@@ -85,37 +156,71 @@ PluginDescList::PluginDescList(QWidget *parent) :
return qstricmp( d1->displayName, d2->displayName ) < 0 ? true : false;
}
);
for (const Plugin::Descriptor* desc : descs)
typedef Plugin::Descriptor::SubPluginFeatures::KeyList PluginKeyList;
typedef Plugin::Descriptor::SubPluginFeatures::Key PluginKey;
PluginKeyList subPluginKeys, pluginKeys;
for (const Plugin::Descriptor* desc: descs)
{
PluginDescWidget* p = new PluginDescWidget( *desc, this );
p->show();
layout->addWidget(p);
if ( desc->subPluginFeatures )
{
desc->subPluginFeatures->listSubPluginKeys(
desc,
subPluginKeys );
}
else
{
pluginKeys << PluginKey( desc, desc->name );
}
}
setLayout(layout);
layout->addStretch();
pluginKeys += subPluginKeys;
for (const PluginKey& key : pluginKeys)
{
QTreeWidgetItem * item = new QTreeWidgetItem();
if ( key.desc->name == QStringLiteral("lv2instrument") )
{
m_lv2Root->addChild( item );
}
else
{
m_lmmsRoot->addChild( item );
}
PluginDescWidget* p = new PluginDescWidget( key, m_descTree );
m_descTree->setItemWidget( item, 0, p );
}
}
PluginDescWidget::PluginDescWidget( const Plugin::Descriptor & _pd,
PluginDescWidget::PluginDescWidget(const PluginKey &_pk,
QWidget * _parent ) :
QWidget( _parent ),
m_pluginDescriptor( _pd ),
m_logo( _pd.logo->pixmap() ),
m_pluginKey( _pk ),
m_logo( _pk.logo()->pixmap() ),
m_mouseOver( false )
{
setFixedHeight( DEFAULT_HEIGHT );
setMouseTracking( true );
setCursor( Qt::PointingHandCursor );
setToolTip(_pd.description);
setToolTip(_pk.description());
}
void PluginDescWidget::paintEvent( QPaintEvent * e )
QString PluginDescWidget::name() const
{
return m_pluginKey.displayName();
}
void PluginDescWidget::paintEvent( QPaintEvent * )
{
QPainter p( this );
@@ -140,8 +245,7 @@ void PluginDescWidget::paintEvent( QPaintEvent * e )
}
p.setFont( f );
p.drawText( 10 + logo_size.width(), 15,
m_pluginDescriptor.displayName );
p.drawText( 10 + logo_size.width(), 15, m_pluginKey.displayName());
}
@@ -169,10 +273,11 @@ void PluginDescWidget::leaveEvent( QEvent * _e )
void PluginDescWidget::mousePressEvent( QMouseEvent * _me )
{
if( _me->button() == Qt::LeftButton )
if ( _me->button() == Qt::LeftButton )
{
new StringPairDrag( "instrument", m_pluginDescriptor.name,
m_logo, this );
Engine::setDndPluginKey(&m_pluginKey);
new StringPairDrag("instrument",
QString::fromUtf8(m_pluginKey.desc->name), m_logo, this);
leaveEvent( _me );
}
}

View File

@@ -139,7 +139,9 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) :
"displaywaveform").toInt() ),
m_disableAutoQuit(ConfigManager::inst()->value( "ui",
"disableautoquit", "1" ).toInt() ),
m_vstEmbedMethod( ConfigManager::inst()->vstEmbedMethod() )
m_vstEmbedMethod( ConfigManager::inst()->vstEmbedMethod() ),
m_vstAlwaysOnTop( ConfigManager::inst()->value( "ui",
"vstalwaysontop" ).toInt() )
{
setWindowIcon( embed::getIconPixmap( "setup_general" ) );
setWindowTitle( tr( "Setup LMMS" ) );
@@ -259,7 +261,7 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) :
}
TabWidget* embed_tw = new TabWidget( tr( "PLUGIN EMBEDDING" ), general);
embed_tw->setFixedHeight( 48 );
embed_tw->setFixedHeight( 66 );
m_vstEmbedComboBox = new QComboBox( embed_tw );
m_vstEmbedComboBox->move( XDelta, YDelta );
@@ -278,6 +280,17 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) :
m_vstEmbedComboBox->addItem( tr( "Embed using XEmbed protocol" ), "xembed" );
}
m_vstEmbedComboBox->setCurrentIndex( m_vstEmbedComboBox->findData( m_vstEmbedMethod ) );
connect( m_vstEmbedComboBox, SIGNAL( currentIndexChanged( int ) ),
this, SLOT( vstEmbedMethodChanged() ) );
m_vstAlwaysOnTopCheckBox = new LedCheckBox(
tr( "Keep plugin windows on top when not embedded" ),
embed_tw );
m_vstAlwaysOnTopCheckBox->move( 20, 44 );
m_vstAlwaysOnTopCheckBox->setChecked( m_vstAlwaysOnTop );
m_vstAlwaysOnTopCheckBox->setVisible( m_vstEmbedMethod == "none" );
connect( m_vstAlwaysOnTopCheckBox, SIGNAL( toggled( bool ) ),
this, SLOT( toggleVSTAlwaysOnTop( bool ) ) );
TabWidget * lang_tw = new TabWidget( tr( "LANGUAGE" ), general );
lang_tw->setFixedHeight( 48 );
@@ -427,7 +440,7 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) :
#endif
addPathEntry("Themes directory", m_artworkDir,
SLOT(setArtworkDir(const QString &)),
SLOT(openArtwortDir()),
SLOT(openArtworkDir()),
m_adLineEdit, pathSelectors);
pathSelectorLayout->addStretch();
addPathEntry("Background artwork", m_backgroundArtwork,
@@ -854,7 +867,9 @@ void SetupDialog::accept()
QString::number( m_disableAutoQuit ) );
ConfigManager::inst()->setValue( "app", "language", m_lang );
ConfigManager::inst()->setValue( "ui", "vstembedmethod",
m_vstEmbedComboBox->currentData().toString() );
m_vstEmbedMethod );
ConfigManager::inst()->setValue( "ui", "vstalwaysontop",
QString::number( m_vstAlwaysOnTop ) );
ConfigManager::inst()->setWorkingDir(QDir::fromNativeSeparators(m_workingDir));
@@ -1057,6 +1072,20 @@ void SetupDialog::toggleOneInstrumentTrackWindow( bool _enabled )
m_oneInstrumentTrackWindow = _enabled;
}
void SetupDialog::vstEmbedMethodChanged()
{
m_vstEmbedMethod = m_vstEmbedComboBox->currentData().toString();
m_vstAlwaysOnTopCheckBox->setVisible( m_vstEmbedMethod == "none" );
}
void SetupDialog::toggleVSTAlwaysOnTop( bool en )
{
m_vstAlwaysOnTop = en;
}
void SetupDialog::setLanguage( int lang )
{
m_lang = m_languages[lang];

Some files were not shown because too many files have changed in this diff Show More