diff options
Diffstat (limited to 'muse2/muse/instruments')
-rw-r--r-- | muse2/muse/instruments/Makefile.am | 15 | ||||
-rw-r--r-- | muse2/muse/instruments/Makefile.in | 599 | ||||
-rw-r--r-- | muse2/muse/instruments/ccontrolbase.ui | 525 | ||||
-rw-r--r-- | muse2/muse/instruments/editinstrument.cpp | 3541 | ||||
-rw-r--r-- | muse2/muse/instruments/editinstrument.h | 92 | ||||
-rw-r--r-- | muse2/muse/instruments/editinstrumentbase.ui | 1840 | ||||
-rw-r--r-- | muse2/muse/instruments/midictrledit.cpp | 733 | ||||
-rw-r--r-- | muse2/muse/instruments/midictrledit.h | 56 | ||||
-rw-r--r-- | muse2/muse/instruments/minstrument.cpp | 850 | ||||
-rw-r--r-- | muse2/muse/instruments/minstrument.h | 135 |
10 files changed, 8386 insertions, 0 deletions
diff --git a/muse2/muse/instruments/Makefile.am b/muse2/muse/instruments/Makefile.am new file mode 100644 index 00000000..6882f39b --- /dev/null +++ b/muse2/muse/instruments/Makefile.am @@ -0,0 +1,15 @@ +include $(top_srcdir)/common.am + +if PCH +AM_CXXFLAGS += -include $(top_srcdir)/all.h +endif + +noinst_LIBRARIES = libinstruments.a + +dist_libinstruments_a_SOURCES = \ + minstrument.cpp minstrument.h \ + editinstrument.h editinstrument.cpp \ + editinstrumentbase.ui + +nodist_libinstruments_a_SOURCES = \ + moc_editinstrument.cpp diff --git a/muse2/muse/instruments/Makefile.in b/muse2/muse/instruments/Makefile.in new file mode 100644 index 00000000..f7eab504 --- /dev/null +++ b/muse2/muse/instruments/Makefile.in @@ -0,0 +1,599 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(top_srcdir)/common.am +@PCH_TRUE@am__append_1 = -include $(top_srcdir)/all.h +subdir = muse/instruments +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/aclocal-include.m4 \ + $(top_srcdir)/m4/alsa.m4 $(top_srcdir)/m4/docbook.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LIBRARIES = $(noinst_LIBRARIES) +ARFLAGS = cru +libinstruments_a_AR = $(AR) $(ARFLAGS) +libinstruments_a_LIBADD = +dist_libinstruments_a_OBJECTS = minstrument.$(OBJEXT) \ + editinstrument.$(OBJEXT) editinstrumentbase.$(OBJEXT) +nodist_libinstruments_a_OBJECTS = moc_editinstrument.$(OBJEXT) +libinstruments_a_OBJECTS = $(dist_libinstruments_a_OBJECTS) \ + $(nodist_libinstruments_a_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(dist_libinstruments_a_SOURCES) \ + $(nodist_libinstruments_a_SOURCES) +DIST_SOURCES = $(dist_libinstruments_a_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALSA_CFLAGS = @ALSA_CFLAGS@ +ALSA_LIBS = @ALSA_LIBS@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DOCBOOKSTYLE = @DOCBOOKSTYLE@ +DOCBOOKTARGETS = @DOCBOOKTARGETS@ +DOT = @DOT@ +DOTPATH = @DOTPATH@ +DOXYGEN = @DOXYGEN@ +DOXYGEN_TREEVIEW = @DOXYGEN_TREEVIEW@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +FLUIDSYNTHDIRS = @FLUIDSYNTHDIRS@ +FST_CFLAGS = @FST_CFLAGS@ +FST_LIBS = @FST_LIBS@ +Fluidsynth_CFLAGS = @Fluidsynth_CFLAGS@ +Fluidsynth_LIBS = @Fluidsynth_LIBS@ +GIVERTCAP = @GIVERTCAP@ +GREP = @GREP@ +HAVEDOT = @HAVEDOT@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JACK_CFLAGS = @JACK_CFLAGS@ +JACK_LIBS = @JACK_LIBS@ +JADE = @JADE@ +LASH_CFLAGS = @LASH_CFLAGS@ +LASH_LIBS = @LASH_LIBS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LO_CFLAGS = @LO_CFLAGS@ +LO_LIBS = @LO_LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MUSECXXFLAGS = @MUSECXXFLAGS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NSGMLS = @NSGMLS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PCH = @PCH@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_INCLUDES = @PYTHON_INCLUDES@ +PYTHON_LIB = @PYTHON_LIB@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +QTDIR_BIN = @QTDIR_BIN@ +QTDIR_INC = @QTDIR_INC@ +QT_LIBS = @QT_LIBS@ +RANLIB = @RANLIB@ +SAMPLERATE_CFLAGS = @SAMPLERATE_CFLAGS@ +SAMPLERATE_LIBS = @SAMPLERATE_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SNDFILE_CFLAGS = @SNDFILE_CFLAGS@ +SNDFILE_LIBS = @SNDFILE_LIBS@ +STRIP = @STRIP@ +SUIDBUILD = @SUIDBUILD@ +SUIDINSTALL = @SUIDINSTALL@ +USE_SSE = @USE_SSE@ +UUID_CFLAGS = @UUID_CFLAGS@ +UUID_LIBS = @UUID_LIBS@ +VERSION = @VERSION@ +XMKMF = @XMKMF@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +have_docbook = @have_docbook@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +synth_fluid = @synth_fluid@ +synth_fluidsynth = @synth_fluidsynth@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AM_CXXFLAGS = $(MUSECXXFLAGS) -I.. -I$(top_srcdir)/synti \ + -I$(top_srcdir)/muse/widgets -DQT_SHARED -DQT_THREAD_SUPPORT \ + -DQT_PLUGIN $(QTDIR_INC) -DQT3_SUPPORT $(am__append_1) +AM_CPPFLAGS = +MOC = $(QTDIR_BIN)/moc +#UIC = $(QTDIR_BIN)/uic3 +UIC = /usr/bin/uic3 +UIFILES = $(wildcard *.ui) +MOCFILES = $(shell for h in $(filter %.h,$(SOURCES)); do \ + if grep -q Q_OBJECT $$h; then \ + echo $$h | sed "s/\(.*\)\.h/moc_\1.cpp/"; \ + fi; \ + done) + +BUILT_SOURCES = $(MOCFILES) $(UIFILES:%.ui=%.h) +MOSTLYCLEANFILES = $(MOCFILES) $(UIFILES:%.ui=%.h) +SUFFIXES = .ui .h.gch +noinst_LIBRARIES = libinstruments.a +dist_libinstruments_a_SOURCES = \ + minstrument.cpp minstrument.h \ + editinstrument.h editinstrument.cpp \ + editinstrumentbase.ui + +nodist_libinstruments_a_SOURCES = \ + moc_editinstrument.cpp + +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .ui .h.gch .cpp .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/common.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu muse/instruments/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu muse/instruments/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +libinstruments.a: $(libinstruments_a_OBJECTS) $(libinstruments_a_DEPENDENCIES) + -rm -f libinstruments.a + $(libinstruments_a_AR) libinstruments.a $(libinstruments_a_OBJECTS) $(libinstruments_a_LIBADD) + $(RANLIB) libinstruments.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/editinstrument.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/minstrument.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/moc_editinstrument.Po@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-am +all-am: Makefile $(LIBRARIES) +installdirs: +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: all check install install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + + +de: + @for base in $(MOCFILES); do echo -e "\t$${base}.cpp $${base}.h \\"; done + +nde: + @for base in $(MOCFILES); do echo -e "\tmoc_$${base}.cpp \\"; done + +.ui.o: %.h + $(UIC) -L $(top_srcdir)/muse/widgets -o $*.cpp -impl $*.h $*.ui + $(MOC) $*.h >> $*.cpp + $(CXXCOMPILE) -c $*.cpp -o $*.o + $(RM) $*.cpp moc_$*.cpp moc_$*.o + +.ui.lo: %.h + $(UIC) -L $(top_srcdir)/muse/widgets -o $*.cpp -impl $*.h $*.ui + $(MOC) $*.h >> $*.cpp + $(LTCXXCOMPILE) -c $*.cpp -o $*.lo + $(RM) $*.cpp moc_$*.cpp moc_$*.lo moc_$*.o + +moc_%.cpp: %.h + $(MOC) $< -o $@ + +%.h: %.ui + $(UIC) -o $@ $< +# $(UIC) -L $(top_srcdir)/muse/widgets -o $@ $< + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/muse2/muse/instruments/ccontrolbase.ui b/muse2/muse/instruments/ccontrolbase.ui new file mode 100644 index 00000000..3094776f --- /dev/null +++ b/muse2/muse/instruments/ccontrolbase.ui @@ -0,0 +1,525 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>MidiControllerEditDialogBase</class> +<widget class="QDialog"> + <property name="name"> + <cstring>MidiControllerEditDialogBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>698</width> + <height>457</height> + </rect> + </property> + <property name="caption"> + <string>MusE: Define Midi Controller</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLayoutWidget" row="3" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>Layout2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonNew</cstring> + </property> + <property name="text"> + <string>&Add</string> + </property> + <property name="accel"> + <string>Alt+A</string> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + <property name="toolTip" stdset="0"> + <string>create new entry</string> + </property> + <property name="whatsThis" stdset="0"> + <string>pressing the New button you create a new entry +in the MusE list of defined controllers</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonDelete</cstring> + </property> + <property name="text"> + <string>&Delete</string> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + <property name="toolTip" stdset="0"> + <string>delete selected entry</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer1</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>0</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonOk</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonApply</cstring> + </property> + <property name="text"> + <string>A&pply</string> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonCancel</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + </widget> + </hbox> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>Predefined Controller:</string> + </property> + </widget> + <widget class="QListView" row="1" column="1"> + <column> + <property name="text"> + <string>Name </string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Type </string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>H-Ctrl</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>false</bool> + </property> + </column> + <column> + <property name="text"> + <string>L-Ctrl</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>false</bool> + </property> + </column> + <column> + <property name="text"> + <string>Min Val</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>false</bool> + </property> + </column> + <column> + <property name="text"> + <string>Max Val</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>false</bool> + </property> + </column> + <property name="name"> + <cstring>viewController</cstring> + </property> + <property name="frameShape"> + <enum>StyledPanel</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="allColumnsShowFocus"> + <bool>true</bool> + </property> + <property name="toolTip" stdset="0"> + <string>list of defined controllers</string> + </property> + <property name="whatsThis" stdset="0"> + <string>This is the MusE list of defined controllers.</string> + </property> + </widget> + <widget class="QLayoutWidget" row="0" column="1"> + <property name="name"> + <cstring>layout2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel2</cstring> + </property> + <property name="text"> + <string>Managed Controller for Port</string> + </property> + </widget> + <widget class="QComboBox"> + <property name="name"> + <cstring>midiPortsList</cstring> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel3</cstring> + </property> + <property name="text"> + <string>Channel</string> + </property> + </widget> + <widget class="QSpinBox"> + <property name="name"> + <cstring>midiChannel</cstring> + </property> + <property name="maxValue"> + <number>16</number> + </property> + <property name="minValue"> + <number>1</number> + </property> + </widget> + </hbox> + </widget> + <widget class="QListBox" row="1" column="0" rowspan="2" colspan="1"> + <property name="name"> + <cstring>listController</cstring> + </property> + <property name="whatsThis" stdset="0"> + <string>This is a list of commonly used midi controllers. +Note that in MusE pitch and program changes are +handled like normal controllers.</string> + </property> + </widget> + <widget class="QGroupBox" row="2" column="1"> + <property name="name"> + <cstring>GroupBox1</cstring> + </property> + <property name="title"> + <string>Properties</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>TextLabel1</cstring> + </property> + <property name="text"> + <string>Name</string> + </property> + </widget> + <widget class="QLayoutWidget" row="2" column="1"> + <property name="name"> + <cstring>layout3</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>TextLabel1_2</cstring> + </property> + <property name="text"> + <string>Min Value</string> + </property> + <property name="indent"> + <number>10</number> + </property> + </widget> + <widget class="QSpinBox"> + <property name="name"> + <cstring>spinboxMin</cstring> + </property> + <property name="maxValue"> + <number>16384</number> + </property> + <property name="minValue"> + <number>-16385</number> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>TextLabel2_2</cstring> + </property> + <property name="text"> + <string>Max Value</string> + </property> + <property name="indent"> + <number>10</number> + </property> + </widget> + <widget class="QSpinBox"> + <property name="name"> + <cstring>spinboxMax</cstring> + </property> + <property name="maxValue"> + <number>16384</number> + </property> + <property name="minValue"> + <number>-16385</number> + </property> + <property name="value"> + <number>127</number> + </property> + </widget> + </hbox> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>TextLabel2</cstring> + </property> + <property name="text"> + <string>Type</string> + </property> + </widget> + <widget class="QLineEdit" row="0" column="1"> + <property name="name"> + <cstring>entryName</cstring> + </property> + </widget> + <widget class="QLayoutWidget" row="1" column="1"> + <property name="name"> + <cstring>layout5</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QComboBox"> + <item> + <property name="text"> + <string>Control7</string> + </property> + </item> + <item> + <property name="text"> + <string>Control14</string> + </property> + </item> + <item> + <property name="text"> + <string>RPN</string> + </property> + </item> + <item> + <property name="text"> + <string>NRPN</string> + </property> + </item> + <item> + <property name="text"> + <string>RPN14</string> + </property> + </item> + <item> + <property name="text"> + <string>NRPN14</string> + </property> + </item> + <item> + <property name="text"> + <string>Pitch</string> + </property> + </item> + <item> + <property name="text"> + <string>Program</string> + </property> + </item> + <property name="name"> + <cstring>comboType</cstring> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>TextLabel3</cstring> + </property> + <property name="text"> + <string>H-Ctrl</string> + </property> + <property name="indent"> + <number>10</number> + </property> + </widget> + <widget class="QSpinBox"> + <property name="name"> + <cstring>spinboxHCtrlNo</cstring> + </property> + <property name="maxValue"> + <number>127</number> + </property> + <property name="minValue"> + <number>0</number> + </property> + <property name="value"> + <number>1</number> + </property> + <property name="toolTip" stdset="0"> + <string>Midi Controller Number High Byte</string> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>TextLabel2_3</cstring> + </property> + <property name="text"> + <string>L-Ctrl</string> + </property> + <property name="indent"> + <number>10</number> + </property> + </widget> + <widget class="QSpinBox"> + <property name="name"> + <cstring>spinboxLCtrlNo</cstring> + </property> + <property name="maxValue"> + <number>127</number> + </property> + <property name="minValue"> + <number>0</number> + </property> + <property name="value"> + <number>1</number> + </property> + <property name="toolTip" stdset="0"> + <string>Midi Controller Number Low Byte</string> + </property> + </widget> + </hbox> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>textLabel4</cstring> + </property> + <property name="text"> + <string>Range</string> + </property> + </widget> + </grid> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>buttonCancel</sender> + <signal>clicked()</signal> + <receiver>MidiControllerEditDialogBase</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>buttonOk</sender> + <signal>clicked()</signal> + <receiver>MidiControllerEditDialogBase</receiver> + <slot>accept()</slot> + </connection> +</connections> +<tabstops> + <tabstop>viewController</tabstop> + <tabstop>entryName</tabstop> + <tabstop>comboType</tabstop> + <tabstop>spinboxHCtrlNo</tabstop> + <tabstop>spinboxLCtrlNo</tabstop> + <tabstop>spinboxMin</tabstop> + <tabstop>spinboxMax</tabstop> + <tabstop>buttonNew</tabstop> + <tabstop>buttonDelete</tabstop> + <tabstop>buttonOk</tabstop> + <tabstop>buttonApply</tabstop> + <tabstop>buttonCancel</tabstop> +</tabstops> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/muse2/muse/instruments/editinstrument.cpp b/muse2/muse/instruments/editinstrument.cpp new file mode 100644 index 00000000..9e85356a --- /dev/null +++ b/muse2/muse/instruments/editinstrument.cpp @@ -0,0 +1,3541 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: editinstrument.cpp,v 1.2.2.6 2009/05/31 05:12:12 terminator356 Exp $ +// +// (C) Copyright 2003 Werner Schweer (ws@seh.de) +//========================================================= + +#include <q3listbox.h> +//Added by qt3to4: +#include <QCloseEvent> +#include <stdio.h> +#include <errno.h> +#include <qmessagebox.h> +#include <qspinbox.h> +#include <qcombobox.h> +#include <qlineedit.h> +#include <qcheckbox.h> +#include <qdir.h> +#include <qfileinfo.h> +#include <q3filedialog.h> +#include <qtoolbutton.h> +#include <q3popupmenu.h> +#include <qpushbutton.h> +#include <qtabwidget.h> +#include <qinputdialog.h> + +#include "editinstrument.h" +#include "minstrument.h" +#include "globals.h" +#include "listitem.h" +#include "song.h" +#include "xml.h" +#include "midictrl.h" +#include "gconfig.h" + +enum { + COL_NAME = 0, COL_TYPE, + COL_HNUM, COL_LNUM, COL_MIN, COL_MAX, COL_DEF + }; + +//--------------------------------------------------------- +// EditInstrument +//--------------------------------------------------------- + +EditInstrument::EditInstrument(QWidget* parent, const char* name, Qt::WFlags fl) + : EditInstrumentBase(parent, name, fl) + { + patchpopup = new Q3PopupMenu(patchButton); + patchpopup->setCheckable(false); + + // populate instrument list + // Populate common controller list. + for(int i = 0; i < 128; ++i) + listController->insertItem(midiCtrlName(i)); + + oldMidiInstrument = 0; + oldPatchItem = 0; + for (iMidiInstrument i = midiInstruments.begin(); i != midiInstruments.end(); ++i) { + // Imperfect, crude way of ignoring internal instruments, soft synths etc. If it has a gui, + // it must be an internal instrument. But this will still allow some vst instruments (without a gui) + // to show up in the list. + // Hmm, try file path instead... + //if((*i)->hasGui()) + if((*i)->filePath().isEmpty()) + continue; + + ListBoxData* item = new ListBoxData((*i)->iname()); + item->setData((void*)*i); + instrumentList->insertItem(item); + } + if(instrumentList->item(0)) + instrumentList->setSelected(instrumentList->item(0), true); + //oldMidiInstrument = (MidiInstrument*)((ListBoxData*)instrumentList->item(0))->data(); + //oldMidiInstrument = (ListBoxData*)instrumentList->item(0); + //oldMidiInstrument = (ListBoxData*)instrumentList->selectedItem(); + +// MidiInstrument* wip = (MidiInstrument*)((ListBoxData*)instrumentList->item(0))->data(); +// if(wip) + // Assignment +// workingInstrument.assign( *wip ); + + + connect(instrumentList, SIGNAL(selectionChanged()), SLOT(instrumentChanged())); + connect(patchView, SIGNAL(selectionChanged()), SLOT(patchChanged())); + + //instrumentChanged(); + changeInstrument(); + + //connect(listController, SIGNAL(selectionChanged()), SLOT(controllerChanged())); + connect(viewController, SIGNAL(selectionChanged()), SLOT(controllerChanged())); + + //connect(instrumentName, SIGNAL(textChanged(const QString&)), SLOT(instrumentNameChanged(const QString&))); + connect(instrumentName, SIGNAL(returnPressed()), SLOT(instrumentNameReturn())); + connect(instrumentName, SIGNAL(lostFocus()), SLOT(instrumentNameReturn())); + + connect(patchNameEdit, SIGNAL(returnPressed()), SLOT(patchNameReturn())); + connect(patchNameEdit, SIGNAL(lostFocus()), SLOT(patchNameReturn())); + connect(patchDelete, SIGNAL(clicked()), SLOT(deletePatchClicked())); + connect(patchNew, SIGNAL(clicked()), SLOT(newPatchClicked())); + connect(patchNewGroup, SIGNAL(clicked()), SLOT(newGroupClicked())); + //connect(newCategory, SIGNAL(clicked()), SLOT(newCategoryClicked())); + + connect(patchButton, SIGNAL(clicked()), SLOT(patchButtonClicked())); + connect(defPatchH, SIGNAL(valueChanged(int)), SLOT(defPatchChanged(int))); + connect(defPatchL, SIGNAL(valueChanged(int)), SLOT(defPatchChanged(int))); + connect(defPatchProg, SIGNAL(valueChanged(int)), SLOT(defPatchChanged(int))); + connect(deleteController, SIGNAL(clicked()), SLOT(deleteControllerClicked())); + connect(newController, SIGNAL(clicked()), SLOT(newControllerClicked())); + connect(addController, SIGNAL(clicked()), SLOT(addControllerClicked())); + connect(listController, SIGNAL(doubleClicked(Q3ListBoxItem*)), SLOT(addControllerClicked())); + connect(ctrlType,SIGNAL(activated(int)), SLOT(ctrlTypeChanged(int))); + connect(ctrlName, SIGNAL(returnPressed()), SLOT(ctrlNameReturn())); + connect(ctrlName, SIGNAL(lostFocus()), SLOT(ctrlNameReturn())); + //connect(ctrlName, SIGNAL(textChanged(const QString&)), SLOT(ctrlNameChanged(const QString&))); + connect(spinBoxHCtrlNo, SIGNAL(valueChanged(int)), SLOT(ctrlHNumChanged(int))); + connect(spinBoxLCtrlNo, SIGNAL(valueChanged(int)), SLOT(ctrlLNumChanged(int))); + connect(spinBoxMin, SIGNAL(valueChanged(int)), SLOT(ctrlMinChanged(int))); + connect(spinBoxMax, SIGNAL(valueChanged(int)), SLOT(ctrlMaxChanged(int))); + connect(spinBoxDefault, SIGNAL(valueChanged(int)), SLOT(ctrlDefaultChanged(int))); + connect(nullParamSpinBoxH, SIGNAL(valueChanged(int)), SLOT(ctrlNullParamHChanged(int))); + connect(nullParamSpinBoxL, SIGNAL(valueChanged(int)), SLOT(ctrlNullParamLChanged(int))); + + connect(tabWidget3, SIGNAL(currentChanged(QWidget*)), SLOT(tabChanged(QWidget*))); + //connect(sysexList, SIGNAL(selectionChanged()), SLOT(sysexChanged())); + //connect(deleteSysex, SIGNAL(clicked()), SLOT(deleteSysexClicked())); + //connect(newSysex, SIGNAL(clicked()), SLOT(newSysexClicked())); + } + +//--------------------------------------------------------- +// helpWhatsThis +//--------------------------------------------------------- + +void EditInstrument::helpWhatsThis() +{ + whatsThis(); +} + +//--------------------------------------------------------- +// fileNew +//--------------------------------------------------------- + +void EditInstrument::fileNew() + { + // Allow these to update... + instrumentNameReturn(); + patchNameReturn(); + ctrlNameReturn(); + + for (int i = 1;; ++i) { + QString s = QString("Instrument-%1").arg(i); + bool found = false; + for (iMidiInstrument i = midiInstruments.begin(); i != midiInstruments.end(); ++i) { + if (s == (*i)->iname()) { + found = true; + break; + } + } + if (!found) { + //if(oldMidiInstrument) + //{ + //MidiInstrument* oi = (MidiInstrument*)old->data(Qt::UserRole).value<void*>(); + MidiInstrument* oi = 0; + if(oldMidiInstrument) + oi = (MidiInstrument*)oldMidiInstrument->data(); + MidiInstrument* wip = &workingInstrument; + //checkDirty(oi); + //if(checkDirty(oi)) + if(checkDirty(wip)) + // No save was chosen. Restore the actual instrument name. + { + if(oi) + { + oldMidiInstrument->setText(oi->iname()); + //workingInstrument.setIName(oi->iname()); + + // No file path? Only a new unsaved instrument can do that. So delete it. + if(oi->filePath().isEmpty()) + // Delete the list item and the instrument. + deleteInstrument(oldMidiInstrument); + + instrumentList->triggerUpdate(true); + } + } + //else + //{ + // if(oi) + // Save was chosen. Assign the working instrument to the actual instrument. + // oi->assign(workingInstrument); + //} + + //oi->setDirty(false); + workingInstrument.setDirty(false); + //} + + MidiInstrument* ni = new MidiInstrument(s); + //midiInstruments.append(ni); + midiInstruments.push_back(ni); + //QListWidgetItem* item = new QListWidgetItem(ni->iname()); + //InstrumentListItem* item = new InstrumentListItem(ni->iname()); + ListBoxData* item = new ListBoxData(ni->iname()); + + //oldMidiInstrument = item; + workingInstrument.assign( *ni ); + //workingInstrument.setDirty(false); + + //item->setText(ni->iname()); + item->setData((void*)ni); + //QVariant v = qVariantFromValue((void*)(ni)); + //item->setData(Qt::UserRole, v); + //instrumentList->addItem(item); + instrumentList->insertItem(item); + + oldMidiInstrument = 0; + + instrumentList->blockSignals(true); + instrumentList->setCurrentItem(item); + instrumentList->blockSignals(false); + + changeInstrument(); + + // We have our new instrument! So set dirty to true. + workingInstrument.setDirty(true); + + break; + } + } + + } + +//--------------------------------------------------------- +// fileOpen +//--------------------------------------------------------- + +void EditInstrument::fileOpen() + { + // Allow these to update... + //instrumentNameReturn(); + //patchNameReturn(); + //ctrlNameReturn(); + + + } + +//--------------------------------------------------------- +// fileSave +//--------------------------------------------------------- + +void EditInstrument::fileSave() +{ + //if (instrument->filePath().isEmpty()) + if (workingInstrument.filePath().isEmpty()) + { + //fileSaveAs(); + saveAs(); + return; + } + + // Do not allow a direct overwrite of a 'built-in' muse instrument. + QFileInfo qfi(workingInstrument.filePath()); + if(qfi.dirPath(true) == museInstruments) + { + //fileSaveAs(); + saveAs(); + return; + } + + //QFile f(instrument->filePath()); + //if (!f.open(QIODevice::WriteOnly)) { + //FILE* f = fopen(instrument->filePath().latin1(), "w"); + FILE* f = fopen(workingInstrument.filePath().latin1(), "w"); + if(f == 0) + { + //fileSaveAs(); + saveAs(); + return; + } + + // Allow these to update... + instrumentNameReturn(); + patchNameReturn(); + ctrlNameReturn(); + + //f.close(); + if(fclose(f) != 0) + { + //QString s = QString("Creating file:\n") + instrument->filePath() + QString("\nfailed: ") + QString s = QString("Creating file:\n") + workingInstrument.filePath() + QString("\nfailed: ") + //+ f.errorString(); + + QString(strerror(errno) ); + //fprintf(stderr, "poll failed: %s\n", strerror(errno)); + QMessageBox::critical(this, tr("MusE: Create file failed"), s); + return; + } + + //if(fileSave(instrument, instrument->filePath())) + // instrument->setDirty(false); + if(fileSave(&workingInstrument, workingInstrument.filePath())) + workingInstrument.setDirty(false); +} + +//--------------------------------------------------------- +// fileSave +//--------------------------------------------------------- + +bool EditInstrument::fileSave(MidiInstrument* instrument, const QString& name) + { + //QFile f(name); + //if (!f.open(QIODevice::WriteOnly)) { + // QString s("Creating file failed: "); + // s += strerror(errno); + // QMessageBox::critical(this, + // tr("MusE: Create file failed"), s); + // return false; + // } + //Xml xml(&f); + + FILE* f = fopen(name.ascii(), "w"); + if(f == 0) + { + //if(debugMsg) + // printf("READ IDF %s\n", fi->filePath().latin1()); + QString s("Creating file failed: "); + s += QString(strerror(errno)); + QMessageBox::critical(this, + tr("MusE: Create file failed"), s); + return false; + } + + Xml xml(f); + + updateInstrument(instrument); + + //instrument->write(xml); + instrument->write(0, xml); + + // Assign the working instrument values to the actual current selected instrument... + if(oldMidiInstrument) + { + MidiInstrument* oi = (MidiInstrument*)oldMidiInstrument->data(); + if(oi) + { + oi->assign(workingInstrument); + + // Now signal the rest of the app so stuff can change... + song->update(SC_CONFIG | SC_MIDI_CONTROLLER); + //song->update(SC_CONFIG | SC_MIDI_CONTROLLER | SC_MIDI_CONTROLLER_ADD); + } + } + + //f.close(); + //if (f.error()) { + if(fclose(f) != 0) + { + QString s = QString("Write File\n") + name + QString("\nfailed: ") + //+ f.errorString(); + + QString(strerror(errno)); + //fprintf(stderr, "poll failed: %s\n", strerror(errno)); + QMessageBox::critical(this, tr("MusE: Write File failed"), s); + return false; + } + return true; + } + +//--------------------------------------------------------- +// saveAs +//--------------------------------------------------------- + +void EditInstrument::saveAs() + { + // Allow these to update... + instrumentNameReturn(); + patchNameReturn(); + ctrlNameReturn(); + + //QListWidgetItem* item = instrumentList->currentItem(); +// ListBoxData* item = (ListBoxData*)instrumentList->selectedItem(); +// if (item == 0) +// return; + //MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>(); +// MidiInstrument* instrument = (MidiInstrument*)item->data(); + + //QString path = QDir::homePath() + "/" + config.instrumentPath; + //QString path = QDir::homeDirPath() + "/" + museGlobalShare; + //QString path = museInstruments; + QString path = museUserInstruments; + + if(!QDir(museUserInstruments).exists()) + { + if(QMessageBox::question(this, + tr("MusE:"), + tr("The user instrument directory\n") + museUserInstruments + tr("\ndoes not exist yet. Create it now?\n") + + tr("(You can override with the environment variable MUSEINSTRUMENTS)"), + QMessageBox::Ok | QMessageBox::Default, + QMessageBox::Cancel | QMessageBox::Escape, + Qt::NoButton) == QMessageBox::Ok) + { + if(QDir().mkdir(museUserInstruments)) + printf("Created user instrument directory: %s\n", museUserInstruments.latin1()); + else + { + printf("Unable to create user instrument directory: %s\n", museUserInstruments.latin1()); + QMessageBox::critical(this, tr("MusE:"), tr("Unable to create user instrument directory\n") + museUserInstruments); + //return; + path = museUser; + } + } + else + // return; + path = museUser; + } + + //if (instrument->filePath().isEmpty()) + if (workingInstrument.filePath().isEmpty()) + path += QString("/%1.idf").arg(workingInstrument.iname()); + else { + //QFileInfo fi(instrument->filePath()); + QFileInfo fi(workingInstrument.filePath()); + + // Prompt for a new instrument name if the name has not been changed, to avoid duplicates. + if(oldMidiInstrument) + { + MidiInstrument* oi = (MidiInstrument*)oldMidiInstrument->data(); + if(oi) + { + if(oi->iname() == workingInstrument.iname()) + { + // Prompt only if it's a user instrument, to avoid duplicates in the user instrument dir. + // This will still allow a user instrument to override a built-in instrument with the same name. + if(fi.dirPath(true) != museInstruments) + { + //QMessageBox::critical(this, + // tr("MusE: Bad instrument name"), + // tr("Please change the instrument name to a new unique name before saving, to avoid duplicates"), + // QMessageBox::Ok, + // QMessageBox::NoButton, + // QMessageBox::NoButton); + printf("EditInstrument::saveAs Error: Instrument name %s already used!\n", workingInstrument.iname().latin1()); + return; + } + } + } + } + path += QString("/%1.idf").arg(fi.baseName()); + } + //QString s = QFileDialog::getSaveFileName(this, + // tr("MusE: Save Instrument Definition"), + // path, + // tr("Instrument Definition (*.idf)")); + + QString s = Q3FileDialog::getSaveFileName(path, tr("Instrument Definition (*.idf)"), this, + tr("MusE: Save Instrument Definition").latin1()); + if (s.isEmpty()) + return; + //instrument->setFilePath(s); + workingInstrument.setFilePath(s); + + //if (fileSave(instrument, s)) + // instrument->setDirty(false); + if(fileSave(&workingInstrument, s)) + workingInstrument.setDirty(false); + } + +//--------------------------------------------------------- +// fileSaveAs +//--------------------------------------------------------- + +void EditInstrument::fileSaveAs() + { + // Is this a new unsaved instrument? Just do a normal save. + if(workingInstrument.filePath().isEmpty()) + { + saveAs(); + return; + } + + // Allow these to update... + instrumentNameReturn(); + patchNameReturn(); + ctrlNameReturn(); + + MidiInstrument* oi = 0; + if(oldMidiInstrument) + oi = (MidiInstrument*)oldMidiInstrument->data(); + + int res = checkDirty(&workingInstrument, true); + switch(res) + { + // No save: + case 1: + //item->setText(instrument->iname()); + //instrumentList->triggerUpdate(true); + //instrument->setDirty(false); + workingInstrument.setDirty(false); + if(oi) + { + oldMidiInstrument->setText(oi->iname()); + //workingInstrument.setIName(oi->iname()); + + //workingInstrument.assign(*oi); + + // No file path? Only a new unsaved instrument can do that. So delete it. + if(oi->filePath().isEmpty()) + { + // Delete the list item and the instrument. + deleteInstrument(oldMidiInstrument); + oldMidiInstrument = 0; + } + + changeInstrument(); + + instrumentList->triggerUpdate(true); + } + return; + break; + + // Abort: + case 2: + return; + break; + + // Save: + case 0: + //if(oi) + // oi->assign(workingInstrument); + workingInstrument.setDirty(false); + break; + } + + //QListWidgetItem* item = instrumentList->currentItem(); +// ListBoxData* item = (ListBoxData*)instrumentList->selectedItem(); +// if (item == 0) +// return; + //MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>(); +// MidiInstrument* instrument = (MidiInstrument*)item->data(); + + bool isuser = false; + QString so; + if(workingInstrument.iname().isEmpty()) + so = QString("Instrument"); + else + so = workingInstrument.iname(); + + for(int i = 1;; ++i) + { + QString s = so + QString("-%1").arg(i); + + bool found = false; + for(iMidiInstrument imi = midiInstruments.begin(); imi != midiInstruments.end(); ++imi) + { + if(s == (*imi)->iname()) + { + // Allow override of built-in instrument names. + QFileInfo fi((*imi)->filePath()); + if(fi.dirPath(true) == museInstruments) + break; + found = true; + break; + } + } + if(found) + continue; + + bool ok; + s = QInputDialog::getText(tr("MusE: Save instrument as"), tr("Enter a new unique instrument name:"), + QLineEdit::Normal, s, &ok, this); + if(!ok) + return; + if(s.isEmpty()) + { + --i; + continue; + } + + isuser = false; + bool builtin = false; + found = false; + for(iMidiInstrument imi = midiInstruments.begin(); imi != midiInstruments.end(); ++imi) + { + // If an instrument with the same name is found... + if((*imi)->iname() == s) + { + // If it's not the same name as the working instrument, and it's not an internal instrument (soft synth etc.)... + if(s != workingInstrument.iname() && !(*imi)->filePath().isEmpty()) + { + QFileInfo fi((*imi)->filePath()); + // Allow override of built-in and user instruments: + // If it's a user instrument, not a built-in instrument... + if(fi.dirPath(true) == museUserInstruments) + { + // No choice really but to overwrite the destination instrument file! + // Can not have two user files containing the same instrument name. + if(QMessageBox::question(this, + tr("MusE: Save instrument as"), + tr("The user instrument:\n") + s + tr("\nalready exists. This will overwrite its .idf instrument file.\nAre you sure?"), + QMessageBox::Ok | QMessageBox::Default, + QMessageBox::Cancel | QMessageBox::Escape, + Qt::NoButton) == QMessageBox::Ok) + { + // Set the working instrument's file path to the found instrument's path. + workingInstrument.setFilePath((*imi)->filePath()); + // Mark as overwriting a user instrument. + isuser = true; + } + else + { + found = true; + break; + } + } + // Assign the found instrument to the working instrument. + //workingInstrument.assign(*(*imi)); + // Assign the found instrument name to the working instrument name. + workingInstrument.setIName(s); + + // Find the instrument in the list and set the old instrument to the item. + oldMidiInstrument = (ListBoxData*)instrumentList->findItem(s, Q3ListBox::ExactMatch); + + // Mark as a built-in instrument. + builtin = true; + break; + } + found = true; + break; + } + } + if(found) + { + so = s; + i = 0; + continue; + } + + so = s; + + // If the name does not belong to a built-in instrument... + if(!builtin) + { + MidiInstrument* ni = new MidiInstrument(); + ni->assign(workingInstrument); + ni->setIName(so); + ni->setFilePath(QString()); + //midiInstruments.append(ni); + midiInstruments.push_back(ni); + //QListWidgetItem* item = new QListWidgetItem(ni->iname()); + //InstrumentListItem* item = new InstrumentListItem(ni->iname()); + //ListBoxData* item = new ListBoxData(ni->iname()); + ListBoxData* item = new ListBoxData(so); + + //oldMidiInstrument = item; + workingInstrument.assign( *ni ); + //workingInstrument.setDirty(false); + + //item->setText(ni->iname()); + item->setData((void*)ni); + //QVariant v = qVariantFromValue((void*)(ni)); + //item->setData(Qt::UserRole, v); + //instrumentList->addItem(item); + instrumentList->insertItem(item); + + oldMidiInstrument = 0; + + instrumentList->blockSignals(true); + instrumentList->setCurrentItem(item); + instrumentList->blockSignals(false); + + changeInstrument(); + + // We have our new instrument! So set dirty to true. + workingInstrument.setDirty(true); + } + + break; + } + + //QString path = QDir::homePath() + "/" + config.instrumentPath; + //QString path = QDir::homeDirPath() + "/" + museGlobalShare; + //QString path = museInstruments; + QString path = museUserInstruments; + + if(!QDir(museUserInstruments).exists()) + { + if(QMessageBox::question(this, + tr("MusE:"), + tr("The user instrument directory\n") + museUserInstruments + tr("\ndoes not exist yet. Create it now?\n") + + tr("(You can override with the environment variable MUSEINSTRUMENTS)"), + QMessageBox::Ok | QMessageBox::Default, + QMessageBox::Cancel | QMessageBox::Escape, + Qt::NoButton) == QMessageBox::Ok) + { + if(QDir().mkdir(museUserInstruments)) + printf("Created user instrument directory: %s\n", museUserInstruments.latin1()); + else + { + printf("Unable to create user instrument directory: %s\n", museUserInstruments.latin1()); + QMessageBox::critical(this, tr("MusE:"), tr("Unable to create user instrument directory\n") + museUserInstruments); + //return; + path = museUser; + } + } + else + // return; + path = museUser; + } + path += QString("/%1.idf").arg(so); + + //QString s = QFileDialog::getSaveFileName(this, + // tr("MusE: Save Instrument Definition"), + // path, + // tr("Instrument Definition (*.idf)")); + + QString sfn; + // If we are overwriting a user instrument just force the path. + if(isuser) + sfn = path; + else + { + sfn = Q3FileDialog::getSaveFileName(path, tr("Instrument Definition (*.idf)"), this, + tr("MusE: Save Instrument Definition").latin1()); + if (sfn.isEmpty()) + return; + //instrument->setFilePath(s); + workingInstrument.setFilePath(sfn); + } + + //if (fileSave(instrument, s)) + // instrument->setDirty(false); + if(fileSave(&workingInstrument, sfn)) + workingInstrument.setDirty(false); + } + +//--------------------------------------------------------- +// fileExit +//--------------------------------------------------------- + +void EditInstrument::fileExit() + { + + } + +//--------------------------------------------------------- +// closeEvent +//--------------------------------------------------------- + +void EditInstrument::closeEvent(QCloseEvent* ev) + { + // Allow these to update... + instrumentNameReturn(); + patchNameReturn(); + ctrlNameReturn(); + + //QListWidgetItem* item = instrumentList->currentItem(); + +// ListBoxData* item = (ListBoxData*)instrumentList->selectedItem(); + +// if(item) +// { + //MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>(); +// MidiInstrument* instrument = (MidiInstrument*)item->data(); +// int res = checkDirty(instrument, true); + MidiInstrument* oi = 0; + if(oldMidiInstrument) + oi = (MidiInstrument*)oldMidiInstrument->data(); + + int res = checkDirty(&workingInstrument, true); + switch(res) + { + // No save: + case 1: + //item->setText(instrument->iname()); + //instrumentList->triggerUpdate(true); + //instrument->setDirty(false); + workingInstrument.setDirty(false); + if(oi) + { + oldMidiInstrument->setText(oi->iname()); + //workingInstrument.setIName(oi->iname()); + + //workingInstrument.assign(*oi); + + // No file path? Only a new unsaved instrument can do that. So delete it. + if(oi->filePath().isEmpty()) + { + // Delete the list item and the instrument. + deleteInstrument(oldMidiInstrument); + oldMidiInstrument = 0; + } + + changeInstrument(); + + instrumentList->triggerUpdate(true); + } + break; + + // Abort: + case 2: + ev->ignore(); + return; + break; + + // Save: + case 0: + //if(oi) + // oi->assign(workingInstrument); + workingInstrument.setDirty(false); + break; + + } + +// } + + Q3MainWindow::closeEvent(ev); + } + +//--------------------------------------------------------- +// changeInstrument +//--------------------------------------------------------- + +void EditInstrument::changeInstrument() +{ + ListBoxData* sel = (ListBoxData*)instrumentList->selectedItem(); + if(!sel) + return; + + //oldMidiInstrument = (MidiInstrument*)sel->data(); + oldMidiInstrument = sel; + // Assignment + //workingInstrument = *((MidiInstrument*)sel->data()); + + // Assign will 'delete' any existing patches, groups, or controllers. + workingInstrument.assign( *((MidiInstrument*)sel->data()) ); + + workingInstrument.setDirty(false); + + // populate patch list + + patchView->clear(); + //listController->clear(); + viewController->clear(); + //category->clear(); + //sysexList->clear(); + + + //MidiInstrument* instrument = (MidiInstrument*)sel->data(Qt::UserRole).value<void*>(); + //MidiInstrument* instrument = (MidiInstrument*)sel->data(); + //instrument->setDirty(false); + + instrumentName->blockSignals(true); + //instrumentName->setText(instrument->iname()); + instrumentName->setText(workingInstrument.iname()); + instrumentName->blockSignals(false); + + nullParamSpinBoxH->blockSignals(true); + nullParamSpinBoxL->blockSignals(true); + int nv = workingInstrument.nullSendValue(); + if(nv == -1) + { + nullParamSpinBoxH->setValue(-1); + nullParamSpinBoxL->setValue(-1); + } + else + { + int nvh = (nv >> 8) & 0xff; + int nvl = nv & 0xff; + if(nvh == 0xff) + nullParamSpinBoxH->setValue(-1); + else + nullParamSpinBoxH->setValue(nvh & 0x7f); + if(nvl == 0xff) + nullParamSpinBoxL->setValue(-1); + else + nullParamSpinBoxL->setValue(nvl & 0x7f); + } + nullParamSpinBoxH->blockSignals(false); + nullParamSpinBoxL->blockSignals(false); + + //std::vector<PatchGroup>* pg = instrument->groups(); + //PatchGroupList* pg = instrument->groups(); + PatchGroupList* pg = workingInstrument.groups(); + //for (std::vector<PatchGroup>::iterator g = pg->begin(); g != pg->end(); ++g) { + for (ciPatchGroup g = pg->begin(); g != pg->end(); ++g) { + PatchGroup* pgp = *g; + if(pgp) + { + //QTreeWidgetItem* item = new QTreeWidgetItem; + ListViewData* item = new ListViewData(patchView); + + //item->setText(0, g->name); + item->setText(0, pgp->name); + + //QVariant v = QVariant::fromValue((void*)0); + //item->setData(0, Qt::UserRole, v); + //item->setData((void*)*g); + //item->setData((void*)0); + //item->setData((void*)&*g); + item->setData((void*)pgp); + //patchView->addTopLevelItem(item); + + //for (ciPatch p = g->patches.begin(); p != g->patches.end(); ++p) + for (ciPatch p = pgp->patches.begin(); p != pgp->patches.end(); ++p) + { + //const Patch& patch = *p; + Patch* patch = *p; + if(patch) + { + //QTreeWidgetItem* sitem = new QTreeWidgetItem; + ListViewData* sitem = new ListViewData(item); + //sitem->setText(0, patch.name); + //sitem->setText(0, p->name); + sitem->setText(0, patch->name); + //QVariant v = QVariant::fromValue((void*)patch); + //sitem->setData(0, Qt::UserRole, v); + //sitem->setData((void*)&*p); + sitem->setData((void*)patch); + //item->addChild(sitem); + } + } + } + } + //patchView->setSelected(patchView->item(0), true); + + oldPatchItem = 0; + + ListViewData* fc = (ListViewData*)patchView->firstChild(); + if(fc) + { + // This may cause a patchChanged call. + //if(patchView->selectedItem() != fc) + patchView->blockSignals(true); + patchView->setSelected(fc, true); + patchView->blockSignals(false); + //else + // patchChanged(); + + //patchView->firstChild()->setSelected(true); + //patchView->triggerUpdate(true); + } + + patchChanged(); + +// oldPatchItem = (ListViewData*)patchView->selectedItem(); + //patchChanged(); +// if(oldPatchItem) +// { +// if(oldPatchItem->parent()) +// patchNameEdit->setText( ((Patch*)oldPatchItem->data())->name ); +// else +// patchNameEdit->setText( ((PatchGroup*)oldPatchItem->data())->name ); +// } + + //MidiControllerList* cl = instrument->controller(); + MidiControllerList* cl = workingInstrument.controller(); + for (ciMidiController ic = cl->begin(); ic != cl->end(); ++ic) { + MidiController* c = ic->second; + //QListWidgetItem* item = new QListWidgetItem(c->name()); + // ListBoxData* item = new ListBoxData(c->name()); + //QVariant v = QVariant::fromValue((void*)c); + //item->setData(Qt::UserRole, v); + // item->setData((void*)c); + // listController->insertItem(item); + + addControllerToView(c); + } + + + //listController->setItemSelected(listController->item(0), true); + +// oldController = 0; + + //ListBoxData* ci = (ListBoxData*)listController->item(0); + ListViewData* ci = (ListViewData*)viewController->firstChild(); + + if(ci) + { + // This may cause a controllerChanged call. + //if(listController->selectedItem != ci) + // listController->blockSignals(true); + // listController->setSelected(ci, true); + // listController->blockSignals(false); + //else + // controllerChanged(); + + viewController->blockSignals(true); + viewController->setSelected(ci, true); + viewController->blockSignals(false); + } + + controllerChanged(); + + //oldController = (ListBoxData*)listController->selectedItem(); + + + //controllerChanged(listController->item(0), 0); + //controllerChanged(); + +/* + category->addItems(instrument->categories()); + + foreach(const SysEx* s, instrument->sysex()) { + QListWidgetItem* item = new QListWidgetItem(s->name); + QVariant v = QVariant::fromValue((void*)s); + item->setData(Qt::UserRole, v); + sysexList->addItem(item); + } + + sysexList->setItemSelected(sysexList->item(0), true); + sysexChanged(sysexList->item(0), 0); + + if (!cl->empty()) { + listController->setItemSelected(listController->item(0), true); + controllerChanged(listController->item(0), 0); + } +*/ + + +} + +//--------------------------------------------------------- +// instrumentChanged +//--------------------------------------------------------- + +void EditInstrument::instrumentChanged() + { + ListBoxData* sel = (ListBoxData*)instrumentList->selectedItem(); + if(!sel) + return; + + //printf("instrument changed: %s\n", sel->text().latin1()); + + //if (old) { + //if(oldMidiInstrument) + //{ + //MidiInstrument* oi = (MidiInstrument*)old->data(Qt::UserRole).value<void*>(); + MidiInstrument* oi = 0; + if(oldMidiInstrument) + oi = (MidiInstrument*)oldMidiInstrument->data(); + MidiInstrument* wip = &workingInstrument; + // Returns true if aborted. + //checkDirty(oi); + //if(checkDirty(oi)) + if(checkDirty(wip)) + { + // No save was chosen. Abandon changes, or delete if it is new... + if(oi) + { + oldMidiInstrument->setText(oi->iname()); + //wip->setText(oi->iname()); + + // No file path? Only a new unsaved instrument can do that. So delete it. + if(oi->filePath().isEmpty()) + { + // Delete the list item and the instrument. + deleteInstrument(oldMidiInstrument); + oldMidiInstrument = 0; + } + + instrumentList->triggerUpdate(true); + } + } + //else + //{ + // Save was chosen. + // if(oi) + // oi->assign(workingInstrument); + //} + + //oi->setDirty(false); + //wip->setDirty(false); + workingInstrument.setDirty(false); + //} + + changeInstrument(); + + } + +//--------------------------------------------------------- +// instrumentNameReturn +//--------------------------------------------------------- + +void EditInstrument::instrumentNameReturn() +//void EditInstrument::instrumentNameChanged(const QString& s) +{ + //instrumentNameChanged(instrumentName->text()); + ListBoxData* item = (ListBoxData*)instrumentList->selectedItem(); + if (item == 0) + return; + QString s = instrumentName->text(); + + if(s == item->text()) + return; + + MidiInstrument* curins = (MidiInstrument*)item->data(); + + for(iMidiInstrument i = midiInstruments.begin(); i != midiInstruments.end(); ++i) + { + if((*i) != curins && s == (*i)->iname()) + { + instrumentName->blockSignals(true); + // Grab the last valid name from the item text, since the instrument has not been updated yet. + //instrumentName->setText(curins->iname()); + instrumentName->setText(item->text()); + instrumentName->blockSignals(false); + + QMessageBox::critical(this, + tr("MusE: Bad instrument name"), + tr("Please choose a unique instrument name.\n(The name might be used by a hidden instrument.)"), + QMessageBox::Ok, + Qt::NoButton, + Qt::NoButton); + + return; + } + } + + //if (s != workingInstrument.iname()) { + item->setText(s); + //MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>(); + //MidiInstrument* instrument = (MidiInstrument*)item->data(); + //instrument->setDirty(true); + workingInstrument.setIName(s); + workingInstrument.setDirty(true); + //instrumentList->updateItem(item); + instrumentList->triggerUpdate(true); + //instrumentList->update(); + // } +} + +//--------------------------------------------------------- +// deleteInstrument +//--------------------------------------------------------- + +void EditInstrument::deleteInstrument(ListBoxData* item) +{ + if(!item) + return; + + //ListBoxData* curritem = (ListBoxData*)instrumentList->selectedItem(); + + MidiInstrument* ins = (MidiInstrument*)item->data(); + + // Be kind to the list item, just in case we install a delete handler or something. + //item->setData(0); + + // Delete the list item. + // Test this: Is this going to change the current selection? + instrumentList->blockSignals(true); + delete item; + instrumentList->blockSignals(false); + + // Test this: Neccessary? + // if(curritem) + // instrumentList->setCurrentItem(curritem); + + if(!ins) + return; + + // Remove the instrument from the list. + midiInstruments.remove(ins); + + // Delete the instrument. + delete ins; +} + +//--------------------------------------------------------- +// tabChanged +// Added so that patch list is updated when switching tabs, +// so that 'Program' default values and text are current in controller tab. +//--------------------------------------------------------- + +void EditInstrument::tabChanged(QWidget* w) +{ + if(!w) + return; + + // If we're switching to the Patches tab, just ignore. + if(QString(w->name()) == QString("patchesTab")) + return; + + if(oldPatchItem) + { + // Don't bother calling patchChanged, just update the patch or group. + if(oldPatchItem->parent()) + updatePatch(&workingInstrument, (Patch*)oldPatchItem->data()); + else + updatePatchGroup(&workingInstrument, (PatchGroup*)oldPatchItem->data()); + } + + // We're still on the same item. No need to set oldPatchItem as in patchChanged... + + // If we're switching to the Controller tab, update the default patch button text in case a patch changed... + if(QString(w->name()) == QString("controllerTab")) + { + ListViewData* sel = (ListViewData*)viewController->selectedItem(); + + if(!sel || !sel->data()) + return; + + MidiController* c = (MidiController*)sel->data(); + MidiController::ControllerType type = midiControllerType(c->num()); + + // Grab the controller number from the actual values showing + // and set the patch button text. + if(type == MidiController::Program) + setDefaultPatchName(getDefaultPatchNumber()); + } +} + +//--------------------------------------------------------- +// patchNameReturn +//--------------------------------------------------------- + +void EditInstrument::patchNameReturn() +{ + ListViewData* item = (ListViewData*)patchView->selectedItem(); + if (item == 0) + return; + + QString s = patchNameEdit->text(); + + if(item->text(0) == s) + return; + + PatchGroupList* pg = workingInstrument.groups(); + for(iPatchGroup g = pg->begin(); g != pg->end(); ++g) + { + PatchGroup* pgp = *g; + // If the item has a parent, it's a patch item. + if(item->parent()) + { + Patch* curp = (Patch*)item->data(); + for(iPatch p = pgp->patches.begin(); p != pgp->patches.end(); ++p) + { + if((*p) != curp && (*p)->name == s) + { + patchNameEdit->blockSignals(true); + // Grab the last valid name from the item text, since the patch has not been updated yet. + //patchNameEdit->setText(curp->name); + patchNameEdit->setText(item->text(0)); + patchNameEdit->blockSignals(false); + + QMessageBox::critical(this, + tr("MusE: Bad patch name"), + tr("Please choose a unique patch name"), + QMessageBox::Ok, + Qt::NoButton, + Qt::NoButton); + + return; + } + } + } + else + // The item has no parent. It's a patch group item. + { + PatchGroup* curpg = (PatchGroup*)item->data(); + if(pgp != curpg && pgp->name == s) + { + patchNameEdit->blockSignals(true); + // Grab the last valid name from the item text, since the patch group has not been updated yet. + //patchNameEdit->setText(curpg->name); + patchNameEdit->setText(item->text(0)); + patchNameEdit->blockSignals(false); + + QMessageBox::critical(this, + tr("MusE: Bad patchgroup name"), + tr("Please choose a unique patchgroup name"), + QMessageBox::Ok, + Qt::NoButton, + Qt::NoButton); + + return; + } + } + } + + item->setText(0, s); + workingInstrument.setDirty(true); + + // Since the name of the patch/group in the working instrument will be updated later, + // there's no need to do manually set the name here now. + /* + // If the item has a parent, it's a patch item. + if(item->parent()) + { + Patch* p = item->data(); + if(s != p->name) + { + item->setText(s); + p->name = s; + workingInstrument.setDirty(true); + //patchView->triggerUpdate(true); + } + } + else + // The item has no parent. It's a patch group item. + { + PatchGroup* pg = (PatchGroup*)item->data(); + if(s != pg->name) + { + item->setText(s); + pg->name = s; + workingInstrument.setDirty(true); + //patchView->triggerUpdate(true); + } + } + */ +} + +//--------------------------------------------------------- +// patchChanged +//--------------------------------------------------------- + +void EditInstrument::patchChanged() + { + //if (old && old->data(0, Qt::UserRole).value<void*>()) { + if(oldPatchItem) + { + //QListWidgetItem* item = instrumentList->currentItem(); + //if (item == 0) + // return; + //MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>(); + //Patch* p = (Patch*)old->data(0, Qt::UserRole).value<void*>(); + //updatePatch(instrument, p); + if(oldPatchItem->parent()) + updatePatch(&workingInstrument, (Patch*)oldPatchItem->data()); + else + updatePatchGroup(&workingInstrument, (PatchGroup*)oldPatchItem->data()); + } + + + ListViewData* sel = (ListViewData*)patchView->selectedItem(); + oldPatchItem = sel; + + if(!sel || !sel->data()) + { + patchNameEdit->setText(""); + spinBoxHBank->setEnabled(false); + spinBoxLBank->setEnabled(false); + spinBoxProgram->setEnabled(false); + checkBoxDrum->setEnabled(false); + checkBoxGM->setEnabled(false); + checkBoxGS->setEnabled(false); + checkBoxXG->setEnabled(false); + return; + } + + // If the item has a parent, it's a patch item. + if(sel->parent()) + { + Patch* p = (Patch*)sel->data(); + patchNameEdit->setText(p->name); + spinBoxHBank->setEnabled(true); + spinBoxLBank->setEnabled(true); + spinBoxProgram->setEnabled(true); + checkBoxDrum->setEnabled(true); + checkBoxGM->setEnabled(true); + checkBoxGS->setEnabled(true); + checkBoxXG->setEnabled(true); + + int hb = ((p->hbank + 1) & 0xff); + int lb = ((p->lbank + 1) & 0xff); + int pr = ((p->prog + 1) & 0xff); + spinBoxHBank->setValue(hb); + spinBoxLBank->setValue(lb); + spinBoxProgram->setValue(pr); + //checkBoxDrum->setChecked(p->drumMap); + checkBoxDrum->setChecked(p->drum); + checkBoxGM->setChecked(p->typ & 1); + checkBoxGS->setChecked(p->typ & 2); + checkBoxXG->setChecked(p->typ & 4); + //category->setCurrentIndex(p->categorie); + } + else + // The item is a patch group item. + { + patchNameEdit->setText( ((PatchGroup*)sel->data())->name ); + spinBoxHBank->setEnabled(false); + spinBoxLBank->setEnabled(false); + spinBoxProgram->setEnabled(false); + checkBoxDrum->setEnabled(false); + checkBoxGM->setEnabled(false); + checkBoxGS->setEnabled(false); + checkBoxXG->setEnabled(false); + } + } + +//--------------------------------------------------------- +// defPatchChanged +//--------------------------------------------------------- + +void EditInstrument::defPatchChanged(int) +{ + ListViewData* item = (ListViewData*)viewController->selectedItem(); + if (!item) + return; + + MidiController* c = (MidiController*)item->data(); + + int val = getDefaultPatchNumber(); + + //if(val == c->minVal() - 1) + // c->setInitVal(CTRL_VAL_UNKNOWN); + //else + c->setInitVal(val); + + setDefaultPatchName(val); + + item->setText(COL_DEF, getPatchItemText(val)); + workingInstrument.setDirty(true); +} + +//--------------------------------------------------------- +// patchButtonClicked +//--------------------------------------------------------- + +void EditInstrument::patchButtonClicked() +{ + //MidiTrack* track = (MidiTrack*)selected; + //int channel = track->outChannel(); + //int port = track->outPort(); + //MidiInstrument* instr = midiPorts[port].instrument(); + + patchpopup->clear(); + + PatchGroupList* pg = workingInstrument.groups(); + + if (pg->size() > 1) { + for (ciPatchGroup i = pg->begin(); i != pg->end(); ++i) { + PatchGroup* pgp = *i; + Q3PopupMenu* pm = new Q3PopupMenu(patchpopup); + pm->setCheckable(false); + pm->setFont(config.fonts[0]); + const PatchList& pl = pgp->patches; + for (ciPatch ipl = pl.begin(); ipl != pl.end(); ++ipl) { + const Patch* mp = *ipl; + //if ((mp->typ & mask) && + // ((drum && songType != MT_GM) || + // (mp->drum == drumchan)) ) + + // { + int id = ((mp->hbank & 0xff) << 16) + + ((mp->lbank & 0xff) << 8) + (mp->prog & 0xff); + pm->insertItem(mp->name, id); + // } + + } + patchpopup->insertItem(pgp->name, pm); + } + } + else if (pg->size() == 1 ){ + // no groups + const PatchList& pl = pg->front()->patches; + for (ciPatch ipl = pl.begin(); ipl != pl.end(); ++ipl) { + const Patch* mp = *ipl; + //if (mp->typ & mask) { + int id = ((mp->hbank & 0xff) << 16) + + ((mp->lbank & 0xff) << 8) + (mp->prog & 0xff); + patchpopup->insertItem(mp->name, id); + // } + } + } + + if(patchpopup->count() == 0) + return; + + int rv = patchpopup->exec(patchButton->mapToGlobal(QPoint(10,5))); + + if (rv != -1) + { + //if(rv != workingInstrument. + + setDefaultPatchControls(rv); + + ListViewData* item = (ListViewData*)viewController->selectedItem(); + if(item) + { + MidiController* c = (MidiController*)item->data(); + c->setInitVal(rv); + + item->setText(COL_DEF, getPatchItemText(rv)); + } + workingInstrument.setDirty(true); + } + +} + +//--------------------------------------------------------- +// addControllerToView +//--------------------------------------------------------- + +ListViewData* EditInstrument::addControllerToView(MidiController* mctrl) +{ + QString hnum; + QString lnum; + QString min; + QString max; + QString def; + int defval = mctrl->initVal(); + int n = mctrl->num(); + //int h = (n >> 7) & 0x7f; + int h = (n >> 8) & 0x7f; + int l = n & 0x7f; + if((n & 0xff) == 0xff) + l = -1; + + MidiController::ControllerType t = midiControllerType(n); + switch(t) + { + case MidiController::Controller7: + //case MidiController::RPN: + //case MidiController::NRPN: + hnum = "---"; + if(l == -1) + lnum = "*"; + else + lnum.setNum(l); + min.setNum(mctrl->minVal()); + max.setNum(mctrl->maxVal()); + if(defval == CTRL_VAL_UNKNOWN) + def = "---"; + else + def.setNum(defval); + break; + case MidiController::RPN: + case MidiController::NRPN: + case MidiController::RPN14: + case MidiController::NRPN14: + case MidiController::Controller14: + hnum.setNum(h); + if(l == -1) + lnum = "*"; + else + lnum.setNum(l); + min.setNum(mctrl->minVal()); + max.setNum(mctrl->maxVal()); + if(defval == CTRL_VAL_UNKNOWN) + def = "---"; + else + def.setNum(defval); + break; + case MidiController::Pitch: + hnum = "---"; + lnum = "---"; + min.setNum(mctrl->minVal()); + max.setNum(mctrl->maxVal()); + if(defval == CTRL_VAL_UNKNOWN) + def = "---"; + else + def.setNum(defval); + break; + case MidiController::Program: + hnum = "---"; + lnum = "---"; + min = "---"; + max = "---"; + def = getPatchItemText(defval); + break; + + default: + hnum = "---"; + lnum = "---"; + //min.setNum(0); + //max.setNum(0); + min = "---"; + max = "---"; + def = "---"; + break; + } + + ListViewData* ci = new ListViewData(viewController, mctrl->name(), int2ctrlType(t), + hnum, lnum, min, max, def); + ci->setData((void*)mctrl); + //setModified(true); + + return ci; +} + +//--------------------------------------------------------- +// controllerChanged +//--------------------------------------------------------- + +void EditInstrument::controllerChanged() + { + //if (old) { +// if(oldController) +// { + //QListWidgetItem* item = instrumentList->currentItem(); + //if (item == 0) + // return; + //MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>(); + //MidiController* oc = (MidiController*)old->data(Qt::UserRole).value<void*>(); + //updateController(instrument, oc); +// updateController(&workingInstrument, (MidiController*)oldController->data()); +// } + + // ListBoxData* sel = (ListBoxData*)listController->selectedItem(); + ListViewData* sel = (ListViewData*)viewController->selectedItem(); +// oldController = sel; + + if(!sel || !sel->data()) + { + ctrlName->blockSignals(true); + ctrlName->setText(""); + ctrlName->blockSignals(false); + //ctrlComment->setText(""); + return; + } + + //MidiController* c = (MidiController*)sel->data(Qt::UserRole).value<void*>(); + MidiController* c = (MidiController*)sel->data(); + + ctrlName->blockSignals(true); + ctrlName->setText(c->name()); + ctrlName->blockSignals(false); + + //ctrlComment->setText(c->comment()); + int ctrlH = (c->num() >> 8) & 0x7f; + int ctrlL = c->num() & 0x7f; + if((c->num() & 0xff) == 0xff) + ctrlL = -1; + + //int type = int(c->type()); + MidiController::ControllerType type = midiControllerType(c->num()); + + //ctrlType->setCurrentIndex(type); + ctrlType->blockSignals(true); + ctrlType->setCurrentItem(type); + ctrlType->blockSignals(false); + + //ctrlTypeChanged(type); + + spinBoxHCtrlNo->blockSignals(true); + spinBoxLCtrlNo->blockSignals(true); + spinBoxMin->blockSignals(true); + spinBoxMax->blockSignals(true); + spinBoxDefault->blockSignals(true); + + //ctrlTypeChanged(type); + + switch (type) { + //case MidiController::RPN: + //case MidiController::NRPN: + case MidiController::Controller7: + spinBoxHCtrlNo->setEnabled(false); + spinBoxLCtrlNo->setEnabled(true); + spinBoxHCtrlNo->setValue(0); + spinBoxLCtrlNo->setValue(ctrlL); + spinBoxMin->setEnabled(true); + spinBoxMax->setEnabled(true); + spinBoxMin->setRange(-128, 127); + spinBoxMax->setRange(-128, 127); + spinBoxMin->setValue(c->minVal()); + spinBoxMax->setValue(c->maxVal()); + enableDefaultControls(true, false); + break; + case MidiController::RPN: + case MidiController::NRPN: + spinBoxHCtrlNo->setEnabled(true); + spinBoxLCtrlNo->setEnabled(true); + spinBoxHCtrlNo->setValue(ctrlH); + spinBoxLCtrlNo->setValue(ctrlL); + spinBoxMin->setEnabled(true); + spinBoxMax->setEnabled(true); + spinBoxMin->setRange(-128, 127); + spinBoxMax->setRange(-128, 127); + spinBoxMin->setValue(c->minVal()); + spinBoxMax->setValue(c->maxVal()); + enableDefaultControls(true, false); + break; + case MidiController::Controller14: + case MidiController::RPN14: + case MidiController::NRPN14: + spinBoxHCtrlNo->setEnabled(true); + spinBoxLCtrlNo->setEnabled(true); + spinBoxHCtrlNo->setValue(ctrlH); + spinBoxLCtrlNo->setValue(ctrlL); + spinBoxMin->setEnabled(true); + spinBoxMax->setEnabled(true); + spinBoxMin->setRange(-16384, 16383); + spinBoxMax->setRange(-16384, 16383); + spinBoxMin->setValue(c->minVal()); + spinBoxMax->setValue(c->maxVal()); + enableDefaultControls(true, false); + break; + case MidiController::Pitch: + spinBoxHCtrlNo->setEnabled(false); + spinBoxLCtrlNo->setEnabled(false); + spinBoxHCtrlNo->setValue(0); + spinBoxLCtrlNo->setValue(0); + spinBoxMin->setEnabled(true); + spinBoxMax->setEnabled(true); + spinBoxMin->setRange(-8192, 8191); + spinBoxMax->setRange(-8192, 8191); + spinBoxMin->setValue(c->minVal()); + spinBoxMax->setValue(c->maxVal()); + enableDefaultControls(true, false); + break; + case MidiController::Program: + spinBoxHCtrlNo->setEnabled(false); + spinBoxLCtrlNo->setEnabled(false); + spinBoxHCtrlNo->setValue(0); + spinBoxLCtrlNo->setValue(0); + spinBoxMin->setEnabled(false); + spinBoxMax->setEnabled(false); + spinBoxMin->setRange(0, 0); + spinBoxMax->setRange(0, 0); + spinBoxMin->setValue(0); + spinBoxMax->setValue(0); + enableDefaultControls(false, true); + break; + default: + spinBoxHCtrlNo->setEnabled(false); + spinBoxLCtrlNo->setEnabled(false); + spinBoxMin->setEnabled(false); + spinBoxMax->setEnabled(false); + enableDefaultControls(false, false); + break; + } + + if(type == MidiController::Program) + { + spinBoxDefault->setRange(0, 0); + spinBoxDefault->setValue(0); + setDefaultPatchControls(c->initVal()); + } + else + { + spinBoxDefault->setRange(c->minVal() - 1, c->maxVal()); + if(c->initVal() == CTRL_VAL_UNKNOWN) + //spinBoxDefault->setValue(c->minVal() - 1); + spinBoxDefault->setValue(spinBoxDefault->minValue()); + else + spinBoxDefault->setValue(c->initVal()); + } + + //moveWithPart->setChecked(c->moveWithPart()); + + spinBoxHCtrlNo->blockSignals(false); + spinBoxLCtrlNo->blockSignals(false); + spinBoxMin->blockSignals(false); + spinBoxMax->blockSignals(false); + spinBoxDefault->blockSignals(false); + } + +//--------------------------------------------------------- +// ctrlNameReturn +//--------------------------------------------------------- + +void EditInstrument::ctrlNameReturn() +//void EditInstrument::ctrlNameChanged(const QString& s) +{ + ListViewData* item = (ListViewData*)viewController->selectedItem(); + if (item == 0) + return; + MidiController* c = (MidiController*)item->data(); + + QString cName = ctrlName->text(); + + if(c->name() == cName) + return; + + //MidiControllerList* cl = instrument->controller(); + MidiControllerList* cl = workingInstrument.controller(); + for(ciMidiController ic = cl->begin(); ic != cl->end(); ++ic) + { + MidiController* mc = ic->second; + if(mc != c && mc->name() == cName) + { + ctrlName->blockSignals(true); + ctrlName->setText(c->name()); + ctrlName->blockSignals(false); + + QMessageBox::critical(this, + tr("MusE: Bad controller name"), + tr("Please choose a unique controller name"), + QMessageBox::Ok, + Qt::NoButton, + Qt::NoButton); + + return; + } + } + + c->setName(ctrlName->text()); + item->setText(COL_NAME, ctrlName->text()); + //c->setName(s); + //item->setText(COL_NAME, s); + workingInstrument.setDirty(true); +} + +//--------------------------------------------------------- +// ctrlTypeChanged +//--------------------------------------------------------- + +void EditInstrument::ctrlTypeChanged(int idx) + { + ListViewData* item = (ListViewData*)viewController->selectedItem(); + if (item == 0) + return; + + MidiController::ControllerType t = (MidiController::ControllerType)idx; + MidiController* c = (MidiController*)item->data(); + if(t == midiControllerType(c->num())) + return; + + //if(item) + item->setText(COL_TYPE, ctrlType->currentText()); + + int hnum = 0, lnum = 0; + //int rng = 0; + //int min = 0, max = 0; + + spinBoxMin->blockSignals(true); + spinBoxMax->blockSignals(true); + spinBoxDefault->blockSignals(true); + + switch (t) { + //case MidiController::RPN: + //case MidiController::NRPN: + case MidiController::Controller7: + spinBoxHCtrlNo->setEnabled(false); + spinBoxLCtrlNo->setEnabled(true); + spinBoxMin->setEnabled(true); + spinBoxMax->setEnabled(true); + enableDefaultControls(true, false); + spinBoxMin->setRange(-128, 127); + spinBoxMax->setRange(-128, 127); + + spinBoxMin->setValue(0); + spinBoxMax->setValue(127); + spinBoxDefault->setRange(spinBoxMin->value() - 1, spinBoxMax->value()); + + spinBoxDefault->setValue(spinBoxDefault->minValue()); + lnum = spinBoxLCtrlNo->value(); + //rng = 127; + //min = -128; + //max = 127; + //if(item) + //{ + //item->setText(COL_LNUM, QString().setNum(spinBoxLCtrlNo->value())); + if(lnum == -1) + item->setText(COL_LNUM, QString("*")); + else + item->setText(COL_LNUM, QString().setNum(lnum)); + item->setText(COL_HNUM, QString("---")); + item->setText(COL_MIN, QString().setNum(spinBoxMin->value())); + item->setText(COL_MAX, QString().setNum(spinBoxMax->value())); + item->setText(COL_DEF, QString("---")); + //} + break; + case MidiController::RPN: + case MidiController::NRPN: + spinBoxHCtrlNo->setEnabled(true); + spinBoxLCtrlNo->setEnabled(true); + spinBoxMin->setEnabled(true); + spinBoxMax->setEnabled(true); + enableDefaultControls(true, false); + spinBoxMin->setRange(-128, 127); + spinBoxMax->setRange(-128, 127); + + spinBoxMin->setValue(0); + spinBoxMax->setValue(127); + spinBoxDefault->setRange(spinBoxMin->value() - 1, spinBoxMax->value()); + spinBoxDefault->setValue(spinBoxDefault->minValue()); + + hnum = spinBoxHCtrlNo->value(); + lnum = spinBoxLCtrlNo->value(); + //rng = 127; + //min = -128; + //max = 127; + //if(item) + //{ + //item->setText(COL_LNUM, QString().setNum(spinBoxLCtrlNo->value())); + //item->setText(COL_HNUM, QString().setNum(spinBoxHCtrlNo->value())); + if(lnum == -1) + item->setText(COL_LNUM, QString("*")); + else + item->setText(COL_LNUM, QString().setNum(lnum)); + item->setText(COL_HNUM, QString().setNum(hnum)); + item->setText(COL_MIN, QString().setNum(spinBoxMin->value())); + item->setText(COL_MAX, QString().setNum(spinBoxMax->value())); + item->setText(COL_DEF, QString("---")); + //} + break; + case MidiController::Controller14: + case MidiController::RPN14: + case MidiController::NRPN14: + spinBoxHCtrlNo->setEnabled(true); + spinBoxLCtrlNo->setEnabled(true); + spinBoxMin->setEnabled(true); + spinBoxMax->setEnabled(true); + enableDefaultControls(true, false); + spinBoxMin->setRange(-16384, 16383); + spinBoxMax->setRange(-16384, 16383); + + spinBoxMin->setValue(0); + spinBoxMax->setValue(16383); + spinBoxDefault->setRange(spinBoxMin->value() - 1, spinBoxMax->value()); + spinBoxDefault->setValue(spinBoxDefault->minValue()); + + hnum = spinBoxHCtrlNo->value(); + lnum = spinBoxLCtrlNo->value(); + //rng = 16383; + //min = -16384; + //max = 16383; + //if(item) + //{ + //item->setText(COL_LNUM, QString().setNum(spinBoxLCtrlNo->value())); + //item->setText(COL_HNUM, QString().setNum(spinBoxHCtrlNo->value())); + if(lnum == -1) + item->setText(COL_LNUM, QString("*")); + else + item->setText(COL_LNUM, QString().setNum(lnum)); + item->setText(COL_HNUM, QString().setNum(hnum)); + item->setText(COL_MIN, QString().setNum(spinBoxMin->value())); + item->setText(COL_MAX, QString().setNum(spinBoxMax->value())); + item->setText(COL_DEF, QString("---")); + //} + break; + case MidiController::Pitch: + spinBoxHCtrlNo->setEnabled(false); + spinBoxLCtrlNo->setEnabled(false); + spinBoxMin->setEnabled(true); + spinBoxMax->setEnabled(true); + enableDefaultControls(true, false); + spinBoxMin->setRange(-8192, 8191); + spinBoxMax->setRange(-8192, 8191); + + spinBoxMin->setValue(-8192); + spinBoxMax->setValue(8191); + spinBoxDefault->setRange(spinBoxMin->value() - 1, spinBoxMax->value()); + spinBoxDefault->setValue(spinBoxDefault->minValue()); + + //rng = 8191; + //min = -8192; + //max = 8191; + //if(item) + //{ + item->setText(COL_LNUM, QString("---")); + item->setText(COL_HNUM, QString("---")); + item->setText(COL_MIN, QString().setNum(spinBoxMin->value())); + item->setText(COL_MAX, QString().setNum(spinBoxMax->value())); + item->setText(COL_DEF, QString("---")); + //} + break; + case MidiController::Program: + spinBoxHCtrlNo->setEnabled(false); + spinBoxLCtrlNo->setEnabled(false); + spinBoxMin->setEnabled(false); + spinBoxMax->setEnabled(false); + enableDefaultControls(false, true); + spinBoxMin->setRange(0, 0); + spinBoxMax->setRange(0, 0); + + spinBoxMin->setValue(0); + spinBoxMax->setValue(0); + spinBoxDefault->setRange(0, 0); + spinBoxDefault->setValue(0); + + //if(item) + //{ + item->setText(COL_LNUM, QString("---")); + item->setText(COL_HNUM, QString("---")); + item->setText(COL_MIN, QString("---")); + item->setText(COL_MAX, QString("---")); + + //item->setText(COL_DEF, QString("0-0-0")); + item->setText(COL_DEF, QString("---")); + //} + break; + // Shouldn't happen... + default: + spinBoxHCtrlNo->setEnabled(false); + spinBoxLCtrlNo->setEnabled(false); + spinBoxMin->setEnabled(false); + spinBoxMax->setEnabled(false); + enableDefaultControls(false, false); + + spinBoxMin->blockSignals(false); + spinBoxMax->blockSignals(false); + return; + + break; + } + + spinBoxMin->blockSignals(false); + spinBoxMax->blockSignals(false); + spinBoxDefault->blockSignals(false); + + c->setNum(MidiController::genNum(t, hnum, lnum)); + + setDefaultPatchControls(0xffffff); + if(t == MidiController::Program) + { + c->setMinVal(0); + c->setMaxVal(0xffffff); + c->setInitVal(0xffffff); + } + else + { + c->setMinVal(spinBoxMin->value()); + c->setMaxVal(spinBoxMax->value()); + if(spinBoxDefault->value() == spinBoxDefault->minValue()) + c->setInitVal(CTRL_VAL_UNKNOWN); + else + c->setInitVal(spinBoxDefault->value()); + } + + + /* + + if(rng != 0) + { + int mn = c->minVal(); + int mx = c->maxVal(); + //if(val > item->text(COL_MAX).toInt()) + if(mx > max) + { + c->setMaxVal(max); + spinBoxMax->blockSignals(true); + spinBoxMax->setValue(max); + spinBoxMax->blockSignals(false); + if(item) + item->setText(COL_MAX, QString().setNum(max)); + } + //else + if(mn < min) + { + c->setMinVal(min); + spinBoxMin->blockSignals(true); + spinBoxMin->setValue(min); + spinBoxMin->blockSignals(false); + if(item) + item->setText(COL_MIN, QString().setNum(min)); + } + //else + if(mx - mn > rng) + { + //mx = val + rng; + c->setMinVal(0); + c->setMaxVal(rng); + spinBoxMin->blockSignals(true); + spinBoxMax->blockSignals(true); + spinBoxMin->setValue(0); + spinBoxMax->setValue(rng); + spinBoxMin->blockSignals(false); + spinBoxMax->blockSignals(false); + if(item) + { + item->setText(COL_MIN, QString().setNum(0)); + item->setText(COL_MAX, QString().setNum(rng)); + } + } + + spinBoxDefault->blockSignals(true); + + spinBoxDefault->setRange(spinBoxMin->value() - 1, spinBoxMax->value()); + int inval = c->initVal(); + if(inval == CTRL_VAL_UNKNOWN) + spinBoxDefault->setValue(spinBoxDefault->minValue()); + else + { + if(inval < c->minVal()) + { + c->setInitVal(c->minVal()); + spinBoxDefault->setValue(c->minVal()); + } + else + if(inval > c->maxVal()) + { + c->setInitVal(c->maxVal()); + spinBoxDefault->setValue(c->maxVal()); + } + } + + //spinBoxDefault->setRange(c->minVal() - 1, c->maxVal()); + spinBoxDefault->blockSignals(false); + + } + + */ + + workingInstrument.setDirty(true); + } + +//--------------------------------------------------------- +// ctrlHNumChanged +//--------------------------------------------------------- + +void EditInstrument::ctrlHNumChanged(int val) + { + ListViewData* item = (ListViewData*)viewController->selectedItem(); + if (item == 0) + return; + QString s; + s.setNum(val); + MidiController* c = (MidiController*)item->data(); + //int n = c->num() & 0xff; + int n = c->num() & 0x7fff00ff; + c->setNum(n | ((val & 0xff) << 8)); + item->setText(COL_HNUM, s); + workingInstrument.setDirty(true); + } + +//--------------------------------------------------------- +// ctrlLNumChanged +//--------------------------------------------------------- + +void EditInstrument::ctrlLNumChanged(int val) + { + ListViewData* item = (ListViewData*)viewController->selectedItem(); + if (item == 0) + return; + MidiController* c = (MidiController*)item->data(); + //int n = c->num() & 0xff00; + int n = c->num() & ~0xff; + c->setNum(n | (val & 0xff)); + if(val == -1) + item->setText(COL_LNUM, QString("*")); + else + { + QString s; + s.setNum(val); + item->setText(COL_LNUM, s); + } + workingInstrument.setDirty(true); + } + +//--------------------------------------------------------- +// ctrlMinChanged +//--------------------------------------------------------- + +void EditInstrument::ctrlMinChanged(int val) +{ + ListViewData* item = (ListViewData*)viewController->selectedItem(); + if (item == 0) + return; + + QString s; + s.setNum(val); + item->setText(COL_MIN, s); + + MidiController* c = (MidiController*)item->data(); + c->setMinVal(val); + + int rng = 0; + //switch((MidiController::ControllerType)ctrlType->currentItem()) + switch(midiControllerType(c->num())) + { + case MidiController::Controller7: + case MidiController::RPN: + case MidiController::NRPN: + rng = 127; + break; + case MidiController::Controller14: + case MidiController::RPN14: + case MidiController::NRPN14: + case MidiController::Pitch: + rng = 16383; + break; + default: + break; + } + + int mx = c->maxVal(); + + //if(val > item->text(COL_MAX).toInt()) + if(val > mx) + { + c->setMaxVal(val); + spinBoxMax->blockSignals(true); + spinBoxMax->setValue(val); + spinBoxMax->blockSignals(false); + item->setText(COL_MAX, s); + } + else + if(mx - val > rng) + { + mx = val + rng; + c->setMaxVal(mx); + spinBoxMax->blockSignals(true); + spinBoxMax->setValue(mx); + spinBoxMax->blockSignals(false); + item->setText(COL_MAX, QString().setNum(mx)); + } + + spinBoxDefault->blockSignals(true); + + spinBoxDefault->setRange(spinBoxMin->value() - 1, spinBoxMax->value()); + + int inval = c->initVal(); + if(inval == CTRL_VAL_UNKNOWN) + spinBoxDefault->setValue(spinBoxDefault->minValue()); + else + { + if(inval < c->minVal()) + { + c->setInitVal(c->minVal()); + spinBoxDefault->setValue(c->minVal()); + } + else + if(inval > c->maxVal()) + { + c->setInitVal(c->maxVal()); + spinBoxDefault->setValue(c->maxVal()); + } + } + + spinBoxDefault->blockSignals(false); + + workingInstrument.setDirty(true); +} + +//--------------------------------------------------------- +// ctrlMaxChanged +//--------------------------------------------------------- + +void EditInstrument::ctrlMaxChanged(int val) +{ + ListViewData* item = (ListViewData*)viewController->selectedItem(); + if (item == 0) + return; + + QString s; + s.setNum(val); + item->setText(COL_MAX, s); + + MidiController* c = (MidiController*)item->data(); + c->setMaxVal(val); + + int rng = 0; + //switch((MidiController::ControllerType)ctrlType->currentItem()) + switch(midiControllerType(c->num())) + { + case MidiController::Controller7: + case MidiController::RPN: + case MidiController::NRPN: + rng = 127; + break; + case MidiController::Controller14: + case MidiController::RPN14: + case MidiController::NRPN14: + case MidiController::Pitch: + rng = 16383; + break; + default: + break; + } + + int mn = c->minVal(); + + //if(val < item->text(COL_MIN).toInt()) + if(val < mn) + { + c->setMinVal(val); + spinBoxMin->blockSignals(true); + spinBoxMin->setValue(val); + spinBoxMin->blockSignals(false); + item->setText(COL_MIN, s); + } + else + if(val - mn > rng) + { + mn = val - rng; + c->setMinVal(mn); + spinBoxMin->blockSignals(true); + spinBoxMin->setValue(mn); + spinBoxMin->blockSignals(false); + item->setText(COL_MIN, QString().setNum(mn)); + } + + spinBoxDefault->blockSignals(true); + + spinBoxDefault->setRange(spinBoxMin->value() - 1, spinBoxMax->value()); + + int inval = c->initVal(); + if(inval == CTRL_VAL_UNKNOWN) + spinBoxDefault->setValue(spinBoxDefault->minValue()); + else + { + if(inval < c->minVal()) + { + c->setInitVal(c->minVal()); + spinBoxDefault->setValue(c->minVal()); + } + else + if(inval > c->maxVal()) + { + c->setInitVal(c->maxVal()); + spinBoxDefault->setValue(c->maxVal()); + } + } + + spinBoxDefault->blockSignals(false); + + workingInstrument.setDirty(true); +} + +//--------------------------------------------------------- +// ctrlDefaultChanged +//--------------------------------------------------------- + +void EditInstrument::ctrlDefaultChanged(int val) +{ + ListViewData* item = (ListViewData*)viewController->selectedItem(); + if (item == 0) + return; + + MidiController* c = (MidiController*)item->data(); + + if(val == c->minVal() - 1) + { + c->setInitVal(CTRL_VAL_UNKNOWN); + item->setText(COL_DEF, QString("---")); + } + else + { + c->setInitVal(val); + item->setText(COL_DEF, QString().setNum(val)); + } + workingInstrument.setDirty(true); +} + +//--------------------------------------------------------- +// ctrlNullParamHChanged +//--------------------------------------------------------- + +void EditInstrument::ctrlNullParamHChanged(int nvh) +{ + int nvl = nullParamSpinBoxL->value(); + if(nvh == -1) + { + nullParamSpinBoxL->blockSignals(true); + nullParamSpinBoxL->setValue(-1); + nullParamSpinBoxL->blockSignals(false); + nvl = -1; + } + else + { + if(nvl == -1) + { + nullParamSpinBoxL->blockSignals(true); + nullParamSpinBoxL->setValue(0); + nullParamSpinBoxL->blockSignals(false); + nvl = 0; + } + } + if(nvh == -1 && nvl == -1) + workingInstrument.setNullSendValue(-1); + else + workingInstrument.setNullSendValue((nvh << 8) | nvl); + workingInstrument.setDirty(true); +} + +//--------------------------------------------------------- +// ctrlNullParamLChanged +//--------------------------------------------------------- + +void EditInstrument::ctrlNullParamLChanged(int nvl) +{ + int nvh = nullParamSpinBoxH->value(); + if(nvl == -1) + { + nullParamSpinBoxH->blockSignals(true); + nullParamSpinBoxH->setValue(-1); + nullParamSpinBoxH->blockSignals(false); + nvh = -1; + } + else + { + if(nvh == -1) + { + nullParamSpinBoxH->blockSignals(true); + nullParamSpinBoxH->setValue(0); + nullParamSpinBoxH->blockSignals(false); + nvh = 0; + } + } + if(nvh == -1 && nvl == -1) + workingInstrument.setNullSendValue(-1); + else + workingInstrument.setNullSendValue((nvh << 8) | nvl); + workingInstrument.setDirty(true); +} + +//--------------------------------------------------------- +// deletePatchClicked +//--------------------------------------------------------- + +void EditInstrument::deletePatchClicked() + { + //QListWidgetItem* item = instrumentList->currentItem(); +// ListBoxData* item = (ListBoxData*)instrumentList->selectedItem(); +// if (item == 0) +// return; + //MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>(); +// MidiInstrument* instrument = (MidiInstrument*)item->data(); + //QTreeWidgetItem* pi = patchView->currentItem(); + ListViewData* pi = (ListViewData*)patchView->selectedItem(); + if (pi == 0) + return; + + //void* p = pi->data(0, Qt::UserRole).value<void*>(); +// Patch* patch = (Patch*)pi->data(); + //if (p == 0) + // If patch is zero it's a patch group. +// if(patch == 0) + + // If the item has a parent item, it's a patch item... + if(pi->parent()) + { + PatchGroup* group = (PatchGroup*)((ListViewData*)pi->parent())->data(); + + // If there is an allocated patch in the data, delete it. + //Patch* patch = (Patch*)pi->auxData(); + Patch* patch = (Patch*)pi->data(); + if(patch) + { + if(group) + { + //for(iPatch ip = group->patches.begin(); ip != group->patches.end(); ++ip) + // if(&*ip == patch) + // if(*ip == patch) + // { + // + // printf("deletePatchClicked: erasing patch\n"); + // + // group->patches.erase(ip); + // break; + // } + //group->patches.remove( (const Patch&)(*patch) ); + group->patches.remove(patch); + } + delete patch; + } + } + else + // The item has no parent item, it's a patch group item... + { + // Is there an allocated patch group in the data? + //PatchGroup* group = (PatchGroup*)pi->auxData(); + PatchGroup* group = (PatchGroup*)pi->data(); + if(group) + { + + PatchGroupList* pg = workingInstrument.groups(); + //for(ciPatchGroup ipg = pg->begin(); ipg != pg->end(); ++ipg) + for(iPatchGroup ipg = pg->begin(); ipg != pg->end(); ++ipg) + { + + //printf("deletePatchClicked: working patch group name:%s ad:%X group name:%s ad:%X\n", (*ipg)->name.latin1(), (unsigned int)(*ipg), group->name.latin1(), (unsigned int) group); + + //if(&*ipg == group) + if(*ipg == group) + { + pg->erase(ipg); + break; + } + } + + // Iterate all child list view (patch) items. Find and delete any allocated patches in the items' data. +// for(ListViewData* i = (ListViewData*)pi->firstChild(); i; i = (ListViewData*)i->nextSibling()) +// { + //Patch* patch = (Patch*)i->auxData(); +// Patch* patch = (Patch*)i->data(); +// if(patch) +// { + //delete patch; + //group->patches.remove(*patch); + const PatchList& pl = group->patches; + for(ciPatch ip = pl.begin(); ip != pl.end(); ++ip) + { +// if(&*ip == patch) +// { +// group->patches.erase(ip); +// break; +// } + + // Delete the patch. + if(*ip) + delete *ip; + } + + //group->patches.clear(); + +// } +// } + + // Now delete the group. + delete group; + + } + } + + //oldPatchItem = (ListViewData*)patchView->selectedItem(); + //oldPatchItem = 0; + + // Now delete the patch or group item (and any child patch items) from the list view tree. + // !!! This will trigger a patchChanged call. + patchView->blockSignals(true); + delete pi; + if(patchView->currentItem()) + patchView->setSelected(patchView->currentItem(), true); + patchView->blockSignals(false); + + oldPatchItem = 0; + patchChanged(); + + //Patch* patch = (Patch*)p; + + //std::vector<PatchGroup>* pg = instrument->groups(); + //for (std::vector<PatchGroup>::iterator g = pg->begin(); g != pg->end(); ++g) { + // for (iPatch p = g->patches.begin(); p != g->patches.end(); ++p) { + // if (patch == *p) { + // g->patches.erase(p); + // delete pi; + // instrument->setDirty(true); + // return; + // } + // } + // } + //printf("fatal: patch not found\n"); + //delete patch; + //delete pi; + + + workingInstrument.setDirty(true); + } + +//--------------------------------------------------------- +// newPatchClicked +//--------------------------------------------------------- + +void EditInstrument::newPatchClicked() + { + //QListWidgetItem* item = instrumentList->currentItem(); +// ListBoxData* item = (ListBoxData*)instrumentList->selectedItem(); +// if (item == 0) +// return; + + if(oldPatchItem) + { + if(oldPatchItem->parent()) + updatePatch(&workingInstrument, (Patch*)oldPatchItem->data()); + else + updatePatchGroup(&workingInstrument, (PatchGroup*)oldPatchItem->data()); + } + + //MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>(); +// MidiInstrument* instrument = (MidiInstrument*)item->data(); + //std::vector<PatchGroup>* pg = instrument->groups(); +// PatchGroupList* pg = instrument->groups(); + PatchGroupList* pg = workingInstrument.groups(); + QString patchName; + for (int i = 1;; ++i) { + patchName = QString("Patch-%1").arg(i); + bool found = false; + + //for (std::vector<PatchGroup>::iterator g = pg->begin(); g != pg->end(); ++g) { + for (iPatchGroup g = pg->begin(); g != pg->end(); ++g) { + PatchGroup* pgp = *g; + //for (iPatch p = g->patches.begin(); p != g->patches.end(); ++p) { + for (iPatch p = pgp->patches.begin(); p != pgp->patches.end(); ++p) { + //if (p->name == patchName) { + if ((*p)->name == patchName) { + found = true; + break; + } + } + if (found) + break; + } + if (!found) + break; + } + + // + // search current patch group + // + //PatchGroup* pGroup = 0; + //QTreeWidgetItem* pi = patchView->currentItem(); + ListViewData* pi = (ListViewData*)patchView->selectedItem(); + if (pi == 0) + return; + + // If there is data then pi is a patch item, and there must be a parent patch group item (with null data). + //if (pi->data(0, Qt::UserRole).value<void*>()) + //if (pi->data()) + + Patch* selpatch = 0; + + // If there is a parent item then pi is a patch item, and there must be a parent patch group item. + if(pi->parent()) + { + // Remember the current selected patch. + selpatch = (Patch*)pi->data(); + + pi = (ListViewData*)pi->parent(); + } + + PatchGroup* group = (PatchGroup*)pi->data(); + if(!group) + return; + + //for (std::vector<PatchGroup>::iterator g = pg->begin(); g != pg->end(); ++g) { +// for (ciPatchGroup g = pg->begin(); g != pg->end(); ++g) { +// if (g->name == pi->text(0)) { +// pGroup = &*g; +// break; +// } +// } +// if (pGroup == 0) { +// printf("group not found\n"); +// return; +// } + + // Create a new Patch, then store its pointer in a new patch item, + // to be added later to the patch group only upon save... + //Patch patch; + //patch.name = patchName; + Patch* patch = new Patch; + int hb = -1; + int lb = -1; + int prg = 0; + patch->hbank = hb; + patch->lbank = lb; + patch->prog = prg; + patch->typ = -1; + patch->drum = false; + + if(selpatch) + { + hb = selpatch->hbank; + lb = selpatch->lbank; + prg = selpatch->prog; + patch->typ = selpatch->typ; + patch->drum = selpatch->drum; + } + + bool found = false; + + // The 129 is to accommodate -1 values. Yes, it may cause one extra redundant loop but hey, + // if it hasn't found an available patch number by then, another loop won't matter. + for(int k = 0; k < 129; ++k) + { + for(int j = 0; j < 129; ++j) + { + for(int i = 0; i < 128; ++i) + { + found = false; + + for(iPatchGroup g = pg->begin(); g != pg->end(); ++g) + { + PatchGroup* pgp = *g; + for(iPatch ip = pgp->patches.begin(); ip != pgp->patches.end(); ++ip) + { + Patch* p = *ip; + if((p->prog == ((prg + i) & 0x7f)) && + ((p->lbank == -1 && lb == -1) || (p->lbank == ((lb + j) & 0x7f))) && + ((p->hbank == -1 && hb == -1) || (p->hbank == ((hb + k) & 0x7f)))) + { + found = true; + break; + } + } + if(found) + break; + } + + if(!found) + { + patch->prog = (prg + i) & 0x7f; + if(lb == -1) + patch->lbank = -1; + else + patch->lbank = (lb + j) & 0x7f; + + if(hb == -1) + patch->hbank = -1; + else + patch->hbank = (hb + k) & 0x7f; + + //patch->typ = selpatch->typ; + //patch->drum = selpatch->drum; + break; + } + + } + if(!found) + break; + } + if(!found) + break; + } + + patch->name = patchName; + + group->patches.push_back(patch); + //Patch* pp = &(group->patches.back()); + + //QTreeWidgetItem* sitem = new QTreeWidgetItem; + ListViewData* sitem = new ListViewData(pi); + //sitem->setText(0, patch->name); + sitem->setText(0, patchName); + + patchNameEdit->setText(patchName); + + //QVariant v = QVariant::fromValue((void*)(patch)); + //sitem->setData(0, Qt::UserRole, v); + + // Set the list view item's data. + sitem->setData((void*)patch); + //sitem->setAuxData((void*)patch); + //sitem->setData((void*)pp); + + //pi->addChild(sitem); + + //printf("newPatchClicked: before patchView->setCurrentItem\n"); + + //patchView->setCurrentItem(sitem); + + //printf("newPatchClicked: after patchView->setCurrentItem\n"); + + //oldPatchItem = 0; + + // May cause patchChanged call. + patchView->blockSignals(true); + patchView->setSelected(sitem, true); + patchView->ensureItemVisible(sitem); + patchView->blockSignals(false); + + //oldPatchItem = (ListViewData*)patchView->selectedItem(); + //oldPatchItem = sitem; + //oldPatchItem = 0; + + spinBoxHBank->setEnabled(true); + spinBoxLBank->setEnabled(true); + spinBoxProgram->setEnabled(true); + checkBoxDrum->setEnabled(true); + checkBoxGM->setEnabled(true); + checkBoxGS->setEnabled(true); + checkBoxXG->setEnabled(true); + + oldPatchItem = 0; + patchChanged(); + + //instrument->setDirty(true); + workingInstrument.setDirty(true); + } + +//--------------------------------------------------------- +// newGroupClicked +//--------------------------------------------------------- + +void EditInstrument::newGroupClicked() + { + //QListWidgetItem* item = instrumentList->currentItem(); +// ListBoxData* item = (ListBoxData*)instrumentList->selectedItem(); +// if (item == 0) +// return; + + if(oldPatchItem) + { + if(oldPatchItem->parent()) + updatePatch(&workingInstrument, (Patch*)oldPatchItem->data()); + else + updatePatchGroup(&workingInstrument, (PatchGroup*)oldPatchItem->data()); + } + + //MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>(); +// MidiInstrument* instrument = (MidiInstrument*)item->data(); + //std::vector<PatchGroup>* pg = instrument->groups(); +// PatchGroupList* pg = instrument->groups(); + PatchGroupList* pg = workingInstrument.groups(); + QString groupName; + for (int i = 1;; ++i) { + groupName = QString("Group-%1").arg(i); + bool found = false; + + //for (std::vector<PatchGroup>::iterator g = pg->begin(); g != pg->end(); ++g) { + for (ciPatchGroup g = pg->begin(); g != pg->end(); ++g) { + //if (g->name == groupName) { + if ((*g)->name == groupName) { + found = true; + break; + } + } + if (!found) + break; + } + + // Create a new PatchGroup, then store its pointer in a new patch group item, + // to be added later to the instrument only upon save... + PatchGroup* group = new PatchGroup; + group->name = groupName; + //PatchGroup group; + //group.name = groupName; + + pg->push_back(group); + //PatchGroup* pgp = &(pg->back()); + + //QTreeWidgetItem* sitem = new QTreeWidgetItem; + ListViewData* sitem = new ListViewData(patchView); + sitem->setText(0, groupName); + + patchNameEdit->setText(groupName); + + //QVariant v = QVariant::fromValue((void*)0); + //sitem->setData(0, Qt::UserRole, v); + //sitem->setData((void*)0); + + // Set the list view item's data. + sitem->setData((void*)group); + //sitem->setAuxData((void*)pgp); + + //patchView->addTopLevelItem(sitem); + //patchView->setCurrentItem(sitem); + + //oldPatchItem = 0; + + // May cause patchChanged call. + patchView->blockSignals(true); + patchView->setSelected(sitem, true); + patchView->blockSignals(false); + + //oldPatchItem = (ListViewData*)patchView->selectedItem(); + oldPatchItem = sitem; + //oldPatchItem = 0; + //patchChanged(); + + spinBoxHBank->setEnabled(false); + spinBoxLBank->setEnabled(false); + spinBoxProgram->setEnabled(false); + checkBoxDrum->setEnabled(false); + checkBoxGM->setEnabled(false); + checkBoxGS->setEnabled(false); + checkBoxXG->setEnabled(false); + + //instrument->setDirty(true); + workingInstrument.setDirty(true); + } + +//--------------------------------------------------------- +// deleteControllerClicked +//--------------------------------------------------------- + +void EditInstrument::deleteControllerClicked() + { + //QListWidgetItem* item = instrumentList->currentItem(); + //ListBoxData* item = (ListBoxData*)instrumentList->selectedItem(); + //QListWidgetItem* item2 = listController->currentItem(); +// ListBoxData* item = (ListBoxData*)listController->selectedItem(); + ListViewData* item = (ListViewData*)viewController->selectedItem(); + + //if (item == 0 || item2 == 0) + if(!item) + return; + //MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>(); +// MidiInstrument* instrument = (MidiInstrument*)item->data(); + //MidiController* ctrl = (MidiController*)item2->data(Qt::UserRole).value<void*>(); + //MidiController* ctrl = (MidiController*)item2->data(); + //MidiControllerList* cl = instrument->controller(); + //cl->removeAll(ctrl); + + MidiController* ctrl = (MidiController*)item->data(); + if(!ctrl) + return; + + workingInstrument.controller()->erase(ctrl->num()); + // Now delete the controller. + delete ctrl; + + // Now remove the controller item from the list. + // This may cause a controllerChanged call. +// listController->blockSignals(true); + viewController->blockSignals(true); + delete item; + if(viewController->currentItem()) + viewController->setSelected(viewController->currentItem(), true); +// listController->blockSignals(false); + viewController->blockSignals(false); + + //oldController = (ListBoxData*)listController->selectedItem(); +// oldController = 0; + + controllerChanged(); + + //instrument->setDirty(true); + workingInstrument.setDirty(true); + } + +//--------------------------------------------------------- +// newControllerClicked +//--------------------------------------------------------- + +void EditInstrument::newControllerClicked() + { + //QListWidgetItem* item = instrumentList->currentItem(); + //if (item == 0) + // return; + //MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>(); + +// if(oldController) +// updateController(&workingInstrument, (MidiController*)oldController->data()); + + QString cName; + //MidiControllerList* cl = instrument->controller(); + MidiControllerList* cl = workingInstrument.controller(); + for (int i = 1;; ++i) { + //ctrlName = QString("Controller-%d").arg(i); + cName = QString("Controller-%1").arg(i); + bool found = false; + for (iMidiController ic = cl->begin(); ic != cl->end(); ++ic) { + MidiController* c = ic->second; + if (c->name() == cName) { + found = true; + break; + } + } + if (!found) + break; + } + + MidiController* ctrl = new MidiController(); + ctrl->setNum(CTRL_MODULATION); + ctrl->setMinVal(0); + ctrl->setMaxVal(127); + ctrl->setInitVal(CTRL_VAL_UNKNOWN); + + ListViewData* ci = (ListViewData*)viewController->selectedItem(); + + // To allow for quick multiple successive controller creation. + // If there's a current controller item selected, copy initial values from it. + bool found = false; + if(ci) + { + MidiController* selctl = (MidiController*)ci->data(); + // Assign. + // *ctrl = *selctl; + + // Auto increment controller number. + //int l = ctrl->num() & 0x7f; + //int h = ctrl->num() & 0xffffff00; + int l = selctl->num() & 0x7f; + int h = selctl->num() & 0xffffff00; + + // Ignore internal controllers and wild cards. + //if(((h & 0xff0000) != 0x40000) && ((ctrl->num() & 0xff) != 0xff)) + if(((h & 0xff0000) != 0x40000) && ((selctl->num() & 0xff) != 0xff)) + { + // Assign. + *ctrl = *selctl; + + for (int i = 1; i < 128; ++i) + { + //ctrlName = QString("Controller-%d").arg(i); + //cName = QString("Controller-%1").arg(i); + int j = ((i + l) & 0x7f) | h; + found = false; + for (iMidiController ic = cl->begin(); ic != cl->end(); ++ic) + { + MidiController* c = ic->second; + if(c->num() == j) + { + found = true; + break; + } + } + if(!found) + { + ctrl->setNum(j); + break; + } + } + } + } + + ctrl->setName(cName); + + //item = new QListWidgetItem(ctrlName); +// ListBoxData* item = new ListBoxData(ctrlName); + + //QVariant v = qVariantFromValue((void*)(ctrl)); + //item->setData(Qt::UserRole, v); +// item->setData((void*)ctrl); + //listController->addItem(item); +// listController->insertItem(item); + //listController->setCurrentItem(item); + + workingInstrument.controller()->add(ctrl); + ListViewData* item = addControllerToView(ctrl); + +// listController->blockSignals(true); +// listController->setSelected(item, true); +// listController->blockSignals(false); + viewController->blockSignals(true); + viewController->setSelected(item, true); + viewController->blockSignals(false); + + //oldController = (ListBoxData*)listController->selectedItem(); +// oldController = item; + //oldController = 0; + // MidiController is a class, with itialized values. We have to call this to show the values. + // To make multiple entries easier, don't bother calling this. + controllerChanged(); + + //instrument->setDirty(true); + workingInstrument.setDirty(true); + } + +//--------------------------------------------------------- +// addControllerClicked +//--------------------------------------------------------- + +void EditInstrument::addControllerClicked() +{ + //int lnum = listController->currentItem(); + //if(lnum == -1) + // return; + + //QString name = midiCtrlName(lnum); + + int idx = listController->currentItem(); + if(idx == -1) + return; + + int lnum = -1; + QString name = listController->currentText(); + for(int i = 0; i < 128; i++) + { + if(midiCtrlName(i) == name) + { + lnum = i; + break; + } + } + if(lnum == -1) + { + printf("Add controller: Controller not found: %s\n", name.latin1()); + return; + } + + int num = MidiController::genNum(MidiController::Controller7, 0, lnum); + + MidiControllerList* cl = workingInstrument.controller(); + for(iMidiController ic = cl->begin(); ic != cl->end(); ++ic) + { + MidiController* c = ic->second; + if(c->name() == name) + { + QMessageBox::critical(this, + tr("MusE: Cannot add common controller"), + tr("A controller named ") + name + tr(" already exists."), + QMessageBox::Ok, + Qt::NoButton, + Qt::NoButton); + + return; + } + + if(c->num() == num) + { + QMessageBox::critical(this, + tr("MusE: Cannot add common controller"), + tr("A controller number ") + QString().setNum(num) + tr(" already exists."), + QMessageBox::Ok, + Qt::NoButton, + Qt::NoButton); + + return; + } + } + + MidiController* ctrl = new MidiController(); + ctrl->setNum(num); + ctrl->setMinVal(0); + ctrl->setMaxVal(127); + ctrl->setInitVal(CTRL_VAL_UNKNOWN); + ctrl->setName(name); + + workingInstrument.controller()->add(ctrl); + + ListViewData* item = addControllerToView(ctrl); + + viewController->blockSignals(true); + viewController->setSelected(item, true); + viewController->blockSignals(false); + + controllerChanged(); + + workingInstrument.setDirty(true); +} + +/* +//--------------------------------------------------------- +// deleteSysexClicked +//--------------------------------------------------------- + +void EditInstrument::deleteSysexClicked() + { + //QListWidgetItem* item = instrumentList->currentItem(); + //QListWidgetItem* item2 = sysexList->currentItem(); + //if (item == 0 || item2 == 0) + // return; + + //MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>(); + //SysEx* sysex = (SysEx*)item2->data(Qt::UserRole).value<void*>(); + //QList<SysEx*> sl = instrument->sysex(); + //instrument->removeSysex(sysex); + //delete item2; + //instrument->setDirty(true); + + + + ListBoxData* item = (ListBoxData*)sysexList->selectedItem(); + if(!item) + return; + + EventList* el = (EventList*)item->data(); + if(!el) + return; + + } +*/ + +//--------------------------------------------------------- +// updatePatchGroup +//--------------------------------------------------------- + +void EditInstrument::updatePatchGroup(MidiInstrument* instrument, PatchGroup* pg) + { + if (pg->name != patchNameEdit->text()) { + pg->name = patchNameEdit->text(); + instrument->setDirty(true); + } + } + +//--------------------------------------------------------- +// updatePatch +//--------------------------------------------------------- + +void EditInstrument::updatePatch(MidiInstrument* instrument, Patch* p) + { + if (p->name != patchNameEdit->text()) { + p->name = patchNameEdit->text(); + instrument->setDirty(true); + } + + signed char hb = (spinBoxHBank->value() - 1) & 0xff; + //if (p->hbank != (spinBoxHBank->value() & 0xff)) { + // p->hbank = spinBoxHBank->value() & 0xff; + if (p->hbank != hb) { + p->hbank = hb; + + instrument->setDirty(true); + } + + signed char lb = (spinBoxLBank->value() - 1) & 0xff; + //if (p->lbank != (spinBoxLBank->value() & 0xff)) { + // p->lbank = spinBoxLBank->value() & 0xff; + if (p->lbank != lb) { + p->lbank = lb; + + instrument->setDirty(true); + } + + signed char pr = (spinBoxProgram->value() - 1) & 0xff; + if (p->prog != pr) { + p->prog = pr; + + instrument->setDirty(true); + } + + if (p->drum != checkBoxDrum->isChecked()) { + p->drum = checkBoxDrum->isChecked(); + instrument->setDirty(true); + } + + // there is no logical xor in c++ + bool a = p->typ & 1; + bool b = p->typ & 2; + bool c = p->typ & 4; + bool aa = checkBoxGM->isChecked(); + bool bb = checkBoxGS->isChecked(); + bool cc = checkBoxXG->isChecked(); + if ((a ^ aa) || (b ^ bb) || (c ^ cc)) { + int value = 0; + if (checkBoxGM->isChecked()) + value |= 1; + if (checkBoxGS->isChecked()) + value |= 2; + if (checkBoxXG->isChecked()) + value |= 4; + p->typ = value; + instrument->setDirty(true); + } + + //if (p->categorie != category->currentIndex()) { + // p->categorie = category->currentIndex(); + // instrument->setDirty(true); + // } + } + +/* +//--------------------------------------------------------- +// updateController +//--------------------------------------------------------- + +void EditInstrument::updateController(MidiInstrument* instrument, MidiController* oc) + { + printf("updateController: A\n"); + + int ctrlH = spinBoxHCtrlNo->value(); + int ctrlL = spinBoxLCtrlNo->value(); + //MidiController::ControllerType type = (MidiController::ControllerType)ctrlType->currentIndex(); + MidiController::ControllerType type = (MidiController::ControllerType)ctrlType->currentItem(); + int num = MidiController::genNum(type, ctrlH, ctrlL); + //int num = (ctrlH << 8) & 0x7f + ctrlL & 0x7f; + + printf("updateController: B\n"); + + if (num != oc->num()) { + + printf("updateController: num changed, setting dirty. num:%d c->num:%d\n", num, oc->num()); + + oc->setNum(num); + instrument->setDirty(true); + } + + if(type != MidiController::Pitch && type != MidiController::Program) + { + if (spinBoxMin->value() != oc->minVal()) { + + printf("updateController: min changed, setting dirty. min:%d c->min:%d\n", spinBoxMin->value(), oc->minVal()); + + oc->setMinVal(spinBoxMin->value()); + instrument->setDirty(true); + } + if (spinBoxMax->value() != oc->maxVal()) { + + printf("updateController: max changed, setting dirty. num:%d max:%d c->max:%d\n", num, spinBoxMax->value(), oc->maxVal()); + + oc->setMaxVal(spinBoxMax->value()); + instrument->setDirty(true); + } + + int dv = spinBoxDefault->value(); + if(dv == oc->minVal() - 1) + dv = CTRL_VAL_UNKNOWN; + + //if (spinBoxDefault->value() != oc->initVal()) { + if(dv != oc->initVal()) { + //oc->setInitVal(spinBoxDefault->value()); + oc->setInitVal(dv); + + printf("updateController: default changed, setting dirty. def:%d c->init:%d\n", dv, oc->initVal()); + + instrument->setDirty(true); + } + } + + + printf("updateController: C\n"); + + //if (moveWithPart->isChecked() ^ oc->moveWithPart()) { + // oc->setMoveWithPart(moveWithPart->isChecked()); + // instrument->setDirty(true); + // } + if (ctrlName->text() != oc->name()) { + oc->setName(ctrlName->text()); + + printf("updateController: name changed, setting dirty. name:%s c->name:%s\n", ctrlName->text().latin1(), oc->name().latin1()); + + instrument->setDirty(true); + } + //if (ctrlComment->toPlainText() != oc->comment()) { + // oc->setComment(ctrlComment->toPlainText()); + // instrument->setDirty(true); + // } + + printf("updateController: D\n"); + + } +*/ + +//--------------------------------------------------------- +// updateInstrument +//--------------------------------------------------------- + +void EditInstrument::updateInstrument(MidiInstrument* instrument) + { + //QListWidgetItem* sysexItem = sysexList->currentItem(); + //ListBoxData* sysexItem = sysexList->currentItem(); + //if (sysexItem) { + // SysEx* so = (SysEx*)sysexItem->data(Qt::UserRole).value<void*>(); + // updateSysex(instrument, so); + // } + + //QListWidgetItem* ctrlItem = listController->currentItem(); + //ListBoxData* ctrlItem = (ListBoxData*)listController->currentItem(); + //ListBoxData* ctrlItem = (ListBoxData*)listController->selectedItem(); +// ListViewData* ctrlItem = (ListViewData*)viewController->selectedItem(); + +// if (ctrlItem) { + //MidiController* ctrl = (MidiController*)ctrlItem->data(Qt::UserRole).value<void*>(); + +// printf("updateInstrument: AB\n"); + +// MidiController* ctrl = (MidiController*)ctrlItem->data(); + +// printf("updateInstrument: AC\n"); + +// updateController(instrument, ctrl); +// } + +// printf("updateInstrument: B\n"); + + //QTreeWidgetItem* patchItem = patchView->currentItem(); + ListViewData* patchItem = (ListViewData*)patchView->selectedItem(); + if (patchItem) + { + //Patch* p = (Patch*)patchItem->data(0, Qt::UserRole).value<void*>(); + + // If the item has a parent, it's a patch item. + if(patchItem->parent()) + updatePatch(instrument, (Patch*)patchItem->data()); + else + updatePatchGroup(instrument, (PatchGroup*)patchItem->data()); + + } + } + +//--------------------------------------------------------- +// checkDirty +// return true on Abort +//--------------------------------------------------------- + +int EditInstrument::checkDirty(MidiInstrument* i, bool isClose) + { + updateInstrument(i); + if (!i->dirty()) + //return false; + return 0; + int n; + if(isClose) + n = QMessageBox::warning(this, tr("MusE"), + tr("The current Instrument contains unsaved data\n" + "Save Current Instrument?"), + tr("&Save"), tr("&Nosave"), tr("&Abort"), 0, 2); + else + n = QMessageBox::warning(this, tr("MusE"), + tr("The current Instrument contains unsaved data\n" + "Save Current Instrument?"), + tr("&Save"), tr("&Nosave"), 0, 1); + if (n == 0) { + if (i->filePath().isEmpty()) + { + //fileSaveAs(); + saveAs(); + } + else { + //QFile f(i->filePath()); + //if (!f.open(QIODevice::WriteOnly)) + FILE* f = fopen(i->filePath().latin1(), "w"); + if(f == 0) + //fileSaveAs(); + saveAs(); + else { + //f.close(); + if(fclose(f) != 0) + printf("EditInstrument::checkDirty: Error closing file\n"); + + if(fileSave(i, i->filePath())) + i->setDirty(false); + } + } + //return false; + return 0; + } + //return n == 2; + return n; + } + +//--------------------------------------------------------- +// getPatchItemText +//--------------------------------------------------------- + +QString EditInstrument::getPatchItemText(int val) +{ + QString s; + if(val == CTRL_VAL_UNKNOWN) + s = "---"; + else + { + int hb = ((val >> 16) & 0xff) + 1; + if (hb == 0x100) + hb = 0; + int lb = ((val >> 8) & 0xff) + 1; + if (lb == 0x100) + lb = 0; + int pr = (val & 0xff) + 1; + if (pr == 0x100) + pr = 0; + s.sprintf("%d-%d-%d", hb, lb, pr); + } + + return s; +} + +//--------------------------------------------------------- +// enableDefaultControls +//--------------------------------------------------------- + +void EditInstrument::enableDefaultControls(bool enVal, bool enPatch) +{ + spinBoxDefault->setEnabled(enVal); + patchButton->setEnabled(enPatch); + if(!enPatch) + { + patchButton->blockSignals(true); + patchButton->setText("---"); + patchButton->blockSignals(false); + } + defPatchH->setEnabled(enPatch); + defPatchL->setEnabled(enPatch); + defPatchProg->setEnabled(enPatch); +} + +//--------------------------------------------------------- +// setDefaultPatchName +//--------------------------------------------------------- + +void EditInstrument::setDefaultPatchName(int val) +{ + const char* patchname = getPatchName(val); + patchButton->blockSignals(true); + patchButton->setText(QString(patchname)); + patchButton->blockSignals(false); +} + +//--------------------------------------------------------- +// getDefaultPatchNumber +//--------------------------------------------------------- + +int EditInstrument::getDefaultPatchNumber() +{ + int hval = defPatchH->value() - 1; + int lval = defPatchL->value() - 1; + int prog = defPatchProg->value() - 1; + if(hval == -1) + hval = 0xff; + if(lval == -1) + lval = 0xff; + if(prog == -1) + prog = 0xff; + + return ((hval & 0xff) << 16) + ((lval & 0xff) << 8) + (prog & 0xff); +} + +//--------------------------------------------------------- +// setDefaultPatchNumbers +//--------------------------------------------------------- + +void EditInstrument::setDefaultPatchNumbers(int val) +{ + int hb; + int lb; + int pr; + + if(val == CTRL_VAL_UNKNOWN) + hb = lb = pr = 0; + else + { + hb = ((val >> 16) & 0xff) + 1; + if (hb == 0x100) + hb = 0; + lb = ((val >> 8) & 0xff) + 1; + if (lb == 0x100) + lb = 0; + pr = (val & 0xff) + 1; + if (pr == 0x100) + pr = 0; + } + + defPatchH->blockSignals(true); + defPatchL->blockSignals(true); + defPatchProg->blockSignals(true); + defPatchH->setValue(hb); + defPatchL->setValue(lb); + defPatchProg->setValue(pr); + defPatchH->blockSignals(false); + defPatchL->blockSignals(false); + defPatchProg->blockSignals(false); +} + +//--------------------------------------------------------- +// setDefaultPatchControls +//--------------------------------------------------------- + +void EditInstrument::setDefaultPatchControls(int val) +{ + setDefaultPatchNumbers(val); + setDefaultPatchName(val); +} + +//--------------------------------------------------------- +// getPatchName +//--------------------------------------------------------- + +const char* EditInstrument::getPatchName(int prog) +{ + int pr = prog & 0xff; + if(prog == CTRL_VAL_UNKNOWN || pr == 0xff) + return "---"; + + //int hbank = (prog >> 16) & 0x7f; + //int lbank = (prog >> 8) & 0x7f; + int hbank = (prog >> 16) & 0xff; + int lbank = (prog >> 8) & 0xff; + + PatchGroupList* pg = workingInstrument.groups(); + + for(ciPatchGroup i = pg->begin(); i != pg->end(); ++i) { + const PatchList& pl = (*i)->patches; + for (ciPatch ipl = pl.begin(); ipl != pl.end(); ++ipl) { + const Patch* mp = *ipl; + if (//(mp->typ & tmask) && + (pr == mp->prog) + //&& ((drum && mode != MT_GM) || + // (mp->drum == drumchan)) + + //&& (hbank == mp->hbank || !hb || mp->hbank == -1) + //&& (lbank == mp->lbank || !lb || mp->lbank == -1)) + && (hbank == mp->hbank || mp->hbank == -1) + && (lbank == mp->lbank || mp->lbank == -1)) + return mp->name.latin1(); + } + } + return "---"; +} + diff --git a/muse2/muse/instruments/editinstrument.h b/muse2/muse/instruments/editinstrument.h new file mode 100644 index 00000000..ef01f525 --- /dev/null +++ b/muse2/muse/instruments/editinstrument.h @@ -0,0 +1,92 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: editinstrument.h,v 1.1.1.1.2.4 2009/05/31 05:12:12 terminator356 Exp $ +// +// (C) Copyright 2003 Werner Schweer (ws@seh.de) +//========================================================= + +#ifndef __EDITINSTRUMENT_H__ +#define __EDITINSTRUMENT_H__ + +#include "editinstrumentbase.h" +#include "minstrument.h" +#include "midictrl.h" +//Added by qt3to4: +#include <Q3PopupMenu> +#include <QCloseEvent> +class ListBoxData; +class ListViewData; + +//--------------------------------------------------------- +// EditInstrument +//--------------------------------------------------------- + +class EditInstrument : public EditInstrumentBase { + Q_OBJECT + + MidiInstrument workingInstrument; + ListBoxData* oldMidiInstrument; + ListViewData* oldPatchItem; + void closeEvent(QCloseEvent*); + int checkDirty(MidiInstrument*, bool isClose = false); + bool fileSave(MidiInstrument*, const QString&); + void saveAs(); + void updateInstrument(MidiInstrument*); + void updatePatch(MidiInstrument*, Patch*); + void updatePatchGroup(MidiInstrument*, PatchGroup*); + void changeInstrument(); + ListViewData* addControllerToView(MidiController* mctrl); + QString getPatchItemText(int); + void enableDefaultControls(bool, bool); + void setDefaultPatchName(int); + int getDefaultPatchNumber(); + void setDefaultPatchNumbers(int); + void setDefaultPatchControls(int); + const char* getPatchName(int); + void deleteInstrument(ListBoxData*); + Q3PopupMenu* patchpopup; + + private slots: + virtual void fileNew(); + virtual void fileOpen(); + virtual void fileSave(); + virtual void fileSaveAs(); + virtual void fileExit(); + virtual void helpWhatsThis(); + void instrumentChanged(); + void tabChanged(QWidget*); + void patchChanged(); + void controllerChanged(); + //void instrumentNameChanged(const QString&); + void instrumentNameReturn(); + void patchNameReturn(); + void deletePatchClicked(); + void newPatchClicked(); + void newGroupClicked(); + void patchButtonClicked(); + void defPatchChanged(int); + //void newCategoryClicked(); + void deleteControllerClicked(); + void newControllerClicked(); + void addControllerClicked(); + void ctrlTypeChanged(int); + //void ctrlNameChanged(const QString&); + void ctrlNameReturn(); + void ctrlHNumChanged(int); + void ctrlLNumChanged(int); + void ctrlMinChanged(int); + void ctrlMaxChanged(int); + void ctrlDefaultChanged(int); + //void sysexChanged(); + //void deleteSysexClicked(); + //void newSysexClicked(); + void ctrlNullParamHChanged(int); + void ctrlNullParamLChanged(int); + + public: + EditInstrument(QWidget* parent = 0, const char* name = 0, Qt::WFlags fl = Qt::WType_TopLevel); + }; + +#endif + diff --git a/muse2/muse/instruments/editinstrumentbase.ui b/muse2/muse/instruments/editinstrumentbase.ui new file mode 100644 index 00000000..8f5ecc7b --- /dev/null +++ b/muse2/muse/instruments/editinstrumentbase.ui @@ -0,0 +1,1840 @@ +<!DOCTYPE UI><UI version="3.2" stdsetdef="1"> +<class>EditInstrumentBase</class> +<widget class="QMainWindow"> + <property name="name"> + <cstring>Form1</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>802</width> + <height>505</height> + </rect> + </property> + <property name="minimumSize"> + <size> + <width>802</width> + <height>464</height> + </size> + </property> + <property name="caption"> + <string>MusE: Instrument Editor</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QSplitter"> + <property name="name"> + <cstring>splitter4</cstring> + </property> + <property name="minimumSize"> + <size> + <width>780</width> + <height>365</height> + </size> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout26</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel2</cstring> + </property> + <property name="text"> + <string>Instrument Name:</string> + </property> + </widget> + <widget class="QLineEdit"> + <property name="name"> + <cstring>instrumentName</cstring> + </property> + <property name="toolTip" stdset="0"> + <string></string> + </property> + <property name="whatsThis" stdset="0"> + <string>Selected instrument name.</string> + </property> + </widget> + <widget class="QListBox"> + <property name="name"> + <cstring>instrumentList</cstring> + </property> + <property name="whatsThis" stdset="0"> + <string>List of defined instruments.</string> + </property> + </widget> + </vbox> + </widget> + <widget class="QTabWidget"> + <property name="name"> + <cstring>tabWidget3</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <widget class="QWidget"> + <property name="name"> + <cstring>patchesTab</cstring> + </property> + <attribute name="title"> + <string>Pa&tches</string> + </attribute> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QSplitter"> + <property name="name"> + <cstring>splitter5</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <widget class="QListView"> + <column> + <property name="text"> + <string>Group/Patch</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>patchView</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="allColumnsShowFocus"> + <bool>true</bool> + </property> + <property name="rootIsDecorated"> + <bool>true</bool> + </property> + <property name="toolTip" stdset="0"> + <string></string> + </property> + <property name="whatsThis" stdset="0"> + <string>List of groups and patches.</string> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout26</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QGroupBox"> + <property name="name"> + <cstring>groupBox2</cstring> + </property> + <property name="title"> + <string>Properties</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabelPatchName</cstring> + </property> + <property name="text"> + <string>Name:</string> + </property> + </widget> + <widget class="QLineEdit"> + <property name="name"> + <cstring>patchNameEdit</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>Group or patch name</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Group or patch name</string> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel2_2</cstring> + </property> + <property name="text"> + <string>High Bank:</string> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout22</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QSpinBox"> + <property name="name"> + <cstring>spinBoxHBank</cstring> + </property> + <property name="specialValueText"> + <string>---</string> + <comment>dont care</comment> + </property> + <property name="maxValue"> + <number>128</number> + </property> + <property name="minValue"> + <number>0</number> + </property> + <property name="value"> + <number>0</number> + </property> + <property name="toolTip" stdset="0"> + <string>Patch high bank number</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Patch high bank number. --- means don't care.</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer8</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>373</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel3_2</cstring> + </property> + <property name="text"> + <string>Low Bank:</string> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout23</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QSpinBox"> + <property name="name"> + <cstring>spinBoxLBank</cstring> + </property> + <property name="specialValueText"> + <string>---</string> + </property> + <property name="maxValue"> + <number>128</number> + </property> + <property name="minValue"> + <number>0</number> + </property> + <property name="value"> + <number>0</number> + </property> + <property name="toolTip" stdset="0"> + <string>Patch low bank number</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Patch low bank number. --- means don't care.</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer9</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>373</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel4_3</cstring> + </property> + <property name="text"> + <string>Program:</string> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout24</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QSpinBox"> + <property name="name"> + <cstring>spinBoxProgram</cstring> + </property> + <property name="maxValue"> + <number>128</number> + </property> + <property name="minValue"> + <number>1</number> + </property> + <property name="value"> + <number>1</number> + </property> + <property name="toolTip" stdset="0"> + <string>Patch program number</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Patch program number</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer10</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>373</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout6</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QCheckBox"> + <property name="name"> + <cstring>checkBoxDrum</cstring> + </property> + <property name="text"> + <string>Drum</string> + </property> + <property name="accel"> + <string></string> + </property> + <property name="toolTip" stdset="0"> + <string>Drum patch</string> + </property> + <property name="whatsThis" stdset="0"> + <string>If set, the patch is available only for drum channels.</string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>checkBoxGM</cstring> + </property> + <property name="text"> + <string>GM</string> + </property> + <property name="accel"> + <string></string> + </property> + <property name="toolTip" stdset="0"> + <string>GM patch</string> + </property> + <property name="whatsThis" stdset="0"> + <string>If set, the patch is available in a 'GM' or 'NO' midi song type.</string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>checkBoxGS</cstring> + </property> + <property name="text"> + <string>GS</string> + </property> + <property name="toolTip" stdset="0"> + <string>GS patch</string> + </property> + <property name="whatsThis" stdset="0"> + <string>If set, the patch is available in a 'GS' or 'NO' midi song type.</string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>checkBoxXG</cstring> + </property> + <property name="text"> + <string>XG</string> + </property> + <property name="toolTip" stdset="0"> + <string>XG patch</string> + </property> + <property name="whatsThis" stdset="0"> + <string>If set, the patch is available in an 'XG' or 'NO' midi song type.</string> + </property> + </widget> + </hbox> + </widget> + </vbox> + </widget> + <spacer> + <property name="name"> + <cstring>spacer7</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>90</height> + </size> + </property> + </spacer> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout5</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QToolButton"> + <property name="name"> + <cstring>patchDelete</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>&Delete</string> + </property> + <property name="accel"> + <string>Alt+D</string> + </property> + <property name="toolTip" stdset="0"> + <string>Delete group or patch</string> + </property> + </widget> + <widget class="QToolButton"> + <property name="name"> + <cstring>patchNew</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>1</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>New &Patch</string> + </property> + <property name="accel"> + <string>Alt+P</string> + </property> + <property name="toolTip" stdset="0"> + <string>New patch</string> + </property> + </widget> + <widget class="QToolButton"> + <property name="name"> + <cstring>patchNewGroup</cstring> + </property> + <property name="text"> + <string>New &Group</string> + </property> + <property name="accel"> + <string>Alt+G</string> + </property> + <property name="toolTip" stdset="0"> + <string>New group</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer11</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>240</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + </vbox> + </widget> + </widget> + </vbox> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>controllerTab</cstring> + </property> + <attribute name="title"> + <string>Contro&ller</string> + </attribute> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QSplitter"> + <property name="name"> + <cstring>splitter4</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout13</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Common:</string> + </property> + </widget> + <widget class="QListBox"> + <property name="name"> + <cstring>listController</cstring> + </property> + <property name="variableWidth"> + <bool>false</bool> + </property> + <property name="toolTip" stdset="0"> + <string></string> + </property> + <property name="whatsThis" stdset="0"> + <string>This is a list of commonly used midi controllers. +Note that in MusE pitch and program changes are +handled like normal controllers.</string> + </property> + </widget> + </vbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout17</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QListView"> + <column> + <property name="text"> + <string>Name </string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Type </string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>H-Ctrl</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>false</bool> + </property> + </column> + <column> + <property name="text"> + <string>L-Ctrl</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>false</bool> + </property> + </column> + <column> + <property name="text"> + <string>Min </string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>false</bool> + </property> + </column> + <column> + <property name="text"> + <string>Max </string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>false</bool> + </property> + </column> + <column> + <property name="text"> + <string>Def </string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>false</bool> + </property> + </column> + <property name="name"> + <cstring>viewController</cstring> + </property> + <property name="frameShape"> + <enum>StyledPanel</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="allColumnsShowFocus"> + <bool>true</bool> + </property> + <property name="toolTip" stdset="0"> + <string>List of defined controllers</string> + </property> + <property name="whatsThis" stdset="0"> + <string>List of defined controllers.</string> + </property> + </widget> + <widget class="QGroupBox"> + <property name="name"> + <cstring>GroupBox1</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Properties</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout33</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>TextLabel1_3</cstring> + </property> + <property name="text"> + <string>Name:</string> + </property> + </widget> + <widget class="QLineEdit"> + <property name="name"> + <cstring>ctrlName</cstring> + </property> + <property name="toolTip" stdset="0"> + <string></string> + </property> + <property name="whatsThis" stdset="0"> + <string>Midi controller name</string> + </property> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout37</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>TextLabel2_4</cstring> + </property> + <property name="text"> + <string>Type:</string> + </property> + </widget> + <widget class="QComboBox"> + <item> + <property name="text"> + <string>Control7</string> + </property> + </item> + <item> + <property name="text"> + <string>Control14</string> + </property> + </item> + <item> + <property name="text"> + <string>RPN</string> + </property> + </item> + <item> + <property name="text"> + <string>NRPN</string> + </property> + </item> + <item> + <property name="text"> + <string>RPN14</string> + </property> + </item> + <item> + <property name="text"> + <string>NRPN14</string> + </property> + </item> + <item> + <property name="text"> + <string>Pitch</string> + </property> + </item> + <item> + <property name="text"> + <string>Program</string> + </property> + </item> + <property name="name"> + <cstring>ctrlType</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>Midi controller type</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Midi controller type</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer15</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLabel"> + <property name="name"> + <cstring>TextLabel3_2</cstring> + </property> + <property name="text"> + <string>H-Ctrl</string> + </property> + <property name="indent"> + <number>10</number> + </property> + </widget> + <widget class="QSpinBox"> + <property name="name"> + <cstring>spinBoxHCtrlNo</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maxValue"> + <number>127</number> + </property> + <property name="minValue"> + <number>0</number> + </property> + <property name="value"> + <number>0</number> + </property> + <property name="toolTip" stdset="0"> + <string>Midi controller number high byte</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Midi controller number high byte</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer16</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLabel"> + <property name="name"> + <cstring>TextLabel2_3_2</cstring> + </property> + <property name="text"> + <string>L-Ctrl</string> + </property> + <property name="indent"> + <number>10</number> + </property> + </widget> + <widget class="QSpinBox"> + <property name="name"> + <cstring>spinBoxLCtrlNo</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="specialValueText"> + <string>*</string> + <comment>wild card</comment> + </property> + <property name="maxValue"> + <number>127</number> + </property> + <property name="minValue"> + <number>-1</number> + </property> + <property name="value"> + <number>0</number> + </property> + <property name="toolTip" stdset="0"> + <string>Midi controller number low byte (* means drum controller)</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Midi controller number low byte. +If low byte is * then the controller is a + 'drum controller'. For drum tracks and + GS/XG type songs and instruments. +Allows controllers for each instrument in + Muse's drum map. The low byte will be + replaced by the 'ANote' in the drum map. +Examples: The GS and XG instruments' + Drum controllers.</string> + </property> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout38</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel4_2</cstring> + </property> + <property name="text"> + <string>Range:</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer17</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLabel"> + <property name="name"> + <cstring>TextLabel1_2_2</cstring> + </property> + <property name="text"> + <string>Min</string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignRight</set> + </property> + <property name="indent"> + <number>10</number> + </property> + </widget> + <widget class="QSpinBox"> + <property name="name"> + <cstring>spinBoxMin</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maxValue"> + <number>16383</number> + </property> + <property name="minValue"> + <number>-16384</number> + </property> + <property name="toolTip" stdset="0"> + <string>Minimum value. If negative, auto-translate.</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Minimum value. If the minimum value + is negative, the range will automatically + be translated to a positive range. + +Useful for controllers which should be + displayed with zero bias. For example, +'Pan': Minimum: -64 Maximum: 63 +True range: Min: 0 Max: 127 (bias = 64) +'CoarseTuning': Min: -24 Max: 23 +True range: Min: 40 Max: 87 (bias = 64) + +Bias is determined from controller type: +7-bit Controller7 / RPN: Bias = 64 +14-bit Controller14 / RPN14: Bias = 8192 + +Type 'Pitch' is the exception. It is biased + at zero, even with a negative minimum: +'Pitch': Min: -8192 Max: 8191 +True range: Min: -8192 Max: 8191 (bias 0)</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer18</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLabel"> + <property name="name"> + <cstring>TextLabel2_2_2</cstring> + </property> + <property name="text"> + <string>Max</string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignRight</set> + </property> + <property name="indent"> + <number>10</number> + </property> + </widget> + <widget class="QSpinBox"> + <property name="name"> + <cstring>spinBoxMax</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maxValue"> + <number>16383</number> + </property> + <property name="minValue"> + <number>-16384</number> + </property> + <property name="value"> + <number>127</number> + </property> + <property name="toolTip" stdset="0"> + <string>Maximum value</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Maximum value</string> + </property> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout16</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer row="1" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>spacer13_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel1_3</cstring> + </property> + <property name="text"> + <string>Default:</string> + </property> + <property name="alignment"> + <set>AlignVCenter</set> + </property> + </widget> + <widget class="QLabel" row="0" column="6"> + <property name="name"> + <cstring>textLabel2_4</cstring> + </property> + <property name="text"> + <string>L-Bank</string> + </property> + </widget> + <widget class="QSpinBox" row="0" column="5"> + <property name="name"> + <cstring>defPatchH</cstring> + </property> + <property name="specialValueText"> + <string>off</string> + </property> + <property name="maxValue"> + <number>128</number> + </property> + <property name="minValue"> + <number>0</number> + </property> + <property name="value"> + <number>0</number> + </property> + </widget> + <widget class="QSpinBox" row="0" column="7"> + <property name="name"> + <cstring>defPatchL</cstring> + </property> + <property name="specialValueText"> + <string>off</string> + </property> + <property name="maxValue"> + <number>128</number> + </property> + <property name="minValue"> + <number>0</number> + </property> + <property name="value"> + <number>0</number> + </property> + </widget> + <widget class="QLabel" row="1" column="6"> + <property name="name"> + <cstring>textLabel3</cstring> + </property> + <property name="text"> + <string>Progr.</string> + </property> + </widget> + <widget class="QSpinBox" row="1" column="7"> + <property name="name"> + <cstring>defPatchProg</cstring> + </property> + <property name="specialValueText"> + <string>off</string> + </property> + <property name="maxValue"> + <number>128</number> + </property> + <property name="minValue"> + <number>0</number> + </property> + <property name="value"> + <number>0</number> + </property> + </widget> + <widget class="QPushButton" row="1" column="2" rowspan="1" colspan="4"> + <property name="name"> + <cstring>patchButton</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="minimumSize"> + <size> + <width>210</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string>???</string> + </property> + <property name="accel"> + <string></string> + </property> + </widget> + <widget class="QLabel" row="0" column="4"> + <property name="name"> + <cstring>textLabel1_5</cstring> + </property> + <property name="text"> + <string>H-Bank</string> + </property> + </widget> + <spacer row="0" column="3"> + <property name="name"> + <cstring>spacer12_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QSpinBox" row="0" column="1" rowspan="1" colspan="2"> + <property name="name"> + <cstring>spinBoxDefault</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>85</width> + <height>32767</height> + </size> + </property> + <property name="specialValueText"> + <string>off</string> + <comment>dont care</comment> + </property> + <property name="maxValue"> + <number>16383</number> + </property> + <property name="minValue"> + <number>-1</number> + </property> + <property name="value"> + <number>-1</number> + </property> + <property name="toolTip" stdset="0"> + <string>Default value. Off: No default.</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Default (initial) value. Off means no default. + +If a default value is chosen, the value will be sent + to the controller when the controller is added to + the song (in piano roll or event editor). When + the song is re-loaded, the value is sent again. +Otherwise the controller remains at its last value. +Controllers are also automatically added to a + song upon reception of a midi controller event. + +Caution! Watch out for controllers such as + 'Sustain' and 'ResetAllController' with default + values. You should probably turn 'off' their + default (in piano roll or drum edit, and + instrument editor).</string> + </property> + </widget> + </grid> + </widget> + </vbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout10</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QToolButton"> + <property name="name"> + <cstring>addController</cstring> + </property> + <property name="text"> + <string>&Add</string> + </property> + <property name="accel"> + <string>Alt+A</string> + </property> + <property name="toolTip" stdset="0"> + <string>Add common controller</string> + </property> + </widget> + <widget class="QToolButton"> + <property name="name"> + <cstring>deleteController</cstring> + </property> + <property name="text"> + <string>&Delete</string> + </property> + <property name="accel"> + <string>Alt+D</string> + </property> + <property name="toolTip" stdset="0"> + <string>Delete controller</string> + </property> + </widget> + <widget class="QToolButton"> + <property name="name"> + <cstring>newController</cstring> + </property> + <property name="text"> + <string>New &Controller</string> + </property> + <property name="accel"> + <string>Alt+C</string> + </property> + <property name="toolTip" stdset="0"> + <string>Create a new controller</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer13</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>200</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLabel"> + <property name="name"> + <cstring>nullValLabelH</cstring> + </property> + <property name="text"> + <string>Null Param Hi:</string> + </property> + </widget> + <widget class="QSpinBox"> + <property name="name"> + <cstring>nullParamSpinBoxH</cstring> + </property> + <property name="specialValueText"> + <string>off</string> + </property> + <property name="maxValue"> + <number>127</number> + </property> + <property name="minValue"> + <number>-1</number> + </property> + <property name="value"> + <number>127</number> + </property> + <property name="toolTip" stdset="0"> + <string>Null parameter number High byte</string> + </property> + <property name="whatsThis" stdset="0"> + <string>If set, these 'null' parameter numbers will + be sent after each RPN/NRPN event. +This prevents subsequent 'data' events + from corrupting the RPN/NRPN controller. +Typically, set to 127/127, or an unused + RPN/NRPN controller number.</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer13_3</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>200</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLabel"> + <property name="name"> + <cstring>nullValLabelL</cstring> + </property> + <property name="text"> + <string> Lo:</string> + </property> + </widget> + <widget class="QSpinBox"> + <property name="name"> + <cstring>nullParamSpinBoxL</cstring> + </property> + <property name="specialValueText"> + <string>off</string> + </property> + <property name="maxValue"> + <number>127</number> + </property> + <property name="minValue"> + <number>-1</number> + </property> + <property name="value"> + <number>127</number> + </property> + <property name="toolTip" stdset="0"> + <string>Null parameter number Low byte</string> + </property> + <property name="whatsThis" stdset="0"> + <string>If set, these 'null' parameter numbers will + be sent after each RPN/NRPN event. +This prevents subsequent 'data' events + from corrupting the RPN/NRPN controller. +Typically, set to 127/127, or an unused + RPN/NRPN controller number.</string> + </property> + </widget> + </hbox> + </widget> + </vbox> + </widget> + </widget> + </vbox> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>sysExTab</cstring> + </property> + <attribute name="title"> + <string>S&ysEx</string> + </attribute> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QSplitter"> + <property name="name"> + <cstring>splitter2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout12</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel2_3</cstring> + </property> + <property name="text"> + <string>SysEx List:</string> + </property> + </widget> + <widget class="QListBox"> + <property name="name"> + <cstring>sysexList</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </vbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout11</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel1_4</cstring> + </property> + <property name="text"> + <string>Name:</string> + </property> + </widget> + <widget class="QLineEdit"> + <property name="name"> + <cstring>sysexName</cstring> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel1_2</cstring> + </property> + <property name="text"> + <string>Hex Entry:</string> + </property> + </widget> + <widget class="QTextEdit"> + <property name="name"> + <cstring>sysexData</cstring> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout10</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QToolButton"> + <property name="name"> + <cstring>deleteSysex</cstring> + </property> + <property name="text"> + <string>&Delete</string> + </property> + <property name="accel"> + <string>Alt+D</string> + </property> + </widget> + <widget class="QToolButton"> + <property name="name"> + <cstring>newSysex</cstring> + </property> + <property name="text"> + <string>New SysE&x</string> + </property> + <property name="accel"> + <string>Alt+X</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer12</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>60</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + </vbox> + </widget> + </widget> + </vbox> + </widget> + </widget> + </widget> + </vbox> +</widget> +<menubar> + <property name="name"> + <cstring>MenuBar</cstring> + </property> + <property name="defaultUp"> + <bool>false</bool> + </property> + <item text="&File" name="fileMenu"> + <action name="fileNewAction"/> + <action name="fileOpenAction"/> + <action name="fileSaveAction"/> + <action name="fileSaveAsAction"/> + <separator/> + <action name="fileExitAction"/> + </item> + <item text="&Help" name="Help"> + <action name="whatsThisAction"/> + </item> +</menubar> +<toolbars> + <toolbar dock="2"> + <property name="name"> + <cstring>toolBar</cstring> + </property> + <property name="label"> + <string>Tools</string> + </property> + <action name="fileNewAction"/> + <action name="fileOpenAction"/> + <action name="fileSaveAction"/> + <action name="fileSaveAsAction"/> + <action name="whatsThisAction"/> + </toolbar> +</toolbars> +<actions> + <action> + <property name="name"> + <cstring>fileNewAction</cstring> + </property> + <property name="iconSet"> + <iconset>image0</iconset> + </property> + <property name="text"> + <string>New</string> + </property> + <property name="menuText"> + <string>&New</string> + </property> + <property name="accel"> + <string>Ctrl+N</string> + </property> + </action> + <action> + <property name="name"> + <cstring>fileOpenAction</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="iconSet"> + <iconset>image1</iconset> + </property> + <property name="text"> + <string>Open</string> + </property> + <property name="menuText"> + <string>&Open...</string> + </property> + <property name="accel"> + <string>Ctrl+O</string> + </property> + <property name="visible"> + <bool>false</bool> + </property> + </action> + <action> + <property name="name"> + <cstring>fileSaveAction</cstring> + </property> + <property name="iconSet"> + <iconset>image2</iconset> + </property> + <property name="text"> + <string>Save</string> + </property> + <property name="menuText"> + <string>&Save</string> + </property> + <property name="accel"> + <string>Ctrl+S</string> + </property> + </action> + <action> + <property name="name"> + <cstring>fileSaveAsAction</cstring> + </property> + <property name="iconSet"> + <iconset>image3</iconset> + </property> + <property name="text"> + <string>Save As</string> + </property> + <property name="menuText"> + <string>Save &As...</string> + </property> + <property name="accel"> + <string></string> + </property> + </action> + <action> + <property name="name"> + <cstring>fileExitAction</cstring> + </property> + <property name="text"> + <string>Exit</string> + </property> + <property name="menuText"> + <string>E&xit</string> + </property> + <property name="accel"> + <string></string> + </property> + </action> + <action> + <property name="name"> + <cstring>filenew_itemAction</cstring> + </property> + <property name="text"> + <string>new item</string> + </property> + <property name="menuText"> + <string>new item</string> + </property> + </action> + <action> + <property name="name"> + <cstring>whatsThisAction</cstring> + </property> + <property name="iconSet"> + <iconset>image4</iconset> + </property> + <property name="text"> + <string>What's this?</string> + </property> + <property name="menuText"> + <string>What's this?</string> + </property> + </action> +</actions> +<images> + <image name="image0"> + <data format="PNG" length="187">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000008249444154388ded95310ac0200c4593d2c334d0c535e0d2c3e75ae9d442353521e0e60741233ee5f355141198a1bd2d30b346168a088ee637aba8aabf0d00804e720f60823d95525c7867454474d0db6766b56c4981af7a7dc6163c05e6ca7dad81a7c088c340e4c04f32bccd52a98868811778810732af74e42df084b3febc6956dc1a2d33a3204eed990000000049454e44ae426082</data> + </image> + <image name="image1"> + <data format="PNG" length="230">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b000000ad49444154388db594510ec3200c436db45371b7699a76375f8b7d8caa11cd18d1827f225af1621908256187ca16ea4ef02dbaa1d6daec5a12c7ff9218021f9bbc4692689b32ebf02c541253321ee3017ac6bf728b420180005a6b00d08e25c835eecc403fbc130ab077e2e57ba47931c68375aee2395eab73b91947b3f6e4666ca1af670c787f7caa9bf1bf50f34072a117c7595003ce859e56bbb2a08019f4995060f5b67fd16c56a4cde3516f027970cd357a563f0000000049454e44ae426082</data> + </image> + <image name="image2"> + <data format="PNG" length="230">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b000000ad49444154388dd595c10a85201045af0f172e5af83d0afd5944f4670f9aef69e1a25d2d62c2b230c302cf460c3b5ca7310511e10d24001863e69c52221292277db78e4d0b0cff2149646bbbbd636b0b00f8650a1920e34bce514e63aac66dce49996862e53494d3c1735f0aaca5e472de123f255a8a63b2bbbc96b83c7150e3be0b5b2786df0d97e2ab85a97cdb6e4d9b2e3aeef2f191f67f5467dfa4bc762b4f2cf8cecb753d1191d88973b300c3df2bac2a2aaca70000000049454e44ae426082</data> + </image> + <image name="image3"> + <data format="PNG" length="264">89504e470d0a1a0a0000000d49484452000000100000001008060000001ff3ff61000000cf49444154388da593410ec2300c0467090f4a8f3df421fd425f013f834b7af5872273a0a952a010c0926545ceaed6eb4480f3471c00628c009c3801978fb5c60870774712ee6d62246d15745df7b5f4a2e0f0d838eb8c74ddadafc2638cbe8cd21435a65981a43501ccac5d41e9d577b8afdf8fb529b5bb9b19df6ce7581f8ab37598d92ef113c1e36c2d0a36269a19ee4e4a49a5ee225f1100ccf3ac699a7c1c4772ce1f9fe6d3087ddfafa01082007fe781587e638c113323a5a49cb3871036b500866158cd36334829b190fc94376721c8f72ecfaff50000000049454e44ae426082</data> + </image> + <image name="image4"> + <data format="PNG" length="243">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b000000ba49444154388dd594db0980300c451371aa0c90b93a5707b86be957306dd387423fbc206221a7370fc30068878e2dd45f824fff212217001e0588e4ab3e4b8948558bb8c6b18834813514500694537ac039971786a588e006351851e9d29f77c133e72b1a36cfc37dda269f7eed98fd0fd273d96ba82f4fddbc330a6801edb4f8464631cb73ecb3891a596bea7836d7afc000783415bdf4bd9a5298437bf766da9e25f0d7b423f16c1f9be3b7976edb6e53c75ff5bf45bf0d7c034d505e874a59314b0000000049454e44ae426082</data> + </image> +</images> +<connections> + <connection> + <sender>fileNewAction</sender> + <signal>activated()</signal> + <receiver>Form1</receiver> + <slot>fileNew()</slot> + </connection> + <connection> + <sender>fileOpenAction</sender> + <signal>activated()</signal> + <receiver>Form1</receiver> + <slot>fileOpen()</slot> + </connection> + <connection> + <sender>fileSaveAction</sender> + <signal>activated()</signal> + <receiver>Form1</receiver> + <slot>fileSave()</slot> + </connection> + <connection> + <sender>fileSaveAsAction</sender> + <signal>activated()</signal> + <receiver>Form1</receiver> + <slot>fileSaveAs()</slot> + </connection> + <connection> + <sender>fileExitAction</sender> + <signal>activated()</signal> + <receiver>Form1</receiver> + <slot>fileExit()</slot> + </connection> + <connection> + <sender>whatsThisAction</sender> + <signal>activated()</signal> + <receiver>Form1</receiver> + <slot>helpWhatsThis()</slot> + </connection> +</connections> +<tabstops> + <tabstop>instrumentName</tabstop> + <tabstop>instrumentList</tabstop> + <tabstop>tabWidget3</tabstop> + <tabstop>patchView</tabstop> + <tabstop>patchNameEdit</tabstop> + <tabstop>spinBoxHBank</tabstop> + <tabstop>spinBoxLBank</tabstop> + <tabstop>spinBoxProgram</tabstop> + <tabstop>checkBoxDrum</tabstop> + <tabstop>checkBoxGM</tabstop> + <tabstop>checkBoxGS</tabstop> + <tabstop>checkBoxXG</tabstop> + <tabstop>listController</tabstop> + <tabstop>viewController</tabstop> + <tabstop>ctrlName</tabstop> + <tabstop>ctrlType</tabstop> + <tabstop>spinBoxHCtrlNo</tabstop> + <tabstop>spinBoxLCtrlNo</tabstop> + <tabstop>spinBoxMin</tabstop> + <tabstop>spinBoxMax</tabstop> + <tabstop>spinBoxDefault</tabstop> + <tabstop>sysexList</tabstop> + <tabstop>sysexName</tabstop> + <tabstop>sysexData</tabstop> +</tabstops> +<slots> + <slot>fileNew()</slot> + <slot>fileOpen()</slot> + <slot>fileSave()</slot> + <slot>fileSaveAs()</slot> + <slot>fileExit()</slot> + <slot>helpWhatsThis()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/muse2/muse/instruments/midictrledit.cpp b/muse2/muse/instruments/midictrledit.cpp new file mode 100644 index 00000000..6577b65f --- /dev/null +++ b/muse2/muse/instruments/midictrledit.cpp @@ -0,0 +1,733 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: midictrledit.cpp,v 1.1.1.1.2.2 2008/08/18 00:15:24 terminator356 Exp $ +// +// (C) Copyright 2003 Werner Schweer (ws@seh.de) +//========================================================= + +#include <stdio.h> + +#include "app.h" +#include "midiport.h" +#include "mididev.h" +#include "midictrl.h" +#include "midictrledit.h" +#include "minstrument.h" +#include "song.h" +#include "xml.h" +#include "filedialog.h" +#include "globals.h" + +#include <q3listview.h> +#include <qlineedit.h> +#include <q3listbox.h> +#include <qcombobox.h> +#include <qspinbox.h> +#include <qpushbutton.h> +#include <qtoolbutton.h> + +MidiControllerEditDialog* midiControllerEditDialog; + +static MidiController predefinedMidiController[] = { + MidiController(QString("Pitch"), 0x40000, -8192, +8191, 0), + }; +enum { + COL_NAME = 0, COL_TYPE, + COL_HNUM, COL_LNUM, COL_MIN, COL_MAX + }; +//--------------------------------------------------------- +// addControllerToView +//--------------------------------------------------------- + +void MidiControllerEditDialog::addControllerToView(MidiController* mctrl) + { + QString hnum; + QString lnum; + QString min; + QString max; + int n = mctrl->num(); + int h = (n >> 8) & 0x7f; + int l = n & 0x7f; + MidiController::ControllerType t = midiControllerType(n); + switch(t) + { + case MidiController::Controller7: + hnum = "---"; + lnum.setNum(l); + min.setNum(mctrl->minVal()); + max.setNum(mctrl->maxVal()); + break; + case MidiController::RPN: + case MidiController::NRPN: + case MidiController::RPN14: + case MidiController::NRPN14: + case MidiController::Controller14: + hnum.setNum(h); + lnum.setNum(l); + min.setNum(mctrl->minVal()); + max.setNum(mctrl->maxVal()); + break; + case MidiController::Pitch: + hnum = "---"; + lnum = "---"; + min.setNum(mctrl->minVal()); + max.setNum(mctrl->maxVal()); + break; + default: + hnum = "---"; + lnum = "---"; + min.setNum(0); + max.setNum(0); + break; + } + + new Q3ListViewItem(viewController, + mctrl->name(), + int2ctrlType(t), + hnum, lnum, min, max + ); + + } +//--------------------------------------------------------- +// MidiControllerEditDialog +//--------------------------------------------------------- + +MidiControllerEditDialog::MidiControllerEditDialog(QWidget* parent, const char* name, bool modal, Qt::WFlags fl) + : MidiControllerEditDialogBase(parent, name, modal, fl) + { + _lastPort = midiPortsList->currentItem(); + viewController->setColumnAlignment(COL_HNUM, Qt::AlignCenter); + viewController->setColumnAlignment(COL_LNUM, Qt::AlignCenter); + viewController->setColumnAlignment(COL_MIN, Qt::AlignCenter); + viewController->setColumnAlignment(COL_MAX, Qt::AlignCenter); + viewController->setColumnWidthMode(COL_NAME, Q3ListView::Maximum); + + // populate list of predefined controller + updatePredefinedList(); + + // populate ports pulldown + updateMidiPortsList(); + connect(buttonNew, SIGNAL(clicked()), SLOT(ctrlAdd())); + connect(buttonDelete, SIGNAL(clicked()), SLOT(ctrlDelete())); + connect(entryName, SIGNAL(textChanged(const QString&)), SLOT(nameChanged(const QString&))); + connect(comboType, SIGNAL(activated(const QString&)), SLOT(typeChanged(const QString&))); + connect(spinboxHCtrlNo, SIGNAL(valueChanged(int)), SLOT(valueHChanged(int))); + connect(spinboxLCtrlNo, SIGNAL(valueChanged(int)), SLOT(valueLChanged(int))); + connect(spinboxMin, SIGNAL(valueChanged(int)), SLOT(minChanged(int))); + connect(spinboxMax, SIGNAL(valueChanged(int)), SLOT(maxChanged(int))); + connect(viewController, SIGNAL(selectionChanged()), SLOT(controllerChanged())); + connect(buttonApply, SIGNAL(clicked()), SLOT(apply())); + connect(midiPortsList, SIGNAL(activated(int)), SLOT(portChanged(int))); + + updateViewController(); + _modified = false; + buttonApply->setEnabled(false); + connect(song, SIGNAL(songChanged(int)), SLOT(songChanged(int))); + } + +//--------------------------------------------------------- +// songChanged +//--------------------------------------------------------- + +void MidiControllerEditDialog::songChanged(int flags) +{ + // Is it simply a midi controller value adjustment? Forget it. + if(flags == SC_MIDI_CONTROLLER) + return; + + if(flags & (SC_CONFIG | SC_MIDI_CONTROLLER)) + //if(flags & (SC_CONFIG | SC_MIDI_CONTROLLER_ADD)) + { + //listController->blockSignals(true); + midiPortsList->blockSignals(true); + //viewController->blockSignals(true); + updatePredefinedList(); + updateMidiPortsList(); + updateViewController(); + //viewController->setCurrentItem(viewController->firstChild()); + //controllerChanged(viewController->currentItem()); + //listController->blockSignals(false); + midiPortsList->blockSignals(false); + //viewController->blockSignals(false); + } +} + +//--------------------------------------------------------- +// updatePredefinedList +//--------------------------------------------------------- + +void MidiControllerEditDialog::updatePredefinedList() +{ + listController->clear(); + int size = sizeof(predefinedMidiController) / sizeof(*predefinedMidiController); + for (int i = 0; i < size; ++i) + listController->insertItem(predefinedMidiController[i].name()); + listController->setSelected(0, true); +} + +//--------------------------------------------------------- +// updateMidiPortsList +//--------------------------------------------------------- + +void MidiControllerEditDialog::updateMidiPortsList() +{ + midiPortsList->clear(); + for (int i = 0; i < MIDI_PORTS; ++i) { + MidiPort* port = &midiPorts[i]; + MidiDevice* dev = port->device(); + QString name; + name.sprintf("%d(%s)", port->portno()+1, + dev ? dev->name().latin1() : "none"); + midiPortsList->insertItem(name, i); + } + _lastPort = midiPortsList->currentItem(); +} + +//--------------------------------------------------------- +// updateViewController +//--------------------------------------------------------- + +void MidiControllerEditDialog::updateViewController() +{ + //for (iMidiController i = midiControllerList.begin(); + // i != midiControllerList.end(); ++i) { + // addControllerToView(&*i); + int mpidx = midiPortsList->currentItem(); + + viewController->clear(); + //MidiControllerList* mcl; + MidiInstrument* mi = midiPorts[mpidx].instrument(); + //if(mi) + MidiControllerList* mcl = mi->controller(); + //else + // mcl = &defaultMidiController; + for (iMidiController i = mcl->begin(); i != mcl->end(); ++i) + addControllerToView(*i); + + viewController->blockSignals(true); + viewController->setCurrentItem(viewController->firstChild()); + controllerChanged(viewController->currentItem()); + viewController->blockSignals(false); + + setModified(false); +} + +//--------------------------------------------------------- +// reject +//--------------------------------------------------------- + +void MidiControllerEditDialog::setModified(bool v) +{ + if(v == _modified) + return; + + _modified = v; + + if(v) + { + buttonApply->setEnabled(true); + } + else + { + buttonApply->setEnabled(false); + } +} + +//--------------------------------------------------------- +// reject +//--------------------------------------------------------- + +void MidiControllerEditDialog::reject() + { + //MidiControllerList* mcl; +// MidiInstrument* mi = midiPorts[mpidx].instrument(); + //if(mi) +// MidiControllerList* mcl = mi->controller(); + //else + // mcl = &defaultMidiController; +// for (iMidiController i = mcl->begin(); i != mcl->end(); ++i) +// addControllerToView(*i); + + // Restore the list before closing this dialog. + updateViewController(); + //setModified(false); + + MidiControllerEditDialogBase::reject(); + } + +//--------------------------------------------------------- +// apply +//--------------------------------------------------------- + +void MidiControllerEditDialog::apply() +{ + int mpidx = midiPortsList->currentItem(); + //MidiControllerList* mcl; + MidiInstrument* mi = midiPorts[mpidx].instrument(); + //if(mi) + MidiControllerList* mcl = mi->controller(); + //else + // mcl = &defaultMidiController; + mcl->clear(); + + + Q3ListViewItem* item = viewController->firstChild(); + int hval; + int lval; + while (item) { + hval = item->text(COL_HNUM).toInt(); + lval = item->text(COL_LNUM).toInt(); + MidiController* c = new MidiController(); + c->setName(item->text(COL_NAME)); + + MidiController::ControllerType type = ctrlType2Int(item->text(COL_TYPE)); + + switch(type) { + case MidiController::Controller7: + c->setNum(lval); + break; + case MidiController::Controller14: + c->setNum((hval << 8 | lval) | CTRL_14_OFFSET); + break; + case MidiController::RPN: + c->setNum((hval << 8 | lval) | CTRL_RPN_OFFSET); + break; + case MidiController::NRPN: + c->setNum((hval << 8 | lval) | CTRL_NRPN_OFFSET); + break; + case MidiController::RPN14: + c->setNum((hval << 8 | lval) | CTRL_RPN14_OFFSET); + break; + case MidiController::NRPN14: + c->setNum((hval << 8 | lval) | CTRL_NRPN14_OFFSET); + break; + case MidiController::Program: + c->setNum(CTRL_PROGRAM); + break; + case MidiController::Pitch: + c->setNum(CTRL_PITCH); + break; + default: + break; + } + if(type == MidiController::Program) + { + c->setMinVal(0); + c->setMaxVal(0xffffff); + } + else + { + c->setMinVal(item->text(COL_MIN).toInt()); + c->setMaxVal(item->text(COL_MAX).toInt()); + } + + mcl->push_back(c); + + item = item->nextSibling(); + } + + // Update the list before closing this dialog. + //updateViewController(); + //setModified(false); + song->update(SC_CONFIG | SC_MIDI_CONTROLLER); +} + +//--------------------------------------------------------- +// ctrlAdd +//--------------------------------------------------------- + +void MidiControllerEditDialog::ctrlAdd() + { + Q3ListBoxItem* item = listController->selectedItem(); + if (item == 0) + return; + QString name = item->text(); + int size = sizeof(predefinedMidiController) / sizeof(*predefinedMidiController); + for (int i = 0; i < size; ++i) { + MidiController* c = &predefinedMidiController[i]; + if (c->name() != name) + continue; + MidiController::ControllerType t = midiControllerType(c->num()); + QString type = int2ctrlType(t); + QString min, max; + QString hno, lno; + int h = (c->num() >> 8) & 0x7f; + int l = c->num() & 0x7f; + + switch(t) { + case MidiController::Controller7: + min.setNum(c->minVal()); + max.setNum(c->maxVal()); + hno = "---"; + lno.setNum(l); + break; + case MidiController::RPN: + case MidiController::NRPN: + case MidiController::RPN14: + case MidiController::NRPN14: + case MidiController::Controller14: + min.setNum(c->minVal()); + max.setNum(c->maxVal()); + hno.setNum(h); + lno.setNum(l); + break; + case MidiController::Pitch: + min.setNum(c->minVal()); + max.setNum(c->maxVal()); + hno = "---"; + lno = "---"; + break; + default: + hno = "---"; + lno = "---"; + min.setNum(0); + max.setNum(0); + break; + } + + Q3ListViewItem* item = new Q3ListViewItem(viewController, + name, type, hno, lno, min, max); + + viewController->blockSignals(true); + viewController->setCurrentItem(item); + controllerChanged(item); + viewController->blockSignals(false); + + setModified(true); + break; + } + } + +//--------------------------------------------------------- +// ctrlDelete +//--------------------------------------------------------- + +void MidiControllerEditDialog::ctrlDelete() + { + Q3ListViewItem* item = viewController->currentItem(); + if (item == 0) + return; + delete item; + + setModified(true); + } + +//--------------------------------------------------------- +// accept +//--------------------------------------------------------- + +void MidiControllerEditDialog::accept() + { + apply(); + MidiControllerEditDialogBase::accept(); + } + +//--------------------------------------------------------- +// portChanged +//--------------------------------------------------------- + +void MidiControllerEditDialog::portChanged(int n) + { + if(n == _lastPort) + return; + _lastPort = n; + + //listController->blockSignals(true); + //midiPortsList->blockSignals(true); + //viewController->blockSignals(true); + //updatePredefinedList(); + //updateMidiPortsList(); + //reject(); // populate list + updateViewController(); + //viewController->setCurrentItem(viewController->firstChild()); + //controllerChanged(viewController->currentItem()); + //listController->blockSignals(false); + //midiPortsList->blockSignals(false); + //viewController->blockSignals(false); + } + +//--------------------------------------------------------- +// nameChanged +//--------------------------------------------------------- + +void MidiControllerEditDialog::nameChanged(const QString& s) + { + Q3ListViewItem* item = viewController->currentItem(); + if (item == 0) + return; + item->setText(COL_NAME, s); + + setModified(true); + } + +//--------------------------------------------------------- +// typeChanged +//--------------------------------------------------------- + +void MidiControllerEditDialog::typeChanged(const QString& s) + { + Q3ListViewItem* item = viewController->currentItem(); + if (item == 0) + return; + item->setText(COL_TYPE, s); + switch(ctrlType2Int(s)) { + case MidiController::Controller14: + case MidiController::RPN14: + case MidiController::NRPN14: + item->setText(COL_LNUM, QString("0")); + item->setText(COL_HNUM, QString("0")); + item->setText(COL_MIN, QString("0")); + item->setText(COL_MAX, QString("16383")); + break; + case MidiController::Controller7: + item->setText(COL_MIN, QString("0")); + item->setText(COL_MAX, QString("127")); + item->setText(COL_LNUM, QString("0")); + item->setText(COL_HNUM, QString("---")); + break; + case MidiController::RPN: + case MidiController::NRPN: + item->setText(COL_MIN, QString("0")); + item->setText(COL_MAX, QString("127")); + item->setText(COL_LNUM, QString("0")); + item->setText(COL_HNUM, QString("0")); + break; + + case MidiController::Program: + + item->setText(COL_MIN, QString("---")); + item->setText(COL_MAX, QString("---")); + item->setText(COL_LNUM, QString("---")); + item->setText(COL_HNUM, QString("---")); + break; + case MidiController::Pitch: + item->setText(COL_MIN, QString("-8192")); + item->setText(COL_MAX, QString("8191")); + item->setText(COL_LNUM, QString("---")); + item->setText(COL_HNUM, QString("---")); + break; + default: + break; + } + + setModified(true); + + controllerChanged(item); + } + +//--------------------------------------------------------- +// valueHChanged +//--------------------------------------------------------- + +void MidiControllerEditDialog::valueHChanged(int val) + { + Q3ListViewItem* item = viewController->currentItem(); + if (item == 0) + return; + QString s; + s.setNum(val); + item->setText(COL_HNUM, s); + + setModified(true); + } + +//--------------------------------------------------------- +// valueLChanged +//--------------------------------------------------------- + +void MidiControllerEditDialog::valueLChanged(int val) + { + Q3ListViewItem* item = viewController->currentItem(); + if (item == 0) + return; + QString s; + s.setNum(val); + item->setText(COL_LNUM, s); + + setModified(true); + } + +//--------------------------------------------------------- +// controllerChanged +//--------------------------------------------------------- + +void MidiControllerEditDialog::controllerChanged() + { + Q3ListViewItem* item = viewController->selectedItem(); + controllerChanged(item); + } + +void MidiControllerEditDialog::controllerChanged(Q3ListViewItem* item) + { + if (item == 0) { + entryName->setEnabled(false); + comboType->setEnabled(false); + spinboxHCtrlNo->setEnabled(false); + spinboxLCtrlNo->setEnabled(false); + spinboxMin->setEnabled(false); + spinboxMax->setEnabled(false); + return; + } + + entryName->blockSignals(true); + comboType->blockSignals(true); + spinboxHCtrlNo->blockSignals(true); + spinboxLCtrlNo->blockSignals(true); + spinboxMin->blockSignals(true); + spinboxMax->blockSignals(true); + + entryName->setEnabled(true); + entryName->setText(item->text(COL_NAME)); + comboType->setCurrentItem(int(ctrlType2Int(item->text(COL_TYPE)))); + switch (ctrlType2Int(item->text(COL_TYPE))) { + case MidiController::Controller7: + comboType->setEnabled(true); + spinboxHCtrlNo->setEnabled(false); + spinboxLCtrlNo->setEnabled(true); + spinboxMin->setEnabled(true); + spinboxMax->setEnabled(true); + spinboxHCtrlNo->setValue(0); + spinboxLCtrlNo->setValue(item->text(COL_LNUM).toInt()); + spinboxMin->setRange(0, 127); + spinboxMax->setRange(0, 127); + spinboxMin->setValue(item->text(COL_MIN).toInt()); + spinboxMax->setValue(item->text(COL_MAX).toInt()); + break; + + case MidiController::RPN: + case MidiController::NRPN: + comboType->setEnabled(true); + spinboxHCtrlNo->setEnabled(true); + spinboxLCtrlNo->setEnabled(true); + spinboxMin->setEnabled(true); + spinboxMax->setEnabled(true); + spinboxHCtrlNo->setValue(item->text(COL_HNUM).toInt()); + spinboxLCtrlNo->setValue(item->text(COL_LNUM).toInt()); + spinboxMin->setRange(0, 127); + spinboxMax->setRange(0, 127); + spinboxMin->setValue(item->text(COL_MIN).toInt()); + spinboxMax->setValue(item->text(COL_MAX).toInt()); + break; + case MidiController::Controller14: + case MidiController::RPN14: + case MidiController::NRPN14: + comboType->setEnabled(true); + spinboxHCtrlNo->setEnabled(true); + spinboxLCtrlNo->setEnabled(true); + spinboxMin->setEnabled(true); + spinboxMax->setEnabled(true); + + spinboxHCtrlNo->setValue(item->text(COL_HNUM).toInt()); + spinboxLCtrlNo->setValue(item->text(COL_LNUM).toInt()); + spinboxMin->setRange(0, 16383); + spinboxMax->setRange(0, 16383); + spinboxMin->setValue(item->text(COL_MIN).toInt()); + spinboxMax->setValue(item->text(COL_MAX).toInt()); + break; + + case MidiController::Pitch: + comboType->setEnabled(true); + spinboxHCtrlNo->setEnabled(false); + spinboxLCtrlNo->setEnabled(false); + spinboxMin->setEnabled(true); + spinboxMax->setEnabled(true); + spinboxHCtrlNo->setValue(0); + spinboxLCtrlNo->setValue(0); + spinboxMin->setRange(-8192, 8191); + spinboxMax->setRange(-8192, 8191); + spinboxMin->setValue(item->text(COL_MIN).toInt()); + spinboxMax->setValue(item->text(COL_MAX).toInt()); + break; + + case MidiController::Program: + comboType->setEnabled(true); + spinboxHCtrlNo->setEnabled(false); + spinboxLCtrlNo->setEnabled(false); + spinboxMin->setEnabled(false); + spinboxMax->setEnabled(false); + spinboxHCtrlNo->setValue(0); + spinboxLCtrlNo->setValue(0); + spinboxMin->setRange(0, 0); + spinboxMax->setRange(0, 0); + spinboxMin->setValue(0); + spinboxMax->setValue(0); + break; + default: + break; + } + entryName->blockSignals(false); + comboType->blockSignals(false); + spinboxHCtrlNo->blockSignals(false); + spinboxLCtrlNo->blockSignals(false); + spinboxMin->blockSignals(false); + spinboxMax->blockSignals(false); + } + +//--------------------------------------------------------- +// minChanged +//--------------------------------------------------------- + +void MidiControllerEditDialog::minChanged(int val) + { + Q3ListViewItem* item = viewController->currentItem(); + if (item == 0) + return; + + QString s; + s.setNum(val); + item->setText(COL_MIN, s); + + if(val > item->text(COL_MAX).toInt()) + { + spinboxMax->blockSignals(true); + spinboxMax->setValue(val); + item->setText(COL_MAX, s); + spinboxMax->blockSignals(false); + } + setModified(true); + } + +//--------------------------------------------------------- +// maxChanged +//--------------------------------------------------------- + +void MidiControllerEditDialog::maxChanged(int val) + { + Q3ListViewItem* item = viewController->currentItem(); + if (item == 0) + return; + + QString s; + s.setNum(val); + item->setText(COL_MAX, s); + + if(val < item->text(COL_MIN).toInt()) + { + spinboxMin->blockSignals(true); + spinboxMin->setValue(val); + item->setText(COL_MIN, s); + spinboxMin->blockSignals(false); + } + setModified(true); + } + +//--------------------------------------------------------- +// configMidiController +//--------------------------------------------------------- + +void configMidiController() + { + if (midiControllerEditDialog == 0) + { + midiControllerEditDialog = new MidiControllerEditDialog(); + midiControllerEditDialog->show(); + } + else + { + if(midiControllerEditDialog->isShown()) + midiControllerEditDialog->hide(); + else + midiControllerEditDialog->show(); + } + } diff --git a/muse2/muse/instruments/midictrledit.h b/muse2/muse/instruments/midictrledit.h new file mode 100644 index 00000000..e1624f29 --- /dev/null +++ b/muse2/muse/instruments/midictrledit.h @@ -0,0 +1,56 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: midictrledit.h,v 1.1.1.1.2.1 2008/08/18 00:15:25 terminator356 Exp $ +// +// (C) Copyright 1999/2000 Werner Schweer (ws@seh.de) +//========================================================= + +#ifndef __MIDICTRLEDIT_H__ +#define __MIDICTRLEDIT_H__ + +#include "ccontrolbase.h" +#include "midictrl.h" + +//--------------------------------------------------------- +// MidiControllerEditDialog +//--------------------------------------------------------- + +class MidiControllerEditDialog : public MidiControllerEditDialogBase { + Q_OBJECT + + int _lastPort; + bool _modified; + + void addControllerToView(MidiController* mctrl); + void mergeReplace(bool replace); + void updatePredefinedList(); + void updateMidiPortsList(); + void updateViewController(); + void setModified(bool); + + private slots: + void ctrlAdd(); + void ctrlDelete(); + virtual void accept(); + virtual void reject(); + void apply(); + void nameChanged(const QString&); + void typeChanged(const QString&); + void valueHChanged(int); + void valueLChanged(int); + void controllerChanged(Q3ListViewItem*); + void controllerChanged(); + void minChanged(int); + void maxChanged(int); + void portChanged(int); + void songChanged(int); + + public: + MidiControllerEditDialog(QWidget* parent = 0, const char* name = 0, bool modal = false, Qt::WFlags fl = 0); + }; + +extern MidiControllerEditDialog* midiControllerEditDialog; +extern void configMidiController(); +#endif + diff --git a/muse2/muse/instruments/minstrument.cpp b/muse2/muse/instruments/minstrument.cpp new file mode 100644 index 00000000..a69f504e --- /dev/null +++ b/muse2/muse/instruments/minstrument.cpp @@ -0,0 +1,850 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: minstrument.cpp,v 1.10.2.5 2009/03/28 01:46:10 terminator356 Exp $ +// +// (C) Copyright 2000-2003 Werner Schweer (ws@seh.de) +//========================================================= + +#include <stdio.h> + +#include <q3popupmenu.h> +#include <qdir.h> +#include <qfileinfo.h> + +#include "minstrument.h" +#include "midiport.h" +#include "globals.h" +#include "xml.h" +#include "event.h" +#include "mpevent.h" +#include "midictrl.h" +#include "gconfig.h" + +MidiInstrumentList midiInstruments; +MidiInstrument* genericMidiInstrument; + +static const char* gmdrumname = "GM-drums"; + +//--------------------------------------------------------- +// readEventList +//--------------------------------------------------------- + +static void readEventList(Xml& xml, EventList* el, const char* name) + { + for (;;) { + Xml::Token token = xml.parse(); + const QString& tag = xml.s1(); + switch (token) { + case Xml::Error: + case Xml::End: + return; + case Xml::TagStart: + if (tag == "event") { + Event e(Note); + e.read(xml); + el->add(e); + } + else + xml.unknown("readEventList"); + break; + case Xml::TagEnd: + if (tag == name) + return; + default: + break; + } + } + } + +//--------------------------------------------------------- +// read +//--------------------------------------------------------- + +//--------------------------------------------------------- +// loadIDF +//--------------------------------------------------------- + +static void loadIDF(QFileInfo* fi) + { +/* + QFile qf(fi->filePath()); + if (!qf.open(IO_ReadOnly)) { + printf("cannot open file %s\n", fi->fileName().latin1()); + return; + } + if (debugMsg) + printf(" load instrument definition <%s>\n", fi->filePath().local8Bit().data()); + QDomDocument doc; + int line, column; + QString err; + if (!doc.setContent(&qf, false, &err, &line, &column)) { + QString col, ln, error; + col.setNum(column); + ln.setNum(line); + error = err + " at line: " + ln + " col: " + col; + printf("error reading file <%s>:\n %s\n", + fi->filePath().latin1(), error.latin1()); + return; + } + QDomNode node = doc.documentElement(); + while (!node.isNull()) { + QDomElement e = node.toElement(); + if (e.isNull()) + continue; + if (e.tagName() == "muse") { + QString version = e.attribute(QString("version")); + for (QDomNode n = node.firstChild(); !n.isNull(); n = n.nextSibling()) { + QDomElement e = n.toElement(); + if (e.tagName() == "MidiInstrument") { + MidiInstrument* i = new MidiInstrument(); + i->read(n); + i->setFilePath(fi->filePath()); + bool replaced = false; + for (int idx = 0; idx < midiInstruments.size(); ++idx) { + if (midiInstruments[idx]->iname() == i->iname()) { + midiInstruments.replace(idx, i); + replaced = true; + if (debugMsg) + printf("Midi Instrument Definition <%s> overwritten\n", + i->iname().toLocal8Bit().data()); + break; + } + } + if (!replaced) + midiInstruments += i; + } + } + } + else + printf("MusE:laodIDF: %s not supported\n", e.tagName().latin1()); + node = node.nextSibling(); + } + qf.close(); +*/ + + FILE* f = fopen(fi->filePath().ascii(), "r"); + if (f == 0) + return; + if (debugMsg) + printf("READ IDF %s\n", fi->filePath().latin1()); + Xml xml(f); + + bool skipmode = true; + for (;;) { + Xml::Token token = xml.parse(); + const QString& tag = xml.s1(); + switch (token) { + case Xml::Error: + case Xml::End: + return; + case Xml::TagStart: + if (skipmode && tag == "muse") + skipmode = false; + else if (skipmode) + break; + else if (tag == "MidiInstrument") { + MidiInstrument* i = new MidiInstrument(); + i->setFilePath(fi->filePath()); + i->read(xml); + // Ignore duplicate named instruments. + iMidiInstrument ii = midiInstruments.begin(); + for(; ii != midiInstruments.end(); ++ii) + { + if((*ii)->iname() == i->iname()) + break; + } + if(ii == midiInstruments.end()) + midiInstruments.push_back(i); + else + delete i; + } + else + xml.unknown("muse"); + break; + case Xml::Attribut: + break; + case Xml::TagEnd: + if (!skipmode && tag == "muse") { + return; + } + default: + break; + } + } + fclose(f); + + + } + +//--------------------------------------------------------- +// initMidiInstruments +//--------------------------------------------------------- + +void initMidiInstruments() + { + genericMidiInstrument = new MidiInstrument(QWidget::tr("generic midi")); + midiInstruments.push_back(genericMidiInstrument); + if (debugMsg) + printf("load user instrument definitions from <%s>\n", museUserInstruments.latin1()); + QDir usrInstrumentsDir(museUserInstruments, QString("*.idf")); + if (usrInstrumentsDir.exists()) { + QFileInfoList list = usrInstrumentsDir.entryInfoList(); + QFileInfoList::iterator it=list.begin(); // ddskrjo + while(it != list.end()) { // ddskrjo + loadIDF(&*it); + ++it; + } + } + //else + //{ + // if(usrInstrumentsDir.mkdir(museUserInstruments)) + // printf("Created user instrument directory: %s\n", museUserInstruments.latin1()); + // else + // printf("Unable to create user instrument directory: %s\n", museUserInstruments.latin1()); + //} + + if (debugMsg) + printf("load instrument definitions from <%s>\n", museInstruments.latin1()); + QDir instrumentsDir(museInstruments, QString("*.idf")); + if (instrumentsDir.exists()) { + QFileInfoList list = instrumentsDir.entryInfoList(); + QFileInfoListIterator it=list.begin(); // ddskrjo + while(it!=list.end()) { + loadIDF(&*it); + ++it; + } + } + else + printf("Instrument directory not found: %s\n", museInstruments.latin1()); + + } + +//--------------------------------------------------------- +// registerMidiInstrument +//--------------------------------------------------------- + +MidiInstrument* registerMidiInstrument(const QString& name) + { + for (iMidiInstrument i = midiInstruments.begin(); + i != midiInstruments.end(); ++i) { + if ((*i)->iname() == name) + return *i; + } + return genericMidiInstrument; + } + +//--------------------------------------------------------- +// removeMidiInstrument +//--------------------------------------------------------- + +void removeMidiInstrument(const QString& name) + { + for (iMidiInstrument i = midiInstruments.begin(); + i != midiInstruments.end(); ++i) { + if ((*i)->iname() == name) { + midiInstruments.erase(i); + return; + } + } + } + +void removeMidiInstrument(const MidiInstrument* instr) + { + for (iMidiInstrument i = midiInstruments.begin(); + i != midiInstruments.end(); ++i) { + if (*i == instr) { + midiInstruments.erase(i); + return; + } + } + } + +//--------------------------------------------------------- +// MidiInstrument +//--------------------------------------------------------- + +void MidiInstrument::init() + { + _nullvalue = -1; + _initScript = 0; + _midiInit = new EventList(); + _midiReset = new EventList(); + _midiState = new EventList(); + _controller = new MidiControllerList; + + // add some default controller to controller list + // this controllers are always available for all instruments + // + MidiController* prog = new MidiController("Program", CTRL_PROGRAM, 0, 0xffffff, 0); + _controller->add(prog); + _dirty = false; + } + +MidiInstrument::MidiInstrument() + { + init(); + } + +//--------------------------------------------------------- +// MidiInstrument +//--------------------------------------------------------- + +MidiInstrument::MidiInstrument(const QString& txt) + { + _name = txt; + init(); + } + +//--------------------------------------------------------- +// MidiInstrument +//--------------------------------------------------------- + +MidiInstrument::~MidiInstrument() + { + for (ciPatchGroup g = pg.begin(); g != pg.end(); ++g) + { + PatchGroup* pgp = *g; + const PatchList& pl = pgp->patches; + for (ciPatch p = pl.begin(); p != pl.end(); ++p) + { + delete *p; + } + delete pgp; + } + + + delete _midiInit; + delete _midiReset; + delete _midiState; + for(iMidiController i = _controller->begin(); i != _controller->end(); ++i) + delete i->second; + delete _controller; + + if (_initScript) + delete _initScript; + } + +/* +//--------------------------------------------------------- +// uniqueCopy +//--------------------------------------------------------- + +MidiInstrument& MidiInstrument::uniqueCopy(const MidiInstrument& ins) +{ + _initScript = 0; + _midiInit = new EventList(); + _midiReset = new EventList(); + _midiState = new EventList(); + //--------------------------------------------------------- + // TODO: Copy the init script, and the lists. + //--------------------------------------------------------- + _controller = new MidiControllerList(*(ins._controller)); + + // Assignment + pg = ins.pg; + + _name = ins._name; + _filePath = ins._filePath; + + // Hmm, dirty, yes? But init sets it to false... + //_dirty = ins._dirty; + //_dirty = false; + _dirty = true; + + return *this; +} +*/ + +//--------------------------------------------------------- +// assign +//--------------------------------------------------------- + +MidiInstrument& MidiInstrument::assign(const MidiInstrument& ins) +{ + //--------------------------------------------------------- + // TODO: Copy the _initScript, and _midiInit, _midiReset, and _midiState lists. + //--------------------------------------------------------- + + for(iMidiController i = _controller->begin(); i != _controller->end(); ++i) + delete i->second; + _controller->clear(); + + _nullvalue = ins._nullvalue; + + // Assignment + // *_controller = *(ins._controller); + for(ciMidiController i = ins._controller->begin(); i != ins._controller->end(); ++i) + { + MidiController* mc = i->second; + _controller->add(new MidiController(*mc)); + } + +// pg.clear(); +// for(iPatchGroup ipg = pg.begin(); ipg != pg.end(); ++ipg) +// { + //ipg->patches.clear(); + + //const PatchGroup& g = *ipg; + //for(ciPatch ip = ipg->begin(); ip != ipg->end(); ++ipg) + //{ + + //} +// } + + for (ciPatchGroup g = pg.begin(); g != pg.end(); ++g) + { + PatchGroup* pgp = *g; + const PatchList& pl = pgp->patches; + for (ciPatch p = pl.begin(); p != pl.end(); ++p) + { + delete *p; + } + + delete pgp; + } + pg.clear(); + + // Assignment +// pg = ins.pg; + for(ciPatchGroup g = ins.pg.begin(); g != ins.pg.end(); ++g) + { + PatchGroup* pgp = *g; + const PatchList& pl = pgp->patches; + PatchGroup* npg = new PatchGroup; + npg->name = pgp->name; + pg.push_back(npg); + for (ciPatch p = pl.begin(); p != pl.end(); ++p) + { + Patch* pp = *p; + Patch* np = new Patch; + np->typ = pp->typ; + np->hbank = pp->hbank; + np->lbank = pp->lbank; + np->prog = pp->prog; + np->name = pp->name; + np->drum = pp->drum; + npg->patches.push_back(np); + } + } + + _name = ins._name; + _filePath = ins._filePath; + + // Hmm, dirty, yes? But init sets it to false... + //_dirty = ins._dirty; + //_dirty = false; + //_dirty = true; + + return *this; +} + +//--------------------------------------------------------- +// reset +// send note off to all channels +//--------------------------------------------------------- + +void MidiInstrument::reset(int portNo, MType) + { + MidiPlayEvent ev; + ev.setType(0x90); + MidiPort* port = &midiPorts[portNo]; + if (port == 0) + return; + ev.setPort(portNo); + for (int chan = 0; chan < MIDI_CHANNELS; ++chan) { + ev.setChannel(chan); + for (int pitch = 0; pitch < 128; ++pitch) { + ev.setA(pitch); + ev.setB(0); + port->sendEvent(ev); + } + } + } + +//--------------------------------------------------------- +// readPatchGroup +//--------------------------------------------------------- + +void PatchGroup::read(Xml& xml) + { + for (;;) { + Xml::Token token = xml.parse(); + const QString& tag = xml.s1(); + switch (token) { + case Xml::Error: + case Xml::End: + return; + case Xml::TagStart: + if (tag == "Patch") { + Patch* patch = new Patch; + patch->read(xml); + patches.push_back(patch); + } + else + xml.unknown("PatchGroup"); + break; + case Xml::Attribut: + if (tag == "name") + name = xml.s2(); + break; + case Xml::TagEnd: + if (tag == "PatchGroup") + return; + default: + break; + } + } + } + +//--------------------------------------------------------- +// read +//--------------------------------------------------------- + +void Patch::read(Xml& xml) + { + typ = -1; + hbank = -1; + lbank = -1; + prog = 0; + drum = false; + for (;;) { + Xml::Token token = xml.parse(); + const QString& tag = xml.s1(); + switch (token) { + case Xml::Error: + case Xml::End: + return; + case Xml::TagStart: + xml.unknown("Patch"); + break; + case Xml::Attribut: + if (tag == "name") + name = xml.s2(); + else if (tag == "mode") + typ = xml.s2().toInt(); + else if (tag == "hbank") + hbank = xml.s2().toInt(); + else if (tag == "lbank") + lbank = xml.s2().toInt(); + else if (tag == "prog") + prog = xml.s2().toInt(); + else if (tag == "drum") + drum = xml.s2().toInt(); + break; + case Xml::TagEnd: + if (tag == "Patch") + return; + default: + break; + } + } + } + +//--------------------------------------------------------- +// write +//--------------------------------------------------------- + +void Patch::write(int level, Xml& xml) + { + //if (drumMap == 0) + //{ + //QString s = QString("Patch name=\"%1\"").arg(Xml::xmlString(name)); + //if (typ != -1) + // s += QString(" mode=\"%d\"").arg(typ); + //s += QString(" hbank=\"%1\" lbank=\"%2\" prog=\"%3\"").arg(hbank).arg(lbank).arg(prog); + //xml.tagE(s); + xml.nput(level, "<Patch name=\"%s\"", Xml::xmlString(name).latin1()); + if(typ != -1) + xml.nput(" mode=\"%d\"", typ); + + if(hbank != -1) + xml.nput(" hbank=\"%d\"", hbank); + + if(lbank != -1) + xml.nput(" lbank=\"%d\"", lbank); + + xml.nput(" prog=\"%d\"", prog); + + //xml.nput(level, " hbank=\"%d\" lbank=\"%d\" prog=\"%d\"", hbank, lbank, prog); + if(drum) + //xml.nput(level, " drum=\"%d\"", int(drum)); + xml.nput(" drum=\"%d\"", int(drum)); + //xml.put(level, " />"); + xml.put(" />"); + + //return; + //} + + //QString s = QString("drummap name=\"%1\"").arg(Xml::xmlString(name)); + //s += QString(" hbank=\"%1\" lbank=\"%2\" prog=\"%3\"").arg(hbank).arg(lbank).arg(prog); + //xml.stag(s); + //for (int i = 0; i < DRUM_MAPSIZE; ++i) { + // DrumMapEntry* dm = drumMap->entry(i); + // dm->write(xml); + // } + //xml.etag("drummap"); + } + +//--------------------------------------------------------- +// readMidiState +//--------------------------------------------------------- + +void MidiInstrument::readMidiState(Xml& xml) + { + _midiState->read(xml, "midistate", true); + } + +//--------------------------------------------------------- +// read +//--------------------------------------------------------- + +void MidiInstrument::read(Xml& xml) + { + bool ok; + int base = 10; + _nullvalue = -1; + for (;;) { + Xml::Token token = xml.parse(); + const QString& tag = xml.s1(); + switch (token) { + case Xml::Error: + case Xml::End: + return; + case Xml::TagStart: + if (tag == "Patch") { + Patch* patch = new Patch; + patch->read(xml); + if (pg.empty()) { + PatchGroup* p = new PatchGroup; + p->patches.push_back(patch); + pg.push_back(p); + } + else + pg[0]->patches.push_back(patch); + } + else if (tag == "PatchGroup") { + PatchGroup* p = new PatchGroup; + p->read(xml); + pg.push_back(p); + } + else if (tag == "Controller") { + MidiController* mc = new MidiController(); + mc->read(xml); + // Added by Tim. Copied from muse 2. + // + // HACK: make predefined "Program" controller overloadable + // + if (mc->name() == "Program") { + for (iMidiController i = _controller->begin(); i != _controller->end(); ++i) { + if (i->second->name() == mc->name()) { + delete i->second; + _controller->erase(i); + break; + } + } + } + + _controller->add(mc); + } + else if (tag == "Init") + readEventList(xml, _midiInit, "Init"); + else if (tag == "Reset") + readEventList(xml, _midiReset, "Reset"); + else if (tag == "State") + readEventList(xml, _midiState, "State"); + else if (tag == "InitScript") { + if (_initScript) + delete _initScript; + const char* istr = xml.parse1().latin1(); + int len = strlen(istr) +1; + if (len > 1) { + _initScript = new char[len]; + memcpy(_initScript, istr, len); + } + } + + else + xml.unknown("MidiInstrument"); + break; + case Xml::Attribut: + if (tag == "name") + setIName(xml.s2()); + else if(tag == "nullparam") { + _nullvalue = xml.s2().toInt(&ok, base); + } + break; + case Xml::TagEnd: + if (tag == "MidiInstrument") + return; + default: + break; + } + } + } + +//--------------------------------------------------------- +// write +//--------------------------------------------------------- + +void MidiInstrument::write(int level, Xml& xml) + { + xml.header(); + //xml.stag("muse version=\"2.1\""); + xml.tag(level, "muse version=\"1.0\""); + //xml.stag(QString("MidiInstrument name=\"%1\"").arg(Xml::xmlString(iname()))); + level++; + //xml.tag(level, "MidiInstrument name=\"%s\"", Xml::xmlString(iname()).latin1()); + xml.nput(level, "<MidiInstrument name=\"%s\"", Xml::xmlString(iname()).latin1()); + + if(_nullvalue != -1) + { + QString nv; + nv.setNum(_nullvalue); + xml.nput(" nullparam=\"%s\"", nv.latin1()); + } + xml.put(">"); + + // ------------- + // What about Init, Reset, State, and InitScript ? + // ------------- + + //std::vector<PatchGroup>* pg = groups(); + //for (std::vector<PatchGroup>::iterator g = pg->begin(); g != pg->end(); ++g) { + level++; + //for (std::vector<PatchGroup>::iterator g = pg.begin(); g != pg.end(); ++g) { + for (ciPatchGroup g = pg.begin(); g != pg.end(); ++g) { + PatchGroup* pgp = *g; + const PatchList& pl = pgp->patches; + //xml.stag(QString("PatchGroup name=\"%1\"").arg(Xml::xmlString(g->name))); + //xml.tag(level, "PatchGroup name=\"%s\"", Xml::xmlString(g->name).latin1()); + xml.tag(level, "PatchGroup name=\"%s\"", Xml::xmlString(pgp->name).latin1()); + level++; + //for (iPatch p = g->patches.begin(); p != g->patches.end(); ++p) + for (ciPatch p = pl.begin(); p != pl.end(); ++p) + //(*p)->write(xml); + //p->write(level, xml); + (*p)->write(level, xml); + level--; + //xml.etag("PatchGroup"); + xml.etag(level, "PatchGroup"); + } + for (iMidiController ic = _controller->begin(); ic != _controller->end(); ++ic) + //(*ic)->write(xml); + ic->second->write(level, xml); + //xml.etag("MidiInstrument"); + level--; + xml.etag(level, "MidiInstrument"); + //xml.etag("muse"); + level--; + xml.etag(level, "muse"); + } + +//--------------------------------------------------------- +// getPatchName +//--------------------------------------------------------- + +const char* MidiInstrument::getPatchName(int channel, int prog, MType mode, bool drum) + { + int pr = prog & 0xff; + if(prog == CTRL_VAL_UNKNOWN || pr == 0xff) + return "<unknown>"; + + int hbank = (prog >> 16) & 0xff; + int lbank = (prog >> 8) & 0xff; + int tmask = 1; + bool drumchan = channel == 9; + bool hb = false; + bool lb = false; + switch (mode) { + case MT_GS: + tmask = 2; + hb = true; + break; + case MT_XG: + hb = true; + lb = true; + tmask = 4; + break; + case MT_GM: + if(drumchan) + return gmdrumname; + tmask = 1; + break; + default: + hb = true; // MSB bank matters + lb = true; // LSB bank matters + break; + } + for (ciPatchGroup i = pg.begin(); i != pg.end(); ++i) { + const PatchList& pl = (*i)->patches; + for (ciPatch ipl = pl.begin(); ipl != pl.end(); ++ipl) { + const Patch* mp = *ipl; + if ((mp->typ & tmask) + && (pr == mp->prog) + && ((drum && mode != MT_GM) || + (mp->drum == drumchan)) + + && (hbank == mp->hbank || !hb || mp->hbank == -1) + && (lbank == mp->lbank || !lb || mp->lbank == -1)) + return mp->name.latin1(); + } + } + return "<unknown>"; + } + +//--------------------------------------------------------- +// populatePatchPopup +//--------------------------------------------------------- + +void MidiInstrument::populatePatchPopup(Q3PopupMenu* menu, int chan, MType songType, bool drum) + { + menu->clear(); + int mask = 0; + bool drumchan = chan == 9; + switch (songType) { + case MT_XG: mask = 4; break; + case MT_GS: mask = 2; break; + case MT_GM: + if(drumchan) + return; + mask = 1; + break; + case MT_UNKNOWN: mask = 7; break; + } + if (pg.size() > 1) { + for (ciPatchGroup i = pg.begin(); i != pg.end(); ++i) { + PatchGroup* pgp = *i; + Q3PopupMenu* pm = new Q3PopupMenu(menu); + pm->setCheckable(false); + pm->setFont(config.fonts[0]); + const PatchList& pl = pgp->patches; + for (ciPatch ipl = pl.begin(); ipl != pl.end(); ++ipl) { + const Patch* mp = *ipl; + if ((mp->typ & mask) && + ((drum && songType != MT_GM) || + (mp->drum == drumchan)) ) + { + int id = ((mp->hbank & 0xff) << 16) + + ((mp->lbank & 0xff) << 8) + (mp->prog & 0xff); + pm->insertItem(mp->name, id); + } + + } + menu->insertItem(pgp->name, pm); + } + } + else if (pg.size() == 1 ){ + // no groups + const PatchList& pl = pg.front()->patches; + for (ciPatch ipl = pl.begin(); ipl != pl.end(); ++ipl) { + const Patch* mp = *ipl; + if (mp->typ & mask) { + int id = ((mp->hbank & 0xff) << 16) + + ((mp->lbank & 0xff) << 8) + (mp->prog & 0xff); + menu->insertItem(mp->name, id); + } + } + } + } + diff --git a/muse2/muse/instruments/minstrument.h b/muse2/muse/instruments/minstrument.h new file mode 100644 index 00000000..70c123ec --- /dev/null +++ b/muse2/muse/instruments/minstrument.h @@ -0,0 +1,135 @@ +//========================================================= +// MusE +// Linux Music Editor +// $Id: minstrument.h,v 1.3.2.3 2009/03/09 02:05:18 terminator356 Exp $ +// +// (C) Copyright 2000 Werner Schweer (ws@seh.de) +//========================================================= + +#ifndef __MINSTRUMENT_H__ +#define __MINSTRUMENT_H__ + +#include "globaldefs.h" +#include <list> +#include <vector> +//Added by qt3to4: +#include <Q3PopupMenu> + +class MidiPort; +class Q3PopupMenu; +class MidiPlayEvent; +class Xml; +class EventList; +class MidiControllerList; +class QString; + +//--------------------------------------------------------- +// Patch +//--------------------------------------------------------- + +struct Patch { + signed char typ; // 1 - GM 2 - GS 4 - XG + signed char hbank, lbank, prog; + QString name; + bool drum; + void read(Xml&); + void write(int level, Xml&); + }; + +typedef std::list<Patch*> PatchList; +typedef PatchList::iterator iPatch; +typedef PatchList::const_iterator ciPatch; + +//--------------------------------------------------------- +// PatchGroup +//--------------------------------------------------------- + +struct PatchGroup { + QString name; + PatchList patches; + void read(Xml&); + }; + +typedef std::vector<PatchGroup*> PatchGroupList; +typedef PatchGroupList::iterator iPatchGroup; +typedef PatchGroupList::const_iterator ciPatchGroup; + +//--------------------------------------------------------- +// MidiInstrument +//--------------------------------------------------------- + +class MidiInstrument { + PatchGroupList pg; + MidiControllerList* _controller; + bool _dirty; + int _nullvalue; + + void init(); + + protected: + EventList* _midiInit; + EventList* _midiReset; + EventList* _midiState; + char* _initScript; + QString _name; + QString _filePath; + + public: + MidiInstrument(); + virtual ~MidiInstrument(); + MidiInstrument(const QString& txt); + const QString& iname() const { return _name; } + void setIName(const QString& txt) { _name = txt; } + + //MidiInstrument& uniqueCopy(const MidiInstrument&); + // Assign will 'delete' all existing patches and groups from the instrument. + MidiInstrument& assign(const MidiInstrument&); + QString filePath() const { return _filePath; } + void setFilePath(const QString& s) { _filePath = s; } + bool dirty() const { return _dirty; } + void setDirty(bool v) { _dirty = v; } + + + EventList* midiInit() const { return _midiInit; } + EventList* midiReset() const { return _midiReset; } + EventList* midiState() const { return _midiState; } + const char* initScript() const { return _initScript; } + MidiControllerList* controller() const { return _controller; } + int nullSendValue() { return _nullvalue; } + void setNullSendValue(int v) { _nullvalue = v; } + + void readMidiState(Xml& xml); + virtual bool guiVisible() const { return false; } + virtual void showGui(bool) {} + virtual bool hasGui() const { return false; } + virtual void writeToGui(const MidiPlayEvent&) {} + + virtual void reset(int, MType); + virtual const char* getPatchName(int,int,MType,bool); + virtual void populatePatchPopup(Q3PopupMenu*, int, MType, bool); + void read(Xml&); + void write(int level, Xml&); + PatchGroupList* groups() { return &pg; } + }; + +//--------------------------------------------------------- +// MidiInstrumentList +//--------------------------------------------------------- + +class MidiInstrumentList : public std::list<MidiInstrument*> { + + public: + MidiInstrumentList() {} + }; + +typedef MidiInstrumentList::iterator iMidiInstrument; + +extern MidiInstrumentList midiInstruments; +extern MidiInstrument* genericMidiInstrument; +extern void initMidiInstruments(); +extern MidiInstrument* registerMidiInstrument(const QString&); +extern void removeMidiInstrument(const QString& name); +extern void removeMidiInstrument(const MidiInstrument* instr); + +#endif + |