summaryrefslogtreecommitdiff
path: root/muse_qt4_evolution/muse
diff options
context:
space:
mode:
Diffstat (limited to 'muse_qt4_evolution/muse')
-rw-r--r--muse_qt4_evolution/muse/CMakeLists.txt226
-rw-r--r--muse_qt4_evolution/muse/aboutbox.ui612
-rw-r--r--muse_qt4_evolution/muse/arranger.cpp1382
-rw-r--r--muse_qt4_evolution/muse/arranger.h175
-rw-r--r--muse_qt4_evolution/muse/astrip.cpp791
-rw-r--r--muse_qt4_evolution/muse/astrip.h101
-rw-r--r--muse_qt4_evolution/muse/audio.cpp655
-rw-r--r--muse_qt4_evolution/muse/audio.h306
-rw-r--r--muse_qt4_evolution/muse/audiodev.h57
-rw-r--r--muse_qt4_evolution/muse/audiogroup.cpp47
-rw-r--r--muse_qt4_evolution/muse/audiogroup.h46
-rw-r--r--muse_qt4_evolution/muse/audioinput.cpp131
-rw-r--r--muse_qt4_evolution/muse/audioinput.h53
-rw-r--r--muse_qt4_evolution/muse/audiooutput.cpp191
-rw-r--r--muse_qt4_evolution/muse/audiooutput.h55
-rw-r--r--muse_qt4_evolution/muse/audioprefetch.cpp199
-rw-r--r--muse_qt4_evolution/muse/audioprefetch.h54
-rw-r--r--muse_qt4_evolution/muse/audiotrack.cpp582
-rw-r--r--muse_qt4_evolution/muse/audiotrack.h105
-rw-r--r--muse_qt4_evolution/muse/audiowriteback.cpp101
-rw-r--r--muse_qt4_evolution/muse/audiowriteback.h44
-rw-r--r--muse_qt4_evolution/muse/auxplugin.cpp190
-rw-r--r--muse_qt4_evolution/muse/auxplugin.h84
-rw-r--r--muse_qt4_evolution/muse/canvas.cpp1187
-rw-r--r--muse_qt4_evolution/muse/canvas.h124
-rw-r--r--muse_qt4_evolution/muse/cliplist/cliplist.cpp251
-rw-r--r--muse_qt4_evolution/muse/cliplist/cliplist.h47
-rw-r--r--muse_qt4_evolution/muse/cobject.cpp55
-rw-r--r--muse_qt4_evolution/muse/cobject.h46
-rw-r--r--muse_qt4_evolution/muse/conf.cpp694
-rw-r--r--muse_qt4_evolution/muse/conf.h46
-rw-r--r--muse_qt4_evolution/muse/configmidifile.ui153
-rw-r--r--muse_qt4_evolution/muse/configtrack.cpp265
-rw-r--r--muse_qt4_evolution/muse/configtrack.h61
-rw-r--r--muse_qt4_evolution/muse/configtrack.ui299
-rw-r--r--muse_qt4_evolution/muse/ctrl.cpp450
-rw-r--r--muse_qt4_evolution/muse/ctrl.h236
-rw-r--r--muse_qt4_evolution/muse/ctrl/CMakeLists.txt46
-rw-r--r--muse_qt4_evolution/muse/ctrl/configmidictrl.cpp202
-rw-r--r--muse_qt4_evolution/muse/ctrl/configmidictrl.h51
-rw-r--r--muse_qt4_evolution/muse/ctrl/configmidictrl.ui204
-rw-r--r--muse_qt4_evolution/muse/ctrl/ctrldialog.cpp191
-rw-r--r--muse_qt4_evolution/muse/ctrl/ctrldialog.h49
-rw-r--r--muse_qt4_evolution/muse/ctrl/ctrldialog.ui126
-rw-r--r--muse_qt4_evolution/muse/ctrl/ctrledit.cpp184
-rw-r--r--muse_qt4_evolution/muse/ctrl/ctrledit.h76
-rw-r--r--muse_qt4_evolution/muse/ctrl/ctrleditor.cpp492
-rw-r--r--muse_qt4_evolution/muse/ctrl/ctrleditor.h76
-rw-r--r--muse_qt4_evolution/muse/ctrl/definemidictrl.cpp110
-rw-r--r--muse_qt4_evolution/muse/ctrl/definemidictrl.h51
-rw-r--r--muse_qt4_evolution/muse/ctrl/definemidictrl.ui285
-rw-r--r--muse_qt4_evolution/muse/debug.h44
-rw-r--r--muse_qt4_evolution/muse/default_click.h1213
-rw-r--r--muse_qt4_evolution/muse/device.h56
-rw-r--r--muse_qt4_evolution/muse/driver.h64
-rw-r--r--muse_qt4_evolution/muse/dssihost.cpp891
-rw-r--r--muse_qt4_evolution/muse/dssihost.h121
-rw-r--r--muse_qt4_evolution/muse/dummyaudio.cpp294
-rw-r--r--muse_qt4_evolution/muse/editor.cpp38
-rw-r--r--muse_qt4_evolution/muse/editor.h44
-rw-r--r--muse_qt4_evolution/muse/esettings.cpp773
-rw-r--r--muse_qt4_evolution/muse/esettings.h361
-rw-r--r--muse_qt4_evolution/muse/evdata.h85
-rw-r--r--muse_qt4_evolution/muse/event.cpp222
-rw-r--r--muse_qt4_evolution/muse/event.h139
-rw-r--r--muse_qt4_evolution/muse/eventbase.h100
-rw-r--r--muse_qt4_evolution/muse/eventlist.cpp93
-rw-r--r--muse_qt4_evolution/muse/exportmidi.cpp376
-rw-r--r--muse_qt4_evolution/muse/exportmidi.h41
-rw-r--r--muse_qt4_evolution/muse/exportmididialog.ui176
-rw-r--r--muse_qt4_evolution/muse/extmidieditor.cpp422
-rw-r--r--muse_qt4_evolution/muse/extmidieditor.h120
-rw-r--r--muse_qt4_evolution/muse/fastlog.h38
-rw-r--r--muse_qt4_evolution/muse/fifo.cpp183
-rw-r--r--muse_qt4_evolution/muse/fifo.h105
-rw-r--r--muse_qt4_evolution/muse/gconfig.cpp121
-rw-r--r--muse_qt4_evolution/muse/gconfig.h133
-rw-r--r--muse_qt4_evolution/muse/globaldefs.h37
-rw-r--r--muse_qt4_evolution/muse/globals.cpp133
-rw-r--r--muse_qt4_evolution/muse/globals.h86
-rw-r--r--muse_qt4_evolution/muse/gui.h54
-rw-r--r--muse_qt4_evolution/muse/help.cpp101
-rw-r--r--muse_qt4_evolution/muse/help.h36
-rw-r--r--muse_qt4_evolution/muse/helper.cpp47
-rw-r--r--muse_qt4_evolution/muse/helper.h27
-rw-r--r--muse_qt4_evolution/muse/icons.cpp341
-rw-r--r--muse_qt4_evolution/muse/icons.h134
-rw-r--r--muse_qt4_evolution/muse/importmidi.cpp589
-rw-r--r--muse_qt4_evolution/muse/importmidi.h46
-rw-r--r--muse_qt4_evolution/muse/importmidi.ui200
-rw-r--r--muse_qt4_evolution/muse/instruments/CMakeLists.txt41
-rw-r--r--muse_qt4_evolution/muse/instruments/editinstrument.cpp844
-rw-r--r--muse_qt4_evolution/muse/instruments/editinstrument.h70
-rw-r--r--muse_qt4_evolution/muse/instruments/editinstrument.ui998
-rw-r--r--muse_qt4_evolution/muse/instruments/midictrledit.cpp418
-rw-r--r--muse_qt4_evolution/muse/instruments/midictrledit.h58
-rw-r--r--muse_qt4_evolution/muse/instruments/minstrument.cpp631
-rw-r--r--muse_qt4_evolution/muse/instruments/minstrument.h160
-rw-r--r--muse_qt4_evolution/muse/jack.cpp886
-rw-r--r--muse_qt4_evolution/muse/jackaudio.h90
-rw-r--r--muse_qt4_evolution/muse/ladspa.h599
-rw-r--r--muse_qt4_evolution/muse/ladspaplugin.cpp235
-rw-r--r--muse_qt4_evolution/muse/ladspaplugin.h127
-rw-r--r--muse_qt4_evolution/muse/liste/CMakeLists.txt48
-rw-r--r--muse_qt4_evolution/muse/liste/ctrllistedit.cpp569
-rw-r--r--muse_qt4_evolution/muse/liste/ctrllistedit.h96
-rw-r--r--muse_qt4_evolution/muse/liste/ctrllistedit.ui334
-rw-r--r--muse_qt4_evolution/muse/liste/ieventdialog.cpp428
-rw-r--r--muse_qt4_evolution/muse/liste/ieventdialog.h117
-rw-r--r--muse_qt4_evolution/muse/liste/listedit.cpp298
-rw-r--r--muse_qt4_evolution/muse/liste/listedit.h98
-rw-r--r--muse_qt4_evolution/muse/liste/partlistedit.cpp434
-rw-r--r--muse_qt4_evolution/muse/liste/partlistedit.h79
-rw-r--r--muse_qt4_evolution/muse/liste/partlistedit.ui166
-rw-r--r--muse_qt4_evolution/muse/liste/tracklistedit.cpp65
-rw-r--r--muse_qt4_evolution/muse/liste/tracklistedit.h50
-rw-r--r--muse_qt4_evolution/muse/liste/tracklistedit.ui146
-rw-r--r--muse_qt4_evolution/muse/marker/CMakeLists.txt45
-rw-r--r--muse_qt4_evolution/muse/marker/markerview.cpp413
-rw-r--r--muse_qt4_evolution/muse/marker/markerview.h98
-rw-r--r--muse_qt4_evolution/muse/master/CMakeLists.txt37
-rw-r--r--muse_qt4_evolution/muse/master/master.cpp233
-rw-r--r--muse_qt4_evolution/muse/master/master.h63
-rw-r--r--muse_qt4_evolution/muse/master/masteredit.cpp302
-rw-r--r--muse_qt4_evolution/muse/master/masteredit.h107
-rw-r--r--muse_qt4_evolution/muse/midi.cpp633
-rw-r--r--muse_qt4_evolution/muse/midi.h68
-rw-r--r--muse_qt4_evolution/muse/midictrl.cpp372
-rw-r--r--muse_qt4_evolution/muse/midictrl.h168
-rw-r--r--muse_qt4_evolution/muse/midiedit/CMakeLists.txt71
-rw-r--r--muse_qt4_evolution/muse/midiedit/citem.cpp82
-rw-r--r--muse_qt4_evolution/muse/midiedit/citem.h70
-rw-r--r--muse_qt4_evolution/muse/midiedit/cmd.h32
-rw-r--r--muse_qt4_evolution/muse/midiedit/dcanvas.cpp723
-rw-r--r--muse_qt4_evolution/muse/midiedit/dcanvas.h77
-rw-r--r--muse_qt4_evolution/muse/midiedit/drumedit.cpp450
-rw-r--r--muse_qt4_evolution/muse/midiedit/drumedit.h93
-rw-r--r--muse_qt4_evolution/muse/midiedit/drummap.cpp219
-rw-r--r--muse_qt4_evolution/muse/midiedit/drummap.h81
-rw-r--r--muse_qt4_evolution/muse/midiedit/ecanvas.cpp1549
-rw-r--r--muse_qt4_evolution/muse/midiedit/ecanvas.h173
-rw-r--r--muse_qt4_evolution/muse/midiedit/gatetime.cpp105
-rw-r--r--muse_qt4_evolution/muse/midiedit/gatetime.h62
-rw-r--r--muse_qt4_evolution/muse/midiedit/gatetime.ui85
-rw-r--r--muse_qt4_evolution/muse/midiedit/midicmd.cpp135
-rw-r--r--muse_qt4_evolution/muse/midiedit/midicmd.h81
-rw-r--r--muse_qt4_evolution/muse/midiedit/midicmd.ui76
-rw-r--r--muse_qt4_evolution/muse/midiedit/midieditor.cpp444
-rw-r--r--muse_qt4_evolution/muse/midiedit/midieditor.h147
-rw-r--r--muse_qt4_evolution/muse/midiedit/miditracker.cpp234
-rw-r--r--muse_qt4_evolution/muse/midiedit/miditracker.h76
-rw-r--r--muse_qt4_evolution/muse/midiedit/pianoroll.cpp526
-rw-r--r--muse_qt4_evolution/muse/midiedit/pianoroll.h126
-rw-r--r--muse_qt4_evolution/muse/midiedit/prcanvas.cpp773
-rw-r--r--muse_qt4_evolution/muse/midiedit/prcanvas.h75
-rw-r--r--muse_qt4_evolution/muse/midiedit/quantconfig.cpp68
-rw-r--r--muse_qt4_evolution/muse/midiedit/quantconfig.h42
-rw-r--r--muse_qt4_evolution/muse/midiedit/quantconfig.ui151
-rw-r--r--muse_qt4_evolution/muse/midiedit/trackpattern.cpp627
-rw-r--r--muse_qt4_evolution/muse/midiedit/trackpattern.h261
-rw-r--r--muse_qt4_evolution/muse/midiedit/velocity.cpp108
-rw-r--r--muse_qt4_evolution/muse/midiedit/velocity.h62
-rw-r--r--muse_qt4_evolution/muse/midiedit/velocity.ui86
-rw-r--r--muse_qt4_evolution/muse/midievent.cpp129
-rw-r--r--muse_qt4_evolution/muse/midievent.h100
-rw-r--r--muse_qt4_evolution/muse/midieventbase.cpp159
-rw-r--r--muse_qt4_evolution/muse/midieventbase.h76
-rw-r--r--muse_qt4_evolution/muse/midififo.cpp103
-rw-r--r--muse_qt4_evolution/muse/midififo.h92
-rw-r--r--muse_qt4_evolution/muse/midifile.cpp673
-rw-r--r--muse_qt4_evolution/muse/midifile.h121
-rw-r--r--muse_qt4_evolution/muse/midiinport.cpp241
-rw-r--r--muse_qt4_evolution/muse/midiinport.h67
-rw-r--r--muse_qt4_evolution/muse/midiout.cpp398
-rw-r--r--muse_qt4_evolution/muse/midiout.h67
-rw-r--r--muse_qt4_evolution/muse/midioutport.cpp262
-rw-r--r--muse_qt4_evolution/muse/midioutport.h70
-rw-r--r--muse_qt4_evolution/muse/midiplugin.cpp625
-rw-r--r--muse_qt4_evolution/muse/midiplugin.h168
-rw-r--r--muse_qt4_evolution/muse/midiportinfo.ui92
-rw-r--r--muse_qt4_evolution/muse/midirack.cpp208
-rw-r--r--muse_qt4_evolution/muse/midirack.h48
-rw-r--r--muse_qt4_evolution/muse/midirc.cpp180
-rw-r--r--muse_qt4_evolution/muse/midirc.h65
-rw-r--r--muse_qt4_evolution/muse/midisynti.cpp225
-rw-r--r--muse_qt4_evolution/muse/midisynti.h62
-rw-r--r--muse_qt4_evolution/muse/miditrack.cpp716
-rw-r--r--muse_qt4_evolution/muse/miditrack.h127
-rw-r--r--muse_qt4_evolution/muse/miditrackbase.cpp136
-rw-r--r--muse_qt4_evolution/muse/miditrackbase.h53
-rw-r--r--muse_qt4_evolution/muse/miditrackinfo.ui292
-rw-r--r--muse_qt4_evolution/muse/miditransform.cpp1534
-rw-r--r--muse_qt4_evolution/muse/miditransform.h113
-rw-r--r--muse_qt4_evolution/muse/mixer.cpp397
-rw-r--r--muse_qt4_evolution/muse/mixer.h95
-rw-r--r--muse_qt4_evolution/muse/mstrip.cpp1211
-rw-r--r--muse_qt4_evolution/muse/mstrip.h191
-rw-r--r--muse_qt4_evolution/muse/mtc.cpp131
-rw-r--r--muse_qt4_evolution/muse/mtc.h68
-rw-r--r--muse_qt4_evolution/muse/muse.cpp3029
-rw-r--r--muse_qt4_evolution/muse/muse.h318
-rw-r--r--muse_qt4_evolution/muse/muse.qrc85
-rw-r--r--muse_qt4_evolution/muse/part.cpp361
-rw-r--r--muse_qt4_evolution/muse/part.h151
-rw-r--r--muse_qt4_evolution/muse/partdrag.cpp199
-rw-r--r--muse_qt4_evolution/muse/partdrag.h69
-rw-r--r--muse_qt4_evolution/muse/pipeline.cpp221
-rw-r--r--muse_qt4_evolution/muse/pipeline.h59
-rw-r--r--muse_qt4_evolution/muse/plugin.cpp466
-rw-r--r--muse_qt4_evolution/muse/plugin.h218
-rw-r--r--muse_qt4_evolution/muse/plugingui.cpp770
-rw-r--r--muse_qt4_evolution/muse/plugingui.h122
-rw-r--r--muse_qt4_evolution/muse/port.h76
-rw-r--r--muse_qt4_evolution/muse/preferences.cpp932
-rw-r--r--muse_qt4_evolution/muse/preferences.h79
-rw-r--r--muse_qt4_evolution/muse/preferences.ui2400
-rw-r--r--muse_qt4_evolution/muse/projectdialog.cpp471
-rw-r--r--muse_qt4_evolution/muse/projectdialog.h73
-rw-r--r--muse_qt4_evolution/muse/projectdialog.ui269
-rw-r--r--muse_qt4_evolution/muse/projectpropsdialog.cpp64
-rw-r--r--muse_qt4_evolution/muse/projectpropsdialog.h46
-rw-r--r--muse_qt4_evolution/muse/projectpropsdialog.ui188
-rw-r--r--muse_qt4_evolution/muse/rack.cpp445
-rw-r--r--muse_qt4_evolution/muse/rack.h66
-rw-r--r--muse_qt4_evolution/muse/revision.cpp27
-rw-r--r--muse_qt4_evolution/muse/revision.h1
-rw-r--r--muse_qt4_evolution/muse/route.cpp417
-rw-r--r--muse_qt4_evolution/muse/route.h108
-rw-r--r--muse_qt4_evolution/muse/routedialog.cpp196
-rw-r--r--muse_qt4_evolution/muse/routedialog.h53
-rw-r--r--muse_qt4_evolution/muse/routedialog.ui170
-rw-r--r--muse_qt4_evolution/muse/selectfilter.h51
-rw-r--r--muse_qt4_evolution/muse/seqmsg.cpp621
-rw-r--r--muse_qt4_evolution/muse/shortcuts.cpp1169
-rw-r--r--muse_qt4_evolution/muse/shortcuts.h135
-rw-r--r--muse_qt4_evolution/muse/song.cpp1552
-rw-r--r--muse_qt4_evolution/muse/song.h416
-rw-r--r--muse_qt4_evolution/muse/songfile.cpp489
-rw-r--r--muse_qt4_evolution/muse/songpart.cpp371
-rw-r--r--muse_qt4_evolution/muse/songtrack.cpp715
-rw-r--r--muse_qt4_evolution/muse/strip.cpp123
-rw-r--r--muse_qt4_evolution/muse/strip.h75
-rw-r--r--muse_qt4_evolution/muse/style.qss66
-rw-r--r--muse_qt4_evolution/muse/sync.cpp499
-rw-r--r--muse_qt4_evolution/muse/sync.h37
-rw-r--r--muse_qt4_evolution/muse/synth.cpp588
-rw-r--r--muse_qt4_evolution/muse/synth.h227
-rw-r--r--muse_qt4_evolution/muse/templatedialog.cpp259
-rw-r--r--muse_qt4_evolution/muse/templatedialog.h51
-rw-r--r--muse_qt4_evolution/muse/templatedialog.ui188
-rw-r--r--muse_qt4_evolution/muse/thread.cpp354
-rw-r--r--muse_qt4_evolution/muse/thread.h109
-rw-r--r--muse_qt4_evolution/muse/ticksynth.cpp181
-rw-r--r--muse_qt4_evolution/muse/ticksynth.h29
-rw-r--r--muse_qt4_evolution/muse/tllineedit.cpp70
-rw-r--r--muse_qt4_evolution/muse/tllineedit.h48
-rw-r--r--muse_qt4_evolution/muse/tlswidget.cpp355
-rw-r--r--muse_qt4_evolution/muse/tlswidget.h83
-rw-r--r--muse_qt4_evolution/muse/tlwidget.cpp641
-rw-r--r--muse_qt4_evolution/muse/tlwidget.h105
-rw-r--r--muse_qt4_evolution/muse/tlwlayout.cpp144
-rw-r--r--muse_qt4_evolution/muse/tlwlayout.h51
-rw-r--r--muse_qt4_evolution/muse/track.cpp1062
-rw-r--r--muse_qt4_evolution/muse/track.h345
-rw-r--r--muse_qt4_evolution/muse/trackdrag.cpp61
-rw-r--r--muse_qt4_evolution/muse/trackdrag.h42
-rw-r--r--muse_qt4_evolution/muse/trackinfo.cpp553
-rw-r--r--muse_qt4_evolution/muse/trackinfo.h203
-rw-r--r--muse_qt4_evolution/muse/transport.cpp411
-rw-r--r--muse_qt4_evolution/muse/transport.h74
-rw-r--r--muse_qt4_evolution/muse/transport.ui856
-rw-r--r--muse_qt4_evolution/muse/transpose.cpp92
-rw-r--r--muse_qt4_evolution/muse/transpose.h40
-rw-r--r--muse_qt4_evolution/muse/transpose.ui193
-rw-r--r--muse_qt4_evolution/muse/trelement.h63
-rw-r--r--muse_qt4_evolution/muse/undo.cpp614
-rw-r--r--muse_qt4_evolution/muse/undo.h103
-rw-r--r--muse_qt4_evolution/muse/value.cpp73
-rw-r--r--muse_qt4_evolution/muse/vst.cpp1063
-rw-r--r--muse_qt4_evolution/muse/vst.h172
-rw-r--r--muse_qt4_evolution/muse/wave.cpp1087
-rw-r--r--muse_qt4_evolution/muse/wave.h162
-rw-r--r--muse_qt4_evolution/muse/waveedit/CMakeLists.txt34
-rw-r--r--muse_qt4_evolution/muse/waveedit/waveedit.cpp289
-rw-r--r--muse_qt4_evolution/muse/waveedit/waveedit.h88
-rw-r--r--muse_qt4_evolution/muse/waveedit/waveview.cpp1124
-rw-r--r--muse_qt4_evolution/muse/waveedit/waveview.h127
-rw-r--r--muse_qt4_evolution/muse/waveevent.cpp137
-rw-r--r--muse_qt4_evolution/muse/waveevent.h61
-rw-r--r--muse_qt4_evolution/muse/wavetrack.cpp427
-rw-r--r--muse_qt4_evolution/muse/wavetrack.h84
-rw-r--r--muse_qt4_evolution/muse/widgets/CMakeLists.txt88
-rw-r--r--muse_qt4_evolution/muse/widgets/action.h42
-rw-r--r--muse_qt4_evolution/muse/widgets/bigtime.cpp267
-rw-r--r--muse_qt4_evolution/muse/widgets/bigtime.h64
-rw-r--r--muse_qt4_evolution/muse/widgets/cliplisteditorbase.h138
-rw-r--r--muse_qt4_evolution/muse/widgets/cliplisteditorbase.ui146
-rw-r--r--muse_qt4_evolution/muse/widgets/comboQuant.cpp69
-rw-r--r--muse_qt4_evolution/muse/widgets/comboQuant.h43
-rw-r--r--muse_qt4_evolution/muse/widgets/combobox.cpp81
-rw-r--r--muse_qt4_evolution/muse/widgets/combobox.h57
-rw-r--r--muse_qt4_evolution/muse/widgets/comment.cpp91
-rw-r--r--muse_qt4_evolution/muse/widgets/comment.h69
-rw-r--r--muse_qt4_evolution/muse/widgets/comment.ui97
-rw-r--r--muse_qt4_evolution/muse/widgets/ctrlcombo.cpp68
-rw-r--r--muse_qt4_evolution/muse/widgets/ctrlcombo.h32
-rw-r--r--muse_qt4_evolution/muse/widgets/dentry.cpp208
-rw-r--r--muse_qt4_evolution/muse/widgets/dentry.h79
-rw-r--r--muse_qt4_evolution/muse/widgets/doublelabel.cpp144
-rw-r--r--muse_qt4_evolution/muse/widgets/doublelabel.h68
-rw-r--r--muse_qt4_evolution/muse/widgets/editmetadialogbase.cpp110
-rw-r--r--muse_qt4_evolution/muse/widgets/editmetadialogbase.ui137
-rw-r--r--muse_qt4_evolution/muse/widgets/fdialogbuttons.ui167
-rw-r--r--muse_qt4_evolution/muse/widgets/filedialog.cpp193
-rw-r--r--muse_qt4_evolution/muse/widgets/filedialog.h65
-rw-r--r--muse_qt4_evolution/muse/widgets/floatlabel.cpp144
-rw-r--r--muse_qt4_evolution/muse/widgets/floatlabel.h68
-rw-r--r--muse_qt4_evolution/muse/widgets/fontsel.cpp138
-rw-r--r--muse_qt4_evolution/muse/widgets/fontsel.h57
-rw-r--r--muse_qt4_evolution/muse/widgets/greendotbutton.h38
-rw-r--r--muse_qt4_evolution/muse/widgets/intlabel.h56
-rw-r--r--muse_qt4_evolution/muse/widgets/menutitle.cpp50
-rw-r--r--muse_qt4_evolution/muse/widgets/menutitle.h41
-rw-r--r--muse_qt4_evolution/muse/widgets/midisync.cpp128
-rw-r--r--muse_qt4_evolution/muse/widgets/midisync.h49
-rw-r--r--muse_qt4_evolution/muse/widgets/midisync.ui711
-rw-r--r--muse_qt4_evolution/muse/widgets/mittransposebase.h111
-rw-r--r--muse_qt4_evolution/muse/widgets/mittransposebase.ui112
-rw-r--r--muse_qt4_evolution/muse/widgets/mixdowndialog.cpp133
-rw-r--r--muse_qt4_evolution/muse/widgets/mixdowndialog.h48
-rw-r--r--muse_qt4_evolution/muse/widgets/mixdowndialog.ui212
-rw-r--r--muse_qt4_evolution/muse/widgets/noteinfo.cpp207
-rw-r--r--muse_qt4_evolution/muse/widgets/noteinfo.h68
-rw-r--r--muse_qt4_evolution/muse/widgets/outportcombo.cpp52
-rw-r--r--muse_qt4_evolution/muse/widgets/outportcombo.h39
-rw-r--r--muse_qt4_evolution/muse/widgets/quantcombo.cpp80
-rw-r--r--muse_qt4_evolution/muse/widgets/quantcombo.h46
-rw-r--r--muse_qt4_evolution/muse/widgets/rastercombo.cpp82
-rw-r--r--muse_qt4_evolution/muse/widgets/rastercombo.h46
-rw-r--r--muse_qt4_evolution/muse/widgets/recordbutton.h38
-rw-r--r--muse_qt4_evolution/muse/widgets/shortcutcapturedialog.cpp97
-rw-r--r--muse_qt4_evolution/muse/widgets/shortcutcapturedialog.h52
-rw-r--r--muse_qt4_evolution/muse/widgets/shortcutcapturedialog.ui162
-rw-r--r--muse_qt4_evolution/muse/widgets/shortcutconfig.cpp167
-rw-r--r--muse_qt4_evolution/muse/widgets/shortcutconfig.h50
-rw-r--r--muse_qt4_evolution/muse/widgets/shortcutconfig.ui180
-rw-r--r--muse_qt4_evolution/muse/widgets/siglabel.cpp165
-rw-r--r--muse_qt4_evolution/muse/widgets/siglabel.h50
-rw-r--r--muse_qt4_evolution/muse/widgets/simplebutton.cpp65
-rw-r--r--muse_qt4_evolution/muse/widgets/simplebutton.h41
-rw-r--r--muse_qt4_evolution/muse/widgets/splitter.cpp107
-rw-r--r--muse_qt4_evolution/muse/widgets/splitter.h62
-rw-r--r--muse_qt4_evolution/muse/widgets/synthwizardbase.h58
-rw-r--r--muse_qt4_evolution/muse/widgets/tb1.cpp180
-rw-r--r--muse_qt4_evolution/muse/widgets/tb1.h71
-rw-r--r--muse_qt4_evolution/muse/widgets/tools.cpp100
-rw-r--r--muse_qt4_evolution/muse/widgets/tools.h58
-rw-r--r--muse_qt4_evolution/muse/widgets/transformbase.ui993
-rw-r--r--muse_qt4_evolution/muse/widgets/utils.cpp451
-rw-r--r--muse_qt4_evolution/muse/widgets/utils.h58
-rw-r--r--muse_qt4_evolution/muse/widgets/wtrackinfobase.ui166
-rw-r--r--muse_qt4_evolution/muse/xpm/activeoff.svg120
-rw-r--r--muse_qt4_evolution/muse/xpm/activeon.svg120
-rw-r--r--muse_qt4_evolution/muse/xpm/addtrack_addmiditrack.xpm26
-rw-r--r--muse_qt4_evolution/muse/xpm/addtrack_audiogroup.xpm35
-rw-r--r--muse_qt4_evolution/muse/xpm/addtrack_audioinput.xpm33
-rw-r--r--muse_qt4_evolution/muse/xpm/addtrack_audiooutput.xpm44
-rw-r--r--muse_qt4_evolution/muse/xpm/addtrack_auxsend.xpm28
-rw-r--r--muse_qt4_evolution/muse/xpm/addtrack_drumtrack.xpm41
-rw-r--r--muse_qt4_evolution/muse/xpm/addtrack_wavetrack.xpm36
-rw-r--r--muse_qt4_evolution/muse/xpm/audio_bounce_to_file.xpm24
-rw-r--r--muse_qt4_evolution/muse/xpm/audio_bounce_to_track.xpm27
-rw-r--r--muse_qt4_evolution/muse/xpm/audio_restartaudio.xpm69
-rw-r--r--muse_qt4_evolution/muse/xpm/back.xpm27
-rw-r--r--muse_qt4_evolution/muse/xpm/bold.xpm16
-rw-r--r--muse_qt4_evolution/muse/xpm/buttondown.xpm27
-rw-r--r--muse_qt4_evolution/muse/xpm/cafter.xpm29
-rw-r--r--muse_qt4_evolution/muse/xpm/cliplistS.xpm28
-rw-r--r--muse_qt4_evolution/muse/xpm/cmark.xpm23
-rw-r--r--muse_qt4_evolution/muse/xpm/config.xpm36
-rw-r--r--muse_qt4_evolution/muse/xpm/configure.xpm36
-rw-r--r--muse_qt4_evolution/muse/xpm/ctrl.xpm27
-rw-r--r--muse_qt4_evolution/muse/xpm/cut.xpm29
-rw-r--r--muse_qt4_evolution/muse/xpm/darkgreendot.svg117
-rw-r--r--muse_qt4_evolution/muse/xpm/delete.xpm27
-rw-r--r--muse_qt4_evolution/muse/xpm/down.xpm15
-rw-r--r--muse_qt4_evolution/muse/xpm/draw.xpm25
-rw-r--r--muse_qt4_evolution/muse/xpm/edit_drumms.xpm45
-rw-r--r--muse_qt4_evolution/muse/xpm/edit_list.xpm31
-rw-r--r--muse_qt4_evolution/muse/xpm/edit_mastertrack.xpm38
-rw-r--r--muse_qt4_evolution/muse/xpm/edit_midi.xpm26
-rw-r--r--muse_qt4_evolution/muse/xpm/edit_pianoroll.xpm28
-rw-r--r--muse_qt4_evolution/muse/xpm/edit_track_add.xpm24
-rw-r--r--muse_qt4_evolution/muse/xpm/edit_track_del.xpm25
-rw-r--r--muse_qt4_evolution/muse/xpm/editcopy.xpm102
-rw-r--r--muse_qt4_evolution/muse/xpm/editcut.xpm33
-rw-r--r--muse_qt4_evolution/muse/xpm/editcutS.xpm24
-rw-r--r--muse_qt4_evolution/muse/xpm/editmute.xpm33
-rw-r--r--muse_qt4_evolution/muse/xpm/editpaste.xpm210
-rw-r--r--muse_qt4_evolution/muse/xpm/fforward.xpm17
-rw-r--r--muse_qt4_evolution/muse/xpm/filenew.pngbin0 -> 575 bytes
-rw-r--r--muse_qt4_evolution/muse/xpm/filenewS.xpm29
-rw-r--r--muse_qt4_evolution/muse/xpm/fileopen.pngbin0 -> 887 bytes
-rw-r--r--muse_qt4_evolution/muse/xpm/filesave.pngbin0 -> 762 bytes
-rw-r--r--muse_qt4_evolution/muse/xpm/flag.xpm28
-rw-r--r--muse_qt4_evolution/muse/xpm/flagS.xpm19
-rw-r--r--muse_qt4_evolution/muse/xpm/folder_new.pngbin0 -> 1278 bytes
-rw-r--r--muse_qt4_evolution/muse/xpm/forward.xpm28
-rw-r--r--muse_qt4_evolution/muse/xpm/frewind.xpm17
-rw-r--r--muse_qt4_evolution/muse/xpm/glue.xpm49
-rw-r--r--muse_qt4_evolution/muse/xpm/greendot.svg117
-rw-r--r--muse_qt4_evolution/muse/xpm/gv.xpm23
-rw-r--r--muse_qt4_evolution/muse/xpm/home.xpm27
-rw-r--r--muse_qt4_evolution/muse/xpm/initS.xpm23
-rw-r--r--muse_qt4_evolution/muse/xpm/inputpluginS.xpm22
-rw-r--r--muse_qt4_evolution/muse/xpm/italic.xpm16
-rw-r--r--muse_qt4_evolution/muse/xpm/listS.xpm26
-rw-r--r--muse_qt4_evolution/muse/xpm/lmark.xpm23
-rw-r--r--muse_qt4_evolution/muse/xpm/localoffS.xpm22
-rw-r--r--muse_qt4_evolution/muse/xpm/lock.xpm86
-rw-r--r--muse_qt4_evolution/muse/xpm/loop.xpm29
-rw-r--r--muse_qt4_evolution/muse/xpm/master.xpm15
-rw-r--r--muse_qt4_evolution/muse/xpm/mastertrackS.xpm25
-rw-r--r--muse_qt4_evolution/muse/xpm/mastertrack_graphic.xpm28
-rw-r--r--muse_qt4_evolution/muse/xpm/mastertrack_list.xpm27
-rw-r--r--muse_qt4_evolution/muse/xpm/meta.xpm27
-rw-r--r--muse_qt4_evolution/muse/xpm/midi_edit_instrument.xpm27
-rw-r--r--muse_qt4_evolution/muse/xpm/midi_init_instr.xpm28
-rw-r--r--muse_qt4_evolution/muse/xpm/midi_local_off.xpm105
-rw-r--r--muse_qt4_evolution/muse/xpm/midi_plugS.xpm22
-rw-r--r--muse_qt4_evolution/muse/xpm/midi_reset_instr.xpm55
-rw-r--r--muse_qt4_evolution/muse/xpm/midi_transform.xpm30
-rw-r--r--muse_qt4_evolution/muse/xpm/midi_transpose.xpm31
-rw-r--r--muse_qt4_evolution/muse/xpm/midiin.xpm23
-rw-r--r--muse_qt4_evolution/muse/xpm/miditransformS.xpm22
-rw-r--r--muse_qt4_evolution/muse/xpm/miditransposeS.xpm25
-rw-r--r--muse_qt4_evolution/muse/xpm/minus.xpm24
-rw-r--r--muse_qt4_evolution/muse/xpm/mixerS.xpm21
-rw-r--r--muse_qt4_evolution/muse/xpm/mixeraudioS.xpm22
-rw-r--r--muse_qt4_evolution/muse/xpm/mono.svg70
-rw-r--r--muse_qt4_evolution/muse/xpm/muse_icon.xpm411
-rw-r--r--muse_qt4_evolution/muse/xpm/muse_icon_64x64.pngbin0 -> 7493 bytes
-rw-r--r--muse_qt4_evolution/muse/xpm/mutebutton_off.xpm165
-rw-r--r--muse_qt4_evolution/muse/xpm/mutebutton_on.xpm352
-rw-r--r--muse_qt4_evolution/muse/xpm/newmutebutton.xpm69
-rw-r--r--muse_qt4_evolution/muse/xpm/off.svg114
-rw-r--r--muse_qt4_evolution/muse/xpm/off.xpm25
-rw-r--r--muse_qt4_evolution/muse/xpm/on.svg114
-rw-r--r--muse_qt4_evolution/muse/xpm/pafter.xpm29
-rw-r--r--muse_qt4_evolution/muse/xpm/panic.xpm50
-rw-r--r--muse_qt4_evolution/muse/xpm/pencil.xpm27
-rw-r--r--muse_qt4_evolution/muse/xpm/piano.xpm24
-rw-r--r--muse_qt4_evolution/muse/xpm/pitch.xpm28
-rw-r--r--muse_qt4_evolution/muse/xpm/play.xpm17
-rw-r--r--muse_qt4_evolution/muse/xpm/plus.xpm21
-rw-r--r--muse_qt4_evolution/muse/xpm/pointer.xpm28
-rw-r--r--muse_qt4_evolution/muse/xpm/punchin.xpm17
-rw-r--r--muse_qt4_evolution/muse/xpm/punchout.xpm18
-rw-r--r--muse_qt4_evolution/muse/xpm/quant.xpm28
-rw-r--r--muse_qt4_evolution/muse/xpm/recordOff.svg117
-rw-r--r--muse_qt4_evolution/muse/xpm/recordOn.svg117
-rw-r--r--muse_qt4_evolution/muse/xpm/redo.xpm92
-rw-r--r--muse_qt4_evolution/muse/xpm/resetS.xpm22
-rw-r--r--muse_qt4_evolution/muse/xpm/rmark.xpm23
-rw-r--r--muse_qt4_evolution/muse/xpm/select.xpm21
-rw-r--r--muse_qt4_evolution/muse/xpm/select_all.xpm21
-rw-r--r--muse_qt4_evolution/muse/xpm/select_all_parts_on_track.xpm39
-rw-r--r--muse_qt4_evolution/muse/xpm/select_deselect_all.xpm22
-rw-r--r--muse_qt4_evolution/muse/xpm/select_inside_loop.xpm21
-rw-r--r--muse_qt4_evolution/muse/xpm/select_invert_selection.xpm21
-rw-r--r--muse_qt4_evolution/muse/xpm/select_outside_loop.xpm21
-rw-r--r--muse_qt4_evolution/muse/xpm/settings_appearance_settings.xpm66
-rw-r--r--muse_qt4_evolution/muse/xpm/settings_configureshortcuts.xpm36
-rw-r--r--muse_qt4_evolution/muse/xpm/settings_follow_song.xpm30
-rw-r--r--muse_qt4_evolution/muse/xpm/settings_globalsettings.xpm89
-rw-r--r--muse_qt4_evolution/muse/xpm/settings_metronome.xpm99
-rw-r--r--muse_qt4_evolution/muse/xpm/settings_midifileexport.xpm30
-rw-r--r--muse_qt4_evolution/muse/xpm/settings_midiport_softsynths.xpm29
-rw-r--r--muse_qt4_evolution/muse/xpm/settings_midisync.xpm53
-rw-r--r--muse_qt4_evolution/muse/xpm/solobutton.xpm39
-rw-r--r--muse_qt4_evolution/muse/xpm/solobutton_off.xpm146
-rw-r--r--muse_qt4_evolution/muse/xpm/solobutton_on.xpm300
-rw-r--r--muse_qt4_evolution/muse/xpm/speaker.xpm23
-rw-r--r--muse_qt4_evolution/muse/xpm/splash.pngbin0 -> 45374 bytes
-rw-r--r--muse_qt4_evolution/muse/xpm/start.xpm17
-rw-r--r--muse_qt4_evolution/muse/xpm/steprec.xpm24
-rw-r--r--muse_qt4_evolution/muse/xpm/stereo.svg68
-rw-r--r--muse_qt4_evolution/muse/xpm/stick.xpm33
-rw-r--r--muse_qt4_evolution/muse/xpm/stop.xpm17
-rw-r--r--muse_qt4_evolution/muse/xpm/sysex.xpm27
-rw-r--r--muse_qt4_evolution/muse/xpm/toc.xpm27
-rw-r--r--muse_qt4_evolution/muse/xpm/track_add.xpm23
-rw-r--r--muse_qt4_evolution/muse/xpm/track_delete.xpm23
-rw-r--r--muse_qt4_evolution/muse/xpm/underlined.xpm16
-rw-r--r--muse_qt4_evolution/muse/xpm/undo.xpm93
-rw-r--r--muse_qt4_evolution/muse/xpm/up.xpm15
-rw-r--r--muse_qt4_evolution/muse/xpm/view_bigtime_window.xpm22
-rw-r--r--muse_qt4_evolution/muse/xpm/view_cliplist.xpm32
-rw-r--r--muse_qt4_evolution/muse/xpm/view_marker.xpm37
-rw-r--r--muse_qt4_evolution/muse/xpm/view_mixer.xpm26
-rw-r--r--muse_qt4_evolution/muse/xpm/view_transport_window.xpm24
-rw-r--r--muse_qt4_evolution/muse/xpm/wave.xpm33
502 files changed, 94901 insertions, 0 deletions
diff --git a/muse_qt4_evolution/muse/CMakeLists.txt b/muse_qt4_evolution/muse/CMakeLists.txt
new file mode 100644
index 00000000..9ef460c3
--- /dev/null
+++ b/muse_qt4_evolution/muse/CMakeLists.txt
@@ -0,0 +1,226 @@
+#=============================================================================
+# MusE
+# Linux Music Editor
+# $Id:$
+#
+# Copyright (C) 2002-2008 by Werner Schweer and others
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#=============================================================================
+
+include(${PROJECT_SOURCE_DIR}/pch.txt)
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ )
+
+subdirs (
+ ctrl
+ midiedit
+ widgets
+ master
+ instruments
+ marker
+ liste
+ waveedit
+ )
+
+QT4_WRAP_UI (muse_ui_headers
+ preferences.ui
+ exportmididialog.ui
+ configmidifile.ui
+ transport.ui
+ aboutbox.ui
+ transpose.ui
+ projectpropsdialog.ui
+ projectdialog.ui
+ templatedialog.ui
+ importmidi.ui
+ routedialog.ui
+ configtrack.ui
+ midiportinfo.ui
+ miditrackinfo.ui
+ )
+
+QT4_WRAP_CPP ( muse_moc_headers
+ projectpropsdialog.h
+ projectdialog.h
+ templatedialog.h
+ preferences.h
+ plugingui.h
+ midiplugin.h
+ muse.h
+ song.h
+ transport.h
+ conf.h
+ editor.h
+ cobject.h
+ transpose.h
+ track.h
+ miditrackbase.h
+ midisynti.h
+ miditrack.h
+ wavetrack.h
+ audiotrack.h
+ audiooutput.h
+ audioinput.h
+ audiogroup.h
+ synth.h
+ exportmidi.h
+ importmidi.h
+ midiinport.h
+ midioutport.h
+ astrip.h
+ midirack.h
+ mixer.h
+ mstrip.h
+ rack.h
+ routedialog.h
+ strip.h
+ arranger.h
+ canvas.h
+ configtrack.h
+ partdrag.h
+ tllineedit.h
+ tlswidget.h
+ tlwidget.h
+ trackdrag.h
+ trackinfo.h
+ )
+
+QT4_ADD_RESOURCES (muse_qrc_files muse.qrc)
+
+add_executable ( muse
+ ${muse_qrc_files}
+ ${muse_moc_headers}
+ ${muse_ui_headers}
+ ${PROJECT_BINARY_DIR}/all.h.pch
+
+ ticksynth.cpp
+ vst.cpp
+ dssihost.cpp
+ synth.cpp
+ plugin.cpp
+ ladspaplugin.cpp
+ auxplugin.cpp
+ pipeline.cpp
+ mtc.cpp
+ thread.cpp
+ audio.cpp
+ audioprefetch.cpp
+ audiowriteback.cpp
+ globals.cpp
+ sync.cpp
+ part.cpp
+ undo.cpp
+ songfile.cpp
+ midi.cpp
+ importmidi.cpp
+ importmidi.h
+ midifile.cpp
+ icons.cpp
+ event.cpp
+ eventlist.cpp
+ midieventbase.cpp
+ waveevent.cpp
+ midievent.cpp
+ wave.cpp
+ seqmsg.cpp
+ help.cpp
+ midictrl.cpp
+ fifo.cpp
+ helper.cpp
+ route.cpp
+ shortcuts.cpp
+ ctrl.cpp
+ gconfig.cpp
+ midirc.cpp
+ midififo.cpp
+ midioutport.cpp
+ midiinport.cpp
+ midiout.cpp
+
+ projectpropsdialog.cpp
+ projectdialog.cpp
+ templatedialog.cpp
+ preferences.cpp
+ plugingui.cpp
+ midiplugin.cpp
+ muse.cpp
+ song.cpp
+ songpart.cpp
+ songtrack.cpp
+ transport.cpp
+ conf.cpp
+ editor.cpp
+ cobject.cpp
+ transpose.cpp
+ track.cpp
+ miditrackbase.cpp
+ midisynti.cpp
+ miditrack.cpp
+ wavetrack.cpp
+ audiotrack.cpp
+ audiooutput.cpp
+ audioinput.cpp
+ audiogroup.cpp
+ exportmidi.cpp
+ revision.cpp
+ jack.cpp dummyaudio.cpp
+ astrip.cpp
+ midirack.cpp
+ mixer.cpp
+ mstrip.cpp
+ rack.cpp
+ routedialog.cpp
+ strip.cpp
+
+ arranger.cpp
+ canvas.cpp
+ configtrack.cpp
+ partdrag.cpp
+ tllineedit.cpp
+ tlswidget.cpp
+ tlwidget.cpp
+ tlwlayout.cpp
+ trackdrag.cpp
+ trackinfo.cpp
+ )
+
+set_target_properties( muse
+ PROPERTIES COMPILE_FLAGS "-include ${PROJECT_BINARY_DIR}/all.h"
+ )
+
+target_link_libraries(muse
+ midiedit
+ master
+ instruments
+ marker
+ liste
+ synti
+ waveedit
+ widgets
+ al
+ awl
+ ctrl
+ ${QT_LIBRARIES}
+ QtSvg
+ ${ALSA_LIB}
+ ${JACK_LIB}
+ ${SNDFILE_LIB}
+ ${SAMPLERATE_LIB}
+ ${LIBLO_LIB}
+ )
+
+install_targets ( /bin muse )
+
diff --git a/muse_qt4_evolution/muse/aboutbox.ui b/muse_qt4_evolution/muse/aboutbox.ui
new file mode 100644
index 00000000..867c5536
--- /dev/null
+++ b/muse_qt4_evolution/muse/aboutbox.ui
@@ -0,0 +1,612 @@
+<ui version="4.0" >
+ <class>AboutBox</class>
+ <widget class="QDialog" name="AboutBox" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>585</width>
+ <height>348</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="palette" >
+ <palette>
+ <active>
+ <colorrole role="WindowText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>221</red>
+ <green>223</green>
+ <blue>228</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Light" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Midlight" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>85</red>
+ <green>85</green>
+ <blue>85</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>199</red>
+ <green>199</green>
+ <blue>199</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="BrightText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ButtonText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Base" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>239</red>
+ <green>237</green>
+ <blue>165</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Shadow" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Highlight" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>103</red>
+ <green>141</green>
+ <blue>178</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="HighlightedText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Link" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>238</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="LinkVisited" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>82</red>
+ <green>24</green>
+ <blue>139</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="AlternateBase" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>232</red>
+ <green>232</green>
+ <blue>232</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </active>
+ <inactive>
+ <colorrole role="WindowText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>221</red>
+ <green>223</green>
+ <blue>228</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Light" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Midlight" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>85</red>
+ <green>85</green>
+ <blue>85</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>199</red>
+ <green>199</green>
+ <blue>199</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="BrightText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ButtonText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Base" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>239</red>
+ <green>237</green>
+ <blue>165</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Shadow" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Highlight" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>103</red>
+ <green>141</green>
+ <blue>178</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="HighlightedText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Link" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>238</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="LinkVisited" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>82</red>
+ <green>24</green>
+ <blue>139</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="AlternateBase" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>232</red>
+ <green>232</green>
+ <blue>232</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </inactive>
+ <disabled>
+ <colorrole role="WindowText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>221</red>
+ <green>223</green>
+ <blue>228</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Light" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Midlight" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>85</red>
+ <green>85</green>
+ <blue>85</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>199</red>
+ <green>199</green>
+ <blue>199</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>199</red>
+ <green>199</green>
+ <blue>199</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="BrightText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ButtonText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Base" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>239</red>
+ <green>237</green>
+ <blue>165</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>239</red>
+ <green>237</green>
+ <blue>165</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Shadow" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Highlight" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>86</red>
+ <green>117</green>
+ <blue>148</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="HighlightedText" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Link" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>0</red>
+ <green>0</green>
+ <blue>238</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="LinkVisited" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>82</red>
+ <green>24</green>
+ <blue>139</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="AlternateBase" >
+ <brush brushstyle="SolidPattern" >
+ <color alpha="255" >
+ <red>232</red>
+ <green>232</green>
+ <blue>232</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </disabled>
+ </palette>
+ </property>
+ <property name="windowTitle" >
+ <string>AboutBox</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <item>
+ <layout class="QHBoxLayout" >
+ <item>
+ <widget class="QLabel" name="museIcon" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Fixed" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="textFormat" >
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="pixmap" >
+ <pixmap resource="muse.qrc" >:/xpm/muse_icon_64x64.png</pixmap>
+ </property>
+ <property name="margin" >
+ <number>20</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" >
+ <item>
+ <widget class="QLabel" name="titleLabel" >
+ <property name="font" >
+ <font>
+ <pointsize>14</pointsize>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text" >
+ <string>MusE</string>
+ </property>
+ <property name="margin" >
+ <number>10</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="versionLabel" >
+ <property name="text" >
+ <string>Version: 2.0.1</string>
+ </property>
+ <property name="indent" >
+ <number>20</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="revisionLabel" >
+ <property name="text" >
+ <string>Revision: 628</string>
+ </property>
+ <property name="indent" >
+ <number>20</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="copyrightLabel" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>&lt;html>&lt;head>&lt;meta name="qrichtext" content="1" />&lt;style type="text/css">
+p, li { white-space: pre-wrap; }
+&lt;/style>&lt;/head>&lt;body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;">
+&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Arial'; font-size:14pt; font-weight:600;">&lt;span style=" font-size:10pt; font-weight:400;">(C) Copyright 1999-2008 Werner Schweer and Others. &lt;/span>&lt;/p>
+&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Arial'; font-size:10pt;">See http://www.muse-sequencer.org for new versions and&lt;/p>
+&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Arial'; font-size:10pt;">more information.&lt;/p>
+&lt;p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Arial'; font-size:10pt;">&lt;/p>
+&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Arial'; font-size:10pt;">Published under the GNU Public License&lt;/p>&lt;/body>&lt;/html></string>
+ </property>
+ <property name="wordWrap" >
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox" >
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11" />
+ <resources>
+ <include location="muse.qrc" />
+ </resources>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>AboutBox</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>531</x>
+ <y>326</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>582</x>
+ <y>29</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/muse_qt4_evolution/muse/arranger.cpp b/muse_qt4_evolution/muse/arranger.cpp
new file mode 100644
index 00000000..82c859cb
--- /dev/null
+++ b/muse_qt4_evolution/muse/arranger.cpp
@@ -0,0 +1,1382 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "song.h"
+#include "muse.h"
+#include "arranger.h"
+#include "tlwidget.h"
+#include "tlswidget.h"
+#include "icons.h"
+#include "widgets/simplebutton.h"
+#include "configtrack.h"
+#include "canvas.h"
+#include "widgets/utils.h"
+#include "widgets/splitter.h"
+#include "astrip.h"
+#include "mstrip.h"
+#include "audio.h"
+#include "shortcuts.h"
+#include "trackinfo.h"
+#include "midictrl.h"
+#include "gconfig.h"
+#include "part.h"
+
+//---------------------------------------------------------
+// TrElement elements
+// list of available track gui elements
+//---------------------------------------------------------
+
+const TrElement trElements[] = {
+ TrElement(TR_NAME, 1, "trackname", -1),
+ TrElement(TR_RECORD, 0, "record",
+ Track::M_MIDI | Track::M_AUDIO_OUTPUT | Track::M_WAVE),
+ TrElement(TR_OFF, 2, "off",
+ Track::M_AUDIO_OUTPUT
+ | Track::M_AUDIO_GROUP
+ | Track::M_WAVE
+ | Track::M_AUDIO_INPUT
+ | Track::M_AUDIO_SOFTSYNTH),
+ TrElement(TR_DRUMMAP, 2, "use drum map", Track::M_MIDI),
+ TrElement(TR_MUTE, 3, "mute", -1),
+ TrElement(TR_SOLO, 3, "solo", -1),
+ TrElement(TR_MONITOR, 3, "monitor",
+ Track::M_MIDI | Track::M_WAVE),
+ TrElement(TR_AREAD, 4, "automation read",
+ -1 & ~(Track::M_MIDI_IN | Track::M_MIDI)),
+ TrElement(TR_AWRITE, 4, "automation write",
+ -1 & ~(Track::M_MIDI_IN | Track::M_MIDI)),
+ TrElement(TR_OCHANNEL, 5, "output channel", Track::M_MIDI),
+ TrElement(TR_INSTRUMENT, 6, "instrument", Track::M_MIDI_OUT),
+ TrElement(TR_PATCH, 7, "patch", Track::M_MIDI),
+ };
+
+const int nTrElements = sizeof(trElements)/sizeof(*trElements);
+
+TrGroupList glist[Track::TRACK_TYPES];
+
+extern void populateAddTrack(QMenu*);
+
+//---------------------------------------------------------
+// sizeHint
+//---------------------------------------------------------
+
+QSize InfoStack::sizeHint() const
+ {
+ return QSize(infoWidth, height());
+ }
+
+//---------------------------------------------------------
+// TLayout
+// simple layout for trackList
+//---------------------------------------------------------
+
+class TLayout : public QLayout {
+ QList<QLayoutItem*> itemList;
+
+ public:
+ TLayout() {}
+ ~TLayout();
+
+ void addItem(QLayoutItem* item);
+ void insertWidget(int index, QWidget* item);
+ Qt::Orientations expandingDirections() const { return 0; }
+ bool hasHeightForWidth() const { return false; }
+ int count() const { return itemList.size(); }
+ void setGeometry(const QRect &rect);
+ QSize sizeHint() const { return ((QWidget*)parent())->size(); }
+ QLayoutItem *itemAt(int index) const { return itemList.value(index); }
+ QLayoutItem *takeAt(int idx) {
+ return idx >= 0 && idx < itemList.size() ? itemList.takeAt(idx) : 0;
+ }
+ void clear() {
+ QLayoutItem* child;
+ while ((child = takeAt(0)) != 0) {
+ delete child;
+ }
+ }
+ };
+
+//---------------------------------------------------------
+// TLayout
+//---------------------------------------------------------
+
+TLayout::~TLayout()
+ {
+ QLayoutItem* child;
+ while ((child = takeAt(0)) != 0)
+ delete child;
+ }
+
+//---------------------------------------------------------
+// insertWidget
+//---------------------------------------------------------
+
+void TLayout::insertWidget(int index, QWidget* item)
+ {
+ if (item->parent() == 0)
+ item->setParent((QWidget*)parent());
+ itemList.insert(index, new QWidgetItem(item));
+ update();
+ }
+
+//---------------------------------------------------------
+// addItem
+//---------------------------------------------------------
+
+void TLayout::addItem(QLayoutItem* item)
+ {
+ itemList.append(item);
+ update();
+ }
+
+//---------------------------------------------------------
+// setGeometry
+//---------------------------------------------------------
+
+void TLayout::setGeometry(const QRect& r)
+ {
+ int y = r.y();
+ int n = itemList.size();
+ int width = r.width(); // ((QWidget*)parent())->width();
+ for (int i = 0; i < n; ++i) {
+ QLayoutItem *item = itemList.at(i);
+ QWidget* w = item->widget();
+ int h = w->height();
+ w->setGeometry(0, y, width, h);
+ y += h;
+ }
+ }
+
+//---------------------------------------------------------
+// TlsvLayout
+//---------------------------------------------------------
+
+class TlsvLayout : public QLayout {
+ QList<QLayoutItem*> itemList;
+ int dx, dy;
+
+ public:
+ TlsvLayout() {
+ dx = 0;
+ dy = 0;
+ }
+ ~TlsvLayout();
+
+ void setOffset(int x, int y) {
+ dx = x;
+ dy = y;
+ }
+ void addItem(QLayoutItem* item);
+ void insertWidget(int index, QWidget* item);
+ Qt::Orientations expandingDirections() const { return 0; }
+ bool hasHeightForWidth() const { return false; }
+ int count() const { return itemList.size(); }
+ void setGeometry(const QRect &rect);
+ QSize sizeHint() const { return ((QWidget*)parent())->size(); }
+ QLayoutItem *itemAt(int index) const { return itemList.value(index); }
+ QLayoutItem *takeAt(int idx) {
+ return idx >= 0 && idx < itemList.size() ? itemList.takeAt(idx) : 0;
+ }
+ };
+
+//---------------------------------------------------------
+// TlsvLayout
+//---------------------------------------------------------
+
+TlsvLayout::~TlsvLayout()
+ {
+ QLayoutItem* child;
+ while ((child = takeAt(0)) != 0)
+ delete child;
+ }
+
+//---------------------------------------------------------
+// insertWidget
+//---------------------------------------------------------
+
+void TlsvLayout::insertWidget(int index, QWidget* item)
+ {
+ if (item->parent() == 0)
+ item->setParent((QWidget*)parent());
+ itemList.insert(index, new QWidgetItem(item));
+ update();
+ }
+
+//---------------------------------------------------------
+// addItem
+//---------------------------------------------------------
+
+void TlsvLayout::addItem(QLayoutItem* item)
+ {
+ itemList.append(item);
+ update();
+ }
+
+//---------------------------------------------------------
+// setGeometry
+//---------------------------------------------------------
+
+void TlsvLayout::setGeometry(const QRect& r)
+ {
+ QLayoutItem *item = itemList.at(0);
+ QWidget* w = item->widget();
+ w->setGeometry(dx, dy, r.width(), w->height());
+ }
+
+//---------------------------------------------------------
+// newAddTrackMenu
+//---------------------------------------------------------
+
+QMenu* newAddTrackMenu(QWidget* parent)
+ {
+ QMenu* menu = new QMenu(parent);
+ populateAddTrack(menu);
+ return menu;
+ }
+
+//---------------------------------------------------------
+// Arranger
+//---------------------------------------------------------
+
+Arranger::Arranger(QMainWindow* parent)
+ : QWidget(parent)
+ {
+// setFocusPolicy(Qt::StrongFocus);
+ setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+
+ for (int i = 0; i < Track::TRACK_TYPES; ++i)
+ trackInfos[i] = 0;
+
+ zeroTrackInfo = 0;
+ _curTrack = 0;
+ strip = 0;
+ info = 0;
+ tool = PointerTool;
+
+ for (int tt = 0; tt < Track::TRACK_TYPES; ++tt) {
+ int gn = 0;
+ TrElementList group;
+ for (int i = 0; i < nTrElements; ++i) {
+ if (!(trElements[i].trackMask & (1<<tt)))
+ continue;
+ if (trElements[i].grp != gn) {
+ glist[tt].push_back(group);
+ group.clear();
+ gn = trElements[i].grp;
+ }
+ group.push_back(&trElements[i]);
+ }
+ if (!group.empty())
+ glist[tt].push_back(group);
+ }
+
+ configTrackEditor = 0;
+ QLayout* ml = new QHBoxLayout;
+ ml->setSpacing(0);
+ ml->setMargin(0);
+ setLayout(ml);
+
+ infoDock = new QDockWidget(tr("TrackInfo"));
+ infoDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
+ infoDockAction = infoDock->toggleViewAction();
+
+ mixerDock = new QDockWidget(tr(""));
+ mixerDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
+ mixerDockAction = mixerDock->toggleViewAction();
+
+ parent->setDockNestingEnabled(true);
+
+ parent->addDockWidget(Qt::LeftDockWidgetArea, infoDock, Qt::Horizontal);
+ parent->addDockWidget(Qt::LeftDockWidgetArea, mixerDock, Qt::Horizontal);
+
+ infoView = new QScrollArea;
+ infoView->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
+
+ infoDock->setWidget(infoView);
+ infoView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+
+ trackInfo = new InfoStack();
+ infoView->setWidget(trackInfo);
+ infoView->setWidgetResizable(true);
+
+ trackInfoVisible = false;
+ mixerStripVisible = false;
+
+ infoDock->setVisible(false);
+ mixerDock->setVisible(false);
+
+ connect(infoDockAction, SIGNAL(toggled(bool)), SLOT(toggleTrackInfo(bool)));
+ connect(mixerDockAction, SIGNAL(toggled(bool)), SLOT(toggleMixerStrip(bool)));
+
+ tlsv = new TrackListWidget;
+ tlsv->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
+ tlsvLayout = new TlsvLayout;
+ tlsv->setLayout(tlsvLayout);
+ trackList = new QWidget;
+ trackList->setAttribute(Qt::WA_StaticContents);
+ trackList->setMouseTracking(true);
+
+ tlsv->layout()->addWidget(trackList);
+ tl = new TLayout;
+ trackList->setLayout(tl);
+
+ //
+ // Toolbox
+ //
+ QHBoxLayout* ttoolsLayout = new QHBoxLayout;
+ ttoolsLayout->setMargin(1);
+ ttoolsLayout->setSpacing(1);
+
+ SimpleButton* configButton = new SimpleButton(configIcon, configIcon);
+ configButton->setAutoRaise(true);
+ configButton->setToolTip(tr("Config Tracklist"));
+ configButton->setFixedHeight(rulerHeight-4);
+ connect(configButton, SIGNAL(clicked()), SLOT(configTrackList()));
+ ttoolsLayout->addWidget(configButton);
+ ttoolsLayout->addStretch(100);
+
+ gmute = newMuteButton();
+ gmute->setFixedWidth(rulerHeight);
+ gmute->setToolTip(tr("all mute off"));
+ gmute->setFixedHeight(rulerHeight-4);
+ ttoolsLayout->addWidget(gmute);
+ setGMute();
+ connect(song, SIGNAL(muteChanged(Track*,bool)), SLOT(setGMute()));
+ connect(gmute, SIGNAL(clicked(bool)), SLOT(offGMute()));
+
+ gsolo = newSoloButton();
+ gsolo->setFixedWidth(rulerHeight);
+ gsolo->setToolTip(tr("all solo off"));
+ gsolo->setFixedHeight(rulerHeight-4);
+ ttoolsLayout->addWidget(gsolo);
+ setGSolo();
+ connect(song, SIGNAL(soloChanged(Track*,bool)), SLOT(setGSolo()));
+ connect(gsolo, SIGNAL(clicked(bool)), SLOT(offGSolo()));
+
+ gar = newAutoReadButton();
+ gar->setFixedWidth(rulerHeight);
+ gar->setToolTip(tr("all autoRead off"));
+ gar->setFixedHeight(rulerHeight-4);
+ ttoolsLayout->addWidget(gar);
+ setGar();
+ connect(song, SIGNAL(autoReadChanged(Track*,bool)), SLOT(setGar()));
+ connect(gar, SIGNAL(clicked(bool)), SLOT(offGar()));
+
+ gaw = newAutoWriteButton();
+ gaw->setFixedWidth(rulerHeight);
+ gaw->setToolTip(tr("all autoWrite off"));
+ gaw->setFixedHeight(rulerHeight-4);
+ ttoolsLayout->addWidget(gaw);
+ setGaw();
+ connect(song, SIGNAL(autoWriteChanged(Track*,bool)), SLOT(setGaw()));
+ connect(gaw, SIGNAL(clicked(bool)), SLOT(offGaw()));
+
+ QHBoxLayout* infoboxLayout = new QHBoxLayout;
+ infoboxLayout->setMargin(1);
+ infoboxLayout->setSpacing(1);
+
+ SimpleButton* tifButton = new SimpleButton(QString());
+ tifButton->setCheckable(true);
+ tifButton->setFixedSize(infoHeight-2, infoHeight);
+ tifButton->setDefaultAction(infoDockAction);
+ infoDockAction->setText(tr("i"));
+ infoDockAction->setToolTip(tr("Show Track Info"));
+ infoboxLayout->addWidget(tifButton);
+
+ SimpleButton* mstButton = new SimpleButton(QString());
+ mstButton->setCheckable(true);
+ mstButton->setFixedSize(infoHeight-2, infoHeight);
+ mstButton->setDefaultAction(mixerDockAction);
+ mixerDockAction->setText(tr("m"));
+ mixerDockAction->setToolTip(tr("Show Mixer Strip"));
+ infoboxLayout->addWidget(mstButton);
+
+ infoboxLayout->addStretch(100);
+
+ split = new Splitter(Qt::Horizontal);
+ split->setOpaqueResize(true);
+ split->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ QWidget* tw = new QWidget;
+ split->addWidget(tw);
+ QVBoxLayout* trackListGrid = new QVBoxLayout;
+ trackListGrid->setMargin(0);
+ trackListGrid->setSpacing(0);
+ tw->setLayout(trackListGrid);
+
+ trackListGrid->addLayout(ttoolsLayout);
+ QFrame* ruler = hLine(0);
+ ruler->setLineWidth(2);
+ trackListGrid->addWidget(ruler);
+ trackListGrid->addWidget(tlsv, 100);
+ trackListGrid->addLayout(infoboxLayout);
+
+ //
+ // canvas widget
+ //
+ canvas = new PartCanvas;
+ canvas->setCornerWidget(new QSizeGrip(canvas));
+ split->addWidget(canvas);
+ split->setStretchFactor(1, 100);
+ canvas->setTool(tool);
+ canvas->verticalScrollBar()->setSingleStep(minTrackHeight/2);
+
+ connect(tlsv, SIGNAL(mouseWheel(QWheelEvent*)), SLOT(mouseWheel(QWheelEvent*)));
+ connect(song, SIGNAL(posChanged(int,const AL::Pos&,bool)), canvas, SLOT(setLocatorPos(int,const AL::Pos&,bool)));
+ connect(song, SIGNAL(lenChanged(const AL::Pos&)), canvas, SLOT(setEndPos(const AL::Pos&)));
+ connect(song, SIGNAL(tempoChanged()), canvas, SLOT(tempoChanged()));
+ connect(canvas, SIGNAL(kbdMovementUpdate(Track*, Part*)), SLOT(kbdMovementUpdate(Track*, Part*)));
+ connect(muse, SIGNAL(rasterChanged(int)), canvas, SLOT(setRaster(int)));
+ connect(canvas, SIGNAL(cursorPos(const AL::Pos&,bool)), SIGNAL(cursorPos(const AL::Pos&,bool)));
+ connect(canvas, SIGNAL(contentsMoving(int,int)), SLOT(setTLViewPos(int,int)));
+ connect(canvas, SIGNAL(posChanged(int,const AL::Pos&)), SLOT(setPos(int,const AL::Pos&)));
+
+ connect(canvas, SIGNAL(createLRPart(Track*)), song, SLOT(cmdCreateLRPart(Track*)));
+ connect(canvas, SIGNAL(doubleClickPart(Part*)), SIGNAL(editPart(Part*)));
+ connect(canvas, SIGNAL(startEditor(Part*,int)), muse, SLOT(startEditor(Part*,int)));
+ connect(canvas, SIGNAL(partChanged(Part*,unsigned,unsigned)),
+ song, SLOT(cmdChangePart(Part*,unsigned,unsigned)));
+ connect(canvas, SIGNAL(addMarker(const AL::Pos&)), SLOT(addMarker(const AL::Pos&)));
+ connect(canvas, SIGNAL(removeMarker(const AL::Pos&)), SLOT(removeMarker(const AL::Pos&)));
+
+ layout()->addWidget(split);
+
+ connect(muse, SIGNAL(configChanged()), SLOT(updateConfiguration()));
+ connect(song, SIGNAL(trackSelectionChanged(Track*)), SLOT(setSelectedTrack(Track*)));
+ connect(song, SIGNAL(trackRemoved(Track*)), SLOT(removeTrack(Track*)));
+ connect(song, SIGNAL(trackAdded(Track*,int)), SLOT(insertTrack(Track*)));
+ connect(muse, SIGNAL(startLoadSong()), SLOT(startLoadSong()));
+ }
+
+//---------------------------------------------------------
+// setPos
+//---------------------------------------------------------
+
+void Arranger::setPos(int idx, const AL::Pos& pos)
+ {
+ song->setPos(idx, pos.snaped(muse->raster()));
+ }
+
+//---------------------------------------------------------
+// setTLViewPos
+//---------------------------------------------------------
+
+void Arranger::setTLViewPos(int /*x*/, int y)
+ {
+#if 1
+ int dy = y + trackList->y();
+ tlsv->scroll(0, -dy);
+#else
+ trackList->setGeometry(0, -y, trackList->width(), trackList->height());
+#endif
+ tlsvLayout->setOffset(0, -y);
+ }
+
+//---------------------------------------------------------
+// tlIndex
+//---------------------------------------------------------
+
+int Arranger::tlIndex(Track* t) const
+ {
+ const TrackList* stl = song->tracks();
+
+ int idx = 0;
+ for (ciTrack i = stl->begin(); i != stl->end(); ++i, ++idx) {
+ if (*i == t)
+ break;
+ ArrangerTrack* at = &(*i)->arrangerTrack;
+ if (at->tw == 0)
+ continue;
+ idx += (*i)->subtracks.size();
+ }
+ return idx;
+ }
+
+int Arranger::tlIndex(ArrangerTrack* t) const
+ {
+ TrackList* stl = song->tracks();
+
+ int idx = 0;
+ for (ciTrack i = stl->begin(); i != stl->end(); ++i, ++idx) {
+ ArrangerTrack* at = &(*i)->arrangerTrack;
+ if (at->tw == 0)
+ continue;
+ ArrangerTrackList& atl = (*i)->subtracks;
+ for (iArrangerTrack k = atl.begin(); k != atl.end(); ++k) {
+ ++idx;
+ if (*k == t)
+ return idx;
+ }
+ }
+ return -1; // crash
+ }
+
+//---------------------------------------------------------
+// insertTrack
+//---------------------------------------------------------
+
+void Arranger::insertTrack1(Track* t)
+ {
+ int idx = tlIndex(t);
+ //-------------------------
+ // track list widget
+ //-------------------------
+
+ TLWidget* tw = new TLWidget(t, &glist[t->type()]);
+ tw->setFixedHeight(t->arrangerTrack.h);
+ tl->insertWidget(idx, tw);
+ tw->show(); // needed if song is reloaded
+
+ connect(tw, SIGNAL(plusClicked(TLWidget*)), SLOT(appendSubtrack(TLWidget*)));
+ connect(tw, SIGNAL(moveTrack(Track*,Track*)), SLOT(moveTrack(Track*,Track*)));
+ connect(this, SIGNAL(configChanged()), tw, SLOT(configChanged()));
+ connect(tw, SIGNAL(drag(int, int)), SLOT(drag(int,int)));
+ connect(tw, SIGNAL(startDrag(int)), SLOT(startDrag(int)));
+ connect(t, SIGNAL(partsChanged()), canvas->widget(), SLOT(update()));
+
+ ArrangerTrack* at = &(t->arrangerTrack);
+ at->tw = tw;
+ }
+
+void Arranger::insertTrack(Track* t)
+ {
+ insertTrack1(t);
+ t->arrangerTrack.tw->show();
+ updateIndex();
+ if (_curTrack == 0)
+ setSelectedTrack(_curTrack);
+ }
+
+//---------------------------------------------------------
+// removeTrack
+//---------------------------------------------------------
+
+void Arranger::removeTrack(Track* t)
+ {
+ ArrangerTrack* at = &t->arrangerTrack;
+ if (at->tw == 0)
+ return;
+
+ tl->removeWidget(at->tw);
+
+ at->tw->close();
+ at->tw = 0;
+
+ for (iArrangerTrack i = t->subtracks.begin(); i != t->subtracks.end(); ++i) {
+ ArrangerTrack* at = *i;
+ tl->removeWidget(at->tw);
+ at->tw->close();
+ }
+ t->subtracks.clear();
+
+ if (t == _curTrack) {
+ if (!song->tracks()->isEmpty())
+ song->selectTrack(song->tracks()->front());
+ }
+ updateIndex();
+ }
+
+//---------------------------------------------------------
+// drag
+//---------------------------------------------------------
+
+void Arranger::drag(int trackIdx, int delta)
+ {
+ int h = startH + delta;
+ if (h < minTrackHeight)
+ h = minTrackHeight;
+ ArrangerTrack* at = atrack(trackIdx);
+ at->tw->setFixedHeight(h);
+ updateIndex();
+ }
+
+//---------------------------------------------------------
+// startDrag
+//---------------------------------------------------------
+
+void Arranger::startDrag(int trackIdx)
+ {
+ ArrangerTrack* at = atrack(trackIdx);
+ startH = at->tw->height();
+ }
+
+//---------------------------------------------------------
+// TrackListWidget
+//---------------------------------------------------------
+
+TrackListWidget::TrackListWidget(QWidget* parent)
+ : QWidget(parent)
+ {
+ setAttribute(Qt::WA_NoSystemBackground);
+ setAttribute(Qt::WA_StaticContents);
+ }
+
+//---------------------------------------------------------
+// paintEvent
+//---------------------------------------------------------
+
+void TrackListWidget::paintEvent(QPaintEvent* ev)
+ {
+ QPainter p(this);
+ p.eraseRect(ev->rect());
+ }
+
+//---------------------------------------------------------
+// mousePressEvent
+//---------------------------------------------------------
+
+void TrackListWidget::mousePressEvent(QMouseEvent* ev)
+ {
+ if (ev->button() == Qt::RightButton) {
+ QMenu* menu = newAddTrackMenu(this);
+ menu->exec(ev->globalPos());
+ }
+ }
+
+//---------------------------------------------------------
+// wheelEvent
+//---------------------------------------------------------
+
+void TrackListWidget::wheelEvent(QWheelEvent* e)
+ {
+ emit mouseWheel(e);
+ }
+
+//---------------------------------------------------------
+// mouseWheel
+// get redirected mouse wheel events from TrackListWidget
+//---------------------------------------------------------
+
+void Arranger::mouseWheel(QWheelEvent* e)
+ {
+ if (e->orientation() != Qt::Vertical)
+ return;
+ QScrollBar* sb = canvas->verticalScrollBar();
+ int step = qMin(QApplication::wheelScrollLines() * sb->singleStep(), sb->pageStep());
+ if ((e->modifiers() & Qt::ControlModifier) || (e->modifiers() & Qt::ShiftModifier))
+ step = sb->pageStep();
+ int offset = e->delta() * step / 120;
+ if (sb->invertedControls())
+ offset = -offset;
+ if (qAbs(offset) < 1)
+ return;
+ sb->setValue(sb->value() + offset);
+ e->accept();
+ }
+
+//---------------------------------------------------------
+// appendSubtrack
+// the user requests a new controller subtrack
+//---------------------------------------------------------
+
+void Arranger::appendSubtrack(TLWidget* trackWidget)
+ {
+ Track* t = trackWidget->track();
+
+ ArrangerTrack* at = new ArrangerTrack;
+ at->h = minTrackHeight;
+ at->ctrl = CTRL_NO_CTRL;
+ t->subtracks.push_back(at);
+ if(initSubtrack(t, at)==true) {
+ updateIndex();
+ }
+ else {
+ t->subtracks.remove(at);
+ delete at;
+ }
+ }
+
+//---------------------------------------------------------
+// initSubtrack
+//---------------------------------------------------------
+
+bool Arranger::initSubtrack(Track* t, ArrangerTrack* at)
+ {
+ TLSWidget* tw = new TLSWidget(t, at, canvas);
+ tw->setFixedHeight(at->h);
+
+ if(tw->setCtrl(at->ctrl) == true) {
+ tl->insertWidget(tlIndex(at), tw);
+ at->tw = tw;
+ connect(tw, SIGNAL(minusClicked(TLSWidget*)), SLOT(removeSubtrack(TLSWidget*)));
+ connect(tw, SIGNAL(controllerChanged(int)), canvas->widget(), SLOT(update()));
+ connect(tw, SIGNAL(drag(int, int)), SLOT(drag(int,int)));
+ connect(tw, SIGNAL(startDrag(int)), SLOT(startDrag(int)));
+ tw->show();
+ }
+ else {
+ delete tw;
+ return false;
+ }
+ return true;
+ }
+
+//---------------------------------------------------------
+// removeSubtrack
+//---------------------------------------------------------
+
+void Arranger::removeSubtrack(TLSWidget* w)
+ {
+ Track* t = w->track();
+ for (iArrangerTrack it = t->subtracks.begin(); it != t->subtracks.end(); ++it) {
+ ArrangerTrack* at = *it;
+ if (at->tw == w) {
+ tl->removeWidget(at->tw);
+// at->tw->close();
+ delete at->tw;
+ t->subtracks.erase(it);
+ delete at;
+ break;
+ }
+ }
+ updateIndex();
+ }
+
+//---------------------------------------------------------
+// configTrackList
+//---------------------------------------------------------
+
+void Arranger::configTrackList()
+ {
+ if (configTrackEditor == 0) {
+ configTrackEditor = new ConfigTrackList(this);
+ connect(configTrackEditor, SIGNAL(trackConfigChanged()), SIGNAL(configChanged()));
+ }
+ configTrackEditor->show();
+ }
+
+//---------------------------------------------------------
+// atrack
+//---------------------------------------------------------
+
+ArrangerTrack* Arranger::atrack(int idx)
+ {
+ int k = 0;
+ TrackList* stl = song->tracks();
+ for (iTrack i = stl->begin(); i != stl->end(); ++i) {
+ ArrangerTrack* at = &(*i)->arrangerTrack;
+ if (idx == k)
+ return at;
+ ++k;
+ for (iArrangerTrack it = (*i)->subtracks.begin(); it != (*i)->subtracks.end(); ++it) {
+ ArrangerTrack* t = *it;
+ if (idx == k)
+ return t;
+ ++k;
+ }
+ }
+ return 0;
+ }
+
+//---------------------------------------------------------
+// updateIndex
+// update vertical scrollbar & index values
+//---------------------------------------------------------
+
+void Arranger::updateIndex()
+ {
+ int idx = 0;
+ int h = 2 * defaultTrackHeight; // always show room for at least two
+ // tracks at end of list
+
+ TrackList* stl = song->tracks();
+ for (iTrack i = stl->begin(); i != stl->end(); ++i) {
+ ArrangerTrack* at = &(*i)->arrangerTrack;
+ if (at->tw == 0)
+ continue;
+ ((TLWidget*)at->tw)->setIdx(idx);
+ h += at->tw->height();
+ ++idx;
+ for (iArrangerTrack it = (*i)->subtracks.begin(); it != (*i)->subtracks.end(); ++it) {
+ ArrangerTrack* t = *it;
+ if (t->tw == 0)
+ continue;
+ ((TLSWidget*)t->tw)->setIdx(idx);
+ h += t->tw->height();
+ ++idx;
+ }
+ }
+ setGMute();
+ setGSolo();
+ setGar();
+ setGaw();
+ canvas->setVSize(h);
+ trackList->setFixedHeight(h + 32);
+ canvas->widget()->update();
+ QPoint p(canvas->getWPos());
+ setTLViewPos(0, p.y());
+ }
+
+//---------------------------------------------------------
+// toggleTrackInfo
+//---------------------------------------------------------
+
+void Arranger::toggleTrackInfo(bool val)
+ {
+ trackInfoVisible = val;
+ if (trackInfoVisible) {
+ if (_curTrack == 0) {
+ if (zeroTrackInfo == 0) {
+ zeroTrackInfo = new QWidget(this);
+ trackInfo->addWidget(zeroTrackInfo);
+ }
+ trackInfo->setCurrentWidget(zeroTrackInfo);
+
+ return;
+ }
+ Track::TrackType t = _curTrack->type();
+ TrackInfo* w = trackInfos[t];
+ if (w == 0) {
+ w = trackInfos[t] = createTrackInfo();
+ trackInfo->addWidget(w);
+ }
+ w->init(_curTrack);
+ trackInfo->setCurrentWidget(w);
+ }
+// infoDock->layout()->invalidate();
+// infoDock->layout()->update();
+ }
+
+//---------------------------------------------------------
+// toggleMixerStrip
+//---------------------------------------------------------
+
+void Arranger::toggleMixerStrip(bool val)
+ {
+ mixerStripVisible = val;
+ if (mixerStripVisible && _curTrack) {
+ if (strip && _curTrack != strip->getTrack()) {
+ strip->close();
+ strip = 0;
+ }
+ if (!strip) {
+ switch(_curTrack->type()) {
+ case Track::MIDI_IN:
+ strip = new MidiInPortStrip(0, (MidiInPort*)_curTrack, false);
+ break;
+ case Track::MIDI_OUT:
+ strip = new MidiOutPortStrip(0, (MidiOutPort*)_curTrack, false);
+ break;
+ case Track::MIDI_SYNTI:
+ strip = new MidiSyntiStrip(0, (MidiSynti*)_curTrack, false);
+ break;
+ case Track::MIDI:
+ strip = new MidiStrip(0, (MidiTrack*)_curTrack, false);
+ break;
+ default:
+ strip = new AudioStrip(0, (AudioTrack*)_curTrack, false);
+ break;
+ }
+ //
+ // it looks like the dock widget has a minimum
+ // width
+ strip->setFixedWidth(STRIP_WIDTH + 10);
+ mixerDock->setWidget(strip);
+ }
+ }
+ else {
+ if (strip) {
+ strip->close();
+ strip = 0;
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// startLoadSong
+//---------------------------------------------------------
+
+void Arranger::startLoadSong()
+ {
+ if (strip)
+ strip->close();
+ strip = 0;
+
+ TrackList* stl = song->tracks();
+ for (iTrack i = stl->begin(); i != stl->end(); ++i) {
+ ArrangerTrack* at = &(*i)->arrangerTrack;
+ tl->removeWidget(at->tw);
+ at->tw->close();
+ delete at->tw;
+ at->tw = 0;
+ for (iArrangerTrack it = (*i)->subtracks.begin(); it != (*i)->subtracks.end(); ++it) {
+ ArrangerTrack* at = *it;
+ tl->removeWidget(at->tw);
+ at->tw->close();
+ delete at->tw;
+ }
+ (*i)->subtracks.clear();
+ }
+ _curTrack = 0;
+ }
+
+//---------------------------------------------------------
+// endLoadSong
+// create track list widgets
+//---------------------------------------------------------
+
+void Arranger::endLoadSong()
+ {
+ TrackList* stl = song->tracks();
+
+ for (iTrack i = stl->begin(); i != stl->end(); ++i) {
+ Track* t = *i;
+ insertTrack1(t);
+ for (iArrangerTrack i = t->subtracks.begin(); i != t->subtracks.end(); ++i) {
+ initSubtrack(t, *i);
+ }
+ }
+ updateIndex();
+ setSelectedTrack(song->selectedTrack());
+ infoDock->setVisible(trackInfoVisible);
+ mixerDock->setVisible(mixerStripVisible);
+ }
+
+//---------------------------------------------------------
+// updateConfiguration
+//---------------------------------------------------------
+
+void Arranger::updateConfiguration()
+ {
+ if (config.canvasUseBgPixmap) {
+ canvas->setCanvasBackground(QPixmap(config.canvasBgPixmap));
+ }
+ else
+ canvas->setCanvasBackground(config.canvasBgColor);
+//TD canvas->setShowGrid(config.canvasShowGrid);
+//TD update();
+ }
+
+//---------------------------------------------------------
+// readStatus
+//---------------------------------------------------------
+
+void Arranger::readStatus(QDomNode node)
+ {
+ TrackList* tl = song->tracks();
+ iTrack it = tl->begin();
+
+ QPoint wpos;
+ double xmag = 0.05;
+ double ymag = 1.0;
+
+ for (; !node.isNull(); node = node.nextSibling()) {
+ QDomElement e = node.toElement();
+ QString tag(e.tagName());
+ QString s = e.text();
+ int i = s.toInt();
+ if (tag == "info")
+ trackInfoVisible = i;
+ else if (tag == "strip")
+ mixerStripVisible = i;
+ else if (tag == "TrackConf") {
+ }
+ else if (tag == "hmag")
+ xmag = s.toDouble();
+ else if (tag == "vmag")
+ ymag = s.toDouble();
+ else if (tag == "hpos")
+ wpos.setX(i);
+ else if (tag == "vpos")
+ wpos.setY(i);
+ else if (tag == "raster") {
+ muse->initRaster(i);
+ canvas->setRaster(i);
+ }
+ else if (tag == "splitter") {
+ split->readStatus(node);
+ QList<int> sizes = split->sizes();
+ split->setSizes(sizes);
+ }
+ else
+ printf("Arranger: unknown tag %s\n", tag.toLatin1().data());
+ }
+ canvas->setMag(xmag, ymag);
+ canvas->setWPos(wpos);
+ }
+
+//---------------------------------------------------------
+// writeStatus
+//---------------------------------------------------------
+
+void Arranger::writeStatus(Xml& xml)
+ {
+ xml.stag("arranger");
+
+ for (int i = 0; i < Track::TRACK_TYPES; ++i) {
+ TrGroupList* gl = &glist[i];
+ xml.stag(QString("TrackConf type=\"%1\"").arg(i));
+ for (iTrGroup ig = gl->begin(); ig != gl->end(); ++ig) {
+ TrElementList& el = *ig;
+ xml.stag("group");
+ for (iTrElement ie = el.begin(); ie != el.end(); ++ie)
+ xml.tagE(QString("element id=\"%1\"").arg((*ie)->id));
+ xml.etag("group");
+ }
+ xml.etag("TrackConf");
+ }
+ xml.tag("info", trackInfoVisible);
+ xml.tag("strip", mixerStripVisible);
+ xml.tag("hmag", canvas->xmag());
+ xml.tag("vmag", canvas->ymag());
+ xml.tag("hpos", canvas->getWPos().x());
+ xml.tag("vpos", canvas->getWPos().y());
+ xml.tag("raster", muse->raster());
+ split->writeStatus("splitter", xml);
+ xml.etag("arranger");
+ }
+
+//---------------------------------------------------------
+// setGMute
+//---------------------------------------------------------
+
+void Arranger::setGMute()
+ {
+ TrackList* tl = song->tracks();
+ bool mute = false;
+ for (iTrack i = tl->begin(); i != tl->end(); ++i) {
+ if ((*i)->mute()) {
+ mute = true;
+ break;
+ }
+ }
+ gmute->setChecked(mute);
+ }
+
+//---------------------------------------------------------
+// setGSolo
+//---------------------------------------------------------
+
+void Arranger::setGSolo()
+ {
+ TrackList* tl = song->tracks();
+ bool solo = false;
+ for (iTrack i = tl->begin(); i != tl->end(); ++i) {
+ if ((*i)->solo()) {
+ solo = true;
+ break;
+ }
+ }
+ gsolo->setChecked(solo);
+ }
+
+//---------------------------------------------------------
+// setGar
+//---------------------------------------------------------
+
+void Arranger::setGar()
+ {
+ TrackList* tl = song->tracks();
+ bool ar = false;
+ for (iTrack i = tl->begin(); i != tl->end(); ++i) {
+ if ((*i)->autoRead()) {
+ ar = true;
+ break;
+ }
+ }
+ if (ar == false) {
+ MidiTrackList* cl = song->midis();
+ for (iMidiTrack i = cl->begin(); i != cl->end(); ++i) {
+ if ((*i)->autoRead()) {
+ ar = true;
+ break;
+ }
+ }
+ }
+ gar->setChecked(ar);
+ }
+
+//---------------------------------------------------------
+// setGaw
+//---------------------------------------------------------
+
+void Arranger::setGaw()
+ {
+ TrackList*tl = song->tracks();
+ bool aw = false;
+ for (iTrack i = tl->begin(); i != tl->end(); ++i) {
+ if ((*i)->autoWrite())
+ aw = true;
+ }
+ if (aw == false) {
+ MidiTrackList* cl = song->midis();
+ for (iMidiTrack i = cl->begin(); i != cl->end(); ++i) {
+ if ((*i)->autoWrite()) {
+ aw = true;
+ break;
+ }
+ }
+ }
+ gaw->setChecked(aw);
+ }
+
+//---------------------------------------------------------
+// offGMute
+//---------------------------------------------------------
+
+void Arranger::offGMute()
+ {
+ TrackList*tl = song->tracks();
+ for (iTrack i = tl->begin(); i != tl->end(); ++i)
+ song->setMute(*i,false);
+ gmute->setChecked(false);
+ }
+
+//---------------------------------------------------------
+// offGSolo
+//---------------------------------------------------------
+
+void Arranger::offGSolo()
+ {
+ TrackList*tl = song->tracks();
+ for (iTrack i = tl->begin(); i != tl->end(); ++i)
+ song->setSolo(*i, false);
+ gsolo->setChecked(false);
+ }
+
+//---------------------------------------------------------
+// offGar
+//---------------------------------------------------------
+
+void Arranger::offGar()
+ {
+ TrackList*tl = song->tracks();
+ for (iTrack i = tl->begin(); i != tl->end(); ++i)
+ song->setAutoRead(*i, false);
+ MidiTrackList* cl = song->midis();
+ for (iMidiTrack i = cl->begin(); i != cl->end(); ++i)
+ song->setAutoRead(*i, false);
+ gar->setChecked(false);
+ }
+
+//---------------------------------------------------------
+// offGaw
+//---------------------------------------------------------
+
+void Arranger::offGaw()
+ {
+ TrackList*tl = song->tracks();
+ for (iTrack i = tl->begin(); i != tl->end(); ++i)
+ song->setAutoWrite(*i, false);
+ MidiTrackList* cl = song->midis();
+ for (iMidiTrack i = cl->begin(); i != cl->end(); ++i)
+ song->setAutoWrite(*i, false);
+ gaw->setChecked(false);
+ }
+
+//---------------------------------------------------------
+// setTool
+//---------------------------------------------------------
+
+void Arranger::setTool(int t)
+ {
+ tool = Tool(t);
+ canvas->setTool(tool);
+ }
+
+//---------------------------------------------------------
+// setSelectedTrack
+//---------------------------------------------------------
+
+void Arranger::setSelectedTrack(Track* t)
+ {
+ _curTrack = t;
+ toggleTrackInfo(trackInfoVisible);
+ toggleMixerStrip(mixerStripVisible);
+ }
+
+//---------------------------------------------------------
+// moveTrack
+// move src before dst
+//---------------------------------------------------------
+
+void Arranger::moveTrack(Track* src, Track* dst)
+ {
+ audio->msgMoveTrack(src, dst);
+ tl->clear();
+ TrackList* stl = song->tracks();
+ for (iTrack i = stl->begin(); i != stl->end(); ++i) {
+ tl->addWidget((*i)->arrangerTrack.tw);
+ for (iArrangerTrack it = (*i)->subtracks.begin(); it != (*i)->subtracks.end(); ++it)
+ tl->addWidget((*it)->tw);
+ }
+ tl->setGeometry(((QWidget*)tl->parent())->geometry());
+ updateIndex();
+ }
+
+//---------------------------------------------------------
+//! \fn Arranger::keyPressEvent(QKeyEvent* e)
+//! \brief Called when a key is pressed
+//! @param e The key event
+//---------------------------------------------------------
+
+void Arranger::keyPressEvent(QKeyEvent* /*e*/)
+ {
+ printf("Arranger::keyPressEvent\n");
+#if 0 //TODOB
+ int key = e->key();
+ bool keypress_handled = false;
+
+ if (e->modifiers() & Qt::ShiftModifier)
+ key += Qt::SHIFT;
+ if (e->modifiers() & Qt::AltModifier)
+ key += Qt::ALT;
+ if (e->modifiers() & Qt::ControlModifier)
+ key += Qt::CTRL;
+
+ if (shortcutsKbdMovement.isValid()) {
+ if (key == shortcuts[SHRT_SEL_LEFT].key || key == shortcuts[SHRT_SEL_LEFT_ADD].key) {
+ keypress_handled = true;
+ bool add = (key == shortcuts[SHRT_SEL_LEFT_ADD].key);
+ PartList* parts = shortcutsKbdMovement.track()->parts();
+ Part* nextLeft = 0;
+
+ for (iPart i = parts->begin(); i != parts->end(); i++) {
+ Part* tmp = i->second;
+ if (!nextLeft) {
+ if (tmp->tick() < shortcutsKbdMovement.getLpos())
+ nextLeft = tmp;
+ }
+ else {
+ if (tmp->tick() > nextLeft->tick() && tmp->tick() < shortcutsKbdMovement.getLpos() )
+ nextLeft = tmp;
+ }
+ }
+ if (nextLeft) {
+ song->selectPart(nextLeft, add);
+ shortcutsKbdMovement.setPart(nextLeft);
+ shortcutsKbdMovement.setPos(nextLeft->tick(), nextLeft->tick() + nextLeft->lenTick());
+ }
+ }
+ else if (key == shortcuts[SHRT_SEL_RIGHT].key || key == shortcuts[SHRT_SEL_RIGHT_ADD].key) {
+ keypress_handled = true;
+ bool add = (key == shortcuts[SHRT_SEL_RIGHT_ADD].key);
+ PartList* parts = shortcutsKbdMovement.track()->parts();
+ Part* nextRight = 0;
+
+ for (iPart i = parts->begin(); i != parts->end(); i++) {
+ Part* tmp = i->second;
+ if (!nextRight) {
+ if (tmp->tick() > shortcutsKbdMovement.getLpos())
+ nextRight = tmp;
+ }
+ else {
+ if (tmp->tick() < nextRight->tick() && tmp->tick() > shortcutsKbdMovement.getLpos() )
+ nextRight = tmp;
+ }
+ }
+ if (nextRight) {
+ song->selectPart(nextRight, add);
+ shortcutsKbdMovement.setPart(nextRight);
+ shortcutsKbdMovement.setPos(nextRight->tick(), nextRight->tick() + nextRight->lenTick());
+ }
+ }
+
+ else if (key == shortcuts[SHRT_SEL_ABOVE].key) {
+ // TODO
+ }
+ else if (key == shortcuts[SHRT_SEL_BELOW].key) {
+ // TODO
+ }
+ } // -- end movement
+ else {
+ if (key == shortcuts[SHRT_TOOL_POINTER].key) {
+ emit toolChanged(PointerTool);
+ return;
+ }
+ else if (key == shortcuts[SHRT_TOOL_PENCIL].key) {
+ emit toolChanged(PencilTool);
+ return;
+ }
+ else if (key == shortcuts[SHRT_TOOL_RUBBER].key) {
+ emit toolChanged(RubberTool);
+ return;
+ }
+ else if (key == shortcuts[SHRT_TOOL_LINEDRAW].key) {
+ emit toolChanged(DrawTool);
+ return;
+ }
+ }
+ // If we haven't dealt with the keypress, pass it along
+ if (!keypress_handled) {
+ e->ignore();
+ }
+#endif
+// e->ignore();
+ }
+
+
+/*!
+ \fn Arranger::kbdMovementUpdate(Track* t, Part* p)
+ \brief Slot connected to canvaswidget, called when a part is selected
+ @param t Track the selected part belongs to (null if no part selected)
+ @param p The selected Part (null if no part selected)
+ */
+void Arranger::kbdMovementUpdate(Track*, Part*)
+ {
+ printf("kbdMovementUpdate\n");
+// if (t && p ) {
+// // If other track selected:
+// if (t != shortcutsKbdMovement.track()) {
+// TrackList* stl = song->tracks();
+// for (iTrack i = stl->begin(); i != stl->end(); ++i) {
+// if (*i == t) {
+// // Set focus and select current track
+// t->arrangerTrack.tw->setFocus();
+// song->selectTrack(t);
+// }
+// }
+// }
+// shortcutsKbdMovement.setTrack(t);
+// shortcutsKbdMovement.setPart(p);
+// shortcutsKbdMovement.setPos(p->tick(), p->tick() + p->lenTick());
+// }
+// else { // Deselected
+// shortcutsKbdMovement.reset();
+// }
+ }
+
+//---------------------------------------------------------
+// addMarker
+//---------------------------------------------------------
+
+void Arranger::addMarker(const AL::Pos& pos)
+ {
+ song->addMarker(QString(), pos);
+ canvas->widget()->update();
+ }
+
+//---------------------------------------------------------
+// removeMarker
+//---------------------------------------------------------
+
+void Arranger::removeMarker(const AL::Pos& pos)
+ {
+ AL::MarkerList* ml = song->marker();
+ for (AL::iMarker i = ml->begin(); i != ml->end(); ++i) {
+ AL::iMarker ni = i;
+ ++ni;
+ if (i->second <= pos && (ni == ml->end() || ni->second > pos)) {
+ song->removeMarker(&(i->second));
+ canvas->widget()->update();
+ return;
+ }
+ }
+ printf("marker not found\n");
+ }
diff --git a/muse_qt4_evolution/muse/arranger.h b/muse_qt4_evolution/muse/arranger.h
new file mode 100644
index 00000000..1c9f6e38
--- /dev/null
+++ b/muse_qt4_evolution/muse/arranger.h
@@ -0,0 +1,175 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __ARRANGER_H__
+#define __ARRANGER_H__
+
+#include "widgets/tools.h"
+#include "track.h"
+
+namespace AL {
+ class Xml;
+ class Pos;
+ };
+using AL::Xml;
+class AL::Pos;
+
+class Track;
+class TrackInfo;
+class TLWidget;
+class TLSWidget;
+class PartCanvas;
+class Part;
+class SimpleButton;
+class Strip;
+class ArrangerTrack;
+class Splitter;
+class TlsvLayout;
+class TLayout;
+
+//---------------------------------------------------------
+// InfoStack
+//---------------------------------------------------------
+
+class InfoStack : public QStackedWidget {
+ Q_OBJECT;
+
+ virtual QSize sizeHint() const;
+
+ public:
+ InfoStack() : QStackedWidget() {}
+ };
+
+//---------------------------------------------------------
+// TrackListWidget
+//---------------------------------------------------------
+
+class TrackListWidget : public QWidget {
+ Q_OBJECT
+
+ void mousePressEvent(QMouseEvent*);
+ void wheelEvent(QWheelEvent*);
+ virtual void paintEvent(QPaintEvent*);
+
+ signals:
+ void mouseWheel(QWheelEvent*);
+
+ public:
+ TrackListWidget(QWidget* parent = 0);
+ };
+
+//---------------------------------------------------------
+// Arranger
+//---------------------------------------------------------
+
+class Arranger : public QWidget {
+ Q_OBJECT
+
+ QAction* infoDockAction;
+ QAction* mixerDockAction;
+
+ TrackInfo* trackInfos[Track::TRACK_TYPES];
+ QWidget* zeroTrackInfo;
+ Tool tool;
+ QWidget* trackList;
+ PartCanvas* canvas;
+ TLayout* tl; // tracklist layout
+ TrackListWidget* tlsv;
+ TlsvLayout* tlsvLayout;
+ QDialog* configTrackEditor;
+ QStackedWidget* trackInfo;
+ QScrollArea* infoView;
+ Track* _curTrack; // current selected track
+ SimpleButton* gmute;
+ SimpleButton* gsolo;
+ SimpleButton* gar;
+ SimpleButton* gaw;
+ Strip* strip;
+ QStackedWidget* info;
+
+ Splitter* split;
+ QDockWidget* infoDock;
+ QDockWidget* mixerDock;
+
+ int startH; // start value for resize track height
+
+ bool trackInfoVisible;
+ bool mixerStripVisible;
+
+ void updateIndex();
+ TrackInfo* createTrackInfo();
+ int tlIndex(Track*) const;
+ int tlIndex(ArrangerTrack* t) const;
+ bool initSubtrack(Track* t, ArrangerTrack*);
+ ArrangerTrack* atrack(int idx);
+ void insertTrack1(Track*);
+
+ private slots:
+ void startDrag(int idx);
+ void drag(int idx, int);
+ void setTLViewPos(int, int);
+ void appendSubtrack(TLWidget*);
+ void removeSubtrack(TLSWidget*);
+ void configTrackList();
+ void toggleTrackInfo(bool);
+ void toggleMixerStrip(bool);
+ void setGMute();
+ void setGSolo();
+ void setGar();
+ void setGaw();
+ void offGMute();
+ void offGSolo();
+ void offGar();
+ void offGaw();
+ void setSelectedTrack(Track*);
+ void moveTrack(Track* src, Track* dst);
+ void kbdMovementUpdate(Track* t, Part* p);
+ void mouseWheel(QWheelEvent*);
+ void setPos(int, const AL::Pos&);
+ void addMarker(const AL::Pos&);
+ void removeMarker(const AL::Pos&);
+
+ public slots:
+ void insertTrack(Track*);
+ void removeTrack(Track*);
+ void setTool(int t);
+ void updateConfiguration();
+ void startLoadSong();
+
+ signals:
+ void configChanged();
+ void toolChanged(int);
+ void editPart(Part*);
+ void cursorPos(const AL::Pos&,bool);
+
+ public:
+ Arranger(QMainWindow* parent = 0);
+ void readStatus(QDomNode);
+ void writeStatus(Xml&);
+ Track* curTrack() const { return _curTrack; }
+ void endLoadSong();
+ Strip* getStrip() const { return strip; }
+
+ protected:
+ virtual void keyPressEvent(QKeyEvent* e);
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/astrip.cpp b/muse_qt4_evolution/muse/astrip.cpp
new file mode 100644
index 00000000..8d6cdd09
--- /dev/null
+++ b/muse_qt4_evolution/muse/astrip.cpp
@@ -0,0 +1,791 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2000-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "audio.h"
+#include "audiodev.h"
+#include "song.h"
+#include "astrip.h"
+#include "synth.h"
+#include "rack.h"
+#include "gconfig.h"
+#include "muse.h"
+#include "widgets/simplebutton.h"
+#include "widgets/utils.h"
+#include "auxplugin.h"
+#include "midiinport.h"
+#include "midioutport.h"
+
+#include "awl/volknob.h"
+#include "awl/panknob.h"
+#include "awl/mslider.h"
+#include "awl/volentry.h"
+#include "awl/panentry.h"
+
+//---------------------------------------------------------
+// AudioStrip
+// create mixer strip
+//---------------------------------------------------------
+
+AudioStrip::AudioStrip(Mixer* m, AudioTrack* t, bool align)
+ : Strip(m, t, align)
+ {
+ iR = 0;
+ oR = 0;
+ off = 0;
+ volume = -1.0;
+ channel = t->channels();
+
+ //---------------------------------------------------
+ // prefader plugin rack
+ //---------------------------------------------------
+
+ rack1 = new EffectRack(this, t, true);
+ rack1->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+ rack1->setFixedHeight(rack1->sizeHint().height() + 2);
+ grid->addWidget(rack1, 1, 0, 1, 2);
+
+ //---------------------------------------------------
+ // mono/stereo pre/post
+ //---------------------------------------------------
+
+ stereo = newStereoButton();
+ stereo->setChecked(channel == 2);
+ stereo->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+ stereo->setFixedHeight(LABEL_HEIGHT);
+ connect(stereo, SIGNAL(clicked(bool)), SLOT(stereoToggled(bool)));
+
+ pre = new QToolButton;
+ pre->setObjectName("preButton");
+ pre->setCheckable(true);
+ pre->setText(tr("Pre"));
+ pre->setToolTip(tr("pre fader - post fader"));
+ pre->setChecked(t->prefader());
+ pre->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+ pre->setFixedHeight(LABEL_HEIGHT);
+ connect(pre, SIGNAL(clicked(bool)), SLOT(preToggled(bool)));
+
+ grid->addWidget(stereo, 2, 0);
+ grid->addWidget(pre, 2, 1);
+
+ //---------------------------------------------------
+ // slider, label
+ //---------------------------------------------------
+
+ slider = new Awl::MeterSlider(this);
+ slider->setRange(config.minSlider, config.maxSlider);
+ slider->setFixedWidth(60);
+ slider->setChannel(channel);
+ Ctrl* ctrl = t->getController(AC_VOLUME);
+ double vol = 0.0f;
+ if (ctrl)
+ vol = ctrl->curVal().f;
+ slider->setValue(vol);
+ grid->addWidget(slider, 3, 0, 1, 2); // 100, Qt::AlignRight);
+
+ sl = new Awl::VolEntry(this);
+ sl->setSuffix(tr("dB"));
+ sl->setFrame(true);
+ sl->setValue(vol);
+ sl->setFixedHeight(entrySize.height());
+
+ connect(slider, SIGNAL(valueChanged(double,int)), SLOT(volumeChanged(double)));
+ connect(sl, SIGNAL(valueChanged(double,int)), SLOT(volumeChanged(double)));
+
+ connect(slider, SIGNAL(sliderPressed(int)), SLOT(volumePressed()));
+ connect(slider, SIGNAL(sliderReleased(int)), SLOT(volumeReleased()));
+ connect(slider, SIGNAL(meterClicked()), SLOT(resetPeaks()));
+ grid->addWidget(sl, 4, 0, 1, 2);
+
+ //---------------------------------------------------
+ // pan, balance
+ //---------------------------------------------------
+
+ pan = addPanKnob(&panl, 5);
+ double panv = t->getController(AC_PAN)->curVal().f;
+ pan->setValue(panv);
+ panl->setValue(panv);
+
+ //---------------------------------------------------
+ // postfader plugin rack
+ //---------------------------------------------------
+
+ rack2 = new EffectRack(this, t, false);
+ rack2->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+ rack2->setFixedHeight(rack1->sizeHint().height() + 2);
+ grid->addWidget(rack2, 7, 0, 1, 2);
+
+ //---------------------------------------------------
+ // mute, solo, record
+ //---------------------------------------------------
+
+ Track::TrackType type = t->type();
+
+ mute = newMuteButton();
+ mute->setChecked(t->mute());
+ mute->setFixedHeight(BUTTON_HEIGHT);
+ connect(mute, SIGNAL(clicked(bool)), SLOT(muteToggled(bool)));
+ connect(t, SIGNAL(muteChanged(bool)), mute, SLOT(setChecked(bool)));
+
+ solo = newSoloButton();
+ solo->setDisabled(true);
+ solo->setFixedHeight(BUTTON_HEIGHT);
+ connect(solo, SIGNAL(clicked(bool)), SLOT(soloToggled(bool)));
+ connect(t, SIGNAL(soloChanged(bool)), solo, SLOT(setChecked(bool)));
+
+ off = newOffButton();
+ off->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+ off->setFixedHeight(BUTTON_HEIGHT);
+ off->setChecked(t->off());
+ connect(off, SIGNAL(clicked(bool)), SLOT(offToggled(bool)));
+ connect(t, SIGNAL(offChanged(bool)), this, SLOT(updateOffState()));
+
+ if (track->canRecord()) {
+ record = newRecordButton();
+ record->setFixedHeight(BUTTON_HEIGHT);
+ if (type == Track::AUDIO_OUTPUT)
+ record->setToolTip(tr("record downmix"));
+ record->setChecked(t->recordFlag());
+ connect(record, SIGNAL(clicked(bool)), SLOT(recordToggled(bool)));
+ connect(t, SIGNAL(recordChanged(bool)), record, SLOT(setChecked(bool)));
+ }
+ else
+ record = 0;
+
+ grid->addWidget(off, 8, 0);
+ if (record)
+ grid->addWidget(record, 8, 1);
+ grid->addWidget(mute, 9, 0);
+ grid->addWidget(solo, 9, 1);
+
+ //---------------------------------------------------
+ // automation read write
+ //---------------------------------------------------
+
+ addAutomationButtons(10);
+
+ //---------------------------------------------------
+ // routing
+ //---------------------------------------------------
+
+ iR = newInRouteButton();
+ grid->addWidget(iR, 12, 0);
+ connect(iR->menu(), SIGNAL(aboutToShow()), SLOT(iRouteShow()));
+ connect(iR->menu(), SIGNAL(aboutToHide()), SLOT(iRouteHide()));
+ connect(iR->menu(), SIGNAL(triggered(QAction*)), song, SLOT(routeChanged(QAction*)));
+
+ oR = newOutRouteButton();
+ grid->addWidget(oR, 12, 1);
+ connect(oR->menu(), SIGNAL(aboutToShow()), SLOT(oRouteShow()));
+ connect(oR->menu(), SIGNAL(aboutToHide()), SLOT(oRouteHide()));
+ connect(oR->menu(), SIGNAL(triggered(QAction*)), song, SLOT(routeChanged(QAction*)));
+
+ if (off) {
+ updateOffState(); // init state
+ }
+ connect(song, SIGNAL(songChanged(int)), SLOT(songChanged(int)));
+ connect(track, SIGNAL(controllerChanged(int)), SLOT(controllerChanged(int)));
+ connect(track, SIGNAL(autoReadChanged(bool)), SLOT(autoChanged()));
+ connect(track, SIGNAL(autoWriteChanged(bool)), SLOT(autoChanged()));
+ autoChanged();
+ }
+
+//---------------------------------------------------------
+// heartBeat
+//---------------------------------------------------------
+
+void AudioStrip::heartBeat()
+ {
+ int peakHold = (config.peakHoldTime * config.guiRefresh) / 1000;
+ for (int ch = 0; ch < channel; ++ch) {
+ int n = track->peakTimer(ch);
+ ++n;
+ double f = track->peak(ch);
+ if (n >= peakHold) {
+ // track->resetPeak(ch);
+ track->setPeak(ch, f * 0.7);
+ }
+ track->setPeakTimer(ch, n);
+ slider->setMeterVal(ch, track->meter(ch), f);
+ }
+ }
+
+//---------------------------------------------------------
+// songChanged
+//---------------------------------------------------------
+
+void AudioStrip::songChanged(int val)
+ {
+ AudioTrack* src = (AudioTrack*)track;
+ if (val & SC_TRACK_MODIFIED)
+ updateLabel();
+ if ((val & SC_ROUTE) && pre)
+ pre->setChecked(src->prefader());
+ if (val & SC_CHANNELS)
+ updateChannels();
+ }
+
+//---------------------------------------------------------
+// offToggled
+//---------------------------------------------------------
+
+void AudioStrip::offToggled(bool val)
+ {
+ song->setOff(track, !val);
+ }
+
+//---------------------------------------------------------
+// updateOffState
+//---------------------------------------------------------
+
+void AudioStrip::updateOffState()
+ {
+ bool val = !track->off();
+ slider->setEnabled(val);
+ sl->setEnabled(val);
+ pan->setEnabled(val);
+ panl->setEnabled(val);
+ pre->setEnabled(val);
+ rack1->setEnabled(val);
+ rack2->setEnabled(val);
+
+ if (track->type() != Track::AUDIO_SOFTSYNTH)
+ stereo->setEnabled(val);
+ label->setEnabled(val);
+ if (solo)
+ solo->setEnabled(val);
+ if (mute)
+ mute->setEnabled(val);
+ if (iR)
+ iR->setEnabled(val);
+ if (oR)
+ oR->setEnabled(val);
+ if (off)
+ off->setChecked(track->off());
+ if (ar)
+ ar->setEnabled(val);
+ if (aw)
+ aw->setEnabled(val);
+ }
+
+//---------------------------------------------------------
+// preToggled
+//---------------------------------------------------------
+
+void AudioStrip::preToggled(bool val)
+ {
+ ((AudioTrack*)track)->setPrefader(val);
+ resetPeaks();
+ song->update(SC_ROUTE);
+ }
+
+//---------------------------------------------------------
+// stereoToggled
+//---------------------------------------------------------
+
+void AudioStrip::stereoToggled(bool val)
+ {
+ int nc = val ? 1 : 2;
+ if (channel == nc)
+ return;
+ audio->msgSetChannels((AudioTrack*)track, nc);
+ song->update(SC_CHANNELS);
+ }
+
+//---------------------------------------------------------
+// volumeChanged
+//---------------------------------------------------------
+
+void AudioStrip::volumeChanged(double v)
+ {
+ CVal val;
+ val.f = v;
+ song->setControllerVal(track, AC_VOLUME, val);
+ }
+
+//---------------------------------------------------------
+// volumePressed
+//---------------------------------------------------------
+
+void AudioStrip::volumePressed()
+ {
+ ((AudioTrack*)track)->startAutoRecord(AC_VOLUME);
+ }
+
+//---------------------------------------------------------
+// volumeReleased
+//---------------------------------------------------------
+
+void AudioStrip::volumeReleased()
+ {
+ ((AudioTrack*)track)->stopAutoRecord(AC_VOLUME);
+ }
+
+//---------------------------------------------------------
+// panChanged
+//---------------------------------------------------------
+
+void AudioStrip::panChanged(double v)
+ {
+ if (v != panVal) {
+ CVal val;
+ val.f = v;
+ song->setControllerVal(track, AC_PAN, val);
+ panVal = v;
+ }
+ }
+
+//---------------------------------------------------------
+// setPan
+//---------------------------------------------------------
+
+void AudioStrip::setPan(double val)
+ {
+ if (val != panVal) {
+ panVal = val;
+ pan->setValue(val);
+ panl->setValue(val);
+ }
+ }
+
+//---------------------------------------------------------
+// panPressed
+//---------------------------------------------------------
+
+void AudioStrip::panPressed()
+ {
+ track->startAutoRecord(AC_PAN);
+ }
+
+//---------------------------------------------------------
+// panReleased
+//---------------------------------------------------------
+
+void AudioStrip::panReleased()
+ {
+ track->stopAutoRecord(AC_PAN);
+ }
+
+//---------------------------------------------------------
+// updateChannels
+//---------------------------------------------------------
+
+void AudioStrip::updateChannels()
+ {
+ AudioTrack* t = (AudioTrack*)track;
+ int c = t->channels();
+ if (c == channel)
+ return;
+ channel = c;
+ slider->setChannel(c);
+ stereo->setChecked(channel == 2);
+ }
+
+//---------------------------------------------------------
+// addPanKnob
+//---------------------------------------------------------
+
+Awl::PanKnob* AudioStrip::addPanKnob(Awl::PanEntry** dlabel, int row)
+ {
+ Awl::PanKnob* knob = new Awl::PanKnob(this);
+ knob->setToolTip(tr("panorama"));
+ knob->setFixedHeight(entrySize.height() * 2);
+
+ Awl::PanEntry* pl = new Awl::PanEntry(this);
+ pl->setPrecision(2);
+
+ if (dlabel)
+ *dlabel = pl;
+// pl->setFont(config.fonts[1]);
+ pl->setFrame(true);
+
+ pl->setFixedSize(entrySize);
+
+ QLabel* plb = new QLabel;
+ plb->setObjectName("knobLabel");
+ plb->setText(tr("Pan"));
+ plb->setFixedSize(entrySize);
+ plb->setAlignment(Qt::AlignCenter);
+
+ grid->addWidget(plb, row, 0);
+ grid->addWidget(pl, row+1, 0);
+ grid->addWidget(knob, row, 1, 2, 1);
+
+ connect(knob, SIGNAL(valueChanged(double,int)), SLOT(panChanged(double)));
+ connect(pl, SIGNAL(valueChanged(double,int)), SLOT(panChanged(double)));
+ connect(knob, SIGNAL(sliderPressed(int)), SLOT(panPressed()));
+ connect(knob, SIGNAL(sliderReleased(int)), SLOT(panReleased()));
+ return knob;
+ }
+
+//---------------------------------------------------------
+// addAuxPorts
+//---------------------------------------------------------
+
+static void addAuxPorts(AudioTrack* track, QMenu* lb, const RouteList& rl)
+ {
+ QList<AuxPluginIF*> pre = track->preAux();
+ QList<AuxPluginIF*> post = track->postAux();
+ foreach (AuxPluginIF* p, pre) {
+ QString s = p->pluginInstance()->name();
+ QAction* a = lb->addAction(p->pluginInstance()->name());
+ a->setCheckable(true);
+// Route route(RouteNode(p), RouteNode(track));
+ Route route = Route(RouteNode(p), RouteNode(track));
+ a->setData(QVariant::fromValue(route));
+ a->setChecked(rl.indexOf(route) != -1);
+ }
+ foreach(AuxPluginIF* p, post) {
+ QAction* a = lb->addAction(p->pluginInstance()->name());
+ a->setCheckable(true);
+// Route route(RouteNode(p), RouteNode(track)); // does not compile?!
+ Route route = Route(RouteNode(p), RouteNode(track));
+ a->setData(QVariant::fromValue(route));
+ a->setChecked(rl.indexOf(route) != -1);
+ }
+ }
+
+//---------------------------------------------------------
+// addInPorts
+//---------------------------------------------------------
+
+static void addInPorts(AudioTrack* t, QMenu* lb, const RouteList& rl, bool input)
+ {
+ RouteNode a(t);
+
+ InputList* al = song->inputs();
+ for (iAudioInput i = al->begin(); i != al->end(); ++i) {
+ AudioTrack* track = (AudioTrack*)*i;
+ if (t == track)
+ continue;
+ QAction* it = lb->addAction(track->name());
+ it->setCheckable(true);
+ RouteNode b(track);
+ Route route = input ? Route(b, a) : Route(a, b);
+ it->setData(QVariant::fromValue(route));
+ it->setChecked(rl.indexOf(route) != -1);
+ if (input)
+ addAuxPorts(track, lb, rl);
+ }
+ }
+
+//---------------------------------------------------------
+// addOutPorts
+//---------------------------------------------------------
+
+static void addOutPorts(AudioTrack* t, QMenu* lb, const RouteList& rl)
+ {
+ OutputList* al = song->outputs();
+ for (iAudioOutput i = al->begin(); i != al->end(); ++i) {
+ Track* track = *i;
+ if (t == track)
+ continue;
+ QAction* it = lb->addAction(track->name());
+ it->setCheckable(true);
+ Route route = Route(RouteNode(t), RouteNode(track));
+ it->setData(QVariant::fromValue(route));
+ it->setChecked(rl.indexOf(route) != -1);
+ }
+ }
+
+//---------------------------------------------------------
+// addGroupPorts
+//---------------------------------------------------------
+
+static void addGroupPorts(AudioTrack* t, QMenu* lb, const RouteList& rl)
+ {
+ GroupList* al = song->groups();
+ for (iAudioGroup i = al->begin(); i != al->end(); ++i) {
+ AudioTrack* track = (AudioTrack*)*i;
+ if (t == track)
+ continue;
+ QAction* it = lb->addAction(track->name());
+ it->setCheckable(true);
+ Route route = Route(RouteNode(t), RouteNode(track));
+ it->setData(QVariant::fromValue(route));
+ it->setChecked(rl.indexOf(route) != -1);
+ }
+ }
+
+//---------------------------------------------------------
+// addWavePorts
+//---------------------------------------------------------
+
+static void addWavePorts(AudioTrack* t, QMenu* lb, const RouteList& rl, bool input)
+ {
+ RouteNode a(t);
+ WaveTrackList* al = song->waves();
+ for (iWaveTrack i = al->begin(); i != al->end(); ++i) {
+ AudioTrack* track = (AudioTrack*)*i;
+ if (t == track) // cannot connect to itself
+ continue;
+ QAction* it = lb->addAction(track->name());
+ it->setCheckable(true);
+ RouteNode b(track);
+ Route route = input ? Route(b, a) : Route(a, b);
+ it->setData(QVariant::fromValue(route));
+ it->setChecked(rl.indexOf(route) != -1);
+ if (input)
+ addAuxPorts(track, lb, rl);
+ }
+ }
+
+//---------------------------------------------------------
+// addSyntiPorts
+//---------------------------------------------------------
+
+static void addSyntiPorts(AudioTrack* t, QMenu* lb, const RouteList& rl)
+ {
+ SynthIList* al = song->syntis();
+ for (iSynthI i = al->begin(); i != al->end(); ++i) {
+ AudioTrack* track = (AudioTrack*)*i;
+ if (t == track)
+ continue;
+ QAction* it = lb->addAction(track->name());
+ it->setCheckable(true);
+ RouteNode a(t);
+ RouteNode b(track);
+ Route route = Route(b, a);
+ it->setData(QVariant::fromValue(route));
+ it->setChecked(rl.indexOf(route) != -1);
+ }
+ }
+
+//---------------------------------------------------------
+// iRouteShow
+//---------------------------------------------------------
+
+extern void addMidiTracks(QMenu* menu, Track* track, int channel, bool input);
+extern void addMidiInPorts(QMenu* menu, Track* dtrack, int channel);
+
+void AudioStrip::iRouteShow()
+ {
+ QMenu* pup = iR->menu();
+ pup->clear();
+ AudioTrack* t = (AudioTrack*)track;
+ RouteList* irl = t->inRoutes();
+
+ switch(track->type()) {
+ default:
+ return;
+ case Track::AUDIO_INPUT:
+ {
+ for (int i = 0; i < channel; ++i) {
+ pup->addSeparator()->setText(QString(tr("Channel %1")).arg(i+1));
+ QList<PortName> ol = audioDriver->outputPorts(false);
+ foreach (PortName ip, ol) {
+ QAction* id = pup->addAction(ip.name);
+ id->setCheckable(true);
+ RouteNode src(ip.port, -1, RouteNode::AUDIOPORT);
+ RouteNode dst(t, i, RouteNode::TRACK);
+ Route route = Route(src, dst);
+ id->setData(QVariant::fromValue(route));
+ id->setChecked(irl->indexOf(route) != -1);
+ }
+ }
+ }
+ break;
+ case Track::AUDIO_OUTPUT:
+ addWavePorts(t, pup, *irl, true);
+ addInPorts(t, pup, *irl, true);
+ addGroupPorts(t, pup, *irl);
+ addSyntiPorts(t, pup, *irl);
+ break;
+ case Track::WAVE:
+ addInPorts(t, pup, *irl, true);
+ break;
+ case Track::AUDIO_GROUP:
+ addWavePorts(t, pup, *irl, true);
+ addInPorts(t, pup, *irl, true);
+ addGroupPorts(t, pup, *irl);
+ addSyntiPorts(t, pup, *irl);
+ break;
+ case Track::AUDIO_SOFTSYNTH:
+ pup->addSeparator()->setText(tr("MidiChannel"));
+ for (int ch = 0; ch < MIDI_CHANNELS; ++ch) {
+ QMenu* m = pup->addMenu(QString("Channel %1").arg(ch+1));
+ addMidiTracks(m, track, ch, true);
+ addMidiInPorts(m, track, ch);
+ }
+ break;
+ }
+ }
+
+//---------------------------------------------------------
+// iRouteHide
+//---------------------------------------------------------
+
+void AudioStrip::iRouteHide()
+ {
+ // dont leave the menu if SHIFT is pressed; this allows
+ // for fast selecting of more than one input source
+ //
+ if (qApp->keyboardModifiers() & Qt::ShiftModifier) {
+ iR->menu()->show();
+ }
+ }
+
+//---------------------------------------------------------
+// oRouteHide
+//---------------------------------------------------------
+
+void AudioStrip::oRouteHide()
+ {
+ // dont leave the menu if SHIFT is pressed; this allows
+ // for fast selecting of more than one input source
+ //
+ if (qApp->keyboardModifiers() & Qt::ShiftModifier) {
+ oR->menu()->show();
+ }
+ }
+
+//---------------------------------------------------------
+// oRouteShow
+//---------------------------------------------------------
+
+void AudioStrip::oRouteShow()
+ {
+ QMenu* pup = oR->menu();
+ pup->clear();
+ AudioTrack* t = (AudioTrack*)track;
+ RouteList* orl = t->outRoutes();
+
+ switch(track->type()) {
+ default:
+ return;
+ case Track::AUDIO_OUTPUT:
+ {
+ for (int i = 0; i < channel; ++i) {
+ char buffer[128];
+ snprintf(buffer, 128, "%s %d", tr("Channel").toLatin1().data(), i+1);
+ pup->addSeparator()->setText(QString(buffer));
+
+ QList<PortName> ol = audioDriver->inputPorts(false);
+ foreach (PortName ip, ol) {
+ QAction* action = pup->addAction(ip.name);
+ action->setCheckable(true);
+ RouteNode src(t, i, RouteNode::TRACK);
+ RouteNode dst(ip.port, -1, RouteNode::AUDIOPORT);
+ Route r = Route(src, dst);
+ action->setData(QVariant::fromValue(r));
+ action->setChecked(orl->indexOf(r) != -1);
+ }
+ }
+ }
+ break;
+ case Track::AUDIO_INPUT:
+ addWavePorts(t, pup, *orl, false);
+ case Track::WAVE:
+ case Track::AUDIO_GROUP:
+ case Track::AUDIO_SOFTSYNTH:
+ addOutPorts(t, pup, *orl);
+ addGroupPorts(t, pup, *orl);
+ break;
+ }
+ }
+
+//---------------------------------------------------------
+// muteToggled
+//---------------------------------------------------------
+
+void AudioStrip::muteToggled(bool val)
+ {
+ song->setMute(track, val);
+ }
+
+//---------------------------------------------------------
+// soloToggled
+//---------------------------------------------------------
+
+void AudioStrip::soloToggled(bool val)
+ {
+ song->setSolo(track, val);
+ }
+
+//---------------------------------------------------------
+// recordToggled
+//---------------------------------------------------------
+
+void AudioStrip::recordToggled(bool val)
+ {
+ song->setRecordFlag(track, !val);
+ }
+
+//---------------------------------------------------------
+// controllerChanged
+//---------------------------------------------------------
+
+void AudioStrip::controllerChanged(int id)
+ {
+ double val = track->getController(id)->curVal().f;
+ switch (id) {
+ case AC_VOLUME:
+ slider->setValue(val);
+ sl->setValue(val);
+ break;
+ case AC_PAN:
+ pan->setValue(val);
+ panl->setValue(val);
+ panVal = val;
+ break;
+ case AC_MUTE:
+ break;
+ default:
+ break;
+ }
+ }
+
+//---------------------------------------------------------
+// autoChanged
+//---------------------------------------------------------
+
+void AudioStrip::autoChanged()
+ {
+ bool ar = track->autoRead();
+ bool aw = track->autoWrite();
+
+ // controller are enabled if
+ // autoRead is off
+ // autoRead and autoWrite are on (touch mode)
+
+ bool ec = !ar || (ar && aw);
+ slider->setEnabled(ec);
+ sl->setEnabled(ec);
+ pan->setEnabled(ec);
+ panl->setEnabled(ec);
+ }
+
+//---------------------------------------------------------
+// autoReadToggled
+//---------------------------------------------------------
+
+void AudioStrip::autoReadToggled(bool val)
+ {
+ song->setAutoRead(track, val);
+ }
+
+//---------------------------------------------------------
+// autoWriteToggled
+//---------------------------------------------------------
+
+void AudioStrip::autoWriteToggled(bool val)
+ {
+ song->setAutoWrite(track, val);
+ }
+
diff --git a/muse_qt4_evolution/muse/astrip.h b/muse_qt4_evolution/muse/astrip.h
new file mode 100644
index 00000000..f0806fda
--- /dev/null
+++ b/muse_qt4_evolution/muse/astrip.h
@@ -0,0 +1,101 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __ASTRIP_H__
+#define __ASTRIP_H__
+
+#include "strip.h"
+
+namespace Awl {
+ class MeterSlider;
+ class VolEntry;
+ class VolKnob;
+ class PanKnob;
+ class PanEntry;
+ };
+
+class AudioTrack;
+class SimpleButton;
+class EffectRack;
+class Mixer;
+
+//---------------------------------------------------------
+// AudioStrip
+//---------------------------------------------------------
+
+class AudioStrip : public Strip {
+ Q_OBJECT
+
+ int channel;
+ EffectRack* rack1;
+ EffectRack* rack2;
+
+ Awl::MeterSlider* slider;
+ Awl::VolEntry* sl;
+ double volume;
+
+ Awl::PanKnob* pan;
+ Awl::PanEntry* panl;
+ double panVal;
+
+ QToolButton* stereo;
+ QToolButton* pre;
+
+ Awl::PanKnob* addPanKnob(Awl::PanEntry**, int);
+
+ QToolButton* iR;
+ QToolButton* oR;
+ SimpleButton* off;
+ SimpleButton* record;
+
+ void updateChannels();
+
+ private slots:
+ void stereoToggled(bool);
+ void preToggled(bool);
+ void offToggled(bool);
+ void iRouteShow();
+ void iRouteHide();
+ void oRouteShow();
+ void oRouteHide();
+ void volumeChanged(double);
+ void volumePressed();
+ void volumeReleased();
+ void panChanged(double);
+ void setPan(double);
+ void panPressed();
+ void panReleased();
+ void muteToggled(bool);
+ void soloToggled(bool);
+ void recordToggled(bool);
+ void autoChanged();
+ virtual void controllerChanged(int id);
+ virtual void songChanged(int);
+ void autoReadToggled(bool);
+ void autoWriteToggled(bool);
+ void updateOffState();
+
+ public:
+ AudioStrip(Mixer*, AudioTrack*, bool align);
+ virtual void heartBeat();
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/audio.cpp b/muse_qt4_evolution/muse/audio.cpp
new file mode 100644
index 00000000..1ad9eefc
--- /dev/null
+++ b/muse_qt4_evolution/muse/audio.cpp
@@ -0,0 +1,655 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include <fcntl.h>
+
+#include "al/al.h"
+#include "muse.h"
+#include "globals.h"
+#include "song.h"
+#include "audiodev.h"
+#include "audioprefetch.h"
+#include "audiowriteback.h"
+#include "audio.h"
+#include "sync.h"
+#include "midi.h"
+#include "gconfig.h"
+#include "al/sig.h"
+#include "al/tempo.h"
+#include "widgets/utils.h"
+#include "synth.h"
+#include "midioutport.h"
+#include "midiinport.h"
+#include "midictrl.h"
+#include "sync.h"
+
+extern bool initJackAudio();
+
+Audio* audio;
+AudioDriver* audioDriver; // current audio device in use
+
+const char* seqMsgList[] = {
+ "SEQM_ADD_TRACK",
+ "SEQM_REMOVE_TRACK",
+ "SEQM_MOVE_TRACK",
+ "SEQM_ADD_PART",
+ "SEQM_REMOVE_PART",
+ "SEQM_CHANGE_PART",
+ "SEQM_ADD_EVENT",
+ "SEQM_REMOVE_EVENT",
+ "SEQM_CHANGE_EVENT",
+ "SEQM_ADD_TEMPO",
+/*10*/"SEQM_SET_TEMPO",
+ "SEQM_REMOVE_TEMPO",
+ "SEQM_ADD_SIG",
+ "SEQM_REMOVE_SIG",
+ "SEQM_SET_GLOBAL_TEMPO",
+ "SEQM_UNDO",
+ "SEQM_REDO",
+ "SEQM_RESET_DEVICES",
+ "SEQM_INIT_DEVICES",
+ "AUDIO_ROUTEADD",
+ "AUDIO_ROUTEREMOVE",
+/*20*/"AUDIO_ADDPLUGIN",
+ "AUDIO_ADDMIDIPLUGIN",
+ "AUDIO_SET_SEG_SIZE",
+ "AUDIO_SET_CHANNELS",
+ "MS_PROCESS",
+ "MS_START",
+ "MS_STOP",
+ "MS_SET_RTC",
+ "SEQM_IDLE",
+ "SEQM_ADD_CTRL",
+ "SEQM_REMOVE_CTRL"
+ };
+
+const char* audioStates[] = {
+ "STOP", "START_PLAY", "PLAY", "LOOP1", "LOOP2", "SYNC", "PRECOUNT"
+ };
+
+
+//---------------------------------------------------------
+// Audio
+//---------------------------------------------------------
+
+Audio::Audio()
+ {
+ recording = false;
+ idle = false;
+ _freewheel = false;
+ _bounce = 0;
+ loopPassed = false;
+
+ _seqTime.pos.setType(AL::FRAMES);
+ startRecordPos.setType(AL::TICKS);
+ endRecordPos.setType(AL::TICKS);
+
+ //---------------------------------------------------
+ // establish pipes/sockets
+ //---------------------------------------------------
+
+ int filedes[2]; // 0 - reading 1 - writing
+ if (pipe(filedes) == -1) {
+ perror("creating pipe0");
+ fatalError("cannot create pipe0");
+ }
+ fromThreadFdw = filedes[1]; // blocking file descriptor
+ fromThreadFdr = filedes[0]; // non blocking file descriptor
+
+ int rv = fcntl(fromThreadFdw, F_SETFL, O_NONBLOCK);
+ if (rv == -1)
+ perror("set pipe O_NONBLOCK");
+
+ if (pipe(filedes) == -1) {
+ perror("creating pipe1");
+ fatalError("cannot create pipe1");
+ }
+ sigFd = filedes[1];
+ QSocketNotifier* ss = new QSocketNotifier(filedes[0], QSocketNotifier::Read);
+ song->connect(ss, SIGNAL(activated(int)), song, SLOT(seqSignal(int)));
+ }
+
+//---------------------------------------------------------
+// start
+// start audio processing
+//---------------------------------------------------------
+
+bool Audio::start()
+ {
+ TrackList* tl = song->tracks();
+
+ _seqTime.curTickPos = 0;
+ _seqTime.nextTickPos = 0;
+ _seqTime.pos.setFrame(~0); // make sure seek is not optimized away
+
+ msg = 0;
+
+ //
+ // init marker for synchronous loop processing
+ //
+ lmark = song->lPos().frame();
+ rmark = song->rPos().frame();
+ state = STOP;
+ muse->setHeartBeat();
+
+ if (audioDriver) {
+ //
+ // allocate ports
+ //
+ for (iTrack i = tl->begin(); i != tl->end(); ++i)
+ (*i)->activate1();
+ seek(song->cpos());
+ process(segmentSize, STOP); // warm up caches; audio must be stopped
+ }
+ else {
+
+ // if audio device has disappeared it probably
+ // means jack has performed a shutdown
+ // try to restart and reconnect everything
+
+ if (false == initJackAudio()) {
+ //
+ // allocate ports, first resetting the old connection
+ //
+ InputList* itl = song->inputs();
+ for (iAudioInput i = itl->begin(); i != itl->end(); ++i) {
+ for (int x=0; x < (*i)->channels();x++) {
+ (*i)->setJackPort(Port(), x); // zero out the old connection
+ }
+ (*i)->activate1();
+ }
+
+ OutputList* otl = song->outputs();
+ for (iAudioOutput i = otl->begin(); i != otl->end(); ++i) {
+ for (int x=0; x < (*i)->channels();x++)
+ (*i)->setJackPort(Port(), x); // zero out the old connection
+ (*i)->activate1();
+ }
+ }
+ else {
+ printf("Failed to init audio!\n");
+ return false;
+ }
+ }
+ audioDriver->start(realTimePriority);
+ audioDriver->stopTransport();
+ return true;
+ }
+
+//---------------------------------------------------------
+// stop
+// stop audio processing
+// non realtime
+//---------------------------------------------------------
+
+void Audio::stop()
+ {
+#if 0
+ MidiOutPortList* opl = song->midiOutPorts();
+ for (iMidiOutPort i = opl->begin(); i != opl->end(); ++i)
+ (*i)->deactivate();
+ MidiInPortList* ipl = song->midiInPorts();
+ for (iMidiInPort i = ipl->begin(); i != ipl->end(); ++i)
+ (*i)->deactivate();
+#endif
+ if (audioDriver)
+ audioDriver->stop();
+ }
+
+//---------------------------------------------------------
+// sync
+// return true if sync is completed
+//---------------------------------------------------------
+
+bool Audio::sync(int jackState, unsigned frame)
+ {
+// printf("Audio::sync() state %s jackState %s frame 0x%x\n", audioStates[state], audioStates[jackState], frame);
+ bool done = true;
+ if (state == LOOP1)
+ state = LOOP2;
+ else {
+ State s = State(jackState);
+ //
+ // STOP -> START_PLAY start rolling
+ // STOP -> STOP seek in stop state
+ // PLAY -> START_PLAY seek in play state
+
+ if (state != START_PLAY) {
+ Pos p(frame, AL::FRAMES);
+ seek(p);
+ if (!_freewheel)
+ done = audioPrefetch->seekDone();
+ if (s == START_PLAY)
+ state = START_PLAY;
+ }
+ else {
+ if (frame != _seqTime.pos.frame()) {
+ // seek during seek
+ seek(Pos(frame, AL::FRAMES));
+ }
+ done = audioPrefetch->seekDone();
+ }
+ }
+ return done;
+ }
+
+//---------------------------------------------------------
+// setFreewheel
+//---------------------------------------------------------
+
+void Audio::setFreewheel(bool val)
+ {
+// printf("JACK: freewheel callback %d\n", val);
+ _freewheel = val;
+ }
+
+//---------------------------------------------------------
+// shutdown
+//---------------------------------------------------------
+
+void Audio::shutdown()
+ {
+ audioState = AUDIO_STOP;
+printf("JACK: shutdown callback\n");
+ sendMsgToGui(MSG_JACK_SHUTDOWN);
+ }
+
+//---------------------------------------------------------
+// process
+// process one audio buffer at position "_seqTime._pos "
+// of size "frames"
+//---------------------------------------------------------
+
+void Audio::process(unsigned frames, int jackState)
+ {
+ _seqTime.lastFrameTime = audioDriver->frameTime();
+
+ for (iMidiOutPort i = song->midiOutPorts()->begin(); i != song->midiOutPorts()->end(); ++i)
+ audioDriver->startMidiCycle((*i)->jackPort(0));
+
+ //
+ // process messages from gui
+ //
+ if (msg) {
+ processMsg();
+ msg = 0; // dont process again
+ int rv = write(fromThreadFdw, "x", 1);
+ if (rv != 1) {
+ fprintf(stderr, "audio: write(%d) pipe failed: %s\n",
+ fromThreadFdw, strerror(errno));
+ }
+ }
+
+ if (jackState != state) {
+ if (state == START_PLAY && jackState == PLAY) {
+ startRolling();
+ if (_bounce)
+ sendMsgToGui(MSG_START_BOUNCE);
+ }
+ else if (state == LOOP2 && jackState == PLAY) {
+ Pos newPos(loopFrame, AL::FRAMES);
+ seek(newPos);
+ startRolling();
+ }
+ else if (isPlaying() && jackState == STOP)
+ stopRolling();
+ else if (state == START_PLAY && jackState == STOP) {
+ state = STOP;
+ updateController = true;
+ if (_bounce)
+ audioDriver->startTransport();
+ else
+ sendMsgToGui(MSG_STOP);
+ }
+ else if (state == STOP && jackState == PLAY)
+ startRolling();
+ }
+
+ if (idle || (state == START_PLAY)) {
+ // deliver silence
+ OutputList* ol = song->outputs();
+ for (iAudioOutput i = ol->begin(); i != ol->end(); ++i)
+ (*i)->silence(frames);
+ return;
+ }
+
+ if (state == PLAY) {
+ //
+ // clear prefetch FIFO if left/right locators
+ // have changed
+ //
+ unsigned llmark = song->lPos().frame();
+ unsigned rrmark = song->rPos().frame();
+
+ if (lmark != llmark || rmark != rrmark) {
+ //
+ // invalidate audio prefetch buffer
+ //
+ audioPrefetch->getFifo()->clear();
+ audioPrefetch->msgSeek(_seqTime.startFrame());
+ lmark = llmark;
+ rmark = rrmark;
+ }
+ }
+
+ if (isPlaying()) {
+ if (_bounce == 1 && _seqTime.pos >= song->rPos()) {
+ _bounce = 2;
+ sendMsgToGui(MSG_STOP_BOUNCE);
+ }
+ //
+ // check for end of song
+ //
+ if ((_seqTime.curTickPos >= song->len())
+ && !(song->record() || _bounce || song->loop())) {
+ audioDriver->stopTransport();
+ return;
+ }
+
+ //
+ // check for loop end
+ //
+ if (state == PLAY && song->loop() && !_bounce && !extSyncFlag) {
+ unsigned n = rmark - _seqTime.startFrame() - (3 * frames);
+ if (n < frames) {
+ // loop end in current cycle
+ // adjust loop start so we get exact loop len
+ if (n > lmark)
+ n = 0;
+ state = LOOP1;
+ loopFrame = lmark - n;
+ audioDriver->seekTransport(loopFrame);
+ }
+ }
+
+ Pos ppp(_seqTime.pos);
+ ppp += frames;
+ _seqTime.nextTickPos = ppp.tick();
+ }
+
+ //
+ // compute current controller values
+ // (automation)
+ //
+ TrackList* tl = song->tracks();
+ if (state == PLAY || updateController) {
+ updateController = false;
+ for (iTrack it = tl->begin(); it != tl->end(); ++it) {
+ if ((*it)->isMidiTrack())
+ continue;
+ AudioTrack* track = (AudioTrack*)(*it);
+ if (!track->autoRead())
+ continue;
+ CtrlList* cl = track->controller();
+ for (iCtrl i = cl->begin(); i != cl->end(); ++i) {
+ Ctrl* c = i->second;
+ float val = c->value(_seqTime.startFrame()).f;
+ if (val != c->curVal().f) {
+ c->setCurVal(val);
+ c->setChanged(true);
+ }
+ }
+ }
+ }
+
+ //-----------------------------------------
+ // process midi
+ //-----------------------------------------
+
+ SynthIList* sl = song->syntis();
+ {
+ MidiOutPortList* ol = song->midiOutPorts();
+ MidiInPortList* mil = song->midiInPorts();
+ MidiTrackList* mtl = song->midis();
+
+ for (iMidiInPort i = mil->begin(); i != mil->end(); ++i)
+ (*i)->beforeProcess();
+ for (iMidiTrack i = mtl->begin(); i != mtl->end(); ++i)
+ (*i)->processMidi(&_seqTime);
+ for (iMidiOutPort i = ol->begin(); i != ol->end(); ++i)
+ (*i)->processMidi(&_seqTime);
+ for (iSynthI i = sl->begin(); i != sl->end(); ++i)
+ (*i)->processMidi(&_seqTime);
+
+ for (iMidiInPort i = mil->begin(); i != mil->end(); ++i)
+ (*i)->afterProcess();
+ }
+
+ //-----------------------------------------
+ // process audio
+ //-----------------------------------------
+
+ GroupList* gl = song->groups();
+ InputList* il = song->inputs();
+ WaveTrackList* wl = song->waves();
+
+ for (iAudioInput i = il->begin(); i != il->end(); ++i)
+ (*i)->process();
+ for (iSynthI i = sl->begin(); i != sl->end(); ++i)
+ (*i)->process();
+
+ _curReadIndex = -1;
+ if (isPlaying() && !wl->empty()) {
+ Fifo1* fifo = audioPrefetch->getFifo();
+ if (fifo->count() == 0) {
+ printf("MusE::Audio: fifo underflow at 0x%x\n", _seqTime.curTickPos);
+ audioPrefetch->msgTick();
+ }
+ else {
+ bool msg = true;
+ do {
+ unsigned fifoPos = fifo->readPos();
+ if (fifoPos == _seqTime.startFrame()) {
+ _curReadIndex = fifo->readIndex();
+ break;
+ }
+ else {
+ if (msg) {
+ printf("Muse::Audio: wrong prefetch data 0x%x, expected 0x%x\n",
+ fifoPos, _seqTime.startFrame());
+ msg = false;
+ }
+ if (fifoPos > _seqTime.startFrame()) {
+ // discard whole prefetch buffer
+ seek(_seqTime.pos + frames);
+ break;
+ }
+ fifo->pop(); // discard buffer
+ }
+ } while (fifo->count());
+ }
+ }
+ for (iWaveTrack i = wl->begin(); i != wl->end(); ++i) {
+ if (song->bounceTrack != *i)
+ (*i)->process();
+ }
+ for (iAudioGroup i = gl->begin(); i != gl->end(); ++i)
+ (*i)->process();
+
+ OutputList* aol = song->outputs();
+ for (iAudioOutput i = aol->begin(); i != aol->end(); ++i)
+ (*i)->process();
+
+ if (_bounce == 1 && song->bounceTrack && song->bounceTrack->type() == Track::WAVE)
+ song->bounceTrack->process();
+
+ if (isPlaying()) {
+ if (!freewheel()) {
+ //
+ // consume prefetch buffer
+ //
+ if (_curReadIndex != -1) {
+ audioPrefetch->getFifo()->pop();
+ audioPrefetch->msgTick(); // wakeup prefetch thread
+ }
+ }
+ if (recording && (_bounce == 0 || _bounce == 1))
+ audioWriteback->trigger();
+ _seqTime.pos += frames;
+ _seqTime.curTickPos = _seqTime.nextTickPos;
+ }
+ }
+
+//---------------------------------------------------------
+// processMsg
+//---------------------------------------------------------
+
+void Audio::processMsg()
+ {
+// printf("---msg %d\n", msg->id);
+ switch(msg->id) {
+ case AUDIO_ROUTEADD:
+ addRoute(msg->route);
+ break;
+ case AUDIO_ROUTEREMOVE:
+ removeRoute(msg->route);
+ break;
+ case AUDIO_SET_CHANNELS:
+ msg->track->setChannels(msg->ival);
+ break;
+ case AUDIO_ADDPLUGIN:
+ ((AudioTrack*)msg->track)->addPlugin(msg->plugin, msg->ival,
+ msg->iival);
+ break;
+
+ case AUDIO_SET_SEG_SIZE:
+ segmentSize = msg->ival;
+ AL::sampleRate = msg->iival;
+#if 0 //TODO
+ audioOutput.segmentSizeChanged();
+ for (int i = 0; i < mixerGroups; ++i)
+ audioGroups[i].segmentSizeChanged();
+ for (iSynthI ii = synthiInstances.begin(); ii != synthiInstances.end();++ii)
+ (*ii)->segmentSizeChanged();
+#endif
+ break;
+
+ case SEQM_INIT_DEVICES:
+ initMidiDevices();
+ break;
+ case SEQM_RESET_DEVICES:
+ resetMidiDevices();
+ break;
+ case SEQM_ADD_TEMPO:
+ case SEQM_REMOVE_TEMPO:
+ case SEQM_SET_GLOBAL_TEMPO:
+ case SEQM_SET_TEMPO:
+ song->processMsg(msg);
+ if (isPlaying())
+ _seqTime.pos.setTick(_seqTime.curTickPos);
+ break;
+
+ case SEQM_IDLE:
+ idle = msg->a;
+ break;
+
+ case AUDIO_ADDMIDIPLUGIN:
+ ((MidiTrackBase*)msg->track)->addPlugin(msg->mplugin, msg->ival);
+ break;
+ default:
+ song->processMsg(msg);
+ break;
+ }
+ }
+
+//---------------------------------------------------------
+// seek
+// - called before start play
+// - initiated from gui
+//---------------------------------------------------------
+
+void Audio::seek(const Pos& p)
+ {
+ _seqTime.pos.setFrame(p.frame());
+ _seqTime.curTickPos = _seqTime.pos.tick();
+ _seqTime.nextTickPos = _seqTime.curTickPos;
+ updateController = true;
+
+ loopPassed = true; // for record loop mode
+ if (state != LOOP2 && !freewheel())
+ audioPrefetch->msgSeek(_seqTime.pos.frame());
+
+ MidiOutPortList* ol = song->midiOutPorts();
+ for (iMidiOutPort i = ol->begin(); i != ol->end(); ++i)
+ (*i)->seek(_seqTime.curTickPos, _seqTime.pos.frame());
+ SynthIList* sl = song->syntis();
+ for (iSynthI i = sl->begin(); i != sl->end(); ++i)
+ (*i)->seek(_seqTime.curTickPos, _seqTime.pos.frame());
+ sendMsgToGui(MSG_SEEK);
+ }
+
+//---------------------------------------------------------
+// startRolling
+//---------------------------------------------------------
+
+void Audio::startRolling()
+ {
+ if (song->record()) {
+ startRecordPos = _seqTime.pos;
+ recording = true;
+ TrackList* tracks = song->tracks();
+ for (iTrack i = tracks->begin(); i != tracks->end(); ++i) {
+ if ((*i)->isMidiTrack())
+ continue;
+ ((AudioTrack*)(*i))->recEvents()->clear();
+ }
+ }
+ state = PLAY;
+ sendMsgToGui(MSG_PLAY);
+
+ MidiOutPortList* ol = song->midiOutPorts();
+ for (iMidiOutPort i = ol->begin(); i != ol->end(); ++i)
+ (*i)->start();
+ SynthIList* sl = song->syntis();
+ for (iSynthI i = sl->begin(); i != sl->end(); ++i)
+ (*i)->start();
+ }
+
+//---------------------------------------------------------
+// stopRolling
+// execution environment: realtime thread
+//---------------------------------------------------------
+
+void Audio::stopRolling()
+ {
+ state = STOP;
+ MidiOutPortList* ol = song->midiOutPorts();
+ for (iMidiOutPort i = ol->begin(); i != ol->end(); ++i)
+ (*i)->stop();
+ SynthIList* sl = song->syntis();
+ for (iSynthI i = sl->begin(); i != sl->end(); ++i)
+ (*i)->stop();
+
+ recording = false;
+ endRecordPos = _seqTime.pos;
+ _bounce = 0;
+ sendMsgToGui(MSG_STOP);
+ seek(_seqTime.pos);
+ }
+
+//---------------------------------------------------------
+// sendMsgToGui
+//---------------------------------------------------------
+
+void Audio::sendMsgToGui(char c)
+ {
+ write(sigFd, &c, 1);
+ }
+
diff --git a/muse_qt4_evolution/muse/audio.h b/muse_qt4_evolution/muse/audio.h
new file mode 100644
index 00000000..5d52ee0f
--- /dev/null
+++ b/muse_qt4_evolution/muse/audio.h
@@ -0,0 +1,306 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __AUDIO_H__
+#define __AUDIO_H__
+
+#include "thread.h"
+#include "midievent.h"
+#include "route.h"
+#include "al/tempo.h"
+#include "al/pos.h"
+#include "event.h"
+#include "ctrl.h"
+
+namespace AL {
+ class TimeSignature;
+ };
+
+using AL::Xml;
+class SndFile;
+class PluginI;
+class MidiPluginI;
+class SynthI;
+class AudioDriver;
+class Track;
+class AudioTrack;
+class Part;
+class Event;
+class MidiEvent;
+class Event;
+class MidiTrack;
+class MidiSeq;
+class MidiTrackBase;
+
+//---------------------------------------------------------
+// GuiMessages
+// messages from sequencer to GUI
+// used in Audio::sendMsgToGui(char c)
+//---------------------------------------------------------
+
+#define MSG_STOP '0'
+#define MSG_PLAY '1'
+#define MSG_RECORD '2'
+#define MSG_SEEK 'G'
+#define MSG_JACK_SHUTDOWN 'S'
+#define MSG_START_BOUNCE 'f'
+#define MSG_STOP_BOUNCE 'F'
+#define MSG_GRAPH_CHANGED 'C'
+#define MSG_ALSA_CHANGED 'P'
+
+//---------------------------------------------------------
+// AudioMsgId
+// this are the messages send from the GUI thread to
+// the midi thread
+//---------------------------------------------------------
+
+enum {
+ SEQM_ADD_TRACK,
+ SEQM_REMOVE_TRACK,
+ SEQM_MOVE_TRACK,
+ SEQM_ADD_PART,
+ SEQM_REMOVE_PART,
+ SEQM_CHANGE_PART,
+ SEQM_ADD_EVENT,
+ SEQM_ADD_EVENTS,
+ SEQM_REMOVE_EVENT,
+ SEQM_CHANGE_EVENT,
+ SEQM_ADD_TEMPO,
+ SEQM_SET_TEMPO,
+ SEQM_REMOVE_TEMPO,
+ SEQM_ADD_SIG,
+ SEQM_REMOVE_SIG,
+ SEQM_SET_GLOBAL_TEMPO,
+ SEQM_UNDO,
+ SEQM_REDO,
+ SEQM_RESET_DEVICES,
+ SEQM_INIT_DEVICES,
+ //
+ AUDIO_ROUTEADD,
+ AUDIO_ROUTEREMOVE,
+ AUDIO_ADDPLUGIN,
+ AUDIO_ADDMIDIPLUGIN,
+ AUDIO_SET_SEG_SIZE,
+ AUDIO_SET_CHANNELS,
+
+ MS_PROCESS,
+ MS_START,
+ MS_STOP,
+ MS_SET_RTC,
+
+ SEQM_IDLE,
+ SEQM_ADD_CTRL,
+ SEQM_REMOVE_CTRL
+ };
+
+extern const char* seqMsgList[]; // for debug
+
+//---------------------------------------------------------
+// Msg
+//---------------------------------------------------------
+
+struct AudioMsg : public ThreadMsg { // this should be an union
+ int serialNo;
+ SndFile* downmix;
+ Route route;
+ int ival;
+ int iival;
+ CVal cval1, cval2;
+ PluginI* plugin;
+ MidiPluginI* mplugin;
+ SynthI* synth;
+ Part* spart;
+ Part* dpart;
+ Track* track;
+ QList<Event>* el;
+
+ const void *p1, *p2, *p3;
+ Event ev1, ev2;
+ char port, channel, ctrl;
+ int a, b, c;
+ Pos pos;
+ unsigned time;
+ };
+
+class AudioOutput;
+
+
+//---------------------------------------------------------
+// SeqTime
+// timing information for sequencer cycle
+//---------------------------------------------------------
+
+extern unsigned int segmentSize;
+
+struct SeqTime {
+ unsigned lastFrameTime; // free running counter
+
+ // transport values for current cycle:
+ Pos pos; // current play position
+ unsigned curTickPos; // pos at start of frame during play/record
+ unsigned nextTickPos; // pos at start of next frame during play/record
+
+ unsigned startFrame() const { return pos.frame(); }
+ unsigned endFrame() const { return startFrame() + segmentSize; }
+
+ //---------------------------------------------------------
+ // tick2frame
+ // translate from tick to frameTime, this event has to
+ // be scheduled
+ //---------------------------------------------------------
+
+ unsigned tick2frame(unsigned tick) {
+ return AL::tempomap.tick2frame(tick) - pos.frame() + lastFrameTime + segmentSize;
+ }
+ unsigned frame2tick(unsigned frame) {
+ return AL::tempomap.frame2tick(frame - lastFrameTime + pos.frame());
+ }
+ };
+
+//---------------------------------------------------------
+// Audio
+//---------------------------------------------------------
+
+class Audio {
+ public:
+ enum State {STOP, START_PLAY, PLAY, LOOP1, LOOP2, SYNC, PRECOUNT};
+
+ private:
+ bool recording; // recording is active
+ bool idle; // do nothing in idle mode
+ bool _freewheel;
+ int _bounce;
+ bool loopPassed;
+ unsigned loopFrame; // startframe of loop if in LOOP mode
+ unsigned lmark; // left loop position
+ unsigned rmark; // right loop position
+
+ SeqTime _seqTime;
+ Pos startRecordPos;
+ Pos endRecordPos;
+
+ int _curReadIndex;
+
+ State state;
+ bool updateController;
+
+ AudioMsg* volatile msg;
+ int fromThreadFdw, fromThreadFdr; // message pipe
+
+ int sigFd; // pipe fd for messages to gui
+
+ bool filterEvent(const MidiEvent* event, int type, bool thru);
+
+ void startRolling();
+ void stopRolling();
+
+ void collectEvents(MidiTrack*, unsigned startTick, unsigned endTick);
+ void processMsg();
+ void initMidiDevices();
+ void resetMidiDevices();
+
+ public:
+ Audio();
+ virtual ~Audio() {}
+
+ void process(unsigned frames, int jackState);
+ bool sync(int state, unsigned frame);
+ void shutdown();
+
+ // transport:
+ bool start();
+ void stop();
+ void seek(const Pos& pos);
+
+ bool isPlaying() const { return state == PLAY || state == LOOP1 || state == LOOP2; }
+ bool isRecording() const { return state == PLAY && recording; }
+
+ //-----------------------------------------
+ // message interface
+ //-----------------------------------------
+
+ void msgSeek(const Pos&);
+ void msgPlay(bool val);
+
+ void msgRemoveTrack(Track*);
+ void msgRemoveTracks();
+ void msgMoveTrack(Track*, Track*);
+
+ void msgAddEvent(const Event&, Part*, bool u = true);
+ void msgAddEvents(QList<Event>* el, Part* part);
+ void msgDeleteEvent(const Event&, Part*, bool u = true);
+ void msgChangeEvent(const Event&, const Event&, Part*, bool u = true);
+
+ void msgAddTempo(int tick, int tempo, bool doUndoFlag = true);
+ void msgSetTempo(int tick, int tempo, bool doUndoFlag = true);
+ void msgSetGlobalTempo(int val);
+ void msgDeleteTempo(int tick, int tempo, bool doUndoFlag = true);
+ void msgAddSig(int tick, const AL::TimeSignature&, bool doUndoFlag = true);
+ void msgRemoveSig(int tick, int z, int n, bool doUndoFlag = true);
+ void msgPanic();
+ void sendMsg(AudioMsg*);
+ bool sendMessage(AudioMsg* m, bool doUndo);
+ void msgRoute(bool add, Route);
+ void msgRemoveRoute(Route);
+ void msgRemoveRoute1(Route);
+ void msgAddRoute(Route);
+ void msgAddRoute1(Route);
+ void msgAddPlugin(AudioTrack*, int idx, PluginI* plugin, bool prefader);
+ void msgAddMidiPlugin(MidiTrackBase*, int idx, MidiPluginI* plugin);
+ void msgSetMute(AudioTrack*, bool val);
+ void msgAddSynthI(SynthI* synth);
+ void msgRemoveSynthI(SynthI* synth);
+ void msgSetSegSize(int, int);
+ void msgSetChannels(AudioTrack*, int);
+ void msgSetOff(AudioTrack*, bool);
+ void msgUndo();
+ void msgRedo();
+ void msgLocalOff();
+ void msgInitMidiDevices();
+ void msgResetMidiDevices();
+ void msgIdle(bool);
+ void msgBounce();
+ void msgAddController(Track*, int id, unsigned time, CVal);
+ void msgRemoveController(Track*, int id, unsigned time);
+ void msgSetRtc();
+
+ const Pos& getStartRecordPos() const { return startRecordPos; }
+ const Pos& getEndRecordPos() const { return endRecordPos; }
+
+ bool freewheel() const { return _freewheel; }
+ void setFreewheel(bool val);
+
+ void sendMsgToGui(char c);
+ bool bounce() const { return _bounce != 0; }
+ MidiEvent* getMidiEvent();
+ void popMidiEvent();
+ int curReadIndex() const { return _curReadIndex; }
+
+ const SeqTime* seqTime() const { return &_seqTime; }
+ };
+
+extern int processAudio(unsigned long, void*);
+extern void processAudio1(void*, void*);
+
+extern Audio* audio;
+class AudioDriver;
+extern AudioDriver* audioDriver; // current audio device in use
+#endif
+
diff --git a/muse_qt4_evolution/muse/audiodev.h b/muse_qt4_evolution/muse/audiodev.h
new file mode 100644
index 00000000..39521a03
--- /dev/null
+++ b/muse_qt4_evolution/muse/audiodev.h
@@ -0,0 +1,57 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __AUDIODEV_H__
+#define __AUDIODEV_H__
+
+#include "driver.h"
+
+class MidiInPort;
+
+//---------------------------------------------------------
+// AudioDevice
+//---------------------------------------------------------
+
+class AudioDriver : public Driver {
+
+ public:
+ AudioDriver() {}
+ virtual ~AudioDriver() {}
+
+ virtual void start(int priority) = 0;
+ virtual bool restart() { return false; } // return true on error
+ virtual void stop () = 0;
+ virtual unsigned frameTime() const = 0;
+ virtual float* getBuffer(Port, unsigned long nframes) = 0;
+ virtual void registerClient() = 0;
+ virtual Port registerOutPort(const QString& name, bool midi) = 0;
+ virtual Port registerInPort(const QString& name, bool midi) = 0;
+ virtual int realtimePriority() const = 0; // return zero if not realtime
+ virtual void startTransport() = 0;
+ virtual void stopTransport() = 0;
+ virtual void seekTransport(unsigned frame) = 0;
+ virtual void setFreewheel(bool f) = 0;
+ virtual void graphChanged() {}
+ virtual void startMidiCycle(Port) {}
+ virtual void collectMidiEvents(MidiInPort*, Port) {}
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/audiogroup.cpp b/muse_qt4_evolution/muse/audiogroup.cpp
new file mode 100644
index 00000000..7adc30e5
--- /dev/null
+++ b/muse_qt4_evolution/muse/audiogroup.cpp
@@ -0,0 +1,47 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "audiogroup.h"
+#include "al/xml.h"
+
+//---------------------------------------------------------
+// read
+//---------------------------------------------------------
+
+void AudioGroup::read(QDomNode node)
+ {
+ while (!node.isNull()) {
+ AudioTrack::readProperties(node);
+ node = node.nextSibling();
+ }
+ }
+
+
+//---------------------------------------------------------
+// write
+//---------------------------------------------------------
+
+void AudioGroup::write(Xml& xml) const
+ {
+ xml.stag("AudioGroup");
+ AudioTrack::writeProperties(xml);
+ xml.etag("AudioGroup");
+ }
+
diff --git a/muse_qt4_evolution/muse/audiogroup.h b/muse_qt4_evolution/muse/audiogroup.h
new file mode 100644
index 00000000..d9837c74
--- /dev/null
+++ b/muse_qt4_evolution/muse/audiogroup.h
@@ -0,0 +1,46 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __AUDIOGROUP_H__
+#define __AUDIOGROUP_H__
+
+#include "audiotrack.h"
+
+//---------------------------------------------------------
+// AudioGroup
+//---------------------------------------------------------
+
+class AudioGroup : public AudioTrack {
+ Q_OBJECT
+
+ public:
+ AudioGroup() : AudioTrack() {}
+ virtual TrackType type() const { return AUDIO_GROUP; }
+ virtual void read(QDomNode);
+ virtual void write(Xml&) const;
+ virtual bool hasAuxSend() const { return true; }
+ };
+
+typedef QList<AudioGroup*> GroupList;
+typedef GroupList::iterator iAudioGroup;
+typedef GroupList::const_iterator ciAudioGroup;
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/audioinput.cpp b/muse_qt4_evolution/muse/audioinput.cpp
new file mode 100644
index 00000000..fe7c57bb
--- /dev/null
+++ b/muse_qt4_evolution/muse/audioinput.cpp
@@ -0,0 +1,131 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "globals.h"
+#include "audioinput.h"
+#include "jackaudio.h"
+#include "audio.h"
+
+//---------------------------------------------------------
+// AudioInput
+//---------------------------------------------------------
+
+AudioInput::AudioInput()
+ : AudioTrack()
+ {
+ // set Default for Input Ports:
+ _mute = muteDefault();
+ _channels = 0;
+ setChannels(2);
+ //
+ // buffers are allocated from AudioTrack()
+ // and not needed by AudioInput which uses
+ // the JACK supplied buffers
+ for (int i = 0; i < MAX_CHANNELS; ++i) {
+ if (buffer[i]) {
+ free(buffer[i]);
+ buffer[i] = 0;
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// ~AudioInput
+//---------------------------------------------------------
+
+AudioInput::~AudioInput()
+ {
+ for (int i = 0; i < _channels; ++i) {
+ if (!jackPort(i).isZero())
+ audioDriver->unregisterPort(jackPort(i));
+ }
+ // AudioInput does not own buffers (they are from JACK)
+ // make sure ~AudioTrack() does not delete them:
+ for (int i = 0; i < MAX_CHANNELS; ++i)
+ buffer[i] = 0;
+ }
+
+//---------------------------------------------------------
+// write
+//---------------------------------------------------------
+
+void AudioInput::write(Xml& xml) const
+ {
+ xml.stag("AudioInput");
+ AudioTrack::writeProperties(xml);
+ xml.etag("AudioInput");
+ }
+
+//---------------------------------------------------------
+// read
+//---------------------------------------------------------
+
+void AudioInput::read(QDomNode node)
+ {
+ for (;!node.isNull(); node = node.nextSibling()) {
+ AudioTrack::readProperties(node);
+ }
+ setName(name()); // allocate jack ports
+ }
+
+//---------------------------------------------------------
+// setChannels
+//---------------------------------------------------------
+
+void AudioInput::setChannels(int n)
+ {
+ if (n == _channels)
+ return;
+ AudioTrack::setChannels(n);
+ }
+
+//---------------------------------------------------------
+// setName
+//---------------------------------------------------------
+
+void AudioInput::setName(const QString& s)
+ {
+ Track::setName(s);
+ for (int i = 0; i < channels(); ++i) {
+ if (!jackPort(i).isZero()) {
+ char buffer[128];
+ snprintf(buffer, 128, "%s-%d", _name.toAscii().data(), i);
+ if (!jackPort(i).isZero())
+ audioDriver->setPortName(jackPort(i), buffer);
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// collectInputData
+// if buffer contains silence, set bufferEmpty to true
+//---------------------------------------------------------
+
+void AudioInput::collectInputData()
+ {
+ bufferEmpty = false;
+ for (int ch = 0; ch < channels(); ++ch) {
+ Port port = jackPort(ch);
+ if (!port.isZero())
+ buffer[ch] = audioDriver->getBuffer(port, segmentSize);
+ }
+ }
+
+
diff --git a/muse_qt4_evolution/muse/audioinput.h b/muse_qt4_evolution/muse/audioinput.h
new file mode 100644
index 00000000..9982daf1
--- /dev/null
+++ b/muse_qt4_evolution/muse/audioinput.h
@@ -0,0 +1,53 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __AUDIOINPUT_H__
+#define __AUDIOINPUT_H__
+
+#include "audiotrack.h"
+
+//---------------------------------------------------------
+// AudioInput
+//---------------------------------------------------------
+
+class AudioInput : public AudioTrack {
+ Q_OBJECT
+
+ void collectInputData();
+
+ public:
+ AudioInput();
+ virtual ~AudioInput();
+ virtual TrackType type() const { return AUDIO_INPUT; }
+
+ virtual void read(QDomNode);
+ virtual void write(Xml&) const;
+ virtual void setName(const QString& s);
+ virtual void setChannels(int n);
+ virtual bool hasAuxSend() const { return true; }
+ virtual bool muteDefault() const { return true; }
+ };
+
+typedef QList<AudioInput*> InputList;
+typedef InputList::iterator iAudioInput;
+typedef InputList::const_iterator ciAudioInput;
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/audiooutput.cpp b/muse_qt4_evolution/muse/audiooutput.cpp
new file mode 100644
index 00000000..e4937a74
--- /dev/null
+++ b/muse_qt4_evolution/muse/audiooutput.cpp
@@ -0,0 +1,191 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "audiooutput.h"
+#include "jackaudio.h"
+#include "audio.h"
+#include "globals.h"
+#include "song.h"
+#include "ticksynth.h"
+
+//---------------------------------------------------------
+// AudioOutput
+//---------------------------------------------------------
+
+AudioOutput::AudioOutput()
+ : AudioTrack()
+ {
+ _channels = 0;
+ setChannels(2);
+
+ //
+ // buffers are allocated from AudioTrack()
+ // and not needed by AudioOutput which uses
+ // the JACK supplied buffers
+
+ for (int i = 0; i < MAX_CHANNELS; ++i) {
+ if (buffer[i]) {
+ free(buffer[i]);
+ buffer[i] = 0;
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// ~AudioOutput
+//---------------------------------------------------------
+
+AudioOutput::~AudioOutput()
+ {
+ for (int i = 0; i < _channels; ++i) {
+ if (!jackPort(i).isZero())
+ audioDriver->unregisterPort(jackPort(i));
+ }
+ // AudioOutput does not own buffers (they are from JACK)
+ // make sure ~AudioTrack() does not delete them:
+ for (int i = 0; i < MAX_CHANNELS; ++i)
+ buffer[i] = 0;
+ }
+
+//---------------------------------------------------------
+// write
+//---------------------------------------------------------
+
+void AudioOutput::write(Xml& xml) const
+ {
+ xml.stag("AudioOutput");
+ AudioTrack::writeProperties(xml);
+ xml.etag("AudioOutput");
+ }
+
+//---------------------------------------------------------
+// read
+//---------------------------------------------------------
+
+void AudioOutput::read(QDomNode node)
+ {
+ while (!node.isNull()) {
+ AudioTrack::readProperties(node);
+ node = node.nextSibling();
+ }
+ setName(name()); // allocate jack ports
+ }
+
+//---------------------------------------------------------
+// setChannels
+//---------------------------------------------------------
+
+void AudioOutput::setChannels(int n)
+ {
+ if (n == _channels)
+ return;
+ AudioTrack::setChannels(n);
+ }
+
+//---------------------------------------------------------
+// silence
+//---------------------------------------------------------
+
+void AudioOutput::silence(unsigned n)
+ {
+ for (int i = 0; i < channels(); ++i) {
+ if (!jackPort(i).isZero())
+ buffer[i] = audioDriver->getBuffer(jackPort(i), n);
+ else {
+ printf("PANIC: silence(): no buffer from audio driver\n");
+ abort();
+ return;
+ }
+ }
+ for (int i = 0; i < channels(); ++i)
+ memset(buffer[i], 0, n * sizeof(float));
+ }
+
+//---------------------------------------------------------
+// setName
+//---------------------------------------------------------
+
+void AudioOutput::setName(const QString& s)
+ {
+ Track::setName(s);
+ for (int i = 0; i < channels(); ++i) {
+ if (!jackPort(i).isZero()) {
+ char buffer[128];
+ snprintf(buffer, 128, "%s-%d", _name.toAscii().data(), i);
+ audioDriver->setPortName(jackPort(i), buffer);
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// stopRecording
+// gui context
+//---------------------------------------------------------
+
+void AudioOutput::stopRecording(const Pos& /*s*/, const Pos& /*e*/)
+ {
+ SndFile* sf = recFile();
+ if (sf)
+ delete sf; // close
+ setRecFile(0);
+ setRecordFlag(false);
+ }
+
+//---------------------------------------------------------
+// process
+// synthesize segmentSize frames at buffer offset "offset"
+// current frame position is "pos"
+//---------------------------------------------------------
+
+void AudioOutput::process()
+ {
+ for (int c = 0; c < channels(); ++c)
+ buffer[c] = audioDriver->getBuffer(jackPort(c), segmentSize);
+
+ AudioTrack::process();
+
+ if (bufferEmpty) {
+ for (int c = 0; c < channels(); ++c)
+ memset(buffer[c], 0, sizeof(float) * segmentSize);
+ }
+
+ int n = segmentSize;
+ if (audio->isRecording() && recordFlag() && _recFile) {
+ // bounce to file
+ if (audio->freewheel())
+ _recFile->write(channels(), buffer, n);
+ else
+ putFifo(channels(), n, buffer);
+ }
+
+#if 0
+ if (audioClickFlag && song->click() && metronome) {
+ float b[n];
+ float* bp[1];
+ bp[0] = b;
+ metronome->getData(pos, 1, n, bp);
+ for (unsigned i = 0; i < n; ++i) {
+ for (int k = 0; k < channels(); ++k)
+ buffer[k][i] += b[i] * audioClickVolume;
+ }
+ }
+#endif
+ }
+
diff --git a/muse_qt4_evolution/muse/audiooutput.h b/muse_qt4_evolution/muse/audiooutput.h
new file mode 100644
index 00000000..8e0c5161
--- /dev/null
+++ b/muse_qt4_evolution/muse/audiooutput.h
@@ -0,0 +1,55 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __AUDIOOUTPUT_H__
+#define __AUDIOOUTPUT_H__
+
+#include "audiotrack.h"
+
+//---------------------------------------------------------
+// AudioOutput
+//---------------------------------------------------------
+
+class AudioOutput : public AudioTrack {
+ Q_OBJECT
+
+ public:
+ AudioOutput();
+ virtual ~AudioOutput();
+ virtual TrackType type() const { return AUDIO_OUTPUT; }
+
+ virtual void read(QDomNode);
+ virtual void write(Xml&) const;
+ virtual void setName(const QString& s);
+ virtual void setChannels(int n);
+
+ virtual bool canRecord() const { return true; }
+ virtual void stopRecording(const AL::Pos&, const AL::Pos&);
+
+ void silence(unsigned);
+ virtual void process();
+ };
+
+typedef QList<AudioOutput*> OutputList;
+typedef OutputList::iterator iAudioOutput;
+typedef OutputList::const_iterator ciAudioOutput;
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/audioprefetch.cpp b/muse_qt4_evolution/muse/audioprefetch.cpp
new file mode 100644
index 00000000..d433c1ac
--- /dev/null
+++ b/muse_qt4_evolution/muse/audioprefetch.cpp
@@ -0,0 +1,199 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include <poll.h>
+
+#include "audioprefetch.h"
+#include "globals.h"
+#include "track.h"
+#include "song.h"
+#include "audio.h"
+#include "sync.h"
+#include "fifo.h"
+
+enum { PREFETCH_TICK, PREFETCH_SEEK };
+
+//---------------------------------------------------------
+// PrefetchMsg
+//---------------------------------------------------------
+
+struct PrefetchMsg : public ThreadMsg {
+ int pos;
+ };
+
+AudioPrefetch* audioPrefetch;
+
+//---------------------------------------------------------
+// AudioPrefetch
+//---------------------------------------------------------
+
+AudioPrefetch::AudioPrefetch(const char* name)
+ : Thread(name)
+ {
+ seekPos = ~0;
+ writePos = ~0;
+ seekCount = 0;
+ }
+
+//---------------------------------------------------------
+// readMsg
+//---------------------------------------------------------
+
+static void readMsgP(void* p, void*)
+ {
+ AudioPrefetch* at = (AudioPrefetch*)p;
+ at->readMsg1(sizeof(PrefetchMsg));
+ }
+
+//---------------------------------------------------------
+// start
+//---------------------------------------------------------
+
+void AudioPrefetch::start(int priority)
+ {
+ clearPollFd();
+ addPollFd(toThreadFdr, POLLIN, ::readMsgP, this, 0);
+ Thread::start(priority);
+ }
+
+//---------------------------------------------------------
+// ~AudioPrefetch
+//---------------------------------------------------------
+
+AudioPrefetch::~AudioPrefetch()
+ {
+ }
+
+//---------------------------------------------------------
+// processMsg
+//---------------------------------------------------------
+
+void AudioPrefetch::processMsg1(const void* m)
+ {
+ const PrefetchMsg* msg = (PrefetchMsg*)m;
+ switch(msg->id) {
+ case PREFETCH_TICK:
+ prefetch(false);
+ seekPos = ~0; // invalidate cached last seek position
+ break;
+
+ case PREFETCH_SEEK:
+ // process seek in background
+ seek(msg->pos);
+ break;
+
+ default:
+ printf("AudioPrefetch::processMsg1: unknown message\n");
+ }
+ }
+
+//---------------------------------------------------------
+// msgTick
+// trigger audio prefetch with next buffer position
+//---------------------------------------------------------
+
+void AudioPrefetch::msgTick()
+ {
+ if (fifo.count() < FIFO_BUFFER/3) {
+ PrefetchMsg msg;
+ msg.id = PREFETCH_TICK;
+ while (sendMsg1(&msg, sizeof(msg))) {
+ printf("AudioPrefetch::msgTick(): send failed!\n");
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// msgSeek
+// called from audio RT context
+//---------------------------------------------------------
+
+void AudioPrefetch::msgSeek(unsigned samplePos)
+ {
+ //
+ // optimize unecessary seeks; seekPos is invalidated on
+ // first prefetch tick
+ //
+ if (samplePos == seekPos)
+ return;
+
+ //q_atomic_increment(&seekCount);
+ ++seekCount;
+
+ PrefetchMsg msg;
+ msg.id = PREFETCH_SEEK;
+ msg.pos = samplePos;
+ msg.serialNo = 0;
+ while (sendMsg1(&msg, sizeof(msg))) {
+ printf("AudioPrefetch::msgSeek::sleep(1)\n");
+ sleep(1);
+ }
+ }
+
+//---------------------------------------------------------
+// prefetch
+//---------------------------------------------------------
+
+void AudioPrefetch::prefetch(bool seekFlag)
+ {
+ WaveTrackList* tl = song->waves();
+ if (tl->empty())
+ return;
+ while (fifo.count() < FIFO_BUFFER) {
+ if (song->loop() && !audio->bounce() && !extSyncFlag) {
+ unsigned rpos = song->rPos().frame();
+ unsigned n = rpos - writePos;
+ //
+ // dont loop if we are beyond right marker
+ //
+ if (writePos <= rpos && (n < segmentSize)) {
+ unsigned lpos = song->lPos().frame();
+ // adjust loop start so we get exact loop len
+ if (n > lpos)
+ n = 0;
+ writePos = lpos - n;
+ }
+ }
+ int widx = fifo.setWritePos(writePos);
+ for (iWaveTrack it = tl->begin(); it != tl->end(); ++it) {
+ WaveTrack* track = *it;
+ if (!seekFlag && ((audio->isRecording() && track->recordFlag()) || !audio->isPlaying()))
+ continue;
+ track->fetchData(writePos, segmentSize, widx);
+ }
+ writePos += segmentSize;
+ fifo.push();
+ }
+ }
+
+//---------------------------------------------------------
+// seek
+//---------------------------------------------------------
+
+void AudioPrefetch::seek(unsigned seekTo)
+ {
+ fifo.clear();
+ writePos = seekTo;
+ prefetch(true);
+ seekPos = seekTo;
+ // q_atomic_decrement(&seekCount);
+ --seekCount;
+ }
+
diff --git a/muse_qt4_evolution/muse/audioprefetch.h b/muse_qt4_evolution/muse/audioprefetch.h
new file mode 100644
index 00000000..14e8096c
--- /dev/null
+++ b/muse_qt4_evolution/muse/audioprefetch.h
@@ -0,0 +1,54 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __AUDIOPREFETCH_H__
+#define __AUDIOPREFETCH_H__
+
+#include "thread.h"
+#include "fifo.h"
+
+//---------------------------------------------------------
+// AudioPrefetch
+//---------------------------------------------------------
+
+class AudioPrefetch : public Thread {
+ Fifo1 fifo;
+ unsigned writePos;
+ unsigned seekPos; // remember last seek to optimize seeks
+
+ virtual void processMsg1(const void*);
+ void prefetch(bool seekFlag);
+ void seek(unsigned pos);
+ volatile int seekCount;
+
+ public:
+ AudioPrefetch(const char* name);
+ ~AudioPrefetch();
+ virtual void start(int);
+
+ void msgTick();
+ void msgSeek(unsigned pos);
+ bool seekDone() const { return seekCount == 0; }
+ Fifo1* getFifo() { return &fifo; }
+ };
+
+extern AudioPrefetch* audioPrefetch;
+
+#endif
diff --git a/muse_qt4_evolution/muse/audiotrack.cpp b/muse_qt4_evolution/muse/audiotrack.cpp
new file mode 100644
index 00000000..04d215f2
--- /dev/null
+++ b/muse_qt4_evolution/muse/audiotrack.cpp
@@ -0,0 +1,582 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "al/al.h"
+#include "al/dsp.h"
+#include "al/xml.h"
+#include "track.h"
+#include "event.h"
+#include "song.h"
+#include "audio.h"
+#include "wave.h"
+#include "auxplugin.h"
+#include "pipeline.h"
+#include "audiodev.h"
+#include "gconfig.h"
+
+//---------------------------------------------------------
+// AudioTrack
+//---------------------------------------------------------
+
+AudioTrack::AudioTrack()
+ : Track()
+ {
+ _tt = AL::FRAMES;
+ _prefader = false;
+ _prePipe = new Pipeline();
+ _postPipe = new Pipeline();
+ _recFile = 0;
+ _channels = 0;
+ bufferEmpty = false;
+ setChannels(1);
+
+ //
+ // add two managed standard controller:
+ // volume and pan
+ //
+ Ctrl* c;
+ c = new Ctrl(AC_VOLUME, "Volume");
+ c->setType(Ctrl::INTERPOLATE | Ctrl::LOG);
+ c->setRange(pow(10.0f, config.minSlider*0.05f), pow(10.0f, config.maxSlider*0.05f));
+
+ addController(c);
+ c = new Ctrl(AC_PAN, "Pan");
+ c->setRange(-1.0f, +1.0f);
+ addController(c);
+
+ for (int i = 0; i < MAX_CHANNELS; ++i)
+ posix_memalign((void**)(buffer + i), 16, sizeof(float) * segmentSize);
+ }
+
+//---------------------------------------------------------
+// ~AudioTrack
+//---------------------------------------------------------
+
+AudioTrack::~AudioTrack()
+ {
+ foreach(PluginI* plugin, *_prePipe)
+ delete plugin;
+ foreach(PluginI* plugin, *_postPipe)
+ delete plugin;
+ delete _prePipe;
+ delete _postPipe;
+ for (int i = 0; i < MAX_CHANNELS; ++i) {
+ if (buffer[i])
+ free(buffer[i]);
+ }
+ }
+
+//---------------------------------------------------------
+// newPart
+//---------------------------------------------------------
+
+Part* AudioTrack::newPart(Part*, bool /*clone*/)
+ {
+ return 0;
+ }
+
+//---------------------------------------------------------
+// addPlugin
+// idx = -1 append
+// plugin = 0 remove plugin
+//---------------------------------------------------------
+
+void AudioTrack::addPlugin(PluginI* plugin, int idx, bool pre)
+ {
+ Pipeline* pipe = pre ? _prePipe : _postPipe;
+ if (plugin == 0) {
+ PluginI* oldPlugin = (*pipe)[idx];
+ if (oldPlugin) {
+ int controller = oldPlugin->plugin()->parameter();
+ for (int i = 0; i < controller; ++i) {
+ int id = genACnum(idx, i, pre);
+ removeController(id);
+ }
+ pipe->removeAt(idx);
+ }
+ }
+ else {
+ if (idx == -1)
+ idx = pipe->size();
+ pipe->insert(idx, plugin);
+ int ncontroller = plugin->plugin()->parameter();
+ for (int i = 0; i < ncontroller; ++i) {
+ int id = genACnum(idx, i, pre);
+ QString name(plugin->getParameterName(i));
+ double min, max;
+ plugin->range(i, &min, &max);
+ Ctrl* cl = getController(id);
+ //printf("Plugin name: %s id:%d\n",name.toAscii().data(), id);
+ if (cl == 0) {
+ cl = new Ctrl(id, name);
+ cl->setRange(min, max);
+ float defaultValue = plugin->defaultValue(i);
+ cl->setDefault(defaultValue);
+ cl->setCurVal(defaultValue);
+ addController(cl);
+ }
+ cl->setRange(min, max);
+ cl->setName(name);
+ plugin->setParam(i, cl->curVal().f);
+ plugin->setControllerList(cl);
+ }
+ }
+ _preAux.clear();
+ _postAux.clear();
+ foreach(PluginI* pi, *_prePipe) {
+ if (pi->plugin() == auxPlugin)
+ _preAux.append((AuxPluginIF*)(pi->pluginIF(0)));
+ }
+ foreach(PluginI* pi, *_postPipe) {
+ if (pi->plugin() == auxPlugin)
+ _postAux.append((AuxPluginIF*)(pi->pluginIF(0)));
+ }
+ }
+
+//---------------------------------------------------------
+// plugin
+//---------------------------------------------------------
+
+PluginI* AudioTrack::plugin(int idx, bool prefader) const
+ {
+ Pipeline* pipe = prefader ? _prePipe : _postPipe;
+ return (*pipe)[idx];
+ }
+
+//---------------------------------------------------------
+// addAuxSend
+//---------------------------------------------------------
+
+void AudioTrack::addAuxSend(int n)
+ {
+ if (n >= NUM_AUX) {
+ printf("too many aux sends (>%d)\n", n);
+ n = NUM_AUX;
+ }
+ for (int i = 0; i < n; ++i) {
+ Ctrl* c = getController(AC_AUX + i);
+ if (c)
+ continue;
+ QString s("AuxSend-");
+ s += QString("%1").arg(i+1);
+ Ctrl* ctrl = new Ctrl(AC_AUX + i, s);
+ ctrl->setRange(pow(10.0f, config.minSlider*0.05f), pow(10.0f, config.maxSlider*0.05f));
+ addController(ctrl);
+
+ c = getController(AC_AUX_PAN + i);
+ if (c)
+ continue;
+ s = ("AuxSendPan-");
+ s += QString("%1").arg(i+1);
+ ctrl = new Ctrl(AC_AUX_PAN + i, s);
+ ctrl->setRange(-1.0f, +1.0f);
+ addController(ctrl);
+ }
+ }
+
+//---------------------------------------------------------
+// AudioTrack::writeProperties
+//---------------------------------------------------------
+
+void AudioTrack::writeProperties(Xml& xml) const
+ {
+ Track::writeProperties(xml);
+ foreach (PluginI* plugin, *_prePipe)
+ plugin->writeConfiguration(xml, true);
+ foreach (PluginI* plugin, *_postPipe)
+ plugin->writeConfiguration(xml, false);
+ }
+
+//---------------------------------------------------------
+// AudioTrack::readProperties
+//---------------------------------------------------------
+
+bool AudioTrack::readProperties(QDomNode node)
+ {
+ QDomElement e = node.toElement();
+ QString tag(e.tagName());
+ if (tag == "plugin") {
+ PluginI* pi = new PluginI(this);
+ bool prefader;
+ if (pi->readConfiguration(node, &prefader)) {
+ delete pi;
+ }
+ else {
+ // insert plugin into first free slot
+ // of plugin rack
+ addPlugin(pi, -1, prefader);
+ }
+ }
+ else if (tag == "prefader")
+ _prefader = e.text().toInt();
+ else if (tag == "recfile")
+ readRecfile(node.firstChild());
+ else
+ return Track::readProperties(node);
+ return false;
+ }
+
+//---------------------------------------------------------
+// setAutoRead
+//---------------------------------------------------------
+
+void AudioTrack::setAutoRead(bool val)
+ {
+ if (_autoRead != val) {
+ _autoRead = val;
+ emit autoReadChanged(_autoRead);
+ }
+ }
+
+//---------------------------------------------------------
+// setAutoWrite
+//---------------------------------------------------------
+
+void AudioTrack::setAutoWrite(bool val)
+ {
+ if (_autoWrite != val) {
+ _autoWrite = val;
+ emit autoWriteChanged(_autoWrite);
+ }
+ }
+
+//---------------------------------------------------------
+// isMute
+//---------------------------------------------------------
+
+bool AudioTrack::isMute() const
+ {
+ if (_solo)
+ return false;
+ if (song->solo())
+ return true;
+ return _mute;
+ }
+
+//---------------------------------------------------------
+// setSolo
+//---------------------------------------------------------
+
+bool AudioTrack::setSolo(bool val)
+ {
+ if (Track::setSolo(val)) {
+ if (mute())
+ resetMeter();
+ return true;
+ }
+ return false;
+ }
+
+//---------------------------------------------------------
+// readRecfile
+//---------------------------------------------------------
+
+void AudioTrack::readRecfile(QDomNode node)
+ {
+ QString path;
+ int channels = 2;
+ int format = SF_FORMAT_WAV | SF_FORMAT_PCM_16;
+ while (!node.isNull()) {
+ QDomElement e = node.toElement();
+ QString tag(e.nodeName());
+ if (tag == "path")
+ path = e.text();
+ else if (tag == "channels")
+ channels = e.text().toInt();
+ else if (tag == "format")
+ format = e.text().toInt();
+ else
+ printf("MusE:readRecfile: unknown tag %s\n", e.tagName().toAscii().data());
+ node = node.nextSibling();
+ }
+ if (QFile::exists(path)) {
+ setRecFile(SndFile::getWave(path, true));
+ }
+ else {
+ setRecFile(new SndFile(path));
+ recFile()->setFormat(format, channels, AL::sampleRate);
+ if (recFile()->openWrite()) {
+ fprintf(stderr, "create wave file(%s) failed: %s\n",
+ path.toAscii().data(), recFile()->strerror().toAscii().data());
+ delete _recFile;
+ _recFile = 0;
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// putFifo
+//---------------------------------------------------------
+
+void AudioTrack::putFifo(int channels, unsigned long n, float** bp)
+ {
+ if (fifo.put(channels, n, bp, audio->seqTime()->pos.frame())) {
+ printf("AudioTrack(%s)::putFifo(): overrun\n", name().toAscii().data());
+ }
+ }
+
+//---------------------------------------------------------
+// setMute
+//---------------------------------------------------------
+
+bool AudioTrack::setMute(bool f)
+ {
+ if (Track::setMute(f)) {
+ resetAllMeter();
+ return true;
+ }
+ return false;
+ }
+
+//---------------------------------------------------------
+// setOff
+//---------------------------------------------------------
+
+bool AudioTrack::setOff(bool val)
+ {
+ if (Track::setOff(val)) {
+ resetAllMeter();
+ return true;
+ }
+ return false;
+ }
+
+//---------------------------------------------------------
+// setPrefader
+//---------------------------------------------------------
+
+void AudioTrack::setPrefader(bool val)
+ {
+ _prefader = val;
+ if (!_prefader && isMute())
+ resetAllMeter();
+ }
+
+//---------------------------------------------------------
+// record
+// called from audio writeback task
+//---------------------------------------------------------
+
+void AudioTrack::record()
+ {
+ float* recBuffer[_channels];
+
+ if (fifo.get(_channels, segmentSize, recBuffer)) {
+ printf("AudioTrack(%s)::record():: fifo underflow\n",
+ name().toAscii().data());
+ return;
+ }
+ if (_recFile) {
+ _recFile->write(_channels, recBuffer, segmentSize);
+ }
+ else {
+ printf("AudioTrack(%s)::record(): no recFile\n",
+ name().toAscii().data());
+ }
+ }
+
+//---------------------------------------------------------
+// setChannels
+//---------------------------------------------------------
+
+void AudioTrack::setChannels(int n)
+ {
+ if (n > MAX_CHANNELS) {
+ fprintf(stderr, "AudioTrack::setChannels(%d): too many channels(>%d)!\n",
+ n, MAX_CHANNELS);
+ n = MAX_CHANNELS;
+ }
+ Track::setChannels(n);
+ if (_prePipe)
+ _prePipe->setChannels(n);
+ if (_postPipe)
+ _postPipe->setChannels(n);
+ }
+
+//---------------------------------------------------------
+// startRecording
+//---------------------------------------------------------
+
+void AudioTrack::startRecording()
+ {
+ if (!recordFlag())
+ return;
+ if (!_recFile)
+ _recFile = SndFile::createRecFile(_channels);
+ _recFile->openWrite();
+ if (debugMsg)
+ printf("AudioTrack::startRecording: create internal file %s\n",
+ _recFile->finfo()->filePath().toAscii().data());
+ }
+
+//---------------------------------------------------------
+// process
+// this is called only once per cycle
+//---------------------------------------------------------
+
+void AudioTrack::process()
+ {
+ bufferEmpty = false;
+ if (_off) {
+ bufferEmpty = true;
+ return;
+ }
+ collectInputData();
+ _prePipe->apply(channels(), segmentSize, buffer);
+
+ if (_prefader) {
+ for (int i = 0; i < channels(); ++i)
+ setMeter(i, AL::dsp->peak(buffer[i], segmentSize, 0.0));
+ }
+
+ //
+ // TODO: we can only handle 1 or 2 channels
+ //
+ double vol[2];
+ double _volume = _mute ? 0.0 : ctrlVal(AC_VOLUME).f;
+ double _pan = ctrlVal(AC_PAN).f;
+ vol[0] = _volume * (1.0 - _pan);
+ vol[1] = _volume * (1.0 + _pan);
+
+ for (int i = 0; i < channels(); ++i)
+ AL::dsp->applyGainToBuffer(buffer[i], segmentSize, vol[i]);
+
+ _postPipe->apply(channels(), segmentSize, buffer);
+
+ if (!_prefader) {
+ for (int i = 0; i < channels(); ++i)
+ setMeter(i, AL::dsp->peak(buffer[i], segmentSize, 0.0));
+ }
+ }
+
+//---------------------------------------------------------
+// add
+// add audio buffer to track buffer
+//---------------------------------------------------------
+
+void AudioTrack::add(int srcChannels, float** srcBuffer)
+ {
+ int dstChannels = channels();
+ float** dstBuffer = buffer;
+
+ if (srcChannels == dstChannels) {
+ for (int c = 0; c < dstChannels; ++c)
+ AL::dsp->mix(dstBuffer[c], srcBuffer[c], segmentSize);
+ }
+ //
+ // mix mono to stereo
+ //
+ else if (srcChannels == 1 && dstChannels == 2) {
+ float* dp1 = dstBuffer[0];
+ float* dp2 = dstBuffer[1];
+ float* sp = srcBuffer[0];
+ for (unsigned k = 0; k < segmentSize; ++k) {
+ dp1[k] += sp[k];
+ dp2[k] += sp[k];
+ }
+ }
+ //
+ // downmix stereo to mono
+ //
+ else if (srcChannels == 2 && dstChannels == 1) {
+ float* sp1 = srcBuffer[0];
+ float* sp2 = srcBuffer[1];
+ float* dp = dstBuffer[0];
+ for (unsigned k = 0; k < segmentSize; ++k)
+ dp[k] += sp1[k] + sp2[k];
+ }
+ }
+
+//---------------------------------------------------------
+// copy
+// add audio buffer to track buffer
+//---------------------------------------------------------
+
+bool AudioTrack::copy(int srcChannels, float** srcBuffer)
+ {
+ int dstChannels = channels();
+
+ if (srcChannels == dstChannels) {
+ for (int c = 0; c < dstChannels; ++c)
+ AL::dsp->cpy(buffer[c], srcBuffer[c], segmentSize);
+ }
+ else if (srcChannels == 1 && dstChannels == 2) {
+ float* sp = srcBuffer[0];
+ for (unsigned k = 0; k < segmentSize; ++k) {
+ float val = *sp++;
+ *(buffer[0] + k) = val;
+ *(buffer[1] + k) = val;
+ }
+ }
+ else if (srcChannels == 2 && dstChannels == 1) {
+ float* sp1 = srcBuffer[0];
+ float* sp2 = srcBuffer[1];
+ float* dp = buffer[0];
+ for (unsigned k = 0; k < segmentSize; ++k)
+ dp[k] = sp1[k] + sp2[k];
+ }
+ return true;
+ }
+
+//---------------------------------------------------------
+// collectInputData
+// if buffer contains silence, set bufferEmpty to true
+//---------------------------------------------------------
+
+void AudioTrack::collectInputData()
+ {
+ bufferEmpty = false;
+ bool copyFlag = true;
+ foreach (const Route& r, _inRoutes) {
+ float** ptr;
+ int ch;
+ if (r.src.type == RouteNode::TRACK) {
+ AudioTrack* track = (AudioTrack*)r.src.track;
+ if (track->off() || song->bounceTrack == track)
+ continue;
+ ptr = track->buffer;
+ ch = track->channels();
+ }
+ else if (r.src.type == RouteNode::AUXPLUGIN) {
+ ch = r.src.plugin->channel();
+ ptr = r.src.plugin->buffer();
+ }
+ else {
+ printf("AudioTrack::collectInputRoutes(): bad route type\n");
+ return;
+ }
+ if (copyFlag) {
+ copy(ch, ptr);
+ copyFlag = false;
+ }
+ else
+ add(ch, ptr);
+ }
+ if (copyFlag) {
+ //
+ // no input,
+ // fill with silence
+ //
+ for (int i = 0; i < channels(); ++i)
+ memset(buffer[i], 0, sizeof(float) * segmentSize);
+ bufferEmpty = true;
+ }
+ }
+
diff --git a/muse_qt4_evolution/muse/audiotrack.h b/muse_qt4_evolution/muse/audiotrack.h
new file mode 100644
index 00000000..1dc77d65
--- /dev/null
+++ b/muse_qt4_evolution/muse/audiotrack.h
@@ -0,0 +1,105 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __AUDIOTRACK_H__
+#define __AUDIOTRACK_H__
+
+#include "fifo.h"
+#include "track.h"
+
+class Pipeline;
+class SndFile;
+class PluginI;
+class AuxPluginIF;
+
+//---------------------------------------------------------
+// AudioTrack
+//---------------------------------------------------------
+
+class AudioTrack : public Track {
+ Q_OBJECT
+
+ bool _prefader; // prefader metering
+ Pipeline* _prePipe;
+ Pipeline* _postPipe;
+ QList<AuxPluginIF*> _preAux;
+ QList<AuxPluginIF*> _postAux;
+
+ void readRecfile(QDomNode);
+
+ protected:
+ float* buffer[MAX_CHANNELS]; // this buffer is filled by process()
+
+ bool bufferEmpty; // set by process() to optimize
+ // data flow
+
+ SndFile* _recFile;
+ Fifo fifo; // fifo -> _recFile
+
+ virtual bool setMute(bool val);
+ virtual bool setOff(bool val);
+ virtual bool setSolo(bool val);
+ virtual void collectInputData();
+
+ private slots:
+ virtual void setAutoRead(bool);
+ virtual void setAutoWrite(bool);
+
+ public:
+ AudioTrack();
+ virtual ~AudioTrack();
+
+ bool readProperties(QDomNode);
+ void writeProperties(Xml&) const;
+
+ virtual Part* newPart(Part*p=0, bool clone=false);
+
+ SndFile* recFile() const { return _recFile; }
+ void setRecFile(SndFile* sf) { _recFile = sf; }
+
+ virtual void setChannels(int n);
+
+ virtual bool isMute() const;
+
+ void putFifo(int channels, unsigned long n, float** bp);
+
+ void record();
+ virtual void startRecording();
+ virtual void stopRecording(const AL::Pos&, const AL::Pos&) {}
+
+ bool prefader() const { return _prefader; }
+ void addAuxSend(int n);
+ void setPrefader(bool val);
+ Pipeline* prePipe() { return _prePipe; }
+ Pipeline* postPipe() { return _postPipe; }
+
+ void addPlugin(PluginI* plugin, int idx, bool pre);
+ PluginI* plugin(int idx, bool prefader) const;
+
+ virtual bool hasAuxSend() const { return false; }
+ virtual void process();
+ void add(int channel, float**);
+ bool copy(int channel, float**);
+ bool isBufferEmpty() const { return bufferEmpty; }
+ QList<AuxPluginIF*> preAux() const { return _preAux; }
+ QList<AuxPluginIF*> postAux() const { return _postAux; }
+ };
+
+#endif
diff --git a/muse_qt4_evolution/muse/audiowriteback.cpp b/muse_qt4_evolution/muse/audiowriteback.cpp
new file mode 100644
index 00000000..391c89bd
--- /dev/null
+++ b/muse_qt4_evolution/muse/audiowriteback.cpp
@@ -0,0 +1,101 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include <poll.h>
+
+#include "audiowriteback.h"
+#include "globals.h"
+#include "audio.h"
+#include "song.h"
+
+AudioWriteback* audioWriteback;
+
+//---------------------------------------------------------
+// AudioWriteback
+//---------------------------------------------------------
+
+AudioWriteback::AudioWriteback(const char* name)
+ : Thread(name)
+ {
+ counter = 0;
+ }
+
+//---------------------------------------------------------
+// readMsg
+//---------------------------------------------------------
+
+static void readMsgP(void* p, void*)
+ {
+ AudioWriteback* at = (AudioWriteback*)p;
+ at->readMsg1(1);
+ }
+
+//---------------------------------------------------------
+// start
+//---------------------------------------------------------
+
+void AudioWriteback::start(int priority)
+ {
+ clearPollFd();
+ addPollFd(toThreadFdr, POLLIN, ::readMsgP, this, 0);
+ Thread::start(priority);
+ }
+
+//---------------------------------------------------------
+// processMsg
+//---------------------------------------------------------
+
+void AudioWriteback::processMsg1(const void*)
+ {
+ while (counter) {
+ //q_atomic_decrement(&counter);
+ --counter;
+
+ OutputList* ol = song->outputs();
+ if (!ol->empty()) {
+ AudioOutput* ao = ol->front();
+ if (ao->recordFlag())
+ ao->record();
+ }
+ WaveTrackList* tl = song->waves();
+ for (iWaveTrack t = tl->begin(); t != tl->end(); ++t) {
+ WaveTrack* track = *t;
+ if (track->recordFlag())
+ track->record();
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// trigger
+// trigger audio writeback loop
+//---------------------------------------------------------
+
+void AudioWriteback::trigger()
+ {
+ // q_atomic_increment(&counter);
+ ++counter;
+ if (counter < 2) {
+ if (sendMsg1("0", 1)) {
+ printf("AudioWriteback::msgTick(): send failed!\n");
+ }
+ }
+ }
+
diff --git a/muse_qt4_evolution/muse/audiowriteback.h b/muse_qt4_evolution/muse/audiowriteback.h
new file mode 100644
index 00000000..000ff2f1
--- /dev/null
+++ b/muse_qt4_evolution/muse/audiowriteback.h
@@ -0,0 +1,44 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __AUDIOWRITEBACK_H__
+#define __AUDIOWRITEBACK_H__
+
+#include "thread.h"
+
+//---------------------------------------------------------
+// AudioWriteback
+//---------------------------------------------------------
+
+class AudioWriteback : public Thread {
+ virtual void processMsg1(const void*);
+ volatile int counter;
+
+ public:
+ AudioWriteback(const char* name);
+ ~AudioWriteback() {}
+ virtual void start(int);
+ void trigger();
+ bool active() const { return counter > 0; }
+ };
+
+extern AudioWriteback* audioWriteback;
+
+#endif
diff --git a/muse_qt4_evolution/muse/auxplugin.cpp b/muse_qt4_evolution/muse/auxplugin.cpp
new file mode 100644
index 00000000..ad203c84
--- /dev/null
+++ b/muse_qt4_evolution/muse/auxplugin.cpp
@@ -0,0 +1,190 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "globaldefs.h"
+#include "auxplugin.h"
+#include "gconfig.h"
+
+AuxPlugin* auxPlugin;
+
+//---------------------------------------------------------
+// AuxPlugin
+//---------------------------------------------------------
+
+AuxPlugin::AuxPlugin()
+ : Plugin(0)
+ {
+ }
+
+//---------------------------------------------------------
+// range
+//---------------------------------------------------------
+
+void AuxPlugin::range(int idx, double* min, double* max) const
+ {
+ switch(idx) {
+ case 0: // volume
+ *min = pow(10.0f, config.minSlider * 0.05f);
+ *max = pow(10.0f, config.maxSlider * 0.05f);
+ break;
+ case 1: // pan
+ *min = -1.0;
+ *max = 1.0;
+ break;
+ default:
+ printf("AuxPlugin::bad index\n");
+ break;
+ }
+ }
+
+//---------------------------------------------------------
+// createPIF
+//---------------------------------------------------------
+
+PluginIF* AuxPlugin::createPIF(PluginI* pi)
+ {
+ AuxPluginIF* pif = new AuxPluginIF(pi);
+ pif->init(pi->plugin());
+ return pif;
+ }
+
+//---------------------------------------------------------
+// isLog
+//---------------------------------------------------------
+
+bool AuxPlugin::isLog(int idx) const
+ {
+ return idx == 0 ? true : false;
+ }
+
+//---------------------------------------------------------
+// isBool
+//---------------------------------------------------------
+
+bool AuxPlugin::isBool(int) const
+ {
+ return false;
+ }
+
+//---------------------------------------------------------
+// isInt
+//---------------------------------------------------------
+
+bool AuxPlugin::isInt(int) const
+ {
+ return false;
+ }
+
+//---------------------------------------------------------
+// defaultValue
+//---------------------------------------------------------
+
+double AuxPlugin::defaultValue(int idx) const
+ {
+ return idx == 0 ? -70.0 : 0.0;
+ }
+
+//---------------------------------------------------------
+// AuxPluginIF
+//---------------------------------------------------------
+
+AuxPluginIF::AuxPluginIF(PluginI* pi)
+ : PluginIF(pi)
+ {
+ for (int i = 0; i < MAX_CHANNELS; ++i)
+ posix_memalign((void**)(_buffer + i), 16, sizeof(float) * segmentSize);
+ }
+
+//---------------------------------------------------------
+// AuxPluginIF
+//---------------------------------------------------------
+
+AuxPluginIF::~AuxPluginIF()
+ {
+ for (int i = 0; i < MAX_CHANNELS; ++i) {
+ if (_buffer[i])
+ free(_buffer[i]);
+ }
+ }
+
+//---------------------------------------------------------
+// apply
+//---------------------------------------------------------
+
+void AuxPluginIF::apply(unsigned nframes, float** s, float** /*dst*/)
+ {
+ // TODO: optimize copy away if there is no route
+ double vol[2];
+ vol[0] = volume * (1.0 - pan);
+ vol[1] = volume * (1.0 + pan);
+
+ for (int i = 0; i < pluginI->channel(); ++i) {
+ float* dst = _buffer[i];
+ float* src = s[i];
+ double v = vol[i];
+ for (unsigned k = 0; k < nframes; ++k)
+ *dst++ = (*src++) * v;
+ }
+ }
+
+//---------------------------------------------------------
+// getParameterName
+//---------------------------------------------------------
+
+const char* AuxPluginIF::getParameterName(int i) const
+ {
+ if (i == 0)
+ return "Volume";
+ else
+ return "Pan";
+ }
+
+//---------------------------------------------------------
+// setParam
+//---------------------------------------------------------
+
+void AuxPluginIF::setParam(int i, double val)
+ {
+ if (i == 0)
+ volume = val;
+ else
+ pan = val;
+ }
+
+//---------------------------------------------------------
+// param
+//---------------------------------------------------------
+
+float AuxPluginIF::param(int i) const
+ {
+ return i == 0 ? volume : pan;
+ }
+
+//---------------------------------------------------------
+// init
+//---------------------------------------------------------
+
+bool AuxPluginIF::init(Plugin* p)
+ {
+ volume = p->defaultValue(0);
+ pan = p->defaultValue(1);
+ return true;
+ }
+
diff --git a/muse_qt4_evolution/muse/auxplugin.h b/muse_qt4_evolution/muse/auxplugin.h
new file mode 100644
index 00000000..cb9c2e4e
--- /dev/null
+++ b/muse_qt4_evolution/muse/auxplugin.h
@@ -0,0 +1,84 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __AUXPLUGIN_H__
+#define __AUXPLUGIN_H__
+
+#include "globaldefs.h"
+#include "plugin.h"
+
+//---------------------------------------------------------
+// AuxPlugin
+//---------------------------------------------------------
+
+class AuxPlugin : public Plugin {
+
+ public:
+ AuxPlugin();
+
+ virtual QString label() const { return "Aux"; }
+ virtual QString name() const { return "Aux"; }
+ virtual unsigned long id() const { return 0; }
+ virtual QString maker() const { return ""; }
+ virtual QString copyright() const { return ""; }
+
+ void* instantiate() { return 0; }
+ virtual void range(int i, double*, double*) const;
+ virtual int parameter() const { return 2; }
+ virtual int inports() const { return 100; }
+ virtual int outports() const { return 100; }
+
+ virtual bool inPlaceCapable() const { return true; }
+ virtual PluginIF* createPIF(PluginI*);
+
+ virtual bool isLog(int k) const;
+ virtual bool isBool(int k) const;
+ virtual bool isInt(int k) const;
+ virtual double defaultValue(int) const;
+ };
+
+//---------------------------------------------------------
+// AuxPluginIF
+//---------------------------------------------------------
+
+class AuxPluginIF : public PluginIF {
+ double volume;
+ double pan;
+ float* _buffer[MAX_CHANNELS]; // this buffer is filled by apply()
+ // _volume and _pan is applied
+
+ public:
+ AuxPluginIF(PluginI* pi);
+ virtual ~AuxPluginIF();
+
+ virtual void apply(unsigned nframes, float** src, float** dst);
+ virtual void activate() {}
+ virtual void deactivate() {}
+ virtual void cleanup() {}
+ virtual const char* getParameterName(int i) const;
+ virtual void setParam(int i, double val);
+ virtual float param(int i) const;
+ bool init(Plugin*);
+ float** buffer() { return _buffer; }
+ int channel() const { return pluginInstance()->channel(); }
+ };
+
+extern AuxPlugin* auxPlugin;
+#endif
diff --git a/muse_qt4_evolution/muse/canvas.cpp b/muse_qt4_evolution/muse/canvas.cpp
new file mode 100644
index 00000000..c445c446
--- /dev/null
+++ b/muse_qt4_evolution/muse/canvas.cpp
@@ -0,0 +1,1187 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "canvas.h"
+#include "al/al.h"
+#include "al/sig.h"
+#include "gconfig.h"
+#include "song.h"
+#include "icons.h"
+#include "audio.h"
+#include "partdrag.h"
+#include "muse.h"
+#include "midictrl.h"
+#include "tlswidget.h"
+#include "part.h"
+#include "gui.h"
+
+#include <samplerate.h>
+
+static const int partLabelHeight = 13;
+static const int handleWidth = 5;
+static const int partBorderWidth = 2;
+
+enum { HIT_NOTHING, HIT_TRACK, HIT_PART, HIT_SUBTRACK };
+
+//---------------------------------------------------------
+// PartCanvas
+//---------------------------------------------------------
+
+PartCanvas::PartCanvas()
+ : TimeCanvas(TIME_CANVAS)
+ {
+ setFocusPolicy(Qt::StrongFocus);
+ state = S_NORMAL;
+ _drawBackground = true;
+ lselected = -1;
+ starty = -1;
+ setMarkerList(song->marker());
+ rubberBand=NULL;
+ connect(song, SIGNAL(markerChanged(int)), SLOT(markerChanged(int)));
+ }
+
+//---------------------------------------------------------
+// markerChanged
+//---------------------------------------------------------
+
+void PartCanvas::markerChanged(int val)
+ {
+ if (val == Song::MARKER_CUR)
+ updateRuler();
+ }
+
+//---------------------------------------------------------
+// drawWavePart
+// y0 - start of track
+// th - track height
+// from - x pixel coordinate start drawing
+// to - x end drawing
+//
+// redraw area is QRect(from, y0, to-from, th)
+//---------------------------------------------------------
+
+void PartCanvas::drawWavePart(QPainter& p, Part* wp, int y0, int th, int from, int to)
+ {
+ int h = th/2;
+ int y = y0 + 1 + h;
+ int cc = th % 2 ? 0 : 1;
+
+ const Pos pos(pix2pos(from));
+ EventList* el = wp->events();
+ for (iEvent e = el->begin(); e != el->end(); ++e) {
+ Event event = e->second;
+ SndFileR f = event.sndFile();
+ if (f.isNull())
+ continue;
+ unsigned channels = f.channels();
+ if (channels == 0) {
+ printf("drawWavePart: channels==0! %s\n", f.finfo()->fileName().toLatin1().data());
+ continue;
+ }
+
+ int x1 = pos2pix(event.pos() + *wp);
+ int x2 = pos2pix(event.end() + *wp);
+ int w = x2 - x1;
+ if (w == 0)
+ continue;
+
+ int samples = event.lenFrame();
+ int xScale = (samples + w/2)/w;
+ int frame = pos.frame() - wp->frame()
+ - event.pos().frame() + event.spos();
+
+ if (h < 20) {
+ //
+ // combine multi channels into one waveform
+ //
+ for (int i = from; i < to; i++) {
+ SampleV sa[channels];
+ f.read(sa, xScale, frame);
+ frame += xScale;
+ int peak = 0;
+ int rms = 0;
+ for (unsigned k = 0; k < channels; ++k) {
+ if (sa[k].peak > peak)
+ peak = sa[k].peak;
+ rms += sa[k].rms;
+ }
+ rms /= channels;
+ peak = (peak * (th-2)) >> 9;
+ rms = (rms * (th-2)) >> 9;
+ p.setPen(QColor(Qt::darkGray));
+ p.drawLine(i, y - peak - cc, i, y + peak);
+ p.setPen(QColor(Qt::black));
+ p.drawLine(i, y - rms - cc, i, y + rms);
+ }
+ }
+ else {
+ //
+ // multi channel display
+ //
+ h = th / (channels * 2);
+ int cc = th % (channels * 2) ? 0 : 1;
+ for (int i = from; i < to; i++) {
+ y = y0 + 1 + h;
+ SampleV sa[channels];
+ f.read(sa, xScale, frame);
+ frame += xScale;
+ for (unsigned k = 0; k < channels; ++k) {
+ // peak = (sa[k].peak * h) / 256;
+ int peak = (sa[k].peak * (h - 1)) >> 8;
+ int rms = (sa[k].rms * (h - 1)) >> 8;
+ p.setPen(QColor(Qt::darkGray));
+ p.drawLine(i, y - peak - cc, i, y + peak);
+ p.setPen(QColor(Qt::black));
+ p.drawLine(i, y - rms - cc, i, y + rms);
+ y += 2 * h;
+ }
+ }
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// paint
+//---------------------------------------------------------
+
+void PartCanvas::paint(QPainter& p, QRect r)
+ {
+ //printf("canvas paint %d %d %d %d\n", r.x(), r.y(), r.width(), r.height());
+ QFont f = font();
+ f.setPointSize(8);
+ p.setFont(f);
+
+ int from = r.x();
+ int to = from + r.width();
+
+ TrackList* tl = song->tracks();
+ ArrangerTrack* at = 0;
+ for (iTrack i = tl->begin(); i != tl->end(); ++i) {
+ Track* t = *i;
+ at = &(t->arrangerTrack);
+ if (at->tw == 0)
+ continue;
+
+ int y = at->tw->y(); // - splitWidth/2;
+ int h = at->tw->height() - 1;
+
+ PartList* pl = t->parts();
+ for (iPart ip = pl->begin(); ip != pl->end(); ++ip) {
+ Part* part = ip->second;
+ int x1 = pos2pix(*part);
+ int x2 = pos2pix(part->end());
+ int len = x2 - x1;
+
+ if (x2 <= from)
+ continue;
+ if (x1 > to)
+ break;
+
+ QRect pr(x1, y, len, h - partBorderWidth);
+ bool clone = part->isClone();
+
+ QPen pen(QColor(100, 100, 100), partBorderWidth, clone ? Qt::DashLine : Qt::SolidLine);
+ QBrush brush(Qt::SolidPattern);
+ QLinearGradient lg(0, pr.y() - wpos.y()-r.y(),
+ 0, pr.y()+ 2*pr.height() -wpos.y()-r.y());
+ lg.setColorAt(0, part->selected()?Qt::gray
+ :config.partColors[part->colorIndex()]);
+ lg.setColorAt(1, Qt::white);
+ QBrush brushLG(lg);
+ if (part->selected()) {
+ pen.setColor(config.partColors[part->colorIndex()]);
+ brush.setColor(config.selectPartBg);
+ p.setBrush(brushLG);
+ }
+ else if (part->mute()) {
+ pen.setColor(Qt::red);
+ brush.setColor(Qt::gray);
+ p.setBrush(brush);
+ }
+ else {
+ //brush.setColor(config.partColors[part->colorIndex()]);
+ p.setBrush(brushLG);
+ }
+ p.setPen(pen);
+ //
+ // we want to draw the rectangle without transformation
+ // to get equal border width horizontal and vertical
+ //
+ QRect rr(p.matrix().mapRect(pr).adjusted(1, 0, -1, 0));
+ p.save();
+ p.resetMatrix();
+ p.drawRect(rr);
+ p.restore();
+
+ int xx1 = x1;
+ if (xx1 < from)
+ xx1 = from;
+ int xx2 = x2;
+ if (xx2 > to)
+ xx2 = to;
+ if (t->isMidiTrack())
+ drawMidiPart(p, part, y, h, xx1, xx2);
+ else if (t->type() == Track::WAVE)
+ drawWavePart(p, part, y, h, xx1, xx2);
+ int yy = y + h - partLabelHeight;
+ p.drawText(x1 + 3, yy, len - 6,
+ partLabelHeight-1, Qt::AlignVCenter | Qt::AlignLeft,
+ part->name());
+
+ // redraw border
+ p.save();
+ p.resetMatrix();
+ p.setPen(pen);
+ p.setBrush(Qt::NoBrush);
+ p.drawRect(rr);
+ p.restore();
+ }
+
+ if (i != tl->begin()) {
+ p.setPen(QPen(Qt::lightGray, trackSeparator, Qt::SolidLine));
+ p.drawLine(from, y + yTrackOffset, to, y + yTrackOffset);
+ }
+ for (iArrangerTrack i = t->subtracks.begin(); i != t->subtracks.end(); ++i) {
+ at = *i;
+ if (at->tw == 0)
+ continue;
+ TLSWidget* tls = (TLSWidget*)(at->tw);
+ int y = tls->y();
+ // int h = tls->height();
+ p.setPen(QPen(Qt::lightGray, trackSeparator, Qt::SolidLine));
+ p.drawLine(from, y + yTrackOffset, to, y + yTrackOffset);
+ y += yTrackOffset + trackSeparator;
+ QPoint off(0, y);
+ p.translate(off);
+ // tls->paint(p, r);
+ tls->paint(p, QRect(from, 0, to-from, tls->height() - (yTrackOffset + trackSeparator)));
+ p.translate(-off);
+ }
+ }
+ if (at && at->tw) {
+ // draw last line
+ int y = at->tw->y() + at->tw->height() + yTrackOffset;
+ p.setPen(QPen(Qt::lightGray, trackSeparator, Qt::SolidLine));
+ p.drawLine(from, y, to, y);
+ }
+ if (state == S_DRAG4 || state == S_DRAG1 || state == S_DRAG2 || state == S_DRAG5) {
+ p.setBrush(Qt::NoBrush);
+ p.setPen(QPen(QColor(Qt::red), partBorderWidth));
+ p.drawRect(drag);
+ }
+ }
+
+//---------------------------------------------------------
+// drawMidiPart
+//---------------------------------------------------------
+
+void PartCanvas::drawMidiPart(QPainter& p, Part* mp, int y, int th, int from, int to)
+ {
+ p.setPen(Qt::black);
+
+ EventList* events = mp->events();
+ // iEvent ito(events->lower_bound(to));
+
+ iEvent ito = events->end();
+// int pos = pos2pix(*mp);
+
+ if (config.canvasShowPartType & 2) { // show events
+ for (iEvent i = events->lower_bound(from); i != ito; ++i) {
+ EventType type = i->second.type();
+ if (
+ ((config.canvasShowPartEvent & 1) && (type == Note))
+ || ((config.canvasShowPartEvent & 2) && (type == PAfter))
+ || ((config.canvasShowPartEvent & 4) && (type == Controller))
+ || ((config.canvasShowPartEvent &16) && (type == CAfter))
+ || ((config.canvasShowPartEvent &64) && (type == Sysex || type == Meta))
+ ) {
+ int t = pos2pix(*mp + i->second.pos());
+ p.drawLine(t, y + 1, t, y + th - 2);
+ }
+ }
+ }
+
+ else { // show Cakewalk Style
+ for (iEvent i = events->begin(); i != ito; ++i) {
+ if (i->second.type() != Note)
+ continue;
+ int x1 = pos2pix(*mp + i->second.pos());
+ int x2 = pos2pix(*mp + i->second.end());
+
+ if (x1 > to)
+ break;
+ if (x2 < from)
+ continue;
+
+ if (x2 > to) // clip to drawing area
+ x2 = to;
+ if (x1 < from)
+ x1 = from;
+ int pitch = i->second.pitch();
+ int yy = y + th - (pitch * th / 127);
+ p.drawLine(x1, yy, x2, yy);
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// searchPart
+//---------------------------------------------------------
+
+int PartCanvas::searchPart(const QPoint& pp)
+ {
+ Pos tp(pix2pos(pp.x()));
+ QPoint p(tp.tick(), pp.y() + wpos.y());
+
+// printf("searchPart %d %d\n", p.x(), p.y());
+ track = 0;
+ part = 0;
+ at = 0;
+ int yp = p.y();
+ if (yp < 0)
+ return HIT_NOTHING;
+
+ TrackList* tl = song->tracks();
+ iTrack i;
+ int y1, y2;
+ for (i = tl->begin(); i != tl->end(); ++i) {
+ track = *i;
+ QWidget* tw = track->arrangerTrack.tw;
+ if (tw == 0) {
+ printf(" invisible Track\n");
+ continue;
+ }
+ y1 = tw->y();
+ y2 = y1 + tw->height();
+ if (yp >= y1 && yp < y2) {
+// printf(" track <%s> %d - %d\n", track->name().toLatin1().data(), y1, y2);
+ break;
+ }
+ for (iArrangerTrack i = track->subtracks.begin(); i != track->subtracks.end(); ++i) {
+ at = *i;
+ if (at->tw == 0) {
+ printf("----empty subtrack?\n");
+ break;
+ }
+ y1 = at->tw->y();
+ y2 = y1 + at->tw->height();
+ if (yp >= y1 && yp < y2) {
+ return HIT_SUBTRACK;
+ }
+ }
+ }
+ if (i == tl->end()) {
+ track = 0;
+ at = 0;
+ return HIT_NOTHING;
+ }
+
+ unsigned x = p.x();
+ PartList* pl = track->parts();
+ for (iPart ip = pl->begin(); ip != pl->end(); ++ip) {
+ part = ip->second;
+ if (x >= part->tick() && x < part->endTick()) {
+ ppos = mapx(part->tick());
+ psize = rmapx(part->lenTick());
+// printf(" part\n");
+ return HIT_PART;
+ }
+ }
+ part = 0;
+ return HIT_TRACK;
+ }
+
+//---------------------------------------------------------
+// contextMenu
+//---------------------------------------------------------
+
+void PartCanvas::contextMenu(const QPoint& pos)
+ {
+ QMenu* pop = new QMenu(widget());
+ QAction* a;
+ if (part) {
+ pop->addAction(getAction("cut", this));
+ pop->addAction(getAction("copy", this));
+ pop->addSeparator();
+ a = pop->addAction(tr("Rename"));
+ a->setData("rename");
+
+ QMenu* cp = pop->addMenu(tr("Color"));
+
+ // part color selection
+ for (int i = 0; i < NUM_PARTCOLORS; ++i) {
+ a = cp->addAction(partColorNames[i]);
+ a->setData(QString("color%1").arg(i));
+ QPixmap pm(20, 20);
+ QPainter p(&pm);
+ p.fillRect(0, 0, 20, 20, config.partColors[i]);
+ a->setIcon(QIcon(pm));
+ }
+ pop->addAction(getAction("delete", this));
+ pop->addAction(getAction("scissor", this));
+ pop->addAction(getAction("glue", this));
+ a = getAction("declone", this);
+ a->setEnabled(part->isClone());
+ pop->addAction(a);
+ if (track->type() == Track::MIDI) {
+ a = pop->addAction(tr("AutoFill..."));
+ a->setData("autofill");
+ }
+ pop->addSeparator();
+ if (track->type() == Track::MIDI) {
+ MidiTrack* track = (MidiTrack*)part->track();
+ if (track->useDrumMap()) {
+ a = pop->addAction(*edit_drummsIcon, tr("drums"));
+ a->setData("editdrums");
+ }
+ else {
+ a = pop->addAction(QIcon(":/xpm/piano.xpm"), tr("pianoroll"));
+ a->setData("editpiano");
+ }
+ a = pop->addAction(*edit_listIcon, tr("miditracker"));
+ a->setData("miditracker");
+ pop->addAction(getAction("listedit", this));
+ }
+ else {
+ a = pop->addAction(*waveIcon, tr("wave edit"));
+ a->setData("waveedit");
+ }
+
+ a = pop->exec(mapToGlobal(pos));
+ if (a) {
+ QString cmd = a->data().toString();
+ if (cmd == "rename")
+ renamePart(part);
+ else if (cmd == "delete")
+ song->cmdRemovePart(part);
+ else if (cmd == "scissor")
+ splitPart(part, startDrag);
+ else if (cmd == "glue")
+ song->cmdGluePart(part);
+ else if (cmd == "cut")
+ cutPart(part);
+ else if (cmd == "copy")
+ copyPart(part);
+ else if (cmd == "editpiano")
+ emit startEditor(part, 0);
+ else if (cmd == "miditracker")
+ emit startEditor(part, 2);
+ else if (cmd == "listedit")
+ emit startEditor(part, 1);
+ else if (cmd == "drumedit")
+ emit startEditor(part, 3);
+ else if (cmd == "waveedit")
+ emit startEditor(part, 4);
+ else if (cmd == "declone")
+ declonePart(part);
+ else if (cmd == "autofill") {
+ bool ok;
+ int ticksM = AL::sigmap.ticksMeasure(part->tick());
+ int n = QInputDialog::getInteger(this,
+ tr("MusE: Get auto fill loop len"),
+ tr("Measures: "),
+ part->fillLen() / ticksM,
+ 0, 16, 1, &ok);
+ if (ok) {
+ part->setFillLen(n * ticksM);
+ }
+ }
+ else if (cmd.startsWith("color")) {
+ int idx = cmd.mid(5).toInt();
+ part->setColorIndex(idx);
+ widget()->update();
+ }
+ else {
+ printf("unknown action <%s>\n", cmd.toLatin1().data());
+ }
+ }
+ }
+ else {
+ for (int i = 0; i < TOOLS; ++i) {
+ if ((arrangerTools & (1 << i))==0)
+ continue;
+ a = getAction(toolList[i], this);
+ pop->addAction(a);
+ a->setCheckable(true);
+ a->setChecked((1 <<i) == (int)_tool);
+ }
+ a = pop->exec(mapToGlobal(pos));
+ if (a)
+ muse->setTool(a->data().toString());
+ }
+ }
+
+//---------------------------------------------------------
+// mousePressEvent
+//---------------------------------------------------------
+
+void PartCanvas::mousePress(QMouseEvent* me)
+ {
+ if (state == S_SUBTRACK) {
+ ((TLSWidget*)(at->tw))->mouseRelease();
+ state = S_NORMAL;
+ }
+
+ QPoint pos(me->pos().x(), me->pos().y() - rulerHeight);
+ startDrag = pos;
+ int hit = searchPart(startDrag);
+
+ if (hit == HIT_SUBTRACK) {
+ TLSWidget* w = (TLSWidget*)(at->tw);
+ int y = wpos.y() + pos.y() - w->y();
+ w->mousePress(QPoint(pos.x(), y), me);
+ // propagate drag events to subtrack if left button pressed:
+ if (me->button() == Qt::LeftButton)
+ state = S_SUBTRACK;
+ return;
+ }
+ else if ( hit == HIT_NOTHING ) { // nothing here we put up a rubberband
+ rubberBandStartPos = me->pos();
+ if (!rubberBand)
+ rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
+ rubberBand->setGeometry(QRect(rubberBandStartPos, QSize()));
+ rubberBand->show();
+ }
+
+ if (button & Qt::RightButton) {
+ contextMenu(me->pos());
+ return;
+ }
+
+ QRect r1,r2;
+ QPoint pos2;
+ int xpos = 0, y = 0, len = 0, h = 0;
+
+ if (hit == HIT_PART) {
+ h = track->arrangerTrack.tw->height();
+ len = rmapx(part->lenTick());
+ y = track->arrangerTrack.tw->y() - splitWidth/2;
+ xpos = mapx(part->tick());
+
+ r1 = QRect(xpos, y, handleWidth, h);
+ r2 = QRect(xpos + len - handleWidth, y, handleWidth, h);
+ pos2 = QPoint(pos.x(), pos.y() + wpos.y());
+ }
+
+ switch (_tool) {
+ case PencilTool:
+ if (r1.contains(pos2))
+ state = S_START_DRAG1;
+ else if (r2.contains(pos2))
+ state = S_START_DRAG2;
+ else
+ state = S_START_DRAG5;
+ ppos = pos2pix(pix2pos(startDrag.x()).downSnaped(raster()));
+ psize = pos2pix(pix2pos(ppos+1).upSnaped(raster())) - ppos;
+ startDragTime = QTime::currentTime();
+ setCursor();
+ break;
+ case RubberTool:
+ if (part)
+ song->cmdRemovePart(part);
+ break;
+ case GlueTool:
+ if (part)
+ song->cmdGluePart(part);
+ break;
+ case CutTool:
+ if (part)
+ splitPart(part, pos);
+ break;
+ case MuteTool:
+ if (part) {
+ part->setMute(!part->mute());
+ widget()->update();
+ }
+ break;
+ default:
+ if (hit == HIT_PART) {
+ QRect r3(xpos, y, len, h);
+
+ if (r1.contains(pos2)) {
+ state = S_START_DRAG1;
+ }
+ else if (r2.contains(pos2)) {
+ state = S_START_DRAG2;
+ }
+ else if (r3.contains(pos2)) {
+ state = S_START_DRAG3;
+ bool add = keyState & Qt::ShiftModifier;
+ song->selectPart(part, add);
+ emit kbdMovementUpdate(track, part);
+ }
+ }
+ if (state == S_NORMAL) {
+ song->selectPart(0, false); // deselect all parts
+ emit kbdMovementUpdate(0, 0); // Tell arranger nothing is selected (Keyboard movement)
+ }
+ startDragTime = QTime::currentTime();
+ setCursor();
+ break;
+ }
+ }
+
+//---------------------------------------------------------
+// mouseMove
+//---------------------------------------------------------
+
+void PartCanvas::mouseMove(QPoint pos)
+ {
+
+ if(rubberBand)
+ rubberBand->setGeometry(QRect(rubberBandStartPos, pos).normalized());
+
+ if (state == S_SUBTRACK) {
+ TLSWidget* w = (TLSWidget*)(at->tw);
+ int y = wpos.y() + pos.y() - w->y() - rulerHeight;
+ w->mouseMove(QPoint(pos.x(), y));
+ return;
+ }
+ pos -= rCanvasA.topLeft();
+ bool update = false;
+ int x = pos.x();
+ int delta = startDrag.x() - x;
+ int t = startDragTime.msecsTo(QTime::currentTime());
+ bool dragActive = (startDrag - pos).manhattanLength() >
+ QApplication::startDragDistance()
+ || t > QApplication::startDragTime();
+ switch (state) {
+ case S_START_DRAG1:
+ if (dragActive)
+ state = S_DRAG1;
+ break;
+ case S_START_DRAG2:
+ if (dragActive)
+ state = S_DRAG2;
+ break;
+ case S_START_DRAG3:
+ if (dragActive)
+ state = S_DRAG3;
+ break;
+ case S_START_DRAG5:
+ if (dragActive)
+ state = S_DRAG5;
+ break;
+ case S_NORMAL:
+ {
+ searchPart(pos);
+ bool found = false;
+ if (part) {
+ int h = track->arrangerTrack.tw->height();
+ int xpos = mapx(part->tick());
+ int len = rmapx(part->lenTick());
+ int y = track->arrangerTrack.tw->y();
+ QRect r1(xpos, y, handleWidth, h);
+ QRect r2(xpos + len - handleWidth, y, handleWidth, h);
+ if (r1.contains(pos) || r2.contains(pos))
+ found = true;
+ }
+ if (found) {
+ widget()->setCursor(Qt::SizeHorCursor);
+ }
+ else
+ setCursor();
+ }
+ break;
+ default:
+ break;
+ }
+ if (!track)
+ return;
+ int y = track->arrangerTrack.tw->y(); // - splitWidth/2;
+ int ph = track->arrangerTrack.tw->height() - 1 - partBorderWidth;
+ if (state == S_DRAG1) {
+ //
+ // drag left edge of part
+ //
+ Pos p(pix2pos(ppos - delta));
+ p.snap(raster());
+ int x1 = pos2pix(p);
+ int x2 = pos2pix(part->end());
+ int size = x2 - x1;
+ drag.setRect(x1, y, size, ph);
+ update = true;
+ }
+ else if (state == S_DRAG2) {
+ //
+ // drag right edge of part
+ //
+ int size = psize - delta;
+ if (size < 10)
+ size = 10;
+ int x2 = mapx(AL::sigmap.raster(part->tick() + rmapxDev(size), raster()));
+ drag.setRect(ppos, y, x2 - ppos, ph);
+ update = true;
+ }
+ else if (state == S_DRAG5) {
+ //
+ // draw part with pencil tool
+ //
+ int size = psize - delta;
+ if (size < 10)
+ size = 10;
+ int x2 = mapx(AL::sigmap.raster(mapxDev(ppos + size), raster()));
+ drag.setRect(ppos, y, x2 - ppos, ph);
+ update = true;
+ }
+ else if (state == S_DRAG3) {
+ //
+ // drag whole part
+ //
+ srcPart = part;
+ QDrag* d = 0;
+ if (track->type() == Track::MIDI)
+ d = new MidiPartDrag(srcPart, this);
+ else if (track->type() == Track::WAVE)
+ d = new AudioPartDrag(srcPart, this);
+ if (d) {
+ Qt::KeyboardModifiers kb = QApplication::keyboardModifiers();
+ Qt::DropActions da = kb ? (Qt::MoveAction | Qt::CopyAction | Qt::LinkAction) : Qt::MoveAction;
+ song->startUndo();
+ _dragOffset = startDrag.x() - rCanvasA.x() - ppos;
+ if (d->start(da) == Qt::MoveAction)
+ song->removePart(srcPart);
+ song->endUndo(0);
+ update = true;
+ }
+ state = S_NORMAL;
+ }
+ if (update)
+ widget()->update();
+ }
+
+//---------------------------------------------------------
+// mouseRelease
+//---------------------------------------------------------
+
+void PartCanvas::mouseRelease(QMouseEvent* me)
+ {
+
+ if (rubberBand)
+ rubberBand->hide(); // TODO robert, nothing more happens for the moment/
+
+ if (state == S_SUBTRACK) {
+ ((TLSWidget*)(at->tw))->mouseRelease();
+ state = S_NORMAL;
+ return;
+ }
+
+ QPoint pos(me->pos());
+ int x = pos.x();
+ int delta = startDrag.x() - x;
+
+ if (state == S_DRAG1) {
+ int val = mapxDev(ppos-delta);
+ int pos = AL::sigmap.raster(val, raster());
+ int size = part->tick() + part->lenTick() - pos;
+ emit partChanged(part, pos, size);
+ }
+ else if (state == S_DRAG2) {
+ int size = psize - delta;
+ int x1 = part->tick();
+ int x2 = AL::sigmap.raster(part->tick() + rmapxDev(size), raster());
+
+ int step = AL::sigmap.rasterStep(x1, raster());
+ if (x2 - x1 < step)
+ x2 = AL::sigmap.raster(x1 + step, raster());
+ emit partChanged(part, x1, x2-x1);
+ }
+ else if (state == S_DRAG5) {
+ if (track && (track->type() == Track::MIDI || track->type() == Track::WAVE)) {
+ Part* part = track->newPart();
+ Pos p1 = pix2pos(drag.x()).snaped(raster());
+ Pos p2 = pix2pos(drag.x() + drag.width()).snaped(raster());
+ part->setPos(p1);
+ part->setLenTick(p2.tick() - p1.tick());
+ song->cmdAddPart(part);
+ }
+ else
+ widget()->update();
+ }
+ state = S_NORMAL;
+ setCursor();
+ }
+
+//---------------------------------------------------------
+// mouseDoubleClickEvent
+//---------------------------------------------------------
+
+void PartCanvas::mouseDoubleClick(QMouseEvent* me)
+ {
+ QPoint pos(me->pos().x(), me->pos().y() - rulerHeight);
+ if (_tool != PointerTool) {
+//TD mousePress(pos);
+ return;
+ }
+ bool shift = keyState & Qt::ShiftModifier;
+ if (searchPart(pos) == HIT_PART) {
+ if (button == Qt::LeftButton && shift) {
+ renamePart(part);
+ }
+ else if (button == Qt::LeftButton) {
+ emit doubleClickPart(part);
+ }
+ }
+ //
+ // double click creates new part between left and
+ // right mark
+
+ else if (track && track->isMidiTrack())
+ emit createLRPart(track);
+ }
+
+
+//---------------------------------------------------------
+// keyboardNavigate
+//---------------------------------------------------------
+
+void PartCanvas::keyboardNavigate(QKeyEvent*)
+ {
+ printf("nothing here go away\n");
+ }
+
+
+//---------------------------------------------------------
+// setCursor
+//---------------------------------------------------------
+
+void PartCanvas::setCursor()
+ {
+ switch(state) {
+ case S_START_DRAG1:
+ case S_START_DRAG2:
+ case S_DRAG1:
+ case S_DRAG2:
+ widget()->setCursor(Qt::SizeHorCursor);
+ return;
+ default:
+ break;
+ }
+ TimeCanvas::setCursor();
+ }
+
+//---------------------------------------------------------
+// declonePart
+//---------------------------------------------------------
+
+void PartCanvas::declonePart(Part* oPart)
+ {
+ Track* track = oPart->track();
+ Part* nPart = track->newPart(oPart, false);
+
+ EventList* se = oPart->events();
+ for (iEvent i = se->begin(); i != se->end(); ++i) {
+ Event oldEvent = i->second;
+// Event ev = oldEvent.clone();
+ nPart->addEvent(oldEvent);
+ }
+ oPart->deref();
+ song->cmdChangePart(oPart, nPart);
+ }
+
+//---------------------------------------------------------
+// splitPart
+//---------------------------------------------------------
+
+void PartCanvas::splitPart(Part* part, const QPoint& p)
+ {
+ song->cmdSplitPart(part, pix2pos(p.x()).snaped(raster()));
+ }
+
+//---------------------------------------------------------
+// renamePart
+//---------------------------------------------------------
+
+void PartCanvas::renamePart(Part* part)
+ {
+ bool ok;
+
+ QString s = QInputDialog::getText(this,
+ tr("MusE: Change Part Name"),
+ tr("PartName:"),
+ QLineEdit::Normal,
+ part->name(),
+ &ok
+ );
+ if (ok && s != part->name()) {
+ song->startUndo();
+ Part* newPart = new Part(*part);
+ newPart->setName(s);
+ song->cmdChangePart(part, newPart);
+ widget()->update();
+ }
+ }
+
+//---------------------------------------------------------
+// cutPart
+//---------------------------------------------------------
+
+void PartCanvas::cutPart(Part* part)
+ {
+ copyPart(part);
+ song->cmdRemovePart(part);
+ }
+
+//---------------------------------------------------------
+// copyPart
+//---------------------------------------------------------
+
+void PartCanvas::copyPart(Part* part)
+ {
+ QBuffer buffer;
+ buffer.open(QIODevice::WriteOnly);
+ AL::Xml xml(&buffer);
+ part->write(xml);
+ buffer.close();
+ QMimeData* mimeData = new QMimeData;
+ mimeData->setData(MidiPartDrag::type, buffer.buffer());
+ QApplication::clipboard()->setMimeData(mimeData);
+ }
+
+//---------------------------------------------------------
+// dragEnter
+//---------------------------------------------------------
+
+void PartCanvas::dragEnter(QDragEnterEvent* event)
+ {
+#if 0
+ QPoint p(event->pos() - rCanvasA.topLeft());
+ searchPart(p);
+ if (!track) {
+ event->ignore();
+ return;
+ }
+ int srcIsMidi = -1;
+ const QMimeData* md = event->mimeData();
+
+ if (MidiPartDrag::canDecode(md))
+ srcIsMidi = 1;
+ else if (AudioPartDrag::canDecode(md))
+ srcIsMidi = 0;
+ else if (WavUriDrag::canDecode(md))
+ srcIsMidi = 0;
+
+ int dstIsMidi = -1;
+ if (track->type() == Track::MIDI)
+ dstIsMidi = 1;
+ else if (track->type() == Track::WAVE)
+ dstIsMidi = 0;
+
+ if ((srcIsMidi == -1) || (dstIsMidi != srcIsMidi)) {
+ event->ignore();
+ return;
+ }
+ Qt::KeyboardModifiers kb = event->keyboardModifiers();
+ if (kb == 0 && (Qt::MoveAction & event->possibleActions())) {
+ event->setDropAction(Qt::MoveAction);
+ event->accept();
+ }
+ else
+#endif
+ event->acceptProposedAction();
+ }
+
+//---------------------------------------------------------
+// dragMoveEvent
+//---------------------------------------------------------
+
+void PartCanvas::dragMove(QDragMoveEvent* event)
+ {
+ QPoint p(event->pos() - rCanvasA.topLeft());
+ searchPart(p);
+ if (!track) {
+ event->acceptProposedAction();
+ return;
+ }
+ Part* srcPart = 0;
+ QString filename;
+
+ bool srcIsMidi;
+ const QMimeData* md = event->mimeData();
+ if (MidiPartDrag::canDecode(md)) {
+ MidiPartDrag::decode(md, srcPart);
+ srcIsMidi = true;
+ }
+ else if (AudioPartDrag::canDecode(md)) {
+ AudioPartDrag::decode(md, srcPart);
+ srcIsMidi = false;
+ }
+ else if (WavUriDrag::canDecode(md)) {
+ WavUriDrag::decode(md, &filename);
+ if (state != S_NORMAL) {
+ state = S_NORMAL;
+ widget()->update();
+ }
+ if (track->type() == Track::WAVE)
+ event->acceptProposedAction();
+ else
+ event->ignore();
+ return;
+ }
+ else {
+ state = S_NORMAL;
+ event->ignore();
+ return;
+ }
+
+ int dstIsMidi = -1;
+ if (track->type() == Track::MIDI)
+ dstIsMidi = 1;
+ else if (track->type() == Track::WAVE)
+ dstIsMidi = 0;
+ if ((srcIsMidi == -1) || (dstIsMidi != srcIsMidi)) {
+ if (state != S_NORMAL) {
+ state = S_NORMAL;
+ widget()->update();
+ }
+ event->ignore();
+ return;
+ }
+ Qt::KeyboardModifiers kb = event->keyboardModifiers();
+ if (kb == 0 && (Qt::MoveAction & event->possibleActions())) {
+ event->setDropAction(Qt::MoveAction);
+ event->accept();
+ }
+ else
+ event->acceptProposedAction();
+ state = S_DRAG4;
+ ArrangerTrack* at = &(track->arrangerTrack);
+
+ PartCanvas* cw = (PartCanvas*)event->source();
+ QRect updateRect(drag);
+
+ Pos pos;
+ if (cw)
+ pos = pix2pos(p.x() - cw->dragOffset()).snaped(raster());
+ else
+ pos = pix2pos(p.x()).snaped(raster());
+ drag.setRect(
+ pos2pix(pos),
+ at->tw->y(),
+ rmapx(srcPart->lenTick()),
+ at->tw->height() - 1 - partBorderWidth
+ );
+ delete srcPart;
+ updateRect |= drag;
+ updateRect.adjust(-1, -1 + rCanvasA.y(), 1, 1 + rCanvasA.y());
+ widget()->update(updateRect);
+ }
+
+//---------------------------------------------------------
+// dropEvent
+//---------------------------------------------------------
+
+void PartCanvas::drop(QDropEvent* event)
+ {
+ state = S_NORMAL;
+ Part* dstPart = 0;
+ QString filename;
+
+ QPoint pos(event->pos() - rCanvasA.topLeft());
+ const QMimeData* md = event->mimeData();
+ if (WavUriDrag::canDecode(md)) {
+ WavUriDrag::decode(md, &filename);
+ int tick = AL::sigmap.raster(mapxDev(pos.x()), raster());
+ Pos pos(tick);
+ muse->importWaveToTrack(filename, track, pos);
+ widget()->update();
+ return;
+ }
+
+ bool isMidi = false;
+ if (MidiPartDrag::canDecode(md)) {
+ MidiPartDrag::decode(md, dstPart);
+ isMidi = true;
+ }
+ else if (AudioPartDrag::canDecode(md))
+ AudioPartDrag::decode(md, dstPart);
+
+ searchPart(pos);
+ if (!dstPart)
+ return;
+ PartCanvas* cw = (PartCanvas*)event->source();
+ bool needEndUndo = false;
+ if (!track) {
+ if (isMidi)
+ track = new MidiTrack();
+ else
+ track = new WaveTrack();
+ track->setDefaultName();
+ if (cw)
+ song->insertTrack(track, -1);
+ else {
+ song->startUndo();
+ song->insertTrack(track, -1);
+ needEndUndo = true;
+ }
+ }
+ else if (isMidi != track->isMidiTrack())
+ return;
+
+ dstPart->setTrack(track);
+
+ //
+ // cw == 0 means that we are dropping to
+ // another application
+
+ unsigned tick;
+ if (cw)
+ tick = AL::sigmap.raster(mapxDev(pos.x() - cw->dragOffset()), raster());
+ else
+ tick = AL::sigmap.raster(mapxDev(pos.x()), raster());
+
+ dstPart->setTick(tick);
+
+ Qt::DropAction da = event->proposedAction();
+ Qt::KeyboardModifiers kb = event->keyboardModifiers();
+ if (kb == 0 && (Qt::MoveAction & event->possibleActions()))
+ da = Qt::MoveAction;
+
+ if ((da == Qt::LinkAction) && (cw == this)) {
+ delete dstPart->events();
+ dstPart->clone(srcPart->events());
+ event->setDropAction(Qt::LinkAction);
+ }
+ else if (da == Qt::MoveAction)
+ event->setDropAction(Qt::MoveAction);
+ else
+ event->setDropAction(Qt::CopyAction);
+ event->accept();
+ if (cw || needEndUndo)
+ song->addPart(dstPart);
+ else
+ song->cmdAddPart(dstPart);
+ if (needEndUndo)
+ song->endUndo(0);
+ widget()->update();
+ }
+
+//---------------------------------------------------------
+// dragLeave
+//---------------------------------------------------------
+
+void PartCanvas::dragLeave(QDragLeaveEvent*)
+ {
+ if (state == S_DRAG4) {
+ state = S_NORMAL;
+ widget()->update();
+ }
+ }
+
diff --git a/muse_qt4_evolution/muse/canvas.h b/muse_qt4_evolution/muse/canvas.h
new file mode 100644
index 00000000..911936c2
--- /dev/null
+++ b/muse_qt4_evolution/muse/canvas.h
@@ -0,0 +1,124 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __CANVAS_H__
+#define __CANVAS_H__
+
+#include "awl/tcanvas.h"
+#include "widgets/tools.h"
+
+class CanvasWidget;
+class Part;
+class Track;
+class ArrangerTrack;
+
+static const int HANDLE1 = 6;
+static const int HANDLE2 = 3;
+
+//---------------------------------------------------------
+// PartCanvas
+//---------------------------------------------------------
+
+class PartCanvas : public TimeCanvas {
+ Q_OBJECT
+
+ // DRAG1 drag part head
+ // DRAG2 drag part tail
+ // DRAG3 drag whole part
+ // DRAG4 Drag&Drop drag
+ // DRAG5 draw part with pencil tool
+
+ enum { S_NORMAL, S_START_DRAG1, S_START_DRAG2, S_START_DRAG3,
+ S_DRAG1, S_DRAG2, S_DRAG3,
+ S_DRAG4,
+ S_START_DRAG5, S_DRAG5, // draw new Part
+ S_SUBTRACK
+ };
+ int state;
+ QPoint startDrag;
+ int _dragOffset;
+ QRect drag;
+ QTime startDragTime;
+ unsigned ppos, psize;
+
+ // values set by searchPart():
+ Track* track;
+ Part* part;
+ ArrangerTrack* at;
+
+ Part* srcPart; // src part of a drag/drop operation
+
+ bool _drawBackground;
+ int selected;
+ int lselected; // in local coordinates
+ int starty;
+ int dragy;
+
+ virtual void paint(QPainter&, QRect);
+ void drawWavePart(QPainter& p, Part* part, int, int, int, int);
+ void drawMidiPart(QPainter& p, Part* mp, int, int, int, int);
+ virtual void mousePress(QMouseEvent*);
+ virtual void mouseMove(QPoint);
+ virtual void mouseRelease(QMouseEvent*);
+ virtual void mouseDoubleClick(QMouseEvent*);
+
+ virtual void dragEnter(QDragEnterEvent*);
+ virtual void drop(QDropEvent*);
+ virtual void dragMove(QDragMoveEvent*);
+ virtual void dragLeave(QDragLeaveEvent*);
+
+ virtual void keyboardNavigate(QKeyEvent *e);
+
+
+ int searchPart(const QPoint& p);
+
+ void declonePart(Part* part);
+ void renamePart(Part*);
+ void splitPart(Part*, const QPoint&);
+ void cutPart(Part*);
+ void copyPart(Part*);
+
+ void setCursor();
+ int dragOffset() const { return _dragOffset; }
+ void drawHandle(QPainter& p, int x, int y) {
+ p.fillRect(x-HANDLE2, y-HANDLE2, HANDLE1, HANDLE1, x == lselected ? Qt::red : Qt::yellow);
+ }
+ void contextMenu(const QPoint&);
+
+ QRubberBand *rubberBand;
+ QPoint rubberBandStartPos;
+
+ private slots:
+ void markerChanged(int);
+
+ signals:
+ void kbdMovementUpdate(Track* t, Part* p);
+ void startEditor(Part*, int);
+ void createLRPart(Track*);
+ void partChanged(Part*, unsigned, unsigned);
+ void doubleClickPart(Part*);
+
+ public:
+ PartCanvas();
+ void setDrawBackground(bool val) { _drawBackground = val; }
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/cliplist/cliplist.cpp b/muse_qt4_evolution/muse/cliplist/cliplist.cpp
new file mode 100644
index 00000000..b39fa367
--- /dev/null
+++ b/muse_qt4_evolution/muse/cliplist/cliplist.cpp
@@ -0,0 +1,251 @@
+//=========================================================
+// MusE
+// Linux Music Editor
+// $Id: cliplist.cpp,v 1.10 2005/09/22 20:12:59 wschweer Exp $
+//
+// (C) Copyright 2000 Werner Schweer (ws@seh.de)
+//=========================================================
+
+#include "cliplist.h"
+#include "song.h"
+#include "globals.h"
+#include "wave.h"
+#include "xml.h"
+// #include "posedit.h"
+#include "cliplisteditorbase.h"
+//Added by qt3to4:
+#include <QCloseEvent>
+
+extern int mtcType;
+enum { COL_NAME=0, COL_REFS, COL_POS, COL_LEN };
+
+//---------------------------------------------------------
+// ClipItem
+//---------------------------------------------------------
+
+class ClipItem : public Q3ListViewItem {
+ SndFileR _wf;
+
+ virtual QString text(int) const;
+
+ public:
+ ClipItem(Q3ListView*, const SndFileR&);
+ SndFileR* wf() { return &_wf; }
+ };
+
+ClipItem::ClipItem(Q3ListView* parent, const SndFileR& w)
+ : Q3ListViewItem(parent), _wf(w)
+ {
+ }
+
+//---------------------------------------------------------
+// samples2smpte
+//---------------------------------------------------------
+
+#if 0
+static QString samples2smpte(int samples)
+ {
+ double time = double(samples) / double(sampleRate);
+ int min = int(time) / 60;
+ int sec = int(time) % 60;
+ double rest = time - (min * 60 + sec);
+ switch(mtcType) {
+ case 0: // 24 frames sec
+ rest *= 24;
+ break;
+ case 1: // 25
+ rest *= 25;
+ break;
+ case 2: // 30 drop frame
+ rest *= 30;
+ break;
+ case 3: // 30 non drop frame
+ rest *= 30;
+ break;
+ }
+ int frame = int(rest);
+ int subframe = int((rest-frame)*100);
+ QString s;
+ s.sprintf("%03d:%02d:%02d:%02d", min, sec, frame, subframe);
+ return s;
+ }
+#endif
+
+//---------------------------------------------------------
+// text
+//---------------------------------------------------------
+
+QString ClipItem::text(int col) const
+ {
+ QString s("");
+ switch(col) {
+ case COL_NAME:
+ s = _wf.name();
+ break;
+ case COL_POS:
+ case COL_LEN:
+ break;
+ case COL_REFS:
+ s.setNum(_wf.getRefCount());
+ break;
+ }
+ return s;
+ }
+
+//---------------------------------------------------------
+// ClipListEdit
+//---------------------------------------------------------
+
+ClipListEdit::ClipListEdit()
+ : TopWin(0, "cliplist", Qt::WType_TopLevel /*|WDestructiveClose*/)
+ {
+ setCaption(tr("MusE: Clip List Editor"));
+
+ editor = new ClipListEditorBase(this, "edit");
+ setCentralWidget(editor);
+
+ editor->view->setColumnAlignment(COL_REFS, AlignRight);
+
+ QFontMetrics fm(editor->view->font());
+ int fw = style().pixelMetric(QStyle::PM_DefaultFrameWidth, this);
+ int w = 2 + fm.width('9') * 9 + fm.width(':') * 3 + fw * 4;
+ editor->view->setColumnAlignment(COL_POS, AlignRight);
+ editor->view->setColumnWidth(COL_POS, w);
+ editor->view->setColumnAlignment(COL_LEN, AlignRight);
+ editor->view->setColumnWidth(COL_LEN, w);
+
+ connect(editor->view, SIGNAL(selectionChanged()), SLOT(clipSelectionChanged()));
+ connect(editor->view, SIGNAL(clicked(Q3ListViewItem*)), SLOT(clicked(Q3ListViewItem*)));
+
+ connect(song, SIGNAL(songChanged(int)), SLOT(songChanged(int)));
+ connect(editor->start, SIGNAL(valueChanged(const Pos&)), SLOT(startChanged(const Pos&)));
+ connect(editor->len, SIGNAL(valueChanged(const Pos&)), SLOT(lenChanged(const Pos&)));
+
+ updateList();
+ }
+
+//---------------------------------------------------------
+// updateList
+//---------------------------------------------------------
+
+void ClipListEdit::updateList()
+ {
+ editor->view->clear();
+ for (iSndFile f = SndFile::sndFiles.begin(); f != SndFile::sndFiles.end(); ++f) {
+ new ClipItem(editor->view, *f);
+ }
+ clipSelectionChanged();
+ }
+
+//---------------------------------------------------------
+// closeEvent
+//---------------------------------------------------------
+
+void ClipListEdit::closeEvent(QCloseEvent* e)
+ {
+ emit deleted((int)this);
+ e->accept();
+ }
+
+//---------------------------------------------------------
+// songChanged
+//---------------------------------------------------------
+
+void ClipListEdit::songChanged(int)
+ {
+ updateList();
+ }
+
+//---------------------------------------------------------
+// readStatus
+//---------------------------------------------------------
+
+void ClipListEdit::readStatus(QDomNode node)
+ {
+#if 0 //TODO2
+ for (;;) {
+ Xml::Token token = xml.parse();
+ const QString& tag = xml.s1();
+ if (token == Xml::Error || token == Xml::End)
+ break;
+ switch (token) {
+ case Xml::TagStart:
+ if (tag == "topwin")
+ TopWin::readStatus(xml);
+ else
+ xml.unknown("CliplistEdit");
+ break;
+ case Xml::TagEnd:
+ if (tag == "cliplist")
+ return;
+ default:
+ break;
+ }
+ }
+#endif
+ }
+
+//---------------------------------------------------------
+// writeStatus
+//---------------------------------------------------------
+
+void ClipListEdit::writeStatus(Xml& xml) const
+ {
+ xml.tag("cliplist");
+ TopWin::writeStatus(xml);
+ xml.etag("cliplist");
+ }
+
+//---------------------------------------------------------
+// startChanged
+//---------------------------------------------------------
+
+void ClipListEdit::startChanged(const Pos& pos)
+ {
+// editor->view->triggerUpdate();
+ }
+
+//---------------------------------------------------------
+// lenChanged
+//---------------------------------------------------------
+
+void ClipListEdit::lenChanged(const Pos& pos)
+ {
+// curClip.setLenFrame(pos.frame());
+// editor->view->triggerUpdate();
+ }
+
+//---------------------------------------------------------
+// clipSelectionChanged
+//---------------------------------------------------------
+
+void ClipListEdit::clipSelectionChanged()
+ {
+ ClipItem* item = (ClipItem*)(editor->view->selectedItem());
+// if (item == 0) {
+ editor->start->setEnabled(false);
+ editor->len->setEnabled(false);
+ return;
+#if 0
+ }
+ editor->start->setEnabled(true);
+ editor->len->setEnabled(true);
+ Pos pos, len;
+ pos.setType(Pos::FRAMES);
+ len.setType(Pos::FRAMES);
+ pos.setFrame(curClip.spos());
+ len.setFrame(curClip.lenFrame());
+ editor->start->setValue(pos);
+ editor->len->setValue(len);
+#endif
+ }
+
+//---------------------------------------------------------
+// clicked
+//---------------------------------------------------------
+
+void ClipListEdit::clicked(Q3ListViewItem*)
+ {
+// printf("clicked\n");
+ }
+
diff --git a/muse_qt4_evolution/muse/cliplist/cliplist.h b/muse_qt4_evolution/muse/cliplist/cliplist.h
new file mode 100644
index 00000000..c3a6d5aa
--- /dev/null
+++ b/muse_qt4_evolution/muse/cliplist/cliplist.h
@@ -0,0 +1,47 @@
+//=========================================================
+// MusE
+// Linux Music Editor
+// $Id: cliplist.h,v 1.7 2006/01/06 22:48:09 wschweer Exp $
+//
+// (C) Copyright 2000 Werner Schweer (ws@seh.de)
+//=========================================================
+
+#ifndef __CLIPLIST_H__
+#define __CLIPLIST_H__
+
+#include "../cobject.h"
+#include "event.h"
+
+class Xml;
+class Pos;
+class ClipListEditorBase;
+
+//---------------------------------------------------------
+// ClipListEdit
+//---------------------------------------------------------
+
+class ClipListEdit : public TopWin {
+ Q_OBJECT
+ ClipListEditorBase* editor;
+
+ virtual void closeEvent(QCloseEvent*);
+ void updateList();
+
+ private slots:
+ void songChanged(int);
+ void startChanged(const Pos&);
+ void lenChanged(const Pos&);
+ void clipSelectionChanged();
+ void clicked(Q3ListViewItem*);
+
+ signals:
+ void deleted(int);
+
+ public:
+ ClipListEdit();
+ virtual void readStatus(QDomNode);
+ virtual void writeStatus(Xml&) const;
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/cobject.cpp b/muse_qt4_evolution/muse/cobject.cpp
new file mode 100644
index 00000000..6339a2b7
--- /dev/null
+++ b/muse_qt4_evolution/muse/cobject.cpp
@@ -0,0 +1,55 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "cobject.h"
+#include "al/xml.h"
+#include "gui.h"
+
+//---------------------------------------------------------
+// TopWin
+//---------------------------------------------------------
+
+TopWin::TopWin()
+ : QMainWindow()
+ {
+ setIconSize(ICON_SIZE);
+ }
+
+//---------------------------------------------------------
+// readStatus
+//---------------------------------------------------------
+
+void TopWin::read(QDomNode node)
+ {
+ for (node = node.firstChild(); !node.isNull(); node = node.nextSibling())
+ AL::readProperties(this, node);
+ }
+
+//---------------------------------------------------------
+// write
+//---------------------------------------------------------
+
+void TopWin::write(Xml& xml) const
+ {
+ xml.stag(metaObject()->className());
+ xml.writeProperties(this);
+ xml.etag(metaObject()->className());
+ }
+
diff --git a/muse_qt4_evolution/muse/cobject.h b/muse_qt4_evolution/muse/cobject.h
new file mode 100644
index 00000000..0dcbdf9d
--- /dev/null
+++ b/muse_qt4_evolution/muse/cobject.h
@@ -0,0 +1,46 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __COBJECT_H__
+#define __COBJECT_H__
+
+namespace AL {
+ class Xml;
+ };
+using AL::Xml;
+
+//---------------------------------------------------------
+// TopWin
+//---------------------------------------------------------
+
+class TopWin : public QMainWindow
+ {
+ Q_OBJECT
+ Q_PROPERTY(bool muse) // hack: start MusE property list
+ Q_PROPERTY(QRect geometry READ geometry WRITE setGeometry)
+
+ public:
+ virtual void read(QDomNode);
+ virtual void write(Xml& xml) const;
+ TopWin();
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/conf.cpp b/muse_qt4_evolution/muse/conf.cpp
new file mode 100644
index 00000000..162f6f9b
--- /dev/null
+++ b/muse_qt4_evolution/muse/conf.cpp
@@ -0,0 +1,694 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "al/al.h"
+#include "muse.h"
+#include "shortcuts.h"
+#include "transport.h"
+#include "widgets/bigtime.h"
+#include "conf.h"
+#include "gconfig.h"
+#include "al/xml.h"
+#include "widgets/midisync.h"
+#include "sync.h"
+#include "mixer.h"
+#include "globals.h"
+#include "midirc.h"
+#include "awl/tcanvas.h"
+#include "midiedit/pianoroll.h"
+#include "midiedit/drumedit.h"
+
+extern void writeMidiTransforms(Xml& xml);
+extern void readMidiTransform(QDomNode);
+
+//---------------------------------------------------------
+// readColor
+//---------------------------------------------------------
+
+QColor readColor(QDomNode node)
+ {
+ QDomElement e = node.toElement();
+ int r = e.attribute("r","0").toInt();
+ int g = e.attribute("g","0").toInt();
+ int b = e.attribute("b","0").toInt();
+ return QColor(r, g, b);
+ }
+
+//---------------------------------------------------------
+// readConfiguration
+//---------------------------------------------------------
+
+void readConfiguration(QDomNode node)
+ {
+ for (; !node.isNull(); node = node.nextSibling()) {
+ QDomElement e = node.toElement();
+ QString tag(e.tagName());
+ QString s(e.text());
+ int i = s.toInt();
+ if (tag == "palette0")
+ QColorDialog::setCustomColor(0, readColor(node).rgb());
+ else if (tag == "palette1")
+ QColorDialog::setCustomColor(1, readColor(node).rgb());
+ else if (tag == "palette2")
+ QColorDialog::setCustomColor(2, readColor(node).rgb());
+ else if (tag == "palette3")
+ QColorDialog::setCustomColor(3, readColor(node).rgb());
+ else if (tag == "palette4")
+ QColorDialog::setCustomColor(4, readColor(node).rgb());
+ else if (tag == "palette5")
+ QColorDialog::setCustomColor(5, readColor(node).rgb());
+ else if (tag == "palette6")
+ QColorDialog::setCustomColor(6, readColor(node).rgb());
+ else if (tag == "palette7")
+ QColorDialog::setCustomColor(7, readColor(node).rgb());
+ else if (tag == "palette8")
+ QColorDialog::setCustomColor(8, readColor(node).rgb());
+ else if (tag == "palette9")
+ QColorDialog::setCustomColor(9, readColor(node).rgb());
+ else if (tag == "palette10")
+ QColorDialog::setCustomColor(10, readColor(node).rgb());
+ else if (tag == "palette11")
+ QColorDialog::setCustomColor(11, readColor(node).rgb());
+ else if (tag == "palette12")
+ QColorDialog::setCustomColor(12, readColor(node).rgb());
+ else if (tag == "palette13")
+ QColorDialog::setCustomColor(13, readColor(node).rgb());
+ else if (tag == "palette14")
+ QColorDialog::setCustomColor(14, readColor(node).rgb());
+ else if (tag == "palette15")
+ QColorDialog::setCustomColor(15, readColor(node).rgb());
+ else if (tag == "selectPartBg")
+ config.selectPartBg = readColor(node);
+ else if (tag == "outputTrackBg")
+ config.trackBg[Track::AUDIO_OUTPUT] = readColor(node);
+ else if (tag == "groupTrackBg")
+ config.trackBg[Track::AUDIO_GROUP] = readColor(node);
+ else if (tag == "waveTrackBg")
+ config.trackBg[Track::WAVE] = readColor(node);
+ else if (tag == "inputTrackBg")
+ config.trackBg[Track::AUDIO_INPUT] = readColor(node);
+ else if (tag == "synthTrackBg")
+ config.trackBg[Track::AUDIO_SOFTSYNTH] = readColor(node);
+ else if (tag == "midiTrackBg")
+ config.trackBg[Track::MIDI] = readColor(node);
+ else if (tag == "midiOutputBg")
+ config.trackBg[Track::MIDI_OUT] = readColor(node);
+ else if (tag == "midiInputBg")
+ config.trackBg[Track::MIDI_IN] = readColor(node);
+ else if (tag == "midiSyntiBg")
+ config.trackBg[Track::MIDI_SYNTI] = readColor(node);
+ else if (tag == "extendedMidi")
+ config.extendedMidi = i;
+ else if (tag == "midiExportDivision")
+ config.midiDivision = i;
+ else if (tag == "copyright")
+ config.copyright = s;
+ else if (tag == "smfFormat")
+ config.smfFormat = i;
+ else if (tag == "bigtimeVisible")
+ config.bigTimeVisible = i;
+ else if (tag == "transportVisible")
+ config.transportVisible = i;
+ else if (tag == "mixer1Visible")
+ config.mixer1Visible = i;
+ else if (tag == "mixer2Visible")
+ config.mixer2Visible = i;
+ else if (tag == "showSplashScreen")
+ config.showSplashScreen = i;
+ else if (tag == "canvasShowPartType")
+ config.canvasShowPartType = i;
+ else if (tag == "canvasShowPartEvent")
+ config.canvasShowPartEvent = i;
+ else if (tag == "canvasShowGrid")
+ config.canvasShowGrid = i;
+ else if (tag == "canvasBgPixmap")
+ config.canvasBgPixmap = s;
+ else if (tag == "canvasUsePixmap")
+ config.canvasUseBgPixmap = i;
+ else if (tag == "geometryMain")
+ ; // obsolete
+ else if (tag == "geometryTransport")
+ config.geometryTransport = AL::readGeometry(node);
+ else if (tag == "geometryBigTime")
+ config.geometryBigTime = AL::readGeometry(node);
+ else if (tag == "geometryPianoroll")
+ config.geometryPianoroll = AL::readGeometry(node);
+ else if (tag == "geometryDrumedit")
+ config.geometryDrumedit = AL::readGeometry(node);
+ else if (tag == "mixer1")
+ config.mixer1.read(node);
+ else if (tag == "mixer2")
+ config.mixer2.read(node);
+ else if (tag == "bigtimeForegroundcolor")
+ config.bigTimeForegroundColor = readColor(node);
+ else if (tag == "bigtimeBackgroundcolor")
+ config.bigTimeBackgroundColor = readColor(node);
+ else if (tag == "freewheelMode")
+ config.useJackFreewheelMode = i;
+ else if (tag == "mtctype")
+ AL::mtcType = i;
+ else if (tag == "extSync")
+ extSyncFlag = i;
+ else if (tag == "syncgentype") {
+ // for compatibility
+ int syncGenType= i;
+ genMTCSync = syncGenType == 1;
+ genMCSync = syncGenType == 2;
+ }
+ else if (tag == "genMTCSync")
+ genMTCSync = i;
+ else if (tag == "genMCSync")
+ genMCSync = i;
+ else if (tag == "genMMC")
+ genMMC = i;
+ else if (tag == "acceptMTC")
+ acceptMTC = i;
+ else if (tag == "acceptMMC")
+ acceptMMC = i;
+ else if (tag == "acceptMC")
+ acceptMC = i;
+ else if (tag == "mtcoffset") {
+ QStringList l = s.simplified().split(":", QString::SkipEmptyParts);
+ if (l.size() != 5) {
+ printf("cannot convert mtcoffset <%s>n\n", s.toAscii().data());
+ }
+ else {
+ int h = l.at(0).toInt();
+ int m = l.at(0).toInt();
+ int s = l.at(0).toInt();
+ int f = l.at(0).toInt();
+ int sf = l.at(0).toInt();
+ mtcOffset = MTC(h, m, s, f, sf);
+ }
+ }
+ else if (tag == "shortcuts")
+ readShortCuts(node.firstChild());
+ else if (tag == "midiRC")
+ midiRCList.read(node);
+ else if (tag == "division")
+ config.division = i;
+ else if (tag == "guiDivision")
+ config.guiDivision = i;
+ else if (tag == "rtcTicks")
+ config.rtcTicks = i;
+ else if (tag == "minMeter")
+ config.minMeter = s.toDouble();
+ else if (tag == "maxMeter")
+ config.maxMeter = s.toDouble();
+ else if (tag == "minSlider")
+ config.minSlider = s.toDouble();
+ else if (tag == "maxSlider")
+ config.maxSlider = s.toDouble();
+ else if (tag == "guiRefresh")
+ config.guiRefresh = i;
+ else if (tag == "peakHoldTime")
+ config.peakHoldTime = i;
+ else if (tag == "helpBrowser")
+ config.helpBrowser = s;
+//TD else if (tag == "midiTransform")
+// readMidiTransform(node.firstChild());
+ else if (tag == "startMode")
+ config.startMode = (StartMode)i;
+ else if (tag == "startProject")
+ config.startProject = s;
+ else if (tag == "followMode")
+ TimeCanvas::followMode = (FollowMode)i;
+ else if (tag == "defaultMidiInputDevice")
+ config.defaultMidiInputDevice = s;
+ else if (tag == "defaultMidiOutputDevice")
+ config.defaultMidiOutputDevice = s;
+ else if (tag == "defaultMidiInstrument")
+ config.defaultMidiInstrument = s;
+ else if (tag == "connectToAllMidiDevices")
+ config.connectToAllMidiDevices = i;
+ else if (tag == "connectToAllMidiTracks")
+ config.connectToAllMidiTracks = i;
+ else if (tag == "createDefaultMidiInput")
+ config.createDefaultMidiInput = i;
+ else if (tag == "projectPath")
+ config.projectPath = s;
+ else if (tag == "templatePath")
+ config.templatePath = s;
+ else if (tag == "instrumentPath")
+ config.instrumentPath = s;
+ else if (tag == "importMidiPath") {
+ config.importMidiPath = s;
+ lastMidiPath = museUser + "/" + s;
+ }
+ else if (tag == "importWavePath") {
+ config.importWavePath = s;
+ lastWavePath = museUser + "/" + s;
+ }
+ else if (tag == "PianoRoll")
+ PianoRoll::readConfiguration(node);
+ else if (tag == "DrumEdit")
+ DrumEdit::readConfiguration(node);
+ else {
+ printf("MusE:readConfiguration(): unknown tag %s\n",
+ e.tagName().toAscii().data());
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// probeMachineSpecificConfiguration
+//---------------------------------------------------------
+
+static void probeMachineSpecificConfiguration()
+ {
+ // set a default help browser (crude way to find out)
+ if (!system("which konqueror &>/dev/null")) {
+ config.helpBrowser = QString("konqueror");
+ }
+ else if (!system("which opera &>/dev/null")) {
+ config.helpBrowser = QString("opera");
+ }
+ else if (!system("which firebird &>/dev/null")) {
+ config.helpBrowser = QString("firebird");
+ }
+ else if (!system("which mozilla &>/dev/null")) {
+ config.helpBrowser = QString("mozilla");
+ }
+ else {
+ // was not able to find a browser
+ }
+ // More preconfiguration
+ }
+
+//---------------------------------------------------------
+// readConfiguration
+//---------------------------------------------------------
+
+bool readConfiguration()
+ {
+ if (debugMsg)
+ printf("readConfiguration <%s>\n", configName.toAscii().data());
+
+ QFile qf(configName);
+ if (!qf.open(QIODevice::ReadOnly)) {
+ if (debugMsg || debugMode)
+ fprintf(stderr, "NO Config File <%s> found\n", configName.toAscii().data());
+
+ // if the config file does not exist launch probeMachineSpecificConfiguration
+ probeMachineSpecificConfiguration();
+ return true;
+ }
+ if (debugMsg)
+ printf("readConfiguration <%s>\n", configName.toAscii().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 + "\n at line: " + ln + " col: " + col;
+ printf("error reading med file: %s\n", error.toAscii().data());
+ return true;
+ }
+ QDomNode node = doc.documentElement();
+ while (!node.isNull()) {
+ QDomElement e = node.toElement();
+ if (e.isNull())
+ continue;
+ if (e.tagName() == "muse") {
+ node = node.firstChild();
+ // QString version = e.attribute(QString("version"));
+ while (!node.isNull()) {
+ QDomElement e = node.toElement();
+ if (e.tagName() == "configuration")
+ readConfiguration(node.firstChild());
+ else
+ printf("MusE:readConfiguration(): unknown tag %s\n", e.tagName().toAscii().data());
+ node = node.nextSibling();
+ }
+ }
+ else
+ printf("MusE:readConfiguration() %s not supported\n", e.tagName().toAscii().data());
+ node = node.nextSibling();
+ }
+ return false;
+ }
+
+//---------------------------------------------------------
+// writeGlobalConfiguration
+//---------------------------------------------------------
+
+void MusE::writeGlobalConfiguration() const
+ {
+ QFile f(configName);
+ if (!f.open(QIODevice::WriteOnly)) {
+ printf("save configuration to <%s> failed: %s\n",
+ configName.toAscii().data(), strerror(errno));
+ return;
+ }
+ Xml xml(&f);
+ xml.header();
+ xml.stag("muse version=\"2.0\"");
+ writeGlobalConfiguration(xml);
+ xml.etag("muse");
+ f.close();
+ }
+
+void MusE::writeGlobalConfiguration(Xml& xml) const
+ {
+ xml.stag("configuration");
+
+ xml.tag("division", config.division);
+ xml.tag("rtcTicks", config.rtcTicks);
+ xml.tag("minMeter", config.minMeter);
+ xml.tag("maxMeter", config.maxMeter);
+ xml.tag("minSlider", config.minSlider);
+ xml.tag("maxSlider", config.maxSlider);
+ xml.tag("guiRefresh", config.guiRefresh);
+ xml.tag("peakHoldTime", config.peakHoldTime);
+ xml.tag("helpBrowser", config.helpBrowser);
+ xml.tag("extendedMidi", config.extendedMidi);
+ xml.tag("midiExportDivision", config.midiDivision);
+ xml.tag("guiDivision", config.guiDivision);
+ xml.tag("copyright", config.copyright);
+ xml.tag("smfFormat", config.smfFormat);
+ xml.tag("startMode", config.startMode);
+ if (!config.startProject.isEmpty())
+ xml.tag("startProject", config.startProject);
+ xml.tag("freewheelMode", config.useJackFreewheelMode);
+
+ for (int i = 0; i < QColorDialog::customCount(); ++i) {
+ char buffer[32];
+ snprintf(buffer, 32, "palette%d", i);
+ xml.tag(buffer, QColorDialog::customColor(i));
+ }
+
+ xml.tag("selectPartBg", config.selectPartBg);
+
+ static const char* colorNames[Track::TRACK_TYPES] = {
+ "outputTrackBg",
+ "groupTrackBg",
+ "waveTrackBg",
+ "inputTrackBg",
+ "synthTrackBg",
+ "midiTrackBg",
+ "midiOutputBg",
+ "midiInputBg",
+ "midiSyntiBg"
+ };
+ for (int i = 0; i < Track::TRACK_TYPES; ++i)
+ xml.tag(colorNames[i], config.trackBg[i]);
+
+ xml.tag("mtctype", AL::mtcType);
+
+ xml.stag("mtcoffset");
+ xml.put(QString("%1:%2:%3:%4:%5")
+ .arg(mtcOffset.h()).arg(mtcOffset.m()).arg(mtcOffset.s())
+ .arg(mtcOffset.f()).arg(mtcOffset.sf()));
+ xml.etag("mtcoffset");
+
+ xml.tag("extSync", extSyncFlag);
+ xml.tag("genMTCSync", genMTCSync);
+ xml.tag("genMCSync", genMCSync);
+ xml.tag("genMMC", genMMC);
+ xml.tag("acceptMTC", acceptMTC);
+ xml.tag("acceptMMC", acceptMMC);
+ xml.tag("acceptMC", acceptMC);
+
+ xml.tag("geometryTransport", config.geometryTransport);
+ xml.tag("geometryBigTime", config.geometryBigTime);
+ xml.tag("geometryPianoroll", config.geometryPianoroll);
+ xml.tag("geometryDrumedit", config.geometryDrumedit);
+
+ xml.tag("bigtimeVisible", config.bigTimeVisible);
+ xml.tag("transportVisible", config.transportVisible);
+
+ xml.tag("mixer1Visible", config.mixer1Visible);
+ xml.tag("mixer2Visible", config.mixer2Visible);
+
+ config.mixer1.write(xml, "mixer1");
+ config.mixer2.write(xml, "mixer2");
+
+ xml.tag("showSplashScreen", config.showSplashScreen);
+ xml.tag("canvasShowPartType", config.canvasShowPartType);
+ xml.tag("canvasShowPartEvent", config.canvasShowPartEvent);
+ xml.tag("canvasShowGrid", config.canvasShowGrid);
+ xml.tag("canvasUsePixmap", config.canvasUseBgPixmap);
+ xml.tag("canvasBgPixmap", config.canvasBgPixmap);
+
+ xml.tag("bigtimeForegroundcolor", config.bigTimeForegroundColor);
+ xml.tag("bigtimeBackgroundcolor", config.bigTimeBackgroundColor);
+
+ writeShortCuts(xml);
+ midiRCList.write(xml);
+ xml.tag("followMode", TimeCanvas::followMode);
+
+ xml.tag("defaultMidiInputDevice", config.defaultMidiInputDevice);
+ xml.tag("defaultMidiOutputDevice", config.defaultMidiOutputDevice);
+ xml.tag("defaultMidiInstrument", config.defaultMidiInstrument);
+ xml.tag("connectToAllMidiDevices", config.connectToAllMidiDevices);
+ xml.tag("connectToAllMidiTracks", config.connectToAllMidiTracks);
+ xml.tag("createDefaultMidiInput", config.createDefaultMidiInput);
+ xml.tag("projectPath", config.projectPath);
+ xml.tag("templatePath", config.templatePath);
+ xml.tag("instrumentPath", config.instrumentPath);
+ xml.tag("importMidiPath", config.importMidiPath);
+ xml.tag("importWavePath", config.importWavePath);
+
+ PianoRoll::writeConfiguration(xml);
+ DrumEdit::writeConfiguration(xml);
+ xml.etag("configuration");
+ }
+
+//---------------------------------------------------------
+// writeConfiguration
+// write song specific configuration
+//---------------------------------------------------------
+
+void MusE::writeConfiguration(Xml& xml) const
+ {
+ xml.stag("configuration");
+
+ xml.tag("mtctype", AL::mtcType);
+ xml.stag("mtcoffset");
+ xml.put(QString("%1:%2:%3:%4:%5")
+ .arg(mtcOffset.h()).arg(mtcOffset.m()).arg(mtcOffset.s())
+ .arg(mtcOffset.f()).arg(mtcOffset.sf()));
+ xml.etag("mtcoffset");
+ xml.tag("extSync", extSyncFlag);
+ xml.tag("genMTCSync", genMTCSync);
+ xml.tag("genMCSync", genMCSync);
+ xml.tag("genMMC", genMMC);
+ xml.tag("acceptMTC", acceptMTC);
+ xml.tag("acceptMMC", acceptMMC);
+ xml.tag("acceptMC", acceptMC);
+
+ xml.tag("bigtimeVisible", bt_id->isChecked());
+ xml.tag("transportVisible", tr_id->isChecked());
+
+ if (transport)
+ xml.tag("geometryTransport", transport);
+ if (bigtime)
+ xml.tag("geometryBigTime", bigtime);
+
+ xml.tag("mixer1Visible", aid1a->isChecked());
+ xml.tag("mixer2Visible", aid1b->isChecked());
+ if (mixer1)
+ mixer1->write(xml, "mixer1");
+ if (mixer2)
+ mixer2->write(xml, "mixer2");
+
+ xml.etag("configuration");
+ }
+
+//---------------------------------------------------------
+// configMidiSync
+//---------------------------------------------------------
+
+void MusE::configMidiSync()
+ {
+ if (!midiSyncConfig) {
+ midiSyncConfig = new MidiSyncConfig(this);
+ connect(midiSyncConfig, SIGNAL(syncChanged()), SLOT(syncChanged()));
+ }
+ midiSyncConfig->raise();
+ midiSyncConfig->show();
+ }
+
+//---------------------------------------------------------
+// syncChanged
+//---------------------------------------------------------
+
+void MusE::syncChanged()
+ {
+ transport->syncChanged();
+ }
+
+//---------------------------------------------------------
+// configMidiFile
+//---------------------------------------------------------
+
+void MusE::configMidiFile()
+ {
+ if (!midiFileConfig)
+ midiFileConfig = new MidiFileConfig();
+ midiFileConfig->updateValues();
+
+ if (midiFileConfig->isVisible()) {
+ midiFileConfig->raise();
+//TD midiFileConfig->setActiveWindow();
+ }
+ else
+ midiFileConfig->show();
+ }
+
+//---------------------------------------------------------
+// MidiFileConfig
+// config properties of exported midi files
+//---------------------------------------------------------
+
+MidiFileConfig::MidiFileConfig()
+ : ConfigMidiFileBase()
+ {
+ setupUi(this);
+ connect(buttonOk, SIGNAL(clicked()), SLOT(okClicked()));
+ connect(buttonCancel, SIGNAL(clicked()), SLOT(cancelClicked()));
+ }
+
+//---------------------------------------------------------
+// updateValues
+//---------------------------------------------------------
+
+void MidiFileConfig::updateValues()
+ {
+ int divisionIdx = 2;
+ switch(config.midiDivision) {
+ case 96: divisionIdx = 0; break;
+ case 192: divisionIdx = 1; break;
+ case 384: divisionIdx = 2; break;
+ }
+ divisionCombo->setCurrentIndex(divisionIdx);
+ formatCombo->setCurrentIndex(config.smfFormat);
+ extendedFormat->setChecked(config.extendedMidi);
+ copyrightEdit->setText(config.copyright);
+ }
+
+//---------------------------------------------------------
+// okClicked
+//---------------------------------------------------------
+
+void MidiFileConfig::okClicked()
+ {
+ int divisionIdx = divisionCombo->currentIndex();
+
+ int divisions[3] = { 96, 192, 384 };
+ if (divisionIdx >= 0 && divisionIdx < 3)
+ config.midiDivision = divisions[divisionIdx];
+ config.extendedMidi = extendedFormat->isChecked();
+ config.smfFormat = formatCombo->currentIndex();
+ config.copyright = copyrightEdit->text();
+
+ muse->changeConfig(true); // write config file
+ close();
+ }
+
+//---------------------------------------------------------
+// cancelClicked
+//---------------------------------------------------------
+
+void MidiFileConfig::cancelClicked()
+ {
+ close();
+ }
+
+//---------------------------------------------------------
+// configGlobalSettings
+//---------------------------------------------------------
+
+//void MusE::configGlobalSettings()
+// {
+// if (!globalSettingsConfig)
+// globalSettingsConfig = new GlobalSettingsConfig();
+//
+// if (globalSettingsConfig->isVisible()) {
+// globalSettingsConfig->raise();
+////TD globalSettingsConfig->setActiveWindow();
+// }
+// else
+// globalSettingsConfig->show();
+// }
+
+//---------------------------------------------------------
+// write
+//---------------------------------------------------------
+
+void MixerConfig::write(Xml& xml, const char* name)
+ {
+ xml.stag(QString(name));
+ xml.tag("geometry", geometry);
+ xml.tag("showMidiTracks", showMidiTracks);
+ xml.tag("showMidiSyntiPorts", showMidiSyntiPorts);
+ xml.tag("showMidiTracks", showMidiTracks);
+ xml.tag("showOutputTracks", showOutputTracks);
+ xml.tag("showWaveTracks", showWaveTracks);
+ xml.tag("showGroupTracks", showGroupTracks);
+ xml.tag("showInputTracks", showInputTracks);
+ xml.tag("showAuxTracks", showAuxTracks);
+ xml.tag("showSyntiTracks", showSyntiTracks);
+ xml.tag("showMidiInPorts", showMidiInPorts);
+ xml.tag("showMidiOutPorts", showMidiOutPorts);
+ xml.etag(name);
+ }
+
+//---------------------------------------------------------
+// read
+//---------------------------------------------------------
+
+void MixerConfig::read(QDomNode node)
+ {
+ for (node = node.firstChild(); !node.isNull(); node = node.nextSibling()) {
+ QDomElement e = node.toElement();
+ QString tag(e.tagName());
+ QString s = e.text();
+ int i = s.toInt();
+ if (tag == "geometry")
+ geometry = AL::readGeometry(node);
+ else if (tag == "showMidiTracks")
+ showMidiTracks = i;
+ else if (tag == "showMidiSyntiPorts")
+ showMidiSyntiPorts = i;
+ else if (tag == "showOutputTracks")
+ showOutputTracks = i;
+ else if (tag == "showWaveTracks")
+ showWaveTracks = i;
+ else if (tag == "showGroupTracks")
+ showGroupTracks = i;
+ else if (tag == "showInputTracks")
+ showInputTracks = i;
+ else if (tag == "showAuxTracks")
+ showAuxTracks = i;
+ else if (tag == "showSyntiTracks")
+ showSyntiTracks = i;
+ else if (tag == "showMidiInPorts")
+ showMidiInPorts = i;
+ else if (tag == "showMidiOutPorts")
+ showMidiOutPorts = i;
+ else
+ printf("MusE:MixerConfig: unknown tag %s\n", e.tagName().toAscii().data());
+ }
+ }
+
diff --git a/muse_qt4_evolution/muse/conf.h b/muse_qt4_evolution/muse/conf.h
new file mode 100644
index 00000000..b026c080
--- /dev/null
+++ b/muse_qt4_evolution/muse/conf.h
@@ -0,0 +1,46 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __CONF_H__
+#define __CONF_H__
+
+#include "ui_configmidifile.h"
+
+//---------------------------------------------------------
+// MidiFileConfig
+// config properties of exported midi files
+//---------------------------------------------------------
+
+class MidiFileConfig : public QDialog, public Ui::ConfigMidiFileBase {
+ Q_OBJECT
+
+ private slots:
+ void okClicked();
+ void cancelClicked();
+
+ public:
+ MidiFileConfig();
+ void updateValues();
+ };
+
+extern bool readConfiguration();
+extern void readConfiguration(QDomNode);
+#endif
+
diff --git a/muse_qt4_evolution/muse/configmidifile.ui b/muse_qt4_evolution/muse/configmidifile.ui
new file mode 100644
index 00000000..ca96f3f5
--- /dev/null
+++ b/muse_qt4_evolution/muse/configmidifile.ui
@@ -0,0 +1,153 @@
+<ui version="4.0" >
+ <author></author>
+ <comment></comment>
+ <exportmacro></exportmacro>
+ <class>ConfigMidiFileBase</class>
+ <widget class="QDialog" name="ConfigMidiFileBase" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>541</width>
+ <height>280</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>MusE: Config Midi File Export</string>
+ </property>
+ <property name="sizeGripEnabled" >
+ <bool>true</bool>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>11</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="4" column="0" colspan="2" >
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonOk" >
+ <property name="text" >
+ <string>&amp;OK</string>
+ </property>
+ <property name="shortcut" >
+ <string/>
+ </property>
+ <property name="autoDefault" >
+ <bool>true</bool>
+ </property>
+ <property name="default" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonCancel" >
+ <property name="text" >
+ <string>&amp;Cancel</string>
+ </property>
+ <property name="shortcut" >
+ <string/>
+ </property>
+ <property name="autoDefault" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QComboBox" name="formatCombo" >
+ <item>
+ <property name="text" >
+ <string>0 (single track)</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>1 (multiple tracks)</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="textLabel3" >
+ <property name="text" >
+ <string>Format:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QComboBox" name="divisionCombo" >
+ <item>
+ <property name="text" >
+ <string>96</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>192</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>384</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="textLabel1" >
+ <property name="text" >
+ <string>Division:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="textLabel2" >
+ <property name="text" >
+ <string>Copyright:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" >
+ <widget class="QLineEdit" name="copyrightEdit" />
+ </item>
+ <item row="3" column="0" colspan="2" >
+ <widget class="QCheckBox" name="extendedFormat" >
+ <property name="text" >
+ <string>Enable extended smf format</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11" />
+ <pixmapfunction>qPixmapFromMimeSource</pixmapfunction>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/muse_qt4_evolution/muse/configtrack.cpp b/muse_qt4_evolution/muse/configtrack.cpp
new file mode 100644
index 00000000..a8fee6a3
--- /dev/null
+++ b/muse_qt4_evolution/muse/configtrack.cpp
@@ -0,0 +1,265 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "configtrack.h"
+#include "trelement.h"
+#include "arranger.h"
+
+//---------------------------------------------------------
+// ConfigTrackList
+//---------------------------------------------------------
+
+ConfigTrackList::ConfigTrackList(QWidget* parent)
+ : QDialog(parent)
+ {
+ setupUi(this);
+ // does not work:
+ configuredList->setSelectionMode(QAbstractItemView::SingleSelection);
+ availableList->setSelectionMode(QAbstractItemView::SingleSelection);
+
+ up->setEnabled(false);
+ down->setEnabled(false);
+ addItem->setEnabled(false);
+ removeItem->setEnabled(false);
+ dirty = false;
+ curType = 0;
+ init();
+
+ connect(trackType, SIGNAL(activated(int)), SLOT(trackTypeChanged(int)));
+ connect(availableList, SIGNAL(itemSelectionChanged()), SLOT(availableSelected()));
+ connect(configuredList, SIGNAL(itemSelectionChanged()), SLOT(configuredSelected()));
+ connect(up, SIGNAL(clicked()), SLOT(upClicked()));
+ connect(down, SIGNAL(clicked()), SLOT(downClicked()));
+ connect(addItem, SIGNAL(clicked()), SLOT(addItemClicked()));
+ connect(removeItem, SIGNAL(clicked()), SLOT(removeItemClicked()));
+ }
+
+//---------------------------------------------------------
+// init
+//---------------------------------------------------------
+
+void ConfigTrackList::init()
+ {
+ trackType->clear();
+ for (int tt = 0; tt < Track::TRACK_TYPES; ++tt) {
+ list[tt] = glist[tt];
+ trackType->addItem(Track::_clname[tt]);
+ }
+ trackTypeChanged(curType);
+ }
+
+//---------------------------------------------------------
+// done
+//---------------------------------------------------------
+
+void ConfigTrackList::done(int code)
+ {
+ if (code) {
+ // OK pressed
+ if (dirty)
+ saveTrackType();
+ for (int tt = 0; tt < Track::TRACK_TYPES; ++tt)
+ glist[tt] = list[tt];
+ emit trackConfigChanged();
+ }
+ else {
+ dirty = false;
+ init();
+ }
+ QDialog::done(code);
+ }
+
+//---------------------------------------------------------
+// saveTrackType
+//---------------------------------------------------------
+
+void ConfigTrackList::saveTrackType()
+ {
+ dirty = false;
+ list[curType].clear();
+ int gn = 0;
+ TrElementList group;
+ int n = configuredList->count();
+ for (int i = 0; i < n; ++i) {
+ QString s = configuredList->item(i)->text();
+ int k;
+ for (k = 0; k < nTrElements; ++k)
+ if (trElements[k].name == s)
+ break;
+ if (trElements[k].grp != gn) {
+ list[curType].push_back(group);
+ group.clear();
+ gn = trElements[k].grp;
+ }
+ group.push_back(&trElements[k]);
+ }
+ if (!group.empty())
+ list[curType].push_back(group);
+ }
+
+//---------------------------------------------------------
+// trackTypeChanged
+//---------------------------------------------------------
+
+void ConfigTrackList::trackTypeChanged(int type)
+ {
+ curType = type;
+ if (dirty)
+ saveTrackType();
+
+ configuredList->clear();
+ TrGroupList& gl = list[type];
+ for (iTrGroup i = gl.begin(); i != gl.end(); ++i) {
+ for (iTrElement k = i->begin(); k != i->end(); ++k)
+ configuredList->addItem((*k)->name);
+ }
+
+ availableList->clear();
+ for (int i = 0; i < nTrElements; ++i) {
+ QString name(trElements[i].name);
+ bool f = false;
+
+ // is gui element available for this track type?
+
+ for (int i = 0; i < nTrElements; ++i) {
+ const TrElement& el = trElements[i];
+ if (el.name == name) {
+ if (el.trackMask & (1 << type)) {
+ f = true;
+ break;
+ }
+ }
+ }
+ if (!f)
+ continue;
+
+ // is gui element already configured?
+
+ for (iTrGroup i = gl.begin(); i != gl.end(); ++i) {
+ for (iTrElement k = i->begin(); k != i->end(); ++k) {
+ if (name == (*k)->name) {
+ f = false;
+ break;
+ }
+ }
+ if (!f)
+ break;
+ }
+ if (f) {
+ availableList->addItem(name);
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// configuredSelected
+//---------------------------------------------------------
+
+void ConfigTrackList::configuredSelected()
+ {
+ QListWidgetItem* item = configuredList->selectedItems().at(0);
+ up->setEnabled(item != 0);
+ down->setEnabled(item != 0);
+ removeItem->setEnabled(item != 0);
+ }
+
+//---------------------------------------------------------
+// availableSelected
+//---------------------------------------------------------
+
+void ConfigTrackList::availableSelected()
+ {
+ QListWidgetItem* item = availableList->selectedItems().at(0);
+ addItem->setEnabled(item != 0);
+ }
+
+//---------------------------------------------------------
+// upClicked
+//---------------------------------------------------------
+
+void ConfigTrackList::upClicked()
+ {
+ QListWidgetItem* item = configuredList->selectedItems().at(0);
+ int n = configuredList->row(item);
+ if (n <= 0)
+ return;
+ QString s = item->text();
+ delete item;
+ configuredList->insertItem(n-1, s);
+ configuredList->setItemSelected(configuredList->item(n-1), true);
+ dirty = true;
+ }
+
+//---------------------------------------------------------
+// downClicked
+//---------------------------------------------------------
+
+void ConfigTrackList::downClicked()
+ {
+ QListWidgetItem* item = configuredList->selectedItems().at(0);
+ int n = configuredList->row(item);
+ if (n >= int(configuredList->count()-1))
+ return;
+ QString s = item->text();
+
+ delete item;
+ configuredList->insertItem(n+1, s);
+ configuredList->setItemSelected(configuredList->item(n+1), true);
+ dirty = true;
+ }
+
+//---------------------------------------------------------
+// addItemClicked
+//---------------------------------------------------------
+
+void ConfigTrackList::addItemClicked()
+ {
+ QListWidgetItem* item = availableList->selectedItems().at(0);
+ if (item == 0)
+ return;
+ QString s = item->text();
+ delete item;
+ configuredList->addItem(s);
+ configuredList->setItemSelected(configuredList->item(configuredList->count()-1), true);
+ QListWidgetItem* ci = availableList->currentItem();
+ if (ci)
+ availableList->setItemSelected(ci, true);
+ dirty = true;
+ }
+
+//---------------------------------------------------------
+// removeItemClicked
+//---------------------------------------------------------
+
+void ConfigTrackList::removeItemClicked()
+ {
+ QListWidgetItem* item = configuredList->selectedItems().at(0);
+ if (item == 0)
+ return;
+ QString s = item->text();
+ delete item;
+ availableList->addItem(s);
+ availableList->setItemSelected(availableList->item(availableList->count()-1), true);
+ QListWidgetItem* ci = configuredList->item(configuredList->currentRow());
+ if (ci)
+ configuredList->setItemSelected(ci, true);
+ dirty = true;
+ }
+
diff --git a/muse_qt4_evolution/muse/configtrack.h b/muse_qt4_evolution/muse/configtrack.h
new file mode 100644
index 00000000..47dd0f4a
--- /dev/null
+++ b/muse_qt4_evolution/muse/configtrack.h
@@ -0,0 +1,61 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __CONFIG_TRACK_H__
+#define __CONFIG_TRACK_H__
+
+#include "ui_configtrack.h"
+#include "track.h"
+#include "trelement.h"
+
+struct TrElement;
+class TrGroupList;
+
+//---------------------------------------------------------
+// ConfigTrackList
+//---------------------------------------------------------
+
+class ConfigTrackList : public QDialog, Ui::ConfigTrackListBase {
+ Q_OBJECT
+
+ TrGroupList list[Track::TRACK_TYPES];
+ void init();
+ bool dirty;
+ void saveTrackType();
+ int curType;
+
+ private slots:
+ void trackTypeChanged(int);
+ void availableSelected();
+ void configuredSelected();
+ void upClicked();
+ void downClicked();
+ void addItemClicked();
+ void removeItemClicked();
+ virtual void done(int);
+
+ signals:
+ void trackConfigChanged();
+
+ public:
+ ConfigTrackList(QWidget*);
+ };
+
+#endif
diff --git a/muse_qt4_evolution/muse/configtrack.ui b/muse_qt4_evolution/muse/configtrack.ui
new file mode 100644
index 00000000..350b405a
--- /dev/null
+++ b/muse_qt4_evolution/muse/configtrack.ui
@@ -0,0 +1,299 @@
+<ui version="4.0" >
+ <author></author>
+ <comment></comment>
+ <exportmacro></exportmacro>
+ <class>ConfigTrackListBase</class>
+ <widget class="QDialog" name="ConfigTrackListBase" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>545</width>
+ <height>352</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>MusE: Config Track List</string>
+ </property>
+ <property name="sizeGripEnabled" >
+ <bool>true</bool>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>11</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="textLabel1" >
+ <property name="text" >
+ <string>Track Type:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="trackType" />
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="textLabel2" >
+ <property name="text" >
+ <string>Available Items:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QListWidget" name="availableList" >
+ <property name="selectionBehavior" >
+ <enum>QAbstractItemView::SelectRows</enum>
+ </property>
+ <property name="modelColumn" >
+ <number>0</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="addItem" >
+ <property name="text" >
+ <string>Add</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="removeItem" >
+ <property name="text" >
+ <string>Remove</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="up" >
+ <property name="text" >
+ <string>Up</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="down" >
+ <property name="text" >
+ <string>Down</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="textLabel3" >
+ <property name="text" >
+ <string>Configured Items</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QListWidget" name="configuredList" >
+ <property name="selectionBehavior" >
+ <enum>QAbstractItemView::SelectRows</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="ok" >
+ <property name="text" >
+ <string>&amp;OK</string>
+ </property>
+ <property name="shortcut" >
+ <string/>
+ </property>
+ <property name="autoDefault" >
+ <bool>true</bool>
+ </property>
+ <property name="default" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="cancel" >
+ <property name="text" >
+ <string>&amp;Cancel</string>
+ </property>
+ <property name="shortcut" >
+ <string/>
+ </property>
+ <property name="autoDefault" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11" />
+ <pixmapfunction>qPixmapFromMimeSource</pixmapfunction>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>ok</sender>
+ <signal>clicked()</signal>
+ <receiver>ConfigTrackListBase</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>393</x>
+ <y>321</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>259</x>
+ <y>326</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>cancel</sender>
+ <signal>clicked()</signal>
+ <receiver>ConfigTrackListBase</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>484</x>
+ <y>327</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>437</x>
+ <y>283</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/muse_qt4_evolution/muse/ctrl.cpp b/muse_qt4_evolution/muse/ctrl.cpp
new file mode 100644
index 00000000..82e8efef
--- /dev/null
+++ b/muse_qt4_evolution/muse/ctrl.cpp
@@ -0,0 +1,450 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "fastlog.h"
+#include "globals.h"
+#include "ctrl.h"
+#include "al/xml.h"
+#include "midictrl.h"
+
+//---------------------------------------------------------
+// Ctrl
+//---------------------------------------------------------
+
+Ctrl::Ctrl(int id, const QString& s, int t)
+ : _id(id), _name(s), _type(t)
+ {
+ setRange(.0f, 1.f);
+ _default.f = 0.0f;
+ _curVal.f = 0.0f;
+ _touched = false;
+ _changed = false;
+ _moveWithPart = false;
+ }
+
+Ctrl::Ctrl(int id, const QString& s, int t, float a, float b)
+ : _id(id), _name(s), _type(t)
+ {
+ if (_type & INT)
+ setRange(int(a), int(b));
+ else
+ setRange(a, b);
+ _default.f = 0.0f;
+ _curVal.f = 0.0f;
+ _touched = false;
+ _changed = false;
+ _moveWithPart = false;
+ }
+
+Ctrl::Ctrl()
+ {
+ _type = INTERPOLATE;
+ setRange(0.0f, 1.0f);
+ _id = 0;
+ _default.f = 0.0f;
+ _curVal.f = 0.0f;
+ _touched = false;
+ _changed = false;
+ _moveWithPart = false;
+ }
+
+Ctrl::Ctrl(const MidiController* mc)
+ {
+ _type = DISCRETE | INT;
+ setRange(mc->minVal(), mc->maxVal());
+ _id = mc->num();
+ _default.i = mc->initVal();
+ _curVal.i = CTRL_VAL_UNKNOWN;
+ _name = mc->name();
+ _touched = false;
+ _changed = false;
+ _moveWithPart = false;
+ }
+
+//---------------------------------------------------------
+// value
+//---------------------------------------------------------
+
+CVal Ctrl::value(unsigned time)
+ {
+ CVal rv;
+
+ if (empty() || _touched)
+ return _curVal;
+ if (_type & DISCRETE) {
+ //
+ // midi controller
+ //
+ ciCtrlVal i = upperBound(time);
+ if (i == end()) {
+ --i;
+ rv = i.value();
+ }
+ else if (i == begin()) {
+ if (i.key() == time)
+ rv = i.value();
+ else
+ return _curVal;
+ }
+ else {
+ --i;
+ rv = i.value();
+ }
+ }
+ else {
+ //
+ // linear interpolated audio
+ // controller
+ //
+ ciCtrlVal i = upperBound(time);
+ if (i == end()) {
+ --i;
+ rv = i.value();
+ }
+ else {
+ int frame2 = i.key();
+ CVal val2 = i.value();
+ int frame1;
+ CVal val1;
+ if (i == begin()) {
+ rv = val2;
+ }
+ else {
+ --i;
+ frame1 = i.key();
+ val1 = i.value();
+ time -= frame1;
+ frame2 -= frame1;
+ if (_type & INT) {
+ val2.i -= val1.i;
+ rv.i = val1.i + (time * val2.i)/frame2;
+ }
+ else {
+ val2.f -= val1.f;
+ rv.f = val1.f + (time * val2.f)/frame2;
+ }
+ }
+ }
+ }
+ if (_type & LOG) {
+ if (rv.f <= -1000.0f)
+ rv.f = 0.0f;
+ else
+ rv.f = pow(10.0f, rv.f);
+ }
+ return rv;
+ }
+
+//---------------------------------------------------------
+// add
+// return true if new value added
+//---------------------------------------------------------
+
+bool Ctrl::add(unsigned frame, CVal val)
+ {
+ if (_type & LOG) {
+ if (val.f <= 0.0)
+ val.f = -1001.0f;
+ else
+ val.f = log10(val.f);
+ }
+ bool rv = find(frame) == end();
+ insert(frame, val);
+ return rv;
+ }
+
+//---------------------------------------------------------
+// del
+//---------------------------------------------------------
+
+void Ctrl::del(unsigned frame)
+ {
+ iCtrlVal e = find(frame);
+ erase(e);
+ }
+
+//---------------------------------------------------------
+// read
+//---------------------------------------------------------
+
+void Ctrl::read(QDomNode node, bool)
+ {
+ QDomElement e = node.toElement();
+ _id = e.attribute("id").toInt();
+ _name = e.attribute("name");
+ _type = e.attribute("type","0").toInt();
+
+ const char* minS = "0.0f";
+ const char* maxS = "1.0f";
+
+ if (_type & INT) {
+ minS = "0";
+ maxS = "127";
+ _curVal.i = e.attribute("cur","-1").toInt();
+ _default.i = e.attribute("default","-1").toInt();
+ }
+ else {
+ if (_id == AC_PAN) {
+ minS = "-1.0f";
+ maxS = "+1.0f";
+ }
+ _curVal.f = e.attribute("cur","0.0").toFloat();
+ _default.f = e.attribute("default","0.0").toFloat();
+ }
+ setCurVal(_curVal);
+ if (_type & INT) {
+ min.i = e.attribute("min", minS).toInt();
+ max.i = e.attribute("max", maxS).toInt();
+ }
+ else {
+ min.f = e.attribute("min", minS).toFloat();
+ max.f = e.attribute("max", maxS).toFloat();
+ }
+
+ QStringList vp = e.text().simplified().split(",", QString::SkipEmptyParts);
+ int n = vp.size();
+ for (int i = 0; i < n; ++i) {
+ QStringList sl = vp.at(i).simplified().split(" ");
+ bool ok;
+ int frame = sl.at(0).toInt(&ok, 0);
+ if (!ok) {
+ printf("Ctrl::read(1): conversion <%s><%s> to int failed\n",
+ vp.at(i).simplified().toAscii().data(),
+ sl.at(0).toAscii().data());
+ break;
+ }
+ CVal val;
+ if (_type & INT)
+ val.i = sl.at(1).toInt(&ok, 0);
+ else
+ val.f = sl.at(1).toDouble(&ok);
+ if (!ok) {
+ printf("Ctrl::read(2): conversion <%s><%s> failed\n",
+ vp.at(i).simplified().toAscii().data(),
+ sl.at(1).toAscii().data());
+ break;
+ }
+ add(frame, val);
+ }
+ }
+
+//---------------------------------------------------------
+// add
+//---------------------------------------------------------
+
+void CtrlList::add(Ctrl* vl)
+ {
+ insert(std::pair<const int, Ctrl*>(vl->id(), vl));
+ }
+
+//---------------------------------------------------------
+// write
+//---------------------------------------------------------
+
+void Ctrl::write(Xml& xml)
+ {
+ QString s("controller id=\"%1\" name=\"%2\" cur=\"%3\" type=\"%4\" min=\"%5\" max=\"%6\" default=\"%7\"");
+
+ QString cn = Xml::xmlString(_name);
+
+ if (empty()) {
+ if (_type & INT)
+ xml.tagE(s.arg(id()).arg(cn).arg(curVal().i).arg(_type).arg(min.i).arg(max.i).arg(_default.i).toAscii().data());
+ else
+ xml.tagE(s.arg(id()).arg(cn).arg(curVal().f).arg(_type).arg(min.f).arg(max.f).arg(_default.f).toAscii().data());
+ return;
+ }
+ if (_type & INT)
+ xml.stag(s.arg(id()).arg(cn).arg(curVal().i).arg(_type).arg(min.i).arg(max.i).arg(_default.i).toAscii().data());
+ else
+ xml.stag(s.arg(id()).arg(cn).arg(curVal().f).arg(_type).arg(min.f).arg(max.f).arg(_default.f).toAscii().data());
+
+ int i = 0;
+ for (ciCtrlVal ic = begin(); ic != end(); ++ic) {
+ if (i == 0)
+ xml.putLevel();
+ int time = ic.key();
+ CVal val = ic.value();
+ if (_type & LOG)
+ val.f = (val.f <= -1000.0) ? 0.0f : pow(10.0f, val.f);
+ if (_type & INT) {
+ xml << time << ' ' << val.i << ',';
+ }
+ else
+ xml << time << ' ' << val.f << ',';
+ ++i;
+ if (i >= 4) {
+ xml << endl;
+ i = 0;
+ }
+ }
+ if (i)
+ xml << endl;
+ xml.etag("controller");
+ }
+
+//---------------------------------------------------------
+// val2pixelR
+// input val is "raw" data
+//---------------------------------------------------------
+
+int Ctrl::val2pixelR(CVal val, int maxpixel)
+ {
+ maxpixel -= 1;
+ if (_type & INT)
+ return maxpixel - ((maxpixel * (val.i - min.i) + (max.i-min.i)/2) / (max.i - min.i));
+ else {
+ if ((_type & LOG) && (val.f <= -1000.0f))
+ return maxpixel;
+ int pixel = maxpixel - lrint(double(maxpixel) * (val.f - min.f) / (max.f-min.f));
+ if (pixel < 0) {
+ printf("%d - lrint(double(%d) * (%f - %f)/(%f-%f)\n",
+ maxpixel, maxpixel, val.f, min.f, max.f, min.f);
+ printf(" %f/%f = %f\n",
+ val.f-min.f, max.f-min.f, (val.f-min.f)/(max.f-min.f));
+ }
+ return pixel;
+// return maxpixel - lrint(double(maxpixel) * (val.f - min.f) / (max.f-min.f));
+ }
+ }
+
+int Ctrl::val2pixelR(int val, int maxpixel)
+ {
+ maxpixel -= 1;
+ int range = max.i - min.i;
+ return maxpixel - ((maxpixel * (val - min.i) + range / 2) / range);
+ }
+
+//---------------------------------------------------------
+// cur2pixel
+//---------------------------------------------------------
+
+int Ctrl::cur2pixel(int maxpixel)
+ {
+#if 0
+ return val2pixelR(_curVal, maxpixel);
+#else
+ maxpixel -= 1;
+
+ if (_type & INT)
+ return maxpixel - ((maxpixel * (_curVal.i - min.i) + (max.i-min.i)/2) / (max.i - min.i));
+ float f = _curVal.f;
+ if (_type & LOG) {
+ if (f <= 0.0)
+ return maxpixel;
+ else
+ f = fast_log10(f);
+ }
+ return maxpixel - lrint(double(maxpixel) * (f - min.f) / (max.f-min.f));
+#endif
+ }
+
+//---------------------------------------------------------
+// pixel2val
+//---------------------------------------------------------
+
+CVal Ctrl::pixel2val(int pixel, int maxpixel)
+ {
+ maxpixel -= 1;
+ pixel = maxpixel - pixel;
+
+// printf("pixel2val %d(%d) int %d, min %d, max %d\n",
+// pixel, maxpixel, _type & INT, min.i, max.i);
+ CVal rv;
+ if (_type & INT) {
+ rv.i = (pixel * (max.i - min.i) + (maxpixel+min.i)/2) / maxpixel + min.i;
+ if (rv.i < min.i)
+ rv.i = min.i;
+ else if (rv.i > max.i)
+ rv.i = max.i;
+ }
+ else {
+ rv.f = double(pixel) * (max.f - min.f) / double(maxpixel) + min.f;
+ if (rv.f < min.f)
+ rv.f = min.f;
+ else if (rv.f > max.f)
+ rv.f = max.f;
+ if (_type & LOG)
+ rv.f = pow(10.0f, rv.f);
+ }
+ return rv;
+ }
+
+//---------------------------------------------------------
+// pixel2valR
+//---------------------------------------------------------
+
+CVal Ctrl::pixel2valR(int pixel, int maxpixel)
+ {
+ maxpixel -= 1;
+ pixel = maxpixel - pixel;
+
+// printf("pixel2val %d(%d) int %d, min %d, max %d\n",
+// pixel, maxpixel, _type & INT, min.i, max.i);
+ CVal rv;
+ if (_type & INT) {
+ rv.i = (pixel * (max.i - min.i) + (maxpixel+min.i)/2) / maxpixel + min.i;
+ if (rv.i < min.i)
+ rv.i = min.i;
+ else if (rv.i > max.i)
+ rv.i = max.i;
+ }
+ else {
+ rv.f = double(pixel) * (max.f - min.f) / double(maxpixel) + min.f;
+ if (rv.f < min.f)
+ rv.f = min.f;
+ else if (rv.f > max.f)
+ rv.f = max.f;
+ }
+ return rv;
+ }
+
+//---------------------------------------------------------
+// setRange
+//---------------------------------------------------------
+
+void Ctrl::setRange(double _min, double _max)
+ {
+ if (_type & LOG) {
+ min.f = log10(_min);
+ max.f = log10(_max);
+ }
+ else {
+ min.f = _min;
+ max.f = _max;
+ }
+ }
+
+void Ctrl::setRange(int _min, int _max)
+ {
+ min.i = _min;
+ max.i = _max;
+ }
+
+//---------------------------------------------------------
+// setRange
+//---------------------------------------------------------
+
+void Ctrl::setRange(CVal mi, CVal ma)
+ {
+ min = mi;
+ max = ma;
+ }
+
diff --git a/muse_qt4_evolution/muse/ctrl.h b/muse_qt4_evolution/muse/ctrl.h
new file mode 100644
index 00000000..eccd17c0
--- /dev/null
+++ b/muse_qt4_evolution/muse/ctrl.h
@@ -0,0 +1,236 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __CTRL_H__
+#define __CTRL_H__
+
+namespace AL {
+ class Xml;
+ };
+using AL::Xml;
+
+class MidiController;
+
+//
+// predefined audio controller id's:
+//
+const int NUM_AUX = 32; // max number of aux channels
+
+const int AC_VOLUME = 0;
+const int AC_PAN = 1;
+const int AC_MUTE = 2;
+const int AC_AUX = 3; // 3 -- 3+NUM_AUX
+const int AC_AUX_PAN = AC_AUX + NUM_AUX;
+
+const int CTRL_PLUGIN_MASK = 0x3ff0000;
+const int CTRL_PLUGIN_OFFSET = 0x10000;
+const int CTRL_INDEX_MASK = 0xffff;
+const int CTRL_PREFADER = 0x40000000;
+
+//---------------------------------------------------------
+// genACnum
+// create a controller number out of plugin index,
+// controller index and prefader flag
+//---------------------------------------------------------
+
+inline static int genACnum(int plugin, int ctrl, bool prefader) {
+ int pre = prefader ? CTRL_PREFADER : 0;
+ return pre | ((plugin+1) * CTRL_PLUGIN_OFFSET + ctrl);
+ }
+
+//---------------------------------------------------------
+// getCtrlPlugin
+// destill plugin index, controller index and prefader
+// flag from controller id
+//---------------------------------------------------------
+
+inline static void getCtrlPlugin(int id, bool* prefader, int* pluginIndex,
+ int* ctrlIndex) {
+ *prefader = (id & CTRL_PREFADER) ? true : false;
+ *pluginIndex = ((id & CTRL_PLUGIN_MASK) / CTRL_PLUGIN_OFFSET) - 1;
+ *ctrlIndex = id & CTRL_INDEX_MASK;
+ }
+
+//---------------------------------------------------------
+// ControllerName
+//---------------------------------------------------------
+
+struct ControllerName {
+ QString name;
+ int id;
+ ControllerName(const QString& s, int i) : name(s), id(i) {}
+ };
+
+typedef std::vector<ControllerName> ControllerNameList;
+typedef ControllerNameList::iterator iControllerName;
+typedef ControllerNameList::const_iterator ciControllerName;
+
+//---------------------------------------------------------
+// CVal
+// Controller value, either float for audio or
+// int for midi.
+//
+//---------------------------------------------------------
+
+struct CVal {
+ union {
+ float f;
+ int i;
+ };
+ };
+
+//---------------------------------------------------------
+// CtrlVal
+// This structure represents a controller event. Time
+// is a midi tick value or a frame value depending on
+// then containing controller list Ctrl
+//---------------------------------------------------------
+
+struct CtrlVal {
+ int time;
+ CVal val;
+ CtrlVal(int f, CVal v) {
+ time = f;
+ val = v;
+ }
+ CtrlVal(int f) {
+ time = f;
+ }
+ };
+
+//---------------------------------------------------------
+// CtrlRecVal
+// recorded controller event, mixer automation
+//---------------------------------------------------------
+
+struct CtrlRecVal : public CtrlVal {
+ int id;
+ int type; // 0 - ctrlVal, 1 - start, 2 - end
+ CtrlRecVal(int f, int n, CVal v) : CtrlVal(f, v), id(n), type(0) {}
+ CtrlRecVal(int f, int n, int t) : CtrlVal(f), id(n), type(t) {}
+ };
+
+//---------------------------------------------------------
+// CtrlRecList
+//---------------------------------------------------------
+
+class CtrlRecList : public std::list<CtrlRecVal> {
+ public:
+ };
+
+typedef CtrlRecList::iterator iCtrlRec;
+
+typedef QMap<unsigned, CVal> CTRL;
+typedef CTRL::iterator iCtrlVal;
+typedef CTRL::const_iterator ciCtrlVal;
+
+//---------------------------------------------------------
+// Ctrl
+// this is a controller list
+//
+// CtrlType == LOG
+// values are internally represented as log10(value)
+//---------------------------------------------------------
+
+class Ctrl : public CTRL {
+ public:
+ enum CtrlType {
+ INTERPOLATE = 0, // values are linear interpolated
+ DISCRETE = 1, // midi controller events
+ LINEAR = 0,
+ LOG = 2,
+ INT = 4
+ };
+
+ private:
+ int _id;
+ QString _name;
+ int _type; // bitmask of CtrlType
+ CVal _default;
+ CVal _curVal; // used to optimize controller events
+ CVal min, max;
+ bool _changed;
+ bool _touched;
+ bool _moveWithPart;
+
+ public:
+ Ctrl();
+ Ctrl(const MidiController*);
+ Ctrl(int id, const QString& name, int t=INTERPOLATE);
+ Ctrl(int id, const QString& name, int t, float a, float b);
+ int type() const { return _type; }
+ void setType(int t) { _type = t; }
+
+ const CVal& getDefault() const { return _default; }
+ void setDefault(float val) { _default.f = val; }
+ void setDefault(CVal val) { _default = val; }
+ void setDefault(int val) { _default.i = val; }
+
+ const CVal& curVal() const { return _curVal; }
+ void setCurVal(CVal v) { _curVal = v; _changed = true; }
+ void setCurVal(float v) { _curVal.f = v; _changed = true; }
+ void setCurVal(int v) { _curVal.i = v; _changed = true; }
+
+ int id() const { return _id; }
+ void setId(int i) { _id = i; }
+ QString name() const { return _name; }
+ void setName(const QString& s) { _name = s; }
+ CVal value(unsigned);
+ bool add(unsigned, CVal);
+ void del(unsigned);
+ void setChanged(bool val) { _changed = val; }
+ bool changed() const { return _changed; }
+ void setTouched(bool val) { _touched = val; }
+ bool touched() const { return _touched; }
+ void setRange(double min, double max);
+ void setRange(int min, int max);
+ void setRange(CVal, CVal);
+ CVal minVal() const { return min; }
+ CVal maxVal() const { return max; }
+ bool moveWithPart() const { return _moveWithPart; }
+ void setMoveWithPart(bool v) { _moveWithPart = v; }
+
+ void read(QDomNode node, bool midi);
+ void write(Xml&);
+ int val2pixelR(CVal, int maxpixel);
+ int cur2pixel(int maxpixel);
+ int val2pixelR(int, int maxpixel);
+ CVal pixel2val(int pixel, int maxpixel);
+ CVal pixel2valR(int pixel, int maxpixel);
+ };
+
+//---------------------------------------------------------
+// CtrlList
+// List of controller value lists.
+// This list represents the controller state of a
+// mixer strip
+//---------------------------------------------------------
+
+typedef std::map<unsigned, Ctrl*, std::less<unsigned> > CLIST;
+typedef CLIST::iterator iCtrl;
+typedef CLIST::const_iterator ciCtrl;
+
+class CtrlList : public CLIST {
+ public:
+ void add(Ctrl* vl);
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/ctrl/CMakeLists.txt b/muse_qt4_evolution/muse/ctrl/CMakeLists.txt
new file mode 100644
index 00000000..0bdb5be6
--- /dev/null
+++ b/muse_qt4_evolution/muse/ctrl/CMakeLists.txt
@@ -0,0 +1,46 @@
+#=============================================================================
+# MusE
+# Linux Music Editor
+# $Id:$
+#
+# Copyright (C) 2002-2006 by Werner Schweer and others
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#=============================================================================
+
+QT4_WRAP_CPP (ctrl_mocs
+ configmidictrl.h
+ definemidictrl.h
+ ctrldialog.h
+ ctrledit.h
+ )
+
+QT4_WRAP_UI (ctrl_ui_headers
+ configmidictrl.ui
+ definemidictrl.ui
+ ctrldialog.ui
+ )
+
+add_library ( ctrl STATIC
+ configmidictrl.cpp
+ definemidictrl.cpp
+ ctrldialog.cpp
+ ctrleditor.cpp
+ ctrledit.cpp
+ ${ctrl_mocs}
+ ${ctrl_ui_headers}
+ )
+set_target_properties( ctrl
+ PROPERTIES COMPILE_FLAGS "-include ${PROJECT_BINARY_DIR}/all.h"
+ )
+
diff --git a/muse_qt4_evolution/muse/ctrl/configmidictrl.cpp b/muse_qt4_evolution/muse/ctrl/configmidictrl.cpp
new file mode 100644
index 00000000..395518a8
--- /dev/null
+++ b/muse_qt4_evolution/muse/ctrl/configmidictrl.cpp
@@ -0,0 +1,202 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "configmidictrl.h"
+#include "definemidictrl.h"
+#include "miditrack.h"
+#include "midioutport.h"
+#include "midictrl.h"
+#include "midiout.h"
+#include "instruments/minstrument.h"
+
+//---------------------------------------------------------
+// ConfigMidiCtrl
+//---------------------------------------------------------
+
+ConfigMidiCtrl::ConfigMidiCtrl(MidiTrack* t)
+ {
+ setupUi(this);
+ track = t;
+
+ //---------------------------------------------------
+ // populate list of managed controllers
+ //---------------------------------------------------
+
+ ControllerNameList* cn = track->controllerNames();
+ for (iControllerName i = cn->begin(); i != cn->end(); ++i)
+ managedController->addItem(i->name);
+
+ //---------------------------------------------------
+ // populate list of available controllers
+ //---------------------------------------------------
+
+ if (track->type() == Track::MIDI) {
+ MidiTrack* mc = (MidiTrack*)track;
+ portName->setText(track->name());
+ instrumentName->setText(mc->instrument()->iname());
+ //
+ // populate popup with all controllers available for
+ // current instrument
+ //
+ MidiControllerList* mcl = mc->instrument()->controller();
+ for (iMidiController ci = mcl->begin(); ci != mcl->end(); ++ci) {
+ iControllerName i;
+ for (i = cn->begin(); i != cn->end(); ++i) {
+ if (i->name == (*ci)->name())
+ break;
+ }
+ if (i == cn->end())
+ availableController->addItem((*ci)->name());
+ }
+ }
+
+ delete cn;
+ buttonAdd->setEnabled(false);
+ buttonRemove->setEnabled(false);
+
+ connect(buttonAdd, SIGNAL(clicked()), SLOT(addClicked()));
+ connect(buttonRemove, SIGNAL(clicked()), SLOT(removeClicked()));
+ connect(availableController, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), SLOT(availableSelected(QListWidgetItem*)));
+ connect(managedController, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), SLOT(managedSelected(QListWidgetItem*)));
+ connect(defineButton, SIGNAL(clicked()), SLOT(defineClicked()));
+ }
+
+//---------------------------------------------------------
+// addClicked
+//---------------------------------------------------------
+
+void ConfigMidiCtrl::addClicked()
+ {
+ QListWidgetItem* n = availableController->currentItem();
+ if (n == 0)
+ return;
+ QString s(n->text());
+ for (int i = 0; i < managedController->count(); ++i) {
+ if (s == managedController->item(i)->text())
+ return;
+ }
+ managedController->addItem(s);
+ managedController->setCurrentItem(managedController->item(managedController->count()-1));
+ delete n;
+ buttonAdd->setEnabled(false);
+ }
+
+//---------------------------------------------------------
+// removeClicked
+//---------------------------------------------------------
+
+void ConfigMidiCtrl::removeClicked()
+ {
+ QListWidgetItem* n = managedController->currentItem();
+ if (n == 0)
+ return;
+ availableController->addItem(n->text());
+ delete n;
+ buttonRemove->setEnabled(false);
+ }
+
+//---------------------------------------------------------
+// availableSelected
+//---------------------------------------------------------
+
+void ConfigMidiCtrl::availableSelected(QListWidgetItem* item)
+ {
+ buttonAdd->setEnabled(item != 0);
+ }
+
+//---------------------------------------------------------
+// managedSelected
+//---------------------------------------------------------
+
+void ConfigMidiCtrl::managedSelected(QListWidgetItem* item)
+ {
+ buttonRemove->setEnabled(item != 0);
+ }
+
+//---------------------------------------------------------
+// done
+//---------------------------------------------------------
+
+void ConfigMidiCtrl::done(int code)
+ {
+ if (!code) {
+ QDialog::done(code);
+ return;
+ }
+ if (track->type() == Track::MIDI) {
+ ControllerNameList* cn = track->controllerNames();
+ MidiInstrument* instr = track->instrument();
+ MidiControllerList* mcl = instr->controller();
+
+ //
+ // search for new, added controller
+ //
+ int n = managedController->count();
+ for (int i = 0; i < n; ++i) {
+ QString name(managedController->item(i)->text());
+ iControllerName ii = cn->begin();
+ for (; ii != cn->end(); ++ii) {
+ if (ii->name == name)
+ break;
+ }
+ if (ii == cn->end()) {
+ // add controller "name" to list of managed controller
+ //
+ for (iMidiController ci = mcl->begin(); ci != mcl->end(); ++ci) {
+ if ((*ci)->name() == name) {
+ Ctrl* ctrl = new Ctrl(*ci);
+ track->addController(ctrl);
+ break;
+ }
+ }
+ }
+ }
+
+ //
+ // search for removed controller
+ //
+ for (iControllerName ii = cn->begin(); ii != cn->end(); ++ii) {
+ int i;
+ for (i = 0; i < n; ++i) {
+ if (managedController->item(i)->text() == ii->name)
+ break;
+ }
+ if (i == n)
+ track->removeController(ii->id);
+ }
+ delete cn;
+ }
+ QDialog::done(code);
+ }
+
+//---------------------------------------------------------
+// defineClicked
+//---------------------------------------------------------
+
+void ConfigMidiCtrl::defineClicked()
+ {
+ DefineMidiCtrl dc(track, this);
+ if (dc.exec()) {
+ Ctrl* ctrl = new Ctrl(dc.midiController());
+ track->addController(ctrl);
+ QDialog::done(0);
+ }
+ }
+
diff --git a/muse_qt4_evolution/muse/ctrl/configmidictrl.h b/muse_qt4_evolution/muse/ctrl/configmidictrl.h
new file mode 100644
index 00000000..0af11e36
--- /dev/null
+++ b/muse_qt4_evolution/muse/ctrl/configmidictrl.h
@@ -0,0 +1,51 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __CONFIGMIDICTRL_H__
+#define __CONFIGMIDICTRL_H__
+
+#include "ui_configmidictrl.h"
+
+class MidiTrack;
+
+//---------------------------------------------------------
+// ConfigMidiCtrl
+//---------------------------------------------------------
+
+class ConfigMidiCtrl : public QDialog, public Ui::ConfigMidiCtrlBase {
+ Q_OBJECT
+
+ MidiTrack* track;
+
+ private slots:
+ void addClicked();
+ void removeClicked();
+ void availableSelected(QListWidgetItem*);
+ void managedSelected(QListWidgetItem*);
+ virtual void done(int);
+ void defineClicked();
+
+ public:
+ ConfigMidiCtrl(MidiTrack*);
+ };
+
+#endif
+
+
diff --git a/muse_qt4_evolution/muse/ctrl/configmidictrl.ui b/muse_qt4_evolution/muse/ctrl/configmidictrl.ui
new file mode 100644
index 00000000..1960c490
--- /dev/null
+++ b/muse_qt4_evolution/muse/ctrl/configmidictrl.ui
@@ -0,0 +1,204 @@
+<ui version="4.0" >
+ <class>ConfigMidiCtrlBase</class>
+ <widget class="QDialog" name="ConfigMidiCtrlBase" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>506</width>
+ <height>355</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>MusE: Config Midi Controller</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="0" colspan="3" >
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_4" >
+ <property name="text" >
+ <string>Midi Instrument:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QLineEdit" name="portName" >
+ <property name="readOnly" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QLineEdit" name="instrumentName" >
+ <property name="readOnly" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label_3" >
+ <property name="text" >
+ <string>&lt;html>&lt;head>&lt;meta name="qrichtext" content="1" />&lt;/head>&lt;body style=" white-space: pre-wrap; font-family:Arial; font-weight:400; font-style:normal; text-decoration:none;">&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Midi Port:&lt;/p>&lt;/body>&lt;/html></string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="2" >
+ <widget class="QLabel" name="label_2" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>&lt;html>&lt;head>&lt;meta name="qrichtext" content="1" />&lt;/head>&lt;body style=" white-space: pre-wrap; font-family:Arial; font-weight:400; font-style:normal; text-decoration:none;">&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Automated Controller:&lt;/p>&lt;/body>&lt;/html></string>
+ </property>
+ </widget>
+ </item>
+ <item rowspan="3" row="2" column="2" >
+ <widget class="QListWidget" name="managedController" />
+ </item>
+ <item rowspan="2" row="1" column="1" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>75</width>
+ <height>81</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>&lt;html>&lt;head>&lt;meta name="qrichtext" content="1" />&lt;/head>&lt;body style=" white-space: pre-wrap; font-family:Arial; font-weight:400; font-style:normal; text-decoration:none;">&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Available Controller:&lt;/p>&lt;/body>&lt;/html></string>
+ </property>
+ </widget>
+ </item>
+ <item rowspan="3" row="2" column="0" >
+ <widget class="QListWidget" name="availableController" />
+ </item>
+ <item row="4" column="1" >
+ <widget class="QPushButton" name="buttonRemove" >
+ <property name="text" >
+ <string>Remove</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1" >
+ <widget class="QPushButton" name="buttonAdd" >
+ <property name="text" >
+ <string>Add</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0" colspan="3" >
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="defineButton" >
+ <property name="text" >
+ <string>Define new Controller</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>131</width>
+ <height>31</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonOk" >
+ <property name="text" >
+ <string>OK</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonCancel" >
+ <property name="text" >
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonOk</sender>
+ <signal>clicked()</signal>
+ <receiver>ConfigMidiCtrlBase</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>278</x>
+ <y>253</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>96</x>
+ <y>254</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonCancel</sender>
+ <signal>clicked()</signal>
+ <receiver>ConfigMidiCtrlBase</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>369</x>
+ <y>253</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>179</x>
+ <y>282</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/muse_qt4_evolution/muse/ctrl/ctrldialog.cpp b/muse_qt4_evolution/muse/ctrl/ctrldialog.cpp
new file mode 100644
index 00000000..fd8a073c
--- /dev/null
+++ b/muse_qt4_evolution/muse/ctrl/ctrldialog.cpp
@@ -0,0 +1,191 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "ctrldialog.h"
+#include "midictrl.h"
+#include "track.h"
+#include "miditrack.h"
+#include "audiotrack.h"
+#include "plugin.h"
+#include "pipeline.h"
+#include "ctrl/configmidictrl.h"
+
+//---------------------------------------------------------
+// CtrlDialog
+//---------------------------------------------------------
+
+CtrlDialog::CtrlDialog(Track* track, int ci, QWidget* parent)
+ : QDialog(parent)
+ {
+ t = track;
+ currentId = ci;
+ setupUi(this);
+ QTreeWidgetItem* header = tw->headerItem();
+ header->setTextAlignment(0, Qt::AlignLeft);
+ header->setTextAlignment(1, Qt::AlignHCenter);
+
+ tw->header()->setResizeMode(0, QHeaderView::Stretch);
+ header->setToolTip(0, tr("controller name"));
+ header->setToolTip(1, tr("flag if controller contains data"));
+
+ updateController();
+ otherButton->setEnabled(track->type() == Track::MIDI);
+ connect(tw,
+ SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)),
+ SLOT(itemDoubleClicked(QTreeWidgetItem*, int)));
+ connect(otherButton, SIGNAL(clicked()), SLOT(otherClicked()));
+ }
+
+//---------------------------------------------------------
+// updateController
+//---------------------------------------------------------
+
+void CtrlDialog::updateController()
+ {
+ tw->clear();
+ QTreeWidgetItem* ci;
+ if (t->type() == Track::MIDI) {
+ //
+ // add special controll for midi tracks
+ //
+ ci = new QTreeWidgetItem(tw, CTRL_VELOCITY);
+ ci->setText(0, "Velocity");
+ if (CTRL_VELOCITY == currentId) {
+ tw->setCurrentItem(ci);
+ tw->setItemSelected(ci, true);
+ }
+ if (((MidiTrack*)(t))->drumMap()) {
+ ci = new QTreeWidgetItem(tw, CTRL_SVELOCITY);
+ ci->setText(0, "Single Velocity");
+
+ if (CTRL_SVELOCITY == currentId) {
+ tw->setCurrentItem(ci);
+ tw->setItemSelected(ci, true);
+ }
+ }
+ }
+ else if (!t->isMidiTrack()) {
+
+ //
+ // present plugin parameter
+ //
+ Pipeline* pl = ((AudioTrack*)t)->prePipe();
+ int idx = 0;
+ foreach (PluginI* plugin, *pl) {
+ ci = new QTreeWidgetItem(tw, CTRL_NO_CTRL);
+ ci->setText(0, plugin->name());
+ int ncontroller = plugin->plugin()->parameter();
+ for (int i = 0; i < ncontroller; ++i) {
+ QString name(plugin->getParameterName(i));
+ int id = genACnum(idx, i, true);
+ QTreeWidgetItem* cci = new QTreeWidgetItem(ci, id);
+ cci->setText(0, name);
+ Ctrl* ctrl = t->getController(id);
+ if (ctrl) {
+ if (!ctrl->empty())
+ cci->setText(1, "*");
+ if (id == currentId) {
+ tw->setCurrentItem(cci);
+ tw->setItemSelected(cci, true);
+ }
+ }
+ else
+ printf("updateController: controller %x not found\n", id);
+ }
+ }
+ pl = ((AudioTrack*)t)->postPipe();
+ idx = 0;
+ foreach (PluginI* plugin, *pl) {
+ ci = new QTreeWidgetItem(tw, CTRL_NO_CTRL);
+ ci->setText(0, plugin->name());
+ int ncontroller = plugin->plugin()->parameter();
+ for (int i = 0; i < ncontroller; ++i) {
+ QString name(plugin->getParameterName(i));
+ int id = genACnum(idx, i, false);
+ QTreeWidgetItem* cci = new QTreeWidgetItem(ci, id);
+ cci->setText(0, name);
+ Ctrl* ctrl = t->getController(id);
+ if (!ctrl->empty())
+ cci->setText(1, "*");
+ if (id == currentId) {
+ tw->setCurrentItem(cci);
+ tw->setItemSelected(cci, true);
+ }
+ }
+ }
+ }
+
+ ControllerNameList* cn = t->controllerNames();
+ for (iControllerName i = cn->begin(); i != cn->end(); ++i) {
+ ci = new QTreeWidgetItem(tw, i->id);
+ ci->setText(0, i->name);
+ Ctrl* ctrl = t->getController(i->id);
+ if (!ctrl->empty())
+ ci->setText(1, "*");
+
+ if (i->id == currentId) {
+ tw->setCurrentItem(ci);
+ tw->setItemSelected(ci, true);
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// itemDoubleClicked
+//---------------------------------------------------------
+
+void CtrlDialog::itemDoubleClicked(QTreeWidgetItem* item, int)
+ {
+ if (item->type() != CTRL_NO_CTRL)
+ accept();
+ }
+
+//---------------------------------------------------------
+// CtrlDialog
+//---------------------------------------------------------
+
+int CtrlDialog::curId() const
+ {
+ QTreeWidgetItem* item = tw->currentItem();
+ if (item == 0)
+ return CTRL_NO_CTRL;
+ return item->type();
+ }
+
+//---------------------------------------------------------
+// otherClicked
+// Add another controller to the list of "managed"
+// controllers.
+//---------------------------------------------------------
+
+void CtrlDialog::otherClicked()
+ {
+ QTreeWidgetItem* item = tw->currentItem();
+ if (item)
+ currentId = item->type();
+ //
+ // present the list of available controller for
+ // the selected midi instrument
+ //
+ ConfigMidiCtrl mce((MidiTrack*)t);
+ mce.exec();
+ updateController();
+ }
+
diff --git a/muse_qt4_evolution/muse/ctrl/ctrldialog.h b/muse_qt4_evolution/muse/ctrl/ctrldialog.h
new file mode 100644
index 00000000..3cb51ef2
--- /dev/null
+++ b/muse_qt4_evolution/muse/ctrl/ctrldialog.h
@@ -0,0 +1,49 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __CTRL_DIALOG_H__
+#define __CTRL_DIALOG_H__
+
+#include "ui_ctrldialog.h"
+
+class Track;
+
+//---------------------------------------------------------
+// CtrlDialog
+//---------------------------------------------------------
+
+class CtrlDialog : public QDialog, public Ui_CtrlDialogBase {
+ Q_OBJECT
+
+ Track* t;
+ int currentId;
+ void updateController();
+
+ private slots:
+ void itemDoubleClicked(QTreeWidgetItem*, int);
+ void otherClicked();
+
+ public:
+ CtrlDialog(Track*, int, QWidget* parent = 0);
+ int curId() const;
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/ctrl/ctrldialog.ui b/muse_qt4_evolution/muse/ctrl/ctrldialog.ui
new file mode 100644
index 00000000..178cf1d3
--- /dev/null
+++ b/muse_qt4_evolution/muse/ctrl/ctrldialog.ui
@@ -0,0 +1,126 @@
+<ui version="4.0" >
+ <class>CtrlDialogBase</class>
+ <widget class="QDialog" name="CtrlDialogBase" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>390</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>MusE: Select Controller</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QTreeWidget" name="tw" >
+ <property name="alternatingRowColors" >
+ <bool>true</bool>
+ </property>
+ <property name="uniformRowHeights" >
+ <bool>true</bool>
+ </property>
+ <property name="columnCount" >
+ <number>3</number>
+ </property>
+ <column>
+ <property name="text" >
+ <string>Controller</string>
+ </property>
+ </column>
+ <column>
+ <property name="text" >
+ <string>A</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="otherButton" >
+ <property name="text" >
+ <string>Other</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>131</width>
+ <height>31</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="okButton" >
+ <property name="text" >
+ <string>OK</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="cancelButton" >
+ <property name="text" >
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>okButton</sender>
+ <signal>clicked()</signal>
+ <receiver>CtrlDialogBase</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>278</x>
+ <y>253</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>96</x>
+ <y>254</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>cancelButton</sender>
+ <signal>clicked()</signal>
+ <receiver>CtrlDialogBase</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>369</x>
+ <y>253</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>179</x>
+ <y>282</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/muse_qt4_evolution/muse/ctrl/ctrledit.cpp b/muse_qt4_evolution/muse/ctrl/ctrledit.cpp
new file mode 100644
index 00000000..20022f47
--- /dev/null
+++ b/muse_qt4_evolution/muse/ctrl/ctrledit.cpp
@@ -0,0 +1,184 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "ctrledit.h"
+#include "midictrl.h"
+#include "widgets/simplebutton.h"
+#include "widgets/utils.h"
+#include "ctrl/configmidictrl.h"
+#include "ctrl/ctrldialog.h"
+#include "widgets/tools.h"
+#include "miditrack.h"
+#include "midioutport.h"
+
+//---------------------------------------------------------
+// CtrlEdit
+//---------------------------------------------------------
+
+CtrlEdit::CtrlEdit(QWidget* parent, TimeCanvas* timeCanvas, Track* t)
+ : QObject(parent), _track(t)
+ {
+ y = 0;
+ _height = 0;
+ setDrawCtrlName(true);
+
+ _tc = timeCanvas;
+ _ctrl = &veloList;
+ if (t->type() == Track::MIDI) {
+ ctrlId = CTRL_VELOCITY;
+ _ctrl = &veloList;
+ }
+ else {
+ ctrlId = AC_VOLUME;
+ _ctrl = t->getController(ctrlId);
+ }
+
+ sel = new SimpleButton(tr("Sel"), parent);
+ sel->setToolTip(tr("select controller"));
+ sel->setAutoRaise(false);
+
+ minus = newMinusButton();
+ minus->setParent(parent);
+ minus->setToolTip(tr("remove controller view"));
+ minus->setAutoRaise(false);
+
+ connect(_track, SIGNAL(controllerChanged(int)), SLOT(controllerListChanged(int)));
+ connect(sel, SIGNAL(clicked()), SLOT(showControllerList()));
+ }
+
+//---------------------------------------------------------
+// CtrlEdit
+//---------------------------------------------------------
+
+CtrlEdit::~CtrlEdit()
+ {
+ delete sel;
+ delete minus;
+ }
+
+//---------------------------------------------------------
+// setCtrl
+//---------------------------------------------------------
+
+void CtrlEdit::setCtrl(int id)
+ {
+ _ctrl = 0;
+
+ if (_track->type() == Track::MIDI) {
+ if (id == CTRL_VELOCITY)
+ _ctrl = &veloList;
+ else if (id == CTRL_SVELOCITY)
+ _ctrl = &sveloList;
+ else
+ _ctrl = _track->getController(id);
+ }
+ else
+ _ctrl = _track->getController(id);
+
+ if (!_ctrl)
+ printf("CtrlEdit::setCtrl(%d): not found for track <%s>\n", id,
+ _track->name().toLocal8Bit().data());
+ }
+
+//---------------------------------------------------------
+// showControllerList
+//---------------------------------------------------------
+
+void CtrlEdit::showControllerList()
+ {
+ Ctrl* c = ctrl();
+ int id;
+ if (c)
+ id = c->id();
+ else
+ id = CTRL_NO_CTRL;
+ CtrlDialog cd(_track, id);
+ int rv = cd.exec();
+ if (rv != 1)
+ return;
+ id = cd.curId();
+ if (id == CTRL_NO_CTRL)
+ return;
+ changeController(id);
+ }
+
+//---------------------------------------------------------
+// changeController
+//---------------------------------------------------------
+
+void CtrlEdit::changeController(int id)
+ {
+ if (id == CTRL_VELOCITY) {
+ ctrlId = id;
+ _ctrl = &veloList;
+ }
+ else if (id == CTRL_SVELOCITY) {
+ ctrlId = id;
+ _ctrl = &sveloList;
+ }
+ else if (id == CTRL_OTHER) { // "other"
+ if (track()->type() == Track::MIDI) {
+ ConfigMidiCtrl* mce = new ConfigMidiCtrl((MidiTrack*)track());
+ mce->exec();
+ sel->showMenu();
+ }
+ else
+ printf("CtrlEdit::changeController: not impl.\n");
+ }
+ else {
+ ctrlId = id;
+ _ctrl = track()->getController(ctrlId);
+ }
+ _tc->updateCanvasB();
+ }
+
+//---------------------------------------------------------
+// controllerListChanged
+//---------------------------------------------------------
+
+void CtrlEdit::controllerListChanged(int id)
+ {
+ if (id != ctrlId)
+ return;
+ tc()->widget()->update(tc()->rCanvasB);
+ }
+
+//---------------------------------------------------------
+// pixel2val
+//---------------------------------------------------------
+
+int CtrlEdit::pixel2val(int y) const
+ {
+ if (ctrl() == 0)
+ return 0;
+ CVal val = ctrl()->pixel2val(y, _height - splitWidth);
+ return val.i;
+ }
+
+
+//---------------------------------------------------------
+// setSinglePitch
+//---------------------------------------------------------
+
+void CtrlEdit::setSinglePitch(int val)
+ {
+ singlePitch = val;
+ }
+
diff --git a/muse_qt4_evolution/muse/ctrl/ctrledit.h b/muse_qt4_evolution/muse/ctrl/ctrledit.h
new file mode 100644
index 00000000..d942c84f
--- /dev/null
+++ b/muse_qt4_evolution/muse/ctrl/ctrledit.h
@@ -0,0 +1,76 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __CTRL_EDIT_H__
+#define __CTRL_EDIT_H__
+
+#include "ctrleditor.h"
+#include "gui.h"
+
+class SimpleButton;
+class TimeCanvas;
+
+//---------------------------------------------------------
+// CtrlEdit
+//---------------------------------------------------------
+
+class CtrlEdit : public QObject, public CtrlEditor {
+ Q_OBJECT
+
+ Track* const _track;
+ Ctrl* _ctrl;
+ TimeCanvas* _tc;
+ int _height;
+
+ virtual Ctrl* ctrl() const { return _ctrl; }
+ virtual TimeCanvas* tc() const { return _tc; }
+ virtual Track* track() const { return _track; }
+
+ public:
+ int ctrlId;
+ int y;
+ SimpleButton* minus;
+ SimpleButton* sel;
+ QMenu* ctrlList;
+
+ private slots:
+ void showControllerList();
+ void changeController(int);
+ void controllerListChanged(int);
+
+ public:
+ CtrlEdit(QWidget*, TimeCanvas*, Track*);
+ ~CtrlEdit();
+ int pixel2val(int) const;
+ void setHeight(int val) { _height = val; }
+ int height() const { return _height; }
+ virtual int cheight() const { return _height - splitWidth; }
+ void setCtrl(Ctrl* c) { _ctrl = c; }
+ void setCtrl(int id);
+ Ctrl* ctrl() { return _ctrl; }
+ void setSinglePitch(int);
+ };
+
+
+typedef std::vector<CtrlEdit*> CtrlEditList;
+typedef CtrlEditList::iterator iCtrlEdit;
+typedef CtrlEditList::const_iterator ciCtrlEdit;
+#endif
+
diff --git a/muse_qt4_evolution/muse/ctrl/ctrleditor.cpp b/muse_qt4_evolution/muse/ctrl/ctrleditor.cpp
new file mode 100644
index 00000000..cc89c4c6
--- /dev/null
+++ b/muse_qt4_evolution/muse/ctrl/ctrleditor.cpp
@@ -0,0 +1,492 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "ctrleditor.h"
+#include "track.h"
+#include "awl/tcanvas.h"
+#include "ctrl.h"
+#include "midictrl.h"
+#include "gconfig.h"
+#include "song.h"
+#include "part.h"
+#include "tools.h"
+#include "muse.h"
+#include "gui.h"
+
+static const int HANDLE1 = 6;
+static const int HANDLE2 = 3;
+static const int veloWidth = 3;
+
+Ctrl veloList(CTRL_VELOCITY, "velocity", Ctrl::DISCRETE |Ctrl::INT, 0.0, 127.0); // dummy
+Ctrl sveloList(CTRL_SVELOCITY, "single velocity", Ctrl::DISCRETE |Ctrl::INT, 0.0, 127.0); // dummy
+
+//---------------------------------------------------------
+// CtrlEditor
+//---------------------------------------------------------
+
+CtrlEditor::CtrlEditor()
+ {
+ _drawCtrlName = false;
+ dragy = -1;
+ lselected = 0;
+ singlePitch = -1;
+ drawRuler = false;
+ }
+
+//---------------------------------------------------------
+// drawHandle
+//---------------------------------------------------------
+
+inline static void drawHandle(QPainter& p, int x, int y, int lselected)
+ {
+ p.fillRect(x-HANDLE2, y-HANDLE2, HANDLE1, HANDLE1,
+ x == lselected ? Qt::red : Qt::yellow);
+ }
+
+//---------------------------------------------------------
+// ctrlY
+//---------------------------------------------------------
+
+int CtrlEditor::ctrlY(int x, const CVal& val) const
+ {
+ if (dragy != -1 && lselected == x)
+ return dragy;
+ return ctrl()->val2pixelR(val, th) + HANDLE2;
+ }
+
+//---------------------------------------------------------
+// paint
+//---------------------------------------------------------
+
+void CtrlEditor::paint(QPainter& p, const QRect& r)
+ {
+ if (!ctrl())
+ return;
+ int from = r.x() - HANDLE1;
+ if (from < 0)
+ from = 0;
+ int to = r.x() + r.width() + HANDLE1;
+ th = cheight() - HANDLE1 + splitWidth;
+
+ p.save();
+ bool aR = track()->autoRead();
+ p.setPen(QPen(aR ? Qt::white : Qt::gray, 2));
+
+ TType tt = track()->timeType();
+
+ if (ctrl()->id() == CTRL_VELOCITY) {
+ p.setRenderHint(QPainter::Antialiasing, false);
+ p.setPen(QPen(Qt::blue, veloWidth));
+ PartList* pl = track()->parts();
+ for (iPart ip = pl->begin(); ip != pl->end(); ++ip) {
+ Part* part = ip->second;
+ int pos1 = tc()->pos2pix(*part);
+ int pos2 = tc()->pos2pix(part->end());
+
+ if (pos2 <= from)
+ continue;
+ if (pos1 > to)
+ break;
+
+ EventList* events = part->events();
+ for (iEvent e = events->begin(); e != events->end(); ++e) {
+ const Event& ev = e->second;
+ if (ev.type() != Note)
+ continue;
+ int pos = tc()->pos2pix(ev.pos() + *part);
+ if (pos <= from)
+ continue;
+ if (pos > to)
+ break;
+ int id = ctrl()->id();
+ if (id == CTRL_VELOCITY ||
+ (id == CTRL_SVELOCITY && ev.pitch() == singlePitch)) {
+ int y1 = ctrl()->val2pixelR(ev.velo(), th+3) + 1;
+ p.drawLine(pos, th+3, pos, y1);
+ }
+ }
+ }
+ }
+ else {
+ p.setRenderHint(QPainter::Antialiasing, true);
+ if (ctrl()->empty()) {
+ if (aR) {
+ int y = ctrl()->cur2pixel(th) + HANDLE2;
+ p.drawLine(r.x(), y, r.x() + r.width(), y);
+ }
+ }
+ else {
+ int x1, y1, x2, y2;
+ int hx = -1;
+ int hy = 0;
+
+ Pos pos1 = tc()->pix2pos(from);
+ ciCtrlVal i = ctrl()->lowerBound(pos1.time(tt));
+
+ if (i == ctrl()->end()) {
+ --i;
+ int x = tc()->pos2pix(Pos(i.key(), tt));
+ int y = ctrlY(x, i.value());
+ p.drawLine(r.x(), y, r.x() + r.width(), y);
+ }
+ else {
+ if (i == ctrl()->begin()) {
+ x1 = tc()->pos2pix(Pos(i.key(), tt));
+ y1 = ctrlY(x1, i.value());
+ x1 = r.x();
+ }
+ else {
+ --i;
+ x1 = tc()->pos2pix(Pos(i.key(), tt));
+ y1 = ctrlY(x1, i.value());
+ hx = x1;
+ hy = y1;
+ ++i;
+ }
+ do {
+ x2 = tc()->pos2pix(Pos(i.key(), tt));
+ y2 = ctrlY(x2, i.value());
+ if (ctrl()->type() & Ctrl::DISCRETE) {
+ p.drawLine(x1, y1, x2, y1);
+ p.drawLine(x2, y1, x2, y2);
+ }
+ else
+ p.drawLine(x1, y1, x2, y2);
+ if (x2 >= to)
+ break;
+ if (hx != -1)
+ drawHandle(p, hx, hy, lselected);
+ hx = x2;
+ hy = y2;
+ x1 = x2;
+ y1 = y2;
+ ++i;
+ } while (i != ctrl()->end());
+ if (x2 < to)
+ p.drawLine(x2, y1, to, y1);
+ if (hx != -1)
+ drawHandle(p, hx, hy, lselected);
+ }
+ }
+ if (!aR) {
+ int y = ctrl()->cur2pixel(th) + HANDLE2;
+ p.drawLine(r.x(), y, r.x() + r.width(), y);
+ }
+ }
+
+ if (drawRuler) {
+ p.setPen(QPen(Qt::white, 2));
+ p.setRenderHint(QPainter::Antialiasing, true);
+ p.drawLine(ruler1, ruler2);
+ }
+ //
+ // this does not work well a.t.m:
+ //
+ if (_drawCtrlName) {
+ QString s(ctrl()->name());
+ QFont f(tc()->font());
+// p.setFont(config.fonts[3]);
+ p.setPen(Qt::black);
+ QFontMetrics fm(f);
+ int ly = fm.lineSpacing() + 2;
+ p.drawText(2, ly, s);
+ }
+ p.restore();
+ }
+
+//---------------------------------------------------------
+// mousePress
+//---------------------------------------------------------
+
+void CtrlEditor::mousePress(const QPoint& pos, QMouseEvent* me)
+ {
+ int button = me->button();
+ Qt::KeyboardModifiers modifiers = me->modifiers();
+ Tool tool = tc()->tool();
+ if (button & Qt::RightButton) {
+ QMenu pop(tc());
+ QAction* a;
+ for (int i = 0; i < TOOLS; ++i) {
+ int id = 1 << i;
+ if ((arrangerTools & id) == 0)
+ continue;
+ a = getAction(toolList[i], &pop);
+ pop.addAction(a);
+ a->setCheckable(true);
+ if (id == (int)tool)
+ a->setChecked(true);
+ }
+ a = pop.addSeparator();
+ a = pop.addAction("List Editor");
+ a->setData(1 << (TOOLS+1));
+
+ a = pop.exec(me->globalPos());
+ if (a) {
+ int n = a->data().toInt();
+ if (n == (1 << (TOOLS+1))) {
+ Pos t(tc()->pix2pos(pos.x()));
+ muse->showListEditor(t, track(), 0, ctrl());
+ }
+ else
+ muse->setTool(n);
+ }
+ return;
+ }
+
+ int wh = cheight();
+ int y = pos.y();
+ int x = pos.x();
+
+ int cid = ctrl()->id();
+
+ if (tool == PencilTool || (modifiers & Qt::ShiftModifier)) {
+ selected = tc()->pix2pos(x);
+ lselected = x;
+ dragy = y;
+ dragx = x;
+ dragYoffset = 0;
+ if (cid == CTRL_VELOCITY || cid == CTRL_SVELOCITY)
+ song->startUndo();
+ else {
+ // add controller:
+ CVal val = ctrl()->pixel2val(dragy-HANDLE2, wh - HANDLE1 + splitWidth);
+ song->cmdAddControllerVal(track(), ctrl(), selected, val);
+ tc()->widget()->update();
+ }
+ }
+ else if (tool == PointerTool || tool == RubberTool) {
+ if (cid == CTRL_VELOCITY || cid == CTRL_SVELOCITY) {
+ dragx = x;
+ song->startUndo();
+ return;
+ }
+
+ Pos pos1(tc()->pix2pos(x - HANDLE2));
+ Pos pos2(tc()->pix2pos(x + HANDLE2));
+
+ TType tt = track()->timeType();
+ ciCtrlVal s = ctrl()->upperBound(pos1.time(tt));
+ ciCtrlVal e = ctrl()->upperBound(pos2.time(tt));
+ for (ciCtrlVal i = s; i != e; ++i) {
+ int yy = ctrl()->val2pixelR(i.value(), wh - HANDLE1 + splitWidth) + HANDLE2;
+ startY = yy;
+ if ((yy >= (y-HANDLE2)) && (yy < (y + HANDLE2))) {
+ if (tt == AL::TICKS)
+ selected.setTick(i.key());
+ else
+ selected.setFrame(i.key());
+ lselected = tc()->pos2pix(selected);
+ if (tool == RubberTool || button == Qt::RightButton
+ || modifiers & Qt::ControlModifier) {
+ song->cmdRemoveControllerVal(track(), ctrl()->id(), i.key());
+ dragy = -1;
+ }
+ else {
+ dragy = yy;
+ dragYoffset = dragy - y;
+ }
+ tc()->widget()->update();
+ break;
+ }
+ }
+ }
+ else if (tool == DrawTool) {
+ ruler1 = ruler2 = pos;
+ drawRuler = true;
+ }
+ }
+
+//---------------------------------------------------------
+// mouseRelease
+//---------------------------------------------------------
+
+void CtrlEditor::mouseRelease()
+ {
+ if (tc()->tool() == DrawTool) {
+ song->startUndo();
+ drawRuler = false;
+ int from, to, y1, y2;
+ if (ruler1.x() > ruler2.x()) {
+ from = ruler2.x();
+ to = ruler1.x();
+ y1 = ruler2.y();
+ y2 = ruler1.y();
+ }
+ else {
+ from = ruler1.x();
+ to = ruler2.x();
+ y1 = ruler1.y();
+ y2 = ruler2.y();
+ }
+ MidiController::ControllerType type = midiControllerType(ctrl()->id());
+ if (type == MidiController::Velo) {
+ PartList* pl = track()->parts();
+ for (iPart ip = pl->begin(); ip != pl->end(); ++ip) {
+ Part* part = ip->second;
+ int pos1 = tc()->pos2pix(*part);
+ int pos2 = tc()->pos2pix(part->end());
+
+ if (pos2 <= from)
+ continue;
+ if (pos1 > to)
+ break;
+
+ EventList* events = part->events();
+ for (iEvent e = events->begin(); e != events->end(); ++e) {
+ if (e->second.type() != Note)
+ continue;
+ int pos = tc()->pos2pix(e->second.pos() + *part);
+ if (pos <= from)
+ continue;
+ if (pos > to)
+ break;
+ int id = ctrl()->id();
+ if (id == CTRL_VELOCITY ||
+ (CTRL_SVELOCITY && e->second.pitch() == singlePitch)) {
+ int y = y1 + (y2 - y1) * (pos - from) / (to - from);
+ int val = (ctrl()->pixel2val(y+HANDLE2, cheight()-HANDLE1+splitWidth)).i;
+ Event clone = e->second.clone();
+ clone.setB(val);
+ song->changeEvent(e->second, clone, part);
+ song->undoOp(UndoOp::ModifyEvent, clone, e->second, part);
+ }
+ }
+ }
+ }
+ else {
+ printf("ctrleditor:: not implemented\n");
+ }
+ song->endUndo(SC_EVENT_MODIFIED);
+ tc()->widget()->update();
+ return;
+ }
+ if (ctrl()->id() == CTRL_VELOCITY || ctrl()->id() == CTRL_SVELOCITY)
+ song->endUndo(SC_EVENT_MODIFIED);
+ else {
+ if (dragy != -1 && dragy != startY) {
+ int wh = cheight() + splitWidth - HANDLE1;
+ CVal val = ctrl()->pixel2val(dragy - HANDLE2, wh);
+ // modify controller:
+ song->cmdAddControllerVal(track(), ctrl(), selected, val);
+ }
+ dragy = -1;
+ }
+ }
+
+//---------------------------------------------------------
+// mouseMove
+// called only with mouse button pressed
+//---------------------------------------------------------
+
+void CtrlEditor::mouseMove(const QPoint& pos)
+ {
+ Tool tool = tc()->tool();
+ int cid = ctrl()->id();
+
+ if (tool == DrawTool) {
+ ruler2 = pos;
+ tc()->widget()->update();
+ return;
+ }
+ if (cid == CTRL_VELOCITY || cid == CTRL_SVELOCITY) {
+ AL::Pos p1(tc()->pix2pos(dragx));
+ AL::Pos p2(tc()->pix2pos(pos.x()));
+ dragx = pos.x();
+
+ int wh = cheight() - HANDLE1 + splitWidth;
+ int val = (ctrl()->pixel2val(pos.y() - HANDLE2, wh)).i;
+ unsigned tick1 = p1.tick();
+ Part* part = track()->parts()->findPart(tick1);
+ if (part == 0)
+ return;
+ unsigned tick2 = p2.tick();
+ if (tick1 > tick2) {
+ int tmp = tick2;
+ tick2 = tick1;
+ tick1 = tmp;
+ }
+ if (part->tick() > tick1)
+ tick1 = 0;
+ else
+ tick1 -= part->tick(); // event time is relative to part
+ if (part->tick() > tick2)
+ tick2 = 0;
+ else
+ tick2 -= part->tick();
+
+ //
+ // change velocity for all notes at tick time
+ //
+ EventList* el = part->events();
+ EventList tel;
+ for (iEvent ie = el->lower_bound(tick1); ie != el->lower_bound(tick2); ie++) {
+ Event e = ie->second;
+ if (!e.isNote() || e.dataB() == val)
+ continue;
+ tel.add(e);
+ }
+ for (iEvent ie = tel.begin(); ie != tel.end(); ++ie) {
+ Event e = ie->second;
+ Event clone = e.clone();
+ clone.setB(val);
+ song->changeEvent(e, clone, part);
+ song->undoOp(UndoOp::ModifyEvent, clone, e, part);
+ }
+ }
+ else {
+ if (tool == RubberTool) {
+ int wh = cheight();
+ int y = pos.y();
+ int x = pos.x();
+
+ Pos pos1(tc()->pix2pos(x - HANDLE2));
+ Pos pos2(tc()->pix2pos(x + HANDLE2));
+
+ TType tt = track()->timeType();
+ ciCtrlVal s = ctrl()->upperBound(pos1.time(tt));
+ ciCtrlVal e = ctrl()->upperBound(pos2.time(tt));
+ for (ciCtrlVal i = s; i != e; ++i) {
+ int yy = ctrl()->val2pixelR(i.value(), wh);
+ startY = yy;
+ if ((yy >= (y-HANDLE2)) && (yy < (y + HANDLE2))) {
+ if (tt == AL::TICKS)
+ selected.setTick(i.key());
+ else
+ selected.setFrame(i.key());
+ lselected = tc()->pos2pix(selected);
+ song->cmdRemoveControllerVal(track(), ctrl()->id(), i.key());
+ dragy = -1;
+ break;
+ }
+ }
+ }
+ if (dragy != -1) {
+ int th = cheight() + splitWidth - HANDLE2 - 1;
+ dragy = pos.y() + dragYoffset;
+ if (dragy < HANDLE2)
+ dragy = HANDLE2;
+ else if (dragy > th) {
+ dragy = th;
+ }
+ }
+ }
+ tc()->widget()->update();
+ }
+
diff --git a/muse_qt4_evolution/muse/ctrl/ctrleditor.h b/muse_qt4_evolution/muse/ctrl/ctrleditor.h
new file mode 100644
index 00000000..e33a8b29
--- /dev/null
+++ b/muse_qt4_evolution/muse/ctrl/ctrleditor.h
@@ -0,0 +1,76 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __CTRL_EDITOR_H__
+#define __CTRL_EDITOR_H__
+
+#include "al/pos.h"
+
+class Ctrl;
+class TimeCanvas;
+class Track;
+struct CVal;
+
+//---------------------------------------------------------
+// CtrlEditor
+//---------------------------------------------------------
+
+class CtrlEditor {
+ bool _drawCtrlName;
+ int dragx, dragy;
+ int dragYoffset;
+ int startY;
+
+ int th; // effective track height, temp value
+
+ int lselected; // cached pixel position of current value
+ AL::Pos selected; // current selected controller value
+
+ bool drawRuler;
+ QPoint ruler1;
+ QPoint ruler2;
+
+ virtual Ctrl* ctrl() const = 0;
+ virtual TimeCanvas* tc() const = 0;
+ virtual int cheight() const = 0;
+ virtual Track* track() const = 0;
+
+ bool searchHandle(unsigned* time) const;
+
+ int ctrlY(int x, const CVal&) const;
+
+ protected:
+ int singlePitch;
+
+ public:
+ CtrlEditor();
+ virtual ~CtrlEditor() {}
+ void paint(QPainter& p, const QRect& r);
+ void setDrawCtrlName(bool val) { _drawCtrlName = val; }
+ void mousePress(const QPoint&, QMouseEvent*);
+ void mouseRelease();
+ void mouseMove(const QPoint& pos);
+ };
+
+
+extern Ctrl veloList;
+extern Ctrl sveloList;
+#endif
+
diff --git a/muse_qt4_evolution/muse/ctrl/definemidictrl.cpp b/muse_qt4_evolution/muse/ctrl/definemidictrl.cpp
new file mode 100644
index 00000000..197d7572
--- /dev/null
+++ b/muse_qt4_evolution/muse/ctrl/definemidictrl.cpp
@@ -0,0 +1,110 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "definemidictrl.h"
+#include "miditrack.h"
+#include "instruments/minstrument.h"
+
+//---------------------------------------------------------
+// DefineMidiCtrlDialog
+// controllerName QLineEdit
+// controllerType QComboBox
+// msbId lsbId minVal maxVal initVal QSpinBox
+// moveWithPart QCheckBox
+//---------------------------------------------------------
+
+DefineMidiCtrl::DefineMidiCtrl(MidiTrack* t, QWidget* parent)
+ : QDialog(parent)
+ {
+ setupUi(this);
+ track = t;
+ connect(controllerType, SIGNAL(currentIndexChanged(int)), SLOT(typeChanged(int)));
+ }
+
+//---------------------------------------------------------
+// done
+// val == 1 -> OK
+//---------------------------------------------------------
+
+void DefineMidiCtrl::done(int val)
+ {
+ if (val) {
+ ctrl.setName(controllerName->text());
+ ctrl.setComment(controllerComment->toPlainText());
+ int num = MidiController::genNum(
+ MidiController::ControllerType(controllerType->currentIndex()),
+ msbId->value(), lsbId->value());
+ ctrl.setNum(num);
+ ctrl.setMinVal(minVal->value());
+ ctrl.setMaxVal(maxVal->value());
+ ctrl.setInitVal(initVal->value());
+ ctrl.setMoveWithPart(moveWithPart->isChecked());
+
+ //
+ // add controller to instrument
+ //
+ MidiInstrument* instrument = track->instrument();
+ MidiControllerList* mcl = instrument->controller();
+ MidiController* c = new MidiController(ctrl);
+ mcl->append(c);
+ }
+
+ QDialog::done(val);
+ }
+
+//---------------------------------------------------------
+// typeChanged
+//---------------------------------------------------------
+
+void DefineMidiCtrl::typeChanged(int val)
+ {
+ MidiController::ControllerType t = (MidiController::ControllerType)val;
+ switch (t) {
+ case MidiController::RPN:
+ case MidiController::NRPN:
+ case MidiController::Controller7:
+ msbId->setEnabled(false);
+ lsbId->setEnabled(true);
+ maxVal->setRange(0, 127);
+ maxVal->setValue(127);
+ initVal->setRange(0, 127);
+ break;
+ case MidiController::Controller14:
+ case MidiController::RPN14:
+ case MidiController::NRPN14:
+ msbId->setEnabled(true);
+ lsbId->setEnabled(true);
+ maxVal->setRange(0, 128*128-1);
+ maxVal->setValue(128*128-1);
+ initVal->setRange(0, 128*128-1);
+ break;
+ case MidiController::Pitch:
+ case MidiController::Program:
+ msbId->setEnabled(false);
+ lsbId->setEnabled(false);
+ maxVal->setRange(0, 128*128-1);
+ initVal->setRange(0, 128*128-1);
+ maxVal->setValue(128*128-1);
+ break;
+ default:
+ break;
+ }
+ }
+
diff --git a/muse_qt4_evolution/muse/ctrl/definemidictrl.h b/muse_qt4_evolution/muse/ctrl/definemidictrl.h
new file mode 100644
index 00000000..bc0df6a9
--- /dev/null
+++ b/muse_qt4_evolution/muse/ctrl/definemidictrl.h
@@ -0,0 +1,51 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __DEFINEMIDICTRL_H__
+#define __DEFINEMIDICTRL_H__
+
+#include "ui_definemidictrl.h"
+#include "midictrl.h"
+
+class MidiTrack;
+
+//---------------------------------------------------------
+// DefineMidiCtrl
+//---------------------------------------------------------
+
+class DefineMidiCtrl : public QDialog, public Ui::DefineMidiCtrlBase {
+ Q_OBJECT
+
+ MidiTrack* track;
+ MidiController ctrl;
+
+ private slots:
+ virtual void done(int);
+ void typeChanged(int);
+
+ public:
+ DefineMidiCtrl(MidiTrack* t, QWidget* parent = 0);
+ const MidiController* midiController() const { return &ctrl; }
+ };
+
+#endif
+
+
+
diff --git a/muse_qt4_evolution/muse/ctrl/definemidictrl.ui b/muse_qt4_evolution/muse/ctrl/definemidictrl.ui
new file mode 100644
index 00000000..a66e55cb
--- /dev/null
+++ b/muse_qt4_evolution/muse/ctrl/definemidictrl.ui
@@ -0,0 +1,285 @@
+<ui version="4.0" >
+ <class>DefineMidiCtrlBase</class>
+ <widget class="QDialog" name="DefineMidiCtrlBase" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>558</width>
+ <height>344</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Dialog</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item rowspan="2" row="0" column="0" >
+ <widget class="QLabel" name="label_13" >
+ <property name="font" >
+ <font>
+ <pointsize>24</pointsize>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Raised</enum>
+ </property>
+ <property name="lineWidth" >
+ <number>5</number>
+ </property>
+ <property name="text" >
+ <string>&lt;html>&lt;head>&lt;meta name="qrichtext" content="1" />&lt;style type="text/css">
+p, li { white-space: pre-wrap; }
+&lt;/style>&lt;/head>&lt;body style=" font-family:'Arial'; font-size:24pt; font-weight:600; font-style:normal; text-decoration:none;">
+&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">&lt;span style=" font-weight:400;"> &lt;/span>&lt;span style=" font-weight:400;">CTRL &lt;/span>&lt;/p>&lt;/body>&lt;/html></string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QLabel" name="label_2" >
+ <property name="text" >
+ <string>Controller Name:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2" >
+ <widget class="QLineEdit" name="controllerName" />
+ </item>
+ <item row="1" column="1" >
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Controller Type:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2" >
+ <widget class="QComboBox" name="controllerType" >
+ <item>
+ <property name="text" >
+ <string>7-Bit</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>14-Bit</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>7-Bit RPN</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>14-Bit RPN</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>7-Bit NRPN</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>14-Bit NRPN</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_14" >
+ <property name="text" >
+ <string>Comment:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QTextEdit" name="controllerComment" />
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="2" >
+ <widget class="QLabel" name="label_8" >
+ <property name="text" >
+ <string>0x00</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QSpinBox" name="lsbId" />
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_4" >
+ <property name="text" >
+ <string>Id LSB</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2" >
+ <widget class="QLabel" name="label_9" >
+ <property name="text" >
+ <string>0x00</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QSpinBox" name="msbId" />
+ </item>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label_3" >
+ <property name="text" >
+ <string>Id MSB</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" colspan="2" >
+ <widget class="QCheckBox" name="moveWithPart" >
+ <property name="text" >
+ <string>Move with Part</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="2" column="1" >
+ <widget class="QSpinBox" name="initVal" />
+ </item>
+ <item row="2" column="2" >
+ <widget class="QLabel" name="label_12" >
+ <property name="text" >
+ <string>0x00</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2" >
+ <widget class="QLabel" name="label_11" >
+ <property name="text" >
+ <string>0x00</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="label_7" >
+ <property name="text" >
+ <string>Init Value</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QSpinBox" name="maxVal" />
+ </item>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label_5" >
+ <property name="text" >
+ <string>Min.Value</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QSpinBox" name="minVal" />
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_6" >
+ <property name="text" >
+ <string>Max.Value</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2" >
+ <widget class="QLabel" name="label_10" >
+ <property name="text" >
+ <string>0x00</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="okButton" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>okButton</sender>
+ <signal>accepted()</signal>
+ <receiver>DefineMidiCtrlBase</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>okButton</sender>
+ <signal>rejected()</signal>
+ <receiver>DefineMidiCtrlBase</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/muse_qt4_evolution/muse/debug.h b/muse_qt4_evolution/muse/debug.h
new file mode 100644
index 00000000..0820fef3
--- /dev/null
+++ b/muse_qt4_evolution/muse/debug.h
@@ -0,0 +1,44 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __MUSE_DEBUG_H__
+#define __MUSE_DEBUG_H__
+
+#include "globals.h"
+
+#ifdef DEBUG_1
+#define M_REPORT(string) printf("%s:%d:%s: " string "\n", __FILE__, __LINE__, __PRETTY_FUNCTION__);
+#define M_REPORTARG(format, args...) printf("%s:%d:%s: " format "\n", __FILE__, __LINE__, __PRETTY_FUNCTION__, ##args);
+#define M_DEBUG(string) if (debugMsg) fprintf(stderr, "%s:%d:%s: " string "\n", __FILE__, __LINE__, __PRETTY_FUNCTION__);
+#define M_DEBUGARG(format, args...) if (debugMsg) fprintf(stderr, "%s:%d:%s: " format "\n", __FILE__, __LINE__, __PRETTY_FUNCTION__, ##args);
+#define M_ERROR(string) fprintf(stderr, "%s:%d:%s: " string "\n", __FILE__, __LINE__, __PRETTY_FUNCTION__);
+#define M_ERRORARG(format, args...) fprintf(stderr, "%s:%d:%s: " format "\n", __FILE__, __LINE__, __PRETTY_FUNCTION__, ##args);
+#else
+#define M_REPORT(string)
+#define M_REPORTARG(format, args...)
+#define M_DEBUG(string)
+#define M_DEBUGARG(format, args...)
+#define M_ERROR(string)
+#define M_ERRORARG(format, args...)
+#endif
+
+#define DEBUG_ARGS __FILE__ << ":" << __LINE__ << ":" << __PRETTY_FUNCTION__ << ": "
+
+#endif /* __MUSE_DEBUG_H__ */
diff --git a/muse_qt4_evolution/muse/default_click.h b/muse_qt4_evolution/muse/default_click.h
new file mode 100644
index 00000000..d6907c80
--- /dev/null
+++ b/muse_qt4_evolution/muse/default_click.h
@@ -0,0 +1,1213 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 20002 Paul Davis
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+static const float defaultClick[] = {
+ -0.0019836426, 0.0097045898, 0.019165039, 0.028594971, 0.036102295,
+ 0.040679932, 0.040649414, 0.036560059, 0.029693604, 0.016967773,
+ 0.0057067871, -0.008026123, -0.021453857, -0.026153564,
+ -0.031921387, -0.036834717, -0.04397583, -0.046844482,
+ -0.045349121, -0.041748047, -0.032623291, -0.026611328,
+ -0.026702881, -0.025482178, -0.013092041, 0.0055847168,
+ 0.023040771, 0.027435303, 0.043426514, 0.07925415, 0.1086731,
+ 0.09463501, 0.039154053, -0.027832031, -0.081542969, -0.099090576,
+ -0.089385986, -0.051055908, -0.0023803711, 0.031951904,
+ 0.044128418, 0.029998779, 0.0086669922, 0.0022888184, 0.0082092285,
+ 0.0085144043, -0.0057983398, -0.027496338, -0.036834717,
+ -0.021759033, -0.020721436, -0.024078369, -0.025360107,
+ -0.090698242, -0.16491699, -0.16052246, -0.090454102, 0.0031433105,
+ 0.013031006, 0.034790039, 0.30599976, 0.58151245, 0.5078125,
+ 0.32858276, 0.21975708, -0.050018311, -0.34790039, -0.46588135,
+ -0.26513672, 0.12893677, 0.19259644, 0.11685181, 0.095825195,
+ -0.039154053, -0.041473389, 0.0069274902, -0.14685059, -0.32232666,
+ -0.21795654, 0.051086426, 0.18112183, 0.30905151, 0.47305298,
+ 0.60980225, 0.59518433, 0.46920776, 0.51705933, 0.47116089,
+ 0.31832886, 0.20901489, 0.059539795, -0.10055542, -0.23834229,
+ -0.26708984, -0.27468872, -0.29516602, -0.22879028, -0.12854004,
+ -0.064300537, -0.0068664551, 0.060211182, 0.10339355, 0.12594604,
+ 0.12954712, 0.063568115, -0.041046143, -0.1184082, -0.19332886,
+ -0.27337646, -0.34906006, -0.40966797, -0.46533203, -0.45361328,
+ -0.39672852, -0.32958984, -0.15246582, 0.086853027, 0.23678589,
+ 0.24838257, 0.13034058, -0.15222168, -0.5199585, -0.80224609,
+ -0.9397583, -0.89654541, -0.71923828, -0.47998047, -0.14666748,
+ 0.26187134, 0.54995728, 0.69186401, 0.84616089, 0.79928589,
+ 0.53170776, 0.39968872, 0.32455444, 0.2137146, 0.19454956,
+ 0.24069214, 0.22750854, 0.14596558, 0.047058105, -0.04876709,
+ -0.13095093, -0.19775391, -0.16293335, -0.059265137, 0.027526855,
+ 0.13961792, 0.26803589, 0.35470581, 0.37600708, 0.34085083,
+ 0.2572937, 0.13265991, -0.008026123, -0.12841797, -0.22216797,
+ -0.30899048, -0.37841797, -0.4251709, -0.45947266, -0.48376465,
+ -0.50341797, -0.52294922, -0.54516602, -0.58447266, -0.62121582,
+ -0.63989258, -0.64990234, -0.63037109, -0.568573, -0.46630859,
+ -0.36468506, -0.27618408, -0.18487549, -0.11065674, -0.070404053,
+ -0.066101074, -0.049835205, -0.026611328, -0.013061523,
+ 0.011444092, 0.034576416, 0.046112061, 0.052215576, 0.045501709,
+ 0.030059814, 0.011657715, 0.026489258, 0.056121826, 0.10122681,
+ 0.20016479, 0.33053589, 0.45944214, 0.54830933, 0.57751465, 0.5625,
+ 0.55612183, 0.55319214, 0.5697937, 0.64987183, 0.73553467,
+ 0.78170776, 0.84420776, 0.89987183, 0.90475464, 0.85861206,
+ 0.75338745, 0.57077026, 0.3354187, 0.067779541, -0.1741333,
+ -0.36557007, -0.47802734, -0.51281738, -0.47766113, -0.36865234,
+ -0.22381592, -0.065765381, 0.066680908, 0.12365723, 0.098114014,
+ 0.020965576, -0.10775757, -0.27294922, -0.41845703, -0.50146484,
+ -0.52563477, -0.48291016, -0.38186646, -0.27264404, -0.16925049,
+ -0.07043457, 0.003326416, 0.025085449, -0.028320312, -0.11358643,
+ -0.18164062, -0.21984863, -0.21286011, -0.16635132, -0.12728882,
+ -0.088104248, 0.016693115, 0.18893433, 0.40280151, 0.59127808,
+ 0.67233276, 0.64682007, 0.54733276, 0.4213562, 0.30703735,
+ 0.19845581, 0.12661743, 0.095611572, 0.10531616, 0.17950439,
+ 0.29904175, 0.41726685, 0.47506714, 0.48678589, 0.48873901,
+ 0.46694946, 0.42233276, 0.38088989, 0.34689331, 0.30709839,
+ 0.26022339, 0.18258667, 0.064544678, -0.09085083, -0.25634766,
+ -0.41540527, -0.54693604, -0.62731934, -0.6809082, -0.70849609,
+ -0.71044922, -0.68469238, -0.64886475, -0.62115479, -0.6104126,
+ -0.62451172, -0.65185547, -0.67504883, -0.68969727, -0.70257568,
+ -0.71337891, -0.68994141, -0.61865234, -0.49755859, -0.32177734,
+ -0.10437012, 0.11209106, 0.30691528, 0.46789551, 0.51602173,
+ 0.44674683, 0.32055664, 0.1769104, 0.06072998, 0.0075378418,
+ -0.013641357, -0.0038146973, 0.082244873, 0.22116089, 0.35787964,
+ 0.47689819, 0.60266113, 0.71801758, 0.81747437, 0.91799927,
+ 0.97079468, 0.97677612, 0.93850708, 0.83322144, 0.65866089,
+ 0.42324829, 0.14834595, -0.10574341, -0.31484985, -0.46813965,
+ -0.54833984, -0.55517578, -0.51220703, -0.43115234, -0.34613037,
+ -0.29052734, -0.2699585, -0.29443359, -0.33349609, -0.38720703,
+ -0.45751953, -0.51318359, -0.54800415, -0.55706787, -0.5402832,
+ -0.48666382, -0.41162109, -0.32958984, -0.24560547, -0.19873047,
+ -0.18457031, -0.19171143, -0.21240234, -0.23876953, -0.25823975,
+ -0.26184082, -0.24902344, -0.21612549, -0.16552734, -0.11083984,
+ -0.058349609, -0.0034179688, 0.053283691, 0.12722778, 0.23052979,
+ 0.35769653, 0.51147461, 0.68243408, 0.85015869, 0.96902466,
+ 0.99908447, 0.99899292, 0.99453735, 0.87936401, 0.72964478,
+ 0.59124756, 0.45162964, 0.29949951, 0.18435669, 0.087219238,
+ 0.0085754395, -0.031677246, -0.057434082, -0.06338501,
+ -0.050262451, -0.021179199, 0.010986328, 0.035095215, 0.041900635,
+ 0.026275635, -0.008972168, -0.067260742, -0.14938354, -0.24298096,
+ -0.33901978, -0.44342041, -0.53179932, -0.59924316, -0.64294434,
+ -0.66220093, -0.65362549, -0.61437988, -0.56277466, -0.48764038,
+ -0.41287231, -0.3420105, -0.25909424, -0.17782593, -0.10604858,
+ -0.033355713, 0.037872314, 0.097198486, 0.15203857, 0.19644165,
+ 0.23324585, 0.2668457, 0.29403687, 0.31442261, 0.33148193,
+ 0.33639526, 0.32794189, 0.31109619, 0.30651855, 0.30456543,
+ 0.31005859, 0.32266235, 0.34017944, 0.36062622, 0.37988281,
+ 0.39459229, 0.40344238, 0.41464233, 0.41500854, 0.41091919,
+ 0.40512085, 0.39819336, 0.3843689, 0.36633301, 0.33621216,
+ 0.28076172, 0.19436646, 0.083892822, -0.056732178, -0.21832275,
+ -0.38809204, -0.55502319, -0.70330811, -0.82672119, -0.909729,
+ -0.93505859, -0.9085083, -0.84347534, -0.74786377, -0.63342285,
+ -0.52468872, -0.42883301, -0.35321045, -0.29504395, -0.26339722,
+ -0.23782349, -0.21252441, -0.19006348, -0.16159058, -0.12472534,
+ -0.075958252, -0.012115479, 0.056091309, 0.11953735, 0.17373657,
+ 0.22116089, 0.25097656, 0.25982666, 0.2539978, 0.24578857,
+ 0.24325562, 0.25292969, 0.28744507, 0.34677124, 0.42510986,
+ 0.51596069, 0.60205078, 0.67550659, 0.71774292, 0.728302,
+ 0.70874023, 0.6612854, 0.59188843, 0.49536133, 0.37322998,
+ 0.23904419, 0.10256958, -0.030303955, -0.15093994, -0.24526978,
+ -0.31253052, -0.3414917, -0.33178711, -0.29302979, -0.23806763,
+ -0.17816162, -0.13470459, -0.12387085, -0.15142822, -0.20706177,
+ -0.28427124, -0.37112427, -0.44927979, -0.50619507, -0.53219604,
+ -0.53118896, -0.49990845, -0.45379639, -0.39599609, -0.31643677,
+ -0.22329712, -0.15414429, -0.1050415, -0.075592041, -0.0753479,
+ -0.088775635, -0.099090576, -0.086639404, -0.035797119,
+ 0.052154541, 0.1661377, 0.28082275, 0.39169312, 0.50491333,
+ 0.59762573, 0.67288208, 0.71621704, 0.73251343, 0.71405029,
+ 0.66171265, 0.60040283, 0.53762817, 0.46520996, 0.3727417,
+ 0.26971436, 0.17245483, 0.092346191, 0.034851074, 0.0072937012,
+ 0.007232666, 0.017547607, 0.01852417, 0.020172119, 0.023345947,
+ 0.014434814, -0.013946533, -0.054168701, -0.094726562, -0.14425659,
+ -0.20623779, -0.27316284, -0.34069824, -0.40481567, -0.4647522,
+ -0.51278687, -0.55215454, -0.57962036, -0.58953857, -0.59140015,
+ -0.57885742, -0.55456543, -0.51055908, -0.45095825, -0.37948608,
+ -0.29974365, -0.22027588, -0.13543701, -0.047271729, 0.033721924,
+ 0.1005249, 0.14877319, 0.18429565, 0.20465088, 0.21621704,
+ 0.2272644, 0.23416138, 0.24511719, 0.26138306, 0.2805481,
+ 0.3006897, 0.32943726, 0.36660767, 0.40802002, 0.44424438,
+ 0.47698975, 0.50256348, 0.52005005, 0.5267334, 0.52258301,
+ 0.50723267, 0.47485352, 0.42205811, 0.34805298, 0.26202393,
+ 0.16522217, 0.067749023, -0.024169922, -0.1060791, -0.18280029,
+ -0.25424194, -0.31921387, -0.37774658, -0.43612671, -0.50094604,
+ -0.56121826, -0.61495972, -0.66091919, -0.69436646, -0.70004272,
+ -0.67868042, -0.63104248, -0.56182861, -0.48074341, -0.39840698,
+ -0.31900024, -0.24609375, -0.18695068, -0.1461792, -0.11993408,
+ -0.11032104, -0.10159302, -0.091918945, -0.076904297, -0.069580078,
+ -0.058898926, -0.038146973, -0.012542725, 0.014831543, 0.043304443,
+ 0.082824707, 0.13180542, 0.1895752, 0.25256348, 0.32229614,
+ 0.38531494, 0.43493652, 0.4697876, 0.48736572, 0.48733521,
+ 0.46533203, 0.42901611, 0.38223267, 0.33636475, 0.2819519,
+ 0.22467041, 0.16455078, 0.10604858, 0.047485352, -0.010040283,
+ -0.057098389, -0.093933105, -0.12252808, -0.14291382, -0.15545654,
+ -0.16064453, -0.16348267, -0.16918945, -0.17095947, -0.17773438,
+ -0.19436646, -0.21868896, -0.25158691, -0.2890625, -0.33297729,
+ -0.37677002, -0.41171265, -0.43563843, -0.44619751, -0.44320679,
+ -0.42520142, -0.39151001, -0.34609985, -0.29324341, -0.23846436,
+ -0.18026733, -0.12319946, -0.068023682, -0.017944336, 0.033691406,
+ 0.08416748, 0.13388062, 0.18310547, 0.23513794, 0.28579712,
+ 0.3314209, 0.37133789, 0.40841675, 0.44143677, 0.46252441,
+ 0.47073364, 0.46435547, 0.44342041, 0.40725708, 0.35971069,
+ 0.30911255, 0.26272583, 0.22372437, 0.19876099, 0.18948364,
+ 0.18948364, 0.19799805, 0.21658325, 0.23733521, 0.25439453,
+ 0.26513672, 0.26702881, 0.25582886, 0.2338562, 0.19677734,
+ 0.15100098, 0.097106934, 0.036804199, -0.02456665, -0.087005615,
+ -0.14819336, -0.20632935, -0.26040649, -0.30117798, -0.33422852,
+ -0.35610962, -0.36178589, -0.3522644, -0.3237915, -0.28857422,
+ -0.24789429, -0.20108032, -0.14822388, -0.097442627, -0.055877686,
+ -0.019500732, 0.0064086914, 0.024627686, 0.033721924, 0.042114258,
+ 0.052032471, 0.069763184, 0.094207764, 0.12030029, 0.14993286,
+ 0.18215942, 0.22003174, 0.26171875, 0.30029297, 0.33355713,
+ 0.35992432, 0.3833313, 0.40148926, 0.41094971, 0.40899658,
+ 0.39849854, 0.37387085, 0.34091187, 0.30215454, 0.26016235,
+ 0.2170105, 0.17681885, 0.13604736, 0.093658447, 0.049316406,
+ 0.0074462891, -0.037322998, -0.086120605, -0.13262939, -0.18286133,
+ -0.22872925, -0.26879883, -0.3026123, -0.33206177, -0.35943604,
+ -0.37924194, -0.39431763, -0.40466309, -0.40936279, -0.40270996,
+ -0.38815308, -0.36676025, -0.3421936, -0.31149292, -0.27597046,
+ -0.24679565, -0.22177124, -0.20294189, -0.19259644, -0.18527222,
+ -0.18157959, -0.17645264, -0.16998291, -0.1524353, -0.12554932,
+ -0.086669922, -0.03894043, 0.016204834, 0.075744629, 0.13665771,
+ 0.18896484, 0.23040771, 0.26107788, 0.28408813, 0.29443359,
+ 0.29440308, 0.28460693, 0.27456665, 0.26107788, 0.24020386,
+ 0.21322632, 0.18551636, 0.15698242, 0.12554932, 0.095855713,
+ 0.069152832, 0.045501709, 0.020141602, -0.0030517578, -0.026702881,
+ -0.0496521, -0.071960449, -0.098327637, -0.12268066, -0.14907837,
+ -0.17523193, -0.20068359, -0.22494507, -0.2482605, -0.27352905,
+ -0.29666138, -0.31420898, -0.32751465, -0.33670044, -0.33874512,
+ -0.32943726, -0.31417847, -0.29504395, -0.26898193, -0.23904419,
+ -0.20245361, -0.16390991, -0.1210022, -0.078308105, -0.039337158,
+ -0.0037231445, 0.029174805, 0.05847168, 0.084106445, 0.1078186,
+ 0.13174438, 0.15719604, 0.17941284, 0.20126343, 0.22348022,
+ 0.2432251, 0.2578125, 0.2640686, 0.26593018, 0.25933838,
+ 0.24685669, 0.2288208, 0.21047974, 0.19494629, 0.18075562,
+ 0.17199707, 0.17199707, 0.17175293, 0.1729126, 0.17126465,
+ 0.16873169, 0.16256714, 0.15036011, 0.1355896, 0.11254883,
+ 0.083465576, 0.050079346, 0.01159668, -0.030029297, -0.074707031,
+ -0.11532593, -0.15432739, -0.18942261, -0.21673584, -0.23681641,
+ -0.24554443, -0.24703979, -0.24472046, -0.23815918, -0.22784424,
+ -0.21243286, -0.19384766, -0.17596436, -0.15844727, -0.14089966,
+ -0.12030029, -0.099395752, -0.076538086, -0.058746338,
+ -0.034484863, -0.0097351074, 0.015625, 0.037445068, 0.063079834,
+ 0.087738037, 0.11401367, 0.13973999, 0.16848755, 0.19680786,
+ 0.2244873, 0.25567627, 0.28305054, 0.30465698, 0.31854248,
+ 0.32287598, 0.31808472, 0.30102539, 0.27633667, 0.24591064,
+ 0.20962524, 0.17144775, 0.13021851, 0.09487915, 0.057861328,
+ 0.023651123, -0.014129639, -0.051239014, -0.086639404, -0.12316895,
+ -0.15304565, -0.18545532, -0.21154785, -0.23434448, -0.25100708,
+ -0.26113892, -0.26712036, -0.26678467, -0.26687622, -0.262146,
+ -0.25656128, -0.24734497, -0.23501587, -0.22433472, -0.20773315,
+ -0.19207764, -0.17459106, -0.15997314, -0.14196777, -0.12670898,
+ -0.1166687, -0.10726929, -0.099243164, -0.090179443, -0.078521729,
+ -0.062225342, -0.038360596, -0.0068054199, 0.031402588,
+ 0.072143555, 0.11181641, 0.15362549, 0.19085693, 0.22195435,
+ 0.24661255, 0.26379395, 0.27166748, 0.27072144, 0.26507568,
+ 0.25247192, 0.2348938, 0.21447754, 0.18756104, 0.15771484,
+ 0.13241577, 0.10873413, 0.087036133, 0.065460205, 0.046875,
+ 0.029754639, 0.013153076, -0.0065917969, -0.024993896,
+ -0.046051025, -0.067810059, -0.092285156, -0.11779785, -0.14529419,
+ -0.17376709, -0.19503784, -0.21487427, -0.23205566, -0.24533081,
+ -0.25128174, -0.2522583, -0.24685669, -0.23486328, -0.21954346,
+ -0.19946289, -0.1786499, -0.15280151, -0.12744141, -0.098022461,
+ -0.069091797, -0.038146973, -0.0079040527, 0.024719238,
+ 0.054351807, 0.082275391, 0.11019897, 0.13510132, 0.15545654,
+ 0.17276001, 0.1854248, 0.19042969, 0.19281006, 0.1930542,
+ 0.19232178, 0.18795776, 0.17938232, 0.17156982, 0.16223145,
+ 0.15603638, 0.15182495, 0.15118408, 0.14651489, 0.14263916,
+ 0.13916016, 0.1343689, 0.12649536, 0.11480713, 0.10400391,
+ 0.091766357, 0.079589844, 0.063781738, 0.04776001, 0.029510498,
+ 0.013061523, -0.0087890625, -0.034454346, -0.06362915,
+ -0.097381592, -0.12896729, -0.15893555, -0.18429565, -0.20910645,
+ -0.22930908, -0.2411499, -0.25009155, -0.2505188, -0.24719238,
+ -0.23956299, -0.22445679, -0.20892334, -0.18774414, -0.16699219,
+ -0.14205933, -0.12145996, -0.10317993, -0.085449219, -0.066101074,
+ -0.050048828, -0.03326416, -0.014404297, 0.0099182129, 0.041809082,
+ 0.077087402, 0.11599731, 0.14718628, 0.18060303, 0.20654297,
+ 0.23117065, 0.25247192, 0.27026367, 0.28042603, 0.27871704,
+ 0.27175903, 0.25527954, 0.2315979, 0.20584106, 0.17654419,
+ 0.1446228, 0.1086731, 0.073699951, 0.040588379, 0.011627197,
+ -0.016143799, -0.044189453, -0.071838379, -0.098449707,
+ -0.12316895, -0.14602661, -0.16595459, -0.17871094, -0.18606567,
+ -0.19488525, -0.20278931, -0.209198, -0.21121216, -0.21276855,
+ -0.21395874, -0.21328735, -0.21072388, -0.20718384, -0.20404053,
+ -0.19812012, -0.19073486, -0.17901611, -0.16781616, -0.15267944,
+ -0.13824463, -0.12042236, -0.098999023, -0.077453613, -0.053497314,
+ -0.029022217, -0.001373291, 0.022583008, 0.050720215, 0.077026367,
+ 0.10748291, 0.13626099, 0.16424561, 0.18908691, 0.21191406,
+ 0.2300415, 0.2428894, 0.25292969, 0.25643921, 0.25924683,
+ 0.25518799, 0.24127197, 0.22161865, 0.19989014, 0.17800903,
+ 0.14935303, 0.12268066, 0.094787598, 0.068878174, 0.041046143,
+ 0.018585205, 0.0020141602, -0.0094604492, -0.01651001, -0.02243042,
+ -0.031860352, -0.049102783, -0.072113037, -0.098083496,
+ -0.12472534, -0.14935303, -0.17062378, -0.18566895, -0.19500732,
+ -0.19784546, -0.19299316, -0.18365479, -0.17153931, -0.1555481,
+ -0.13491821, -0.11233521, -0.090209961, -0.063781738, -0.038879395,
+ -0.017089844, 0.0027770996, 0.021697998, 0.041046143, 0.059844971,
+ 0.078674316, 0.093536377, 0.10656738, 0.11816406, 0.12698364,
+ 0.13323975, 0.13742065, 0.14559937, 0.1522522, 0.15563965,
+ 0.15548706, 0.1583252, 0.15756226, 0.15576172, 0.15216064,
+ 0.1479187, 0.14260864, 0.13577271, 0.1272583, 0.11904907,
+ 0.10968018, 0.10412598, 0.096618652, 0.087615967, 0.07522583,
+ 0.059265137, 0.039978027, 0.017852783, -0.0061950684, -0.029510498,
+ -0.05065918, -0.075500488, -0.099395752, -0.12225342, -0.1418457,
+ -0.16101074, -0.17797852, -0.1932373, -0.20556641, -0.20901489,
+ -0.21026611, -0.20684814, -0.20016479, -0.18768311, -0.17312622,
+ -0.15994263, -0.14834595, -0.13482666, -0.11865234, -0.10229492,
+ -0.083404541, -0.063079834, -0.039276123, -0.014129639,
+ 0.011199951, 0.035583496, 0.059417725, 0.079925537, 0.098571777,
+ 0.11416626, 0.1270752, 0.14013672, 0.15286255, 0.16619873,
+ 0.17810059, 0.18783569, 0.19454956, 0.19598389, 0.19143677,
+ 0.18264771, 0.16867065, 0.15258789, 0.13143921, 0.10482788,
+ 0.075073242, 0.045928955, 0.018371582, -0.0075683594, -0.032928467,
+ -0.054992676, -0.072662354, -0.089813232, -0.10479736, -0.12127686,
+ -0.13748169, -0.15161133, -0.16473389, -0.17370605, -0.18240356,
+ -0.18569946, -0.18682861, -0.18756104, -0.18310547, -0.18099976,
+ -0.17584229, -0.17102051, -0.16162109, -0.15145874, -0.1421814,
+ -0.12973022, -0.11398315, -0.096557617, -0.078460693, -0.061035156,
+ -0.042541504, -0.023590088, -0.0029296875, 0.020996094,
+ 0.044403076, 0.068237305, 0.092926025, 0.11682129, 0.13772583,
+ 0.15460205, 0.17050171, 0.18438721, 0.19360352, 0.19952393,
+ 0.20303345, 0.2048645, 0.20132446, 0.1930542, 0.18280029,
+ 0.16989136, 0.1546936, 0.13711548, 0.12115479, 0.10336304,
+ 0.087890625, 0.068023682, 0.049804688, 0.028320312, 0.0081787109,
+ -0.012664795, -0.030334473, -0.046783447, -0.061584473,
+ -0.073883057, -0.084655762, -0.093719482, -0.10314941, -0.11251831,
+ -0.12094116, -0.1300354, -0.13421631, -0.13647461, -0.13491821,
+ -0.13186646, -0.12530518, -0.11520386, -0.10275269, -0.088775635,
+ -0.074310303, -0.061462402, -0.046875, -0.032409668, -0.014892578,
+ 0.00057983398, 0.016967773, 0.031738281, 0.0440979, 0.054656982,
+ 0.063659668, 0.073791504, 0.081176758, 0.088562012, 0.095916748,
+ 0.10043335, 0.10443115, 0.10519409, 0.1076355, 0.1071167,
+ 0.10748291, 0.10601807, 0.1026001, 0.10031128, 0.095123291,
+ 0.08972168, 0.082763672, 0.075164795, 0.06729126, 0.057922363,
+ 0.049865723, 0.042144775, 0.035125732, 0.026367188, 0.016571045,
+ 0.0040893555, -0.0084228516, -0.025054932, -0.042053223,
+ -0.060974121, -0.077178955, -0.093902588, -0.10845947, -0.1229248,
+ -0.13531494, -0.14489746, -0.15274048, -0.15701294, -0.15966797,
+ -0.15670776, -0.15130615, -0.140625, -0.12561035, -0.10900879,
+ -0.091644287, -0.077362061, -0.063690186, -0.051879883,
+ -0.04083252, -0.028869629, -0.017059326, -0.0053710938,
+ 0.0051574707, 0.020172119, 0.034484863, 0.051361084, 0.067810059,
+ 0.085540771, 0.10223389, 0.11761475, 0.13146973, 0.14044189,
+ 0.1468811, 0.14923096, 0.14846802, 0.14407349, 0.13641357,
+ 0.12796021, 0.11773682, 0.1076355, 0.09463501, 0.081207275,
+ 0.065124512, 0.050323486, 0.035552979, 0.020965576, 0.0063476562,
+ -0.0094299316, -0.024810791, -0.040008545, -0.054534912,
+ -0.0703125, -0.084228516, -0.096862793, -0.10809326, -0.1171875,
+ -0.12515259, -0.13067627, -0.13568115, -0.13632202, -0.13449097,
+ -0.131073, -0.12503052, -0.11868286, -0.11099243, -0.10317993,
+ -0.095306396, -0.087158203, -0.077667236, -0.068115234,
+ -0.059082031, -0.047241211, -0.033966064, -0.019805908,
+ -0.0041503906, 0.012573242, 0.030029297, 0.047637939, 0.063751221,
+ 0.079162598, 0.092987061, 0.1055603, 0.11737061, 0.12628174,
+ 0.13504028, 0.14266968, 0.14840698, 0.1519165, 0.15158081,
+ 0.14685059, 0.14041138, 0.13082886, 0.11962891, 0.10525513,
+ 0.089599609, 0.072784424, 0.057556152, 0.044464111, 0.032470703,
+ 0.02053833, 0.0086364746, -0.0019226074, -0.013336182,
+ -0.026184082, -0.039398193, -0.052368164, -0.064605713,
+ -0.076293945, -0.086303711, -0.09475708, -0.10128784, -0.10568237,
+ -0.10748291, -0.10894775, -0.10787964, -0.10577393, -0.10229492,
+ -0.097198486, -0.090087891, -0.081695557, -0.07244873,
+ -0.062927246, -0.051940918, -0.041748047, -0.028839111,
+ -0.015960693, -0.0022277832, 0.011779785, 0.024932861, 0.038482666,
+ 0.048614502, 0.059326172, 0.066925049, 0.072021484, 0.077026367,
+ 0.079681396, 0.082733154, 0.082855225, 0.081481934, 0.08001709,
+ 0.079833984, 0.079345703, 0.079162598, 0.078582764, 0.078521729,
+ 0.078582764, 0.077575684, 0.073059082, 0.065612793, 0.055480957,
+ 0.044189453, 0.031768799, 0.019744873, 0.008972168, -0.00094604492,
+ -0.0081176758, -0.013885498, -0.018463135, -0.025634766,
+ -0.032623291, -0.041442871, -0.05279541, -0.0652771, -0.078399658,
+ -0.088256836, -0.098297119, -0.10681152, -0.112854, -0.11355591,
+ -0.11132812, -0.10617065, -0.098449707, -0.087738037, -0.077606201,
+ -0.068054199, -0.059051514, -0.051330566, -0.041503906,
+ -0.031066895, -0.019470215, -0.0077514648, 0.0030517578,
+ 0.014892578, 0.026062012, 0.038879395, 0.050079346, 0.060028076,
+ 0.069793701, 0.076568604, 0.082611084, 0.088989258, 0.094360352,
+ 0.098754883, 0.10293579, 0.10635376, 0.10720825, 0.10586548,
+ 0.10314941, 0.0987854, 0.093475342, 0.087432861, 0.079406738,
+ 0.070159912, 0.059204102, 0.048095703, 0.036529541, 0.023071289,
+ 0.010406494, -0.0024719238, -0.01361084, -0.026184082,
+ -0.036682129, -0.047180176, -0.056213379, -0.065765381,
+ -0.07510376, -0.082702637, -0.091064453, -0.09677124, -0.10232544,
+ -0.10546875, -0.1072998, -0.10693359, -0.10385132, -0.10055542,
+ -0.093078613, -0.085235596, -0.075439453, -0.065643311,
+ -0.054138184, -0.042449951, -0.029785156, -0.017822266,
+ -0.0068359375, 0.0038452148, 0.01373291, 0.023773193, 0.033081055,
+ 0.042053223, 0.049560547, 0.057952881, 0.066223145, 0.075775146,
+ 0.083190918, 0.08984375, 0.096191406, 0.10202026, 0.10595703,
+ 0.10742188, 0.10778809, 0.10528564, 0.1020813, 0.096069336,
+ 0.08883667, 0.07925415, 0.069458008, 0.057952881, 0.047454834,
+ 0.036804199, 0.026397705, 0.015777588, 0.004119873, -0.0077819824,
+ -0.019927979, -0.030822754, -0.040405273, -0.048980713,
+ -0.056610107, -0.062805176, -0.069366455, -0.074035645,
+ -0.077026367, -0.079406738, -0.079986572, -0.080322266,
+ -0.078338623, -0.07598877, -0.072479248, -0.067230225,
+ -0.061218262, -0.055847168, -0.050048828, -0.043823242,
+ -0.037536621, -0.030792236, -0.02230835, -0.012634277,
+ -0.0030822754, 0.0069580078, 0.016204834, 0.023040771, 0.03024292,
+ 0.036865234, 0.043518066, 0.051025391, 0.056396484, 0.061645508,
+ 0.063720703, 0.065185547, 0.065032959, 0.0652771, 0.06439209,
+ 0.06451416, 0.063598633, 0.062011719, 0.058654785, 0.055297852,
+ 0.053131104, 0.051208496, 0.048950195, 0.046905518, 0.042175293,
+ 0.035675049, 0.028411865, 0.019622803, 0.0091247559, -0.0016174316,
+ -0.012207031, -0.022521973, -0.031616211, -0.040618896,
+ -0.047302246, -0.052734375, -0.057098389, -0.060455322,
+ -0.064849854, -0.068664551, -0.07321167, -0.074829102, -0.07623291,
+ -0.075378418, -0.072814941, -0.069152832, -0.064819336,
+ -0.059417725, -0.052368164, -0.044769287, -0.036712646,
+ -0.027679443, -0.018005371, -0.0093383789, 0.0010375977,
+ 0.011474609, 0.022399902, 0.03125, 0.03793335, 0.042449951,
+ 0.045379639, 0.048065186, 0.050567627, 0.054260254, 0.058166504,
+ 0.062316895, 0.066436768, 0.068786621, 0.072113037, 0.074707031,
+ 0.077453613, 0.076507568, 0.074523926, 0.071838379, 0.06729126,
+ 0.061126709, 0.053771973, 0.045410156, 0.037078857, 0.027862549,
+ 0.019134521, 0.0096435547, 0.00079345703, -0.0076293945,
+ -0.016296387, -0.024810791, -0.034454346, -0.043334961,
+ -0.052703857, -0.06048584, -0.066101074, -0.070739746, -0.07220459,
+ -0.073394775, -0.072967529, -0.072509766, -0.072296143,
+ -0.070404053, -0.06842041, -0.064819336, -0.062072754,
+ -0.058624268, -0.05380249, -0.048400879, -0.039764404,
+ -0.031280518, -0.021881104, -0.012786865, -0.0053100586,
+ 0.0022888184, 0.0081176758, 0.014038086, 0.020568848, 0.026885986,
+ 0.032867432, 0.037628174, 0.042999268, 0.046722412, 0.052276611,
+ 0.056884766, 0.061584473, 0.065124512, 0.066955566, 0.068054199,
+ 0.067565918, 0.066589355, 0.06362915, 0.058410645, 0.052764893,
+ 0.045349121, 0.036987305, 0.029144287, 0.021606445, 0.015197754,
+ 0.0087280273, 0.0020446777, -0.004699707, -0.012115479,
+ -0.018920898, -0.02633667, -0.032897949, -0.037841797,
+ -0.042205811, -0.046783447, -0.050567627, -0.055114746,
+ -0.05847168, -0.061004639, -0.061401367, -0.059173584,
+ -0.056915283, -0.053955078, -0.049255371, -0.043121338,
+ -0.037384033, -0.032501221, -0.027709961, -0.023468018,
+ -0.018951416, -0.01385498, -0.0096740723, -0.005279541,
+ -0.0010986328, 0.0033874512, 0.0088806152, 0.01348877, 0.01953125,
+ 0.025024414, 0.031097412, 0.036895752, 0.0418396, 0.045837402,
+ 0.048492432, 0.050231934, 0.051208496, 0.052490234, 0.052856445,
+ 0.053344727, 0.052581787, 0.051452637, 0.049224854, 0.046356201,
+ 0.042938232, 0.038543701, 0.034362793, 0.029602051, 0.025726318,
+ 0.021606445, 0.017272949, 0.013641357, 0.009185791, 0.0037841797,
+ -0.0022888184, -0.0105896, -0.019439697, -0.027709961,
+ -0.034454346, -0.039642334, -0.044464111, -0.046569824,
+ -0.048400879, -0.047546387, -0.046142578, -0.043395996,
+ -0.040405273, -0.037994385, -0.035217285, -0.03414917,
+ -0.031890869, -0.029205322, -0.026306152, -0.021820068,
+ -0.018035889, -0.01361084, -0.0084228516, -0.001373291,
+ 0.0057067871, 0.011962891, 0.018157959, 0.022766113, 0.02722168,
+ 0.030090332, 0.032928467, 0.03503418, 0.036895752, 0.039001465,
+ 0.04107666, 0.042816162, 0.04397583, 0.045074463, 0.045562744,
+ 0.045654297, 0.045532227, 0.045135498, 0.043518066, 0.040618896,
+ 0.036437988, 0.032012939, 0.027099609, 0.021911621, 0.016296387,
+ 0.010955811, 0.006072998, 0.00048828125, -0.0053100586,
+ -0.011535645, -0.017303467, -0.023529053, -0.028717041,
+ -0.03427124, -0.038604736, -0.042572021, -0.045074463,
+ -0.046661377, -0.047851562, -0.04776001, -0.047668457,
+ -0.046691895, -0.045379639, -0.04385376, -0.042297363,
+ -0.040435791, -0.037322998, -0.033691406, -0.029205322,
+ -0.024749756, -0.019775391, -0.014556885, -0.0090942383,
+ -0.0034790039, 0.0011901855, 0.0063171387, 0.0095214844,
+ 0.013519287, 0.016174316, 0.019622803, 0.022094727, 0.024627686,
+ 0.027435303, 0.029876709, 0.032958984, 0.035858154, 0.038208008,
+ 0.039398193, 0.040374756, 0.040222168, 0.039978027, 0.039154053,
+ 0.037811279, 0.034820557, 0.030822754, 0.025695801, 0.020721436,
+ 0.015991211, 0.010864258, 0.006439209, 0.0018005371, -0.002166748,
+ -0.0062561035, -0.0096740723, -0.013244629, -0.01663208,
+ -0.019927979, -0.023742676, -0.026611328, -0.029907227,
+ -0.032684326, -0.035064697, -0.037261963, -0.037811279,
+ -0.037902832, -0.036437988, -0.033233643, -0.029876709,
+ -0.026031494, -0.021759033, -0.017456055, -0.014251709,
+ -0.011566162, -0.0094909668, -0.0071105957, -0.0048217773,
+ -0.0027770996, 0.00036621094, 0.0036010742, 0.0076904297,
+ 0.01159668, 0.015350342, 0.019226074, 0.021697998, 0.024749756,
+ 0.026947021, 0.029266357, 0.030853271, 0.032104492, 0.032470703,
+ 0.032165527, 0.03225708, 0.031860352, 0.03213501, 0.032104492,
+ 0.03213501, 0.031860352, 0.031005859, 0.029205322, 0.026550293,
+ 0.023406982, 0.01940918, 0.015258789, 0.010437012, 0.005859375,
+ 0.0013122559, -0.003112793, -0.0067443848, -0.010040283,
+ -0.01361084, -0.016662598, -0.020324707, -0.023193359,
+ -0.026062012, -0.028503418, -0.029663086, -0.030487061,
+ -0.030059814, -0.029418945, -0.027374268, -0.025024414,
+ -0.022857666, -0.0206604, -0.018585205, -0.016113281, -0.013397217,
+ -0.010192871, -0.0072021484, -0.0043029785, -0.002166748, 0,
+ 0.0024414062, 0.005065918, 0.0079345703, 0.01071167, 0.012878418,
+ 0.015380859, 0.017669678, 0.019958496, 0.021575928, 0.023284912,
+ 0.024078369, 0.024719238, 0.025024414, 0.02557373, 0.02633667,
+ 0.026275635, 0.02520752, 0.024017334, 0.022369385, 0.021057129,
+ 0.019622803, 0.017578125, 0.015258789, 0.012054443, 0.0086975098,
+ 0.0051269531, 0.0020141602, -0.00082397461, -0.00390625,
+ -0.0068054199, -0.010406494, -0.014129639, -0.017425537,
+ -0.020385742, -0.02230835, -0.025054932, -0.026916504,
+ -0.028961182, -0.029724121, -0.029937744, -0.029907227,
+ -0.02911377, -0.027770996, -0.025238037, -0.023010254,
+ -0.019714355, -0.016540527, -0.013641357, -0.011077881,
+ -0.008605957, -0.0062866211, -0.0043945312, -0.0021972656,
+ -0.00067138672, 0.0012512207, 0.0020751953, 0.0036315918,
+ 0.0053405762, 0.0081481934, 0.011352539, 0.014709473, 0.017944336,
+ 0.020202637, 0.022003174, 0.023742676, 0.02520752, 0.026031494,
+ 0.026062012, 0.025421143, 0.024261475, 0.022766113, 0.020904541,
+ 0.019287109, 0.017852783, 0.017333984, 0.017181396, 0.016357422,
+ 0.014770508, 0.012298584, 0.0095825195, 0.0057373047, 0.0017089844,
+ -0.0032043457, -0.0075073242, -0.011260986, -0.014068604,
+ -0.016021729, -0.017608643, -0.0184021, -0.019104004, -0.019775391,
+ -0.020507812, -0.020721436, -0.020355225, -0.019348145,
+ -0.017974854, -0.016235352, -0.014648438, -0.013183594,
+ -0.011657715, -0.010498047, -0.0097961426, -0.0091552734,
+ -0.0082702637, -0.0070800781, -0.0055236816, -0.003112793,
+ -0.00054931641, 0.0024719238, 0.0049743652, 0.0075073242,
+ 0.0095825195, 0.011352539, 0.012512207, 0.013580322, 0.014251709,
+ 0.015045166, 0.016113281, 0.017089844, 0.018096924, 0.018890381,
+ 0.019897461, 0.020629883, 0.020965576, 0.020782471, 0.019744873,
+ 0.018371582, 0.016113281, 0.014068604, 0.011260986, 0.0094604492,
+ 0.0072631836, 0.0054016113, 0.0033874512, 0.0014343262,
+ -0.0007019043, -0.0032958984, -0.0055847168, -0.0082397461,
+ -0.010650635, -0.013275146, -0.015167236, -0.016662598,
+ -0.017852783, -0.018218994, -0.018157959, -0.017486572,
+ -0.017181396, -0.01675415, -0.01651001, -0.015808105, -0.015014648,
+ -0.01385498, -0.012390137, -0.01083374, -0.0090332031,
+ -0.0072937012, -0.0054626465, -0.0038757324, -0.0022888184,
+ -0.00051879883, 0.0011901855, 0.0027770996, 0.0043334961,
+ 0.0057067871, 0.0071716309, 0.0084533691, 0.010101318, 0.011047363,
+ 0.011993408, 0.012969971, 0.013092041, 0.013427734, 0.013641357,
+ 0.013946533, 0.014221191, 0.014099121, 0.01385498, 0.012756348,
+ 0.012054443, 0.011322021, 0.010162354, 0.0087280273, 0.0073547363,
+ 0.0061950684, 0.0046386719, 0.0029602051, 0.0014953613,
+ -0.00033569336, -0.0021362305, -0.0043640137, -0.0064086914,
+ -0.0086975098, -0.010498047, -0.012023926, -0.013092041,
+ -0.013366699, -0.01348877, -0.013793945, -0.013763428,
+ -0.013977051, -0.013824463, -0.013519287, -0.013305664,
+ -0.012878418, -0.012390137, -0.011352539, -0.010131836,
+ -0.0085144043, -0.0065307617, -0.0048217773, -0.0028076172,
+ -0.00094604492, 0.00082397461, 0.0019836426, 0.0028991699,
+ 0.0037841797, 0.0042114258, 0.0050048828, 0.0057067871,
+ 0.0067443848, 0.0078735352, 0.0088195801, 0.0099182129,
+ 0.010986328, 0.011657715, 0.012145996, 0.012573242, 0.012969971,
+ 0.013000488, 0.0128479, 0.012481689, 0.011993408, 0.011352539,
+ 0.010498047, 0.0093688965, 0.0081176758, 0.0067749023,
+ 0.0054931641, 0.0044250488, 0.0032958984, 0.001953125,
+ 0.00054931641, -0.00085449219, -0.0026855469, -0.0042114258,
+ -0.0060119629, -0.0071716309, -0.0086364746, -0.0095825195,
+ -0.010284424, -0.010528564, -0.010498047, -0.010284424,
+ -0.0096740723, -0.0094299316, -0.0088195801, -0.0082092285,
+ -0.0076599121, -0.007232666, -0.0068359375, -0.0063171387,
+ -0.0056152344, -0.0047607422, -0.0038146973, -0.0027770996,
+ -0.0015563965, -0.00061035156, 0.00057983398, 0.0016174316,
+ 0.002532959, 0.0032348633, 0.0037536621, 0.0041503906,
+ 0.0043945312, 0.0048217773, 0.0053405762, 0.0060119629,
+ 0.0067443848, 0.0075073242, 0.0080566406, 0.0084228516,
+ 0.008392334, 0.0083618164, 0.0080566406, 0.0076293945,
+ 0.0071411133, 0.0067749023, 0.0062255859, 0.0054626465,
+ 0.0046081543, 0.0036315918, 0.0026550293, 0.0014648438,
+ 0.0002746582, -0.00076293945, -0.0018615723, -0.0027160645,
+ -0.0035400391, -0.0041809082, -0.0048522949, -0.0054626465,
+ -0.0061035156, -0.0067138672, -0.0072021484, -0.0072937012,
+ -0.0072937012, -0.0069885254, -0.0065002441, -0.0059204102,
+ -0.0051269531, -0.0045471191, -0.0039672852, -0.0036010742,
+ -0.0031738281, -0.0027770996, -0.0023803711, -0.0018310547,
+ -0.0012817383, -0.00064086914, -3.0517578e-05, 0.00064086914,
+ 0.0011901855, 0.0017700195, 0.0021972656, 0.002532959,
+ 0.0028381348, 0.003112793, 0.0034484863, 0.0038146973,
+ 0.0040893555, 0.0043334961, 0.0044250488, 0.0044555664,
+ 0.0045776367, 0.0046691895, 0.0047302246, 0.0046691895,
+ 0.0045471191, 0.0042724609, 0.00390625, 0.0035095215, 0.0029296875,
+ 0.0024414062, 0.001953125, 0.0014343262, 0.00085449219,
+ 0.00021362305, -0.00018310547, -0.00073242188, -0.0012207031,
+ -0.001739502, -0.002166748, 0
+ };
+
+static const unsigned defaultClickLength = sizeof(defaultClick) / sizeof(*defaultClick);
+
+static const float defaultClickEmphasis[] = {
+ 0.002166748, 0.0023193359, 0.001739502, 0.002166748, 0.0021362305,
+ 0.0018615723, 0.0020446777, 0.002166748, 0.0019836426, 0.0022277832,
+ 0.0018310547, 0.0023803711, 0.0022277832, 0.001953125, 0.0022888184,
+ 0.0018005371, 0.0025024414, 0.0018310547, 0.0019836426, 0.001953125,
+ 0.0020446777, 0.0017700195, 0.0021057129, 0.0020751953,
+ 0.0019836426, 0.0014343262, 0.0024414062, 0.0015869141,
+ 0.0022888184, 0.0016784668, 0.0025024414, 0.0017089844,
+ 0.0024719238, 0.0020141602, 0.0026855469, 0.0013427734,
+ 0.0028381348, 0.0015563965, 0.0020446777, 0.0018615723, 0.002532959,
+ 0.0015258789, 0.0021972656, 0.0016784668, 0.002166748, 0.0016479492,
+ 0.0021362305, 0.0018920898, 0.0021362305, 0.0017700195,
+ 0.0020141602, 0.0022277832, 0.001739502, 0.0022583008, 0.001953125,
+ 0.0021362305, 0.0018920898, 0.0020446777, 0.001953125, 0.0026550293,
+ 0.0014953613, 0.0023803711, 0.001953125, 0.0021972656, 0.0015869141,
+ 0.0017700195, 0.0020141602, 0.0022277832, 0.0015258789,
+ 0.0015869141, -0.0045471191, -0.011230469, -0.009185791,
+ -0.0038757324, -0.020690918, -0.030731201, -0.0088806152,
+ 0.0032958984, -0.0068664551, -0.0024719238, 0.024688721,
+ 0.035400391, 0.014892578, 0.0047607422, 0.011779785, 0.0035095215,
+ -0.012573242, -0.0059814453, 0.0065612793, 0.0039672852,
+ 0.0014343262, 0.010406494, 0.027374268, 0.021942139, 0.0065612793,
+ 0.010681152, 0.024688721, 0.024291992, 0.012451172, 0.023590088,
+ 0.033203125, 0.024139404, 0.010375977, 0.016662598, 0.026885986,
+ 0.039215088, 0.038330078, 0.039703369, 0.048309326, 0.046447754,
+ 0.029937744, 0.031311035, 0.066497803, 0.052856445, -0.0074768066,
+ -0.016998291, 0.016784668, 0.039428711, 0.021759033, 0.0040893555,
+ -0.0016174316, 0.012451172, 0.052215576, 0.047485352, 0.017150879,
+ 0.015075684, 0.013397217, 0.024475098, 0.035247803, 0.039978027,
+ 0.06137085, 0.080108643, 0.078521729, 0.054779053, 0.0625,
+ 0.1076355, 0.10934448, 0.079803467, 0.056945801, 0.056182861,
+ 0.047851562, 0.028503418, 0.022979736, 0.010803223, -0.015686035,
+ -0.050811768, -0.072509766, -0.057891846, -0.032073975,
+ -0.051300049, -0.078887939, -0.069366455, -0.038146973,
+ -0.0099182129, 0.010528564, 0.048492432, 0.082305908, 0.084838867,
+ 0.059753418, 0.0043029785, -0.087158203, -0.18395996, -0.2911377,
+ -0.37133789, -0.33422852, -0.28649902, -0.31976318, -0.33630371,
+ -0.22824097, 0.020385742, 0.24456787, 0.31582642, 0.37380981,
+ 0.40820312, 0.40539551, 0.41415405, 0.34210205, 0.20877075,
+ 0.010498047, -0.17623901, -0.22705078, -0.15548706, -0.039855957,
+ 0.0067443848, -0.0022277832, -0.050048828, -0.10186768, -0.11407471,
+ -0.1050415, -0.067352295, 0.0018615723, 0.079742432, 0.11517334,
+ 0.12005615, 0.14709473, 0.19543457, 0.2015686, 0.150177,
+ 0.052703857, -0.029602051, -0.084838867, -0.14590454, -0.18951416,
+ -0.18814087, -0.15014648, -0.11505127, -0.094360352, -0.076721191,
+ -0.037872314, 0.011749268, 0.034851074, 0.060791016, 0.11419678,
+ 0.14096069, 0.13140869, 0.1277771, 0.12313843, 0.10934448,
+ 0.055541992, -0.026397705, -0.07144165, -0.050262451, -0.0097961426,
+ -0.02822876, -0.15008545, -0.28927612, -0.32809448, -0.2772522,
+ -0.15994263, 0.016448975, 0.13085938, 0.12866211, 0.1072998,
+ 0.094177246, 0.036346436, -0.026245117, -0.040496826, -0.01348877,
+ 0.0085144043, 0.0070800781, -0.0086669922, -0.0038452148,
+ 0.040252686, 0.077026367, 0.071960449, 0.032470703, 0.002166748,
+ 0.0065612793, 0.0053100586, -0.025115967, -0.058532715,
+ -0.060699463, -0.015563965, 0.048278809, 0.086273193, 0.078582764,
+ 0.031524658, -0.026580811, -0.077911377, -0.11288452, -0.13244629,
+ -0.15325928, -0.14471436, -0.095672607, -0.048858643, -0.012115479,
+ 0.023132324, 0.051544189, 0.046691895, 0.01373291, -0.0097961426,
+ -0.016143799, -0.022460938, -0.025726318, 0.0075378418, 0.091522217,
+ 0.19741821, 0.23269653, 0.16726685, 0.12173462, 0.12973022,
+ 0.064300537, -0.12158203, -0.29794312, -0.33813477, -0.27990723,
+ -0.19500732, -0.063903809, 0.10449219, 0.23712158, 0.34381104,
+ 0.41766357, 0.37658691, 0.22747803, 0.056365967, -0.088317871,
+ -0.19509888, -0.21295166, -0.15499878, -0.1114502, -0.093597412,
+ -0.071289062, -0.034606934, 0.009552002, 0.068084717, 0.12075806,
+ 0.13098145, 0.11383057, 0.08291626, 0.037322998, -0.017211914,
+ -0.05456543, -0.074829102, -0.087768555, -0.076202393, -0.022735596,
+ 0.032653809, 0.045623779, 0.045806885, 0.040496826, 0.016845703,
+ -0.023712158, -0.057769775, -0.07232666, -0.055145264,
+ -0.00091552734, 0.063201904, 0.11480713, 0.13497925, 0.11572266,
+ 0.030731201, -0.11346436, -0.23406982, -0.27478027, -0.23690796,
+ -0.13735962, -0.016479492, 0.076904297, 0.09487915, 0.070220947,
+ 0.058074951, 0.05355835, 0.017181396, -0.096893311, -0.21951294,
+ -0.26168823, -0.20983887, -0.093109131, 0.051879883, 0.15631104,
+ 0.18319702, 0.15551758, 0.078826904, -0.012084961, -0.083007812,
+ -0.10766602, -0.085479736, -0.059906006, -0.040039062, -0.031646729,
+ -0.046142578, -0.065551758, -0.03414917, 0.025482178, 0.046325684,
+ 0.054473877, 0.073303223, 0.073791504, 0.068786621, 0.082366943,
+ 0.080596924, 0.052215576, 0.015594482, -0.0053405762, 0.0040588379,
+ 0.032501221, 0.065551758, 0.093322754, 0.1199646, 0.13677979,
+ 0.14523315, 0.1401062, 0.12902832, 0.11553955, 0.09664917,
+ 0.091278076, 0.13305664, 0.24594116, 0.38180542, 0.45907593,
+ 0.45343018, 0.4213562, 0.36801147, 0.31027222, 0.30541992,
+ 0.33691406, 0.35479736, 0.3321228, 0.27334595, 0.25701904,
+ 0.23641968, 0.18139648, 0.16793823, 0.17538452, 0.17803955,
+ 0.19009399, 0.25280762, 0.38833618, 0.54940796, 0.70336914,
+ 0.74789429, 0.64334106, 0.49359131, 0.30703735, 0.071624756,
+ -0.075897217, -0.096191406, -0.076568604, 0.023406982, 0.15078735,
+ 0.21612549, 0.30493164, 0.39697266, 0.41009521, 0.32348633,
+ 0.24707031, 0.20645142, 0.11102295, 0.0075073242, -0.046325684,
+ -0.038085938, 0.014251709, 0.096618652, 0.1842041, 0.21417236,
+ 0.15905762, 0.0016174316, -0.25387573, -0.57302856, -0.85641479,
+ -0.99038696, -0.99038696, -0.99038696, -0.99038696, -0.99038696,
+ -0.90664673, -0.64364624, -0.42892456, -0.32131958, -0.23550415,
+ -0.25338745, -0.32595825, -0.44995117, -0.57858276, -0.68716431,
+ -0.80804443, -0.90670776, -0.9654541, -0.97409058, -0.95211792,
+ -0.90264893, -0.85357666, -0.80429077, -0.7482605, -0.69125366,
+ -0.60876465, -0.46228027, -0.23776245, -0.049041748, 0.019989014,
+ 0.048950195, 0.033172607, -0.02142334, -0.084259033, -0.15020752,
+ -0.16220093, -0.14608765, -0.14526367, -0.16497803, -0.1781311,
+ -0.19717407, -0.24871826, -0.26089478, -0.21688843, -0.19818115,
+ -0.23718262, -0.2824707, -0.32797241, -0.36758423, -0.3258667,
+ -0.18960571, -0.082885742, -0.056365967, -0.054534912, -0.10766602,
+ -0.26501465, -0.44006348, -0.58209229, -0.71032715, -0.77719116,
+ -0.76467896, -0.68914795, -0.51403809, -0.27841187, -0.092163086,
+ 0.056030273, 0.16799927, 0.19827271, 0.18478394, 0.17562866,
+ 0.15100098, 0.066619873, -0.040313721, -0.15875244, -0.27044678,
+ -0.35754395, -0.39682007, -0.34078979, -0.22293091, -0.13269043,
+ -0.048034668, 0.0730896, 0.19732666, 0.30789185, 0.39804077,
+ 0.44244385, 0.41928101, 0.35534668, 0.29177856, 0.22891235,
+ 0.18084717, 0.15231323, 0.13360596, 0.13049316, 0.13156128,
+ 0.1293335, 0.11477661, 0.12258911, 0.1824646, 0.26675415,
+ 0.35171509, 0.43341064, 0.49163818, 0.51086426, 0.50985718,
+ 0.49337769, 0.45962524, 0.43182373, 0.42025757, 0.4161377,
+ 0.40631104, 0.40435791, 0.42172241, 0.44003296, 0.45986938,
+ 0.47451782, 0.47540283, 0.48825073, 0.51907349, 0.5612793,
+ 0.62319946, 0.7109375, 0.79650879, 0.86904907, 0.92111206,
+ 0.96124268, 0.96994019, 0.92593384, 0.83483887, 0.70803833,
+ 0.57583618, 0.45834351, 0.3828125, 0.35479736, 0.35110474,
+ 0.38894653, 0.45022583, 0.49264526, 0.48919678, 0.45336914,
+ 0.40823364, 0.35009766, 0.28097534, 0.22503662, 0.18313599,
+ 0.14697266, 0.11010742, 0.07019043, 0.023956299, -0.024658203,
+ -0.087219238, -0.14846802, -0.19796753, -0.23556519, -0.25576782,
+ -0.25366211, -0.2333374, -0.19955444, -0.13546753, -0.052581787,
+ 0.018371582, 0.079620361, 0.14343262, 0.20013428, 0.2388916,
+ 0.25930786, 0.26889038, 0.26208496, 0.24691772, 0.22842407,
+ 0.19110107, 0.14624023, 0.093017578, 0.034301758, -0.044189453,
+ -0.1378479, -0.22967529, -0.29983521, -0.32650757, -0.31271362,
+ -0.26196289, -0.19345093, -0.11380005, -0.032806396, 0.038330078,
+ 0.087677002, 0.10690308, 0.092254639, 0.035766602, -0.057952881,
+ -0.17190552, -0.28945923, -0.40023804, -0.49761963, -0.5635376,
+ -0.59222412, -0.60348511, -0.61352539, -0.60958862, -0.57702637,
+ -0.53674316, -0.49453735, -0.45465088, -0.42507935, -0.40863037,
+ -0.4095459, -0.42730713, -0.45852661, -0.49362183, -0.53048706,
+ -0.55499268, -0.5526123, -0.52798462, -0.49053955, -0.44320679,
+ -0.38500977, -0.30548096, -0.2182312, -0.14306641, -0.073547363,
+ -0.0094299316, 0.045196533, 0.083312988, 0.11129761, 0.14489746,
+ 0.19921875, 0.24578857, 0.25418091, 0.23397827, 0.20111084,
+ 0.14822388, 0.078582764, 0.020812988, -0.012390137, -0.02520752,
+ -0.010559082, 0.026947021, 0.081542969, 0.13687134, 0.18441772,
+ 0.21426392, 0.22711182, 0.21377563, 0.17559814, 0.12246704,
+ 0.060882568, -0.0017089844, -0.067504883, -0.12475586, -0.16159058,
+ -0.16809082, -0.15145874, -0.12081909, -0.077362061, -0.03012085,
+ 0.011444092, 0.044189453, 0.075256348, 0.1050415, 0.13238525,
+ 0.15667725, 0.17337036, 0.17050171, 0.14389038, 0.10055542,
+ 0.057220459, 0.016204834, -0.012664795, -0.025024414, -0.014221191,
+ 0.012939453, 0.063781738, 0.12664795, 0.19824219, 0.26501465,
+ 0.32858276, 0.3782959, 0.40698242, 0.42160034, 0.42788696,
+ 0.43948364, 0.46075439, 0.48413086, 0.49819946, 0.50167847,
+ 0.49963379, 0.48529053, 0.45324707, 0.40890503, 0.36273193,
+ 0.31619263, 0.27200317, 0.23919678, 0.21868896, 0.2046814,
+ 0.18276978, 0.15286255, 0.11727905, 0.071807861, 0.015777588,
+ -0.054199219, -0.12478638, -0.19580078, -0.25622559, -0.30892944,
+ -0.34820557, -0.37606812, -0.39535522, -0.40704346, -0.42147827,
+ -0.43313599, -0.4447937, -0.44998169, -0.44503784, -0.431427,
+ -0.40750122, -0.37838745, -0.34109497, -0.29644775, -0.24822998,
+ -0.1991272, -0.15881348, -0.12728882, -0.10827637, -0.09979248,
+ -0.094055176, -0.091125488, -0.089508057, -0.087646484, -0.0809021,
+ -0.072387695, -0.055328369, -0.035583496, -0.0079956055,
+ 0.018188477, 0.04309082, 0.060577393, 0.073272705, 0.080413818,
+ 0.084503174, 0.083343506, 0.07522583, 0.071136475, 0.076141357,
+ 0.088348389, 0.10449219, 0.12374878, 0.14376831, 0.1534729,
+ 0.14807129, 0.1255188, 0.092559814, 0.047485352, -0.0028076172,
+ -0.062286377, -0.12301636, -0.17855835, -0.22631836, -0.26260376,
+ -0.28588867, -0.29559326, -0.29629517, -0.287323, -0.27877808,
+ -0.26751709, -0.25668335, -0.24749756, -0.24139404, -0.24041748,
+ -0.23944092, -0.23544312, -0.22592163, -0.20898438, -0.184021,
+ -0.15014648, -0.11633301, -0.082702637, -0.0496521, -0.017944336,
+ 0.017486572, 0.052581787, 0.092041016, 0.13427734, 0.18481445,
+ 0.24057007, 0.29467773, 0.33944702, 0.37042236, 0.38433838,
+ 0.38241577, 0.36376953, 0.33966064, 0.31497192, 0.29443359,
+ 0.27792358, 0.2600708, 0.24700928, 0.23727417, 0.23452759,
+ 0.23358154, 0.23257446, 0.23406982, 0.23239136, 0.23312378,
+ 0.22958374, 0.22579956, 0.21710205, 0.20043945, 0.17419434,
+ 0.13870239, 0.096466064, 0.051971436, 0.010437012, -0.024963379,
+ -0.052490234, -0.066467285, -0.068969727, -0.058563232,
+ -0.044616699, -0.030029297, -0.017486572, -0.0077209473,
+ -0.0032043457, -0.0048217773, -0.012481689, -0.027801514,
+ -0.042724609, -0.060211182, -0.072937012, -0.081756592,
+ -0.082977295, -0.07800293, -0.064605713, -0.043792725, -0.013031006,
+ 0.028625488, 0.077667236, 0.13046265, 0.18130493, 0.22851562,
+ 0.26617432, 0.29119873, 0.3039856, 0.30383301, 0.2925415,
+ 0.27261353, 0.24078369, 0.20632935, 0.16989136, 0.13552856,
+ 0.1038208, 0.074462891, 0.045898438, 0.013061523, -0.021087646,
+ -0.06072998, -0.099700928, -0.14016724, -0.17874146, -0.21130371,
+ -0.23596191, -0.25204468, -0.26132202, -0.26803589, -0.27981567,
+ -0.29934692, -0.32730103, -0.36425781, -0.40698242, -0.45092773,
+ -0.48971558, -0.51776123, -0.53198242, -0.5333252, -0.52218628,
+ -0.50076294, -0.47000122, -0.43017578, -0.38583374, -0.33612061,
+ -0.28347778, -0.23306274, -0.18682861, -0.14859009, -0.11853027,
+ -0.099853516, -0.09072876, -0.088562012, -0.091369629, -0.098022461,
+ -0.10787964, -0.11395264, -0.11013794, -0.093841553, -0.069274902,
+ -0.035369873, 0.0026245117, 0.046783447, 0.090698242, 0.1315918,
+ 0.16296387, 0.18664551, 0.2038269, 0.2154541, 0.22036743,
+ 0.21444702, 0.20489502, 0.18753052, 0.16650391, 0.13882446,
+ 0.10861206, 0.078735352, 0.049346924, 0.024078369, 0.0013427734,
+ -0.017974854, -0.032165527, -0.043243408, -0.050262451, -0.05670166,
+ -0.061157227, -0.068695068, -0.078918457, -0.085601807,
+ -0.090698242, -0.093658447, -0.095581055, -0.092529297, -0.08404541,
+ -0.068939209, -0.053649902, -0.037017822, -0.016448975,
+ 0.0096740723, 0.041687012, 0.074798584, 0.10549927, 0.13494873,
+ 0.16445923, 0.1937561, 0.2208252, 0.24539185, 0.26721191,
+ 0.28359985, 0.29733276, 0.30651855, 0.31622314, 0.32266235,
+ 0.31842041, 0.31008911, 0.29681396, 0.2819519, 0.26678467,
+ 0.25457764, 0.24642944, 0.24273682, 0.23709106, 0.22891235,
+ 0.2197876, 0.21051025, 0.20257568, 0.19024658, 0.17764282,
+ 0.1607666, 0.14309692, 0.12210083, 0.096893311, 0.073150635,
+ 0.049530029, 0.028045654, 0.0048522949, -0.017669678, -0.036224365,
+ -0.050506592, -0.059112549, -0.066345215, -0.068939209,
+ -0.070495605, -0.073059082, -0.073028564, -0.076812744,
+ -0.080963135, -0.092010498, -0.10275269, -0.11016846, -0.11907959,
+ -0.12677002, -0.13555908, -0.13842773, -0.13674927, -0.13088989,
+ -0.11846924, -0.099334717, -0.072784424, -0.042541504,
+ -0.0082702637, 0.031524658, 0.072387695, 0.10968018, 0.13861084,
+ 0.15847778, 0.16812134, 0.16650391, 0.15774536, 0.14169312,
+ 0.12005615, 0.092895508, 0.061737061, 0.02923584, -0.0022277832,
+ -0.032836914, -0.05670166, -0.075439453, -0.093322754, -0.1121521,
+ -0.13204956, -0.15255737, -0.17541504, -0.19900513, -0.21817017,
+ -0.23519897, -0.25091553, -0.27148438, -0.29296875, -0.31069946,
+ -0.3243103, -0.33599854, -0.34689331, -0.35461426, -0.3598938,
+ -0.36212158, -0.36105347, -0.35699463, -0.34725952, -0.33319092,
+ -0.31484985, -0.29327393, -0.26959229, -0.24423218, -0.21859741,
+ -0.18777466, -0.15194702, -0.11468506, -0.079498291, -0.0496521,
+ -0.023529053, 0.001159668, 0.025848389, 0.044494629, 0.054168701,
+ 0.058135986, 0.059844971, 0.066894531, 0.075195312, 0.087585449,
+ 0.10009766, 0.11755371, 0.13864136, 0.16278076, 0.18545532,
+ 0.20370483, 0.22076416, 0.23773193, 0.25531006, 0.26928711,
+ 0.27508545, 0.27371216, 0.26660156, 0.25100708, 0.2260437,
+ 0.1942749, 0.16079712, 0.12878418, 0.10110474, 0.07244873,
+ 0.046051025, 0.024993896, 0.010284424, -0.0010070801, -0.0082397461,
+ -0.011383057, -0.0072937012, -0.0034179688, 0.0040893555,
+ 0.013519287, 0.022583008, 0.031219482, 0.032714844, 0.034851074,
+ 0.033508301, 0.033935547, 0.030975342, 0.031982422, 0.039794922,
+ 0.05569458, 0.077392578, 0.10113525, 0.1277771, 0.15429688,
+ 0.18026733, 0.20275879, 0.21591187, 0.22341919, 0.224823,
+ 0.22775269, 0.22766113, 0.22491455, 0.2170105, 0.20431519,
+ 0.19171143, 0.17459106, 0.15859985, 0.14315796, 0.12554932,
+ 0.10998535, 0.09463501, 0.083435059, 0.070465088, 0.057983398,
+ 0.048278809, 0.041351318, 0.036224365, 0.030639648, 0.021850586,
+ 0.012176514, -0.0034484863, -0.022735596, -0.045166016,
+ -0.068908691, -0.094421387, -0.11810303, -0.13882446, -0.15774536,
+ -0.17269897, -0.18533325, -0.19125366, -0.19116211, -0.18655396,
+ -0.18423462, -0.18267822, -0.17877197, -0.17248535, -0.16625977,
+ -0.16271973, -0.16104126, -0.16125488, -0.16192627, -0.16333008,
+ -0.16461182, -0.16616821, -0.16235352, -0.15325928, -0.13644409,
+ -0.11523438, -0.090240479, -0.058013916, -0.024383545, 0.0089111328,
+ 0.039093018, 0.067749023, 0.096221924, 0.11837769, 0.13458252,
+ 0.13946533, 0.13269043, 0.12045288, 0.099212646, 0.073608398,
+ 0.042266846, 0.011627197, -0.019042969, -0.04876709, -0.07409668,
+ -0.096038818, -0.11062622, -0.1239624, -0.1340332, -0.14199829,
+ -0.14428711, -0.14074707, -0.13641357, -0.13253784, -0.13400269,
+ -0.13830566, -0.1505127, -0.16162109, -0.17391968, -0.1847229,
+ -0.19418335, -0.2019043, -0.20770264, -0.21234131, -0.21121216,
+ -0.20510864, -0.19058228, -0.16986084, -0.14498901, -0.11407471,
+ -0.082061768, -0.048492432, -0.015533447, 0.018341064, 0.052185059,
+ 0.078826904, 0.10336304, 0.12106323, 0.1315918, 0.13513184,
+ 0.13653564, 0.13986206, 0.14501953, 0.14926147, 0.15634155,
+ 0.16189575, 0.16915894, 0.17584229, 0.18264771, 0.19329834,
+ 0.20681763, 0.22433472, 0.24029541, 0.25708008, 0.27435303,
+ 0.28552246, 0.28768921, 0.2796936, 0.26013184, 0.23287964,
+ 0.20193481, 0.17483521, 0.14996338, 0.12689209, 0.10336304,
+ 0.081939697, 0.063842773, 0.047302246, 0.031677246, 0.01953125,
+ 0.010559082, 0.0013427734, -0.0082397461, -0.016357422,
+ -0.019348145, -0.023223877, -0.023406982, -0.023895264,
+ -0.022155762, -0.020477295, -0.017089844, -0.013031006,
+ -0.0098571777, -0.0046691895, 6.1035156e-05, 0.0072937012,
+ 0.0128479, 0.025878906, 0.040618896, 0.055908203, 0.066558838,
+ 0.072021484, 0.076965332, 0.080383301, 0.081237793, 0.077575684,
+ 0.072113037, 0.067443848, 0.064880371, 0.063720703, 0.058959961,
+ 0.054534912, 0.047576904, 0.039276123, 0.025390625, 0.010986328,
+ -0.0061645508, -0.018859863, -0.028900146, -0.036376953,
+ -0.041473389, -0.047241211, -0.054260254, -0.063049316, -0.0730896,
+ -0.081085205, -0.090118408, -0.10089111, -0.11264038, -0.12442017,
+ -0.1350708, -0.14535522, -0.15383911, -0.16052246, -0.16329956,
+ -0.1668396, -0.17166138, -0.17819214, -0.18157959, -0.18133545,
+ -0.17935181, -0.1758728, -0.17181396, -0.16687012, -0.16067505,
+ -0.15344238, -0.14562988, -0.13626099, -0.12780762, -0.11743164,
+ -0.10961914, -0.098510742, -0.085601807, -0.071716309, -0.05758667,
+ -0.041412354, -0.024078369, -0.0043640137, 0.015960693, 0.037567139,
+ 0.060455322, 0.082855225, 0.10211182, 0.11419678, 0.12088013,
+ 0.12197876, 0.12145996, 0.11743164, 0.11026001, 0.096984863,
+ 0.077789307, 0.054504395, 0.031890869, 0.010986328, -0.0061340332,
+ -0.020507812, -0.032836914, -0.042541504, -0.050476074,
+ -0.056762695, -0.06137085, -0.065032959, -0.064727783, -0.064147949,
+ -0.060119629, -0.05770874, -0.056549072, -0.057098389, -0.059692383,
+ -0.063140869, -0.067321777, -0.072021484, -0.075439453,
+ -0.078033447, -0.077575684, -0.073059082, -0.063995361,
+ -0.049560547, -0.030212402, -0.008605957, 0.015930176, 0.039794922,
+ 0.065917969, 0.090820312, 0.11099243, 0.12619019, 0.13739014,
+ 0.1472168, 0.15374756, 0.15893555, 0.16152954, 0.16671753,
+ 0.17425537, 0.17889404, 0.18060303, 0.17886353, 0.17861938,
+ 0.17984009, 0.18179321, 0.18499756, 0.18548584, 0.18609619,
+ 0.18521118, 0.18234253, 0.17956543, 0.17547607, 0.1690979,
+ 0.16101074, 0.15505981, 0.14837646, 0.13739014, 0.12255859,
+ 0.10522461, 0.082397461, 0.05770874, 0.030609131, 0.0046691895,
+ -0.018676758, -0.037872314, -0.054779053, -0.069458008,
+ -0.078826904, -0.084136963, -0.085479736, -0.083404541,
+ -0.076324463, -0.066314697, -0.056060791, -0.049926758,
+ -0.043182373, -0.040252686, -0.037811279, -0.038543701,
+ -0.039276123, -0.040771484, -0.041687012, -0.042053223,
+ -0.043548584, -0.040161133, -0.034637451, -0.024841309,
+ -0.015197754, -0.0059509277, 0.001159668, 0.0042114258,
+ 0.0062866211, 0.0049438477, 0.0047302246, 0.0028686523,
+ -0.00082397461, -0.0034790039, -0.0077514648, -0.01260376,
+ -0.019500732, -0.02645874, -0.032409668, -0.041351318, -0.049163818,
+ -0.058532715, -0.068603516, -0.078948975, -0.088897705,
+ -0.094543457, -0.097167969, -0.095581055, -0.094726562,
+ -0.095001221, -0.095336914, -0.094726562, -0.096160889, -0.09866333,
+ -0.10427856, -0.1104126, -0.11727905, -0.12301636, -0.13006592,
+ -0.13479614, -0.13574219, -0.13119507, -0.12451172, -0.11630249,
+ -0.10476685, -0.094543457, -0.08416748, -0.074066162, -0.061767578,
+ -0.050415039, -0.040557861, -0.031402588, -0.023834229, -0.01361084,
+ -0.0036010742, 0.0055236816, 0.013122559, 0.02142334, 0.029418945,
+ 0.041717529, 0.056518555, 0.075714111, 0.095062256, 0.11523438,
+ 0.13363647, 0.146698, 0.15646362, 0.16061401, 0.16043091,
+ 0.15634155, 0.14889526, 0.13769531, 0.12127686, 0.10272217,
+ 0.085418701, 0.070739746, 0.055541992, 0.040405273, 0.024200439,
+ 0.010803223, -0.00048828125, -0.0087890625, -0.012481689,
+ -0.014404297, -0.014068604, -0.011230469, -0.0081787109,
+ -0.0049438477, -0.0041809082, -0.0060119629, -0.012237549,
+ -0.020355225, -0.027832031, -0.034759521, -0.042053223, -0.04675293,
+ -0.045349121, -0.042297363, -0.03604126, -0.027862549, -0.015777588,
+ -0.0011291504, 0.013397217, 0.030212402, 0.04598999, 0.061401367,
+ 0.074615479, 0.086242676, 0.094238281, 0.09979248, 0.10458374,
+ 0.10662842, 0.10894775, 0.11077881, 0.11056519, 0.11022949,
+ 0.10903931, 0.1072998, 0.10266113, 0.098999023, 0.095977783,
+ 0.095916748, 0.095611572, 0.094909668, 0.093963623, 0.092895508,
+ 0.092559814, 0.090423584, 0.084014893, 0.073852539, 0.059020996,
+ 0.044830322, 0.02822876, 0.012023926, -0.0049743652, -0.020050049,
+ -0.036193848, -0.052398682, -0.066253662, -0.078796387,
+ -0.089019775, -0.098083496, -0.10592651, -0.11224365, -0.11618042,
+ -0.11715698, -0.11807251, -0.11676025, -0.11459351, -0.11108398,
+ -0.10748291, -0.10400391, -0.10064697, -0.096923828, -0.092163086,
+ -0.086639404, -0.08114624, -0.075531006, -0.071838379, -0.06854248,
+ -0.064971924, -0.061035156, -0.054382324, -0.047393799,
+ -0.043518066, -0.04095459, -0.041351318, -0.041259766, -0.041931152,
+ -0.04095459, -0.037841797, -0.034210205, -0.029541016, -0.026550293,
+ -0.02444458, -0.024139404, -0.026397705, -0.03036499, -0.035675049,
+ -0.041046143, -0.04675293, -0.054168701, -0.061218262, -0.065704346,
+ -0.066650391, -0.066650391, -0.063537598, -0.06048584, -0.055664062,
+ -0.053375244, -0.052642822, -0.052764893, -0.054718018,
+ -0.053955078, -0.05355835, -0.052764893, -0.053405762, -0.056213379,
+ -0.06036377, -0.062744141, -0.063110352, -0.06072998, -0.054504395,
+ -0.044647217, -0.034057617, -0.022949219, -0.011810303, 0.002532959,
+ 0.015594482, 0.024383545, 0.032165527, 0.03894043, 0.047302246,
+ 0.055236816, 0.064605713, 0.072387695, 0.081115723, 0.088348389,
+ 0.094940186, 0.10223389, 0.11135864, 0.12249756, 0.13082886,
+ 0.13803101, 0.14520264, 0.14993286, 0.15118408, 0.14987183,
+ 0.14846802, 0.14581299, 0.13851929, 0.12878418, 0.11639404,
+ 0.10375977, 0.09173584, 0.078796387, 0.063842773, 0.048980713,
+ 0.034576416, 0.022338867, 0.011932373, 0.0039672852, 0.0011291504,
+ -0.00094604492, -0.0015563965, -0.0034484863, -0.0050354004,
+ -0.0083312988, -0.012390137, -0.01651001, -0.019683838,
+ -0.022003174, -0.024414062, -0.027557373, -0.03137207, -0.03314209,
+ -0.030700684, -0.028045654, -0.025482178, -0.022247314,
+ -0.018737793, -0.013275146, -0.0074157715, 0.0010070801,
+ 0.0093078613, 0.01763916, 0.027404785, 0.035583496, 0.043151855,
+ 0.047485352, 0.051239014, 0.053649902, 0.054626465, 0.054382324,
+ 0.053039551, 0.050323486, 0.046691895, 0.044158936, 0.041534424,
+ 0.039794922, 0.035797119, 0.031494141, 0.026580811, 0.021575928,
+ 0.017944336, 0.014038086, 0.0093688965, 0.0051574707,
+ -0.00067138672, -0.0070495605, -0.014984131, -0.021728516,
+ -0.030151367, -0.037719727, -0.049804688, -0.062255859,
+ -0.073791504, -0.08416748, -0.089599609, -0.096496582, -0.10055542,
+ -0.10531616, -0.10870361, -0.11083984, -0.11102295, -0.10925293,
+ -0.10610962, -0.10125732, -0.094848633, -0.086700439, -0.07925415,
+ -0.074005127, -0.070770264, -0.068511963, -0.065643311,
+ -0.060577393, -0.054595947, -0.049407959, -0.043914795,
+ -0.039794922, -0.033813477, -0.027923584, -0.022674561,
+ -0.017791748, -0.01260376, -0.008972168, -0.0076293945,
+ -0.0053100586, -0.0030517578, -0.0024719238, -0.0032043457,
+ -0.0035705566, -0.002746582, -0.0013427734, -0.0011901855,
+ -0.0012817383, -0.0016479492, -0.0030212402, -0.0040588379,
+ -0.0071411133, -0.0085449219, -0.010375977, -0.01171875,
+ -0.011230469, -0.012512207, -0.013305664, -0.014190674,
+ -0.014099121, -0.015625, -0.01763916, -0.020202637, -0.020172119,
+ -0.017730713, -0.014068604, -0.0097351074, -0.0065917969,
+ -0.0020751953, 0.0018310547, 0.0045471191, 0.0046691895,
+ 0.003326416, 0.0018615723, -0.00021362305, 0.0010986328,
+ 0.0056152344, 0.011962891, 0.019866943, 0.029846191, 0.040130615,
+ 0.050811768, 0.058746338, 0.068267822, 0.076721191, 0.083862305,
+ 0.091491699, 0.096008301, 0.10150146, 0.1036377, 0.10562134,
+ 0.10449219, 0.1026001, 0.10076904, 0.099822998, 0.098297119,
+ 0.095245361, 0.094207764, 0.091949463, 0.092773438, 0.093048096,
+ 0.093658447, 0.090881348, 0.084747314, 0.078186035, 0.068328857,
+ 0.058197021, 0.044403076, 0.031768799, 0.019866943, 0.010345459,
+ 0.0029602051, -0.0044555664, -0.011932373, -0.018920898,
+ -0.024993896, -0.029205322, -0.031768799, -0.034790039,
+ -0.036773682, -0.037841797, -0.04019165, -0.042785645, -0.045928955,
+ -0.045776367, -0.044006348, -0.040649414, -0.037902832,
+ -0.036834717, -0.035308838, -0.033569336, -0.030090332,
+ -0.025543213, -0.020263672, -0.014678955, -0.0094604492,
+ -0.0042114258, -0.00067138672, 0.0016784668, 0.0021362305,
+ 0.0038452148, 0.007598877, 0.0099487305, 0.013793945, 0.015838623,
+ 0.01852417, 0.019958496, 0.021087646, 0.021270752, 0.021911621,
+ 0.021789551, 0.020965576, 0.01776123, 0.013275146, 0.0070495605,
+ 0.00076293945, -0.004119873, -0.007232666, -0.009552002,
+ -0.012695312, -0.016052246, -0.019226074, -0.02331543, -0.028625488,
+ -0.032348633, -0.035736084, -0.038909912, -0.044372559,
+ -0.050354004, -0.056610107, -0.061309814, -0.065704346,
+ -0.065948486, -0.067230225, -0.06652832, -0.0652771, -0.061981201,
+ -0.057128906, -0.052185059, -0.046112061, -0.041595459,
+ -0.035461426, -0.031097412, -0.025970459, -0.022979736,
+ -0.019836426, -0.015899658, -0.01260376, -0.0087585449,
+ -0.0061950684, -0.0028991699, -0.0014953613, 0.0018615723,
+ 0.0055847168, 0.008605957, 0.011871338, 0.015594482, 0.020629883,
+ 0.025970459, 0.030212402, 0.034973145, 0.037322998, 0.037597656,
+ 0.036254883, 0.034698486, 0.032440186, 0.029937744, 0.026062012,
+ 0.021972656, 0.018432617, 0.013397217, 0.010528564, 0.0077514648,
+ 0.0076904297, 0.0078430176, 0.0095825195, 0.012512207, 0.01550293,
+ 0.017486572, 0.017150879, 0.015563965, 0.013031006, 0.010070801,
+ 0.0068969727, 0.0039367676, 0.0021057129, 0.0018920898,
+ 0.0032653809, 0.0064697266, 0.0092163086, 0.010437012, 0.0097961426,
+ 0.0078125, 0.0053405762, 0.0048828125, 0.0055236816, 0.0086669922,
+ 0.013061523, 0.019897461, 0.027252197, 0.035675049, 0.043518066,
+ 0.050018311, 0.056427002, 0.06072998, 0.062011719, 0.061859131,
+ 0.060546875, 0.060577393, 0.059173584, 0.056945801, 0.054138184,
+ 0.053283691, 0.053131104, 0.052764893, 0.050811768, 0.04864502,
+ 0.046295166, 0.044921875, 0.043182373, 0.040161133, 0.036529541,
+ 0.032287598, 0.028411865, 0.022247314, 0.015960693, 0.0095825195,
+ 0.0032958984, -0.0028991699, -0.01159668, -0.018249512, -0.02532959,
+ -0.03137207, -0.035919189, -0.040710449, -0.044006348, -0.049163818,
+ -0.052246094, -0.055969238, -0.056396484, -0.055511475,
+ -0.052825928, -0.049194336, -0.046844482, -0.04598999, -0.045227051,
+ -0.044586182, -0.042388916, -0.039611816, -0.037719727,
+ -0.035766602, -0.032806396, -0.030700684, -0.027313232, -0.02444458,
+ -0.020019531, -0.015533447, -0.012145996, -0.0091552734,
+ -0.0064697266, -0.0040893555, -0.00048828125, 0.001953125,
+ 0.0048522949, 0.0061950684, 0.007019043, 0.0083007812, 0.0091247559,
+ 0.0094909668, 0.0098876953, 0.010894775, 0.011566162, 0.0105896,
+ 0.0083007812, 0.0047607422, 0.0010986328, -0.0036621094,
+ -0.0073242188, -0.010223389, -0.011505127, -0.011993408,
+ -0.012786865, -0.015350342, -0.017669678, -0.019500732,
+ -0.022613525, -0.025115967, -0.027862549, -0.027832031,
+ -0.028320312, -0.029602051, -0.030761719, -0.033111572,
+ -0.033630371, -0.032592773, -0.030914307, -0.027008057, -0.02355957,
+ -0.020507812, -0.017211914, -0.014709473, -0.0097351074,
+ -0.0033874512, 0.0032958984, 0.010284424, 0.014007568, 0.017272949,
+ 0.017791748, 0.018371582, 0.018096924, 0.017272949, 0.016326904,
+ 0.016021729, 0.017028809, 0.020507812, 0.025238037, 0.031280518,
+ 0.036834717, 0.040283203, 0.04284668, 0.045410156, 0.048339844,
+ 0.050109863, 0.04800415, 0.044311523, 0.040557861, 0.036010742,
+ 0.031982422, 0.026977539, 0.022766113, 0.018829346, 0.015411377,
+ 0.012359619, 0.010925293, 0.0095214844, 0.010498047, 0.012054443,
+ 0.014221191, 0.016326904, 0.017150879, 0.016784668, 0.01473999,
+ 0.012481689, 0.0090026855, 0.0057678223, 0.002746582,
+ -0.00024414062, -6.1035156e-05, -0.00042724609, -0.00039672852,
+ -0.0024414062, -0.0037841797, -0.0043334961, -0.0034790039,
+ -0.0015563965, 0.0011901855, 0.0047302246, 0.0079345703,
+ 0.011108398, 0.013885498, 0.017150879, 0.020874023, 0.024139404,
+ 0.028411865, 0.031860352, 0.036010742, 0.038330078, 0.038574219,
+ 0.03805542, 0.035980225, 0.033905029, 0.03112793, 0.027496338,
+ 0.024414062, 0.020690918, 0.017791748, 0.013549805, 0.0098876953,
+ 0.0071105957, 0.0046081543, 0.0029296875, 0.0013122559,
+ 0.0002746582, -0.0014343262, -0.0029907227, -0.0065307617,
+ -0.009979248, -0.014831543, -0.02041626, -0.027008057, -0.036132812,
+ -0.043670654, -0.049591064, -0.053894043, -0.057312012,
+ -0.059570312, -0.059051514, -0.057617188, -0.05581665, -0.054962158,
+ -0.053283691, -0.051300049, -0.049591064, -0.049407959,
+ -0.049560547, -0.0496521, -0.04788208, -0.044830322, -0.040771484,
+ -0.03616333, -0.031066895, -0.024902344, -0.019226074, -0.014312744,
+ -0.010925293, -0.0085754395, -0.0065612793, -0.0048217773,
+ -0.0020141602, -0.00039672852, 0.0014648438, 0.003326416,
+ 0.0067749023, 0.009979248, 0.014068604, 0.016052246, 0.017486572,
+ 0.017700195, 0.018127441, 0.018066406, 0.017608643, 0.016845703,
+ 0.015838623, 0.014404297, 0.013214111, 0.011901855, 0.010650635,
+ 0.0085754395, 0.0069885254, 0.0051269531, 0.0030212402,
+ 0.00015258789, -0.0031738281, -0.0065307617, -0.0090637207,
+ -0.010498047, -0.011505127, -0.012023926, -0.01260376, -0.012115479,
+ -0.010406494, -0.0086975098, -0.0063781738, -0.005859375,
+ -0.0042114258, -0.0034179688, -0.0012207031, 0.00057983398,
+ 0.0030822754, 0.0048828125, 0.0070800781, 0.010040283, 0.013793945,
+ 0.01763916, 0.020935059, 0.024047852, 0.026245117, 0.02822876,
+ 0.028381348, 0.028015137, 0.027618408, 0.027496338, 0.0284729,
+ 0.029174805, 0.029815674, 0.030670166, 0.033081055, 0.035797119,
+ 0.037445068, 0.039154053, 0.039825439, 0.040283203, 0.03918457,
+ 0.036987305, 0.033874512, 0.02935791, 0.025177002, 0.020507812,
+ 0.016479492, 0.013031006, 0.010070801, 0.0077209473, 0.0056152344,
+ 0.003326416, 0.00048828125, -0.0017089844, -0.0030517578,
+ -0.0029602051, -0.003112793, -0.0025024414, -0.0024414062,
+ -0.0021362305, -0.0023498535, -0.0029907227, -0.0043029785,
+ -0.0059814453, -0.0078735352, -0.01083374, -0.013397217,
+ -0.016448975, -0.018890381, -0.020568848, -0.020080566, -0.01852417,
+ -0.016845703, -0.014007568, -0.0105896, -0.0066833496,
+ -0.0030517578, 0.0014953613, 0.0065002441, 0.0098571777,
+ 0.013122559, 0.014404297, 0.015472412, 0.016571045, 0.018035889,
+ 0.018585205, 0.018371582, 0.016540527, 0.014099121, 0.011413574,
+ 0.009185791, 0.0065917969, 0.0032653809, 0.00054931641,
+ -0.0018005371, -0.0024719238, -0.0046081543, -0.0062255859,
+ -0.0078430176, -0.009979248, -0.011627197, -0.015289307,
+ -0.017456055, -0.019897461, -0.022918701, -0.025543213,
+ -0.028747559, -0.031524658, -0.036865234, -0.041534424,
+ -0.045410156, -0.046875, -0.048126221, -0.049499512, -0.049163818,
+ -0.048828125, -0.047790527, -0.04574585, -0.043579102, -0.040924072,
+ -0.040222168, -0.038360596, -0.036895752, -0.034210205,
+ -0.031616211, -0.028289795, -0.024200439, -0.020294189,
+ -0.015838623, -0.011993408, -0.007598877, -0.0036010742,
+ 0.00054931641, 0.004486084, 0.0074157715, 0.0098571777, 0.012054443,
+ 0.01473999, 0.017700195, 0.019744873, 0.022399902, 0.02432251,
+ 0.025817871, 0.027130127, 0.027709961, 0.0284729, 0.027893066,
+ 0.027496338, 0.026580811, 0.025634766, 0.023681641, 0.021972656,
+ 0.019775391, 0.017730713, 0.016052246, 0.014556885, 0.014434814,
+ 0.013763428, 0.012268066, 0.0105896, 0.0091247559, 0.0077819824,
+ 0.0054626465, 0.0030822754, 0.00067138672, -0.0012207031,
+ -0.0028686523, -0.0048217773, -0.0047912598, -0.004486084,
+ -0.002746582, -0.00067138672, 0.0012512207, 0.0037231445,
+ 0.0054321289, 0.0074157715, 0.010192871, 0.013214111, 0.016448975,
+ 0.018005371, 0.019134521, 0.018463135, 0.017944336, 0.016723633,
+ 0.016448975, 0.01651001, 0.01651001, 0.017669678, 0.019622803,
+ 0.022064209, 0.024017334, 0.025909424, 0.026977539, 0.027008057,
+ 0.026733398, 0.025634766, 0.024261475, 0.022247314, 0.020202637,
+ 0.017730713, 0.01663208, 0.015319824, 0.014404297, 0.013092041,
+ 0.0098266602, 0.0065307617, 0.0032653809, 0.00061035156,
+ -0.0028076172, -0.0061340332, -0.0094909668, -0.012115479,
+ -0.013244629, -0.014251709, -0.015075684, -0.015808105,
+ -0.015991211, -0.016418457, -0.016601562, -0.01663208, -0.01675415,
+ -0.017333984, -0.018615723, -0.019775391, -0.02053833, -0.020721436,
+ -0.021820068, -0.022918701, -0.023651123, -0.023895264,
+ -0.023590088, -0.02331543, -0.022338867, -0.020141602, -0.017669678,
+ -0.014068604, -0.010528564, -0.0055236816, 0, 0.0051574707,
+ 0.008972168, 0.011291504, 0.012207031, 0.012420654, 0.01159668,
+ 0.0105896, 0.009185791, 0.0078735352, 0.0067749023, 0.0052490234,
+ 0.0040588379, 0.0025024414, 0.0013427734, 0.0014038086,
+ 0.0009765625, 0.00076293945, -0.00079345703, -0.0029907227,
+ -0.0054626465, -0.0073547363, -0.0095825195, -0.011383057,
+ -0.012237549, -0.013000488, -0.014373779, -0.016448975,
+ -0.018341064, -0.020446777, -0.02331543, -0.025909424, -0.02835083,
+ -0.028869629, -0.028839111, -0.028686523, -0.028106689,
+ -0.027740479, -0.027435303, -0.027313232, -0.026672363,
+ -0.025604248, -0.02355957, -0.020263672, -0.016204834, -0.011383057,
+ -0.0068359375, -0.0024719238, 0.00021362305, 0.0022583008,
+ 0.0036621094, 0.0053710938, 0.0079040527, 0.010162354, 0.013214111,
+ 0.016052246, 0.019042969, 0.022064209, 0.024871826, 0.027618408,
+ 0.029205322, 0.030761719, 0.031921387, 0.032012939, 0.032562256,
+ 0.032714844, 0.032958984, 0.032318115, 0.031860352, 0.030822754,
+ 0.03024292, 0.029510498, 0.028167725, 0.027099609, 0.024810791,
+ 0.022674561, 0.019958496, 0.018218994, 0.016143799, 0.014373779,
+ 0.012145996, 0.010101318, 0.0079345703, 0.0063476562, 0.0045471191,
+ 0.003112793, 0.00085449219, -0.00088500977, -0.002532959,
+ -0.0035095215, -0.0039672852, -0.0041503906, -0.0031433105,
+ -0.0017700195, -3.0517578e-05, 0.0010681152, 0.0033874512,
+ 0.0053405762, 0.0074768066, 0.0082397461, 0.0075683594, 0.007019043,
+ 0.005279541, 0.004486084, 0.0035400391, 0.0035400391, 0.0047607422,
+ 0.0061645508, 0.0079345703, 0.0090332031, 0.010314941, 0.010681152,
+ 0.010467529, 0.010467529, 0.009979248, 0.009765625, 0.0090637207,
+ 0.0083007812, 0.0075683594, 0.0065917969, 0.0066223145,
+ 0.0054626465, 0.0040893555, 0.0021362305, -3.0517578e-05,
+ -0.0024719238, -0.0052490234, -0.008026123, -0.010375977,
+ -0.012573242, -0.01461792, -0.01651001, -0.017822266, -0.018981934,
+ -0.019622803, -0.019592285, -0.020172119, -0.020751953,
+ -0.021728516, -0.022186279, -0.02230835, -0.02230835, -0.022155762,
+ -0.022583008, -0.022338867, -0.023193359, -0.023284912,
+ -0.023406982, -0.022766113, -0.022216797, -0.022094727,
+ -0.021484375, -0.021026611, -0.019836426, -0.018005371,
+ -0.015533447, -0.012512207, -0.0092773438, -0.0061340332,
+ -0.0029907227, 0.00076293945, 0.00390625, 0.0065002441,
+ 0.0084228516, 0.010070801, 0.011566162, 0.012054443, 0.012573242,
+ 0.011779785, 0.011077881, 0.010131836, 0.0088500977, 0.0075073242,
+ 0.0054321289, 0.0044555664, 0.003692627, 0.0032348633, 0.0028991699,
+ 0.0022583008, 0.0026245117, 0.0021972656, 0.001953125,
+ 0.00079345703, -0.001159668, -0.0028381348, -0.0046386719,
+ -0.0059814453, -0.0075378418, -0.0087890625, -0.010192871,
+ -0.01083374, -0.011993408, -0.012695312, -0.012756348, -0.012908936,
+ -0.012695312, -0.013061523, -0.012756348, -0.012145996,
+ -0.011352539, -0.010253906, -0.0094909668, -0.0081787109,
+ -0.0067138672, -0.0047912598, -0.0016784668, 0.00085449219,
+ 0.0041809082, 0.0070495605, 0.0098571777, 0.013061523, 0.016052246,
+ 0.019012451, 0.020965576, 0.022613525, 0.023590088, 0.024169922,
+ 0.02432251, 0.024078369, 0.024261475, 0.023681641, 0.024291992,
+ 0.024475098, 0.025390625, 0.026306152, 0.026641846, 0.027008057,
+ 0.026672363, 0.026641846, 0.026153564, 0.025482178, 0.024108887,
+ 0.022155762, 0.020050049, 0.017578125, 0.01461792, 0.011932373,
+ 0.0090332031, 0.0069580078, 0.0048828125, 0.0032653809, 0.001953125,
+ 0.0007019043, -0.00036621094, -0.0019226074, -0.0037536621,
+ -0.0056152344, -0.0076904297, -0.0087280273, -0.0090942383,
+ -0.0088195801, -0.0081481934, -0.0072937012, -0.006439209,
+ -0.005279541, -0.0043640137, -0.0034179688, -0.003112793,
+ -0.0025024414, -0.0022888184, -0.0019226074, -0.0015869141,
+ -0.0015869141, -0.0015258789, -0.0016784668, -0.0017700195,
+ -0.0016784668, -0.0013427734, -0.0011291504, -0.00061035156, 0,
+ 0.00079345703, 0.0012207031, 0.0015869141, 0.0016479492,
+ 0.0015258789, 0.0012817383, 0.00094604492, 0.00045776367,
+ -0.0002746582, -0.00088500977, -0.0016479492, -0.0024108887,
+ -0.0036621094, -0.0050354004, -0.0063476562, -0.0079956055,
+ -0.0096435547, -0.011535645, -0.013458252, -0.014953613,
+ -0.016296387, -0.017364502, -0.01776123, -0.018280029, -0.018371582,
+ -0.018035889, -0.017456055, -0.016479492, -0.015838623,
+ -0.015167236, -0.015228271, -0.015380859, -0.015625, -0.015716553,
+ -0.015411377, -0.015197754, -0.015106201, -0.01473999, -0.014221191,
+ -0.013092041, -0.012054443, -0.010742188, -0.008605957,
+ -0.006439209, -0.0038757324, -0.0016479492, 0.00079345703,
+ 0.0026550293, 0.0045471191, 0.0065612793, 0.009185791, 0.011566162,
+ 0.013427734, 0.014404297, 0.015075684, 0.015411377, 0.015319824,
+ 0.014801025, 0.013977051, 0.013305664, 0.012634277, 0.011932373,
+ 0.010864258, 0.0099182129, 0.0098571777, 0.0093994141, 0.0091247559,
+ 0.0080566406, 0.0068359375, 0.0056762695, 0.0043640137,
+ 0.0037841797, 0.0027770996, 0.0023803711, 0.0017700195,
+ 0.0010375977, 0, -0.0011901855, -0.0020446777, -0.0028991699,
+ -0.0037841797, -0.0050964355, -0.0057983398, -0.0063476562,
+ -0.0065917969, -0.0063781738, -0.0061950684, -0.0056152344,
+ -0.0050354004, -0.0045471191, -0.0035705566, -0.0025939941,
+ -0.00091552734, 0.00082397461, 0.0028076172, 0.0045471191,
+ 0.0061950684, 0.0078430176, 0.0096435547, 0.010742188, 0.011474609,
+ 0.012176514, 0.01260376, 0.013153076, 0.013458252, 0.014129639,
+ 0.014801025, 0.015228271, 0.015991211, 0.016204834, 0.01663208,
+ 0.016601562, 0.016357422, 0.015808105, 0.014770508, 0.014007568,
+ 0.012939453, 0.012268066, 0.011444092, 0.01071167, 0.010070801,
+ 0.0086975098, 0.0075683594, 0.0058288574, 0.0040588379,
+ 0.0018615723, 6.1035156e-05, -0.0015258789, -0.0029602051,
+ -0.0040283203, -0.0055236816, -0.0065307617, -0.0078735352,
+ -0.0090942383, -0.010131836, -0.010925293, -0.011260986,
+ -0.011322021, -0.011199951, -0.010955811, -0.010925293, -0.0105896,
+ -0.010375977, -0.0097351074, -0.0092163086, -0.0085754395,
+ -0.0077819824, -0.007232666, -0.0067443848, -0.0063171387,
+ -0.0060119629, -0.0053405762, -0.0050048828, -0.0045166016,
+ -0.0040588379, -0.0035400391, -0.0030517578, -0.0029907227,
+ -0.0027160645, -0.0028076172, -0.0025024414, -0.0021972656,
+ -0.001953125, -0.0013122559, -0.00091552734, -0.00033569336,
+ -0.00012207031, -0.00024414062, -0.00054931641, -0.0010375977,
+ -0.0018615723, -0.0028686523, -0.0036010742, -0.0042724609,
+ -0.0046691895, -0.0052490234, -0.0056152344, -0.0061035156,
+ -0.0066833496, -0.0074768066, -0.0083007812, -0.0089111328,
+ -0.0093688965, -0.0096435547, -0.0096740723, -0.0093994141,
+ -0.0086669922, -0.0079040527, -0.0073242188, -0.007019043,
+ -0.0067749023, -0.0067138672, -0.0064697266, -0.0060424805,
+ -0.0054931641, -0.0048828125, -0.0044250488, -0.0039367676,
+ -0.0031738281, -0.0024414062, -0.0014953613, -0.00039672852,
+ 0.0007019043, 0.001739502, 0.0028991699, 0.0042724609, 0.005645752,
+ 0.0072021484, 0.0087585449, 0.010192871, 0.011627197, 0.012542725,
+ 0.013244629, 0.01361084, 0.013671875, 0.013580322, 0.013122559,
+ 0.012512207, 0.012145996, 0.011993408, 0.011932373, 0.011779785,
+ 0.011352539, 0.010742188, 0.0099487305, 0.0090942383, 0.0079956055,
+ 0.0068054199, 0.0057373047, 0.0047912598, 0.004119873, 0.003326416,
+ 0.0027770996, 0.0021057129, 0.0015869141, 0.0010375977,
+ 0.00024414062, -0.00030517578, -0.00085449219, -0.0012512207,
+ -0.0015869141, -0.002166748, -0.0025939941, -0.0032043457,
+ -0.0038757324, -0.0043640137, -0.0044250488, -0.004486084,
+ -0.004119873, -0.0036621094, -0.0028381348, -0.0020751953,
+ -0.0012817383, -0.00064086914, -0.00012207031, 0.00051879883,
+ 0.0012512207, 0.002166748, 0.0032653809, 0.0042419434, 0.0049743652,
+ 0.0056152344, 0.0059509277, 0.0061645508, 0.0062866211,
+ 0.0061035156, 0.0059204102, 0.005645752, 0.005645752, 0.0054016113,
+ 0.0051879883, 0.0050354004, 0.0049133301, 0.0049133301, 0.004699707,
+ 0.0045776367, 0.0043640137, 0.0040283203, 0.0033569336,
+ 0.0025024414, 0.0013122559, 6.1035156e-05, -0.0009765625,
+ -0.0021972656, -0.0028076172, -0.0036010742, -0.0038452148,
+ -0.0042419434, -0.004699707, -0.0052185059, -0.0058898926,
+ -0.0064697266, -0.0073242188, -0.0082397461, -0.0091552734,
+ -0.0096740723, -0.0099182129, -0.0096435547, -0.0091552734,
+ -0.0085449219, -0.0079040527, -0.0074768066, -0.0068969727,
+ -0.0066223145, -0.0062561035, -0.005859375, -0.0055236816,
+ -0.0049438477, -0.0045471191, -0.0039672852, -0.0035095215,
+ -0.0030822754, -0.002746582, -0.0026245117, -0.0025939941,
+ -0.002532959, -0.0024414062, -0.0020141602, -0.0015869141,
+ -0.001159668, -0.00067138672, -0.0002746582, 0.00021362305,
+ 0.00033569336, 0.00045776367, 0.00051879883, 0.00064086914,
+ 0.00079345703, 0.00088500977, 0.00094604492, 0.00082397461,
+ 0.00064086914, 0.00030517578, 0.00015258789, -0.00024414062,
+ -0.00061035156, -0.0011901855, -0.0016174316, -0.0020446777,
+ -0.0022888184, -0.0023803711, -0.0023803711, -0.0023803711,
+ -0.0023498535, -0.0022888184, -0.0020446777, -0.0018005371,
+ -0.0014343262, -0.0011901855, -0.00088500977, -0.00064086914,
+ -0.00045776367, -0.00039672852, -0.00033569336, -0.00015258789, 0,
+ 0.00030517578, 0.00054931641, 0.0010375977, 0.001373291,
+ 0.0016784668, 0.001953125, 0.0023193359, 0.0028381348, 0.0035095215,
+ 0.0043334961, 0.0049133301, 0.0056152344, 0.006072998, 0.0065917969,
+ 0.0068664551, 0.0072021484, 0.0073547363, 0.0074768066,
+ 0.0075378418, 0.0073547363, 0.0070800781, 0.0066223145,
+ 0.0062866211, 0.005859375, 0.0054321289, 0.0050048828, 0.0045776367,
+ 0.0043334961, 0.0039978027, 0.003692627, 0.0032958984, 0.0029602051,
+ 0.0024108887, 0.0019226074, 0.0014343262, 0.00088500977,
+ 0.00054931641, 0.00012207031, -0.00015258789, -0.00045776367,
+ -0.00067138672, -0.0009765625, -0.0012512207, -0.0015869141,
+ -0.001953125, -0.0022888184, -3.0517578e-05, -3.0517578e-05,
+ -3.0517578e-05, -3.0517578e-05, -3.0517578e-05, -3.0517578e-05,
+ -3.0517578e-05, -3.0517578e-05, -3.0517578e-05, -6.1035156e-05,
+ -3.0517578e-05, -6.1035156e-05, -3.0517578e-05, -6.1035156e-05,
+ -6.1035156e-05, -3.0517578e-05, -3.0517578e-05, -3.0517578e-05,
+ -3.0517578e-05, -3.0517578e-05, -3.0517578e-05, -3.0517578e-05,
+ -3.0517578e-05, -3.0517578e-05, -3.0517578e-05, -3.0517578e-05,
+ -3.0517578e-05, -3.0517578e-05, 0,
+ };
+
+static const unsigned defaultClickEmphasisLength = sizeof(defaultClickEmphasis) / sizeof(*defaultClickEmphasis);
+
diff --git a/muse_qt4_evolution/muse/device.h b/muse_qt4_evolution/muse/device.h
new file mode 100644
index 00000000..6ccf13cf
--- /dev/null
+++ b/muse_qt4_evolution/muse/device.h
@@ -0,0 +1,56 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __DEVICE_H__
+#define __DEVICE_H__
+
+//---------------------------------------------------------
+// Device
+//---------------------------------------------------------
+
+class Device {
+
+ public:
+ enum DeviceType { MidiDevice, WaveDevice };
+
+ protected:
+ QString _name;
+ DeviceType _type;
+ int _port;
+
+ public:
+ Device() {}
+ virtual ~Device() {}
+ Device(const QString& name, DeviceType t = MidiDevice)
+ : _name(name), _type(t) {}
+
+ virtual QString open(int) = 0;
+ virtual void close() = 0;
+
+ const QString& name() const { return _name; }
+ void setName(const QString& s) { _name = s; }
+ const DeviceType type() const { return _type; }
+ void setDeviceType(DeviceType t) { _type = t; }
+ int port() const { return _port; }
+ void setPort(int p) { _port = p; }
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/driver.h b/muse_qt4_evolution/muse/driver.h
new file mode 100644
index 00000000..c8bbfc7f
--- /dev/null
+++ b/muse_qt4_evolution/muse/driver.h
@@ -0,0 +1,64 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __DRIVER_H__
+#define __DRIVER_H__
+
+#include <jack/midiport.h>
+#include "port.h"
+
+struct PortName {
+ Port port;
+ QString name;
+ };
+
+class MidiEvent;
+
+//---------------------------------------------------------
+// Driver
+// abstract driver base class; used for midi and
+// audio
+//---------------------------------------------------------
+
+class Driver {
+
+ public:
+ Driver() {}
+ virtual ~Driver() {}
+ virtual bool init() = 0;
+
+ virtual QList<PortName> outputPorts(bool midi) = 0;
+ virtual QList<PortName> inputPorts(bool midi) = 0;
+
+ virtual Port registerOutPort(const QString&, bool midi) = 0;
+ virtual Port registerInPort(const QString&, bool midi) = 0;
+ virtual void unregisterPort(Port) = 0;
+ virtual void setPortName(Port p, const QString&) = 0;
+ virtual QString portName(Port) = 0;
+ virtual Port findPort(const QString&) = 0;
+
+ virtual bool connect(Port, Port) = 0;
+ virtual bool disconnect(Port, Port) = 0;
+ virtual void putEvent(Port, const MidiEvent&) = 0;
+ virtual void updateConnections() {}
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/dssihost.cpp b/muse_qt4_evolution/muse/dssihost.cpp
new file mode 100644
index 00000000..f72d4740
--- /dev/null
+++ b/muse_qt4_evolution/muse/dssihost.cpp
@@ -0,0 +1,891 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "config.h"
+
+#ifdef DSSI_SUPPORT
+
+#include <signal.h>
+#include <dlfcn.h>
+#include <dssi.h>
+#include <alsa/asoundlib.h>
+
+#include "dssihost.h"
+#include "synth.h"
+#include "jackaudio.h"
+#include "midi.h"
+#include "al/al.h"
+#include "al/xml.h"
+#include "song.h"
+#include "midictrl.h"
+#include "ladspaplugin.h"
+
+static lo_server_thread serverThread;
+static char osc_path_tmp[1024];
+static char* url;
+
+//---------------------------------------------------------
+// oscError
+//---------------------------------------------------------
+
+static void oscError(int num, const char *msg, const char *path)
+ {
+ fprintf(stderr, "MusE: liblo server error %d in path %s: %s\n",
+ num, path, msg);
+ }
+
+//---------------------------------------------------------
+// oscDebugHandler
+//---------------------------------------------------------
+
+static int oscDebugHandler(const char* path, const char* types, lo_arg** argv,
+ int argc, void*, void*)
+ {
+ printf("MusE: got unhandled OSC message:\n path: <%s>\n", path);
+ for (int i = 0; i < argc; i++) {
+ printf(" arg %d '%c' ", i, types[i]);
+ lo_arg_pp(lo_type(types[i]), argv[i]);
+ printf("\n");
+ }
+ return 1;
+ }
+
+//---------------------------------------------------------
+// oscUpdate
+//---------------------------------------------------------
+
+int DssiSynthIF::oscUpdate(lo_arg **argv)
+ {
+ const char *url = (char *)&argv[0]->s;
+
+ if (uiTarget)
+ lo_address_free(uiTarget);
+ char* host = lo_url_get_hostname(url);
+ char* port = lo_url_get_port(url);
+ uiTarget = lo_address_new(host, port);
+ free(host);
+ free(port);
+
+ if (uiOscPath)
+ free(uiOscPath);
+ uiOscPath = lo_url_get_path(url);
+ int pl = strlen(uiOscPath);
+
+ if (uiOscControlPath)
+ free(uiOscControlPath);
+ uiOscControlPath = (char *)malloc(pl + 10);
+ sprintf(uiOscControlPath, "%s/control", uiOscPath);
+
+ if (uiOscConfigurePath)
+ free(uiOscConfigurePath);
+ uiOscConfigurePath = (char *)malloc(pl + 12);
+ sprintf(uiOscConfigurePath, "%s/configure", uiOscPath);
+
+ if (uiOscProgramPath)
+ free(uiOscProgramPath);
+ uiOscProgramPath = (char *)malloc(pl + 10);
+ sprintf(uiOscProgramPath, "%s/program", uiOscPath);
+
+ if (uiOscShowPath)
+ free(uiOscShowPath);
+ uiOscShowPath = (char *)malloc(pl + 10);
+ sprintf(uiOscShowPath, "%s/show", uiOscPath);
+
+ /* At this point a more substantial host might also call
+ * configure() on the UI to set any state that it had remembered
+ * for the plugin instance. But we don't remember state for
+ * plugin instances (see our own configure() implementation in
+ * osc_configure_handler), and so we have nothing to send except
+ * the optional project directory.
+ */
+
+ lo_send(uiTarget, uiOscConfigurePath, "ss",
+ DSSI_PROJECT_DIRECTORY_KEY, song->projectPath().toAscii().data());
+
+#if 0
+ /* Send current bank/program (-FIX- another race...) */
+ if (instance->pendingProgramChange < 0) {
+ unsigned long bank = instance->currentBank;
+ unsigned long program = instance->currentProgram;
+ instance->uiNeedsProgramUpdate = 0;
+ if (instance->uiTarget) {
+ lo_send(instance->uiTarget, instance->ui_osc_program_path, "ii", bank, program);
+ }
+ }
+
+ /* Send control ports */
+ for (i = 0; i < instance->plugin->controlIns; i++) {
+ int in = i + instance->firstControlIn;
+ int port = pluginControlInPortNumbers[in];
+ lo_send(instance->uiTarget, instance->ui_osc_control_path, "if", port,
+ pluginControlIns[in]);
+ /* Avoid overloading the GUI if there are lots and lots of ports */
+ if ((i+1) % 50 == 0)
+ usleep(300000);
+ }
+#endif
+ return 0;
+ }
+
+//---------------------------------------------------------
+// oscMessageHandler
+//---------------------------------------------------------
+
+int oscMessageHandler(const char* path, const char* types, lo_arg** argv,
+ int argc, void* data, void* user_data)
+ {
+ const char* p = path;
+ if (strncmp(p, "/dssi/", 6))
+ return oscDebugHandler(path, types, argv, argc, data, user_data);
+
+ p += 6;
+
+ SynthIList* sl = song->syntis();
+ DssiSynthIF* instance = 0;
+ SynthI* synti = 0;
+
+ for (iSynthI si = sl->begin(); si != sl->end(); ++si) {
+ int l = strlen((*si)->name().toAscii().data());
+ if (!strncmp(p, (*si)->name().toAscii().data(), l)) {
+ synti = *si;
+ instance = (DssiSynthIF*)(synti->sif());
+ p += l;
+ break;
+ }
+ }
+ if (!instance)
+ return oscDebugHandler(path, types, argv, argc, data, user_data);
+
+ if (*p != '/' || *(p + 1) == 0)
+ return oscDebugHandler(path, types, argv, argc, data, user_data);
+ ++p;
+
+ if (!strcmp(p, "configure") && argc == 2 && !strcmp(types, "ss"))
+ return instance->oscConfigure(argv);
+ else if (!strcmp(p, "control") && argc == 2 && !strcmp(types, "if"))
+ return instance->oscControl(argv);
+ else if (!strcmp(p, "midi") && argc == 1 && !strcmp(types, "m"))
+ return instance->oscMidi(argv);
+ else if (!strcmp(p, "program") && argc == 2 && !strcmp(types, "ii"))
+ return instance->oscProgram(argv);
+ else if (!strcmp(p, "update") && argc == 1 && !strcmp(types, "s"))
+ return instance->oscUpdate(argv);
+ else if (!strcmp(p, "exiting") && argc == 0)
+ return instance->oscExiting(argv);
+ return oscDebugHandler(path, types, argv, argc, data, user_data);
+ }
+
+//---------------------------------------------------------
+// scanDSSILib
+//---------------------------------------------------------
+
+static void scanDSSILib(const QFileInfo& fi)
+ {
+ void* handle = dlopen(fi.filePath().toAscii().data(), RTLD_NOW);
+ if (handle == 0) {
+ fprintf(stderr, "dlopen(%s) failed: %s\n",
+ fi.filePath().toAscii().data(), dlerror());
+ return;
+ }
+ DSSI_Descriptor_Function dssi = (DSSI_Descriptor_Function)dlsym(handle, "dssi_descriptor");
+
+ if (!dssi) {
+ const char *txt = dlerror();
+ if (txt) {
+ fprintf(stderr,
+ "Unable to find dssi_descriptor() function in plugin "
+ "library file \"%s\": %s.\n"
+ "Are you sure this is a DSSI plugin file?\n",
+ fi.filePath().toAscii().data(),
+ txt);
+ exit(1);
+ }
+ }
+ const DSSI_Descriptor* descr;
+ for (int i = 0;; ++i) {
+ descr = dssi(i);
+ if (descr == 0)
+ break;
+ QString label(descr->LADSPA_Plugin->Label);
+ DssiSynth* s = new DssiSynth(&fi, label);
+ synthis.push_back(s);
+ }
+ dlclose(handle);
+ }
+
+//---------------------------------------------------------
+// scanVstDir
+//---------------------------------------------------------
+
+static void scanDSSIDir(const QString& s)
+ {
+ if (debugMsg)
+ printf("scan DSSI plugin dir <%s>\n", s.toAscii().data());
+
+#ifdef __APPLE__
+ QDir pluginDir(s, QString("*.dylib"), QDir::Unsorted, QDir::Files);
+#else
+ QDir pluginDir(s, QString("*.so"), QDir::Unsorted, QDir::Files);
+#endif
+ if (!pluginDir.exists())
+ return;
+
+ const QFileInfoList list = pluginDir.entryInfoList();
+ for (int i = 0; i < list.size(); ++i) {
+ QFileInfo fi = list.at(i);
+ scanDSSILib(fi);
+ }
+ }
+
+//---------------------------------------------------------
+// initDSSI
+//---------------------------------------------------------
+
+void initDSSI()
+ {
+ const char* dssiPath = getenv("DSSI_PATH");
+ if (dssiPath == 0)
+ dssiPath = "/usr/lib/dssi:/usr/local/lib/dssi";
+
+ const char* p = dssiPath;
+ while (*p != '\0') {
+ const char* pe = p;
+ while (*pe != ':' && *pe != '\0')
+ pe++;
+
+ int n = pe - p;
+ if (n) {
+ char* buffer = new char[n + 1];
+ strncpy(buffer, p, n);
+ buffer[n] = '\0';
+ scanDSSIDir(QString(buffer));
+ delete[] buffer;
+ }
+ p = pe;
+ if (*p == ':')
+ p++;
+ }
+ // Create OSC thread
+
+ serverThread = lo_server_thread_new(0, oscError);
+ snprintf(osc_path_tmp, 31, "/dssi");
+ char* tmp = lo_server_thread_get_url(serverThread);
+ url = (char *)malloc(strlen(tmp) + strlen(osc_path_tmp));
+ sprintf(url, "%s%s", tmp, osc_path_tmp + 1);
+ free(tmp);
+
+ lo_server_thread_add_method(serverThread, 0, 0, oscMessageHandler, 0);
+ lo_server_thread_start(serverThread);
+ }
+
+//---------------------------------------------------------
+// guiVisible
+//---------------------------------------------------------
+
+bool DssiSynthIF::guiVisible() const
+ {
+ return _guiVisible;
+ }
+
+//---------------------------------------------------------
+// showGui
+//---------------------------------------------------------
+
+void DssiSynthIF::showGui(bool v)
+ {
+ if (v == guiVisible())
+ return;
+ for (int i = 0; i < 5; ++i) {
+ if (uiOscPath)
+ break;
+ sleep(1);
+ }
+ if (uiOscPath == 0) {
+ printf("DssiSynthIF::showGui(): no uiOscPath\n");
+ return;
+ }
+ char uiOscGuiPath[strlen(uiOscPath)+6];
+ sprintf(uiOscGuiPath, "%s/%s", uiOscPath, v ? "show" : "hide");
+ lo_send(uiTarget, uiOscGuiPath, "");
+ _guiVisible = v;
+ }
+
+//---------------------------------------------------------
+// receiveEvent
+//---------------------------------------------------------
+
+MidiEvent DssiSynthIF::receiveEvent()
+ {
+ return MidiEvent();
+ }
+
+//---------------------------------------------------------
+// init
+//---------------------------------------------------------
+
+bool DssiSynthIF::init(DssiSynth* s)
+ {
+ synth = s;
+ const DSSI_Descriptor* dssi = synth->dssi;
+ const LADSPA_Descriptor* ld = dssi->LADSPA_Plugin;
+ handle = ld->instantiate(ld, AL::sampleRate);
+
+ queryPrograms();
+
+ int controlPorts = synth->_controller;
+ controls = new LadspaPort[controlPorts];
+
+ for (int k = 0; k < controlPorts; ++k) {
+ int i = synth->pIdx[k];
+ controls[k].val = ladspaDefaultValue(ld, i);
+ ld->connect_port(handle, i, &controls[k].val);
+ }
+
+ if (ld->activate)
+ ld->activate(handle);
+
+ if (dssi->configure) {
+ char *rv = dssi->configure(handle, DSSI_PROJECT_DIRECTORY_KEY,
+ song->projectPath().toAscii().data());
+ if (rv)
+ fprintf(stderr, "MusE: Warning: plugin doesn't like project directory: \"%s\"\n", rv);
+ }
+ return true;
+ }
+
+//---------------------------------------------------------
+// DssiSynthIF
+//---------------------------------------------------------
+
+DssiSynthIF::DssiSynthIF(SynthI* s)
+ : SynthIF(s)
+ {
+ _guiVisible = false;
+ uiTarget = 0;
+ uiOscShowPath = 0;
+ uiOscControlPath = 0;
+ uiOscConfigurePath = 0;
+ uiOscProgramPath = 0;
+ uiOscPath = 0;
+ guiPid = -1;
+ }
+
+//---------------------------------------------------------
+// ~DssiSynthIF
+//---------------------------------------------------------
+
+DssiSynthIF::~DssiSynthIF()
+ {
+ const DSSI_Descriptor* dssi = synth->dssi;
+ const LADSPA_Descriptor* descr = dssi->LADSPA_Plugin;
+
+ if (descr->cleanup)
+ descr->cleanup(handle);
+ if (guiPid != -1)
+ kill(guiPid, SIGHUP);
+ }
+
+//---------------------------------------------------------
+// setParameter
+//---------------------------------------------------------
+
+void DssiSynthIF::setParameter(int, float)
+ {
+ }
+
+//---------------------------------------------------------
+// write
+//---------------------------------------------------------
+
+void DssiSynthIF::write(Xml&) const
+ {
+ }
+
+//---------------------------------------------------------
+// getData
+//---------------------------------------------------------
+
+void DssiSynthIF::getData(MidiEventList* el, unsigned pos, int ch, unsigned samples, float** data)
+ {
+ const DSSI_Descriptor* dssi = synth->dssi;
+ const LADSPA_Descriptor* descr = dssi->LADSPA_Plugin;
+
+ unsigned long nevents = el->size();
+
+ while (!synti->putFifo.isEmpty()) {
+ MidiEvent event = synti->putFifo.get();
+ printf("Dssi: FIFO\n");
+ }
+
+ snd_seq_event_t events[nevents];
+ memset(events, 0, sizeof(events));
+
+ nevents = 0;
+ unsigned endPos = pos + samples;
+ iMidiEvent i = el->begin();
+ for (; i != el->end(); ++i, ++nevents) {
+ if (i->time() >= endPos)
+ break;
+ MidiEvent e = *i;
+
+ int chn = e.channel();
+ int a = e.dataA();
+ int b = e.dataB();
+ //for sysex
+ QByteArray ba = QByteArray((const char*)e.data(), e.len());
+ //we must had 0xF0 at the beginning and 0xF7 at the end of e.data()
+ ba.push_front(0xF0);
+ ba.push_back(0xF7);
+ int len = e.len() + 2;
+
+
+ snd_seq_event_t* event = &events[nevents];
+ event->queue = SND_SEQ_QUEUE_DIRECT;
+
+ switch(e.type()) {
+ case ME_NOTEON:
+ if (b)
+ snd_seq_ev_set_noteon(event, chn, a, b);
+ else
+ snd_seq_ev_set_noteoff(event, chn, a, 0);
+ break;
+ case ME_NOTEOFF:
+ snd_seq_ev_set_noteoff(event, chn, a, 0);
+ break;
+ case ME_CONTROLLER:
+ if (a == CTRL_PROGRAM) {
+ int bank = b >> 8;
+ int prog = b & 0xff;
+ if (dssi->select_program)
+ dssi->select_program(handle, bank, prog);
+ break;
+ }
+ snd_seq_ev_set_controller(event, chn, a, b);
+ break;
+ case ME_PITCHBEND:
+ snd_seq_ev_set_pitchbend(event, chn, a);
+ break;
+ case ME_AFTERTOUCH:
+ snd_seq_ev_set_chanpress(event, chn, a);
+ break;
+ case ME_SYSEX:
+ snd_seq_ev_set_sysex(event, len,
+ (unsigned char*)ba.data());
+ break;
+ default:
+ --nevents;
+ break;
+ }
+ }
+ el->erase(el->begin(), i);
+ for (int k = 0; k < ch; ++k)
+ descr->connect_port(handle, synth->oIdx[k], data[k]);
+
+ if (synth->dssi->run_synth)
+ synth->dssi->run_synth(handle, samples, events, nevents);
+ else if (synth->dssi->run_multiple_synths) {
+ snd_seq_event_t* ev = events;
+ synth->dssi->run_multiple_synths(1, &handle, samples, &ev, &nevents);
+ }
+ }
+
+//---------------------------------------------------------
+// putEvent
+//---------------------------------------------------------
+
+bool DssiSynthIF::putEvent(const MidiEvent& ev)
+ {
+ if (midiOutputTrace)
+ ev.dump();
+ return false;
+ }
+
+//---------------------------------------------------------
+// incInstances
+//---------------------------------------------------------
+
+void DssiSynth::incInstances(int val)
+ {
+ _instances += val;
+ if (_instances == 0) {
+ if (handle)
+ dlclose(handle);
+ dssi = 0;
+ df = 0;
+ }
+ }
+
+//---------------------------------------------------------
+// createSIF
+//---------------------------------------------------------
+
+SynthIF* DssiSynth::createSIF(SynthI* synti)
+ {
+ if (_instances == 0) {
+ handle = dlopen(info.filePath().toAscii().data(), RTLD_NOW);
+ if (handle == 0) {
+ fprintf(stderr, "dlopen(%s) failed: %s\n",
+ info.filePath().toAscii().data(), dlerror());
+ return 0;
+ }
+ df = (DSSI_Descriptor_Function)dlsym(handle, "dssi_descriptor");
+
+ if (!df) {
+ const char *txt = dlerror();
+ fprintf(stderr,
+ "Unable to find dssi_descriptor() function in plugin "
+ "library file \"%s\": %s.\n"
+ "Are you sure this is a DSSI plugin file?\n",
+ info.filePath().toAscii().data(),
+ txt ? txt : "?");
+ dlclose(handle);
+ handle = 0;
+ return 0;
+ }
+ for (int i = 0;; ++i) {
+ dssi = df(i);
+ if (dssi == 0)
+ break;
+ QString label(dssi->LADSPA_Plugin->Label);
+ if (label == _name)
+ break;
+ }
+
+ _inports = 0;
+ _outports = 0;
+ _controller = 0;
+ const LADSPA_Descriptor* d = dssi->LADSPA_Plugin;
+ for (unsigned k = 0; k < d->PortCount; ++k) {
+ LADSPA_PortDescriptor pd = d->PortDescriptors[k];
+ if (LADSPA_IS_PORT_AUDIO(pd)) {
+ if (LADSPA_IS_PORT_INPUT(pd)) {
+ ++_inports;
+ iIdx.push_back(k);
+ }
+ else if (LADSPA_IS_PORT_OUTPUT(pd)) {
+ ++_outports;
+ oIdx.push_back(k);
+ }
+ }
+ else if (LADSPA_IS_PORT_CONTROL(pd)) {
+ if (LADSPA_IS_PORT_INPUT(pd)) {
+ ++_controller;
+ pIdx.push_back(k);
+ }
+ else {
+ // ??
+ }
+ }
+ }
+ }
+ if (dssi == 0) {
+ fprintf(stderr, "cannot found DSSI synti %s\n", _name.toAscii().data());
+ dlclose(handle);
+ handle = 0;
+ df = 0;
+ return 0;
+ }
+ DssiSynthIF* sif = new DssiSynthIF(synti);
+ ++_instances;
+ sif->init(this);
+
+ //
+ // start gui
+ //
+ static char oscUrl[1024];
+ snprintf(oscUrl, 1024, "%s/%s", url, synti->name().toAscii().data());
+
+ QString guiPath(info.path() + "/" + info.baseName());
+ QDir guiDir(guiPath, "*", QDir::Unsorted, QDir::Files);
+ if (guiDir.exists()) {
+ const QFileInfoList list = guiDir.entryInfoList();
+ for (int i = 0; i < list.size(); ++i) {
+ QFileInfo fi = list.at(i);
+ QString gui(fi.filePath());
+ if (gui.contains('_') == 0)
+ continue;
+ struct stat buf;
+ if (stat(gui.toAscii().data(), &buf)) {
+ perror("stat failed");
+ continue;
+ }
+
+ if ((S_ISREG(buf.st_mode) || S_ISLNK(buf.st_mode)) &&
+ (buf.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) {
+ if ((sif->guiPid = fork()) == 0) {
+ execlp(
+ fi.filePath().toAscii().data(),
+ fi.fileName().toAscii().data(),
+ oscUrl,
+ info.filePath().toAscii().data(),
+ name().toAscii().data(),
+ "channel 1", (void*)0);
+ fprintf(stderr, "exec %s %s %s %s failed: %s\n",
+ fi.filePath().toAscii().data(),
+ fi.fileName().toAscii().data(),
+ oscUrl,
+ name().toAscii().data(),
+ strerror(errno));
+ exit(1);
+ }
+ }
+ }
+ _hasGui = true;
+ }
+ else {
+ printf("%s: no dir for dssi gui found: %s\n",
+ name().toAscii().data(), guiPath.toAscii().data());
+ _hasGui = false;
+ }
+ return sif;
+ }
+
+//---------------------------------------------------------
+// oscProgram
+//---------------------------------------------------------
+
+int DssiSynthIF::oscProgram(lo_arg** argv)
+ {
+ int bank = argv[0]->i;
+ int program = argv[1]->i;
+ int ch = 0; // TODO: ??
+ MidiEvent event(0, ch, ME_CONTROLLER, CTRL_PROGRAM, (bank << 8) + program);
+ synti->playMidiEvent(&event);
+ return 0;
+ }
+
+//---------------------------------------------------------
+// oscControl
+//---------------------------------------------------------
+
+int DssiSynthIF::oscControl(lo_arg**)
+ {
+printf("received oscControl\n");
+#if 0
+ int port = argv[0]->i;
+ LADSPA_Data value = argv[1]->f;
+
+ if (port < 0 || port > instance->plugin->descriptor->LADSPA_Plugin->PortCount) {
+ fprintf(stderr, "MusE: OSC: %s port number (%d) is out of range\n",
+ instance->friendly_name, port);
+ return 0;
+ }
+ if (instance->pluginPortControlInNumbers[port] == -1) {
+ fprintf(stderr, "MusE: OSC: %s port %d is not a control in\n",
+ instance->friendly_name, port);
+ return 0;
+ }
+ pluginControlIns[instance->pluginPortControlInNumbers[port]] = value;
+ if (verbose) {
+ printf("MusE: OSC: %s port %d = %f\n",
+ instance->friendly_name, port, value);
+ }
+#endif
+ return 0;
+ }
+
+//---------------------------------------------------------
+// oscExiting
+//---------------------------------------------------------
+
+int DssiSynthIF::oscExiting(lo_arg**)
+ {
+ printf("not impl.: oscExiting\n");
+#if 0
+ int i;
+
+ if (verbose) {
+ printf("MusE: OSC: got exiting notification for instance %d\n",
+ instance->number);
+ }
+
+ if (instance->plugin) {
+
+ /*!!! No, this isn't safe -- plugins deactivated in this way
+ would still be included in a run_multiple_synths call unless
+ we re-jigged the instance array at the same time -- leave it
+ for now
+ if (instance->plugin->descriptor->LADSPA_Plugin->deactivate) {
+ instance->plugin->descriptor->LADSPA_Plugin->deactivate
+ (instanceHandles[instance->number]);
+ }
+ */
+ /* Leave this flag though, as we need it to determine when to exit */
+ instance->inactive = 1;
+ }
+
+ /* Do we have any plugins left running? */
+
+ for (i = 0; i < instance_count; ++i) {
+ if (!instances[i].inactive)
+ return 0;
+ }
+
+ if (verbose) {
+ printf("MusE: That was the last remaining plugin, exiting...\n");
+ }
+ exiting = 1;
+#endif
+ return 0;
+ }
+
+//---------------------------------------------------------
+// oscMidi
+//---------------------------------------------------------
+
+int DssiSynthIF::oscMidi(lo_arg** argv)
+ {
+ int a = argv[0]->m[1];
+ int b = argv[0]->m[2];
+ int c = argv[0]->m[3];
+ if (a == ME_NOTEOFF) {
+ a = ME_NOTEON;
+ c = 0;
+ }
+ int channel = 0;
+ MidiEvent event(0, channel, a, b, c);
+ synti->playMidiEvent(&event);
+ return 0;
+ }
+
+//---------------------------------------------------------
+// oscConfigure
+//---------------------------------------------------------
+
+int DssiSynthIF::oscConfigure(lo_arg** argv)
+ {
+ if (!synth->dssi->configure)
+ return 0;
+
+ const char *key = (const char *)&argv[0]->s;
+ const char *value = (const char *)&argv[1]->s;
+
+ /* This is pretty much the simplest legal implementation of
+ * configure in a DSSI host. */
+
+ /* The host has the option to remember the set of (key,value)
+ * pairs associated with a particular instance, so that if it
+ * wants to restore the "same" instance on another occasion it can
+ * just call configure() on it for each of those pairs and so
+ * restore state without any input from a GUI. Any real-world GUI
+ * host will probably want to do that. This host doesn't have any
+ * concept of restoring an instance from one run to the next, so
+ * we don't bother remembering these at all. */
+
+ if (!strncmp(key, DSSI_RESERVED_CONFIGURE_PREFIX,
+ strlen(DSSI_RESERVED_CONFIGURE_PREFIX))) {
+ fprintf(stderr, "MusE: OSC: UI for plugin '%s' attempted to use reserved configure key \"%s\", ignoring\n",
+ synti->name().toAscii().data(), key);
+ return 0;
+ }
+
+ char* message = synth->dssi->configure(handle, key, value);
+ if (message) {
+ printf("MusE: on configure '%s' '%s', plugin '%s' returned error '%s'\n",
+ key, value, synti->name().toAscii().data(), message);
+ free(message);
+ }
+
+ // also call back on UIs for plugins other than the one
+ // that requested this:
+ // if (n != instance->number && instances[n].uiTarget) {
+ // lo_send(instances[n].uiTarget,
+ // instances[n].ui_osc_configure_path, "ss", key, value);
+ // }
+
+ /* configure invalidates bank and program information, so
+ we should do this again now: */
+ queryPrograms();
+ return 0;
+ }
+
+//---------------------------------------------------------
+// queryPrograms
+//---------------------------------------------------------
+
+void DssiSynthIF::queryPrograms()
+ {
+ for (std::vector<DSSI_Program_Descriptor>::const_iterator i = programs.begin();
+ i != programs.end(); ++i) {
+ free((void*)(i->Name));
+ }
+ programs.clear();
+
+ if (!(synth->dssi->get_program && synth->dssi->select_program))
+ return;
+
+ for (int i = 0;; ++i) {
+ const DSSI_Program_Descriptor* pd = synth->dssi->get_program(handle, i);
+ if (pd == 0)
+ break;
+ DSSI_Program_Descriptor d;
+ d.Name = strdup(pd->Name);
+ d.Program = pd->Program;
+ d.Bank = pd->Bank;
+ programs.push_back(d);
+ }
+ }
+
+//---------------------------------------------------------
+// getPatchName
+//---------------------------------------------------------
+
+QString DssiSynthIF::getPatchName(int, int prog)
+ {
+ unsigned program = prog & 0x7f;
+ int lbank = (prog >> 8) & 0xff;
+ int hbank = (prog >> 16) & 0xff;
+
+ if (lbank == 0xff)
+ lbank = 0;
+ if (hbank == 0xff)
+ hbank = 0;
+ unsigned bank = (hbank << 8) + lbank;
+
+ for (std::vector<DSSI_Program_Descriptor>::const_iterator i = programs.begin();
+ i != programs.end(); ++i) {
+ if (i->Bank == bank && i->Program ==program)
+ return i->Name;
+ }
+ return "?";
+ }
+
+//---------------------------------------------------------
+// populatePatchPopup
+//---------------------------------------------------------
+
+void DssiSynthIF::populatePatchPopup(QMenu* menu, int)
+ {
+ menu->clear();
+
+ for (std::vector<DSSI_Program_Descriptor>::const_iterator i = programs.begin();
+ i != programs.end(); ++i) {
+ int bank = i->Bank;
+ int prog = i->Program;
+ int id = (bank << 16) + prog;
+ QAction* a = menu->addAction(QString(i->Name));
+ a->setData(id);
+ }
+ }
+
+#else
+void initDSSI() {}
+#endif
+
diff --git a/muse_qt4_evolution/muse/dssihost.h b/muse_qt4_evolution/muse/dssihost.h
new file mode 100644
index 00000000..0ec251ac
--- /dev/null
+++ b/muse_qt4_evolution/muse/dssihost.h
@@ -0,0 +1,121 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __DSSIHOST_H__
+#define __DSSIHOST_H__
+
+#include <lo/lo.h>
+#include "synth.h"
+#include "plugin.h"
+
+struct _DSSI;
+class DssiPluginIF;
+class LadspaPort;
+
+//---------------------------------------------------------
+// DssiSynth
+//---------------------------------------------------------
+
+class DssiSynth : public Synth {
+ protected:
+ char* label;
+ void* handle;
+ const DSSI_Descriptor* dssi;
+ DSSI_Descriptor_Function df;
+ std::vector<int> pIdx;
+ std::vector<int> iIdx;
+ std::vector<int> oIdx;
+ int _inports, _outports, _controller;
+ bool _hasGui;
+
+ public:
+ DssiSynth(const QFileInfo* fi, QString l) : Synth(fi, l) {
+ df = 0;
+ handle = 0;
+ dssi = 0;
+ _hasGui = false;
+ }
+ virtual ~DssiSynth() {
+ delete label;
+ }
+ virtual void incInstances(int val);
+ virtual SynthIF* createSIF(SynthI*);
+ friend class DssiSynthIF;
+ float defaultValue(int);
+ };
+
+//---------------------------------------------------------
+// DssiSynthIF
+// VSTi synthesizer instance
+//---------------------------------------------------------
+
+class DssiSynthIF : public SynthIF
+ {
+ bool _guiVisible;
+ DssiSynth* synth;
+ LADSPA_Handle handle;
+ LadspaPort* controls;
+ void* uiTarget;
+ char* uiOscShowPath;
+ char* uiOscControlPath;
+ char* uiOscConfigurePath;
+ char* uiOscProgramPath;
+ char* uiOscPath;
+
+ std::vector<DSSI_Program_Descriptor> programs;
+ void queryPrograms();
+
+ protected:
+ int guiPid;
+
+ public:
+ DssiSynthIF(SynthI* s);
+ virtual ~DssiSynthIF();
+
+ virtual bool guiVisible() const;
+ virtual void showGui(bool v);
+ virtual bool hasGui() const { return synth->_hasGui; }
+ virtual void getGeometry(int*, int*, int*, int*) const {}
+ virtual void setGeometry(int, int, int, int) {}
+ virtual void getData(MidiEventList*, unsigned pos, int ports, unsigned n, float** buffer) ;
+ virtual bool putEvent(const MidiEvent& ev);
+ virtual MidiEvent receiveEvent();
+ virtual int eventsPending() const { return 0; }
+ virtual int channels() const { return synth->_outports; }
+ virtual void deactivate3() {}
+ virtual QString getPatchName(int, int);
+ virtual void populatePatchPopup(QMenu*, int);
+ virtual void write(Xml& xml) const;
+ virtual void setParameter(int idx, float value);
+ virtual int getControllerInfo(int, const char**, int*, int*, int*) { return 0; }
+ bool init(DssiSynth* s);
+
+ int oscUpdate(lo_arg**);
+ int oscProgram(lo_arg**);
+ int oscControl(lo_arg**);
+ int oscExiting(lo_arg**);
+ int oscMidi(lo_arg**);
+ int oscConfigure(lo_arg**);
+
+ friend class DssiSynth;
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/dummyaudio.cpp b/muse_qt4_evolution/muse/dummyaudio.cpp
new file mode 100644
index 00000000..b4bc73ff
--- /dev/null
+++ b/muse_qt4_evolution/muse/dummyaudio.cpp
@@ -0,0 +1,294 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "al/al.h"
+#include "widgets/utils.h"
+#include "audio.h"
+#include "audiodev.h"
+#include "globals.h"
+#include "song.h"
+
+static const unsigned dummyFrames = 1024;
+static double startTime;
+
+//---------------------------------------------------------
+// DummyAudio
+//---------------------------------------------------------
+
+class DummyAudio : public AudioDriver {
+ float* buffer;
+ pthread_t dummyThread;
+ std::vector<QString> oPorts;
+ std::vector<QString> iPorts;
+ int realTimePriority;
+
+ public:
+ int state;
+ bool seekflag;
+ unsigned pos;
+
+ DummyAudio() {
+ state = Audio::STOP;
+ seekflag = false;
+ startTime = curTime();
+ posix_memalign((void**)&buffer, 16, sizeof(float) * dummyFrames);
+ }
+ virtual ~DummyAudio() {
+ free(buffer);
+ }
+
+ virtual bool init() { return true; }
+ virtual void start(int);
+ virtual void stop ();
+ virtual unsigned frameTime() const {
+ return lrint(curTime() * AL::sampleRate);
+ }
+ virtual unsigned lastFrameTime() const {
+ return lrint(startTime * AL::sampleRate);
+ }
+ virtual unsigned curFrame() const { return pos; }
+
+ virtual float* getBuffer(Port /*port*/, unsigned long nframes)
+ {
+ if (nframes > dummyFrames) {
+ fprintf(stderr, "error: segment size > %d\n", dummyFrames);
+ exit(-1);
+ }
+ memset(buffer, 0, nframes * sizeof(float));
+ return buffer;
+ }
+
+ virtual QList<PortName> outputPorts(bool midi = false);
+ virtual QList<PortName> inputPorts(bool midi = false);
+
+ virtual void registerClient() {}
+
+ virtual Port registerOutPort(const QString& s, bool) {
+ iPorts.push_back(QString(s));
+ Port port(0, iPorts.size() + 3000);
+ return port;
+ }
+ virtual Port registerInPort(const QString& s, bool) {
+ oPorts.push_back(QString(s));
+ Port port(0, oPorts.size() + 40);
+ return port;
+ }
+ virtual void unregisterPort(Port) {
+/* if (long(p) >= 100)
+ oPorts.erase(oPorts.begin() + (long(p)-40));
+ else
+ iPorts.erase(iPorts.begin() + long(p)-30);
+*/
+ }
+ virtual bool connect(Port, Port) { return true; }
+ virtual bool disconnect(Port, Port) { return true; }
+ virtual void setPortName(Port, const QString&) {}
+ virtual Port findPort(const QString& s) {
+ if (s == "input1")
+ return Port(0, 10);
+ if (s == "input2")
+ return Port(0, 11);
+ if (s == "output1")
+ return Port(0, 20);
+ if (s == "output2")
+ return Port(0, 21);
+ int k = 0;
+ for (std::vector<QString>::const_iterator i = iPorts.begin(); i != iPorts.end(); ++i, ++k) {
+ if (s == *i)
+ return Port(0, 30+k);
+ }
+ k = 0;
+ for (std::vector<QString>::const_iterator i = oPorts.begin(); i != oPorts.end(); ++i, ++k) {
+ if (s == *i)
+ return Port(0, 40);
+ }
+ return Port();
+ }
+ virtual QString portName(Port port) {
+ if (port.alsaPort() == 10)
+ return QString("input1");
+ if (port.alsaPort() == 11)
+ return QString("input2");
+ if (port.alsaPort() == 20)
+ return QString("output1");
+ if (port.alsaPort() == 21)
+ return QString("output2");
+ if (port.alsaPort() >= 40)
+ return QString(oPorts[port.alsaPort() - 40]);
+ else
+ return QString(iPorts[port.alsaPort() - 30]);
+ }
+ virtual int realtimePriority() const { return 40; }
+ virtual void startTransport() {
+ state = Audio::PLAY;
+ }
+ virtual void stopTransport() {
+ state = Audio::STOP;
+ }
+ virtual void seekTransport(unsigned n) {
+ seekflag = true;
+ pos = n;
+ }
+ virtual void setFreewheel(bool) {}
+ virtual void putEvent(Port, const MidiEvent&) {}
+ };
+
+DummyAudio* dummyAudio;
+
+//---------------------------------------------------------
+// initDummyAudio
+//---------------------------------------------------------
+
+bool initDummyAudio()
+ {
+ dummyAudio = new DummyAudio();
+ audioDriver = dummyAudio;
+ return false;
+ }
+
+//---------------------------------------------------------
+// outputPorts
+//---------------------------------------------------------
+
+QList<PortName> DummyAudio::outputPorts(bool midi)
+ {
+ QList<PortName> clientList;
+ if (!midi) {
+ PortName p1;
+ p1.name = QString("output1");
+ p1.port = Port(0, 100);
+ PortName p2;
+ p2.name = QString("output2");
+ p2.port = Port(0, 101);
+ clientList.append(p1);
+ clientList.append(p2);
+ }
+ return clientList;
+ }
+
+//---------------------------------------------------------
+// inputPorts
+//---------------------------------------------------------
+
+QList<PortName> DummyAudio::inputPorts(bool midi)
+ {
+ QList<PortName> clientList;
+ if (!midi) {
+ PortName p1;
+ p1.name = QString("input1");
+ p1.port = Port(0, 0);
+ PortName p2;
+ p2.name = QString("input2");
+ p2.port = Port(0, 1);
+ clientList.append(p1);
+ clientList.append(p2);
+ }
+ return clientList;
+ }
+
+//---------------------------------------------------------
+// dummyLoop
+//---------------------------------------------------------
+
+static void* dummyLoop(void*)
+ {
+#ifndef __APPLE__
+ if (realTimePriority) {
+ //
+ // check if we really got realtime priviledges
+ //
+ int policy;
+ if ((policy = sched_getscheduler (0)) < 0) {
+ printf("cannot get current client scheduler for audio dummy thread: %s!\n", strerror(errno));
+ }
+ else
+ {
+ if (policy != SCHED_FIFO)
+ printf("audio dummy thread _NOT_ running SCHED_FIFO\n");
+ else if (debugMsg) {
+ struct sched_param rt_param;
+ memset(&rt_param, 0, sizeof(sched_param));
+ int type;
+ int rv = pthread_getschedparam(pthread_self(), &type, &rt_param);
+ if (rv == -1)
+ perror("get scheduler parameter");
+ printf("audio dummy thread running SCHED_FIFO priority %d\n",
+ rt_param.sched_priority);
+ }
+ }
+ }
+#endif
+
+ for (;;) {
+ if (audioState == AUDIO_RUNNING)
+ audio->process(segmentSize, dummyAudio->state);
+ else if (audioState == AUDIO_START1)
+ audioState = AUDIO_START2;
+ usleep(dummyFrames*1000000/AL::sampleRate);
+ if (dummyAudio->seekflag) {
+ audio->sync(Audio::STOP, dummyAudio->pos);
+ dummyAudio->seekflag = false;
+ }
+ if (dummyAudio->state == Audio::PLAY) {
+ dummyAudio->pos += dummyFrames;
+ }
+ }
+ pthread_exit(0);
+ }
+
+//---------------------------------------------------------
+// start
+//---------------------------------------------------------
+
+void DummyAudio::start(int priority)
+ {
+ realTimePriority = priority;
+ pthread_attr_t* attributes = 0;
+
+ if (priority) {
+ attributes = (pthread_attr_t*) malloc(sizeof(pthread_attr_t));
+ pthread_attr_init(attributes);
+
+ if (pthread_attr_setschedpolicy(attributes, SCHED_FIFO)) {
+ printf("cannot set FIFO scheduling class for RT thread\n");
+ }
+ if (pthread_attr_setscope (attributes, PTHREAD_SCOPE_SYSTEM)) {
+ printf("Cannot set scheduling scope for RT thread\n");
+ }
+ struct sched_param rt_param;
+ memset(&rt_param, 0, sizeof(rt_param));
+ rt_param.sched_priority = priority;
+ if (pthread_attr_setschedparam (attributes, &rt_param)) {
+ printf("Cannot set scheduling priority %d for RT thread (%s)\n",
+ priority, strerror(errno));
+ }
+ }
+ if (pthread_create(&dummyThread, attributes, ::dummyLoop, this))
+ perror("creating thread failed:");
+ if (priority)
+ pthread_attr_destroy(attributes);
+ }
+
+void DummyAudio::stop ()
+ {
+ pthread_cancel(dummyThread);
+ pthread_join(dummyThread, 0);
+ }
+
diff --git a/muse_qt4_evolution/muse/editor.cpp b/muse_qt4_evolution/muse/editor.cpp
new file mode 100644
index 00000000..a37e1baa
--- /dev/null
+++ b/muse_qt4_evolution/muse/editor.cpp
@@ -0,0 +1,38 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "editor.h"
+
+//---------------------------------------------------------
+// Editor
+//---------------------------------------------------------
+
+Editor::Editor()
+ {
+ tcanvas = 0;
+ }
+
+//---------------------------------------------------------
+// MidiEditor
+//---------------------------------------------------------
+
+Editor::~Editor()
+ {
+ }
diff --git a/muse_qt4_evolution/muse/editor.h b/muse_qt4_evolution/muse/editor.h
new file mode 100644
index 00000000..7de2d9e4
--- /dev/null
+++ b/muse_qt4_evolution/muse/editor.h
@@ -0,0 +1,44 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __EDITOR_H__
+#define __EDITOR_H__
+
+#include "cobject.h"
+
+class TimeCanvas;
+
+//---------------------------------------------------------
+// Editor
+//---------------------------------------------------------
+
+class Editor : public TopWin {
+ Q_OBJECT
+
+ protected:
+ TimeCanvas* tcanvas;
+
+ public:
+ Editor();
+ virtual ~Editor();
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/esettings.cpp b/muse_qt4_evolution/muse/esettings.cpp
new file mode 100644
index 00000000..7d3886f0
--- /dev/null
+++ b/muse_qt4_evolution/muse/esettings.cpp
@@ -0,0 +1,773 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2004 Mathias Lundgren <lunar_shuttle@users.sourceforge.net>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "esettings.h"
+#include "al/xml.h"
+#include "midieditor.h" //only for debug prints
+
+//---------------------------------------------------------
+// readStatus
+//---------------------------------------------------------
+
+void CtrlEditSettings::readStatus(QDomNode node)
+ {
+ while (!node.isNull()) {
+ QDomElement e = node.toElement();
+ QString tag = e.tagName();
+ QString s = e.text();
+ int i = s.toInt();
+ if (tag == "controller")
+ controller = i;
+ else if (tag == "height")
+ height = i;
+ else
+ printf("MusE:CtrlEditSettings: unknown tag: %s\n", e.tagName().toAscii().data());
+ node = node.nextSibling();
+ }
+ }
+
+//---------------------------------------------------------
+// writeStatus
+//---------------------------------------------------------
+
+void CtrlEditSettings::writeStatus(Xml& xml)
+ {
+ xml.tag("ctrleditsettings");
+ xml.intTag("height", height);
+ xml.intTag("controller", controller);
+ xml.etag("ctrleditsettings");
+ }
+
+//---------------------------------------------------------
+// readStatus
+//---------------------------------------------------------
+
+void EditorSettings::readStatus(QDomNode node)
+ {
+ while (!node.isNull()) {
+ QDomElement e = node.toElement();
+ QString tag = e.tagName();
+ QString s = e.text();
+ int i = s.toInt();
+ if (tag == "width")
+ _width = i;
+ else if (tag == "height")
+ _height = i;
+ else if (tag == "x")
+ _x = i;
+ else if (tag == "y")
+ _y = i;
+ else if (tag == "raster")
+ _raster = i;
+ else
+ printf("MusE:EditorSettings: unknown tag %s\n", e.tagName().toAscii().data());
+ node = node.nextSibling();
+ }
+ }
+
+//---------------------------------------------------------
+// writeStatus
+//---------------------------------------------------------
+
+void EditorSettings::writeStatus(Xml& xml) const
+ {
+ xml.tag("editorsettings");
+ xml.intTag("width", _width);
+ xml.intTag("height", _height);
+ xml.intTag("x", _x);
+ xml.intTag("y", _y);
+ xml.intTag("raster", _raster);
+ xml.etag("editorsettings");
+ }
+
+//---------------------------------------------------------
+// readStatus
+//---------------------------------------------------------
+
+void GraphEditorSettings::readStatus(QDomNode node)
+ {
+ while (!node.isNull()) {
+ QDomElement e = node.toElement();
+ QString tag = e.tagName();
+ QString s = e.text();
+ int i = s.toInt();
+ if (tag == "editorsettings") {
+ EditorSettings::readStatus(node.firstChild());
+ }
+ else if (tag == "xmag")
+ _xmag = s.toDouble();
+ else if (tag == "ymag")
+ _ymag = s.toDouble();
+ else if (tag == "xpos")
+ _pos.setX(i);
+ else if (tag == "ypos")
+ _pos.setY(i);
+ else
+ printf("MusE:GraphEditorSettings: unknown tag %s\n", e.tagName().toAscii().data());
+ node = node.nextSibling();
+ }
+ }
+
+//---------------------------------------------------------
+// writeStatus
+//---------------------------------------------------------
+
+void GraphEditorSettings::writeStatus(Xml& xml) const
+ {
+ xml.tag("grapheditorsettings");
+ EditorSettings::writeStatus(xml);
+ xml.doubleTag("xmag", _xmag);
+ xml.doubleTag("ymag", _ymag);
+ xml.intTag("xpos", _pos.x());
+ xml.intTag("ypos", _pos.y());
+ xml.etag("grapheditorsettings");
+ }
+
+bool ExtEditorSettings::_steprec = false;
+bool ExtEditorSettings::_midiin = false;
+
+
+//---------------------------------------------------------
+// ExtEditorSettings constructor
+//---------------------------------------------------------
+
+ExtEditorSettings::ExtEditorSettings(int r, int w, int h, int x, int y, double xm, double ym, QPoint pos, int q, int apply)
+ : GraphEditorSettings(r, w, h, x, y, xm, ym, pos), _quant(q), _applyTo(apply)
+ {
+ for (int i=0; i<MAXNOOFCTRLEDITSETTINGS; i++)
+ ctrlEdits[i] = 0;
+ _numOfCtrlEdits = 0;
+ }
+
+//---------------------------------------------------------
+// ExtEditorSettings destructor
+//---------------------------------------------------------
+ExtEditorSettings::~ExtEditorSettings()
+ {
+ for (int i=0; i<MAXNOOFCTRLEDITSETTINGS; i++) {
+ if (this->ctrlEdits[i])
+ delete ctrlEdits[i];
+ }
+ }
+
+//---------------------------------------------------------
+// setControlEditSettings
+//---------------------------------------------------------
+
+void ExtEditorSettings::setControlEditSettings(int pos, CtrlEditSettings* c)
+ {
+ if (ctrlEdits[pos])
+ delete ctrlEdits[pos];
+
+ ctrlEdits[pos] = c;
+ }
+//---------------------------------------------------------
+// clone
+//---------------------------------------------------------
+
+EditorSettings* ExtEditorSettings::clone()
+ {
+ ExtEditorSettings* newSettings = new ExtEditorSettings(_raster, _width, _height, _x, _y, _xmag, _ymag, _pos, _quant, _applyTo);
+ CtrlEditSettings* c;
+ for (int i=0; i<_numOfCtrlEdits; i++) {
+ c = new CtrlEditSettings();
+ *c = *(ctrlEdits[i]); //copy
+ newSettings->setControlEditSettings(i, c);
+ }
+ newSettings->setControlEditSize(_numOfCtrlEdits);
+ return (EditorSettings*) newSettings;
+ }
+
+//---------------------------------------------------------
+// readStatic
+//---------------------------------------------------------
+
+void ExtEditorSettings::readStatic(QDomNode node)
+ {
+ while (!node.isNull()) {
+ QDomElement e = node.toElement();
+ QString tag = e.tagName();
+ QString s = e.text();
+ int i = s.toInt();
+ if (tag == "steprec")
+ _steprec = i;
+ else if (tag == "midiin")
+ _midiin = i;
+ else
+ printf("MusE:ExtEditorSettings Static: unknown tag %s\n", e.tagName().toAscii().data());
+ node = node.nextSibling();
+ }
+ }
+
+//---------------------------------------------------------
+// writeStatic
+//---------------------------------------------------------
+
+void ExtEditorSettings::writeStatic(Xml& xml)
+ {
+ xml.tag("exteditorstatic");
+ xml.intTag("steprec", _steprec);
+ xml.intTag("midiin", _midiin);
+ xml.etag("exteditorstatic");
+ }
+
+//---------------------------------------------------------
+// readStatus
+//---------------------------------------------------------
+
+void ExtEditorSettings::readStatus(QDomNode node)
+ {
+ while (!node.isNull()) {
+ QDomElement e = node.toElement();
+ QString tag = e.tagName();
+ QString s = e.text();
+ int i = s.toInt();
+ if (tag == "grapheditorsettings")
+ GraphEditorSettings::readStatus(node.firstChild());
+ else if (tag == "quant")
+ _quant = i;
+ else if (tag == "applyTo")
+ _applyTo = i;
+ else if (tag == "steprec")
+ _steprec = i;
+ else if (tag == "midiin")
+ _midiin = i;
+ else if (tag == "ctrleditsettings") {
+ ctrlEdits[_numOfCtrlEdits] = new CtrlEditSettings();
+ ctrlEdits[_numOfCtrlEdits]->readStatus(node.firstChild());
+ _numOfCtrlEdits++;
+ }
+ else
+ printf("MusE:ExtEditorSettings: unknown tag %s\n", e.tagName().toAscii().data());
+ node = node.nextSibling();
+ }
+ }
+
+//---------------------------------------------------------
+// writeStatus
+//---------------------------------------------------------
+
+void ExtEditorSettings::writeStatus(Xml& xml) const
+ {
+ //TODO: The ctrlEdits need to be updated (created) before trying to write status of ctrlEdits...
+ xml.tag("exteditorsettings");
+ GraphEditorSettings::writeStatus(xml);
+ xml.intTag("quant", _quant);
+ xml.intTag("applyTo", _applyTo);
+ xml.intTag("steprec", _steprec);
+ xml.intTag("midiin", _midiin);
+ for (int i=0; i<_numOfCtrlEdits; i++) {
+ ctrlEdits[i]->writeStatus(xml);
+ }
+ xml.etag("exteditorsettings");
+ }
+
+//
+// DrumEditorSettings static init default values:
+//
+int DrumEditorSettings::_quantInit = 96;
+int DrumEditorSettings::_rasterInit = 96;
+int DrumEditorSettings::_widthInit = 600;
+int DrumEditorSettings::_heightInit = 400;
+
+//---------------------------------------------------------
+// DrumEditorSettings
+//---------------------------------------------------------
+
+DrumEditorSettings::DrumEditorSettings(int r, int w, int h, int x, int y,
+ double xm, double ym, QPoint pos, int q, int apply, int dl, int dw)
+ : ExtEditorSettings(r, w, h, x, y, xm, ym, pos, q, apply),
+ _dlistWidth(dl), _dcanvasWidth(dw)
+ {
+ // For uninitialized values, go with static default values instead
+ if (w == ES_UNINIT)
+ _width = _widthInit;
+ if (h == ES_UNINIT)
+ _height = _heightInit;
+ if (r == ES_UNINIT)
+ _raster = _rasterInit;
+ if (q == ES_UNINIT)
+ _quant = _quantInit;
+ }
+
+//---------------------------------------------------------
+// clone
+//---------------------------------------------------------
+
+EditorSettings* DrumEditorSettings::clone()
+ {
+ DrumEditorSettings* newSettings = new DrumEditorSettings(_raster, _width, _height, _x, _y, _xmag, _ymag, _pos, _quant, _applyTo, _dlistWidth, _dcanvasWidth);
+ for (int i=0; i<_numOfCtrlEdits; i++) {
+ CtrlEditSettings* c = new CtrlEditSettings();
+ *c = *(ctrlEdits[i]); //copy
+ newSettings->setControlEditSettings(i, c);
+ }
+ newSettings->setControlEditSize(_numOfCtrlEdits);
+ return (EditorSettings*) newSettings;
+ }
+
+//---------------------------------------------------------
+// readStatus
+//---------------------------------------------------------
+
+void DrumEditorSettings::readStatus(QDomNode node)
+ {
+ while (!node.isNull()) {
+ QDomElement e = node.toElement();
+ QString tag = e.tagName();
+ QString s = e.text();
+ int i = s.toInt();
+ if (tag == "exteditorsettings")
+ ExtEditorSettings::readStatus(node.firstChild());
+ else if (tag == "dlistwidth")
+ _dlistWidth = i;
+ else if (tag == "dcanvaswidth")
+ _dcanvasWidth = i;
+ else
+ printf("MusE:DrumEditorSettings: unknown tag %s\n", e.tagName().toAscii().data());
+ node = node.nextSibling();
+ }
+ }
+
+//---------------------------------------------------------
+// writeStatus
+//---------------------------------------------------------
+
+void DrumEditorSettings::writeStatus(Xml& xml) const
+ {
+ xml.tag("drumeditorsettings");
+ ExtEditorSettings::writeStatus(xml);
+ xml.intTag("dlistwidth", _dlistWidth);
+ xml.intTag("dcanvaswidth", _dcanvasWidth);
+ xml.etag("drumeditorsettings");
+ }
+
+//---------------------------------------------------------
+// setStaticInitValues
+//---------------------------------------------------------
+void DrumEditorSettings::setStaticInitValues(int widthinit, int heightinit, int rasterinit, int quantinit)
+ {
+ _widthInit = widthinit;
+ _heightInit = heightinit;
+ _rasterInit = rasterinit;
+ _quantInit = quantinit;
+ }
+
+//---------------------------------------------------------
+// writeStatic
+//! write static configuration values for pianoroll
+//---------------------------------------------------------
+
+void DrumEditorSettings::writeStatic(Xml& xml)
+ {
+ xml.tag("drumeditorstatic");
+ xml.intTag("quantDefault", _quantInit);
+ xml.intTag("rasterDefault", _rasterInit);
+ xml.intTag("widthDefault", _widthInit);
+ xml.intTag("heightDefault", _heightInit);
+ xml.etag("drumeditorstatic");
+ }
+
+//---------------------------------------------------------
+// readStatic
+//---------------------------------------------------------
+
+void DrumEditorSettings::readStatic(QDomNode node)
+ {
+ while (!node.isNull()) {
+ QDomElement e = node.toElement();
+ QString tag = e.tagName();
+ QString s = e.text();
+ int i = s.toInt();
+ if (tag == "quantDefault")
+ _quantInit = i;
+ else if (tag == "rasterDefault")
+ _rasterInit = i;
+ else if (tag == "widthDefault")
+ _widthInit = i;
+ else if (tag == "heightDefault")
+ _heightInit = i;
+ else
+ printf("MusE:DrumEditorSettings Static: unknown tag %s\n", e.tagName().toAscii().data());
+ node = node.nextSibling();
+ }
+ }
+
+//---------------------------------------------------------
+// dump
+//---------------------------------------------------------
+
+void DrumEditorSettings::dump()
+ {
+// printf("%x: DrumEditorSettings: q=%d r=%d w=%d h=%d dlw=%d dcw=%d xmag: %d pos: %d ypos: %d\n", this, _quant, _raster, _width, _height, _dlistWidth, _dcanvasWidth, _xmag, _pos, _ypos);
+ }
+
+//
+// PianorollSettings static init default values:
+//
+int PianorollSettings::_quantInit = 96;
+int PianorollSettings::_rasterInit = 96;
+int PianorollSettings::_widthInit = 600;
+int PianorollSettings::_heightInit = 400;
+
+PianorollSettings::PianorollSettings(int r, int w, int h, int x, int y,
+ double xm, double ym, QPoint pos, int q, int apply,
+ int qs, int qlim, int cmode, bool qlen, int pw)
+ : ExtEditorSettings(r, w, h, x, y, xm, ym, pos, q, apply),
+ _quantStrength(qs), _quantLimit(qlim), _colorMode(cmode),
+ _quantLen(qlen), _pianoWidth(pw)
+ {
+ // For uninitialized values, go with static default values instead
+ if (w == ES_UNINIT)
+ _width = _widthInit;
+ if (h == ES_UNINIT)
+ _height = _heightInit;
+ if (r == ES_UNINIT)
+ _raster = _rasterInit;
+ if (q == ES_UNINIT)
+ _quant = _quantInit;
+ }
+
+//---------------------------------------------------------
+// clone
+//---------------------------------------------------------
+
+EditorSettings* PianorollSettings::clone()
+ {
+ PianorollSettings* newSettings = new PianorollSettings(_raster, _width,
+ _height, _x, _y, _xmag, _ymag, _pos, _quant, _applyTo, _quantStrength, _quantLimit, _colorMode, _quantLen, _pianoWidth);
+ CtrlEditSettings* c;
+ for (int i=0; i<_numOfCtrlEdits; i++) {
+ c = new CtrlEditSettings();
+ *c = *(ctrlEdits[i]); //copy
+ newSettings->setControlEditSettings(i, c);
+ }
+ newSettings->setControlEditSize(_numOfCtrlEdits);
+ return (EditorSettings*) newSettings;
+ }
+
+//---------------------------------------------------------
+// readStatus
+//---------------------------------------------------------
+
+void PianorollSettings::readStatus(QDomNode node)
+ {
+ while (!node.isNull()) {
+ QDomElement e = node.toElement();
+ QString tag = e.tagName();
+ QString s = e.text();
+ int i = s.toInt();
+ if (tag == "exteditorsettings")
+ ExtEditorSettings::readStatus(node.firstChild());
+ else if (tag == "quantstrength")
+ _quantStrength = i;
+ else if (tag == "quantlimit")
+ _quantLimit = i;
+ else if (tag == "colormode")
+ _colorMode = i;
+ else if (tag == "quantLen")
+ _quantLen = i;
+ else if (tag == "pianowidth")
+ _pianoWidth = i;
+ else
+ printf("MusE:PianorollSettings: unknown tag %s\n", e.tagName().toAscii().data());
+ node = node.nextSibling();
+ }
+ }
+
+//---------------------------------------------------------
+// writeStatus
+//---------------------------------------------------------
+
+void PianorollSettings::writeStatus(Xml& xml) const
+ {
+ xml.tag("prollsettings");
+ ExtEditorSettings::writeStatus(xml);
+ xml.intTag("quantstrength", _quantStrength);
+ xml.intTag("quantlimit", _quantLimit);
+ xml.intTag("colormode", _colorMode);
+ xml.intTag("quantLen", _quantLen);
+ xml.intTag("pianowidth", _pianoWidth);
+ xml.etag("prollsettings");
+ }
+
+//---------------------------------------------------------
+// dump
+//---------------------------------------------------------
+
+void PianorollSettings::dump()
+ {
+// printf("%x: PianorollSettings: q=%d r=%d w=%d h=%d x:%d y:%d xmag: %d pos:%d ypos:%d qs:%d ql:%d cm:%d at:%d ql:%d pw:%d\n", this, _quant, _raster, _width, _height, _x, _y, _xmag, _pos, _ypos, _quantStrength, _quantLimit, _colorMode, _applyTo, _quantLen, _pianoWidth);
+ }
+
+
+//---------------------------------------------------------
+// setStaticInitValues
+//! set static initialization values
+//---------------------------------------------------------
+void PianorollSettings::setStaticInitValues(int widthinit, int heightinit, int rasterinit, int quantinit)
+ {
+ _widthInit = widthinit;
+ _heightInit = heightinit;
+ _rasterInit = rasterinit;
+ _quantInit = quantinit;
+ }
+
+//---------------------------------------------------------
+// writeStatic
+//! write static configuration values for pianoroll
+//---------------------------------------------------------
+
+void PianorollSettings::writeStatic(Xml& xml)
+ {
+ xml.tag("pianorollstatic");
+ xml.intTag("quantDefault", _quantInit);
+ xml.intTag("rasterDefault", _rasterInit);
+ xml.intTag("widthDefault", _widthInit);
+ xml.intTag("heightDefault", _heightInit);
+ xml.etag("pianorollstatic");
+ }
+
+//---------------------------------------------------------
+// readStatic
+//---------------------------------------------------------
+
+void PianorollSettings::readStatic(QDomNode node)
+ {
+ while (!node.isNull()) {
+ QDomElement e = node.toElement();
+ QString tag = e.tagName();
+ QString s = e.text();
+ int i = s.toInt();
+ if (tag == "quantDefault")
+ _quantInit = i;
+ else if (tag == "rasterDefault")
+ _rasterInit = i;
+ else if (tag == "widthDefault")
+ _widthInit = i;
+ else if (tag == "heightDefault")
+ _heightInit = i;
+ else
+ printf("MusE:PianorollSettings Static: unknown tag %s\n", e.tagName().toAscii().data());
+ node = node.nextSibling();
+ }
+ }
+
+//---------------------------------------------------------
+// SettingsList
+//---------------------------------------------------------
+
+SettingsList::SettingsList()
+ {
+ //_default = d;
+ //dump();
+ }
+
+//---------------------------------------------------------
+// ~SettingsList
+//---------------------------------------------------------
+
+SettingsList::~SettingsList()
+ {
+ for(iSettingsList i = begin(); i!=end(); i++)
+ delete(i->second);
+ }
+
+//---------------------------------------------------------
+// set
+//---------------------------------------------------------
+
+void SettingsList::set(unsigned id, EditorSettings* e)
+ {
+ iSettingsList i = find(id);
+ if (i == end()) {
+ //Create a new item
+ EditorSettings* newItem = e->clone();
+ if (DBG_ESETTINGS)
+ printf("SettingsList::set - storing item with id=%d, "
+ "object at %p, cloned object at: %p.\n", id, e, newItem);
+ insert(std::pair<unsigned, EditorSettings*>(id, newItem));
+ }
+ else {
+ EditorSettings* newItem = e->clone();
+ if (DBG_ESETTINGS)
+ printf("SettingsList::set - Cloning item with id=%d, object at %p to obj at %p\n", id, e, newItem);
+ printf("SettingsList::set - deleting settings at: %p\n", i->second);
+ delete(i->second); //Hmmm, hehhh... Perhaps better to use copy-constructor instead of deletion in different places, but then it's difficult to create object of correct subclass (in a neat way)... (ml)
+ i->second = newItem;
+ }
+ }
+
+//---------------------------------------------------------
+// get
+//---------------------------------------------------------
+
+EditorSettings* SettingsList::get(unsigned id)
+ {
+ iSettingsList i = find(id);
+
+ if (i == end()) {
+ if (DBG_ESETTINGS)
+ printf("SettingsList::get - no match for id=%d\n", id);
+ return 0;
+ }
+ else
+ return i->second;
+ }
+
+//---------------------------------------------------------
+// removeSettings
+// remove settings for parts that don't exist anymore
+//---------------------------------------------------------
+
+void SettingsList::removeSettings(unsigned id)
+ {
+ for(iSettingsList i = begin(); i!=end(); i++) {
+ int bc = i->first;
+ bc&= ~(0xf0000000);
+ if (unsigned(bc) == id) {
+ if (DBG_ESETTINGS)
+ printf("SettingsList::removeSettings, deleting obj at %p\n", i->second);
+ delete i->second;
+ erase(i);
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// dump
+//---------------------------------------------------------
+
+void SettingsList::dump()
+ {
+#if 0
+ printf("-------SettingsList-DUMP------\n");
+ for(iSettingsList i = begin(); i!=end(); i++) {
+ //printf("i=%x ",i);
+ printf("PART NO: %x ", i->first);
+ printf("- i->second at %x\n", i->second);
+
+ i->second->dump();
+ }
+ printf("---END-SettingsList-DUMP------\n");
+#endif
+ }
+
+//---------------------------------------------------------
+// writeStatus
+//! writes out the settings for all editors and parts
+//---------------------------------------------------------
+
+void SettingsList::writeStatus(Xml& xml) const
+ {
+ xml.tag("settingslist");
+ // Write static
+ ExtEditorSettings::writeStatic(xml);
+ PianorollSettings::writeStatic(xml);
+ DrumEditorSettings::writeStatic(xml);
+
+ //Write all nodes
+ for (ciSettingsList i = begin(); i != end(); i++) {
+ xml.tag("elem");
+ xml.intTag("id", i->first);
+ i->second->writeStatus(xml);
+ xml.etag("elem");
+ }
+ xml.etag("settingslist");
+ }
+
+//---------------------------------------------------------
+// readStatus
+//! reads the settings for all editors and parts
+//---------------------------------------------------------
+
+void SettingsList::readStatus(QDomNode node)
+ {
+ while (!node.isNull()) {
+ QDomElement e = node.toElement();
+ QString tag = e.tagName();
+ if (tag == "elem")
+ readElem(node.firstChild());
+ else if (tag == "exteditorstatic")
+ ExtEditorSettings::readStatic(node.firstChild());
+ else if (tag == "pianorollstatic")
+ PianorollSettings::readStatic(node.firstChild());
+ else if (tag == "drumeditorstatic")
+ DrumEditorSettings::readStatic(node.firstChild());
+ else
+ printf("MusE:SettingsList: unknown tag %s\n", e.tagName().toAscii().data());
+ node = node.nextSibling();
+ }
+ }
+
+//---------------------------------------------------------
+// readElem
+//---------------------------------------------------------
+
+void SettingsList::readElem(QDomNode node)
+ {
+ int id = 0;
+ while (!node.isNull()) {
+ QDomElement e = node.toElement();
+ QString tag = e.tagName();
+ QString s = e.text();
+ int i = s.toInt();
+ if (tag == "grapheditorsettings") {
+ GraphEditorSettings* temp = new GraphEditorSettings();
+ temp->readStatus(node.firstChild());
+ insert(std::pair<unsigned, EditorSettings*>(id, temp));
+ }
+ else if (tag == "editorsettings") {
+ EditorSettings* temp = new EditorSettings();
+ temp->readStatus(node.firstChild());
+ insert(std::pair<unsigned, EditorSettings*>(id, temp));
+ }
+ else if (tag == "drumeditorsettings") {
+ DrumEditorSettings* temp = new DrumEditorSettings();
+ temp->readStatus(node.firstChild());
+ insert(std::pair<unsigned, EditorSettings*>(id, temp));
+ }
+ else if (tag == "prollsettings") {
+ PianorollSettings* temp = new PianorollSettings();
+ temp->readStatus(node.firstChild());
+ insert(std::pair<unsigned, EditorSettings*>(id, temp));
+ }
+ else if (tag == "id")
+ id = i;
+ else
+ printf("MusE:SettingsList element: unknown tag %s\n", e.tagName().toAscii().data());
+ node = node.nextSibling();
+ }
+ }
+
+
+//---------------------------------------------------------
+/*!
+ \fn SettingsList::reset()
+ \brief Remove all previous settings and clean up
+ */
+//---------------------------------------------------------
+void SettingsList::reset()
+ {
+ for (iSettingsList i = begin(); i != end(); i++) {
+ delete i->second;
+ }
+ clear();
+ }
diff --git a/muse_qt4_evolution/muse/esettings.h b/muse_qt4_evolution/muse/esettings.h
new file mode 100644
index 00000000..292c02c7
--- /dev/null
+++ b/muse_qt4_evolution/muse/esettings.h
@@ -0,0 +1,361 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Description:
+// Configuration settings for the midi-editors.
+//
+// Copyright (C) 2004 Mathias Lundgren <lunar_shuttle@users.sourceforge.net>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __ESETTINGS_H__
+#define __ESETTINGS_H__
+
+#include <unistd.h>
+#include <fcntl.h>
+
+#define ET_LISTEDIT 0x1000000
+#define ET_MASTEREDIT 0x4000000
+#define ET_PIANO_ROLL 0x10000000
+#define ET_DRUMEDIT 0x20000000
+#define ET_WAVEEDIT 0x40000000
+
+#define MAXNOOFCTRLEDITSETTINGS 16
+
+#define ES_UNINIT -1 /* Uninitialized parameter */
+
+#define ESETTINGS_DEBUG 0
+
+#include "debug.h"
+#define DBG_ESETTINGS_ON 0
+#define DBG_ESETTINGS debugMsg && DBG_ESETTINGS_ON
+
+namespace AL {
+ class Xml;
+ };
+using AL::Xml;
+
+class CtrlEdit;
+
+//-----------------------------------------------
+// CtrlEditSettings class
+// stores ctrleditsettings
+//-----------------------------------------------
+class CtrlEditSettings
+ {
+ private:
+ int height;
+ int controller;
+
+ public:
+ //const MidiController* controller;
+ CtrlEditSettings() {}
+ CtrlEditSettings(int h, int c) { height = h; controller = c; }
+ CtrlEditSettings(const CtrlEditSettings& c) { height = c.height; controller = c.controller; }
+ int getHeight() { return height; }
+ int getController() { return controller; }
+ void readStatus(QDomNode);
+ void writeStatus(Xml& xml);
+
+ bool operator==(const CtrlEditSettings& c) const { return (c.height == height && c.controller == controller); }
+ bool operator!=(const CtrlEditSettings& c) const { return !(c == *this); }
+ };
+
+//-----------------------------------------------
+// EditorSettings
+// base class for midieditorsettings
+//-----------------------------------------------
+class EditorSettings
+ {
+ protected:
+ int _raster;
+ int _width, _height, _x, _y;
+
+ public:
+ EditorSettings(int r=96, int w=600, int h=400, int x=-1, int y=-1) : _raster(r), _width(w), _height(h), _x(x), _y(y) { }
+ virtual ~EditorSettings() {}
+ int raster() const { return _raster; }
+ void setRaster(int r) { _raster = r; }
+ int* rasterPtr() { return &_raster; }
+ int width() const { return _width; }
+ int height() const { return _height; }
+ void setWidth(int w) { _width = w; }
+ void setHeight(int h) { _height = h; }
+ int x() const { return _x; }
+ void setX(int x) { _x = x; }
+ int y() const { return _y; }
+ void setY(int y) { _y = y; }
+
+ virtual void readStatus(QDomNode);
+ virtual void writeStatus(Xml&) const;
+ virtual bool operator==(const EditorSettings& e) const {
+ return ((e._raster == _raster) && (e._width == _width) && (e._height == _height)/* && (e._x == _x) && (e._y == _y)*/);
+ }
+ virtual bool operator!=(const EditorSettings& e) const { return !(e == *this); }
+ virtual EditorSettings* clone() { return new EditorSettings(_raster, _width, _height, _x, _y); }
+ virtual void dump() { printf("%p: EditorSettings: r:%d w:%d h:%d x:%d y:%d\n", this, _raster, _width, _height, _x, _y); }
+ };
+
+//---------------------------------------------------------
+// GraphEditorSettings
+//---------------------------------------------------------
+class GraphEditorSettings : public EditorSettings
+ {
+ protected:
+ //Values considering scroll + zoom
+ double _xmag, _ymag;
+ QPoint _pos;
+
+ public:
+ GraphEditorSettings(int r=96, int w=600, int h=400, int x=-1, int y=-1,
+ double xmag=0.05, double ymag=1.0, QPoint pos = QPoint(0, 0))
+ : EditorSettings(r, w, h, x, y), _xmag(xmag), _ymag(ymag), _pos(pos)
+ {
+ }
+ virtual ~GraphEditorSettings() {}
+
+ double xmag() const { return _xmag; }
+ double ymag() const { return _ymag; }
+ void setXmag(double x) { _xmag = x; }
+ void setYmag(double y) { _xmag = y; }
+ QPoint pos() const { return _pos; }
+ void setPos(const QPoint& p) { _pos = p; }
+ int ypos() const { return _pos.y(); }
+ void setYpos(int y) { _pos.setY(y); }
+
+ virtual bool operator==(const EditorSettings& e) const {
+ const GraphEditorSettings& f = (GraphEditorSettings&) e;
+ return ((f._raster == _raster) && (f._width == _width) && (f._height == _height)// && (f._x == _x) && (f._y == _y)
+ && (f._xmag == _xmag)
+ && (f._ymag == _ymag)
+ && (f._pos == _pos));
+ }
+ virtual bool operator!=(const EditorSettings& e) const { return !(e == *this); }
+ virtual EditorSettings* clone() { return new GraphEditorSettings(_raster, _width, _height, _x, _y, _xmag, _ymag, _pos); }
+ virtual void readStatus(QDomNode);
+ virtual void writeStatus(Xml&) const;
+ virtual void dump() {
+ printf("%p: GraphEditorSettings: r:%d w:%d h:%d x:%d y:%d mag:%f:%f pos:%d ypos:%d\n",
+ this, _raster, _width, _height, _x, _y, _xmag, _ymag, _pos.x(), _pos.y());
+ }
+ };
+
+//---------------------------------------------------------
+// ExtEditorSettings
+// Common settings for drumeditor and pianoroll
+//---------------------------------------------------------
+
+class ExtEditorSettings : public GraphEditorSettings
+ {
+ private:
+
+ protected:
+ int _quant;
+ int _applyTo;
+ static bool _steprec;
+ static bool _midiin;
+ int _numOfCtrlEdits;
+
+ public:
+ ExtEditorSettings(int r=96, int w=600, int h=400, int x=-1, int y=-1, double xm=0.05, double ym=1.0, QPoint pos = QPoint(0,0), int q=96, int apply=0);
+ virtual ~ExtEditorSettings();
+ //ExtEditorSettings(const ExtEditorSettings& e) : EditorSettings(e._raster) , _quant(e._quant) { }
+ static void readStatic(QDomNode);
+ static void writeStatic(Xml& xml);
+ CtrlEditSettings* ctrlEdits[MAXNOOFCTRLEDITSETTINGS];
+
+ virtual bool operator==(const EditorSettings& e) const { //örk...
+ const ExtEditorSettings& f = (ExtEditorSettings&) e;
+ bool ctrlEditsEqual = true;
+ for (int i=0; i<MAXNOOFCTRLEDITSETTINGS; i++) {
+ if (ctrlEdits[i] != f.ctrlEdits[i])
+ ctrlEditsEqual = false;
+ }
+ return ((f._raster == _raster) && (f._width == _width) && (f._height == _height)// && (f._x == _x) && (f._y == _y)
+ && (f._xmag == _xmag)
+ && (f._ymag == _ymag)
+ && (f._pos == _pos)
+ && (f._quant == _quant) && (f._applyTo == _applyTo)
+ && (ctrlEditsEqual));
+ };
+ virtual bool operator!=(const EditorSettings& e) const { const ExtEditorSettings& f = (ExtEditorSettings&) e; return !(f == *this); }
+
+ virtual EditorSettings* clone();
+ virtual void readStatus(QDomNode);
+ virtual void writeStatus(Xml&) const;
+ virtual void dump() {
+ printf("%p: ExtEditorSettings: r:%d q:%d w:%d h:%d x:%d y:%d mag=%f:%f xpos=%d ypos=%d applyTo=%d\n",
+ this, _raster, _quant, _width, _height, _x, _y, _xmag, _ymag, _pos.x(), _pos.y(), _applyTo);
+ }
+ void setControlEditSettings(int pos, CtrlEditSettings* c);
+ void setControlEditSize(int s) { _numOfCtrlEdits = s; }
+ int getControlEditSize() { return _numOfCtrlEdits; }
+ CtrlEditSettings* getControlEditSettings(int pos) { return ctrlEdits[pos]; }
+
+ int quant() const { return _quant; }
+ void setQuant(int q) { _quant = q; }
+
+ static bool steprec() { return _steprec; }
+ static void setSteprec(bool b) { _steprec = b; }
+ static bool midiin() { return _midiin; }
+ static void setMidiin(bool b) { _midiin = b; }
+ };
+
+
+//---------------------------------------------------------
+// DrumEditorSettings
+// Settings for drumeditor
+//---------------------------------------------------------
+class DrumEditorSettings : public ExtEditorSettings
+ {
+ int _dlistWidth, _dcanvasWidth;
+
+ // Default initialization values
+ static int _quantInit, _rasterInit;
+ static int _widthInit, _heightInit;
+
+ public:
+ DrumEditorSettings(int r=ES_UNINIT, int w=ES_UNINIT, int h=ES_UNINIT,
+ int x=-1, int y=-1,
+ double xm=0.05, double ym=1.0, QPoint pos=QPoint(0,0), int q=ES_UNINIT, int apply=0, int dl=50, int dw=300);
+ virtual ~DrumEditorSettings() {}
+
+ static void readStatic(QDomNode);
+ static void writeStatic(Xml& xml);
+ int dlistWidth() const { return _dlistWidth; }
+ int dcanvasWidth() const { return _dcanvasWidth; }
+ void setdlistWidth(int d) { _dlistWidth = d; }
+ void setdcanvasWidth(int d) { _dcanvasWidth = d; }
+
+ virtual bool operator==(const EditorSettings& e) const { //öööörk...
+ DrumEditorSettings& f = (DrumEditorSettings&) e;
+ bool ctrlEditsEqual = true;
+ for (int i=0; i<MAXNOOFCTRLEDITSETTINGS; i++) {
+ if (ctrlEdits[i] != f.ctrlEdits[i])
+ ctrlEditsEqual = false;
+ }
+ return ((f._raster == _raster) && (f._width == _width) && (f._height == _height)// && (f._x == _x) && (f._y == _y)
+ && (f._xmag == _xmag)
+ && (f._ymag == _ymag)
+ && (f._pos == _pos)
+ && (f._quant == _quant) && (f._applyTo == _applyTo)
+ && (ctrlEditsEqual)
+ && (f._dlistWidth == _dlistWidth) && (f._dcanvasWidth == _dcanvasWidth));
+ }
+ virtual bool operator!=(const EditorSettings& e) const { DrumEditorSettings& f = (DrumEditorSettings&) e; return !(f==*this); }
+ virtual EditorSettings* clone();
+ virtual void readStatus(QDomNode);
+ virtual void writeStatus(Xml&) const;
+ virtual void dump();
+
+ static void setStaticInitValues(int widthinit, int heightinit, int rasterinit, int quantinit);
+ };
+
+
+//---------------------------------------------------------
+// PianorollSettings
+// Settings for pianoroll
+//---------------------------------------------------------
+class PianorollSettings : public ExtEditorSettings
+ {
+ int _quantStrength, _quantLimit, _colorMode;
+ bool _quantLen;
+ int _pianoWidth;
+
+ // Default initialization values
+ static int _quantInit;
+ static int _rasterInit;
+ static int _widthInit;
+ static int _heightInit;
+
+ public:
+ PianorollSettings(int r=ES_UNINIT, int w=ES_UNINIT, int h=ES_UNINIT,
+ int x=-1, int y=-1, double xm=0.05, double ym = 1.0,
+ QPoint pos = QPoint(0, 245), int q=ES_UNINIT, int apply=0,
+ int qs=80, int qlim=50, int cmode=0, bool qlen=false, int pw=40);
+ virtual ~PianorollSettings() {}
+
+ static void readStatic(QDomNode);
+ static void writeStatic(Xml& xml);
+ int quantStrength() const { return _quantStrength; }
+ void setQuantStrength(int c) { _quantStrength = c; }
+ int quantLimit() const { return _quantLimit; }
+ void setQuantLimit(int q) { _quantLimit = q; }
+ int colorMode() const { return _colorMode; }
+ void setColorMode(int c) { _colorMode = c; }
+ int applyTo() const { return _applyTo; }
+ void setApplyTo(int a) { _applyTo = a; }
+ bool quantLen() const { return _quantLen; }
+ void setQuantLen(bool b) { _quantLen = b; }
+ int pianoWidth() const { return _pianoWidth; }
+ void setPianoWidth(int w) { _pianoWidth = w; }
+
+ virtual bool operator==(const EditorSettings& e) const { //öööörkk...
+ PianorollSettings& f = (PianorollSettings&) e;
+ bool ctrlEditsEqual = true;
+ for (int i=0; i<MAXNOOFCTRLEDITSETTINGS; i++) {
+ if (ctrlEdits[i] != f.ctrlEdits[i])
+ ctrlEditsEqual = false;
+ }
+ return ((f._raster == _raster) && (f._width == _width) && (f._height == _height)// && (f._x == _x) && (f._y == _y)
+ && (f._xmag == _xmag)
+ && (f._ymag == _ymag)
+ && (f._pos == _pos)
+ && (f._quant == _quant) && (f._applyTo == _applyTo)
+ && (ctrlEditsEqual)
+ && (f._quantStrength == _quantStrength) && (f._quantLimit == _quantLimit) && (f._colorMode == _colorMode)
+ && (f._quantLen == _quantLen) && (f._pianoWidth == _pianoWidth));
+ }
+ virtual bool operator!=(const EditorSettings& e) const { PianorollSettings& f = (PianorollSettings&) e; return !(f==*this); }
+ virtual void readStatus(QDomNode);
+ virtual void writeStatus(Xml&) const;
+ virtual EditorSettings* clone();
+ virtual void dump();
+
+ static void setStaticInitValues(int widthinit, int heightinit, int rasterinit, int quantinit);
+ };
+
+//---------------------------------------------------------
+// SettingsList
+//
+// Multimap containing a list of editor settings
+// There is one big list with settings for all editors and
+// different parts. When opening an editor for a specific
+// part, the part-id is matched against the correct editortype
+// If one exists, the editor gets when calling getSettings(),
+// otherwise, a new one is created.
+// The setting has a final update on destruction, and if it
+// has changed, it is stored to the settingslist
+//---------------------------------------------------------
+typedef std::multimap<unsigned, EditorSettings*>::iterator iSettingsList;
+typedef std::multimap<unsigned, EditorSettings*>::const_iterator ciSettingsList;
+
+class SettingsList : public std::multimap<unsigned, EditorSettings*>
+ {
+ public:
+ SettingsList();
+ ~SettingsList();
+ void set(unsigned id, EditorSettings* e);
+ EditorSettings* get(unsigned);
+ void removeSettings(unsigned id);
+ void readElem(QDomNode);
+ void readStatus(QDomNode);
+ void writeStatus(Xml&) const;
+ void dump();
+ void reset();
+ };
+
+#endif
diff --git a/muse_qt4_evolution/muse/evdata.h b/muse_qt4_evolution/muse/evdata.h
new file mode 100644
index 00000000..629b9e9a
--- /dev/null
+++ b/muse_qt4_evolution/muse/evdata.h
@@ -0,0 +1,85 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __EVDATA_H__
+#define __EVDATA_H__
+
+#include <string.h>
+
+//---------------------------------------------------------
+// EvData
+// variable len event data (sysex, meta etc.)
+//---------------------------------------------------------
+
+class EvData {
+ int* refCount;
+
+ public:
+ unsigned char* data;
+ int dataLen;
+
+ EvData() {
+ data = 0;
+ dataLen = 0;
+ refCount = new int(1);
+ }
+ EvData(const EvData& ed) {
+ data = ed.data;
+ dataLen = ed.dataLen;
+ refCount = ed.refCount;
+ (*refCount)++;
+ }
+
+ EvData& operator=(const EvData& ed) {
+ if (data == ed.data)
+ return *this;
+ if (--(*refCount) == 0) {
+ delete refCount;
+ delete[] data;
+ }
+ data = ed.data;
+ dataLen = ed.dataLen;
+ refCount = ed.refCount;
+ (*refCount)++;
+ return *this;
+ }
+
+ bool operator==(const EvData& ed) const {
+ if(dataLen==ed.dataLen) {
+ return memcmp(data, ed.data, sizeof(unsigned char) * dataLen)==0;
+ }
+ else return false;
+ }
+
+ ~EvData() {
+ if (--(*refCount) == 0) {
+ delete[] data;
+ delete refCount;
+ }
+ }
+ void setData(const unsigned char* p, int l) {
+ data = new unsigned char[l];
+ memcpy(data, p, l);
+ dataLen = l;
+ }
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/event.cpp b/muse_qt4_evolution/muse/event.cpp
new file mode 100644
index 00000000..53d68c08
--- /dev/null
+++ b/muse_qt4_evolution/muse/event.cpp
@@ -0,0 +1,222 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "event.h"
+#include "eventbase.h"
+#include "waveevent.h"
+#include "midieventbase.h"
+
+using AL::Pos;
+
+//---------------------------------------------------------
+// Event
+//---------------------------------------------------------
+
+EventBase::EventBase(EventType t)
+ {
+ _type = t;
+ Pos::setType(_type == Wave ? AL::FRAMES : AL::TICKS);
+ refCount = 0;
+ _selected = false;
+ _recorded = false;
+ }
+
+EventBase::EventBase(const EventBase& ev)
+ : PosLen(ev)
+ {
+ refCount = 0;
+ _selected = ev._selected;
+ _type = ev._type;
+ _recorded = ev._recorded;
+ }
+
+//---------------------------------------------------------
+// move
+//---------------------------------------------------------
+
+void EventBase::move(int tickOffset)
+ {
+ setTick(tick() + tickOffset);
+ }
+
+//---------------------------------------------------------
+// dump
+//---------------------------------------------------------
+
+void EventBase::dump(int n) const
+ {
+ for (int i = 0; i < n; ++i)
+ putchar(' ');
+ printf("Event %p refs:%d ", this, refCount);
+ PosLen::dump(n+2);
+ }
+
+//---------------------------------------------------------
+// clone
+//---------------------------------------------------------
+
+Event Event::clone() const
+ {
+ return Event(ev->clone());
+ }
+
+Event::Event(EventType t)
+ {
+ if (t == Wave)
+ ev = new WaveEventBase(t);
+ else
+ ev = new MidiEventBase(t);
+ ++(ev->refCount);
+ }
+
+Event::Event(const Event& e)
+ {
+ ev = e.ev;
+ if (ev)
+ ++(ev->refCount);
+ }
+
+Event::Event(EventBase* eb)
+ {
+ ev = eb;
+ ++(ev->refCount);
+ }
+
+Event::~Event()
+ {
+ if (ev && --(ev->refCount) == 0)
+ delete ev;
+ }
+
+bool Event::empty() const
+ {
+ return ev == 0;
+ }
+
+EventType Event::type() const
+ {
+ return ev ? ev->type() : Note;
+ }
+
+void Event::setType(EventType t)
+ {
+ if (ev && --(ev->refCount) == 0)
+ delete ev;
+ if (t == Wave)
+ ev = new WaveEventBase(t);
+ else
+ ev = new MidiEventBase(t);
+ ++(ev->refCount);
+ }
+
+Event& Event::operator=(const Event& e)
+ {
+ if (ev == e.ev)
+ return *this;
+ if (ev && --(ev->refCount) == 0)
+ delete ev;
+ ev = e.ev;
+ if (ev)
+ ++(ev->refCount);
+ return *this;
+ }
+
+bool Event::operator==(const Event& e) const {
+ return *ev == *e.ev;
+ }
+
+
+int Event::getRefCount() const { return ev->getRefCount(); }
+bool Event::selected() const { return ev->_selected; }
+void Event::setSelected(bool val) { ev->_selected = val; }
+bool Event::recorded() const { return ev->_recorded; }
+void Event::setRecorded(bool val) { ev->_recorded = val; }
+void Event::move(int offset) { ev->move(offset); }
+
+void Event::read(QDomNode node) { ev->read(node); }
+void Event::write(Xml& xml, const Pos& o) const { ev->write(xml, o); }
+void Event::dump(int n) const { ev->dump(n); }
+Event Event::mid(unsigned a, unsigned b) { return Event(ev->mid(a, b)); }
+
+bool Event::isNote() const { return ev->isNote(); }
+bool Event::isNoteOff() const { return ev->isNoteOff(); }
+bool Event::isNoteOff(const Event& e) const { return ev->isNoteOff(e); }
+int Event::dataA() const { return ev->dataA(); }
+int Event::pitch() const { return ev->dataA(); }
+void Event::setA(int val) { ev->setA(val); }
+void Event::setPitch(int val) { ev->setA(val); }
+int Event::dataB() const { return ev->dataB(); }
+int Event::velo() const { return ev->dataB(); }
+void Event::setB(int val) { ev->setB(val); }
+void Event::setVelo(int val) { ev->setB(val); }
+int Event::dataC() const { return ev->dataC(); }
+int Event::veloOff() const { return ev->dataC(); }
+void Event::setC(int val) { ev->setC(val); }
+void Event::setVeloOff(int val) { ev->setC(val); }
+
+const unsigned char* Event::data() const { return ev->data(); }
+int Event::dataLen() const { return ev->dataLen(); }
+void Event::setData(const unsigned char* data, int len) { ev->setData(data, len); }
+const EvData Event::eventData() const { return ev->eventData(); }
+
+const QString Event::name() const { return ev->name(); }
+void Event::setName(const QString& s) { ev->setName(s); }
+int Event::spos() const { return ev->spos(); }
+void Event::setSpos(int s) { ev->setSpos(s); }
+SndFileR Event::sndFile() const { return ev->sndFile(); }
+void Event::setSndFile(SndFileR& sf) { ev->setSndFile(sf); }
+void Event::read(unsigned offset, float** bpp, int channels, int nn)
+ {
+ ev->read(offset, bpp, channels, nn);
+ }
+
+void Event::setTick(unsigned val) { ev->setTick(val); }
+unsigned Event::tick() const { return ev->tick(); }
+Pos Event::pos() const { return *ev; }
+unsigned Event::frame() const { return ev->frame(); }
+void Event::setFrame(unsigned val) { ev->setFrame(val); }
+void Event::setLenTick(unsigned val) { ev->setLenTick(val); }
+void Event::setLenFrame(unsigned val) { ev->setLenFrame(val); }
+unsigned Event::lenTick() const { return ev->lenTick(); }
+unsigned Event::lenFrame() const { return ev->lenFrame(); }
+Pos Event::end() const { return ev->end(); }
+unsigned Event::endTick() const { return ev->end().tick(); }
+unsigned Event::endFrame() const { return ev->end().frame(); }
+void Event::setPos(const Pos& p) { ev->setPos(p); }
+QString Event::eventTypeName() const { return ev->eventTypeName(); }
+
+
+//---------------------------------------------------------
+// eventTypeName
+//---------------------------------------------------------
+
+QString EventBase::eventTypeName() const
+ {
+ switch(type()) {
+ case Note: return QString("Note");
+ case Controller: return QString("Ctrl");
+ case Sysex: return QString("Sysex");
+ case PAfter: return QString("PAfter");
+ case CAfter: return QString("CAfter");
+ case Meta: return QString("Meta");
+ default: return QString("??");
+ }
+ }
+
diff --git a/muse_qt4_evolution/muse/event.h b/muse_qt4_evolution/muse/event.h
new file mode 100644
index 00000000..62b79756
--- /dev/null
+++ b/muse_qt4_evolution/muse/event.h
@@ -0,0 +1,139 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __EVENT_H__
+#define __EVENT_H__
+
+#include "wave.h" // wg. SndFile
+#include "al/xml.h"
+#include "al/pos.h"
+#include "evdata.h"
+
+using AL::Xml;
+using AL::Pos;
+
+enum EventType { Note, Controller, Sysex, PAfter, CAfter, Meta, Wave };
+class EventBase;
+
+//---------------------------------------------------------
+// Event
+//---------------------------------------------------------
+
+class Event {
+ EventBase* ev;
+
+ public:
+ Event() { ev = 0; }
+ Event(EventType t);
+ Event(const Event& e);
+ Event(EventBase* eb);
+ virtual ~Event();
+
+ bool empty() const;
+ EventType type() const;
+ QString eventTypeName() const;
+
+ void setType(EventType t);
+ Event& operator=(const Event& e);
+ bool operator==(const Event& e) const;
+
+ int getRefCount() const;
+ bool selected() const;
+ void setSelected(bool val);
+ bool recorded() const;
+ void setRecorded(bool val);
+ void move(int offset);
+
+ void read(QDomNode);
+ void write(AL::Xml& xml, const Pos& offset) const;
+ void dump(int n = 0) const;
+ Event clone() const;
+ Event mid(unsigned a, unsigned b);
+
+ bool isNote() const;
+ bool isNoteOff() const;
+ bool isNoteOff(const Event& e) const;
+ int dataA() const;
+ int pitch() const;
+ void setA(int val);
+ void setPitch(int val);
+ int dataB() const;
+ int velo() const;
+ void setB(int val);
+ void setVelo(int val);
+ int dataC() const;
+ int veloOff() const;
+ void setC(int val);
+ void setVeloOff(int val);
+
+ const unsigned char* data() const;
+ int dataLen() const;
+ void setData(const unsigned char* data, int len);
+ const EvData eventData() const;
+
+ const QString name() const;
+ void setName(const QString& s);
+ int spos() const;
+ void setSpos(int s);
+ SndFileR sndFile() const;
+ virtual void setSndFile(SndFileR& sf);
+ virtual void read(unsigned offset, float** bpp, int channels, int nn);
+
+ Pos pos() const;
+ Pos end() const;
+
+ void setTick(unsigned val);
+ unsigned tick() const;
+ unsigned frame() const;
+ void setFrame(unsigned val);
+ void setLenTick(unsigned val);
+ void setLenFrame(unsigned val);
+ unsigned lenTick() const;
+ unsigned lenFrame() const;
+ unsigned endTick() const;
+ unsigned endFrame() const;
+ void setPos(const Pos& p);
+ };
+
+typedef std::multimap<unsigned, Event, std::less<unsigned> > EL;
+typedef EL::iterator iEvent;
+typedef EL::reverse_iterator riEvent;
+typedef EL::const_iterator ciEvent;
+typedef std::pair <iEvent, iEvent> EventRange;
+
+//---------------------------------------------------------
+// EventList
+// tick sorted list of events
+//---------------------------------------------------------
+
+class EventList : public EL {
+ public:
+ int cloneCount;
+ EventList() { cloneCount = 0; }
+ iEvent find(const Event&);
+ iEvent add(const Event& event);
+ iEvent add(const Event& event, unsigned tick);
+ void move(const Event& event, unsigned tick);
+ void dump() const;
+ void read(QDomNode, bool midi);
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/eventbase.h b/muse_qt4_evolution/muse/eventbase.h
new file mode 100644
index 00000000..27d9e323
--- /dev/null
+++ b/muse_qt4_evolution/muse/eventbase.h
@@ -0,0 +1,100 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __EVENTBASE_H__
+#define __EVENTBASE_H__
+
+#include "al/pos.h"
+
+//---------------------------------------------------------
+// EventBase
+//---------------------------------------------------------
+
+class EventBase : public AL::PosLen {
+ EventType _type;
+
+ protected:
+ int refCount;
+ bool _selected;
+ bool _recorded;
+
+ public:
+ EventBase(EventType t);
+ EventBase(const EventBase& ev);
+ QString eventTypeName() const;
+
+ virtual ~EventBase() {}
+
+ int getRefCount() const { return refCount; }
+ EventType type() const { return _type; }
+ void setType(EventType t) { _type = t; }
+ bool selected() const { return _selected; }
+ void setSelected(bool val) { _selected = val; }
+ bool recorded() const { return _recorded; }
+ void setRecorded(bool val) { _recorded = val; }
+
+ void move(int offset);
+
+ virtual void read(QDomNode) = 0;
+ virtual void write(Xml&, const Pos& offset) const = 0;
+ virtual void dump(int n = 0) const;
+ virtual EventBase* mid(unsigned, unsigned) = 0;
+ friend class Event;
+
+ virtual bool isNote() const { return false; }
+ virtual bool isNoteOff() const { return false; }
+ virtual bool isNoteOff(const Event&) const { return false; }
+ virtual int pitch() const { return 0; }
+ virtual int program() const { return 0; }
+ virtual int cntrl() const { return 0; }
+ virtual int dataA() const { return 0; }
+ virtual void setA(int) { }
+ virtual void setPitch(int) { }
+
+ virtual int cntrlVal() const { return 0; }
+ virtual int dataB() const { return 0; }
+ virtual int velo() const { return 0; }
+ virtual void setB(int) { }
+ virtual void setVelo(int) { }
+
+ virtual int veloOff() const { return 0; }
+ virtual int dataC() const { return 0; }
+ virtual void setC(int) { }
+ virtual void setVeloOff(int) { }
+
+ virtual const unsigned char* data() const { return 0; }
+ virtual int dataLen() const { return 0; }
+ virtual void setData(const unsigned char*, int) { }
+ virtual const EvData eventData() const { return EvData(); }
+
+ virtual const QString name() const { return QString("?"); }
+ virtual void setName(const QString&) { }
+ virtual int spos() const { return 0; }
+ virtual void setSpos(int) { }
+ virtual SndFileR sndFile() const { return 0; }
+ virtual void setSndFile(SndFileR&) { }
+ virtual EventBase* clone() const = 0;
+ virtual void read(unsigned /*offset*/, float** /*bpp*/, int /*channels*/, int /*nn*/) {}
+
+ virtual bool operator==(const EventBase&) const { return false; }
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/eventlist.cpp b/muse_qt4_evolution/muse/eventlist.cpp
new file mode 100644
index 00000000..82d3b389
--- /dev/null
+++ b/muse_qt4_evolution/muse/eventlist.cpp
@@ -0,0 +1,93 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "event.h"
+#include "al/xml.h"
+
+//---------------------------------------------------------
+// readEventList
+//---------------------------------------------------------
+
+void EventList::read(QDomNode node, bool midi)
+ {
+ for (; !node.isNull(); node = node.nextSibling()) {
+ QDomElement e = node.toElement();
+ QString tag(e.tagName());
+ if (tag.isEmpty())
+ continue;
+ if (tag == "event") {
+ Event e(midi ? Note : Wave);
+ e.read(node);
+ add(e);
+ }
+ else
+ printf("EventListData:read(): unknown tag %s\n", tag.toAscii().data());
+ }
+ }
+
+//---------------------------------------------------------
+// add
+//---------------------------------------------------------
+
+iEvent EventList::add(const Event& event, unsigned tick)
+ {
+ return std::multimap<unsigned, Event, std::less<unsigned> >::insert(std::pair<const unsigned, Event> (tick, event));
+ }
+
+iEvent EventList::add(const Event& event)
+ {
+ return add(event, event.tick());
+ }
+
+//---------------------------------------------------------
+// move
+//---------------------------------------------------------
+
+void EventList::move(const Event& event, unsigned tick)
+ {
+ iEvent i = find(event);
+ erase(i);
+ std::multimap<unsigned, Event, std::less<unsigned> >::insert(std::pair<const unsigned, Event> (tick, event));
+ }
+
+//---------------------------------------------------------
+// find
+//---------------------------------------------------------
+
+iEvent EventList::find(const Event& event)
+ {
+ EventRange range = equal_range(event.tick());
+ for (iEvent i = range.first; i != range.second; ++i) {
+ if (i->second == event)
+ return i;
+ }
+ return end();
+ }
+
+//---------------------------------------------------------
+// dump
+//---------------------------------------------------------
+
+void EventList::dump() const
+ {
+ for (ciEvent i = begin(); i != end(); ++i)
+ i->second.dump();
+ }
+
diff --git a/muse_qt4_evolution/muse/exportmidi.cpp b/muse_qt4_evolution/muse/exportmidi.cpp
new file mode 100644
index 00000000..f18794ab
--- /dev/null
+++ b/muse_qt4_evolution/muse/exportmidi.cpp
@@ -0,0 +1,376 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "muse.h"
+#include "midifile.h"
+#include "midi.h"
+#include "midictrl.h"
+#include "globals.h"
+#include "widgets/filedialog.h"
+#include "song.h"
+#include "midievent.h"
+#include "event.h"
+#include "midiedit/drummap.h"
+#include "gconfig.h"
+#include "al/sig.h"
+#include "al/tempo.h"
+#include "al/marker.h"
+#include "part.h"
+#include "exportmidi.h"
+
+//---------------------------------------------------------
+// addController
+//---------------------------------------------------------
+
+static void addController(MidiEventList* l, int tick, int channel, int a, int b)
+ {
+ if (a < 0x1000) { // 7 Bit Controller
+ l->insert(MidiEvent(tick, channel, ME_CONTROLLER, a, b));
+ }
+ else if (a < 0x20000) { // 14 Bit Controller
+ int ctrlH = (a >> 8) & 0x7f;
+ int ctrlL = a & 0x7f;
+ int dataH = (b >> 7) & 0x7f;
+ int dataL = b & 0x7f;
+ l->insert(MidiEvent(tick, channel, ME_CONTROLLER, ctrlH, dataH));
+ l->insert(MidiEvent(tick+1, channel, ME_CONTROLLER, ctrlL, dataL));
+ }
+ else if (a < 0x30000) { // RPN 7-Bit Controller
+ int ctrlH = (a >> 8) & 0x7f;
+ int ctrlL = a & 0x7f;
+ l->insert(MidiEvent(tick, channel, ME_CONTROLLER, CTRL_HRPN, ctrlH));
+ l->insert(MidiEvent(tick+1, channel, ME_CONTROLLER, CTRL_LRPN, ctrlL));
+ l->insert(MidiEvent(tick+2, channel, ME_CONTROLLER, CTRL_HDATA, b));
+ }
+ else if (a < 0x40000) { // NRPN 7-Bit Controller
+ int ctrlH = (a >> 8) & 0x7f;
+ int ctrlL = a & 0x7f;
+ l->insert(MidiEvent(tick, channel, ME_CONTROLLER, CTRL_HNRPN, ctrlH));
+ l->insert(MidiEvent(tick+1, channel, ME_CONTROLLER, CTRL_LNRPN, ctrlL));
+ l->insert(MidiEvent(tick+2, channel, ME_CONTROLLER, CTRL_HDATA, b));
+ }
+ else if (a == CTRL_PITCH) {
+ int a = b + 8192;
+ int b = a >> 7;
+ l->insert(MidiEvent(tick, channel, ME_PITCHBEND, a & 0x7f, b & 0x7f));
+ }
+ else if (a == CTRL_PROGRAM) {
+ int hb = (b >> 16) & 0xff;
+ int lb = (b >> 8) & 0xff;
+ int pr = b & 0x7f;
+ int tickoffset = 0;
+ if (hb != 0xff) {
+ l->insert(MidiEvent(tick, channel, ME_CONTROLLER, CTRL_HBANK, hb));
+ ++tickoffset;
+ }
+ if (lb != 0xff) {
+ l->insert(MidiEvent(tick+tickoffset, channel, ME_CONTROLLER, CTRL_LBANK, lb));
+ ++tickoffset;
+ }
+ l->insert(MidiEvent(tick+tickoffset, channel, ME_PROGRAM, pr, 0));
+ }
+ else if (a < 0x60000) { // RPN14 Controller
+ int ctrlH = (a >> 8) & 0x7f;
+ int ctrlL = a & 0x7f;
+ int dataH = (b >> 7) & 0x7f;
+ int dataL = b & 0x7f;
+ l->insert(MidiEvent(tick, channel, ME_CONTROLLER, CTRL_HRPN, ctrlH));
+ l->insert(MidiEvent(tick+1, channel, ME_CONTROLLER, CTRL_LRPN, ctrlL));
+ l->insert(MidiEvent(tick+2, channel, ME_CONTROLLER, CTRL_HDATA, dataH));
+ l->insert(MidiEvent(tick+3, channel, ME_CONTROLLER, CTRL_LDATA, dataL));
+ }
+ else if (a < 0x70000) { // NRPN14 Controller
+ int ctrlH = (a >> 8) & 0x7f;
+ int ctrlL = a & 0x7f;
+ int dataH = (b >> 7) & 0x7f;
+ int dataL = b & 0x7f;
+ l->insert(MidiEvent(tick, channel, ME_CONTROLLER, CTRL_HNRPN, ctrlH));
+ l->insert(MidiEvent(tick+1, channel, ME_CONTROLLER, CTRL_LNRPN, ctrlL));
+ l->insert(MidiEvent(tick+2, channel, ME_CONTROLLER, CTRL_HDATA, dataH));
+ l->insert(MidiEvent(tick+3, channel, ME_CONTROLLER, CTRL_LDATA, dataL));
+ }
+ }
+
+//---------------------------------------------------------
+// exportMidi
+//---------------------------------------------------------
+
+void MusE::exportMidi()
+ {
+ if (exportMidiDialog == 0)
+ exportMidiDialog = new ExportMidiDialog(song->projectPath());
+ int rv = exportMidiDialog->exec();
+ if (rv == 0)
+ return;
+ QString name = exportMidiDialog->filename->text();
+ QFile fp(name);
+ if (fp.exists()) {
+ QString s(QWidget::tr("File\n") + name + QWidget::tr("\nexists"));
+ int rv = QMessageBox::warning(this,
+ QWidget::tr("MusE: export midi file:"),
+ s,
+ QWidget::tr("Overwrite"),
+ QWidget::tr("Quit"), QString::null, 0, 1);
+ if (rv == 1)
+ return;
+ }
+
+ MidiFile mf;
+ int format = exportMidiDialog->smf0->isChecked() ? 0 : 1;
+ mf.setFormat(format);
+
+ MidiFileTrackList* mtl = new MidiFileTrackList;
+
+ MidiTrackList* mt = song->midis();
+ for (iMidiTrack im = mt->begin(); im != mt->end(); ++im) {
+ MidiTrack* track = *im;
+
+ MidiFileTrack* mft = new MidiFileTrack;
+ mtl->push_back(mft);
+
+ MidiEventList* l = &(mft->events);
+ int channel = 0;
+ channel = track->channelNo();
+
+ //-----------------------------------
+ // track name
+ //-----------------------------------
+
+ if (!track->name().isEmpty()) {
+ const char* name = track->name().toAscii().data();
+ int len = strlen(name);
+ MidiEvent ev(0, ME_META, (unsigned char*)name, len+1);
+ ev.setA(0x3); // Meta Sequence/Track Name
+ l->insert(ev);
+ }
+
+ //-----------------------------------
+ // managed controller
+ //-----------------------------------
+
+ CtrlList* cll = track->controller();
+ for (iCtrl ivl = cll->begin(); ivl != cll->end(); ++ivl) {
+ Ctrl* c = ivl->second;
+ int id = c->id();
+ for (iCtrlVal iv = c->begin(); iv != c->end(); ++iv) {
+ int tick = iv.key();
+ int val = iv.value().i;
+ addController(l, tick, channel, id, val);
+ }
+ }
+
+ //-----------------------------------
+ // track comment
+ //-----------------------------------
+
+ if (!track->comment().isEmpty()) {
+ const char* comment = track->comment().toAscii().data();
+ int len = strlen(comment);
+ MidiEvent ev(0, ME_META, (unsigned char*)comment, len+1);
+ ev.setA(0xf); // Meta Text
+ l->insert(ev);
+ }
+ PartList* parts = track->parts();
+ for (iPart p = parts->begin(); p != parts->end(); ++p) {
+ Part* part = p->second;
+ EventList* evlist = part->events();
+ for (iEvent i = evlist->begin(); i != evlist->end(); ++i) {
+ Event ev = i->second;
+ int tick = ev.tick() + part->tick();
+
+ switch (ev.type()) {
+ case Note:
+ {
+ if (ev.velo() == 0) {
+ printf("Warning: midi note has velocity 0, (ignored)\n");
+ continue;
+ }
+ int pitch = ev.pitch();
+ int velo = ev.velo();
+ int len = ev.lenTick();
+
+ //---------------------------------------
+ // apply trackinfo values
+ //---------------------------------------
+
+ if (track->transposition()
+ || track->velocity()
+ || track->compression() != 100
+ || track->len() != 100) {
+ pitch += track->transposition();
+ if (pitch > 127)
+ pitch = 127;
+ if (pitch < 0)
+ pitch = 0;
+
+ velo += track->velocity();
+ velo = (velo * track->compression()) / 100;
+ if (velo > 127)
+ velo = 127;
+ if (velo < 1) // no off event
+ velo = 1;
+ len = (len * track->len()) / 100;
+ }
+ if (len <= 0)
+ len = 1;
+ l->insert(MidiEvent(tick, channel, ME_NOTEON, pitch, velo));
+ l->insert(MidiEvent(tick+len, channel, ME_NOTEON, pitch, 0));
+ }
+ break;
+
+ case Controller:
+ addController(l, tick, channel, ev.dataA(), ev.dataB());
+ break;
+
+ case Sysex:
+ l->insert(MidiEvent(tick, ME_SYSEX, ev.eventData()));
+ break;
+
+ case PAfter:
+ l->insert(MidiEvent(tick, channel, ME_AFTERTOUCH, ev.dataA(), ev.dataB()));
+ break;
+
+ case CAfter:
+ l->insert(MidiEvent(tick, channel, ME_POLYAFTER, ev.dataA(), ev.dataB()));
+ break;
+
+ case Meta:
+ {
+ MidiEvent mpev(tick, ME_META, ev.eventData());
+ mpev.setA(ev.dataA());
+ l->insert(mpev);
+ }
+ break;
+ case Wave:
+ break;
+ }
+ }
+ }
+ }
+
+ MidiFileTrack* mft = mtl->front();
+ MidiEventList* l = &(mft->events);
+
+ //---------------------------------------------------
+ // Write Track Marker
+ //
+ AL::MarkerList* ml = song->marker();
+ for (AL::ciMarker m = ml->begin(); m != ml->end(); ++m) {
+ const char* name = m->second.name().toAscii().data();
+ int len = strlen(name);
+ MidiEvent ev(m->first, ME_META, (unsigned char*)name, len);
+ ev.setA(0x6);
+ l->insert(ev);
+ }
+
+ //---------------------------------------------------
+ // Write Copyright
+ //
+ const char* copyright = config.copyright.toAscii().data();
+ if (copyright && *copyright) {
+ int len = strlen(copyright);
+ MidiEvent ev(0, ME_META, (unsigned char*)copyright, len);
+ ev.setA(0x2);
+ l->insert(ev);
+ }
+
+ //---------------------------------------------------
+ // Write Tempomap
+ //
+ AL::TempoList* tl = &AL::tempomap;
+ for (AL::ciTEvent e = tl->begin(); e != tl->end(); ++e) {
+ AL::TEvent* event = e->second;
+ unsigned char data[3];
+ int tempo = event->tempo;
+ data[2] = tempo & 0xff;
+ data[1] = (tempo >> 8) & 0xff;
+ data[0] = (tempo >> 16) & 0xff;
+ MidiEvent ev(event->tick, ME_META, data, 3);
+ ev.setA(0x51);
+ l->insert(ev);
+ }
+
+ //---------------------------------------------------
+ // Write Signatures
+ //
+ const AL::SigList* sl = &AL::sigmap;
+ for (AL::ciSigEvent e = sl->begin(); e != sl->end(); ++e) {
+ AL::SigEvent* event = e->second;
+ unsigned char data[2];
+ data[0] = event->sig.z;
+ switch(event->sig.n) {
+ case 1: data[1] = 0; break;
+ case 2: data[1] = 1; break;
+ case 4: data[1] = 2; break;
+ case 8: data[1] = 3; break;
+ case 16: data[1] = 4; break;
+ case 32: data[1] = 5; break;
+ case 64: data[1] = 6; break;
+ default:
+ fprintf(stderr, "falsche Signatur; nenner %d\n", event->sig.n);
+ break;
+ }
+ MidiEvent ev(event->tick, ME_META, data, 2);
+ ev.setA(0x58);
+ l->insert(ev);
+ }
+
+ mf.setDivision(config.midiDivision);
+ mf.setTrackList(mtl);
+ fp.open(QIODevice::WriteOnly);
+ mf.write(&fp);
+ fp.close();
+ }
+
+//---------------------------------------------------------
+// ExportMidiDialog
+//---------------------------------------------------------
+
+ExportMidiDialog::ExportMidiDialog(const QString& name, QWidget* parent)
+ : QDialog(parent)
+ {
+ setupUi(this);
+
+ smf0->setChecked(config.smfFormat == 0);
+ smf1->setChecked(config.smfFormat == 1);
+ QFileInfo fi(name);
+ QString s(fi.path() + "/" + fi.baseName() + ".mid");
+ label->setText(tr("Save ") + fi.baseName() + tr(" as smf midi file"));
+ filename->setText(s);
+ connect(fileButton, SIGNAL(clicked()), SLOT(startFileBrowser()));
+ }
+
+//---------------------------------------------------------
+// startFileBrowser
+//---------------------------------------------------------
+
+void ExportMidiDialog::startFileBrowser()
+ {
+ QString s = QFileDialog::getSaveFileName(
+ (QWidget*)this,
+ tr("MusE: export midi smf file"),
+ QFileInfo(filename->text()).path(),
+ QString("Midi Files (*.mid *.kar *.MID)"),
+ 0,
+ QFileDialog::DontConfirmOverwrite);
+ if (!s.isEmpty())
+ filename->setText(s);
+ }
+
diff --git a/muse_qt4_evolution/muse/exportmidi.h b/muse_qt4_evolution/muse/exportmidi.h
new file mode 100644
index 00000000..0a4fa071
--- /dev/null
+++ b/muse_qt4_evolution/muse/exportmidi.h
@@ -0,0 +1,41 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __EXPORTMIDI_H__
+#define __EXPORTMIDI_H__
+
+#include "ui_exportmididialog.h"
+
+//---------------------------------------------------------
+// ExportMidiDialog
+//---------------------------------------------------------
+
+class ExportMidiDialog : public QDialog, public Ui::ExportMidiDialogBase {
+ Q_OBJECT
+
+ private slots:
+ void startFileBrowser();
+
+ public:
+ ExportMidiDialog(const QString&, QWidget* parent = 0);
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/exportmididialog.ui b/muse_qt4_evolution/muse/exportmididialog.ui
new file mode 100644
index 00000000..69d35da1
--- /dev/null
+++ b/muse_qt4_evolution/muse/exportmididialog.ui
@@ -0,0 +1,176 @@
+<ui version="4.0" >
+ <author></author>
+ <comment></comment>
+ <exportmacro></exportmacro>
+ <class>ExportMidiDialogBase</class>
+ <widget class="QDialog" name="ExportMidiDialogBase" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>425</width>
+ <height>316</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>MusE: Export Midi</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Line" name="line" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="smf0" >
+ <property name="text" >
+ <string>SMF Typ 0 (single track)</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="smf1" >
+ <property name="text" >
+ <string>SMF Typ 1 (multiple tracks)</string>
+ </property>
+ <property name="checked" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Save As:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="filename" />
+ </item>
+ <item>
+ <widget class="QToolButton" name="fileButton" >
+ <property name="text" >
+ <string>...</string>
+ </property>
+ <property name="icon" >
+ <iconset resource="../muse.qrc" >:/xpm/filenew.png</iconset>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>131</width>
+ <height>31</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="okButton" >
+ <property name="text" >
+ <string>OK</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="cancelButton" >
+ <property name="text" >
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <pixmapfunction></pixmapfunction>
+ <resources>
+ <include location="../muse.qrc" />
+ </resources>
+ <connections>
+ <connection>
+ <sender>okButton</sender>
+ <signal>clicked()</signal>
+ <receiver>ExportMidiDialogBase</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>321</x>
+ <y>274</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>96</x>
+ <y>254</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>cancelButton</sender>
+ <signal>clicked()</signal>
+ <receiver>ExportMidiDialogBase</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>414</x>
+ <y>274</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>179</x>
+ <y>282</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/muse_qt4_evolution/muse/extmidieditor.cpp b/muse_qt4_evolution/muse/extmidieditor.cpp
new file mode 100644
index 00000000..38377b94
--- /dev/null
+++ b/muse_qt4_evolution/muse/extmidieditor.cpp
@@ -0,0 +1,422 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2004 Mathias Lundgren <lunar_shuttle@users.sourceforge.net>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __EXTMIDIEDITOR_CPP__
+#define __EXTMIDIEDITOR_CPP__
+
+#include "extmidieditor.h"
+#include "part.h"
+#include "al/xml.h"
+#include "al/pos.h"
+#include "song.h"
+#include "midiedit/ecanvas.h"
+#include "waveedit/waveview.h"
+#include "esettings.h"
+// #include "../ctrl/ctrledit.h"
+
+//---------------------------------------------------------
+// GraphMidiEditor
+//---------------------------------------------------------
+
+GraphMidiEditor::GraphMidiEditor(PartList* pl)
+ : MidiEditor(pl)
+ {
+ setIconSize(QSize(ICON_SIZE));
+ _followSong = true;
+ }
+
+//---------------------------------------------------------
+// ~GraphMidiEditor
+//---------------------------------------------------------
+
+GraphMidiEditor::~GraphMidiEditor()
+ {
+ refreshSettings();
+ }
+
+//---------------------------------------------------------
+// newDefaultSettings
+//---------------------------------------------------------
+
+EditorSettings* GraphMidiEditor::newDefaultSettings()
+ {
+ return new GraphEditorSettings();
+ }
+
+//---------------------------------------------------------
+// initSettings
+//---------------------------------------------------------
+
+void GraphMidiEditor::initSettings()
+ {
+ MidiEditor::initSettings();
+#if 0 //TD
+ GraphEditorSettings* s = ((GraphEditorSettings*)(settings));
+ hscroll->setXmag(s->xmag()); //horizontal zoom
+ hscroll->setPos(s->pos());
+
+ if (editorType != ET_WAVEEDIT)
+ vscroll->setPos(((GraphEditorSettings*)settings)->ypos());
+#endif
+ }
+
+
+//---------------------------------------------------------
+// refreshSettings
+//---------------------------------------------------------
+void GraphMidiEditor::refreshSettings() const
+ {
+ MidiEditor::refreshSettings();
+// if (editorType != ET_WAVEEDIT) //hACK! TODO: Separate waveedit class
+// ((GraphEditorSettings*)settings)->setYpos(vscroll->pos());
+ }
+
+//---------------------------------------------------------
+// raster
+//---------------------------------------------------------
+int GraphMidiEditor::raster() const
+ {
+ return settings->raster();
+ }
+
+//---------------------------------------------------------
+// setRaster
+//---------------------------------------------------------
+void GraphMidiEditor::setRaster(int val)
+ {
+ settings->setRaster(val);
+// canvas->setFocus(); // give back focus after kb input
+ //_raster = val;
+ }
+
+//---------------------------------------------------------
+// rasterStep
+//---------------------------------------------------------
+int GraphMidiEditor::rasterStep(unsigned tick) const
+ {
+ return AL::sigmap.rasterStep(tick, settings->raster());
+ }
+
+//---------------------------------------------------------
+// rasterVal
+//---------------------------------------------------------
+unsigned GraphMidiEditor::rasterVal(unsigned v) const
+ {
+ return AL::sigmap.raster(v, settings->raster());
+ }
+
+//---------------------------------------------------------
+// rasterVal1
+//---------------------------------------------------------
+unsigned GraphMidiEditor::rasterVal1(unsigned v) const
+ {
+ return AL::sigmap.raster1(v, settings->raster());
+ }
+
+//---------------------------------------------------------
+// rasterVal2
+//---------------------------------------------------------
+unsigned GraphMidiEditor::rasterVal2(unsigned v) const
+ {
+ return AL::sigmap.raster2(v, settings->raster());
+ }
+
+
+//---------------------------------------------------------
+// ExtMidiEditor
+//---------------------------------------------------------
+
+ExtMidiEditor::ExtMidiEditor(PartList* pl)
+ : GraphMidiEditor(pl)
+ {
+ _curDrumInstrument = -1;
+ //printf("ExtMidiEditor, defaultSettings: %x\n",&defaultSettings);
+ }
+
+//---------------------------------------------------------
+// ~ExtMidiEditor
+//---------------------------------------------------------
+
+ExtMidiEditor::~ExtMidiEditor()
+ {
+ refreshSettings();
+ }
+
+//---------------------------------------------------------
+// updateCtrlEdits
+//---------------------------------------------------------
+
+void ExtMidiEditor::updateCtrlEdits() const
+ {
+#if 0 //TD
+ ExtEditorSettings* s = (ExtEditorSettings*) settings;
+ int j=0;
+ for (std::list<CtrlEdit*>::const_iterator i = ctrlEditList.begin(); i != ctrlEditList.end(); ++i, j++) {
+ CtrlEdit* ctrlEdit = (*i);
+ int ctrlid = ctrlEdit->controllerId();
+ CtrlEditSettings* ctrl = new CtrlEditSettings(ctrlEdit->getPanelHeight(), ctrlid);
+ s->setControlEditSettings(j, ctrl);
+ }
+#endif
+ }
+
+//---------------------------------------------------------
+// newDefaultSettings
+//---------------------------------------------------------
+EditorSettings* ExtMidiEditor::newDefaultSettings()
+ {
+ return (EditorSettings*) new ExtEditorSettings();
+ }
+
+//---------------------------------------------------------
+// initSettings
+//---------------------------------------------------------
+
+void ExtMidiEditor::initSettings()
+ {
+ GraphMidiEditor::initSettings();
+
+ ExtEditorSettings* s = (ExtEditorSettings*) settings;
+ srec->setChecked(s->steprec()); //set steprec
+ midiin->setChecked(s->midiin()); //set midiin
+ int ctrlsize = s->getControlEditSize();
+ //Set to 0 again to not get the double amount of ctrledits:
+ s->setControlEditSize(0);
+ for (int i=0; i< ctrlsize; i++) {
+ CtrlEditSettings* settings = s->getControlEditSettings(i);
+ CtrlEdit* ctrlEdit = addCtrl();
+//TD ctrlEdit->setController(settings->getController());
+ }
+ QList<int> vl;
+ vl.push_back(400); // dummy: canvas height
+ for (int i = 0; i < ctrlsize; i++) {
+ CtrlEditSettings* settings = s->getControlEditSettings(i);
+ vl.push_back(settings->getHeight());
+ }
+//TD splitter->setSizes(vl);
+ }
+
+//---------------------------------------------------------
+// quantVal
+//---------------------------------------------------------
+
+int ExtMidiEditor::quantVal(int v) const
+ {
+ ExtEditorSettings* s = (ExtEditorSettings*) settings;
+ //int val = ((v+_quant/2)/_quant)*_quant;
+ int q = s->quant();
+ int val = ((v+q/2)/q)*q;
+ if (val == 0)
+ val = q;
+ return val;
+ }
+
+//---------------------------------------------------------
+// readStatus
+//---------------------------------------------------------
+
+/*
+void ExtMidiEditor::readStatus(Xml& xml)
+ {
+ if (_pl == 0)
+ _pl = new PartList;
+
+ for (;;) {
+ Xml::Token token = xml.parse();
+ QString tag = xml.s1();
+ switch (token) {
+ case Xml::Error:
+ case Xml::End:
+ return;
+ case Xml::TagStart:
+ if (tag == "quant")
+ _quant = xml.parseInt();
+ else if (tag == "raster")
+ _raster = xml.parseInt();
+ else if (tag == "topwin")
+ TopWin::readStatus(xml);
+ else
+ xml.unknown("MidiEditor");
+ break;
+ case Xml::TagEnd:
+ if (tag == "midieditor")
+ return;
+ default:
+ break;
+ }
+ }
+ }
+*/
+
+//---------------------------------------------------------
+// setCurDrumInstrument
+//---------------------------------------------------------
+
+void ExtMidiEditor::setCurDrumInstrument(int instr)
+ {
+ _curDrumInstrument = instr;
+ emit curDrumInstrumentChanged(_curDrumInstrument);
+ }
+
+//---------------------------------------------------------
+// writeStatus
+//---------------------------------------------------------
+/*
+void ExtMidiEditor::writeStatus(int level, Xml& xml) const
+ {
+ xml.tag(level++, "midieditor");
+ TopWin::writeStatus(level, xml);
+ xml.intTag(level, "quant", _quant);
+ xml.intTag(level, "raster", _raster);
+ xml.tag(level, "/midieditor");
+ }
+*/
+
+//---------------------------------------------------------
+// quant
+//---------------------------------------------------------
+int ExtMidiEditor::quant() const
+ {
+ ExtEditorSettings* s = (ExtEditorSettings*) settings;
+ return s->quant();
+ }
+
+//---------------------------------------------------------
+// setQuant
+//---------------------------------------------------------
+
+void ExtMidiEditor::setQuant(int val)
+ {
+ ExtEditorSettings* s = (ExtEditorSettings*) settings;
+ s->setQuant(val);
+ canvas->setQuant(val);
+ canvas->setFocus();
+ }
+
+
+//---------------------------------------------------------
+// follow
+//---------------------------------------------------------
+
+void ExtMidiEditor::follow(int pos)
+ {
+ int s, e;
+ canvas->range(&s, &e);
+
+// if (pos < e && pos >= s)
+// hscroll->setOffset(pos);
+// if (pos < s)
+// hscroll->setOffset(s);
+ }
+
+//---------------------------------------------------------
+// removeCtrl
+//---------------------------------------------------------
+
+void ExtMidiEditor::removeCtrl(CtrlEdit* ctrl)
+ {
+ for (std::list<CtrlEdit*>::iterator i = ctrlEditList.begin();
+ i != ctrlEditList.end(); ++i) {
+ if (*i == ctrl) {
+ ctrlEditList.erase(i);
+ break;
+ }
+ }
+ ExtEditorSettings* s = (ExtEditorSettings*)settings;
+ int n = s->getControlEditSize();
+ n--;
+ s->setControlEditSize(n);
+ }
+
+//---------------------------------------------------------
+// addCtrl
+//---------------------------------------------------------
+
+CtrlEdit* ExtMidiEditor::addCtrl()
+ {
+#if 0 //TD
+ bool expanding = editorType == ET_DRUMEDIT ? true : false;
+
+ CtrlEdit* ctrlEdit = new CtrlEdit(splitter, this, EXTMIDIEDITOR_XSCALE, expanding, "extMidiEditorCtrlEdit");
+ splitter->setResizeMode(ctrlEdit, QSplitter::KeepSize);
+
+ // Calculate sizes:
+ QList<int> sizes = splitter->sizes();
+ QList<int> newSizes;
+ QListIterator<int> i = sizes.begin();
+
+ int editorHeight = *i - EXTMIDIEDITOR_DEFAULT_CTRLHEIGHT;
+ int ctrlHeight = EXTMIDIEDITOR_DEFAULT_CTRLHEIGHT;
+ if (editorHeight < 0) {
+ ctrlHeight = EXTMIDIEDITOR_DEFAULT_CTRLHEIGHT + editorHeight;
+ editorHeight = *i - ctrlHeight;
+ }
+ if (editorHeight < 0) {
+ editorHeight = 5;
+ }
+
+ newSizes.append(editorHeight);
+ for (i++; i != sizes.end(); i++) {
+ newSizes.append(*i);
+ }
+ newSizes.pop_back();
+ newSizes.append(ctrlHeight);
+ splitter->setSizes(newSizes);
+
+ ctrlEdit->blockSignals(true);
+ connect(tools2, SIGNAL(toolChanged(int)), ctrlEdit, SLOT(setTool(int)));
+// connect(hscroll, SIGNAL(scrollChanged(int)), ctrlEdit, SLOT(setXPos(int)));
+// connect(hscroll, SIGNAL(scaleChanged(int)), ctrlEdit, SLOT(setXMag(int)));
+ connect(ctrlEdit, SIGNAL(timeChanged(unsigned)), SLOT(setTime(unsigned)));
+ connect(ctrlEdit, SIGNAL(destroyedCtrl(CtrlEdit*)), SLOT(removeCtrl(CtrlEdit*)));
+// connect(ctrlEdit, SIGNAL(yposChanged(int)), toolbar, SLOT(setInt(int)));
+
+ ctrlEdit->setTool(tools2->curTool());
+// ctrlEdit->setXPos(hscroll->pos());
+// ctrlEdit->setXMag(hscroll->getScaleValue());
+ ctrlEdit->setController(CTRL_VELOCITY);
+
+ ctrlEdit->show();
+ ctrlEditList.push_back(ctrlEdit);
+ ctrlEdit->blockSignals(false);
+ ExtEditorSettings* s = (ExtEditorSettings*)settings;
+ int n = s->getControlEditSize();
+ n++;
+ s->setControlEditSize(n);
+ return ctrlEdit;
+#endif
+ return 0;
+ }
+
+//---------------------------------------------------------
+// refreshSettings
+//---------------------------------------------------------
+void ExtMidiEditor::refreshSettings() const
+ {
+ GraphMidiEditor::refreshSettings();
+ ExtEditorSettings* s = (ExtEditorSettings*) settings;
+ s->setSteprec(canvas->steprec());
+ s->setMidiin(canvas->midiin());
+// s->setXmag(hscroll->xmag());
+// s->setPos(hscroll->pos());
+ updateCtrlEdits();
+ }
+
+#endif
diff --git a/muse_qt4_evolution/muse/extmidieditor.h b/muse_qt4_evolution/muse/extmidieditor.h
new file mode 100644
index 00000000..b02ac730
--- /dev/null
+++ b/muse_qt4_evolution/muse/extmidieditor.h
@@ -0,0 +1,120 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2004 Mathias Lundgren <lunar_shuttle@users.sourceforge.net>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __EXTMIDIEDITOR_H__
+#define __EXTMIDIEDITOR_H__
+
+#include "midiedit/midieditor.h"
+#include "esettings.h"
+
+namespace AL {
+ class Pos;
+ };
+
+class EditToolBar;
+class NoteInfo;
+class PartList;
+class CtrlEdit;
+class Toolbar1;
+class Part;
+
+//---------------------------------------------------------
+// GraphMidiEditor
+//
+// Base class for graphical editors
+// Currently used by WaveEdit and MasterEdit
+//---------------------------------------------------------
+
+class GraphMidiEditor : public MidiEditor {
+ Q_OBJECT
+
+ protected:
+ virtual EditorSettings* newDefaultSettings(); //TODO: = 0
+ virtual void initSettings();
+ virtual void refreshSettings() const;
+ QAction* srec;
+ QAction* midiin;
+ bool _followSong;
+ EditToolBar* tools2;
+
+ protected slots:
+ void setRaster(int val);
+
+ public:
+ GraphMidiEditor(PartList*);
+ virtual ~GraphMidiEditor();
+ int rasterStep(unsigned tick) const;
+ unsigned rasterVal(unsigned v) const;
+ unsigned rasterVal1(unsigned v) const;
+ unsigned rasterVal2(unsigned v) const;
+ int raster() const;
+ bool followSong() const { return _followSong; }
+ };
+
+
+//---------------------------------------------------------
+// ExtMidiEditor
+//
+// Inherited by Drumeditor and Pianoroll
+// Not instantiated directly - virtual
+//---------------------------------------------------------
+
+class ExtMidiEditor : public GraphMidiEditor {
+ Q_OBJECT
+ int _curDrumInstrument; // currently selected instrument if drum
+ // editor
+
+ protected:
+ std::list<CtrlEdit*> ctrlEditList;
+ virtual EditorSettings* newDefaultSettings();
+ virtual void initSettings();
+ virtual void refreshSettings() const;
+ Toolbar1* toolbar;
+ Part* selPart;
+ NoteInfo* info;
+ QToolBar* tools;
+ EventCanvas* canvas;
+ WaveView* wview;
+
+ void updateCtrlEdits() const;
+
+ signals:
+ void curDrumInstrumentChanged(int); //hACK!
+
+ protected slots:
+ void setQuant(int val);
+ void follow(int pos);
+ void removeCtrl(CtrlEdit* ctrl);
+ virtual CtrlEdit* addCtrl();
+
+ public slots:
+ void setCurDrumInstrument(int instr); //hACK!
+
+ public:
+ ExtMidiEditor(PartList*);
+ virtual ~ExtMidiEditor();
+ int quantVal(int v) const;
+ int quant() const;
+
+ int curDrumInstrument() const { return _curDrumInstrument; }
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/fastlog.h b/muse_qt4_evolution/muse/fastlog.h
new file mode 100644
index 00000000..23710a8b
--- /dev/null
+++ b/muse_qt4_evolution/muse/fastlog.h
@@ -0,0 +1,38 @@
+/* Copyright unknown. Code by Laurent de Soras <laurent@ohmforce.com>.
+ */
+
+#ifndef __pbd_fastlog_h__
+#define __pbd_fastlog_h__
+
+#include <math.h> /* for HUGE_VAL */
+
+static inline float fast_log2 (float val)
+ {
+ /* don't use reinterpret_cast<> because that prevents this
+ from being used by pure C code (for example, GnomeCanvasItems)
+ */
+ union {float f; int i;} t;
+ t.f = val;
+ int* const exp_ptr = &t.i;
+ int x = *exp_ptr;
+ const int log_2 = ((x >> 23) & 255) - 128;
+ x &= ~(255 << 23);
+ x += 127 << 23;
+ *exp_ptr = x;
+ val = ((-1.0f/3) * t.f + 2) * t.f - 2.0f/3;
+ return (val + log_2);
+ }
+
+static inline float fast_log (const float val)
+ {
+ return (fast_log2 (val) * 0.69314718f);
+ }
+
+static inline float fast_log10 (const float val)
+ {
+ return fast_log2(val) / 3.312500f;
+ }
+
+static inline float minus_infinity() { return -HUGE_VAL; }
+
+#endif /* __pbd_fastlog_h__ */
diff --git a/muse_qt4_evolution/muse/fifo.cpp b/muse_qt4_evolution/muse/fifo.cpp
new file mode 100644
index 00000000..12c2febf
--- /dev/null
+++ b/muse_qt4_evolution/muse/fifo.cpp
@@ -0,0 +1,183 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "fifo.h"
+#include "globals.h"
+#include "al/dsp.h"
+
+//---------------------------------------------------------
+// clear
+//---------------------------------------------------------
+
+void FifoBase::clear()
+ {
+ ridx = 0;
+ widx = 0;
+ counter = 0;
+ }
+
+//---------------------------------------------------------
+// push
+//---------------------------------------------------------
+
+void FifoBase::push()
+ {
+ widx = (widx + 1) % FIFO_BUFFER;
+// q_atomic_increment(&counter);
+ ++counter;
+ }
+
+//---------------------------------------------------------
+// pop
+//---------------------------------------------------------
+
+void FifoBase::pop()
+ {
+ ridx = (ridx + 1) % FIFO_BUFFER;
+ // q_atomic_decrement(&counter);
+ --counter;
+ }
+
+//---------------------------------------------------------
+// Fifo
+//---------------------------------------------------------
+
+Fifo::Fifo()
+ {
+ nbuffer = FIFO_BUFFER;
+ buffer = new FifoBuffer*[nbuffer];
+ for (int i = 0; i < nbuffer; ++i)
+ buffer[i] = new FifoBuffer;
+ clear();
+ }
+
+Fifo::~Fifo()
+ {
+ for (int i = 0; i < nbuffer; ++i)
+ delete buffer[i];
+ delete[] buffer;
+ }
+
+//---------------------------------------------------------
+// put
+// return true if fifo full
+//---------------------------------------------------------
+
+bool Fifo::put(int segs, unsigned long samples, float** src, unsigned pos)
+ {
+ if (counter == nbuffer) {
+ printf("FIFO %p overrun at 0x%x\n", this, pos);
+ return true;
+ }
+ FifoBuffer* b = buffer[widx];
+ int n = segs * samples;
+ if (b->maxSize < n) {
+ if (b->buffer)
+ free(b->buffer);
+ posix_memalign((void**)&(b->buffer), 16, sizeof(float) * n);
+ b->maxSize = n;
+ }
+ b->size = samples;
+ b->segs = segs;
+ b->pos = pos;
+ for (int i = 0; i < segs; ++i)
+ AL::dsp->cpy(b->buffer + i * samples, src[i], samples);
+ push();
+ return false;
+ }
+
+//---------------------------------------------------------
+// get
+// return true if fifo empty
+//---------------------------------------------------------
+
+bool Fifo::get(int segs, unsigned long samples, float** dst, unsigned pos)
+ {
+ FifoBuffer* b;
+ bool errMsg = true;
+ for (;;) {
+ if (counter == 0) {
+ printf("FIFO %p underrun at 0x%x\n", this, pos);
+ return true;
+ }
+ b = buffer[ridx];
+ if (pos == b->pos)
+ break;
+ //
+ // skip all buffer until we get the rigth one or the
+ // fifo is empty
+ //
+// if (errMsg)
+ printf("Fifo %p::get(0x%x) n=%d, discard wrong prefetch block(s) 0x%x\n",
+ this, pos, counter, b->pos);
+ pop();
+ errMsg = false;
+ }
+ for (int i = 0; i < segs; ++i)
+ dst[i] = b->buffer + samples * (i % b->segs);
+ pop();
+ return false;
+ }
+
+//---------------------------------------------------------
+// get
+// return true if fifo empty
+//---------------------------------------------------------
+
+bool Fifo::get(int segs, unsigned long samples, float** dst)
+ {
+ FifoBuffer* b;
+ if (counter == 0) {
+ printf("FIFO %p underrun --cannot happen!\n", this);
+ return true;
+ }
+ b = buffer[ridx];
+ for (int i = 0; i < segs; ++i)
+ dst[i] = b->buffer + samples * (i % b->segs);
+ pop();
+ return false;
+ }
+
+//---------------------------------------------------------
+// getWriteBuffer
+// return true, if no more buffer available
+// (overflow)
+//---------------------------------------------------------
+
+bool Fifo::getWriteBuffer(int segs, unsigned long samples, float** buf, unsigned pos)
+ {
+ if (counter == nbuffer)
+ return true;
+ FifoBuffer* b = buffer[widx];
+ int n = segs * samples;
+ if (b->maxSize < n) {
+ if (b->buffer)
+ free(b->buffer);
+ posix_memalign((void**)&(b->buffer), 16, sizeof(float) * n);
+ b->maxSize = n;
+ }
+ for (int i = 0; i < segs; ++i)
+ buf[i] = b->buffer + i * samples;
+ b->size = samples;
+ b->segs = segs;
+ b->pos = pos;
+ return false;
+ }
+
diff --git a/muse_qt4_evolution/muse/fifo.h b/muse_qt4_evolution/muse/fifo.h
new file mode 100644
index 00000000..b4c49288
--- /dev/null
+++ b/muse_qt4_evolution/muse/fifo.h
@@ -0,0 +1,105 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __FIFO_H__
+#define __FIFO_H__
+
+const int FIFO_BUFFER = 256;
+
+//---------------------------------------------------------
+// Fifo
+//---------------------------------------------------------
+
+struct FifoBuffer {
+ float* buffer;
+ int size;
+ int maxSize;
+ unsigned pos;
+ int segs;
+
+ FifoBuffer() {
+ buffer = 0;
+ size = 0;
+ maxSize = 0;
+ }
+ };
+
+//---------------------------------------------------------
+// FifoBase
+// - works only for one reader/writer
+// - reader writes ridx
+// - writer writes widx
+// - reader decrements counter
+// - writer increments counter
+// - counter increment/decrement must be atomic
+//---------------------------------------------------------
+
+class FifoBase {
+
+ protected:
+ int ridx; // read index
+ int widx; // write index
+ volatile int counter; // objects in fifo
+
+ public:
+ FifoBase() { clear(); }
+ virtual ~FifoBase() {}
+ void clear();
+ virtual void push(); // put object on fifo
+ virtual void pop(); // remove object from fifo
+ int count() const { return counter; }
+ int readIndex() const { return ridx; }
+ };
+
+//---------------------------------------------------------
+// Fifo
+//---------------------------------------------------------
+
+class Fifo : public FifoBase {
+ int nbuffer; // max buffer size (fifo-size)
+ FifoBuffer** buffer;
+
+ public:
+ Fifo();
+ ~Fifo();
+ bool put(int, unsigned long, float** buffer, unsigned pos);
+ bool getWriteBuffer(int, unsigned long, float** buffer, unsigned pos);
+ bool get(int, unsigned long, float** buffer, unsigned pos);
+ bool get(int, unsigned long, float** buffer);
+ };
+
+//---------------------------------------------------------
+// Fifo1
+//---------------------------------------------------------
+
+class Fifo1 : public FifoBase {
+ public:
+ unsigned positions[FIFO_BUFFER];
+
+ Fifo1() : FifoBase() {}
+ int setWritePos(unsigned pos) {
+ positions[widx] = pos;
+ return widx;
+ }
+ unsigned readPos() const { return positions[ridx]; }
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/gconfig.cpp b/muse_qt4_evolution/muse/gconfig.cpp
new file mode 100644
index 00000000..f80542cb
--- /dev/null
+++ b/muse_qt4_evolution/muse/gconfig.cpp
@@ -0,0 +1,121 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "gconfig.h"
+
+GlobalConfigValues config = {
+ ":/style.qss", // default style sheet
+ {
+ QColor(255, 232, 140), // part colors
+ QColor(0xff, 0x00, 0x00),
+ QColor(0x00, 0xff, 0x00),
+ QColor(0x00, 0x00, 0xff),
+ QColor(0xff, 0xff, 0x00),
+ QColor(0x00, 0xff, 0xff),
+ QColor(0xff, 0x00, 0xff),
+ QColor(0x9f, 0xc7, 0xef),
+ QColor(0x00, 0xff, 0x7f),
+ QColor(0x7f, 0x00, 0x00),
+ QColor(0x00, 0x7f, 0x00),
+ QColor(0x00, 0x00, 0x7f),
+ QColor(0x7f, 0x7f, 0x3f),
+ QColor(0x00, 0x7f, 0x7f),
+ QColor(0x7f, 0x00, 0x7f),
+ QColor(0x00, 0x7f, 0xff),
+ QColor(0x00, 0x3f, 0x3f)
+ },
+ QColor(100, 100, 100), // selected Part Bg
+ QColor(0, 0, 255), // transportHandleColor;
+ QColor(255, 0, 0), // bigTimeForegroundColor;
+ QColor(0, 0, 0), // bigTimeBackgroundColor;
+ QColor(200, 200, 200), // waveEditBackgroundColor;
+ {
+ QColor(Qt::white), // outputTrackBg;
+ QColor(Qt::yellow), // groupTrackBg;
+ QColor(Qt::green), // waveTrackBg;
+ QColor(Qt::red), // inputTrackBg;
+ QColor(Qt::blue), // synthTrackBg;
+ QColor(Qt::gray), // midi;
+ QColor(Qt::gray), // midiOut;
+ QColor(Qt::gray), // midiIn;
+ QColor(Qt::gray), // midiSynti;
+ },
+
+ QColor(0, 0, 0), // mixerBg;
+
+ 384, // division;
+ 1024, // rtcTicks
+ -60.0, // minMeter (dB)
+ 10.0, // maxMeter (dB)
+ -60.0, // double minSlider (dB)
+ 10.0, // double maxSlider (dB)
+ 20, // int guiRefresh;
+ 2000, // peak hold time (ms)
+ QString(""), // helpBrowser
+ true, // extendedMidi
+ 384, // division for smf export
+ QString(""), // copyright string for smf export
+ 1, // smf export file format
+ START_ASK_FOR_PROJECT, // startMode
+ QString(""), // start song path
+ 384, // gui division
+ QRect(0, 0, 200, 100), // GeometryTransport;
+ QRect(0, 0, 600, 200), // GeometryBigTime;
+ QRect(100, 100, 600, 400), // GeometryPianoroll;
+ QRect(0, 0, 600, 400), // GeometryDrumedit;
+ {
+ QRect(0, 0, 300, 500), // Mixer1
+ false, true, true, true,
+ true, true, true, true, true, true
+ },
+ {
+ QRect(200, 200, 300, 500), // Mixer2
+ false, true, true, true,
+ true, true, true, true, true, true
+ },
+ false, // TransportVisible
+ false, // BigTimeVisible;
+ false, // mixerVisible1;
+ false, // mixerVisible2;
+
+ true, // showSplashScreen
+
+ QColor(0x71, 0x8d, 0xbe), // canvasBgColor
+ QString(""), // canvasBgPixmap;
+ false, // canvasUseBgPixmap;
+ 1, // canvasShowPartType 1 - names, 2 events
+ 5, // canvasShowPartEvent
+ false, // canvasShowGrid;
+
+ false, // use JACK freewheel mode
+ QString("sweep"), // externalWavEditor shell command
+
+ QString(""), // defaultMidiInputDevice
+ QString(""), // defaultMidiOutputDevice
+ QString(""), // defaultMidiInstrument
+ true, // connectToAllMidiDevices
+ true, // connectToAllMidiTracks
+ true, // createDefaultMidiInput
+ QString("MusE/projects"), // projectPath
+ QString("MusE/templates"), // templatePath
+ QString("MusE/instruments"), // instrumentPath
+ QString("MusE/"), // midi import path
+ QString("MusE/"), // wave import path
+ };
diff --git a/muse_qt4_evolution/muse/gconfig.h b/muse_qt4_evolution/muse/gconfig.h
new file mode 100644
index 00000000..b30fdebb
--- /dev/null
+++ b/muse_qt4_evolution/muse/gconfig.h
@@ -0,0 +1,133 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __CONFIG_H__
+#define __CONFIG_H__
+
+#define NUM_PARTCOLORS 17
+
+#include "track.h"
+#include "al/xml.h"
+using AL::Xml;
+
+enum StartMode {
+ START_ASK_FOR_PROJECT,
+ START_LAST_PROJECT,
+ START_START_PROJECT
+ };
+
+//---------------------------------------------------------
+// MixerConfig
+//---------------------------------------------------------
+
+struct MixerConfig {
+ QRect geometry;
+ bool showMidiTracks;
+ bool showMidiInPorts;
+ bool showMidiSyntiPorts;
+ bool showMidiOutPorts;
+ bool showOutputTracks;
+ bool showWaveTracks;
+ bool showGroupTracks;
+ bool showInputTracks;
+ bool showAuxTracks;
+ bool showSyntiTracks;
+
+ void write(Xml&, const char* name);
+ void read(QDomNode);
+ };
+
+//---------------------------------------------------------
+// GlobalConfigValues
+//---------------------------------------------------------
+
+struct GlobalConfigValues {
+ QString styleSheetFile;
+ QColor partColors[NUM_PARTCOLORS];
+ QColor selectPartBg;
+ QColor transportHandleColor;
+ QColor bigTimeForegroundColor;
+ QColor bigTimeBackgroundColor;
+ QColor waveEditBackgroundColor;
+
+ QColor trackBg[Track::TRACK_TYPES];
+
+ QColor mixerBg;
+
+ int division;
+ int rtcTicks;
+ double minMeter;
+ double maxMeter;
+ double minSlider;
+ double maxSlider;
+ int guiRefresh;
+ int peakHoldTime; // peak meter hold time (ms)
+ QString helpBrowser;
+
+ bool extendedMidi; // extended smf format
+ int midiDivision; // division for smf export
+ QString copyright; // copyright string for smf export
+ int smfFormat; // smf export file type
+
+ enum StartMode startMode;
+ QString startProject; // path for start project
+ int guiDivision; // division for tick display
+
+ QRect geometryTransport;
+ QRect geometryBigTime;
+ QRect geometryPianoroll;
+ QRect geometryDrumedit;
+ MixerConfig mixer1;
+ MixerConfig mixer2;
+ bool transportVisible;
+ bool bigTimeVisible;
+ bool mixer1Visible;
+ bool mixer2Visible;
+
+ bool showSplashScreen;
+
+ QColor canvasBgColor;
+ QString canvasBgPixmap;
+ bool canvasUseBgPixmap;
+
+ int canvasShowPartType; // 1 - names, 2 events
+ int canvasShowPartEvent; //
+ bool canvasShowGrid;
+
+ bool useJackFreewheelMode;
+ QString externalWavEditor;
+
+ QString defaultMidiInputDevice;
+ QString defaultMidiOutputDevice;
+ QString defaultMidiInstrument;
+ bool connectToAllMidiDevices;
+ bool connectToAllMidiTracks;
+ bool createDefaultMidiInput;
+ QString projectPath;
+ QString templatePath;
+ QString instrumentPath;
+ QString importMidiPath;
+ QString importWavePath;
+ };
+
+extern GlobalConfigValues config;
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/globaldefs.h b/muse_qt4_evolution/muse/globaldefs.h
new file mode 100644
index 00000000..4f72bcc3
--- /dev/null
+++ b/muse_qt4_evolution/muse/globaldefs.h
@@ -0,0 +1,37 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __GLOBALDEFS_H__
+#define __GLOBALDEFS_H__
+
+static const int MAX_CHANNELS = 2; // max audio channels
+// const int MIDI_PORTS = 16; // max Number of Midi Ports
+
+#ifndef MIDI_CHANNELS
+#define MIDI_CHANNELS 16 // Channels per Port
+
+enum MidiInstrumentType {
+ MT_GENERIC, MT_GM, MT_GS, MT_XG
+ };
+
+#endif
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/globals.cpp b/muse_qt4_evolution/muse/globals.cpp
new file mode 100644
index 00000000..86871a0c
--- /dev/null
+++ b/muse_qt4_evolution/muse/globals.cpp
@@ -0,0 +1,133 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "globals.h"
+enum AudioState audioState;
+
+unsigned segmentSize = 1024U; // segmentSize in frames (set by JACK)
+int segmentCount = 2;
+
+bool overrideAudioOutput = false;
+bool overrideAudioInput = false;
+
+QTimer* heartBeatTimer;
+
+const signed char sharpTab[14][7] = {
+ { 0, 3, -1, 2, 5, 1, 4 },
+ { 0, 3, -1, 2, 5, 1, 4 },
+ { 0, 3, -1, 2, 5, 1, 4 },
+ { 0, 3, -1, 2, 5, 1, 4 },
+ { 2, 5, 1, 4, 7, 3, 6 },
+ { 2, 5, 1, 4, 7, 3, 6 },
+ { 2, 5, 1, 4, 7, 3, 6 },
+ { 4, 0, 3, -1, 2, 5, 1 },
+ { 7, 3, 6, 2, 5, 1, 4 },
+ { 5, 8, 4, 7, 3, 6, 2 },
+ { 3, 6, 2, 5, 1, 4, 7 },
+ { 1, 4, 0, 3, 6, 2, 5 },
+ { 6, 2, 5, 1, 4, 0, 3 },
+ { 0, 3, -1, 2, 5, 1, 4 },
+ };
+const signed char flatTab[14][7] = {
+ { 4, 1, 5, 2, 6, 3, 7 },
+ { 4, 1, 5, 2, 6, 3, 7 },
+ { 4, 1, 5, 2, 6, 3, 7 },
+ { 4, 1, 5, 2, 6, 3, 7 },
+ { 6, 3, 7, 4, 8, 5, 9 },
+ { 6, 3, 7, 4, 8, 5, 9 },
+ { 6, 3, 7, 4, 8, 5, 9 },
+
+ { 1, 5, 2, 6, 3, 7, 4 },
+ { 4, 1, 5, 2, 6, 3, 7 },
+ { 2, 6, 3, 7, 4, 8, 5 },
+ { 7, 4, 1, 5, 2, 6, 3 },
+ { 5, 2, 6, 3, 7, 4, 8 },
+ { 3, 0, 4, 1, 5, 2, 6 },
+ { 4, 1, 5, 2, 6, 3, 7 },
+ };
+
+QString museGlobalLib;
+QString museGlobalShare;
+QString museUser;
+QString configName;
+
+QString lastWavePath(".");
+QString lastMidiPath(".");
+
+bool debugMode = false;
+bool debugMsg = false;
+bool midiInputTrace = false;
+bool midiOutputTrace = false;
+int realTimePriority = 50;
+bool loadPlugins = true;
+bool loadVST = true;
+bool loadDSSI = true;
+bool midiOnly = false;
+
+const char* midi_file_pattern[] = {
+ "Midi/Kar (*.mid *.MID *.kar *.KAR *.mid.gz *.mid.bz2)",
+ "Midi (*.mid *.MID *.mid.gz *.mid.bz2)",
+ "Karaoke (*.kar *.KAR *.kar.gz *.kar.bz2)",
+ "All Files (*)",
+ 0
+ };
+QString medFilePattern =
+ "med Files (*.med *.med.gz *.med.bz2);;"
+ "All Files (*)";
+
+const char* med_midi_file_pattern[] = {
+ "med Files (*.med *.med.gz *.med.bz2)",
+ "Midi/Kar (*.mid *.kar *.mid.gz *.mid.bz2)",
+ "Midi (*.mid *.mid.gz *.mid.bz2)",
+ "Karaoke (*.kar *.kar.gz *.kar.bz2)",
+ "All Files (*)",
+ 0
+ };
+const char* med_file_pattern[] = {
+ "med Files (*.med *.med.gz *.med.bz2)",
+ "All Files (*)",
+ 0
+ };
+const char* image_file_pattern[] = {
+ "(*.jpg *.gif *.png)",
+ "(*.jpg)",
+ "(*.gif)",
+ "(*.png)",
+ "All Files (*)",
+ 0
+ };
+
+const char* ctrl_file_pattern[] = {
+ "ctrl Files (*.ctrl *.ctrl.gz *.ctrl.bz2)",
+ "All Files (*)",
+ 0
+ };
+
+QAction* undoAction;
+QAction* redoAction;
+
+QAction* loopAction;
+QAction* punchinAction;
+QAction* punchoutAction;
+QAction* recordAction;
+QAction* panicAction;
+
+bool rcEnable = false;
+
diff --git a/muse_qt4_evolution/muse/globals.h b/muse_qt4_evolution/muse/globals.h
new file mode 100644
index 00000000..eaf121d8
--- /dev/null
+++ b/muse_qt4_evolution/muse/globals.h
@@ -0,0 +1,86 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef GLOBALS_H
+#define GLOBALS_H
+
+#include <sys/types.h>
+#include "mtc.h"
+
+enum AudioState {
+ AUDIO_STOP,
+ AUDIO_START1,
+ AUDIO_START2,
+ AUDIO_RUNNING
+ };
+extern enum AudioState audioState;
+
+extern unsigned segmentSize;
+extern int segmentCount;
+
+extern bool overrideAudioOutput;
+extern bool overrideAudioInput;
+
+class QTimer;
+extern QTimer* heartBeatTimer;
+
+extern const signed char sharpTab[14][7];
+extern const signed char flatTab[14][7];
+
+extern QString museGlobalLib;
+extern QString museGlobalShare;
+extern QString museUser;
+extern QString configName;
+
+extern QString lastWavePath;
+extern QString lastMidiPath;
+
+extern bool debugMode;
+extern bool midiInputTrace;
+extern bool midiOutputTrace;
+extern bool debugMsg;
+extern bool debugSync;
+extern bool loadPlugins;
+extern bool loadVST;
+extern bool loadDSSI;
+extern bool midiOnly;
+
+extern int realTimePriority;
+extern const char* midi_file_pattern[];
+extern QString medFilePattern;
+extern const char* med_file_pattern[];
+extern const char* med_midi_file_pattern[];
+extern const char* image_file_pattern[];
+extern const char* ctrl_file_pattern[];
+
+enum { CMD_RANGE_ALL, CMD_RANGE_SELECTED, CMD_RANGE_LOOP };
+
+extern QAction* undoAction;
+extern QAction* redoAction;
+
+extern QAction* loopAction;
+extern QAction* punchinAction;
+extern QAction* punchoutAction;
+extern QAction* recordAction;
+extern QAction* panicAction;
+
+extern bool rcEnable;
+#endif
+
diff --git a/muse_qt4_evolution/muse/gui.h b/muse_qt4_evolution/muse/gui.h
new file mode 100644
index 00000000..784e58e2
--- /dev/null
+++ b/muse_qt4_evolution/muse/gui.h
@@ -0,0 +1,54 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __GUI_H__
+#define __GUI_H__
+
+//
+// GUI constants
+// central point of tweaking the gui
+//
+
+// size of horizontal and vertical splitter
+//
+static const int splitWidth = 6;
+
+// arranger:
+static const int trackRowHeight = 24;
+static const int minTrackHeight = trackRowHeight + splitWidth + 1;
+static const int defaultTrackHeight = minTrackHeight;
+static const int infoHeight = 20;
+static const int infoWidth = 140;
+static const int trackSeparator = 1;
+static const int yTrackOffset = -2; // -4;
+
+// mixer:
+static const int STRIP_WIDTH = 60;
+static const int LABEL_HEIGHT = 20;
+static const int BUTTON_HEIGHT = STRIP_WIDTH / 3;
+static const int ENTRY_HEIGHT = 17;
+
+static const int ICON_WIDTH = 18;
+static const QSize ICON_SIZE(ICON_WIDTH, ICON_WIDTH);
+
+#endif
+
+
+
diff --git a/muse_qt4_evolution/muse/help.cpp b/muse_qt4_evolution/muse/help.cpp
new file mode 100644
index 00000000..c17581ae
--- /dev/null
+++ b/muse_qt4_evolution/muse/help.cpp
@@ -0,0 +1,101 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "config.h"
+#include "muse.h"
+#include "globals.h"
+#include "gconfig.h"
+#include "icons.h"
+#include "help.h"
+
+//---------------------------------------------------------
+// AboutBoxDialog
+//---------------------------------------------------------
+
+AboutBoxDialog::AboutBoxDialog()
+ {
+ extern int revision;
+ setupUi(this);
+ versionLabel->setText("Version: " VERSION);
+ revisionLabel->setText(QString("Revision: %1").arg(revision));
+ }
+
+//---------------------------------------------------------
+// startHelpBrowser
+//---------------------------------------------------------
+
+void MusE::startHelpBrowser()
+ {
+ QString lang(getenv("LANG"));
+ QFileInfo museHelp(museGlobalShare + QString("/doc/man-") + lang + QString(".pdf"));
+ if (!museHelp.isReadable()) {
+ museHelp.setFile(museGlobalShare + QString("/doc/man-en.pdf"));
+ if (!museHelp.isReadable()) {
+ QString info(tr("MusE manual not found at: "));
+ info += museHelp.filePath();
+ QMessageBox::critical(this, tr("MusE: Open Help"), info);
+ return;
+ }
+ }
+ QString url("file://" + museHelp.filePath());
+ QDesktopServices::openUrl(url);
+ }
+
+//---------------------------------------------------------
+// startHelpBrowser
+//---------------------------------------------------------
+
+void MusE::startHomepageBrowser()
+ {
+ QString museHome = QString("http://lmuse.sourceforge.net");
+
+ QDesktopServices::openUrl(museHome);
+ }
+
+//---------------------------------------------------------
+// startBugBrowser
+//---------------------------------------------------------
+
+void MusE::startBugBrowser()
+ {
+ QString museBugPage("http://lmuse.sourceforge.net/bugs.html");
+ QDesktopServices::openUrl(museBugPage);
+ }
+
+//---------------------------------------------------------
+// about
+//---------------------------------------------------------
+
+void MusE::about()
+ {
+ AboutBoxDialog ab;
+ ab.show();
+ ab.exec();
+ }
+
+//---------------------------------------------------------
+// aboutQt
+//---------------------------------------------------------
+
+void MusE::aboutQt()
+ {
+ QMessageBox::aboutQt(this, QString("MusE"));
+ }
+
diff --git a/muse_qt4_evolution/muse/help.h b/muse_qt4_evolution/muse/help.h
new file mode 100644
index 00000000..c2a54d90
--- /dev/null
+++ b/muse_qt4_evolution/muse/help.h
@@ -0,0 +1,36 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __HELP_H__
+#define __HELP_H__
+
+#include "ui_aboutbox.h"
+
+//---------------------------------------------------------
+// AboutBoxDialog
+//---------------------------------------------------------
+
+class AboutBoxDialog : public QDialog, Ui::AboutBox {
+ public:
+ AboutBoxDialog();
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/helper.cpp b/muse_qt4_evolution/muse/helper.cpp
new file mode 100644
index 00000000..6b534a6d
--- /dev/null
+++ b/muse_qt4_evolution/muse/helper.cpp
@@ -0,0 +1,47 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "helper.h"
+
+extern bool hIsB;
+static const char* vall[] = {
+ "c","c#","d","d#","e","f","f#","g","g#","a","a#","h"
+ };
+static const char* valu[] = {
+ "C","C#","D","D#","E","F","F#","G","G#","A","A#","H"
+ };
+
+//---------------------------------------------------------
+// pitch2string
+//---------------------------------------------------------
+
+QString pitch2string(int v)
+ {
+ if (v < 0 || v > 127)
+ return QString("----");
+ int octave = (v / 12) - 2;
+ QString o;
+ o.sprintf("%d", octave);
+ int i = v % 12;
+ QString s(octave < 0 ? valu[i] : vall[i]);
+ return s + o;
+ }
+
+
diff --git a/muse_qt4_evolution/muse/helper.h b/muse_qt4_evolution/muse/helper.h
new file mode 100644
index 00000000..3f255393
--- /dev/null
+++ b/muse_qt4_evolution/muse/helper.h
@@ -0,0 +1,27 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __HELPER_H__
+#define __HELPER_H__
+
+extern QString pitch2string(int v);
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/icons.cpp b/muse_qt4_evolution/muse/icons.cpp
new file mode 100644
index 00000000..2fa62f9a
--- /dev/null
+++ b/muse_qt4_evolution/muse/icons.cpp
@@ -0,0 +1,341 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "globals.h"
+#include "gui.h"
+
+#include "xpm/audio_bounce_to_file.xpm"
+#include "xpm/audio_bounce_to_track.xpm"
+#include "xpm/audio_restartaudio.xpm"
+#include "xpm/edit_midi.xpm"
+#include "xpm/midi_edit_instrument.xpm"
+#include "xpm/midi_init_instr.xpm"
+#include "xpm/midi_local_off.xpm"
+#include "xpm/midi_reset_instr.xpm"
+#include "xpm/settings_appearance_settings.xpm"
+#include "xpm/settings_configureshortcuts.xpm"
+#include "xpm/settings_follow_song.xpm"
+#include "xpm/settings_globalsettings.xpm"
+#include "xpm/settings_metronome.xpm"
+#include "xpm/settings_midifileexport.xpm"
+#include "xpm/settings_midisync.xpm"
+
+#include "xpm/play.xpm"
+
+#include "xpm/stick.xpm"
+#include "xpm/wave.xpm"
+#include "xpm/cmark.xpm"
+#include "xpm/lmark.xpm"
+#include "xpm/rmark.xpm"
+#include "xpm/steprec.xpm"
+#include "xpm/master.xpm"
+#include "xpm/filenewS.xpm"
+#include "xpm/home.xpm"
+#include "xpm/back.xpm"
+#include "xpm/forward.xpm"
+
+#include "xpm/up.xpm"
+#include "xpm/down.xpm"
+#include "xpm/bold.xpm"
+#include "xpm/italic.xpm"
+#include "xpm/underlined.xpm"
+#include "xpm/midiin.xpm"
+#include "xpm/sysex.xpm"
+#include "xpm/ctrl.xpm"
+#include "xpm/meta.xpm"
+#include "xpm/pitch.xpm"
+#include "xpm/cafter.xpm"
+#include "xpm/pafter.xpm"
+#include "xpm/flag.xpm"
+#include "xpm/flagS.xpm"
+#include "xpm/lock.xpm"
+#include "xpm/toc.xpm"
+#include "xpm/editcut.xpm"
+#include "xpm/editcopy.xpm"
+#include "xpm/editpaste.xpm"
+
+#include "xpm/speaker.xpm"
+#include "xpm/buttondown.xpm"
+#include "xpm/configure.xpm"
+
+#include "xpm/mastertrackS.xpm"
+#include "xpm/localoffS.xpm"
+#include "xpm/miditransformS.xpm"
+#include "xpm/midi_plugS.xpm"
+#include "xpm/miditransposeS.xpm"
+#include "xpm/mixerS.xpm"
+#include "xpm/resetS.xpm"
+#include "xpm/track_add.xpm"
+#include "xpm/track_delete.xpm"
+#include "xpm/listS.xpm"
+#include "xpm/inputpluginS.xpm"
+#include "xpm/cliplistS.xpm"
+#include "xpm/mixeraudioS.xpm"
+#include "xpm/initS.xpm"
+
+#include "xpm/addtrack_addmiditrack.xpm"
+#include "xpm/addtrack_audiogroup.xpm"
+#include "xpm/addtrack_audioinput.xpm"
+#include "xpm/addtrack_audiooutput.xpm"
+#include "xpm/addtrack_drumtrack.xpm"
+#include "xpm/addtrack_wavetrack.xpm"
+#include "xpm/edit_drumms.xpm"
+#include "xpm/edit_list.xpm"
+#include "xpm/edit_mastertrack.xpm"
+#include "xpm/edit_track_add.xpm"
+#include "xpm/edit_track_del.xpm"
+#include "xpm/mastertrack_graphic.xpm"
+#include "xpm/mastertrack_list.xpm"
+#include "xpm/midi_transform.xpm"
+#include "xpm/midi_transpose.xpm"
+#include "xpm/select.xpm"
+// #include "xpm/select_all.xpm"
+#include "xpm/select_all_parts_on_track.xpm"
+// #include "xpm/select_deselect_all.xpm"
+// #include "xpm/select_inside_loop.xpm"
+// #include "xpm/select_invert_selection.xpm"
+// #include "xpm/select_outside_loop.xpm"
+
+#include "xpm/muse_icon.xpm"
+#include "xpm/config.xpm"
+#include "xpm/minus.xpm"
+#include "xpm/plus.xpm"
+
+QPixmap* mastertrackSIcon;
+QPixmap* localoffSIcon;
+QPixmap* miditransformSIcon;
+QPixmap* midi_plugSIcon;
+QPixmap* miditransposeSIcon;
+QPixmap* mixerSIcon;
+QPixmap* resetSIcon;
+QPixmap* track_addIcon;
+QPixmap* track_deleteIcon;
+QPixmap* listSIcon;
+QPixmap* inputpluginSIcon;
+QPixmap* cliplistSIcon;
+QPixmap* mixerAudioSIcon;
+QPixmap* initSIcon;
+
+QPixmap* playIcon;
+
+QPixmap* stopIcon;
+QPixmap* fforwardIcon;
+QPixmap* frewindIcon;
+QPixmap* stickIcon;
+QPixmap* waveIcon;
+QPixmap* markIcon[3];
+QPixmap* steprecIcon;
+QPixmap* openIcon;
+QPixmap* saveIcon;
+QPixmap* masterIcon;
+QPixmap* filenewIcon;
+QPixmap* filenewIconS;
+QPixmap* homeIcon;
+QPixmap* backIcon;
+QPixmap* forwardIcon;
+QPixmap* muteIcon;
+QPixmap* upIcon;
+QPixmap* downIcon;
+QPixmap* boldIcon;
+QPixmap* italicIcon;
+QPixmap* underlinedIcon;
+QPixmap* midiinIcon;
+QPixmap* sysexIcon;
+QPixmap* ctrlIcon;
+QPixmap* metaIcon;
+QPixmap* pitchIcon;
+QPixmap* cafterIcon;
+QPixmap* pafterIcon;
+QPixmap* flagIcon;
+QPixmap* flagIconS;
+QPixmap* lockIcon;
+QPixmap* tocIcon;
+
+QPixmap* speakerIcon;
+QPixmap* buttondownIcon;
+QPixmap* configureIcon;
+
+QIcon* editcutIconSet;
+QIcon* editcopyIconSet;
+QIcon* editpasteIconSet;
+QIcon* recordIcon;
+QIcon* onOffIcon;
+QPixmap* offIcon;
+
+QPixmap* addtrack_addmiditrackIcon;
+QPixmap* addtrack_audiogroupIcon;
+QPixmap* addtrack_audioinputIcon;
+QPixmap* addtrack_audiooutputIcon;
+QPixmap* addtrack_drumtrackIcon;
+QPixmap* addtrack_wavetrackIcon;
+QPixmap* edit_drummsIcon;
+QPixmap* edit_listIcon;
+QPixmap* edit_mastertrackIcon;
+QPixmap* edit_track_addIcon;
+QPixmap* edit_track_delIcon;
+QPixmap* mastertrack_graphicIcon;
+QPixmap* mastertrack_listIcon;
+QPixmap* midi_transformIcon;
+QPixmap* midi_transposeIcon;
+QPixmap* selectIcon;
+// QPixmap* select_allIcon;
+QPixmap* select_all_parts_on_trackIcon;
+// QPixmap* select_deselect_allIcon;
+// QPixmap* select_inside_loopIcon;
+// QPixmap* select_invert_selectionIcon;
+// QPixmap* select_outside_loopIcon;
+
+QPixmap* audio_bounce_to_fileIcon;
+QPixmap* audio_bounce_to_trackIcon;
+QPixmap* audio_restartaudioIcon;
+QPixmap* edit_midiIcon;
+QPixmap* midi_edit_instrumentIcon;
+QPixmap* midi_init_instrIcon;
+QPixmap* midi_local_offIcon;
+QPixmap* midi_reset_instrIcon;
+QPixmap* settings_appearance_settingsIcon;
+QPixmap* settings_configureshortcutsIcon;
+QPixmap* settings_follow_songIcon;
+QPixmap* settings_globalsettingsIcon;
+QPixmap* settings_metronomeIcon;
+QPixmap* settings_midifileexportIcon;
+QPixmap* settings_midisyncIcon;
+
+QPixmap* museIcon;
+QPixmap* museIcon64;
+QPixmap* configIcon;
+QPixmap* minusIcon;
+QPixmap* plusIcon;
+
+//---------------------------------------------------------
+// initIcons
+//---------------------------------------------------------
+
+void initIcons()
+ {
+ playIcon = new QPixmap(play_xpm);
+
+ stickIcon = new QPixmap(stick_xpm);
+ waveIcon = new QPixmap(wave_xpm);
+ markIcon[0] = new QPixmap(cmark_xpm);
+ markIcon[1] = new QPixmap(lmark_xpm);
+ markIcon[2] = new QPixmap(rmark_xpm);
+ steprecIcon = new QPixmap(steprec_xpm);
+ saveIcon = new QPixmap(":/xpm/filesave.png");
+ openIcon = new QPixmap(":/xpm/fileopen.png");
+ masterIcon = new QPixmap(master_xpm);
+ filenewIcon = new QPixmap(":/xpm/filenew.png");
+ filenewIconS = new QPixmap(filenewS_xpm);
+ homeIcon = new QPixmap(home_xpm);
+ backIcon = new QPixmap(back_xpm);
+ forwardIcon = new QPixmap(forward_xpm);
+ upIcon = new QPixmap(up_xpm);
+ downIcon = new QPixmap(down_xpm);
+ boldIcon = new QPixmap(bold_xpm);
+ italicIcon = new QPixmap(italic_xpm);
+ underlinedIcon = new QPixmap(underlined_xpm);
+ midiinIcon = new QPixmap(midiin_xpm);
+ sysexIcon = new QPixmap(sysex_xpm);
+ ctrlIcon = new QPixmap(ctrl_xpm);
+ metaIcon = new QPixmap(meta_xpm);
+ pitchIcon = new QPixmap(pitch_xpm);
+ cafterIcon = new QPixmap(cafter_xpm);
+ pafterIcon = new QPixmap(pafter_xpm);
+ flagIcon = new QPixmap(flag_xpm);
+ flagIconS = new QPixmap(flagS_xpm);
+ lockIcon = new QPixmap(lock_xpm);
+ tocIcon = new QPixmap(toc_xpm);
+
+ speakerIcon = new QPixmap(speaker_xpm);
+ buttondownIcon = new QPixmap(buttondown_xpm);
+ configureIcon = new QPixmap(configure_xpm);
+
+ editcutIconSet = new QIcon(QPixmap(editcut_xpm));
+ editcopyIconSet = new QIcon(QPixmap(editcopy_xpm));
+ editpasteIconSet = new QIcon(QPixmap(editpaste_xpm));
+
+ mastertrackSIcon = new QPixmap(mastertrackS_xpm);
+ localoffSIcon = new QPixmap(localoffS_xpm);
+ miditransformSIcon = new QPixmap(miditransformS_xpm);
+ midi_plugSIcon = new QPixmap(midi_plugS_xpm);
+ miditransposeSIcon = new QPixmap(miditransposeS_xpm);
+ mixerSIcon = new QPixmap(mixerS_xpm);
+ resetSIcon = new QPixmap(resetS_xpm);
+ track_addIcon = new QPixmap(track_add_xpm);
+ track_deleteIcon = new QPixmap(track_delete_xpm);
+ listSIcon = new QPixmap(listS_xpm);
+ inputpluginSIcon = new QPixmap(inputpluginS_xpm);
+ cliplistSIcon = new QPixmap(cliplistS_xpm);
+ mixerAudioSIcon = new QPixmap(mixerAudioS_xpm);
+ initSIcon = new QPixmap(initS_xpm);
+
+ addtrack_addmiditrackIcon = new QPixmap(addtrack_addmiditrack_xpm);
+ addtrack_audiogroupIcon = new QPixmap(addtrack_audiogroup_xpm);
+ addtrack_audioinputIcon = new QPixmap(addtrack_audioinput_xpm);
+ addtrack_audiooutputIcon = new QPixmap(addtrack_audiooutput_xpm);
+ addtrack_drumtrackIcon = new QPixmap(addtrack_drumtrack_xpm);
+ addtrack_wavetrackIcon = new QPixmap(addtrack_wavetrack_xpm);
+ edit_drummsIcon = new QPixmap(edit_drumms_xpm);
+ edit_listIcon = new QPixmap(edit_list_xpm);
+ edit_mastertrackIcon = new QPixmap(edit_mastertrack_xpm);
+ edit_track_addIcon = new QPixmap(edit_track_add_xpm);
+ edit_track_delIcon = new QPixmap(edit_track_del_xpm);
+ mastertrack_graphicIcon = new QPixmap(mastertrack_graphic_xpm);
+ mastertrack_listIcon = new QPixmap(mastertrack_list_xpm);
+ midi_transformIcon = new QPixmap(midi_transform_xpm);
+ midi_transposeIcon = new QPixmap(midi_transpose_xpm);
+ selectIcon = new QPixmap(select_xpm);
+// select_allIcon = new QPixmap(select_all_xpm);
+ select_all_parts_on_trackIcon = new QPixmap(select_all_parts_on_track_xpm);
+// select_deselect_allIcon = new QPixmap(select_deselect_all);
+// select_inside_loopIcon = new QPixmap(select_inside_loop_xpm);
+// select_invert_selectionIcon = new QPixmap(select_invert_selection);
+// select_outside_loopIcon = new QPixmap(select_outside_loop_xpm);
+
+ audio_bounce_to_fileIcon = new QPixmap(audio_bounce_to_file_xpm);
+ audio_bounce_to_trackIcon = new QPixmap(audio_bounce_to_track_xpm);
+ audio_restartaudioIcon = new QPixmap(audio_restartaudio_xpm);
+ edit_midiIcon = new QPixmap(edit_midi_xpm);
+ midi_edit_instrumentIcon = new QPixmap(midi_edit_instrument_xpm);
+ midi_init_instrIcon = new QPixmap(midi_init_instr_xpm);
+ midi_local_offIcon = new QPixmap(midi_local_off_xpm);
+ midi_reset_instrIcon = new QPixmap(midi_reset_instr_xpm);
+ settings_appearance_settingsIcon = new QPixmap(settings_appearance_settings_xpm);
+ settings_configureshortcutsIcon = new QPixmap(settings_configureshortcuts_xpm);
+ settings_follow_songIcon = new QPixmap(settings_follow_song_xpm);
+ settings_globalsettingsIcon = new QPixmap(settings_globalsettings_xpm);
+ settings_metronomeIcon = new QPixmap(settings_metronome_xpm);
+ settings_midifileexportIcon = new QPixmap(settings_midifileexport_xpm);
+ settings_midisyncIcon = new QPixmap(settings_midisync_xpm);
+
+ museIcon = new QPixmap(muse_icon_xpm);
+ configIcon = new QPixmap(config_xpm);
+ minusIcon = new QPixmap(minus_xpm);
+ plusIcon = new QPixmap(plus_xpm);
+
+ recordIcon = new QIcon;
+ recordIcon->addFile(":/xpm/recordOn.svg", ICON_SIZE, QIcon::Normal, QIcon::On);
+ recordIcon->addFile(":/xpm/recordOff.svg", ICON_SIZE, QIcon::Normal, QIcon::Off);
+
+ onOffIcon = new QIcon;
+ onOffIcon->addFile(":/xpm/on.svg", ICON_SIZE, QIcon::Normal, QIcon::On);
+ onOffIcon->addFile(":/xpm/off.svg", ICON_SIZE, QIcon::Normal, QIcon::Off);
+ }
+
diff --git a/muse_qt4_evolution/muse/icons.h b/muse_qt4_evolution/muse/icons.h
new file mode 100644
index 00000000..788f0ad0
--- /dev/null
+++ b/muse_qt4_evolution/muse/icons.h
@@ -0,0 +1,134 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef ICONS_H
+#define ICONS_H
+
+extern QPixmap* playIcon;
+extern QPixmap* stickIcon;
+extern QPixmap* waveIcon;
+extern QPixmap* markIcon[3];
+
+extern QPixmap* cutIcon;
+extern QPixmap* steprecIcon;
+extern QPixmap* glueIcon;
+extern QPixmap* drawIcon;
+
+extern QPixmap* quantIcon;
+extern QPixmap* openIcon;
+extern QPixmap* saveIcon;
+extern QPixmap* archiveIcon;
+extern QPixmap* findIcon;
+extern QPixmap* masterIcon;
+extern QPixmap* filenewIcon;
+extern QPixmap* filenewIconS;
+extern QPixmap* homeIcon;
+extern QPixmap* backIcon;
+extern QPixmap* forwardIcon;
+extern QPixmap* upIcon;
+extern QPixmap* downIcon;
+extern QPixmap* boldIcon;
+extern QPixmap* italicIcon;
+extern QPixmap* underlinedIcon;
+extern QPixmap* midiinIcon;
+extern QPixmap* sysexIcon;
+extern QPixmap* ctrlIcon;
+extern QPixmap* metaIcon;
+extern QPixmap* pitchIcon;
+extern QPixmap* cafterIcon;
+extern QPixmap* pafterIcon;
+extern QPixmap* flagIcon;
+extern QPixmap* flagIconS;
+extern QPixmap* lockIcon;
+extern QPixmap* tocIcon;
+
+extern QPixmap* speakerIcon;
+extern QPixmap* buttondownIcon;
+extern QPixmap* configureIcon;
+
+extern QIcon* editcutIconSet;
+extern QIcon* editcopyIconSet;
+extern QIcon* editpasteIconSet;
+
+extern QPixmap* offIcon;
+
+extern QPixmap* mastertrackSIcon;
+extern QPixmap* localoffSIcon;
+extern QPixmap* miditransformSIcon;
+extern QPixmap* midi_plugSIcon;
+extern QPixmap* miditransposeSIcon;
+extern QPixmap* mixerSIcon;
+extern QPixmap* resetSIcon;
+extern QPixmap* track_addIcon;
+extern QPixmap* track_deleteIcon;
+extern QPixmap* listSIcon;
+extern QPixmap* inputpluginSIcon;
+extern QPixmap* cliplistSIcon;
+extern QPixmap* mixerAudioSIcon;
+extern QPixmap* initSIcon;
+
+extern QPixmap* addtrack_addmiditrackIcon;
+extern QPixmap* addtrack_audiogroupIcon;
+extern QPixmap* addtrack_audioinputIcon;
+extern QPixmap* addtrack_audiooutputIcon;
+extern QPixmap* addtrack_drumtrackIcon;
+extern QPixmap* addtrack_wavetrackIcon;
+extern QPixmap* edit_drummsIcon;
+extern QPixmap* edit_listIcon;
+extern QPixmap* edit_mastertrackIcon;
+extern QPixmap* edit_track_addIcon;
+extern QPixmap* edit_track_delIcon;
+extern QPixmap* mastertrack_graphicIcon;
+extern QPixmap* mastertrack_listIcon;
+extern QPixmap* midi_transformIcon;
+extern QPixmap* midi_transposeIcon;
+extern QPixmap* selectIcon;
+// extern QPixmap* select_allIcon;
+extern QPixmap* select_all_parts_on_trackIcon;
+// extern QPixmap* select_deselect_allIcon;
+// extern QPixmap* select_inside_loopIcon;
+// extern QPixmap* select_invert_selectionIcon;
+// extern QPixmap* select_outside_loopIcon;
+
+extern QPixmap* audio_bounce_to_fileIcon;
+extern QPixmap* audio_bounce_to_trackIcon;
+extern QPixmap* audio_restartaudioIcon;
+extern QPixmap* edit_midiIcon;
+extern QPixmap* midi_edit_instrumentIcon;
+extern QPixmap* midi_init_instrIcon;
+extern QPixmap* midi_local_offIcon;
+extern QPixmap* midi_reset_instrIcon;
+extern QPixmap* settings_appearance_settingsIcon;
+extern QPixmap* settings_configureshortcutsIcon;
+extern QPixmap* settings_follow_songIcon;
+extern QPixmap* settings_globalsettingsIcon;
+extern QPixmap* settings_metronomeIcon;
+extern QPixmap* settings_midifileexportIcon;
+extern QPixmap* settings_midisyncIcon;
+
+extern QPixmap* museIcon;
+extern QPixmap* configIcon;
+extern QPixmap* minusIcon;
+extern QPixmap* plusIcon;
+
+extern QIcon* recordIcon;
+extern QIcon* onOffIcon;
+#endif
+
diff --git a/muse_qt4_evolution/muse/importmidi.cpp b/muse_qt4_evolution/muse/importmidi.cpp
new file mode 100644
index 00000000..0bd33df8
--- /dev/null
+++ b/muse_qt4_evolution/muse/importmidi.cpp
@@ -0,0 +1,589 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "globals.h"
+#include "muse.h"
+#include "song.h"
+#include "widgets/filedialog.h"
+#include "midi.h"
+#include "midifile.h"
+#include "transport.h"
+#include "midiedit/drummap.h"
+#include "al/sig.h"
+#include "al/tempo.h"
+#include "instruments/minstrument.h"
+#include "gconfig.h"
+#include "part.h"
+#include "importmidi.h"
+#include "projectdialog.h"
+#include "templatedialog.h"
+#include "audio.h"
+#include "mixer.h"
+#include "arranger.h"
+#include "midictrl.h"
+#include "midiinport.h"
+#include "midioutport.h"
+
+//---------------------------------------------------------
+// ImportMidiDialog
+//---------------------------------------------------------
+
+ImportMidiDialog::ImportMidiDialog(QWidget* parent)
+ : QDialog(parent)
+ {
+ setupUi(this);
+ bg = new QButtonGroup(this);
+ bg->setExclusive(true);
+ bg->addButton(addToProject, 0);
+ bg->addButton(createNewProject, 1);
+ createNewProject->setChecked(true);
+ connect(selectTemplate,SIGNAL(clicked()), SLOT(selectTemplateClicked()));
+ connect(selectProject, SIGNAL(clicked()), SLOT(selectProjectClicked()));
+ }
+
+//---------------------------------------------------------
+// selectTemplateClicked
+//---------------------------------------------------------
+
+void ImportMidiDialog::selectTemplateClicked()
+ {
+ TemplateDialog templateDialog;
+ templateDialog.setTemplatePath(templateName->text());
+ int rv = templateDialog.exec();
+ if (rv == 0)
+ return;
+ templateName->setText(templateDialog.templatePath());
+ }
+
+//---------------------------------------------------------
+// selectProjectClicked
+//---------------------------------------------------------
+
+void ImportMidiDialog::selectProjectClicked()
+ {
+ ProjectDialog projectDialog;
+ projectDialog.setProjectName(projectName->text());
+ int rv = projectDialog.exec();
+ if (rv == 0)
+ return;
+ projectName->setText(projectDialog.projectName());
+ }
+
+//---------------------------------------------------------
+// setProjectName
+//---------------------------------------------------------
+
+void ImportMidiDialog::setProjectName(const QString& name)
+ {
+ projectName->setText(name);
+ }
+
+//---------------------------------------------------------
+// setTemplateName
+//---------------------------------------------------------
+
+void ImportMidiDialog::setTemplateName(const QString& name)
+ {
+ templateName->setText(name);
+ }
+
+//---------------------------------------------------------
+// importMidi
+//---------------------------------------------------------
+
+void MusE::importMidi()
+ {
+ importMidi(QString());
+ }
+
+void MusE::importMidi(const QString &file)
+ {
+ QString fn;
+ QStringList pattern;
+
+ const char** s = midi_file_pattern;
+ while (*s)
+ pattern << *s++;
+
+ if (file.isEmpty()) {
+ fn = getOpenFileName(lastMidiPath, pattern, this,
+ tr("MusE: Import Midi"));
+ lastMidiPath = fn;
+ if (fn.isEmpty())
+ return;
+ }
+ else
+ fn = file;
+
+ QFileInfo fi(fn);
+
+ ImportMidiDialog mid(this);
+ mid.setProjectName(fi.baseName());
+ mid.setTemplateName("");
+
+ if (mid.exec() == 0)
+ return;
+
+ if (mid.doCreateNewProject()) {
+ QString header = tr("MusE: import midi file");
+ QString path(mid.projectName->text());
+ QDir pd(QDir::homePath() + "/" + config.projectPath + "/" + path);
+
+ if (leaveProject())
+ return;
+ if (!pd.mkdir(pd.path())) {
+ QString s(tr("Cannot create project folder <%1>"));
+ QMessageBox::critical(this, header, s.arg(pd.path()));
+ return;
+ }
+ if (audio->isPlaying()) {
+ audio->msgPlay(false);
+ while (audio->isPlaying())
+ qApp->processEvents();
+ }
+ addProject(path); // add to history
+ seqStop();
+ if (mixer1)
+ mixer1->clear();
+ if (mixer2)
+ mixer2->clear();
+ //===========================================================
+ //
+ // close all toplevel windows
+ //
+ foreach(QWidget* w, QApplication::topLevelWidgets()) {
+ if (!w->isVisible())
+ continue;
+ if (strcmp("DrumEdit", w->metaObject()->className()) == 0)
+ w->close();
+ else if (strcmp("PianoRoll", w->metaObject()->className()) == 0)
+ w->close();
+ else if (strcmp("MasterEdit", w->metaObject()->className()) == 0)
+ w->close();
+ else if (strcmp("WaveEdit", w->metaObject()->className()) == 0)
+ w->close();
+ else if (strcmp("ListEdit", w->metaObject()->className()) == 0)
+ w->close();
+ }
+ emit startLoadSong();
+ song->setProjectPath(path);
+ song->clear(false);
+ song->setCreated(true);
+
+ QString s = mid.templateName->text();
+ bool rv = true;
+ if (!s.isEmpty()) {
+ QFile f(s);
+ if (f.open(QIODevice::ReadOnly)) {
+ rv = song->read(&f);
+ f.close();
+ }
+ else {
+ QString msg(tr("Cannot open template file\n%1"));
+ QMessageBox::critical(this, header, msg.arg(s));
+ }
+ }
+ if (!rv) {
+ QString msg(tr("File <%1> read error"));
+ QMessageBox::critical(this, header, msg.arg(s));
+ }
+ addMidiFile(fn);
+
+ tr_id->setChecked(config.transportVisible);
+ bt_id->setChecked(config.bigTimeVisible);
+
+ //
+ // dont emit song->update():
+ song->blockSignals(true);
+
+ showBigtime(config.bigTimeVisible);
+ showMixer1(config.mixer1Visible);
+ showMixer2(config.mixer2Visible);
+ if (mixer1 && config.mixer1Visible)
+ mixer1->setUpdateMixer();
+ if (mixer2 && config.mixer2Visible)
+ mixer2->setUpdateMixer();
+
+ if (config.transportVisible)
+ transport->show();
+ transport->move(config.geometryTransport.topLeft());
+ showTransport(config.transportVisible);
+
+ song->blockSignals(false);
+
+ transport->setMasterFlag(song->masterFlag());
+ punchinAction->setChecked(song->punchin());
+ punchoutAction->setChecked(song->punchout());
+ loopAction->setChecked(song->loop());
+ clipboardChanged(); // enable/disable "Paste"
+ song->setLen(song->len()); // emit song->lenChanged() signal
+
+ //
+ // add connected channels
+ //
+ TrackList* tl = song->tracks();
+#if 0
+ MidiChannelList* mcl = song->midiChannel();
+ for (iMidiChannel i = mcl->begin(); i != mcl->end(); ++i) {
+ MidiChannel* mc = (MidiChannel*)*i;
+ if (mc->noInRoute() || song->trackExists(mc))
+ continue;
+ tl->push_back(mc);
+ }
+#endif
+
+ selectionChanged(); // enable/disable "Copy" & "Paste"
+ arranger->endLoadSong();
+ song->updatePos();
+ //
+ // send "cur" controller values to devices
+ //
+
+ for (iTrack i = tl->begin(); i != tl->end(); ++i) {
+ Track* track = *i;
+ track->blockSignals(true);
+ CtrlList* cl = track->controller();
+ for (iCtrl ic = cl->begin(); ic != cl->end(); ++ic) {
+ Ctrl* ctrl = ic->second;
+ if (ctrl->type() & Ctrl::INT) {
+ CVal val;
+ val = ctrl->curVal();
+ ctrl->setCurVal(CTRL_VAL_UNKNOWN);
+ song->setControllerVal(track, ctrl, val);
+ }
+ }
+ track->blockSignals(false);
+ }
+ setWindowTitle(QString("MusE: Song: ") + path);
+ seqStart();
+ audio->msgSeek(song->cPos());
+ }
+ else {
+ // add to project
+ addMidiFile(fn);
+ song->update(-1);
+ }
+ }
+
+//---------------------------------------------------------
+// addMidiFile
+//---------------------------------------------------------
+
+void MusE::addMidiFile(const QString name)
+ {
+ QFile* fp = fileOpen(this, name, QString(".mid"), QIODevice::ReadOnly);
+ if (fp == 0)
+ return;
+ MidiFile mf;
+ bool rv = mf.read(fp);
+ fp->close();
+ delete fp;
+
+ if (rv) {
+ QString s(tr("reading midifile\n "));
+ s += name;
+ s += tr("\nfailed: ");
+ s += mf.error();
+ QMessageBox::critical(this, QString("MusE"), s);
+ return;
+ }
+ MidiFileTrackList* etl = mf.trackList();
+ int division = mf.division();
+
+ MidiOutPort* outPort = 0;
+
+ if (song->midiOutPorts()->empty()) {
+ outPort = new MidiOutPort();
+ outPort->setDefaultName();
+ song->insertTrack0(outPort, -1);
+
+ //
+ // set preferred instrument
+ //
+ MidiInstrument* instr = 0; // genericMidiInstrument;
+ for (iMidiInstrument mi = midiInstruments.begin(); mi != midiInstruments.end(); ++mi) {
+ if ((*mi)->iname() == config.defaultMidiInstrument) {
+ instr = *mi;
+ break;
+ }
+ }
+
+ //
+ // if midi file is GM/GS/XG this overrides the preferred
+ // instrument setting
+
+ if (mf.midiType() != MT_GENERIC) {
+ MidiInstrument* instr2 = 0;
+ for (iMidiInstrument i = midiInstruments.begin(); i != midiInstruments.end(); ++i) {
+ MidiInstrument* mi = *i;
+ switch(mf.midiType()) {
+ case MT_GM:
+ if (mi->iname() == "GM")
+ instr2 = mi;
+ break;
+ case MT_GS:
+ if (mi->iname() == "GS")
+ instr2 = mi;
+ break;
+ case MT_XG:
+ if (mi->iname() == "XG")
+ instr2 = mi;
+ break;
+ case MT_GENERIC: // cannot happen
+ break;
+ }
+ if (instr2)
+ break;
+ }
+ if (instr2)
+ instr = instr2;
+ }
+ if (instr == 0)
+ instr = genericMidiInstrument;
+ outPort->setInstrument(instr);
+ }
+ else
+ outPort = song->midiOutPorts()->front();
+
+ //
+ // create MidiTrack and copy events to ->events()
+ // - combine note on/off events
+ // - calculate tick value for internal resolution
+ //
+
+ foreach(const MidiFileTrack* t, *etl) {
+ const MidiEventList& el = t->events;
+ if (el.empty())
+ continue;
+ //
+ // if we split the track, SYSEX and META events go into
+ // the first target track
+
+ bool first = true;
+ for (int channel = 0; channel < MIDI_CHANNELS; ++channel) {
+ //
+ // check if there are any events for channel in track:
+ //
+ iMidiEvent i;
+ for (i = el.begin(); i != el.end(); ++i) {
+ MidiEvent ev = *i;
+ if (ev.type() != ME_SYSEX && ev.type() != ME_META && ev.channel() == channel)
+ break;
+ }
+ if (i == el.end())
+ continue;
+
+ MidiTrack* track = new MidiTrack();
+ if (t->isDrumTrack)
+ track->setUseDrumMap(true);
+//TODOB track->outRoutes()->push_back(Route(outPort->channel(channel), -1, Route::TRACK));
+// if (inPort && config.connectToAllMidiTracks) {
+// for (int ch = 0; ch < MIDI_CHANNELS; ++ch) {
+// Route src(inPort, ch, Route::TRACK);
+// track->inRoutes()->push_back(src);
+// }
+// }
+
+ EventList* mel = track->events();
+ buildMidiEventList(mel, &el, track, channel, division, first);
+ first = false;
+
+ for (iEvent i = mel->begin(); i != mel->end(); ++i) {
+ Event event = i->second;
+ if (event.type() == Controller) {
+ int ctrl = event.dataA();
+ MidiInstrument* instr = outPort->instrument();
+ track->addMidiController(instr, ctrl);
+ CVal val;
+ val.i = event.dataB();
+ track->addControllerVal(ctrl, event.tick(), val);
+ }
+ }
+ processTrack(track);
+ if (track->name().isEmpty())
+ track->setDefaultName();
+ song->insertTrack0(track, -1);
+ }
+ if (first) {
+ //
+ // track does only contain non-channel messages
+ // (SYSEX or META)
+ //
+ MidiTrack* track = new MidiTrack();
+ EventList* mel = track->events();
+ buildMidiEventList(mel, &el, track, 0, division, true);
+ processTrack(track);
+ if (track->name().isEmpty())
+ track->setDefaultName();
+ song->insertTrack0(track, -1);
+ }
+ }
+
+ TrackList* tl = song->tracks();
+ if (!tl->empty()) {
+ Track* track = tl->front();
+ track->setSelected(true);
+ }
+ unsigned int l = 1;
+ MidiTrackList* mtl = song->midis();
+ for (iMidiTrack t = mtl->begin(); t != mtl->end(); ++t) {
+ MidiTrack* track = *t;
+ PartList* parts = track->parts();
+ for (iPart p = parts->begin(); p != parts->end(); ++p) {
+ unsigned last = p->second->tick() + p->second->lenTick();
+ if (last > l)
+ l = last;
+ }
+ }
+ song->setLen(l);
+ AL::TimeSignature sig = AL::sigmap.timesig(0);
+ int z = sig.z;
+ int n = sig.n;
+
+ transport->setTimesig(z, n);
+// int tempo = AL::tempomap.tempo(0);
+// transport->setTempo(tempo);
+
+ bool masterF = !AL::tempomap.empty();
+ song->setMasterFlag(masterF);
+ transport->setMasterFlag(masterF);
+
+ song->updatePos();
+ }
+
+//---------------------------------------------------------
+// processTrack
+// divide events into parts
+//---------------------------------------------------------
+
+void MusE::processTrack(MidiTrack* track)
+ {
+ EventList* tevents = track->events();
+ if (tevents->empty())
+ return;
+
+ //---------------------------------------------------
+ // create parts
+ // Break midi tracks into parts.
+ // A new part is created when a gap of at least
+ // one measure is detected. Part len is aligned
+ // to one measure.
+ //---------------------------------------------------
+
+ PartList* pl = track->parts();
+
+ int lastTick = 0;
+ for (iEvent i = tevents->begin(); i != tevents->end(); ++i) {
+ Event event = i->second;
+ int epos = event.tick() + event.lenTick();
+ if (epos > lastTick)
+ lastTick = epos;
+ }
+
+ int len = song->roundUpBar(lastTick+1);
+ int bar2, beat;
+ unsigned tick;
+ AL::sigmap.tickValues(len, &bar2, &beat, &tick);
+
+ QString partname = track->name();
+
+ int lastOff = 0;
+ int st = -1; // start tick current part
+ int x1 = 0; // start tick current measure
+ int x2 = 0; // end tick current measure
+
+ for (int bar = 0; bar < bar2; ++bar, x1 = x2) {
+ x2 = AL::sigmap.bar2tick(bar+1, 0, 0);
+ if (lastOff > x2) {
+ // this measure is busy!
+ continue;
+ }
+ iEvent i1 = tevents->lower_bound(x1);
+ iEvent i2 = tevents->lower_bound(x2);
+
+ if (i1 == i2) { // empty?
+ if (st != -1) {
+ Part* part = new Part(track);
+ part->ref();
+ part->setType(AL::TICKS);
+ part->setTick(st);
+ part->setLenTick(x1-st);
+ part->setName(partname);
+ pl->add(part);
+ st = -1;
+ }
+ }
+ else {
+ if (st == -1)
+ st = x1; // begin new part
+ //HACK:
+ //lastOff:
+ for (iEvent i = i1; i != i2; ++i) {
+ Event event = i->second;
+ if (event.type() == Note) {
+ int off = event.tick() + event.lenTick();
+ if (off > lastOff)
+ lastOff = off;
+ }
+ }
+ }
+ }
+ if (st != -1) {
+ Part* part = new Part(track);
+ part->ref();
+ part->setType(AL::TICKS);
+ part->setTick(st);
+ part->setLenTick(x2-st);
+ part->setName(partname);
+ pl->add(part);
+ }
+
+ //-------------------------------------------------------------
+ // assign events to parts
+ //-------------------------------------------------------------
+
+ for (iPart p = pl->begin(); p != pl->end(); ++p) {
+ Part* part = p->second;
+ int stick = part->tick();
+ int etick = part->tick() + part->lenTick();
+ iEvent r1 = tevents->lower_bound(stick);
+ iEvent r2 = tevents->lower_bound(etick);
+ int startTick = part->tick();
+
+ EventList* el = part->events();
+ for (iEvent i = r1; i != r2; ++i) {
+ Event ev = i->second;
+ int ntick = ev.tick() - startTick;
+ ev.setTick(ntick);
+ el->add(ev, ntick);
+ }
+ tevents->erase(r1, r2);
+ }
+
+ if (tevents->size())
+ printf("-----------events left: %zd\n", tevents->size());
+ for (iEvent i = tevents->begin(); i != tevents->end(); ++i) {
+ printf("%d===\n", i->first);
+ i->second.dump();
+ }
+ // all events should be processed:
+ assert(tevents->empty());
+ }
+
diff --git a/muse_qt4_evolution/muse/importmidi.h b/muse_qt4_evolution/muse/importmidi.h
new file mode 100644
index 00000000..b7aa1571
--- /dev/null
+++ b/muse_qt4_evolution/muse/importmidi.h
@@ -0,0 +1,46 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __IMPORTMIDI_H__
+#define __IMPORTMIDI_H__
+
+#include "ui_importmidi.h"
+
+//---------------------------------------------------------
+// ImportMidiDialog
+//---------------------------------------------------------
+
+class ImportMidiDialog : public QDialog, public Ui::ImportMidiDialogBase {
+ Q_OBJECT
+ QButtonGroup* bg;
+
+ private slots:
+ void selectProjectClicked();
+ void selectTemplateClicked();
+
+ public:
+ ImportMidiDialog(QWidget*);
+ void setProjectName(const QString&);
+ void setTemplateName(const QString&);
+ bool doCreateNewProject() const { return bg->checkedId() == 1; }
+ };
+
+
+#endif
diff --git a/muse_qt4_evolution/muse/importmidi.ui b/muse_qt4_evolution/muse/importmidi.ui
new file mode 100644
index 00000000..ccf22220
--- /dev/null
+++ b/muse_qt4_evolution/muse/importmidi.ui
@@ -0,0 +1,200 @@
+<ui version="4.0" >
+ <class>ImportMidiDialogBase</class>
+ <widget class="QDialog" name="ImportMidiDialogBase" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>312</width>
+ <height>185</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Import Midi File</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QRadioButton" name="addToProject" >
+ <property name="text" >
+ <string>add to current project</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="createNewProject" >
+ <property name="text" >
+ <string>create new project:</string>
+ </property>
+ <property name="checked" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="3" >
+ <widget class="QToolButton" name="selectProject" >
+ <property name="toolTip" >
+ <string>select project name</string>
+ </property>
+ <property name="text" >
+ <string>...</string>
+ </property>
+ <property name="icon" >
+ <iconset resource="muse.qrc" >:/xpm/filenew.png</iconset>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Project Name: </string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3" >
+ <widget class="QToolButton" name="selectTemplate" >
+ <property name="toolTip" >
+ <string>select template</string>
+ </property>
+ <property name="text" >
+ <string>...</string>
+ </property>
+ <property name="icon" >
+ <iconset resource="muse.qrc" >:/xpm/filenew.png</iconset>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2" >
+ <widget class="QLineEdit" name="templateName" />
+ </item>
+ <item row="0" column="0" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>30</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QLabel" name="label_2" >
+ <property name="text" >
+ <string>Template:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2" >
+ <widget class="QLineEdit" name="projectName" />
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>31</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>131</width>
+ <height>31</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="okButton" >
+ <property name="text" >
+ <string>OK</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="cancelButton" >
+ <property name="text" >
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources>
+ <include location="muse.qrc" />
+ </resources>
+ <connections>
+ <connection>
+ <sender>okButton</sender>
+ <signal>clicked()</signal>
+ <receiver>ImportMidiDialogBase</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>278</x>
+ <y>253</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>96</x>
+ <y>254</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>cancelButton</sender>
+ <signal>clicked()</signal>
+ <receiver>ImportMidiDialogBase</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>369</x>
+ <y>253</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>179</x>
+ <y>282</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/muse_qt4_evolution/muse/instruments/CMakeLists.txt b/muse_qt4_evolution/muse/instruments/CMakeLists.txt
new file mode 100644
index 00000000..b86764d4
--- /dev/null
+++ b/muse_qt4_evolution/muse/instruments/CMakeLists.txt
@@ -0,0 +1,41 @@
+#=============================================================================
+# MusE
+# Linux Music Editor
+# $Id:$
+#
+# Copyright (C) 2002-2006 by Werner Schweer and others
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#=============================================================================
+
+QT4_WRAP_CPP ( instruments_mocs
+ minstrument.h editinstrument.h
+ )
+
+QT4_WRAP_UI ( instruments_ui_headers
+ editinstrument.ui
+ )
+
+add_library ( instruments STATIC
+ minstrument.cpp
+ editinstrument.cpp
+ minstrument.h
+ editinstrument.h
+ ${instruments_mocs}
+ ${instruments_ui_headers}
+ )
+
+set_target_properties( instruments
+ PROPERTIES COMPILE_FLAGS "-include ${PROJECT_BINARY_DIR}/all.h"
+ )
+
diff --git a/muse_qt4_evolution/muse/instruments/editinstrument.cpp b/muse_qt4_evolution/muse/instruments/editinstrument.cpp
new file mode 100644
index 00000000..823a20e3
--- /dev/null
+++ b/muse_qt4_evolution/muse/instruments/editinstrument.cpp
@@ -0,0 +1,844 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "editinstrument.h"
+#include "minstrument.h"
+#include "ctrl.h"
+#include "midictrl.h"
+#include "al/xml.h"
+#include "gconfig.h"
+
+extern int string2sysex(const QString& s, unsigned char** data);
+extern QString sysex2string(int len, unsigned char* data);
+
+//---------------------------------------------------------
+// EditInstrument
+//---------------------------------------------------------
+
+EditInstrument::EditInstrument(QWidget* parent)
+ : QMainWindow(parent)
+ {
+ setupUi(this);
+ // populate instrument list
+ for (iMidiInstrument i = midiInstruments.begin(); i != midiInstruments.end(); ++i) {
+ QListWidgetItem* item = new QListWidgetItem((*i)->iname());
+ QVariant v = qVariantFromValue((void*)(*i));
+ item->setData(Qt::UserRole, v);
+ instrumentList->addItem(item);
+ }
+ instrumentList->setItemSelected(instrumentList->item(0), true);
+ connect(instrumentList, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)),
+ SLOT(instrumentChanged(QListWidgetItem*,QListWidgetItem*)));
+ connect(patchView, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
+ SLOT(patchChanged(QTreeWidgetItem*, QTreeWidgetItem*)));
+ instrumentChanged(instrumentList->item(0), instrumentList->item(0));
+ connect(listController, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)),
+ SLOT(controllerChanged(QListWidgetItem*, QListWidgetItem*)));
+ connect(sysexList, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)),
+ SLOT(sysexChanged(QListWidgetItem*, QListWidgetItem*)));
+ connect(instrumentName, SIGNAL(textChanged(const QString&)), SLOT(instrumentNameChanged(const QString&)));
+ connect(fileSaveAsAction, SIGNAL(triggered()), SLOT(fileSaveAs()));
+ connect(fileSaveAction, SIGNAL(triggered()), SLOT(fileSave()));
+ connect(fileNewAction, SIGNAL(triggered()), SLOT(fileNew()));
+ connect(fileExitAction, SIGNAL(triggered()), SLOT(close()));
+
+ connect(deletePatch, SIGNAL(clicked()), SLOT(deletePatchClicked()));
+ connect(newPatch, SIGNAL(clicked()), SLOT(newPatchClicked()));
+ connect(newGroup, SIGNAL(clicked()), SLOT(newGroupClicked()));
+ connect(newCategory, SIGNAL(clicked()), SLOT(newCategoryClicked()));
+ connect(deleteController, SIGNAL(clicked()), SLOT(deleteControllerClicked()));
+ connect(newController, SIGNAL(clicked()), SLOT(newControllerClicked()));
+ connect(deleteSysex, SIGNAL(clicked()), SLOT(deleteSysexClicked()));
+ connect(newSysex, SIGNAL(clicked()), SLOT(newSysexClicked()));
+
+ connect(ctrlType,SIGNAL(activated(int)), SLOT(ctrlTypeChanged(int)));
+ }
+
+//---------------------------------------------------------
+// fileNew
+//---------------------------------------------------------
+
+void EditInstrument::fileNew()
+ {
+ 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) {
+ MidiInstrument* ni = new MidiInstrument(s);
+ midiInstruments.append(ni);
+ QListWidgetItem* item = new QListWidgetItem(ni->iname());
+ QVariant v = qVariantFromValue((void*)(ni));
+ item->setData(Qt::UserRole, v);
+ instrumentList->addItem(item);
+ instrumentList->setCurrentItem(item);
+ break;
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// fileSave
+//---------------------------------------------------------
+
+void EditInstrument::fileSave()
+ {
+ QListWidgetItem* item = instrumentList->currentItem();
+ if (item == 0)
+ return;
+ MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>();
+ if (instrument->filePath().isEmpty())
+ fileSaveAs();
+ else {
+ QFile f(instrument->filePath());
+ if (!f.open(QIODevice::WriteOnly)) {
+ fileSaveAs();
+ }
+ else {
+ f.close();
+ if (fileSave(instrument, instrument->filePath()))
+ instrument->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);
+ updateInstrument(instrument);
+ instrument->write(xml);
+ f.close();
+ if (f.error()) {
+ QString s = QString("Write File\n") + f.fileName() + QString("\nfailed: ")
+ + f.errorString();
+ QMessageBox::critical(this, tr("MusE: Write File failed"), s);
+ return false;
+ }
+ return true;
+ }
+
+//---------------------------------------------------------
+// fileSaveAs
+//---------------------------------------------------------
+
+void EditInstrument::fileSaveAs()
+ {
+ QListWidgetItem* item = instrumentList->currentItem();
+ if (item == 0)
+ return;
+ MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>();
+ QString path = QDir::homePath() + "/" + config.instrumentPath;
+ if (instrument->filePath().isEmpty())
+ path += QString("/%1.idf").arg(instrument->iname());
+ else {
+ QFileInfo fi(instrument->filePath());
+ path += QString("/%1.idf").arg(fi.baseName());
+ }
+ QString s = QFileDialog::getSaveFileName(this,
+ tr("MusE: Save Instrument Definition"),
+ path,
+ tr("Instrument Definition (*.idf)"));
+ if (s.isEmpty())
+ return;
+ instrument->setFilePath(s);
+ if (fileSave(instrument, s))
+ instrument->setDirty(false);
+ }
+
+//---------------------------------------------------------
+// closeEvent
+//---------------------------------------------------------
+
+void EditInstrument::closeEvent(QCloseEvent* ev)
+ {
+ QListWidgetItem* item = instrumentList->currentItem();
+ if (item) {
+ MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>();
+ if (checkDirty(instrument)) {
+ ev->ignore();
+ return;
+ }
+ }
+ QMainWindow::closeEvent(ev);
+ }
+
+//---------------------------------------------------------
+// instrumentNameChanged
+//---------------------------------------------------------
+
+void EditInstrument::instrumentNameChanged(const QString& s)
+ {
+ QListWidgetItem* item = instrumentList->currentItem();
+ if (item == 0)
+ return;
+ if (s != item->text()) {
+ item->setText(s);
+ MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>();
+ instrument->setDirty(true);
+ }
+ }
+
+//---------------------------------------------------------
+// deletePatchClicked
+//---------------------------------------------------------
+
+void EditInstrument::deletePatchClicked()
+ {
+ QListWidgetItem* item = instrumentList->currentItem();
+ if (item == 0)
+ return;
+ MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>();
+ QTreeWidgetItem* pi = patchView->currentItem();
+ if (pi == 0)
+ return;
+ void* p = pi->data(0, Qt::UserRole).value<void*>();
+ if (p == 0)
+ return;
+ 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");
+ }
+
+//---------------------------------------------------------
+// newPatchClicked
+//---------------------------------------------------------
+
+void EditInstrument::newPatchClicked()
+ {
+ QListWidgetItem* item = instrumentList->currentItem();
+ if (item == 0)
+ return;
+ MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>();
+ std::vector<PatchGroup>* pg = instrument->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 (iPatch p = g->patches.begin(); p != g->patches.end(); ++p) {
+ if ((*p)->name == patchName) {
+ found = true;
+ break;
+ }
+ }
+ if (found)
+ break;
+ }
+ if (!found)
+ break;
+ }
+
+ //
+ // search current patch group
+ //
+ PatchGroup* pGroup = 0;
+ QTreeWidgetItem* pi = patchView->currentItem();
+ if (pi == 0)
+ return;
+ if (pi->data(0, Qt::UserRole).value<void*>())
+ pi = pi->parent();
+ for (std::vector<PatchGroup>::iterator 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;
+ }
+ Patch* patch = new Patch;
+ patch->name = patchName;
+ pGroup->patches.push_back(patch);
+ QTreeWidgetItem* sitem = new QTreeWidgetItem;
+ sitem->setText(0, patch->name);
+ QVariant v = QVariant::fromValue((void*)(patch));
+ sitem->setData(0, Qt::UserRole, v);
+
+ pi->addChild(sitem);
+ patchView->setCurrentItem(sitem);
+ instrument->setDirty(true);
+ }
+
+//---------------------------------------------------------
+// newGroupClicked
+//---------------------------------------------------------
+
+void EditInstrument::newGroupClicked()
+ {
+ QListWidgetItem* item = instrumentList->currentItem();
+ if (item == 0)
+ return;
+ MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>();
+ std::vector<PatchGroup>* pg = instrument->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) {
+ if (g->name == groupName) {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ break;
+ }
+
+ PatchGroup pGroup;
+ pGroup.name = groupName;
+ pg->push_back(pGroup);
+
+ QTreeWidgetItem* sitem = new QTreeWidgetItem;
+ sitem->setText(0, groupName);
+ QVariant v = QVariant::fromValue((void*)0);
+ sitem->setData(0, Qt::UserRole, v);
+ patchView->addTopLevelItem(sitem);
+ patchView->setCurrentItem(sitem);
+ instrument->setDirty(true);
+ }
+
+//---------------------------------------------------------
+// newCategoryClicked
+//---------------------------------------------------------
+
+void EditInstrument::newCategoryClicked()
+ {
+ QListWidgetItem* item = instrumentList->currentItem();
+ if (item == 0)
+ return;
+ MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>();
+ bool ok;
+ QString cat = QInputDialog::getText(this,
+ tr("MusE: Enter new Category"),
+ tr("Enter new Category:"),
+ QLineEdit::Normal, "", &ok
+ );
+ if (ok && !cat.isEmpty()) {
+ category->addItem(cat);
+ instrument->addCategory(cat);
+ instrument->setDirty(true);
+ }
+ }
+
+//---------------------------------------------------------
+// deleteControllerClicked
+//---------------------------------------------------------
+
+void EditInstrument::deleteControllerClicked()
+ {
+ QListWidgetItem* item = instrumentList->currentItem();
+ QListWidgetItem* item2 = listController->currentItem();
+ if (item == 0 || item2 == 0)
+ return;
+ MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>();
+ MidiController* ctrl = (MidiController*)item2->data(Qt::UserRole).value<void*>();
+ MidiControllerList* cl = instrument->controller();
+ cl->removeAll(ctrl);
+ delete item2;
+ instrument->setDirty(true);
+ }
+
+//---------------------------------------------------------
+// newControllerClicked
+//---------------------------------------------------------
+
+void EditInstrument::newControllerClicked()
+ {
+ QListWidgetItem* item = instrumentList->currentItem();
+ if (item == 0)
+ return;
+ MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>();
+
+ QString ctrlName;
+ MidiControllerList* cl = instrument->controller();
+ for (int i = 1;; ++i) {
+ ctrlName = QString("Controller-%d").arg(i);
+
+ bool found = false;
+ for (iMidiController ic = cl->begin(); ic != cl->end(); ++ic) {
+ MidiController* c = *ic;
+ if (c->name() == ctrlName) {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ break;
+ }
+
+ MidiController* ctrl = new MidiController();
+ ctrl->setName(ctrlName);
+ item = new QListWidgetItem(ctrlName);
+ QVariant v = qVariantFromValue((void*)(ctrl));
+ item->setData(Qt::UserRole, v);
+ listController->addItem(item);
+ listController->setCurrentItem(item);
+ instrument->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);
+ }
+
+//---------------------------------------------------------
+// newSysexClicked
+//---------------------------------------------------------
+
+void EditInstrument::newSysexClicked()
+ {
+ QListWidgetItem* item = instrumentList->currentItem();
+ if (item == 0)
+ return;
+ MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>();
+
+ QString sysexName;
+ for (int i = 1;; ++i) {
+ sysexName = QString("Sysex-%1").arg(i);
+
+ bool found = false;
+ foreach(const SysEx* s, instrument->sysex()) {
+ if (s->name == sysexName) {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ break;
+ }
+ SysEx* nsysex = new SysEx;
+ nsysex->name = sysexName;
+ instrument->addSysex(nsysex);
+
+ item = new QListWidgetItem(sysexName);
+ QVariant v = QVariant::fromValue((void*)nsysex);
+ item->setData(Qt::UserRole, v);
+ sysexList->addItem(item);
+ sysexList->setCurrentItem(item);
+ instrument->setDirty(true);
+ }
+
+//---------------------------------------------------------
+// instrumentChanged
+//---------------------------------------------------------
+
+void EditInstrument::instrumentChanged(QListWidgetItem* sel, QListWidgetItem* old)
+ {
+ if (sel == 0)
+ return;
+ if (old) {
+ MidiInstrument* oi = (MidiInstrument*)old->data(Qt::UserRole).value<void*>();
+ checkDirty(oi);
+ oi->setDirty(false);
+ }
+
+ patchView->clear();
+ listController->clear();
+ category->clear();
+ sysexList->clear();
+
+ // populate patch list
+
+ MidiInstrument* instrument = (MidiInstrument*)sel->data(Qt::UserRole).value<void*>();
+ instrument->setDirty(false);
+
+ instrumentName->setText(instrument->iname());
+ std::vector<PatchGroup>* pg = instrument->groups();
+ for (std::vector<PatchGroup>::iterator g = pg->begin(); g != pg->end(); ++g) {
+ QTreeWidgetItem* item = new QTreeWidgetItem;
+ item->setText(0, g->name);
+ QVariant v = QVariant::fromValue((void*)0);
+ item->setData(0, Qt::UserRole, v);
+ patchView->addTopLevelItem(item);
+ for (iPatch p = g->patches.begin(); p != g->patches.end(); ++p) {
+ Patch* patch = *p;
+ QTreeWidgetItem* sitem = new QTreeWidgetItem;
+ sitem->setText(0, patch->name);
+ QVariant v = QVariant::fromValue((void*)patch);
+ sitem->setData(0, Qt::UserRole, v);
+ item->addChild(sitem);
+ }
+ }
+ MidiControllerList* cl = instrument->controller();
+ for (iMidiController ic = cl->begin(); ic != cl->end(); ++ic) {
+ MidiController* c = *ic;
+ QListWidgetItem* item = new QListWidgetItem(c->name());
+ QVariant v = QVariant::fromValue((void*)c);
+ item->setData(Qt::UserRole, v);
+ listController->addItem(item);
+ }
+ listController->setItemSelected(listController->item(0), true);
+ controllerChanged(listController->item(0), 0);
+
+ 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);
+ }
+ }
+
+//---------------------------------------------------------
+// updatePatch
+//---------------------------------------------------------
+
+void EditInstrument::updatePatch(MidiInstrument* instrument, Patch* p)
+ {
+ if (p->name != patchNameEdit->text()) {
+ p->name = patchNameEdit->text();
+ instrument->setDirty(true);
+ }
+ if (p->hbank != spinBoxHBank->value()) {
+ p->hbank = spinBoxHBank->value();
+ instrument->setDirty(true);
+ }
+ if (p->lbank != spinBoxLBank->value()) {
+ p->hbank = spinBoxHBank->value();
+ instrument->setDirty(true);
+ }
+ if (p->prog != spinBoxProgram->value()) {
+ p->prog = spinBoxProgram->value();
+ 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);
+ }
+ }
+
+//---------------------------------------------------------
+// patchChanged
+//---------------------------------------------------------
+
+void EditInstrument::patchChanged(QTreeWidgetItem* sel, QTreeWidgetItem* old)
+ {
+ if (old && old->data(0, Qt::UserRole).value<void*>()) {
+ 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 (sel == 0 || sel->data(0, Qt::UserRole).value<void*>() == 0) {
+ patchNameEdit->setText("");
+ return;
+ }
+ Patch* p = (Patch*)sel->data(0, Qt::UserRole).value<void*>();
+ patchNameEdit->setText(p->name);
+ spinBoxHBank->setValue(p->hbank);
+ spinBoxLBank->setValue(p->lbank);
+ spinBoxProgram->setValue(p->prog);
+ checkBoxDrum->setChecked(p->drumMap);
+ checkBoxGM->setChecked(p->typ & 1);
+ checkBoxGS->setChecked(p->typ & 2);
+ checkBoxXG->setChecked(p->typ & 4);
+ category->setCurrentIndex(p->categorie);
+ }
+
+//---------------------------------------------------------
+// updateController
+//---------------------------------------------------------
+
+void EditInstrument::updateController(MidiInstrument* instrument, MidiController* oc)
+ {
+ int ctrlH = spinBoxHCtrlNo->value();
+ int ctrlL = spinBoxLCtrlNo->value();
+ MidiController::ControllerType type = (MidiController::ControllerType)ctrlType->currentIndex();
+ int num = MidiController::genNum(type, ctrlH, ctrlL);
+
+ if (num != oc->num()) {
+ oc->setNum(num);
+ instrument->setDirty(true);
+ }
+ if (spinBoxMin->value() != oc->minVal()) {
+ oc->setMinVal(spinBoxMin->value());
+ instrument->setDirty(true);
+ }
+ if (spinBoxMax->value() != oc->maxVal()) {
+ oc->setMaxVal(spinBoxMax->value());
+ instrument->setDirty(true);
+ }
+ if (spinBoxDefault->value() != oc->initVal()) {
+ oc->setInitVal(spinBoxDefault->value());
+ instrument->setDirty(true);
+ }
+ if (moveWithPart->isChecked() ^ oc->moveWithPart()) {
+ oc->setMoveWithPart(moveWithPart->isChecked());
+ instrument->setDirty(true);
+ }
+ if (ctrlName->text() != oc->name()) {
+ oc->setName(ctrlName->text());
+ instrument->setDirty(true);
+ }
+ if (ctrlComment->toPlainText() != oc->comment()) {
+ oc->setComment(ctrlComment->toPlainText());
+ instrument->setDirty(true);
+ }
+ }
+
+//---------------------------------------------------------
+// controllerChanged
+//---------------------------------------------------------
+
+void EditInstrument::controllerChanged(QListWidgetItem* sel, QListWidgetItem* old)
+ {
+ if (old) {
+ 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);
+ }
+ if (sel == 0 || sel->data(Qt::UserRole).value<void*>() == 0) {
+ ctrlName->setText("");
+ ctrlComment->setText("");
+ return;
+ }
+ MidiController* c = (MidiController*)sel->data(Qt::UserRole).value<void*>();
+ ctrlName->setText(c->name());
+ ctrlComment->setText(c->comment());
+ int ctrlH = (c->num() >> 8) & 0x7f;
+ int ctrlL = c->num() & 0x7f;
+ int type = int(c->type());
+ ctrlType->setCurrentIndex(type);
+ ctrlTypeChanged(type);
+ spinBoxHCtrlNo->setValue(ctrlH);
+ spinBoxLCtrlNo->setValue(ctrlL);
+ spinBoxMin->setValue(c->minVal());
+ spinBoxMax->setValue(c->maxVal());
+ spinBoxDefault->setRange(c->minVal()-1, c->maxVal());
+ spinBoxDefault->setValue(c->initVal());
+ moveWithPart->setChecked(c->moveWithPart());
+ }
+
+//---------------------------------------------------------
+// updateSysex
+//---------------------------------------------------------
+
+void EditInstrument::updateSysex(MidiInstrument* instrument, SysEx* so)
+ {
+ if (sysexName->text() != so->name) {
+ so->name = sysexName->text();
+ instrument->setDirty(true);
+ }
+ if (sysexComment->toPlainText() != so->comment) {
+ so->comment = sysexComment->toPlainText();
+ instrument->setDirty(true);
+ }
+ unsigned char* data;
+ int len = string2sysex(sysexData->toPlainText(), &data);
+ if (so->dataLen != len || !memcmp(data, so->data, len)) {
+ delete so->data;
+ so->data = data;
+ so->dataLen = len;
+ }
+ }
+
+//---------------------------------------------------------
+// sysexChanged
+//---------------------------------------------------------
+
+void EditInstrument::sysexChanged(QListWidgetItem* sel, QListWidgetItem* old)
+ {
+ if (old) {
+ QListWidgetItem* item = instrumentList->currentItem();
+ if (item == 0)
+ return;
+ MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>();
+ SysEx* so = (SysEx*)item->data(Qt::UserRole).value<void*>();
+ updateSysex(instrument, so);
+ }
+ if (sel == 0) {
+ sysexName->setText("");
+ sysexComment->setText("");
+ sysexData->setText("");
+ sysexName->setEnabled(false);
+ sysexComment->setEnabled(false);
+ sysexData->setEnabled(false);
+ return;
+ }
+ sysexName->setEnabled(true);
+ sysexComment->setEnabled(true);
+ sysexData->setEnabled(true);
+
+ SysEx* sx = (SysEx*)sel->data(Qt::UserRole).value<void*>();
+ sysexName->setText(sx->name);
+ sysexComment->setText(sx->comment);
+ sysexData->setText(sysex2string(sx->dataLen, sx->data));
+ }
+
+//---------------------------------------------------------
+// checkDirty
+// return true on Abort
+//---------------------------------------------------------
+
+bool EditInstrument::checkDirty(MidiInstrument* i)
+ {
+ updateInstrument(i);
+ if (!i->dirty())
+ return false;
+ int 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);
+ if (n == 0) {
+ if (i->filePath().isEmpty())
+ fileSaveAs();
+ else {
+ QFile f(i->filePath());
+ if (!f.open(QIODevice::WriteOnly))
+ fileSaveAs();
+ else {
+ f.close();
+ if (fileSave(i, i->filePath()))
+ i->setDirty(false);
+ }
+ }
+ return false;
+ }
+ return n == 2;
+ }
+
+//---------------------------------------------------------
+// ctrlTypeChanged
+//---------------------------------------------------------
+
+void EditInstrument::ctrlTypeChanged(int idx)
+ {
+ MidiController::ControllerType t = (MidiController::ControllerType)idx;
+ switch (t) {
+ case MidiController::RPN:
+ case MidiController::NRPN:
+ case MidiController::Controller7:
+ spinBoxHCtrlNo->setEnabled(false);
+ spinBoxLCtrlNo->setEnabled(true);
+ break;
+ case MidiController::Controller14:
+ case MidiController::RPN14:
+ case MidiController::NRPN14:
+ spinBoxHCtrlNo->setEnabled(true);
+ spinBoxLCtrlNo->setEnabled(true);
+ break;
+ case MidiController::Pitch:
+ case MidiController::Program:
+ spinBoxHCtrlNo->setEnabled(false);
+ spinBoxLCtrlNo->setEnabled(false);
+ break;
+ default:
+ break;
+ }
+ }
+
+//---------------------------------------------------------
+// updateInstrument
+//---------------------------------------------------------
+
+void EditInstrument::updateInstrument(MidiInstrument* instrument)
+ {
+ QListWidgetItem* sysexItem = sysexList->currentItem();
+ if (sysexItem) {
+ SysEx* so = (SysEx*)sysexItem->data(Qt::UserRole).value<void*>();
+ updateSysex(instrument, so);
+ }
+ QListWidgetItem* ctrlItem = listController->currentItem();
+ if (ctrlItem) {
+ MidiController* ctrl = (MidiController*)ctrlItem->data(Qt::UserRole).value<void*>();
+ updateController(instrument, ctrl);
+ }
+ QTreeWidgetItem* patchItem = patchView->currentItem();
+ if (patchItem) {
+ Patch* p = (Patch*)patchItem->data(0, Qt::UserRole).value<void*>();
+ updatePatch(instrument, p);
+ }
+ }
+
diff --git a/muse_qt4_evolution/muse/instruments/editinstrument.h b/muse_qt4_evolution/muse/instruments/editinstrument.h
new file mode 100644
index 00000000..cefafe74
--- /dev/null
+++ b/muse_qt4_evolution/muse/instruments/editinstrument.h
@@ -0,0 +1,70 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __EDITINSTRUMENT_H__
+#define __EDITINSTRUMENT_H__
+
+#include "ui_editinstrument.h"
+
+class MidiInstrument;
+class SysEx;
+class MidiController;
+struct Patch;
+
+//---------------------------------------------------------
+// EditInstrument
+//---------------------------------------------------------
+
+class EditInstrument : public QMainWindow, public Ui::EditInstrumentBase {
+ Q_OBJECT
+
+ bool fileSave(MidiInstrument*, const QString& name);
+ void closeEvent(QCloseEvent*);
+ bool checkDirty(MidiInstrument*);
+ void updateInstrument(MidiInstrument*);
+ void updateSysex(MidiInstrument*, SysEx*);
+ void updateController(MidiInstrument*, MidiController*);
+ void updatePatch(MidiInstrument* instrument, Patch* p);
+
+ private slots:
+ virtual void fileNew();
+ virtual void fileSave();
+ virtual void fileSaveAs();
+ void instrumentChanged(QListWidgetItem*, QListWidgetItem*);
+ void patchChanged(QTreeWidgetItem*, QTreeWidgetItem*);
+ void controllerChanged(QListWidgetItem*, QListWidgetItem*);
+ void sysexChanged(QListWidgetItem*, QListWidgetItem*);
+ void instrumentNameChanged(const QString&);
+ void deletePatchClicked();
+ void newPatchClicked();
+ void newGroupClicked();
+ void newCategoryClicked();
+ void deleteControllerClicked();
+ void newControllerClicked();
+ void deleteSysexClicked();
+ void newSysexClicked();
+ void ctrlTypeChanged(int);
+
+ public:
+ EditInstrument(QWidget* parent = 0);
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/instruments/editinstrument.ui b/muse_qt4_evolution/muse/instruments/editinstrument.ui
new file mode 100644
index 00000000..f58d9d28
--- /dev/null
+++ b/muse_qt4_evolution/muse/instruments/editinstrument.ui
@@ -0,0 +1,998 @@
+<ui version="4.0" >
+ <class>EditInstrumentBase</class>
+ <widget class="QMainWindow" name="EditInstrumentBase" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>821</width>
+ <height>551</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>MusE: Instrument Editor</string>
+ </property>
+ <widget class="QWidget" name="widget" >
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QSplitter" name="splitter_3" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <widget class="QListWidget" name="instrumentList" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="resizeMode" >
+ <enum>QListView::Adjust</enum>
+ </property>
+ <property name="layoutMode" >
+ <enum>QListView::Batched</enum>
+ </property>
+ </widget>
+ <widget class="QWidget" name="layoutWidget" >
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Instrument Name:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="instrumentName" />
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QTabWidget" name="tabWidget3" >
+ <property name="currentIndex" >
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="tab" >
+ <attribute name="title" >
+ <string>Patches</string>
+ </attribute>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QSplitter" name="splitter" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <widget class="QTreeWidget" name="patchView" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="rootIsDecorated" >
+ <bool>true</bool>
+ </property>
+ <column>
+ <property name="text" >
+ <string>Patch/Group</string>
+ </property>
+ </column>
+ </widget>
+ <widget class="QWidget" name="layoutWidget" >
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="1" colspan="2" >
+ <widget class="QLineEdit" name="patchNameEdit" />
+ </item>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="textLabelPatchName" >
+ <property name="text" >
+ <string>Patch Name:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0" >
+ <widget class="QLabel" name="textLabel4_3" >
+ <property name="text" >
+ <string>Program:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="0" colspan="3" >
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QToolButton" name="deletePatch" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>&amp;Delete</string>
+ </property>
+ <property name="shortcut" >
+ <string>Alt+D</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="newPatch" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>&amp;New Patch</string>
+ </property>
+ <property name="shortcut" >
+ <string>Alt+N</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="newGroup" >
+ <property name="text" >
+ <string>New Group</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>240</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="newCategory" >
+ <property name="text" >
+ <string>New Category</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="3" column="2" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>280</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="4" column="2" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>280</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="2" column="2" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>280</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="3" column="1" >
+ <widget class="QSpinBox" name="spinBoxLBank" >
+ <property name="specialValueText" >
+ <string>d.c.</string>
+ </property>
+ <property name="maximum" >
+ <number>127</number>
+ </property>
+ <property name="minimum" >
+ <number>-1</number>
+ </property>
+ <property name="value" >
+ <number>-1</number>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="textLabel2_2" >
+ <property name="text" >
+ <string>High Bank:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" >
+ <widget class="QLabel" name="textLabel3_2" >
+ <property name="text" >
+ <string>Low Bank:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="2" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>90</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="2" column="1" >
+ <widget class="QSpinBox" name="spinBoxHBank" >
+ <property name="specialValueText" >
+ <string>d.c.</string>
+ </property>
+ <property name="maximum" >
+ <number>127</number>
+ </property>
+ <property name="minimum" >
+ <number>-1</number>
+ </property>
+ <property name="value" >
+ <number>-1</number>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1" >
+ <widget class="QSpinBox" name="spinBoxProgram" />
+ </item>
+ <item row="5" column="0" colspan="3" >
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QCheckBox" name="checkBoxDrum" >
+ <property name="text" >
+ <string>Drum</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="checkBoxGM" >
+ <property name="text" >
+ <string>GM</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="checkBoxGS" >
+ <property name="text" >
+ <string>GS</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="checkBoxXG" >
+ <property name="text" >
+ <string>XG</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QComboBox" name="category" >
+ <property name="editable" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_6" >
+ <property name="text" >
+ <string>Category:</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab" >
+ <attribute name="title" >
+ <string>Controller</string>
+ </attribute>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QSplitter" name="splitter_2" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <widget class="QWidget" name="layoutWidget" >
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="textLabel1" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Controller List:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QListWidget" name="listController" >
+ <property name="whatsThis" >
+ <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>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="layoutWidget" >
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QGroupBox" name="GroupBox1" >
+ <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>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="TextLabel1_3" >
+ <property name="text" >
+ <string>Name</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2" >
+ <widget class="QLineEdit" name="ctrlName" />
+ </item>
+ <item row="1" column="0" colspan="2" >
+ <widget class="QLabel" name="label_2" >
+ <property name="text" >
+ <string>Comment</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2" >
+ <widget class="QTextEdit" name="ctrlComment" />
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="TextLabel2_4" >
+ <property name="text" >
+ <string>Type</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" colspan="2" >
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>2</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QComboBox" name="ctrlType" >
+ <item>
+ <property name="text" >
+ <string>Controller-7Bit</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Controller-14Bit</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>RPN-7Bit</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>NRPN-7Bit</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>RPN-14Bit</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>NRPN-14Bit</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Pitch</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Program</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="TextLabel3_2" >
+ <property name="text" >
+ <string>H-Ctrl</string>
+ </property>
+ <property name="indent" >
+ <number>10</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="spinBoxHCtrlNo" >
+ <property name="toolTip" >
+ <string>Midi Controller Number High Byte</string>
+ </property>
+ <property name="maximum" >
+ <number>127</number>
+ </property>
+ <property name="minimum" >
+ <number>0</number>
+ </property>
+ <property name="value" >
+ <number>1</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="TextLabel2_3_2" >
+ <property name="text" >
+ <string>L-Ctrl</string>
+ </property>
+ <property name="indent" >
+ <number>10</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="spinBoxLCtrlNo" >
+ <property name="toolTip" >
+ <string>Midi Controller Number Low Byte</string>
+ </property>
+ <property name="maximum" >
+ <number>127</number>
+ </property>
+ <property name="minimum" >
+ <number>0</number>
+ </property>
+ <property name="value" >
+ <number>1</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="3" column="0" >
+ <widget class="QLabel" name="textLabel4_2" >
+ <property name="text" >
+ <string>Range</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1" colspan="2" >
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="TextLabel1_2_2" >
+ <property name="text" >
+ <string>Min</string>
+ </property>
+ <property name="indent" >
+ <number>10</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="spinBoxMin" >
+ <property name="maximum" >
+ <number>16384</number>
+ </property>
+ <property name="minimum" >
+ <number>-16385</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="TextLabel2_2_2" >
+ <property name="text" >
+ <string>Max</string>
+ </property>
+ <property name="indent" >
+ <number>10</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="spinBoxMax" >
+ <property name="maximum" >
+ <number>8388607</number>
+ </property>
+ <property name="minimum" >
+ <number>-16385</number>
+ </property>
+ <property name="value" >
+ <number>127</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="textLabel1_3" >
+ <property name="text" >
+ <string>Default</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="spinBoxDefault" >
+ <property name="specialValueText" >
+ <string>??</string>
+ </property>
+ <property name="minimum" >
+ <number>-1</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="4" column="0" colspan="3" >
+ <widget class="QCheckBox" name="moveWithPart" >
+ <property name="text" >
+ <string>Move Controller Values with Part</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="deleteController" >
+ <property name="text" >
+ <string>Delete</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="newController" >
+ <property name="text" >
+ <string>New Controller</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="TabPage" >
+ <attribute name="title" >
+ <string>SysEx</string>
+ </attribute>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QSplitter" name="splitter_4" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <widget class="QWidget" name="layoutWidget" >
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label_3" >
+ <property name="text" >
+ <string>SYSEX-List:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QListWidget" name="sysexList" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="resizeMode" >
+ <enum>QListView::Adjust</enum>
+ </property>
+ <property name="uniformItemSizes" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="layoutWidget" >
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QGroupBox" name="groupBox" >
+ <property name="title" >
+ <string>Properties</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label_4" >
+ <property name="text" >
+ <string>Name:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QLineEdit" name="sysexName" />
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_5" >
+ <property name="text" >
+ <string>Comment:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QTextEdit" name="sysexComment" />
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="textLabel1_2" >
+ <property name="text" >
+ <string>Data:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" >
+ <widget class="QTextEdit" name="sysexData" />
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="deleteSysex" >
+ <property name="text" >
+ <string>Delete</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="newSysex" >
+ <property name="text" >
+ <string>New Sysex</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QMenuBar" name="MenuBar" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>821</width>
+ <height>32</height>
+ </rect>
+ </property>
+ <property name="defaultUp" >
+ <bool>false</bool>
+ </property>
+ <widget class="QMenu" name="fileMenu" >
+ <property name="geometry" >
+ <rect>
+ <x>434</x>
+ <y>167</y>
+ <width>146</width>
+ <height>168</height>
+ </rect>
+ </property>
+ <property name="title" >
+ <string>&amp;File</string>
+ </property>
+ <addaction name="fileNewAction" />
+ <addaction name="fileSaveAction" />
+ <addaction name="fileSaveAsAction" />
+ <addaction name="separator" />
+ <addaction name="fileExitAction" />
+ </widget>
+ <addaction name="fileMenu" />
+ </widget>
+ <widget class="QToolBar" name="toolBar" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <attribute name="toolBarArea" >
+ <number>4</number>
+ </attribute>
+ <addaction name="fileExitAction" />
+ <addaction name="fileNewAction" />
+ <addaction name="fileSaveAction" />
+ </widget>
+ <action name="fileNewAction" >
+ <property name="icon" >
+ <iconset resource="../muse.qrc" >:/xpm/filenew.png</iconset>
+ </property>
+ <property name="text" >
+ <string>&amp;New</string>
+ </property>
+ <property name="iconText" >
+ <string>New</string>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+N</string>
+ </property>
+ </action>
+ <action name="fileOpenAction" >
+ <property name="icon" >
+ <iconset resource="../muse.qrc" >:/xpm/fileopen.png</iconset>
+ </property>
+ <property name="text" >
+ <string>&amp;Open...</string>
+ </property>
+ <property name="iconText" >
+ <string>Open</string>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+O</string>
+ </property>
+ </action>
+ <action name="fileSaveAction" >
+ <property name="icon" >
+ <iconset resource="../muse.qrc" >:/xpm/filesave.png</iconset>
+ </property>
+ <property name="text" >
+ <string>&amp;Save</string>
+ </property>
+ <property name="iconText" >
+ <string>Save</string>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+S</string>
+ </property>
+ </action>
+ <action name="fileSaveAsAction" >
+ <property name="icon" >
+ <iconset resource="../muse.qrc" >:/xpm/fileopen.png</iconset>
+ </property>
+ <property name="text" >
+ <string>Save &amp;As...</string>
+ </property>
+ <property name="iconText" >
+ <string>Save As</string>
+ </property>
+ <property name="shortcut" >
+ <string/>
+ </property>
+ </action>
+ <action name="fileExitAction" >
+ <property name="icon" >
+ <iconset resource="../muse.qrc" >:/xpm/off.svg</iconset>
+ </property>
+ <property name="text" >
+ <string>E&amp;xit</string>
+ </property>
+ <property name="iconText" >
+ <string>Exit</string>
+ </property>
+ <property name="shortcut" >
+ <string/>
+ </property>
+ </action>
+ </widget>
+ <layoutdefault spacing="6" margin="11" />
+ <resources>
+ <include location="../muse.qrc" />
+ </resources>
+ <connections/>
+</ui>
diff --git a/muse_qt4_evolution/muse/instruments/midictrledit.cpp b/muse_qt4_evolution/muse/instruments/midictrledit.cpp
new file mode 100644
index 00000000..b2f33e30
--- /dev/null
+++ b/muse_qt4_evolution/muse/instruments/midictrledit.cpp
@@ -0,0 +1,418 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "app.h"
+#include "driver/mididev.h"
+#include "midictrl.h"
+#include "midictrledit.h"
+#include "xml.h"
+#include "filedialog.h"
+#include "globals.h"
+
+MidiControllerEditDialog* midiControllerEditDialog;
+
+static MidiController predefinedMidiController[] = {
+ MidiController("Pitch", 0x40000, -10000, +10000),
+ MidiController("Program", 0x40001, 0, 127),
+ MidiController("BankSel", 0x10000, 0, 16383)
+ };
+
+enum {
+ COL_NAME = 0, COL_TYPE,
+ COL_HNUM, COL_LNUM, COL_MIN, COL_MAX
+ };
+
+//---------------------------------------------------------
+// addControllerToView
+//---------------------------------------------------------
+
+void MidiControllerEditDialog::addControllerToView(MidiController* mctrl)
+ {
+ QString hnum;
+ hnum.setNum(mctrl->num());
+ QString lnum("---");
+ QString min;
+ min.setNum(mctrl->minVal());
+ QString max;
+ max.setNum(mctrl->maxVal());
+ new Q3ListViewItem(viewController,
+ mctrl->name(),
+ int2ctrlType(mctrl->type()),
+ hnum, lnum, min, max
+ );
+ }
+
+//---------------------------------------------------------
+// MidiControllerEditDialog
+//---------------------------------------------------------
+
+MidiControllerEditDialog::MidiControllerEditDialog(QWidget* parent, const char* name, bool modal, Qt::WFlags fl)
+ : MidiControllerEditDialogBase(parent, name, modal, fl)
+ {
+ viewController->setColumnAlignment(COL_HNUM, AlignCenter);
+ viewController->setColumnAlignment(COL_LNUM, AlignCenter);
+ viewController->setColumnAlignment(COL_MIN, AlignCenter);
+ viewController->setColumnAlignment(COL_MAX, AlignCenter);
+ viewController->setColumnWidthMode(COL_NAME, Q3ListView::Maximum);
+
+ // populate list of predefined controller
+ int size = sizeof(predefinedMidiController) / sizeof(*predefinedMidiController);
+ for (int i = 0; i < size; ++i)
+ listController->insertItem(predefinedMidiController[i].name());
+ listController->setSelected(0, true);
+
+ // populate ports pulldown
+ 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);
+ }
+
+ reject(); // populate list
+ viewController->setCurrentItem(viewController->firstChild());
+
+ 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()));
+
+ controllerChanged(viewController->currentItem());
+ }
+
+//---------------------------------------------------------
+// reject
+//---------------------------------------------------------
+
+void MidiControllerEditDialog::reject()
+ {
+ viewController->clear();
+ for (iMidiController i = midiControllerList.begin();
+ i != midiControllerList.end(); ++i) {
+ addControllerToView(&*i);
+ }
+ MidiControllerEditDialogBase::reject();
+ }
+
+//---------------------------------------------------------
+// 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 = c->type();
+ QString type = int2ctrlType(t);
+ QString min, max;
+ min.setNum(c->minVal());
+ max.setNum(c->maxVal());
+
+ QString hno, lno;
+ int h = (c->num() >> 14) & 0x7f;
+ int l = c->num() & 0x7f;
+
+ switch(t) {
+ case MidiController::Controller7:
+ hno = "---";
+ lno.setNum(l);
+ break;
+ case MidiController::RPN:
+ case MidiController::NRPN:
+ case MidiController::Controller14:
+ hno.setNum(h);
+ lno.setNum(l);
+ break;
+ case MidiController::Pitch:
+ case MidiController::Program:
+ hno = "---";
+ lno = "---";
+ default:
+ break;
+ }
+
+ Q3ListViewItem* item = new Q3ListViewItem(viewController,
+ name, type, hno, lno, min, max);
+
+ viewController->setCurrentItem(item);
+ controllerChanged(item);
+ break;
+ }
+ }
+
+//---------------------------------------------------------
+// ctrlDelete
+//---------------------------------------------------------
+
+void MidiControllerEditDialog::ctrlDelete()
+ {
+ Q3ListViewItem* item = viewController->currentItem();
+ if (item == 0)
+ return;
+ delete item;
+ }
+
+//---------------------------------------------------------
+// accept
+//---------------------------------------------------------
+
+void MidiControllerEditDialog::accept()
+ {
+ midiControllerList.clear();
+
+ Q3ListViewItem* item = viewController->firstChild();
+ int hval = item->text(COL_HNUM).toInt();
+ int lval = item->text(COL_LNUM).toInt();
+
+ while (item) {
+ MidiController c;
+ c.setName(item->text(COL_NAME));
+ MidiController::ControllerType type = ctrlType2Int(item->text(COL_TYPE));
+
+ switch(type) {
+ case MidiController::Controller7:
+ c.setNum(hval);
+ break;
+ case MidiController::Controller14:
+ c.setNum((hval << 8 | lval) | 0x10000);
+ break;
+ case MidiController::RPN:
+ c.setNum((hval << 8 | lval) | 0x20000);
+ break;
+ case MidiController::NRPN:
+ c.setNum((hval << 8 | lval) | 0x30000);
+ break;
+ case MidiController::Pitch:
+ c.setNum(CTRL_PITCH);
+ break;
+ default:
+ break;
+ }
+ c.setMinVal(item->text(COL_MIN).toInt());
+ c.setMaxVal(item->text(COL_MAX).toInt());
+ midiControllerList.push_back(c);
+ item = item->nextSibling();
+ }
+ MidiControllerEditDialogBase::accept();
+ }
+
+//---------------------------------------------------------
+// nameChanged
+//---------------------------------------------------------
+
+void MidiControllerEditDialog::nameChanged(const QString& s)
+ {
+ Q3ListViewItem* item = viewController->currentItem();
+ if (item == 0)
+ return;
+ item->setText(COL_NAME, s);
+ }
+
+//---------------------------------------------------------
+// typeChanged
+//---------------------------------------------------------
+
+void MidiControllerEditDialog::typeChanged(const QString& s)
+ {
+ Q3ListViewItem* item = viewController->currentItem();
+ if (item == 0)
+ return;
+ item->setText(COL_TYPE, s);
+ item->setText(COL_MIN, QString("0"));
+ switch(ctrlType2Int(s)) {
+ case 2: // RPN
+ case 3: // NRPN
+ case MidiController::Controller14:
+ item->setText(COL_MAX, QString("16383"));
+ break;
+ case MidiController::Controller7:
+ case MidiController::Program:
+ item->setText(COL_MAX, QString("127"));
+ break;
+ case MidiController::Pitch:
+ item->setText(COL_MIN, QString("-5000"));
+ item->setText(COL_MAX, QString("+5000"));
+ break;
+ default:
+ break;
+ }
+ 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);
+ }
+
+//---------------------------------------------------------
+// valueLChanged
+//---------------------------------------------------------
+
+void MidiControllerEditDialog::valueLChanged(int val)
+ {
+ Q3ListViewItem* item = viewController->currentItem();
+ if (item == 0)
+ return;
+ QString s;
+ s.setNum(val);
+ item->setText(COL_LNUM, s);
+ }
+
+//---------------------------------------------------------
+// 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(item->text(COL_HNUM).toInt());
+ spinboxMin->setValue(item->text(COL_MIN).toInt());
+ spinboxMax->setValue(item->text(COL_MAX).toInt());
+ item->setText(COL_LNUM, QString("---"));
+ break;
+
+ case MidiController::Controller14:
+ 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->setValue(item->text(COL_MIN).toInt());
+ spinboxMax->setValue(item->text(COL_MAX).toInt());
+ break;
+
+ case MidiController::Pitch:
+ case MidiController::Program:
+ comboType->setEnabled(true);
+ spinboxHCtrlNo->setEnabled(false);
+ spinboxLCtrlNo->setEnabled(false);
+ spinboxMin->setEnabled(true);
+ spinboxMax->setEnabled(true);
+ 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);
+ }
+
+//---------------------------------------------------------
+// maxChanged
+//---------------------------------------------------------
+
+void MidiControllerEditDialog::maxChanged(int val)
+ {
+ Q3ListViewItem* item = viewController->currentItem();
+ if (item == 0)
+ return;
+ QString s;
+ s.setNum(val);
+ item->setText(COL_MAX, s);
+ }
+
+//---------------------------------------------------------
+// configMidiController
+//---------------------------------------------------------
+
+void configMidiController()
+ {
+ if (midiControllerEditDialog == 0)
+ midiControllerEditDialog = new MidiControllerEditDialog();
+ midiControllerEditDialog->show();
+ }
diff --git a/muse_qt4_evolution/muse/instruments/midictrledit.h b/muse_qt4_evolution/muse/instruments/midictrledit.h
new file mode 100644
index 00000000..321f14b7
--- /dev/null
+++ b/muse_qt4_evolution/muse/instruments/midictrledit.h
@@ -0,0 +1,58 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __MIDICTRLEDIT_H__
+#define __MIDICTRLEDIT_H__
+
+#include "ccontrolbase.h"
+#include "midictrl.h"
+
+//---------------------------------------------------------
+// MidiControllerEditDialog
+//---------------------------------------------------------
+
+class MidiControllerEditDialog : public MidiControllerEditDialogBase {
+ Q_OBJECT
+
+ void addControllerToView(MidiController* mctrl);
+ void mergeReplace(bool replace);
+
+ private slots:
+ void ctrlAdd();
+ void ctrlDelete();
+ virtual void accept();
+ virtual void reject();
+ 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);
+
+ 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/muse_qt4_evolution/muse/instruments/minstrument.cpp b/muse_qt4_evolution/muse/instruments/minstrument.cpp
new file mode 100644
index 00000000..a189c63d
--- /dev/null
+++ b/muse_qt4_evolution/muse/instruments/minstrument.cpp
@@ -0,0 +1,631 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "minstrument.h"
+#include "midioutport.h"
+#include "globals.h"
+#include "event.h"
+#include "midievent.h"
+#include "midictrl.h"
+#include "gconfig.h"
+#include "midiedit/drummap.h"
+
+MidiInstrumentList midiInstruments;
+MidiInstrument* genericMidiInstrument;
+
+//---------------------------------------------------------
+// string2sysex
+//---------------------------------------------------------
+
+int string2sysex(const QString& s, unsigned char** data)
+ {
+ const char* src = s.toLatin1().data();
+ char buffer[2048];
+ char* dst = buffer;
+
+ if(src) {
+ while (*src) {
+ while (*src == ' ' || *src == '\n') {
+ ++src;
+ }
+ char* ep;
+ long val = strtol(src, &ep, 16);
+ if (ep == src) {
+ QMessageBox::information(0,
+ QString("MusE"),
+ QWidget::tr("Cannot convert sysex string"));
+ return 0;
+ }
+ src = ep;
+ *dst++ = val;
+ if (dst - buffer >= 2048) {
+ QMessageBox::information(0,
+ QString("MusE"),
+ QWidget::tr("Hex String too long (2048 bytes limit)"));
+ return 0;
+ }
+ }
+ }
+ int len = dst - buffer;
+ unsigned char* b = new unsigned char[len+1];
+ memcpy(b, buffer, len);
+ b[len] = 0;
+ *data = b;
+ return len;
+ }
+
+//---------------------------------------------------------
+// sysex2string
+//---------------------------------------------------------
+
+QString sysex2string(int len, unsigned char* data)
+ {
+ QString d;
+ QString s;
+ for (int i = 0; i < len; ++i) {
+ if ((i > 0) && ((i % 8)==0)) {
+ d += "\n";
+ }
+ else if (i)
+ d += " ";
+ d += s.sprintf("%02x", data[i]);
+ }
+ return d;
+ }
+
+//---------------------------------------------------------
+// Patch
+//---------------------------------------------------------
+
+Patch::Patch()
+ {
+ drumMap = 0;
+ categorie = -1;
+ }
+
+Patch::~Patch()
+ {
+ if (drumMap)
+ delete drumMap;
+ }
+
+//---------------------------------------------------------
+// loadIDF
+//---------------------------------------------------------
+
+static void loadIDF(QFileInfo* fi)
+ {
+ QFile qf(fi->filePath());
+ if (!qf.open(QIODevice::ReadOnly)) {
+ printf("cannot open file %s\n", fi->fileName().toLatin1().data());
+ return;
+ }
+ if (debugMsg)
+ printf(" load instrument definition <%s>\n", fi->filePath().toLocal8Bit().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().toLatin1().data(), error.toLatin1().data());
+ 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().toLatin1().data());
+ node = node.nextSibling();
+ }
+ qf.close();
+ }
+
+//---------------------------------------------------------
+// initMidiInstruments
+//---------------------------------------------------------
+
+void initMidiInstruments()
+ {
+ genericMidiInstrument = new MidiInstrument(QWidget::tr("generic midi"));
+
+ midiInstruments.push_back(genericMidiInstrument);
+ QString museGlobalInstruments(museGlobalShare
+ + QString("/instruments"));
+ if (debugMsg)
+ printf("load instrument definitions from <%s>\n", museGlobalInstruments.toLatin1().data());
+ QDir instrumentsDir(museGlobalInstruments, QString("*.idf"),
+ QDir::SortFlags(QDir::Name | QDir::IgnoreCase), QDir::Files);
+ if (instrumentsDir.exists()) {
+ QFileInfoList list = instrumentsDir.entryInfoList();
+ int n = list.size();
+ for (int i = 0; i < n; ++i) {
+ QFileInfo fi = list.at(i);
+ loadIDF(&fi);
+ }
+ }
+ QString path2 = QDir::homePath() + "/" + config.instrumentPath;
+ if (debugMsg)
+ printf("load instrument definitions from <%s>\n", path2.toLatin1().data());
+ QDir instrumentsDir2(path2, QString("*.idf"),
+ QDir::SortFlags(QDir::Name | QDir::IgnoreCase), QDir::Files);
+ if (instrumentsDir2.exists()) {
+ QFileInfoList list = instrumentsDir2.entryInfoList();
+ int n = list.size();
+ for (int i = 0; i < n; ++i) {
+ QFileInfo fi = list.at(i);
+ loadIDF(&fi);
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// 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()
+ {
+ _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, 0x7fffff, 0);
+ _controller->push_back(prog);
+ _dirty = false;
+ _readonly = false;
+ }
+
+MidiInstrument::MidiInstrument()
+ {
+ init();
+ }
+
+//---------------------------------------------------------
+// MidiInstrument
+//---------------------------------------------------------
+
+MidiInstrument::MidiInstrument(const QString& txt)
+ {
+ _name = txt;
+ init();
+ }
+
+//---------------------------------------------------------
+// MidiInstrument
+//---------------------------------------------------------
+
+MidiInstrument::~MidiInstrument()
+ {
+ delete _midiInit;
+ delete _midiReset;
+ delete _midiState;
+ delete _controller;
+ if (_initScript)
+ delete _initScript;
+ }
+
+//---------------------------------------------------------
+// readPatchGroup
+//---------------------------------------------------------
+
+void PatchGroup::read(QDomNode node, MidiInstrument* instrument)
+ {
+ for (; !node.isNull(); node = node.nextSibling()) {
+ QDomElement e = node.toElement();
+ QString tag(e.tagName());
+
+ if (tag == "Patch") {
+ Patch* patch = new Patch;
+ patch->read(node, false, instrument);
+ patches.push_back(patch);
+ }
+ else if (tag == "drummap") {
+ Patch* patch = new Patch;
+ patch->read(node, true, instrument);
+ patches.push_back(patch);
+ }
+ else if (!tag.isEmpty())
+ printf("MusE:PatchGroup(): unknown tag %s in group %s\n",
+ e.tagName().toLatin1().data(), name.toLatin1().data());
+ }
+ }
+
+//---------------------------------------------------------
+// read
+//---------------------------------------------------------
+
+void Patch::read(QDomNode node, bool dr, MidiInstrument* instrument)
+ {
+ QDomElement e = node.toElement();
+ name = e.attribute("name");
+ typ = e.attribute("mode", "-1").toInt();
+ hbank = e.attribute("hbank", "-1").toInt();
+ lbank = e.attribute("lbank", "-1").toInt();
+ prog = e.attribute("prog", "0").toInt();
+ QString cat = e.attribute("cat");
+ categorie = instrument->categories().indexOf(cat);
+ drumMap = 0;
+ if (!dr)
+ return;
+ drumMap = new DrumMap(name);
+ int idx = 0;
+ for (node = node.firstChild(); !node.isNull(); node = node.nextSibling()) {
+ e = node.toElement();
+ QString tag(e.tagName());
+ if (tag == "entry") {
+ DrumMapEntry* de = drumMap->entry(idx);
+ de->read(node);
+ ++idx;
+ }
+ else if (!tag.isEmpty()) {
+ printf("Patch: read drummap: unknown tag %s\n", tag.toLatin1().data());
+ }
+ }
+ drumMap->init();
+ }
+
+//---------------------------------------------------------
+// write
+//---------------------------------------------------------
+
+void Patch::write(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);
+ 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(QDomNode node)
+ {
+ _midiState->read(node, true);
+ }
+
+//---------------------------------------------------------
+// read
+//---------------------------------------------------------
+
+void MidiInstrument::read(QDomNode node)
+ {
+ QDomElement e = node.toElement();
+ _name = e.attribute("name");
+
+ for (node = node.firstChild(); !node.isNull(); node = node.nextSibling()) {
+ e = node.toElement();
+ QString tag(e.tagName());
+ if (tag == "Patch") {
+ Patch* patch = new Patch;
+ patch->read(node, false, this);
+ if (pg.empty()) {
+ PatchGroup p;
+ p.patches.push_back(patch);
+ pg.push_back(p);
+ }
+ else
+ pg[0].patches.push_back(patch);
+ }
+ else if (tag == "Category") {
+ QString name = e.attribute(QString("name"));
+ _categories.append(name);
+ }
+ else if (tag == "drummap") {
+ Patch* patch = new Patch;
+ patch->read(node, true, this);
+ if (pg.empty()) {
+ PatchGroup p;
+ p.patches.push_back(patch);
+ pg.push_back(p);
+ }
+ else
+ pg[0].patches.push_back(patch);
+ }
+ else if (tag == "PatchGroup") {
+ PatchGroup p;
+ p.name = e.attribute("name");
+ p.read(node.firstChild(), this);
+ pg.push_back(p);
+ }
+ else if (tag == "Controller") {
+ MidiController* mc = new MidiController();
+ mc->read(node);
+ //
+ // HACK: make predefined "Program" controller overloadable
+ //
+ if (mc->name() == "Program") {
+ for (iMidiController i = _controller->begin(); i != _controller->end(); ++i) {
+ if ((*i)->name() == mc->name()) {
+ _controller->erase(i);
+ break;
+ }
+ }
+ }
+ _controller->push_back(mc);
+ }
+ else if (tag == "Init")
+ _midiInit->read(node.firstChild(), true);
+ else if (tag == "SysEx") {
+ SysEx* se = new SysEx;
+ se->name = e.attribute("name");
+ for (QDomNode nnode = node.firstChild(); !nnode.isNull(); nnode = nnode.nextSibling()) {
+ e = nnode.toElement();
+ QString tag(e.tagName());
+ if (tag == "comment")
+ se->comment = e.text();
+ else if (tag == "data") {
+ se->dataLen = string2sysex(e.text(), &(se->data));
+ }
+ else
+ printf("MidiInstrument::read():SysEx: unknown tag %s\n", tag.toLatin1().data());
+ }
+ _sysex.append(se);
+ }
+ else if (!tag.isEmpty()) {
+ printf("MidiInstrument::read(): unknown tag %s\n", tag.toLatin1().data());
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// getPatchName
+//---------------------------------------------------------
+
+QString MidiInstrument::getPatchName(int /*channel*/, int prog)
+ {
+ int hbank = (prog >> 16) & 0xff;
+ int lbank = (prog >> 8) & 0xff;
+ prog &= 0xff;
+ if (prog == 0xff)
+ return "---";
+
+ int tmask = 1;
+ bool hb = hbank == 0xff;
+ bool lb = lbank == 0xff;
+
+ for (std::vector<PatchGroup>::iterator i = pg.begin(); i != pg.end(); ++i) {
+ PatchList& pl = i->patches;
+ for (PatchList::const_iterator ipl = pl.begin(); ipl != pl.end(); ++ipl) {
+ const Patch* mp = *ipl;
+ if ((mp->typ & tmask)
+ && (prog == mp->prog)
+ && (hbank == mp->hbank || hb || mp->hbank == -1)
+ && (lbank == mp->lbank || lb || mp->lbank == -1))
+ return mp->name;
+ }
+ }
+ return QString("---");
+ }
+
+//---------------------------------------------------------
+// getDrumMap
+//---------------------------------------------------------
+
+DrumMap* MidiInstrument::getDrumMap(int prog)
+ {
+ int hbank = (prog >> 16) & 0xff;
+ int lbank = (prog >> 8) & 0xff;
+ prog &= 0xff;
+ if (prog == 0xff)
+ return 0;
+
+ int tmask = 1;
+ bool hb = hbank == 0xff;
+ bool lb = lbank == 0xff;
+
+ for (std::vector<PatchGroup>::iterator i = pg.begin(); i != pg.end(); ++i) {
+ PatchList& pl = i->patches;
+ for (PatchList::const_iterator ipl = pl.begin(); ipl != pl.end(); ++ipl) {
+ const Patch* mp = *ipl;
+ if ((mp->typ & tmask)
+ && (prog == mp->prog)
+ && (hbank == mp->hbank || hb || mp->hbank == -1)
+ && (lbank == mp->lbank || lb || mp->lbank == -1)) {
+ return mp->drumMap;
+ }
+ }
+ }
+ return 0;
+ }
+
+//---------------------------------------------------------
+// populatePatchPopup
+//---------------------------------------------------------
+
+void MidiInstrument::populatePatchPopup(QMenu* menu, int)
+ {
+ menu->clear();
+ int mask = 7;
+
+ if (pg.size() > 1) {
+ for (std::vector<PatchGroup>::iterator i = pg.begin(); i != pg.end(); ++i) {
+ QMenu* pm = menu->addMenu(i->name);
+// pm->setFont(config.fonts[0]);
+ PatchList& pl = i->patches;
+ for (PatchList::const_iterator 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);
+ QAction* a = pm->addAction(mp->name);
+ a->setData(id);
+ }
+ }
+ }
+ }
+ else if (pg.size() == 1 ){
+ // no groups
+ PatchList& pl = pg.front().patches;
+ for (PatchList::const_iterator 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);
+ QAction* a = menu->addAction(mp->name);
+ a->setData(id);
+ }
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// getMidiController
+//---------------------------------------------------------
+
+MidiController* MidiInstrument::midiController(int num) const
+ {
+ for (iMidiController i = _controller->begin(); i != _controller->end(); ++i) {
+ int cn = (*i)->num();
+ if (cn == num)
+ return *i;
+ // wildcard?
+ if (((cn & 0xff) == 0xff) && ((cn & ~0xff) == (num & ~0xff)))
+ return *i;
+ }
+ for (iMidiController i = defaultMidiController.begin(); i != defaultMidiController.end(); ++i) {
+ int cn = (*i)->num();
+ if (cn == num)
+ return *i;
+ // wildcard?
+ if (((cn & 0xff) == 0xff) && ((cn & ~0xff) == (num & ~0xff)))
+ return *i;
+ }
+ QString name = midiCtrlName(num);
+ int min = 0;
+ int max = 127;
+ MidiController* c = new MidiController(name, num, min, max, 0);
+ defaultMidiController.push_back(c);
+ return c;
+ }
+
+//---------------------------------------------------------
+// write
+//---------------------------------------------------------
+
+void MidiInstrument::write(Xml& xml)
+ {
+ xml.header();
+ xml.stag("muse version=\"2.1\"");
+ xml.stag(QString("MidiInstrument name=\"%1\"").arg(Xml::xmlString(iname())));
+
+ foreach(const QString& s, _categories)
+ xml.tagE(QString("Category name=\"%1\"").arg(Xml::xmlString(s)));
+
+ std::vector<PatchGroup>* pg = groups();
+ for (std::vector<PatchGroup>::iterator g = pg->begin(); g != pg->end(); ++g) {
+ xml.stag(QString("PatchGroup name=\"%1\"").arg(Xml::xmlString(g->name)));
+ for (iPatch p = g->patches.begin(); p != g->patches.end(); ++p)
+ (*p)->write(xml);
+ xml.etag("PatchGroup");
+ }
+ for (iMidiController ic = _controller->begin(); ic != _controller->end(); ++ic)
+ (*ic)->write(xml);
+ xml.etag("MidiInstrument");
+ xml.etag("muse");
+ }
+
diff --git a/muse_qt4_evolution/muse/instruments/minstrument.h b/muse_qt4_evolution/muse/instruments/minstrument.h
new file mode 100644
index 00000000..5bcf2616
--- /dev/null
+++ b/muse_qt4_evolution/muse/instruments/minstrument.h
@@ -0,0 +1,160 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __MINSTRUMENT_H__
+#define __MINSTRUMENT_H__
+
+#include "globaldefs.h"
+
+namespace AL {
+ class Xml;
+ };
+using AL::Xml;
+
+class MidiOutPort;
+class EventList;
+class MidiControllerList;
+class MidiController;
+class MidiEvent;
+class DrumMap;
+class MidiInstrument;
+
+//---------------------------------------------------------
+// Patch
+//---------------------------------------------------------
+
+struct Patch {
+ signed char typ; // 1 - GM 2 - GS 4 - XG
+ signed char hbank, lbank, prog;
+ QString name;
+ int categorie;
+ DrumMap* drumMap;
+
+ void read(QDomNode, bool, MidiInstrument*);
+ void write(Xml& xml);
+
+ Patch();
+ ~Patch();
+ };
+
+typedef std::list<Patch*> PatchList;
+typedef PatchList::iterator iPatch;
+typedef PatchList::const_iterator ciPatch;
+
+//---------------------------------------------------------
+// PatchGroup
+//---------------------------------------------------------
+
+struct PatchGroup {
+ QString name;
+ PatchList patches;
+ void read(QDomNode, MidiInstrument*);
+ };
+
+struct SysEx {
+ QString name;
+ QString comment;
+ int dataLen;
+ unsigned char* data;
+ };
+
+//---------------------------------------------------------
+// MidiInstrument
+//---------------------------------------------------------
+
+class MidiInstrument {
+ std::vector<PatchGroup> pg;
+ MidiControllerList* _controller;
+ QList<SysEx*> _sysex;
+ bool _dirty;
+ bool _readonly;
+
+ void init();
+
+ protected:
+ QList<QString> _categories;
+ 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; }
+ QString filePath() const { return _filePath; }
+ void setFilePath(const QString& s) { _filePath = s; }
+ bool dirty() const { return _dirty; }
+ void setDirty(bool v) { _dirty = v; }
+ bool readonly() const { return _readonly; }
+ void setReadonly(bool v) { _readonly = 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; }
+
+ void readMidiState(QDomNode);
+ virtual bool guiVisible() const { return false; }
+ virtual void showGui(bool) {}
+ virtual bool hasGui() const { return false; }
+ virtual void writeToGui(const MidiEvent&) {}
+
+ virtual QString getPatchName(int,int);
+ virtual DrumMap* getDrumMap(int);
+
+ virtual void populatePatchPopup(QMenu*, int);
+ void read(QDomNode);
+ void write(Xml& xml);
+ const QList<SysEx*>& sysex() const { return _sysex; }
+ void removeSysex(SysEx* sysex) { _sysex.removeAll(sysex); }
+ void addSysex(SysEx* sysex) { _sysex.append(sysex); }
+
+ MidiController* midiController(int num) const;
+
+ std::vector<PatchGroup>* groups() { return &pg; }
+ const QList<QString>& categories() const { return _categories; }
+ void addCategory(const QString& s) { _categories.append(s); }
+ };
+
+//---------------------------------------------------------
+// MidiInstrumentList
+//---------------------------------------------------------
+
+class MidiInstrumentList : public QList<MidiInstrument*> {
+ };
+
+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
+
diff --git a/muse_qt4_evolution/muse/jack.cpp b/muse_qt4_evolution/muse/jack.cpp
new file mode 100644
index 00000000..bc372357
--- /dev/null
+++ b/muse_qt4_evolution/muse/jack.cpp
@@ -0,0 +1,886 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "config.h"
+#include "al/al.h"
+#include "al/tempo.h"
+#include "audio.h"
+#include "globals.h"
+#include "song.h"
+#include "jackaudio.h"
+#include "track.h"
+#include "midiinport.h"
+
+#ifdef VST_SUPPORT
+#include <fst.h>
+#endif
+
+JackAudio* jackAudio;
+
+//---------------------------------------------------------
+// init
+//---------------------------------------------------------
+
+bool JackAudio::init()
+ {
+ return true;
+ }
+
+//---------------------------------------------------------
+// jack_thread_init
+//---------------------------------------------------------
+
+static void jack_thread_init (void* /*data*/)
+ {
+#ifdef VST_SUPPORT
+ if (loadVST)
+ fst_adopt_thread();
+#endif
+ }
+
+//---------------------------------------------------------
+// timebase_callback
+//---------------------------------------------------------
+
+static void timebase_callback(jack_transport_state_t /* state */,
+ jack_nframes_t /* nframes */,
+ jack_position_t* pos,
+ int /* new_pos */,
+ void*)
+ {
+ AL::Pos p(pos->frame, AL::FRAMES);
+ pos->valid = JackPositionBBT;
+ p.mbt(&pos->bar, &pos->beat, &pos->tick);
+ pos->bar++;
+ pos->beat++;
+ pos->bar_start_tick = Pos(pos->bar, 0, 0).tick();
+ //
+ // dummy:
+ //
+ pos->beats_per_bar = 4;
+ pos->beat_type = 4;
+ pos->ticks_per_beat = 384;
+ int tempo = AL::tempomap.tempo(p.tick());
+ pos->beats_per_minute = (60000000.0 / tempo) * AL::tempomap.globalTempo()/100.0;
+ }
+
+//---------------------------------------------------------
+// processAudio
+// JACK callback
+//---------------------------------------------------------
+
+int JackAudio::processAudio(jack_nframes_t frames, void*)
+ {
+ jackAudio->_frameCounter += frames;
+
+ int jackState = jackAudio->getTransportState();
+ segmentSize = frames;
+ if (audioState == AUDIO_RUNNING)
+ audio->process((unsigned long)frames, jackState);
+ else if (audioState == AUDIO_STOP) {
+ if (debugMsg)
+ puts("jack calling when audio is stopped!\n");
+ }
+ else if (audioState == AUDIO_START1)
+ audioState = AUDIO_START2;
+ return 0;
+ }
+
+//---------------------------------------------------------
+// getTransportState
+//---------------------------------------------------------
+
+int JackAudio::getTransportState()
+ {
+ int jackState;
+ transportState = jack_transport_query(_client, &pos);
+ switch (jackAudio->transportState) {
+ case JackTransportStopped:
+ jackState = Audio::STOP;
+ break;
+ case JackTransportLooping:
+ case JackTransportRolling:
+ jackState = Audio::PLAY;
+ break;
+ case JackTransportStarting:
+ jackState = Audio::START_PLAY;
+ break;
+ default:
+ jackState = Audio::STOP;
+ break;
+ }
+ return jackState;
+ }
+
+//---------------------------------------------------------
+// processSync
+// return TRUE (non-zero) when ready to roll.
+//---------------------------------------------------------
+
+static int processSync(jack_transport_state_t state, jack_position_t* pos, void*)
+ {
+ int audioState = Audio::STOP;
+ switch (state) {
+ case JackTransportStopped:
+ audioState = Audio::STOP;
+ break;
+ case JackTransportLooping:
+ case JackTransportRolling:
+ audioState = Audio::PLAY;
+ break;
+ case JackTransportStarting:
+ audioState = Audio::START_PLAY;
+ break;
+ }
+ unsigned frame = pos->frame;
+ return audio->sync(audioState, frame);
+ }
+
+//---------------------------------------------------------
+// processShutdown
+//---------------------------------------------------------
+
+static void processShutdown(void*)
+ {
+ audio->shutdown();
+
+ for (int i = 0; i < 10; ++i) {
+ if (audioState == AUDIO_STOP)
+ break;
+ sleep(1);
+ }
+ if (audioState == AUDIO_RUNNING)
+ fprintf(stderr, "MusE: sequencer still running, something is very wrong.\n");
+ jackAudio->zeroClientPtr(); // jack disconnect client no longer valid
+ }
+
+//---------------------------------------------------------
+// jackError
+//---------------------------------------------------------
+
+static void jackError(const char* s)
+ {
+ fprintf(stderr, "JACK ERROR: %s\n", s);
+ }
+
+//---------------------------------------------------------
+// noJackError
+//---------------------------------------------------------
+
+static void noJackError(const char* /* s */)
+ {
+ }
+
+//---------------------------------------------------------
+// JackAudio
+//---------------------------------------------------------
+
+JackAudio::JackAudio(jack_client_t* cl, char* name)
+ : AudioDriver()
+ {
+ strcpy(jackRegisteredName, name);
+ _client = cl;
+ _frameCounter = 0;
+ }
+
+//---------------------------------------------------------
+// ~JackAudio
+//---------------------------------------------------------
+
+JackAudio::~JackAudio()
+ {
+ if (_client) {
+ if (jack_client_close(_client)) {
+ fprintf(stderr, "jack_client_close() failed: %s\n",
+ strerror(errno));
+ }
+ }
+ _client = 0;
+ }
+
+//---------------------------------------------------------
+// getJackName()
+//---------------------------------------------------------
+
+char* JackAudio::getJackName()
+ {
+ return jackRegisteredName;
+ }
+
+//---------------------------------------------------------
+// restart
+//---------------------------------------------------------
+
+bool JackAudio::restart()
+ {
+ printf("JackAudio::restart\n");
+ _client = jack_client_new(jackRegisteredName);
+ if (!_client)
+ return true;
+ registerClient();
+ return false;
+ }
+
+//---------------------------------------------------------
+// bufsize_callback
+//---------------------------------------------------------
+
+static int bufsize_callback(jack_nframes_t n, void*)
+ {
+ printf("JACK: buffersize changed %d\n", n);
+ return 0;
+ }
+
+//---------------------------------------------------------
+// freewheel_callback
+//---------------------------------------------------------
+
+static void freewheel_callback(int starting, void*)
+ {
+ audio->setFreewheel(starting);
+ }
+
+//---------------------------------------------------------
+// srate_callback
+//---------------------------------------------------------
+
+static int srate_callback(jack_nframes_t n, void*)
+ {
+ if (debugMsg)
+ printf("JACK: sample rate changed: %d\n", n);
+ return 0;
+ }
+
+//---------------------------------------------------------
+// registration_callback
+//---------------------------------------------------------
+
+static void registration_callback(jack_port_id_t, int, void*)
+ {
+ if (debugMsg)
+ printf("JACK: registration changed\n");
+ }
+
+//---------------------------------------------------------
+// graph_callback
+// this is called from jack when the connections
+// changed
+//---------------------------------------------------------
+
+static int graph_callback(void*)
+ {
+ // we cannot call JackAudio::graphChanged() from this
+ // context, so we send a message to the gui thread which in turn
+ // calls graphChanged()
+
+ audio->sendMsgToGui(MSG_GRAPH_CHANGED);
+ if (debugMsg)
+ printf("JACK: graph changed!\n");
+ return 0;
+ }
+
+//---------------------------------------------------------
+// JackAudio::graphChanged
+// this is called from song in gui context triggered
+// by graph_callback()
+//---------------------------------------------------------
+
+void JackAudio::graphChanged()
+ {
+ RouteList rr, ra;
+
+ InputList* il = song->inputs();
+ for (iAudioInput ii = il->begin(); ii != il->end(); ++ii) {
+ AudioInput* it = *ii;
+ int channels = it->channels();
+ RouteList* irl = it->inRoutes();
+
+ for (int channel = 0; channel < channels; ++channel) {
+ jack_port_t* port = it->jackPort(channel).jackPort();
+ if (port == 0)
+ continue;
+ const char** ports = jack_port_get_all_connections(_client, port);
+
+ //---------------------------------------
+ // check for disconnects
+ //---------------------------------------
+
+ foreach (const Route& r, *irl) {
+ if (r.dst.channel != channel)
+ continue;
+ const char* name = jack_port_name(r.src.port.jackPort());
+ bool found = false;
+ for (const char** pn = ports; pn && *pn; ++pn) {
+ if (strcmp(*pn, name) == 0) {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ rr.append(r);
+ }
+
+ //---------------------------------------
+ // check for connects
+ //---------------------------------------
+
+ if (ports) {
+ for (const char** pn = ports; *pn; ++pn) {
+ bool found = false;
+ foreach(const Route& r, *irl) {
+ if (r.dst.channel != channel)
+ continue;
+ const char* name = jack_port_name(r.src.port.jackPort());
+ if (strcmp(*pn, name) == 0) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ Route a;
+ Port port(jack_port_by_name(_client, *pn));
+ a.src = RouteNode(port, -1, RouteNode::AUDIOPORT);
+ a.dst = RouteNode(it, channel);
+ ra.append(a);
+ }
+ }
+ free(ports);
+ }
+ }
+ }
+
+// printf(" input: remove %d add %d routes\n", rr.size(), ra.size());
+ foreach(Route r, rr)
+ audio->msgRemoveRoute1(r);
+ foreach(Route r, ra)
+ audio->msgAddRoute1(r);
+ rr.clear();
+ ra.clear();
+
+ OutputList* ol = song->outputs();
+ for (iAudioOutput ii = ol->begin(); ii != ol->end(); ++ii) {
+ AudioOutput* it = *ii;
+ int channels = it->channels();
+ for (int channel = 0; channel < channels; ++channel) {
+ jack_port_t* port = it->jackPort(channel).jackPort();
+ if (port == 0)
+ continue;
+ const char** ports = jack_port_get_all_connections(_client, port);
+ RouteList* rl = it->outRoutes();
+
+ //---------------------------------------
+ // check for disconnects
+ //---------------------------------------
+
+ foreach(const Route& r, *rl) {
+ if (r.src.channel != channel)
+ continue;
+ const char* name = jack_port_name(r.dst.port.jackPort());
+ bool found = false;
+ const char** pn = ports;
+ while (pn && *pn) {
+ if (strcmp(*pn, name) == 0) {
+ found = true;
+ break;
+ }
+ ++pn;
+ }
+ if (!found)
+ rr.append(r);
+ }
+
+ //---------------------------------------
+ // check for connects
+ //---------------------------------------
+
+ if (ports) {
+ const char** pn = ports;
+ while (*pn) {
+ bool found = false;
+ foreach (const Route& r, *rl) {
+ if (r.src.channel != channel)
+ continue;
+ const char* name = jack_port_name(r.dst.port.jackPort());
+ if (strcmp(*pn, name) == 0) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ Route a;
+ Port port(jack_port_by_name(_client, *pn));
+ a.src = RouteNode(it, channel, RouteNode::TRACK);
+ a.dst = RouteNode(port, -1, RouteNode::AUDIOPORT);
+ ra.append(a);
+ }
+ ++pn;
+ }
+ free(ports);
+ }
+ }
+ }
+// printf(" output: remove %d add %d routes\n", rr.size(), ra.size());
+ foreach(Route r, rr)
+ audio->msgRemoveRoute1(r);
+ foreach(Route r, ra)
+ audio->msgAddRoute1(r);
+ }
+
+//---------------------------------------------------------
+// register
+//---------------------------------------------------------
+
+void JackAudio::registerClient()
+ {
+ jack_set_process_callback(_client, processAudio, 0);
+ jack_set_sync_callback(_client, processSync, 0);
+ jack_on_shutdown(_client, processShutdown, 0);
+ jack_set_buffer_size_callback(_client, bufsize_callback, 0);
+ jack_set_sample_rate_callback(_client, srate_callback, 0);
+ jack_set_port_registration_callback(_client, registration_callback, 0);
+ jack_set_graph_order_callback(_client, graph_callback, 0);
+ jack_set_freewheel_callback (_client, freewheel_callback, 0);
+ jack_set_thread_init_callback(_client, (JackThreadInitCallback) jack_thread_init, 0);
+ jack_set_timebase_callback(_client, 0, timebase_callback, 0);
+ }
+
+//---------------------------------------------------------
+// registerInPort
+//---------------------------------------------------------
+
+Port JackAudio::registerInPort(const QString& name, bool midi)
+ {
+ const char* type = midi ? JACK_DEFAULT_MIDI_TYPE : JACK_DEFAULT_AUDIO_TYPE;
+ Port p(jack_port_register(_client, name.toLatin1().data(), type, JackPortIsInput, 0));
+// printf("JACK: registerInPort<%s>: <%s> %p\n", type, name.toLatin1().data(), p.jackPort());
+ if (!p.jackPort())
+ p.setZero();
+ return p;
+ }
+
+//---------------------------------------------------------
+// registerOutPort
+//---------------------------------------------------------
+
+Port JackAudio::registerOutPort(const QString& name, bool midi)
+ {
+ const char* type = midi ? JACK_DEFAULT_MIDI_TYPE : JACK_DEFAULT_AUDIO_TYPE;
+ Port p(jack_port_register(_client, name.toLatin1().data(), type, JackPortIsOutput, 0));
+// printf("JACK: registerOutPort<%s>: <%s> %p\n", type, name.toLatin1().data(), p.jackPort());
+ if (!p.jackPort())
+ p.setZero();
+ return p;
+ }
+
+//---------------------------------------------------------
+// exitJackAudio
+//---------------------------------------------------------
+
+void exitJackAudio()
+ {
+ if (jackAudio)
+ delete jackAudio;
+ }
+
+//---------------------------------------------------------
+// connect
+// return false on error
+//---------------------------------------------------------
+
+bool JackAudio::connect(Port src, Port dst)
+ {
+ if (src.isZero() || dst.isZero()) {
+ fprintf(stderr, "JackAudio::connect(1): unknown jack ports (%d-%d)\n",
+ src.isZero(), dst.isZero());
+ return false;
+ }
+ const char* sn = jack_port_name(src.jackPort());
+ const char* dn = jack_port_name(dst.jackPort());
+
+ if (debugMsg)
+ printf("jack connect <%s>%p - <%s>%p\n", sn, src.jackPort(), dn, dst.jackPort());
+
+ if (sn == 0 || dn == 0) {
+ fprintf(stderr, "JackAudio::connect(2): unknown jack ports\n");
+ return false;
+ }
+ int rv = jack_connect(_client, sn, dn);
+ if (rv) {
+ fprintf(stderr, "%d: jack connect <%s> - <%s> failed\n",
+ rv, sn, dn);
+ if (rv == EEXIST)
+ fprintf(stderr, " connection already made\n");
+ else {
+ int pf = jack_port_flags(src.jackPort());
+ if (!(pf & JackPortIsOutput))
+ fprintf(stderr, " src is not an output port\n");
+ pf = jack_port_flags(dst.jackPort());
+ if (!(pf & JackPortIsInput))
+ fprintf(stderr, " dst is not an input port\n");
+ }
+ return false;
+ }
+ return true;
+ }
+
+//---------------------------------------------------------
+// disconnect
+//---------------------------------------------------------
+
+bool JackAudio::disconnect(Port src, Port dst)
+ {
+ const char* sn = jack_port_name(src.jackPort());
+ const char* dn = jack_port_name(dst.jackPort());
+
+ if (debugMsg)
+ printf("jack disconnect <%s>%p - <%s>%p\n", sn, src.jackPort(), dn, dst.jackPort());
+
+ if (sn == 0 || dn == 0) {
+ fprintf(stderr, "JackAudio::disconnect: unknown jack ports\n");
+ return false;
+ }
+ if (jack_disconnect(_client, sn, dn)) {
+ fprintf(stderr, "jack disconnect <%s> - <%s> failed\n",
+ sn, dn);
+ return false;
+ }
+ return true;
+ }
+
+//---------------------------------------------------------
+// start
+//---------------------------------------------------------
+
+void JackAudio::start(int)
+ {
+ if (jack_activate(_client)) {
+ fprintf (stderr, "JACK: cannot activate client\n");
+ exit(-1);
+ }
+ }
+
+//---------------------------------------------------------
+// stop
+//---------------------------------------------------------
+
+void JackAudio::stop()
+ {
+ if (_client == 0)
+ return;
+ if (jack_deactivate(_client))
+ fprintf (stderr, "JACK: cannot deactivate client\n");
+ }
+
+//---------------------------------------------------------
+// outputPorts
+//---------------------------------------------------------
+
+QList<PortName> JackAudio::outputPorts(bool midi)
+ {
+ const char* type = midi ? JACK_DEFAULT_MIDI_TYPE : JACK_DEFAULT_AUDIO_TYPE;
+ const char** ports = jack_get_ports(_client, 0, type, JackPortIsOutput);
+ QList<PortName> clientList;
+ for (const char** p = ports; p && *p; ++p) {
+ jack_port_t* port = jack_port_by_name(_client, *p);
+ char buffer[128];
+ strncpy(buffer, *p, 128);
+ if (strncmp(buffer, "MusE", 4) == 0)
+ continue;
+ PortName pn;
+ pn.name = QString(buffer);
+ pn.port = Port(port);
+ clientList.append(pn);
+ }
+ return clientList;
+ }
+
+//---------------------------------------------------------
+// inputPorts
+//---------------------------------------------------------
+
+QList<PortName> JackAudio::inputPorts(bool midi)
+ {
+ const char* type = midi ? JACK_DEFAULT_MIDI_TYPE : JACK_DEFAULT_AUDIO_TYPE;
+ const char** ports = jack_get_ports(_client, 0, type, JackPortIsInput);
+ QList<PortName> clientList;
+ for (const char** p = ports; p && *p; ++p) {
+ jack_port_t* port = jack_port_by_name(_client, *p);
+ char buffer[128];
+ strncpy(buffer, *p, 128);
+ if (strncmp(buffer, "MusE", 4) == 0)
+ continue;
+ PortName pn;
+ pn.name = QString(buffer);
+ pn.port = Port(port);
+ clientList.append(pn);
+ }
+ return clientList;
+ }
+
+//---------------------------------------------------------
+// portName
+//---------------------------------------------------------
+
+QString JackAudio::portName(Port port)
+ {
+ const char* nameStrPtr = jack_port_name(port.jackPort());
+ QString s(nameStrPtr);
+ return s;
+ }
+
+//---------------------------------------------------------
+// unregisterPort
+//---------------------------------------------------------
+
+void JackAudio::unregisterPort(Port p)
+ {
+ if (_client) {
+// printf("JACK: unregister Port %p\n", p);
+ if (jack_port_unregister(_client, p.jackPort()))
+ fprintf(stderr, "jack unregister port %p failed\n", p.jackPort());
+ }
+ }
+
+//---------------------------------------------------------
+// setFreewheel
+//---------------------------------------------------------
+
+void JackAudio::setFreewheel(bool f)
+ {
+// printf("JACK: setFreewheel %d\n", f);
+ jack_set_freewheel(_client, f);
+ }
+
+//---------------------------------------------------------
+// startTransport
+//---------------------------------------------------------
+
+void JackAudio::startTransport()
+ {
+ jack_transport_start(_client);
+ }
+
+//---------------------------------------------------------
+// stopTransport
+//---------------------------------------------------------
+
+void JackAudio::stopTransport()
+ {
+ if (_client)
+ jack_transport_stop(_client);
+ }
+
+//---------------------------------------------------------
+// seekTransport
+//---------------------------------------------------------
+
+void JackAudio::seekTransport(unsigned frame)
+ {
+ jack_transport_locate(_client, frame);
+ }
+
+//---------------------------------------------------------
+// findPort
+//---------------------------------------------------------
+
+Port JackAudio::findPort(const QString& name)
+ {
+ if (_client == 0) {
+ printf("JackAudio(%p)::findPort(%s): _client==0\n", this, qPrintable(name));
+ return Port();
+ }
+ jack_port_t* port = jack_port_by_name(_client, name.toLatin1().data());
+ return (port == 0) ? Port() : Port(port);
+ }
+
+//---------------------------------------------------------
+// realtimePriority
+// return zero if not running realtime
+// can only be called if JACK client thread is already
+// running
+//---------------------------------------------------------
+
+int JackAudio::realtimePriority() const
+ {
+ pthread_t t = jack_client_thread_id(_client);
+ int policy;
+ struct sched_param param;
+ memset(&param, 0, sizeof(param));
+ int rv = pthread_getschedparam(t, &policy, &param);
+ if (rv) {
+ perror("MusE: get jack schedule parameter");
+ return 0;
+ }
+ if (policy != SCHED_FIFO) {
+ printf("JACK is not running realtime\n");
+ return 0;
+ }
+ return param.sched_priority;
+ }
+
+//---------------------------------------------------------
+// initJackAudio
+// return true if JACK not found
+//---------------------------------------------------------
+
+bool initJackAudio()
+ {
+ if (debugMsg) {
+ fprintf(stderr, "init Jack Audio\n");
+ jack_set_error_function(jackError);
+ }
+ else
+ jack_set_error_function(noJackError);
+
+ jack_client_t* client = 0;
+ jack_status_t status;
+ jack_options_t options = JackNullOption;
+ client = jack_client_open("MusE", options, &status);
+ if (!client) {
+ if (status & JackServerStarted)
+ printf("jack server started...\n");
+ if (status & JackServerFailed)
+ printf("cannot connect to jack server\n");
+ if (status & JackServerError)
+ printf("communication with jack server failed\n");
+ if (status & JackShmFailure)
+ printf("jack cannot access shared memory\n");
+ if (status & JackVersionError)
+ printf("jack server has wrong version\n");
+ printf("cannot create jack client\n");
+ return true;
+ }
+
+ if (debugMsg)
+ fprintf(stderr, "init Jack Audio: register device\n");
+
+ jack_set_error_function(jackError);
+ if (debugMsg)
+ fprintf(stderr, "init Jack Audio: register device\n");
+
+ jackAudio = new JackAudio(client, jack_get_client_name(client));
+ if (debugMsg)
+ fprintf(stderr, "init Jack Audio: register client\n");
+ jackAudio->registerClient();
+ AL::sampleRate = jack_get_sample_rate(client);
+ segmentSize = jack_get_buffer_size(client);
+ audioDriver = jackAudio;
+ return false;
+ }
+
+//---------------------------------------------------------
+// putEvent
+//---------------------------------------------------------
+
+void JackAudio::putEvent(Port port, const MidiEvent& e)
+ {
+ if (midiOutputTrace) {
+ printf("MidiOut<%s>: jackMidi: ", portName(port).toLatin1().data());
+ e.dump();
+ }
+ void* pb = jack_port_get_buffer(port.jackPort(), segmentSize);
+ int ft = e.time() - _frameCounter;
+ if (ft < 0)
+ ft = 0;
+ if (ft >= (int)segmentSize) {
+ printf("JackAudio::putEvent: time out of range %d(seg=%d)\n", ft, segmentSize);
+ if (ft > (int)segmentSize)
+ ft = segmentSize - 1;
+ }
+ switch(e.type()) {
+ case ME_NOTEON:
+ case ME_NOTEOFF:
+ case ME_POLYAFTER:
+ case ME_CONTROLLER:
+ case ME_PITCHBEND:
+ {
+ unsigned char* p = jack_midi_event_reserve(pb, ft, 3);
+ if (p == 0) {
+ fprintf(stderr, "JackMidi: buffer overflow, event lost\n");
+ return;
+ }
+ p[0] = e.type() | e.channel();
+ p[1] = e.dataA();
+ p[2] = e.dataB();
+ }
+ break;
+
+ case ME_PROGRAM:
+ case ME_AFTERTOUCH:
+ {
+ unsigned char* p = jack_midi_event_reserve(pb, ft, 2);
+ if (p == 0) {
+ fprintf(stderr, "JackMidi: buffer overflow, event lost\n");
+ return;
+ }
+ p[0] = e.type() | e.channel();
+ p[1] = e.dataA();
+ }
+ break;
+ case ME_SYSEX:
+ {
+ const unsigned char* data = e.data();
+ int len = e.len();
+ unsigned char* p = jack_midi_event_reserve(pb, ft, len+2);
+ if (p == 0) {
+ fprintf(stderr, "JackMidi: buffer overflow, event lost\n");
+ return;
+ }
+ p[0] = 0xf0;
+ p[len+1] = 0xf7;
+ memcpy(p+1, data, len);
+ }
+ break;
+ case ME_SONGPOS:
+ case ME_CLOCK:
+ case ME_START:
+ case ME_CONTINUE:
+ case ME_STOP:
+ printf("JackMidi: event type %x not supported\n", e.type());
+ break;
+ }
+ }
+
+//---------------------------------------------------------
+// startMidiCycle
+//---------------------------------------------------------
+
+void JackAudio::startMidiCycle(Port port)
+ {
+ void* port_buf = jack_port_get_buffer(port.jackPort(), segmentSize);
+ jack_midi_clear_buffer(port_buf);
+ }
+
+//---------------------------------------------------------
+// collectMidiEvents
+//---------------------------------------------------------
+
+void JackAudio::collectMidiEvents(MidiInPort* track, Port port)
+ {
+ void* port_buf = jack_port_get_buffer(port.jackPort(), segmentSize);
+ jack_midi_event_t event;
+ jack_nframes_t eventCount = jack_midi_get_event_count(port_buf);
+ for (jack_nframes_t i = 0; i < eventCount; ++i) {
+ jack_midi_event_get(&event, port_buf, i);
+ track->eventReceived(&event);
+ }
+ }
+
+
diff --git a/muse_qt4_evolution/muse/jackaudio.h b/muse_qt4_evolution/muse/jackaudio.h
new file mode 100644
index 00000000..1839d27e
--- /dev/null
+++ b/muse_qt4_evolution/muse/jackaudio.h
@@ -0,0 +1,90 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __JACKAUDIO_H__
+#define __JACKAUDIO_H__
+
+#include "audiodev.h"
+class MidiInPort;
+
+//---------------------------------------------------------
+// JackAudio
+//---------------------------------------------------------
+
+class JackAudio : public AudioDriver {
+ jack_client_t* _client;
+ jack_position_t pos;
+ char jackRegisteredName[8];
+ jack_transport_state_t transportState;
+ jack_nframes_t _frameCounter;
+
+ static int processAudio(jack_nframes_t frames, void*);
+
+ public:
+ JackAudio(jack_client_t* cl, char * jack_id_string);
+ virtual ~JackAudio();
+
+ int getTransportState();
+ virtual bool init();
+ virtual void start(int);
+ virtual bool restart();
+ virtual void stop ();
+ virtual void zeroClientPtr() { _client = 0; }
+ virtual float* getBuffer(Port port, unsigned long nframes) {
+ return (float*)jack_port_get_buffer(port.jackPort(), nframes);
+ }
+
+ virtual QList<PortName> outputPorts(bool midi);
+ virtual QList<PortName> inputPorts(bool midi);
+
+ virtual void registerClient();
+
+ virtual Port registerOutPort(const QString& name, bool midi);
+ virtual Port registerInPort(const QString& name, bool midi);
+
+ virtual char* getJackName();
+
+ virtual void unregisterPort(Port);
+ virtual bool connect(Port, Port);
+ virtual bool disconnect(Port, Port);
+ virtual void setPortName(Port p, const QString& n) {
+ jack_port_set_name(p.jackPort(), n.toLatin1().data());
+ }
+ virtual Port findPort(const QString& name);
+ virtual QString portName(Port);
+ virtual int realtimePriority() const;
+ virtual void startTransport();
+ virtual void stopTransport();
+ virtual void seekTransport(unsigned frame);
+ virtual void setFreewheel(bool f);
+
+ jack_transport_state_t transportQuery(jack_position_t* pos) {
+ return jack_transport_query(_client, pos);
+ }
+ void graphChanged();
+ virtual void putEvent(Port, const MidiEvent&);
+ virtual void startMidiCycle(Port);
+
+ virtual unsigned frameTime() const { return _frameCounter; }
+ virtual void collectMidiEvents(MidiInPort*, Port);
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/ladspa.h b/muse_qt4_evolution/muse/ladspa.h
new file mode 100644
index 00000000..7bbc338f
--- /dev/null
+++ b/muse_qt4_evolution/muse/ladspa.h
@@ -0,0 +1,599 @@
+/* ladspa.h
+
+ Linux Audio Developer's Simple Plugin API Version 1.1[provisional,
+ LGPL]. Copyright (C) 2000-2002 Richard W.E. Furse, Paul
+ Barton-Davis, Stefan Westerfeld.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License
+ as published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA. */
+
+#ifndef LADSPA_INCLUDED
+#define LADSPA_INCLUDED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*****************************************************************************/
+
+/* Overview:
+
+ There is a large number of synthesis packages in use or development
+ on the Linux platform at this time. This API (`The Linux Audio
+ Developer's Simple Plugin API') attempts to give programmers the
+ ability to write simple `plugin' audio processors in C/C++ and link
+ them dynamically (`plug') into a range of these packages (`hosts').
+ It should be possible for any host and any plugin to communicate
+ completely through this interface.
+
+ This API is deliberately short and simple. To achieve compatibility
+ with a range of promising Linux sound synthesis packages it
+ attempts to find the `greatest common divisor' in their logical
+ behaviour. Having said this, certain limiting decisions are
+ implicit, notably the use of a fixed type (LADSPA_Data) for all
+ data transfer and absence of a parameterised `initialisation'
+ phase. See below for the LADSPA_Data typedef.
+
+ Plugins are expected to distinguish between control and audio
+ data. Plugins have `ports' that are inputs or outputs for audio or
+ control data and each plugin is `run' for a `block' corresponding
+ to a short time interval measured in samples. Audio data is
+ communicated using arrays of LADSPA_Data, allowing a block of audio
+ to be processed by the plugin in a single pass. Control data is
+ communicated using single LADSPA_Data values. Control data has a
+ single value at the start of a call to the `run()' or `run_adding()'
+ function, and may be considered to remain this value for its
+ duration. The plugin may assume that all its input and output ports
+ have been connected to the relevant data location (see the
+ `connect_port()' function below) before it is asked to run.
+
+ Plugins will reside in shared object files suitable for dynamic
+ linking by dlopen() and family. The file will provide a number of
+ `plugin types' that can be used to instantiate actual plugins
+ (sometimes known as `plugin instances') that can be connected
+ together to perform tasks.
+
+ This API contains very limited error-handling. */
+
+/*****************************************************************************/
+
+/* Fundamental data type passed in and out of plugin. This data type
+ is used to communicate audio samples and control values. It is
+ assumed that the plugin will work sensibly given any numeric input
+ value although it may have a preferred range (see hints below).
+
+ For audio it is generally assumed that 1.0f is the `0dB' reference
+ amplitude and is a `normal' signal level. */
+
+typedef float LADSPA_Data;
+
+/*****************************************************************************/
+
+/* Special Plugin Properties:
+
+ Optional features of the plugin type are encapsulated in the
+ LADSPA_Properties type. This is assembled by ORing individual
+ properties together. */
+
+typedef int LADSPA_Properties;
+
+/* Property LADSPA_PROPERTY_REALTIME indicates that the plugin has a
+ real-time dependency (e.g. listens to a MIDI device) and so its
+ output must not be cached or subject to significant latency. */
+#define LADSPA_PROPERTY_REALTIME 0x1
+
+/* Property LADSPA_PROPERTY_INPLACE_BROKEN indicates that the plugin
+ may cease to work correctly if the host elects to use the same data
+ location for both input and output (see connect_port()). This
+ should be avoided as enabling this flag makes it impossible for
+ hosts to use the plugin to process audio `in-place.' */
+#define LADSPA_PROPERTY_INPLACE_BROKEN 0x2
+
+/* Property LADSPA_PROPERTY_HARD_RT_CAPABLE indicates that the plugin
+ is capable of running not only in a conventional host but also in a
+ `hard real-time' environment. To qualify for this the plugin must
+ satisfy all of the following:
+
+ (1) The plugin must not use malloc(), free() or other heap memory
+ management within its run() or run_adding() functions. All new
+ memory used in run() must be managed via the stack. These
+ restrictions only apply to the run() function.
+
+ (2) The plugin will not attempt to make use of any library
+ functions with the exceptions of functions in the ANSI standard C
+ and C maths libraries, which the host is expected to provide.
+
+ (3) The plugin will not access files, devices, pipes, sockets, IPC
+ or any other mechanism that might result in process or thread
+ blocking.
+
+ (4) The plugin will take an amount of time to execute a run() or
+ run_adding() call approximately of form (A+B*SampleCount) where A
+ and B depend on the machine and host in use. This amount of time
+ may not depend on input signals or plugin state. The host is left
+ the responsibility to perform timings to estimate upper bounds for
+ A and B. */
+#define LADSPA_PROPERTY_HARD_RT_CAPABLE 0x4
+
+#define LADSPA_IS_REALTIME(x) ((x) & LADSPA_PROPERTY_REALTIME)
+#define LADSPA_IS_INPLACE_BROKEN(x) ((x) & LADSPA_PROPERTY_INPLACE_BROKEN)
+#define LADSPA_IS_HARD_RT_CAPABLE(x) ((x) & LADSPA_PROPERTY_HARD_RT_CAPABLE)
+
+/*****************************************************************************/
+
+/* Plugin Ports:
+
+ Plugins have `ports' that are inputs or outputs for audio or
+ data. Ports can communicate arrays of LADSPA_Data (for audio
+ inputs/outputs) or single LADSPA_Data values (for control
+ input/outputs). This information is encapsulated in the
+ LADSPA_PortDescriptor type which is assembled by ORing individual
+ properties together.
+
+ Note that a port must be an input or an output port but not both
+ and that a port must be a control or audio port but not both. */
+
+typedef int LADSPA_PortDescriptor;
+
+/* Property LADSPA_PORT_INPUT indicates that the port is an input. */
+#define LADSPA_PORT_INPUT 0x1
+
+/* Property LADSPA_PORT_OUTPUT indicates that the port is an output. */
+#define LADSPA_PORT_OUTPUT 0x2
+
+/* Property LADSPA_PORT_CONTROL indicates that the port is a control
+ port. */
+#define LADSPA_PORT_CONTROL 0x4
+
+/* Property LADSPA_PORT_AUDIO indicates that the port is a audio
+ port. */
+#define LADSPA_PORT_AUDIO 0x8
+
+#define LADSPA_IS_PORT_INPUT(x) ((x) & LADSPA_PORT_INPUT)
+#define LADSPA_IS_PORT_OUTPUT(x) ((x) & LADSPA_PORT_OUTPUT)
+#define LADSPA_IS_PORT_CONTROL(x) ((x) & LADSPA_PORT_CONTROL)
+#define LADSPA_IS_PORT_AUDIO(x) ((x) & LADSPA_PORT_AUDIO)
+
+/*****************************************************************************/
+
+/* Plugin Port Range Hints:
+
+ The host may wish to provide a representation of data entering or
+ leaving a plugin (e.g. to generate a GUI automatically). To make
+ this more meaningful, the plugin should provide `hints' to the host
+ describing the usual values taken by the data.
+
+ Note that these are only hints. The host may ignore them and the
+ plugin must not assume that data supplied to it is meaningful. If
+ the plugin receives invalid input data it is expected to continue
+ to run without failure and, where possible, produce a sensible
+ output (e.g. a high-pass filter given a negative cutoff frequency
+ might switch to an all-pass mode).
+
+ Hints are meaningful for all input and output ports but hints for
+ input control ports are expected to be particularly useful.
+
+ More hint information is encapsulated in the
+ LADSPA_PortRangeHintDescriptor type which is assembled by ORing
+ individual hint types together. Hints may require further
+ LowerBound and UpperBound information.
+
+ All the hint information for a particular port is aggregated in the
+ LADSPA_PortRangeHint structure. */
+
+typedef int LADSPA_PortRangeHintDescriptor;
+
+/* Hint LADSPA_HINT_BOUNDED_BELOW indicates that the LowerBound field
+ of the LADSPA_PortRangeHint should be considered meaningful. The
+ value in this field should be considered the (inclusive) lower
+ bound of the valid range. If LADSPA_HINT_SAMPLE_RATE is also
+ specified then the value of LowerBound should be multiplied by the
+ sample rate. */
+#define LADSPA_HINT_BOUNDED_BELOW 0x1
+
+/* Hint LADSPA_HINT_BOUNDED_ABOVE indicates that the UpperBound field
+ of the LADSPA_PortRangeHint should be considered meaningful. The
+ value in this field should be considered the (inclusive) upper
+ bound of the valid range. If LADSPA_HINT_SAMPLE_RATE is also
+ specified then the value of UpperBound should be multiplied by the
+ sample rate. */
+#define LADSPA_HINT_BOUNDED_ABOVE 0x2
+
+/* Hint LADSPA_HINT_TOGGLED indicates that the data item should be
+ considered a Boolean toggle. Data less than or equal to zero should
+ be considered `off' or `false,' and data above zero should be
+ considered `on' or `true.' LADSPA_HINT_TOGGLED may not be used in
+ conjunction with any other hint except LADSPA_HINT_DEFAULT_0 or
+ LADSPA_HINT_DEFAULT_1. */
+#define LADSPA_HINT_TOGGLED 0x4
+
+/* Hint LADSPA_HINT_SAMPLE_RATE indicates that any bounds specified
+ should be interpreted as multiples of the sample rate. For
+ instance, a frequency range from 0Hz to the Nyquist frequency (half
+ the sample rate) could be requested by this hint in conjunction
+ with LowerBound = 0 and UpperBound = 0.5. Hosts that support bounds
+ at all must support this hint to retain meaning. */
+#define LADSPA_HINT_SAMPLE_RATE 0x8
+
+/* Hint LADSPA_HINT_LOGARITHMIC indicates that it is likely that the
+ user will find it more intuitive to view values using a logarithmic
+ scale. This is particularly useful for frequencies and gains. */
+#define LADSPA_HINT_LOGARITHMIC 0x10
+
+/* Hint LADSPA_HINT_INTEGER indicates that a user interface would
+ probably wish to provide a stepped control taking only integer
+ values. Any bounds set should be slightly wider than the actual
+ integer range required to avoid floating point rounding errors. For
+ instance, the integer set {0,1,2,3} might be described as [-0.1,
+ 3.1]. */
+#define LADSPA_HINT_INTEGER 0x20
+
+/* The various LADSPA_HINT_HAS_DEFAULT_* hints indicate a `normal'
+ value for the port that is sensible as a default. For instance,
+ this value is suitable for use as an initial value in a user
+ interface or as a value the host might assign to a control port
+ when the user has not provided one. Defaults are encoded using a
+ mask so only one default may be specified for a port. Some of the
+ hints make use of lower and upper bounds, in which case the
+ relevant bound or bounds must be available and
+ LADSPA_HINT_SAMPLE_RATE must be applied as usual. The resulting
+ default must be rounded if LADSPA_HINT_INTEGER is present. Default
+ values were introduced in LADSPA v1.1. */
+#define LADSPA_HINT_DEFAULT_MASK 0x3C0
+
+/* This default values indicates that no default is provided. */
+#define LADSPA_HINT_DEFAULT_NONE 0x0
+
+/* This default hint indicates that the suggested lower bound for the
+ port should be used. */
+#define LADSPA_HINT_DEFAULT_MINIMUM 0x40
+
+/* This default hint indicates that a low value between the suggested
+ lower and upper bounds should be chosen. For ports with
+ LADSPA_HINT_LOGARITHMIC, this should be exp(log(lower) * 0.75 +
+ log(upper) * 0.25). Otherwise, this should be (lower * 0.75 + upper
+ * 0.25). */
+#define LADSPA_HINT_DEFAULT_LOW 0x80
+
+/* This default hint indicates that a middle value between the
+ suggested lower and upper bounds should be chosen. For ports with
+ LADSPA_HINT_LOGARITHMIC, this should be exp(log(lower) * 0.5 +
+ log(upper) * 0.5). Otherwise, this should be (lower * 0.5 + upper *
+ 0.5). */
+#define LADSPA_HINT_DEFAULT_MIDDLE 0xC0
+
+/* This default hint indicates that a high value between the suggested
+ lower and upper bounds should be chosen. For ports with
+ LADSPA_HINT_LOGARITHMIC, this should be exp(log(lower) * 0.25 +
+ log(upper) * 0.75). Otherwise, this should be (lower * 0.25 + upper
+ * 0.75). */
+#define LADSPA_HINT_DEFAULT_HIGH 0x100
+
+/* This default hint indicates that the suggested upper bound for the
+ port should be used. */
+#define LADSPA_HINT_DEFAULT_MAXIMUM 0x140
+
+/* This default hint indicates that the number 0 should be used. Note
+ that this default may be used in conjunction with
+ LADSPA_HINT_TOGGLED. */
+#define LADSPA_HINT_DEFAULT_0 0x200
+
+/* This default hint indicates that the number 1 should be used. Note
+ that this default may be used in conjunction with
+ LADSPA_HINT_TOGGLED. */
+#define LADSPA_HINT_DEFAULT_1 0x240
+
+/* This default hint indicates that the number 100 should be used. */
+#define LADSPA_HINT_DEFAULT_100 0x280
+
+/* This default hint indicates that the Hz frequency of `concert A'
+ should be used. This will be 440 unless the host uses an unusual
+ tuning convention, in which case it may be within a few Hz. */
+#define LADSPA_HINT_DEFAULT_440 0x2C0
+
+#define LADSPA_IS_HINT_BOUNDED_BELOW(x) ((x) & LADSPA_HINT_BOUNDED_BELOW)
+#define LADSPA_IS_HINT_BOUNDED_ABOVE(x) ((x) & LADSPA_HINT_BOUNDED_ABOVE)
+#define LADSPA_IS_HINT_TOGGLED(x) ((x) & LADSPA_HINT_TOGGLED)
+#define LADSPA_IS_HINT_SAMPLE_RATE(x) ((x) & LADSPA_HINT_SAMPLE_RATE)
+#define LADSPA_IS_HINT_LOGARITHMIC(x) ((x) & LADSPA_HINT_LOGARITHMIC)
+#define LADSPA_IS_HINT_INTEGER(x) ((x) & LADSPA_HINT_INTEGER)
+
+#define LADSPA_IS_HINT_HAS_DEFAULT(x) ((x) & LADSPA_HINT_DEFAULT_MASK)
+#define LADSPA_IS_HINT_DEFAULT_MINIMUM(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \
+ == LADSPA_HINT_DEFAULT_MINIMUM)
+#define LADSPA_IS_HINT_DEFAULT_LOW(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \
+ == LADSPA_HINT_DEFAULT_LOW)
+#define LADSPA_IS_HINT_DEFAULT_MIDDLE(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \
+ == LADSPA_HINT_DEFAULT_MIDDLE)
+#define LADSPA_IS_HINT_DEFAULT_HIGH(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \
+ == LADSPA_HINT_DEFAULT_HIGH)
+#define LADSPA_IS_HINT_DEFAULT_MAXIMUM(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \
+ == LADSPA_HINT_DEFAULT_MAXIMUM)
+#define LADSPA_IS_HINT_DEFAULT_0(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \
+ == LADSPA_HINT_DEFAULT_0)
+#define LADSPA_IS_HINT_DEFAULT_1(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \
+ == LADSPA_HINT_DEFAULT_1)
+#define LADSPA_IS_HINT_DEFAULT_100(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \
+ == LADSPA_HINT_DEFAULT_100)
+#define LADSPA_IS_HINT_DEFAULT_440(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \
+ == LADSPA_HINT_DEFAULT_440)
+
+typedef struct _LADSPA_PortRangeHint {
+
+ /* Hints about the port. */
+ LADSPA_PortRangeHintDescriptor HintDescriptor;
+
+ /* Meaningful when hint LADSPA_HINT_BOUNDED_BELOW is active. When
+ LADSPA_HINT_SAMPLE_RATE is also active then this value should be
+ multiplied by the relevant sample rate. */
+ LADSPA_Data LowerBound;
+
+ /* Meaningful when hint LADSPA_HINT_BOUNDED_ABOVE is active. When
+ LADSPA_HINT_SAMPLE_RATE is also active then this value should be
+ multiplied by the relevant sample rate. */
+ LADSPA_Data UpperBound;
+
+} LADSPA_PortRangeHint;
+
+/*****************************************************************************/
+
+/* Plugin Handles:
+
+ This plugin handle indicates a particular instance of the plugin
+ concerned. It is valid to compare this to NULL (0 for C++) but
+ otherwise the host should not attempt to interpret it. The plugin
+ may use it to reference internal instance data. */
+
+typedef void * LADSPA_Handle;
+
+/*****************************************************************************/
+
+/* Descriptor for a Type of Plugin:
+
+ This structure is used to describe a plugin type. It provides a
+ number of functions to examine the type, instantiate it, link it to
+ buffers and workspaces and to run it. */
+
+typedef struct _LADSPA_Descriptor {
+
+ /* This numeric identifier indicates the plugin type
+ uniquely. Plugin programmers may reserve ranges of IDs from a
+ central body to avoid clashes. Hosts may assume that IDs are
+ below 0x1000000. */
+ unsigned long UniqueID;
+
+ /* This identifier can be used as a unique, case-sensitive
+ identifier for the plugin type within the plugin file. Plugin
+ types should be identified by file and label rather than by index
+ or plugin name, which may be changed in new plugin
+ versions. Labels must not contain white-space characters. */
+ const char * Label;
+
+ /* This indicates a number of properties of the plugin. */
+ LADSPA_Properties Properties;
+
+ /* This member points to the null-terminated name of the plugin
+ (e.g. "Sine Oscillator"). */
+ const char * Name;
+
+ /* This member points to the null-terminated string indicating the
+ maker of the plugin. This can be an empty string but not NULL. */
+ const char * Maker;
+
+ /* This member points to the null-terminated string indicating any
+ copyright applying to the plugin. If no Copyright applies the
+ string "None" should be used. */
+ const char * Copyright;
+
+ /* This indicates the number of ports (input AND output) present on
+ the plugin. */
+ unsigned long PortCount;
+
+ /* This member indicates an array of port descriptors. Valid indices
+ vary from 0 to PortCount-1. */
+ const LADSPA_PortDescriptor * PortDescriptors;
+
+ /* This member indicates an array of null-terminated strings
+ describing ports (e.g. "Frequency (Hz)"). Valid indices vary from
+ 0 to PortCount-1. */
+ const char * const * PortNames;
+
+ /* This member indicates an array of range hints for each port (see
+ above). Valid indices vary from 0 to PortCount-1. */
+ const LADSPA_PortRangeHint * PortRangeHints;
+
+ /* This may be used by the plugin developer to pass any custom
+ implementation data into an instantiate call. It must not be used
+ or interpreted by the host. It is expected that most plugin
+ writers will not use this facility as LADSPA_Handle should be
+ used to hold instance data. */
+ void * ImplementationData;
+
+ /* This member is a function pointer that instantiates a plugin. A
+ handle is returned indicating the new plugin instance. The
+ instantiation function accepts a sample rate as a parameter. The
+ plugin descriptor from which this instantiate function was found
+ must also be passed. This function must return NULL if
+ instantiation fails.
+
+ Note that instance initialisation should generally occur in
+ activate() rather than here. */
+ LADSPA_Handle (*instantiate)(const struct _LADSPA_Descriptor * Descriptor,
+ unsigned long SampleRate);
+
+ /* This member is a function pointer that connects a port on an
+ instantiated plugin to a memory location at which a block of data
+ for the port will be read/written. The data location is expected
+ to be an array of LADSPA_Data for audio ports or a single
+ LADSPA_Data value for control ports. Memory issues will be
+ managed by the host. The plugin must read/write the data at these
+ locations every time run() or run_adding() is called and the data
+ present at the time of this connection call should not be
+ considered meaningful.
+
+ connect_port() may be called more than once for a plugin instance
+ to allow the host to change the buffers that the plugin is
+ reading or writing. These calls may be made before or after
+ activate() or deactivate() calls.
+
+ connect_port() must be called at least once for each port before
+ run() or run_adding() is called. When working with blocks of
+ LADSPA_Data the plugin should pay careful attention to the block
+ size passed to the run function as the block allocated may only
+ just be large enough to contain the block of samples.
+
+ Plugin writers should be aware that the host may elect to use the
+ same buffer for more than one port and even use the same buffer
+ for both input and output (see LADSPA_PROPERTY_INPLACE_BROKEN).
+ However, overlapped buffers or use of a single buffer for both
+ audio and control data may result in unexpected behaviour. */
+ void (*connect_port)(LADSPA_Handle Instance,
+ unsigned long Port,
+ LADSPA_Data * DataLocation);
+
+ /* This member is a function pointer that initialises a plugin
+ instance and activates it for use. This is separated from
+ instantiate() to aid real-time support and so that hosts can
+ reinitialise a plugin instance by calling deactivate() and then
+ activate(). In this case the plugin instance must reset all state
+ information dependent on the history of the plugin instance
+ except for any data locations provided by connect_port() and any
+ gain set by set_run_adding_gain(). If there is nothing for
+ activate() to do then the plugin writer may provide a NULL rather
+ than an empty function.
+
+ When present, hosts must call this function once before run() (or
+ run_adding()) is called for the first time. This call should be
+ made as close to the run() call as possible and indicates to
+ real-time plugins that they are now live. Plugins should not rely
+ on a prompt call to run() after activate(). activate() may not be
+ called again unless deactivate() is called first. Note that
+ connect_port() may be called before or after a call to
+ activate(). */
+ void (*activate)(LADSPA_Handle Instance);
+
+ /* This method is a function pointer that runs an instance of a
+ plugin for a block. Two parameters are required: the first is a
+ handle to the particular instance to be run and the second
+ indicates the block size (in samples) for which the plugin
+ instance may run.
+
+ Note that if an activate() function exists then it must be called
+ before run() or run_adding(). If deactivate() is called for a
+ plugin instance then the plugin instance may not be reused until
+ activate() has been called again.
+
+ If the plugin has the property LADSPA_PROPERTY_HARD_RT_CAPABLE
+ then there are various things that the plugin should not do
+ within the run() or run_adding() functions (see above). */
+ void (*run)(LADSPA_Handle Instance,
+ unsigned long SampleCount);
+
+ /* This method is a function pointer that runs an instance of a
+ plugin for a block. This has identical behaviour to run() except
+ in the way data is output from the plugin. When run() is used,
+ values are written directly to the memory areas associated with
+ the output ports. However when run_adding() is called, values
+ must be added to the values already present in the memory
+ areas. Furthermore, output values written must be scaled by the
+ current gain set by set_run_adding_gain() (see below) before
+ addition.
+
+ run_adding() is optional. When it is not provided by a plugin,
+ this function pointer must be set to NULL. When it is provided,
+ the function set_run_adding_gain() must be provided also. */
+ void (*run_adding)(LADSPA_Handle Instance,
+ unsigned long SampleCount);
+
+ /* This method is a function pointer that sets the output gain for
+ use when run_adding() is called (see above). If this function is
+ never called the gain is assumed to default to 1. Gain
+ information should be retained when activate() or deactivate()
+ are called.
+
+ This function should be provided by the plugin if and only if the
+ run_adding() function is provided. When it is absent this
+ function pointer must be set to NULL. */
+ void (*set_run_adding_gain)(LADSPA_Handle Instance,
+ LADSPA_Data Gain);
+
+ /* This is the counterpart to activate() (see above). If there is
+ nothing for deactivate() to do then the plugin writer may provide
+ a NULL rather than an empty function.
+
+ Hosts must deactivate all activated units after they have been
+ run() (or run_adding()) for the last time. This call should be
+ made as close to the last run() call as possible and indicates to
+ real-time plugins that they are no longer live. Plugins should
+ not rely on prompt deactivation. Note that connect_port() may be
+ called before or after a call to deactivate().
+
+ Deactivation is not similar to pausing as the plugin instance
+ will be reinitialised when activate() is called to reuse it. */
+ void (*deactivate)(LADSPA_Handle Instance);
+
+ /* Once an instance of a plugin has been finished with it can be
+ deleted using the following function. The instance handle passed
+ ceases to be valid after this call.
+
+ If activate() was called for a plugin instance then a
+ corresponding call to deactivate() must be made before cleanup()
+ is called. */
+ void (*cleanup)(LADSPA_Handle Instance);
+
+} LADSPA_Descriptor;
+
+/**********************************************************************/
+
+/* Accessing a Plugin: */
+
+/* The exact mechanism by which plugins are loaded is host-dependent,
+ however all most hosts will need to know is the name of shared
+ object file containing the plugin types. To allow multiple hosts to
+ share plugin types, hosts may wish to check for environment
+ variable LADSPA_PATH. If present, this should contain a
+ colon-separated path indicating directories that should be searched
+ (in order) when loading plugin types.
+
+ A plugin programmer must include a function called
+ "ladspa_descriptor" with the following function prototype within
+ the shared object file. This function will have C-style linkage (if
+ you are using C++ this is taken care of by the `extern "C"' clause
+ at the top of the file).
+
+ A host will find the plugin shared object file by one means or
+ another, find the ladspa_descriptor() function, call it, and
+ proceed from there.
+
+ Plugin types are accessed by index (not ID) using values from 0
+ upwards. Out of range indexes must result in this function
+ returning NULL, so the plugin count can be determined by checking
+ for the least index that results in NULL being returned. */
+
+const LADSPA_Descriptor * ladspa_descriptor(unsigned long Index);
+
+/* Datatype corresponding to the ladspa_descriptor() function. */
+typedef const LADSPA_Descriptor *
+(*LADSPA_Descriptor_Function)(unsigned long Index);
+
+/**********************************************************************/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LADSPA_INCLUDED */
+
+/* EOF */
diff --git a/muse_qt4_evolution/muse/ladspaplugin.cpp b/muse_qt4_evolution/muse/ladspaplugin.cpp
new file mode 100644
index 00000000..85398d74
--- /dev/null
+++ b/muse_qt4_evolution/muse/ladspaplugin.cpp
@@ -0,0 +1,235 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "al/al.h"
+#include "ladspaplugin.h"
+#include "fastlog.h"
+#include "ctrl.h"
+
+//---------------------------------------------------------
+// defaultValue
+//---------------------------------------------------------
+
+float ladspaDefaultValue(const LADSPA_Descriptor* plugin, int k)
+ {
+ LADSPA_PortRangeHint range = plugin->PortRangeHints[k];
+ LADSPA_PortRangeHintDescriptor rh = range.HintDescriptor;
+// bool isLog = LADSPA_IS_HINT_LOGARITHMIC(rh);
+ double val = 1.0;
+ float m = (rh & LADSPA_HINT_SAMPLE_RATE) ? float(AL::sampleRate) : 1.0f;
+ if (LADSPA_IS_HINT_DEFAULT_MINIMUM(rh)) {
+ val = range.LowerBound * m;
+ }
+ else if (LADSPA_IS_HINT_DEFAULT_LOW(rh)) {
+ if (LADSPA_IS_HINT_LOGARITHMIC(rh))
+ val = exp(fast_log10(range.LowerBound * m) * .75 +
+ log(range.UpperBound * m) * .25);
+ else
+ val = range.LowerBound*.75*m + range.UpperBound*.25*m;
+ }
+ else if (LADSPA_IS_HINT_DEFAULT_MIDDLE(rh)) {
+ if (LADSPA_IS_HINT_LOGARITHMIC(rh))
+ val = exp(log(range.LowerBound * m) * .5 +
+ log10(range.UpperBound * m) * .5);
+ else
+ val = range.LowerBound*.5*m + range.UpperBound*.5*m;
+ }
+ else if (LADSPA_IS_HINT_DEFAULT_HIGH(rh)) {
+ if (LADSPA_IS_HINT_LOGARITHMIC(rh))
+ val = exp(log(range.LowerBound * m) * .25 +
+ log(range.UpperBound * m) * .75);
+ else
+ val = range.LowerBound*.25*m + range.UpperBound*.75*m;
+ }
+ else if (LADSPA_IS_HINT_DEFAULT_MAXIMUM(rh)) {
+ val = range.UpperBound*m;
+ }
+ else if (LADSPA_IS_HINT_DEFAULT_0(rh))
+ val = 0.0;
+ else if (LADSPA_IS_HINT_DEFAULT_1(rh))
+ val = 1.0;
+ else if (LADSPA_IS_HINT_DEFAULT_100(rh))
+ val = 100.0;
+ else if (LADSPA_IS_HINT_DEFAULT_440(rh))
+ val = 440.0;
+ return val;
+ }
+
+//---------------------------------------------------------
+// LadpsaPlugin
+//---------------------------------------------------------
+
+LadspaPlugin::LadspaPlugin(const QFileInfo* f,
+ const LADSPA_Descriptor_Function ldf,
+ const LADSPA_Descriptor* d)
+ : Plugin(f), ladspa(ldf), plugin(d)
+ {
+ _inports = 0;
+ _outports = 0;
+ _parameter = 0;
+ for (unsigned k = 0; k < plugin->PortCount; ++k) {
+ LADSPA_PortDescriptor pd = d->PortDescriptors[k];
+ static const int CI = LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT;
+ if ((pd & CI) == CI) {
+ ++_parameter;
+ pIdx.push_back(k);
+ }
+ else if (pd & LADSPA_PORT_INPUT) {
+ ++_inports;
+ iIdx.push_back(k);
+ }
+ else if (pd & LADSPA_PORT_OUTPUT) {
+ ++_outports;
+ oIdx.push_back(k);
+ }
+ }
+ LADSPA_Properties properties = plugin->Properties;
+ _inPlaceCapable = !LADSPA_IS_INPLACE_BROKEN(properties);
+ if (_inports != _outports)
+ _inPlaceCapable = false;
+ }
+
+//---------------------------------------------------------
+// instantiate
+//---------------------------------------------------------
+
+void* LadspaPlugin::instantiate()
+ {
+ return plugin->instantiate(plugin, AL::sampleRate);
+ }
+
+//---------------------------------------------------------
+// range
+//---------------------------------------------------------
+
+void LadspaPlugin::range(int i, double* min, double* max) const
+ {
+ i = pIdx[i];
+ LADSPA_PortRangeHint range = plugin->PortRangeHints[i];
+ LADSPA_PortRangeHintDescriptor desc = range.HintDescriptor;
+ if (desc & LADSPA_HINT_TOGGLED) {
+ *min = -1.0;
+ *max = 1.0;
+ return;
+ }
+ double m = (desc & LADSPA_HINT_SAMPLE_RATE) ? float(AL::sampleRate) : 1.0f;
+
+ if (desc & LADSPA_HINT_BOUNDED_BELOW)
+ *min = range.LowerBound * m;
+ else
+ *min = 0.0;
+ if (desc & LADSPA_HINT_BOUNDED_ABOVE)
+ *max = range.UpperBound * m;
+ else
+ *max = 1.0;
+ }
+
+//---------------------------------------------------------
+// createPIF
+//---------------------------------------------------------
+
+PluginIF* LadspaPlugin::createPIF(PluginI* pi)
+ {
+ LadspaPluginIF* pif = new LadspaPluginIF(pi);
+ pif->init(pi->plugin());
+ return pif;
+ }
+
+//---------------------------------------------------------
+// LadspaPluginIF
+//---------------------------------------------------------
+
+LadspaPluginIF::LadspaPluginIF(PluginI* pi)
+ : PluginIF(pi)
+ {
+ descr = 0;
+ plugin = (LadspaPlugin*)(pi->plugin());
+ }
+
+//---------------------------------------------------------
+// init
+// return true on error
+//---------------------------------------------------------
+
+bool LadspaPluginIF::init(Plugin* pl)
+ {
+ handle = (LADSPA_Descriptor*) ((LadspaPlugin*)pl)->instantiate();
+ plugin = (LadspaPlugin*)pl;
+ descr = plugin->ladspaDescriptor();
+
+ int controlPorts = plugin->parameter();
+ controls = new LadspaPort[controlPorts];
+
+ for (int k = 0; k < controlPorts; ++k) {
+ controls[k].val = plugin->defaultValue(k);
+ descr->connect_port(handle, plugin->pIdx[k], &controls[k].val);
+ }
+ return handle == 0;
+ }
+
+//---------------------------------------------------------
+// apply
+//---------------------------------------------------------
+
+void LadspaPluginIF::apply(unsigned nframes, float** src, float** dst)
+ {
+ int iports = plugin->inports();
+ int oports = plugin->outports();
+ int cports = plugin->parameter();
+
+ //
+ // update parameter
+ //
+ for (int i = 0; i < cports; ++i)
+ controls[i].val = pluginI->controllerList[i]->curVal().f;
+ //
+ // set connections
+ //
+ for (int k = 0; k < iports; ++k)
+ descr->connect_port(handle, plugin->iIdx[k], src[k]);
+ for (int k = 0; k < oports; ++k)
+ descr->connect_port(handle, plugin->oIdx[k], dst[k]);
+
+ descr->run(handle, nframes);
+ }
+
+//---------------------------------------------------------
+// defaultValue
+//---------------------------------------------------------
+
+double LadspaPlugin::defaultValue(int k) const
+ {
+ k = pIdx[k];
+ return ladspaDefaultValue(plugin, k);
+ }
+
+//---------------------------------------------------------
+// activate
+//---------------------------------------------------------
+
+void LadspaPluginIF::activate()
+ {
+ //
+ // TODO: init values?
+ //
+ if (descr->activate)
+ descr->activate(handle);
+ }
+
diff --git a/muse_qt4_evolution/muse/ladspaplugin.h b/muse_qt4_evolution/muse/ladspaplugin.h
new file mode 100644
index 00000000..4c492813
--- /dev/null
+++ b/muse_qt4_evolution/muse/ladspaplugin.h
@@ -0,0 +1,127 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __LADSPAPLUGIN_H__
+#define __LADSPAPLUGIN_H__
+
+#include "ladspa.h"
+#include "plugin.h"
+
+//---------------------------------------------------------
+// LadspaPlugin
+//---------------------------------------------------------
+
+class LadspaPlugin : public Plugin {
+ LADSPA_Descriptor_Function ladspa;
+ const LADSPA_Descriptor* plugin;
+
+ protected:
+ int _parameter;
+ std::vector<int> pIdx;
+
+ int _inports;
+ std::vector<int> iIdx;
+
+ int _outports;
+ std::vector<int> oIdx;
+
+ bool _inPlaceCapable;
+ friend class LadspaPluginIF;
+
+ public:
+ LadspaPlugin(const QFileInfo* f,
+ const LADSPA_Descriptor_Function,
+ const LADSPA_Descriptor* d);
+
+ virtual QString label() const { return QString(plugin->Label); }
+ virtual QString name() const { return QString(plugin->Name); }
+ virtual unsigned long id() const { return plugin->UniqueID; }
+ virtual QString maker() const { return QString(plugin->Maker); }
+ virtual QString copyright() const { return QString(plugin->Copyright); }
+
+ void* instantiate();
+ virtual void range(int i, double*, double*) const;
+ virtual int parameter() const { return _parameter; }
+ virtual int inports() const { return _inports; }
+ virtual int outports() const { return _outports; }
+
+ virtual bool inPlaceCapable() const { return _inPlaceCapable; }
+ virtual PluginIF* createPIF(PluginI*);
+ const LADSPA_Descriptor* ladspaDescriptor() const { return plugin; }
+
+ virtual bool isLog(int k) const {
+ LADSPA_PortRangeHint r = plugin->PortRangeHints[pIdx[k]];
+ return LADSPA_IS_HINT_LOGARITHMIC(r.HintDescriptor);
+ }
+ virtual bool isBool(int k) const {
+ return LADSPA_IS_HINT_TOGGLED(plugin->PortRangeHints[pIdx[k]].HintDescriptor);
+ }
+ virtual bool isInt(int k) const {
+ LADSPA_PortRangeHint r = plugin->PortRangeHints[pIdx[k]];
+ return LADSPA_IS_HINT_INTEGER(r.HintDescriptor);
+ }
+ virtual double defaultValue(int) const;
+ };
+
+//---------------------------------------------------------
+// LadspaPort
+//---------------------------------------------------------
+
+struct LadspaPort {
+ float val;
+ };
+
+//---------------------------------------------------------
+// LadspaPluginIF
+//---------------------------------------------------------
+
+class LadspaPluginIF : public PluginIF {
+ const LADSPA_Descriptor* descr;
+ LADSPA_Handle handle; // per instance
+ LadspaPlugin* plugin;
+
+ LadspaPort* controls;
+
+ public:
+ LadspaPluginIF(PluginI* pi);
+
+ virtual void apply(unsigned nframes, float** src, float** dst);
+ virtual void activate();
+ virtual void deactivate() {
+ if (descr->deactivate)
+ descr->deactivate(handle);
+ }
+ virtual void cleanup() {
+ if (descr->cleanup)
+ descr->cleanup(handle);
+ }
+ virtual const char* getParameterName(int i) const {
+ return plugin->plugin->PortNames[plugin->pIdx[i]];
+ }
+ virtual void setParam(int i, double val) { controls[i].val = val; }
+ virtual float param(int i) const { return controls[i].val; }
+ bool init(Plugin*);
+ };
+
+extern float ladspaDefaultValue(const LADSPA_Descriptor* plugin, int k);
+
+#endif
+
+
diff --git a/muse_qt4_evolution/muse/liste/CMakeLists.txt b/muse_qt4_evolution/muse/liste/CMakeLists.txt
new file mode 100644
index 00000000..988efaf8
--- /dev/null
+++ b/muse_qt4_evolution/muse/liste/CMakeLists.txt
@@ -0,0 +1,48 @@
+#=============================================================================
+# MusE
+# Linux Music Editor
+# $Id:$
+#
+# Copyright (C) 2002-2006 by Werner Schweer and others
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#=============================================================================
+
+QT4_WRAP_CPP ( liste_mocs
+ listedit.h
+ ctrllistedit.h
+ tracklistedit.h
+ partlistedit.h
+ ieventdialog.h
+ )
+
+QT4_WRAP_UI ( liste_ui_headers
+ ctrllistedit.ui
+ partlistedit.ui
+ tracklistedit.ui
+ )
+
+add_library ( liste STATIC
+ listedit.cpp listedit.h
+ ctrllistedit.cpp ctrllistedit.h
+ partlistedit.cpp partlistedit.h
+ tracklistedit.cpp tracklistedit.h
+ ieventdialog.cpp ieventdialog.h
+ ${liste_mocs}
+ ${liste_ui_headers}
+ )
+set_target_properties( liste
+ PROPERTIES COMPILE_FLAGS "-include ${PROJECT_BINARY_DIR}/all.h"
+ )
+
+
diff --git a/muse_qt4_evolution/muse/liste/ctrllistedit.cpp b/muse_qt4_evolution/muse/liste/ctrllistedit.cpp
new file mode 100644
index 00000000..ab9e66e3
--- /dev/null
+++ b/muse_qt4_evolution/muse/liste/ctrllistedit.cpp
@@ -0,0 +1,569 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "ctrllistedit.h"
+#include "ctrl.h"
+#include "track.h"
+#include "song.h"
+#include "al/pos.h"
+#include "awl/posedit.h"
+
+//---------------------------------------------------------
+// CtrlListEditor
+//---------------------------------------------------------
+
+CtrlListEditor::CtrlListEditor(ListEdit* e, QWidget* parent)
+ : ListWidget(parent)
+ {
+ listEdit = e;
+ updateListDisabled = false;
+ QWidget* cew = new QWidget;
+ le.setupUi(cew);
+ QVBoxLayout* layout = new QVBoxLayout;
+ layout->addWidget(cew);
+ setLayout(layout);
+ le.minValue->setRange(-10000000.0, 100000000.0);
+ le.maxValue->setRange(-10000000.0, 100000000.0);
+ le.defaultValue->setRange(-10000000.0, 100000000.0);
+ le.minValue->setSingleStep(1.0);
+ le.maxValue->setSingleStep(1.0);
+ le.defaultValue->setSingleStep(1.0);
+
+ QFontMetrics fm(le.ctrlList->font());
+ int zW = fm.width("0");
+ le.ctrlList->setColumnWidth(TICK_COL, zW * 8);
+ le.ctrlList->setColumnWidth(TIME_COL, zW * 14);
+ CtrlDelegate* ctrlDelegate = new CtrlDelegate(this);
+ le.ctrlList->setItemDelegate(ctrlDelegate);
+
+ track = 0;
+ connect(le.ctrlList, SIGNAL(itemActivated(QTreeWidgetItem*, int)),
+ SLOT(itemActivated(QTreeWidgetItem*,int)));
+ connect(le.ctrlList, SIGNAL(itemChanged(QTreeWidgetItem*, int)),
+ SLOT(itemChanged(QTreeWidgetItem*, int)));
+ connect(le.ctrlList, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)),
+ SLOT(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)));
+ connect(le.insertButton, SIGNAL(clicked()), SLOT(insertClicked()));
+ connect(le.deleteButton, SIGNAL(clicked()), SLOT(deleteClicked()));
+ connect(le.controllerName, SIGNAL(textEdited(const QString&)),
+ SLOT(nameEdited(const QString&)));
+ connect(le.minValue, SIGNAL(valueChanged(double)), SLOT(minValChanged(double)));
+ connect(le.maxValue, SIGNAL(valueChanged(double)), SLOT(maxValChanged(double)));
+ connect(le.defaultValue, SIGNAL(valueChanged(double)), SLOT(defaultValChanged(double)));
+ EscapeFilter* ef = new EscapeFilter(this);
+ installEventFilter(ef);
+ }
+
+//---------------------------------------------------------
+// eventFilter
+//---------------------------------------------------------
+
+bool EscapeFilter::eventFilter(QObject* obj, QEvent* event)
+ {
+ if (event->type() == QEvent::KeyPress) {
+ if (((QKeyEvent*)event)->key() == Qt::Key_Escape) {
+ ((CtrlListEditor*)parent())->sendEscape();
+ return true;
+ }
+ }
+ return QObject::eventFilter(obj, event);
+ }
+
+//---------------------------------------------------------
+// setup
+//---------------------------------------------------------
+
+void CtrlListEditor::setup(const ListType& lt)
+ {
+ if (track)
+ disconnect(track, SIGNAL(controllerChanged(int)), this, SLOT(controllerChanged(int)));
+ track = lt.track;
+ connect(track, SIGNAL(controllerChanged(int)), SLOT(controllerChanged(int)));
+
+ c = lt.ctrl;
+ le.controllerName->setText(c->name());
+ le.discreteCheckBox->setChecked(c->type() & Ctrl::DISCRETE);
+ le.logarithmicCheckBox->setChecked(c->type() & Ctrl::LOG);
+ le.floatCheckBox->setChecked(!(c->type() & Ctrl::INT));
+ le.ctrlId->setValue(c->id());
+ if (c->type() & Ctrl::INT) {
+ le.minValue->setDecimals(0);
+ le.minValue->setValue(c->minVal().i);
+ le.maxValue->setDecimals(0);
+ le.maxValue->setValue(c->maxVal().i);
+ le.defaultValue->setDecimals(0);
+ le.defaultValue->setValue(c->getDefault().i);
+ }
+ else {
+ if (c->type() & Ctrl::LOG) {
+ le.minValue->setDecimals(0);
+ le.minValue->setValue(c->minVal().f * 20.0);
+ le.minValue->setSuffix(tr("dB"));
+ le.maxValue->setDecimals(0);
+ le.maxValue->setValue(c->maxVal().f * 20.0);
+ le.maxValue->setSuffix(tr("dB"));
+ le.defaultValue->setDecimals(0);
+ le.defaultValue->setValue(c->getDefault().f * 20.0);
+ le.defaultValue->setSuffix(tr("dB"));
+ }
+ else {
+ le.minValue->setDecimals(1);
+ le.minValue->setValue(c->minVal().f);
+ le.maxValue->setDecimals(1);
+ le.maxValue->setValue(c->maxVal().f);
+ le.defaultValue->setDecimals(1);
+ le.defaultValue->setValue(c->getDefault().f);
+ }
+ }
+ updateList();
+ }
+
+//---------------------------------------------------------
+// updateList
+//---------------------------------------------------------
+
+void CtrlListEditor::updateList()
+ {
+ if (updateListDisabled)
+ return;
+ le.ctrlList->clear();
+ int idx = 0;
+ bool curItemSet = false;
+ for (iCtrlVal i = c->begin(); i != c->end(); ++i, ++idx) {
+ CVal v = i.value();
+ QTreeWidgetItem* item = new QTreeWidgetItem;
+ item->setData(TICK_COL, Qt::TextAlignmentRole, int(Qt::AlignRight | Qt::AlignVCenter));
+ item->setData(TIME_COL, Qt::TextAlignmentRole, int(Qt::AlignRight | Qt::AlignVCenter));
+ item->setData(VAL_COL, Qt::TextAlignmentRole, int(Qt::AlignHCenter | Qt::AlignVCenter));
+
+ item->setData(TICK_COL, Qt::DisplayRole, i.key());
+ item->setData(TIME_COL, Qt::DisplayRole, i.key());
+ if (c->type() & Ctrl::INT)
+ item->setData(VAL_COL, Qt::DisplayRole, v.i);
+ else
+ item->setData(VAL_COL, Qt::DisplayRole, v.f);
+ le.ctrlList->insertTopLevelItem(idx, item);
+ if (!curItemSet && (i.key() >= listEdit->pos().tick())) {
+ le.ctrlList->setCurrentItem(item);
+ curItemSet = true;
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// controllerChanged
+//---------------------------------------------------------
+
+void CtrlListEditor::controllerChanged(int id)
+ {
+ if (id != c->id())
+ return;
+ updateList();
+ }
+
+//---------------------------------------------------------
+// itemActivated
+//---------------------------------------------------------
+
+void CtrlListEditor::itemActivated(QTreeWidgetItem* item, int column)
+ {
+ le.ctrlList->openPersistentEditor(item, column);
+ }
+
+//---------------------------------------------------------
+// itemChanged
+//---------------------------------------------------------
+
+void CtrlListEditor::itemChanged(QTreeWidgetItem* item, int column)
+ {
+ CVal val;
+ if (c->type() & Ctrl::INT) {
+ val.i = item->data(VAL_COL, Qt::DisplayRole).toInt();
+ bool updateData = false;
+ if (val.i < c->minVal().i) {
+ val.i = c->minVal().i;
+ updateData = true;
+ }
+ else if (val.i > c->maxVal().i) {
+ val.i = c->maxVal().i;
+ updateData = true;
+ }
+ if (updateData)
+ item->setData(VAL_COL, Qt::DisplayRole, val.i);
+ }
+ else {
+ val.f = item->data(VAL_COL, Qt::DisplayRole).toDouble();
+ bool updateData = false;
+ if (val.f < c->minVal().f) {
+ val.f = c->minVal().f;
+ updateData = true;
+ }
+ else if (val.f > c->maxVal().f) {
+ val.f = c->maxVal().f;
+ updateData = true;
+ }
+ if (updateData)
+ item->setData(VAL_COL, Qt::DisplayRole, val.f);
+ }
+ le.ctrlList->closePersistentEditor(item, TICK_COL);
+ le.ctrlList->closePersistentEditor(item, TIME_COL);
+ le.ctrlList->closePersistentEditor(item, VAL_COL);
+ updateListDisabled = true;
+ switch(column) {
+ case TICK_COL:
+ {
+ int otick = item->data(TIME_COL, Qt::DisplayRole).toInt();
+ int tick = item->data(TICK_COL, Qt::DisplayRole).toInt();
+ item->setData(TIME_COL, Qt::DisplayRole, tick);
+ song->cmdRemoveControllerVal(track, c->id(), otick);
+ song->cmdAddControllerVal(track, c, tick, val);
+ }
+ break;
+ case TIME_COL:
+ {
+ int otick = item->data(TICK_COL, Qt::DisplayRole).toInt();
+ int tick = item->data(TIME_COL, Qt::DisplayRole).toInt();
+ item->setData(TICK_COL, Qt::DisplayRole, tick);
+ song->cmdRemoveControllerVal(track, c->id(), otick);
+ song->cmdAddControllerVal(track, c, tick, val);
+ }
+ break;
+ case VAL_COL:
+ song->cmdAddControllerVal(track, c, listEdit->pos(), val);
+ break;
+ }
+ updateListDisabled = false;
+ }
+
+//---------------------------------------------------------
+// sendEscape
+//---------------------------------------------------------
+
+void CtrlListEditor::sendEscape()
+ {
+ QTreeWidgetItem* cur = le.ctrlList->currentItem();
+ if (cur == 0)
+ return;
+ le.ctrlList->closePersistentEditor(cur, TICK_COL);
+ le.ctrlList->closePersistentEditor(cur, TIME_COL);
+ le.ctrlList->closePersistentEditor(cur, VAL_COL);
+ }
+
+//---------------------------------------------------------
+// currentItemChanged
+//---------------------------------------------------------
+
+void CtrlListEditor::currentItemChanged(QTreeWidgetItem* cur, QTreeWidgetItem* prev)
+ {
+ if (prev) {
+ le.ctrlList->closePersistentEditor(prev, TICK_COL);
+ le.ctrlList->closePersistentEditor(prev, TIME_COL);
+ le.ctrlList->closePersistentEditor(prev, VAL_COL);
+ }
+ if (cur) {
+ Pos pos(cur->data(TICK_COL, Qt::DisplayRole).toInt(), track->timeType());
+ listEdit->pos() = pos;
+ }
+ le.deleteButton->setEnabled(cur);
+ }
+
+//---------------------------------------------------------
+// insertClicked
+// insert one tick before current value
+//---------------------------------------------------------
+
+void CtrlListEditor::insertClicked()
+ {
+ CVal val = c->minVal();
+ QTreeWidgetItem* cur = le.ctrlList->currentItem();
+ if (cur) {
+ int tick = cur->data(TICK_COL, Qt::DisplayRole).toInt();
+ if (tick == 0) // cannot insert value at position < 0
+ return;
+ listEdit->pos().setTick(tick - 1);
+ if (c->type() & Ctrl::INT)
+ val.i = cur->data(VAL_COL, Qt::DisplayRole).toInt();
+ else
+ val.f = cur->data(VAL_COL, Qt::DisplayRole).toDouble();
+ }
+ song->cmdAddControllerVal(track, c, listEdit->pos(), val);
+ }
+
+//---------------------------------------------------------
+// deleteClicked
+//---------------------------------------------------------
+
+void CtrlListEditor::deleteClicked()
+ {
+ QTreeWidgetItem* cur = le.ctrlList->currentItem();
+ if (cur == 0)
+ return;
+ int tick = cur->data(TICK_COL, Qt::DisplayRole).toInt();
+ song->cmdRemoveControllerVal(track, c->id(), tick);
+ }
+
+//---------------------------------------------------------
+// nameEdited
+//---------------------------------------------------------
+
+void CtrlListEditor::nameEdited(const QString& s)
+ {
+ track->changeCtrlName(c, s);
+ }
+
+//---------------------------------------------------------
+// minValChanged
+//---------------------------------------------------------
+
+void CtrlListEditor::minValChanged(double v)
+ {
+ CVal val;
+ if (c->type() & Ctrl::INT)
+ val.i = int(v);
+ else {
+ if (c->type() & Ctrl::LOG)
+ v /= 20.0;
+ val.f = v;
+ }
+ c->setRange(val, c->maxVal());
+ }
+
+//---------------------------------------------------------
+// maxValChanged
+//---------------------------------------------------------
+
+void CtrlListEditor::maxValChanged(double v)
+ {
+ CVal val;
+ if (c->type() & Ctrl::INT)
+ val.i = int(v);
+ else {
+ if (c->type() & Ctrl::LOG)
+ v /= 20.0;
+ val.f = v;
+ }
+ c->setRange(c->minVal(), val);
+ }
+
+//---------------------------------------------------------
+// defaultValChanged
+//---------------------------------------------------------
+
+void CtrlListEditor::defaultValChanged(double v)
+ {
+ CVal val;
+ if (c->type() & Ctrl::INT)
+ val.i = int(v);
+ else
+ val.f = v;
+ c->setDefault(val);
+ }
+
+//---------------------------------------------------------
+// CtrlDelegate
+//---------------------------------------------------------
+
+CtrlDelegate::CtrlDelegate(QObject* parent)
+ : QItemDelegate(parent)
+ {
+ }
+
+//---------------------------------------------------------
+// createEditor
+//---------------------------------------------------------
+
+QWidget* CtrlDelegate::createEditor(QWidget* pw,
+ const QStyleOptionViewItem& option, const QModelIndex& index) const
+ {
+ switch(index.column()) {
+ case CtrlListEditor::TICK_COL:
+ break;
+ case CtrlListEditor::TIME_COL:
+ return new Awl::PosEdit(pw);
+ case CtrlListEditor::VAL_COL:
+ {
+ CtrlListEditor* ce = static_cast<CtrlListEditor*>(parent());
+ Ctrl* c = ce->ctrl();
+ if (c->type() & Ctrl::INT) {
+ QSpinBox* w = new QSpinBox(pw);
+ w->setRange(c->minVal().i, c->maxVal().i);
+ w->installEventFilter(const_cast<CtrlDelegate*>(this));
+ return w;
+ }
+ QDoubleSpinBox* w = new QDoubleSpinBox(pw);
+ if (c->type() & Ctrl::LOG)
+ w->setSuffix(tr("dB"));
+// w->setRange(c->minVal().f, c->maxVal().f);
+ w->installEventFilter(const_cast<CtrlDelegate*>(this));
+ return w;
+ }
+ }
+ return QItemDelegate::createEditor(pw, option, index);
+ }
+
+//---------------------------------------------------------
+// setEditorData
+//---------------------------------------------------------
+
+void CtrlDelegate::setEditorData(QWidget* editor,
+ const QModelIndex& index) const
+ {
+ switch(index.column()) {
+ case CtrlListEditor::TICK_COL:
+ break;
+ case CtrlListEditor::TIME_COL:
+ {
+ Awl::PosEdit* pe = static_cast<Awl::PosEdit*>(editor);
+ pe->setValue(AL::Pos(index.data().toInt()));
+ }
+ return;
+ case CtrlListEditor::VAL_COL:
+ {
+ CtrlListEditor* ce = static_cast<CtrlListEditor*>(parent());
+ Ctrl* c = ce->ctrl();
+ if (c->type() & Ctrl::INT) {
+ QSpinBox* w = static_cast<QSpinBox*>(editor);
+ w->setValue(index.data().toInt());
+ }
+ else {
+ QDoubleSpinBox* w = static_cast<QDoubleSpinBox*>(editor);
+ double v = index.data().toDouble();
+printf("type %x\n", c->type());
+ if (c->type() & Ctrl::LOG)
+ v *= 20.0;
+ w->setValue(v);
+ }
+ }
+ return;
+ }
+ QItemDelegate::setEditorData(editor, index);
+ }
+
+//---------------------------------------------------------
+// setModelData
+//---------------------------------------------------------
+
+void CtrlDelegate::setModelData(QWidget* editor, QAbstractItemModel* model,
+ const QModelIndex& index) const
+ {
+ switch(index.column()) {
+ case CtrlListEditor::TICK_COL:
+ break;
+ case CtrlListEditor::TIME_COL:
+ {
+ Awl::PosEdit* pe = static_cast<Awl::PosEdit*>(editor);
+ model->setData(index, pe->pos().tick(), Qt::DisplayRole);
+ }
+ return;
+ case CtrlListEditor::VAL_COL:
+ {
+ CtrlListEditor* ce = static_cast<CtrlListEditor*>(parent());
+ Ctrl* c = ce->ctrl();
+ if (c->type() & Ctrl::INT) {
+ QSpinBox* w = static_cast<QSpinBox*>(editor);
+ model->setData(index, w->value(), Qt::DisplayRole);
+ }
+ else {
+ QDoubleSpinBox* w = static_cast<QDoubleSpinBox*>(editor);
+ double v = w->value();
+ if (c->type() & Ctrl::LOG)
+ v /= 20.0;
+ model->setData(index, v, Qt::DisplayRole);
+ }
+ }
+ break;
+ }
+ QItemDelegate::setModelData(editor, model, index);
+ }
+
+//---------------------------------------------------------
+// paint
+//---------------------------------------------------------
+
+void CtrlDelegate::paint(QPainter* painter,
+ const QStyleOptionViewItem& option, const QModelIndex& index) const
+ {
+ QString text;
+ CtrlListEditor* ce = static_cast<CtrlListEditor*>(parent());
+
+ switch(index.column()) {
+ case CtrlListEditor::TICK_COL:
+ {
+ Track* track = ce->getTrack();
+ AL::Pos pos(index.data().toInt(), track->timeType());
+ text = QString("%1").arg(pos.tick());
+ }
+ break;
+ case CtrlListEditor::TIME_COL:
+ {
+ Track* track = ce->getTrack();
+ AL::Pos pos(index.data().toInt(), track->timeType());
+ int measure, beat, tick;
+ pos.mbt(&measure, &beat, &tick);
+ text.sprintf("%04d.%02d.%03u", measure+1, beat+1, tick);
+ }
+ break;
+ case CtrlListEditor::VAL_COL:
+ {
+ Ctrl* c = ce->ctrl();
+ if (c->type() & Ctrl::INT) {
+ text = QString("%1").arg(index.data().toInt());
+ }
+ else {
+ if (c->type() & Ctrl::LOG) {
+ double f = index.data().toDouble();
+ if (f <= -1000.0f)
+ text = tr("off");
+ else
+ text = QString("%1 dB").arg(f * 20.0);
+ }
+ else {
+ text = QString("%1").arg(index.data().toDouble());
+ }
+ }
+ }
+ break;
+ }
+
+ QStyleOptionViewItemV2 opt = setOptions(index, option);
+ const QStyleOptionViewItemV2 *v2 = qstyleoption_cast<const QStyleOptionViewItemV2 *>(&option);
+ opt.features = v2 ? v2->features : QStyleOptionViewItemV2::ViewItemFeatures(QStyleOptionViewItemV2::None);
+
+ painter->save();
+ QVariant value;
+ QRect displayRect;
+ displayRect = option.rect; // textRectangle(painter, d->textLayoutBounds(opt), opt.font, text);
+
+ QRect checkRect;
+ Qt::CheckState checkState = Qt::Unchecked;
+ value = index.data(Qt::CheckStateRole);
+ if (value.isValid()) {
+ checkState = static_cast<Qt::CheckState>(value.toInt());
+ checkRect = check(opt, opt.rect, value);
+ }
+
+ drawBackground(painter, opt, index);
+ drawCheck(painter, opt, checkRect, checkState);
+ drawDisplay(painter, opt, displayRect, text);
+ drawFocus(painter, opt, text.isEmpty() ? QRect() : displayRect);
+ painter->restore();
+ }
+
+
diff --git a/muse_qt4_evolution/muse/liste/ctrllistedit.h b/muse_qt4_evolution/muse/liste/ctrllistedit.h
new file mode 100644
index 00000000..75ed6008
--- /dev/null
+++ b/muse_qt4_evolution/muse/liste/ctrllistedit.h
@@ -0,0 +1,96 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __CTRLLISTEDIT_H__
+#define __CTRLLISTEDIT_H__
+
+#include "al/pos.h"
+#include "listedit.h"
+#include "ui_ctrllistedit.h"
+
+//---------------------------------------------------------
+// CtrlDelegate
+//---------------------------------------------------------
+
+class CtrlDelegate : public QItemDelegate {
+ Q_OBJECT
+
+ virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem&,
+ const QModelIndex& index) const;
+ virtual void setEditorData(QWidget* editor, const QModelIndex&) const;
+ virtual void setModelData(QWidget* editor, QAbstractItemModel*,
+ const QModelIndex&) const;
+ void paint(QPainter*, const QStyleOptionViewItem&,
+ const QModelIndex&) const;
+
+ public:
+ CtrlDelegate(QObject* parent = 0);
+ };
+
+//---------------------------------------------------------
+// EscapeFilter
+//---------------------------------------------------------
+
+class EscapeFilter : public QObject {
+ Q_OBJECT
+ protected:
+ bool eventFilter(QObject*, QEvent*);
+ public:
+ EscapeFilter(QObject* parent = 0): QObject(parent) {}
+ };
+
+//---------------------------------------------------------
+// CtrlListEditor
+//---------------------------------------------------------
+
+class CtrlListEditor : public ListWidget {
+ Q_OBJECT
+
+ Ui::CtrlListEdit le;
+ Track* track;
+ Ctrl* c;
+ bool updateListDisabled;
+ ListEdit* listEdit;
+
+ void updateList();
+
+ private slots:
+ void controllerChanged(int id);
+ void itemActivated(QTreeWidgetItem*,int);
+ void itemChanged(QTreeWidgetItem*,int);
+ void currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*);
+ void insertClicked();
+ void deleteClicked();
+ void nameEdited(const QString&);
+ void minValChanged(double);
+ void maxValChanged(double);
+ void defaultValChanged(double);
+
+ public:
+ CtrlListEditor(ListEdit*, QWidget* parent = 0);
+ virtual void setup(const ListType&);
+ void sendEscape();
+ Ctrl* ctrl() const { return c; }
+ Track* getTrack() const { return track; }
+ enum { TICK_COL, TIME_COL, VAL_COL };
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/liste/ctrllistedit.ui b/muse_qt4_evolution/muse/liste/ctrllistedit.ui
new file mode 100644
index 00000000..27389b7c
--- /dev/null
+++ b/muse_qt4_evolution/muse/liste/ctrllistedit.ui
@@ -0,0 +1,334 @@
+<ui version="4.0" >
+ <class>CtrlListEdit</class>
+ <widget class="QWidget" name="CtrlListEdit" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>341</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="font" >
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text" >
+ <string>Controller:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="controllerName" />
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label_3" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Id:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="ctrlId" >
+ <property name="readOnly" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="moveWithPart" >
+ <property name="text" >
+ <string>move with part</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QCheckBox" name="discreteCheckBox" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>discrete</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="logarithmicCheckBox" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>logarithmic</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="floatCheckBox" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>float</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label_2" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>min:</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDoubleSpinBox" name="minValue" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="l2" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>max:</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDoubleSpinBox" name="maxValue" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="l3" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>default:</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDoubleSpinBox" name="defaultValue" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QTreeWidget" name="ctrlList" >
+ <property name="alternatingRowColors" >
+ <bool>true</bool>
+ </property>
+ <property name="indentation" >
+ <number>0</number>
+ </property>
+ <property name="rootIsDecorated" >
+ <bool>false</bool>
+ </property>
+ <property name="uniformRowHeights" >
+ <bool>true</bool>
+ </property>
+ <property name="itemsExpandable" >
+ <bool>false</bool>
+ </property>
+ <column>
+ <property name="text" >
+ <string>Tick</string>
+ </property>
+ </column>
+ <column>
+ <property name="text" >
+ <string>Time</string>
+ </property>
+ </column>
+ <column>
+ <property name="text" >
+ <string>Value</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QToolButton" name="deleteButton" >
+ <property name="text" >
+ <string>Delete</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="insertButton" >
+ <property name="text" >
+ <string>Insert</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>231</width>
+ <height>29</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/muse_qt4_evolution/muse/liste/ieventdialog.cpp b/muse_qt4_evolution/muse/liste/ieventdialog.cpp
new file mode 100644
index 00000000..a2914ffc
--- /dev/null
+++ b/muse_qt4_evolution/muse/liste/ieventdialog.cpp
@@ -0,0 +1,428 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2007 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include <QColor>
+#include <QDialogButtonBox>
+#include "ieventdialog.h"
+
+InsertEventDialog::InsertEventDialog(const Pos& time, Part* part, Event* ev,
+ QWidget* parent, Qt::WindowFlags f)
+ : QDialog(parent, f) {
+ setWindowTitle("Insert Event Dialog");
+
+ _selectedType = -1;
+
+
+ _part = part;
+
+ _lastDir = QDir::currentPath();
+
+ _mainLayout = new QGridLayout(parent);
+ //event type
+ QLabel* eventTypeLabel = new QLabel("Event Type", parent);
+ _mainLayout->addWidget(eventTypeLabel, 0, 0);
+ _eventTypeComboBox = new QComboBox(parent);
+ for(unsigned i = 0; i < IED_TypeCount; i++) {
+ _typeWidget.push_back(new QWidget(parent));
+ QGridLayout* tLayout = new QGridLayout(_typeWidget[i]);
+ if(i == IED_Note) {
+ _eventTypeComboBox->addItem(NoteSTR);
+ //pitch
+ QLabel* pitchLabel = new QLabel("Pitch", _typeWidget[i]);
+ tLayout->addWidget(pitchLabel, 0, 0);
+ /*_noteLabel = new QLabel("C4", _typeWidget[i]);
+ _noteLabel->setFrameShape(QFrame::Panel);
+ _noteLabel->setFrameShadow(QFrame::Sunken);
+ tLayout->addWidget(_noteLabel, 0, 1);*/
+ _pitchSpinBox = new QSpinBox(_typeWidget[i]);
+ _pitchSpinBox->setMaximum(127);
+ _pitchSpinBox->setMinimum(0);
+ _pitchSpinBox->setValue(ev && ev->type()==Note?ev->pitch():72/*C4*/);
+ tLayout->addWidget(_pitchSpinBox, 0, 1);
+ //Velocity
+ QLabel* velocityLabel = new QLabel("Velocity", _typeWidget[i]);
+ tLayout->addWidget(velocityLabel, 1, 0);
+ _velocitySpinBox = new QSpinBox(_typeWidget[i]);
+ _velocitySpinBox->setMaximum(127);
+ _velocitySpinBox->setMinimum(0);
+ _velocitySpinBox->setValue(ev && ev->type()==Note?ev->velo():70);
+ tLayout->addWidget(_velocitySpinBox, 1, 1);
+ //Velocity Off
+ /*QLabel* veloOffLabel = new QLabel("Velocity Off", _typeWidget[i]);
+ tLayout->addWidget(veloOffLabel, 2, 0);
+ _veloOffSpinBox = new QSpinBox(_typeWidget[i]);
+ _veloOffSpinBox->setMaximum(127);
+ _veloOffSpinBox->setMinimum(0);
+ _veloOffSpinBox->setValue(0);
+ tLayout->addWidget(_veloOffSpinBox, 2, 1);*/
+ //Length
+ QLabel* lengthLabel = new QLabel("Length", _typeWidget[i]);
+ tLayout->addWidget(lengthLabel, 2, 0);
+ _lengthSpinBox = new QSpinBox(_typeWidget[i]);
+ _lengthSpinBox->setMaximum(32768);
+ _lengthSpinBox->setMinimum(1);
+ _lengthSpinBox->setValue(ev && ev->type()==Note?ev->lenTick():384);
+ tLayout->addWidget(_lengthSpinBox, 2, 1);
+ }
+ else if(i == IED_ProgramChange) {
+ _eventTypeComboBox->addItem(ProgramChangeSTR);
+ //TODO
+ QLabel* programChangeEventTODO =
+ new QLabel("TODO : Program change event", _typeWidget[i]);
+ tLayout->addWidget(programChangeEventTODO, 0, 0, 1, 2);
+ }
+ else if(i == IED_ControlChange) {
+ _eventTypeComboBox->addItem(ControlChangeSTR);
+ //TODO
+ QLabel* controlChangeEventTODO =
+ new QLabel("TODO : Control change event", _typeWidget[i]);
+ tLayout->addWidget(controlChangeEventTODO, 0, 0, 1, 2);
+ }
+ else if(i == IED_Sysex) {
+ _eventTypeComboBox->addItem(SysexSTR);
+ //number of sysex
+ QLabel* numOfSysexLabel = new QLabel("Number of Sysex", _typeWidget[i]);
+ tLayout->addWidget(numOfSysexLabel, 0, 0);
+ _sysexCountSpinBox = new QSpinBox(_typeWidget[i]);
+ _sysexCountSpinBox->setMaximum(1024);
+ _sysexCountSpinBox->setMinimum(1);
+ _sysexCountSpinBox->setValue(1);
+ tLayout->addWidget(_sysexCountSpinBox, 0, 1);
+ //current sysex
+ QLabel* curSysexLabel = new QLabel("Current Sysex", _typeWidget[i]);
+ tLayout->addWidget(curSysexLabel, 1, 0);
+ _curSysexSpinBox = new QSpinBox(_typeWidget[i]);
+ _curSysexSpinBox->setMaximum(0);
+ _curSysexSpinBox->setMinimum(0);
+ _curSysexSpinBox->setValue(0);
+ tLayout->addWidget(_curSysexSpinBox, 1, 1);
+ //select from the instrument
+ QPushButton* selectButton = new QPushButton("Select from instrument",
+ _typeWidget[i]);
+ tLayout->addWidget(selectButton, 2, 0, 1, 2);
+ //load
+ _loadButton = new QPushButton("Load...", _typeWidget[i]);
+ tLayout->addWidget(_loadButton, 3, 0);
+ //save
+ _saveButton = new QPushButton("Save...", _typeWidget[i]);
+ tLayout->addWidget(_saveButton, 3, 1);
+ //length
+ QLabel* lengthLabel = new QLabel("Length", _typeWidget[i]);
+ tLayout->addWidget(lengthLabel, 4, 0);
+ _lengthIntLabel = new QLabel(ev && ev->type()==Sysex?
+ QString::number(ev->dataLen()):"0",
+ _typeWidget[i]);
+ tLayout->addWidget(_lengthIntLabel, 4, 1);
+ //text edit
+ _sysexTextEdit = new QTextEdit(_typeWidget[i]);
+ _sysexCursorPos = 0;
+ _dataSysex.push_back(ev && ev->type()==Sysex?
+ QByteArray((const char*)ev->data(), ev->dataLen())
+ :QByteArray());
+ _lengthIntLabel->setText(QString::number(sysexLength()));
+ _dataSysexStr.push_back(ev && ev->type()==Sysex?
+ charArray2Str((const char*)ev->data(),
+ ev->dataLen()):
+ "F0 F7");
+ tLayout->addWidget(_sysexTextEdit, 5, 0, 3, 2);
+ setSysexTextEdit();
+ QString HEX = "(?!F7)([A-F]|\\d){1,2}";
+ QString SRE = QString("^F0(\\s+)(") + HEX + QString("(\\s+))*F7$");
+ _hexRegExp = new QRegExp(SRE, Qt::CaseInsensitive);
+ }
+ tLayout->setMargin(0);
+ _typeWidget[i]->setLayout(tLayout);
+ _mainLayout->addWidget(_typeWidget[i], 2, 0, 1, 2);
+ }
+ _mainLayout->addWidget(_eventTypeComboBox, 0, 1);
+ //time
+ QLabel* timeLabel = new QLabel("Time", parent);
+ _mainLayout->addWidget(timeLabel, 1, 0);
+ _timePosEdit = new PosEdit(parent);
+ _timePosEdit->setValue(time);
+ _mainLayout->addWidget(_timePosEdit, 1, 1);
+ //Ok, cancel
+ QDialogButtonBox* OkCancelBox =
+ new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
+ Qt::Horizontal, parent);
+ _mainLayout->addWidget(OkCancelBox, 3, 0, 1, 2);
+
+ if(ev)
+ if(ev->type()==Note) _eventTypeComboBox->setCurrentIndex(IED_Note);
+ else if(ev->type()==Sysex) _eventTypeComboBox->setCurrentIndex(IED_Sysex);
+ else _eventTypeComboBox->setCurrentIndex(IED_Note);
+ else _eventTypeComboBox->setCurrentIndex(IED_Note);
+
+ updateType(_eventTypeComboBox->currentIndex());
+
+ setLayout(_mainLayout);
+
+ //connection
+ connect(_sysexTextEdit, SIGNAL(textChanged()), this,
+ SLOT(updateSysexTextEdit()));
+ connect(_sysexTextEdit, SIGNAL(cursorPositionChanged()), this,
+ SLOT(updateSysexCursor()));
+ connect(_eventTypeComboBox, SIGNAL(currentIndexChanged(int)), this,
+ SLOT(updateType(int)));
+ connect(_sysexCountSpinBox, SIGNAL(valueChanged(int)), this,
+ SLOT(updateSysexCount(int)));
+ connect(_curSysexSpinBox, SIGNAL(valueChanged(int)), this,
+ SLOT(updateCurSysexSpinBox(int)));
+ connect(_loadButton, SIGNAL(clicked()), this, SLOT(updateSysexLoad()));
+ connect(_saveButton, SIGNAL(clicked()), this, SLOT(updateSysexSave()));
+ connect(OkCancelBox, SIGNAL(accepted()), this, SLOT(accept()));
+ connect(OkCancelBox, SIGNAL(rejected()), this, SLOT(reject()));
+}
+
+InsertEventDialog::~InsertEventDialog() {
+}
+
+EventList* InsertEventDialog::elResult() {
+ unsigned evTick;
+ evTick = (unsigned)IED_MAX(0, (int)_timePosEdit->pos().tick()
+ - (int)_part->tick());
+ Pos evPos(evTick);
+ EventList* res = new EventList;
+
+ int curType = _eventTypeComboBox->currentIndex();
+
+ if(curType == IED_Note) {
+ Event evNote(Note);
+ evNote.setPos(evPos);
+ evNote.setPitch(_pitchSpinBox->value());
+ evNote.setVelo(_velocitySpinBox->value());
+ //evNote.setVeloOff(_veloOffSpinBox->value());
+ evNote.setLenTick(_lengthSpinBox->value());
+ res->add(evNote);
+ return res;
+ }
+ else if(curType == IED_ProgramChange) {
+ //TODO
+ return NULL;
+ }
+ else if(curType == IED_ControlChange) {
+ //TODO
+ return NULL;
+ }
+ else if(curType == IED_Sysex) {
+ for(unsigned i = 0; (int)i < _sysexCountSpinBox->value(); i++) {
+ Event evSysex(Sysex);
+ evSysex.setPos(evPos);
+ evSysex.setData((const unsigned char*) _dataSysex[i].data(),
+ _dataSysex[i].size());
+ res->add(evSysex);
+ }
+ return res;
+ }
+ else return NULL;
+}
+
+int InsertEventDialog::sysexLength() {
+ return _dataSysex[_curSysexSpinBox->value()].size();
+}
+QString InsertEventDialog::charArray2Str(const char* s, int length) {
+ return ByteArray2Str(QByteArray(s, length));
+}
+QString InsertEventDialog::ByteArray2Str(const QByteArray& ba) {
+ QString res = "F0 ";
+ for(int i = 0; i < ba.size(); i++) {
+ res += QString::number((unsigned char)ba.at(i), 16);
+ res += " ";
+ }
+ res += "F7";
+ return res.toUpper();
+}
+QByteArray InsertEventDialog::Str2ByteArray(const QString& s) {
+ QByteArray ba;
+ QString simpli = s.simplified();
+ QStringList sl = simpli.split(" ");
+ bool ok;
+ for(int i = 1; i < sl.size() - 1; i++) {//i=1 and until size-1 to skip F0, F7
+ ba.push_back(sl[i].toInt(&ok, 16));
+ }
+ return ba;
+}
+char* InsertEventDialog::Str2CharArray(const QString& s) {
+ return Str2ByteArray(s).data();
+}
+
+void InsertEventDialog::setSysexTextEdit() {
+ QString s = _dataSysexStr[_curSysexSpinBox->value()].toUpper();
+ _sysexTextEdit->blockSignals(true);
+ //print in gray F0
+ _sysexTextEdit->setTextColor(Qt::darkGray);
+ _sysexTextEdit->setPlainText(s.left(2));
+ //move cursor at the end
+ QTextCursor tc1(_sysexTextEdit->document());
+ tc1.movePosition(QTextCursor::End);
+ _sysexTextEdit->setTextCursor(tc1);
+ //print in black the core
+ _sysexTextEdit->setTextColor(Qt::black);
+ _sysexTextEdit->insertPlainText(s.mid(2, s.size()-4));
+ //move cursor at the end
+ QTextCursor tc2(_sysexTextEdit->document());
+ tc2.movePosition(QTextCursor::End);
+ _sysexTextEdit->setTextCursor(tc2);
+ //print in gray F7
+ _sysexTextEdit->setTextColor(Qt::darkGray);
+ _sysexTextEdit->insertPlainText(s.right(2));
+ //relocate cursor
+ QTextCursor tc(_sysexTextEdit->document());
+ tc.setPosition(_sysexCursorPos);
+ _sysexTextEdit->setTextCursor(tc);
+ //update length label
+ _lengthIntLabel->setText(QString::number(sysexLength()));
+
+ _sysexTextEdit->blockSignals(false);
+}
+
+//SLOTS
+void InsertEventDialog::updateSysexTextEdit() {
+ int cur = _curSysexSpinBox->value();
+ int curCursor = _sysexTextEdit->textCursor().position();
+ QString data = _sysexTextEdit->toPlainText();
+ bool correctInput = _hexRegExp->exactMatch(data);
+
+ if(correctInput) {
+ _dataSysexStr[cur] = data;
+ _sysexCursorPos = curCursor;
+ }
+
+ //display text, relocate cursor and update length
+ setSysexTextEdit();
+ //update _dataSysex
+ _dataSysex[cur] = Str2ByteArray(_dataSysexStr[cur]);
+}
+void InsertEventDialog::updateSysexCursor() {
+ if(_dataSysexStr[_curSysexSpinBox->value()]
+ == _sysexTextEdit->toPlainText()) //only if the text hasn't changed
+ _sysexCursorPos = _sysexTextEdit->textCursor().position();
+}
+void InsertEventDialog::updateSysexCount(int c) {
+ while((int)_dataSysexStr.size() < c) {
+ _dataSysexStr.push_back(QString("F0 F7"));
+ QByteArray ba;
+ _dataSysex.push_back(ba);
+ }
+ if(c <= _curSysexSpinBox->value()) _curSysexSpinBox->setValue(c-1);
+ _curSysexSpinBox->setMaximum(c-1);
+}
+void InsertEventDialog::updateCurSysexSpinBox(int /*c*/) {
+ setSysexTextEdit();
+}
+void InsertEventDialog::updateSysexLoad() {
+ QByteArray ba;
+ QString fileName =
+ QFileDialog::getOpenFileName(this,
+ tr("Load Sysex dialog"),
+ _lastDir,
+ QString("*.syx;; *"));
+ if(!fileName.isEmpty()) {
+ QFileInfo fi(fileName);
+ _lastDir = fi.path();
+
+ QFile f(fileName);
+ if(f.open(QIODevice::ReadOnly)) {
+ ba = f.readAll();
+ bool sysexStart = false;
+ int sysexCount = 0;
+ for(int i = 0; i < ba.size(); i++) {
+ if((unsigned char)ba.at(i) == 0xF0) {
+ sysexStart = true;
+ sysexCount++;
+ while((int)_dataSysex.size() < sysexCount) {
+ QByteArray tempba;
+ _dataSysex.push_back(tempba);
+ _dataSysexStr.push_back(QString(""));
+ }
+ _dataSysex[sysexCount-1].clear();
+ }
+ else if((unsigned char)ba.at(i) == 0xF7) {
+ QByteArray endba(_dataSysex[sysexCount-1]);
+ sysexStart = false;
+ _dataSysexStr[sysexCount-1] = ByteArray2Str(endba);
+ }
+ else if(sysexStart) _dataSysex[sysexCount-1].push_back(ba.at(i));
+ }
+ _sysexCountSpinBox->setValue(sysexCount);
+ _curSysexSpinBox->setValue(0);
+ updateCurSysexSpinBox(0);
+ //Message dialog
+ if(sysexCount > 0) {
+ QMessageBox::information(this, tr("Sysex loaded"),
+ tr("MusE has successfully detected"
+ " and loaded ") +
+ QString::number(sysexCount) +
+ tr(" sysex messages."));
+ }
+ else {
+ QMessageBox::information(this, tr("No sysex"),
+ tr("No sysex in this file"));
+ }
+ }
+ else {
+ QMessageBox::critical(0,
+ tr("Critical Error"),
+ tr("Cannot open file %1").arg(fileName));
+ }
+ }
+}
+void InsertEventDialog::updateSysexSave() {
+ QString filename =
+ QFileDialog::getSaveFileName(
+ this,
+ tr("Save Sysex Dialog"),
+ _lastDir,
+ QString("*"));
+ if(!filename.isEmpty()) {
+ QFileInfo fi(filename);
+ _lastDir = fi.path();
+ QFile f(filename);
+ if(f.open(QIODevice::WriteOnly)) {
+ for(unsigned i = 0; i < _dataSysex.size(); i++) {
+ qint64 wok;
+ wok = f.write(QByteArray(1, 0xF0));
+ wok = f.write(_dataSysex[i]);
+ wok = f.write(QByteArray(1, 0xF7));
+ if(wok == -1) {
+ QMessageBox::critical(0,
+ tr("Critical Error"),
+ tr("Cannot write the sysex number %1")
+ .arg(i));
+ }
+ }
+ }
+ else {
+ QMessageBox::critical(0,
+ tr("Critical Error"),
+ tr("Cannot save file %1").arg(filename));
+ }
+ }
+}
+void InsertEventDialog::updateType(int type) {
+ if(_selectedType != type) {
+ for(unsigned i = 0; i < IED_TypeCount; i++) {
+ if(type == (int)i) _typeWidget[i]->show();
+ else _typeWidget[i]->hide();
+ }
+ _selectedType = type;
+ resize(1, 1);
+ }
+}
diff --git a/muse_qt4_evolution/muse/liste/ieventdialog.h b/muse_qt4_evolution/muse/liste/ieventdialog.h
new file mode 100644
index 00000000..7906f6c9
--- /dev/null
+++ b/muse_qt4_evolution/muse/liste/ieventdialog.h
@@ -0,0 +1,117 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2007 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __IEVENTDIALOG_H__
+#define __IEVENTDIALOG_H__
+
+#include <QDialog>
+#include <vector>
+#include <QStringList>
+#include <QLineEdit>
+#include <QTextEdit>
+#include <QRegExp>
+#include <QDir>
+#include "awl/posedit.h"
+#include "midievent.h"
+#include "al/pos.h"
+#include "muse/event.h"
+#include "muse/part.h"
+
+class QDialog;
+using Awl::PosEdit;
+using AL::Pos;
+
+#define NoteSTR "Note"
+#define ProgramChangeSTR "Program change"
+#define ControlChangeSTR "Control change"
+#define SysexSTR "Sysex"
+
+#define IED_MAX(x, y) (x > y? x : y)
+
+class InsertEventDialog : public QDialog {
+ Q_OBJECT
+
+ QGridLayout* _mainLayout;
+ std::vector<QWidget*> _typeWidget;
+ int _selectedType;
+
+ QString _lastDir;
+
+ Part* _part;
+
+
+ //event type
+ QComboBox* _eventTypeComboBox;
+
+ //time
+ PosEdit* _timePosEdit;
+
+ //Note
+ QSpinBox* _pitchSpinBox;
+ QSpinBox* _velocitySpinBox;
+ QSpinBox* _veloOffSpinBox;
+ QSpinBox* _lengthSpinBox;
+ //QLabel* _noteLabel;
+
+ //Sysex
+ QSpinBox* _sysexCountSpinBox;
+ QSpinBox* _curSysexSpinBox;
+ QLabel* _lengthIntLabel;
+ QTextEdit* _sysexTextEdit;
+ QRegExp* _hexRegExp;
+ int _sysexCursorPos;
+ QPushButton* _loadButton;
+ QPushButton* _saveButton;
+ std::vector<QByteArray> _dataSysex;
+ std::vector<QString> _dataSysexStr;
+
+ enum {
+ IED_Note,
+ IED_ProgramChange,
+ IED_ControlChange,
+ IED_Sysex,
+ IED_TypeCount };
+
+ int sysexLength(); //return the length of the current sysex
+ void setSysexTextEdit(); //set the display of sysexTextEdit
+
+ public:
+ InsertEventDialog(const Pos& time, Part* part, Event* ev = NULL,
+ QWidget* parent = 0, Qt::WindowFlags f = 0);
+ ~InsertEventDialog();
+
+ EventList* elResult();
+
+ static QString charArray2Str(const char* s, int length); //add F0 and F7
+ static QString ByteArray2Str(const QByteArray& ba); //add F0 and F7
+ static QByteArray Str2ByteArray(const QString& s); //skip F0 and F7
+ static char* Str2CharArray(const QString& s);
+
+ private slots:
+ void updateSysexTextEdit();
+ void updateSysexCursor();
+ void updateSysexCount(int c);
+ void updateCurSysexSpinBox(int c);
+ void updateSysexLoad();
+ void updateSysexSave();
+ void updateType(int type);
+};
+
+#endif
diff --git a/muse_qt4_evolution/muse/liste/listedit.cpp b/muse_qt4_evolution/muse/liste/listedit.cpp
new file mode 100644
index 00000000..1f6138a8
--- /dev/null
+++ b/muse_qt4_evolution/muse/liste/listedit.cpp
@@ -0,0 +1,298 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "listedit.h"
+#include "ctrllistedit.h"
+#include "partlistedit.h"
+#include "tracklistedit.h"
+#include "song.h"
+#include "part.h"
+#include "ctrl.h"
+
+//---------------------------------------------------------
+// operator==
+//---------------------------------------------------------
+
+bool ListType::operator==(const ListType& t) const
+ {
+ return id == t.id && track == t.track
+ && part == t.part && (ctrl ? ctrl->id() == t.ctrl->id() : true);
+ }
+
+//---------------------------------------------------------
+// ListEdit
+//---------------------------------------------------------
+
+ListEdit::ListEdit(QWidget*)
+ : TopWin()
+ {
+ setWindowTitle(tr("MusE: List Edit"));
+
+ QSplitter* split = new QSplitter;
+ split->setOpaqueResize(true);
+ setCentralWidget(split);
+
+ list = new QTreeWidget;
+ list->setColumnCount(1);
+ list->setSelectionMode(QAbstractItemView::SingleSelection);
+ list->setRootIsDecorated(true);
+ list->setColumnCount(1);
+ list->setHeaderLabels(QStringList("Element"));
+ list->setSortingEnabled(false);
+ list->setUniformRowHeights(true);
+ split->addWidget(list);
+
+ stack = new QStackedWidget;
+ split->addWidget(stack);
+
+ ctrlPanel = new CtrlListEditor(this);
+ stack->addWidget(ctrlPanel);
+ partPanel = new PartListEditor(this);
+ stack->addWidget(partPanel);
+ trackPanel = new TrackListEditor(this);
+ stack->addWidget(trackPanel);
+
+ connect(list, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)),
+ SLOT(itemChanged(QTreeWidgetItem*,QTreeWidgetItem*)));
+ connect(list, SIGNAL(itemExpanded(QTreeWidgetItem*)), SLOT(itemExpanded(QTreeWidgetItem*)));
+ connect(list, SIGNAL(itemCollapsed(QTreeWidgetItem*)), SLOT(itemExpanded(QTreeWidgetItem*)));
+ connect(song, SIGNAL(songChanged(int)), SLOT(songChanged(int)));
+ list->resizeColumnToContents(0);
+ resize(900, 400);
+ }
+
+//---------------------------------------------------------
+// itemExpanded
+//---------------------------------------------------------
+
+void ListEdit::itemExpanded(QTreeWidgetItem*)
+ {
+ list->resizeColumnToContents(0);
+ }
+
+//---------------------------------------------------------
+// itemChanged
+//---------------------------------------------------------
+
+void ListEdit::itemChanged(QTreeWidgetItem* i, QTreeWidgetItem*)
+ {
+ if (i == 0)
+ return;
+ ListWidget* ew = ctrlPanel;
+ lt = i->data(0, Qt::UserRole).value<ListType>();
+ switch(lt.id) {
+ case LIST_TRACK:
+ ew = trackPanel;
+ break;
+ case LIST_PART:
+ ew = partPanel;
+ break;
+ case LIST_CTRL:
+ ew = ctrlPanel;
+ break;
+ default:
+ return;
+ }
+ ew->setup(lt);
+ stack->setCurrentWidget(ew);
+ }
+
+//---------------------------------------------------------
+// buildList
+//---------------------------------------------------------
+
+void ListEdit::buildList()
+ {
+ list->clear();
+ TrackList* tl = song->tracks();
+ int idx = 0;
+ ListType lt;
+
+ for (iTrack i = tl->begin(); i != tl->end(); ++i,++idx) {
+ QTreeWidgetItem* item = new QTreeWidgetItem;
+ Track* t = *i;
+ item->setText(0, t->name());
+ lt.id = LIST_TRACK;
+ lt.track = t;
+ item->setData(0, Qt::UserRole, QVariant::fromValue(lt));
+ list->insertTopLevelItem(idx, item);
+
+ PartList* pl = t->parts();
+ if (!pl->empty()) {
+ QTreeWidgetItem* pitem = new QTreeWidgetItem(item);
+ pitem->setFlags(pitem->flags() & ~Qt::ItemIsSelectable);
+ pitem->setText(0, tr("Parts"));
+ lt.id = LIST_NONE;
+ pitem->setData(0, Qt::UserRole, QVariant::fromValue(lt));
+ for (iPart pi = pl->begin(); pi != pl->end(); ++pi) {
+ lt.id = LIST_PART;
+ lt.part = pi->second;
+ QTreeWidgetItem* ppitem = new QTreeWidgetItem(pitem);
+ ppitem->setData(0, Qt::UserRole, QVariant::fromValue(lt));
+ ppitem->setText(0, pi->second->name());
+ }
+ }
+
+ CtrlList* cl = t->controller();
+ lt.part = 0;
+ if (!cl->empty()) {
+ QTreeWidgetItem* citem = new QTreeWidgetItem(item);
+ citem->setText(0, tr("Controller"));
+ citem->setFlags(citem->flags() & ~Qt::ItemIsSelectable);
+ lt.id = LIST_NONE;
+ citem->setData(0, Qt::UserRole, QVariant::fromValue(lt));
+ for (iCtrl ci = cl->begin(); ci != cl->end(); ++ci) {
+ QTreeWidgetItem* ccitem = new QTreeWidgetItem(citem);
+ ccitem->setText(0, ci->second->name());
+ lt.id = LIST_CTRL;
+ lt.ctrl = ci->second;
+ ccitem->setData(0, Qt::UserRole, QVariant::fromValue(lt));
+ }
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// songChanged
+//---------------------------------------------------------
+
+void ListEdit::songChanged(int flags)
+ {
+ if (flags & (SC_TRACK_INSERTED | SC_TRACK_REMOVED | SC_PART_INSERTED
+ | SC_PART_REMOVED)) {
+ buildList();
+ selectItem();
+ }
+ }
+
+//---------------------------------------------------------
+// findItem
+//---------------------------------------------------------
+
+QTreeWidgetItem* ListEdit::findItem(const ListType& lt, QTreeWidgetItem* item)
+ {
+ if (item->flags() & Qt::ItemIsSelectable) {
+ if (lt == item->data(0, Qt::UserRole).value<ListType>())
+ return item;
+ }
+ for (int n = 0; n < item->childCount(); ++n) {
+ QTreeWidgetItem* i = findItem(lt, item->child(n));
+ if (i)
+ return i;
+ }
+ return 0;
+ }
+
+//---------------------------------------------------------
+// selectItem
+//---------------------------------------------------------
+
+void ListEdit::selectItem(const AL::Pos& p, Track* track, Part* part, Ctrl* ctrl)
+ {
+ _pos = p;
+ stack->setCurrentWidget(ctrlPanel);
+ if (ctrl)
+ lt.id = LIST_CTRL;
+ else if (part)
+ lt.id = LIST_PART;
+ else if (track)
+ lt.id = LIST_TRACK;
+ else
+ return;
+ lt.track = track;
+ lt.part = part;
+ lt.ctrl = ctrl;
+ selectItem();
+ }
+
+void ListEdit::selectItem()
+ {
+ stack->setCurrentWidget(ctrlPanel);
+ buildList();
+ for (int i = 0;; ++i) {
+ QTreeWidgetItem* item = list->topLevelItem(i);
+ if (item == 0) {
+ printf("MusE::ListEdit: Element not found\n");
+ break;
+ }
+ item = findItem(lt, item);
+ if (item) {
+ list->setItemExpanded(item, true);
+ list->setCurrentItem(item);
+ list->scrollToItem(item);
+ break;
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// readStatus
+//---------------------------------------------------------
+
+void ListEdit::read(QDomNode node)
+ {
+ QString trackName;
+ Track* track = 0;
+ Part* part = 0;
+ Ctrl* ctrl = 0;
+
+ for (node = node.firstChild(); !node.isNull(); node = node.nextSibling()) {
+ QDomElement e = node.toElement();
+ QString tag(e.tagName());
+ if (tag == "Track") {
+ track = song->findTrack(e.text());
+ if (track == 0) {
+ printf("MusE::ListEdit::read: track not found\n");
+ }
+ }
+ else if (tag == "Pos")
+ _pos.read(node);
+ else if (tag == "Ctrl") {
+ int ctrlId = e.text().toInt();
+ ctrl = track->getController(ctrlId);
+ if (ctrl == 0) {
+ printf("MusE::ListEdit::read: controller not found: track %p\n", track);
+ printf("MusE::ListEdit::read: controller %d not found\n", ctrlId);
+ return;
+ }
+ }
+ else
+ AL::readProperties(this, node);
+ }
+ selectItem(_pos, track, part, ctrl);
+ }
+
+//---------------------------------------------------------
+// write
+//---------------------------------------------------------
+
+void ListEdit::write(Xml& xml) const
+ {
+ xml.stag(metaObject()->className());
+ xml.writeProperties(this);
+
+ xml.tag("Track", lt.track->name());
+ if (lt.ctrl) {
+ xml.tag("Ctrl", lt.ctrl->id());
+ _pos.write(xml, "Pos");
+ }
+ xml.etag(metaObject()->className());
+ }
+
diff --git a/muse_qt4_evolution/muse/liste/listedit.h b/muse_qt4_evolution/muse/liste/listedit.h
new file mode 100644
index 00000000..b49e61c3
--- /dev/null
+++ b/muse_qt4_evolution/muse/liste/listedit.h
@@ -0,0 +1,98 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __LISTEDIT_H__
+#define __LISTEDIT_H__
+
+#include "al/pos.h"
+#include "cobject.h"
+
+class Track;
+class Part;
+class Ctrl;
+class CtrlListEditor;
+class PartListEditor;
+class TrackListEditor;
+
+//---------------------------------------------------------
+// ListType
+//---------------------------------------------------------
+
+enum { LIST_NONE, LIST_TRACK, LIST_PART, LIST_CTRL };
+
+struct ListType {
+ int id;
+ Track* track;
+ Part* part;
+ Ctrl* ctrl;
+
+ bool operator==(const ListType& t) const;
+ };
+
+Q_DECLARE_METATYPE(struct ListType);
+
+//---------------------------------------------------------
+// ListWidget
+// interface class
+//---------------------------------------------------------
+
+class ListWidget : public QWidget {
+ Q_OBJECT;
+
+ public:
+ ListWidget(QWidget* = 0) {}
+ virtual void setup(const ListType&) = 0;
+ };
+
+//---------------------------------------------------------
+// ListEdit
+//---------------------------------------------------------
+
+class ListEdit : public TopWin {
+ Q_OBJECT;
+
+ ListType lt;
+ AL::Pos _pos;
+
+ QStackedWidget* stack;
+ QTreeWidget* list;
+ CtrlListEditor* ctrlPanel;
+ PartListEditor* partPanel;
+ TrackListEditor* trackPanel;
+
+ void buildList();
+ QTreeWidgetItem* findItem(const ListType& lt, QTreeWidgetItem* item);
+ void selectItem();
+
+ private slots:
+ void itemChanged(QTreeWidgetItem*, QTreeWidgetItem*);
+ void itemExpanded(QTreeWidgetItem*);
+ void songChanged(int);
+
+ public:
+ ListEdit(QWidget* parent = 0);
+ void selectItem(const AL::Pos&, Track*, Part*, Ctrl*);
+ virtual void read(QDomNode);
+ virtual void write(Xml& xml) const;
+ AL::Pos& pos() { return _pos; }
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/liste/partlistedit.cpp b/muse_qt4_evolution/muse/liste/partlistedit.cpp
new file mode 100644
index 00000000..d3db4de2
--- /dev/null
+++ b/muse_qt4_evolution/muse/liste/partlistedit.cpp
@@ -0,0 +1,434 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "partlistedit.h"
+#include "track.h"
+#include "song.h"
+#include "al/pos.h"
+#include "awl/posedit.h"
+#include "part.h"
+
+//---------------------------------------------------------
+// PartListEditor
+//---------------------------------------------------------
+
+PartListEditor::PartListEditor(ListEdit* e, QWidget* parent)
+ : ListWidget(parent)
+ {
+ listEdit = e;
+ updateListDisabled = false;
+ curEvent = NULL;
+ QWidget* cew = new QWidget;
+ le.setupUi(cew);
+ QVBoxLayout* layout = new QVBoxLayout;
+ layout->addWidget(cew);
+ setLayout(layout);
+
+ QFontMetrics fm(le.eventList->font());
+ int zW = fm.width("0");
+ le.eventList->setColumnWidth(TICK_COL, zW * 8);
+ le.eventList->setColumnWidth(TIME_COL, zW * 14);
+ EventDelegate* eventDelegate = new EventDelegate(this);
+ le.eventList->setItemDelegate(eventDelegate);
+
+ part = 0;
+
+ connect(le.eventList, SIGNAL(itemActivated(QTreeWidgetItem*, int)),
+ SLOT(itemActivated(QTreeWidgetItem*,int)));
+ connect(le.eventList, SIGNAL(itemChanged(QTreeWidgetItem*, int)),
+ SLOT(itemChanged(QTreeWidgetItem*, int)));
+ connect(le.eventList,
+ SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)),
+ SLOT(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)));
+ connect(le.insertButton, SIGNAL(clicked()), SLOT(insertClicked()));
+ connect(le.deleteButton, SIGNAL(clicked()), SLOT(deleteClicked()));
+ }
+
+//---------------------------------------------------------
+// getTrack
+//---------------------------------------------------------
+
+Track* PartListEditor::getTrack() const
+ {
+ return part->track();
+ }
+
+//---------------------------------------------------------
+// setup
+//---------------------------------------------------------
+
+void PartListEditor::setup(const ListType& lt)
+ {
+ part = lt.part;
+ le.partName->setText(part->name());
+ updateList();
+ }
+
+//---------------------------------------------------------
+// updateList
+//---------------------------------------------------------
+
+void PartListEditor::updateList() {
+ if(updateListDisabled) {
+ updateListDisabled = false;
+ return;
+ }
+ EventList* el = part->events();
+ int idx = 0;
+ le.eventList->clear();
+ for (iEvent i = el->begin(); i != el->end(); ++i, ++idx) {
+ Event e = i->second;
+ QTreeWidgetItem* item = new QTreeWidgetItem;
+ item->setData(TICK_COL, Qt::TextAlignmentRole,
+ int(Qt::AlignRight | Qt::AlignVCenter));
+ item->setData(TIME_COL, Qt::TextAlignmentRole,
+ int(Qt::AlignRight | Qt::AlignVCenter));
+ item->setData(TICK_COL, Qt::DisplayRole, e.tick() + part->tick());
+ item->setData(TIME_COL, Qt::DisplayRole, e.tick() + part->tick());
+ item->setData(TYPE_COL, Qt::TextAlignmentRole,
+ int(Qt::AlignRight | Qt::AlignVCenter));
+ item->setData(TYPE_COL, Qt::DisplayRole, e.eventTypeName());
+ item->setData(A_COL, Qt::TextAlignmentRole,
+ int(Qt::AlignHCenter | Qt::AlignVCenter));
+ if(e.type()!=Sysex) item->setData(A_COL, Qt::DisplayRole, e.dataA());
+ item->setData(B_COL, Qt::TextAlignmentRole,
+ int(Qt::AlignHCenter | Qt::AlignVCenter));
+ if(e.type()!=Sysex) item->setData(B_COL, Qt::DisplayRole, e.dataB());
+ item->setData(C_COL, Qt::TextAlignmentRole,
+ int(Qt::AlignHCenter | Qt::AlignVCenter));
+ if(e.type()!=Sysex) item->setData(C_COL, Qt::DisplayRole, e.dataC());
+ item->setData(LEN_COL, Qt::TextAlignmentRole,
+ int(Qt::AlignHCenter | Qt::AlignVCenter));
+ item->setData(LEN_COL, Qt::DisplayRole,
+ (e.type()==Sysex?e.dataLen():e.lenTick()));
+ QString dataStr;
+ if(e.type()==Sysex)
+ dataStr = InsertEventDialog::charArray2Str((const char*)e.data(),
+ e.dataLen());
+ else dataStr = QString("");
+ item->setText(DATA_COL, dataStr);
+ le.eventList->insertTopLevelItem(idx, item);
+ }
+}
+
+//---------------------------------------------------------
+// item2Event
+//---------------------------------------------------------
+
+Event* PartListEditor::item2Event(QTreeWidgetItem* item, int time_col) {
+ if(item) {
+ int tick;
+ if(time_col == TICK_COL)
+ tick = item->data(TICK_COL, Qt::DisplayRole).toInt();
+ else tick = item->data(TIME_COL, Qt::DisplayRole).toInt();
+ int evTick = (unsigned)IED_MAX(0, (int)tick - (int)part->tick());
+ QString type = item->text(TYPE_COL);
+ if(type == "Note") {
+ Event* ev = new Event(Note);
+ int pitch = item->data(A_COL, Qt::DisplayRole).toInt();
+ int velo = item->data(B_COL, Qt::DisplayRole).toInt();
+ int len = item->data(LEN_COL, Qt::DisplayRole).toInt();
+ ev->setTick(evTick);
+ ev->setPitch(pitch);
+ ev->setVelo(velo);
+ ev->setLenTick(len);
+ return ev;
+ }
+ else if(type == "Sysex") {
+ Event* ev = new Event(Sysex);
+ QString dataStr = item->text(DATA_COL);
+ char* data = InsertEventDialog::Str2CharArray(dataStr);
+ int len = item->data(LEN_COL, Qt::DisplayRole).toInt();
+ ev->setTick(evTick);
+ ev->setData((const unsigned char*)data, len);
+ return ev;
+ }
+ else return NULL;
+ }
+ else return NULL;
+}
+
+//---------------------------------------------------------
+// itemActivated
+//---------------------------------------------------------
+
+void PartListEditor::itemActivated(QTreeWidgetItem* item, int column) {
+ AL::Pos time;
+ int tick = item->data(TIME_COL, Qt::DisplayRole).toInt();
+ time.setTick(tick);
+ Event* ev = item2Event(item);
+ EventList* el;
+
+ if(column == TYPE_COL) {
+ InsertEventDialog dialog(time, part, ev, this);
+ if(dialog.exec() == QDialog::Accepted) {
+ el = dialog.elResult();
+ if(el) {
+ if(ev) song->deleteEvent(*ev, part);
+ for(iEvent ie = el->begin(); ie != el->end(); ie++) {
+ Event e = ie->second;
+ song->addEvent(e, part);
+ }
+ }
+ }
+ }
+ else if((column==A_COL || column==B_COL || column==C_COL || column==LEN_COL)
+ && ev && ev->type()==Sysex) {
+ //DO NOTHING
+ }
+ else if(column == DATA_COL) {
+ if(ev && ev->type()==Sysex) {
+ InsertEventDialog dialog(time, part, ev, this);
+ if(dialog.exec() == QDialog::Accepted) {
+ el = dialog.elResult();
+ if(el) {
+ if(ev) song->deleteEvent(*ev, part);
+ for(iEvent ie = el->begin(); ie != el->end(); ie++) {
+ Event e = ie->second;
+ song->addEvent(e, part);
+ }
+ }
+ }
+ }
+ }
+ else le.eventList->openPersistentEditor(item, column);
+}
+
+//---------------------------------------------------------
+// itemChanged
+//---------------------------------------------------------
+
+void PartListEditor::itemChanged(QTreeWidgetItem* item, int column) {
+ updateListDisabled = (column != TICK_COL && column != TIME_COL);
+ if(item) {
+ Event* newEvent = item2Event(item, column);
+ song->changeEvent(*curEvent, *newEvent, part);
+ }
+}
+
+//---------------------------------------------------------
+// currentItemChanged
+//---------------------------------------------------------
+
+void PartListEditor::currentItemChanged(QTreeWidgetItem* cur,
+ QTreeWidgetItem* pre) {
+ if(pre) {
+ le.eventList->closePersistentEditor(pre, TICK_COL);
+ le.eventList->closePersistentEditor(pre, TIME_COL);
+ le.eventList->closePersistentEditor(pre, A_COL);
+ le.eventList->closePersistentEditor(pre, B_COL);
+ le.eventList->closePersistentEditor(pre, C_COL);
+ le.eventList->closePersistentEditor(pre, LEN_COL);
+ }
+ if(cur) {
+ curEvent = item2Event(cur);
+ }
+}
+
+//---------------------------------------------------------
+// insertClicked
+// insert one tick before current value
+//---------------------------------------------------------
+
+void PartListEditor::insertClicked()
+ {
+ QTreeWidgetItem* cur = le.eventList->currentItem();
+ AL::Pos time;
+ if(cur) {
+ int tick = cur->data(TIME_COL, Qt::DisplayRole).toInt();
+ time.setTick(tick);
+ }
+
+ EventList* el;
+
+ InsertEventDialog dialog(time, part, NULL, this);
+ if(dialog.exec() == QDialog::Accepted) {
+ el = dialog.elResult();
+ if(el) {
+ for(iEvent ie = el->begin(); ie != el->end(); ie++) {
+ Event e = ie->second;
+ song->addEvent(e, part);
+ }
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// deleteClicked
+//---------------------------------------------------------
+
+void PartListEditor::deleteClicked()
+ {
+ QTreeWidgetItem* cur = le.eventList->currentItem();
+ if (cur == 0)
+ return;
+ Event* ev = item2Event(cur);
+ song->deleteEvent(*ev, part);
+ }
+
+//---------------------------------------------------------
+// EventDelegate
+//---------------------------------------------------------
+
+EventDelegate::EventDelegate(QObject* parent)
+ : QItemDelegate(parent)
+ {
+ }
+
+//---------------------------------------------------------
+// createEditor
+//---------------------------------------------------------
+
+QWidget* EventDelegate::createEditor(QWidget* pw,
+ const QStyleOptionViewItem& option, const QModelIndex& index) const
+ {
+ switch(index.column()) {
+ case PartListEditor::TICK_COL:
+ break;
+ case PartListEditor::TIME_COL:
+ return new Awl::PosEdit(pw);
+ case PartListEditor::TYPE_COL:
+ case PartListEditor::A_COL:
+ case PartListEditor::B_COL:
+ case PartListEditor::C_COL:
+ case PartListEditor::LEN_COL:
+ case PartListEditor::DATA_COL:
+ break;
+ }
+ return QItemDelegate::createEditor(pw, option, index);
+ }
+
+//---------------------------------------------------------
+// setEditorData
+//---------------------------------------------------------
+
+void EventDelegate::setEditorData(QWidget* editor,
+ const QModelIndex& index) const
+ {
+ switch(index.column()) {
+ case PartListEditor::TICK_COL:
+ break;
+ case PartListEditor::TIME_COL:
+ {
+ Awl::PosEdit* pe = static_cast<Awl::PosEdit*>(editor);
+ pe->setValue(AL::Pos(index.data().toInt()));
+ }
+ return;
+ case PartListEditor::TYPE_COL:
+ case PartListEditor::A_COL:
+ case PartListEditor::B_COL:
+ case PartListEditor::C_COL:
+ case PartListEditor::LEN_COL:
+ case PartListEditor::DATA_COL:
+ break;
+ }
+ QItemDelegate::setEditorData(editor, index);
+ }
+
+//---------------------------------------------------------
+// setModelData
+//---------------------------------------------------------
+
+void EventDelegate::setModelData(QWidget* editor, QAbstractItemModel* model,
+ const QModelIndex& index) const
+ {
+ switch(index.column()) {
+ case PartListEditor::TICK_COL:
+ break;
+ case PartListEditor::TIME_COL:
+ {
+ Awl::PosEdit* pe = static_cast<Awl::PosEdit*>(editor);
+ model->setData(index, pe->pos().tick(), Qt::DisplayRole);
+ }
+ return;
+ case PartListEditor::TYPE_COL:
+ case PartListEditor::A_COL:
+ case PartListEditor::B_COL:
+ case PartListEditor::C_COL:
+ case PartListEditor::LEN_COL:
+ case PartListEditor::DATA_COL:
+ break;
+ }
+ QItemDelegate::setModelData(editor, model, index);
+ }
+
+//---------------------------------------------------------
+// paint
+//---------------------------------------------------------
+
+void EventDelegate::paint(QPainter* painter,
+ const QStyleOptionViewItem& option, const QModelIndex& index) const
+ {
+ QString text;
+ PartListEditor* ce = static_cast<PartListEditor*>(parent());
+
+ switch(index.column()) {
+ case PartListEditor::TICK_COL:
+ {
+ Track* track = ce->getTrack();
+ AL::Pos pos(index.data().toInt(), track->timeType());
+ text = QString("%1").arg(pos.tick());
+ }
+ break;
+ case PartListEditor::TIME_COL:
+ {
+ Track* track = ce->getTrack();
+ AL::Pos pos(index.data().toInt(), track->timeType());
+ int measure, beat, tick;
+ pos.mbt(&measure, &beat, &tick);
+ text.sprintf("%04d.%02d.%03u", measure+1, beat+1, tick);
+ }
+ break;
+ case PartListEditor::TYPE_COL:
+ case PartListEditor::A_COL:
+ case PartListEditor::B_COL:
+ case PartListEditor::C_COL:
+ case PartListEditor::LEN_COL:
+ case PartListEditor::DATA_COL:
+ QItemDelegate::paint(painter, option, index);
+ return;
+ }
+
+ QStyleOptionViewItemV2 opt = setOptions(index, option);
+ const QStyleOptionViewItemV2 *v2 = qstyleoption_cast<const QStyleOptionViewItemV2 *>(&option);
+ opt.features = v2 ? v2->features : QStyleOptionViewItemV2::ViewItemFeatures(QStyleOptionViewItemV2::None);
+
+ painter->save();
+ QVariant value;
+ QRect displayRect;
+ displayRect = option.rect; // textRectangle(painter, d->textLayoutBounds(opt), opt.font, text);
+
+ QRect checkRect;
+ Qt::CheckState checkState = Qt::Unchecked;
+ value = index.data(Qt::CheckStateRole);
+ if (value.isValid()) {
+ checkState = static_cast<Qt::CheckState>(value.toInt());
+ checkRect = check(opt, opt.rect, value);
+ }
+
+ drawBackground(painter, opt, index);
+ drawCheck(painter, opt, checkRect, checkState);
+ drawDisplay(painter, opt, displayRect, text);
+ drawFocus(painter, opt, text.isEmpty() ? QRect() : displayRect);
+ painter->restore();
+ }
+
+
+
diff --git a/muse_qt4_evolution/muse/liste/partlistedit.h b/muse_qt4_evolution/muse/liste/partlistedit.h
new file mode 100644
index 00000000..10eda46a
--- /dev/null
+++ b/muse_qt4_evolution/muse/liste/partlistedit.h
@@ -0,0 +1,79 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __PARTLISTEDIT_H__
+#define __PARTLISTEDIT_H__
+
+#include "al/pos.h"
+#include "ieventdialog.h"
+#include "listedit.h"
+#include "ui_partlistedit.h"
+
+//---------------------------------------------------------
+// EventDelegate
+//---------------------------------------------------------
+
+class EventDelegate : public QItemDelegate {
+ Q_OBJECT
+
+ virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem&,
+ const QModelIndex& index) const;
+ virtual void setEditorData(QWidget* editor, const QModelIndex&) const;
+ virtual void setModelData(QWidget* editor, QAbstractItemModel*,
+ const QModelIndex&) const;
+ void paint(QPainter*, const QStyleOptionViewItem&,
+ const QModelIndex&) const;
+
+ public:
+ EventDelegate(QObject* parent = 0);
+ };
+
+//---------------------------------------------------------
+// PartListEditor
+//---------------------------------------------------------
+
+class PartListEditor : public ListWidget {
+ Q_OBJECT
+
+ ListEdit* listEdit;
+ Ui::PartListEdit le;
+ Part* part;
+ Event* curEvent;
+ bool updateListDisabled;
+
+ void updateList();
+ Event* item2Event(QTreeWidgetItem* item, int time_col = TICK_COL);
+
+ private slots:
+ void itemActivated(QTreeWidgetItem* item, int column);
+ void itemChanged(QTreeWidgetItem* item, int column);
+ void currentItemChanged(QTreeWidgetItem* cur, QTreeWidgetItem* pre);
+ void insertClicked();
+ void deleteClicked();
+
+ public:
+ PartListEditor(ListEdit*, QWidget* parent = 0);
+ virtual void setup(const ListType&);
+ Track* getTrack() const;
+ enum { TICK_COL, TIME_COL, TYPE_COL, A_COL, B_COL, C_COL, LEN_COL, DATA_COL};
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/liste/partlistedit.ui b/muse_qt4_evolution/muse/liste/partlistedit.ui
new file mode 100644
index 00000000..c575ef03
--- /dev/null
+++ b/muse_qt4_evolution/muse/liste/partlistedit.ui
@@ -0,0 +1,166 @@
+<ui version="4.0" >
+ <class>PartListEdit</class>
+ <widget class="QWidget" name="PartListEdit" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>341</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="font" >
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text" >
+ <string>&lt;html>&lt;head>&lt;meta name="qrichtext" content="1" />&lt;style type="text/css">
+p, li { white-space: pre-wrap; }
+&lt;/style>&lt;/head>&lt;body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600; font-style:normal; text-decoration:none;">
+&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">&lt;span style=" font-weight:400;">Part:&lt;/span>&lt;/p>&lt;/body>&lt;/html></string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="partName" />
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_2" >
+ <property name="text" >
+ <string>Eventlist:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QTreeWidget" name="eventList" >
+ <property name="alternatingRowColors" >
+ <bool>true</bool>
+ </property>
+ <property name="indentation" >
+ <number>0</number>
+ </property>
+ <property name="rootIsDecorated" >
+ <bool>false</bool>
+ </property>
+ <property name="uniformRowHeights" >
+ <bool>true</bool>
+ </property>
+ <property name="itemsExpandable" >
+ <bool>false</bool>
+ </property>
+ <column>
+ <property name="text" >
+ <string>Tick</string>
+ </property>
+ </column>
+ <column>
+ <property name="text" >
+ <string>Time</string>
+ </property>
+ </column>
+ <column>
+ <property name="text" >
+ <string>Type</string>
+ </property>
+ </column>
+ <column>
+ <property name="text" >
+ <string>Val A</string>
+ </property>
+ </column>
+ <column>
+ <property name="text" >
+ <string>Val B</string>
+ </property>
+ </column>
+ <column>
+ <property name="text" >
+ <string>Val C</string>
+ </property>
+ </column>
+ <column>
+ <property name="text" >
+ <string>Length</string>
+ </property>
+ </column>
+ <column>
+ <property name="text" >
+ <string>Data</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QToolButton" name="deleteButton" >
+ <property name="text" >
+ <string>Delete</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="insertButton" >
+ <property name="text" >
+ <string>Insert</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>231</width>
+ <height>29</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/muse_qt4_evolution/muse/liste/tracklistedit.cpp b/muse_qt4_evolution/muse/liste/tracklistedit.cpp
new file mode 100644
index 00000000..24fc4722
--- /dev/null
+++ b/muse_qt4_evolution/muse/liste/tracklistedit.cpp
@@ -0,0 +1,65 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "tracklistedit.h"
+#include "track.h"
+#include "song.h"
+#include "al/pos.h"
+#include "awl/posedit.h"
+
+//---------------------------------------------------------
+// TrackListEditor
+//---------------------------------------------------------
+
+TrackListEditor::TrackListEditor(ListEdit* e, QWidget* parent)
+ : ListWidget(parent)
+ {
+ listEdit = e;
+ QWidget* cew = new QWidget;
+ le.setupUi(cew);
+ QVBoxLayout* layout = new QVBoxLayout;
+ layout->addWidget(cew);
+ setLayout(layout);
+
+ QFontMetrics fm(le.partList->font());
+ int zW = fm.width("0");
+ le.partList->setColumnWidth(TICK_COL, zW * 8);
+ le.partList->setColumnWidth(TIME_COL, zW * 14);
+ track = 0;
+ }
+
+//---------------------------------------------------------
+// setup
+//---------------------------------------------------------
+
+void TrackListEditor::setup(const ListType& lt)
+ {
+ track = lt.track;
+ le.trackName->setText(track->name());
+ updateList();
+ }
+
+//---------------------------------------------------------
+// updateList
+//---------------------------------------------------------
+
+void TrackListEditor::updateList()
+ {
+ }
diff --git a/muse_qt4_evolution/muse/liste/tracklistedit.h b/muse_qt4_evolution/muse/liste/tracklistedit.h
new file mode 100644
index 00000000..7d4b57f7
--- /dev/null
+++ b/muse_qt4_evolution/muse/liste/tracklistedit.h
@@ -0,0 +1,50 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __TRACKLISTEDIT_H__
+#define __TRACKLISTEDIT_H__
+
+#include "al/pos.h"
+#include "listedit.h"
+#include "ui_tracklistedit.h"
+
+//---------------------------------------------------------
+// TrackListEditor
+//---------------------------------------------------------
+
+class TrackListEditor : public ListWidget {
+ Q_OBJECT
+
+ ListEdit* listEdit;
+ Ui::TrackListEdit le;
+ Track* track;
+
+ void updateList();
+
+ private slots:
+
+ public:
+ TrackListEditor(ListEdit*, QWidget* parent = 0);
+ virtual void setup(const ListType&);
+ enum { TICK_COL, TIME_COL };
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/liste/tracklistedit.ui b/muse_qt4_evolution/muse/liste/tracklistedit.ui
new file mode 100644
index 00000000..dfddf1c7
--- /dev/null
+++ b/muse_qt4_evolution/muse/liste/tracklistedit.ui
@@ -0,0 +1,146 @@
+<ui version="4.0" >
+ <class>TrackListEdit</class>
+ <widget class="QWidget" name="TrackListEdit" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>341</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="font" >
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text" >
+ <string>&lt;html>&lt;head>&lt;meta name="qrichtext" content="1" />&lt;style type="text/css">
+p, li { white-space: pre-wrap; }
+&lt;/style>&lt;/head>&lt;body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600; font-style:normal; text-decoration:none;">
+&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">&lt;span style=" font-weight:400;">Track:&lt;/span>&lt;/p>&lt;/body>&lt;/html></string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="trackName" />
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_2" >
+ <property name="text" >
+ <string>Partlist:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QTreeWidget" name="partList" >
+ <property name="alternatingRowColors" >
+ <bool>true</bool>
+ </property>
+ <property name="indentation" >
+ <number>0</number>
+ </property>
+ <property name="rootIsDecorated" >
+ <bool>false</bool>
+ </property>
+ <property name="uniformRowHeights" >
+ <bool>true</bool>
+ </property>
+ <property name="itemsExpandable" >
+ <bool>false</bool>
+ </property>
+ <column>
+ <property name="text" >
+ <string>Tick</string>
+ </property>
+ </column>
+ <column>
+ <property name="text" >
+ <string>Time</string>
+ </property>
+ </column>
+ <column>
+ <property name="text" >
+ <string>Len</string>
+ </property>
+ </column>
+ <column>
+ <property name="text" >
+ <string>Name</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QToolButton" name="deleteButton" >
+ <property name="text" >
+ <string>Delete</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="insertButton" >
+ <property name="text" >
+ <string>Insert</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>231</width>
+ <height>29</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/muse_qt4_evolution/muse/marker/CMakeLists.txt b/muse_qt4_evolution/muse/marker/CMakeLists.txt
new file mode 100644
index 00000000..d031533c
--- /dev/null
+++ b/muse_qt4_evolution/muse/marker/CMakeLists.txt
@@ -0,0 +1,45 @@
+#
+#
+#
+#
+
+MACRO(WRAP_CPP outfiles )
+ FOREACH(it ${ARGN})
+ SET(${outfiles} ${${outfiles}} ${it}.cpp)
+ ENDFOREACH(it)
+ ENDMACRO(WRAP_CPP)
+
+MACRO(WRAP_H outfiles )
+ FOREACH(it ${ARGN})
+ SET(${outfiles} ${${outfiles}} ${it}.h)
+ ENDFOREACH(it)
+ ENDMACRO(WRAP_H)
+
+MACRO(WRAP_UI outfiles )
+ FOREACH(it ${ARGN})
+ SET(${outfiles} ${${outfiles}} ${it}.ui)
+ ENDFOREACH(it)
+ ENDMACRO(WRAP_UI)
+
+set(mocs
+ markerview
+ )
+
+WRAP_H(mocH ${mocs})
+WRAP_CPP(mocCPP ${mocs})
+
+QT4_WRAP_CPP (moc_headers ${mocH})
+
+set (uics
+ )
+
+WRAP_UI(uiUI ${uics})
+QT4_WRAP_UI (ui_headers ${uiUI})
+
+set ( marker_src ${mocCPP} ${moc_headers})
+
+add_library ( marker STATIC ${marker_src})
+set_target_properties( marker
+ PROPERTIES COMPILE_FLAGS "-include ${PROJECT_BINARY_DIR}/all.h"
+ )
+
diff --git a/muse_qt4_evolution/muse/marker/markerview.cpp b/muse_qt4_evolution/muse/marker/markerview.cpp
new file mode 100644
index 00000000..7cab2d02
--- /dev/null
+++ b/muse_qt4_evolution/muse/marker/markerview.cpp
@@ -0,0 +1,413 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "markerview.h"
+#include "globals.h"
+#include "sync.h"
+#include "icons.h"
+#include "song.h"
+#include "awl/posedit.h"
+#include "al/al.h"
+#include "al/xml.h"
+#include "al/sig.h"
+#include "al/tempo.h"
+#include "al/marker.h"
+#include "shortcuts.h"
+
+enum { COL_TICK = 0, COL_SMPTE, COL_LOCK, COL_NAME };
+
+//---------------------------------------------------------
+// tick
+//---------------------------------------------------------
+
+unsigned MarkerItem::tick() const
+ {
+ return _marker->tick();
+ }
+
+//---------------------------------------------------------
+// name
+//---------------------------------------------------------
+
+const QString MarkerItem::name() const
+ {
+ return _marker->name();
+ }
+
+//---------------------------------------------------------
+// lock
+//---------------------------------------------------------
+
+bool MarkerItem::lock() const
+ {
+ return _marker->type() == AL::FRAMES;
+ }
+
+//---------------------------------------------------------
+// MarkerItem
+//---------------------------------------------------------
+
+MarkerItem::MarkerItem(QTreeWidget* parent, AL::Marker* m)
+ : QTreeWidgetItem(parent)
+ {
+ _marker = m;
+ setText(COL_NAME, m->name());
+ setTick(m->tick());
+ setIcon(COL_LOCK, m->type() == AL::FRAMES ? *lockIcon : QIcon());
+ }
+
+//---------------------------------------------------------
+// setName
+//---------------------------------------------------------
+
+void MarkerItem::setName(const QString& s)
+ {
+ setText(COL_NAME, s);
+ _marker = song->setMarkerName(_marker, s);
+ }
+
+//---------------------------------------------------------
+// setLock
+//---------------------------------------------------------
+
+void MarkerItem::setLock(bool lck)
+ {
+ setIcon(COL_LOCK, lck ? *lockIcon : QIcon());
+ _marker = song->setMarkerLock(_marker, lck);
+ }
+
+//---------------------------------------------------------
+// setTick
+//---------------------------------------------------------
+
+void MarkerItem::setTick(unsigned v)
+ {
+ if (_marker->tick() != v)
+ _marker = song->setMarkerTick(_marker, v);
+ QString s;
+ int bar, beat;
+ int tick;
+ _marker->mbt(&bar, &beat, &tick);
+ s.sprintf("%04d.%02d.%03d", bar+1, beat+1, tick);
+ setText(COL_TICK, s);
+
+ int min, sec, frame, subframe;
+ _marker->msf(&min, &sec, &frame, &subframe);
+
+ s.sprintf("%03d:%02d:%02d:%02d", min, sec, frame, subframe);
+ setText(COL_SMPTE, s);
+ }
+
+//---------------------------------------------------------
+// MarkerView
+//---------------------------------------------------------
+
+MarkerView::MarkerView()
+ : TopWin()
+ {
+ lockChange = false;
+ setWindowTitle(tr("MusE: Marker"));
+
+ //---------Actions----------------------------
+ QAction* markerAdd = new QAction(QIcon(*flagIcon), tr("add marker"), this);
+ markerAdd->setToolTip(tr("Add Marker"));
+ connect(markerAdd, SIGNAL(triggered()), SLOT(addMarker()));
+
+ QAction* markerDelete = getAction("delete", this);
+ connect(markerDelete, SIGNAL(triggered()), SLOT(deleteMarker()));
+
+ //---------Pulldown Menu----------------------------
+ QMenuBar* mb = menuBar();
+
+ QMenu* editMenu = mb->addMenu(tr("&Edit"));
+ editMenu->addAction(markerAdd);
+ editMenu->addAction(markerDelete);
+
+ //---------ToolBar----------------------------------
+ QToolBar* tools = addToolBar(tr("marker-tools"));
+ tools->addAction(undoAction);
+ tools->addAction(redoAction);
+
+ QToolBar* edit = addToolBar(tr("edit tools"));
+ edit->addAction(markerAdd);
+ edit->addAction(markerDelete);
+
+ //---------------------------------------------------
+ // master
+ //---------------------------------------------------
+
+ QWidget* w = new QWidget;
+ setCentralWidget(w);
+ QVBoxLayout* vbox = new QVBoxLayout;
+ w->setLayout(vbox);
+
+ table = new QTreeWidget;
+ table->setUniformRowHeights(true);
+ table->setAlternatingRowColors(true);
+ table->setSelectionBehavior(QAbstractItemView::SelectRows);
+ table->setSelectionMode(QTreeWidget::SingleSelection);
+ table->setSortingEnabled(false);
+ table->setIndentation(0);
+ QStringList labels;
+ labels << tr("Bar:Beat:Tick")
+ << tr("Min:Sc:Fr:Sf")
+ << tr("Lock")
+ << tr("Text");
+ table->setHeaderLabels(labels);
+
+ table->header()->resizeSection(0, 120);
+ table->header()->resizeSection(1, 120);
+ table->header()->resizeSection(2, 50);
+ table->header()->resizeSection(3, 200);
+// table->header()->resizeSection(mnWidthMode(3, QTreeWidget::Maximum);
+ connect(table, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), SLOT(currentChanged(QTreeWidgetItem*)));
+ connect(table, SIGNAL(itemSelectionChanged()), SLOT(selectionChanged()));
+ connect(table, SIGNAL(itemClicked(QTreeWidgetItem*,int)), SLOT(clicked(QTreeWidgetItem*)));
+
+ QGroupBox* props = new QGroupBox(tr("Marker Properties"));
+ QHBoxLayout* propsLayout = new QHBoxLayout;
+ props->setLayout(propsLayout);
+
+ editTick = new Awl::PosEdit;
+ propsLayout->addWidget(editTick);
+ editTick->setSizePolicy(QSizePolicy(QSizePolicy::Fixed,
+ QSizePolicy::Fixed));
+
+ editSMPTE = new Awl::PosEdit;
+ propsLayout->addWidget(editSMPTE);
+ editSMPTE->setSmpte(true);
+ editSMPTE->setSizePolicy(QSizePolicy(QSizePolicy::Fixed,
+ QSizePolicy::Fixed));
+
+ lock = new QToolButton;
+ propsLayout->addWidget(lock);
+ lock->setIcon(*lockIcon);
+ lock->setCheckable(true);
+
+ editName = new QLineEdit;
+ propsLayout->addWidget(editName);
+ editName->setSizePolicy(QSizePolicy(QSizePolicy::Expanding,
+ QSizePolicy::Preferred));
+ connect(editName, SIGNAL(textChanged(const QString&)),
+ SLOT(nameChanged(const QString&)));
+ connect(editTick, SIGNAL(valueChanged(const Pos&)),
+ SLOT(tickChanged(const Pos&)));
+ connect(editSMPTE, SIGNAL(valueChanged(const Pos&)),
+ SLOT(tickChanged(const Pos&)));
+ connect(editSMPTE, SIGNAL(valueChanged(const Pos&)),
+ editTick, SLOT(setValue(const Pos&)));
+ connect(editTick, SIGNAL(valueChanged(const Pos&)),
+ editSMPTE, SLOT(setValue(const Pos&)));
+ connect(lock, SIGNAL(toggled(bool)),
+ SLOT(lockChanged(bool)));
+ connect(song, SIGNAL(markerChanged(int)), SLOT(markerChanged(int)));
+
+ vbox->addWidget(table);
+ vbox->addWidget(props);
+
+ //---------------------------------------------------
+ // Rest
+ //---------------------------------------------------
+
+// connect(song, SIGNAL(songChanged(int)), SLOT(updateList()));
+ updateList();
+ markerChanged(Song::MARKER_CUR); // select current marker
+ }
+
+//---------------------------------------------------------
+// addMarker
+//---------------------------------------------------------
+
+void MarkerView::addMarker()
+ {
+ addMarker(song->cPos());
+ }
+
+void MarkerView::addMarker(const AL::Pos& pos)
+ {
+// new MarkerItem(table, m);
+ song->addMarker(QString(""), pos);
+ table->sortItems(0, Qt::AscendingOrder);
+ }
+
+//---------------------------------------------------------
+// deleteMarker
+//---------------------------------------------------------
+
+void MarkerView::deleteMarker()
+ {
+ MarkerItem* item = (MarkerItem*)table->currentItem();
+ if (item) {
+ AL::Marker* marker = item->marker();
+ delete item;
+ song->removeMarker(marker);
+ }
+ }
+
+//---------------------------------------------------------
+// updateList
+//---------------------------------------------------------
+
+void MarkerView::updateList()
+ {
+ table->clear();
+ AL::MarkerList* marker = song->marker();
+ for (AL::iMarker i = marker->begin(); i != marker->end(); ++i) {
+ AL::Marker* m = &i->second;
+ new MarkerItem(table, m);
+ }
+ }
+
+//---------------------------------------------------------
+// currentChanged
+//---------------------------------------------------------
+
+void MarkerView::currentChanged(QTreeWidgetItem* i)
+ {
+ MarkerItem* item = (MarkerItem*)i;
+ if (item == 0) { // never triggered
+ editTick->setValue(0);
+ editSMPTE->setValue(0);
+ editName->setText(QString(""));
+ lock->setChecked(false);
+ editSMPTE->setEnabled(false);
+ editTick->setEnabled(false);
+ lock->setEnabled(false);
+ editName->setEnabled(false);
+ }
+ else {
+ editTick->setValue(item->tick());
+ editSMPTE->setValue(item->tick());
+ editName->setText(item->name());
+ editName->setEnabled(true);
+ lock->setChecked(item->lock());
+ lock->setEnabled(true);
+ editSMPTE->setEnabled(item->lock());
+ editTick->setEnabled(!item->lock());
+ }
+ }
+
+//---------------------------------------------------------
+// selectionChanged
+//---------------------------------------------------------
+
+void MarkerView::selectionChanged()
+ {
+#if 0
+ QList<QTreeWidgetItem*> sel = table->selectedItems();
+ if (!sel.empty()) {
+ MarkerItem* item = (MarkerItem*)(sel[0]);
+ }
+#endif
+ }
+
+//---------------------------------------------------------
+// clicked
+//---------------------------------------------------------
+
+void MarkerView::clicked(QTreeWidgetItem* i)
+ {
+ MarkerItem* item = (MarkerItem*)i;
+ if (item == 0) {
+ table->clearSelection();
+ return;
+ }
+ Pos p(item->tick(), AL::TICKS);
+ song->setPos(0, p, true, true, false);
+ }
+
+//---------------------------------------------------------
+// nameChanged
+//---------------------------------------------------------
+
+void MarkerView::nameChanged(const QString& s)
+ {
+ MarkerItem* item = (MarkerItem*)table->currentItem();
+ if (item)
+ item->setName(s);
+ }
+
+//---------------------------------------------------------
+// tickChanged
+//---------------------------------------------------------
+
+void MarkerView::tickChanged(const Pos& pos)
+ {
+ MarkerItem* item = (MarkerItem*)table->currentItem();
+ if (item) {
+ lockChange = true;
+ item->setTick(pos.tick());
+ Pos p(pos.tick(), AL::TICKS);
+ song->setPos(0, p, true, true, false);
+ lockChange = false;
+ }
+ }
+
+//---------------------------------------------------------
+// lockChanged
+//---------------------------------------------------------
+
+void MarkerView::lockChanged(bool lck)
+ {
+ MarkerItem* item = (MarkerItem*)table->currentItem();
+ if (item) {
+ item->setLock(lck);
+ editSMPTE->setEnabled(item->lock());
+ editTick->setEnabled(!item->lock());
+ }
+ }
+
+//---------------------------------------------------------
+// markerChanged
+//---------------------------------------------------------
+
+void MarkerView::markerChanged(int val)
+ {
+ if (lockChange)
+ return;
+ switch (val) {
+ case Song::MARKER_ADD:
+ case Song::MARKER_REMOVE:
+ updateList();
+ // fall through
+ case Song::MARKER_CUR:
+ {
+ AL::MarkerList* marker = song->marker();
+ for (AL::iMarker i = marker->begin(); i != marker->end(); ++i) {
+ if (i->second.current()) {
+ int n = table->topLevelItemCount();
+ for (int k = 0; k < n; ++k) {
+ MarkerItem* item = (MarkerItem*)(table->topLevelItem(k));
+ if (item->marker() == &i->second) {
+ table->setCurrentItem(item);
+ return;
+ }
+ }
+ }
+ }
+ }
+ break;
+ case Song::MARKER_NAME:
+ case Song::MARKER_TICK:
+ case Song::MARKER_LOCK:
+ break;
+ }
+ }
+
diff --git a/muse_qt4_evolution/muse/marker/markerview.h b/muse_qt4_evolution/muse/marker/markerview.h
new file mode 100644
index 00000000..53205e3d
--- /dev/null
+++ b/muse_qt4_evolution/muse/marker/markerview.h
@@ -0,0 +1,98 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __MARKERVIEW_H__
+#define __MARKERVIEW_H__
+
+#include "cobject.h"
+
+namespace Awl {
+ class PosEdit;
+ };
+
+namespace AL {
+ class Pos;
+ class Xml;
+ class Marker;
+ };
+using AL::Pos;
+using AL::Xml;
+
+
+//---------------------------------------------------------
+// MarkerItem
+//---------------------------------------------------------
+
+class MarkerItem : public QTreeWidgetItem {
+ AL::Marker* _marker;
+
+ public:
+ MarkerItem(QTreeWidget* parent, AL::Marker* m);
+ AL::Marker* marker() const { return _marker; }
+ unsigned tick() const;
+ const QString name() const;
+ bool lock() const;
+ void setName(const QString& s);
+ void setTick(unsigned t);
+ void setLock(bool lck);
+ };
+
+//---------------------------------------------------------
+// MarkerView
+//---------------------------------------------------------
+
+class MarkerView : public TopWin {
+ Q_OBJECT
+
+ bool lockChange;
+
+ QTreeWidget* table;
+ QLineEdit* editName;
+ Awl::PosEdit* editSMPTE;
+ Awl::PosEdit* editTick;
+ QToolButton* lock;
+
+ void closeEvent(QCloseEvent* e) {
+ emit closed();
+ QMainWindow::closeEvent(e);
+ }
+
+ signals:
+ void closed();
+
+ private slots:
+ void addMarker();
+ void addMarker(const AL::Pos&);
+ void deleteMarker();
+ void currentChanged(QTreeWidgetItem*);
+ void selectionChanged();
+ void nameChanged(const QString&);
+ void tickChanged(const Pos&);
+ void lockChanged(bool);
+ void markerChanged(int);
+ void clicked(QTreeWidgetItem*);
+ void updateList();
+
+ public:
+ MarkerView();
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/master/CMakeLists.txt b/muse_qt4_evolution/muse/master/CMakeLists.txt
new file mode 100644
index 00000000..a20d3be1
--- /dev/null
+++ b/muse_qt4_evolution/muse/master/CMakeLists.txt
@@ -0,0 +1,37 @@
+#
+#
+#
+#
+
+MACRO(WRAP_CPP outfiles )
+ FOREACH(it ${ARGN})
+ SET(${outfiles} ${${outfiles}} ${it}.cpp)
+ ENDFOREACH(it)
+ ENDMACRO(WRAP_CPP)
+
+MACRO(WRAP_H outfiles )
+ FOREACH(it ${ARGN})
+ SET(${outfiles} ${${outfiles}} ${it}.h)
+ ENDFOREACH(it)
+ ENDMACRO(WRAP_H)
+
+MACRO(WRAP_UI outfiles )
+ FOREACH(it ${ARGN})
+ SET(${outfiles} ${${outfiles}} ${it}.ui)
+ ENDFOREACH(it)
+ ENDMACRO(WRAP_UI)
+
+set( mocs master masteredit )
+
+WRAP_H(mocH ${mocs})
+WRAP_CPP(mocCPP ${mocs})
+
+QT4_WRAP_CPP (moc_headers ${mocH})
+
+set ( master_src ${mocCPP} ${moc_headers})
+
+add_library ( master STATIC ${master_src})
+set_target_properties( master
+ PROPERTIES COMPILE_FLAGS "-include ${PROJECT_BINARY_DIR}/all.h"
+ )
+
diff --git a/muse_qt4_evolution/muse/master/master.cpp b/muse_qt4_evolution/muse/master/master.cpp
new file mode 100644
index 00000000..d033753c
--- /dev/null
+++ b/muse_qt4_evolution/muse/master/master.cpp
@@ -0,0 +1,233 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "master.h"
+#include "icons.h"
+#include "audio.h"
+#include "al/tempo.h"
+#include "song.h"
+
+static const int minTempo = 50;
+static const int maxTempo = 250;
+
+//---------------------------------------------------------
+// pix2tempo
+//---------------------------------------------------------
+
+int MasterCanvas::pix2tempo(int val) const
+ {
+ return maxTempo*1000 - mapyDev(val);
+ }
+
+//---------------------------------------------------------
+// tempo2pix
+//---------------------------------------------------------
+
+int MasterCanvas::tempo2pix(int val) const
+ {
+ return mapy(maxTempo*1000 - lrint(60000000000.0/val));
+ }
+
+//---------------------------------------------------------
+// MasterCanvas
+//---------------------------------------------------------
+
+MasterCanvas::MasterCanvas()
+ : TimeCanvas(TIME_CANVAS)
+ {
+ setMarkerList(song->marker());
+ setMag(xmag(), 400.0 / (maxTempo * 1000.0));
+ setYMagRange(40.0 / (maxTempo*1000), 4000.0 / (maxTempo*1000));
+ setVSize((maxTempo - minTempo) * 1000);
+ setYFit(true);
+ verticalScrollBar()->setSingleStep(1000);
+ verticalScrollBar()->setMinimum(minTempo * 1000);
+ verticalScrollBar()->setMaximum(maxTempo * 1000);
+ drag = DRAG_OFF;
+ }
+
+//---------------------------------------------------------
+// paint
+//---------------------------------------------------------
+
+void MasterCanvas::paint(QPainter& p, QRect rect)
+ {
+ int y = rect.y();
+
+ //---------------------------------------------------
+ // draw Canvas Items
+ //---------------------------------------------------
+
+ int y2 = lrint(maxTempo * 1000 * _ymag);
+ const AL::TempoList* tl = &AL::tempomap;
+ for (AL::ciTEvent i = tl->begin(); i != tl->end(); ++i) {
+ AL::TEvent* e = i->second;
+ int x1 = pos2pix(AL::Pos(i->first));
+ int x2 = pos2pix(AL::Pos(i->second->tick));
+ int y1 = lrint(_ymag * (maxTempo*1000 - lrint(60000000000.0/e->tempo)));
+ if (y1 < y)
+ y1 = y;
+ p.fillRect(x1, y1, x2 - x1, y2 - y1, Qt::blue);
+ }
+ }
+
+//---------------------------------------------------------
+// viewMousePressEvent
+//---------------------------------------------------------
+
+void MasterCanvas::mousePress(QMouseEvent* event)
+ {
+ start = event->pos();
+ int x = start.x() - rCanvasA.x();
+ int y = start.y() - rCanvasA.y();
+
+ switch (tool()) {
+ case PointerTool:
+ drag = DRAG_LASSO_START;
+ break;
+
+ case PencilTool:
+ drag = DRAG_NEW;
+ song->startUndo();
+ newVal(x, x, y);
+ break;
+
+ case RubberTool:
+ drag = DRAG_DELETE;
+ song->startUndo();
+ deleteVal(x, x);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+//---------------------------------------------------------
+// viewMouseMoveEvent
+//---------------------------------------------------------
+
+void MasterCanvas::mouseMove(QPoint pos)
+ {
+ int y = pos.y() - rCanvasA.y();
+ int x = pos.x() - rCanvasA.x();
+
+ QPoint dist = pos - start;
+ // bool moving = dist.y() >= 3 || dist.y() <= 3 || dist.x() >= 3 || dist.x() <= 3;
+
+ int sx = start.x() - rCanvasA.x();
+ switch (drag) {
+ case DRAG_NEW:
+ newVal(sx, x, y);
+ start = pos;
+ break;
+
+ case DRAG_DELETE:
+ deleteVal(sx, x);
+ start = pos;
+ break;
+
+ default:
+ break;
+ }
+ emit tempoChanged(pix2tempo(y));
+// emit timeChanged(editor->rasterVal(x));
+ }
+
+//---------------------------------------------------------
+// mouseRelease
+//---------------------------------------------------------
+
+void MasterCanvas::mouseRelease(QMouseEvent*)
+ {
+ switch (drag) {
+ case DRAG_RESIZE:
+ case DRAG_NEW:
+ case DRAG_DELETE:
+ song->endUndo(SC_TEMPO);
+ break;
+ default:
+ break;
+ }
+ drag = DRAG_OFF;
+ }
+
+//---------------------------------------------------------
+// deleteVal
+//---------------------------------------------------------
+
+bool MasterCanvas::deleteVal1(const AL::Pos& p1, const AL::Pos& p2)
+ {
+ bool songChanged = false;
+
+ AL::TempoList* tl = &AL::tempomap;
+ for (AL::iTEvent i = tl->begin(); i != tl->end(); ++i) {
+ if (i->first < p1.tick())
+ continue;
+ if (i->first >= p2.tick())
+ break;
+ AL::iTEvent ii = i;
+ ++ii;
+ if (ii != tl->end()) {
+ int tempo = ii->second->tempo;
+ audio->msgDeleteTempo(i->first, tempo, false);
+ songChanged = true;
+ }
+ }
+ return songChanged;
+ }
+
+//---------------------------------------------------------
+// deleteVal
+//---------------------------------------------------------
+
+void MasterCanvas::deleteVal(int x1, int x2)
+ {
+ AL::Pos p1(pix2pos(x1));
+ AL::Pos p2(pix2pos(x2));
+ p1.downSnap(raster());
+ p2.upSnap(raster());
+ if (deleteVal1(p1, p2))
+ widget()->update();
+ }
+
+//---------------------------------------------------------
+// newVal
+//---------------------------------------------------------
+
+void MasterCanvas::newVal(int x1, int x2, int y)
+ {
+ int tempo = lrint(60000000000.0 / pix2tempo(y));
+ AL::Pos p1 = pix2pos(x1);
+ p1.downSnap(raster());
+ AL::Pos p2 = pix2pos(x2);
+ p2.upSnap(raster());
+
+ if (p1 > p2) {
+ AL::Pos tmp = p2;
+ p2 = p1;
+ p1 = tmp;
+ }
+ deleteVal1(p1, p2);
+ audio->msgAddTempo(p1.tick(), tempo, false);
+ widget()->update();
+ }
+
+
diff --git a/muse_qt4_evolution/muse/master/master.h b/muse_qt4_evolution/muse/master/master.h
new file mode 100644
index 00000000..54899663
--- /dev/null
+++ b/muse_qt4_evolution/muse/master/master.h
@@ -0,0 +1,63 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __MASTER_H__
+#define __MASTER_H__
+
+#include "awl/tcanvas.h"
+
+class GraphMidiEditor;
+
+//---------------------------------------------------------
+// MasterCanvas
+//---------------------------------------------------------
+
+class MasterCanvas : public TimeCanvas {
+ QPoint start;
+
+ enum {
+ DRAG_OFF, DRAG_LASSO_START, DRAG_RESIZE, DRAG_NEW,
+ DRAG_DELETE
+ } drag;
+
+ Q_OBJECT
+ virtual void mouseMove(QPoint);
+ virtual void mousePress(QMouseEvent* event);
+ virtual void mouseRelease(QMouseEvent*);
+
+ virtual void paint(QPainter&, QRect);
+
+ void newVal(int x1, int x2, int y);
+ bool deleteVal1(const AL::Pos&, const AL::Pos&);
+ void deleteVal(int x1, int x2);
+
+ int pix2tempo(int) const;
+ int tempo2pix(int) const;
+
+ signals:
+ void tempoChanged(int);
+
+ public:
+ MasterCanvas();
+ virtual ~MasterCanvas() {}
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/master/masteredit.cpp b/muse_qt4_evolution/muse/master/masteredit.cpp
new file mode 100644
index 00000000..e3271ea6
--- /dev/null
+++ b/muse_qt4_evolution/muse/master/masteredit.cpp
@@ -0,0 +1,302 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "song.h"
+#include "masteredit.h"
+#include "awl/poslabel.h"
+#include "awl/tempoedit.h"
+#include "awl/tempolabel.h"
+#include "awl/sigedit.h"
+#include "master.h"
+#include "al/tempo.h"
+#include "widgets/tools.h"
+
+static int rasterTable[] = { 1, 0, 768, 384, 192, 96 };
+static const char* rastval[] = {
+ QT_TR_NOOP("Off"), "Bar", "1/2", "1/4", "1/8", "1/16"
+ };
+
+int MasterEdit::initRaster = MasterEdit::INIT_RASTER;
+int MasterEdit::initWidth = MasterEdit::INIT_WIDTH;
+int MasterEdit::initHeight = MasterEdit::INIT_HEIGHT;
+double MasterEdit::initXmag = 0.04;
+double MasterEdit::initYmag = 1.0;
+
+//---------------------------------------------------------
+// MasterEdit
+//---------------------------------------------------------
+
+MasterEdit::MasterEdit()
+ : Editor()
+ {
+ setWindowTitle(tr("MusE: Mastertrack"));
+
+ //---------ToolBar----------------------------------
+ tools = addToolBar(tr("edit tools"));
+ tools->addAction(undoAction);
+ tools->addAction(redoAction);
+ tools->addSeparator();
+
+ tools2 = new EditToolBar(this,
+ PointerTool | PencilTool | RubberTool);
+ addToolBar(tools2);
+
+ QToolBar* enableMaster = addToolBar(tr("EnableTempomap"));
+ enableMasterAction = enableMaster->addAction(tr("Tempomap"));
+ enableMasterAction->setCheckable(true);
+ enableMasterAction->setToolTip(tr("Enable use of tempo map"));
+ enableMasterAction->setChecked(song->masterFlag());
+ connect(enableMasterAction, SIGNAL(triggered(bool)), song, SLOT(setMasterFlag(bool)));
+
+ addToolBarBreak();
+ QToolBar* info = new QToolBar(tr("Info"), this);
+ addToolBar(info);
+
+ QLabel* label = new QLabel(tr("Cursor"));
+ info->addWidget(label);
+
+ cursorPos = new PosLabel;
+ info->addWidget(cursorPos);
+ tempo = new TempoLabel(info);
+ info->addWidget(tempo);
+
+ info->addWidget(new QLabel(tr("Snap")));
+ rasterLabel = new QComboBox;
+ info->addWidget(rasterLabel);
+ for (int i = 0; i < 6; i++)
+ rasterLabel->addItem(tr(rastval[i]), i);
+ connect(rasterLabel, SIGNAL(activated(int)), SLOT(_setRaster(int)));
+
+ cursorPos->setToolTip(tr("time at cursor position"));
+ tempo->setToolTip(tr("tempo at cursor position"));
+
+ //---------values for current position---------------
+ info->addWidget(new QLabel(tr("CurPos ")));
+ curTempo = new TempoEdit(info);
+ info->addWidget(curTempo);
+ curSig = new SigEdit(info);
+ info->addWidget(curSig);
+ curSig->setValue(AL::TimeSignature(4, 4));
+ curTempo->setToolTip(tr("tempo at current position"));
+ curSig->setToolTip(tr("time signature at current position"));
+ connect(curSig, SIGNAL(valueChanged(const AL::TimeSignature&)), song, SLOT(setSig(const AL::TimeSignature&)));
+ connect(curTempo, SIGNAL(tempoChanged(int)), song, SLOT(setTempo(int)));
+
+ //---------------------------------------------------
+ // master
+ //---------------------------------------------------
+
+ tcanvas = new MasterCanvas;
+ setCentralWidget(tcanvas);
+ tcanvas->setEndPos(AL::Pos(song->len()));
+ setRaster(INIT_RASTER);
+ tcanvas->setMag(initXmag, initYmag);
+
+ connect(song, SIGNAL(posChanged(int,const AL::Pos&,bool)), tcanvas, SLOT(setLocatorPos(int,const AL::Pos&,bool)));
+ connect(song, SIGNAL(posChanged(int,const AL::Pos&,bool)), SLOT(posChanged(int,const AL::Pos&,bool)));
+ connect(song, SIGNAL(lenChanged(const AL::Pos&)), tcanvas, SLOT(setEndPos(const AL::Pos&)));
+ connect(song, SIGNAL(tempoChanged()), tcanvas, SLOT(tempoChanged()));
+
+ connect(tcanvas, SIGNAL(posChanged(int,const AL::Pos&)), song, SLOT(setPos(int,const AL::Pos&)));
+ connect(tcanvas, SIGNAL(cursorPos(const AL::Pos&,bool)), cursorPos, SLOT(setValue(const AL::Pos&,bool)));
+
+ connect(tcanvas, SIGNAL(tempoChanged(int)), SLOT(setTempo(int)));
+ connect(tools2, SIGNAL(toolChanged(int)), tcanvas, SLOT(setTool(int)));
+ connect(song, SIGNAL(songChanged(int)), SLOT(songChanged(int)));
+
+ resize(initWidth, initHeight);
+ }
+
+//---------------------------------------------------------
+// ~MasterEdit
+//---------------------------------------------------------
+
+MasterEdit::~MasterEdit()
+ {
+ }
+
+//---------------------------------------------------------
+// songChanged
+//---------------------------------------------------------
+
+void MasterEdit::songChanged(int type)
+ {
+ if (type & SC_TEMPO) {
+ int tempo = AL::tempomap.tempo(song->cpos());
+ curTempo->setTempo(tempo);
+ }
+ if (type & SC_MASTER)
+ enableMasterAction->setChecked(song->masterFlag());
+ }
+
+//---------------------------------------------------------
+// _setRaster
+//---------------------------------------------------------
+
+void MasterEdit::_setRaster(int index)
+ {
+ setRaster(rasterTable[index]);
+ }
+
+//---------------------------------------------------------
+// setRaster
+//---------------------------------------------------------
+
+void MasterEdit::setRaster(int val)
+ {
+ _raster = val;
+ tcanvas->setRaster(val);
+ for (unsigned i = 0; i < sizeof(rasterTable)/sizeof(*rasterTable); ++i) {
+ if (rasterTable[i] == val) {
+ rasterLabel->setCurrentIndex(i);
+ return;
+ }
+ }
+ rasterLabel->setCurrentIndex(1);
+ }
+
+//---------------------------------------------------------
+// posChanged
+//---------------------------------------------------------
+
+void MasterEdit::posChanged(int idx, const AL::Pos& pos, bool)
+ {
+ if (idx == 0) {
+ unsigned val = pos.tick();
+ int tempo = AL::tempomap.tempo(val);
+ AL::TimeSignature sig = AL::sigmap.timesig(val);
+ curSig->blockSignals(true);
+
+ curTempo->setTempo(tempo);
+ curSig->setValue(sig);
+
+ curSig->blockSignals(false);
+ }
+ }
+
+//---------------------------------------------------------
+// setTempo
+//---------------------------------------------------------
+
+void MasterEdit::setTempo(int val)
+ {
+ if (val == -1)
+ tempo->setEnabled(false);
+ else {
+ tempo->setEnabled(true);
+ tempo->setValue(val);
+ }
+ }
+
+//---------------------------------------------------------
+// read
+//---------------------------------------------------------
+
+void MasterEdit::read(QDomNode node)
+ {
+ for (node = node.firstChild(); !node.isNull(); node = node.nextSibling())
+ AL::readProperties(this, node);
+ }
+
+//---------------------------------------------------------
+// write
+//---------------------------------------------------------
+
+void MasterEdit::write(Xml& xml) const
+ {
+ xml.stag(metaObject()->className());
+ xml.writeProperties(this);
+ xml.etag(metaObject()->className());
+ }
+
+//---------------------------------------------------------
+// tool
+//---------------------------------------------------------
+
+int MasterEdit::tool() const
+ {
+ return tcanvas->tool();
+ }
+
+//---------------------------------------------------------
+// setTool
+//---------------------------------------------------------
+
+void MasterEdit::setTool(int n)
+ {
+ tcanvas->setTool(n);
+ tools2->set(n);
+ }
+
+//---------------------------------------------------------
+// canvasPos
+//---------------------------------------------------------
+
+QPoint MasterEdit::canvasPos() const
+ {
+ return tcanvas->getWPos();
+ }
+
+//---------------------------------------------------------
+// setCanvasPos
+//---------------------------------------------------------
+
+void MasterEdit::setCanvasPos(const QPoint& p)
+ {
+ tcanvas->setWPos(p);
+ }
+
+//---------------------------------------------------------
+// xmag
+//---------------------------------------------------------
+
+double MasterEdit::xmag() const
+ {
+ return tcanvas->xmag();
+ }
+
+//---------------------------------------------------------
+// setXmag
+//---------------------------------------------------------
+
+void MasterEdit::setXmag(double val)
+ {
+ tcanvas->setMag(val, tcanvas->ymag());
+ }
+
+//---------------------------------------------------------
+// ymag
+//---------------------------------------------------------
+
+double MasterEdit::ymag() const
+ {
+ return tcanvas->ymag();
+ }
+
+//---------------------------------------------------------
+// setYmag
+//---------------------------------------------------------
+
+void MasterEdit::setYmag(double val)
+ {
+ tcanvas->setMag(tcanvas->xmag(), val);
+ }
+
+
diff --git a/muse_qt4_evolution/muse/master/masteredit.h b/muse_qt4_evolution/muse/master/masteredit.h
new file mode 100644
index 00000000..e60f3a67
--- /dev/null
+++ b/muse_qt4_evolution/muse/master/masteredit.h
@@ -0,0 +1,107 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __MASTER_EDIT_H__
+#define __MASTER_EDIT_H__
+
+#include "editor.h"
+#include "widgets/noteinfo.h"
+#include "cobject.h"
+
+class MasterCanvas;
+class EditToolBar;
+
+namespace AL {
+ class Xml;
+ };
+using AL::Xml;
+
+namespace Awl {
+ class TempoEdit;
+ class SigEdit;
+ class PosLabel;
+ class TempoLabel;
+ };
+using Awl::TempoEdit;
+using Awl::SigEdit;
+using Awl::PosLabel;
+using Awl::TempoLabel;
+
+//---------------------------------------------------------
+// MasterEdit
+//---------------------------------------------------------
+
+class MasterEdit : public Editor {
+ Q_OBJECT
+ Q_PROPERTY(int raster READ raster WRITE setRaster)
+ Q_PROPERTY(QPoint canvasPos READ canvasPos WRITE setCanvasPos)
+ Q_PROPERTY(int tool READ tool WRITE setTool)
+ Q_PROPERTY(double xmag READ xmag WRITE setXmag)
+ Q_PROPERTY(double ymag READ ymag WRITE setYmag)
+
+ EditToolBar* tools2;
+ QAction* enableMasterAction;
+ TempoEdit* curTempo;
+ SigEdit* curSig;
+ QComboBox* rasterLabel;
+ QToolBar* tools;
+ PosLabel* cursorPos;
+ TempoLabel* tempo;
+
+ int _raster;
+
+ MasterCanvas* canvas() { return (MasterCanvas*)tcanvas; }
+
+ private slots:
+ void _setRaster(int);
+ void posChanged(int idx, const AL::Pos& pos, bool);
+ void setTempo(int);
+ void songChanged(int);
+
+ signals:
+ void deleted(void*);
+
+ public:
+ MasterEdit();
+ ~MasterEdit();
+ void read(QDomNode);
+ void write(Xml&) const;
+
+ int raster() const { return _raster; }
+ void setRaster(int val);
+ QPoint canvasPos() const;
+ void setCanvasPos(const QPoint&);
+ double xmag() const;
+ void setXmag(double val);
+ double ymag() const;
+ void setYmag(double val);
+ int tool() const;
+ void setTool(int);
+
+ static int initRaster, initWidth, initHeight;
+ static double initXmag, initYmag;
+
+ static const int INIT_RASTER = 384;
+ static const int INIT_WIDTH = 650;
+ static const int INIT_HEIGHT = 450;
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/midi.cpp b/muse_qt4_evolution/muse/midi.cpp
new file mode 100644
index 00000000..a182fe4a
--- /dev/null
+++ b/muse_qt4_evolution/muse/midi.cpp
@@ -0,0 +1,633 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "song.h"
+#include "midi.h"
+#include "midiedit/drummap.h"
+#include "event.h"
+#include "globals.h"
+#include "midictrl.h"
+#include "midictrl.h"
+#include "audio.h"
+#include "audiodev.h"
+#include "wave.h"
+#include "synth.h"
+#include "sync.h"
+#include "gconfig.h"
+#include "ticksynth.h"
+#include "al/tempo.h"
+#include "al/sig.h"
+#include "part.h"
+#include "midiplugin.h"
+#include "midiinport.h"
+#include "midioutport.h"
+#include "instruments/minstrument.h"
+
+extern void dump(const unsigned char* p, int n);
+
+unsigned const char gmOnMsg[] = {
+ 0x7e, // Non-Real Time header
+ 0x7f, // ID of target device (7f = all devices)
+ 0x09,
+ 0x01
+ };
+unsigned const char gsOnMsg[] = {
+ 0x41, // roland id
+ 0x10, // Id of target device (default = 10h for roland)
+ 0x42, // model id (42h = gs devices)
+ 0x12, // command id (12h = data set)
+ 0x40, // address & value
+ 0x00,
+ 0x7f,
+ 0x00,
+ 0x41 // checksum?
+ };
+unsigned const char xgOnMsg[] = {
+ 0x43, // yamaha id
+ 0x10, // device number (0)
+ 0x4c, // model id
+ 0x00, // address (high, mid, low)
+ 0x00,
+ 0x7e,
+ 0x00 // data
+ };
+unsigned const int gmOnMsgLen = sizeof(gmOnMsg);
+unsigned const int gsOnMsgLen = sizeof(gsOnMsg);
+unsigned const int xgOnMsgLen = sizeof(xgOnMsg);
+
+/*---------------------------------------------------------
+ * midi_meta_name
+ *---------------------------------------------------------*/
+
+QString midiMetaName(int meta)
+ {
+ const char* s = "";
+ switch (meta) {
+ case 0: s = "Sequence Number"; break;
+ case 1: s = "Text Event"; break;
+ case 2: s = "Copyright"; break;
+ case 3: s = "Sequence/Track Name"; break;
+ case 4: s = "Instrument Name"; break;
+ case 5: s = "Lyric"; break;
+ case 6: s = "Marker"; break;
+ case 7: s = "Cue Point"; break;
+ case 8:
+ case 9:
+ case 0x0a:
+ case 0x0b:
+ case 0x0c:
+ case 0x0d:
+ case 0x0e:
+ case 0x0f: s = "Text"; break;
+ case 0x20: s = "Channel Prefix"; break;
+ case 0x21: s = "Port Change"; break;
+ case 0x2f: s = "End of Track"; break;
+ case 0x51: s = "Set Tempo"; break;
+ case 0x54: s = "SMPTE Offset"; break;
+ case 0x58: s = "Time Signature"; break;
+ case 0x59: s = "Key Signature"; break;
+ case 0x74: s = "Sequencer-Specific1"; break;
+ case 0x7f: s = "Sequencer-Specific2"; break;
+ default:
+ break;
+ }
+ return QString(s);
+ }
+
+//---------------------------------------------------------
+// QString nameSysex
+//---------------------------------------------------------
+
+QString nameSysex(unsigned int len, const unsigned char* buf)
+ {
+ QString s;
+ switch(buf[0]) {
+ case 0x00:
+ if (buf[1] == 0 && buf[2] == 0x41)
+ s = "Microsoft";
+ break;
+ case 0x01: s = "Sequential Circuits: "; break;
+ case 0x02: s = "Big Briar: "; break;
+ case 0x03: s = "Octave / Plateau: "; break;
+ case 0x04: s = "Moog: "; break;
+ case 0x05: s = "Passport Designs: "; break;
+ case 0x06: s = "Lexicon: "; break;
+ case 0x07: s = "Kurzweil"; break;
+ case 0x08: s = "Fender"; break;
+ case 0x09: s = "Gulbransen"; break;
+ case 0x0a: s = "Delta Labas"; break;
+ case 0x0b: s = "Sound Comp."; break;
+ case 0x0c: s = "General Electro"; break;
+ case 0x0d: s = "Techmar"; break;
+ case 0x0e: s = "Matthews Research"; break;
+ case 0x10: s = "Oberheim"; break;
+ case 0x11: s = "PAIA: "; break;
+ case 0x12: s = "Simmons: "; break;
+ case 0x13: s = "DigiDesign"; break;
+ case 0x14: s = "Fairlight: "; break;
+ case 0x15: s = "JL Cooper"; break;
+ case 0x16: s = "Lowery"; break;
+ case 0x17: s = "Lin"; break;
+ case 0x18: s = "Emu"; break;
+ case 0x1b: s = "Peavy"; break;
+ case 0x20: s = "Bon Tempi: "; break;
+ case 0x21: s = "S.I.E.L: "; break;
+ case 0x23: s = "SyntheAxe: "; break;
+ case 0x24: s = "Hohner"; break;
+ case 0x25: s = "Crumar"; break;
+ case 0x26: s = "Solton"; break;
+ case 0x27: s = "Jellinghaus Ms"; break;
+ case 0x28: s = "CTS"; break;
+ case 0x29: s = "PPG"; break;
+ case 0x2f: s = "Elka"; break;
+ case 0x36: s = "Cheetah"; break;
+ case 0x3e: s = "Waldorf"; break;
+ case 0x40: s = "Kawai: "; break;
+ case 0x41: s = "Roland: "; break;
+ case 0x42: s = "Korg: "; break;
+ case 0x43: s = "Yamaha: "; break;
+ case 0x44: s = "Casio"; break;
+ case 0x45: s = "Akai"; break;
+ case 0x7c: s = "MusE Soft Synth"; break;
+ case 0x7d: s = "Educational Use"; break;
+ case 0x7e: s = "Universal: Non Real Time"; break;
+ case 0x7f: s = "Universal: Real Time"; break;
+ default: s = "??: "; break;
+ }
+ //
+ // following messages should not show up in event list
+ // they are filtered while importing midi files
+ //
+ if ((len == gmOnMsgLen) && memcmp(buf, gmOnMsg, gmOnMsgLen) == 0)
+ s += "GM-ON";
+ else if ((len == gsOnMsgLen) && memcmp(buf, gsOnMsg, gsOnMsgLen) == 0)
+ s += "GS-ON";
+ else if ((len == xgOnMsgLen) && memcmp(buf, xgOnMsg, xgOnMsgLen) == 0)
+ s += "XG-ON";
+ return s;
+ }
+
+//---------------------------------------------------------
+// buildMidiEventList
+// TODO:
+// parse data increment/decrement controller
+// NRPN/RPN fine/course data 7/14 Bit
+// must we set datah/datal to zero after change
+// of NRPN/RPN register?
+// generally: how to handle incomplete messages?
+//---------------------------------------------------------
+
+void buildMidiEventList(EventList* del, const MidiEventList* el, MidiTrack* track, int channel,
+ int div, bool addSysexMeta)
+ {
+ QString tname;
+ int hbank = 0xff;
+ int lbank = 0xff;
+ int rpnh = -1;
+ int rpnl = -1;
+ int datah = 0;
+ int datal = 0;
+ int dataType = 0; // 0 : disabled, 0x20000 : rpn, 0x30000 : nrpn
+
+ EventList mel;
+ int metaChannel = -1;
+ for (iMidiEvent i = el->begin(); i != el->end(); ++i) {
+ MidiEvent ev = *i;
+ if (ev.type() == ME_META) {
+ if (ev.dataA() == 0x20) {
+ metaChannel = ((char*)(ev.data()))[0];
+ }
+ if (metaChannel == channel) {
+ if (ev.dataA() == 0x4) {
+ tname = (char*)(ev.data());
+ }
+ }
+ }
+ if (!addSysexMeta && (ev.type() == ME_SYSEX || ev.type() == ME_META))
+ continue;
+ if (!(ev.type() == ME_SYSEX || ev.type() == ME_META || (ev.channel() == channel)))
+ continue;
+ int tick = ev.time();
+ Event e;
+ switch(ev.type()) {
+ case ME_NOTEON:
+ e.setType(Note);
+
+ if (track->useDrumMap()) {
+ int instr = track->drumMap()->inmap(ev.dataA());
+ e.setPitch(instr);
+ }
+ else
+ e.setPitch(ev.dataA());
+
+ e.setVelo(ev.dataB());
+ e.setLenTick(0);
+ break;
+ case ME_NOTEOFF:
+ e.setType(Note);
+ if (track->useDrumMap()) {
+ int instr = track->drumMap()->inmap(ev.dataA());
+ e.setPitch(instr);
+ }
+ else
+ e.setPitch(ev.dataA());
+ e.setVelo(0);
+ e.setVeloOff(ev.dataB());
+ e.setLenTick(0);
+ break;
+ case ME_POLYAFTER:
+ e.setType(PAfter);
+ e.setA(ev.dataA());
+ e.setB(ev.dataB());
+ break;
+ case ME_CONTROLLER:
+ {
+ int val = ev.dataB();
+ switch(ev.dataA()) {
+ case CTRL_HBANK:
+ hbank = val;
+ break;
+
+ case CTRL_LBANK:
+ lbank = val;
+ break;
+
+ case CTRL_HDATA:
+ datah = val;
+ // check if a CTRL_LDATA follows
+ // e.g. wie have a 14 bit controller:
+ {
+ iMidiEvent ii = i;
+ ++ii;
+ bool found = false;
+ for (; ii != el->end(); ++ii) {
+ MidiEvent ev = *ii;
+ if (ev.type() == ME_CONTROLLER) {
+ if (ev.dataA() == CTRL_LDATA) {
+ // handle later
+ found = true;
+ }
+ break;
+ }
+ }
+ if (!found) {
+ if (rpnh == -1 || rpnl == -1) {
+ printf("parameter number not defined, data 0x%x\n", datah);
+ }
+ else {
+ int ctrl = dataType | (rpnh << 8) | rpnl;
+ e.setType(Controller);
+ e.setA(ctrl);
+ e.setB(datah);
+ }
+ }
+ }
+ break;
+
+ case CTRL_LDATA:
+ datal = val;
+
+ if (rpnh == -1 || rpnl == -1) {
+ printf("parameter number not defined, data 0x%x 0x%x, tick %d, channel %d\n",
+ datah, datal, tick, channel);
+ break;
+ }
+ // assume that the sequence is always
+ // CTRL_HDATA - CTRL_LDATA
+ // eg. that LDATA is always send last
+
+ e.setType(Controller);
+ // 14 Bit RPN/NRPN
+ e.setA((dataType+0x30000) | (rpnh << 8) | rpnl);
+ e.setB((datah << 7) | datal);
+ break;
+
+ case CTRL_HNRPN:
+ rpnh = val;
+ dataType = 0x30000;
+ break;
+
+ case CTRL_LNRPN:
+ rpnl = val;
+ dataType = 0x30000;
+ break;
+
+ case CTRL_HRPN:
+ rpnh = val;
+ dataType = 0x20000;
+ break;
+
+ case CTRL_LRPN:
+ rpnl = val;
+ dataType = 0x20000;
+ break;
+
+ default:
+ e.setType(Controller);
+ e.setA(ev.dataA());
+ e.setB(val);
+ break;
+ }
+ }
+ break;
+
+ case ME_PROGRAM:
+ e.setType(Controller);
+ e.setA(CTRL_PROGRAM);
+ e.setB((hbank << 16) | (lbank << 8) | ev.dataA());
+ break;
+
+ case ME_AFTERTOUCH:
+ e.setType(CAfter);
+ e.setA(ev.dataA());
+ break;
+
+ case ME_PITCHBEND:
+ e.setType(Controller);
+ e.setA(CTRL_PITCH);
+ e.setB(ev.dataA());
+ break;
+
+ case ME_SYSEX:
+ e.setType(Sysex);
+ e.setData(ev.data(), ev.len());
+ break;
+
+ case ME_META:
+ {
+ const unsigned char* data = ev.data();
+ switch (ev.dataA()) {
+ case 0x01: // Text
+ if (track->comment().isEmpty())
+ track->setComment(QString((const char*)data));
+ else
+ track->setComment(track->comment() + "\n" + QString((const char*)data));
+ break;
+ case 0x02: // Copyright
+ config.copyright = (char*)data;
+ break;
+ case 0x03: // Sequence-/TrackName
+ tname = (char*)data;
+ break;
+ case 0x6: // Marker
+ {
+ Pos pos((tick * config.division + div/2) / div, AL::TICKS);
+ song->addMarker(QString((const char*)(data)), pos);
+ }
+ break;
+ case 0x4: // Instrument Name
+ case 0x5: // Lyrics
+ case 0x8: // text
+ case 0x9:
+ case 0xa:
+ case 0x20: // channel prefix
+ case 0x21: // port change
+ break;
+
+ case 0x0f: // Track Comment
+ track->setComment(QString((char*)data));
+ break;
+
+ case 0x51: // Tempo
+ {
+ int tempo = data[2] + (data[1] << 8) + (data[0] <<16);
+ int ltick = (tick * config.division + div/2) / div;
+ AL::tempomap.addTempo(ltick, tempo);
+ }
+ break;
+
+ case 0x58: // Time Signature
+ {
+ int timesig_z = data[0];
+ int n = data[1];
+ int timesig_n = 1;
+ for (int i = 0; i < n; i++)
+ timesig_n *= 2;
+ int ltick = (tick * config.division + div/2) / div;
+ AL::sigmap.add(ltick, AL::TimeSignature(timesig_z, timesig_n));
+ }
+ break;
+
+ case 0x59: // Key Signature
+ printf("Meta: Key Signature %d %d\n", data[0], data[1]);
+ // track->scale.set(data[0]);
+ // track->scale.setMajorMinor(data[1]);
+ break;
+
+ case 0x7f: // Sequencer Specific
+ printf("Meta: Seq specific:len %d\n", ev.len());
+ break;
+
+ default:
+ printf("unknown Meta 0x%x %d\n", ev.dataA(), ev.dataA());
+ }
+ }
+ break;
+ } // switch(ev.type()
+ if (!e.empty()) {
+ e.setTick(tick);
+ mel.add(e);
+ }
+ } // i != el->end()
+
+ //---------------------------------------------------
+ // resolve NoteOff events
+ //---------------------------------------------------
+
+ for (iEvent i = mel.begin(); i != mel.end(); ++i) {
+ Event ev = i->second;
+ if (!ev.isNote())
+ continue;
+ if (ev.lenTick())
+ continue;
+// printf("%d note %d %d\n", ev.tick(), ev.pitch(), ev.velo());
+ if (ev.isNoteOff()) {
+ bool found = false;
+ iEvent k = i;
+// printf(" start with note off\n");
+ for (++k; k != mel.end(); ++k) {
+ Event event = k->second;
+ if (event.tick() > ev.tick())
+ break;
+ if (event.isNote() && event.velo() && event.pitch() == ev.pitch()) {
+ ev.setLenTick(1);
+ ev.setVelo(event.velo());
+ ev.setVeloOff(0);
+ found = true;
+// printf(" found on: %d\n", event.tick());
+ break;
+ }
+ }
+ if (!found) {
+ // maybe found note with velocity zero is really a
+ // note-on !
+ k = i;
+ found = true;
+ for (++k; k != mel.end(); ++k) {
+ Event event = k->second;
+ if (!event.isNote())
+ continue;
+ if (event.pitch() == ev.pitch()) {
+ if (event.velo() == 0) {
+ found = true;
+ int t = event.tick() - ev.tick();
+ ev.setLenTick(t);
+ ev.setVelo(1);
+ ev.setVeloOff(0);
+ mel.erase(k);
+ i = mel.begin();
+ }
+ break;
+ }
+ }
+ if (!found) {
+ printf("NOTE OFF without Note ON tick %d type %d %d %d\n",
+ ev.tick(), ev.type(), ev.pitch(), ev.velo());
+ }
+ else
+ continue;
+ }
+ else {
+ mel.erase(k);
+ i = mel.begin(); // DEBUG
+ continue;
+ }
+ }
+ iEvent k;
+ // ev is noteOn
+ for (k = mel.lower_bound(ev.tick()); k != mel.end(); ++k) {
+ Event event = k->second;
+// printf(" - %d(%d,%d)\n", event.tick(), event.pitch(), event.velo());
+ if (ev.isNoteOff(event)) {
+ int t = k->first - i->first;
+ if (t <= 0) {
+ if (debugMsg) {
+ printf("Note len is (%d-%d)=%d, set to 1\n",
+ k->first, i->first, k->first - i->first);
+ ev.dump();
+ event.dump();
+ }
+ t = 1;
+ }
+ ev.setLenTick(t);
+ ev.setVeloOff(event.veloOff());
+ break;
+ }
+ }
+ if (k == mel.end()) {
+ printf(" -no note-off! %d pitch %d velo %d\n",
+ ev.tick(), ev.pitch(), ev.velo());
+ //
+ // switch off at end of measure
+ //
+ int endTick = song->roundUpBar(ev.tick()+1);
+ ev.setLenTick(endTick-ev.tick());
+ }
+ else {
+ mel.erase(k);
+ i = mel.begin();
+ }
+ }
+
+ for (iEvent i = mel.begin(); i != mel.end(); ++i) {
+ Event ev = i->second;
+ if (ev.isNoteOff()) {
+ printf("+extra note-off! %d pitch %d velo %d\n",
+ i->first, ev.pitch(), ev.velo());
+// ev.dump();
+ continue;
+ }
+ int tick = (ev.tick() * config.division + div/2) / div;
+ if (ev.isNote()) {
+ int lenTick = (ev.lenTick() * config.division + div/2) / div;
+ ev.setLenTick(lenTick);
+ }
+ ev.setTick(tick);
+ if (ev.type() == Controller) {
+ int id = ev.dataA();
+ CVal val;
+ val.i = ev.dataB();
+
+// bool found = false;
+ Ctrl* c = track->getController(id);
+ if (c)
+ c->add(tick, val);
+ else
+ // if no managed controller, store as event
+ del->add(ev);
+ }
+ else
+ del->add(ev);
+ }
+ if (!tname.isEmpty())
+ track->setName(tname);
+ }
+
+//---------------------------------------------------------
+// initMidiDevices
+//---------------------------------------------------------
+
+void Audio::initMidiDevices()
+ {
+ //
+ // test for explicit instrument initialization
+ //
+ MidiOutPortList* mpl = song->midiOutPorts();
+ for (iMidiOutPort i = mpl->begin(); i != mpl->end(); ++i) {
+ MidiOutPort* mp = *i;
+ MidiInstrument* instr = mp->instrument();
+ if (!instr)
+ continue; // TODO: use default instrument?
+ EventList* events = instr->midiInit();
+ for (iEvent ie = events->begin(); ie != events->end(); ++ie) {
+ MidiEvent ev(0, 0, ie->second);
+ mp->playMidiEvent(&ev);
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// resetMidiDevices
+//---------------------------------------------------------
+
+void Audio::resetMidiDevices()
+ {
+ MidiTrackList* mcl = song->midis();
+ for (iMidiTrack i = mcl->begin(); i != mcl->end(); ++i) {
+ MidiTrack* mc = *i;
+ if (!mc->mute() && mc->autoRead()) {
+ CtrlList* cl = mc->controller();
+ for (iCtrl ic = cl->begin(); ic != cl->end(); ++ic) {
+ ic->second->setCurVal(CTRL_VAL_UNKNOWN);
+ }
+ }
+ }
+ MidiOutPortList* mpl = song->midiOutPorts();
+ for (iMidiOutPort i = mpl->begin(); i != mpl->end(); ++i) {
+ MidiOutPort* mp = *i;
+ if (!mp->mute() && mp->autoRead()) {
+ CtrlList* cl = mp->controller();
+ for (iCtrl ic = cl->begin(); ic != cl->end(); ++ic) {
+ ic->second->setCurVal(CTRL_VAL_UNKNOWN);
+ }
+ }
+ }
+ }
+
diff --git a/muse_qt4_evolution/muse/midi.h b/muse_qt4_evolution/muse/midi.h
new file mode 100644
index 00000000..d6713c5a
--- /dev/null
+++ b/muse_qt4_evolution/muse/midi.h
@@ -0,0 +1,68 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __MIDI_H__
+#define __MIDI_H__
+
+enum {
+ ME_NOTEOFF = 0x80,
+ ME_NOTEON = 0x90,
+ ME_POLYAFTER = 0xa0,
+ ME_CONTROLLER = 0xb0,
+ ME_PROGRAM = 0xc0,
+ ME_AFTERTOUCH = 0xd0,
+ ME_PITCHBEND = 0xe0,
+ ME_SYSEX = 0xf0,
+ ME_META = 0xff,
+ ME_MTC_QUARTER = 0xf1,
+ ME_SONGPOS = 0xf2,
+ ME_SONGSEL = 0xf3,
+ ME_TUNE_REQ = 0xf6,
+ ME_SYSEX_END = 0xf7,
+ ME_CLOCK = 0xf8,
+ ME_TICK = 0xf9,
+ ME_START = 0xfa,
+ ME_CONTINUE = 0xfb,
+ ME_STOP = 0xfc,
+ ME_SENSE = 0xfe,
+ };
+
+#define ME_TIMESIG 0x58
+
+extern unsigned const char gmOnMsg[];
+extern unsigned const char gsOnMsg[];
+extern unsigned const char xgOnMsg[];
+
+extern unsigned const int gmOnMsgLen;
+extern unsigned const int gsOnMsgLen;
+extern unsigned const int xgOnMsgLen;
+
+QString nameSysex(unsigned int len, const unsigned char* buf);
+QString midiMetaName(int);
+
+class EventList;
+class MidiTrack;
+class MidiEventList;
+
+extern void buildMidiEventList(EventList* mel, const MidiEventList* el, MidiTrack* track,
+ int channel, int division, bool);
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/midictrl.cpp b/muse_qt4_evolution/muse/midictrl.cpp
new file mode 100644
index 00000000..89e40ec1
--- /dev/null
+++ b/muse_qt4_evolution/muse/midictrl.cpp
@@ -0,0 +1,372 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "midictrl.h"
+#include "al/xml.h"
+
+static const char* ctrlName[] = {
+ "BankSelMSB", "Modulation", "BreathCtrl", "Control 3", "Foot Ctrl",
+ "Porta Time", "DataEntMSB", "MainVolume", "Balance", "Control 9",
+/*10*/ "Pan", "Expression", "Control 12", "Control 13", "Control 14",
+ "Control 15", "Gen.Purp.1", "Gen.Purp.2", "Gen.Purp.3", "Gen.Purp.4",
+/*20*/ "Control 20", "Control 21", "Control 22", "Control 23", "Control 24",
+ "Control 25", "Control 26", "Control 27", "Control 28", "Control 29",
+/*30*/ "Control 30", "Control 31", "BankSelLSB", "Modul. LSB", "BrthCt.LSB",
+ "Control 35", "FootCt.LSB", "Port.T LSB", "DataEntLSB", "MainVolLSB",
+ "BalanceLSB", "Control 41", "Pan LSB", "Expr. LSB", "Control 44",
+ "Control 45", "Control 46", "Control 47", "Gen.P.1LSB", "Gen.P.2LSB",
+/*50*/ "Gen.P.3LSB", "Gen.P.4LSB", "Control 52", "Control 53", "Control 54",
+ "Control 55", "Control 56", "Control 57", "Control 58", "Control 59",
+ "Control 60", "Control 61", "Control 62", "Control 63", "Sustain",
+ "Porta Ped", "Sostenuto", "Soft Pedal", "Control 68", "Hold 2",
+ "Control 70", "HarmonicCo", "ReleaseTime", "Attack Time", "Brightness",
+ "Control 75", "Control 76", "Control 77", "Control 78", "Control 79",
+ "Gen.Purp.5", "Gen.Purp.6", "Gen.Purp.7", "Gen.Purp.8", "Porta Ctrl",
+ "Control 85", "Control 86", "Control 87", "Control 88", "Control 89",
+ "Control 90", "Effect1Dep", "Effect2Dep", "Effect3Dep", "Effect4Dep",
+ "Phaser Dep", "Data Incr", "Data Decr", "NRPN LSB", "NRPN MSB",
+/*100*/ "RPN LSB", "RPN MSB", "Control102", "Control103", "Control104",
+ "Control105", "Control106", "Control107", "Control108", "Control109",
+ "Control110", "Control111", "Control112", "Control113", "Control114",
+ "Control115", "Control116", "Control117", "Control118", "Control119",
+ "AllSndOff", "Reset Ctrl", "Local Ctrl", "AllNoteOff", "OmniModOff",
+ "OmniModeOn", "MonoModeOn", "PolyModeOn"
+ };
+
+#if 0
+static const char* ctrl14Name[] = {
+ "BankSel", "Modulation", "BreathCtrl",
+ "Control 3", "Foot Ctrl", "Porta Time", "DataEntry",
+ "MainVolume", "Balance", "Control 9", "Pan",
+ "Expression", "Control 12", "Control 13", "Control 14",
+ "Control 15", "Gen.Purp.1", "Gen.Purp.2", "Gen.Purp.3",
+ "Gen.Purp.4", "Control 20", "Control 21", "Control 22",
+ "Control 23", "Control 24", "Control 25", "Control 26",
+ "Control 27", "Control 28", "Control 29", "Control 30",
+ "Control 31",
+ };
+#endif
+
+enum {
+ COL_NAME = 0, COL_TYPE,
+ COL_HNUM, COL_LNUM, COL_MIN, COL_MAX
+ };
+
+MidiControllerList defaultMidiController;
+//
+// some global controller which are always available:
+//
+MidiController veloCtrl("Velocity", CTRL_VELOCITY, 0, 127, 0);
+static MidiController pitchCtrl("PitchBend", CTRL_PITCH, -8192, +8191, 0);
+static MidiController programCtrl("Program", CTRL_PROGRAM, 0, 0xffffff, 0);
+static MidiController mastervolCtrl("MasterVolume", CTRL_MASTER_VOLUME, 0, 0x3fff, 0x3000);
+static MidiController volumeCtrl("MainVolume", CTRL_VOLUME, 0, 127, 100);
+static MidiController panCtrl("Pan", CTRL_PANPOT, 0, 127, 64);
+static MidiController reverbCtrl("ReverbSend", CTRL_REVERB_SEND, 0, 127, 0);
+static MidiController chorusCtrl("ChorusSend", CTRL_CHORUS_SEND, 0, 127, 0);
+static MidiController variationCtrl("VariationSend",CTRL_VARIATION_SEND,0, 127, 0);
+
+//---------------------------------------------------------
+// ctrlType2Int
+// int2ctrlType
+//---------------------------------------------------------
+
+static struct {
+ MidiController::ControllerType type;
+ QString name;
+ } ctrlTypes[] = {
+ { MidiController::Controller7, QString("Control7") },
+ { MidiController::Controller14, QString("Control14") },
+ { MidiController::RPN, QString("RPN") },
+ { MidiController::NRPN, QString("NRPN") },
+ { MidiController::Pitch, QString("Pitch") },
+ { MidiController::Program, QString("Program") },
+ { MidiController::RPN14, QString("RPN14") },
+ { MidiController::NRPN14, QString("NRPN14") },
+ { MidiController::Controller7, QString("Control") }, // alias
+ };
+
+//---------------------------------------------------------
+// ctrlType2Int
+//---------------------------------------------------------
+
+MidiController::ControllerType ctrlType2Int(const QString& s)
+ {
+ int n = sizeof(ctrlTypes)/sizeof(*ctrlTypes);
+ for (int i = 0; i < n; ++i) {
+ if (ctrlTypes[i].name == s)
+ return ctrlTypes[i].type;
+ }
+ return MidiController::ControllerType(0);
+ }
+
+//---------------------------------------------------------
+// int2ctrlType
+//---------------------------------------------------------
+
+const QString& int2ctrlType(int n)
+ {
+ static QString dontKnow("?T?");
+ int size = sizeof(ctrlTypes)/sizeof(*ctrlTypes);
+ for (int i = 0; i < size; ++i) {
+ if (ctrlTypes[i].type == n)
+ return ctrlTypes[i].name;
+ }
+ return dontKnow;
+ }
+
+//---------------------------------------------------------
+// initMidiController
+//---------------------------------------------------------
+
+void initMidiController()
+ {
+ static bool initialized = false;
+ if (initialized)
+ return;
+ defaultMidiController.push_back(&veloCtrl);
+ defaultMidiController.push_back(&pitchCtrl);
+ defaultMidiController.push_back(&programCtrl);
+ defaultMidiController.push_back(&mastervolCtrl);
+ defaultMidiController.push_back(&volumeCtrl);
+ defaultMidiController.push_back(&panCtrl);
+ defaultMidiController.push_back(&reverbCtrl);
+ defaultMidiController.push_back(&chorusCtrl);
+ defaultMidiController.push_back(&variationCtrl);
+ initialized = true;
+ }
+
+//---------------------------------------------------------
+// midiCtrlName
+//---------------------------------------------------------
+
+QString midiCtrlName(int ctrl)
+ {
+ if (ctrl < 0x10000)
+ return QString(ctrlName[ctrl]);
+ QString s("?N?");
+ switch(ctrl) {
+ case CTRL_PITCH:
+ s = "Pitch";
+ break;
+ case CTRL_PROGRAM:
+ s = "ProgramChange";
+ break;
+ case CTRL_VELOCITY:
+ s = "Velocity";
+ break;
+ case CTRL_MASTER_VOLUME:
+ s = "MasterVolume";
+ break;
+ default:
+ printf("midiCtrlName unknown %x\n", ctrl);
+ break;
+ }
+ return s;
+ }
+
+//---------------------------------------------------------
+// MidiController
+//---------------------------------------------------------
+
+MidiController::MidiController()
+ : _name(QString(QT_TR_NOOP("Velocity")))
+ {
+ _num = CTRL_VELOCITY;
+ _minVal = 0;
+ _maxVal = 127;
+ _initVal = 0;
+ _moveWithPart = true;
+ }
+
+MidiController::MidiController(const QString& s, int n, int min, int max, int init,
+ bool mwp)
+ : _name(s), _num(n), _minVal(min), _maxVal(max), _initVal(init),
+ _moveWithPart(mwp)
+ {
+ }
+
+//---------------------------------------------------------
+// type
+//---------------------------------------------------------
+
+MidiController::ControllerType midiControllerType(int num)
+ {
+ if (num == CTRL_PITCH)
+ return MidiController::Pitch;
+ if (num == CTRL_PROGRAM)
+ return MidiController::Program;
+ if (num == CTRL_VELOCITY || num == CTRL_SVELOCITY)
+ return MidiController::Velo;
+ if (num < CTRL_14_OFFSET)
+ return MidiController::Controller7;
+ if (num < CTRL_RPN_OFFSET)
+ return MidiController::Controller14;
+ if (num < CTRL_NRPN_OFFSET)
+ return MidiController::RPN;
+ if (num < CTRL_RPN14_OFFSET)
+ return MidiController::NRPN;
+ if (num < CTRL_NRPN14_OFFSET)
+ return MidiController::RPN14;
+ if (num < CTRL_NONE_OFFSET)
+ return MidiController::NRPN14;
+ return MidiController::Controller7;
+ }
+
+//---------------------------------------------------------
+// MidiController::write
+//---------------------------------------------------------
+
+void MidiController::write(Xml& xml) const
+ {
+ ControllerType t = midiControllerType(_num);
+ QString type(int2ctrlType(t));
+
+ int h = (_num >> 8) & 0x7f;
+ int l = _num & 0x7f;
+
+ QString sl;
+ if ((_num & 0xff) == 0xff)
+ sl = "Pitch";
+ else
+ sl.setNum(l);
+
+ QString s = QString("Controller name=\"%1\" type=\"%2\" h=\"%3\" l=\"%4\" min=\"%5\" max=\"%6\" init=\"%7\"")
+ .arg(Xml::xmlString(_name)).arg(type).arg(h).arg(sl).arg(_minVal).arg(_maxVal).arg(_initVal);
+ if (_comment.isEmpty())
+ xml.tagE(s);
+ else {
+ xml.putLevel();
+ xml << '<' << s << '>' << Xml::xmlString(_comment) << "</Controller>\n";
+ }
+ }
+
+//---------------------------------------------------------
+// MidiController::read
+//---------------------------------------------------------
+
+void MidiController::read(QDomNode node)
+ {
+ ControllerType t = Controller7;
+ static const int NOT_SET = 0x100000;
+ int l = 0;
+
+ QDomElement e = node.toElement();
+ _name = e.attribute("name");
+ _comment = e.text();
+ t = ctrlType2Int(e.attribute("type"));
+ int h = e.attribute("h","0").toInt(0,0);
+ QString s = e.attribute("l");
+ if (s == "pitch")
+ l = 0xff;
+ else
+ l = s.toInt(0,0);
+ _minVal = e.attribute("min", "0").toInt(0,0);
+ _maxVal = e.attribute("max", "0x100000").toInt(0,0);
+ _initVal = e.attribute("init", "-1").toInt(0,0);
+
+ _num = (h << 8) + l;
+ switch (t) {
+ case RPN:
+ if (_maxVal == NOT_SET)
+ _maxVal = 127;
+ _num |= 0x20000;
+ break;
+ case NRPN:
+ if (_maxVal == NOT_SET)
+ _maxVal = 127;
+ _num |= 0x30000;
+ break;
+ case Controller7:
+ if (_maxVal == NOT_SET)
+ _maxVal = 127;
+ break;
+ case Controller14:
+ _num |= 0x10000;
+ if (_maxVal == NOT_SET)
+ _maxVal = 127 * 127 * 127;
+ break;
+ case RPN14:
+ if (_maxVal == NOT_SET)
+ _maxVal = 127 * 127 * 127;
+ _num |= 0x50000;
+ break;
+ case NRPN14:
+ if (_maxVal == NOT_SET)
+ _maxVal = 127 * 127 * 127;
+ _num |= 0x60000;
+ break;
+ case Pitch:
+ if (_maxVal == NOT_SET)
+ _maxVal = 8191;
+ if (_minVal == NOT_SET)
+ _minVal = -8192;
+ _num = CTRL_PITCH;
+ break;
+ case Program:
+ if (_maxVal == NOT_SET)
+ _maxVal = 127 * 127 * 127;
+ _num = CTRL_PROGRAM;
+ break;
+ case Velo: // cannot happen
+ break;
+ }
+ return;
+ }
+
+//---------------------------------------------------------
+// type
+//---------------------------------------------------------
+
+MidiController::ControllerType MidiController::type() const
+ {
+ return midiControllerType(num());
+ }
+
+//---------------------------------------------------------
+// genNum
+//---------------------------------------------------------
+
+
+int MidiController::genNum(MidiController::ControllerType t, int h, int l)
+ {
+ int val = (h << 8) + l;
+ switch(t) {
+ case Controller7:
+ return l;
+ case Controller14:
+ return val + CTRL_14_OFFSET;
+ case RPN:
+ return l + CTRL_RPN_OFFSET;
+ case NRPN:
+ return l + CTRL_NRPN_OFFSET;
+ case RPN14:
+ return val + CTRL_RPN14_OFFSET;
+ case NRPN14:
+ return val + CTRL_NRPN14_OFFSET;
+ case Pitch:
+ return CTRL_PITCH;
+ case Program:
+ return CTRL_PROGRAM;
+ default:
+ return -1;
+ }
+ }
+
diff --git a/muse_qt4_evolution/muse/midictrl.h b/muse_qt4_evolution/muse/midictrl.h
new file mode 100644
index 00000000..9d20fdcc
--- /dev/null
+++ b/muse_qt4_evolution/muse/midictrl.h
@@ -0,0 +1,168 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __MIDICTRL_H__
+#define __MIDICTRL_H__
+
+const int CTRL_HBANK = 0x00;
+const int CTRL_LBANK = 0x20;
+
+const int CTRL_HDATA = 0x06;
+const int CTRL_LDATA = 0x26;
+
+const int CTRL_HNRPN = 0x63;
+const int CTRL_LNRPN = 0x62;
+
+const int CTRL_HRPN = 0x65;
+const int CTRL_LRPN = 0x64;
+
+const int CTRL_MODULATION = 0x01;
+const int CTRL_PORTAMENTO_TIME = 0x05;
+const int CTRL_VOLUME = 0x07;
+const int CTRL_PANPOT = 0x0a;
+const int CTRL_EXPRESSION = 0x0b;
+const int CTRL_SUSTAIN = 0x40;
+const int CTRL_PORTAMENTO = 0x41;
+const int CTRL_SOSTENUTO = 0x42;
+const int CTRL_SOFT_PEDAL = 0x43;
+const int CTRL_HARMONIC_CONTENT = 0x47;
+const int CTRL_RELEASE_TIME = 0x48;
+const int CTRL_ATTACK_TIME = 0x49;
+
+const int CTRL_BRIGHTNESS = 0x4a;
+const int CTRL_PORTAMENTO_CONTROL = 0x54;
+const int CTRL_REVERB_SEND = 0x5b;
+const int CTRL_CHORUS_SEND = 0x5d;
+const int CTRL_VARIATION_SEND = 0x5e;
+
+const int CTRL_ALL_SOUNDS_OFF = 0x78; // 120
+const int CTRL_RESET_ALL_CTRL = 0x79; // 121
+const int CTRL_LOCAL_OFF = 0x7a; // 122
+
+// controller types 0x10000 - 0x1ffff are 14 bit controller with
+// 0x1xxyy
+// xx - MSB controller
+// yy - LSB controller
+
+// RPN - registered parameter numbers 0x20000 -
+// NRPN - non registered parameter numbers 0x30000 -
+
+// internal controller types:
+const int CTRL_PITCH = 0x40000;
+const int CTRL_PROGRAM = 0x40001;
+const int CTRL_VELOCITY = 0x40002;
+const int CTRL_MASTER_VOLUME = 0x40003;
+const int CTRL_OTHER = 0x40004;
+const int CTRL_SVELOCITY = 0x40005; // single velocity, used for drum editor
+ // to show only velocity for current instrument
+const int CTRL_NO_CTRL = 0x40006;
+
+const int CTRL_VAL_UNKNOWN = -1; // used as unknown hwVal
+
+const int CTRL_14_OFFSET = 0x10000;
+const int CTRL_RPN_OFFSET = 0x20000;
+const int CTRL_NRPN_OFFSET = 0x30000;
+const int CTRL_RPN14_OFFSET = 0x50000;
+const int CTRL_NRPN14_OFFSET = 0x60000;
+const int CTRL_NONE_OFFSET = 0x70000;
+
+namespace AL {
+ class Xml;
+ };
+using AL::Xml;
+
+//---------------------------------------------------------
+// MidiController
+//---------------------------------------------------------
+
+class MidiController {
+ public:
+ //
+ // mapping of midi controller types to
+ // controller number:
+ //
+ enum ControllerType {
+ Controller7, // num values from 0 - 0x7f
+ Controller14, // values from 0x10000 - 0x12fff
+ RPN, // registered parameter 0x20000 -
+ NRPN, // non registered parameter 0x30000 -
+ RPN14, // registered parameter 0x50000
+ NRPN14, // non registered parameter 0x60000 -
+ Pitch, // num value = CTRL_PITCH
+ Program, // num value = CTRL_PROGRAM
+ Velo // not assigned
+ };
+ private:
+ QString _name;
+ QString _comment;
+ int _num; // Controller Number
+ int _minVal; // controller value range (used in gui)
+ int _maxVal;
+ int _initVal;
+ bool _moveWithPart;
+
+ public:
+ MidiController();
+ MidiController(const QString& n, int num, int min, int max, int init,
+ bool mwp = true);
+ const QString& name() const { return _name; }
+ void setName(const QString& s) { _name = s; }
+ const QString& comment() const { return _comment; }
+ void setComment(const QString& s) { _comment = s; }
+ int num() const { return _num; }
+ void setNum(int v) { _num = v; }
+ void write(Xml& xml) const;
+ void read(QDomNode);
+ int minVal() const { return _minVal; }
+ int maxVal() const { return _maxVal; }
+ int initVal() const { return _initVal; }
+ void setInitVal(int val) { _initVal = val; }
+ void setMinVal(int val) { _minVal = val; }
+ void setMaxVal(int val) { _maxVal = val; }
+ bool moveWithPart() const { return _moveWithPart; }
+ void setMoveWithPart(bool v) { _moveWithPart = v; }
+ ControllerType type() const;
+ static int genNum(ControllerType, int, int);
+ };
+
+//---------------------------------------------------------
+// MidiControllerList
+// this is a list of used midi controllers created
+// - excplicit by user
+// - implicit during import of a midi file
+//---------------------------------------------------------
+
+class MidiControllerList : public QList<MidiController*> {};
+
+typedef MidiControllerList::iterator iMidiController;
+typedef MidiControllerList::const_iterator ciMidiController;
+
+extern MidiControllerList defaultMidiController;
+extern void initMidiController();
+
+extern MidiController::ControllerType midiControllerType(int num);
+extern void configMidiController();
+extern const QString& int2ctrlType(int n);
+extern MidiController::ControllerType ctrlType2Int(const QString& s);
+extern QString midiCtrlName(int ctrl);
+extern MidiController veloCtrl;
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/midiedit/CMakeLists.txt b/muse_qt4_evolution/muse/midiedit/CMakeLists.txt
new file mode 100644
index 00000000..a71aed71
--- /dev/null
+++ b/muse_qt4_evolution/muse/midiedit/CMakeLists.txt
@@ -0,0 +1,71 @@
+#=============================================================================
+# MusE
+# Linux Music Editor
+# $Id:$
+#
+# Copyright (C) 2002-2006 by Werner Schweer and others
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#=============================================================================
+
+QT4_WRAP_CPP ( midiedit_mocs
+ midicmd.h
+ gatetime.h
+ velocity.h
+ quantconfig.h
+ dcanvas.h
+ drumedit.h
+ ecanvas.h
+ midieditor.h
+ pianoroll.h
+ prcanvas.h
+ miditracker.h
+ trackpattern.h
+ )
+
+QT4_WRAP_UI ( midiedit_ui_headers
+ midicmd.ui
+ gatetime.ui
+ velocity.ui
+ quantconfig.ui
+ )
+
+add_library ( midiedit STATIC
+ midicmd.h
+ gatetime.h
+ ${midiedit_ui_headers}
+ ${midiedit_mocs}
+ midicmd.cpp
+ gatetime.cpp
+ velocity.cpp
+ quantconfig.cpp
+ citem.h
+ cmd.h
+ drummap.h
+ midicmd.h
+ citem.cpp
+ dcanvas.cpp
+ drumedit.cpp
+ drummap.cpp
+ ecanvas.cpp
+ midieditor.cpp
+ pianoroll.cpp
+ prcanvas.cpp
+ miditracker.cpp
+ trackpattern.cpp
+ )
+
+set_target_properties( midiedit
+ PROPERTIES COMPILE_FLAGS "-include ${PROJECT_BINARY_DIR}/all.h"
+ )
+
diff --git a/muse_qt4_evolution/muse/midiedit/citem.cpp b/muse_qt4_evolution/muse/midiedit/citem.cpp
new file mode 100644
index 00000000..b7ae8287
--- /dev/null
+++ b/muse_qt4_evolution/muse/midiedit/citem.cpp
@@ -0,0 +1,82 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "part.h"
+#include "citem.h"
+
+//---------------------------------------------------------
+// CItem
+//---------------------------------------------------------
+
+CItem::CItem()
+ {
+ isMoving = false;
+ }
+
+CItem::CItem(const Event& e, Part* p)
+ {
+ event = e;
+ part = p;
+ isMoving = false;
+ pos = e.pos() + *p;
+ }
+
+//---------------------------------------------------------
+// isSelected
+//---------------------------------------------------------
+
+bool CItem::isSelected() const
+ {
+ return event.empty() ? part->selected() : event.selected();
+ }
+
+//---------------------------------------------------------
+// setSelected
+//---------------------------------------------------------
+
+void CItem::setSelected(bool f)
+ {
+ event.empty() ? part->setSelected(f) : event.setSelected(f);
+ }
+
+//---------------------------------------------------------
+// CItemList
+//---------------------------------------------------------
+
+CItem* CItemList::find(const QPoint& pos) const
+ {
+ for (rciCItem i = rbegin(); i != rend(); ++i) {
+ if (i->second->contains(pos))
+ return i->second;
+ }
+ return 0;
+ }
+
+//---------------------------------------------------------
+// CItemList
+//---------------------------------------------------------
+
+void CItemList::add(CItem* item)
+ {
+ std::multimap<int, CItem*, std::less<int> >::insert(
+ std::pair<const unsigned int, CItem*> (item->pos.tick(), item)
+ );
+ }
+
diff --git a/muse_qt4_evolution/muse/midiedit/citem.h b/muse_qt4_evolution/muse/midiedit/citem.h
new file mode 100644
index 00000000..5b3452ac
--- /dev/null
+++ b/muse_qt4_evolution/muse/midiedit/citem.h
@@ -0,0 +1,70 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __CITEM_H__
+#define __CITEM_H__
+
+#include "al/pos.h"
+#include "event.h"
+
+class Part;
+
+//---------------------------------------------------------
+// CItem
+// Canvas Item
+//---------------------------------------------------------
+
+struct CItem {
+ Event event;
+ Part* part;
+
+ bool isMoving;
+ AL::Pos moving;
+ int my;
+
+ QRect bbox;
+ AL::Pos pos;
+
+ CItem();
+ CItem(const Event& e, Part* p);
+
+ bool isSelected() const;
+ void setSelected(bool f);
+ bool contains(const QPoint& p) const { return bbox.contains(p); }
+ bool intersects(const QRect& r) const { return r.intersects(bbox); }
+ };
+
+typedef std::multimap<int, CItem*, std::less<int> >::iterator iCItem;
+typedef std::multimap<int, CItem*, std::less<int> >::const_iterator ciCItem;
+typedef std::multimap<int, CItem*, std::less<int> >::const_reverse_iterator rciCItem;
+
+//---------------------------------------------------------
+// CItemList
+// Canvas Item List
+//---------------------------------------------------------
+
+class CItemList: public std::multimap<int, CItem*, std::less<int> > {
+ public:
+ void add(CItem*);
+ CItem* find(const QPoint& pos) const;
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/midiedit/cmd.h b/muse_qt4_evolution/muse/midiedit/cmd.h
new file mode 100644
index 00000000..7f51abdd
--- /dev/null
+++ b/muse_qt4_evolution/muse/midiedit/cmd.h
@@ -0,0 +1,32 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __CMD_H__
+#define __CMD_H__
+
+enum {
+ MCMD_LEFT,
+ MCMD_RIGHT,
+ MCMD_INSERT,
+ MCMD_DELETE,
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/midiedit/dcanvas.cpp b/muse_qt4_evolution/muse/midiedit/dcanvas.cpp
new file mode 100644
index 00000000..20d8170d
--- /dev/null
+++ b/muse_qt4_evolution/muse/midiedit/dcanvas.cpp
@@ -0,0 +1,723 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "dcanvas.h"
+#include "song.h"
+#include "midieditor.h"
+#include "drummap.h"
+#include "audio.h"
+#include "velocity.h"
+#include "gconfig.h"
+#include "part.h"
+
+#define CARET 12
+#define CARET2 6
+
+//---------------------------------------------------------
+// drumMap
+//---------------------------------------------------------
+
+DrumMap* DrumCanvas::drumMap() const
+ {
+ DrumMap* drumMap = track()->drumMap();
+ if (drumMap == 0)
+ drumMap = &noDrumMap;
+ return drumMap;
+ }
+
+//---------------------------------------------------------
+// y2pitch
+//---------------------------------------------------------
+
+int DrumCanvas::y2pitch(int y) const
+ {
+ return drumMap()->anote(EventCanvas::y2pitch(y));
+ }
+
+//---------------------------------------------------------
+// pitch2y
+//---------------------------------------------------------
+
+int DrumCanvas::pitch2y(int pitch) const
+ {
+ return EventCanvas::pitch2y(drumMap()->outmap(pitch));
+ }
+
+//---------------------------------------------------------
+// DrumCanvas
+//---------------------------------------------------------
+
+DrumCanvas::DrumCanvas(MidiEditor* pr)
+ : EventCanvas(pr, TIME_CANVAS_DRUMEDIT)
+ {
+ singlePitch = -1;
+ verticalScrollBar()->setSingleStep(drumHeight/2);
+ canvasTools = PointerTool | PencilTool | RubberTool;
+ songChanged(SC_TRACK_INSERTED);
+ connect(track(), SIGNAL(drumMapChanged()), widget(), SLOT(update()));
+ }
+
+//---------------------------------------------------------
+// addItem
+//---------------------------------------------------------
+
+void DrumCanvas::addItem(Part* part, const Event& event)
+ {
+ CItem* item = new CItem(event, part);
+ unsigned tick = event.tick() + part->tick();
+ item->pos = Pos(tick);
+ items.add(item);
+ }
+
+//---------------------------------------------------------
+// paint
+//---------------------------------------------------------
+
+void DrumCanvas::paint(QPainter& p, QRect r)
+ {
+ p.setPen(QPen(Qt::black, 0.0));
+
+ QPainterPath pa;
+ pa.moveTo(-CARET2, 0);
+ pa.lineTo(0, - CARET2);
+ pa.lineTo(CARET2, 0);
+ pa.lineTo(0, CARET2);
+ pa.closeSubpath();
+
+ Pos p1(pix2pos(r.x() - CARET2));
+ Pos p2(pix2pos(r.x() + r.width() + CARET2));
+ iCItem from(items.lower_bound(p1.tick()));
+ iCItem to(items.upper_bound(p2.tick()));
+
+ for (iCItem i = from; i != to; ++i) {
+ CItem* e = i->second;
+ int x = pos2pix(AL::Pos(i->first));
+ int y = pitch2y(e->event.pitch()) + drumHeight/2;
+ QPoint pt(x, y);
+ Event me(e->event);
+
+ DrumMapEntry* dm = drumMap()->entry(me.pitch()); //Get the drum item
+ QColor color;
+ int velo = me.velo();
+ if (velo < dm->lv1)
+ color.setRgb(240, 240, 255);
+ else if (velo < dm->lv2)
+ color.setRgb(200, 200, 255);
+ else if (velo < dm->lv3)
+ color.setRgb(170, 170, 255);
+ else
+ color.setRgb(0, 0, 255);
+
+ if (e->part != curPart)
+ p.setBrush(Qt::lightGray);
+ else if (e->isMoving) {
+ p.setBrush(Qt::gray);
+ p.translate(pt);
+ p.drawPath(pa);
+ p.translate(-pt);
+ p.setBrush(Qt::black);
+
+ int x = pos2pix(e->moving);
+ int y = e->my + drumHeight/2;
+ pt = QPoint(x, y);
+ }
+ else if (e->isSelected())
+ p.setBrush(Qt::black);
+ else
+ p.setBrush(color);
+ p.translate(pt);
+ p.drawPath(pa);
+ p.translate(-pt);
+ }
+
+ //---------------------------------------------------
+ // draw lasso
+ //---------------------------------------------------
+
+ if (drag == DRAG_LASSO) {
+ p.setPen(Qt::blue);
+ p.setBrush(Qt::NoBrush);
+ p.drawRect(lasso);
+ }
+ }
+
+//---------------------------------------------------------
+// moveItem
+//---------------------------------------------------------
+
+void DrumCanvas::moveItem(CItem* nevent, DragType dtype)
+ {
+ Part* part = nevent->part;
+ Event event = nevent->event;
+ int npitch = y2pitch(nevent->my);
+
+ Event newEvent = event.clone();
+ newEvent.setPitch(npitch);
+ newEvent.setPos(nevent->moving - *(nevent->part));
+ if (dtype == MOVE_COPY)
+ audio->msgAddEvent(newEvent, part, false);
+ else
+ audio->msgChangeEvent(event, newEvent, part, false);
+ }
+
+//---------------------------------------------------------
+// newItem
+//---------------------------------------------------------
+
+CItem* DrumCanvas::newItem(const QPoint& p, int state)
+ {
+ AL::Pos pos(pix2pos(p.x()));
+ pos.snap(raster());
+ if (pos < partPos1 || pos >= partPos2) {
+ return 0;
+ }
+
+ int pitch = y2pitch(p.y());
+ int instr = drumMap()->outmap(pitch);
+ DrumMapEntry* dm = drumMap()->entry(instr);
+ int velo = dm->lv4;
+ if (state == Qt::ShiftModifier)
+ velo = dm->lv3;
+ else if (state == Qt::ControlModifier)
+ velo = dm->lv2;
+ else if (state == (Qt::ControlModifier | Qt::ShiftModifier))
+ velo = dm->lv1;
+
+ Event e(Note);
+ e.setPos(pos - *curPart);
+ e.setPitch(drumMap()->anote(instr));
+ e.setVelo(velo);
+ e.setLenTick(dm->len);
+ return new CItem(e, curPart);
+ }
+
+//---------------------------------------------------------
+// resizeItem
+//---------------------------------------------------------
+
+void DrumCanvas::resizeItem(CItem* nevent, bool)
+ {
+ Event ev = nevent->event;
+ audio->msgDeleteEvent(ev, nevent->part);
+ }
+
+//---------------------------------------------------------
+// newItem
+//---------------------------------------------------------
+
+void DrumCanvas::newItem(CItem* nevent, bool noSnap)
+ {
+ Event event = nevent->event;
+ Pos pos(nevent->pos);
+ if (!noSnap)
+ pos.snap(editor->raster());
+ event.setPos(pos - *(nevent->part));
+ int npitch = event.pitch();
+ event.setPitch(npitch);
+
+ //
+ // check for existing event
+ // if found change command semantic from insert to delete
+ //
+ EventList* el = nevent->part->events();
+ iEvent lower = el->lower_bound(event.tick());
+ iEvent upper = el->upper_bound(event.tick());
+
+ for (iEvent i = lower; i != upper; ++i) {
+ Event ev = i->second;
+ if (ev.pitch() == npitch) {
+ audio->msgDeleteEvent(ev, nevent->part);
+ return;
+ }
+ }
+
+ audio->msgAddEvent(event, nevent->part);
+ }
+
+//---------------------------------------------------------
+// deleteItem
+//---------------------------------------------------------
+
+bool DrumCanvas::deleteItem(CItem* item)
+ {
+ Event ev = item->event;
+ audio->msgDeleteEvent(ev, item->part);
+ return false;
+ }
+
+//---------------------------------------------------------
+// cmd
+//---------------------------------------------------------
+
+void DrumCanvas::cmd(QAction* a)
+ {
+ QString cmd(a->data().toString());
+
+ if (cmd == "paste")
+ paste();
+ else if (cmd == "sel_all") {
+ for (iCItem k = items.begin(); k != items.end(); ++k) {
+ if (!k->second->isSelected())
+ selectItem(k->second, true);
+ }
+ }
+ else if (cmd == "sel_none")
+ deselectAll();
+ else if (cmd == "sel_inv") {
+ for (iCItem k = items.begin(); k != items.end(); ++k)
+ selectItem(k->second, !k->second->isSelected());
+ }
+ else if (cmd == "sel_ins_loc") {
+ for (iCItem k = items.begin(); k != items.end(); ++k) {
+ CItem* nevent = k->second;
+ Part* part = nevent->part;
+ Event event = nevent->event;
+ unsigned tick = event.tick() + part->tick();
+ if (tick < song->lpos() || tick >= song->rpos())
+ selectItem(k->second, false);
+ else
+ selectItem(k->second, true);
+ }
+ }
+ else if (cmd == "sel_out_loc") {
+ for (iCItem k = items.begin(); k != items.end(); ++k) {
+ CItem* nevent = k->second;
+ Part* part = nevent->part;
+ Event event = nevent->event;
+ unsigned tick = event.tick() + part->tick();
+ if (tick < song->lpos() || tick >= song->rpos())
+ selectItem(k->second, true);
+ else
+ selectItem(k->second, false);
+ }
+ }
+ else if (cmd == "delete") {
+ if (selectionSize()) {
+ song->startUndo();
+ for (iCItem i = items.begin(); i != items.end(); ++i) {
+ if (!i->second->isSelected())
+ continue;
+ Event ev = i->second->event;
+ audio->msgDeleteEvent(ev, i->second->part, false);
+ }
+ song->endUndo(SC_EVENT_REMOVED);
+ }
+ return;
+ }
+ else if (cmd == "midi_fixed_len") {
+ if (selectionSize()) {
+ song->startUndo();
+ for (iCItem k = items.begin(); k != items.end(); ++k) {
+ if (k->second->isSelected()) {
+ CItem* devent = k->second;
+ Event event = devent->event;
+ Event newEvent = event.clone();
+ newEvent.setLenTick(drumMap()->entry(event.pitch())->len);
+ audio->msgChangeEvent(event, newEvent, devent->part, false);
+ }
+ }
+ song->endUndo(SC_EVENT_MODIFIED);
+ }
+ }
+ else if (cmd == "goto_left") {
+ int frames = pos[0].tick() - editor->rasterStep(pos[0].tick());
+ if (frames < 0)
+ frames = 0;
+ Pos p(frames, AL::TICKS);
+ song->setPos(0, p, true, true, true);
+ }
+ else if (cmd == "goto_right") {
+ Pos p(pos[0].tick() + editor->rasterStep(pos[0].tick()), AL::TICKS);
+ song->setPos(0, p, true, true, true);
+ }
+ else if (cmd == "mid_mod_velo") {
+ Velocity w(this);
+ w.setRange(editor->applyTo());
+ if (w.exec()) {
+ editor->setApplyTo(w.range());
+ int rate = w.rateVal();
+ int offset = w.offsetVal();
+
+ song->startUndo();
+ for (iCItem k = items.begin(); k != items.end(); ++k) {
+ CItem* devent = k->second;
+ Event event = devent->event;
+ if (event.type() != Note)
+ continue;
+ unsigned tick = event.tick();
+ bool selected = devent->isSelected();
+ bool inLoop = (tick >= song->lpos()) && (tick < song->rpos());
+
+ int range = editor->applyTo();
+ if ((range == RANGE_ALL)
+ || (range == RANGE_SELECTED && selected)
+ || (range == RANGE_LOOPED && inLoop)
+ || (range == (RANGE_LOOPED | RANGE_SELECTED) && selected && inLoop)) {
+ int velo = event.velo();
+
+ //velo = rate ? (velo * 100) / rate : 64;
+ velo = (velo * rate) / 100;
+ velo += offset;
+
+ if (velo <= 0)
+ velo = 1;
+ if (velo > 127)
+ velo = 127;
+ if (event.velo() != velo) {
+ Event newEvent = event.clone();
+ newEvent.setVelo(velo);
+ audio->msgChangeEvent(event, newEvent, devent->part, false);
+ }
+ }
+ }
+ song->endUndo(SC_EVENT_MODIFIED);
+ }
+ }
+ widget()->update();
+ }
+
+//---------------------------------------------------------
+// paste
+// paste events
+//---------------------------------------------------------
+
+void DrumCanvas::paste()
+ {
+ QString stype("x-muse-eventlist");
+ QString s = QApplication::clipboard()->text(stype, QClipboard::Selection);
+ pasteAt(s, song->cpos());
+ }
+
+//---------------------------------------------------------
+// startDrag
+//---------------------------------------------------------
+
+void DrumCanvas::startDrag(CItem* /* item*/, bool /*copymode*/)
+ {
+printf("DrumCanvas: startDrag\n");
+#if 0 //TD
+ QMimeData* drag = getTextDrag();
+ if (drag) {
+ QApplication::clipboard()->setMimeData(drag, QClipboard::Selection);
+ if (copymode)
+ drag->dragCopy();
+ else
+ drag->dragMove();
+ }
+#endif
+ }
+
+//---------------------------------------------------------
+// dragEnterEvent
+//---------------------------------------------------------
+
+void DrumCanvas::dragEnterEvent(QDragEnterEvent* /*event*/)
+ {
+printf("DrumCanvas: dragEnterEvent\n");
+//TD event->accept(Q3TextDrag::canDecode(event));
+ }
+
+//---------------------------------------------------------
+// dragMoveEvent
+//---------------------------------------------------------
+
+void DrumCanvas::dragMoveEvent(QDragMoveEvent*)
+ {
+ printf("drag move %p\n", this);
+ }
+
+//---------------------------------------------------------
+// dragLeaveEvent
+//---------------------------------------------------------
+
+void DrumCanvas::dragLeaveEvent(QDragLeaveEvent*)
+ {
+ printf("drag leave\n");
+ }
+
+//---------------------------------------------------------
+// dropEvent
+//---------------------------------------------------------
+
+void DrumCanvas::viewDropEvent(QDropEvent* /*event*/)
+ {
+printf("DrumCanvas: viewDropEvent\n");
+#if 0 //TD
+ QString text;
+ if (event->source() == this) {
+ printf("local DROP\n");
+ return;
+ }
+ if (Q3TextDrag::decode(event, text)) {
+// printf("drop <%s>\n", text.ascii());
+ int x = editor->rasterVal(event->pos().x());
+ if (x < 0)
+ x = 0;
+ pasteAt(text, x);
+ }
+#endif
+ }
+
+//---------------------------------------------------------
+// keyPressed
+//---------------------------------------------------------
+
+void DrumCanvas::keyPressed(int index, bool)
+ {
+ int pitch = drumMap()->entry(index)->anote;
+
+ // play note:
+ MidiEvent e(0, 0, 0x90, pitch, 127);
+ track()->playMidiEvent(&e);
+ }
+
+//---------------------------------------------------------
+// keyReleased
+//---------------------------------------------------------
+
+void DrumCanvas::keyReleased(int index, bool)
+ {
+ int pitch = drumMap()->entry(index)->anote;
+
+ // release note:
+ MidiEvent e(0, 0, 0x90, pitch, 0);
+ track()->playMidiEvent(&e);
+ }
+
+//---------------------------------------------------------
+// resizeEvent
+//---------------------------------------------------------
+
+void DrumCanvas::resizeEvent(QResizeEvent* ev)
+ {
+ if (ev->size().width() != ev->oldSize().width())
+ emit newWidth(ev->size().width());
+ EventCanvas::resizeEvent(ev);
+ }
+
+
+//---------------------------------------------------------
+// modifySelected
+//---------------------------------------------------------
+
+void DrumCanvas::modifySelected(NoteInfo::ValType type, int delta)
+ {
+ audio->msgIdle(true);
+ song->startUndo();
+ for (iCItem i = items.begin(); i != items.end(); ++i) {
+ if (!(i->second->isSelected()))
+ continue;
+ CItem* e = i->second;
+ Event event = e->event;
+ if (event.type() != Note)
+ continue;
+
+ Part* part = e->part;
+ Event newEvent = event.clone();
+
+ switch (type) {
+ case NoteInfo::VAL_TIME:
+ {
+ int newTime = event.tick() + delta;
+ if (newTime < 0)
+ newTime = 0;
+ newEvent.setTick(newTime);
+ }
+ break;
+ case NoteInfo::VAL_LEN:
+ /*
+ {
+ int len = event.lenTick() + delta;
+ if (len < 1)
+ len = 1;
+ newEvent.setLenTick(len);
+ }
+ */
+ printf("DrumCanvas::modifySelected - NoteInfo::VAL_LEN not implemented\n");
+ break;
+ case NoteInfo::VAL_VELON:
+ /*
+ {
+ int velo = event->velo() + delta;
+ if (velo > 127)
+ velo = 127;
+ else if (velo < 0)
+ velo = 0;
+ newEvent.setVelo(velo);
+ }
+ */
+ printf("DrumCanvas::modifySelected - NoteInfo::VAL_VELON not implemented\n");
+ break;
+ case NoteInfo::VAL_VELOFF:
+ /*
+ {
+ int velo = event.veloOff() + delta;
+ if (velo > 127)
+ velo = 127;
+ else if (velo < 0)
+ velo = 0;
+ newEvent.setVeloOff(velo);
+ }
+ */
+ printf("DrumCanvas::modifySelected - NoteInfo::VAL_VELOFF not implemented\n");
+ break;
+ case NoteInfo::VAL_PITCH:
+ {
+ int pitch = event.pitch() - delta; // Reversing order since the drumlist is displayed in increasing order
+ if (pitch > 127)
+ pitch = 127;
+ else if (pitch < 0)
+ pitch = 0;
+ newEvent.setPitch(pitch);
+ }
+ break;
+ }
+ song->changeEvent(event, newEvent, part);
+ song->undoOp(UndoOp::ModifyEvent, newEvent, event, part);
+ }
+ song->endUndo(SC_EVENT_MODIFIED);
+ audio->msgIdle(false);
+ }
+
+//---------------------------------------------------------
+// paintDrumList
+//---------------------------------------------------------
+
+void DrumCanvas::paintDrumList(QPainter& p, QRect r)
+ {
+ p.fillRect(r, QColor(0xe0, 0xe0, 0xe0));
+ paintVLine(p, 0, rPanelB.y(), rPanelA.x() + rPanelA.width());
+// p.setFont(config.fonts[1]);
+
+ int yoff = wpos.y() - rPanelA.y();
+ int i = (r.y() + yoff) / drumHeight;
+ if (i < 0)
+ i = 0;
+ if (i > 127)
+ return;
+ int y = i * drumHeight - yoff;
+ DrumMap* dm = drumMap();
+
+ for (; i < 128; ++i, y += drumHeight) {
+ if (y > r.y() + r.height())
+ break;
+ QRect r(3, y, drumWidth-4, drumHeight);
+ if (dm->anote(i) == curPitch || dm->anote(i) == singlePitch)
+ p.fillRect(0, y, drumWidth-4, drumHeight, Qt::white);
+ DrumMapEntry* de = dm->entry(i);
+ if (de->mute) {
+ p.setPen(Qt::red);
+ p.drawText(r, Qt::AlignVCenter | Qt::AlignLeft, "m");
+ p.setPen(Qt::darkGray);
+ p.drawText(r.adjusted(16, 0, 0, 0), Qt::AlignVCenter | Qt::AlignLeft, de->name);
+ }
+ else {
+ p.setPen(Qt::black);
+ p.drawText(r, Qt::AlignVCenter | Qt::AlignLeft, "m");
+ p.drawText(r.adjusted(16, 0, 0, 0), Qt::AlignVCenter | Qt::AlignLeft, de->name);
+ }
+ if (i != 0)
+ p.drawLine(0, y, drumWidth-3, y);
+ }
+ p.setPen(QPen(Qt::darkGray, 1));
+ p.drawLine(17, r.y(), 17, r.y() + r.height());
+ }
+
+//---------------------------------------------------------
+// searchItem
+//---------------------------------------------------------
+
+CItem* DrumCanvas::searchItem(const QPoint& p) const
+ {
+ Pos p1(pix2pos(p.x() - CARET2));
+ Pos p2(pix2pos(p.x() + CARET2));
+
+ ciCItem from(items.lower_bound(p1.tick()));
+ ciCItem to(items.upper_bound(p2.tick()));
+
+ int pitch = y2pitch(p.y());
+ for (ciCItem i = from; i != to; ++i) {
+ if (pitch == i->second->event.pitch())
+ return i->second;
+ }
+ return 0;
+ }
+
+//---------------------------------------------------------
+// selectLasso
+//---------------------------------------------------------
+
+void DrumCanvas::selectLasso(bool toggle)
+ {
+ Pos p1(pix2pos(lasso.x()));
+ Pos p2(pix2pos(lasso.x() + lasso.width()));
+
+ iCItem from(items.lower_bound(p1.tick()));
+ iCItem to(items.upper_bound(p2.tick()));
+ int y = lasso.y();
+ int pitch1 = y2pitch(y);
+ int pitch2 = y2pitch(y + lasso.height());
+
+ int n = 0;
+ for (iCItem i = from; i != to; ++i) {
+ CItem* item = i->second;
+ int pitch = item->event.pitch();
+ if (pitch >= pitch1 && pitch <= pitch2) {
+ selectItem(item, !(toggle && item->isSelected()));
+ ++n;
+ }
+ }
+ if (n) {
+ updateSelection();
+ widget()->update();
+ }
+ }
+
+//---------------------------------------------------------
+// mousePress
+//---------------------------------------------------------
+
+void DrumCanvas::mousePress(QMouseEvent* ev)
+ {
+ QPoint r(ev->pos());
+ int pitch = y2pitch(r.y() - rPanelA.y() - wpos.y());
+ if (r.x() < 20) {
+ //
+ // "mute" button click
+ //
+ DrumMap* dm = drumMap();
+ int idx = dm->outmap(pitch);
+ DrumMapEntry* de = dm->entry(idx);
+ de->mute = !de->mute;
+ widget()->update(rPanelA);
+ return;
+ }
+ else if (r.x() < rCanvasA.x()) {
+ if (pitch != singlePitch) {
+ singlePitch = pitch;
+ for (iCtrlEdit i = ctrlEditList.begin(); i != ctrlEditList.end(); ++i)
+ (*i)->setSinglePitch(singlePitch);
+ widget()->update();
+ }
+ }
+ EventCanvas::mousePress(ev);
+ }
+
+
diff --git a/muse_qt4_evolution/muse/midiedit/dcanvas.h b/muse_qt4_evolution/muse/midiedit/dcanvas.h
new file mode 100644
index 00000000..9d4ab754
--- /dev/null
+++ b/muse_qt4_evolution/muse/midiedit/dcanvas.h
@@ -0,0 +1,77 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __DCANVAS_H__
+#define __DCANVAS_H__
+
+#include "ecanvas.h"
+
+class MidiEditor;
+class DrumMap;
+
+//---------------------------------------------------------
+// DrumCanvas
+//---------------------------------------------------------
+
+class DrumCanvas : public EventCanvas {
+ Q_OBJECT
+
+ int singlePitch;
+ virtual void mousePress(QMouseEvent*);
+ virtual void paint(QPainter&, QRect);
+ virtual void addItem(Part* part, const Event& event);
+ virtual void moveItem(CItem*, DragType);
+ virtual CItem* newItem(const QPoint&, int);
+ virtual void resizeItem(CItem*, bool);
+ virtual void newItem(CItem*, bool);
+ virtual bool deleteItem(CItem*);
+ virtual CItem* searchItem(const QPoint& p) const;
+
+ void copy();
+ void paste();
+ void startDrag(CItem*, bool copymode);
+ void dragEnterEvent(QDragEnterEvent* event);
+ void dragMoveEvent(QDragMoveEvent*);
+ void dragLeaveEvent(QDragLeaveEvent*);
+ void viewDropEvent(QDropEvent* event);
+ virtual void resizeEvent(QResizeEvent*);
+ virtual void paintDrumList(QPainter&, QRect);
+ virtual void selectLasso(bool toggle);
+
+ DrumMap* drumMap() const;
+
+ protected:
+ virtual int y2pitch(int y) const;
+ virtual int pitch2y(int pitch) const;
+
+ signals:
+ void newWidth(int);
+
+ public slots:
+ void keyPressed(int, bool);
+ void keyReleased(int, bool);
+
+ public:
+ DrumCanvas(MidiEditor*);
+ void cmd(QAction*);
+ virtual void modifySelected(NoteInfo::ValType type, int delta);
+ };
+#endif
+
diff --git a/muse_qt4_evolution/muse/midiedit/drumedit.cpp b/muse_qt4_evolution/muse/midiedit/drumedit.cpp
new file mode 100644
index 00000000..a21a56a0
--- /dev/null
+++ b/muse_qt4_evolution/muse/midiedit/drumedit.cpp
@@ -0,0 +1,450 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "drumedit.h"
+#include "icons.h"
+#include "drummap.h"
+#include "audio.h"
+#include "shortcuts.h"
+#include "part.h"
+#include "muse.h"
+#include "song.h"
+
+static const int drumeditTools = PointerTool | PencilTool | RubberTool | DrawTool;
+
+int DrumEdit::initWidth = DrumEdit::INIT_WIDTH;
+int DrumEdit::initHeight = DrumEdit::INIT_HEIGHT;
+int DrumEdit::initRaster = DrumEdit::INIT_RASTER;
+int DrumEdit::initQuant = DrumEdit::INIT_QUANT;
+bool DrumEdit::initFollow = DrumEdit::INIT_FOLLOW;
+bool DrumEdit::initSpeaker = DrumEdit::INIT_SPEAKER;
+bool DrumEdit::initMidiin = DrumEdit::INIT_MIDIIN;
+double DrumEdit::initXmag = 0.08; // DrumEdit::INIT_XMAG;
+int DrumEdit::initApplyTo = DrumEdit::INIT_APPLY_TO;
+
+//---------------------------------------------------------
+// DrumEdit
+//---------------------------------------------------------
+
+DrumEdit::DrumEdit(PartList* pl, bool init)
+ : MidiEditor(pl)
+ {
+ _applyTo = initApplyTo;
+
+ deltaMode = false;
+ drumMap = &noDrumMap;
+
+ //---------Pulldown Menu----------------------------
+ QMenuBar* mb = menuBar();
+
+ menuEdit->addSeparator();
+ menuEdit->addAction(getAction("delete", this));
+
+ // Functions
+ menuFunctions = mb->addMenu(tr("&Functions"));
+ menuFunctions->addAction(getAction("midi_fixed_len", this));
+ menuFunctions->addAction(getAction("midi_mod_velo", this));
+
+ menuSelect = menuEdit->addMenu(tr("&Select"));
+ menuSelect->setIcon(QIcon(*selectIcon));
+
+ menuSelect->addAction(getAction("sel_all", this));
+ menuSelect->addAction(getAction("sel_none", this));
+ menuSelect->addAction(getAction("sel_inv", this));
+ menuSelect->addSeparator();
+ menuSelect->addAction(getAction("sel_ins_loc", this));
+ menuSelect->addAction(getAction("sel_out_loc", this));
+
+ connect(menuSelect, SIGNAL(triggered(QAction*)), SLOT(cmd(QAction*)));
+ connect(menuFunctions, SIGNAL(triggered(QAction*)), SLOT(cmd(QAction*)));
+
+ //---------------------------------------------------
+ // Toolbars
+ //---------------------------------------------------
+
+ tools = addToolBar(tr("Drum Tools"));
+ tools->addAction(undoAction);
+ tools->addAction(redoAction);
+ tools->addSeparator();
+
+ tools->addAction(stepRecAction);
+ stepRecAction->setChecked(INIT_SREC);
+
+ tools->addAction(midiInAction);
+ midiInAction->setChecked(INIT_MIDIIN);
+
+ tools->addAction(speaker);
+ speaker->setChecked(INIT_SPEAKER);
+
+ tools->addAction(followSongAction);
+ followSongAction->setChecked(INIT_FOLLOW);
+
+ tools2 = new EditToolBar(this, drumeditTools);
+ addToolBar(tools2);
+
+ QToolBar* transport = addToolBar(tr("Transport"));
+ muse->setupTransportToolbar(transport);
+
+ addToolBarBreak();
+ toolbar = new Toolbar1(initRaster, initQuant, false);
+ addToolBar(toolbar);
+ addToolBarBreak();
+ info = new NoteInfo(this);
+ addToolBar(info);
+
+ tcanvas = new DrumCanvas(this);
+ setCentralWidget(tcanvas);
+ tcanvas->setCornerWidget(new QSizeGrip(tcanvas));
+ tcanvas->setFollow(INIT_FOLLOW);
+
+ connect(song, SIGNAL(posChanged(int,const AL::Pos&,bool)), canvas(), SLOT(setLocatorPos(int,const AL::Pos&,bool)));
+ connect(canvas(), SIGNAL(posChanged(int,const AL::Pos&)), SLOT(setPos(int,const AL::Pos&)));
+
+ connect(canvas(), SIGNAL(toolChanged(int)), tools2, SLOT(set(int)));
+ connect(tools2, SIGNAL(toolChanged(int)), canvas(), SLOT(setTool(int)));
+
+ connect(canvas(), SIGNAL(selectionChanged(int, Event&, Part*)),
+ SLOT(setSelection(int, Event&, Part*)));
+
+ setWindowTitle(canvas()->getCaption());
+
+ Pos p1(0, AL::TICKS), p2(0, AL::TICKS);
+ canvas()->range(p1, p2);
+ p2 += AL::sigmap.ticksMeasure(p2.tick()); // show one more measure
+ canvas()->setTimeRange(p1, p2);
+
+ // connect toolbar
+ connect(canvas(), SIGNAL(cursorPos(const AL::Pos&,bool)), toolbar, SLOT(setTime(const AL::Pos&,bool)));
+ connect(toolbar, SIGNAL(quantChanged(int)), SLOT(setQuant(int)));
+ connect(toolbar, SIGNAL(rasterChanged(int)), SLOT(setRaster(int)));
+ connect(toolbar, SIGNAL(soloChanged(bool)), SLOT(soloChanged(bool)));
+ connect(toolbar, SIGNAL(toChanged(int)), SLOT(setApplyTo(int)));
+
+ connect(info, SIGNAL(valueChanged(NoteInfo::ValType, int)), SLOT(noteinfoChanged(NoteInfo::ValType, int)));
+
+ clipboardChanged(); // enable/disable "Paste"
+ selectionChanged(); // enable/disable "Copy" & "Paste"
+
+ canvas()->selectFirst();
+
+ //
+ // install misc shortcuts
+ //
+ QShortcut* sc;
+ sc = new QShortcut(Qt::Key_Escape, this);
+ sc->setContext(Qt::WindowShortcut);
+ connect(sc, SIGNAL(activated()), SLOT(close()));
+
+ QSignalMapper* cmdMap = new QSignalMapper(this);
+ static const char* actions[] = {
+ "curpos_increase", "curpos_decrease",
+ "pointer", "pencil", "eraser",
+ "midi_quant_1", "midi_quant_2", "midi_quant_3", "midi_quant_4",
+ "midi_quant_5", "midi_quant_6", "midi_quant_7",
+ "midi_quant_triol", "midi_quant_punct", "midi_quant_punct2"
+ };
+ for (unsigned i = 0; i < sizeof(actions)/sizeof(*actions); ++i) {
+ QAction* a = getAction(actions[i], this);
+ addAction(a);
+ cmdMap->setMapping(a, a);
+ connect(a, SIGNAL(triggered()), cmdMap, SLOT(map()));
+ }
+ connect(cmdMap, SIGNAL(mapped(QObject*)), SLOT(drumCmd(QObject*)));
+
+
+ connect(song, SIGNAL(songChanged(int)), canvas(), SLOT(songChanged(int)));
+ connect(followSongAction, SIGNAL(toggled(bool)), canvas(), SLOT(setFollow(bool)));
+ canvas()->selectFirst();
+
+ Part* part = canvas()->part();
+
+ setRaster(part->raster() != -1 ? part->raster() : initRaster);
+ setQuant(part->quant() != -1 ? part->quant() : initQuant);
+ setXmag(part->xmag() != -1.0 ? part->xmag() : initXmag);
+
+ if (init)
+ initFromPart();
+ else
+ resize(initWidth, initHeight);
+ }
+
+//---------------------------------------------------------
+// ~DrumEdit
+//---------------------------------------------------------
+
+DrumEdit::~DrumEdit()
+ {
+ }
+
+//---------------------------------------------------------
+// closeEvent
+//---------------------------------------------------------
+
+void DrumEdit::closeEvent(QCloseEvent* e)
+ {
+ MidiEditor::closeEvent(e);
+ }
+
+//---------------------------------------------------------
+// setSelection
+// update Info Line
+//---------------------------------------------------------
+
+void DrumEdit::setSelection(int tick, Event& e, Part* p)
+ {
+ int selections = canvas()->selectionSize();
+ selEvent = e;
+ selPart = p;
+
+ if (selections > 1) {
+ info->setEnabled(true);
+ info->setDeltaMode(true);
+ if (!deltaMode) {
+ deltaMode = true;
+ info->setValues(0, 0, 0, 0, 0);
+ tickOffset = 0;
+ lenOffset = 0;
+ pitchOffset = 0;
+ veloOnOffset = 0;
+ veloOffOffset = 0;
+ }
+ }
+ else if (selections == 1) {
+ deltaMode = false;
+ info->setEnabled(true);
+ info->setDeltaMode(false);
+ info->setValues(tick,
+ selEvent.lenTick(),
+ selEvent.pitch(),
+ selEvent.velo(),
+ selEvent.veloOff());
+ }
+ else {
+ deltaMode = false;
+ info->setEnabled(false);
+ }
+ selectionChanged();
+ }
+
+//---------------------------------------------------------
+// soloChanged
+//---------------------------------------------------------
+
+void DrumEdit::soloChanged(bool flag)
+ {
+ song->setSolo(canvas()->track(), flag);
+ }
+
+//---------------------------------------------------------
+// edit currently selected Event
+//---------------------------------------------------------
+
+void DrumEdit::noteinfoChanged(NoteInfo::ValType type, int val)
+ {
+ int selections = canvas()->selectionSize();
+
+ if (selections == 0) {
+ printf("noteinfoChanged while nothing selected\n");
+ }
+ else if (selections == 1) {
+ Event event = selEvent.clone();
+ switch(type) {
+ case NoteInfo::VAL_TIME:
+ event.setTick(val - selPart->tick());
+ break;
+ case NoteInfo::VAL_LEN:
+ event.setLenTick(val);
+ break;
+ case NoteInfo::VAL_VELON:
+ event.setVelo(val);
+ break;
+ case NoteInfo::VAL_VELOFF:
+ event.setVeloOff(val);
+ break;
+ case NoteInfo::VAL_PITCH:
+ event.setPitch(val);
+ break;
+ }
+ audio->msgChangeEvent(selEvent, event, selPart);
+ }
+ else {
+ // multiple events are selected; treat noteinfo values
+ // as offsets to event values
+
+ int delta = 0;
+ switch (type) {
+ case NoteInfo::VAL_TIME:
+ delta = val - tickOffset;
+ tickOffset = val;
+ break;
+ case NoteInfo::VAL_LEN:
+ delta = val - lenOffset;
+ lenOffset = val;
+ break;
+ case NoteInfo::VAL_VELON:
+ delta = val - veloOnOffset;
+ veloOnOffset = val;
+ break;
+ case NoteInfo::VAL_VELOFF:
+ delta = val - veloOffOffset;
+ veloOffOffset = val;
+ break;
+ case NoteInfo::VAL_PITCH:
+ delta = val - pitchOffset;
+ pitchOffset = val;
+ break;
+ }
+ if (delta)
+ canvas()->modifySelected(type, delta);
+ }
+ }
+
+//---------------------------------------------------------
+// cmd
+// pulldown menu commands
+//---------------------------------------------------------
+
+void DrumEdit::cmd(QAction* a)
+ {
+ canvas()->cmd(a);
+ }
+
+//---------------------------------------------------------
+// drumCmd
+//---------------------------------------------------------
+
+void DrumEdit::drumCmd(QObject* object)
+ {
+ QAction* a = (QAction*)object;
+ QString cmd(a->data().toString());
+
+ static const int rasterTable[] = {
+ //-9----8- 7 6 5 4 3(1/4) 2 1
+ 4, 8, 16, 32, 64, 128, 256, 512, 1024, // triple
+ 6, 12, 24, 48, 96, 192, 384, 768, 1536,
+ 9, 18, 36, 72, 144, 288, 576, 1152, 2304 // dot
+ };
+
+ DrumCanvas* dc = canvas();
+ int index = 0;
+ int n = sizeof(rasterTable);
+ for (; index < n; ++index)
+ if (rasterTable[index] == raster())
+ break;
+ int off = (index / 9) * 9;
+ index = index % 9;
+ int val;
+
+ if (cmd == "curpos_increase") {
+ dc->cmd(a);
+ return;
+ }
+ else if (cmd == "curpos_decrease") {
+ dc->cmd(a);
+ return;
+ }
+ else if (cmd == "pointer") {
+ tools2->set(PointerTool);
+ return;
+ }
+ else if (cmd == "pencil") {
+ tools2->set(PencilTool);
+ return;
+ }
+ else if (cmd == "eraser") {
+ tools2->set(RubberTool);
+ return;
+ }
+ else if (cmd == "midi_quant_1")
+ val = rasterTable[8 + off];
+ else if (cmd == "midi_quant_2")
+ val = rasterTable[7 + off];
+ else if (cmd == "midi_quant_3")
+ val = rasterTable[6 + off];
+ else if (cmd == "midi_quant_4")
+ val = rasterTable[5 + off];
+ else if (cmd == "midi_quant_5")
+ val = rasterTable[4 + off];
+ else if (cmd == "midi_quant_6")
+ val = rasterTable[3 + off];
+ else if (cmd == "midi_quant_7")
+ val = rasterTable[2 + off];
+ else if (cmd == "midi_quant_triol")
+ val = rasterTable[index + ((off == 0) ? 9 : 0)];
+ else if (cmd == "midi_quant_punct")
+ val = rasterTable[index + ((off == 18) ? 9 : 18)];
+
+ else if (cmd == "midi_quant_punct2") {
+ if ((off == 18) && (index > 2)) {
+ val = rasterTable[index + 9 - 1];
+ }
+ else if ((off == 9) && (index < 8)) {
+ val = rasterTable[index + 18 + 1];
+ }
+ else
+ return;
+ }
+ else {
+ printf("DrumEdit::drumCmd: unknown cmd <%s>\n", cmd.toLatin1().data());
+ return;
+ }
+ setQuant(val);
+ setRaster(val);
+ toolbar->setQuant(quant());
+ toolbar->setRaster(raster());
+ }
+
+//---------------------------------------------------------
+// writeConfiguration
+//---------------------------------------------------------
+
+void DrumEdit::writeConfiguration(Xml& xml)
+ {
+ xml.stag("DrumEdit");
+ if (DrumEdit::initWidth != DrumEdit::INIT_WIDTH)
+ xml.tag("width", DrumEdit::initWidth);
+ if (DrumEdit::initHeight != DrumEdit::INIT_HEIGHT)
+ xml.tag("height", DrumEdit::initHeight);
+ if (DrumEdit::initRaster != DrumEdit::INIT_RASTER)
+ xml.tag("raster", DrumEdit::initRaster);
+ xml.etag("DrumEdit");
+ }
+
+//---------------------------------------------------------
+// readConfiguration
+//---------------------------------------------------------
+
+void DrumEdit::readConfiguration(QDomNode node)
+ {
+ for (node = node.firstChild(); !node.isNull(); node = node.nextSibling()) {
+ QDomElement e = node.toElement();
+ QString tag(e.tagName());
+ int i = e.text().toInt();
+ if (tag == "width")
+ DrumEdit::initWidth = i;
+ else if (tag == "height")
+ DrumEdit::initHeight = i;
+ else if (tag == "raster")
+ DrumEdit::initRaster = i;
+ else
+ printf("MusE:DrumEdit: unknown tag %s\n", tag.toLatin1().data());
+ }
+ }
+
diff --git a/muse_qt4_evolution/muse/midiedit/drumedit.h b/muse_qt4_evolution/muse/midiedit/drumedit.h
new file mode 100644
index 00000000..20cf99f6
--- /dev/null
+++ b/muse_qt4_evolution/muse/midiedit/drumedit.h
@@ -0,0 +1,93 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __DRUM_EDIT_H__
+#define __DRUM_EDIT_H__
+
+#include "midieditor.h"
+#include "dcanvas.h"
+
+namespace AL {
+ class Xml;
+ };
+using AL::Xml;
+
+
+class PartList;
+class Part;
+class DrumMap;
+
+//---------------------------------------------------------
+// DrumEdit
+//---------------------------------------------------------
+
+class DrumEdit : public MidiEditor {
+ Q_OBJECT
+
+ Event selEvent;
+ DrumMap* drumMap;
+ int selTick;
+ QMenu *menuFunctions, *menuSelect;
+
+ int tickOffset;
+ int lenOffset;
+ int pitchOffset;
+ int veloOnOffset;
+ int veloOffOffset;
+ bool deltaMode;
+
+ virtual void closeEvent(QCloseEvent*);
+ QWidget* genToolbar(QWidget* parent);
+ DrumCanvas* canvas() { return (DrumCanvas*)tcanvas; }
+
+ private slots:
+ void noteinfoChanged(NoteInfo::ValType type, int val);
+ virtual void cmd(QAction*);
+ void drumCmd(QObject* object);
+
+ public slots:
+ void setSelection(int, Event&, Part*);
+ void soloChanged(bool); // called by Solo button
+
+ public:
+ DrumEdit(PartList*, bool);
+ ~DrumEdit();
+
+ static int initRaster, initQuant, initWidth, initHeight;
+ static bool initFollow, initSpeaker, initMidiin;
+ static int initApplyTo;
+ static double initXmag;
+
+ static void readConfiguration(QDomNode);
+ static void writeConfiguration(Xml&);
+
+ static const int INIT_WIDTH = 650;
+ static const int INIT_HEIGHT = 450;
+ static const int INIT_RASTER = 384 / 4;
+ static const int INIT_QUANT = 384 / 4;
+ static const bool INIT_FOLLOW = false;
+ static const bool INIT_SPEAKER = true;
+ static const bool INIT_SREC = false;
+ static const bool INIT_MIDIIN = false;
+ static const double INIT_XMAG = 0.08;
+ static const int INIT_APPLY_TO = 0;
+ };
+
+#endif
diff --git a/muse_qt4_evolution/muse/midiedit/drummap.cpp b/muse_qt4_evolution/muse/midiedit/drummap.cpp
new file mode 100644
index 00000000..978c7dab
--- /dev/null
+++ b/muse_qt4_evolution/muse/midiedit/drummap.cpp
@@ -0,0 +1,219 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "drummap.h"
+#include "al/xml.h"
+
+static const int DEFAULT_QUANT = 16;
+static const int DEFAULT_LEN = 32;
+static const int DEFAULT_CHANNEL = -1;
+static const int DEFAULT_LV1 = 70;
+static const int DEFAULT_LV2 = 90;
+static const int DEFAULT_LV3 = 110;
+static const int DEFAULT_LV4 = 127;
+
+//---------------------------------------------------------
+// GM default drum map
+//---------------------------------------------------------
+
+DrumMap gmDrumMap("generic");
+DrumMap noDrumMap("no-map");
+
+//---------------------------------------------------------
+// DrumMap
+//---------------------------------------------------------
+
+DrumMap::DrumMap(const QString& s)
+ {
+ _name = s;
+ for (int i = 0; i < DRUM_MAPSIZE; ++i) {
+ map[i].name = "?";
+ map[i].enote = i;
+ map[i].anote = i;
+ map[i].quant = DEFAULT_QUANT;
+ map[i].len = DEFAULT_LEN;
+ map[i].channel = DEFAULT_CHANNEL;
+ map[i].lv1 = DEFAULT_LV1;
+ map[i].lv2 = DEFAULT_LV2;
+ map[i].lv3 = DEFAULT_LV3;
+ map[i].lv4 = DEFAULT_LV4;
+ map[i].mute = false;
+ }
+ init();
+ }
+
+//---------------------------------------------------------
+// initGm
+//---------------------------------------------------------
+
+void DrumMap::initGm()
+ {
+ static const char* gmNames[] = {
+ "Acoustic Bass Drum", "Bass Drum 1", "Side Stick", "Acoustic Snare",
+ "Hand Clap", "Electric Snare", "Low Floor Tom", "Closed Hi-Hat",
+ "High Floor Tom", "Pedal Hi-Hat", "Low Tom", "Open Hi-Hat", "Low-Mid Tom",
+ "Hi-Mid Tom", "Crash Cymbal 1", "High Tom", "Ride Cymbal 1",
+ "Chinese Cymbal", "Ride Bell", "Tambourine", "Splash Cymbal",
+ "Cowbell", "Crash Cymbal 2", "Vibraslap", "Ride Cymbal 2",
+ "Hi Bongo", "Low Bongo", "Mute Hi Conga", "Open Hi Conga",
+ "Low Conga", "High Timbale", "Low Timbale", "High Agogo",
+ "Low Agogo", "Cabasa", "Maracas", "Short Whistle",
+ "Long Whistle", "Short Guiro", "Long Guiro", "Claves",
+ "Hi Wood Block", "Low Wood Block", "Mute Cuica",
+ "Open Cuica", "Mute Triangle", "Open Triangle", 0
+ };
+ init();
+ int idx = 0;
+ const char** p = &gmNames[0];
+ int val = 35;
+ for (; *p; ++p, ++val, ++idx) {
+ map[idx].name = *p;
+ map[idx].enote = val;
+ map[idx].anote = val;
+ _inmap[int(map[idx].enote)] = idx;
+ _outmap[int(map[idx].anote)] = idx;
+ }
+ }
+
+//---------------------------------------------------------
+// init
+// populate Inmap and Outmap
+//---------------------------------------------------------
+
+void DrumMap::init()
+ {
+ memset(_inmap, 0, sizeof(_inmap));
+ memset(_outmap, 0, sizeof(_outmap));
+ for (int i = 0; i < DRUM_MAPSIZE; ++i) {
+ _inmap[int(map[i].enote)] = i;
+ _outmap[int(map[i].anote)] = i;
+ }
+ }
+
+//---------------------------------------------------------
+// writeDrumMap
+//---------------------------------------------------------
+
+void DrumMap::write(Xml& xml)
+ {
+ xml.stag("drummap");
+ for (int i = 0; i < DRUM_MAPSIZE; ++i) {
+ DrumMapEntry* dm = &map[i];
+ dm->write(xml);
+ }
+ xml.etag("drummap");
+ }
+
+//---------------------------------------------------------
+// write
+//---------------------------------------------------------
+
+void DrumMapEntry::write(Xml& xml)
+ {
+ xml.stag("entry");
+ xml.tag("name", name);
+ if (quant != DEFAULT_QUANT)
+ xml.tag("quant", quant);
+ if (len != DEFAULT_LEN)
+ xml.tag("len", len);
+ if (channel != DEFAULT_CHANNEL)
+ xml.tag("channel", channel);
+ if (lv1 != DEFAULT_LV1)
+ xml.tag("lv1", lv1);
+ if (lv2 != DEFAULT_LV2)
+ xml.tag("lv2", lv2);
+ if (lv3 != DEFAULT_LV3)
+ xml.tag("lv3", lv3);
+ if (lv4 != DEFAULT_LV4)
+ xml.tag("lv4", lv4);
+ xml.tag("enote", enote);
+ if (anote != enote)
+ xml.tag("anote", anote);
+ xml.etag("entry");
+ }
+
+//---------------------------------------------------------
+// read
+//---------------------------------------------------------
+
+void DrumMapEntry::read(QDomNode n)
+ {
+ anote = -1;
+ for (QDomNode node = n.firstChild(); !node.isNull(); node = node.nextSibling()) {
+ QDomElement e = node.toElement();
+ QString tag(e.tagName());
+ QString s(e.text());
+ if (tag == "name")
+ name = s;
+ else if (tag == "quant")
+ quant = s.toInt();
+ else if (tag == "len")
+ len = s.toInt();
+ else if (tag == "channel")
+ channel = s.toInt();
+ else if (tag == "lv1")
+ lv1 = s.toInt();
+ else if (tag == "lv2")
+ lv2 = s.toInt();
+ else if (tag == "lv3")
+ lv3 = s.toInt();
+ else if (tag == "lv4")
+ lv4 = s.toInt();
+ else if (tag == "enote")
+ enote = s.toInt();
+ else if (tag == "anote")
+ anote = s.toInt();
+ else if (tag == "mute")
+ mute = s.toInt();
+ else {
+ printf("read Drummap Entry: unknown tag %s\n", tag.toLatin1().data());
+ break;
+ }
+ }
+ if (anote == -1)
+ anote = enote;
+ }
+
+//---------------------------------------------------------
+// readDrummap
+//---------------------------------------------------------
+
+void DrumMap::read(QDomNode node)
+ {
+ init();
+ int idx = 0;
+ for (; !node.isNull(); node = node.nextSibling()) {
+ QDomElement e = node.toElement();
+ QString tag(e.tagName());
+
+ if (tag == "entry") {
+ QDomNode entryNode = node.firstChild();
+ map[idx].read(entryNode);
+ _inmap[int(map[idx].enote)] = idx;
+ _outmap[int(map[idx].anote)] = idx;
+ ++idx;
+ }
+ else {
+ printf("read Drummap: unknown tag %s\n", tag.toLatin1().data());
+ break;
+ }
+ }
+ }
+
diff --git a/muse_qt4_evolution/muse/midiedit/drummap.h b/muse_qt4_evolution/muse/midiedit/drummap.h
new file mode 100644
index 00000000..0ec1d536
--- /dev/null
+++ b/muse_qt4_evolution/muse/midiedit/drummap.h
@@ -0,0 +1,81 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __DRUMMAP_H__
+#define __DRUMMAP_H__
+
+namespace AL {
+ class Xml;
+ };
+using AL::Xml;
+
+const int DRUM_MAPSIZE = 128;
+
+//---------------------------------------------------------
+// DrumMapEntry
+//---------------------------------------------------------
+
+struct DrumMapEntry {
+ QString name;
+ int quant;
+ int len; // len of event in ticks
+ int channel; // midi channel
+ char lv1, lv2, lv3, lv4; // velocities
+ char enote, anote; // input note - output note
+ bool mute;
+
+ void read(QDomNode node);
+ void write(Xml& xml);
+ };
+
+//---------------------------------------------------------
+// DrumMap
+//---------------------------------------------------------
+
+class DrumMap {
+ QString _name;
+ DrumMapEntry map[DRUM_MAPSIZE];
+ char _outmap[DRUM_MAPSIZE];
+ char _inmap[DRUM_MAPSIZE];
+
+ public:
+ DrumMap(const QString& name);
+ void init();
+ void write(Xml& xml);
+ void read(QDomNode);
+ void initGm();
+ DrumMapEntry* entry(int idx) { return &map[idx]; }
+ QString name() const { return _name; }
+ QString name(int i) const { return map[i].name; }
+ int quant(int i) const { return map[i].quant; }
+ int len(int i) const { return map[i].len; }
+ int channel(int i) const { return map[i].channel; }
+ int enote(int i) const { return map[i].enote; }
+ int anote(int i) const { return map[i].anote; }
+ bool mute(int i) const { return map[i].mute; }
+ int inmap(int i) const { return _inmap[i]; }
+ int outmap(int i) const { return _outmap[i]; }
+ };
+
+extern DrumMap gmDrumMap;
+extern DrumMap noDrumMap;
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/midiedit/ecanvas.cpp b/muse_qt4_evolution/muse/midiedit/ecanvas.cpp
new file mode 100644
index 00000000..8c2eefbf
--- /dev/null
+++ b/muse_qt4_evolution/muse/midiedit/ecanvas.cpp
@@ -0,0 +1,1549 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "midieditor.h"
+#include "ecanvas.h"
+#include "song.h"
+#include "shortcuts.h"
+#include "widgets/simplebutton.h"
+#include "widgets/tools.h"
+#include "widgets/utils.h"
+#include "part.h"
+#include "audio.h"
+#include "midi.h"
+
+//---------------------------------------------------------
+// EventCanvas
+//---------------------------------------------------------
+
+EventCanvas::EventCanvas(MidiEditor* pr, TimeCanvasType type)
+ : TimeCanvas(type)
+ {
+ setMarkerList(song->marker());
+ canvasTools = 0;
+ curItem = 0;
+ curSplitter = -1;
+ dragSplitter = false;
+
+ keyDown = -1;
+
+ itemPopupMenu = 0;
+ canvasPopupMenu = 0;
+ drag = DRAG_OFF;
+
+ editor = pr;
+ curVelo = 70;
+
+ setAcceptDrops(true);
+ setFocusPolicy(Qt::StrongFocus);
+ setMouseTracking(true);
+
+ curPart = editor->parts()->begin()->second;
+ connect(song, SIGNAL(midiEvent(const MidiEvent&)), SLOT(midiNote(const MidiEvent&)));
+ }
+
+//---------------------------------------------------------
+// range
+//---------------------------------------------------------
+
+void EventCanvas::range(AL::Pos& s, AL::Pos& e) const
+ {
+ s.setTick(startTick);
+ e.setTick(endTick);
+ }
+
+//---------------------------------------------------------
+// getCaption
+//---------------------------------------------------------
+
+QString EventCanvas::getCaption() const
+ {
+ int bar1, bar2, xx;
+ unsigned x;
+ AL::sigmap.tickValues(curPart->tick(), &bar1, &xx, &x);
+ AL::sigmap.tickValues(curPart->tick() + curPart->lenTick(), &bar2, &xx, &x);
+
+ return QString("MusE: Part <") + curPart->name()
+ + QString("> %1-%2").arg(bar1+1).arg(bar2+1);
+ }
+
+//---------------------------------------------------------
+// startUndo
+//---------------------------------------------------------
+
+void EventCanvas::startUndo(DragType)
+ {
+ song->startUndo();
+ }
+
+//---------------------------------------------------------
+// endUndo
+//---------------------------------------------------------
+
+void EventCanvas::endUndo(DragType dtype)
+ {
+ song->endUndo((dtype == MOVE_COPY) ? SC_EVENT_INSERTED : SC_EVENT_MODIFIED);
+ }
+
+//---------------------------------------------------------
+// updateSelection
+//---------------------------------------------------------
+
+void EventCanvas::updateSelection()
+ {
+ song->update(SC_SELECTION);
+ }
+
+//---------------------------------------------------------
+// songChanged(type)
+// called from MidiEditor
+//---------------------------------------------------------
+
+void EventCanvas::songChanged(int flags)
+ {
+ if ((flags & ~SC_SELECTION) && !editor->parts()->empty()) {
+ items.clear();
+ startTick = INT_MAX;
+ endTick = 0;
+ for (iPart p = editor->parts()->begin(); p != editor->parts()->end(); ++p) {
+ Part* part = p->second;
+ unsigned stick = part->tick();
+ unsigned etick = stick + part->lenTick();
+ if (stick < startTick)
+ startTick = stick;
+ if (etick > endTick)
+ endTick = etick;
+
+ EventList* el = part->events();
+ for (iEvent i = el->begin(); i != el->end(); ++i) {
+ Event e = i->second;
+ if (e.isNote())
+ addItem(part, e);
+ }
+ }
+ }
+
+ Event event;
+ Part* part = 0;
+ int x = 0;
+ CItem* nevent = 0;
+
+ int n = 0; // count selections
+ for (iCItem k = items.begin(); k != items.end(); ++k) {
+ Event ev = k->second->event;
+ bool selected = ev.selected();
+ if (selected) {
+ k->second->setSelected(true);
+ ++n;
+ if (!nevent) {
+ nevent = k->second;
+ Event mi = nevent->event;
+ curVelo = mi.velo();
+ }
+ }
+ }
+ startTick = song->roundDownBar(startTick);
+ endTick = song->roundUpBar(endTick);
+
+ if (n == 1) {
+ x = nevent->bbox.x();
+ event = nevent->event;
+ part = nevent->part;
+ }
+ emit selectionChanged(x, event, part);
+ if (curPart)
+ setPart(*curPart, curPart->end());
+ widget()->update();
+ }
+
+//---------------------------------------------------------
+// selectFirst
+//---------------------------------------------------------
+
+void EventCanvas::selectFirst()
+ {
+ //Select leftmost note if none selected and there are any
+ if (!items.empty() && selectionSize() == 0) {
+ iCItem i = items.begin();
+ if (!i->second->isSelected()) {
+ selectItem(i->second, true);
+ songChanged(SC_SELECTION);
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// track
+//---------------------------------------------------------
+
+MidiTrack* EventCanvas::track() const
+ {
+ return (MidiTrack*)(curPart->track());
+ }
+
+//---------------------------------------------------------
+// keyPress
+//---------------------------------------------------------
+
+void EventCanvas::keyPress(QKeyEvent* event)
+ {
+#if 0 // TODOB
+ int key = event->key();
+ if (event->modifiers() & Qt::ShiftModifier)
+ key += Qt::SHIFT;
+ if (event->modifiers() & Qt::AltModifier)
+ key += Qt::ALT;
+ if (event->modifiers() & Qt::ControlModifier)
+ key += Qt::CTRL;
+
+ //
+ // Shortcut for DrumEditor & PianoRoll
+ // Sets locators to selected events
+ //
+ if (key == shortcuts[SHRT_LOCATORS_TO_SELECTION].key) {
+ int tick_max = 0;
+ int tick_min = INT_MAX;
+ bool found = false;
+
+ for (iCItem i= items.begin(); i != items.end(); i++) {
+ if (!i->second->isSelected())
+ continue;
+
+ int tick = i->second->bbox.x();
+ int len = i->second->event.lenTick();
+ found = true;
+ if (tick + len > tick_max)
+ tick_max = tick + len;
+ if (tick < tick_min)
+ tick_min = tick;
+ }
+ if (found) {
+ Pos p1(tick_min, AL::TICKS);
+ Pos p2(tick_max, AL::TICKS);
+ song->setPos(1, p1);
+ song->setPos(2, p2);
+ }
+ }
+ // Select items by key (PianoRoll & DrumEditor)
+ else if (key == shortcuts[SHRT_SEL_RIGHT].key || key == shortcuts[SHRT_SEL_RIGHT_ADD].key) {
+ iCItem i, iRightmost;
+ CItem* rightmost = NULL;
+ //Get the rightmost selected note (if any)
+ for (i = items.begin(); i != items.end(); ++i) {
+ if (i->second->isSelected()) {
+ iRightmost = i;
+ rightmost = i->second;
+ }
+ }
+ if (rightmost) {
+ iCItem temp = iRightmost;
+ temp++;
+ //If so, deselect current note and select the one to the right
+ if (temp != items.end()) {
+ if (key != shortcuts[SHRT_SEL_RIGHT_ADD].key)
+ deselectAll();
+
+ iRightmost++;
+ iRightmost->second->setSelected(true);
+ updateSelection();
+ }
+ }
+ }
+ //Select items by key: (PianoRoll & DrumEditor)
+ else if (key == shortcuts[SHRT_SEL_LEFT].key || key == shortcuts[SHRT_SEL_LEFT_ADD].key) {
+ iCItem i, iLeftmost;
+ CItem* leftmost = NULL;
+ for (i = items.end(), i--; i != items.begin(); i--) {
+ if (i->second->isSelected()) {
+ iLeftmost = i;
+ leftmost = i->second;
+ }
+ }
+ if (leftmost) {
+ if (iLeftmost != items.begin()) {
+ //Add item
+ if (key != shortcuts[SHRT_SEL_LEFT_ADD].key)
+ deselectAll();
+
+ iLeftmost--;
+ iLeftmost->second->setSelected(true);
+ updateSelection();
+ }
+ }
+ }
+ else if (key == shortcuts[SHRT_INC_PITCH].key) {
+ modifySelected(NoteInfo::VAL_PITCH, 1);
+ }
+ else if (key == shortcuts[SHRT_DEC_PITCH].key) {
+ modifySelected(NoteInfo::VAL_PITCH, -1);
+ }
+ else if (key == shortcuts[SHRT_INC_POS].key) {
+ // TODO: Check boundaries
+ modifySelected(NoteInfo::VAL_TIME, editor->raster());
+ }
+ else if (key == shortcuts[SHRT_DEC_POS].key) {
+ // TODO: Check boundaries
+ modifySelected(NoteInfo::VAL_TIME, 0 - editor->raster());
+ }
+ else
+ event->ignore();
+#endif
+ }
+
+//---------------------------------------------------------
+// mousePressCanvasA
+//---------------------------------------------------------
+
+void EventCanvas::mousePressCanvasA(QMouseEvent* me)
+ {
+ QPoint p(me->pos() - rCanvasA.topLeft());
+
+ // special events if right button is clicked while operations
+ // like moving or drawing lasso is performed.
+
+ if (button == Qt::RightButton) {
+ switch (drag) {
+ case DRAG_LASSO:
+ drag = DRAG_OFF;
+ widget()->update();
+ return;
+ case DRAG_MOVE:
+ drag = DRAG_OFF;
+ endMoveItems(MOVE_MOVE);
+ return;
+ default:
+ break;
+ }
+ }
+ // ignore event if (another) button is already active:
+ if (me->buttons() & (Qt::LeftButton | Qt::RightButton | Qt::MidButton)
+ & ~button)
+ return;
+
+ bool shift = keyState & Qt::ShiftModifier;
+ bool ctrl = keyState & Qt::ControlModifier;
+ start = p;
+ startPitch = y2pitch(start.y());
+ deltaPitch = 0;
+
+ //---------------------------------------------------
+ // set curItem to item mouse is pointing
+ // (if any)
+ //---------------------------------------------------
+
+ curItem = searchItem(start);
+ if (curItem && editor->playEvents()) {
+ int pitch = curItem->event.pitch() + track()->transposition();
+ MidiEvent e(0, 0, ME_NOTEON, pitch, curItem->event.velo());
+ track()->playMidiEvent(&e);
+ }
+
+ if (curItem && (button == Qt::MidButton)) {
+ if (!curItem->isSelected()) {
+ selectItem(curItem, true);
+ updateSelection();
+ widget()->update();
+ }
+ startDrag(curItem, shift);
+ }
+ else if (button == Qt::RightButton) {
+ if (curItem) {
+ if (shift) {
+ drag = DRAG_RESIZE;
+ setCursor();
+ Pos p1(curItem->bbox.x(), timeType());
+ Pos p2(pix2pos(start.x()));
+ curItem->bbox.setWidth(p2.time(timeType())-p1.time(timeType()));
+
+ start.setX(curItem->bbox.x());
+ deselectAll();
+ selectItem(curItem, true);
+ updateSelection();
+ widget()->update();
+ }
+ else {
+ itemPopupMenu = genItemPopup(curItem);
+ if (itemPopupMenu) {
+ QAction* a = itemPopupMenu->exec(QCursor::pos());
+ if (a) {
+ int n = a->data().toInt();
+ itemPopup(curItem, n, start);
+ }
+ delete itemPopupMenu;
+ }
+ }
+ }
+ else {
+ canvasPopupMenu = genCanvasPopup();
+ if (canvasPopupMenu) {
+ QAction* a = canvasPopupMenu->exec(QCursor::pos(), 0);
+ if (a) {
+ int n = a->data().toInt();
+ canvasPopup(n);
+ }
+ delete canvasPopupMenu;
+ }
+ }
+ }
+ else if (button == Qt::LeftButton) {
+ switch (_tool) {
+ case PointerTool:
+ if (curItem) {
+ itemPressed(curItem);
+ if (curItem->part != curPart)
+ setCurPart(curItem->part);
+ if (shift && !ctrl)
+ drag = DRAG_COPY_START;
+ else if (!shift && ctrl) {
+ //Select all on the same pitch
+ deselectAll();
+ int pitch = curItem->event.pitch();
+ for (iCItem i = items.begin(); i != items.end(); ++i) {
+ if (i->second->event.pitch() == pitch)
+ selectItem(i->second, true);
+ }
+ updateSelection();
+ widget()->update();
+ drag = DRAG_MOVE_START;
+ }
+ else
+ drag = DRAG_MOVE_START;
+ }
+ else
+ drag = DRAG_LASSO_START;
+ setCursor();
+ break;
+
+ case RubberTool:
+ deleteItem(p);
+ drag = DRAG_DELETE;
+ setCursor();
+ break;
+
+ case PencilTool:
+ if (curItem) {
+ drag = DRAG_RESIZE;
+ setCursor();
+
+ Pos p1(curItem->bbox.x(), timeType());
+ Pos p2(pix2pos(start.x()));
+ int w = p2.time(timeType()) - p1.time(timeType());
+ curItem->bbox.setWidth(w);
+ start.setX(curItem->bbox.x());
+ start.setY(curItem->bbox.y());
+ }
+ else {
+ drag = DRAG_NEW;
+ setCursor();
+ curItem = newItem(start, keyState);
+ if (curItem) {
+ items.add(curItem);
+ if (editor->playEvents()) {
+ int pitch = curItem->event.pitch() + track()->transposition();
+ MidiEvent e(0, 0, ME_NOTEON, pitch, curItem->event.velo());
+ track()->playMidiEvent(&e);
+ }
+ }
+ else {
+ drag = DRAG_OFF;
+ setCursor();
+ }
+ }
+ deselectAll();
+ if (curItem)
+ selectItem(curItem, true);
+ updateSelection();
+ widget()->update();
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// mouseMoveCanvasA
+// pos is relative to CanvasA
+//---------------------------------------------------------
+
+void EventCanvas::mouseMoveCanvasA(QPoint pos)
+ {
+ QPoint dist = pos - start;
+ bool isMoving = dist.manhattanLength() >= QApplication::startDragDistance();
+
+ switch (drag) {
+ case DRAG_LASSO_START:
+ if (!isMoving)
+ break;
+ drag = DRAG_LASSO;
+ setCursor();
+ // proceed with DRAG_LASSO:
+
+ case DRAG_LASSO:
+ lasso = QRect(start, QSize(dist.x(), dist.y()));
+ widget()->update();
+ break;
+
+ case DRAG_MOVE_START:
+ case DRAG_COPY_START:
+ if (!isMoving)
+ break;
+ {
+ bool shift = keyState & Qt::ShiftModifier;
+ bool ctrl = keyState & Qt::ControlModifier;
+ if (shift && ctrl) {
+ if (qAbs(dist.x()) > qAbs(dist.y())) {
+ if (drag == DRAG_MOVE_START)
+ drag = DRAGX_MOVE;
+ else
+ drag = DRAGX_COPY;
+ }
+ else {
+ if (drag == DRAG_MOVE_START)
+ drag = DRAGY_MOVE;
+ else
+ drag = DRAGY_COPY;
+ }
+ }
+ else {
+ if (drag == DRAG_MOVE_START)
+ drag = DRAG_MOVE;
+ else
+ drag = DRAG_COPY;
+ }
+ setCursor();
+ if (!curItem->isSelected()) {
+ if (drag == DRAG_MOVE)
+ deselectAll();
+ selectItem(curItem, true);
+ updateSelection();
+ widget()->update();
+ }
+ for (iCItem i = items.begin(); i != items.end(); ++i) {
+ if (i->second->isSelected()) {
+ i->second->isMoving = true;
+ moving.add(i->second);
+ }
+ }
+ moveItems(pos, 0);
+ }
+ break;
+
+ case DRAG_MOVE:
+ case DRAG_COPY:
+ moveItems(pos, 0);
+ break;
+
+ case DRAGX_MOVE:
+ case DRAGX_COPY:
+ moveItems(pos, 1);
+ break;
+
+ case DRAGY_MOVE:
+ case DRAGY_COPY:
+ moveItems(pos, 2);
+ break;
+
+ case DRAG_NEW:
+ case DRAG_RESIZE:
+ if (dist.x()) {
+ Pos p1(curItem->bbox.x(), timeType());
+ Pos p2(pix2pos(pos.x()));
+ int w = p2.time(timeType()) - p1.time(timeType());
+ if (w < 1)
+ w = 1;
+ curItem->bbox.setWidth(w);
+ widget()->update();
+ }
+ break;
+ case DRAG_DELETE:
+ deleteItem(pos);
+ break;
+
+ case DRAG_OFF:
+ break;
+ }
+ }
+
+//---------------------------------------------------------
+// mouseReleaseCanvasA
+//---------------------------------------------------------
+
+void EventCanvas::mouseReleaseCanvasA(QMouseEvent* me)
+ {
+ if (curItem && editor->playEvents()) {
+ int pitch = curItem->event.pitch() + track()->transposition();
+ MidiEvent e(0, 0, ME_NOTEON, pitch, 0);
+ track()->playMidiEvent(&e);
+ }
+ // ignore event if (another) button is already active:
+
+ if (me->buttons() & (Qt::LeftButton | Qt::RightButton | Qt::MidButton)
+ & ~button)
+ return;
+
+ bool shift = keyState & Qt::ShiftModifier;
+ bool ctrl = keyState & Qt::ControlModifier;
+ bool redrawFlag = false;
+
+ switch (drag) {
+ case DRAG_MOVE_START:
+ case DRAG_COPY_START:
+ if (!(shift || ctrl))
+ deselectAll();
+ if (!ctrl)
+ selectItem(curItem, !(shift && curItem->isSelected()));
+ updateSelection();
+ redrawFlag = true;
+ itemReleased();
+ break;
+ case DRAG_COPY:
+ case DRAGX_COPY:
+ case DRAGY_COPY:
+ endMoveItems(MOVE_COPY);
+ break;
+ case DRAG_MOVE:
+ case DRAGX_MOVE:
+ case DRAGY_MOVE:
+ endMoveItems(MOVE_MOVE);
+ break;
+ case DRAG_OFF:
+ break;
+ case DRAG_RESIZE:
+ resizeItem(curItem, false);
+ break;
+ case DRAG_NEW:
+ newItem(curItem, false);
+ redrawFlag = true;
+ break;
+ case DRAG_LASSO_START:
+ lasso.setRect(-1, -1, -1, -1);
+ if (!shift)
+ deselectAll();
+ updateSelection();
+ redrawFlag = true;
+ break;
+
+ case DRAG_LASSO:
+ if (!shift)
+ deselectAll();
+ lasso = lasso.normalized();
+ selectLasso(shift);
+ updateSelection();
+ redrawFlag = true;
+ break;
+
+ case DRAG_DELETE:
+ break;
+ }
+ drag = DRAG_OFF;
+ if (redrawFlag)
+ widget()->update();
+ setCursor();
+ }
+
+
+//---------------------------------------------------------
+// endMoveItems
+//---------------------------------------------------------
+
+void EventCanvas::endMoveItems(DragType dragtype)
+ {
+ startUndo(dragtype);
+
+ for (iCItem i = moving.begin(); i != moving.end(); ++i) {
+ selectItem(i->second, true);
+ moveItem(i->second, dragtype);
+//TD if (moving.size() == 1) {
+// itemReleased();
+// }
+ if (dragtype == MOVE_COPY)
+ selectItem(i->second, false);
+ }
+ endUndo(dragtype);
+ moving.clear();
+ updateSelection();
+ widget()->update();
+ }
+
+//---------------------------------------------------------
+// selectItem
+//---------------------------------------------------------
+
+void EventCanvas::selectItem(CItem* e, bool flag)
+ {
+ e->setSelected(flag);
+ }
+
+//---------------------------------------------------------
+// deselectAll
+//---------------------------------------------------------
+
+void EventCanvas::deselectAll()
+ {
+ for (iCItem i = items.begin(); i != items.end(); ++i)
+ i->second->setSelected(false);
+ }
+
+//---------------------------------------------------------
+// genCanvasPopup
+//---------------------------------------------------------
+
+QMenu* EventCanvas::genCanvasPopup()
+ {
+ if (canvasTools == 0)
+ return 0;
+ QMenu* canvasPopup = new QMenu(this);
+
+ for (int i = 0; i < TOOLS; ++i) {
+ int data = 1 << i;
+ if ((canvasTools & data) == 0)
+ continue;
+ QAction* a = getAction(toolList[i], this);
+ a->setData(data);
+ a->setCheckable(true);
+ a->setChecked(data == int(_tool));
+ canvasPopup->addAction(a);
+ }
+ return canvasPopup;
+ }
+
+//---------------------------------------------------------
+// canvasPopup
+//---------------------------------------------------------
+
+void EventCanvas::canvasPopup(int n)
+ {
+ setTool(n);
+ }
+
+//---------------------------------------------------------
+// setCursor
+//---------------------------------------------------------
+
+void EventCanvas::setCursor()
+ {
+ if (curSplitter != -1) {
+ widget()->setCursor(Qt::SplitVCursor);
+ return;
+ }
+ switch (drag) {
+ case DRAGX_MOVE:
+ case DRAGX_COPY:
+ widget()->setCursor(QCursor(Qt::SizeHorCursor));
+ break;
+
+ case DRAGY_MOVE:
+ case DRAGY_COPY:
+ widget()->setCursor(QCursor(Qt::SizeVerCursor));
+ break;
+
+ case DRAG_MOVE:
+ case DRAG_COPY:
+ widget()->setCursor(QCursor(Qt::SizeAllCursor));
+ break;
+
+ case DRAG_RESIZE:
+ widget()->setCursor(QCursor(Qt::SizeHorCursor));
+ break;
+
+ case DRAG_DELETE:
+ case DRAG_COPY_START:
+ case DRAG_MOVE_START:
+ case DRAG_NEW:
+ case DRAG_LASSO_START:
+ case DRAG_LASSO:
+ case DRAG_OFF:
+ TimeCanvas::setCursor();
+ break;
+ }
+ }
+
+//---------------------------------------------------------
+// deleteItem
+// p is relative to CanvasA
+//---------------------------------------------------------
+
+void EventCanvas::deleteItem(const QPoint& p)
+ {
+ Pos pos(pix2pos(p.x()));
+ int pitch(y2pitch(p.y()));
+
+// printf("%d %d - %d %d\n", p.x(), p.y(), pos.tick(), pitch);
+
+ pos -= *curPart;
+ for (iCItem i = items.begin(); i != items.end(); ++i) {
+ Event& event = i->second->event;
+ if (event.pitch() == pitch
+ && (pos >= event.pos())
+ && (pos < event.end())) {
+ deleteItem(i->second);
+ break;
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// moveItems
+// dir = 0 move in all directions
+// 1 move only horizontal
+// 2 move only vertical
+//---------------------------------------------------------
+
+void EventCanvas::moveItems(const QPoint& pos, int dir)
+ {
+ int dpitch = y2pitch(pos.y()) - startPitch;
+
+ Pos sp(pix2pos(start.x()));
+ Pos cp(pix2pos(pos.x()));
+
+ bool left = sp > cp;
+ Pos dx(left ? sp - cp : cp - sp);
+
+ if (dir == 2)
+ dx.setTick(0);
+
+ for (iCItem i = moving.begin(); i != moving.end(); ++i) {
+ CItem* item = i->second;
+ Pos p;
+ if (left) {
+ //
+ // restrict movement to pos >= 0
+ //
+ if (dx > item->pos)
+ p.setTick(0);
+ else
+ p = item->pos - dx;
+ }
+ else
+ p = item->pos + dx;
+ p.snap(raster());
+
+ if (p < *curPart)
+ p = *curPart;
+
+ if (item->moving != p || dpitch != deltaPitch) {
+ item->moving = p;
+ if (dir != 1)
+ item->my = pitch2y(item->event.pitch() + dpitch)
+ + (int)(wpos.y() / _ymag);
+ itemMoved(item);
+ }
+ }
+ deltaPitch = dpitch;
+ widget()->update();
+ }
+
+//---------------------------------------------------------
+// selectionSize
+//---------------------------------------------------------
+
+int EventCanvas::selectionSize() const
+ {
+ int n = 0;
+ for (ciCItem i = items.begin(); i != items.end(); ++i) {
+ if (i->second->isSelected())
+ ++n;
+ }
+ return n;
+ }
+
+//---------------------------------------------------------
+// layout
+// called after resize
+//---------------------------------------------------------
+
+void EventCanvas::layout()
+ {
+ int n = ctrlEditList.size();
+ if (n == 0)
+ return;
+ if (ctrlHeight == 0) {
+ int wh = widget()->height();
+ resizeController(wh < 120 ? wh / 2 : 100);
+ }
+
+ // check, if layout is ok already; this happens after
+ // song load
+ int h = 0;
+ for (iCtrlEdit i = ctrlEditList.begin(); i != ctrlEditList.end(); ++i) {
+ CtrlEdit* c = *i;
+ h += c->height();
+ }
+ if (h == ctrlHeight) {
+ for (iCtrlEdit i = ctrlEditList.begin(); i != ctrlEditList.end(); ++i)
+ layoutPanelB(*i);
+ return;
+ }
+
+ int y = 0;
+ int sch = ctrlHeight / n;
+ for (iCtrlEdit i = ctrlEditList.begin(); i != ctrlEditList.end(); ++i) {
+ CtrlEdit* c = *i;
+ c->y = y;
+ c->setHeight(sch);
+ layoutPanelB(c);
+ y += sch;
+ }
+ }
+
+//---------------------------------------------------------
+// layout1
+// called after read song
+//---------------------------------------------------------
+
+void EventCanvas::layout1()
+ {
+ int n = ctrlEditList.size();
+ if (n == 0)
+ return;
+ int y = 0;
+ for (iCtrlEdit i = ctrlEditList.begin(); i != ctrlEditList.end(); ++i) {
+ CtrlEdit* c = *i;
+ c->y = y;
+ y += c->height();
+ }
+ resizeController(y);
+ }
+
+//---------------------------------------------------------
+// layoutPanelB
+//---------------------------------------------------------
+
+void EventCanvas::layoutPanelB(CtrlEdit* c)
+ {
+ int y = c->y;
+ int h = c->height();
+ int bx = rPanelB.x() + rPanelB.width() - 23;
+ int by = rPanelB.y() + y + h - 19;
+ c->minus->setGeometry(bx, by, 18, 18);
+ bx = rPanelB.x() + 1;
+ by = rPanelB.y() + y + 5;
+ c->sel->setGeometry(bx, by, rPanelB.width()-5, 18);
+ }
+
+//---------------------------------------------------------
+// addController
+//---------------------------------------------------------
+
+void EventCanvas::addController()
+ {
+ int n = ctrlEditList.size();
+ CtrlEdit* ce = new CtrlEdit(widget(), this, track());
+ ce->setHeight(50);
+ ctrlEditList.push_back(ce);
+
+ ce->minus->defaultAction()->setData(n);
+ connect(ce->minus, SIGNAL(triggered(QAction*)), SLOT(removeController(QAction*)));
+ ce->minus->show();
+ ce->sel->show();
+
+ layout();
+ widget()->update();
+ updatePartControllerList();
+ }
+
+void EventCanvas::addController(int id, int h)
+ {
+ ctrlHeight += h;
+ int n = ctrlEditList.size();
+
+ CtrlEdit* ce = new CtrlEdit(widget(), this, track());
+ ce->setHeight(h);
+ ce->setCtrl(id);
+ ctrlEditList.push_back(ce);
+
+ ce->minus->defaultAction()->setData(n);
+ connect(ce->minus, SIGNAL(triggered(QAction*)), SLOT(removeController(QAction*)));
+ }
+
+//---------------------------------------------------------
+// paintControllerCanvas
+// r(0, 0) is PanelB topLeft()
+//---------------------------------------------------------
+
+void EventCanvas::paintControllerCanvas(QPainter& p, QRect r)
+ {
+ int x1 = r.x();
+ int x2 = x1 + r.width();
+
+ int xx2 = rCanvasB.width();
+ if (xx2 >= x2)
+ x2 = xx2 - 2;
+ for (iCtrlEdit i = ctrlEditList.begin(); i != ctrlEditList.end(); ++i) {
+ CtrlEdit* c = *i;
+ int y = c->y;
+ paintHLine(p, x1, x2, y);
+ p.setPen(lineColor[0]);
+ p.drawLine(xx2-1, 1, xx2-1, splitWidth-2);
+
+ QRect rc(0, y + splitWidth, rCanvasB.width(), c->cheight());
+ QPoint pt(rc.topLeft());
+ rc &= r;
+ if (!rc.isEmpty()) {
+ p.translate(pt);
+ c->paint(p, rc.translated(-pt));
+ p.translate(-pt);
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// paintControllerPanel
+// panelB
+//---------------------------------------------------------
+
+void EventCanvas::paintControllerPanel(QPainter& p, QRect r)
+ {
+ p.fillRect(r, QColor(0xe0, 0xe0, 0xe0));
+ int x1 = r.x();
+ int x2 = x1 + r.width();
+
+ paintVLine(p, r.y() + splitWidth, r.y() + r.height(),
+ rPanelB.x() + rPanelB.width());
+
+ if (x1 == 0)
+ x1 = 1;
+ for (iCtrlEdit i = ctrlEditList.begin(); i != ctrlEditList.end(); ++i) {
+ CtrlEdit* c = *i;
+ paintHLine(p, x1, x2, c->y);
+ p.setPen(lineColor[0]);
+ p.drawLine(0, 1, 0, splitWidth-2);
+ }
+ }
+
+//---------------------------------------------------------
+// removeController
+//---------------------------------------------------------
+
+void EventCanvas::removeController(QAction* a)
+ {
+ int id = a->data().toInt();
+
+ int k = 0;
+ for (iCtrlEdit i = ctrlEditList.begin(); i != ctrlEditList.end(); ++i, ++k) {
+ if (k == id) {
+ CtrlEdit* c = *i;
+ delete c;
+ ctrlEditList.erase(i);
+ break;
+ }
+ }
+ k = 0;
+ for (iCtrlEdit i = ctrlEditList.begin(); i != ctrlEditList.end(); ++i, ++k) {
+ CtrlEdit* c = *i;
+ c->minus->defaultAction()->setData(k);
+ }
+
+ if (ctrlEditList.empty())
+ resizeController(0);
+ else
+ layout();
+ widget()->update();
+ updatePartControllerList();
+ }
+
+//---------------------------------------------------------
+// enterB
+//---------------------------------------------------------
+
+void EventCanvas::enterB()
+ {
+ if ((button == 0) && curSplitter != -1) {
+ curSplitter = -1;
+ setCursor();
+ }
+ }
+
+//---------------------------------------------------------
+// leaveB
+//---------------------------------------------------------
+
+void EventCanvas::leaveB()
+ {
+ if ((button == 0) && (curSplitter != -1)) {
+ curSplitter = -1;
+ setCursor();
+ }
+ }
+
+//---------------------------------------------------------
+// noteOn
+//---------------------------------------------------------
+
+void EventCanvas::noteOn(int pitch, int velocity, bool shift)
+ {
+ DrumMap* dm = track()->drumMap();
+ if (!dm)
+ pitch += track()->transposition();
+
+ // play note:
+ if (editor->playEvents()) {
+ MidiEvent e(0, 0, ME_NOTEON, pitch, velocity);
+ track()->playMidiEvent(&e);
+ }
+
+ if (curPart && editor->stepRec()
+ && pos[0].tick() >= startTick
+ && pos[0].tick() < endTick) {
+ int len = editor->quant();
+ unsigned tick = pos[0].tick() - curPart->tick(); //CDW
+ if (shift)
+ tick -= editor->rasterStep(tick);
+ Event e(Note);
+ e.setTick(tick);
+ e.setPitch(pitch);
+ e.setVelo(127);
+ e.setLenTick(len);
+ audio->msgAddEvent(e, curPart);
+ tick += editor->rasterStep(tick) + curPart->tick();
+ if (tick != song->cpos()) {
+ Pos p(tick, AL::TICKS);
+ song->setPos(0, p, true, false, true);
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// noteOff
+//---------------------------------------------------------
+
+void EventCanvas::noteOff(int pitch)
+ {
+ if (!editor->playEvents())
+ return;
+ DrumMap* dm = track()->drumMap();
+ if (!dm)
+ pitch += track()->transposition();
+
+ // release key:
+ MidiEvent e(0, 0, ME_NOTEON, pitch, 0);
+ track()->playMidiEvent(&e);
+ }
+
+//---------------------------------------------------------
+// mouseDoubleClick
+//---------------------------------------------------------
+
+void EventCanvas::mouseDoubleClick(QMouseEvent* me)
+ {
+ mousePress(me);
+ }
+
+//---------------------------------------------------------
+// mousePress
+//---------------------------------------------------------
+
+void EventCanvas::mousePress(QMouseEvent* me)
+ {
+ QPoint pos(me->pos());
+ if (rPanelA.contains(pos)) {
+ bool shift = keyState & Qt::ShiftModifier;
+ if (keyDown != -1) {
+ noteOff(keyDown);
+ keyDown = -1;
+ }
+ keyDown = y2pitch(pos.y() - rCanvasA.y());
+ int velocity = me->x()*127/40;
+ if (keyDown != -1)
+ noteOn(keyDown, velocity, shift);
+ return;
+ }
+ if (rCanvasA.contains(pos)) {
+ mousePressCanvasA(me);
+ return;
+ }
+ if (curSplitter != -1) {
+ dragSplitter = true;
+ splitterY = pos.y();
+ return;
+ }
+ if (rCanvasB.contains(pos)) {
+ for (iCtrlEdit i = ctrlEditList.begin(); i != ctrlEditList.end(); ++i) {
+ CtrlEdit* c = *i;
+ QRect r(rCanvasB.x(), rCanvasB.y() + c->y + splitWidth,
+ rCanvasB.width(), c->cheight());
+ if (r.contains(pos)) {
+ c->mousePress(pos - r.topLeft(), me);
+ break;
+ }
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// mouseMove
+//---------------------------------------------------------
+
+void EventCanvas::mouseMove(QPoint pos)
+ {
+ if (rPanelA.contains(pos) || rCanvasA.contains(pos)) {
+ int y = pos.y() - rCanvasA.y();
+ int pitch = y2pitch(y);
+ if (curPitch != pitch) {
+ curPitch = pitch;
+ widget()->update(rPanelA); // update keyboard
+ emit pitchChanged(curPitch);
+ if (button != Qt::NoButton) {
+ if (keyDown != -1 && curPitch != -1) {
+ bool shift = keyState & Qt::ShiftModifier;
+ if (curPitch != keyDown) {
+ noteOff(keyDown);
+ keyDown = curPitch;
+ int velocity = std::min(pos.x()*127/40, 127);
+ noteOn(keyDown, velocity, shift);
+ }
+ }
+ }
+ }
+ }
+ if (dragSplitter) {
+ int deltaY = pos.y() - splitterY;
+
+ iCtrlEdit i = ctrlEditList.begin();
+ int y = 0;
+ if (curSplitter > 0) {
+ int k = 0;
+ CtrlEdit* c = 0;
+ for (; i != ctrlEditList.end(); ++i, ++k) {
+ c = *i;
+ y += c->height();
+ if ((k+1) == curSplitter)
+ break;
+ }
+ if (i == ctrlEditList.end()) {
+ printf("unexpected edit list end, curSplitter %d\n", curSplitter);
+ return;
+ }
+ if (c->height() + deltaY < splitWidth)
+ deltaY = splitWidth - c->height();
+ ++i;
+ int rest = 0;
+ for (iCtrlEdit ii = i; ii != ctrlEditList.end(); ++ii)
+ rest += (*ii)->cheight();
+ if (rest < deltaY)
+ deltaY = rest;
+ c->setHeight(c->height() + deltaY);
+ layoutPanelB(c);
+ y += deltaY;
+ }
+ //
+ // layout rest, add deltaY vertical
+ //
+ int rest = 0;
+ for (iCtrlEdit ii = i; ii != ctrlEditList.end(); ++ii) {
+ CtrlEdit* c = *ii;
+ rest += c->cheight();
+ }
+ if (rest < deltaY)
+ deltaY = rest;
+ rest = deltaY;
+ for (; i != ctrlEditList.end(); ++i) {
+ CtrlEdit* c = *i;
+ int d = c->cheight();
+ if (d > deltaY)
+ d = deltaY;
+ c->setHeight(c->height() - d);
+ c->y = y;
+ layoutPanelB(c);
+ y += c->height();
+ deltaY -= d;
+ if (deltaY == 0)
+ break;
+ }
+ if (i != ctrlEditList.end())
+ ++i;
+ for (; i != ctrlEditList.end(); ++i) {
+ CtrlEdit* c = *i;
+ c->y = y;
+ y += c->height();
+ }
+ if (curSplitter == 0)
+ resizeController(ctrlHeight - rest);
+ else
+ widget()->update(rPanelB | rCanvasB);
+ splitterY = pos.y();
+ updatePartControllerList();
+ return;
+ }
+ if (rCanvasA.contains(pos)) {
+ mouseMoveCanvasA(pos - rCanvasA.topLeft());
+ return;
+ }
+ if (button == 0) {
+ if (rPanelB.contains(pos) || rCanvasB.contains(pos)) {
+ int y = pos.y() - rPanelB.y();
+ int k = 0;
+ for (iCtrlEdit i = ctrlEditList.begin(); i != ctrlEditList.end(); ++i, ++k) {
+ CtrlEdit* c = *i;
+ if (y >= c->y && y < (c->y + splitWidth)) {
+ curSplitter = k;
+ setCursor();
+ return;
+ }
+ int ypos = y - c->y - splitWidth;
+ if (ypos >= 0)
+ emit yChanged(c->pixel2val(ypos));
+ }
+ }
+ if (curSplitter != -1) {
+ curSplitter = -1;
+ setCursor();
+ }
+ return;
+ }
+ if (rCanvasB.contains(pos)) {
+ for (iCtrlEdit i = ctrlEditList.begin(); i != ctrlEditList.end(); ++i) {
+ CtrlEdit* c = *i;
+ QRect r(rCanvasB.x(), rCanvasB.y() + c->y + splitWidth,
+ rCanvasB.width(), c->cheight());
+ if (r.contains(pos)) {
+ c->mouseMove(pos - r.topLeft());
+ break;
+ }
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// mouseRelease
+//---------------------------------------------------------
+
+void EventCanvas::mouseRelease(QMouseEvent* me)
+ {
+ if (keyDown != -1) {
+ noteOff(keyDown);
+ keyDown = -1;
+ }
+ if (dragSplitter) {
+ dragSplitter = false;
+ return;
+ }
+ QPoint pos(me->pos());
+ if (rCanvasA.contains(pos)) {
+ mouseReleaseCanvasA(me);
+ return;
+ }
+ if (rCanvasB.contains(pos)) {
+ for (iCtrlEdit i = ctrlEditList.begin(); i != ctrlEditList.end(); ++i) {
+ CtrlEdit* c = *i;
+ QRect r(rCanvasB.x(), rCanvasB.y() + c->y + splitWidth,
+ rCanvasB.width(), c->cheight());
+ if (r.contains(pos)) {
+ c->mouseRelease();
+ break;
+ }
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// setCurPart
+//---------------------------------------------------------
+
+void EventCanvas::setCurPart(Part* part)
+ {
+ curPart = part;
+
+ if (curPart->raster() != -1)
+ editor->setRaster(curPart->raster());
+ if (curPart->quant() != -1)
+ editor->setQuant(curPart->quant());
+ if (curPart->xmag() != 0.0)
+ editor->setXmag(curPart->xmag());
+ curPart->setRaster(editor->raster());
+ curPart->setQuant(editor->quant());
+ curPart->setXmag(editor->xmag());
+ setPart(*curPart, curPart->end());
+ editor->setWindowTitle(getCaption());
+ }
+
+//---------------------------------------------------------
+// getTextDrag
+//---------------------------------------------------------
+
+QMimeData* EventCanvas::getTextDrag()
+ {
+ //---------------------------------------------------
+ // generate event list from selected events
+ //---------------------------------------------------
+
+ EventList el;
+ unsigned startTick = INT_MAX;
+ for (iCItem i = items.begin(); i != items.end(); ++i) {
+ if (!i->second->isSelected())
+ continue;
+ CItem* ne = i->second;
+ Event e = ne->event;
+ if (startTick == INT_MAX)
+ startTick = e.tick();
+ el.add(e);
+ }
+ QBuffer buffer;
+ buffer.open(QIODevice::WriteOnly);
+ Xml xml(&buffer);
+ xml.header();
+
+ xml.stag("eventlist");
+ for (ciEvent e = el.begin(); e != el.end(); ++e)
+ e->second.write(xml, -startTick);
+ xml.etag("eventlist");
+
+ QByteArray data = buffer.buffer();
+ QMimeData* drag = new QMimeData;
+ drag->setData("text/x-muse-eventlist", data);
+ buffer.close();
+ return drag;
+ }
+
+//---------------------------------------------------------
+// pasteAt
+//---------------------------------------------------------
+
+void EventCanvas::pasteAt(const QString& pt, unsigned pos)
+ {
+ QDomDocument doc;
+
+ if (!doc.setContent(pt, false)) {
+ printf("MusE:pasteAt(): syntax error\n");
+ printf(">>%s<<\n", pt.toLatin1().data());
+ return;
+ }
+ for (QDomNode node = doc.documentElement(); !node.isNull(); node = node.nextSibling()) {
+ QDomElement e = node.toElement();
+ if (e.isNull())
+ continue;
+ if (e.tagName() == "eventlist") {
+ EventList el;
+ el.read(node.firstChild(), true);
+ song->startUndo();
+ for (iEvent i = el.begin(); i != el.end(); ++i) {
+ Event e = i->second;
+ e.setTick(e.tick() + pos - curPart->tick());
+ audio->msgAddEvent(e, curPart, false);
+ }
+ song->endUndo(SC_EVENT_INSERTED);
+ }
+ else
+ printf("MusE:pasteAt(): tag %s not supported\n", e.tagName().toLatin1().data());
+ }
+ }
+
+//---------------------------------------------------------
+// midiNote
+//---------------------------------------------------------
+
+void EventCanvas::midiNote(const MidiEvent& me)
+ {
+ if (me.type() != ME_NOTEON)
+ return;
+ int pitch = me.dataA();
+ int velo = me.dataB();
+
+ if (editor->midiIn() && editor->stepRec() && curPart
+ && !audio->isPlaying() && velo && pos[0].tick() >= startTick
+ && pos[0].tick() < endTick
+ && !(keyState & Qt::AltModifier)) {
+ int len = editor->quant();
+ unsigned tick = pos[0].tick(); //CDW
+ unsigned starttick = tick;
+ if (keyState & Qt::ShiftModifier)
+ tick -= editor->rasterStep(tick);
+
+ //
+ // extend len of last note?
+ //
+ EventList* events = curPart->events();
+ if (keyState & Qt::ControlModifier) {
+ for (iEvent i = events->begin(); i != events->end(); ++i) {
+ Event ev = i->second;
+ if (!ev.isNote())
+ continue;
+ if (ev.pitch() == pitch && ((ev.tick() + ev.lenTick()) == starttick)) {
+ Event e = ev.clone();
+ e.setLenTick(ev.lenTick() + editor->rasterStep(starttick));
+ audio->msgChangeEvent(ev, e, curPart);
+ tick += editor->rasterStep(tick);
+ if (tick != song->cpos()) {
+ Pos p(tick, AL::TICKS);
+ song->setPos(0, p, true, false, true);
+ }
+ return;
+ }
+ }
+ }
+
+ //
+ // if we already entered the note, delete it
+ //
+ EventRange range = events->equal_range(tick);
+ for (iEvent i = range.first; i != range.second; ++i) {
+ Event ev = i->second;
+ if (ev.isNote() && ev.pitch() == pitch) {
+ audio->msgDeleteEvent(ev, curPart);
+ if (keyState & Qt::ShiftModifier)
+ tick += editor->rasterStep(tick);
+ return;
+ }
+ }
+ Event e(Note);
+ e.setTick(tick - curPart->tick());
+ e.setPitch(pitch);
+ e.setVelo(velo);
+ e.setLenTick(len);
+ audio->msgAddEvent(e, curPart);
+ tick += editor->rasterStep(tick);
+ if (tick != song->cpos()) {
+ Pos p(tick, AL::TICKS);
+ song->setPos(0, p, true, false, true);
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// magChanged
+//---------------------------------------------------------
+
+void EventCanvas::magChanged()
+ {
+ if (part()) {
+ part()->setXmag(_xmag);
+ }
+ }
+
+//---------------------------------------------------------
+// updatePartControllerList
+//---------------------------------------------------------
+
+void EventCanvas::updatePartControllerList()
+ {
+ if (curPart == 0)
+ return;
+ CtrlCanvasList* cl = curPart->getCtrlCanvasList();
+ cl->clear();
+ for (iCtrlEdit i = ctrlEditList.begin(); i != ctrlEditList.end(); ++i) {
+ CtrlCanvas cc;
+ cc.ctrlId = (*i)->ctrlId;
+ cc.height = (*i)->height();
+ cl->push_back(cc);
+ }
+ }
+
diff --git a/muse_qt4_evolution/muse/midiedit/ecanvas.h b/muse_qt4_evolution/muse/midiedit/ecanvas.h
new file mode 100644
index 00000000..f128e5fa
--- /dev/null
+++ b/muse_qt4_evolution/muse/midiedit/ecanvas.h
@@ -0,0 +1,173 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __ECANVAS_H__
+#define __ECANVAS_H__
+
+#include "al/pos.h"
+#include "awl/tcanvas.h"
+#include "widgets/noteinfo.h"
+#include "citem.h"
+#include "ctrl/ctrledit.h"
+#include "widgets/tb1.h"
+
+class MidiTrack;
+class MidiEditor;
+class MidiEvent;
+class Part;
+class Event;
+class CtrlEdit;
+
+//---------------------------------------------------------
+// EventCanvas
+//---------------------------------------------------------
+
+class EventCanvas : public TimeCanvas {
+ Q_OBJECT
+
+ int startPitch; // on start dragging events
+ int deltaPitch;
+ int keyDown; // pressed key on piano keypad (or drum instrument list)
+ int playedPitch;
+
+ void noteOn(int pitch, int velocity, bool shift);
+ void noteOff(int pitch);
+ virtual void layout();
+ virtual void magChanged();
+
+ protected:
+ enum DragMode {
+ DRAG_OFF, DRAG_NEW,
+ DRAG_MOVE_START, DRAG_MOVE,
+ DRAG_COPY_START, DRAG_COPY,
+ DRAGX_MOVE, DRAGY_MOVE,
+ DRAGX_COPY, DRAGY_COPY,
+ DRAG_DELETE,
+ DRAG_RESIZE, DRAG_LASSO_START, DRAG_LASSO,
+ };
+
+ enum DragType {
+ MOVE_MOVE, MOVE_COPY
+ };
+
+ CtrlEditList ctrlEditList;
+ MidiEditor* editor;
+ CItemList items;
+ CItemList moving;
+ CItem* curItem;
+ Part* curPart;
+ int canvasTools;
+ int curSplitter; // -1 mouse not in splitter
+ bool dragSplitter;
+ int splitterY;
+
+ DragMode drag;
+ QRect lasso;
+ QPoint start;
+ QMenu* itemPopupMenu;
+ QMenu* canvasPopupMenu;
+
+ unsigned startTick, endTick;
+ int curVelo;
+
+ virtual void mousePress(QMouseEvent*);
+ virtual void mouseDoubleClick(QMouseEvent*);
+ virtual void mouseMove(QPoint);
+ virtual void enterB();
+ virtual void leaveB();
+ virtual void mouseRelease(QMouseEvent*);
+ void layoutPanelB(CtrlEdit* c);
+
+ void updateSelection();
+ virtual CItem* searchItem(const QPoint& p) const = 0;
+ virtual void addItem(Part*, const Event&) = 0;
+ virtual void moveItem(CItem*, DragType) = 0;
+ virtual CItem* newItem(const QPoint&, int state) = 0;
+ virtual void newItem(CItem*, bool noSnap=false) = 0;
+ virtual bool deleteItem(CItem*) = 0;
+ virtual void resizeItem(CItem*, bool noSnap=false) = 0;
+
+ virtual void startDrag(CItem*, bool) {}
+ virtual QMenu* genItemPopup(CItem*) { return 0; }
+ virtual void itemPopup(CItem*, int, const QPoint&) {}
+ virtual void itemReleased() {}
+ virtual void itemPressed(const CItem*) {}
+ virtual void itemMoved(const CItem*) {}
+
+ virtual void addController();
+
+ void endMoveItems(DragType);
+ virtual void selectItem(CItem* e, bool);
+ virtual void deselectAll();
+ QMenu* genCanvasPopup();
+ void canvasPopup(int);
+ virtual void startUndo(DragType);
+ virtual void endUndo(DragType);
+ virtual void selectLasso(bool) {}
+ void setCursor();
+ virtual void deleteItem(const QPoint&);
+ void moveItems(const QPoint& pos, int dir);
+ void mousePressCanvasA(QPoint pos);
+ void mousePressCanvasA(QMouseEvent*);
+ void mouseMoveCanvasA(QPoint pos);
+ void mouseReleaseCanvasA(QMouseEvent*);
+
+ virtual void paintControllerCanvas(QPainter&, QRect);
+ virtual void paintControllerPanel(QPainter&, QRect);
+
+ void pasteAt(const QString& pt, unsigned pos);
+ void updatePartControllerList();
+
+ private slots:
+ void removeController(QAction*);
+ void midiNote(const MidiEvent&);
+
+ public slots:
+ void setQuant(int) { update(); }
+ void songChanged(int);
+
+ signals:
+ void selectionChanged(int, Event&, Part*);
+ void enterCanvas();
+ void yChanged(int); // emitted from mouseMove in controller canvas
+
+ public:
+ EventCanvas(MidiEditor*, TimeCanvasType);
+ MidiTrack* track() const;
+ Part* part() const { return curPart; }
+ QString getCaption() const;
+ void range(AL::Pos& s, AL::Pos& e) const;
+ void selectFirst();
+ virtual void modifySelected(NoteInfo::ValType, int) {}
+ virtual void keyPress(QKeyEvent*);
+ int selectionSize() const;
+ void setCurPart(Part*);
+ QMimeData* getTextDrag();
+ CItemList* getItems() { return &items; }
+ CtrlEditList* getCtrlEditors() { return &ctrlEditList; }
+ const CtrlEditList* getCtrlEditors() const { return &ctrlEditList; }
+ void addController(int id, int h);
+ void layout1();
+ };
+
+extern void paintVLine(QPainter& p, int y1, int y2, int x);
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/midiedit/gatetime.cpp b/muse_qt4_evolution/muse/midiedit/gatetime.cpp
new file mode 100644
index 00000000..862d4aaf
--- /dev/null
+++ b/muse_qt4_evolution/muse/midiedit/gatetime.cpp
@@ -0,0 +1,105 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "gatetime.h"
+#include "song.h"
+#include "tb1.h"
+
+//---------------------------------------------------------
+// GateTime
+//---------------------------------------------------------
+
+GateTime::GateTime(QWidget*)
+ : MidiCmdDialog()
+ {
+ setWindowTitle(tr("MusE: Modify Gate Time"));
+ QWidget* gateTime = new QWidget;
+ gt.setupUi(gateTime);
+ layout->addWidget(gateTime);
+ layout->addStretch(10);
+ _rateVal = 0;
+ _offsetVal = 0;
+ gt.rate->setValue(_rateVal);
+ gt.offset->setValue(_offsetVal);
+ }
+
+//---------------------------------------------------------
+// accept
+//---------------------------------------------------------
+
+void GateTime::accept()
+ {
+ _rateVal = gt.rate->value();
+ _offsetVal = gt.offset->value();
+ MidiCmdDialog::accept();
+ }
+
+//---------------------------------------------------------
+// MidifyGateTime
+//---------------------------------------------------------
+
+ModifyGateTimeCmd::ModifyGateTimeCmd(MidiEditor* e)
+ : MidiCmd(e)
+ {
+ dialog = 0;
+ }
+
+//---------------------------------------------------------
+// guiDialog
+//---------------------------------------------------------
+
+MidiCmdDialog* ModifyGateTimeCmd::guiDialog()
+ {
+ if (dialog == 0)
+ dialog = new GateTime(0);
+ return dialog;
+ }
+
+//---------------------------------------------------------
+// process
+//---------------------------------------------------------
+
+void ModifyGateTimeCmd::process(CItemList* items)
+ {
+ int rate = dialog->rateVal();
+ int offset = dialog->offsetVal();
+
+ for (iCItem k = items->begin(); k != items->end(); ++k) {
+ CItem* item = k->second;
+ Event event = item->event;
+ if (event.type() != Note)
+ continue;
+
+ if (itemInRange(item)) {
+ unsigned len = event.lenTick();
+ len = rate ? (len * 100) / rate : 1;
+ len += offset;
+ if (len <= 1)
+ len = 1;
+
+ if (event.lenTick() != len) {
+ Event newEvent = event.clone();
+ newEvent.setLenTick(len);
+ changeEvent(event, newEvent, item->part);
+ }
+ }
+ }
+ }
+
diff --git a/muse_qt4_evolution/muse/midiedit/gatetime.h b/muse_qt4_evolution/muse/midiedit/gatetime.h
new file mode 100644
index 00000000..699b7c61
--- /dev/null
+++ b/muse_qt4_evolution/muse/midiedit/gatetime.h
@@ -0,0 +1,62 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __GATETIME_H__
+#define __GATETIME_H__
+
+#include "ui_gatetime.h"
+#include "midicmd.h"
+
+//---------------------------------------------------------
+// GateTime
+//---------------------------------------------------------
+
+class GateTime : public MidiCmdDialog {
+ Q_OBJECT
+
+ Ui::GateTimeBase gt;
+ int _rateVal;
+ int _offsetVal;
+
+ protected slots:
+ void accept();
+
+ public:
+ GateTime(QWidget* parent = 0);
+ int rateVal() const { return _rateVal; }
+ int offsetVal() const { return _offsetVal; }
+ };
+
+//---------------------------------------------------------
+// ModifyGateTimeCmd
+//---------------------------------------------------------
+
+class ModifyGateTimeCmd : public MidiCmd
+ {
+ GateTime* dialog;
+ virtual MidiCmdDialog* guiDialog();
+ virtual void process(CItemList* items);
+
+ public:
+ ModifyGateTimeCmd(MidiEditor* e);
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/midiedit/gatetime.ui b/muse_qt4_evolution/muse/midiedit/gatetime.ui
new file mode 100644
index 00000000..e1b92e7e
--- /dev/null
+++ b/muse_qt4_evolution/muse/midiedit/gatetime.ui
@@ -0,0 +1,85 @@
+<ui version="4.0" >
+ <author></author>
+ <comment></comment>
+ <exportmacro></exportmacro>
+ <class>GateTimeBase</class>
+ <widget class="QWidget" name="GateTimeBase" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>262</width>
+ <height>149</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>MusE: Modify Gate Time</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>11</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QGroupBox" name="GroupBox3" >
+ <property name="title" >
+ <string>Values</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>6</number>
+ </property>
+ <property name="spacing" >
+ <number>3</number>
+ </property>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="TextLabel3" >
+ <property name="text" >
+ <string>Rate:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="TextLabel4" >
+ <property name="text" >
+ <string>Offset:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QSpinBox" name="rate" >
+ <property name="suffix" >
+ <string>%</string>
+ </property>
+ <property name="maximum" >
+ <number>200</number>
+ </property>
+ <property name="value" >
+ <number>100</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QSpinBox" name="offset" >
+ <property name="maximum" >
+ <number>999</number>
+ </property>
+ <property name="minimum" >
+ <number>-999</number>
+ </property>
+ <property name="singleStep" >
+ <number>1</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <pixmapfunction>qPixmapFromMimeSource</pixmapfunction>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/muse_qt4_evolution/muse/midiedit/midicmd.cpp b/muse_qt4_evolution/muse/midiedit/midicmd.cpp
new file mode 100644
index 00000000..bb6b1972
--- /dev/null
+++ b/muse_qt4_evolution/muse/midiedit/midicmd.cpp
@@ -0,0 +1,135 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "midicmd.h"
+#include "song.h"
+#include "gatetime.h"
+#include "velocity.h"
+#include "audio.h"
+#include "midieditor.h"
+#include "widgets/tb1.h"
+
+//==========================================================
+// class MidiCmd is an attempt to formalize the
+// interface between midi command code and MusE.
+// Maybe this can be extended to an specialized
+// plugin interface
+//==========================================================
+
+//---------------------------------------------------------
+// MidiCmdDialog
+//---------------------------------------------------------
+
+MidiCmdDialog::MidiCmdDialog()
+ : QDialog()
+ {
+ QWidget* rangeWidget = new QWidget;
+ mc.setupUi(rangeWidget);
+ layout = new QVBoxLayout;
+ setLayout(layout);
+ layout->addWidget(rangeWidget);
+ rangeGroup = new QButtonGroup(this);
+ rangeGroup->setExclusive(true);
+ rangeGroup->addButton(mc.allEventsButton, RANGE_ALL);
+ rangeGroup->addButton(mc.selectedEventsButton, RANGE_SELECTED);
+ rangeGroup->addButton(mc.loopedEventsButton, RANGE_LOOPED);
+ rangeGroup->addButton(mc.selectedLoopedButton, RANGE_SELECTED | RANGE_LOOPED);
+ mc.allEventsButton->setChecked(true);
+ }
+
+//---------------------------------------------------------
+// setRange
+//---------------------------------------------------------
+
+void MidiCmdDialog::setRange(int id)
+ {
+ if (rangeGroup->button(id))
+ rangeGroup->button(id)->setChecked(true);
+ else
+ printf("setRange: not button %d!\n", id);
+ }
+
+//---------------------------------------------------------
+// accept
+//---------------------------------------------------------
+
+void MidiCmdDialog::accept()
+ {
+ _range = rangeGroup->checkedId();
+ QDialog::accept();
+ }
+
+//---------------------------------------------------------
+// MidiCmd
+//---------------------------------------------------------
+
+MidiCmd::MidiCmd(MidiEditor* e)
+ {
+ editor = e;
+ }
+
+//---------------------------------------------------------
+// processEvents
+//---------------------------------------------------------
+
+void MidiCmd::processEvents(CItemList* items)
+ {
+ MidiCmdDialog* dialog = guiDialog();
+ range = editor->applyTo();
+ dialog->setRange(range);
+ bool rv = dialog->exec();
+ if (!rv)
+ return;
+ range = dialog->range(); // all, selected, looped, sel+loop
+ editor->setApplyTo(range);
+
+ modified = 0;
+ song->startUndo();
+ process(items);
+ song->endUndo(modified);
+ }
+
+//---------------------------------------------------------
+// eventInRange
+//---------------------------------------------------------
+
+bool MidiCmd::itemInRange(CItem* item)
+ {
+ unsigned tick = item->event.tick();
+ bool selected = item->isSelected();
+ bool inLoop = (tick >= song->lpos()) && (tick < song->rpos());
+ return (
+ (range == 0)
+ || (range == 1 && selected)
+ || (range == 2 && inLoop)
+ || (range == 3 && selected && inLoop)
+ );
+ }
+
+//---------------------------------------------------------
+// changeEvent
+//---------------------------------------------------------
+
+void MidiCmd::changeEvent(Event oldEvent, Event newEvent, Part* part)
+ {
+ audio->msgChangeEvent(oldEvent, newEvent, part, false);
+ modified = SC_EVENT_MODIFIED;
+ }
+
diff --git a/muse_qt4_evolution/muse/midiedit/midicmd.h b/muse_qt4_evolution/muse/midiedit/midicmd.h
new file mode 100644
index 00000000..f78f9cb9
--- /dev/null
+++ b/muse_qt4_evolution/muse/midiedit/midicmd.h
@@ -0,0 +1,81 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __MIDICMD_H__
+#define __MIDICMD_H__
+
+#include "citem.h"
+#include "ui_midicmd.h"
+
+class MidiEditor;
+class MidiCmdDialog;
+
+//---------------------------------------------------------
+// MidiCmdDialog
+// GUI base class for midiCmd
+//---------------------------------------------------------
+
+class MidiCmdDialog : public QDialog
+ {
+ Q_OBJECT
+
+ QButtonGroup* rangeGroup;
+ int _range;
+ Ui::MidiCmd mc;
+
+ protected:
+ void accept();
+ QVBoxLayout* layout;
+
+ public:
+ MidiCmdDialog();
+ int range() const { return _range; }
+ void setRange(int);
+ };
+
+//---------------------------------------------------------
+// MidiCmd
+// abstract base class for midi commands
+//---------------------------------------------------------
+
+class MidiCmd {
+ int modified;
+
+ protected:
+ MidiEditor* editor;
+ int range;
+
+ // convenience classes for derived classes
+ bool itemInRange(CItem* item);
+ void changeEvent(Event oldEvent, Event newEvent, Part* part);
+
+ // virtual functions provided by derived classes
+ virtual void process(CItemList*) = 0;
+ virtual MidiCmdDialog* guiDialog() { return 0; }
+
+ public:
+ MidiCmd(MidiEditor*);
+ virtual ~MidiCmd() {}
+ void processEvents(CItemList*);
+ };
+
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/midiedit/midicmd.ui b/muse_qt4_evolution/muse/midiedit/midicmd.ui
new file mode 100644
index 00000000..e64e6ba4
--- /dev/null
+++ b/muse_qt4_evolution/muse/midiedit/midicmd.ui
@@ -0,0 +1,76 @@
+<ui version="4.0" >
+ <author></author>
+ <comment></comment>
+ <exportmacro></exportmacro>
+ <class>MidiCmd</class>
+ <widget class="QWidget" name="MidiCmd" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>387</width>
+ <height>392</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>MusE: Modify Gate Time</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>11</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QGroupBox" name="rangeGroup" >
+ <property name="title" >
+ <string>Apply To</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>6</number>
+ </property>
+ <property name="spacing" >
+ <number>3</number>
+ </property>
+ <item>
+ <widget class="QRadioButton" name="allEventsButton" >
+ <property name="text" >
+ <string>All Events</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="selectedEventsButton" >
+ <property name="text" >
+ <string>Selected Events</string>
+ </property>
+ <property name="checked" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="loopedEventsButton" >
+ <property name="text" >
+ <string>Looped Events</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="selectedLoopedButton" >
+ <property name="text" >
+ <string>Selected AND Looped</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <pixmapfunction>qPixmapFromMimeSource</pixmapfunction>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/muse_qt4_evolution/muse/midiedit/midieditor.cpp b/muse_qt4_evolution/muse/midiedit/midieditor.cpp
new file mode 100644
index 00000000..d004ef29
--- /dev/null
+++ b/muse_qt4_evolution/muse/midiedit/midieditor.cpp
@@ -0,0 +1,444 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "midieditor.h"
+#include "part.h"
+#include "song.h"
+#include "widgets/tools.h"
+#include "ecanvas.h"
+#include "icons.h"
+#include "audio.h"
+#include "shortcuts.h"
+
+//---------------------------------------------------------
+// MidiEditor
+//---------------------------------------------------------
+
+MidiEditor::MidiEditor(PartList* pl)
+ : Editor()
+ {
+ _pl = pl;
+ selPart = 0;
+ tools2 = 0;
+ info = 0;
+ tools = 0;
+ toolbar = 0;
+
+ QMenuBar* mb = menuBar();
+
+ //---------Menu-------------------------------
+ menuEdit = new QMenu(tr("&Edit"));
+ mb->addMenu(menuEdit);
+
+ menuEdit->addAction(undoAction);
+ menuEdit->addAction(redoAction);
+
+ menuEdit->addSeparator();
+ cutAction = getAction("cut", this);
+ menuEdit->addAction(cutAction);
+ copyAction = getAction("copy", this);
+ menuEdit->addAction(copyAction);
+ pasteAction = getAction("paste", this);
+ menuEdit->addAction(pasteAction);
+
+ speaker = new QAction(this);
+ speaker->setCheckable(true);
+ speaker->setIcon(QIcon(*speakerIcon));
+ speaker->setText(tr("Play Events"));
+ speaker->setToolTip(tr("Play Events"));
+
+ stepRecAction = new QAction(this);
+ stepRecAction->setIcon(QIcon(*steprecIcon));
+ stepRecAction->setText(tr("Step Record"));
+ stepRecAction->setToolTip(tr("Step Record"));
+ stepRecAction->setCheckable(true);
+
+ midiInAction = new QAction(this);
+ midiInAction->setIcon(QIcon(*midiinIcon));
+ midiInAction->setText(tr("Midi Input"));
+ midiInAction->setToolTip(tr("Midi Input"));
+ midiInAction->setCheckable(true);
+
+ followSongAction = new QAction(this);
+ followSongAction->setText("F");
+ followSongAction->setToolTip(tr("Follow Song"));
+ followSongAction->setCheckable(true);
+
+ connect(song, SIGNAL(songChanged(int)), SLOT(songChanged(int)));
+
+ QClipboard* cb = QApplication::clipboard();
+ connect(cb, SIGNAL(dataChanged()), SLOT(clipboardChanged()));
+ connect(cb, SIGNAL(selectionChanged()), SLOT(clipboardChanged()));
+ connect(menuEdit, SIGNAL(triggered(QAction*)), SLOT(midiCmd(QAction*)));
+ }
+
+//---------------------------------------------------------
+// cmd
+//---------------------------------------------------------
+
+void MidiEditor::midiCmd(QAction* a)
+ {
+ QString s(a->data().toString());
+ if (s == "cut") {
+ copy();
+ song->startUndo();
+ CItemList* items = canvas()->getItems();
+ for (iCItem i = items->begin(); i != items->end(); ++i) {
+ if (!i->second->isSelected())
+ continue;
+ CItem* e = i->second;
+ Event event = e->event;
+ audio->msgDeleteEvent(event, e->part, false);
+ }
+ song->endUndo(SC_EVENT_REMOVED);
+ }
+ else if (s == "copy")
+ copy();
+ else
+ cmd(a);
+ }
+
+//---------------------------------------------------------
+// copy
+// cut copy paste
+//---------------------------------------------------------
+
+void MidiEditor::copy()
+ {
+ QMimeData* drag = canvas()->getTextDrag();
+ if (drag)
+ QApplication::clipboard()->setMimeData(drag, QClipboard::Selection);
+ }
+
+
+//---------------------------------------------------------
+// setPos
+// snap locator positioning
+//---------------------------------------------------------
+
+void MidiEditor::setPos(int idx, const AL::Pos& pos)
+ {
+ song->setPos(idx, pos.snaped(_raster));
+ }
+
+//---------------------------------------------------------
+// genPartlist
+//---------------------------------------------------------
+
+void MidiEditor::genPartlist()
+ {
+ MidiTrackList* tl = song->midis();
+ PartList* npl = new PartList;
+ for (iPart ip = _pl->begin(); ip != _pl->end(); ++ip) {
+ Part* part = ip->second;
+ for (iMidiTrack it = tl->begin(); it != tl->end(); ++it) {
+ PartList* pl2 = (*it)->parts();
+ iPart ip2 = pl2->begin();
+ for (; ip2 != pl2->end(); ++ip2)
+ if (ip2->second == part) {
+ npl->add(part);
+ break;
+ }
+ if (ip2 != pl2->end())
+ break;
+ }
+ }
+ delete _pl;
+ _pl = npl;
+ for (iPart ip = _pl->begin(); ip != _pl->end(); ++ip) {
+ if (ip->second == selPart)
+ return;
+ }
+ if (_pl->empty())
+ return;
+ selPart = _pl->begin()->second;
+ if (canvas())
+ canvas()->setCurPart(selPart);
+ }
+
+//---------------------------------------------------------
+// MidiEditor
+//---------------------------------------------------------
+
+MidiEditor::~MidiEditor()
+ {
+ if (_pl)
+ delete _pl;
+ }
+
+//---------------------------------------------------------
+// writePartList
+//---------------------------------------------------------
+
+void MidiEditor::writePartList(Xml& xml) const
+ {
+ for (ciPart p = _pl->begin(); p != _pl->end(); ++p) {
+ Part* part = p->second;
+ Track* track = part->track();
+ int trkIdx = song->tracks()->indexOf(track);
+ int partIdx = track->parts()->index(part);
+ xml.stag("part");
+ xml.put(QString("%1:%2").arg(trkIdx).arg(partIdx));
+ xml.etag("part");
+ }
+ }
+
+//---------------------------------------------------------
+// songChanged
+//---------------------------------------------------------
+
+void MidiEditor::songChanged(int type)
+ {
+ if (type & (SC_PART_REMOVED | SC_PART_MODIFIED
+ | SC_PART_INSERTED | SC_TRACK_REMOVED)) {
+ genPartlist();
+ // close window if editor has no parts anymore
+ if (parts()->empty()) {
+ close();
+ return;
+ }
+ }
+ canvas()->songChanged(type);
+ }
+
+//---------------------------------------------------------
+// setQuant
+//---------------------------------------------------------
+
+void MidiEditor::setQuant(int val)
+ {
+ _quant = val;
+ if (toolbar)
+ toolbar->setQuant(val);
+ if (canvas() && canvas()->part())
+ canvas()->part()->setQuant(val);
+ }
+
+//---------------------------------------------------------
+// setRaster
+//---------------------------------------------------------
+
+void MidiEditor::setRaster(int val)
+ {
+ _raster = val;
+ if (toolbar)
+ toolbar->setRaster(val);
+ if (canvas()) {
+ canvas()->setRaster(val);
+ if (canvas()->part())
+ canvas()->part()->setRaster(val);
+ }
+ }
+
+//---------------------------------------------------------
+// setApplyTo
+//---------------------------------------------------------
+
+void MidiEditor::setApplyTo(int val)
+ {
+ _applyTo = val;
+ if (toolbar)
+ toolbar->setApplyTo(_applyTo);
+ }
+
+//---------------------------------------------------------
+// rasterStep
+//---------------------------------------------------------
+
+int MidiEditor::rasterStep(unsigned tick) const
+ {
+ return AL::sigmap.rasterStep(tick, raster());
+ }
+
+//---------------------------------------------------------
+// rasterVal
+//---------------------------------------------------------
+
+unsigned MidiEditor::rasterVal(unsigned v) const
+ {
+ return AL::sigmap.raster(v, raster());
+ }
+
+//---------------------------------------------------------
+// rasterVal1
+//---------------------------------------------------------
+
+unsigned MidiEditor::rasterVal1(unsigned v) const
+ {
+ return AL::sigmap.raster1(v, raster());
+ }
+
+//---------------------------------------------------------
+// rasterVal2
+//---------------------------------------------------------
+
+unsigned MidiEditor::rasterVal2(unsigned v) const
+ {
+ return AL::sigmap.raster2(v, raster());
+ }
+
+//---------------------------------------------------------
+// quantVal
+//---------------------------------------------------------
+
+int MidiEditor::quantVal(int v) const
+ {
+ int q = quant();
+ int val = ((v+q/2)/q)*q;
+ if (val == 0)
+ val = q;
+ return val;
+ }
+
+//---------------------------------------------------------
+// xmag
+//---------------------------------------------------------
+
+double MidiEditor::xmag() const
+ {
+ return tcanvas->xmag();
+ }
+
+//---------------------------------------------------------
+// setXmag
+//---------------------------------------------------------
+
+void MidiEditor::setXmag(double val)
+ {
+ if (canvas())
+ canvas()->setMag(val, tcanvas->ymag());
+ }
+
+//---------------------------------------------------------
+// tool
+//---------------------------------------------------------
+
+int MidiEditor::tool() const
+ {
+ return tcanvas->tool();
+ }
+
+//---------------------------------------------------------
+// setTool
+//---------------------------------------------------------
+
+void MidiEditor::setTool(int n)
+ {
+ tcanvas->setTool(n);
+ tools2->set(n);
+ }
+
+//---------------------------------------------------------
+// canvasPos
+//---------------------------------------------------------
+
+QPoint MidiEditor::canvasPos() const
+ {
+ return tcanvas->getWPos();
+ }
+
+//---------------------------------------------------------
+// setCanvasPos
+//---------------------------------------------------------
+
+void MidiEditor::setCanvasPos(const QPoint& p)
+ {
+ if (tcanvas)
+ tcanvas->setWPos(p);
+ }
+
+//---------------------------------------------------------
+// clipboardChanged
+//---------------------------------------------------------
+
+void MidiEditor::clipboardChanged()
+ {
+ QString stype("x-muse-eventlist");
+ QString s = QApplication::clipboard()->text(stype, QClipboard::Selection);
+ pasteAction->setEnabled(!s.isEmpty());
+ }
+
+//---------------------------------------------------------
+// selectionChanged
+//---------------------------------------------------------
+
+void MidiEditor::selectionChanged()
+ {
+ bool flag = canvas()->selectionSize() > 0;
+ cutAction->setEnabled(flag);
+ copyAction->setEnabled(flag);
+ }
+
+//---------------------------------------------------------
+// read
+//---------------------------------------------------------
+
+void MidiEditor::read(QDomNode node)
+ {
+ for (node = node.firstChild(); !node.isNull(); node = node.nextSibling()) {
+ QDomElement e = node.toElement();
+ QString tag(e.tagName());
+ if (tag == "CtrlEdit") {
+ int id = e.attribute("id","0").toInt();
+ int h = e.attribute("h","50").toInt();
+ canvas()->addController(id, h);
+ }
+ else
+ AL::readProperties(this, node);
+ }
+ canvas()->layout1();
+ }
+
+//---------------------------------------------------------
+// write
+//---------------------------------------------------------
+
+void MidiEditor::write(Xml& xml) const
+ {
+ writePartList(xml);
+ xml.stag(metaObject()->className());
+ xml.writeProperties(this);
+ const CtrlEditList* el = canvas()->getCtrlEditors();
+ for (ciCtrlEdit i = el->begin(); i != el->end(); ++i) {
+ xml.tagE(QString("CtrlEdit h=\"%1\" id=\"%2\"")
+ .arg((*i)->height()).arg((*i)->ctrl()->id()));
+ }
+ xml.etag(metaObject()->className());
+ }
+
+//---------------------------------------------------------
+// initFromPart
+//---------------------------------------------------------
+
+void MidiEditor::initFromPart()
+ {
+ Part* part = canvas()->part();
+ CtrlCanvasList* cl = part->getCtrlCanvasList();
+ if (!cl->empty()) {
+#if 0
+ for (iCtrlCanvas i = cl->begin(); i != cl->end(); ++i) {
+printf("MidiEditor::initFromPart(): add controller %d %d\n", i->ctrlId, i->height);
+ canvas()->addController(i->ctrlId, i->height);
+ }
+#endif
+ canvas()->layout1();
+ }
+ }
+
diff --git a/muse_qt4_evolution/muse/midiedit/midieditor.h b/muse_qt4_evolution/muse/midiedit/midieditor.h
new file mode 100644
index 00000000..3791e017
--- /dev/null
+++ b/muse_qt4_evolution/muse/midiedit/midieditor.h
@@ -0,0 +1,147 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __MIDIEDITOR_H__
+#define __MIDIEDITOR_H__
+
+#include "editor.h"
+
+namespace AL {
+ class Xml;
+ class Pos;
+ };
+using AL::Xml;
+
+class EditToolBar;
+class NoteInfo;
+class Toolbar1;
+class Part;
+class PartList;
+class EventCanvas;
+class ScrollScale;
+class MTScale;
+class WaveView;
+
+//---------------------------------------------------------
+// MidiEditor
+//---------------------------------------------------------
+
+class MidiEditor : public Editor {
+ Q_OBJECT
+
+ Q_PROPERTY(int raster READ raster WRITE setRaster)
+ Q_PROPERTY(int quant READ quant WRITE setQuant)
+ Q_PROPERTY(bool stepRec READ stepRec WRITE setStepRec)
+ Q_PROPERTY(bool midiIn READ midiIn WRITE setMidiIn)
+ Q_PROPERTY(bool playEvents READ playEvents WRITE setPlayEvents)
+ Q_PROPERTY(bool followSong READ followSong WRITE setFollowSong)
+ Q_PROPERTY(double xmag READ xmag WRITE setXmag)
+ Q_PROPERTY(int applyTo READ applyTo WRITE setApplyTo)
+ Q_PROPERTY(QPoint canvasPos READ canvasPos WRITE setCanvasPos)
+ Q_PROPERTY(int tool READ tool WRITE setTool)
+
+ bool _playEvents;
+
+ EventCanvas* canvas() { return (EventCanvas*)tcanvas; }
+ const EventCanvas* canvas() const { return (EventCanvas*)tcanvas; }
+ void copy();
+
+ protected:
+ int _raster;
+ int _quant;
+ int _applyTo;
+
+ PartList* _pl;
+ Part* selPart;
+
+ QMenu *menuEdit;
+ QAction* speaker;
+ QAction* stepRecAction;
+ QAction* midiInAction;
+ QAction* followSongAction;
+ QAction* cutAction;
+ QAction* copyAction;
+ QAction* pasteAction;
+
+ EditToolBar* tools2;
+ NoteInfo* info;
+ QToolBar* tools;
+ Toolbar1* toolbar;
+
+ void writePartList(Xml&) const;
+ void genPartlist();
+ void writeStatus(Xml&) const;
+ void initFromPart();
+
+ private slots:
+ void midiCmd(QAction*);
+
+ protected slots:
+ void clipboardChanged(); // enable/disable "Paste"
+ void selectionChanged(); // enable/disable "Copy" & "Paste"
+ virtual void songChanged(int); //add virtual to allow editors that do not use
+ //ecancav to use there own songChanged slot
+ //and avoid crashing, like MidiTrackerEditor
+ void setPos(int, const AL::Pos&);
+ virtual void cmd(QAction*) = 0;
+
+ public slots:
+ void setQuant(int val);
+ void setApplyTo(int val);
+ void setRaster(int val);
+
+ public:
+ MidiEditor(PartList*);
+ virtual ~MidiEditor();
+
+ void read(QDomNode);
+ void write(Xml&) const;
+ void readStatus(QDomNode);
+
+ PartList* parts() { return _pl; }
+ int rasterStep(unsigned tick) const;
+ unsigned rasterVal(unsigned v) const;
+ unsigned rasterVal1(unsigned v) const;
+ unsigned rasterVal2(unsigned v) const;
+ int quantVal(int v) const;
+ int raster() const { return _raster; }
+ int quant() const { return _quant; }
+ int applyTo() const { return _applyTo; }
+ bool playEvents() const { return speaker->isChecked(); }
+ void setPlayEvents(bool val) { speaker->setChecked(val); }
+ bool stepRec() const { return stepRecAction->isChecked(); }
+ void setStepRec(bool val) { stepRecAction->setChecked(val); }
+ bool midiIn() const { return midiInAction->isChecked(); }
+ void setMidiIn(bool val) { midiInAction->setChecked(val); }
+ bool followSong() const { return followSongAction->isChecked(); }
+ void setFollowSong(bool val) { followSongAction->setChecked(val); }
+ double xmag() const;
+ void setXmag(double val);
+ QPoint canvasPos() const;
+ void setCanvasPos(const QPoint&);
+ void setTool(int);
+ int tool() const;
+ enum {
+ CMD_CUT, CMD_COPY, CMD_PASTE
+ };
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/midiedit/miditracker.cpp b/muse_qt4_evolution/muse/midiedit/miditracker.cpp
new file mode 100644
index 00000000..e345f454
--- /dev/null
+++ b/muse_qt4_evolution/muse/midiedit/miditracker.cpp
@@ -0,0 +1,234 @@
+//=================================================================
+// miditracker
+// midi editor a la soundtracker
+// miditracker.cpp
+// (C) Copyright 2006 Nil Geisweiller (a_lin@user.sourceforge.net)
+//=================================================================
+
+#include "ecanvas.h"
+#include "miditracker.h"
+#include "trackpattern.h"
+#include "song.h"
+#include "muse.h"
+#include "part.h"
+
+#define MAX(x,y) (x>y?x:y)
+
+class TrackPattern;
+//class EventCanvas;
+
+//---------------------------------------------------------
+// MidiTrackerEditor
+//---------------------------------------------------------
+
+MidiTrackerEditor::MidiTrackerEditor(PartList* pl, bool /*init*/)
+ : MidiEditor(pl) {
+ //--------
+ //menuView
+ //--------
+ menuView = menuBar()->addMenu(tr("&View"));
+
+ //-------
+ //ToolBar
+ //-------
+ tools = addToolBar(tr("MidiTracker Tools"));
+ tools->addAction(undoAction);
+ tools->addAction(redoAction);
+ tools->addSeparator();
+
+ tools->addAction(stepRecAction);
+ stepRecAction->setChecked(INIT_SREC);
+
+ tools->addAction(midiInAction);
+ midiInAction->setChecked(INIT_MIDIIN);
+
+ tools->addAction(speaker);
+ speaker->setChecked(INIT_SPEAKER);
+
+ tools->addAction(followSongAction);
+ followSongAction->setChecked(INIT_FOLLOW);
+ setFollow(INIT_FOLLOW);
+
+ //panic button
+ QToolBar* panicToolbar = addToolBar(tr("Panic"));
+ panicToolbar->addAction(panicAction);
+
+ //Transport Bar
+ QToolBar* transport = addToolBar(tr("Transport"));
+ muse->setupTransportToolbar(transport);
+
+ //frame containing the different matrices of time and notes and FX
+ //QFrame* matricesFrame = new QFrame
+
+ //second bar
+ addToolBarBreak();
+ //row per bar
+ QToolBar* rowfeatures = addToolBar(tr("row features"));
+
+ QLabel* quantLabel = new QLabel(tr("Quantize"));
+ quantLabel->setIndent(5);
+ rowfeatures->addWidget(quantLabel);
+ _quantCombo = new QuantCombo(rowfeatures);
+ rowfeatures->addWidget(_quantCombo);
+
+ //QLabel* rpmLabel = new QLabel(tr("Row per bar"), rowfeatures);
+ //rpmLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
+ //rpmLabel->setIndent(3);
+ //rowfeatures->addWidget(rpmLabel);
+ //_rpmSpinBox = new QSpinBox(rowfeatures);
+ //_rpmSpinBox->setRange(1, 256);
+ //_rpmSpinBox->setFixedHeight(24);
+ //rowfeatures->addWidget(_rpmSpinBox);
+
+ //init row per bar
+ setQuant(96); //corresponds to 16 quant
+ updateQuant();
+
+ //number of visible rows
+ //rowfeatures->addSeparator();
+ /*QLabel* nvrLabel = new QLabel(tr("Number of visible rows"), rowfeatures);
+ nvrLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
+ nvrLabel->setIndent(3);
+ rowfeatures->addWidget(nvrLabel);
+ _nvrSpinBox = new QSpinBox(rowfeatures);
+ _nvrSpinBox->setRange(1, 256);
+ _nvrSpinBox->setFixedHeight(24);
+ rowfeatures->addWidget(_nvrSpinBox);*/
+ //init number of visible row
+ /*setNumVisibleRows(20);
+ updateNumVisibleRows();*/
+
+ //evaluate fisrtTick and lastTick
+ unsigned firstTick = _pl->begin()->second->tick();
+ unsigned lastTick = 0;
+ for(ciPart p = _pl->begin(); p != _pl->end(); ++p) {
+ Part* part = p->second;
+ lastTick = MAX(lastTick, part->endTick());
+ }
+
+ //-------------
+ //timing matrix
+ //-------------
+ _timingPattern =
+ new TimingPattern(this, "Timing", firstTick, lastTick, _quant);
+ int nbrRow = _timingPattern->getAbsoluteNbrRow();
+
+ //---------------
+ //tracks matrices
+ //---------------
+ for(ciPart p = _pl->begin(); p != _pl->end(); ++p) {
+ Part* part = p->second;
+ Track* track = part->track();
+ if(track->isMidiTrack()) {
+ bool trackNotFound = true;
+ for(unsigned int i = 0; i < _trackPatterns.size(); i++)
+ if(_trackPatterns[i]->getTrack()==track) trackNotFound = false;
+ if(trackNotFound) {
+ TrackPattern* tp;
+ tp = new TrackPattern(this, track->name(), firstTick, lastTick,
+ _quant, pl, (MidiTrack*) track, nbrRow);
+ _trackPatterns.push_back(tp);
+ }
+ }
+ }
+
+ //signals from TimingPattern and TrackPattern
+ connect(_timingPattern, SIGNAL(moveCurrentRow(unsigned)),
+ this, SLOT(updateMoveCurrentRow(unsigned)));
+ for(unsigned i = 0; i < _trackPatterns.size(); i++) {
+ connect(_trackPatterns[i], SIGNAL(moveCurrentRow(unsigned)),
+ this, SLOT(updateMoveCurrentRow(unsigned)));
+ }
+
+ /*
+ addToolBarBreak();
+ toolbar = new Toolbar1(initRaster, initQuant);
+ addToolBar(toolbar);
+
+ addToolBarBreak();
+ info = new NoteInfo(this);
+ addToolBar(info);
+
+ setCentralWidget(tcanvas);
+ tcanvas->setCornerWidget(new QSizeGrip(tcanvas));
+
+ connect(song, SIGNAL(posChanged(int,const AL::Pos&,bool)), canvas(),
+ SLOT(setLocatorPos(int,const AL::Pos&,bool)));
+ connect(canvas(), SIGNAL(posChanged(int,const AL::Pos&)),
+ SLOT(setPos(int,const AL::Pos&)));
+
+ connect(canvas(), SIGNAL(toolChanged(int)), tools2, SLOT(set(int)));
+ connect(tools2, SIGNAL(toolChanged(int)), canvas(), SLOT(setTool(int)));
+
+ connect(info, SIGNAL(valueChanged(NoteInfo::ValType, int)),
+ SLOT(noteinfoChanged(NoteInfo::ValType, int)));
+
+ connect(canvas(), SIGNAL(selectionChanged(int, Event&, Part*)), this,
+ SLOT(setSelection(int, Event&, Part*)));
+
+ info->setEnabled(false);
+
+ setWindowTitle(canvas()->getCaption());
+ int s1, e;
+ canvas()->range(&s1, &e);
+ e += AL::sigmap.ticksMeasure(e); // show one more measure
+ canvas()->setTimeRange(s1, e);*/
+
+}
+
+//---------------------------------------------------------
+// setQuant
+//---------------------------------------------------------
+void MidiTrackerEditor::setQuant(int q) {
+ _quant = q;
+}
+
+//---------------------------------------------------------
+// getQuant
+//---------------------------------------------------------
+int MidiTrackerEditor::getQuant() {
+ return _quant;
+}
+
+//---------------------------------------------------------
+// updateQuant
+//---------------------------------------------------------
+void MidiTrackerEditor::updateQuant() {
+ _quantCombo->blockSignals(true);
+ _quantCombo->setQuant(_quant);
+ _quantCombo->blockSignals(false);
+}
+
+//---------------------------------------------------------
+// setFollow
+//---------------------------------------------------------
+void MidiTrackerEditor::setFollow(bool f) {
+ _follow = f;
+}
+
+//---------------------------------------------------------
+// songChanged
+//---------------------------------------------------------
+void MidiTrackerEditor::songChanged(int i) {
+ emit signalSongChanged(i);
+}
+
+//---------------------------------------------------------
+// cmd
+// pulldown menu commands
+//---------------------------------------------------------
+
+void MidiTrackerEditor::cmd(QAction* /*a*/) {
+ //int cmd = a->data().toInt();
+ //canvas()->cmd(cmd, _quantStrength, _quantLimit, _quantLen);
+}
+
+//void MidiTrackerEditor::resizeEvent(QResizeEvent *event) {
+// for(int i = 0; i < _trackPatterns.size(); i++)
+// _trackPatterns[i]->fillTrackPat();
+// _timingPattern->fillTimmingPat();
+//}
+
+void MidiTrackerEditor::updateMoveCurrentRow(unsigned index) {
+ emit signalMoveCurrentRow(index);
+}
diff --git a/muse_qt4_evolution/muse/midiedit/miditracker.h b/muse_qt4_evolution/muse/midiedit/miditracker.h
new file mode 100644
index 00000000..5e6d706a
--- /dev/null
+++ b/muse_qt4_evolution/muse/midiedit/miditracker.h
@@ -0,0 +1,76 @@
+//=================================================================
+// miditracker
+// midi editor a la soundtracker
+// miditracker.h
+// (C) Copyright 2006 Nil Geisweiller (a_lin@user.sourceforge.net)
+//=================================================================
+
+#ifndef __MTEDITOR_H__
+#define __MTEDITOR_H__
+
+#include "midieditor.h"
+#include "trackpattern.h"
+#include "quantcombo.h"
+#include <vector>
+
+
+class QuantCombo;
+
+namespace AL {
+ class Xml;
+ };
+using AL::Xml;
+
+//---------------------------------------------------------
+// MidiTrackerEditor
+//---------------------------------------------------------
+
+class MidiTrackerEditor : public MidiEditor {
+ Q_OBJECT
+
+ private:
+ int _quant;
+ QuantCombo* _quantCombo;
+ //int _numVisibleRows;
+ //QSpinBox* _nvrSpinBox;
+
+ QMenu* menuView;
+ bool _follow;
+ void setFollow(bool);
+
+ std::vector<TrackPattern*> _trackPatterns;
+ TimingPattern* _timingPattern;
+
+ private slots:
+ void updateMoveCurrentRow(unsigned);
+ virtual void cmd(QAction*);
+
+ protected slots:
+ virtual void songChanged(int);
+
+ public:
+ MidiTrackerEditor(PartList*, bool);
+ ~MidiTrackerEditor() {}
+
+ void setQuant(int rpm);
+ int getQuant();
+ void updateQuant(); //update the gui
+
+ void setNumVisibleRows(int nvr);
+ int getNumVisibleRows();
+ void updateNumVisibleRows(); //update the gui
+
+ static const bool INIT_FOLLOW = false;
+ static const bool INIT_SPEAKER = true;
+ static const bool INIT_SREC = false;
+ static const bool INIT_MIDIIN = false;
+
+ protected:
+ //void resizeEvent(QResizeEvent *event);
+
+ signals:
+ void signalMoveCurrentRow(unsigned);
+ void signalSongChanged(int);
+};
+
+#endif
diff --git a/muse_qt4_evolution/muse/midiedit/pianoroll.cpp b/muse_qt4_evolution/muse/midiedit/pianoroll.cpp
new file mode 100644
index 00000000..c9be06e9
--- /dev/null
+++ b/muse_qt4_evolution/muse/midiedit/pianoroll.cpp
@@ -0,0 +1,526 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "pianoroll.h"
+#include "song.h"
+#include "icons.h"
+#include "cmd.h"
+#include "muse.h"
+#include "widgets/tools.h"
+#include "quantconfig.h"
+#include "shortcuts.h"
+#include "audio.h"
+#include "part.h"
+
+static int pianorollTools = PointerTool | PencilTool | RubberTool | DrawTool;
+int PianoRoll::initWidth = PianoRoll::INIT_WIDTH;
+int PianoRoll::initHeight = PianoRoll::INIT_HEIGHT;
+int PianoRoll::initRaster = PianoRoll::INIT_RASTER;
+int PianoRoll::initQuant = PianoRoll::INIT_QUANT;
+int PianoRoll::initColorMode = PianoRoll::INIT_COLOR_MODE;
+bool PianoRoll::initFollow = PianoRoll::INIT_FOLLOW;
+bool PianoRoll::initSpeaker = PianoRoll::INIT_SPEAKER;
+bool PianoRoll::initMidiin = PianoRoll::INIT_MIDIIN;
+double PianoRoll::initXmag = 0.08; // PianoRoll::INIT_XMAG; (compiler problem?)
+int PianoRoll::initApplyTo = PianoRoll::INIT_APPLY_TO;
+int PianoRoll::initQuantStrength = PianoRoll::INIT_QUANT_STRENGTH;
+int PianoRoll::initQuantLimit = PianoRoll::INIT_QUANT_LIMIT;
+bool PianoRoll::initQuantLen = PianoRoll::INIT_QUANT_LEN;
+
+//---------------------------------------------------------
+// PianoRoll
+//---------------------------------------------------------
+
+PianoRoll::PianoRoll(PartList* pl, bool init)
+ : MidiEditor(pl)
+ {
+ _applyTo = initApplyTo;
+ _colorMode = initColorMode;
+ _quantStrength = initQuantStrength;
+ _quantLimit = initQuantLimit;
+ _quantLen = initQuantLen;
+
+ deltaMode = false;
+ quantConfig = 0;
+
+ tcanvas = new PianoCanvas(this);
+ QMenuBar* mb = menuBar();
+
+ menu_ids[CMD_EVENT_COLOR] = getAction("change_event_color", this);
+ menu_ids[CMD_CONFIG_QUANT] = getAction("config_quant", this);
+
+ //---------Menu----------------------------------
+ menuEdit->addSeparator();
+
+ QAction* a = getAction("delete", this);
+ menuEdit->addAction(a);
+
+ menuEdit->addSeparator();
+
+ menuSelect = menuEdit->addMenu(QIcon(*selectIcon),tr("&Select"));
+
+ menuSelect->addAction(getAction("sel_all", this));
+ menuSelect->addAction(getAction("sel_none", this));
+ menuSelect->addAction(getAction("sel_inv", this));
+ menuSelect->addAction(getAction("sel_ins_loc", this));
+ menuSelect->addAction(getAction("sel_out_loc", this));
+
+ menuConfig = mb->addMenu(tr("&Config"));
+ eventColor = menuConfig->addMenu(tr("event color"));
+ menu_ids[CMD_EVENT_COLOR] = eventColor->menuAction();
+
+ colorModeAction[0] = eventColor->addAction(tr("blue"));
+ colorModeAction[0]->setData(0);
+ colorModeAction[0]->setCheckable(true);
+ colorModeAction[1] = eventColor->addAction(tr("pitch colors"));
+ colorModeAction[1]->setData(1);
+ colorModeAction[1]->setCheckable(true);
+ colorModeAction[2] = eventColor->addAction(tr("velocity colors"));
+ colorModeAction[2]->setData(2);
+ colorModeAction[2]->setCheckable(true);
+ connect(eventColor, SIGNAL(triggered(QAction*)), SLOT(setEventColorMode(QAction*)));
+
+ menuFunctions = mb->addMenu(tr("&Functions"));
+
+ menuFunctions->addAction(getAction("midi_over_quant", this));
+ menuFunctions->addAction(getAction("midi_quant_noteon", this));
+ menuFunctions->addAction(getAction("midi_quant_noteoff", this));
+ menuFunctions->addAction(getAction("midi_quant_iterative", this));
+
+ menuFunctions->addSeparator();
+
+ menu_ids[CMD_CONFIG_QUANT] = menuFunctions->addAction(tr("Config Quant..."));
+ connect(menu_ids[CMD_CONFIG_QUANT], SIGNAL(triggered()), this, SLOT(configQuant()));
+
+ menuFunctions->addSeparator();
+
+ menuFunctions->addAction(getAction("midi_mod_gate_time", this));
+ menuFunctions->addAction(getAction("midi_mod_velo", this));
+
+#if 0 // TODO
+ menuFunctions->addAction(getAction("midi_crescendo", this));
+ menuFunctions->addAction(getAction("midi_transpose", this));
+ menuFunctions->addAction(getAction("midi_thin_out", this));
+ menuFunctions->addAction(getAction("midi_erase_event", this));
+ menuFunctions->addAction(getAction("midi_note_shift", this));
+ menuFunctions->addAction(getAction("midi_move_clock", this));
+ menuFunctions->addAction(getAction("midi_copy_measure", this));
+ menuFunctions->addAction(getAction("midi_erase_measure", this));
+ menuFunctions->addAction(getAction("midi_delete_measure", this));
+ menuFunctions->addAction(getAction("midi_create_measure", this));
+#endif
+
+ connect(menuSelect, SIGNAL(triggered(QAction*)), SLOT(cmd(QAction*)));
+ connect(menuFunctions, SIGNAL(triggered(QAction*)), SLOT(cmd(QAction*)));
+
+ //---------ToolBar----------------------------------
+ tools = addToolBar(tr("Pianoroll Tools"));
+ tools->addAction(undoAction);
+ tools->addAction(redoAction);
+ tools->addSeparator();
+
+ tools->addAction(stepRecAction);
+ stepRecAction->setChecked(INIT_SREC);
+
+ tools->addAction(midiInAction);
+ midiInAction->setChecked(INIT_MIDIIN);
+
+ tools->addAction(speaker);
+ speaker->setChecked(INIT_SPEAKER);
+
+ tools->addAction(followSongAction);
+ followSongAction->setChecked(INIT_FOLLOW);
+ tcanvas->setFollow(INIT_FOLLOW);
+
+ tools2 = new EditToolBar(this, pianorollTools);
+ addToolBar(tools2);
+
+ QToolBar* panicToolbar = addToolBar(tr("Panic"));
+ panicToolbar->addAction(panicAction);
+
+ //-------------------------------------------------------------
+ // Transport Bar
+
+ QToolBar* transport = addToolBar(tr("Transport"));
+ muse->setupTransportToolbar(transport);
+
+ addToolBarBreak();
+ toolbar = new Toolbar1(initRaster, initQuant);
+ addToolBar(toolbar);
+
+ addToolBarBreak();
+ info = new NoteInfo(this);
+ addToolBar(info);
+
+ setCentralWidget(tcanvas);
+ tcanvas->setCornerWidget(new QSizeGrip(tcanvas));
+
+ connect(song, SIGNAL(posChanged(int,const AL::Pos&,bool)), canvas(), SLOT(setLocatorPos(int,const AL::Pos&,bool)));
+ connect(canvas(), SIGNAL(posChanged(int,const AL::Pos&)), SLOT(setPos(int,const AL::Pos&)));
+
+ connect(canvas(), SIGNAL(toolChanged(int)), tools2, SLOT(set(int)));
+ connect(tools2, SIGNAL(toolChanged(int)), canvas(), SLOT(setTool(int)));
+
+ connect(info, SIGNAL(valueChanged(NoteInfo::ValType, int)), SLOT(noteinfoChanged(NoteInfo::ValType, int)));
+
+ connect(canvas(), SIGNAL(selectionChanged(int, Event&, Part*)), this,
+ SLOT(setSelection(int, Event&, Part*)));
+
+ info->setEnabled(false);
+
+ setWindowTitle(canvas()->getCaption());
+ Pos p1(0, AL::TICKS), p2(0, AL::TICKS);
+ canvas()->range(p1, p2);
+ p2 += AL::sigmap.ticksMeasure(p2.tick()); // show one more measure
+ canvas()->setTimeRange(p1, p2);
+
+ // connect to toolbar
+ connect(canvas(), SIGNAL(pitchChanged(int)), toolbar, SLOT(setPitch(int)));
+ connect(canvas(), SIGNAL(yChanged(int)), toolbar, SLOT(setInt(int)));
+ connect(canvas(), SIGNAL(cursorPos(const AL::Pos&,bool)), toolbar, SLOT(setTime(const AL::Pos&,bool)));
+ connect(toolbar, SIGNAL(quantChanged(int)), SLOT(setQuant(int)));
+ connect(toolbar, SIGNAL(rasterChanged(int)),SLOT(setRaster(int)));
+ connect(toolbar, SIGNAL(toChanged(int)), SLOT(setApplyTo(int)));
+ connect(toolbar, SIGNAL(soloChanged(bool)), SLOT(soloChanged(bool)));
+
+ setEventColorMode(_colorMode);
+
+ clipboardChanged(); // enable/disable "Paste"
+ selectionChanged(); // enable/disable "Copy" & "Paste"
+
+ //
+ // install misc shortcuts
+ //
+ QShortcut* sc = new QShortcut(Qt::Key_Escape, this);
+ sc->setContext(Qt::WindowShortcut);
+ connect(sc, SIGNAL(activated()), SLOT(close()));
+
+ QSignalMapper* cmdMap = new QSignalMapper(this);
+ static const char* actions[] = {
+ "curpos_increase", "curpos_decrease",
+ "midi_insert_at_loc",
+ "midi_quant_1", "midi_quant_2", "midi_quant_3", "midi_quant_4",
+ "midi_quant_5", "midi_quant_6", "midi_quant_7",
+ "midi_quant_punct", "midi_quant_punct2", "midi_quant_triol",
+ };
+ for (unsigned i = 0; i < sizeof(actions)/sizeof(*actions); ++i) {
+ a = getAction(actions[i], this);
+ addAction(a);
+ cmdMap->setMapping(a, a);
+ connect(a, SIGNAL(triggered()), cmdMap, SLOT(map()));
+ }
+ connect(cmdMap, SIGNAL(mapped(QObject*)), SLOT(pianoCmd(QObject*)));
+
+ connect(song, SIGNAL(songChanged(int)), canvas(), SLOT(songChanged(int)));
+ connect(followSongAction, SIGNAL(toggled(bool)), canvas(), SLOT(setFollow(bool)));
+ canvas()->selectFirst();
+
+ Part* part = canvas()->part();
+ setRaster(part->raster() != -1 ? part->raster() : initRaster);
+ setQuant(part->quant() != -1 ? part->quant() : initQuant);
+ setXmag(part->xmag() != -1.0 ? part->xmag() : initXmag);
+
+ if (init)
+ initFromPart();
+ else {
+ resize(initWidth, initHeight);
+ }
+ }
+
+//---------------------------------------------------------
+// cmd
+// pulldown menu commands
+//---------------------------------------------------------
+
+void PianoRoll::cmd(QAction* a)
+ {
+ canvas()->cmd(a, _quantStrength, _quantLimit, _quantLen);
+ }
+
+//---------------------------------------------------------
+// setSelection
+// update Info Line
+//---------------------------------------------------------
+
+void PianoRoll::setSelection(int tick, Event& e, Part* p)
+ {
+ int selections = canvas()->selectionSize();
+
+ selEvent = e;
+ selPart = p;
+
+ if (selections > 1) {
+ info->setEnabled(true);
+ info->setDeltaMode(true);
+ if (!deltaMode) {
+ deltaMode = true;
+ info->setValues(0, 0, 0, 0, 0);
+ tickOffset = 0;
+ lenOffset = 0;
+ pitchOffset = 0;
+ veloOnOffset = 0;
+ veloOffOffset = 0;
+ }
+ }
+ else if (selections == 1) {
+ deltaMode = false;
+ info->setEnabled(true);
+ info->setDeltaMode(false);
+ info->setValues(tick,
+ selEvent.lenTick(),
+ selEvent.pitch(),
+ selEvent.velo(),
+ selEvent.veloOff());
+ }
+ else {
+ deltaMode = false;
+ info->setEnabled(false);
+ }
+ selectionChanged();
+ }
+
+//---------------------------------------------------------
+// edit currently selected Event
+//---------------------------------------------------------
+
+void PianoRoll::noteinfoChanged(NoteInfo::ValType type, int val)
+ {
+ int selections = canvas()->selectionSize();
+
+ if (selections == 0) {
+ printf("noteinfoChanged while nothing selected\n");
+ }
+ else if (selections == 1) {
+ Event event = selEvent.clone();
+ switch(type) {
+ case NoteInfo::VAL_TIME:
+ event.setTick(val - selPart->tick());
+ break;
+ case NoteInfo::VAL_LEN:
+ event.setLenTick(val);
+ break;
+ case NoteInfo::VAL_VELON:
+ event.setVelo(val);
+ break;
+ case NoteInfo::VAL_VELOFF:
+ event.setVeloOff(val);
+ break;
+ case NoteInfo::VAL_PITCH:
+ event.setPitch(val);
+ break;
+ }
+ audio->msgChangeEvent(selEvent, event, selPart);
+ }
+ else {
+ // multiple events are selected; treat noteinfo values
+ // as offsets to event values
+
+ int delta = 0;
+ switch (type) {
+ case NoteInfo::VAL_TIME:
+ delta = val - tickOffset;
+ tickOffset = val;
+ break;
+ case NoteInfo::VAL_LEN:
+ delta = val - lenOffset;
+ lenOffset = val;
+ break;
+ case NoteInfo::VAL_VELON:
+ delta = val - veloOnOffset;
+ veloOnOffset = val;
+ break;
+ case NoteInfo::VAL_VELOFF:
+ delta = val - veloOffOffset;
+ veloOffOffset = val;
+ break;
+ case NoteInfo::VAL_PITCH:
+ delta = val - pitchOffset;
+ pitchOffset = val;
+ break;
+ }
+ if (delta)
+ canvas()->modifySelected(type, delta);
+ }
+ }
+
+//---------------------------------------------------------
+// soloChanged
+// signal from solo button
+//---------------------------------------------------------
+
+void PianoRoll::soloChanged(bool flag)
+ {
+ song->setSolo(canvas()->track(), flag);
+ }
+
+//---------------------------------------------------------
+// pianoCmd
+//---------------------------------------------------------
+
+void PianoRoll::pianoCmd(QObject* object)
+ {
+ QAction* a = (QAction*)object;
+ QString cmd(a->data().toString());
+
+ static int rasterTable[] = {
+ //-9----8- 7 6 5 4 3(1/4) 2 1
+ 4, 8, 16, 32, 64, 128, 256, 512, 1024, // triple
+ 6, 12, 24, 48, 96, 192, 384, 768, 1536,
+ 9, 18, 36, 72, 144, 288, 576, 1152, 2304 // dot
+ };
+
+ int index;
+ int n = sizeof(rasterTable)/sizeof(*rasterTable);
+ for (index = 0; index < n; ++index)
+ if (rasterTable[index] == raster())
+ break;
+ if (index == n) {
+ index = 0;
+ // raster 1 is not in table
+ }
+ int off = (index / 9) * 9;
+ index = index % 9;
+
+ int val = 0;
+
+ PianoCanvas* pc = canvas();
+
+ if (cmd == "curpos_increase")
+ canvas()->pianoCmd(MCMD_LEFT);
+ else if (cmd == "curpos_decrease")
+ canvas()->pianoCmd(MCMD_RIGHT);
+ else if (cmd == "midi_insert_at_loc") {
+ pc->pianoCmd(MCMD_INSERT);
+ return;
+ }
+ else if (cmd == "midi_quant_1")
+ val = rasterTable[8 + off];
+ else if (cmd == "midi_quant_2")
+ val = rasterTable[7 + off];
+ else if (cmd == "midi_quant_3")
+ val = rasterTable[6 + off];
+ else if (cmd == "midi_quant_4")
+ val = rasterTable[5 + off];
+ else if (cmd == "midi_quant_5")
+ val = rasterTable[4 + off];
+ else if (cmd == "midi_quant_6")
+ val = rasterTable[3 + off];
+ else if (cmd == "midi_quant_7")
+ val = rasterTable[2 + off];
+ else if (cmd == "midi_quant_triol")
+ val = rasterTable[index + ((off == 0) ? 9 : 0)];
+ else if (cmd == "change_event_color") {
+ _colorMode = (_colorMode + 1) % 3;
+ setEventColorMode(_colorMode);
+ return;
+ }
+ else if (cmd == "midi_quant_punct")
+ val = rasterTable[index + ((off == 18) ? 9 : 18)];
+ else if (cmd == "midi_quant_punct2") {
+ if ((off == 18) && (index > 2)) {
+ val = rasterTable[index + 9 - 1];
+ }
+ else if ((off == 9) && (index < 8)) {
+ val = rasterTable[index + 18 + 1];
+ }
+ else
+ return;
+ }
+ else
+ printf("unknown cmd <%s>\n", cmd.toLatin1().data());
+ setQuant(val);
+ setRaster(val);
+ toolbar->setQuant(quant());
+ toolbar->setRaster(raster());
+ }
+
+//---------------------------------------------------------
+// configQuant
+//---------------------------------------------------------
+
+void PianoRoll::configQuant()
+ {
+ QuantConfig quantConfig(_quantStrength, _quantLimit, _quantLen, this);
+ if (!quantConfig.exec())
+ return;
+ _quantStrength = quantConfig.quantStrength();
+ _quantLimit = quantConfig.quantLimit();
+ _quantLen = quantConfig.doQuantLen();
+ }
+
+//---------------------------------------------------------
+// setEventColorMode
+//---------------------------------------------------------
+
+void PianoRoll::setEventColorMode(QAction* a)
+ {
+ setEventColorMode(a->data().toInt());
+ }
+
+void PianoRoll::setEventColorMode(int mode)
+ {
+ _colorMode = mode;
+ for (int i = 0; i < 3; ++i)
+ colorModeAction[i]->setChecked(mode == i);
+ canvas()->setColorMode(mode);
+ }
+
+//---------------------------------------------------------
+// readConfiguration
+// read static init values
+//---------------------------------------------------------
+
+void PianoRoll::readConfiguration(QDomNode node)
+ {
+ for (node = node.firstChild(); !node.isNull(); node = node.nextSibling()) {
+ QDomElement e = node.toElement();
+ QString tag(e.tagName());
+ int i = e.text().toInt();
+ if (tag == "width")
+ PianoRoll::initWidth = i;
+ else if (tag == "height")
+ PianoRoll::initHeight = i;
+ else if (tag == "raster")
+ PianoRoll::initRaster = i;
+ else if (tag == "quant")
+ PianoRoll::initQuant = i;
+ else
+ printf("MusE:PianoRoll: unknown tag %s\n", tag.toLatin1().data());
+ }
+ }
+
+//---------------------------------------------------------
+// writeConfiguration
+// write static init values
+//---------------------------------------------------------
+
+void PianoRoll::writeConfiguration(Xml& xml)
+ {
+ xml.stag("PianoRoll");
+ if (PianoRoll::initWidth != PianoRoll::INIT_WIDTH)
+ xml.tag("width", PianoRoll::initWidth);
+ if (PianoRoll::initHeight != PianoRoll::INIT_HEIGHT)
+ xml.tag("height", PianoRoll::initHeight);
+ if (PianoRoll::initRaster != PianoRoll::INIT_RASTER)
+ xml.tag("raster", PianoRoll::initRaster);
+ if (PianoRoll::initQuant != PianoRoll::INIT_QUANT)
+ xml.tag("quant", PianoRoll::initQuant);
+ xml.etag("PianoRoll");
+ }
diff --git a/muse_qt4_evolution/muse/midiedit/pianoroll.h b/muse_qt4_evolution/muse/midiedit/pianoroll.h
new file mode 100644
index 00000000..e510408c
--- /dev/null
+++ b/muse_qt4_evolution/muse/midiedit/pianoroll.h
@@ -0,0 +1,126 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __PIANOROLL_H__
+#define __PIANOROLL_H__
+
+#include "midieditor.h"
+#include "prcanvas.h"
+
+namespace AL {
+ class Xml;
+ };
+using AL::Xml;
+
+class PianoCanvas;
+class PartList;
+class QuantConfig;
+class Part;
+class TimeCanvas;
+
+//---------------------------------------------------------
+// PianoRoll
+//---------------------------------------------------------
+
+class PianoRoll : public MidiEditor {
+ Q_OBJECT
+
+ Q_PROPERTY(int colorMode READ colorMode WRITE setColorMode)
+ Q_PROPERTY(int quantStrength READ quantStrength WRITE setQuantStrength)
+ Q_PROPERTY(int quantLimit READ quantLimit WRITE setQuantLimit)
+ Q_PROPERTY(bool quantLen READ quantLen WRITE setQuantLen)
+
+ int _quantStrength, _quantLimit;
+ bool _quantLen;
+ int _colorMode;
+
+ Event selEvent;
+
+ enum { CMD_EVENT_COLOR, CMD_CONFIG_QUANT, CMD_LAST };
+
+ QAction* menu_ids[CMD_LAST];
+ QMenu *menuFunctions, *menuSelect, *menuConfig;
+
+ int tickOffset;
+ int lenOffset;
+ int pitchOffset;
+ int veloOnOffset;
+ int veloOffOffset;
+ bool deltaMode;
+
+ QAction* colorModeAction[3];
+ QMenu* eventColor;
+ QuantConfig* quantConfig;
+
+ QWidget* genToolbar(QWidget* parent);
+ void setEventColorMode(int);
+ PianoCanvas* canvas() { return (PianoCanvas*)tcanvas; }
+ const PianoCanvas* canvas() const { return (PianoCanvas*)tcanvas; }
+
+ private slots:
+ void setSelection(int, Event&, Part*);
+ void noteinfoChanged(NoteInfo::ValType, int);
+ void soloChanged(bool flag);
+ void configQuant();
+
+ virtual void cmd(QAction*);
+ void setEventColorMode(QAction*);
+ void pianoCmd(QObject*);
+
+ public:
+ PianoRoll(PartList*, bool);
+ ~PianoRoll() {}
+
+ int colorMode() const { return _colorMode; }
+ void setColorMode(int val) { _colorMode = val; }
+ int quantStrength() const { return _quantStrength; }
+ int quantLimit() const { return _quantLimit; }
+ bool quantLen() const { return _quantLen; }
+ void setQuantStrength(int val) { _quantStrength = val; }
+ void setQuantLimit(int val) { _quantLimit = val; }
+ void setQuantLen(bool val) { _quantLen = val; }
+
+ static void readConfiguration(QDomNode);
+ static void writeConfiguration(Xml&);
+ static int initRaster, initQuant, initWidth, initHeight;
+ static bool initFollow, initSpeaker, initMidiin;
+ static int initColorMode, initApplyTo;
+ static double initXmag;
+ static int initQuantStrength, initQuantLimit;
+ static bool initQuantLen;
+
+ static const int INIT_WIDTH = 650;
+ static const int INIT_HEIGHT = 450;
+ static const int INIT_RASTER = 384 / 2;
+ static const int INIT_QUANT = 384 / 2;
+ static const bool INIT_FOLLOW = false;
+ static const bool INIT_SPEAKER = true;
+ static const bool INIT_MIDIIN = false;
+ static const bool INIT_SREC = false;
+ static const bool INIT_COLOR_MODE = 0;
+ static const double INIT_XMAG = 0.08;
+ static const int INIT_APPLY_TO = 0;
+ static const int INIT_QUANT_STRENGTH = 100;
+ static const int INIT_QUANT_LIMIT = 0;
+ static const int INIT_QUANT_LEN = false;
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/midiedit/prcanvas.cpp b/muse_qt4_evolution/muse/midiedit/prcanvas.cpp
new file mode 100644
index 00000000..f6890b02
--- /dev/null
+++ b/muse_qt4_evolution/muse/midiedit/prcanvas.cpp
@@ -0,0 +1,773 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "midieditor.h"
+#include "prcanvas.h"
+#include "cmd.h"
+#include "gatetime.h"
+#include "velocity.h"
+#include "song.h"
+#include "audio.h"
+#include "part.h"
+
+#include "velocity.h"
+#include "gatetime.h"
+
+//---------------------------------------------------------
+// PianoCanvas
+//---------------------------------------------------------
+
+PianoCanvas::PianoCanvas(MidiEditor* pr)
+ : EventCanvas(pr, TIME_CANVAS_PIANOROLL)
+ {
+ verticalScrollBar()->setSingleStep(keyHeight/2);
+ playedPitch = -1;
+ colorMode = 0;
+ canvasTools = PointerTool | PencilTool | RubberTool | DrawTool;
+
+ // register midi commands
+ cmdModifyGateTime = new ModifyGateTimeCmd(pr);
+ cmdModifyVelocity = new ModifyVelocityCmd(pr);
+
+ songChanged(SC_TRACK_INSERTED);
+ }
+
+//---------------------------------------------------------
+// addItem
+//---------------------------------------------------------
+
+void PianoCanvas::addItem(Part* part, const Event& event)
+ {
+ CItem* item = new CItem(event, part);
+ int y = pitch2y(event.pitch()) + keyHeight/4 + (int)(wpos.y()/_ymag);
+ item->pos = event.pos() + *part;
+ unsigned time = item->pos.time(timeType());
+ item->bbox = QRect(time, y, event.lenTick(), keyHeight/2);
+ items.add(item);
+ }
+
+//---------------------------------------------------------
+// timeTypeChanged
+//---------------------------------------------------------
+
+void PianoCanvas::timeTypeChanged()
+ {
+ //
+ // recalculate bounding boxes
+ //
+ for (iCItem i = items.begin(); i != items.end(); ++i) {
+ CItem* item = i->second;
+ unsigned t1 = item->event.pos().time(timeType());
+ unsigned t2 = item->event.end().time(timeType());
+ item->bbox.setX(t1 + (item->part)->time(timeType()));
+ item->bbox.setWidth(t2 - t1);
+ }
+ }
+
+//---------------------------------------------------------
+// paint
+//---------------------------------------------------------
+
+void PianoCanvas::paint(QPainter& p, QRect cr)
+ {
+ static QColor color1[12] = {
+ QColor(0xff, 0x3d, 0x39),
+ QColor(0x39, 0xff, 0x39),
+ QColor(0x39, 0x3d, 0xff),
+ QColor(0xff, 0xff, 0x39),
+ QColor(0xff, 0x3d, 0xff),
+ QColor(0x39, 0xff, 0xff),
+ QColor(0xff, 0x7e, 0x7a),
+ QColor(0x7a, 0x7e, 0xff),
+ QColor(0x7a, 0xff, 0x7a),
+ QColor(0xff, 0x7e, 0xbf),
+ QColor(0x7a, 0xbf, 0xff),
+ QColor(0xff, 0xbf, 0x7a)
+ };
+
+ QPoint off(MAP_OFFSET - wpos.x(), -wpos.y());
+ p.translate(off);
+ cr.translate(-off);
+
+ int time1 = lrint(cr.x() / _xmag);
+ int w = lrint(cr.width() / _xmag);
+ cr.setRect(
+ time1,
+ lrint(cr.y() / _ymag),
+ w,
+ lrint(cr.height() / _ymag)
+ );
+ p.scale(_xmag, _ymag);
+
+ int time2 = time1 + w;
+
+ //---------------------------------------------------
+ // draw Canvas Items
+ //---------------------------------------------------
+
+ p.setPen(QPen(Qt::black, 0.0));
+
+ for (iCItem i = items.begin(); i != items.end(); ++i) {
+ CItem* item = i->second;
+ QRect r(item->bbox);
+ if (r.x() >= time2)
+ break;
+ if (!cr.intersects(r))
+ continue;
+ Event event(item->event);
+
+ QColor color;
+ if (item->part != curPart)
+ p.setBrush(Qt::lightGray);
+ else {
+ if (item->isMoving) {
+ p.setBrush(Qt::gray);
+ p.drawRect(r);
+ p.setBrush(Qt::NoBrush);
+ int x = item->moving.tick();
+ int y = item->my + item->bbox.height()/2;
+ int w = item->bbox.width();
+ int h = item->bbox.height();
+ p.drawRect(x, y, w, h);
+ }
+ else if (item->isSelected()) {
+ p.setBrush(Qt::black);
+ }
+ else {
+ if (colorMode == 1)
+ color = color1[event.pitch() % 12];
+ else if (colorMode == 2) {
+ int velo = event.velo();
+ if (velo < 64)
+ color.setRgb(velo*4, 0, 0xff);
+ else
+ color.setRgb(0xff, 0, (127-velo) * 4);
+ }
+ else
+ color.setRgb(0, 0, 255);
+ p.setBrush(color);
+ }
+ }
+ p.drawRect(r);
+ }
+
+ //---------------------------------------------------
+ // draw lasso
+ //---------------------------------------------------
+
+ p.resetMatrix();
+ p.translate(rCanvasA.topLeft());
+
+ if (drag == DRAG_LASSO) {
+ p.setPen(Qt::blue);
+ p.setBrush(Qt::NoBrush);
+ p.drawRect(lasso);
+ QColor fillColor(Qt::blue);
+ fillColor.setAlpha(40);
+ QBrush fillBrush(fillColor);
+ p.fillRect(lasso,fillBrush);
+ }
+ }
+
+//---------------------------------------------------------
+// viewMouseDoubleClickEvent
+//---------------------------------------------------------
+
+void PianoCanvas::viewMouseDoubleClickEvent(QMouseEvent* event)
+ {
+ if ((_tool != PointerTool) && (event->button() != Qt::LeftButton)) {
+// mousePress(event);
+ return;
+ }
+ }
+
+//---------------------------------------------------------
+// moveItem
+// called after moving an object
+//---------------------------------------------------------
+
+void PianoCanvas::moveItem(CItem* item, DragType dtype)
+ {
+ Part* part = item->part;
+ Event event = item->event;
+ int npitch = y2pitch((int)((item->my - (int)(wpos.y()/_ymag)
+ + item->bbox.height())*_ymag));
+ if ((curItem==item) //remove this if want to have all selection playing
+ && event.pitch() != npitch && editor->playEvents()) {
+ // release note:
+ MidiEvent ev1(0, 0, 0x90, playedPitch, 0);
+ track()->playMidiEvent(&ev1);
+ //remove below because the note is never cut off
+ //MidiEvent ev2(0, 0, 0x90, npitch + track()->transposition(), event.velo());
+ //track()->playMidiEvent(&ev2);
+ }
+
+ Event newEvent = event.clone();
+ newEvent.setPitch(npitch);
+ newEvent.setPos(item->moving - *part);
+
+ if (dtype == MOVE_COPY)
+ audio->msgAddEvent(newEvent, part, false);
+ else
+ audio->msgChangeEvent(event, newEvent, part, false);
+ }
+
+//---------------------------------------------------------
+// newItem(p, state)
+//---------------------------------------------------------
+
+CItem* PianoCanvas::newItem(const QPoint& p, int)
+ {
+ Pos opos(pix2pos(p.x()));
+ Pos pos(opos);
+ pos.downSnap(raster());
+
+ if (pos < partPos1 || pos >= partPos2)
+ return 0;
+
+ int pitch = y2pitch(p.y());
+
+ Event e(Note);
+ e.setPitch(pitch);
+ e.setVelo(curVelo);
+ e.setPos(pos - *curPart);
+
+ CItem* i = new CItem(e, curPart);
+ int l = timeType() == AL::TICKS ? e.lenTick() : e.lenFrame();
+ int x = pos.time(timeType());
+ int y = pitch2y(pitch) + keyHeight/4 + (int)(wpos.y() / _ymag);
+ i->bbox = QRect(x, y, l, keyHeight/2);
+
+ return i;
+ }
+
+void PianoCanvas::newItem(CItem* item, bool noSnap)
+ {
+ Event event = item->event;
+ Pos p1(item->bbox.x(), timeType());
+ Pos p2(item->bbox.x() + item->bbox.width(), timeType());
+ int tickLen;
+
+ if (noSnap)
+ tickLen = p2.tick() - p1.tick();
+ else {
+ p1.downSnap(raster());
+ tickLen = editor->quantVal(p2.tick() - p1.tick());
+ }
+
+ Part* part = item->part;
+ event.setPos(p1 - *part);
+ event.setLenTick(tickLen);
+ audio->msgAddEvent(event, part);
+ }
+
+//---------------------------------------------------------
+// resizeItem
+//---------------------------------------------------------
+
+void PianoCanvas::resizeItem(CItem* item, bool noSnap)
+ {
+ Event event = item->event;
+ Event newEvent = event.clone();
+ int len;
+ if (noSnap)
+ len = item->bbox.width();
+ else
+ len = editor->quantVal(item->bbox.width());
+ newEvent.setLenTick(len);
+ audio->msgChangeEvent(event, newEvent, item->part);
+ }
+
+//---------------------------------------------------------
+// deleteItem
+//---------------------------------------------------------
+
+bool PianoCanvas::deleteItem(CItem* item)
+ {
+ if (item->part == curPart) {
+ Event ev = item->event;
+ audio->msgDeleteEvent(ev, curPart);
+ return true;
+ }
+ return false;
+ }
+
+//---------------------------------------------------------
+// pianoCmd
+//---------------------------------------------------------
+
+void PianoCanvas::pianoCmd(int cmd)
+ {
+ switch(cmd) {
+ case MCMD_LEFT:
+ {
+ int frames = pos[0].tick() - editor->rasterStep(pos[0].tick());
+ if (frames < 0)
+ frames = 0;
+ Pos p(frames, AL::TICKS);
+ song->setPos(0, p, true, true, true); //CDW
+ }
+ break;
+ case MCMD_RIGHT:
+ {
+ Pos p(pos[0].tick() + editor->rasterStep(pos[0].tick()), AL::TICKS);
+ //if (p > part->tick())
+ // p = part->tick();
+ song->setPos(0, p, true, true, true); //CDW
+ }
+ break;
+ case MCMD_INSERT:
+ {
+ if (pos[0].tick() < startTick || pos[0].tick() >= endTick)
+ break;
+ Part* part = curPart;
+
+ if (part == 0)
+ break;
+ song->startUndo();
+ EventList* el = part->events();
+
+ std::list <Event> elist;
+ for (iEvent e = el->lower_bound(pos[0].tick() - part->tick()); e != el->end(); ++e)
+ elist.push_back((Event)e->second);
+ for (std::list<Event>::iterator i = elist.begin(); i != elist.end(); ++i) {
+ Event event = *i;
+ Event newEvent = event.clone();
+ newEvent.setTick(event.tick() + editor->raster());
+ audio->msgChangeEvent(event, newEvent, part, false);
+ }
+ song->endUndo(SC_EVENT_MODIFIED);
+ Pos p(editor->rasterVal(pos[0].tick() + editor->rasterStep(pos[0].tick())), AL::TICKS);
+ song->setPos(0, p, true, false, true);
+ }
+ return;
+ case MCMD_DELETE:
+ if (pos[0].tick() < startTick || pos[0].tick() >= endTick)
+ break;
+ {
+ Part* part = curPart;
+ if (part == 0)
+ break;
+ song->startUndo();
+ EventList* el = part->events();
+
+ std::list<Event> elist;
+ for (iEvent e = el->lower_bound(pos[0].tick()); e != el->end(); ++e)
+ elist.push_back((Event)e->second);
+ for (std::list<Event>::iterator i = elist.begin(); i != elist.end(); ++i) {
+ Event event = *i;
+ Event newEvent = event.clone();
+ newEvent.setTick(event.tick() - editor->raster() - part->tick());
+ audio->msgChangeEvent(event, newEvent, part, false);
+ }
+ song->endUndo(SC_EVENT_MODIFIED);
+ Pos p(editor->rasterVal(pos[0].tick() - editor->rasterStep(pos[0].tick())), AL::TICKS);
+ song->setPos(0, p, true, false, true);
+ }
+ break;
+ }
+ }
+
+//---------------------------------------------------------
+// cmd
+// pulldown menu commands
+//---------------------------------------------------------
+
+void PianoCanvas::cmd(QAction* a, int quantStrength, int quantLimit, bool quantLen)
+ {
+ QString cmd(a->data().toString());
+
+ if (cmd == "paste")
+ paste();
+ else if (cmd == "delete") {
+ if (selectionSize()) {
+ song->startUndo();
+ for (iCItem i = items.begin(); i != items.end(); ++i) {
+ if (!i->second->isSelected())
+ continue;
+ Event ev = i->second->event;
+ audio->msgDeleteEvent(ev, i->second->part, false);
+ }
+ song->endUndo(SC_EVENT_REMOVED);
+ }
+ return;
+ }
+ if (cmd == "midi_over_quant")
+ quantize(100, 1, quantLen);
+ else if (cmd == "midi_quant_noteon")
+ quantize(50, 1, false);
+ else if (cmd == "midi_quant_noteoff")
+ quantize(50, 1, true);
+ else if (cmd == "midi_quant_iterative")
+ quantize(quantStrength, quantLimit, quantLen);
+ else if (cmd == "sel_all") {
+ for (iCItem k = items.begin(); k != items.end(); ++k) {
+ if (!k->second->isSelected())
+ selectItem(k->second, true);
+ }
+ }
+ else if (cmd == "sel_none")
+ deselectAll();
+ else if (cmd == "sel_inv") {
+ for (iCItem k = items.begin(); k != items.end(); ++k)
+ selectItem(k->second, !k->second->isSelected());
+ }
+ else if (cmd == "sel_ins_loc") {
+ for (iCItem k = items.begin(); k != items.end(); ++k) {
+ CItem* item = k->second;
+ Event event = item->event;
+ unsigned tick = event.tick();
+ if (tick < song->lpos() || tick >= song->rpos())
+ selectItem(k->second, false);
+ else
+ selectItem(k->second, true);
+ }
+ }
+ else if (cmd == "sel_out_loc") {
+ for (iCItem k = items.begin(); k != items.end(); ++k) {
+ CItem* item = k->second;
+ Event event = item->event;
+ unsigned tick = event.tick();
+ if (tick < song->lpos() || tick >= song->rpos())
+ selectItem(k->second, true);
+ else
+ selectItem(k->second, false);
+ }
+ }
+ else if (cmd == "midi_mod_gate_time")
+ cmdModifyGateTime->processEvents(&items);
+ else if (cmd == "midi_mod_velo")
+ cmdModifyVelocity->processEvents(&items);
+ updateSelection();
+ widget()->update();
+ }
+
+//---------------------------------------------------------
+// quantize
+//---------------------------------------------------------
+
+void PianoCanvas::quantize(int strength, int limit, bool quantLen)
+ {
+ song->startUndo();
+ for (iCItem k = items.begin(); k != items.end(); ++k) {
+ CItem* item = k->second;
+ Event event = item->event;
+ Part* part = item->part;
+ if (event.type() != Note)
+ continue;
+
+ if ((editor->applyTo() & CMD_RANGE_SELECTED) && !k->second->isSelected())
+ continue;
+
+ unsigned tick = event.tick() + part->tick();
+
+ if ((editor->applyTo() & CMD_RANGE_LOOP)
+ && ((tick < song->lpos() || tick >= song->rpos())))
+ continue;
+
+ unsigned len = event.lenTick();
+ int tick2 = tick + len;
+
+ // quant start position
+ int diff = editor->rasterVal(tick) - tick;
+ if (abs(diff) > limit)
+ tick += ((diff * strength) / 100);
+
+ // quant len
+ diff = editor->rasterVal(tick2) - tick2;
+ if (quantLen && (abs(diff) > limit))
+ len += ((diff * strength) / 100);
+
+ // something changed?
+ if (((event.tick() + part->tick()) != tick) || (event.lenTick() != len)) {
+ Event newEvent = event.clone();
+ newEvent.setTick(tick - part->tick());
+ newEvent.setLenTick(len);
+ audio->msgChangeEvent(event, newEvent, part, false);
+ }
+ }
+ song->endUndo(SC_EVENT_MODIFIED);
+ }
+
+//---------------------------------------------------------
+// paste
+// paste events
+//---------------------------------------------------------
+
+void PianoCanvas::paste()
+ {
+ QString stype("x-muse-eventlist");
+ QString s = QApplication::clipboard()->text(stype, QClipboard::Selection);
+ pasteAt(s, song->cpos());
+ }
+
+//---------------------------------------------------------
+// startDrag
+//---------------------------------------------------------
+
+void PianoCanvas::startDrag(CItem* /*item*/, bool /*copymode*/)
+ {
+printf("PianoCanvas: startDrag\n");
+ QMimeData* drag = getTextDrag();
+ if (drag) {
+ QApplication::clipboard()->setMimeData(drag);
+#if 0
+ if (copymode)
+ drag->dragCopy();
+ else
+ drag->dragMove();
+#endif
+ }
+ }
+
+//---------------------------------------------------------
+// dragEnterEvent
+//---------------------------------------------------------
+
+void PianoCanvas::dragEnterEvent(QDragEnterEvent*)
+ {
+printf("PianoCanvas: dragEnterEvent\n");
+//TD event->accept(Q3TextDrag::canDecode(event));
+ }
+
+//---------------------------------------------------------
+// dragMoveEvent
+//---------------------------------------------------------
+
+void PianoCanvas::dragMoveEvent(QDragMoveEvent*)
+ {
+ printf("drag move %p\n", this);
+ }
+
+//---------------------------------------------------------
+// dragLeaveEvent
+//---------------------------------------------------------
+
+void PianoCanvas::dragLeaveEvent(QDragLeaveEvent*)
+ {
+ printf("drag leave\n");
+ }
+
+//---------------------------------------------------------
+// dropEvent
+//---------------------------------------------------------
+
+void PianoCanvas::viewDropEvent(QDropEvent*)
+ {
+printf("PianoCanvas: viewDropEvent\n");
+#if 0 //TD
+ QString text;
+ if (event->source() == this) {
+ printf("local DROP\n");
+ return;
+ }
+ if (Q3TextDrag::decode(event, text)) {
+ int x = editor->rasterVal(event->pos().x());
+ if (x < 0)
+ x = 0;
+ pasteAt(text, x);
+ }
+ else {
+ printf("cannot decode drop\n");
+ }
+#endif
+ }
+
+
+//---------------------------------------------------------
+// itemPressed
+//---------------------------------------------------------
+
+void PianoCanvas::itemPressed(const CItem* item)
+ {
+ if (!editor->playEvents())
+ return;
+ Event event = item->event;
+ playedPitch = event.pitch() + track()->transposition();
+ //int velo = event.velo();
+
+ // play note:
+ //I comment the following code because a note
+ //is already played in EventCanvas::mousePressCanvasA(QMouseEvent* me)
+ /*MidiEvent e(0, 0, 0x90, playedPitch, velo);
+ track()->playMidiEvent(&e);*/
+ }
+
+//---------------------------------------------------------
+// itemReleased
+//---------------------------------------------------------
+
+void PianoCanvas::itemReleased()
+ {
+ if (!editor->playEvents())
+ return;
+
+ // release note:
+ MidiEvent ev(0, 0, 0x90, playedPitch, 0);
+ track()->playMidiEvent(&ev);
+ playedPitch = -1;
+ }
+
+//---------------------------------------------------------
+// itemMoved
+//---------------------------------------------------------
+
+void PianoCanvas::itemMoved(const CItem* item)
+ {
+ int npitch = y2pitch((int)((item->my - (int)(wpos.y()/_ymag)
+ + item->bbox.height())*_ymag));
+ npitch += track()->transposition();
+ if ((curItem==item) //remove this if want to have all selection playing
+ && (playedPitch != -1) && (playedPitch != npitch)
+ && editor->playEvents()) {
+ Event event = item->event;
+ // release note:
+ MidiEvent ev1(0, 0, 0x90, playedPitch, 0);
+ track()->playMidiEvent(&ev1);
+ // play note:
+ MidiEvent e2(0, 0, 0x90, npitch, event.velo());
+ track()->playMidiEvent(&e2);
+ playedPitch = npitch;
+ }
+ }
+
+//---------------------------------------------------------
+// modifySelected
+//---------------------------------------------------------
+
+void PianoCanvas::modifySelected(NoteInfo::ValType type, int delta)
+ {
+ audio->msgIdle(true);
+ song->startUndo();
+ for (iCItem i = items.begin(); i != items.end(); ++i) {
+ if (!(i->second->isSelected()))
+ continue;
+ CItem* e = i->second;
+ Event event = e->event;
+ if (event.type() != Note)
+ continue;
+
+ Part* part = e->part;
+ Event newEvent = event.clone();
+
+ switch (type) {
+ case NoteInfo::VAL_TIME:
+ {
+ int newTime = event.tick() + delta;
+ if (newTime < 0)
+ newTime = 0;
+ newEvent.setTick(newTime);
+ }
+ break;
+ case NoteInfo::VAL_LEN:
+ {
+ int len = event.lenTick() + delta;
+ if (len < 1)
+ len = 1;
+ newEvent.setLenTick(len);
+ }
+ break;
+ case NoteInfo::VAL_VELON:
+ {
+ int velo = event.velo() + delta;
+ if (velo > 127)
+ velo = 127;
+ else if (velo < 0)
+ velo = 0;
+ newEvent.setVelo(velo);
+ }
+ break;
+ case NoteInfo::VAL_VELOFF:
+ {
+ int velo = event.veloOff() + delta;
+ if (velo > 127)
+ velo = 127;
+ else if (velo < 0)
+ velo = 0;
+ newEvent.setVeloOff(velo);
+ }
+ break;
+ case NoteInfo::VAL_PITCH:
+ {
+ int pitch = event.pitch() + delta;
+ if (pitch > 127)
+ pitch = 127;
+ else if (pitch < 0)
+ pitch = 0;
+ newEvent.setPitch(pitch);
+ }
+ break;
+ }
+ song->changeEvent(event, newEvent, part);
+ song->undoOp(UndoOp::ModifyEvent, newEvent, event, part);
+ }
+ song->endUndo(SC_EVENT_MODIFIED);
+ audio->msgIdle(false);
+ }
+
+//---------------------------------------------------------
+// setColorMode
+//---------------------------------------------------------
+
+void PianoCanvas::setColorMode(int mode)
+ {
+ colorMode = mode;
+ widget()->update();
+ }
+
+//---------------------------------------------------------
+// searchItem
+//---------------------------------------------------------
+
+CItem* PianoCanvas::searchItem(const QPoint& pt) const
+ {
+ QPoint p(
+ lrint((pt.x() - MAP_OFFSET + wpos.x()) / _xmag),
+ lrint((pt.y() + wpos.y()) / _ymag)
+ );
+ return items.find(p);
+ }
+
+//---------------------------------------------------------
+// selectLasso
+//---------------------------------------------------------
+
+void PianoCanvas::selectLasso(bool toggle)
+ {
+ QRect r(
+ lrint((lasso.x() + wpos.x()) / _xmag),
+ lrint((lasso.y() + wpos.y()) / _ymag),
+ lrint(lasso.width() / _xmag),
+ lrint(lasso.height() / _ymag)
+ );
+
+ int n = 0;
+ for (iCItem i = items.begin(); i != items.end(); ++i) {
+ if (i->second->intersects(r)) {
+ selectItem(i->second, !(toggle && i->second->isSelected()));
+ ++n;
+ }
+ }
+ if (n) {
+ updateSelection();
+ widget()->update();
+ }
+ }
+
diff --git a/muse_qt4_evolution/muse/midiedit/prcanvas.h b/muse_qt4_evolution/muse/midiedit/prcanvas.h
new file mode 100644
index 00000000..7f92e95e
--- /dev/null
+++ b/muse_qt4_evolution/muse/midiedit/prcanvas.h
@@ -0,0 +1,75 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __PRCANVAS_H__
+#define __PRCANVAS_H__
+
+#include "ecanvas.h"
+
+class CItem;
+class MidiCmd;
+
+//---------------------------------------------------------
+// PianoCanvas
+//---------------------------------------------------------
+
+class PianoCanvas : public EventCanvas {
+ Q_OBJECT
+
+ int colorMode;
+ int playedPitch;
+
+ MidiCmd* cmdModifyGateTime;
+ MidiCmd* cmdModifyVelocity;
+
+ virtual void paint(QPainter&, QRect);
+ virtual CItem* searchItem(const QPoint& p) const;
+ virtual void addItem(Part* part, const Event& event);
+ virtual void viewMouseDoubleClickEvent(QMouseEvent*);
+ virtual void moveItem(CItem*, DragType);
+ virtual CItem* newItem(const QPoint&, int);
+ virtual void resizeItem(CItem*, bool noSnap);
+ virtual void newItem(CItem*, bool noSnap);
+ virtual bool deleteItem(CItem*);
+ virtual void startDrag(CItem* item, bool copymode);
+ virtual void dragEnterEvent(QDragEnterEvent* event);
+ virtual void dragMoveEvent(QDragMoveEvent*);
+ virtual void dragLeaveEvent(QDragLeaveEvent*);
+ virtual void viewDropEvent(QDropEvent* event);
+ virtual void selectLasso(bool toggle);
+ virtual void timeTypeChanged();
+
+ void quantize(int, int, bool);
+ void paste();
+ virtual void itemPressed(const CItem*);
+ virtual void itemReleased();
+ virtual void itemMoved(const CItem*);
+
+ public slots:
+ void pianoCmd(int);
+
+ public:
+ PianoCanvas(MidiEditor*);
+ void cmd(QAction*, int, int, bool);
+ void setColorMode(int mode);
+ virtual void modifySelected(NoteInfo::ValType type, int delta);
+ };
+#endif
+
diff --git a/muse_qt4_evolution/muse/midiedit/quantconfig.cpp b/muse_qt4_evolution/muse/midiedit/quantconfig.cpp
new file mode 100644
index 00000000..229b8875
--- /dev/null
+++ b/muse_qt4_evolution/muse/midiedit/quantconfig.cpp
@@ -0,0 +1,68 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "quantconfig.h"
+
+const char* wtStrengthTxt = QT_TR_NOOP("sets amount of quantization:\n"
+ "0 - no quantization\n"
+ "100 - full quantization");
+const char* wtQLimitTxt = QT_TR_NOOP("don't quantize notes above this tick limit");
+const char* wtQLenTxt = QT_TR_NOOP("quantize also note len as default");
+
+//---------------------------------------------------------
+// QuantConfig
+//---------------------------------------------------------
+
+QuantConfig::QuantConfig(int s, int l, bool lenFlag, QWidget* parent)
+ : QDialog(parent)
+ {
+ setupUi(this);
+ strength->setValue(s);
+ dontQuantize->setValue(l);
+ quantLen->setChecked(lenFlag);
+ }
+
+//---------------------------------------------------------
+// quantStrength
+//---------------------------------------------------------
+
+int QuantConfig::quantStrength() const
+ {
+ return strength->value();
+ }
+
+//---------------------------------------------------------
+// quantLimit
+//---------------------------------------------------------
+
+int QuantConfig::quantLimit() const
+ {
+ return dontQuantize->value();
+ }
+
+//---------------------------------------------------------
+// doQuantLen
+//---------------------------------------------------------
+
+bool QuantConfig::doQuantLen() const
+ {
+ return quantLen->isChecked();
+ }
+
diff --git a/muse_qt4_evolution/muse/midiedit/quantconfig.h b/muse_qt4_evolution/muse/midiedit/quantconfig.h
new file mode 100644
index 00000000..08e75cb2
--- /dev/null
+++ b/muse_qt4_evolution/muse/midiedit/quantconfig.h
@@ -0,0 +1,42 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __QCONFIG_H__
+#define __QCONFIG_H__
+
+#include "ui_quantconfig.h"
+
+//---------------------------------------------------------
+// QuantConfig
+//---------------------------------------------------------
+
+class QuantConfig : public QDialog, public Ui::QuantConfigBase {
+ Q_OBJECT
+
+ public:
+ QuantConfig(int, int, bool, QWidget* parent = 0);
+ int quantStrength() const;
+ int quantLimit() const;
+ bool doQuantLen() const;
+ };
+
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/midiedit/quantconfig.ui b/muse_qt4_evolution/muse/midiedit/quantconfig.ui
new file mode 100644
index 00000000..1da9f790
--- /dev/null
+++ b/muse_qt4_evolution/muse/midiedit/quantconfig.ui
@@ -0,0 +1,151 @@
+<ui version="4.0" >
+ <author></author>
+ <comment></comment>
+ <exportmacro></exportmacro>
+ <class>QuantConfigBase</class>
+ <widget class="QDialog" name="QuantConfigBase" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>333</width>
+ <height>193</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>MusE: Configure Quantize</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="1" column="1" >
+ <widget class="QSpinBox" name="dontQuantize" >
+ <property name="maximum" >
+ <number>500</number>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0" colspan="2" >
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>131</width>
+ <height>31</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="okButton" >
+ <property name="text" >
+ <string>OK</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="cancelButton" >
+ <property name="text" >
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Strength:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QSpinBox" name="strength" >
+ <property name="suffix" >
+ <string>%</string>
+ </property>
+ <property name="maximum" >
+ <number>100</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_2" >
+ <property name="text" >
+ <string>Don't Quantize:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" colspan="2" >
+ <widget class="QCheckBox" name="quantLen" >
+ <property name="text" >
+ <string>Quant Len</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <pixmapfunction></pixmapfunction>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>okButton</sender>
+ <signal>clicked()</signal>
+ <receiver>QuantConfigBase</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>278</x>
+ <y>253</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>96</x>
+ <y>254</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>cancelButton</sender>
+ <signal>clicked()</signal>
+ <receiver>QuantConfigBase</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>369</x>
+ <y>253</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>179</x>
+ <y>282</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/muse_qt4_evolution/muse/midiedit/trackpattern.cpp b/muse_qt4_evolution/muse/midiedit/trackpattern.cpp
new file mode 100644
index 00000000..d50fffd0
--- /dev/null
+++ b/muse_qt4_evolution/muse/midiedit/trackpattern.cpp
@@ -0,0 +1,627 @@
+#include "trackpattern.h"
+#include "event.h"
+#include "al/sig.h"
+
+class EventList;
+
+#define MAX(x,y) (x>y?x:y)
+
+#define EMPTYCHAR "-"
+#define NONREADCHAR "*"
+#define SPACECHAR "-"
+#define PLUSCHAR "+"
+#define STOPCHAR "="
+#define SEPCHAR " "
+//#define FONT "Console"
+#define FONT "Monospace"
+//#define FONT "MiscFixed"
+#define FONT_HEIGHT 14
+#define OFFSET_HEIGHT 3
+#define OFFSET_Y 3
+
+//----------------------------------------------------------
+// EventPat
+// has to be derived, can be note or control
+//----------------------------------------------------------
+EventPat::EventPat(bool e, bool r) {_isEmpty = e; _isReadable = r;}
+EventPat::EventPat() {EventPat(true, true);}
+EventPat::~EventPat() {}
+
+void EventPat::setEmpty(bool e) {_isEmpty = e;}
+bool EventPat::getEmpty() {return _isEmpty;}
+void EventPat::setReadable(bool r) {_isReadable = r;}
+bool EventPat::getReadable() {return _isReadable;}
+
+//----------------------------------------------------------
+// VoiceEventPat
+//----------------------------------------------------------
+VoiceEventPat::VoiceEventPat(int n, int v):EventPat(false, true) {
+ _noteNum = n;
+ _velocity = v;
+}
+
+VoiceEventPat::VoiceEventPat(bool e, bool r):EventPat(e, r) {}
+
+VoiceEventPat::VoiceEventPat():EventPat(true, true) {}
+
+VoiceEventPat::~VoiceEventPat() {}
+
+
+void VoiceEventPat::setNoteNum(int n) { _noteNum = n; }
+
+int VoiceEventPat::getNoteNum() { return _noteNum; }
+
+void VoiceEventPat::setVelocity(int n) { _velocity = n; }
+
+int VoiceEventPat::getVelocity() { return _velocity; }
+
+QString VoiceEventPat::str() {
+ if(_isEmpty) {
+ return QString(EMPTYCHAR EMPTYCHAR EMPTYCHAR EMPTYCHAR)
+ + QString(SEPCHAR) + QString(EMPTYCHAR EMPTYCHAR EMPTYCHAR);
+ }
+ else if(_isReadable) {
+ if(_velocity==0) {
+ return QString(STOPCHAR STOPCHAR STOPCHAR STOPCHAR)
+ + QString(SEPCHAR) + QString(EMPTYCHAR EMPTYCHAR EMPTYCHAR);
+ }
+ else {
+ int octave = _noteNum/12 - 2;
+ int note = _noteNum%12;
+ QString sNote;
+ switch(note) {
+ case 0: sNote = QString("C") + QString(SPACECHAR);
+ break;
+ case 1: sNote = QString("C#");
+ break;
+ case 2: sNote = QString("D") + QString(SPACECHAR);
+ break;
+ case 3: sNote = QString("D#");
+ break;
+ case 4: sNote = QString("E") + QString(SPACECHAR);
+ break;
+ case 5: sNote = QString("F") + QString(SPACECHAR);
+ break;
+ case 6: sNote = QString("F#");
+ break;
+ case 7: sNote = QString("G") + QString(SPACECHAR);
+ break;
+ case 8: sNote = QString("G#");
+ break;
+ case 9: sNote = QString("A") + QString(SPACECHAR);
+ break;
+ case 10: sNote = QString("A#");
+ break;
+ case 11: sNote = QString("F") + QString(SPACECHAR);
+ break;
+ default:
+ printf("VoiceEventPat::str() Error : case note not treated\n");
+ break;
+ }
+ QString sOctave;
+ sOctave.setNum(octave);
+ if(octave>=0) {
+ sOctave = QString(PLUSCHAR) + sOctave;
+ }
+ QString sVel;
+ sVel.setNum(_velocity);
+ if(_velocity<10) {
+ sVel = QString("00") + sVel;
+ }
+ else if(_velocity<100) {
+ sVel = QString("0") + sVel;
+ }
+ return sNote + sOctave + QString(SEPCHAR) + sVel;
+ }
+ }
+ else {
+ return QString(NONREADCHAR NONREADCHAR NONREADCHAR NONREADCHAR)
+ + QString(SEPCHAR) + QString(NONREADCHAR NONREADCHAR NONREADCHAR);
+ }
+}
+
+//----------------------------------------------------------
+// CtrlEventPat
+//----------------------------------------------------------
+CtrlEventPat::CtrlEventPat(int c, int v):EventPat(false, true) {
+ _ctrlNum = c;
+ _value = v;
+}
+
+CtrlEventPat::CtrlEventPat():EventPat(true, true) {}
+
+CtrlEventPat::~CtrlEventPat() {}
+
+
+void CtrlEventPat::setCtrlNum(int n) { _ctrlNum = n; }
+
+int CtrlEventPat::getCtrlNum() { return _ctrlNum; }
+
+void CtrlEventPat::setValue(int n) { _value = n; }
+
+int CtrlEventPat::getValue() { return _value; }
+
+QString CtrlEventPat::str() {
+ //TODO
+ if(_isReadable) {
+ QString sCtrl;
+ sCtrl.setNum(_ctrlNum);
+ QString s = " ";
+ QString sVal;
+ sVal.setNum(_value);
+ return sCtrl + s + sVal;
+ }
+ else {
+ QString s = "***";
+ return s;
+ }
+}
+
+//----------------------------------------------------------
+// BasePat
+//----------------------------------------------------------
+BasePat::BasePat() {
+}
+BasePat::BasePat(QString name, unsigned firstTick,
+ unsigned lastTick, int quant) {
+ _name = name;
+ _firstTick = firstTick;
+ _lastTick = lastTick;
+ _quant = quant;
+}
+
+BasePat::~BasePat() {}
+
+QString BasePat::getName() {
+ return _name;
+}
+
+bool BasePat::isRow(unsigned tick) {
+ Pos p = AL::sigmap.raster(_firstTick + tick, _quant);
+ return p.tick() == _firstTick + tick;
+}
+
+unsigned BasePat::tick2row(unsigned tick) {
+ return (_firstTick + tick) / _quant - (_firstTick / _quant);
+}
+
+//----------------------------------------------------------
+// VoicePat
+//----------------------------------------------------------
+VoicePat::VoicePat(QString name, unsigned firstTick, unsigned lastTick,
+ int quant):BasePat(name, firstTick, lastTick, quant) {
+ _events = new EventList();
+}
+
+VoicePat::~VoicePat() {
+ delete(_events);
+}
+
+
+std::vector<VoiceEventPat*> VoicePat::getEventsCol() {
+ return _eventsCol;
+}
+
+bool VoicePat::add(const Event* ev, unsigned tick) {
+ Event* e = new Event(*ev);
+ if(isFreeSpace(e, tick)) {
+ //add into the list of events
+ _events->add(*e, tick);
+ //add the begin tick into the column
+ unsigned beginRow = tick2row(tick);
+ if(beginRow >= _eventsCol.size()) {
+ for(unsigned i = _eventsCol.size(); i <= beginRow; i++) {
+ //empty voice event
+ _eventsCol.push_back(new VoiceEventPat());
+ }
+ }
+ VoiceEventPat* vbep;
+ if(isRow(tick)) vbep = new VoiceEventPat(e->pitch(), e->velo());
+ else vbep = new VoiceEventPat(false, false); //non-readable
+ if(_eventsCol[beginRow]) delete(_eventsCol[beginRow]);
+ _eventsCol[beginRow] = vbep;
+
+ //add the end tick into the column
+ unsigned endTick = e->lenTick() + tick;
+ unsigned endRow = tick2row(endTick);
+ if(endRow >= _eventsCol.size()) {
+ for(unsigned i = _eventsCol.size(); i <= endRow; i++) {
+ //empty voice event
+ _eventsCol.push_back(new VoiceEventPat());
+ }
+ }
+ VoiceEventPat* veep;
+ if(isRow(endTick)) veep = new VoiceEventPat(e->pitch(), 0);
+ else veep = new VoiceEventPat(false, false); //non-readable
+ if(_eventsCol[endRow]
+ &&
+ (_eventsCol[endRow]->getEmpty() || tick2row(endTick)==tick2row(tick))) {
+ delete(_eventsCol[endRow]);
+ _eventsCol[endRow] = veep;
+ }
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
+bool VoicePat::isFreeSpace(const Event* e, unsigned tick) {
+ bool isFree = true;
+ for(ciEvent ce = _events->begin(); ce != _events->end(); ce++) {
+ const Event* cevent = &ce->second;
+ unsigned beginTick = ce->first;
+ unsigned endTick = ce->first + cevent->lenTick();
+ isFree = (endTick <= tick) || (beginTick >= tick + e->lenTick());
+ if(!isFree) break;
+ }
+ return isFree;
+}
+
+//----------------------------------------------------------
+// CtrlPat
+//----------------------------------------------------------
+CtrlPat::CtrlPat(QString /*name*/) {
+}
+
+CtrlPat::~CtrlPat() {}
+
+//----------------------------------------------------------
+// BaseTrackPat
+//----------------------------------------------------------
+BaseTrackPat::BaseTrackPat(QMainWindow* parent, unsigned anr) {
+ _parent = parent;
+ _tree = new QTreeWidget(this);
+
+ _absoluteNbrRow = anr;
+
+ _update = false;
+
+ connect(_tree, SIGNAL(itemClicked(QTreeWidgetItem*, int)),
+ SLOT(currentItemChanged(QTreeWidgetItem*)));
+ connect(_tree, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)),
+ SLOT(currentItemChanged(QTreeWidgetItem*)));
+ connect(_parent, SIGNAL(signalMoveCurrentRow(unsigned)), this,
+ SLOT(moveRowFromSignal(unsigned)));
+ //connect signalSongChanged to update the pattern
+ connect(parent, SIGNAL(signalSongChanged(int)), this, SLOT(updatePattern(int)));
+}
+
+BaseTrackPat::~BaseTrackPat() {
+}
+
+void BaseTrackPat::setRowMag() {
+ _rowMag = (unsigned) height()/_fontHeight - OFFSET_Y;
+ _lastRow = _firstRow + _rowMag - 1;
+}
+void BaseTrackPat::setFirstRow(unsigned f) {
+ _firstRow = f;
+ _lastRow = f + _rowMag - 1;
+}
+void BaseTrackPat::setRelativeCurrentRow(unsigned r) {
+ _relativeCurrentRow = r;
+ _absoluteCurrentRow = r + _firstRow;
+}
+void BaseTrackPat::setAbsoluteCurrentRow(unsigned a) {
+ _absoluteCurrentRow = a;
+ _relativeCurrentRow = a - _firstRow;
+}
+
+unsigned BaseTrackPat::getRowMag() {
+ return _rowMag;
+}
+unsigned BaseTrackPat::getFirstRow() {
+ return _firstRow;
+}
+unsigned BaseTrackPat::getLastRow() {
+ return _lastRow;
+}
+unsigned BaseTrackPat::getRelativeCurrentRow() {
+ return _relativeCurrentRow;
+}
+unsigned BaseTrackPat::getAbsoluteCurrentRow() {
+ return _absoluteCurrentRow;
+}
+
+unsigned BaseTrackPat::getAbsoluteNbrRow() {
+ return _absoluteNbrRow;
+}
+
+void BaseTrackPat::moveRelativeCurrentRow(unsigned newIndex) {
+ if(newIndex==0 && getFirstRow()>0) {
+ setFirstRow(getFirstRow() - 1);
+ setRelativeCurrentRow(newIndex + 1);
+ _update = true;
+ }
+ else if(newIndex==getRowMag()-1 && getLastRow()<_absoluteNbrRow-1) {
+ setFirstRow(getFirstRow() + 1);
+ setRelativeCurrentRow(newIndex - 1);
+ _update = true;
+ }
+ else setRelativeCurrentRow(newIndex);
+}
+
+//void BaseTrackPat::itemSelectionChanged() {
+void BaseTrackPat::currentItemChanged(QTreeWidgetItem* nitem) {
+ int index;
+ if(nitem) {
+ index = _tree->indexOfTopLevelItem(nitem);
+
+ emit moveCurrentRow(index);
+ }
+}
+
+void BaseTrackPat::moveRowFromSignal(unsigned index) {
+ moveRelativeCurrentRow(index);
+ if(_update==true) {
+ fillPattern();
+ _update = false;
+ }
+ selectCurrentRow();
+}
+
+void BaseTrackPat::resizeEvent(QResizeEvent* /*event*/) {
+ setRowMag();
+ fillPattern();
+ selectCurrentRow();
+}
+
+void BaseTrackPat::selectCurrentRow() {
+ unsigned rcr = getRelativeCurrentRow();
+ if(rcr < getRowMag()) {
+ QTreeWidgetItem* item = _tree->topLevelItem(getRelativeCurrentRow());
+ if(item) {
+ _tree->blockSignals(true);
+ item->setSelected(true);
+ _tree->setCurrentItem(item);
+ _tree->blockSignals(false);
+ }
+ }
+}
+
+void BaseTrackPat::updatePattern(int /*type*/) {
+ clearMatrix();
+ buildMatrix();
+ fillPattern();
+ selectCurrentRow();
+}
+
+//----------------------------------------------------------
+// TrackPattern
+//----------------------------------------------------------
+TrackPattern::TrackPattern(QMainWindow* parent, QString name,
+ unsigned firstTick, unsigned lastTick,
+ int quant, PartList* pl, MidiTrack* t, unsigned anr)
+ : BaseTrackPat(parent, anr), BasePat(name, firstTick, lastTick, quant) {
+
+ //set attributs
+ _track = t;
+
+ //build the list of parts belonging to track t
+ _partList = new PartList;
+ for(ciPart p = pl->begin(); p != pl->end(); p++) {
+ Part* part = p->second;
+ if(t==part->track())
+ _partList->add(part);
+ }
+
+ //build the matrix of events
+ buildMatrix();
+
+ //configure and add the dockWidget
+ setWindowTitle(_track->name());
+ setFeatures(QDockWidget::DockWidgetClosable |QDockWidget::DockWidgetMovable);
+ parent->addDockWidget(Qt::LeftDockWidgetArea, this, Qt::Horizontal);
+
+ //build the treeWidget
+ _tree->setColumnCount(_voiceColumns.size() + _ctrlColumns.size());
+ QStringList headerLabels;
+ for(unsigned i = 0; i < _voiceColumns.size(); i++) {
+ headerLabels += QStringList(_voiceColumns[i]->getName());
+ }
+ for(unsigned i = 0; i < _ctrlColumns.size(); i++) {
+ //TODO CTRL
+ //headerLabels += QStringList(_ctrlColumns[i]->getName());
+ }
+ _tree->setHeaderLabels(headerLabels);
+ //set some display properties
+ _tree->setRootIsDecorated(false);
+ _tree->setUniformRowHeights(true);
+ _tree->setAlternatingRowColors(true);
+ QFont font =_tree->font();
+ font.setFamily(FONT);
+ _tree->setFont(font);
+ font.setPixelSize(FONT_HEIGHT);
+ _fontHeight = font.pixelSize() + OFFSET_HEIGHT;
+ setWidget(_tree);
+
+ //set the range of rows to display
+ setFirstRow(10); //TODO : choose accordingly to current position of muse song
+ setAbsoluteCurrentRow(10); //TODO : the same
+ setRowMag();
+
+ //fill the treeWidget
+ fillPattern();
+ selectCurrentRow();
+
+ //Resize the columns
+ for(unsigned i = 0; i < _voiceColumns.size(); i++)
+ _tree->resizeColumnToContents(i);
+}
+
+TrackPattern::~TrackPattern() {
+}
+
+void TrackPattern::add(const Event* e, unsigned tick) {
+ if(e->isNote()) {
+ bool success = false;
+ for(unsigned i = 0; i < _voiceColumns.size(); i++) {
+ success = _voiceColumns[i]->add(e, tick);
+ if(success) break;
+ }
+ if(!success) {
+ QString voiceName;
+ voiceName.setNum(_voiceColumns.size());
+ voiceName = QString("Voice " + voiceName);
+ VoicePat* vp = new VoicePat(voiceName, _firstTick, 0, _quant);
+ _voiceColumns.push_back(vp);
+ bool success = vp->add(e, tick);
+ if(!success) printf("Error TrackPattern::add\n");
+ }
+ }
+ else {
+ //TODO Ctrl
+ }
+}
+
+void TrackPattern::setQuant(int /*quant*/) {
+ //TODO
+}
+
+void TrackPattern::clearMatrix() {
+ _voiceColumns.clear();
+ _ctrlColumns.clear();
+}
+
+void TrackPattern::buildMatrix() {
+ for(ciPart p = _partList->begin(); p != _partList->end(); p++) {
+ Part* part = p->second;
+ EventList* events = part->events();
+ for(ciEvent e = events->begin(); e != events->end(); e++) {
+ const Event* event = &e->second;
+ unsigned rescaledTick = part->tick() + event->tick() - _firstTick;
+ add(event, rescaledTick);
+ }
+ }
+}
+
+void TrackPattern::fillPattern() {
+ _tree->blockSignals(true);
+
+ _tree->clear();
+ for(unsigned i = 0; i < _voiceColumns.size(); i++) {
+ for(unsigned j = getFirstRow(); j <= getLastRow(); j++) {
+ QTreeWidgetItem* item = _tree->topLevelItem(j - getFirstRow());
+ if(!item) item = new QTreeWidgetItem(_tree);
+ VoiceEventPat* vep = (_voiceColumns[i]->getEventsCol())[j];
+ if(vep) item->setText(i, vep->str());
+ }
+ }
+ for(unsigned i = 0; i < _ctrlColumns.size(); i++) {
+ //TODO CTRL
+ }
+
+ _tree->blockSignals(false);
+}
+
+//---------------------------------------------------------------
+// TimingEvent
+//---------------------------------------------------------------
+TimingEvent::TimingEvent(unsigned row) {
+ _row = row;
+}
+TimingEvent::~TimingEvent() {
+}
+
+void TimingEvent::setBarBeatTick(unsigned tick) {
+ AL::sigmap.tickValues(tick, &_bar, &_beat, &_tick);
+}
+
+QString TimingEvent::barBeatTickStr() {
+ QString barS;
+ barS.setNum(_bar + 1);
+ if(_bar<10) barS = QString("000") + barS;
+ else if(_bar<100) barS = QString("00") + barS;
+ else if(_bar<1000) barS = QString("0") + barS;
+ QString beatS;
+ beatS.setNum(_beat + 1);
+ if(_beat<10) beatS = QString("0") + beatS;
+ QString tickS;
+ tickS.setNum(_tick);
+ if(_tick<10) tickS = QString("00") + tickS;
+ else if(_tick<100) tickS = QString("0") + tickS;
+ return barS + QString(":") + beatS + QString(":") + tickS;
+}
+
+QString TimingEvent::rowStr() {
+ QString r;
+ r.setNum(_row);
+ if(_row<10) r = QString("00") + r;
+ else if(_row<100) r = QString("0") + r;
+ return r;
+}
+
+//---------------------------------------------------------------
+// TimingPattern
+//---------------------------------------------------------------
+TimingPattern::TimingPattern(QMainWindow* parent, QString name,
+ unsigned firstTick, unsigned lastTick, int quant)
+ : BasePat(name, firstTick, lastTick, quant), BaseTrackPat(parent) {
+ //build the timing matrix
+ buildMatrix();
+
+ //configure and add the dockWidget
+ setWindowTitle(name);
+ setFeatures(QDockWidget::DockWidgetClosable |QDockWidget::DockWidgetMovable);
+ parent->addDockWidget(Qt::LeftDockWidgetArea, this, Qt::Horizontal);
+
+ //build the treeWidget
+ QStringList headerLabels;
+ _tree->setHeaderLabels(QStringList("bar:bt:tick") + QStringList("row"));
+ _tree->setHeaderLabels(headerLabels);
+ //set some display properties
+ _tree->setRootIsDecorated(false);
+ _tree->setUniformRowHeights(true);
+ _tree->setAlternatingRowColors(true);
+ QFont font =_tree->font();
+ font.setFamily(FONT);
+ _tree->setFont(font);
+ font.setPixelSize(FONT_HEIGHT);
+ _fontHeight = font.pixelSize() + OFFSET_HEIGHT;
+ setWidget(_tree);
+
+ //set the range of rows to display
+ setFirstRow(10); //TODO : choose accordingly to current position of muse song
+ setAbsoluteCurrentRow(10); //TODO : the same
+ setRowMag();
+
+ //fill the treeWidget
+ fillPattern();
+ selectCurrentRow();
+
+ //resize the columns
+ for(int i = 0; i < _tree->columnCount(); i++)
+ _tree->resizeColumnToContents(i);
+}
+
+TimingPattern::~TimingPattern() {
+}
+
+void TimingPattern::clearMatrix() {
+ _timingEvents.clear();
+}
+
+void TimingPattern::buildMatrix() {
+ for(unsigned tick = _firstTick; tick <= _lastTick; tick++) {
+ if(isRow(tick)) {
+ TimingEvent* te = new TimingEvent(tick2row(tick) - tick2row(_firstTick));
+ te->setBarBeatTick(tick);
+ _timingEvents.push_back(te);
+ }
+ }
+ _absoluteNbrRow = _timingEvents.size();
+}
+
+void TimingPattern::fillPattern() {
+ _tree->blockSignals(true);
+
+ _tree->clear();
+ for(unsigned i = getFirstRow(); i <= getLastRow(); i++) {
+ QTreeWidgetItem* item = new QTreeWidgetItem(_tree);
+ TimingEvent* te = _timingEvents[i];
+ item->setText(0, te->barBeatTickStr());
+ item->setText(1, te->rowStr());
+ }
+
+ _tree->blockSignals(false);
+}
diff --git a/muse_qt4_evolution/muse/midiedit/trackpattern.h b/muse_qt4_evolution/muse/midiedit/trackpattern.h
new file mode 100644
index 00000000..d9d91aee
--- /dev/null
+++ b/muse_qt4_evolution/muse/midiedit/trackpattern.h
@@ -0,0 +1,261 @@
+//=================================================================
+// trackpattern.h
+// TrackPattern class for miditracker, QDock, QTree, Part, matrix
+// miditracker.h
+// (C) Copyright 2006 Nil Geisweiller (a_lin@user.sourceforge.net)
+//=================================================================
+
+#ifndef __TRACKERPATTERN_H__
+#define __TRACKERPATTERN_H__
+
+#include <vector>
+#include "miditrack.h"
+#include "part.h"
+
+class PartList;
+
+//----------------------------------------------------------
+// EventPat
+// has to be derived, can be note or control
+//----------------------------------------------------------
+class EventPat {
+ private:
+ protected:
+ bool _isReadable; //true iff the time of the event is the exact row time
+ bool _isEmpty;
+ public:
+ EventPat(bool isEmpty, bool isReadable);
+ EventPat(); //_isEmpty=true and_isReadable=true at the initialization
+ ~EventPat();
+
+ void setEmpty(bool);
+ bool getEmpty();
+ void setReadable(bool);
+ bool getReadable();
+};
+
+//----------------------------------------------------------
+// VoiceEventPat
+//----------------------------------------------------------
+class VoiceEventPat : public EventPat {
+ private:
+ int _noteNum; //absolute note number including octave
+ int _velocity; //if velocity is 0 note is off
+ public:
+ VoiceEventPat(int noteNum, int velocity); // _isReadable is initialized true
+ VoiceEventPat(bool isEmpty, bool isReadable);
+ VoiceEventPat(); //_isEmpty = true, _isReadable = true
+ ~VoiceEventPat();
+
+ void setNoteNum(int n);
+ int getNoteNum();
+ void setVelocity(int n);
+ int getVelocity();
+ QString str(); //return the string to display on the entry of the pattern
+};
+
+//----------------------------------------------------------
+// CtrlEventPat
+//----------------------------------------------------------
+class CtrlEventPat : public EventPat {
+ private:
+ int _ctrlNum;
+ int _value; //if velocity is 0 note is off
+ public:
+ CtrlEventPat(int ctrlNum, int value); // _isReadable is initialized true
+ CtrlEventPat(); // _isReadable is initialized false
+ ~CtrlEventPat();
+
+ void setCtrlNum(int n);
+ int getCtrlNum();
+ void setValue(int n);
+ int getValue();
+ QString str(); //return the string to display on the entry of the pattern
+};
+
+//----------------------------------------------------------
+// BasePat
+//----------------------------------------------------------
+class BasePat {
+ protected:
+ QString _name;
+ unsigned _firstTick;
+ unsigned _lastTick;
+ int _quant;
+ public:
+ BasePat();
+ BasePat(QString name, unsigned firstTick, unsigned lastTick, int quant);
+ ~BasePat();
+
+ QString getName();
+
+ bool isRow(unsigned tick); //return true iff tick coincides with one row
+ unsigned tick2row(unsigned tick);
+};
+
+//----------------------------------------------------------
+// VoicePat
+//----------------------------------------------------------
+class VoicePat : public BasePat {
+ private:
+ std::vector<VoiceEventPat*> _eventsCol; //column of VoiceEventPat to display
+ EventList* _events; //actual list of events, only one at a time
+ public:
+ VoicePat(QString name, unsigned firstTick, unsigned lastTick, int quant);
+ ~VoicePat();
+
+ std::vector<VoiceEventPat*> getEventsCol();
+
+ bool add(const Event* e, unsigned tick); //add the Event e into the EventList
+ //and update properly _events
+ //return true if success, that is
+ //there is an empty space of the
+ //event
+ bool isFreeSpace(const Event* e, unsigned tick); //return true iff there
+ //is space to add the
+ //event e without
+ //overlapping other events
+};
+
+//----------------------------------------------------------
+// CtrlPat
+//----------------------------------------------------------
+class CtrlPat {
+ private:
+ std::vector<CtrlEventPat> _events; //column of CtrlEventPat
+ public:
+ CtrlPat(QString name);
+ ~CtrlPat();
+};
+
+//------------------------------------------------------
+// BaseTrackPat
+//------------------------------------------------------
+class BaseTrackPat : public QDockWidget {
+ Q_OBJECT
+
+ protected:
+ QTreeWidget* _tree;
+ QMainWindow* _parent;
+
+ unsigned _rowMag; //contains the number of rows
+ unsigned _firstRow; //absolute index of the first row
+ unsigned _lastRow; //absolute index of the last row, included
+ unsigned _relativeCurrentRow; //index of the current according to the tree
+ unsigned _absoluteCurrentRow; //index of the current row according to the
+ //event matrix
+ unsigned _absoluteNbrRow; //contains the number of rows of the matrix
+
+ int _fontHeight;
+
+ bool _update; //if true then the tree must updated
+
+ public:
+ BaseTrackPat(QMainWindow* parent, unsigned anr = 0);
+ ~BaseTrackPat();
+
+ void setRowMag(); //set _rowMag with the number of rows to display according
+ //to the size of the window, adjust _lastRow accordingly,
+ //assum that first row is set appropriately
+ void setFirstRow(unsigned f); //set _firstRow with f, that is the absolute index
+ //of the first row, adjust _lastRow appropriately
+ void setRelativeCurrentRow(unsigned r); //set _relativeCurrentRow with r
+ //and _absoluteCurrentRow accordingly
+ void setAbsoluteCurrentRow(unsigned a); //set _absoluteCurrentRow with a
+ //and _relativeCurrentRow accordingly
+
+ unsigned getRowMag();
+ unsigned getFirstRow();
+ unsigned getLastRow();
+ unsigned getRelativeCurrentRow();
+ unsigned getAbsoluteCurrentRow();
+
+ unsigned getAbsoluteNbrRow();
+
+ void moveRelativeCurrentRow(unsigned newIndex); //update _firstRow, _lastrow
+ //relativeCurrentRow,
+ //absoluteCurrentRow, considering
+ //that the new relative index is
+ //newIndex
+
+ void resizeEvent(QResizeEvent* /*event*/);
+
+ virtual void clearMatrix() {}
+ virtual void buildMatrix() {}
+ virtual void fillPattern() {} //fill the treeWidget with the right window of times
+ //according to _firstRow and _lastRow
+
+
+ void selectCurrentRow(); //block the signals and select the current row
+
+ signals:
+ void moveCurrentRow(unsigned i); //send the signal that the current row is moved
+ //at the relative index i
+ private slots:
+ void currentItemChanged(QTreeWidgetItem* nitem);
+ void moveRowFromSignal(unsigned index);
+ void updatePattern(int songChangeType);
+};
+
+//------------------------------------------------------
+// TrackPattern
+//------------------------------------------------------
+class TrackPattern : public BaseTrackPat, public BasePat {
+ private:
+ PartList* _partList; //partList concerned by a track
+ MidiTrack* _track;
+ std::vector<VoicePat*> _voiceColumns; //matrix of voice events
+ std::vector<CtrlPat*> _ctrlColumns; //matrix of ctrl events
+ public:
+ TrackPattern(QMainWindow* parent, QString name,
+ unsigned firstTick, unsigned lastTick,
+ int quant, PartList* pl, MidiTrack* t, unsigned anr = 0);
+ ~TrackPattern();
+
+ void add(const Event* e, unsigned tick); //add the Event e and
+ //build consequently
+ //the matrix,
+ //creating new voices when necessary
+ MidiTrack* getTrack() {return _track;}
+ void setQuant(int quant);
+
+ virtual void clearMatrix();
+ virtual void buildMatrix();
+ virtual void fillPattern();
+};
+
+//------------------------------------------------------
+// TimingEvent
+//------------------------------------------------------
+class TimingEvent {
+ private:
+ int _bar;
+ int _beat;
+ unsigned _tick;
+ unsigned _row;
+
+ public:
+ TimingEvent(unsigned row);
+ ~TimingEvent();
+
+ void setBarBeatTick(unsigned tick);
+
+ QString barBeatTickStr();
+ QString rowStr();
+};
+
+class TimingPattern : public BasePat, public BaseTrackPat {
+ private:
+ //QTreeWidget* _tree;
+ std::vector<TimingEvent*> _timingEvents;
+ public:
+ TimingPattern(QMainWindow* parent, QString name, unsigned firstTick,
+ unsigned lastTick, int quant);
+ ~TimingPattern();
+
+ virtual void clearMatrix();
+ virtual void buildMatrix();
+ virtual void fillPattern();
+};
+
+#endif
diff --git a/muse_qt4_evolution/muse/midiedit/velocity.cpp b/muse_qt4_evolution/muse/midiedit/velocity.cpp
new file mode 100644
index 00000000..f0abd845
--- /dev/null
+++ b/muse_qt4_evolution/muse/midiedit/velocity.cpp
@@ -0,0 +1,108 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "velocity.h"
+#include "song.h"
+#include "tb1.h"
+#include "audio.h"
+
+//---------------------------------------------------------
+// Velocity
+//---------------------------------------------------------
+
+Velocity::Velocity(QWidget*)
+ : MidiCmdDialog()
+ {
+ setWindowTitle(tr("MusE: Modify Velocity"));
+ QWidget* velocityWidget = new QWidget;
+ velo.setupUi(velocityWidget);
+ layout->addWidget(velocityWidget);
+ layout->addStretch(10);
+ _rateVal = 0;
+ _offsetVal = 0;
+ velo.rate->setValue(_rateVal);
+ velo.offset->setValue(_offsetVal);
+ }
+
+//---------------------------------------------------------
+// accept
+//---------------------------------------------------------
+
+void Velocity::accept()
+ {
+ _rateVal = velo.rate->value();
+ _offsetVal = velo.offset->value();
+ MidiCmdDialog::accept();
+ }
+
+//---------------------------------------------------------
+// ModifyVelocityCmd
+//---------------------------------------------------------
+
+ModifyVelocityCmd::ModifyVelocityCmd(MidiEditor* e)
+ : MidiCmd(e)
+ {
+ dialog = 0;
+ }
+
+//---------------------------------------------------------
+// guiDialog
+//---------------------------------------------------------
+
+MidiCmdDialog* ModifyVelocityCmd::guiDialog()
+ {
+ if (dialog == 0)
+ dialog = new Velocity(0);
+ return dialog;
+ }
+
+//---------------------------------------------------------
+// process
+//---------------------------------------------------------
+
+void ModifyVelocityCmd::process(CItemList* items)
+ {
+ int rate = dialog->rateVal();
+ int offset = dialog->offsetVal();
+
+ for (iCItem k = items->begin(); k != items->end(); ++k) {
+ CItem* item = k->second;
+ Event event = item->event;
+ if (event.type() != Note)
+ continue;
+ if (itemInRange(item)) {
+ int velo = event.velo();
+ velo = (velo * rate) / 100;
+ velo += offset;
+
+ if (velo <= 0)
+ velo = 1;
+ if (velo > 127)
+ velo = 127;
+ if (event.velo() != velo) {
+ Event newEvent = event.clone();
+ newEvent.setVelo(velo);
+ audio->msgChangeEvent(event, newEvent, item->part, false);
+ }
+ }
+ }
+ }
+
+
diff --git a/muse_qt4_evolution/muse/midiedit/velocity.h b/muse_qt4_evolution/muse/midiedit/velocity.h
new file mode 100644
index 00000000..2ac4e700
--- /dev/null
+++ b/muse_qt4_evolution/muse/midiedit/velocity.h
@@ -0,0 +1,62 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __VELOCITY_H__
+#define __VELOCITY_H__
+
+#include "ui_velocity.h"
+#include "midicmd.h"
+
+//---------------------------------------------------------
+// Velocity
+//---------------------------------------------------------
+
+class Velocity : public MidiCmdDialog {
+ Q_OBJECT
+
+ Ui::VelocityBase velo;
+ int _rateVal;
+ int _offsetVal;
+
+ protected slots:
+ void accept();
+
+ public:
+ Velocity(QWidget* parent = 0);
+ int rateVal() const { return _rateVal; }
+ int offsetVal() const { return _offsetVal; }
+ };
+
+//---------------------------------------------------------
+// ModifyVelocityCmd
+//---------------------------------------------------------
+
+class ModifyVelocityCmd : public MidiCmd
+ {
+ Velocity* dialog;
+ virtual MidiCmdDialog* guiDialog();
+ virtual void process(CItemList* items);
+
+ public:
+ ModifyVelocityCmd(MidiEditor* e);
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/midiedit/velocity.ui b/muse_qt4_evolution/muse/midiedit/velocity.ui
new file mode 100644
index 00000000..342611c0
--- /dev/null
+++ b/muse_qt4_evolution/muse/midiedit/velocity.ui
@@ -0,0 +1,86 @@
+<ui version="4.0" >
+ <author></author>
+ <comment></comment>
+ <exportmacro></exportmacro>
+ <class>VelocityBase</class>
+ <widget class="QWidget" name="VelocityBase" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>275</width>
+ <height>335</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>MusE: Modify Velocity</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>11</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QGroupBox" name="GroupBox3" >
+ <property name="title" >
+ <string>Values</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>6</number>
+ </property>
+ <property name="spacing" >
+ <number>3</number>
+ </property>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="TextLabel3" >
+ <property name="text" >
+ <string>Rate:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="TextLabel4" >
+ <property name="text" >
+ <string>Offset:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QSpinBox" name="rate" >
+ <property name="suffix" >
+ <string>%</string>
+ </property>
+ <property name="maximum" >
+ <number>200</number>
+ </property>
+ <property name="value" >
+ <number>100</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QSpinBox" name="offset" >
+ <property name="maximum" >
+ <number>127</number>
+ </property>
+ <property name="minimum" >
+ <number>1</number>
+ </property>
+ <property name="singleStep" >
+ <number>1</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11" />
+ <pixmapfunction>qPixmapFromMimeSource</pixmapfunction>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/muse_qt4_evolution/muse/midievent.cpp b/muse_qt4_evolution/muse/midievent.cpp
new file mode 100644
index 00000000..80fd30a8
--- /dev/null
+++ b/muse_qt4_evolution/muse/midievent.cpp
@@ -0,0 +1,129 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "midievent.h"
+
+#include "helper.h"
+#include "event.h"
+#include "midictrl.h"
+#include "muse/midi.h"
+
+//---------------------------------------------------------
+// MidiEvent
+//---------------------------------------------------------
+
+MidiEvent::MidiEvent(unsigned t, int tpe, const unsigned char* data, int len)
+ {
+ _time = t;
+ edata.setData(data, len);
+ _type = tpe;
+ }
+
+MidiEvent::MidiEvent(unsigned tick, int channel, const Event& e)
+ {
+ setChannel(channel);
+ setTime(tick);
+ switch(e.type()) {
+ case Note:
+ setType(ME_NOTEON);
+ setA(e.dataA());
+ setB(e.dataB());
+ break;
+ case Controller:
+ setType(ME_CONTROLLER);
+ setA(e.dataA()); // controller number
+ setB(e.dataB()); // controller value
+ break;
+ case PAfter:
+ setType(ME_POLYAFTER);
+ setA(e.dataA());
+ setB(e.dataB());
+ break;
+ case CAfter:
+ setType(ME_AFTERTOUCH);
+ setA(e.dataA());
+ setB(0);
+ break;
+ case Sysex:
+ setType(ME_SYSEX);
+ setData(e.eventData());
+ break;
+ default:
+ printf("MEvent::MEvent(): event type %d not implemented\n",
+ type());
+ break;
+ }
+ }
+
+//---------------------------------------------------------
+// dump
+//---------------------------------------------------------
+
+void MidiEvent::dump() const
+ {
+ printf("chan:%d ", _channel+1);
+ if (_type == ME_NOTEON) {
+ QString s = pitch2string(_a);
+ printf("NoteOn %3s(0x%02x) %3d\n", s.toLatin1().data(), _a, _b);
+ }
+ else if (_type == ME_NOTEOFF) {
+ QString s = pitch2string(_a);
+ printf("NoteOff %3s(0x%02x) %3d\n", s.toLatin1().data(), _a, _b);
+ }
+ else if (_type == ME_SYSEX) {
+ printf("SysEx len %d ", len());
+ int n = len() < 7 ? len() : 7;
+ unsigned char* p = data();
+ for (int i = 0; i < n; ++i)
+ printf("%02x ", *p++);
+ printf("\n");
+ }
+ else if (_type == ME_CONTROLLER)
+ printf("Ctrl %d(0x%02x) %d(0x%02x)\n", _a, _a, _b, _b);
+ else if (_type == ME_PROGRAM)
+ printf("Prog %d(0x%02x)\n", _a, _a);
+ else if (_type == ME_AFTERTOUCH)
+ printf("Aftertouch %d\n", _a);
+ else if (_type == ME_PITCHBEND)
+ printf("PitchBend %d\n", _a);
+ else
+ printf("type:0x%02x a=%d(0x%02x) b=%d(0x%02x)\n", _type, _a, _a, _b, _b);
+ }
+
+//---------------------------------------------------------
+// operator <
+//---------------------------------------------------------
+
+bool MidiEvent::operator<(const MidiEvent& e) const
+ {
+ if (time() != e.time())
+ return time() < e.time();
+
+ // play note off events first to prevent overlapping
+ // notes
+
+ if (channel() == e.channel())
+ return type() == ME_NOTEOFF
+ || (type() == ME_NOTEON && dataB() == 0);
+
+ int map[16] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, 11, 12, 13, 14, 15 };
+ return map[channel()] < map[e.channel()];
+ }
+
diff --git a/muse_qt4_evolution/muse/midievent.h b/muse_qt4_evolution/muse/midievent.h
new file mode 100644
index 00000000..780c7ce6
--- /dev/null
+++ b/muse_qt4_evolution/muse/midievent.h
@@ -0,0 +1,100 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __MIDIEVENT_H__
+#define __MIDIEVENT_H__
+
+#include <set>
+#include "evdata.h"
+
+#include "midi.h"
+
+class Event;
+
+//---------------------------------------------------------
+// MidiEvent
+//---------------------------------------------------------
+
+class MidiEvent {
+ unsigned _time;
+ EvData edata;
+ unsigned char _channel, _type;
+ int _a, _b;
+
+ public:
+ MidiEvent() {}
+ MidiEvent(unsigned tm, int c, int t, int a, int b)
+ : _time(tm), _channel(c & 0xf), _type(t), _a(a), _b(b) {}
+ MidiEvent(unsigned t, int type, const unsigned char* data, int len);
+ MidiEvent(unsigned t, int tpe, EvData d) : _time(t), edata(d), _type(tpe) {}
+ MidiEvent(unsigned t, int channel, const Event& e);
+
+ ~MidiEvent() {}
+
+ MidiEvent& operator=(const MidiEvent& ed) {
+ _time = ed._time;
+ edata = ed.edata;
+ _channel = ed._channel;
+ _type = ed._type;
+ _a = ed._a;
+ _b = ed._b;
+ return *this;
+ }
+
+ int channel() const { return _channel; }
+ int type() const { return _type; }
+ int dataA() const { return _a; }
+ int dataB() const { return _b; }
+ unsigned time() const { return _time; }
+
+ void setChannel(int val) { _channel = val; }
+ void setType(int val) { _type = val; }
+ void setA(int val) { _a = val; }
+ void setB(int val) { _b = val; }
+ void setTime(unsigned val) { _time = val; }
+
+ const EvData& eventData() const { return edata; }
+ unsigned char* data() const { return edata.data; }
+ int len() const { return edata.dataLen; }
+ void setData(const EvData& e) { edata = e; }
+ void setData(const unsigned char* p, int len) { edata.setData(p, len); }
+ void dump() const;
+ bool isNote() const { return _type == ME_NOTEON; }
+ bool isNoteOff() const { return (_type == ME_NOTEOFF)||(_type == ME_NOTEON && _b == 0); }
+ bool operator<(const MidiEvent&) const;
+ };
+
+//---------------------------------------------------------
+// MidiEventList
+//---------------------------------------------------------
+
+// typedef std::multiset<MidiEvent, std::less<MidiEvent>,
+// __gnu_cxx::__mt_alloc<MidiEvent> > MPEL;
+
+class MidiEventList : public std::multiset<MidiEvent, std::less<MidiEvent> >
+ {
+ public:
+ };
+
+typedef MidiEventList::iterator iMidiEvent;
+typedef MidiEventList::const_iterator ciMidiEvent;
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/midieventbase.cpp b/muse_qt4_evolution/muse/midieventbase.cpp
new file mode 100644
index 00000000..2e3f371c
--- /dev/null
+++ b/muse_qt4_evolution/muse/midieventbase.cpp
@@ -0,0 +1,159 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "event.h"
+#include "midieventbase.h"
+#include "al/xml.h"
+#include "midievent.h"
+#include "midictrl.h"
+#include "muse.h"
+
+//---------------------------------------------------------
+// MidiEventBase
+//---------------------------------------------------------
+
+MidiEventBase::MidiEventBase(EventType t)
+ : EventBase(t)
+ {
+ a = 0;
+ b = 0;
+ c = 0;
+ }
+
+//---------------------------------------------------------
+// MidiEventBase::mid
+//---------------------------------------------------------
+
+EventBase* MidiEventBase::mid(unsigned b, unsigned e)
+ {
+ if (tick() < b || tick() >= e)
+ return 0;
+ return new MidiEventBase(*this);
+ }
+
+//---------------------------------------------------------
+// isNoteOff
+//---------------------------------------------------------
+
+bool MidiEventBase::isNoteOff() const
+ {
+ return (type() == Note && (velo() == 0));
+ }
+
+bool MidiEventBase::isNoteOff(const Event& e) const
+ {
+ return (e.isNoteOff() && (e.pitch() == a));
+ }
+
+//---------------------------------------------------------
+// dump
+//---------------------------------------------------------
+
+void MidiEventBase::dump(int n) const
+ {
+ EventBase::dump(n);
+ QString p = eventTypeName();
+ QString s;
+ s.sprintf("%s<%s> a:0x%x(%d) b:0x%x(%d)\n",
+ QString(n+2, ' ').toLocal8Bit().data(), p.toLocal8Bit().data(), a, a, b, b);
+ printf("%s\n", s.toLocal8Bit().data());
+ }
+
+//---------------------------------------------------------
+// MidiEventBase::write
+//---------------------------------------------------------
+
+void MidiEventBase::write(Xml& xml, const Pos& offset) const
+ {
+ QString s = QString("event tick=\"%1\"").arg(tick() + offset.tick());
+
+ switch (type()) {
+ case Note:
+ s += QString(" len=\"%1\"").arg(lenTick());
+ break;
+ default:
+ s += QString(" type=\"%1\"").arg(type());
+ break;
+ }
+ if (edata.dataLen) {
+ s += QString(" datalen=\"%1\"").arg(edata.dataLen);
+ xml.stag(s);
+ xml.dump(edata.dataLen, edata.data);
+ xml.etag("event");
+ }
+ else {
+ if (a)
+ s += QString(" a=\"%1\"").arg(a);
+ if (b)
+ s += QString(" b=\"%1\"").arg(b);
+ if (c)
+ s += QString(" b=\"%1\"").arg(c);
+ xml.tagE(s);
+ }
+ }
+
+//---------------------------------------------------------
+// MidiEventBase::read
+//---------------------------------------------------------
+
+void MidiEventBase::read(QDomNode node)
+ {
+ QDomElement e = node.toElement();
+ setTick(e.attribute("tick","0").toInt());
+ setType(EventType(e.attribute("type","0").toInt()));
+ setLenTick(e.attribute("len","0").toInt());
+ a = e.attribute("a","0").toInt();
+ b = e.attribute("b","0").toInt();
+ c = e.attribute("c","0").toInt();
+ int dataLen = e.attribute("datalen","0").toInt();
+
+ if (dataLen) {
+ QStringList l = e.text().simplified().split(" ", QString::SkipEmptyParts);
+ if (dataLen != l.size()) {
+ printf("error converting init string <%s>\n", e.text().toLatin1().data());
+ }
+ edata.data = new unsigned char[dataLen];
+ edata.dataLen = dataLen;
+ unsigned char* d = edata.data;
+ int numberBase = 16;
+ for (int i = 0; i < l.size(); ++i) {
+ bool ok;
+ *d++ = l.at(i).toInt(&ok, numberBase);
+ if (!ok)
+ printf("error converting data val <%s>\n", l.at(i).toLatin1().data());
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// MidiEventBase::operator==
+//---------------------------------------------------------
+
+bool MidiEventBase::operator==(const EventBase& ev) const {
+ const MidiEventBase* pev = dynamic_cast<const MidiEventBase*>(&ev);
+
+ if(pev) return operator==(*pev);
+ else return false;
+}
+
+bool MidiEventBase::operator==(const MidiEventBase& ev) const {
+ return (ev.a==a && ev.b==b && ev.c==c && ev.edata==edata
+ && PosLen::operator==((const PosLen&)ev));
+}
diff --git a/muse_qt4_evolution/muse/midieventbase.h b/muse_qt4_evolution/muse/midieventbase.h
new file mode 100644
index 00000000..64a8269c
--- /dev/null
+++ b/muse_qt4_evolution/muse/midieventbase.h
@@ -0,0 +1,76 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __MIDI_EVENT_BASE_H__
+#define __MIDI_EVENT_BASE_H__
+
+#include "eventbase.h"
+
+//---------------------------------------------------------
+// MidiEventBase
+//---------------------------------------------------------
+
+class MidiEventBase : public EventBase {
+ int a, b, c; // pitch, velo-on, velo-off
+ EvData edata;
+
+ virtual EventBase* clone() const { return new MidiEventBase(*this); }
+
+ public:
+ MidiEventBase(EventType t);
+ virtual ~MidiEventBase() {}
+
+ virtual bool isNote() const { return type() == Note; }
+ virtual bool isNoteOff() const;
+ virtual bool isNoteOff(const Event&) const;
+ virtual int pitch() const { return a; }
+ virtual int program() const { return a; }
+ virtual int cntrl() const { return a; }
+ virtual int dataA() const { return a; }
+ virtual void setA(int val) { a = val; }
+ virtual void setPitch(int v) { a = v; }
+
+ virtual int cntrlVal() const { return b; }
+ virtual int dataB() const { return b; }
+ virtual int velo() const { return b; }
+ virtual void setB(int val) { b = val; }
+ virtual void setVelo(int v) { b = v; }
+
+ virtual int veloOff() const { return c; }
+ virtual int dataC() const { return c; }
+ virtual void setC(int val) { c = val; }
+ virtual void setVeloOff(int v) { c = v; }
+
+ virtual const unsigned char* data() const { return edata.data; }
+ virtual int dataLen() const { return edata.dataLen; }
+ virtual void setData(const unsigned char* data, int len) { edata.setData(data, len); }
+ virtual const EvData eventData() const { return edata; }
+
+ virtual void dump(int n = 0) const;
+ virtual void read(QDomNode);
+ virtual void write(Xml&, const Pos& offset) const;
+ virtual EventBase* mid(unsigned, unsigned);
+
+ virtual bool operator==(const EventBase&) const;
+ virtual bool operator==(const MidiEventBase&) const;
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/midififo.cpp b/muse_qt4_evolution/muse/midififo.cpp
new file mode 100644
index 00000000..f68afd83
--- /dev/null
+++ b/muse_qt4_evolution/muse/midififo.cpp
@@ -0,0 +1,103 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "midififo.h"
+
+//---------------------------------------------------------
+// put
+// return true on fifo overflow
+//---------------------------------------------------------
+
+bool MidiFifo::put(const MidiEvent& event)
+ {
+ if (size < MIDI_FIFO_SIZE) {
+ fifo[wIndex] = event;
+ wIndex = (wIndex + 1) % MIDI_FIFO_SIZE;
+ // q_atomic_increment(&size);
+ ++size;
+ return false;
+ }
+ return true;
+ }
+
+//---------------------------------------------------------
+// get
+//---------------------------------------------------------
+
+MidiEvent MidiFifo::get()
+ {
+ MidiEvent event(fifo[rIndex]);
+ rIndex = (rIndex + 1) % MIDI_FIFO_SIZE;
+ // q_atomic_decrement(&size);
+ --size;
+ return event;
+ }
+
+//---------------------------------------------------------
+// peek
+//---------------------------------------------------------
+
+const MidiEvent& MidiFifo::peek(int n)
+ {
+ int idx = (rIndex + n) % MIDI_FIFO_SIZE;
+ return fifo[idx];
+ }
+
+//---------------------------------------------------------
+// remove
+//---------------------------------------------------------
+
+void MidiFifo::remove()
+ {
+ rIndex = (rIndex + 1) % MIDI_FIFO_SIZE;
+ // q_atomic_decrement(&size);
+ --size;
+ }
+
+//---------------------------------------------------------
+// put
+// return true on fifo overflow
+//---------------------------------------------------------
+
+bool MidiOutFifo::put(const MidiOutEvent& event)
+ {
+ if (size < MIDI_FIFO_SIZE) {
+ fifo[wIndex] = event;
+ wIndex = (wIndex + 1) % MIDI_FIFO_SIZE;
+ // q_atomic_increment(&size);
+ ++size;
+ return false;
+ }
+ return true;
+ }
+
+//---------------------------------------------------------
+// get
+//---------------------------------------------------------
+
+MidiOutEvent MidiOutFifo::get()
+ {
+ MidiOutEvent event(fifo[rIndex]);
+ rIndex = (rIndex + 1) % MIDI_FIFO_SIZE;
+ // q_atomic_decrement(&size);
+ --size;
+ return event;
+ }
+
diff --git a/muse_qt4_evolution/muse/midififo.h b/muse_qt4_evolution/muse/midififo.h
new file mode 100644
index 00000000..e2342feb
--- /dev/null
+++ b/muse_qt4_evolution/muse/midififo.h
@@ -0,0 +1,92 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __MIDIFIFO_H__
+#define __MIDIFIFO_H__
+
+#include "midievent.h"
+#include "port.h"
+
+#define MIDI_FIFO_SIZE 512
+
+//---------------------------------------------------------
+// MidiFifo
+//---------------------------------------------------------
+
+class MidiFifo {
+ MidiEvent fifo[MIDI_FIFO_SIZE];
+ volatile int size;
+ int wIndex;
+ int rIndex;
+
+ public:
+ MidiFifo() { clear(); }
+ bool put(const MidiEvent& event); // returns true on fifo overflow
+ MidiEvent get();
+ const MidiEvent& peek(int n = 0);
+ void remove();
+ bool isEmpty() const { return size == 0; }
+ void clear() { size = 0, wIndex = 0, rIndex = 0; }
+ int getSize() const { return size; }
+ };
+
+//---------------------------------------------------------
+// MidiOutEvent
+//---------------------------------------------------------
+
+struct MidiOutEvent {
+ Port port;
+ MidiEvent event;
+
+ MidiOutEvent() {}
+ MidiOutEvent(const Port& p, const MidiEvent& e)
+ : port(p), event(e) {}
+ bool operator<(const MidiOutEvent& e) const {
+ if (port == e.port)
+ return event < e.event;
+ return event < e.event;
+ }
+ };
+
+typedef std::multiset<MidiOutEvent, std::less<MidiOutEvent> > MidiOutEventList;
+typedef MidiOutEventList::iterator iMidiOutEvent;
+typedef MidiOutEventList::const_iterator ciMidiOutEvent;
+
+//---------------------------------------------------------
+// MidiOutFifo
+//---------------------------------------------------------
+
+class MidiOutFifo {
+ MidiOutEvent fifo[MIDI_FIFO_SIZE];
+ volatile int size;
+ int wIndex;
+ int rIndex;
+
+ public:
+ MidiOutFifo() { clear(); }
+ bool put(const MidiOutEvent& event); // returns true on fifo overflow
+ MidiOutEvent get();
+ bool isEmpty() const { return size == 0; }
+ void clear() { size = 0, wIndex = 0, rIndex = 0; }
+ };
+
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/midifile.cpp b/muse_qt4_evolution/muse/midifile.cpp
new file mode 100644
index 00000000..c45c57d2
--- /dev/null
+++ b/muse_qt4_evolution/muse/midifile.cpp
@@ -0,0 +1,673 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "song.h"
+#include "midi.h"
+#include "midifile.h"
+#include "midiedit/drummap.h"
+#include "event.h"
+#include "globals.h"
+#include "midictrl.h"
+#include "midictrl.h"
+#include "midievent.h"
+#include "gconfig.h"
+
+const char* errString[] = {
+ "no Error",
+ "unexpected EOF",
+ "read Error",
+ "write Error",
+ "bad midifile: 'MTrk' expected",
+ "bad midifile: 'MThd' expected",
+ "bad midi fileformat",
+ };
+
+enum ERROR {
+ MF_NO_ERROR,
+ MF_EOF,
+ MF_READ,
+ MF_WRITE,
+ MF_MTRK,
+ MF_MTHD,
+ MF_FORMAT,
+ };
+
+//---------------------------------------------------------
+// error
+//---------------------------------------------------------
+
+QString MidiFile::error()
+ {
+ return QString(errString[_error]);
+ }
+
+//---------------------------------------------------------
+// MidiFile
+//---------------------------------------------------------
+
+MidiFile::MidiFile()
+ {
+ fp = 0;
+ curPos = 0;
+ _error = MF_NO_ERROR;
+ _tracks = new MidiFileTrackList;
+ _midiType = MT_GENERIC;
+ }
+
+MidiFile::~MidiFile()
+ {
+ delete _tracks;
+ }
+
+//---------------------------------------------------------
+// read
+// return true on error
+//---------------------------------------------------------
+
+bool MidiFile::read(void* p, size_t len)
+ {
+ for (;;) {
+ curPos += len;
+ qint64 rv = fp->read((char*)p, len);
+ if (rv == len)
+ return false;
+ if (fp->atEnd()) {
+ _error = MF_EOF;
+ return true;
+ }
+ _error = MF_READ;
+ return true;
+ }
+ return false;
+ }
+
+//---------------------------------------------------------
+// write
+// return true on error
+//---------------------------------------------------------
+
+bool MidiFile::write(const void* p, size_t len)
+ {
+ qint64 rv = fp->write((char*)p, len);
+ if (rv == len)
+ return false;
+ _error = MF_WRITE;
+ return true;
+ }
+
+//---------------------------------------------------------
+// writeShort
+// return true on error
+//---------------------------------------------------------
+
+bool MidiFile::writeShort(int i)
+ {
+ short format = BE_SHORT(i);
+ return write(&format, 2);
+ }
+
+//---------------------------------------------------------
+// writeLong
+// return true on error
+//---------------------------------------------------------
+
+bool MidiFile::writeLong(int i)
+ {
+ int format = BE_LONG(i);
+ return write(&format, 4);
+ }
+
+//---------------------------------------------------------
+// readShort
+//---------------------------------------------------------
+
+int MidiFile::readShort()
+ {
+ short format;
+ read(&format, 2);
+ return BE_SHORT(format);
+ }
+
+//---------------------------------------------------------
+// readLong
+// writeLong
+//---------------------------------------------------------
+
+int MidiFile::readLong()
+ {
+ int format;
+ read(&format, 4);
+ return BE_LONG(format);
+ }
+
+/*---------------------------------------------------------
+ * skip
+ * This is meant for skipping a few bytes in a
+ * file or fifo.
+ *---------------------------------------------------------*/
+
+bool MidiFile::skip(size_t len)
+ {
+ char tmp[len];
+ return read(tmp, len);
+ }
+
+/*---------------------------------------------------------
+ * getvl
+ * Read variable-length number (7 bits per byte, MSB first)
+ *---------------------------------------------------------*/
+
+int MidiFile::getvl()
+ {
+ int l = 0;
+ for (int i = 0; i < 16; i++) {
+ uchar c;
+ if (read(&c, 1))
+ return -1;
+ l += (c & 0x7f);
+ if (!(c & 0x80))
+ return l;
+ l <<= 7;
+ }
+ return -1;
+ }
+
+/*---------------------------------------------------------
+ * putvl
+ * Write variable-length number (7 bits per byte, MSB first)
+ *---------------------------------------------------------*/
+
+void MidiFile::putvl(unsigned val)
+ {
+ unsigned long buf = val & 0x7f;
+ while ((val >>= 7) > 0) {
+ buf <<= 8;
+ buf |= 0x80;
+ buf += (val & 0x7f);
+ }
+ for (;;) {
+ put(buf);
+ if (buf & 0x80)
+ buf >>= 8;
+ else
+ break;
+ }
+ }
+
+//---------------------------------------------------------
+// readTrack
+// return true on error
+//---------------------------------------------------------
+
+bool MidiFile::readTrack(MidiFileTrack* t)
+ {
+ MidiEventList* el = &(t->events);
+ char tmp[4];
+ if (read(tmp, 4))
+ return true;
+ if (memcmp(tmp, "MTrk", 4)) {
+ _error = MF_MTRK;
+ return true;
+ }
+ int len = readLong(); // len
+ int endPos = curPos + len;
+ status = -1;
+ sstatus = -1; // running status, not reset scanning meta or sysex
+ click = 0;
+
+ int port = 0;
+ int channel = 0;
+
+ for (;;) {
+ MidiEvent event;
+ lastport = -1;
+ lastchannel = -1;
+
+ int rv = readEvent(&event, t);
+ if (lastport != -1)
+ port = lastport;
+ if (lastchannel != -1) {
+ channel = lastchannel;
+ if (channel >= MIDI_CHANNELS) {
+ printf("channel %d >= %d, reset to 0\n", port, MIDI_CHANNELS);
+ channel = 0;
+ }
+ }
+ if (rv == 0)
+ break;
+ else if (rv == -1)
+ continue;
+ else if (rv == -2) // error
+ return true;
+
+//TODO3 event.setPort(port);
+ if (event.type() == ME_SYSEX || event.type() == ME_META)
+ event.setChannel(channel);
+ else
+ channel = event.channel();
+ el->insert(event);
+ }
+ int end = curPos;
+ if (end != endPos) {
+ printf("MidiFile::readTrack(): TRACKLEN does not fit %d+%d != %d, %d too much\n",
+ endPos-len, len, end, endPos-end);
+ if (end < endPos)
+ skip(endPos - end);
+ }
+ return false;
+ }
+
+//---------------------------------------------------------
+// readEvent
+// returns:
+// 0 End of track
+// -1 Event filtered
+// -2 Error
+//---------------------------------------------------------
+
+int MidiFile::readEvent(MidiEvent* event, MidiFileTrack* t)
+ {
+ uchar me, type, a, b;
+
+ int nclick = getvl();
+ if (nclick == -1) {
+ printf("readEvent: error 1\n");
+ return 0;
+ }
+ click += nclick;
+ for (;;) {
+ if (read(&me, 1)) {
+ printf("readEvent: error 2\n");
+ return 0;
+ }
+ if (me >= 0xf8 && me <= 0xfe)
+ printf("Midi: Real Time Message 0x%02x??\n", me & 0xff);
+ else
+ break;
+ }
+
+ event->setTime(click);
+ int len;
+ unsigned char* buffer;
+
+ if ((me & 0xf0) == 0xf0) {
+ if (me == 0xf0 || me == 0xf7) {
+ //
+ // SYSEX
+ //
+ status = -1; // no running status
+ len = getvl();
+ if (len == -1) {
+ printf("readEvent: error 3\n");
+ return -2;
+ }
+ buffer = new unsigned char[len];
+ if (read(buffer, len)) {
+ printf("readEvent: error 4\n");
+ delete[] buffer;
+ return -2;
+ }
+ if (buffer[len-1] != 0xf7) {
+ printf("SYSEX endet nicht mit 0xf7!\n");
+ // Forstsetzung folgt?
+ }
+ else
+ --len; // don't count 0xf7
+ event->setType(ME_SYSEX);
+ event->setData(buffer, len);
+
+ if ((len == (signed)gmOnMsgLen) && memcmp(buffer, gmOnMsg, gmOnMsgLen) == 0)
+ _midiType = MT_GM;
+ else if ((len == (signed)gsOnMsgLen) && memcmp(buffer, gsOnMsg, gsOnMsgLen) == 0)
+ _midiType = MT_GS;
+
+ if (buffer[0] == 0x43) { // Yamaha
+ _midiType = MT_XG;
+ int type = buffer[1] & 0xf0;
+ switch (type) {
+ case 0x00: // bulk dump
+ buffer[1] = 0;
+ break;
+ case 0x10:
+ if (buffer[1] != 0x10) {
+ buffer[1] = 0x10; // fix to Device 1
+ }
+ if (len == 7 && buffer[2] == 0x4c && buffer[3] == 0x08 && buffer[5] == 7) {
+ // part mode
+ // 0 - normal
+ // 1 - DRUM
+ // 2 - DRUM 1
+ // 3 - DRUM 2
+ // 4 - DRUM 3
+ // 5 - DRUM 4
+ printf("xg set part mode channel %d to %d\n", buffer[4]+1, buffer[6]);
+ if (buffer[6] != 0)
+ t->isDrumTrack = true;
+ }
+ break;
+ case 0x20:
+ printf("YAMAHA DUMP REQUEST\n");
+ return -1;
+ case 0x30:
+ printf("YAMAHA PARAMETER REQUEST\n");
+ return -1;
+ default:
+ printf("YAMAHA unknown SYSEX: data[2]=%02x\n", buffer[1]);
+ return -1;
+ }
+ }
+ else if (buffer[0] == 0x43) {
+ if (_midiType != MT_XG)
+ _midiType = MT_GS;
+ }
+
+ return 3;
+ }
+ if (me == 0xff) {
+ //
+ // META
+ //
+ status = -1; // no running status
+ if (read(&type, 1)) { // read type
+ printf("readEvent: error 5\n");
+ return -2;
+ }
+ len = getvl(); // read len
+ if (len == -1) {
+ printf("readEvent: error 6\n");
+ return -2;
+ }
+ buffer = new unsigned char[len+1];
+ *buffer = 0;
+ if (len) {
+ if (read(buffer, len)) {
+ printf("readEvent: error 7\n");
+ delete[] buffer;
+ return -2;
+ }
+ buffer[len] = 0;
+ }
+ event->setType(ME_META);
+ event->setData(buffer, len+1);
+ event->setA(type);
+ buffer[len] = 0;
+ switch(type) {
+ case 0x21: // switch port
+ lastport = buffer[0];
+ return 3;
+ case 0x20: // switch channel
+ lastchannel = buffer[0];
+ return 3;
+ case 0x2f: // End of Track
+ delete[] buffer;
+ return 0;
+ default:
+ return 3;
+ }
+ }
+ else {
+ printf("Midi: unknown Message 0x%02x\n", me & 0xff);
+ return -1;
+ }
+ }
+
+ if (me & 0x80) { // status byte
+ status = me;
+ sstatus = status;
+ if (read(&a, 1)) {
+ printf("readEvent: error 9\n");
+ return -2;
+ }
+ a &= 0x7F;
+ }
+ else {
+ if (status == -1) {
+ // Meta events and sysex events cancel running status.
+ // There are some midi files which do not send
+ // status again after this events. Silently assume
+ // old running status.
+
+ if (debugMsg || sstatus == -1)
+ printf("readEvent: no running status, read 0x%02x, old status 0x%02x\n", me, sstatus);
+ if (sstatus == -1)
+ return -1;
+ status = sstatus;
+ }
+ a = me;
+ }
+ b = 0;
+ switch (status & 0xf0) {
+ case ME_NOTEOFF:
+ case ME_NOTEON:
+ case ME_POLYAFTER:
+ case ME_CONTROLLER:
+ case ME_PITCHBEND:
+ if (read(&b, 1)) {
+ printf("readEvent: error 15\n");
+ return -2;
+ }
+ event->setB(b & 0x80 ? 0 : b);
+ break;
+ case ME_PROGRAM:
+ case ME_AFTERTOUCH:
+ break;
+ default: // f1 f2 f3 f4 f5 f6 f7 f8 f9
+ printf("BAD STATUS 0x%02x, me 0x%02x\n", status, me);
+ return -2;
+ }
+ event->setA(a & 0x7f);
+ event->setType(status & 0xf0);
+ event->setChannel(status & 0xf);
+ if ((a & 0x80) || (b & 0x80)) {
+ printf("8'tes Bit in Daten(%02x %02x): tick %d read 0x%02x status:0x%02x\n",
+ a & 0xff, b & 0xff, click, me, status);
+ printf("readEvent: error 16\n");
+ if (b & 0x80) {
+ // Try to fix: interpret as channel byte
+ status = b & 0xf0;
+ sstatus = status;
+ return 3;
+ }
+ return -1;
+ }
+ if (event->type() == ME_PITCHBEND) {
+ int val = (event->dataB() << 7) + event->dataA();
+ val -= 8192;
+ event->setA(val);
+ }
+ return 3;
+ }
+
+//---------------------------------------------------------
+// writeTrack
+//---------------------------------------------------------
+
+bool MidiFile::writeTrack(const MidiFileTrack* t)
+ {
+ const MidiEventList* events = &(t->events);
+ write("MTrk", 4);
+ int lenpos = fp->pos();
+ writeLong(0); // dummy len
+
+ status = -1;
+ int tick = 0;
+ for (iMidiEvent i = events->begin(); i != events->end(); ++i) {
+ int ntick = i->time();
+ if (ntick < tick) {
+ printf("MidiFile::writeTrack: ntick %d < tick %d\n", ntick, tick);
+ ntick = tick;
+ }
+ putvl(((ntick - tick) * config.midiDivision + config.division/2)/config.division);
+ tick = ntick;
+ writeEvent(&(*i));
+ }
+
+ //---------------------------------------------------
+ // write "End Of Track" Meta
+ // write Track Len
+ //
+
+ putvl(0);
+ put(0xff); // Meta
+ put(0x2f); // EOT
+ putvl(0); // len 0
+ int endpos = fp->pos();
+ fp->seek(lenpos);
+ writeLong(endpos-lenpos-4); // tracklen
+ fp->seek(endpos);
+ return false;
+ }
+
+//---------------------------------------------------------
+// writeEvent
+//---------------------------------------------------------
+
+void MidiFile::writeEvent(const MidiEvent* event)
+ {
+ int c = event->channel();
+ int nstat = event->type();
+
+ // we dont save meta data into smf type 0 files:
+
+ if (config.smfFormat == 0 && nstat == ME_META)
+ return;
+
+ nstat |= c;
+ //
+ // running status; except for Sysex- and Meta Events
+ //
+ if (((nstat & 0xf0) != 0xf0) && (nstat != status)) {
+ status = nstat;
+ put(nstat);
+ }
+ switch (event->type()) {
+ case ME_NOTEOFF:
+ case ME_NOTEON:
+ case ME_POLYAFTER:
+ case ME_CONTROLLER:
+ case ME_PITCHBEND:
+ put(event->dataA());
+ put(event->dataB());
+ break;
+ case ME_PROGRAM: // Program Change
+ case ME_AFTERTOUCH: // Channel Aftertouch
+ put(event->dataA());
+ break;
+ case ME_SYSEX:
+ put(0xf0);
+ putvl(event->len() + 1); // including 0xf7
+ write(event->data(), event->len());
+ put(0xf7);
+ status = -1; // invalidate running status
+ break;
+ case ME_META:
+ put(0xff);
+ put(event->dataA());
+ putvl(event->len());
+ write(event->data(), event->len());
+ status = -1;
+ break;
+ }
+ }
+
+//---------------------------------------------------------
+// write
+// returns true on error
+//---------------------------------------------------------
+
+bool MidiFile::write(QFile* _fp)
+ {
+ fp = _fp;
+ write("MThd", 4);
+ writeLong(6); // header len
+ writeShort(format);
+ if (format == 0) {
+ // ?? writeShort(1);
+ MidiFileTrack dst;
+ for (iMidiFileTrack i = _tracks->begin(); i != _tracks->end(); ++i) {
+ MidiEventList* sl = &((*i)->events);
+ for (iMidiEvent ie = sl->begin(); ie != sl->end(); ++ie)
+ dst.events.insert(*ie);
+ }
+ writeShort(1);
+ writeShort(_division);
+ writeTrack(&dst);
+ }
+ else {
+ writeShort(_tracks->size());
+ writeShort(_division);
+ for (ciMidiFileTrack i = _tracks->begin(); i != _tracks->end(); ++i)
+ writeTrack(*i);
+ }
+ return false; // (ferror(fp) != 0);
+ }
+
+//---------------------------------------------------------
+// readMidi
+// returns true on error
+//---------------------------------------------------------
+
+bool MidiFile::read(QFile* _fp)
+ {
+ fp = _fp;
+ _error = MF_NO_ERROR;
+ int i;
+ char tmp[4];
+
+ if (read(tmp, 4))
+ return true;
+ int len = readLong();
+ if (memcmp(tmp, "MThd", 4) || len < 6) {
+ _error = MF_MTHD;
+ return true;
+ }
+ format = readShort();
+ ntracks = readShort();
+ _division = readShort();
+
+ if (_division < 0)
+ _division = (-(_division/256)) * (_division & 0xff);
+ if (len > 6)
+ skip(len-6); // skip excess bytes
+
+ switch (format) {
+ case 0:
+ {
+ MidiFileTrack* t = new MidiFileTrack;
+ _tracks->push_back(t);
+ if (readTrack(t))
+ return true;
+ }
+ break;
+ case 1:
+ for (i = 0; i < ntracks; i++) {
+ MidiFileTrack* t = new MidiFileTrack;
+ _tracks->push_back(t);
+ if (readTrack(t))
+ return true;
+ }
+ break;
+ default:
+ _error = MF_FORMAT;
+ return true;
+ }
+ return false;
+ }
+
diff --git a/muse_qt4_evolution/muse/midifile.h b/muse_qt4_evolution/muse/midifile.h
new file mode 100644
index 00000000..dd51a7d3
--- /dev/null
+++ b/muse_qt4_evolution/muse/midifile.h
@@ -0,0 +1,121 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __MIDIFILE_H__
+#define __MIDIFILE_H__
+
+#include "globaldefs.h"
+#include "midievent.h"
+
+struct MidiEventList;
+class MidiEvent;
+
+//---------------------------------------------------------
+// MidiFileTrack
+//---------------------------------------------------------
+
+struct MidiFileTrack {
+ MidiEventList events;
+ bool isDrumTrack;
+ MidiFileTrack() {
+ isDrumTrack = false;
+ }
+ };
+
+typedef std::list<MidiFileTrack*> MidiFileTrackList;
+typedef MidiFileTrackList::iterator iMidiFileTrack;
+typedef MidiFileTrackList::const_iterator ciMidiFileTrack;
+
+//---------------------------------------------------------
+// MidiFile
+//---------------------------------------------------------
+
+class MidiFile {
+ int _error;
+ int format; // smf file format
+ int ntracks; // number of midi tracks
+ int _division;
+ MidiInstrumentType _midiType;
+ MidiFileTrackList* _tracks;
+
+ int status, click;
+ int sstatus;
+ int lastport, lastchannel;
+ QFile* fp;
+ int curPos;
+
+ bool read(void*, size_t);
+ bool write(const void*, size_t);
+ void put(unsigned char c) { write(&c, 1); }
+ bool skip(size_t);
+ int readShort();
+ bool writeShort(int);
+ int readLong();
+ bool writeLong(int);
+ int getvl();
+ void putvl(unsigned);
+
+ bool readTrack(MidiFileTrack*);
+ bool writeTrack(const MidiFileTrack*);
+
+ int readEvent(MidiEvent*, MidiFileTrack*);
+ void writeEvent(const MidiEvent*);
+
+ public:
+ MidiFile();
+ ~MidiFile();
+ bool read(QFile* f);
+ bool write(QFile* f);
+ QString error();
+ MidiFileTrackList* trackList() { return _tracks; }
+ int tracks() const { return ntracks; }
+ void setTrackList(MidiFileTrackList* tr) {
+ _tracks = tr;
+ }
+ void setDivision(int d) { _division = d; }
+ int division() const { return _division; }
+ void setFormat(int val) { format = val; }
+ MidiInstrumentType midiType() const { return _midiType; }
+ };
+
+#define XCHG_SHORT(x) ((((x)&0xFF)<<8) | (((x)>>8)&0xFF))
+#ifdef __i486__
+#define XCHG_LONG(x) \
+ ({ int __value; \
+ asm ("bswap %1; movl %1,%0" : "=g" (__value) : "r" (x)); \
+ __value; })
+#else
+#define XCHG_LONG(x) ((((x)&0xFF)<<24) | \
+ (((x)&0xFF00)<<8) | \
+ (((x)&0xFF0000)>>8) | \
+ (((x)>>24)&0xFF))
+#endif
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define BE_SHORT(x) XCHG_SHORT(x)
+#define BE_LONG(x) XCHG_LONG(x)
+#else
+#define BE_SHORT(x) x
+#define BE_LONG(x) x
+#endif
+
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/midiinport.cpp b/muse_qt4_evolution/muse/midiinport.cpp
new file mode 100644
index 00000000..afe53876
--- /dev/null
+++ b/muse_qt4_evolution/muse/midiinport.cpp
@@ -0,0 +1,241 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "song.h"
+#include "midiplugin.h"
+#include "midi.h"
+#include "midictrl.h"
+#include "al/xml.h"
+#include "audiodev.h"
+#include "audio.h"
+#include "gconfig.h"
+#include "midiinport.h"
+#include "jackaudio.h"
+
+//---------------------------------------------------------
+// MidiInPort
+//---------------------------------------------------------
+
+MidiInPort::MidiInPort()
+ : MidiTrackBase()
+ {
+ _channels = 1;
+ for (int i = 0; i < MIDI_CHANNELS; ++i)
+ activity[i] = 0;
+ }
+
+//---------------------------------------------------------
+// MidiInPort
+//---------------------------------------------------------
+
+MidiInPort::~MidiInPort()
+ {
+ }
+
+//---------------------------------------------------------
+// setName
+//---------------------------------------------------------
+
+void MidiInPort::setName(const QString& s)
+ {
+ Track::setName(s);
+ if (!jackPort(0).isZero())
+ audioDriver->setPortName(jackPort(), s);
+ }
+
+//---------------------------------------------------------
+// MidiInPort::write
+//---------------------------------------------------------
+
+void MidiInPort::write(Xml& xml) const
+ {
+ xml.stag("MidiInPort");
+ MidiTrackBase::writeProperties(xml);
+ xml.etag("MidiInPort");
+ }
+
+//---------------------------------------------------------
+// MidiInPort::read
+//---------------------------------------------------------
+
+void MidiInPort::read(QDomNode node)
+ {
+ while (!node.isNull()) {
+ QDomElement e = node.toElement();
+ QString tag(e.tagName());
+ if (MidiTrackBase::readProperties(node))
+ printf("MusE:MidiInPort: unknown tag %s\n", tag.toLatin1().data());
+ node = node.nextSibling();
+ }
+ }
+
+//---------------------------------------------------------
+// midiReceived
+// called from midiSeq context
+//---------------------------------------------------------
+
+void MidiInPort::eventReceived(jack_midi_event_t* ev)
+ {
+ MidiEvent event;
+ event.setB(0);
+
+ //
+ // move all events 2*segmentSize into the future to get
+ // jitterfree playback
+ //
+ // cycle n-1 n n+1
+ // -+----------+----------+----------+-
+ // ^ ^ ^
+ // catch process play
+ //
+ const SeqTime* st = audio->seqTime();
+
+// unsigned curFrame = st->startFrame() + segmentSize;
+ unsigned curFrame = st->lastFrameTime;
+ event.setTime(curFrame + ev->time);
+
+ event.setChannel(*(ev->buffer) & 0xf);
+ int type = *(ev->buffer) & 0xf0;
+ int a = *(ev->buffer + 1) & 0x7f;
+ int b = *(ev->buffer + 2) & 0x7f;
+ event.setType(type);
+ switch(type) {
+ case ME_NOTEON:
+ case ME_NOTEOFF:
+ case ME_CONTROLLER:
+ event.setA(*(ev->buffer + 1));
+ event.setB(*(ev->buffer + 2));
+ break;
+ case ME_PROGRAM:
+ case ME_AFTERTOUCH:
+ event.setA(*(ev->buffer + 1));
+ break;
+
+ case ME_PITCHBEND:
+ event.setA(((b << 7) + a) - 8192);
+ break;
+
+ case ME_SYSEX:
+ {
+ int type = *(ev->buffer) & 0xff;
+ switch(type) {
+ case ME_SYSEX:
+ event.setTime(0); // mark as used
+ event.setType(ME_SYSEX);
+ event.setData((unsigned char*)(ev->buffer + 1),
+ ev->size - 2);
+ break;
+ case ME_CLOCK:
+ case ME_SENSE:
+ break;
+ default:
+ printf("unknown event 0x%02x\n", type);
+ return;
+ }
+ }
+ return;
+ }
+
+ if (midiInputTrace) {
+ printf("MidiInput<%s>: ", name().toLatin1().data());
+ event.dump();
+ }
+ //
+ // process midi filter pipeline and add event to
+ // _recordEvents
+ //
+
+ MidiEventList il, ol;
+ il.insert(event);
+ pipeline()->apply(st->curTickPos, st->nextTickPos, &il, &ol);
+
+ //
+ // update midi activity
+ // notify gui of new events
+ //
+
+ for (iMidiEvent i = ol.begin(); i != ol.end(); ++i) {
+ triggerActivity(i->channel());
+ song->putEvent(*i);
+ if (recordFifo.put(*i))
+ printf("MusE: eventReceived(): fifo overflow\n");
+ }
+ }
+
+//---------------------------------------------------------
+// afterProcess
+// clear all recorded events after a process cycle
+//---------------------------------------------------------
+
+void MidiInPort::afterProcess()
+ {
+ while (tmpRecordCount--)
+ recordFifo.remove();
+ }
+
+//---------------------------------------------------------
+// beforeProcess
+// "freeze" fifo for this process cycle
+//---------------------------------------------------------
+
+void MidiInPort::beforeProcess()
+ {
+ if (!jackPort(0).isZero())
+ audioDriver->collectMidiEvents(this, jackPort(0));
+ tmpRecordCount = recordFifo.getSize();
+ }
+
+//---------------------------------------------------------
+// getEvents
+// called from jack process context
+// This method can be called multiple times in a process
+// cycle so we have to empty the fifo at
+// "afterProcess()".
+//---------------------------------------------------------
+
+void MidiInPort::getEvents(unsigned, unsigned, int ch, MidiEventList* dst)
+ {
+ for (int i = 0; i < tmpRecordCount; ++i) {
+ const MidiEvent& ev = recordFifo.peek(i);
+ if (ch == -1 || (ev.channel() == ch))
+ dst->insert(ev);
+ }
+ }
+
+//---------------------------------------------------------
+// checkActivity
+//---------------------------------------------------------
+
+bool MidiInPort::checkActivity(int channel)
+ {
+ if (activity[channel])
+ --activity[channel];
+ return activity[channel] != 0;
+ }
+
+//---------------------------------------------------------
+// triggerActivity
+//---------------------------------------------------------
+
+void MidiInPort::triggerActivity(int channel)
+ {
+ activity[channel] = config.guiRefresh / 5 + 1; // hold for >= 1/5 sec
+ }
+
diff --git a/muse_qt4_evolution/muse/midiinport.h b/muse_qt4_evolution/muse/midiinport.h
new file mode 100644
index 00000000..899ee0a8
--- /dev/null
+++ b/muse_qt4_evolution/muse/midiinport.h
@@ -0,0 +1,67 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __MIDIINPORT_H__
+#define __MIDIINPORT_H__
+
+#include "midififo.h"
+#include "miditrackbase.h"
+#include "midievent.h"
+
+static const int RECORD_FIFO_SIZE = 512;
+
+//---------------------------------------------------------
+// MidiInPort
+//---------------------------------------------------------
+
+class MidiInPort : public MidiTrackBase {
+ Q_OBJECT
+
+ MidiFifo recordFifo;
+
+ int tmpRecordCount;
+ int activity[MIDI_CHANNELS];
+
+ public:
+ MidiInPort();
+ ~MidiInPort();
+ virtual TrackType type() const { return MIDI_IN; }
+
+ virtual void setName(const QString& s);
+ virtual void write(Xml&) const;
+ virtual void read(QDomNode);
+ virtual bool isMute() const { return _mute; }
+ virtual Part* newPart(Part*, bool) { return 0; }
+
+ void eventReceived(jack_midi_event_t*);
+
+ virtual void getEvents(unsigned from, unsigned to, int channel, MidiEventList* dst);
+ void beforeProcess();
+ void afterProcess();
+ bool checkActivity(int channel);
+ void triggerActivity(int channel);
+ };
+
+typedef QList<MidiInPort*> MidiInPortList;
+typedef MidiInPortList::iterator iMidiInPort;
+typedef MidiInPortList::const_iterator ciMidiInPort;
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/midiout.cpp b/muse_qt4_evolution/muse/midiout.cpp
new file mode 100644
index 00000000..c35f115f
--- /dev/null
+++ b/muse_qt4_evolution/muse/midiout.cpp
@@ -0,0 +1,398 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "midiout.h"
+#include "midictrl.h"
+#include "miditrackbase.h"
+#include "al/al.h"
+#include "al/tempo.h"
+#include "event.h"
+#include "sync.h"
+#include "audio.h"
+#include "gconfig.h"
+
+static const unsigned char mmcDeferredPlayMsg[] = { 0x7f, 0x7f, 0x06, 0x03 };
+static const unsigned char mmcStopMsg[] = { 0x7f, 0x7f, 0x06, 0x01 };
+
+//---------------------------------------------------------
+// MidiOut
+//---------------------------------------------------------
+
+MidiOut::MidiOut()
+ {
+ track = 0;
+ }
+
+//---------------------------------------------------------
+// sendGmOn
+// send GM-On message to midi device and keep track
+// of device state
+//---------------------------------------------------------
+
+void MidiOut::sendGmOn()
+ {
+ sendSysex(gmOnMsg, gmOnMsgLen);
+ track->setHwCtrlState(CTRL_PROGRAM, 0);
+ track->setHwCtrlState(CTRL_PITCH, 0);
+ track->setHwCtrlState(CTRL_VOLUME, 100);
+ track->setHwCtrlState(CTRL_PANPOT, 64);
+ track->setHwCtrlState(CTRL_REVERB_SEND, 40);
+ track->setHwCtrlState(CTRL_CHORUS_SEND, 0);
+ track->setMeter(0, 0.0);
+ }
+
+//---------------------------------------------------------
+// sendGsOn
+// send Roland GS-On message to midi device and keep track
+// of device state
+//---------------------------------------------------------
+
+void MidiOut::sendGsOn()
+ {
+ static unsigned char data2[] = { 0x41, 0x10, 0x42, 0x12, 0x40, 0x01, 0x33, 0x50, 0x3c };
+ static unsigned char data3[] = { 0x41, 0x10, 0x42, 0x12, 0x40, 0x01, 0x34, 0x50, 0x3b };
+
+ sendSysex(data2, sizeof(data2));
+ sendSysex(data3, sizeof(data3));
+ }
+
+//---------------------------------------------------------
+// sendXgOn
+// send Yamaha XG-On message to midi device and keep track
+// of device state
+//---------------------------------------------------------
+
+void MidiOut::sendXgOn()
+ {
+ sendSysex(xgOnMsg, xgOnMsgLen);
+ track->setHwCtrlState(CTRL_PROGRAM, 0);
+ track->setHwCtrlState(CTRL_MODULATION, 0);
+ track->setHwCtrlState(CTRL_PORTAMENTO_TIME, 0);
+ track->setHwCtrlState(CTRL_VOLUME, 0x64);
+ track->setHwCtrlState(CTRL_PANPOT, 0x40);
+ track->setHwCtrlState(CTRL_EXPRESSION, 0x7f);
+ track->setHwCtrlState(CTRL_SUSTAIN, 0x0);
+ track->setHwCtrlState(CTRL_PORTAMENTO, 0x0);
+ track->setHwCtrlState(CTRL_SOSTENUTO, 0x0);
+ track->setHwCtrlState(CTRL_SOFT_PEDAL, 0x0);
+ track->setHwCtrlState(CTRL_HARMONIC_CONTENT, 0x40);
+ track->setHwCtrlState(CTRL_RELEASE_TIME, 0x40);
+ track->setHwCtrlState(CTRL_ATTACK_TIME, 0x40);
+ track->setHwCtrlState(CTRL_BRIGHTNESS, 0x40);
+ track->setHwCtrlState(CTRL_REVERB_SEND, 0x28);
+ track->setHwCtrlState(CTRL_CHORUS_SEND, 0x0);
+ track->setHwCtrlState(CTRL_VARIATION_SEND, 0x0);
+ track->setMeter(0, 0.0);
+ }
+
+//---------------------------------------------------------
+// sendSysex
+// send SYSEX message to midi device
+//---------------------------------------------------------
+
+void MidiOut::sendSysex(const unsigned char* p, int n)
+ {
+ MidiEvent event(0, ME_SYSEX, p, n);
+ track->routeEvent(event);
+ }
+
+//---------------------------------------------------------
+// sendStart
+//---------------------------------------------------------
+
+void MidiOut::sendStart()
+ {
+ MidiEvent event(0, 0, ME_START, 0, 0);
+ track->routeEvent(event);
+ }
+
+//---------------------------------------------------------
+// sendStop
+//---------------------------------------------------------
+
+void MidiOut::sendStop()
+ {
+ MidiEvent event(0, 0, ME_STOP, 0, 0);
+ track->routeEvent(event);
+ }
+
+//---------------------------------------------------------
+// sendClock
+//---------------------------------------------------------
+
+void MidiOut::sendClock()
+ {
+ MidiEvent event(0, 0, ME_CLOCK, 0, 0);
+ track->routeEvent(event);
+ }
+
+//---------------------------------------------------------
+// sendContinue
+//---------------------------------------------------------
+
+void MidiOut::sendContinue()
+ {
+ MidiEvent event(0, 0, ME_CONTINUE, 0, 0);
+ track->routeEvent(event);
+ }
+
+//---------------------------------------------------------
+// sendSongpos
+//---------------------------------------------------------
+
+void MidiOut::sendSongpos(int pos)
+ {
+ MidiEvent event(0, 0, ME_SONGPOS, pos, 0);
+ track->routeEvent(event);
+ }
+
+//---------------------------------------------------------
+// playMidiEvent
+// called from GUI
+//---------------------------------------------------------
+
+void MidiOut::playMidiEvent(MidiEvent* ev)
+ {
+ if (eventFifo.put(*ev))
+ printf("MidiPort::playMidiEvent(): port overflow, drop event\n");
+ }
+
+//---------------------------------------------------------
+// seek
+//---------------------------------------------------------
+
+void MidiOut::seek(unsigned tickPos, unsigned framePos)
+ {
+ if (genMCSync && track->sendSync()) {
+ int beat = (tickPos * 4) / config.division;
+ sendStop();
+ sendSongpos(beat);
+ sendContinue();
+ }
+ if (track->mute())
+ return;
+
+// if (pos == 0 && !song->record())
+// audio->initDevices();
+
+ //---------------------------------------------------
+ // stop all notes
+ //---------------------------------------------------
+
+ for (iMidiEvent i = _schedEvents.begin(); i != _schedEvents.end(); ++i) {
+ MidiEvent ev = *i;
+ if (ev.isNoteOff()) {
+ ev.setTime(framePos);
+ track->routeEvent(ev);
+ }
+ }
+ _schedEvents.clear();
+
+ //---------------------------------------------------
+ // set all controller
+ //---------------------------------------------------
+
+ if (track->autoRead()) {
+ CtrlList* cl = track->controller();
+ for (iCtrl ic = cl->begin(); ic != cl->end(); ++ic) {
+ Ctrl* c = ic->second;
+ int val = c->value(tickPos).i;
+ if ((val != CTRL_VAL_UNKNOWN) && (c->curVal().i != val)) {
+ MidiEvent ev(0, -1, ME_CONTROLLER, c->id(), val);
+ track->routeEvent(ev);
+ c->setCurVal(val);
+ }
+ }
+ }
+ foreach (const Route& r, *track->inRoutes()) {
+ MidiTrackBase* t = (MidiTrackBase*)r.src.track;
+ int dstChannel = r.dst.channel;
+ if (t->isMute() || !t->autoRead())
+ continue;
+ CtrlList* cl = t->controller();
+ for (iCtrl ic = cl->begin(); ic != cl->end(); ++ic) {
+ Ctrl* c = ic->second;
+ int val = c->value(tickPos).i;
+ if ((val != CTRL_VAL_UNKNOWN) && (c->curVal().i != val)) {
+ MidiEvent ev(0, dstChannel, ME_CONTROLLER, c->id(), val);
+ track->routeEvent(ev);
+ c->setCurVal(val);
+ }
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// stop
+//---------------------------------------------------------
+
+void MidiOut::stop()
+ {
+ //---------------------------------------------------
+ // stop all notes
+ //---------------------------------------------------
+
+ int time = audio->seqTime()->lastFrameTime;
+ for (iMidiEvent i = _schedEvents.begin(); i != _schedEvents.end(); ++i) {
+ MidiEvent ev = *i;
+ if (ev.isNoteOff()) {
+ ev.setTime(time);
+ track->routeEvent(ev);
+ }
+ }
+ _schedEvents.clear();
+
+ //---------------------------------------------------
+ // reset sustain
+ //---------------------------------------------------
+
+ foreach (const Route& r, *track->inRoutes()) {
+ MidiTrackBase* t = (MidiTrackBase*)r.src.track;
+ int dstChannel = r.dst.channel;
+ if (t->isMute() || !t->autoRead())
+ continue;
+ CtrlList* cl = t->controller();
+ for (iCtrl ic = cl->begin(); ic != cl->end(); ++ic) {
+ Ctrl* c = ic->second;
+ if (c->id() == CTRL_SUSTAIN) {
+ if (c->curVal().i > 0) {
+ MidiEvent ev(time, dstChannel, ME_CONTROLLER, c->id(), 0);
+ track->routeEvent(ev);
+ c->setCurVal(0);
+ }
+ }
+ }
+ }
+
+ if (track->sendSync()) {
+ if (genMMC) {
+ unsigned char mmcPos[] = {
+ 0x7f, 0x7f, 0x06, 0x44, 0x06, 0x01,
+ 0, 0, 0, 0, 0
+ };
+ double frame = double(audio->seqTime()->pos.frame());
+ MTC mtc(frame / double(AL::sampleRate));
+ mmcPos[6] = mtc.h() | (AL::mtcType << 5);
+ mmcPos[7] = mtc.m();
+ mmcPos[8] = mtc.s();
+ mmcPos[9] = mtc.f();
+ mmcPos[10] = mtc.sf();
+ sendSysex(mmcStopMsg, sizeof(mmcStopMsg));
+ sendSysex(mmcPos, sizeof(mmcPos));
+ }
+ if (genMCSync) { // Midi Clock
+ // send STOP and
+ // "set song position pointer"
+ sendStop();
+ sendSongpos(audio->seqTime()->curTickPos * 4 / config.division);
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// start
+//---------------------------------------------------------
+
+void MidiOut::start()
+ {
+ // TODO: set sustain to old value?
+
+ if (!(genMMC || genMCSync || track->sendSync()))
+ return;
+ if (genMMC)
+ sendSysex(mmcDeferredPlayMsg, sizeof(mmcDeferredPlayMsg));
+ if (genMCSync) {
+ if (audio->seqTime()->curTickPos)
+ sendContinue();
+ else
+ sendStart();
+ }
+ }
+
+//---------------------------------------------------------
+// reset
+//---------------------------------------------------------
+
+void MidiOut::reset()
+ {
+/* TODO
+ MidiEvent ev;
+ ev.setType(0x90);
+ for (int chan = 0; chan < MIDI_CHANNELS; ++chan) {
+ ev.setChannel(chan);
+ for (int pitch = 0; pitch < 128; ++pitch) {
+ ev.setA(pitch);
+ ev.setB(0);
+ mp->putEvent(ev);
+ }
+ }
+*/
+ }
+
+//-------------------------------------------------------------------
+// process
+// Collect all midi events for the current process cycle and put
+// into _schedEvents queue. For note on events create the proper
+// note off events. The note off events maybe played later after the
+// current process cycle.
+// From _schedEvents queue copy all events for the current cycle
+// to all output routes. Events routed to ALSA go into the
+// _playEvents queue which is processed by the MidiSeq thread.
+//-------------------------------------------------------------------
+
+void MidiOut::processMidi(MidiEventList& el, const SeqTime* time)
+ {
+ while (!eventFifo.isEmpty())
+ el.insert(eventFifo.get());
+
+ // collect port controller
+ if (track->autoRead() && (time->curTickPos != time->nextTickPos)) { // if rolling
+ CtrlList* cl = track->controller();
+ for (iCtrl ic = cl->begin(); ic != cl->end(); ++ic) {
+ Ctrl* c = ic->second;
+ iCtrlVal is = c->lowerBound(time->curTickPos);
+ iCtrlVal ie = c->lowerBound(time->nextTickPos);
+ for (iCtrlVal ic = is; ic != ie; ++ic) {
+ unsigned frame = AL::tempomap.tick2frame(ic.key());
+ MidiEvent ev(frame, -1, ME_CONTROLLER, c->id(), ic.value().i);
+ el.insert(ev);
+ c->setCurVal(ic.value().i);
+ }
+ }
+ }
+ foreach (const Route& r, *track->inRoutes()) {
+ MidiTrackBase* t = (MidiTrackBase*)r.src.track;
+ int dstChannel = r.dst.channel;
+ if (t->isMute())
+ continue;
+ MidiEventList ell;
+ t->getEvents(time->curTickPos, time->nextTickPos, r.src.channel, &ell);
+ int velo = 0;
+ for (iMidiEvent i = ell.begin(); i != ell.end(); ++i) {
+ MidiEvent ev(*i);
+ ev.setChannel(dstChannel);
+ el.insert(ev);
+ if (ev.type() == ME_NOTEON)
+ velo += ev.dataB();
+ }
+ t->addMidiMeter(velo);
+ }
+ }
+
diff --git a/muse_qt4_evolution/muse/midiout.h b/muse_qt4_evolution/muse/midiout.h
new file mode 100644
index 00000000..8bf25261
--- /dev/null
+++ b/muse_qt4_evolution/muse/midiout.h
@@ -0,0 +1,67 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __MIDIOUT_H__
+#define __MIDIOUT_H__
+
+#include "midififo.h"
+
+class Track;
+class MidiInstrument;
+class SeqTime;
+
+//---------------------------------------------------------
+// MidiOut
+//---------------------------------------------------------
+
+class MidiOut
+ {
+ public:
+ Track* track;
+ MidiInstrument* _instrument;
+ MidiEventList _schedEvents; // scheduled events by process()
+
+ // fifo for midi events send from gui
+ // direct to midi port:
+
+ MidiFifo eventFifo;
+
+ MidiOut();
+ void processMidi(MidiEventList&, const SeqTime*);
+
+ void seek(unsigned, unsigned);
+ void stop();
+ void start();
+ void reset();
+
+ void sendSysex(const unsigned char*, int);
+ void sendSongpos(int);
+ void sendGmOn();
+ void sendGsOn();
+ void sendXgOn();
+ void sendStart();
+ void sendStop();
+ void sendContinue();
+ void sendClock();
+ void playMidiEvent(MidiEvent* ev);
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/midioutport.cpp b/muse_qt4_evolution/muse/midioutport.cpp
new file mode 100644
index 00000000..695f51a6
--- /dev/null
+++ b/muse_qt4_evolution/muse/midioutport.cpp
@@ -0,0 +1,262 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "song.h"
+#include "midiplugin.h"
+#include "midictrl.h"
+#include "al/al.h"
+#include "al/tempo.h"
+#include "al/xml.h"
+#include "audiodev.h"
+#include "audio.h"
+#include "midioutport.h"
+#include "sync.h"
+#include "gconfig.h"
+#include "instruments/minstrument.h"
+
+//---------------------------------------------------------
+// MidiOutPort
+//---------------------------------------------------------
+
+MidiOutPort::MidiOutPort()
+ : MidiTrackBase()
+ {
+ track = this;
+ _instrument = genericMidiInstrument;
+ setDeviceId(127); // all
+ addMidiController(_instrument, CTRL_MASTER_VOLUME);
+ _channels = 1;
+ }
+
+//---------------------------------------------------------
+// MidiOutPort
+//---------------------------------------------------------
+
+MidiOutPort::~MidiOutPort()
+ {
+ }
+
+//---------------------------------------------------------
+// setName
+//---------------------------------------------------------
+
+void MidiOutPort::setName(const QString& s)
+ {
+ Track::setName(s);
+ if (!jackPort().isZero())
+ audioDriver->setPortName(jackPort(), s);
+ }
+
+//---------------------------------------------------------
+// MidiOutPort::write
+//---------------------------------------------------------
+
+void MidiOutPort::write(Xml& xml) const
+ {
+ xml.stag("MidiOutPort");
+ MidiTrackBase::writeProperties(xml);
+ if (_instrument)
+ xml.tag("instrument", _instrument->iname());
+ xml.tag("sendSync", sendSync());
+ xml.tag("deviceId", deviceId());
+ xml.etag("MidiOutPort");
+ }
+
+//---------------------------------------------------------
+// MidiOutPort::read
+//---------------------------------------------------------
+
+void MidiOutPort::read(QDomNode node)
+ {
+ for (; !node.isNull(); node = node.nextSibling()) {
+ QDomElement e = node.toElement();
+ QString tag(e.tagName());
+ if (tag == "instrument") {
+ QString iname = e.text();
+ _instrument = registerMidiInstrument(iname);
+ }
+ else if (tag == "sendSync")
+ setSendSync(e.text().toInt());
+ else if (tag == "deviceId")
+ setDeviceId(e.text().toInt());
+ else if (MidiTrackBase::readProperties(node))
+ printf("MusE:MidiOutPort: unknown tag %s\n", tag.toLatin1().data());
+ }
+ }
+
+//---------------------------------------------------------
+// routeEvent
+//---------------------------------------------------------
+
+void MidiOutPort::routeEvent(const MidiEvent& event)
+ {
+ for (iRoute r = _outRoutes.begin(); r != _outRoutes.end(); ++r) {
+ if (r->dst.type == RouteNode::JACKMIDIPORT)
+ queueJackEvent(event);
+ else
+ fprintf(stderr, "MidiOutPort::process(): invalid routetype\n");
+ }
+ }
+
+//---------------------------------------------------------
+// queueJackEvent
+// called from MidiSeq
+//---------------------------------------------------------
+
+#define JO(e) audioDriver->putEvent(jackPort(0), e);
+
+void MidiOutPort::queueJackEvent(const MidiEvent& ev)
+ {
+ if (ev.type() == ME_CONTROLLER) {
+ int a = ev.dataA();
+ int b = ev.dataB();
+ int chn = ev.channel();
+ unsigned t = ev.time();
+
+ if (a == CTRL_PITCH) {
+ int v = b + 8192;
+ audioDriver->putEvent(jackPort(0), MidiEvent(t, chn, ME_PITCHBEND, v & 0x7f, (v >> 7) & 0x7f));
+ }
+ else if (a == CTRL_PROGRAM) {
+ // don't output program changes for GM drum channel
+// if (!(song->mtype() == MT_GM && chn == 9)) {
+ int hb = (b >> 16) & 0xff;
+ int lb = (b >> 8) & 0xff;
+ int pr = b & 0x7f;
+ if (hb != 0xff)
+ JO(MidiEvent(t, chn, ME_CONTROLLER, CTRL_HBANK, hb));
+ if (lb != 0xff)
+ JO(MidiEvent(t+1, chn, ME_CONTROLLER, CTRL_LBANK, lb));
+ JO(MidiEvent(t+2, chn, ME_PROGRAM, pr, 0));
+// }
+ }
+ else if (a == CTRL_MASTER_VOLUME) {
+ unsigned char sysex[] = {
+ 0x7f, 0x7f, 0x04, 0x01, 0x00, 0x00
+ };
+ sysex[1] = deviceId();
+ sysex[4] = b & 0x7f;
+ sysex[5] = (b >> 7) & 0x7f;
+ JO(MidiEvent(t, ME_SYSEX, sysex, 6));
+ }
+ else if (a < CTRL_14_OFFSET) { // 7 Bit Controller
+ JO(ev);
+ }
+ else if (a < CTRL_RPN_OFFSET) { // 14 bit high resolution controller
+ int ctrlH = (a >> 8) & 0x7f;
+ int ctrlL = a & 0x7f;
+ int dataH = (b >> 7) & 0x7f;
+ int dataL = b & 0x7f;
+ JO(MidiEvent(t, chn, ME_CONTROLLER, ctrlH, dataH));
+ JO(MidiEvent(t+1, chn, ME_CONTROLLER, ctrlL, dataL));
+ }
+ else if (a < CTRL_NRPN_OFFSET) { // RPN 7-Bit Controller
+ int ctrlH = (a >> 8) & 0x7f;
+ int ctrlL = a & 0x7f;
+ JO(MidiEvent(t, chn, ME_CONTROLLER, CTRL_HRPN, ctrlH));
+ JO(MidiEvent(t+1, chn, ME_CONTROLLER, CTRL_LRPN, ctrlL));
+ JO(MidiEvent(t+2, chn, ME_CONTROLLER, CTRL_HDATA, b));
+ }
+ else if (a < CTRL_RPN14_OFFSET) { // NRPN 7-Bit Controller
+ int ctrlH = (a >> 8) & 0x7f;
+ int ctrlL = a & 0x7f;
+ JO(MidiEvent(t, chn, ME_CONTROLLER, CTRL_HNRPN, ctrlH));
+ JO(MidiEvent(t+1, chn, ME_CONTROLLER, CTRL_LNRPN, ctrlL));
+ JO(MidiEvent(t+2, chn, ME_CONTROLLER, CTRL_HDATA, b));
+ }
+ else if (a < CTRL_NRPN14_OFFSET) { // RPN14 Controller
+ int ctrlH = (a >> 8) & 0x7f;
+ int ctrlL = a & 0x7f;
+ int dataH = (b >> 7) & 0x7f;
+ int dataL = b & 0x7f;
+ JO(MidiEvent(t, chn, ME_CONTROLLER, CTRL_HRPN, ctrlH));
+ JO(MidiEvent(t+1, chn, ME_CONTROLLER, CTRL_LRPN, ctrlL));
+ JO(MidiEvent(t+2, chn, ME_CONTROLLER, CTRL_HDATA, dataH));
+ JO(MidiEvent(t+3, chn, ME_CONTROLLER, CTRL_LDATA, dataL));
+ }
+ else if (a < CTRL_NONE_OFFSET) { // NRPN14 Controller
+ int ctrlH = (a >> 8) & 0x7f;
+ int ctrlL = a & 0x7f;
+ int dataH = (b >> 7) & 0x7f;
+ int dataL = b & 0x7f;
+ JO(MidiEvent(t, chn, ME_CONTROLLER, CTRL_HNRPN, ctrlH));
+ JO(MidiEvent(t+1, chn, ME_CONTROLLER, CTRL_LNRPN, ctrlL));
+ JO(MidiEvent(t+2, chn, ME_CONTROLLER, CTRL_HDATA, dataH));
+ JO(MidiEvent(t+3, chn, ME_CONTROLLER, CTRL_LDATA, dataL));
+ }
+ else {
+ printf("putEvent: unknown controller type 0x%x\n", a);
+ }
+ }
+ else {
+ JO(ev);
+ }
+ }
+#undef JO
+
+//---------------------------------------------------------
+// setInstrument
+//---------------------------------------------------------
+
+void MidiOutPort::setInstrument(MidiInstrument* i)
+ {
+ _instrument = i;
+ emit instrumentChanged();
+ }
+
+//-------------------------------------------------------------------
+// process
+// Collect all midi events for the current process cycle and put
+// into _schedEvents queue. For note on events create the proper
+// note off events. The note off events maybe played after the
+// current process cycle.
+// From _schedEvents queue copy all events for the current cycle
+// to all output routes.
+//-------------------------------------------------------------------
+
+void MidiOutPort::processMidi(const SeqTime* t)
+ {
+ if (track->mute())
+ return;
+
+ MidiEventList el;
+ MidiOut::processMidi(el, t);
+
+ pipeline()->apply(t->curTickPos, t->nextTickPos, &el, &_schedEvents);
+
+ //
+ // route events to destination
+ //
+
+ int portVelo = 0;
+ unsigned endFrame = t->lastFrameTime + segmentSize;
+ iMidiEvent i = _schedEvents.begin();
+
+ for (; i != _schedEvents.end(); ++i) {
+ if (i->time() >= endFrame)
+ break;
+ routeEvent(*i);
+ if (i->type() == ME_NOTEON)
+ portVelo += i->dataB();
+ }
+ _schedEvents.erase(_schedEvents.begin(), i);
+ addMidiMeter(portVelo);
+ }
+
diff --git a/muse_qt4_evolution/muse/midioutport.h b/muse_qt4_evolution/muse/midioutport.h
new file mode 100644
index 00000000..31529349
--- /dev/null
+++ b/muse_qt4_evolution/muse/midioutport.h
@@ -0,0 +1,70 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __MIDIOUTPORT_H__
+#define __MIDIOUTPORT_H__
+
+#include "miditrackbase.h"
+#include "midiout.h"
+
+struct SeqTime;
+
+//---------------------------------------------------------
+// MidiOutPort
+//---------------------------------------------------------
+
+class MidiOutPort : public MidiTrackBase, public MidiOut {
+ Q_OBJECT
+
+ MidiInstrument* _instrument;
+ void routeEvent(const MidiEvent&);
+ void queueAlsaEvent(const MidiEvent& event);
+ void queueJackEvent(const MidiEvent& event);
+
+ signals:
+ void instrumentChanged();
+
+ public:
+ MidiOutPort();
+ ~MidiOutPort();
+ virtual TrackType type() const { return MIDI_OUT; }
+
+ virtual void setName(const QString& s);
+ virtual void write(Xml&) const;
+ virtual void read(QDomNode);
+ virtual bool isMute() const { return _mute; }
+ virtual Part* newPart(Part*, bool) { return 0; }
+
+ virtual MidiInstrument* instrument() { return _instrument; }
+ virtual MidiOut* midiOut() { return this; }
+ void setInstrument(MidiInstrument* i);
+
+ bool guiVisible() const;
+ bool hasGui() const;
+
+ virtual void processMidi(const SeqTime*);
+ };
+
+typedef QList<MidiOutPort*> MidiOutPortList;
+typedef MidiOutPortList::iterator iMidiOutPort;
+typedef MidiOutPortList::const_iterator ciMidiOutPort;
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/midiplugin.cpp b/muse_qt4_evolution/muse/midiplugin.cpp
new file mode 100644
index 00000000..1d13828d
--- /dev/null
+++ b/muse_qt4_evolution/muse/midiplugin.cpp
@@ -0,0 +1,625 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include <dlfcn.h>
+
+#include "al/al.h"
+#include "al/xml.h"
+#include "al/tempo.h"
+#include "al/sig.h"
+#include "midiplugin.h"
+#include "ctrl.h"
+#include "midiplugins/libmidiplugin/mempi.h"
+#include "audio.h"
+#include "gconfig.h"
+
+MidiPluginList midiPlugins;
+
+MempiHost mempiHost;
+
+//---------------------------------------------------------
+// division
+//---------------------------------------------------------
+
+int MempiHost::division() const
+ {
+ return config.division;
+ }
+
+//---------------------------------------------------------
+// tempo
+//---------------------------------------------------------
+
+int MempiHost::tempo(unsigned tick) const
+ {
+ return AL::tempomap.tempo(tick);
+ }
+
+//---------------------------------------------------------
+// tick2frame
+//---------------------------------------------------------
+
+unsigned MempiHost::tick2frame(unsigned tick) const
+ {
+ return AL::tempomap.tick2frame(tick);
+ }
+
+//---------------------------------------------------------
+// frame2tick
+//---------------------------------------------------------
+
+unsigned MempiHost::frame2tick(unsigned frame) const
+ {
+ return AL::tempomap.frame2tick(frame);
+ }
+
+//---------------------------------------------------------
+// bar
+//---------------------------------------------------------
+
+void MempiHost::bar(int t, int* bar, int* beat, unsigned* tick) const
+ {
+ AL::sigmap.tickValues(t, bar, beat, tick);
+ }
+
+//---------------------------------------------------------
+// bar2tick
+//---------------------------------------------------------
+
+unsigned MempiHost::bar2tick(int bar, int beat, int tick) const
+ {
+ return AL::sigmap.bar2tick(bar, beat, tick);
+ }
+
+//---------------------------------------------------------
+// MidiPlugin
+//---------------------------------------------------------
+
+MidiPlugin::MidiPlugin(const QFileInfo* f, const MEMPI_Function mf,
+ const MEMPI* d) : fi(*f)
+ {
+ mempi = mf;
+ plugin = d;
+ _instances = 0;
+ }
+
+//---------------------------------------------------------
+// instantiate
+//---------------------------------------------------------
+
+MidiPluginI* MidiPlugin::instantiate(MidiTrackBase* t)
+ {
+ if (plugin == 0) {
+ printf("initMidiPluginInstance: zero plugin\n");
+ return 0;
+ }
+ ++_instances;
+ QString inst("-" + QString::number(_instances));
+ QString s = name() + inst;
+
+ Mempi* m = plugin->instantiate(s.toLatin1().data(), &mempiHost);
+ if (m->init()) {
+ delete m;
+ return 0;
+ }
+ MidiPluginI* mp = new MidiPluginI(this, t, m);
+ return mp;
+ }
+
+bool MidiPlugin::instantiate(MidiPluginI* mp)
+ {
+ if (plugin == 0) {
+ printf("initMidiPluginInstance: zero plugin\n");
+ return 0;
+ }
+ ++_instances;
+ QString inst("-" + QString::number(_instances));
+ QString s = name() + inst;
+
+ Mempi* m = plugin->instantiate(s.toLatin1().data(), &mempiHost);
+ if (m->init()) {
+ delete m;
+ return true;
+ }
+ mp->setMempi(m);
+ return false;
+ }
+
+//---------------------------------------------------------
+// MidiPluginI
+//---------------------------------------------------------
+
+MidiPluginI::MidiPluginI(MidiPlugin* p, MidiTrackBase* t, Mempi* m)
+ {
+ _track = t;
+ _plugin = p;
+ mempi = m;
+ _on = true;
+ }
+
+//---------------------------------------------------------
+// MidiPluginI
+//---------------------------------------------------------
+
+MidiPluginI::MidiPluginI(MidiTrackBase* t)
+ {
+ _track = t;
+ _plugin = 0;
+ mempi = 0;
+ _on = true;
+ }
+
+//---------------------------------------------------------
+// MidiPluginI
+//---------------------------------------------------------
+
+MidiPluginI::~MidiPluginI()
+ {
+ if (mempi)
+ delete mempi;
+ }
+
+//---------------------------------------------------------
+// loadMidiPlugin
+//---------------------------------------------------------
+
+static void loadMidiPlugin(QFileInfo* fi)
+ {
+ if (debugMsg)
+ printf(" load midi plugin <%s>\n", fi->filePath().toAscii().data());
+ void* handle = dlopen(fi->filePath().toLocal8Bit().data(), RTLD_NOW);
+ if (handle == 0) {
+ fprintf(stderr, "loadMidiPlugin::dlopen(%s) failed: %s\n",
+ fi->filePath().toLatin1().data(), dlerror());
+ return;
+ }
+ MEMPI_Function mempi = (MEMPI_Function)dlsym(handle, "mempi_descriptor");
+
+ if (!mempi) {
+ const char *txt = dlerror();
+ if (txt) {
+ fprintf(stderr,
+ "Unable to find mempi_descriptor() function in plugin "
+ "library file \"%s\": %s.\n"
+ "Are you sure this is a MEMPI plugin file?\n",
+ fi->filePath().toLatin1().data(),
+ txt);
+ return;
+ }
+ }
+ const MEMPI* descr = mempi();
+
+ if (descr == 0) {
+ fprintf(stderr, "Mempi::instantiate: no MEMPI descr found\n");
+ return;
+ }
+ if (descr->majorMempiVersion != MEMPI_MAJOR_VERSION) {
+ fprintf(stderr, "Mempi::instantiate: bad MEMPI version %d, expected %d\n",
+ descr->majorMempiVersion, MEMPI_MAJOR_VERSION);
+ return;
+ }
+ midiPlugins.push_back(new MidiPlugin(fi, mempi, descr));
+ }
+
+//---------------------------------------------------------
+// loadMidiPluginDir
+//---------------------------------------------------------
+
+static void loadMidiPluginDir(const QString& s)
+ {
+ if (debugMsg)
+ printf("scan midi plugin dir <%s>\n", s.toLatin1().data());
+#ifdef __APPLE__
+ QDir pluginDir(s, QString("*.dylib"), 0, QDir::Files);
+#else
+ QDir pluginDir(s, QString("*.so"), 0, QDir::Files);
+#endif
+ if (pluginDir.exists()) {
+ QFileInfoList list = pluginDir.entryInfoList();
+ for (int i = 0; i < list.size(); ++i) {
+ QFileInfo fi = list.at(i);
+ loadMidiPlugin(&fi);
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// initMidiPlugins
+// search for midi MEPI plugins
+//---------------------------------------------------------
+
+void initMidiPlugins()
+ {
+ loadMidiPluginDir(museGlobalLib + QString("/midiplugins"));
+ }
+
+//---------------------------------------------------------
+// find
+//---------------------------------------------------------
+
+MidiPlugin* MidiPluginList::find(const QString& /*file*/, const QString& name)
+ {
+ for (iMidiPlugin i = begin(); i != end(); ++i) {
+ if (name == (*i)->name())
+ return *i;
+ }
+ printf("MidiPlugin <%s> not found\n", name.toLatin1().data());
+ return 0;
+ }
+
+//---------------------------------------------------------
+// Pipeline
+//---------------------------------------------------------
+
+MidiPipeline::MidiPipeline()
+ : QList<MidiPluginI*>()
+ {
+ }
+
+//---------------------------------------------------------
+// isOn
+//---------------------------------------------------------
+
+bool MidiPipeline::isOn(int idx) const
+ {
+ MidiPluginI* p = (*this)[idx];
+ if (p)
+ return p->on();
+ return false;
+ }
+
+//---------------------------------------------------------
+// setOn
+//---------------------------------------------------------
+
+void MidiPipeline::setOn(int idx, bool flag)
+ {
+ MidiPluginI* p = (*this)[idx];
+ if (p) {
+ p->setOn(flag);
+ }
+ }
+
+//---------------------------------------------------------
+// name
+//---------------------------------------------------------
+
+QString MidiPipeline::name(int idx) const
+ {
+ MidiPluginI* p = (*this)[idx];
+ if (p)
+ return p->name();
+ return QString("empty");
+ }
+
+#if 0
+//---------------------------------------------------------
+// empty
+//---------------------------------------------------------
+
+bool MidiPipeline::empty(int idx) const
+ {
+ MidiPluginI* p = (*this)[idx];
+ return p == 0;
+ }
+#endif
+
+//---------------------------------------------------------
+// move
+//---------------------------------------------------------
+
+void MidiPipeline::move(int idx, bool up)
+ {
+ MidiPluginI* p1 = (*this)[idx];
+ if (up) {
+ (*this)[idx] = (*this)[idx-1];
+ (*this)[idx-1] = p1;
+ }
+ else {
+ (*this)[idx] = (*this)[idx+1];
+ (*this)[idx+1] = p1;
+ }
+ }
+
+//---------------------------------------------------------
+// showGui
+//---------------------------------------------------------
+
+void MidiPipeline::showGui(int idx, bool flag)
+ {
+ MidiPluginI* p = (*this)[idx];
+ if (p)
+ p->showGui(flag);
+ }
+
+//---------------------------------------------------------
+// guiVisible
+//---------------------------------------------------------
+
+bool MidiPipeline::guiVisible(int idx) const
+ {
+ MidiPluginI* p = (*this)[idx];
+ if (p)
+ return p->guiVisible();
+ return false;
+ }
+
+//---------------------------------------------------------
+// hasGui
+//---------------------------------------------------------
+
+bool MidiPipeline::hasGui(int idx) const
+ {
+ MidiPluginI* p = (*this)[idx];
+ if (p)
+ return p->hasGui();
+ return false;
+ }
+
+//---------------------------------------------------------
+// apply
+//---------------------------------------------------------
+
+void MidiPipeline::apply(unsigned from, unsigned to, MidiEventList* il, MidiEventList* ool)
+ {
+ MidiEventList oList;
+ MidiEventList* ol = &oList;
+
+ bool swap = true;
+ for (iMidiPluginI i = begin(); i != end(); ++i) {
+ MidiPluginI* p = *i;
+ if (p == 0 || !p->on())
+ continue;
+ if (swap) {
+ ol->clear();
+ p->apply(from, to, il, ol);
+ }
+ else {
+ il->clear();
+ p->apply(from, to, ol, il);
+ }
+ swap = !swap;
+ }
+ MidiEventList* l = swap ? il : ol;
+ for (iMidiEvent i = l->begin(); i != l->end(); ++i)
+ ool->insert(*i);
+ }
+
+//---------------------------------------------------------
+// apply
+//---------------------------------------------------------
+
+void MidiPluginI::apply(unsigned from, unsigned to, MidiEventList* il, MidiEventList* ol)
+ {
+ mempi->process(from, to, il, ol);
+ }
+
+//---------------------------------------------------------
+// saveConfiguration
+//---------------------------------------------------------
+
+void MidiPluginI::writeConfiguration(Xml& xml)
+ {
+ xml.stag(QString("midiPlugin file=\"%1\" name=\"%2\"")
+ .arg(_plugin->lib()).arg(_plugin->name()));
+ if (_on == false)
+ xml.tag("on", _on);
+ if (mempi->hasGui()) {
+ xml.tag("guiVisible", mempi->guiVisible());
+ int x, y, w, h;
+ w = 0;
+ h = 0;
+ mempi->getGeometry(&x, &y, &w, &h);
+ if (h || w)
+ xml.tag("geometry", QRect(x, y, w, h));
+ }
+
+ //---------------------------------------------
+ // dump current state of plugin
+ //---------------------------------------------
+
+ int len = 0;
+ const unsigned char* p;
+ mempi->getInitData(&len, &p);
+ if (len) {
+ xml.stag(QString("init len=\"%1\"").arg(len));
+ xml.dump(len, p);
+ xml.etag("init");
+ }
+ xml.etag("midiPlugin");
+ }
+
+//---------------------------------------------------------
+// readConfiguration
+// return true on error
+//---------------------------------------------------------
+
+bool MidiPluginI::readConfiguration(QDomNode node)
+ {
+ QDomElement e = node.toElement();
+ QString file = e.attribute("file");
+ QString label = e.attribute("name");
+
+ if (_plugin == 0) {
+ _plugin = midiPlugins.find(file, label);
+ if (_plugin == 0)
+ return true;
+ if (_plugin->instantiate(this))
+ return true;
+ }
+ node = node.firstChild();
+ while (!node.isNull()) {
+ e = node.toElement();
+ int i = e.text().toInt();
+ QString tag(e.tagName());
+ if (tag == "on") {
+ bool flag = i;
+ _on = flag;
+ }
+ else if (tag == "guiVisible") {
+ showGui(i);
+ }
+ else if (tag == "geometry") {
+ QRect r(AL::readGeometry(node));
+ mempi->setGeometry(r.x(), r.y(), r.width(), r.height());
+ }
+ else if (tag == "init") {
+ int len = e.attribute("len","0").toInt();
+ if (len) {
+ const char* s = e.text().toLatin1().data();
+ unsigned char data[len];
+ unsigned char* d = data;
+ int numberBase = 16;
+ for (int i = 0; i < len; ++i) {
+ char* endp;
+ *d++ = strtol(s, &endp, numberBase);
+ s = endp;
+ if (s == 0)
+ break;
+ }
+ mempi->setInitData(len, data);
+ }
+ }
+ else
+ printf("MusE:MidiPluginI: unknown tag %s\n", e.tagName().toLatin1().data());
+ node = node.nextSibling();
+ }
+ return false;
+ }
+
+//---------------------------------------------------------
+// showGui
+//---------------------------------------------------------
+
+void MidiPluginI::showGui()
+ {
+ mempi->showGui(!mempi->guiVisible());
+ }
+
+void MidiPluginI::showGui(bool flag)
+ {
+ mempi->showGui(flag);
+ }
+
+//---------------------------------------------------------
+// guiVisible
+//---------------------------------------------------------
+
+bool MidiPluginI::guiVisible() const
+ {
+ return mempi->guiVisible();
+ }
+
+//---------------------------------------------------------
+// MidiPluginDialog
+//---------------------------------------------------------
+
+MidiPluginDialog::MidiPluginDialog(QWidget* parent)
+ : QDialog(parent)
+ {
+ resize(QSize(550, 300));
+ setModal(true);
+ setWindowTitle(tr("MusE: select midi plugin"));
+ QVBoxLayout* layout = new QVBoxLayout(this);
+
+ pList = new QTreeWidget(this);
+ pList->setIndentation(0);
+ pList->setColumnCount(4);
+ pList->setSortingEnabled(true);
+ pList->setSelectionBehavior(QAbstractItemView::SelectRows);
+ pList->setSelectionMode(QAbstractItemView::SingleSelection);
+ pList->setAlternatingRowColors(true);
+
+ QStringList headerLabels;
+
+ headerLabels << tr("File") << tr("Name") << tr("Version") << tr("Description");
+ pList->header()->resizeSection(0, 100);
+ pList->header()->resizeSection(1, 120);
+ pList->header()->resizeSection(2, 70);
+ pList->header()->setResizeMode(3, QHeaderView::Stretch);
+ pList->setHeaderLabels(headerLabels);
+
+ fillPlugs();
+
+ layout->addWidget(pList);
+
+ //---------------------------------------------------
+ // Ok/Cancel Buttons
+ //---------------------------------------------------
+
+ QBoxLayout* w5 = new QHBoxLayout;
+ layout->addLayout(w5);
+
+ QPushButton* okB = new QPushButton(tr("Ok"));
+ QPushButton* cancelB = new QPushButton(tr("Cancel"));
+ okB->setFixedWidth(80);
+ cancelB->setFixedWidth(80);
+ okB->setDefault(true);
+ w5->addStretch(100);
+ w5->addWidget(okB);
+ w5->addWidget(cancelB);
+
+ connect(pList, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), SLOT(accept()));
+ connect(cancelB, SIGNAL(clicked()), SLOT(reject()));
+ connect(okB, SIGNAL(clicked()), SLOT(accept()));
+ }
+
+//---------------------------------------------------------
+// getPlugin
+//---------------------------------------------------------
+
+MidiPlugin* MidiPluginDialog::getPlugin(QWidget* parent)
+ {
+ MidiPluginDialog* dialog = new MidiPluginDialog(parent);
+ if (dialog->exec())
+ return dialog->value();
+ return 0;
+ }
+
+//---------------------------------------------------------
+// value
+//---------------------------------------------------------
+
+MidiPlugin* MidiPluginDialog::value()
+ {
+ QTreeWidgetItem* item = pList->selectedItems().at(0);
+ if (item)
+ return midiPlugins.find(item->text(0), item->text(1));
+ return 0;
+ }
+
+//---------------------------------------------------------
+// fillPlugs
+//---------------------------------------------------------
+
+void MidiPluginDialog::fillPlugs()
+ {
+ pList->clear();
+ for (iMidiPlugin i = midiPlugins.begin(); i != midiPlugins.end(); ++i) {
+ if ((*i)->type() != MEMPI_FILTER)
+ continue;
+ QTreeWidgetItem* item = new QTreeWidgetItem;
+ item->setText(0, (*i)->lib());
+ item->setText(1, (*i)->name());
+ item->setText(2, (*i)->version());
+ item->setText(3, (*i)->description());
+ pList->addTopLevelItem(item);
+ }
+ }
diff --git a/muse_qt4_evolution/muse/midiplugin.h b/muse_qt4_evolution/muse/midiplugin.h
new file mode 100644
index 00000000..87e91953
--- /dev/null
+++ b/muse_qt4_evolution/muse/midiplugin.h
@@ -0,0 +1,168 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __MIDIPLUGIN_H__
+#define __MIDIPLUGIN_H__
+
+#include "globals.h"
+#include "midiplugins/libmidiplugin/mempi.h"
+
+namespace AL {
+ class Xml;
+ };
+using AL::Xml;
+
+class MidiPluginIF;
+class MidiPluginGui;
+class MidiPluginI;
+class MidiTrackBase;
+class Ctrl;
+class MidiEventList;
+class MidiTrackBase;
+
+typedef const MEMPI* (*MEMPI_Function)();
+
+//---------------------------------------------------------
+// MidiPlugin
+//---------------------------------------------------------
+
+class MidiPlugin {
+ MEMPI_Function mempi;
+ const MEMPI* plugin;
+
+ protected:
+ int _instances;
+ QFileInfo fi;
+
+ public:
+ MidiPlugin(const QFileInfo* f, const MEMPI_Function, const MEMPI* d);
+ virtual ~MidiPlugin() {}
+
+ int instances() const { return _instances; }
+ virtual void incInstances(int val) { _instances += val; }
+
+ QString lib() const { return fi.baseName(); }
+ QString path() const { return fi.absolutePath(); }
+ QString name() const { return QString(plugin->name); }
+ QString description() const { return QString(plugin->description); }
+ QString version() const { return QString(plugin->version); }
+ MempiType type() const { return plugin->type; }
+ MidiPluginI* instantiate(MidiTrackBase*);
+ bool instantiate(MidiPluginI*);
+ };
+
+//---------------------------------------------------------
+// MidiPluginList
+//---------------------------------------------------------
+
+typedef QList<MidiPlugin*>::iterator iMidiPlugin;
+
+class MidiPluginList : public QList<MidiPlugin*> {
+ public:
+ MidiPlugin* find(const QString&, const QString&);
+ MidiPluginList() {}
+ };
+
+//---------------------------------------------------------
+// MidiPluginI
+// plugin instance
+//---------------------------------------------------------
+
+class MidiPluginI {
+ MidiPlugin* _plugin;
+ Mempi* mempi;
+
+ MidiTrackBase* _track;
+ bool _on;
+
+ public:
+ MidiPluginI(MidiPlugin*, MidiTrackBase*, Mempi*);
+ MidiPluginI(MidiTrackBase*);
+ ~MidiPluginI();
+
+ void setMempi(Mempi* m) { mempi = m; }
+
+ MidiPlugin* plugin() const { return _plugin; }
+ bool on() const { return _on; }
+ void setOn(bool val) { _on = val; }
+ void apply(unsigned, unsigned, MidiEventList*, MidiEventList*);
+
+ QString name() const { return QString(mempi->name()); }
+ QString lib() const { return _plugin->lib(); }
+ MidiTrackBase* track() const { return _track; }
+ void getGeometry(int*x, int*y, int* w, int* h) const { mempi->getGeometry(x, y, w, h); }
+ void setGeometry(int x, int y, int w, int h) { mempi->setGeometry(x, y, w, h); }
+ void writeConfiguration(Xml& xml);
+ bool readConfiguration(QDomNode);
+
+ void showGui();
+ void showGui(bool);
+ bool hasGui() const { return mempi->hasGui(); }
+ bool guiVisible() const;
+ void getInitData(int* len, const unsigned char** p) { mempi->getInitData(len, p); }
+ void setInitData(int len, const unsigned char* p) { mempi->setInitData(len, p); }
+ };
+
+//---------------------------------------------------------
+// Pipeline
+// chain of connected efx inserts
+//---------------------------------------------------------
+
+class MidiPipeline : public QList<MidiPluginI*> {
+ public:
+ MidiPipeline();
+ bool isOn(int idx) const;
+ void setOn(int, bool);
+ QString name(int idx) const;
+ void showGui(int, bool);
+ bool guiVisible(int) const;
+ bool hasGui(int) const;
+ void apply(unsigned, unsigned, MidiEventList*, MidiEventList*);
+ void move(int idx, bool up);
+ };
+
+typedef MidiPipeline::iterator iMidiPluginI;
+typedef MidiPipeline::const_iterator ciMidiPluginI;
+
+//---------------------------------------------------------
+// MidiPluginDialog
+//---------------------------------------------------------
+
+class MidiPluginDialog : public QDialog {
+ QTreeWidget* pList;
+
+ Q_OBJECT
+
+ public:
+ MidiPluginDialog(QWidget* parent=0);
+ static MidiPlugin* getPlugin(QWidget* parent);
+ MidiPlugin* value();
+
+ public slots:
+ void fillPlugs();
+ };
+
+static const int MidiPipelineDepth = 4;
+
+extern void initMidiPlugins();
+extern MidiPluginList midiPlugins;
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/midiportinfo.ui b/muse_qt4_evolution/muse/midiportinfo.ui
new file mode 100644
index 00000000..ad8ae201
--- /dev/null
+++ b/muse_qt4_evolution/muse/midiportinfo.ui
@@ -0,0 +1,92 @@
+<ui version="4.0" >
+ <class>MidiPortInfoBase</class>
+ <widget class="QWidget" name="MidiPortInfoBase" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>142</width>
+ <height>96</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle" >
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <property name="horizontalSpacing" >
+ <number>0</number>
+ </property>
+ <property name="verticalSpacing" >
+ <number>0</number>
+ </property>
+ <item row="0" column="0" colspan="2" >
+ <widget class="QComboBox" name="instrument" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize" >
+ <size>
+ <width>16777215</width>
+ <height>24</height>
+ </size>
+ </property>
+ <property name="toolTip" >
+ <string>Midi Instrument</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QSpinBox" name="deviceId" >
+ <property name="maximumSize" >
+ <size>
+ <width>16777215</width>
+ <height>24</height>
+ </size>
+ </property>
+ <property name="maximum" >
+ <number>127</number>
+ </property>
+ <property name="value" >
+ <number>127</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label" >
+ <property name="maximumSize" >
+ <size>
+ <width>16777215</width>
+ <height>24</height>
+ </size>
+ </property>
+ <property name="text" >
+ <string>Device-Id:</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/muse_qt4_evolution/muse/midirack.cpp b/muse_qt4_evolution/muse/midirack.cpp
new file mode 100644
index 00000000..0b054729
--- /dev/null
+++ b/muse_qt4_evolution/muse/midirack.cpp
@@ -0,0 +1,208 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "icons.h"
+#include "gconfig.h"
+#include "midirack.h"
+#include "track.h"
+#include "song.h"
+#include "midiplugin.h"
+#include "audio.h"
+#include "muse.h"
+#include "gui.h"
+
+//---------------------------------------------------------
+// MidiRack
+//---------------------------------------------------------
+
+MidiRack::MidiRack(QWidget* parent, MidiTrackBase* t)
+ : QListWidget(parent)
+ {
+ setUniformItemSizes(true);
+ setAlternatingRowColors(true);
+ setAttribute(Qt::WA_DeleteOnClose, true);
+ verticalScrollBar()->setStyle(smallStyle);
+ track = t;
+// setFont(config.fonts[1]);
+
+ setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+
+ setSelectionMode(QAbstractItemView::SingleSelection);
+ songChanged(SC_RACK); // force update
+ connect(this, SIGNAL(itemDoubleClicked(QListWidgetItem*)),
+ this, SLOT(doubleClicked(QListWidgetItem*)));
+ connect(song, SIGNAL(songChanged(int)), SLOT(songChanged(int)));
+ setToolTip(tr("midi effect rack"));
+ }
+
+//---------------------------------------------------------
+// sizeHint
+//---------------------------------------------------------
+
+QSize MidiRack::sizeHint() const
+ {
+ QFontMetrics fm(font());
+ int h = fm.lineSpacing() * MidiPipelineDepth + 1;
+ return QSize(STRIP_WIDTH, h);
+ }
+
+//---------------------------------------------------------
+// songChanged
+//---------------------------------------------------------
+
+void MidiRack::songChanged(int typ)
+ {
+ if (typ & (SC_ROUTE | SC_RACK)) {
+ clear();
+ foreach(MidiPluginI* plugin, *(track->pipeline())) {
+ QListWidgetItem* item = new QListWidgetItem;
+ item->setText(plugin->name());
+ // tooltip should only be set if name does not fit
+ // (is elided)
+ item->setToolTip(plugin->name());
+ item->setBackgroundColor(plugin->on() ? Qt::white : Qt::gray);
+ addItem(item);
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// contextMenuEvent
+//---------------------------------------------------------
+
+void MidiRack::contextMenuEvent(QContextMenuEvent* ev)
+ {
+ QPoint pt(ev->pos());
+ QListWidgetItem* item = itemAt(pt);
+ MidiPipeline* pipe = track->pipeline();
+
+ QMenu* menu = new QMenu;
+ QAction* upAction = menu->addAction(QIcon(*upIcon), tr("move up"));
+ QAction* downAction = menu->addAction(QIcon(*downIcon), tr("move down"));
+ QAction* removeAction = menu->addAction(tr("remove"));
+ QAction* bypassAction = menu->addAction(tr("bypass"));
+ QAction* showAction = menu->addAction(tr("show gui"));
+ QAction* newAction = menu->addAction(tr("new"));
+ bypassAction->setCheckable(true);
+ showAction->setCheckable(true);
+
+ int idx = -1;
+ if (item == 0) {
+ upAction->setEnabled(false);
+ downAction->setEnabled(false);
+ removeAction->setEnabled(false);
+ bypassAction->setEnabled(false);
+ showAction->setEnabled(false);
+ }
+ else {
+ idx = row(item);
+ upAction->setEnabled(idx != 0);
+ downAction->setEnabled(idx < (pipe->size() - 1));
+ showAction->setEnabled(pipe->hasGui(idx));
+ bypassAction->setEnabled(true);
+ bypassAction->setChecked(!pipe->isOn(idx));
+ showAction->setChecked(pipe->guiVisible(idx));
+ }
+
+ QAction* sel = menu->exec(mapToGlobal(pt), newAction);
+ delete menu;
+ if (sel == 0)
+ return;
+
+ if (sel == newAction) {
+ selectNew();
+ return;
+ }
+ if (sel == removeAction) {
+ audio->msgAddMidiPlugin(track, idx, 0);
+ }
+ else if (sel == bypassAction) {
+ bool flag = !pipe->isOn(idx);
+ pipe->setOn(idx, flag);
+ }
+ else if (sel == showAction) {
+ bool flag = !pipe->guiVisible(idx);
+ pipe->showGui(idx, flag);
+ }
+ else if (sel == upAction) {
+ if (idx > 0) {
+ setCurrentRow(idx-1);
+ pipe->move(idx, true);
+ }
+ }
+ else if (sel == downAction) {
+ if (idx < (pipe->size() - 1)) {
+ setCurrentRow(idx+1);
+ pipe->move(idx, false);
+ }
+ }
+ song->update(SC_RACK);
+ }
+
+//---------------------------------------------------------
+// doubleClicked
+// toggle gui
+//---------------------------------------------------------
+
+void MidiRack::doubleClicked(QListWidgetItem* it)
+ {
+ if (track == 0)
+ return;
+ int idx = row(it);
+ MidiPipeline* pipe = track->pipeline();
+ bool flag = !pipe->guiVisible(idx);
+ pipe->showGui(idx, flag);
+ song->update(SC_RACK);
+ }
+
+//---------------------------------------------------------
+// mouseDoubleClickEvent
+//---------------------------------------------------------
+
+void MidiRack::mouseDoubleClickEvent(QMouseEvent* event)
+ {
+ QListWidgetItem* it = itemAt(event->pos());
+ if (it || (track == 0)) {
+ QListWidget::mouseDoubleClickEvent(event);
+ return;
+ }
+ selectNew();
+ }
+
+//---------------------------------------------------------
+// selectNew
+//---------------------------------------------------------
+
+void MidiRack::selectNew()
+ {
+ MidiPlugin* plugin = MidiPluginDialog::getPlugin(this);
+ if (plugin) {
+ MidiPluginI* plugi = plugin->instantiate(track);
+ if (plugi == 0) {
+ printf("cannot instantiate plugin <%s>\n",
+ plugin->name().toLatin1().data());
+ delete plugi;
+ }
+ else
+ audio->msgAddMidiPlugin(track, track->pipeline()->size(), plugi);
+ song->update(SC_RACK);
+ }
+ }
+
diff --git a/muse_qt4_evolution/muse/midirack.h b/muse_qt4_evolution/muse/midirack.h
new file mode 100644
index 00000000..7f83ca42
--- /dev/null
+++ b/muse_qt4_evolution/muse/midirack.h
@@ -0,0 +1,48 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __MIDIRACK_H__
+#define __MIDIRACK_H__
+
+class MidiTrackBase;
+
+//---------------------------------------------------------
+// MidiRack
+//---------------------------------------------------------
+
+class MidiRack : public QListWidget {
+ MidiTrackBase* track;
+ Q_OBJECT
+
+ virtual void contextMenuEvent(QContextMenuEvent*);
+ virtual void mouseDoubleClickEvent(QMouseEvent*);
+ void selectNew();
+
+ private slots:
+ void doubleClicked(QListWidgetItem*);
+ void songChanged(int);
+
+ public:
+ MidiRack(QWidget*, MidiTrackBase* t);
+ QSize sizeHint() const;
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/midirc.cpp b/muse_qt4_evolution/muse/midirc.cpp
new file mode 100644
index 00000000..14b69d55
--- /dev/null
+++ b/muse_qt4_evolution/muse/midirc.cpp
@@ -0,0 +1,180 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "midirc.h"
+#include "song.h"
+#include "midi.h"
+
+MidiRCList midiRCList;
+
+//---------------------------------------------------------
+// isActive
+//---------------------------------------------------------
+
+bool MidiRCList::isActive(int action)
+ {
+ for (iMidiRC i = begin(); i != end(); ++i) {
+ if (i->action == action)
+ return true;
+ }
+ return false;
+ }
+
+//---------------------------------------------------------
+// setAction
+//---------------------------------------------------------
+
+void MidiRCList::setAction(const MidiEvent& e, int action)
+ {
+ //
+ // TODO: check for already used events
+ //
+ for (iMidiRC i = begin(); i != end(); ++i) {
+ if (i->action == action) {
+// printf("replace action %d: ", action);
+// i->event.dump();
+ i->event = e;
+ return;
+ }
+ }
+ push_back(MidiRC(e, action));
+// printf("add action %d: ", action);
+ e.dump();
+ }
+
+//---------------------------------------------------------
+// emitAction
+//---------------------------------------------------------
+
+void MidiRCList::emitAction(int action) const
+ {
+// printf("emit action %d\n", action);
+ switch(action) {
+ case RC_STOP:
+ song->setStop(true);
+ break;
+ case RC_PLAY:
+ song->setPlay(true);
+ break;
+ case RC_RECORD:
+ song->setRecord(true);
+ break;
+ case RC_GOTO_LEFT_MARK:
+ song->setPos(0, song->lpos(), true, true, true);
+ break;
+ }
+ }
+
+//---------------------------------------------------------
+// doAction
+// emit action associated with event e
+// return true if action found
+//---------------------------------------------------------
+
+bool MidiRCList::doAction(const MidiEvent& e)
+ {
+// printf("MidiRCList::doAction ");
+// e.dump();
+ for (iMidiRC i = begin(); i != end(); ++i) {
+ if ((i->event.type()& 0xf0) == (e.type() & 0xf0)) {
+ //
+ // for note on events only compare pitch, not velocity
+ // ignore note off events (note on with velicity zero
+ //
+ if ((e.type() == ME_NOTEON)
+ && i->event.dataA() == e.dataA()
+ && e.dataB() != 0) {
+ emitAction(i->action);
+ return true;
+ }
+ //
+ // compare controller and controller value
+ // TODO: maybe we need a special option to
+ // ignore the controller value
+ //
+ if ((e.type() == ME_CONTROLLER)
+ && i->event.dataA() == e.dataA()
+ && i->event.dataB() == e.dataB()) {
+ emitAction(i->action);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+//---------------------------------------------------------
+// read
+//---------------------------------------------------------
+
+void MidiRCList::read(QDomNode node)
+ {
+ int action = 0;
+ MidiEvent event;
+ for (node = node.firstChild(); !node.isNull(); node = node.nextSibling()) {
+ QDomElement e = node.toElement();
+ if (e.isNull())
+ continue;
+ if (e.tagName() == "action") {
+ action = e.attribute("id", "0").toInt();
+ for (QDomNode n = node.firstChild(); !n.isNull(); n = n.nextSibling()) {
+ QDomElement e1 = node.toElement();
+ if (e1.isNull())
+ continue;
+ if (e1.tagName() == "noteOn") {
+ event.setType(ME_NOTEON);
+ event.setA(e1.attribute("pitch","0").toInt());
+ }
+ else if (e1.tagName() == "controller") {
+ event.setType(ME_CONTROLLER);
+ event.setA(e1.attribute("no","0").toInt());
+ event.setB(e1.attribute("val","0").toInt());
+ }
+ else
+ printf("MusE:midiRC:action: unknown tag %s\n", e1.tagName().toLatin1().data());
+ }
+ setAction(event, action);
+ }
+ else
+ printf("MusE:midiRC: unknown tag %s\n", e.tagName().toLatin1().data());
+ }
+ }
+
+//---------------------------------------------------------
+// write
+//---------------------------------------------------------
+
+void MidiRCList::write(Xml& xml)
+ {
+ xml.stag("midiRC");
+ for (iMidiRC i = begin(); i != end(); ++i) {
+ xml.stag(QString("action id=\"%1\"").arg(i->action));
+ if (i->event.type() == ME_NOTEON)
+ xml.stag(QString("noteOn pitch=\"%1\"").arg(i->event.dataA()));
+ else if (i->event.type() == ME_CONTROLLER)
+ xml.stag(QString("controller no=\"%1\" val=\"%2\"")
+ .arg(i->event.dataA()).arg(i->event.dataB()));
+ else
+ printf("remote event type %d not supported\n", i->event.type());
+ xml.etag("action");
+ }
+ xml.etag("midiRC");
+ }
+
diff --git a/muse_qt4_evolution/muse/midirc.h b/muse_qt4_evolution/muse/midirc.h
new file mode 100644
index 00000000..670fca63
--- /dev/null
+++ b/muse_qt4_evolution/muse/midirc.h
@@ -0,0 +1,65 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __MIDIRC_H__
+#define __MIDIRC_H__
+
+#include "event.h"
+#include "midievent.h"
+
+enum {
+ RC_STOP, RC_PLAY, RC_RECORD, RC_GOTO_LEFT_MARK
+ };
+
+//---------------------------------------------------------
+// MidiRC
+//---------------------------------------------------------
+
+struct MidiRC {
+ MidiEvent event;
+ int action;
+
+ MidiRC(const MidiEvent& e, int a)
+ : event(e), action(a)
+ {
+ }
+ };
+
+//---------------------------------------------------------
+// MidiRCList
+//---------------------------------------------------------
+
+class MidiRCList : public std::list<MidiRC> {
+
+ void emitAction(int) const;
+
+ public:
+ MidiRCList() {}
+ void setAction(const MidiEvent& e, int action);
+ bool isActive(int action);
+ bool doAction(const MidiEvent&);
+ void read(QDomNode);
+ void write(Xml&);
+ };
+
+typedef MidiRCList::iterator iMidiRC;
+
+extern MidiRCList midiRCList;
+#endif
diff --git a/muse_qt4_evolution/muse/midisynti.cpp b/muse_qt4_evolution/muse/midisynti.cpp
new file mode 100644
index 00000000..b53693af
--- /dev/null
+++ b/muse_qt4_evolution/muse/midisynti.cpp
@@ -0,0 +1,225 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "song.h"
+#include "midi.h"
+#include "midisynti.h"
+#include "midiplugin.h"
+#include "midiplugins/libmidiplugin/mempi.h"
+#include "al/tempo.h"
+
+//---------------------------------------------------------
+// MidiSynti
+//---------------------------------------------------------
+
+MidiSynti::MidiSynti()
+ : MidiTrackBase()
+ {
+ _synti = 0;
+ init();
+ }
+
+MidiSynti::~MidiSynti()
+ {
+ }
+
+//---------------------------------------------------------
+// init
+//---------------------------------------------------------
+
+void MidiSynti::init()
+ {
+ }
+
+//---------------------------------------------------------
+// hasGui
+//---------------------------------------------------------
+
+bool MidiSynti::hasGui() const
+ {
+ return _synti->hasGui();
+ }
+
+//---------------------------------------------------------
+// hasGui
+//---------------------------------------------------------
+
+void MidiSynti::showGui(bool val)
+ {
+ return _synti->showGui(val);
+ }
+
+//---------------------------------------------------------
+// guiVisible
+//---------------------------------------------------------
+
+bool MidiSynti::guiVisible() const
+ {
+ return _synti->guiVisible();
+ }
+
+//---------------------------------------------------------
+// initInstance
+// return true on error
+//---------------------------------------------------------
+
+bool MidiSynti::initInstance(MidiPlugin* plugin)
+ {
+ _synti = plugin->instantiate(this);
+ return _synti == 0;
+ }
+
+//---------------------------------------------------------
+// MidiSynti::write
+//---------------------------------------------------------
+
+void MidiSynti::write(Xml& xml) const
+ {
+ xml.stag("MidiSynti");
+ MidiTrackBase::writeProperties(xml);
+ xml.tag("class", _synti->plugin()->name());
+ if (_synti->hasGui()) {
+ xml.tag("guiVisible", _synti->guiVisible());
+ int x, y, w, h;
+ w = 0;
+ h = 0;
+ _synti->getGeometry(&x, &y, &w, &h);
+ if (h || w)
+ xml.tag("geometry", QRect(x, y, w, h));
+ }
+ //---------------------------------------------
+ // dump current state of plugin
+ //---------------------------------------------
+
+ int len = 0;
+ const unsigned char* p;
+ _synti->getInitData(&len, &p);
+ if (len) {
+ xml.stag(QString("init len=\"%1\"").arg(len));
+ xml.dump(len, p);
+ xml.etag("init");
+ }
+ xml.etag("MidiSynti");
+ }
+
+//---------------------------------------------------------
+// MidiSynti::read
+//---------------------------------------------------------
+
+void MidiSynti::read(QDomNode node)
+ {
+ bool startGui = false;
+ QRect r;
+ QString sclass;
+ unsigned char* data = 0;
+ int len = 0;
+ for (; !node.isNull(); node = node.nextSibling()) {
+ QDomElement e = node.toElement();
+ QString tag(e.tagName());
+ if (tag == "class")
+ sclass = e.text();
+ else if (tag == "guiVisible")
+ startGui = e.text().toInt();
+ else if (tag == "geometry")
+ r = AL::readGeometry(node);
+ else if (tag == "init") {
+ len = e.attribute("len", "0").toInt();
+ if (len) {
+ QStringList l = e.text().simplified().split(" ", QString::SkipEmptyParts);
+ if (len != l.size()) {
+ printf("error converting init string <%s>\n", e.text().toLatin1().data());
+ }
+ data = new unsigned char[len];
+ unsigned char* d = data;
+ int numberBase = 16;
+ for (int i = 0; i < l.size(); ++i) {
+ bool ok;
+ *d++ = l.at(i).toInt(&ok, numberBase);
+ if (!ok)
+ printf("error converting init val <%s>\n", l.at(i).toLatin1().data());
+ }
+ }
+ }
+ else if (MidiTrackBase::readProperties(node))
+ printf("MusE:MidiSynti: unknown tag %s\n", node.toElement().tagName().toLatin1().data());
+ }
+ iMidiPlugin i;
+ for (i = midiPlugins.begin(); i != midiPlugins.end(); ++i) {
+ if ((*i)->type() != MEMPI_GENERATOR)
+ continue;
+ if ((*i)->name() == sclass)
+ break;
+ }
+ if (i == midiPlugins.end()) {
+ fprintf(stderr, "MidiSynti::read: midi plugin not found\n");
+ return;
+ }
+ MidiPlugin* mp = *i;
+ if (initInstance(mp)) {
+ fprintf(stderr, "MidiSynti::read: instantiate failed\n");
+ return;
+ }
+ if (data) {
+ _synti->setInitData(len, data);
+ delete[] data;
+ }
+ song->insertTrack0(this, -1);
+ _synti->showGui(startGui);
+ _synti->setGeometry(r.x(), r.y(), r.width(), r.height());
+ }
+
+//---------------------------------------------------------
+// getEvents
+//---------------------------------------------------------
+
+void MidiSynti::getEvents(unsigned from, unsigned to, int, MidiEventList* dst)
+ {
+ MidiEventList il;
+ foreach(const Route& r, *inRoutes()) {
+ MidiTrackBase* track = (MidiTrackBase*)r.src.track;
+ if (track->isMute())
+ continue;
+ track->getEvents(from, to, r.src.channel, &il);
+ }
+ MidiEventList ol;
+ _synti->apply(from, to, &il, &ol);
+ for (iMidiEvent i = ol.begin(); i != ol.end(); ++i) {
+ MidiEvent ev(*i);
+ if (ev.type() == ME_NOTEON) {
+ _meter[0] += ev.dataB()/2;
+ if (_meter[0] > 127.0f)
+ _meter[0] = 127.0f;
+ }
+ // convert tick-time to sample-time
+ ev.setTime(AL::tempomap.tick2frame(ev.time()));
+ dst->insert(ev);
+ }
+ }
+
+bool MidiSynti::isMute() const
+ {
+ if (_solo)
+ return false;
+ if (song->solo())
+ return true;
+ return _mute;
+ }
+
+
diff --git a/muse_qt4_evolution/muse/midisynti.h b/muse_qt4_evolution/muse/midisynti.h
new file mode 100644
index 00000000..89c77764
--- /dev/null
+++ b/muse_qt4_evolution/muse/midisynti.h
@@ -0,0 +1,62 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __MIDISYNTH_H__
+#define __MIDISYNTH_H__
+
+#include "miditrackbase.h"
+
+//---------------------------------------------------------
+// MidiSynti
+//---------------------------------------------------------
+
+class MidiSynti : public MidiTrackBase {
+ Q_OBJECT
+
+ MidiPluginI* _synti;
+
+ public:
+ MidiSynti();
+ virtual ~MidiSynti();
+ virtual TrackType type() const { return MIDI_SYNTI; }
+
+ void init();
+
+ virtual void read(QDomNode);
+ virtual void write(Xml&) const;
+ virtual bool isMute() const;
+
+ virtual Part* newPart(Part*, bool) { return 0; }
+
+ bool initInstance(MidiPlugin*);
+ virtual void getEvents(unsigned from, unsigned to, int channel, MidiEventList* dst);
+
+ bool hasGui() const;
+ bool guiVisible() const;
+ void showGui(bool);
+ };
+
+
+typedef QList<MidiSynti*> MidiSyntiList;
+typedef MidiSyntiList::iterator iMidiSynti;
+typedef MidiSyntiList::const_iterator ciMidiSynti;
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/miditrack.cpp b/muse_qt4_evolution/muse/miditrack.cpp
new file mode 100644
index 00000000..276eeccb
--- /dev/null
+++ b/muse_qt4_evolution/muse/miditrack.cpp
@@ -0,0 +1,716 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "miditrack.h"
+#include "event.h"
+#include "song.h"
+#include "midi.h"
+#include "midictrl.h"
+#include "audio.h"
+#include "part.h"
+#include "al/tempo.h"
+#include "midiedit/drummap.h"
+
+//---------------------------------------------------------
+// MidiTrack
+//---------------------------------------------------------
+
+MidiTrack::MidiTrack()
+ : MidiTrackBase()
+ {
+ _transposition = 0;
+ _velocity = 0;
+ _delay = 0;
+ _len = 100; // percent
+ _compression = 100; // percent
+
+ initMidiController();
+ recordPart = 0;
+ _drumMap = 0;
+ _useDrumMap = false;
+
+ //
+ // create minimal set of managed controllers
+ // to make midi mixer operational
+ //
+ MidiInstrument* mi = genericMidiInstrument;
+ addMidiController(mi, CTRL_PROGRAM);
+ addMidiController(mi, CTRL_VOLUME);
+ addMidiController(mi, CTRL_PANPOT);
+ addMidiController(mi, CTRL_REVERB_SEND);
+ addMidiController(mi, CTRL_CHORUS_SEND);
+ addMidiController(mi, CTRL_VARIATION_SEND);
+ }
+
+MidiTrack::~MidiTrack()
+ {
+ }
+
+//---------------------------------------------------------
+// newPart
+//---------------------------------------------------------
+
+Part* MidiTrack::newPart(Part* p, bool clone)
+ {
+ Part* part = new Part(this);
+ if (p) {
+ if (clone)
+ part->clone(p->events());
+ else
+ part->ref();
+ part->setName(p->name());
+ part->setColorIndex(p->colorIndex());
+
+ *(AL::PosLen*)part = *(AL::PosLen*)p;
+ part->setMute(p->mute());
+ }
+ else
+ part->ref();
+ return part;
+ }
+
+//---------------------------------------------------------
+// MidiTrack::write
+//---------------------------------------------------------
+
+void MidiTrack::write(Xml& xml) const
+ {
+ xml.stag("miditrack");
+ MidiTrackBase::writeProperties(xml);
+
+ xml.tag("transposition", _transposition);
+ xml.tag("velocity", _velocity);
+ xml.tag("delay", _delay);
+ xml.tag("len", _len);
+ xml.tag("compression", _compression);
+ xml.tag("useDrumMap", _useDrumMap);
+
+ const PartList* pl = parts();
+ for (ciPart p = pl->begin(); p != pl->end(); ++p)
+ p->second->write(xml);
+ xml.etag("miditrack");
+ }
+
+//---------------------------------------------------------
+// MidiTrack::read
+//---------------------------------------------------------
+
+void MidiTrack::read(QDomNode node)
+ {
+ for (; !node.isNull(); node = node.nextSibling()) {
+ QDomElement e = node.toElement();
+ QString tag(e.tagName());
+ QString s(e.text());
+ int i = s.toInt();
+ if (tag == "transposition")
+ _transposition = i;
+ else if (tag == "velocity")
+ _velocity = i;
+ else if (tag == "delay")
+ _delay = i;
+ else if (tag == "len")
+ _len = i;
+ else if (tag == "compression")
+ _compression = i;
+ else if (tag == "part") {
+ Part* p = newPart();
+ p->read(node, true);
+ parts()->add(p);
+ }
+ else if (tag == "locked")
+ _locked = i;
+ else if (tag == "useDrumMap")
+ _useDrumMap = e.text().toInt();
+ else if (MidiTrackBase::readProperties(node))
+ printf("MusE:MidiTrack: unknown tag %s\n", e.tagName().toLatin1().data());
+ }
+ }
+
+//---------------------------------------------------------
+// playMidiEvent
+//---------------------------------------------------------
+
+void MidiTrack::playMidiEvent(MidiEvent* ev)
+ {
+ foreach (const Route& r, _outRoutes) {
+ Track* track = r.dst.track;
+ ev->setChannel(r.dst.channel);
+ if (track->type() == MIDI_OUT)
+ ((MidiOutPort*)track)->playMidiEvent(ev);
+ else if (track->type() == AUDIO_SOFTSYNTH)
+ ((SynthI*)track)->playMidiEvent(ev);
+ }
+ }
+
+//---------------------------------------------------------
+// startRecording
+// gui context
+//---------------------------------------------------------
+
+void MidiTrack::startRecording()
+ {
+ hbank = 0;
+ lbank = 0;
+ datah = 0;
+ datal = 0;
+ rpnh = 0;
+ rpnl = 0;
+ dataType = 0;
+ recordedEvents = 0;
+ partCreated = false;
+ recordPart = 0;
+ recordFifo.clear();
+ keyDown.clear();
+
+ AL::Pos start = song->punchin() ? song->lPos() : song->cPos();
+
+ for (iPart ip = parts()->begin(); ip != parts()->end(); ++ip) {
+ Part* part = ip->second;
+ unsigned partStart = part->tick();
+ unsigned partEnd = partStart + part->lenTick();
+ if (start.tick() >= partStart && start.tick() < partEnd) {
+ recordPart = part;
+ }
+ }
+ if (recordPart == 0) {
+ //
+ // create new part for recording
+ //
+ recordPart = new Part(this);
+ recordPart->ref();
+ recordPart->setTrack(this);
+ int startTick = song->roundDownBar(start.tick());
+ int endTick = song->roundUpBar(start.tick());
+ recordPart->setTick(startTick);
+ recordPart->setLenTick(endTick - startTick);
+ recordPart->setName(name());
+ song->addPart(recordPart);
+ partCreated = true;
+ }
+ }
+
+//---------------------------------------------------------
+// recordBeat
+// gui context
+// update current recording
+//---------------------------------------------------------
+
+void MidiTrack::recordBeat()
+ {
+ int updateFlags = 0;
+ unsigned cpos = song->cpos();
+ unsigned ptick = recordPart->tick();
+
+ if (song->punchout()) {
+ if (song->rPos() >= song->cPos()) {
+ while (!recordFifo.isEmpty())
+ recordFifo.get();
+ return;
+ }
+ }
+ QList<Event> el;
+ while (!recordFifo.isEmpty()) {
+ MidiEvent me(recordFifo.get());
+
+ unsigned time = me.time();
+ if (song->punchin() && time < song->lpos())
+ continue;
+ bool isOff = me.isNoteOff();
+
+ if (song->punchout() && (time >= song->rpos()) && !isOff)
+ continue;
+
+ if (!partCreated && song->recMode() == Song::REC_REPLACE) {
+ // TODO: remove old events
+ }
+
+ time -= ptick;
+ if (isOff) {
+ //
+ // process note off
+ //
+ for (std::list<Event>::iterator i = keyDown.begin(); i != keyDown.end(); ++i) {
+ if (i->pitch() == me.dataA()) {
+ unsigned tl = time - i->tick();
+ if (tl != i->lenTick()) {
+ i->setLenTick(tl);
+ updateFlags |= SC_EVENT_MODIFIED;
+ }
+ keyDown.erase(i);
+ break;
+ }
+ }
+ }
+ else if (me.type() == ME_NOTEON && me.dataB() != 0) {
+ //
+ // create Note event on "note on"
+ //
+ Event event(Note);
+ event.setTick(time);
+ event.setLenTick(1);
+ event.setPitch(me.dataA());
+ event.setVelo(me.dataB());
+ keyDown.push_front(event);
+ el.append(event);
+ }
+ else if (me.type() == ME_POLYAFTER) {
+ Event event(PAfter);
+ event.setTick(time);
+ event.setA(me.dataA());
+ event.setB(me.dataB());
+ }
+ else if (me.type() == ME_CONTROLLER) {
+ Event event(Controller);
+ event.setTick(time + ptick);
+ switch(me.dataA()) {
+ case CTRL_HBANK:
+ hbank = me.dataB();
+ break;
+
+ case CTRL_LBANK:
+ lbank = me.dataB();
+ break;
+
+ case CTRL_HDATA:
+ datah = me.dataB();
+ event.setA(dataType | (rpnh << 8) | rpnl);
+ event.setB(datah);
+ el.append(event);
+ break;
+
+ case CTRL_LDATA:
+ datal = me.dataB();
+ if (dataType == CTRL_NRPN_OFFSET)
+ dataType = CTRL_NRPN14_OFFSET;
+ else if (dataType == CTRL_RPN_OFFSET)
+ dataType = CTRL_RPN14_OFFSET;
+ break;
+
+ case CTRL_HNRPN:
+ rpnh = me.dataB();
+ dataType = CTRL_NRPN_OFFSET;
+ break;
+
+ case CTRL_LNRPN:
+ rpnl = me.dataB();
+ dataType = CTRL_NRPN_OFFSET;
+ break;
+
+ case CTRL_HRPN:
+ rpnh = me.dataB();
+ dataType = CTRL_RPN_OFFSET;
+ break;
+
+ case CTRL_LRPN:
+ rpnl = me.dataB();
+ dataType = CTRL_RPN_OFFSET;
+ break;
+
+ default:
+ event.setA(me.dataA());
+ event.setB(me.dataB());
+ el.append(event);
+ break;
+ }
+ }
+ else if (me.type() == ME_PROGRAM) {
+ Event event(Controller);
+ event.setTick(time + ptick);
+ event.setA(CTRL_PROGRAM);
+ event.setB((hbank << 16) | (lbank << 8) | me.dataA());
+ el.append(event);
+ }
+ else if (me.type() == ME_PITCHBEND) {
+ Event event(Controller);
+ event.setTick(time + ptick);
+ event.setA(CTRL_PITCH);
+ event.setB(me.dataA());
+ el.append(event);
+ }
+ else if (me.type() == ME_SYSEX) {
+ Event event(Sysex);
+ event.setTick(time + ptick);
+ event.setData(me.data(), me.len());
+ el.append(event);
+ }
+ else if (me.type() == ME_AFTERTOUCH) {
+ Event event(CAfter);
+ event.setTick(time + ptick);
+ event.setA(me.dataA());
+ el.append(event);
+ }
+ }
+ if (!el.isEmpty()) {
+ for (int i = 0; i < el.size(); ++i)
+ el[i].setRecorded(true);
+ audio->msgAddEvents(&el, recordPart);
+ recordedEvents += el.size();
+ updateFlags |= SC_EVENT_INSERTED;
+ }
+
+ if (partCreated) {
+ recordPart->setLenTick(cpos - ptick);
+ updateFlags |= SC_PART_MODIFIED;
+ }
+ //
+ // modify len of all hold keys
+ //
+ for (std::list<Event>::iterator i = keyDown.begin(); i != keyDown.end(); ++i) {
+ if (cpos > (i->tick() + ptick))
+ i->setLenTick(cpos - (i->tick() + ptick));
+ updateFlags |= SC_EVENT_MODIFIED;
+ }
+ song->update(updateFlags);
+ }
+
+//---------------------------------------------------------
+// stopRecording
+// gui context
+//---------------------------------------------------------
+
+void MidiTrack::stopRecording()
+ {
+ for (iEvent e = recordPart->events()->begin(); e != recordPart->events()->end(); ++e) {
+ e->second.setRecorded(false);
+ }
+ if (recordedEvents == 0 && partCreated) {
+ // TD: remove empty part?
+ }
+ //
+ // modify len of all hold keys
+ //
+ unsigned ptick = recordPart->tick();
+ unsigned cpos = song->cpos();
+ for (std::list<Event>::iterator i = keyDown.begin(); i != keyDown.end(); ++i) {
+ i->setLenTick(cpos - (i->tick() + ptick));
+ }
+ //
+ // adjust part len && song len
+ //
+ if (recordPart->lenTick() < (cpos-ptick)) {
+ //
+ // TODO: check for events outside part boundaries
+ //
+ int endTick = song->roundUpBar(cpos);
+ recordPart->setLenTick(endTick - ptick);
+ }
+
+ unsigned etick = recordPart->endTick();
+ if (song->len() < etick)
+ song->setLen(etick);
+ }
+
+//---------------------------------------------------------
+// clone
+//---------------------------------------------------------
+
+void MidiTrack::clone(MidiTrack* t)
+ {
+ QString name;
+ for (int i = 1; ; ++i) {
+ name.sprintf("%s-%d", t->name().toLatin1().data(), i);
+ TrackList* tl = song->tracks();
+ bool found = false;
+ for (iTrack it = tl->begin(); it != tl->end(); ++it) {
+ if ((*it)->name() == name) {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ break;
+ }
+ setName(name);
+ _transposition = t->_transposition;
+ _velocity = t->_velocity;
+ _delay = t->_delay;
+ _len = t->_len;
+ _compression = t->_compression;
+ _recordFlag = t->_recordFlag;
+ _mute = t->_mute;
+ _solo = t->_solo;
+ _off = t->_off;
+ _monitor = t->_monitor;
+ _channels = t->_channels;
+ _locked = t->_locked;
+ _inRoutes = t->_inRoutes;
+ _outRoutes = t->_outRoutes;
+ _controller = t->_controller;
+ _autoRead = t->_autoRead;
+ _autoWrite = t->_autoWrite;
+ }
+
+//---------------------------------------------------------
+// isMute
+//---------------------------------------------------------
+
+bool MidiTrack::isMute() const
+ {
+ if (_solo)
+ return false;
+ if (song->solo())
+ return true;
+ return _mute;
+ }
+
+//---------------------------------------------------------
+// processMidi
+//---------------------------------------------------------
+
+void MidiTrack::processMidi(SeqTime* t)
+ {
+ schedEvents.clear();
+ //
+ // collect events only when transport is rolling
+ //
+ if (t->curTickPos < t->nextTickPos) {
+ for (iPart p = parts()->begin(); p != parts()->end(); ++p) {
+ Part* part = p->second;
+ if (part->mute())
+ continue;
+ DrumMap* dm = drumMap();
+ unsigned offset = _delay + part->tick();
+
+ if (offset > t->nextTickPos)
+ break;
+
+ EventList* events = part->events();
+
+ iEvent ie = events->lower_bound((offset > t->curTickPos) ? 0 : t->curTickPos - offset);
+ iEvent iend = events->lower_bound(t->nextTickPos - offset);
+
+ for (; ie != iend; ++ie) {
+ Event ev = ie->second;
+ if (ev.recorded())
+ continue;
+ if (ev.type() == Meta) // ignore meta events
+ continue;
+ unsigned tick = ev.tick() + offset;
+ unsigned frame = t->tick2frame(tick);
+ if (ev.type() == Note) {
+ if (dm) {
+ if (dm->entry(dm->outmap(ev.pitch()))->mute)
+ continue;
+ }
+ //
+ // maybe we should skip next lines if using a
+ // drummap
+
+ int pitch = ev.pitch() + _transposition + song->globalPitchShift();
+ if (pitch > 127)
+ pitch = 127;
+ if (pitch < 0)
+ pitch = 0;
+ int velo = ev.velo();
+ velo += _velocity;
+ velo = (velo * _compression) / 100;
+ if (velo > 127)
+ velo = 127;
+ if (velo < 1) // no off event
+ velo = 1;
+ int elen = (ev.lenTick() * _len)/100;
+ if (elen <= 0) // dont allow zero length
+ elen = 1;
+ int veloOff = ev.veloOff();
+
+ unsigned eframe = t->tick2frame(tick+elen);
+ schedEvents.insert(MidiEvent(frame, 0, ME_NOTEON, pitch, velo));
+ schedEvents.insert(MidiEvent(eframe, 0, veloOff ? ME_NOTEOFF : ME_NOTEON, pitch, veloOff));
+ _meter[0] += velo/2;
+ if (_meter[0] > 127.0f)
+ _meter[0] = 127.0f;
+ }
+ else {
+ schedEvents.insert(MidiEvent(frame, 0, ev));
+ }
+ }
+ }
+ //
+ // collect controller
+ //
+ if (autoRead()) {
+ for (iCtrl ic = controller()->begin(); ic != controller()->end(); ++ic) {
+ Ctrl* c = ic->second;
+ iCtrlVal is = c->lowerBound(t->curTickPos);
+ iCtrlVal ie = c->lowerBound(t->nextTickPos);
+ for (iCtrlVal ic = is; ic != ie; ++ic) {
+ unsigned frame = t->tick2frame(ic.key());
+ Event ev(Controller);
+ ev.setA(c->id());
+ ev.setB(ic.value().i);
+ schedEvents.insert(MidiEvent(frame, -1, ev));
+ c->setCurVal(ic.value().i);
+ }
+ }
+ }
+ }
+
+ //
+ // process input routing
+ //
+
+ foreach(const Route& r, *inRoutes()) {
+ MidiTrackBase* track = (MidiTrackBase*)r.src.track;
+ if (track->isMute())
+ continue;
+ MidiEventList el;
+ track->getEvents(t->curTickPos, t->nextTickPos, r.src.channel, &el);
+
+ for (iMidiEvent ie = el.begin(); ie != el.end(); ++ie) {
+ MidiEvent event(*ie);
+ unsigned eventTime = event.time();
+ if (recordFlag() && audio->isRecording()) {
+ unsigned time = t->frame2tick(eventTime);
+ event.setTime(time); // set tick time
+ recordFifo.put(event);
+ }
+ if (event.type() == ME_NOTEON && (monitor() || recordFlag()))
+ addMidiMeter(event.dataB());
+ if (monitor()) {
+ if (event.type() == ME_NOTEON) {
+ int pitch = event.dataA() + _transposition + song->globalPitchShift();
+ if (pitch > 127)
+ pitch = 127;
+ if (pitch < 0)
+ pitch = 0;
+ event.setA(pitch);
+ if (!event.isNoteOff()) {
+ int velo = event.dataB() + _velocity;
+ velo = (velo * _compression) / 100;
+ if (velo > 127)
+ velo = 127;
+ if (velo < 1)
+ velo = 1;
+ event.setB(velo);
+ }
+ }
+ event.setTime(eventTime + segmentSize);
+ schedEvents.insert(event);
+ }
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// getEvents
+// from/to - midi ticks
+//---------------------------------------------------------
+
+void MidiTrack::getEvents(unsigned /*from*/, unsigned /*to*/, int, MidiEventList* dst)
+ {
+ for (iMidiEvent i = schedEvents.begin(); i != schedEvents.end(); ++i) {
+ dst->insert(*i);
+ }
+ }
+
+//---------------------------------------------------------
+// emitControllerChanged
+//---------------------------------------------------------
+
+void MidiTrack::emitControllerChanged(int id)
+ {
+ if (id == CTRL_PROGRAM && _useDrumMap) {
+ int val = ctrlVal(id).i;
+ MidiInstrument* mi = instrument();
+ DrumMap* dm = mi->getDrumMap(val);
+ if (dm == 0)
+ dm = &gmDrumMap;
+ if (dm != _drumMap)
+ _drumMap = dm;
+ emit drumMapChanged();
+ }
+ emit controllerChanged(id);
+ }
+
+//---------------------------------------------------------
+// setUseDrumMap
+//---------------------------------------------------------
+
+void MidiTrack::setUseDrumMap(bool val)
+ {
+ if (_useDrumMap != val) {
+ _useDrumMap = val;
+ if (_useDrumMap) {
+ MidiInstrument* mi = instrument();
+ DrumMap* dm;
+ if (mi) {
+ int val = ctrlVal(CTRL_PROGRAM).i;
+ dm = mi->getDrumMap(val);
+ if (dm == 0)
+ dm = &gmDrumMap;
+ }
+ _drumMap = dm;
+ }
+ else
+ _drumMap = &noDrumMap;
+ emit drumMapChanged();
+ emit useDrumMapChanged(_useDrumMap);
+ }
+ }
+
+//---------------------------------------------------------
+// instrument
+//---------------------------------------------------------
+
+MidiInstrument* MidiTrack::instrument()
+ {
+ if (_outRoutes.isEmpty())
+ return genericMidiInstrument;
+ return _outRoutes[0].dst.track->instrument();
+ }
+
+//---------------------------------------------------------
+// channelNo
+//---------------------------------------------------------
+
+int MidiTrack::channelNo() const
+ {
+ if (_outRoutes.isEmpty()) // TODO: better: remember old channel setting
+ return 0;
+ return _outRoutes[0].dst.channel;
+ }
+
+//---------------------------------------------------------
+// midiOut
+//---------------------------------------------------------
+
+MidiOut* MidiTrack::midiOut()
+ {
+ if (_outRoutes.isEmpty())
+ return 0;
+ return _outRoutes[0].dst.track->midiOut();
+ }
+
+//---------------------------------------------------------
+// setChannel
+//---------------------------------------------------------
+
+void MidiTrack::setChannel(int n)
+ {
+ if (_outRoutes.isEmpty())
+ return;
+ Route r = _outRoutes[0];
+ if (r.dst.channel == n)
+ return;
+ audio->msgRemoveRoute(r);
+ r.dst.channel = n;
+ audio->msgAddRoute(r);
+ emit channelChanged(n);
+ }
diff --git a/muse_qt4_evolution/muse/miditrack.h b/muse_qt4_evolution/muse/miditrack.h
new file mode 100644
index 00000000..994c3c92
--- /dev/null
+++ b/muse_qt4_evolution/muse/miditrack.h
@@ -0,0 +1,127 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __MIDITRACK_H__
+#define __MIDITRACK_H__
+
+#include "miditrackbase.h"
+#include "midififo.h"
+#include "event.h"
+
+class Part;
+class EventList;
+class MidiOut;
+class SeqTime;
+
+//---------------------------------------------------------
+// MidiTrack
+//---------------------------------------------------------
+
+class MidiTrack : public MidiTrackBase {
+ Q_OBJECT
+
+ EventList _events; // tmp Events during midi import
+
+ // recording:
+ MidiFifo recordFifo; // for event transfer from RT-thread to gui thread
+ std::list<Event> keyDown; // keep track of "note on" events
+ Part* recordPart; // part we are recording into
+ int recordedEvents;
+ bool partCreated;
+ int hbank, lbank;
+ int datah, datal;
+ int rpnh, rpnl;
+ int dataType;
+
+ // channel data:
+ DrumMap* _drumMap;
+ bool _useDrumMap;
+
+ // play parameter
+ int _transposition;
+ int _velocity;
+ int _delay;
+ int _len;
+ int _compression;
+
+ MidiEventList schedEvents; // scheduled events by process()
+
+ signals:
+ void drumMapChanged() const;
+ void useDrumMapChanged(bool);
+ void channelChanged(int);
+
+ public slots:
+ void setChannel(int);
+
+ public:
+ MidiTrack();
+ virtual ~MidiTrack();
+ virtual TrackType type() const { return MIDI; }
+ void clone(MidiTrack*);
+
+ int transposition() const { return _transposition; }
+ int velocity() const { return _velocity; }
+ int delay() const { return _delay; }
+ int len() const { return _len; }
+ int compression() const { return _compression; }
+ void setTransposition(int val) { _transposition = val; }
+ void setVelocity(int val) { _velocity = val; }
+ void setDelay(int val) { _delay = val; }
+ void setLen(int val) { _len = val; }
+ void setCompression(int val) { _compression = val; }
+
+ void startRecording();
+ void recordBeat();
+ void stopRecording();
+
+ EventList* events() { return &_events; }
+
+ virtual void read(QDomNode);
+ virtual void write(Xml&) const;
+
+ virtual Part* newPart(Part*p=0, bool clone=false);
+
+ virtual bool isMute() const;
+ virtual bool canRecord() const { return true; }
+ void playMidiEvent(MidiEvent*);
+
+ virtual void processMidi(SeqTime*);
+ virtual void getEvents(unsigned from, unsigned to, int channel, MidiEventList* dst);
+
+ bool useDrumMap() const { return _useDrumMap; }
+ DrumMap* drumMap() const { return _drumMap; }
+ void setUseDrumMap(bool val);
+
+ int channelNo() const;
+ virtual void emitControllerChanged(int id);
+
+ virtual MidiOut* midiOut();
+ virtual MidiInstrument* instrument();
+ };
+
+typedef QList<MidiTrack*> MidiTrackList;
+typedef MidiTrackList::iterator iMidiTrack;
+typedef MidiTrackList::const_iterator ciMidiTrack;
+
+Q_DECLARE_METATYPE(class MidiTrack*);
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/miditrackbase.cpp b/muse_qt4_evolution/muse/miditrackbase.cpp
new file mode 100644
index 00000000..7af53299
--- /dev/null
+++ b/muse_qt4_evolution/muse/miditrackbase.cpp
@@ -0,0 +1,136 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "miditrackbase.h"
+#include "midiplugin.h"
+
+//---------------------------------------------------------
+// MidiTrackBase
+//---------------------------------------------------------
+
+MidiTrackBase::MidiTrackBase()
+ : Track()
+ {
+ _pipeline = new MidiPipeline();
+ }
+
+//---------------------------------------------------------
+// MidiTrackBase
+//---------------------------------------------------------
+
+MidiTrackBase::~MidiTrackBase()
+ {
+ foreach(MidiPluginI* plugin, *_pipeline)
+ delete plugin;
+ delete _pipeline;
+ }
+
+//---------------------------------------------------------
+// MidiTrackBase::writeProperties
+//---------------------------------------------------------
+
+void MidiTrackBase::writeProperties(Xml& xml) const
+ {
+ Track::writeProperties(xml);
+ for (ciMidiPluginI ip = _pipeline->begin(); ip != _pipeline->end(); ++ip) {
+ if (*ip)
+ (*ip)->writeConfiguration(xml);
+ }
+ }
+
+//---------------------------------------------------------
+// MidiTrackBase::readProperties
+//---------------------------------------------------------
+
+bool MidiTrackBase::readProperties(QDomNode node)
+ {
+ QDomElement e = node.toElement();
+ QString tag(e.tagName());
+ if (tag == "midiPlugin") {
+ MidiPluginI* pi = new MidiPluginI(this);
+ if (pi->readConfiguration(node))
+ delete pi;
+ else
+ addPlugin(pi, -1);
+ }
+ else
+ return Track::readProperties(node);
+ return false;
+ }
+
+//---------------------------------------------------------
+// plugin
+//---------------------------------------------------------
+
+MidiPluginI* MidiTrackBase::plugin(int idx) const
+ {
+ return _pipeline->value(idx);
+ }
+
+//---------------------------------------------------------
+// addPlugin
+// realtime context
+// idx = -1 append
+// plugin = 0 remove slot
+//---------------------------------------------------------
+
+void MidiTrackBase::addPlugin(MidiPluginI* plugin, int idx)
+ {
+ if (plugin) {
+ if (idx == -1)
+ idx = _pipeline->size();
+ _pipeline->insert(idx, plugin);
+#if 0
+ int ncontroller = plugin->plugin()->parameter();
+ for (int i = 0; i < ncontroller; ++i) {
+ int id = (idx + 1) * 0x1000 + i;
+ QString name(plugin->getParameterName(i));
+ double min, max;
+ plugin->range(i, &min, &max);
+ Ctrl* cl = getController(id);
+ if (cl == 0) {
+ cl = new Ctrl(id, name);
+ cl->setRange(min, max);
+ double defaultValue = plugin->defaultValue(i);
+ cl->setDefault(defaultValue);
+ cl->setCurVal(defaultValue);
+ addController(cl);
+ }
+ plugin->setParam(i, cl->schedVal().f);
+ plugin->setControllerList(cl);
+ }
+#endif
+ }
+ else {
+ MidiPluginI* oldPlugin = _pipeline->takeAt(idx);
+ if (oldPlugin) {
+#if 0
+ int controller = oldPlugin->plugin()->parameter();
+ for (int i = 0; i < controller; ++i) {
+ int id = (idx + 1) * 0x1000 + i;
+ removeController(id);
+ }
+#endif
+ }
+ }
+ }
+
+
+
diff --git a/muse_qt4_evolution/muse/miditrackbase.h b/muse_qt4_evolution/muse/miditrackbase.h
new file mode 100644
index 00000000..d10b2bb3
--- /dev/null
+++ b/muse_qt4_evolution/muse/miditrackbase.h
@@ -0,0 +1,53 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __MIDITRACKBASE_H__
+#define __MIDITRACKBASE_H__
+
+#include "track.h"
+
+//---------------------------------------------------------
+// MidiTrackBase
+//---------------------------------------------------------
+
+class MidiTrackBase : public Track {
+ Q_OBJECT
+
+ MidiPipeline* _pipeline;
+
+ public:
+ MidiTrackBase();
+ virtual ~MidiTrackBase();
+
+ bool readProperties(QDomNode);
+ void writeProperties(Xml&) const;
+
+ MidiPipeline* pipeline() { return _pipeline; }
+ void addPlugin(MidiPluginI* plugin, int idx);
+ MidiPluginI* plugin(int idx) const;
+
+ virtual void processMidi(unsigned, unsigned, unsigned, unsigned) {}
+ virtual void getEvents(unsigned /*from*/, unsigned /*to*/, int /*channel*/, MidiEventList* /*dst*/) {}
+ };
+
+#endif
+
+
+
diff --git a/muse_qt4_evolution/muse/miditrackinfo.ui b/muse_qt4_evolution/muse/miditrackinfo.ui
new file mode 100644
index 00000000..c1624188
--- /dev/null
+++ b/muse_qt4_evolution/muse/miditrackinfo.ui
@@ -0,0 +1,292 @@
+<ui version="4.0" >
+ <class>MidiTrackInfoBase</class>
+ <widget class="QWidget" name="MidiTrackInfoBase" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>135</width>
+ <height>165</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle" >
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <property name="horizontalSpacing" >
+ <number>0</number>
+ </property>
+ <property name="verticalSpacing" >
+ <number>0</number>
+ </property>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize" >
+ <size>
+ <width>16777215</width>
+ <height>24</height>
+ </size>
+ </property>
+ <property name="text" >
+ <string>Transp.</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QSpinBox" name="transposition" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize" >
+ <size>
+ <width>16777215</width>
+ <height>24</height>
+ </size>
+ </property>
+ <property name="toolTip" >
+ <string>Pitch Transpose</string>
+ </property>
+ <property name="minimum" >
+ <number>-127</number>
+ </property>
+ <property name="maximum" >
+ <number>127</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_2" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize" >
+ <size>
+ <width>16777215</width>
+ <height>24</height>
+ </size>
+ </property>
+ <property name="text" >
+ <string>Delay</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QSpinBox" name="delay" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize" >
+ <size>
+ <width>16777215</width>
+ <height>24</height>
+ </size>
+ </property>
+ <property name="toolTip" >
+ <string>Track Delay (ticks)</string>
+ </property>
+ <property name="minimum" >
+ <number>-1000</number>
+ </property>
+ <property name="maximum" >
+ <number>1000</number>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="label_3" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize" >
+ <size>
+ <width>16777215</width>
+ <height>24</height>
+ </size>
+ </property>
+ <property name="text" >
+ <string>Length</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" >
+ <widget class="QSpinBox" name="length" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize" >
+ <size>
+ <width>16777215</width>
+ <height>24</height>
+ </size>
+ </property>
+ <property name="toolTip" >
+ <string>Modify Note Length</string>
+ </property>
+ <property name="suffix" >
+ <string>%</string>
+ </property>
+ <property name="minimum" >
+ <number>25</number>
+ </property>
+ <property name="maximum" >
+ <number>200</number>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" >
+ <widget class="QLabel" name="label_4" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize" >
+ <size>
+ <width>16777215</width>
+ <height>24</height>
+ </size>
+ </property>
+ <property name="text" >
+ <string>Velocity</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1" >
+ <widget class="QSpinBox" name="velocity" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize" >
+ <size>
+ <width>16777215</width>
+ <height>24</height>
+ </size>
+ </property>
+ <property name="toolTip" >
+ <string>Modify Note Velocity</string>
+ </property>
+ <property name="minimum" >
+ <number>-127</number>
+ </property>
+ <property name="maximum" >
+ <number>127</number>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0" >
+ <widget class="QLabel" name="label_5" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize" >
+ <size>
+ <width>16777215</width>
+ <height>24</height>
+ </size>
+ </property>
+ <property name="text" >
+ <string>Compr.</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1" >
+ <widget class="QSpinBox" name="compression" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize" >
+ <size>
+ <width>16777215</width>
+ <height>24</height>
+ </size>
+ </property>
+ <property name="toolTip" >
+ <string>Compress Note Velocity</string>
+ </property>
+ <property name="suffix" >
+ <string>%</string>
+ </property>
+ <property name="minimum" >
+ <number>25</number>
+ </property>
+ <property name="maximum" >
+ <number>200</number>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0" colspan="2" >
+ <widget class="QPushButton" name="patch" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize" >
+ <size>
+ <width>16777215</width>
+ <height>24</height>
+ </size>
+ </property>
+ <property name="toolTip" >
+ <string>Instrument Patch</string>
+ </property>
+ <property name="text" >
+ <string>???</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/muse_qt4_evolution/muse/miditransform.cpp b/muse_qt4_evolution/muse/miditransform.cpp
new file mode 100644
index 00000000..f4e85be2
--- /dev/null
+++ b/muse_qt4_evolution/muse/miditransform.cpp
@@ -0,0 +1,1534 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "helper.h"
+#include "event.h"
+#include "miditransform.h"
+#include "track.h"
+#include "song.h"
+#include "al/xml.h"
+#include "globals.h"
+#include "comboQuant.h"
+#include "audio.h"
+#include "gconfig.h"
+#include "al/sig.h"
+
+static int eventTypeTable[] = {
+ Note, Controller, Sysex, PAfter, CAfter, Meta
+ };
+
+static int procVal2Map[] = { 0, 1, 2, 3, 4, 5, 6, 7, 10, 11 };
+
+//---------------------------------------------------------
+// MidiTransformation
+//---------------------------------------------------------
+
+class MidiTransformation {
+ public:
+ QString name;
+ QString comment;
+
+ ValOp selEventOp;
+ EventType selType;
+
+ ValOp selVal1;
+ int selVal1a, selVal1b;
+ ValOp selVal2;
+ int selVal2a, selVal2b;
+ ValOp selLen;
+ int selLenA, selLenB;
+ ValOp selRange;
+ int selRangeA, selRangeB;
+
+ TransformOperator procEvent;
+ EventType eventType;
+ TransformOperator procVal1;
+ int procVal1a, procVal1b;
+ TransformOperator procVal2;
+ int procVal2a, procVal2b;
+ TransformOperator procLen;
+ int procLenA;
+ TransformOperator procPos;
+ int procPosA;
+
+ TransformFunction funcOp;
+ int quantVal;
+ bool selectedTracks;
+ bool insideLoop;
+
+ MidiTransformation(const QString& s) {
+ name = s;
+ selEventOp = All;
+ selType = Note;
+ selVal1 = Ignore;
+ selVal1a = 0;
+ selVal1b = 0;
+ selVal2 = Ignore;
+ selVal2a = 0;
+ selVal2b = 0;
+ selLen = Ignore;
+ selLenA = 0;
+ selLenB = 0;
+ selRange = Ignore;
+ selRangeA = 0;
+ selRangeB = 0;
+ procEvent = Keep;
+ eventType = Note;
+ procVal1 = Keep;
+ procVal1a = 0;
+ procVal1b = 0;
+ procVal2 = Keep;
+ procVal2a = 0;
+ procVal2b = 0;
+ procLen = Keep;
+ procLenA = 0;
+ procPos = Keep;
+ procPosA = 0;
+ funcOp = Select;
+ quantVal = config.division;
+ selectedTracks = false;
+ insideLoop = false;
+ }
+ void write(Xml& xml);
+ };
+
+class MidiTransformPrivate {
+ public:
+ MidiTransformation* cmt;
+ int cindex; // current index in preset list
+ };
+
+typedef std::list<MidiTransformation* > MidiTransformationList;
+typedef std::list<MidiTransformation* >::iterator iMidiTransformation;
+typedef std::list<MidiTransformation* >::const_iterator ciMidiTransformation;
+
+static MidiTransformationList mtlist;
+
+//---------------------------------------------------------
+// MidiTransformDialog
+// Widgets:
+// presetList nameEntry commentEntry
+// selEventOp selType
+// selVal1Op selVal1a selVal1b
+// selVal2Op selVal2a selVal2b
+// selLenOp selLenA selLenB
+// selRangeOp selBarA selBarB
+//
+// procEventOp procType
+// procVal1Op procVal1a procVal1b
+// procVal2Op procVal2a procVal2b
+// procLenOp procLenA
+// procPosOp procPosA
+// funcOp funcQuantVal
+// processAll selectedTracks insideLoop
+// buttonNew buttonDelete buttonApply buttonOk
+//---------------------------------------------------------
+
+MidiTransformerDialog::MidiTransformerDialog(QWidget* parent,
+ const char* name, bool modal, Qt::WFlags fl)
+ : MidiTransformDialogBase(parent, name, modal, fl)
+ {
+ data = new MidiTransformPrivate;
+ data->cmt = 0;
+ data->cindex = -1;
+ connect(buttonApply, SIGNAL(clicked()), SLOT(apply()));
+ connect(buttonNew, SIGNAL(clicked()), SLOT(presetNew()));
+ connect(buttonDelete, SIGNAL(clicked()), SLOT(presetDelete()));
+ connect(selEventOp, SIGNAL(activated(int)), SLOT(selEventOpSel(int)));
+ connect(selType, SIGNAL(activated(int)), SLOT(selTypeSel(int)));
+ connect(selVal1Op, SIGNAL(activated(int)), SLOT(selVal1OpSel(int)));
+ connect(selVal2Op, SIGNAL(activated(int)), SLOT(selVal2OpSel(int)));
+ connect(selLenOp, SIGNAL(activated(int)), SLOT(selLenOpSel(int)));
+ connect(selRangeOp, SIGNAL(activated(int)), SLOT(selRangeOpSel(int)));
+ connect(procEventOp, SIGNAL(activated(int)), SLOT(procEventOpSel(int)));
+ connect(procType, SIGNAL(activated(int)), SLOT(procEventTypeSel(int)));
+ connect(procVal1Op, SIGNAL(activated(int)), SLOT(procVal1OpSel(int)));
+ connect(procVal2Op, SIGNAL(activated(int)), SLOT(procVal2OpSel(int)));
+ connect(procLenOp, SIGNAL(activated(int)), SLOT(procLenOpSel(int)));
+ connect(procPosOp, SIGNAL(activated(int)), SLOT(procPosOpSel(int)));
+ connect(funcOp, SIGNAL(activated(int)), SLOT(funcOpSel(int)));
+ connect(funcQuantVal, SIGNAL(valueChanged(int)), SLOT(funcQuantValSel(int)));
+ connect(presetList, SIGNAL(highlighted(Q3ListBoxItem*)),
+ SLOT(presetChanged(Q3ListBoxItem*)));
+ connect(nameEntry, SIGNAL(textChanged(const QString&)),
+ SLOT(nameChanged(const QString&)));
+ connect(commentEntry, SIGNAL(textChanged()), SLOT(commentChanged()));
+
+ connect(selVal1a, SIGNAL(valueChanged(int)), SLOT(selVal1aChanged(int)));
+ connect(selVal1b, SIGNAL(valueChanged(int)), SLOT(selVal1bChanged(int)));
+ connect(selVal2a, SIGNAL(valueChanged(int)), SLOT(selVal2aChanged(int)));
+ connect(selVal2b, SIGNAL(valueChanged(int)), SLOT(selVal2bChanged(int)));
+ connect(selLenA, SIGNAL(valueChanged(int)), SLOT(selLenAChanged(int)));
+ connect(selLenB, SIGNAL(valueChanged(int)), SLOT(selLenBChanged(int)));
+ connect(selBarA, SIGNAL(valueChanged(int)), SLOT(selBarAChanged(int)));
+ connect(selBarB, SIGNAL(valueChanged(int)), SLOT(selBarBChanged(int)));
+ connect(procVal1a, SIGNAL(valueChanged(int)), SLOT(procVal1aChanged(int)));
+ connect(procVal1b, SIGNAL(valueChanged(int)), SLOT(procVal1bChanged(int)));
+ connect(procVal2a, SIGNAL(valueChanged(int)), SLOT(procVal2aChanged(int)));
+ connect(procVal2b, SIGNAL(valueChanged(int)), SLOT(procVal2bChanged(int)));
+ connect(procLenA, SIGNAL(valueChanged(int)), SLOT(procLenAChanged(int)));
+ connect(procPosA, SIGNAL(valueChanged(int)), SLOT(procPosAChanged(int)));
+
+ connect(processAll, SIGNAL(toggled(bool)), SLOT(processAllChanged(bool)));
+ connect(selectedTracks, SIGNAL(toggled(bool)), SLOT(selectedTracksChanged(bool)));
+ connect(insideLoop, SIGNAL(toggled(bool)), SLOT(insideLoopChanged(bool)));
+
+ //---------------------------------------------------
+ // populate preset list
+ //---------------------------------------------------
+
+ for (iMidiTransformation i = mtlist.begin(); i != mtlist.end(); ++i) {
+ presetList->insertItem((*i)->name);
+ if (data->cmt == 0)
+ data->cmt = *i;
+ }
+ if (data->cmt == 0) {
+ data->cmt = new MidiTransformation(tr("New"));
+ mtlist.push_back(data->cmt);
+ presetList->insertItem(tr("New"));
+ }
+ data->cindex = 0;
+ presetList->setCurrentItem(0);
+ }
+
+//---------------------------------------------------------
+// ~MidiTransformDialog
+//---------------------------------------------------------
+
+MidiTransformerDialog::~MidiTransformerDialog()
+ {
+ delete data;
+ }
+
+//---------------------------------------------------------
+// writeMidiTransforms
+//---------------------------------------------------------
+
+void writeMidiTransforms(Xml& xml)
+ {
+ for (iMidiTransformation i = mtlist.begin(); i != mtlist.end(); ++i) {
+ (*i)->write(xml);
+ }
+ }
+
+//---------------------------------------------------------
+// write
+//---------------------------------------------------------
+
+void MidiTransformation::write(Xml& xml)
+ {
+ xml.tag("midiTransform");
+ xml.strTag("name", name);
+ xml.strTag("comment", comment);
+ xml.intTag("function", int(funcOp));
+ xml.intTag("selectedTracks", selectedTracks);
+ xml.intTag("insideLoop", insideLoop);
+ if (funcOp == Quantize) {
+ xml.intTag("quantVal", quantVal);
+ }
+ if (funcOp == Transform || funcOp == Insert) {
+ if (procEvent != Keep) {
+ xml.intTag("procEventOp", int(procEvent));
+ xml.intTag("eventType", int(eventType));
+ }
+ if (procVal1 != Keep) {
+ xml.intTag("procVal1Op", int(procVal1));
+ xml.intTag("procVal1a", procVal1a);
+ xml.intTag("procVal1b", procVal1b);
+ }
+ if (procVal2 != Keep) {
+ xml.intTag("procVal2Op", int(procVal2));
+ xml.intTag("procVal2a", procVal2a);
+ xml.intTag("procVal2b", procVal2b);
+ }
+ if (procLen != Keep) {
+ xml.intTag("procLenOp", int(procLen));
+ xml.intTag("procLen", procLenA);
+ }
+ if (procPos != Keep) {
+ xml.intTag("procPosOp", int(procPos));
+ xml.intTag("procPos", procPosA);
+ }
+ }
+ if (selEventOp != Ignore) {
+ xml.intTag("selEventOp", int(selEventOp));
+ xml.intTag("selEventType", int(selType));
+ }
+ if (selVal1 != Ignore) {
+ xml.intTag("selVal1Op", int(selVal1));
+ xml.intTag("selVal1a", selVal1a);
+ xml.intTag("selVal1b", selVal1b);
+ }
+ if (selVal2 != Ignore) {
+ xml.intTag("selVal2Op", int(selVal2));
+ xml.intTag("selVal2a", selVal2a);
+ xml.intTag("selVal2b", selVal2b);
+ }
+ if (selLen != Ignore) {
+ xml.intTag("selLenOp", int(selLen));
+ xml.intTag("selLenA", selLenA);
+ xml.intTag("selLenB", selLenB);
+ }
+ if (selRange != Ignore) {
+ xml.intTag("selRangeOp", int(selRange));
+ xml.intTag("selRangeA", selRangeA);
+ xml.intTag("selRangeB", selRangeB);
+ }
+ xml.etag("midiTransform");
+ }
+
+//---------------------------------------------------------
+// readMidiTransform
+//---------------------------------------------------------
+
+void readMidiTransform(QDomNode node)
+ {
+ MidiTransformation trans(QWidget::tr("new"));
+
+ while (!node.isNull()) {
+ QDomElement e = node.toElement();
+ QString tag(e.tagName());
+ QString s(e.text());
+ int i = s.toInt();
+
+ if (tag == "name")
+ trans.name = s;
+ else if (tag == "comment")
+ trans.comment = s;
+ else if (tag == "function")
+ trans.funcOp = TransformFunction(i);
+ else if (tag == "selectedTracks")
+ trans.selectedTracks = i;
+ else if (tag == "insideLoop")
+ trans.insideLoop = i;
+ else if (tag == "quantVal")
+ trans.quantVal = i;
+ else if (tag == "procEventOp")
+ trans.procEvent = TransformOperator(i);
+ else if (tag == "eventType")
+ trans.eventType = EventType(i);
+ else if (tag == "procVal1Op")
+ trans.procVal1 = TransformOperator(i);
+ else if (tag == "procVal1a")
+ trans.procVal1a = i;
+ else if (tag == "procVal1b")
+ trans.procVal1b = i;
+ else if (tag == "procVal2Op")
+ trans.procVal2 = TransformOperator(i);
+ else if (tag == "procVal2a")
+ trans.procVal2a = i;
+ else if (tag == "procVal2b")
+ trans.procVal2b = i;
+ else if (tag == "procLenOp")
+ trans.procLen = TransformOperator(i);
+ else if (tag == "procLen")
+ trans.procLenA = i;
+ else if (tag == "procPosOp")
+ trans.procPos = TransformOperator(i);
+ else if (tag == "procPos")
+ trans.procPosA = i;
+ else if (tag == "selEventOp")
+ trans.selEventOp = ValOp(i);
+ else if (tag == "selEventType")
+ trans.selType = EventType(i);
+ else if (tag == "selVal1Op")
+ trans.selVal1 = ValOp(i);
+ else if (tag == "selVal1a")
+ trans.selVal1a = i;
+ else if (tag == "selVal1b")
+ trans.selVal1b = i;
+ else if (tag == "selVal2Op")
+ trans.selVal2 = ValOp(i);
+ else if (tag == "selVal2a")
+ trans.selVal2a = i;
+ else if (tag == "selVal2b")
+ trans.selVal2b = i;
+ else if (tag == "selLenOp")
+ trans.selLen = ValOp(i);
+ else if (tag == "selLenA")
+ trans.selLenA = i;
+ else if (tag == "selLenB")
+ trans.selLenB = i;
+ else if (tag == "selRangeOp")
+ trans.selRange = ValOp(i);
+ else if (tag == "selRangeA")
+ trans.selRangeA = i;
+ else if (tag == "selRangeB")
+ trans.selRangeB = i;
+ else
+ printf("MusE:readMidiTransform(): unknown tag %s\n", e.tagName().toLatin1().data());
+ node = node.nextSibling();
+ }
+ MidiTransformation* t = new MidiTransformation(trans);
+ mtlist.push_back(t);
+ }
+
+//---------------------------------------------------------
+// accept
+//---------------------------------------------------------
+
+void MidiTransformerDialog::accept()
+ {
+ apply();
+ reject();
+ }
+
+//---------------------------------------------------------
+// transformEvent
+// subfunction of processEvent()
+//---------------------------------------------------------
+
+void MidiTransformerDialog::transformEvent(Event& event, MidiPart* part,
+ MidiPart* newPart)
+ {
+ MidiTransformation* cmt = data->cmt;
+ Event newEvent = event.clone();
+
+ if (cmt->procEvent != Keep)
+ newEvent.setType(cmt->eventType);
+
+ //---------------------------------------------------
+ // transform value A
+ //---------------------------------------------------
+
+ int val = newEvent.dataA();
+ switch (cmt->procVal1) {
+ case Keep:
+ break;
+ case Plus:
+ val += cmt->procVal1a;
+ break;
+ case Minus:
+ val -= cmt->procVal1a;
+ break;
+ case Multiply:
+ val = int(val * (cmt->procVal1a/100.0) + .5);
+ break;
+ case Divide:
+ val = int(val / (cmt->procVal1a/100.0) + .5);
+ break;
+ case Fix:
+ val = cmt->procVal1a;
+ break;
+ case Value:
+ val = cmt->procVal2a;
+ break;
+ case Invert:
+ val = 128 - val;
+ break;
+ case ScaleMap:
+ printf("scale map not implemented\n");
+ break;
+ case Flip:
+ val = cmt->procVal1a - val;
+ break;
+ case Dynamic: // "crescendo"
+ val = (((cmt->procVal2b-cmt->procVal2a)
+ * (newEvent.tick() - song->lpos()))
+ / (song->rpos() - song->lpos())) + cmt->procVal2a;
+ break;
+ case Random:
+ {
+ int range = cmt->procVal1b - cmt->procVal1a;
+ if (range > 0)
+ val = (rand() % range) + cmt->procVal1a;
+ else if (range < 0)
+ val = (rand() % -range) + cmt->procVal1b;
+ else
+ val = cmt->procVal1a;
+ }
+ break;
+ }
+ if (val < 0)
+ val = 0;
+ if (val > 127)
+ val = 127;
+ newEvent.setA(val);
+
+ //---------------------------------------------------
+ // transform value B
+ //---------------------------------------------------
+
+ val = newEvent.dataB();
+ switch (cmt->procVal2) {
+ case Plus:
+ val += cmt->procVal2a;
+ break;
+ case Minus:
+ val -= cmt->procVal2a;
+ break;
+ case Multiply:
+ val = int(val * (cmt->procVal2a/100.0) + .5);
+ break;
+ case Divide:
+ val = int(val / (cmt->procVal2a/100.0) + .5);
+ break;
+ case Fix:
+ val = cmt->procVal2a;
+ break;
+ case Value:
+ val = cmt->procVal1a;
+ break;
+ case Invert:
+ val = 128 - val;
+ break;
+ case Dynamic:
+ val = (((cmt->procVal2b-cmt->procVal2a)
+ * (newEvent.tick() - song->lpos()))
+ / (song->rpos() - song->lpos())) + cmt->procVal2a;
+ break;
+ case Random:
+ {
+ int range = cmt->procVal2b - cmt->procVal2a;
+ if (range > 0)
+ val = (rand() % range) + cmt->procVal2a;
+ else if (range < 0)
+ val = (rand() % -range) + cmt->procVal2b;
+ else
+ val = cmt->procVal1a;
+ }
+ break;
+ case ScaleMap:
+ case Keep:
+ case Flip:
+ break;
+ }
+ if (val < 0)
+ val = 0;
+ if (val > 127)
+ val = 127;
+ newEvent.setB(val);
+
+ //---------------------------------------------------
+ // transform len
+ //---------------------------------------------------
+
+ int len = newEvent.lenTick();
+ switch (cmt->procLen) {
+ case Plus:
+ len += cmt->procLenA;
+ break;
+ case Minus:
+ len -= cmt->procLenA;
+ break;
+ case Multiply:
+ len = int(val * (cmt->procLenA/100.0) + .5);
+ break;
+ case Divide:
+ len = int(val / (cmt->procLenA/100.0) + .5);
+ break;
+ case Fix:
+ len = cmt->procLenA;
+ break;
+ case Invert:
+ case ScaleMap:
+ case Dynamic:
+ case Random:
+ case Keep:
+ case Flip:
+ case Value:
+ break;
+ }
+ if (len < 0)
+ len = 0;
+ newEvent.setLenTick(len);
+
+ //---------------------------------------------------
+ // transform pos
+ //---------------------------------------------------
+
+ int pos = newEvent.tick();
+ switch (cmt->procPos) {
+ case Plus:
+ pos += cmt->procPosA;
+ break;
+ case Minus:
+ pos -= cmt->procPosA;
+ break;
+ case Multiply:
+ pos = int(val * (cmt->procPosA/100.0) + .5);
+ break;
+ case Divide:
+ pos = int(val / (cmt->procPosA/100.0) + .5);
+ break;
+ case Fix:
+ case Invert:
+ case ScaleMap:
+ case Dynamic:
+ case Random:
+ case Keep:
+ case Flip:
+ case Value:
+ break;
+ }
+ if (pos < 0)
+ pos = 0;
+ newEvent.setTick(pos);
+
+ Event dummy;
+ switch(data->cmt->funcOp) {
+ case Transform:
+ song->changeEvent(event, newEvent, part);
+ song->undoOp(UndoOp::ModifyEvent, newEvent, event, part);
+ song->addUpdateFlags(SC_EVENT_MODIFIED);
+ break;
+ case Insert:
+ song->undoOp(UndoOp::AddEvent, dummy, newEvent, part);
+ song->addEvent(newEvent, part);
+ song->addUpdateFlags(SC_EVENT_INSERTED);
+ break;
+ case Extract:
+ song->undoOp(UndoOp::DeleteEvent, dummy, event, part);
+ song->deleteEvent(event, part);
+ song->addUpdateFlags(SC_EVENT_REMOVED);
+ case Copy:
+ newPart->addEvent(newEvent);
+ break;
+ default:
+ break;
+ }
+ }
+
+//---------------------------------------------------------
+// processEvent
+//---------------------------------------------------------
+
+void MidiTransformerDialog::processEvent(Event& event, MidiPart* part, MidiPart* newPart)
+ {
+ switch(data->cmt->funcOp) {
+ case Select:
+ break;
+ case Quantize:
+ {
+ int tick = event.tick();
+ int rt = AL::sigmap.raster(tick, data->cmt->quantVal) - tick;
+ if (tick != rt) {
+ Event newEvent = event.clone();
+ newEvent.setTick(rt);
+ song->changeEvent(event, newEvent, part);
+ song->undoOp(UndoOp::ModifyEvent, newEvent, event, part);
+ song->addUpdateFlags(SC_EVENT_MODIFIED);
+ }
+ }
+ break;
+ case Delete:
+ {
+ Event ev;
+ song->undoOp(UndoOp::DeleteEvent, ev, event, part);
+ song->deleteEvent(event, part);
+ song->addUpdateFlags(SC_EVENT_REMOVED);
+ }
+ break;
+ case Transform:
+ case Insert:
+ case Copy:
+ case Extract:
+ transformEvent(event, part, newPart);
+ break;
+ }
+ }
+
+//---------------------------------------------------------
+// isSelected
+// apply Select filter
+// return true if event is selected
+//---------------------------------------------------------
+
+bool MidiTransformerDialog::isSelected(Event& event, MidiPart*)
+ {
+ MidiTransformation* cmt = data->cmt;
+
+ switch (cmt->selEventOp) {
+ case Equal:
+ if (event.type() != cmt->selType) {
+ return false;
+ }
+ break;
+ case Unequal:
+ if (event.type() == cmt->selType) {
+ return false;
+ }
+ break;
+ default:
+ break;
+ }
+ switch (cmt->selVal1) {
+ case Ignore:
+ break;
+ case Equal:
+ if (event.dataA() != cmt->selVal1a)
+ return false;
+ break;
+ case Unequal:
+ if (event.dataA() == cmt->selVal1a)
+ return false;
+ break;
+ case Higher:
+ if (event.dataA() <= cmt->selVal1a)
+ return false;
+ break;
+ case Lower:
+ if (event.dataA() >= cmt->selVal1a)
+ return false;
+ break;
+ case Inside:
+ if ((event.dataA() < cmt->selVal1a)
+ || (event.dataA() >= cmt->selVal1b))
+ return false;
+ break;
+ case Outside:
+ if ((event.dataA() >= cmt->selVal1a)
+ && (event.dataA() < cmt->selVal1b))
+ return false;
+ break;
+ }
+ switch (cmt->selVal2) {
+ case Ignore:
+ break;
+ case Equal:
+ if (event.dataB() != cmt->selVal2a)
+ return false;
+ break;
+ case Unequal:
+ if (event.dataB() == cmt->selVal2a)
+ return false;
+ break;
+ case Higher:
+ if (event.dataB() <= cmt->selVal2a)
+ return false;
+ break;
+ case Lower:
+ if (event.dataB() >= cmt->selVal2a)
+ return false;
+ break;
+ case Inside:
+ if ((event.dataB() < cmt->selVal2a)
+ || (event.dataB() >= cmt->selVal2b))
+ return false;
+ break;
+ case Outside:
+ if ((event.dataB() >= cmt->selVal2a)
+ && (event.dataB() < cmt->selVal2b))
+ return false;
+ break;
+ }
+ int len = event.lenTick();
+ switch (cmt->selLen) {
+ case Ignore:
+ break;
+ case Equal:
+ if (len != cmt->selLenA)
+ return false;
+ break;
+ case Unequal:
+ if (len == cmt->selLenA)
+ return false;
+ break;
+ case Higher:
+ if (len <= cmt->selLenA)
+ return false;
+ break;
+ case Lower:
+ if (len >= cmt->selLenA)
+ return false;
+ break;
+ case Inside:
+ if ((len < cmt->selLenA) || (len >= cmt->selLenB))
+ return false;
+ break;
+ case Outside:
+ if ((len >= cmt->selLenA) && (len < cmt->selLenB))
+ return false;
+ break;
+ }
+ int bar, beat;
+ unsigned tick;
+ AL::sigmap.tickValues(event.tick(), &bar, &beat, &tick);
+ int beat1 = cmt->selRangeA / 1000;
+ unsigned tick1 = cmt->selRangeA % 1000;
+ int beat2 = cmt->selRangeB / 1000;
+ unsigned tick2 = cmt->selRangeB % 1000;
+ switch (cmt->selRange) {
+ case Ignore:
+ break;
+ case Equal:
+ if (beat != beat1 || tick != tick1)
+ return false;
+ break;
+ case Unequal:
+ if (beat == beat1 && tick == tick1)
+ return false;
+ break;
+ case Higher:
+ if (beat <= beat1)
+ return false;
+ if (beat == beat1 && tick <= tick1)
+ return false;
+ break;
+ case Lower:
+ if (beat >= beat1)
+ return false;
+ if (beat == beat1 && tick >= tick1)
+ return false;
+ break;
+ case Inside:
+ if ((beat < beat1) || (beat >= beat2))
+ return false;
+ if (beat == beat1 && tick < tick1)
+ return false;
+ if (beat == beat2 && tick >= tick2)
+ return false;
+ break;
+ case Outside:
+ if ((beat >= beat1) || (beat < beat2))
+ return false;
+ if (beat == beat1 && tick >= tick1)
+ return false;
+ if (beat == beat2 && tick < tick2)
+ return false;
+ break;
+ }
+ return true;
+ }
+
+//---------------------------------------------------------
+// apply
+//---------------------------------------------------------
+
+void MidiTransformerDialog::apply()
+ {
+ int flags = 0;
+ song->startUndo();
+ audio->msgIdle(true);
+ bool copyExtract = (data->cmt->funcOp == Copy)
+ || (data->cmt->funcOp == Extract);
+
+ MidiTrackList* tracks = song->midis();
+ MidiTrackList tl;
+ for (iMidiTrack t = tracks->begin(); t != tracks->end(); ++t) {
+ if (data->cmt->selectedTracks && !(*t)->selected())
+ continue;
+ MidiTrack* newTrack = 0;
+ PartList *pl = (*t)->parts();
+ if (copyExtract) {
+ // check wether we must generate a new track
+ for (iPart p = pl->begin(); p != pl->end(); ++p) {
+ MidiPart* part = (MidiPart *) p->second;
+ EventList* el = part->events();
+ for (iEvent i = el->begin(); i != el->end(); ++i) {
+ Event event = i->second;
+ unsigned tick = event.tick();
+ if (data->cmt->insideLoop && (tick < song->lpos() || tick >= song->rpos()))
+ continue;
+ if (isSelected(event, part)) {
+ newTrack = new MidiTrack();
+ tl.push_back(newTrack);
+ break;
+ }
+ }
+ if (newTrack)
+ break;
+ }
+ }
+
+ for (iPart p = pl->begin(); p != pl->end(); ++p) {
+ MidiPart* part = (MidiPart *) p->second;
+ MidiPart* newPart = 0;
+ EventList* el = part->events();
+ if (copyExtract) {
+ // check wether we must generate a new part
+ for (iEvent i = el->begin(); i != el->end(); ++i) {
+ Event event = i->second;
+ unsigned tick = event.tick();
+ if (data->cmt->insideLoop && (tick < song->lpos() || tick >= song->rpos()))
+ continue;
+ if (isSelected(event, part)) {
+ newPart = new MidiPart(newTrack);
+ newPart->setName(part->name());
+ newPart->setColorIndex(part->colorIndex());
+ newPart->setTick(part->tick());
+ newPart->setLenTick(part->lenTick());
+ song->addPart(newPart);
+ flags |= SC_PART_INSERTED;
+ break;
+ }
+ }
+ }
+ EventList pel;
+ for (iEvent i = el->begin(); i != el->end(); ++i) {
+ Event event = i->second;
+ unsigned tick = event.tick();
+ if (data->cmt->insideLoop && (tick < song->lpos() || tick >= song->rpos()))
+ continue;
+ bool flag = isSelected(event, part);
+ if (data->cmt->funcOp == Select)
+ event.setSelected(flag);
+ else if (flag)
+ pel.add(event);
+ }
+ for (iEvent i = pel.begin(); i != pel.end(); ++i) {
+ Event event = i->second;
+ processEvent(event, part, newPart);
+ }
+ }
+ }
+ if (!tl.empty()) {
+ flags |= SC_TRACK_INSERTED;
+ for (iTrack t = tl.begin(); t != tl.end(); ++t) {
+ song->insertTrack0(*t, -1);
+ }
+ }
+
+ switch(data->cmt->funcOp) {
+ case Select:
+ flags |= SC_SELECTION;
+ break;
+ case Quantize:
+ flags |= SC_EVENT_MODIFIED;
+ break;
+ case Delete:
+ flags |= SC_EVENT_REMOVED;
+ break;
+ case Transform:
+ flags |= SC_EVENT_MODIFIED;
+ break;
+ case Insert:
+ flags |= SC_EVENT_INSERTED;
+ break;
+ case Copy:
+ flags |= SC_EVENT_INSERTED;
+ case Extract:
+ break;
+ }
+ audio->msgIdle(false);
+ song->endUndo(flags);
+ }
+
+//---------------------------------------------------------
+// setValOp
+//---------------------------------------------------------
+
+void MidiTransformerDialog::setValOp(QWidget* a, QWidget* b, ValOp op)
+ {
+ switch (op) {
+ case Ignore:
+ a->setEnabled(false);
+ b->setEnabled(false);
+ break;
+ case Equal:
+ case Unequal:
+ case Higher:
+ case Lower:
+ a->setEnabled(true);
+ b->setEnabled(false);
+ break;
+ case Inside:
+ case Outside:
+ a->setEnabled(true);
+ b->setEnabled(true);
+ break;
+ }
+ }
+
+//---------------------------------------------------------
+// selEventOpSel
+//---------------------------------------------------------
+
+void MidiTransformerDialog::selEventOpSel(int val)
+ {
+ selType->setEnabled(val != All);
+ data->cmt->selEventOp = ValOp(val);
+ selVal1aChanged(data->cmt->selVal1a);
+ selVal1bChanged(data->cmt->selVal1b);
+ }
+
+//---------------------------------------------------------
+// selTypeSel
+//---------------------------------------------------------
+
+void MidiTransformerDialog::selTypeSel(int val)
+ {
+ data->cmt->selType = EventType(eventTypeTable[val]);
+ selVal1aChanged(data->cmt->selVal1a);
+ selVal1bChanged(data->cmt->selVal1b);
+ }
+
+//---------------------------------------------------------
+// selVal1OpSel
+//---------------------------------------------------------
+
+void MidiTransformerDialog::selVal1OpSel(int val)
+ {
+ setValOp(selVal1a, selVal1b, ValOp(val));
+ data->cmt->selVal1 = ValOp(val);
+ }
+
+//---------------------------------------------------------
+// selVal2OpSel
+//---------------------------------------------------------
+
+void MidiTransformerDialog::selVal2OpSel(int val)
+ {
+ setValOp(selVal2a, selVal2b, ValOp(val));
+ data->cmt->selVal2 = ValOp(val);
+ }
+
+//---------------------------------------------------------
+// selLenOpSel
+//---------------------------------------------------------
+
+void MidiTransformerDialog::selLenOpSel(int val)
+ {
+ setValOp(selLenA, selLenB, ValOp(val));
+ data->cmt->selLen = ValOp(val);
+ }
+
+//---------------------------------------------------------
+// selRangeOpSel
+//---------------------------------------------------------
+
+void MidiTransformerDialog::selRangeOpSel(int val)
+ {
+ setValOp(selBarA, selBarB, ValOp(val));
+ data->cmt->selRange = ValOp(val);
+ }
+
+//---------------------------------------------------------
+// procEventOpSel
+//---------------------------------------------------------
+
+void MidiTransformerDialog::procEventOpSel(int val)
+ {
+ TransformOperator op = val == 0 ? Keep : Fix;
+ procType->setEnabled(op == Fix);
+ data->cmt->procEvent = op;
+ }
+
+//---------------------------------------------------------
+// procEventTypeSel
+//---------------------------------------------------------
+
+void MidiTransformerDialog::procEventTypeSel(int val)
+ {
+ data->cmt->eventType = EventType(eventTypeTable[val]);
+ }
+
+//---------------------------------------------------------
+// procVal1OpSel
+//---------------------------------------------------------
+
+void MidiTransformerDialog::procVal1OpSel(int val)
+ {
+ data->cmt->procVal1 = TransformOperator(val);
+ switch(TransformOperator(val)) {
+ case Keep:
+ case Invert:
+ procVal1a->setEnabled(false);
+ procVal1b->setEnabled(false);
+ break;
+ case Multiply:
+ case Divide:
+ procVal1a->setEnabled(true);
+// procVal1a->setPrecision(2);
+ procVal1b->setEnabled(false);
+ break;
+ case Plus:
+ case Minus:
+ case Fix:
+ case Value:
+ case Flip:
+// procVal1a->setPrecision(0);
+ procVal1a->setEnabled(true);
+ procVal1b->setEnabled(false);
+ break;
+ case Random:
+ case ScaleMap:
+ case Dynamic:
+// procVal1a->setPrecision(0);
+ procVal1a->setEnabled(true);
+ procVal1b->setEnabled(true);
+ break;
+ }
+ }
+
+//---------------------------------------------------------
+// procVal2OpSel
+//---------------------------------------------------------
+
+void MidiTransformerDialog::procVal2OpSel(int val)
+ {
+ TransformOperator op = TransformOperator(procVal2Map[val]);
+ data->cmt->procVal2 = op;
+
+ switch (op) {
+ case Keep:
+ case Invert:
+ procVal2a->setEnabled(false);
+ procVal2b->setEnabled(false);
+ break;
+ case Multiply:
+ case Divide:
+ procVal2a->setEnabled(true);
+// procVal2a->setPrecision(2);
+ procVal2b->setEnabled(false);
+ break;
+ case Plus:
+ case Minus:
+ case Fix:
+ case Value:
+// procVal2a->setPrecision(0);
+ procVal2a->setEnabled(true);
+ procVal2b->setEnabled(false);
+ break;
+ case Random:
+ case Dynamic:
+// procVal2a->setPrecision(0);
+ procVal2a->setEnabled(true);
+ procVal2b->setEnabled(true);
+ break;
+ default:
+ break;
+ }
+ }
+
+//---------------------------------------------------------
+// procLenOpSel
+//---------------------------------------------------------
+
+void MidiTransformerDialog::procLenOpSel(int val)
+ {
+ TransformOperator op = TransformOperator(val);
+ data->cmt->procLen = op;
+
+ switch (op) {
+ case Keep:
+ case Invert:
+ procLenA->setEnabled(false);
+ break;
+ case Plus:
+ case Minus:
+ case Fix:
+// procLenA->setPrecision(0);
+ procLenA->setEnabled(true);
+ break;
+ case Multiply:
+ case Divide:
+// procLenA->setPrecision(2);
+ procLenA->setEnabled(true);
+ break;
+ default:
+ break;
+ }
+ }
+
+//---------------------------------------------------------
+// procPosOpSel
+//---------------------------------------------------------
+
+void MidiTransformerDialog::procPosOpSel(int val)
+ {
+ TransformOperator op = TransformOperator(val);
+ data->cmt->procPos = op;
+
+ switch (op) {
+ case Keep:
+ case Invert:
+ procPosA->setEnabled(false);
+ break;
+ case Multiply:
+ case Divide:
+// procPosA->setPrecision(2);
+ procPosA->setEnabled(true);
+ break;
+ case Plus:
+ case Minus:
+// procPosA->setPrecision(0);
+ procPosA->setEnabled(true);
+ break;
+ default:
+ break;
+ }
+ }
+
+//---------------------------------------------------------
+// funcOpSel
+//---------------------------------------------------------
+
+void MidiTransformerDialog::funcOpSel(int val)
+ {
+ funcQuantVal->setEnabled(val == Quantize);
+ bool isFuncOp = val == Transform || val == Insert;
+
+ procEventOp->setEnabled(isFuncOp);
+ procType->setEnabled(isFuncOp);
+ procVal1Op->setEnabled(isFuncOp);
+ procVal1a->setEnabled(isFuncOp);
+ procVal1b->setEnabled(isFuncOp);
+ procVal2Op->setEnabled(isFuncOp);
+ procVal2a->setEnabled(isFuncOp);
+ procVal2b->setEnabled(isFuncOp);
+ procLenOp->setEnabled(isFuncOp);
+ procLenA->setEnabled(isFuncOp);
+ procPosOp->setEnabled(isFuncOp);
+ procPosA->setEnabled(isFuncOp);
+ if (isFuncOp) {
+ procEventOpSel(data->cmt->procEvent);
+ procVal1OpSel(data->cmt->procVal1);
+ procVal2OpSel(data->cmt->procVal2);
+ procLenOpSel(data->cmt->procLen);
+ procPosOpSel(data->cmt->procPos);
+ }
+ data->cmt->funcOp = TransformFunction(val);
+ }
+
+//---------------------------------------------------------
+// presetNew
+//---------------------------------------------------------
+
+void MidiTransformerDialog::presetNew()
+ {
+ QString name;
+ for (int i = 0;; ++i) {
+ name.sprintf("New-%d", i);
+ iMidiTransformation imt;
+ for (imt = mtlist.begin(); imt != mtlist.end(); ++imt) {
+ if (name == (*imt)->name)
+ break;
+ }
+ if (imt == mtlist.end())
+ break;
+ }
+ MidiTransformation* mt = new MidiTransformation(name);
+ Q3ListBoxText* lbi = new Q3ListBoxText(presetList, name);
+ mtlist.push_back(mt);
+ presetList->setCurrentItem(lbi);
+ }
+
+//---------------------------------------------------------
+// presetDelete
+//---------------------------------------------------------
+
+void MidiTransformerDialog::presetDelete()
+ {
+ if (data->cindex != -1) {
+ iMidiTransformation mt = mtlist.begin();
+ for (int i = 0; i < data->cindex; ++i, ++mt) {
+ mtlist.erase(mt);
+ presetList->removeItem(data->cindex);
+ break;
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// presetChanged
+//---------------------------------------------------------
+
+void MidiTransformerDialog::presetChanged(Q3ListBoxItem* item)
+ {
+ data->cindex = presetList->index(item);
+ iMidiTransformation i;
+ for (i = mtlist.begin(); i != mtlist.end(); ++i) {
+ if (item->text() == (*i)->name) {
+ data->cmt = *i;
+ break;
+ }
+ }
+ if (i == mtlist.end()) {
+ printf("MidiTransformerDialog::presetChanged: not found\n");
+ return;
+ }
+ nameEntry->setText(data->cmt->name);
+ commentEntry->setText(data->cmt->comment);
+
+ selEventOp->setCurrentItem(data->cmt->selEventOp);
+ selEventOpSel(data->cmt->selEventOp);
+
+ for (unsigned i = 0; i < sizeof(eventTypeTable)/sizeof(*eventTypeTable); ++i) {
+ if (eventTypeTable[i] == data->cmt->selType) {
+ selType->setCurrentItem(i);
+ break;
+ }
+ }
+
+ selVal1Op->setCurrentItem(data->cmt->selVal1);
+ selVal1OpSel(data->cmt->selVal1);
+
+ selVal2Op->setCurrentItem(data->cmt->selVal2);
+ selVal2OpSel(data->cmt->selVal2);
+
+ selLenOp->setCurrentItem(data->cmt->selLen);
+ selLenOpSel(data->cmt->selLen);
+
+ selRangeOp->setCurrentItem(data->cmt->selRange);
+ selRangeOpSel(data->cmt->selRange);
+
+ funcOp->setCurrentItem(data->cmt->funcOp);
+ funcOpSel(data->cmt->funcOp);
+
+ // TransformOperator procEvent: Keep, Fix
+ procEventOp->setCurrentItem(data->cmt->procEvent == Fix);
+
+ procEventOpSel(data->cmt->procEvent);
+
+ procVal1Op->setCurrentItem(data->cmt->procVal1);
+ procVal1OpSel(data->cmt->procVal1);
+
+ for (unsigned i = 0; i < sizeof(procVal2Map)/sizeof(*procVal2Map); ++i) {
+ if (procVal2Map[i] == data->cmt->procVal2) {
+ procVal2Op->setCurrentItem(i);
+ break;
+ }
+ }
+ procLenOp->setCurrentItem(data->cmt->procLen);
+ procLenOpSel(data->cmt->procLen);
+
+ procPosOp->setCurrentItem(data->cmt->procPos);
+ procPosOpSel(data->cmt->procPos);
+
+ selVal1aChanged(data->cmt->selVal1a);
+ selVal1bChanged(data->cmt->selVal1b);
+ selVal2a->setValue(data->cmt->selVal2a);
+ selVal2b->setValue(data->cmt->selVal2b);
+ selLenA->setValue(data->cmt->selLenA);
+ selLenB->setValue(data->cmt->selLenB);
+ selBarA->setValue(data->cmt->selRangeA);
+ selBarB->setValue(data->cmt->selRangeB);
+ procVal1a->setValue(data->cmt->procVal1a);
+ procVal1b->setValue(data->cmt->procVal1b);
+ procVal2a->setValue(data->cmt->procVal2a);
+ procVal2b->setValue(data->cmt->procVal2b);
+ procLenA->setValue(data->cmt->procLenA);
+ procPosA->setValue(data->cmt->procPosA);
+ funcQuantVal->setValue(data->cmt->quantVal);
+
+ selectedTracks->setChecked(data->cmt->selectedTracks);
+ selectedTracksChanged(data->cmt->selectedTracks);
+ insideLoop->setChecked(data->cmt->insideLoop);
+ insideLoopChanged(data->cmt->insideLoop);
+ }
+
+//---------------------------------------------------------
+// nameChanged
+//---------------------------------------------------------
+
+void MidiTransformerDialog::nameChanged(const QString& s)
+ {
+ data->cmt->name = s;
+ Q3ListBoxItem* item = presetList->item(data->cindex);
+ if (s != item->text()) {
+ disconnect(presetList, SIGNAL(highlighted(Q3ListBoxItem*)),
+ this, SLOT(presetChanged(Q3ListBoxItem*)));
+ presetList->changeItem(s, data->cindex);
+ connect(presetList, SIGNAL(highlighted(Q3ListBoxItem*)),
+ SLOT(presetChanged(Q3ListBoxItem*)));
+ }
+ }
+
+//---------------------------------------------------------
+// commentChanged
+//---------------------------------------------------------
+
+void MidiTransformerDialog::commentChanged()
+ {
+ data->cmt->comment = commentEntry->text();
+ }
+
+//---------------------------------------------------------
+// selVal1aChanged
+//---------------------------------------------------------
+
+void MidiTransformerDialog::selVal1aChanged(int val)
+ {
+ data->cmt->selVal1a = val;
+ if ((data->cmt->selEventOp != All)
+ && (data->cmt->selType == Note)) {
+ selVal1a->setSuffix(" - " + pitch2string(val));
+ }
+ else
+ selVal1a->setSuffix(QString(""));
+ }
+
+//---------------------------------------------------------
+// selVal1bChanged
+//---------------------------------------------------------
+
+void MidiTransformerDialog::selVal1bChanged(int val)
+ {
+ data->cmt->selVal1b = val;
+ if ((data->cmt->selEventOp != All)
+ && (data->cmt->selType == Note)) {
+ selVal1b->setSuffix(" - " + pitch2string(val));
+ }
+ else
+ selVal1b->setSuffix(QString(""));
+ }
+
+//---------------------------------------------------------
+// selVal2aChanged
+//---------------------------------------------------------
+
+void MidiTransformerDialog::selVal2aChanged(int val)
+ {
+ data->cmt->selVal2a = val;
+ }
+
+//---------------------------------------------------------
+// selVal2bChanged
+//---------------------------------------------------------
+
+void MidiTransformerDialog::selVal2bChanged(int val)
+ {
+ data->cmt->selVal2b = val;
+ }
+
+//---------------------------------------------------------
+// selLenAChanged
+//---------------------------------------------------------
+
+void MidiTransformerDialog::selLenAChanged(int val)
+ {
+ data->cmt->selLenA = val;
+ }
+
+//---------------------------------------------------------
+// selLenBChanged
+//---------------------------------------------------------
+
+void MidiTransformerDialog::selLenBChanged(int val)
+ {
+ data->cmt->selLenB = val;
+ }
+
+//---------------------------------------------------------
+// selBarAChanged
+//---------------------------------------------------------
+
+void MidiTransformerDialog::selBarAChanged(int val)
+ {
+ data->cmt->selRangeA = val;
+ }
+
+//---------------------------------------------------------
+// selBarBChanged
+//---------------------------------------------------------
+
+void MidiTransformerDialog::selBarBChanged(int val)
+ {
+ data->cmt->selRangeB = val;
+ }
+
+//---------------------------------------------------------
+// procVal1aChanged
+//---------------------------------------------------------
+
+void MidiTransformerDialog::procVal1aChanged(int val)
+ {
+ data->cmt->procVal1a = val;
+ }
+
+//---------------------------------------------------------
+// procVal1bChanged
+//---------------------------------------------------------
+
+void MidiTransformerDialog::procVal1bChanged(int val)
+ {
+ data->cmt->procVal1b = val;
+ }
+
+//---------------------------------------------------------
+// procVal2aChanged
+//---------------------------------------------------------
+
+void MidiTransformerDialog::procVal2aChanged(int val)
+ {
+ data->cmt->procVal2a = val;
+ }
+
+//---------------------------------------------------------
+// procVal2bChanged
+//---------------------------------------------------------
+
+void MidiTransformerDialog::procVal2bChanged(int val)
+ {
+ data->cmt->procVal2b = val;
+ }
+
+//---------------------------------------------------------
+// procLenAChanged
+//---------------------------------------------------------
+
+void MidiTransformerDialog::procLenAChanged(int val)
+ {
+ data->cmt->procLenA = val;
+ }
+
+//---------------------------------------------------------
+// procPosAChanged
+//---------------------------------------------------------
+
+void MidiTransformerDialog::procPosAChanged(int val)
+ {
+ data->cmt->procPosA = val;
+ }
+
+//---------------------------------------------------------
+// funcQuantValSel
+//---------------------------------------------------------
+
+void MidiTransformerDialog::funcQuantValSel(int val)
+ {
+ data->cmt->quantVal = val;
+ }
+
+//---------------------------------------------------------
+// processAllChanged
+//---------------------------------------------------------
+
+void MidiTransformerDialog::processAllChanged(bool val)
+ {
+ if (val == true) {
+ selectedTracks->setChecked(false);
+ insideLoop->setChecked(false);
+ data->cmt->selectedTracks = false;
+ data->cmt->insideLoop = false;
+ }
+ }
+
+//---------------------------------------------------------
+// selectedTracksChanged
+//---------------------------------------------------------
+
+void MidiTransformerDialog::selectedTracksChanged(bool val)
+ {
+ data->cmt->selectedTracks = val;
+ processAll->setChecked(!val && !data->cmt->insideLoop);
+ }
+
+//---------------------------------------------------------
+// insideLoopChanged
+//---------------------------------------------------------
+
+void MidiTransformerDialog::insideLoopChanged(bool val)
+ {
+ data->cmt->insideLoop = val;
+ processAll->setChecked(!data->cmt->selectedTracks && !val);
+ }
+
diff --git a/muse_qt4_evolution/muse/miditransform.h b/muse_qt4_evolution/muse/miditransform.h
new file mode 100644
index 00000000..1931ce78
--- /dev/null
+++ b/muse_qt4_evolution/muse/miditransform.h
@@ -0,0 +1,113 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __MIDITRANSFORM_H__
+#define __MIDITRANSFORM_H__
+
+#include "widgets/transformbase.h"
+
+class MidiTransformation;
+class MidiTransformPrivate;
+class Event;
+class Part;
+
+namespace AL {
+ class Xml;
+ };
+using AL::Xml;
+
+enum ValOp {
+ All=0, Ignore=0, Equal=1, Unequal=2, Higher=3, Lower=4,
+ Inside=5, Outside=6
+ };
+
+enum TransformFunction {
+ Select, Quantize, Delete, Transform, Insert, Copy, Extract
+ };
+
+enum TransformOperator {
+ Keep, Plus, Minus, Multiply, Divide, Fix, Value, Invert,
+ ScaleMap, Flip, Dynamic, Random
+ };
+
+//---------------------------------------------------------
+// MidiTransformDialog
+//---------------------------------------------------------
+
+class MidiTransformerDialog : public MidiTransformDialogBase {
+ Q_OBJECT
+ MidiTransformPrivate* data;
+
+ virtual void accept();
+// virtual void reject();
+ void setValOp(QWidget* a, QWidget* b, ValOp op);
+ void processEvent(Event&, Part*, Part*);
+ bool isSelected(Event&, Part*);
+ void transformEvent(Event&, Part*, Part*);
+
+ private slots:
+ void apply();
+ void presetNew();
+ void presetDelete();
+
+ void selEventOpSel(int);
+ void selTypeSel(int);
+ void selVal1OpSel(int);
+ void selVal2OpSel(int);
+ void selLenOpSel(int);
+ void selRangeOpSel(int);
+ void procEventOpSel(int);
+ void procEventTypeSel(int);
+ void procVal1OpSel(int);
+ void procVal2OpSel(int);
+ void procLenOpSel(int);
+ void procPosOpSel(int);
+ void funcOpSel(int);
+ void presetChanged(QListWidgetItem*);
+ void nameChanged(const QString&);
+ void commentChanged();
+ void selVal1aChanged(int);
+ void selVal1bChanged(int);
+ void selVal2aChanged(int);
+ void selVal2bChanged(int);
+ void selLenAChanged(int);
+ void selLenBChanged(int);
+ void selBarAChanged(int);
+ void selBarBChanged(int);
+ void procVal1aChanged(int);
+ void procVal1bChanged(int);
+ void procVal2aChanged(int);
+ void procVal2bChanged(int);
+ void procLenAChanged(int);
+ void procPosAChanged(int);
+ void funcQuantValSel(int);
+ void processAllChanged(bool);
+ void selectedTracksChanged(bool);
+ void insideLoopChanged(bool);
+
+ public:
+ MidiTransformerDialog(QWidget* parent = 0, const char* name = 0,
+ bool modal = false, Qt::WFlags fl = 0);
+ ~MidiTransformerDialog();
+ };
+
+extern void writeMidiTransforms(Xml& xml);
+extern void readMidiTransform(QDomNode);
+#endif
diff --git a/muse_qt4_evolution/muse/mixer.cpp b/muse_qt4_evolution/muse/mixer.cpp
new file mode 100644
index 00000000..b3e5ce06
--- /dev/null
+++ b/muse_qt4_evolution/muse/mixer.cpp
@@ -0,0 +1,397 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "muse.h"
+#include "mixer.h"
+#include "song.h"
+#include "icons.h"
+#include "astrip.h"
+#include "mstrip.h"
+#include "routedialog.h"
+#include "synth.h"
+#include "midiinport.h"
+#include "midioutport.h"
+
+extern void populateAddTrack(QMenu* addTrack);
+
+//---------------------------------------------------------
+// Mixer
+//
+// inputs | synthis | tracks | groups | master
+//---------------------------------------------------------
+
+Mixer::Mixer(QWidget* parent, MixerConfig* c)
+ : QMainWindow(parent)
+ {
+ mustUpdateMixer = false;
+ cfg = c;
+ routingDialog = 0;
+ setWindowTitle(tr("MusE: Mixer"));
+ setWindowIcon(*museIcon);
+
+ QMenu* menuCreate = menuBar()->addMenu(tr("&Create"));
+ populateAddTrack(menuCreate);
+
+ menuView = menuBar()->addMenu(tr("&View"));
+ routingAction = menuView->addAction(tr("Routing"), this, SLOT(toggleRouteDialog()));
+ routingAction->setCheckable(true);
+
+ showMidiTracksId = menuView->addAction(tr("Show Midi Tracks"));
+ showMidiOutPortId = menuView->addAction(tr("Show Midi Out Ports"));
+ showMidiInPortId = menuView->addAction(tr("Show Midi In Ports"));
+
+ menuView->addSeparator();
+
+ showWaveTracksId = menuView->addAction(tr("Show Wave Tracks"));
+ showOutputTracksId = menuView->addAction(tr("Show Output Tracks"));
+ showGroupTracksId = menuView->addAction(tr("Show Group Tracks"));
+ showInputTracksId = menuView->addAction(tr("Show Input Tracks"));
+ showSyntiTracksId = menuView->addAction(tr("Show Synthesizer"));
+ connect(menuView, SIGNAL(triggered(QAction*)), SLOT(showTracksChanged(QAction*)));
+
+ showMidiTracksId->setCheckable(true);
+ showMidiInPortId->setCheckable(true);
+ showMidiOutPortId->setCheckable(true);
+ showWaveTracksId->setCheckable(true);
+ showOutputTracksId->setCheckable(true);
+ showGroupTracksId->setCheckable(true);
+ showInputTracksId->setCheckable(true);
+ showSyntiTracksId->setCheckable(true);
+
+ QScrollArea* view = new QScrollArea;
+ view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ setCentralWidget(view);
+
+ central = new QWidget;
+ layout = new QHBoxLayout;
+ central->setLayout(layout);
+ layout->setSpacing(0);
+ layout->setMargin(0);
+ view->setWidget(central);
+ view->setWidgetResizable(true);
+
+ connect(song, SIGNAL(songChanged(int)), SLOT(songChanged(int)));
+ connect(muse, SIGNAL(configChanged()), SLOT(configChanged()));
+ song->update(); // calls update mixer
+ }
+
+//---------------------------------------------------------
+// addStrip
+//---------------------------------------------------------
+
+void Mixer::addStrip(Track* t, int idx)
+ {
+ StripList::iterator si = stripList.begin();
+ for (int i = 0; i < idx; ++i) {
+ if (si != stripList.end())
+ ++si;
+ }
+ if (si != stripList.end() && (*si)->getTrack() == t)
+ return;
+
+ StripList::iterator nsi = si;
+ ++nsi;
+ if (si != stripList.end()
+ && nsi != stripList.end()
+ && (*nsi)->getTrack() == t) {
+ layout->removeWidget(*si);
+ delete *si;
+ stripList.erase(si);
+ }
+ else {
+ Strip* strip;
+ switch(t->type()) {
+ case Track::MIDI_IN:
+ strip = new MidiInPortStrip(this, (MidiInPort*)t, true);
+ break;
+ case Track::MIDI_OUT:
+ strip = new MidiOutPortStrip(this, (MidiOutPort*)t, true);
+ break;
+ case Track::MIDI:
+ strip = new MidiStrip(this, (MidiTrack*)t, true);
+ break;
+ case Track::MIDI_SYNTI:
+ strip = new MidiSyntiStrip(this, (MidiSynti*)t, true);
+ break;
+ default:
+ strip = new AudioStrip(this, (AudioTrack*)t, true);
+ break;
+ }
+ layout->insertWidget(idx, strip);
+ stripList.insert(si, strip);
+ strip->show();
+ }
+ }
+
+//---------------------------------------------------------
+// clear
+//---------------------------------------------------------
+
+void Mixer::clear()
+ {
+ QLayoutItem* i;
+ while ((i = layout->takeAt(0))) {
+ if (i->widget())
+ delete i->widget();
+ delete i;
+ }
+ stripList.clear();
+ }
+
+//---------------------------------------------------------
+// updateMixer
+//---------------------------------------------------------
+
+void Mixer::updateMixer(int action)
+ {
+ showMidiTracksId->setChecked(cfg->showMidiTracks);
+ showMidiInPortId->setChecked(cfg->showMidiInPorts);
+ showMidiOutPortId->setChecked(cfg->showMidiOutPorts);
+ showWaveTracksId->setChecked(cfg->showWaveTracks);
+ showOutputTracksId->setChecked(cfg->showOutputTracks);
+ showGroupTracksId->setChecked(cfg->showGroupTracks);
+ showInputTracksId->setChecked(cfg->showInputTracks);
+ showSyntiTracksId->setChecked(cfg->showSyntiTracks);
+
+ if (action == STRIP_REMOVED) {
+ foreach(Strip* strip, stripList) {
+ Track* track = strip->getTrack();
+ if (song->trackExists(track))
+ continue;
+ layout->removeWidget(strip);
+ delete strip;
+ stripList.removeAt(stripList.indexOf(strip));
+ }
+ int idx = stripList.size();
+ setMaximumWidth(STRIP_WIDTH * idx + 4);
+ central->setFixedWidth(STRIP_WIDTH * idx);
+ if (idx < 4)
+ setMinimumWidth(idx * STRIP_WIDTH + 4);
+ return;
+ }
+
+ clear();
+
+ int idx = 0;
+ //---------------------------------------------------
+ // generate Input Strips
+ //---------------------------------------------------
+
+ if (cfg->showInputTracks) {
+ InputList* itl = song->inputs();
+ for (iAudioInput i = itl->begin(); i != itl->end(); ++i)
+ addStrip(*i, idx++);
+ }
+
+ //---------------------------------------------------
+ // Synthesizer Strips
+ //---------------------------------------------------
+
+ if (cfg->showSyntiTracks) {
+ SynthIList* sl = song->syntis();
+ for (iSynthI i = sl->begin(); i != sl->end(); ++i)
+ addStrip(*i, idx++);
+ }
+
+ //---------------------------------------------------
+ // generate Wave Track Strips
+ //---------------------------------------------------
+
+ if (cfg->showWaveTracks) {
+ WaveTrackList* wtl = song->waves();
+ for (iWaveTrack i = wtl->begin(); i != wtl->end(); ++i)
+ addStrip(*i, idx++);
+ }
+
+ //---------------------------------------------------
+ // generate Midi strips
+ //---------------------------------------------------
+
+ if (cfg->showMidiInPorts) {
+ MidiInPortList* mpl = song->midiInPorts();
+ for (iMidiInPort i = mpl->begin(); i != mpl->end(); ++i)
+ addStrip(*i, idx++);
+ }
+
+ if (cfg->showMidiSyntiPorts) {
+ MidiSyntiList* mpl = song->midiSyntis();
+ for (iMidiSynti i = mpl->begin(); i != mpl->end(); ++i)
+ addStrip(*i, idx++);
+ }
+
+ if (cfg->showMidiTracks) {
+ MidiTrackList* mtl = song->midis();
+ for (iMidiTrack i = mtl->begin(); i != mtl->end(); ++i)
+ addStrip(*i, idx++);
+ }
+
+ if (cfg->showMidiOutPorts) {
+ MidiOutPortList* mpl = song->midiOutPorts();
+ for (iMidiOutPort i = mpl->begin(); i != mpl->end(); ++i)
+ addStrip(*i, idx++);
+ }
+
+ //---------------------------------------------------
+ // Groups
+ //---------------------------------------------------
+
+ if (cfg->showGroupTracks) {
+ GroupList* gtl = song->groups();
+ for (iAudioGroup i = gtl->begin(); i != gtl->end(); ++i)
+ addStrip(*i, idx++);
+ }
+
+ //---------------------------------------------------
+ // Master
+ //---------------------------------------------------
+
+ if (cfg->showOutputTracks) {
+ OutputList* otl = song->outputs();
+ for (iAudioOutput i = otl->begin(); i != otl->end(); ++i)
+ addStrip(*i, idx++);
+ }
+ setMaximumWidth(STRIP_WIDTH * idx + 4);
+ central->setFixedWidth(STRIP_WIDTH * idx);
+ if (idx < 4)
+ setMinimumWidth(idx * STRIP_WIDTH + 4);
+ layout->update();
+ }
+
+//---------------------------------------------------------
+// songChanged
+//---------------------------------------------------------
+
+void Mixer::songChanged(int flags)
+ {
+ int action = NO_UPDATE;
+ if (flags == -1)
+ action = UPDATE_ALL;
+ else {
+ if (flags & SC_TRACK_REMOVED)
+ action |= STRIP_REMOVED;
+ if (flags & SC_TRACK_INSERTED)
+ action |= STRIP_INSERTED;
+ }
+ if (action != NO_UPDATE)
+ updateMixer(action);
+ }
+
+//---------------------------------------------------------
+// closeEvent
+//---------------------------------------------------------
+
+void Mixer::closeEvent(QCloseEvent* e)
+ {
+ emit closed();
+ e->accept();
+ }
+
+//---------------------------------------------------------
+// toggleRouteDialog
+//---------------------------------------------------------
+
+void Mixer::toggleRouteDialog()
+ {
+ showRouteDialog(routingAction->isChecked());
+ }
+
+//---------------------------------------------------------
+// showRouteDialog
+//---------------------------------------------------------
+
+void Mixer::showRouteDialog(bool on)
+ {
+ if (on && routingDialog == 0) {
+ routingDialog = new RouteDialog(this);
+ connect(routingDialog, SIGNAL(closed()), SLOT(routingDialogClosed()));
+ }
+ if (routingDialog)
+ routingDialog->setShown(on);
+ routingAction->setChecked(on);
+ }
+
+//---------------------------------------------------------
+// routingDialogClosed
+//---------------------------------------------------------
+
+void Mixer::routingDialogClosed()
+ {
+ routingAction->setChecked(false);
+ }
+
+//---------------------------------------------------------
+// showTracksChanged
+//---------------------------------------------------------
+
+void Mixer::showTracksChanged(QAction* id)
+ {
+ bool val = id->isChecked();
+ if (id == showMidiTracksId)
+ cfg->showMidiTracks = val;
+ else if (id == showOutputTracksId)
+ cfg->showOutputTracks = val;
+ else if (id == showWaveTracksId)
+ cfg->showWaveTracks = val;
+ else if (id == showGroupTracksId)
+ cfg->showGroupTracks = val;
+ else if (id == showInputTracksId)
+ cfg->showInputTracks = val;
+ else if (id == showSyntiTracksId)
+ cfg->showSyntiTracks = val;
+ else if (id == showMidiInPortId)
+ cfg->showMidiInPorts = val;
+ else if (id == showMidiOutPortId)
+ cfg->showMidiOutPorts = val;
+ updateMixer(UPDATE_ALL);
+ }
+
+//---------------------------------------------------------
+// write
+//---------------------------------------------------------
+
+void Mixer::write(Xml& xml, const char* name)
+ {
+ xml.stag(QString(name));
+ xml.tag("geometry", geometry());
+ xml.tag("showMidiTracks", cfg->showMidiTracks);
+ xml.tag("showOutputTracks", cfg->showOutputTracks);
+ xml.tag("showWaveTracks", cfg->showWaveTracks);
+ xml.tag("showGroupTracks", cfg->showGroupTracks);
+ xml.tag("showInputTracks", cfg->showInputTracks);
+ xml.tag("showSyntiTracks", cfg->showSyntiTracks);
+ xml.tag("showMidiInPorts", cfg->showMidiInPorts);
+ xml.tag("showMidiOutPorts", cfg->showMidiOutPorts);
+ xml.etag(name);
+ }
+
+//---------------------------------------------------------
+// heartBeat
+//---------------------------------------------------------
+
+void Mixer::heartBeat()
+ {
+ if (mustUpdateMixer) {
+ updateMixer(STRIP_INSERTED | STRIP_REMOVED);
+ mustUpdateMixer = false;
+ }
+ foreach(Strip* s, stripList)
+ s->heartBeat();
+ }
+
diff --git a/muse_qt4_evolution/muse/mixer.h b/muse_qt4_evolution/muse/mixer.h
new file mode 100644
index 00000000..62c526a6
--- /dev/null
+++ b/muse_qt4_evolution/muse/mixer.h
@@ -0,0 +1,95 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __AMIXER_H__
+#define __AMIXER_H__
+
+#include "gconfig.h"
+
+class Meter;
+class Track;
+class Slider;
+class Knob;
+class RouteDialog;
+class Strip;
+
+typedef QList<Strip*> StripList;
+
+//---------------------------------------------------------
+// Mixer
+//---------------------------------------------------------
+
+class Mixer : public QMainWindow {
+ Q_OBJECT
+
+ MixerConfig* cfg;
+ StripList stripList;
+ QWidget* central;
+ QHBoxLayout* lbox;
+ Strip* master;
+ QHBoxLayout* layout;
+ QMenu* menuView;
+ RouteDialog* routingDialog;
+ QAction* routingAction;
+
+ QAction* routingId;
+ QAction* showMidiTracksId;
+ QAction* showMidiInPortId;
+ QAction* showMidiOutPortId;
+ QAction* showOutputTracksId;
+ QAction* showWaveTracksId;
+ QAction* showGroupTracksId;
+ QAction* showInputTracksId;
+ QAction* showSyntiTracksId;
+
+ bool mustUpdateMixer;
+
+ virtual void closeEvent(QCloseEvent*);
+ void addStrip(Track*, int);
+ void showRouteDialog(bool);
+
+ enum {
+ NO_UPDATE = 0,
+ STRIP_INSERTED = 1,
+ STRIP_REMOVED = 2,
+ UPDATE_ALL = 4
+ };
+ void updateMixer(int);
+
+ signals:
+ void closed();
+
+ private slots:
+ void songChanged(int);
+ void configChanged() { songChanged(-1); }
+ void toggleRouteDialog();
+ void routingDialogClosed();
+ void showTracksChanged(QAction*);
+
+ public:
+ Mixer(QWidget* parent, MixerConfig*);
+ void clear();
+ void write(Xml&, const char* name);
+ void setUpdateMixer() { mustUpdateMixer = true; }
+ void heartBeat();
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/mstrip.cpp b/muse_qt4_evolution/muse/mstrip.cpp
new file mode 100644
index 00000000..64b8132c
--- /dev/null
+++ b/muse_qt4_evolution/muse/mstrip.cpp
@@ -0,0 +1,1211 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2008 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "midictrl.h"
+#include "mstrip.h"
+#include "audio.h"
+#include "song.h"
+#include "mixer.h"
+#include "widgets/simplebutton.h"
+#include "widgets/utils.h"
+#include "audiodev.h"
+#include "synth.h"
+#include "midirack.h"
+#include "midiplugin.h"
+#include "midiinport.h"
+#include "midioutport.h"
+
+#include "awl/midimslider.h"
+#include "awl/midimeter.h"
+#include "awl/midivolentry.h"
+#include "awl/midipanentry.h"
+#include "awl/midipanknob.h"
+#include "awl/knob.h"
+
+enum { KNOB_PAN, KNOB_CHOR_SEND, KNOB_VAR_SEND, KNOB_REV_SEND };
+
+//---------------------------------------------------------
+// addMidiTracks
+// input == true
+// add routes from all possible midi tracks to input
+// route list of track(channel)
+// input == false
+// add routes to all midi tracks to output route
+// list of track(channel)
+//
+// Note: midi tracks do not have channels
+//---------------------------------------------------------
+
+void addMidiTracks(QMenu* menu, Track* track, int channel, bool input)
+ {
+ RouteList* rl = input ? track->inRoutes() : track->outRoutes();
+ RouteNode a(track, channel, RouteNode::TRACK);
+
+ MidiTrackList* tl = song->midis();
+ for (iMidiTrack i = tl->begin();i != tl->end(); ++i) {
+ MidiTrack* track = *i;
+ QAction* action = menu->addAction(track->name());
+ action->setCheckable(true);
+ RouteNode b(track);
+ Route r = input ? Route(b, a) : Route(a, b);
+ action->setData(QVariant::fromValue(r));
+ action->setChecked(rl->indexOf(r) != -1);
+ }
+ }
+
+//---------------------------------------------------------
+// addMidiInPorts
+// can only be added to input route lists
+//---------------------------------------------------------
+
+void Strip::addMidiInPorts(QMenu* menu, Track* dtrack, int channel)
+ {
+ RouteList* rl = dtrack->inRoutes();
+ RouteNode dst(dtrack, channel, RouteNode::TRACK);
+
+ MidiInPortList* tl = song->midiInPorts();
+ for (iMidiInPort i = tl->begin();i != tl->end(); ++i) {
+ MidiInPort* track = *i;
+ QMenu* m = menu->addMenu(track->name());
+ for (int ch = 0; ch < MIDI_CHANNELS; ++ch) {
+ QAction* a = m->addAction(QString("Channel %1").arg(ch+1));
+ a->setCheckable(true);
+ RouteNode src(track, ch, RouteNode::TRACK);
+ Route r = Route(src, dst);
+ a->setData(QVariant::fromValue(r));
+ a->setChecked(rl->indexOf(r) != -1);
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// addMidiOutPorts
+// can only be added to output route lists
+//---------------------------------------------------------
+
+void Strip::addMidiOutPorts(QMenu* menu, Track* strack, int channel)
+ {
+ RouteList* rl = strack->outRoutes();
+ RouteNode src(strack, channel, RouteNode::TRACK);
+
+ MidiOutPortList* tl = song->midiOutPorts();
+ for (iMidiOutPort i = tl->begin();i != tl->end(); ++i) {
+ MidiOutPort* op = *i;
+ QMenu* m = menu->addMenu(op->name());
+ for (int ch = 0; ch < MIDI_CHANNELS; ++ch) {
+ QAction* a = m->addAction(QString("Channel %1").arg(ch+1));
+ a->setCheckable(true);
+ RouteNode dst(op, ch, RouteNode::TRACK);
+ Route r = Route(src, dst);
+ a->setData(QVariant::fromValue(r));
+ a->setChecked(rl->indexOf(r) != -1);
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// addSyntiPorts
+// can only be added to output route lists
+//---------------------------------------------------------
+
+static void addSyntiPorts(QMenu* menu, Track* strack, int channel)
+ {
+ RouteList* rl = strack->outRoutes();
+ RouteNode src(strack, channel, RouteNode::TRACK);
+
+ SynthIList* sl = song->syntis();
+ for (iSynthI i = sl->begin(); i != sl->end(); ++i) {
+ SynthI* sy = *i;
+ QMenu* m = menu->addMenu(sy->name());
+ for (int ch = 0; ch < MIDI_CHANNELS; ++ch) {
+ QAction* a = m->addAction(QString("Channel %1").arg(ch+1));
+ a->setCheckable(true);
+ RouteNode dst(sy, ch, RouteNode::TRACK);
+ Route r = Route(src, dst);
+ a->setData(QVariant::fromValue(r));
+ a->setChecked(rl->indexOf(r) != -1);
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// addKnob
+//---------------------------------------------------------
+
+void MidiStrip::addKnob(int ctrl, int idx, const QString& tt, const QString& label,
+ const char* slot, bool enabled, int row)
+ {
+ Awl::FloatEntry* dl;
+ Awl::Knob* knob;
+
+ if (idx == KNOB_PAN) {
+ dl = new Awl::MidiPanEntry(this);
+ knob = new Awl::MidiPanKnob(this);
+ }
+ else {
+ dl = new Awl::MidiVolEntry(this);
+ knob = new Awl::Knob(this);
+ knob->setRange(0.0, 127.0);
+ }
+ knob->setId(ctrl);
+ dl->setId(ctrl);
+ dl->setFrame(true);
+
+ controller[idx].knob = knob;
+ knob->setToolTip(tt);
+ knob->setEnabled(enabled);
+
+ controller[idx].dl = dl;
+ dl->setFixedSize(entrySize);
+ dl->setEnabled(enabled);
+
+ QLabel* lb = new QLabel(label, this);
+ lb->setObjectName("knobLabel");
+ controller[idx].lb = lb;
+ lb->setFixedSize(entrySize);
+ lb->setAlignment(Qt::AlignCenter);
+ lb->setEnabled(enabled);
+
+ grid->addWidget(lb, row, 0);
+ grid->addWidget(dl, row+1, 0);
+ grid->addWidget(knob, row, 1, 2, 1);
+
+ connect(knob, SIGNAL(valueChanged(double,int)), slot);
+ connect(dl, SIGNAL(valueChanged(double,int)), slot);
+ connect(knob, SIGNAL(sliderPressed(int)), SLOT(sliderPressed(int)));
+ connect(knob, SIGNAL(sliderReleased(int)), SLOT(sliderReleased(int)));
+ }
+
+//---------------------------------------------------------
+// MidiStrip
+//---------------------------------------------------------
+
+MidiStrip::MidiStrip(Mixer* m, MidiTrack* t, bool align)
+ : Strip(m, t, align)
+ {
+ volumeTouched = false;
+ panTouched = false;
+ reverbSendTouched = false;
+ variSendTouched = false;
+ chorusSendTouched = false;
+
+ addKnob(CTRL_VARIATION_SEND, KNOB_VAR_SEND, tr("VariationSend"), tr("Var"), SLOT(ctrlChanged(double,int)), true, 1);
+ addKnob(CTRL_REVERB_SEND, KNOB_REV_SEND, tr("ReverbSend"), tr("Rev"), SLOT(ctrlChanged(double,int)), true, 3);
+ addKnob(CTRL_CHORUS_SEND, KNOB_CHOR_SEND, tr("ChorusSend"), tr("Cho"), SLOT(ctrlChanged(double,int)), true, 5);
+
+ //---------------------------------------------------
+ // slider, label, meter
+ //---------------------------------------------------
+
+ slider = new Awl::MidiMeterSlider(this);
+ slider->setId(CTRL_VOLUME);
+ slider->setFixedWidth(40);
+ grid->addWidget(slider, 7, 0, 1, 2, Qt::AlignRight);
+
+ sl = new Awl::MidiVolEntry(this);
+ sl->setId(CTRL_VOLUME);
+ sl->setFixedHeight(entrySize.height());
+
+ connect(slider, SIGNAL(valueChanged(double,int)), SLOT(ctrlChanged(double, int)));
+ connect(slider, SIGNAL(sliderPressed(int)), SLOT(sliderPressed(int)));
+ connect(slider, SIGNAL(sliderReleased(int)), SLOT(sliderReleased(int)));
+ connect(sl, SIGNAL(valueChanged(double,int)), SLOT(ctrlChanged(double, int)));
+ grid->addWidget(sl, 8, 0, 1, 2);
+
+ //---------------------------------------------------
+ // pan, balance
+ //---------------------------------------------------
+
+ addKnob(CTRL_PANPOT, KNOB_PAN, tr("Pan/Balance"), tr("Pan"), SLOT(ctrlChanged(double,int)), true, 9);
+
+ //---------------------------------------------------
+ // --- record
+ // mute, solo
+ //---------------------------------------------------
+
+ SimpleButton* monitor = newMonitorButton();
+ monitor->setFixedHeight(BUTTON_HEIGHT);
+ monitor->setChecked(track->monitor());
+ connect(monitor, SIGNAL(clicked(bool)), SLOT(monitorToggled(bool)));
+ connect(t, SIGNAL(monitorChanged(bool)), monitor, SLOT(setChecked(bool)));
+
+ SimpleButton* record = newRecordButton();
+ record->setFixedHeight(BUTTON_HEIGHT);
+ record->setChecked(track->recordFlag());
+ connect(record, SIGNAL(clicked(bool)), SLOT(recordToggled(bool)));
+ connect(t, SIGNAL(recordChanged(bool)), record, SLOT(setChecked(bool)));
+
+ mute = newMuteButton();
+ mute->setChecked(track->isMute());
+ mute->setFixedHeight(BUTTON_HEIGHT);
+ connect(mute, SIGNAL(clicked(bool)), SLOT(muteToggled(bool)));
+
+ solo = newSoloButton();
+ solo->setFixedHeight(BUTTON_HEIGHT);
+ solo->setChecked(track->solo());
+ connect(solo, SIGNAL(clicked(bool)), SLOT(soloToggled(bool)));
+
+ grid->addWidget(monitor, 11, 0);
+ grid->addWidget(record, 11, 1);
+ grid->addWidget(mute, 12, 0);
+ grid->addWidget(solo, 12, 1);
+
+ //---------------------------------------------------
+ // automation mode
+ //---------------------------------------------------
+
+ addAutomationButtons(13);
+
+ //---------------------------------------------------
+ // routing
+ //---------------------------------------------------
+
+ iR = newInRouteButton();
+ grid->addWidget(iR, 14, 0);
+ connect(iR->menu(), SIGNAL(aboutToShow()), SLOT(iRouteShow()));
+ connect(iR->menu(), SIGNAL(triggered(QAction*)), song, SLOT(routeChanged(QAction*)));
+
+ oR = newOutRouteButton();
+ grid->addWidget(oR, 14, 1);
+ connect(oR->menu(), SIGNAL(aboutToShow()), SLOT(oRouteShow()));
+ connect(oR->menu(), SIGNAL(triggered(QAction*)), song, SLOT(routeChanged(QAction*)));
+
+ connect(song, SIGNAL(songChanged(int)), SLOT(songChanged(int)));
+ connect(track, SIGNAL(muteChanged(bool)), mute, SLOT(setChecked(bool)));
+ connect(track, SIGNAL(soloChanged(bool)), solo, SLOT(setChecked(bool)));
+ connect(track, SIGNAL(autoReadChanged(bool)), SLOT(autoChanged()));
+ connect(track, SIGNAL(autoWriteChanged(bool)), SLOT(autoChanged()));
+ connect(track, SIGNAL(controllerChanged(int)), SLOT(controllerChanged(int)));
+ autoChanged();
+ controllerChanged(CTRL_VOLUME);
+ controllerChanged(CTRL_PANPOT);
+ controllerChanged(CTRL_VARIATION_SEND);
+ controllerChanged(CTRL_REVERB_SEND);
+ controllerChanged(CTRL_CHORUS_SEND);
+ }
+
+//---------------------------------------------------------
+// songChanged
+//---------------------------------------------------------
+
+void MidiStrip::songChanged(int val)
+ {
+ if (val & SC_TRACK_MODIFIED)
+ updateLabel();
+ }
+
+//---------------------------------------------------------
+// heartBeat
+//---------------------------------------------------------
+
+void MidiStrip::heartBeat()
+ {
+ double a = track->meter(0); // fast_log10(track->meter(0)) * .2f;
+ slider->setMeterVal(a * 0.008);
+ track->setMeter(0, a * 0.8); // hack
+ }
+
+//---------------------------------------------------------
+// controllerChanged
+//---------------------------------------------------------
+
+void MidiStrip::controllerChanged(int id)
+ {
+ CVal cv = track->ctrlVal(id);
+ double val = double(cv.i);
+
+ switch (id) {
+ case CTRL_VOLUME:
+ if (!volumeTouched)
+ slider->setValue(val);
+ sl->setValue(val);
+ break;
+ case CTRL_PANPOT:
+ if (!panTouched)
+ controller[KNOB_PAN].knob->setValue(val);
+ controller[KNOB_PAN].dl->setValue(val);
+ break;
+ case CTRL_VARIATION_SEND:
+ if (!variSendTouched)
+ controller[KNOB_VAR_SEND].knob->setValue(val);
+ controller[KNOB_VAR_SEND].dl->setValue(val);
+ break;
+ case CTRL_REVERB_SEND:
+ if (!reverbSendTouched)
+ controller[KNOB_REV_SEND].knob->setValue(val);
+ controller[KNOB_REV_SEND].dl->setValue(val);
+ break;
+ case CTRL_CHORUS_SEND:
+ if (!chorusSendTouched)
+ controller[KNOB_CHOR_SEND].knob->setValue(val);
+ controller[KNOB_CHOR_SEND].dl->setValue(val);
+ break;
+ }
+ }
+
+//---------------------------------------------------------
+// ctrlChanged
+// called when user changes controller
+//---------------------------------------------------------
+
+void MidiStrip::ctrlChanged(double val, int num)
+ {
+ int ival = int(val);
+ CVal cval;
+ cval.i = ival;
+ song->setControllerVal(track, num, cval);
+ }
+
+//---------------------------------------------------------
+// sliderPressed
+//---------------------------------------------------------
+
+void MidiStrip::sliderPressed(int id)
+ {
+ switch (id) {
+ case CTRL_VOLUME: volumeTouched = true; break;
+ case CTRL_PANPOT: panTouched = true; break;
+ case CTRL_VARIATION_SEND: variSendTouched = true; break;
+ case CTRL_REVERB_SEND: reverbSendTouched = true; break;
+ case CTRL_CHORUS_SEND: chorusSendTouched = true; break;
+ }
+ track->startAutoRecord(id);
+ }
+
+//---------------------------------------------------------
+// sliderReleased
+//---------------------------------------------------------
+
+void MidiStrip::sliderReleased(int id)
+ {
+ switch (id) {
+ case CTRL_VOLUME: volumeTouched = false; break;
+ case CTRL_PANPOT: panTouched = false; break;
+ case CTRL_VARIATION_SEND: variSendTouched = false; break;
+ case CTRL_REVERB_SEND: reverbSendTouched = false; break;
+ case CTRL_CHORUS_SEND: chorusSendTouched = false; break;
+ }
+ track->stopAutoRecord(id);
+ }
+
+//---------------------------------------------------------
+// muteToggled
+//---------------------------------------------------------
+
+void MidiStrip::muteToggled(bool val)
+ {
+ song->setMute(track, val);
+ }
+
+//---------------------------------------------------------
+// soloToggled
+//---------------------------------------------------------
+
+void MidiStrip::soloToggled(bool val)
+ {
+ song->setSolo(track, val);
+ }
+
+//---------------------------------------------------------
+// autoChanged
+//---------------------------------------------------------
+
+void MidiStrip::autoChanged()
+ {
+ bool ar = track->autoRead();
+ bool aw = track->autoWrite();
+
+ // controller are enabled if
+ // autoRead is off
+ // autoRead and autoWrite are on (touch mode)
+
+ bool ec = !ar || (ar && aw);
+ for (unsigned i = 0; i < sizeof(controller)/sizeof(*controller); ++i) {
+ controller[i].knob->setEnabled(ec);
+ controller[i].dl->setEnabled(ec);
+ }
+ slider->setEnabled(ec);
+ sl->setEnabled(ec);
+ }
+
+//---------------------------------------------------------
+// autoReadToggled
+//---------------------------------------------------------
+
+void MidiStrip::autoReadToggled(bool val)
+ {
+ song->setAutoRead(track, val);
+ }
+
+//---------------------------------------------------------
+// autoWriteToggled
+//---------------------------------------------------------
+
+void MidiStrip::autoWriteToggled(bool val)
+ {
+ song->setAutoWrite(track, val);
+ }
+
+//---------------------------------------------------------
+// iRouteShow
+//---------------------------------------------------------
+
+void MidiStrip::iRouteShow()
+ {
+ QMenu* pup = iR->menu();
+ pup->clear();
+ addMidiInPorts(pup, track, -1); // add midi inputs to menu
+ }
+
+//---------------------------------------------------------
+// oRouteShow
+//---------------------------------------------------------
+
+void MidiStrip::oRouteShow()
+ {
+ QMenu* pup = oR->menu();
+ pup->clear();
+ addMidiOutPorts(pup, track, -1);
+ addSyntiPorts(pup, track, -1);
+ }
+
+//---------------------------------------------------------
+// monitorToggled
+//---------------------------------------------------------
+
+void MidiStrip::monitorToggled(bool val)
+ {
+ song->setMonitor(track, val);
+ }
+
+//---------------------------------------------------------
+// recordToggled
+//---------------------------------------------------------
+
+void MidiStrip::recordToggled(bool val)
+ {
+ song->setRecordFlag(track, !val);
+ }
+
+//---------------------------------------------------------
+// MidiOutPortStrip
+//---------------------------------------------------------
+
+MidiOutPortStrip::MidiOutPortStrip(Mixer* m, MidiOutPort* t, bool align)
+ : Strip(m, t, align)
+ {
+ //---------------------------------------------------
+ // plugin rack
+ //---------------------------------------------------
+
+ MidiRack* rack = new MidiRack(this, t);
+ rack->setFixedHeight(rack->sizeHint().height()+2);
+ grid->addWidget(rack, 1, 0, 1, 2);
+
+
+ if (_align)
+ grid->setRowMinimumHeight(2, STRIP_WIDTH/2);
+
+ volumeTouched = false;
+
+ //---------------------------------------------------
+ // slider, label, meter
+ //---------------------------------------------------
+
+ slider = new Awl::MidiMeterSlider(this);
+ slider->setId(CTRL_MASTER_VOLUME);
+ slider->setRange(0.0, 1024*16.0);
+ slider->setFixedWidth(40);
+ grid->addWidget(slider, 3, 0, 1, 2, Qt::AlignRight);
+
+ sl = new Awl::MidiVolEntry(this);
+ sl->setId(CTRL_MASTER_VOLUME);
+ sl->setMax(128 * 128 - 1);
+// sl->setFont(config.fonts[1]);
+ sl->setFixedHeight(entrySize.height());
+
+ controllerChanged(CTRL_MASTER_VOLUME);
+
+ connect(slider, SIGNAL(valueChanged(double,int)), SLOT(ctrlChanged(double, int)));
+ connect(slider, SIGNAL(sliderPressed(int)), SLOT(sliderPressed(int)));
+ connect(slider, SIGNAL(sliderReleased(int)), SLOT(sliderReleased(int)));
+ connect(sl, SIGNAL(valueChanged(double,int)), SLOT(ctrlChanged(double, int)));
+ grid->addWidget(sl, 4, 0, 1, 2);
+
+ //---------------------------------------------------
+ // pan, balance
+ //---------------------------------------------------
+
+ if (_align)
+ grid->setRowMinimumHeight(5, entrySize.height() * 2);
+
+ //---------------------------------------------------
+ // sync
+ // mute, solo
+ //---------------------------------------------------
+
+ sync = newSyncButton();
+ sync->setFixedHeight(BUTTON_HEIGHT);
+ sync->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+ sync->setChecked(((MidiOutPort*)track)->sendSync());
+ grid->addWidget(sync, 6, 0, 1, 2);
+ connect(sync, SIGNAL(clicked(bool)), SLOT(syncToggled(bool)));
+ connect(track, SIGNAL(sendSyncChanged(bool)), sync, SLOT(setChecked(bool)));
+
+ mute = newMuteButton();
+ mute->setChecked(track->isMute());
+ mute->setFixedHeight(BUTTON_HEIGHT);
+ connect(mute, SIGNAL(clicked(bool)), SLOT(muteToggled(bool)));
+
+ solo = newSoloButton();
+ solo->setFixedHeight(BUTTON_HEIGHT);
+ solo->setChecked(track->solo());
+ connect(solo, SIGNAL(clicked(bool)), SLOT(soloToggled(bool)));
+
+ grid->addWidget(mute, 7, 0);
+ grid->addWidget(solo, 7, 1);
+
+ //---------------------------------------------------
+ // automation mode
+ //---------------------------------------------------
+
+ addAutomationButtons(8);
+
+ //---------------------------------------------------
+ // output routing
+ //---------------------------------------------------
+
+ iR = newInRouteButton();
+ grid->addWidget(iR, 9, 0);
+ connect(iR->menu(), SIGNAL(aboutToShow()), SLOT(iRouteShow()));
+ connect(iR->menu(), SIGNAL(triggered(QAction*)), song, SLOT(routeChanged(QAction*)));
+
+ oR = newOutRouteButton();
+ grid->addWidget(oR, 9, 1);
+ connect(oR->menu(), SIGNAL(aboutToShow()), SLOT(oRouteShow()));
+ connect(oR->menu(), SIGNAL(triggered(QAction*)), song, SLOT(routeChanged(QAction*)));
+
+ connect(song, SIGNAL(songChanged(int)), SLOT(songChanged(int)));
+ connect(track, SIGNAL(muteChanged(bool)), mute, SLOT(setChecked(bool)));
+ connect(track, SIGNAL(soloChanged(bool)), solo, SLOT(setChecked(bool)));
+ connect(track, SIGNAL(autoReadChanged(bool)), SLOT(autoChanged()));
+ connect(track, SIGNAL(autoWriteChanged(bool)), SLOT(autoChanged()));
+ autoChanged();
+ controllerChanged(CTRL_MASTER_VOLUME);
+ }
+
+//---------------------------------------------------------
+// songChanged
+//---------------------------------------------------------
+
+void MidiOutPortStrip::songChanged(int val)
+ {
+ if (val & SC_TRACK_MODIFIED)
+ updateLabel();
+ }
+
+//---------------------------------------------------------
+// heartBeat
+//---------------------------------------------------------
+
+void MidiOutPortStrip::heartBeat()
+ {
+ double a = track->meter(0); // fast_log10(track->meter(0)) * .2f;
+ slider->setMeterVal(a * 0.008);
+ track->setMeter(0, a * 0.8); // hack
+ }
+
+//---------------------------------------------------------
+// ctrlChanged
+//---------------------------------------------------------
+
+void MidiOutPortStrip::ctrlChanged(double val, int num)
+ {
+ int ival = int(val);
+ CVal cval;
+ cval.i = ival;
+ song->setControllerVal(track, num, cval);
+ }
+
+//---------------------------------------------------------
+// sliderPressed
+//---------------------------------------------------------
+
+void MidiOutPortStrip::sliderPressed(int id)
+ {
+ switch (id) {
+ case CTRL_MASTER_VOLUME: volumeTouched = true; break;
+ }
+ track->startAutoRecord(id);
+ }
+
+//---------------------------------------------------------
+// sliderReleased
+//---------------------------------------------------------
+
+void MidiOutPortStrip::sliderReleased(int id)
+ {
+ switch (id) {
+ case CTRL_MASTER_VOLUME: volumeTouched = false; break;
+ }
+ track->stopAutoRecord(id);
+ }
+
+//---------------------------------------------------------
+// muteToggled
+//---------------------------------------------------------
+
+void MidiOutPortStrip::muteToggled(bool val)
+ {
+ song->setMute(track, val);
+ }
+
+//---------------------------------------------------------
+// soloToggled
+//---------------------------------------------------------
+
+void MidiOutPortStrip::soloToggled(bool val)
+ {
+ song->setSolo(track, val);
+ }
+
+//---------------------------------------------------------
+// autoChanged
+//---------------------------------------------------------
+
+void MidiOutPortStrip::autoChanged()
+ {
+ bool ar = track->autoRead();
+ bool aw = track->autoWrite();
+
+ // controller are enabled if
+ // autoRead is off
+ // autoRead and autoWrite are on (touch mode)
+
+ bool ec = !ar || (ar && aw);
+ slider->setEnabled(ec);
+ sl->setEnabled(ec);
+ }
+
+//---------------------------------------------------------
+// autoReadToggled
+//---------------------------------------------------------
+
+void MidiOutPortStrip::autoReadToggled(bool val)
+ {
+ song->setAutoRead(track, val);
+ }
+
+//---------------------------------------------------------
+// autoWriteToggled
+//---------------------------------------------------------
+
+void MidiOutPortStrip::autoWriteToggled(bool val)
+ {
+ song->setAutoWrite(track, val);
+ }
+
+//---------------------------------------------------------
+// controllerChanged
+//---------------------------------------------------------
+
+void MidiOutPortStrip::controllerChanged(int id)
+ {
+ if (id == CTRL_MASTER_VOLUME) {
+ double val = double(track->ctrlVal(id).i);
+ if (!volumeTouched)
+ slider->setValue(val);
+ sl->setValue(val);
+ }
+ }
+
+//---------------------------------------------------------
+// iRouteShow
+//---------------------------------------------------------
+
+void MidiOutPortStrip::iRouteShow()
+ {
+ QMenu* pup = iR->menu();
+ pup->clear();
+
+ for (int ch = 0; ch < MIDI_CHANNELS; ++ch) {
+ QMenu* m = pup->addMenu(QString("Channel %1").arg(ch+1));
+ addMidiTracks(m, track, ch, true);
+ addMidiInPorts(m, track, ch);
+ }
+ }
+
+//---------------------------------------------------------
+// oRouteShow
+//---------------------------------------------------------
+
+void MidiOutPortStrip::oRouteShow()
+ {
+ QMenu* pup = oR->menu();
+ pup->clear();
+ RouteList* orl = track->outRoutes();
+
+ QList<PortName> ol;
+ //
+ // add JACK midi ports to list
+ //
+ ol = audioDriver->inputPorts(true);
+ foreach (PortName ip, ol) {
+ QAction* oa = pup->addAction(ip.name);
+ oa->setCheckable(true);
+ RouteNode dst(ip.port, RouteNode::JACKMIDIPORT);
+ Route r = Route(RouteNode(track), dst);
+ oa->setData(QVariant::fromValue(r));
+ oa->setChecked(orl->indexOf(r) != -1);
+ }
+ }
+
+//---------------------------------------------------------
+// syncToggled
+//---------------------------------------------------------
+
+void MidiOutPortStrip::syncToggled(bool val) const
+ {
+ ((MidiOutPort*)track)->setSendSync(val);
+ }
+
+//---------------------------------------------------------
+// MidiInPortStrip
+//---------------------------------------------------------
+
+MidiInPortStrip::MidiInPortStrip(Mixer* m, MidiInPort* t, bool align)
+ : Strip(m, t, align)
+ {
+ //---------------------------------------------------
+ // plugin rack
+ //---------------------------------------------------
+
+ MidiRack* rack = new MidiRack(this, t);
+ rack->setFixedHeight(rack->sizeHint().height()+2);
+ grid->addWidget(rack, 1, 0, 1, 2);
+
+ //---------------------------------------------------
+ // input activity
+ //---------------------------------------------------
+
+ grid->setRowStretch(2, 100);
+
+ QGridLayout* ag = new QGridLayout;
+ ag->setMargin(4);
+ ag->setSpacing(1);
+ QSvgRenderer sr;
+ QPainter painter;
+
+ sr.load(QString(":/xpm/activeon.svg"));
+ QSize aSize(sr.defaultSize());
+ activityOn = new QPixmap(aSize);
+ activityOn->fill(Qt::transparent);
+ painter.begin(activityOn);
+ sr.render(&painter);
+ painter.end();
+
+ sr.load(QString(":/xpm/activeoff.svg"));
+ activityOff = new QPixmap(aSize);
+ activityOff->fill(Qt::transparent);
+ painter.begin(activityOff);
+ sr.render(&painter);
+ painter.end();
+
+ for (int ch = MIDI_CHANNELS-1; ch >= 0; --ch) {
+ QLabel* l = new QLabel(QString("%1").arg(ch+1));
+ l->setObjectName("midiChannelLabel");
+ ag->addWidget(l, ch, 0, Qt::AlignCenter);
+ channelActivity[ch] = new QLabel;
+ ag->addWidget(channelActivity[ch], ch, 1, Qt::AlignCenter);
+ channelActivity[ch]->setPixmap(*activityOff);
+ activity[ch] = 0;
+ }
+ grid->addLayout(ag, 3, 0, 2, Qt::AlignHCenter);
+
+ if (_align)
+ grid->setRowMinimumHeight(4, BUTTON_HEIGHT);
+
+ //---------------------------------------------------
+ // mute, solo
+ // or
+ // record, mixdownfile
+ //---------------------------------------------------
+
+ mute = newMuteButton();
+ mute->setChecked(track->isMute());
+ mute->setFixedHeight(BUTTON_HEIGHT);
+ connect(mute, SIGNAL(clicked(bool)), SLOT(muteToggled(bool)));
+
+ solo = newSoloButton();
+ solo->setFixedHeight(BUTTON_HEIGHT);
+ solo->setChecked(track->solo());
+ connect(solo, SIGNAL(clicked(bool)), SLOT(soloToggled(bool)));
+
+ grid->addWidget(mute, 5, 0);
+ grid->addWidget(solo, 5, 1);
+
+ //---------------------------------------------------
+ // output routing
+ //---------------------------------------------------
+
+ if (_align)
+ grid->setRowMinimumHeight(6, BUTTON_HEIGHT);
+
+ iR = newInRouteButton();
+ connect(iR->menu(), SIGNAL(aboutToShow()), SLOT(iRouteShow()));
+ connect(iR->menu(), SIGNAL(triggered(QAction*)), song, SLOT(routeChanged(QAction*)));
+
+ oR = newOutRouteButton();
+ connect(oR->menu(), SIGNAL(aboutToShow()), SLOT(oRouteShow()));
+ connect(oR->menu(), SIGNAL(triggered(QAction*)), song, SLOT(routeChanged(QAction*)));
+
+ grid->addWidget(iR, 7, 0);
+ grid->addWidget(oR, 7, 1);
+
+ connect(song, SIGNAL(songChanged(int)), SLOT(songChanged(int)));
+ connect(track, SIGNAL(muteChanged(bool)), mute, SLOT(setChecked(bool)));
+ connect(track, SIGNAL(soloChanged(bool)), solo, SLOT(setChecked(bool)));
+ }
+
+//---------------------------------------------------------
+// songChanged
+//---------------------------------------------------------
+
+void MidiInPortStrip::songChanged(int val)
+ {
+ if (val & SC_TRACK_MODIFIED)
+ updateLabel();
+ }
+
+//---------------------------------------------------------
+// heartBeat
+//---------------------------------------------------------
+
+void MidiInPortStrip::heartBeat()
+ {
+ for (int i = 0; i < MIDI_CHANNELS; ++i) {
+ bool isActive = inport()->checkActivity(i);
+ if (activity[i] != isActive) {
+ channelActivity[i]->setPixmap(isActive ? *activityOn : *activityOff);
+ activity[i] = isActive;
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// muteToggled
+//---------------------------------------------------------
+
+void MidiInPortStrip::muteToggled(bool val)
+ {
+ song->setMute(track, val);
+ }
+
+//---------------------------------------------------------
+// soloToggled
+//---------------------------------------------------------
+
+void MidiInPortStrip::soloToggled(bool val)
+ {
+ song->setSolo(track, val);
+ }
+
+//---------------------------------------------------------
+// iRouteShow
+//---------------------------------------------------------
+
+void MidiInPortStrip::iRouteShow()
+ {
+ QMenu* pup = iR->menu();
+ pup->clear();
+
+ RouteList* irl = track->inRoutes();
+
+ QList<PortName> ol;
+ //
+ // add JACK midi ports to list
+ //
+ ol = audioDriver->outputPorts(true);
+ foreach (PortName ip, ol) {
+ QAction* action = pup->addAction(ip.name);
+ action->setCheckable(true);
+ RouteNode src(ip.port, RouteNode::JACKMIDIPORT);
+ Route r = Route(src, RouteNode(track));
+ action->setData(QVariant::fromValue(r));
+ action->setChecked(irl->indexOf(r) != -1);
+ }
+ }
+
+//---------------------------------------------------------
+// oRouteShow
+//---------------------------------------------------------
+
+void MidiInPortStrip::oRouteShow()
+ {
+ QMenu* pup = oR->menu();
+ pup->clear();
+
+ for (int ch = 0; ch < MIDI_CHANNELS; ++ch) {
+ QMenu* m = pup->addMenu(QString("Channel %1").arg(ch+1));
+ addMidiTracks(m, track, ch, false);
+ addSyntiPorts(m, track, ch);
+ addMidiOutPorts(m, track, ch);
+ }
+ }
+
+//---------------------------------------------------------
+// MidiSyntiStrip
+//---------------------------------------------------------
+
+MidiSyntiStrip::MidiSyntiStrip(Mixer* m, MidiSynti* t, bool align)
+ : Strip(m, t, align)
+ {
+ if (_align)
+ grid->setRowMinimumHeight(1, STRIP_WIDTH/2 * 3);
+
+ volumeTouched = false;
+
+ //---------------------------------------------------
+ // slider, label, meter
+ //---------------------------------------------------
+
+ slider = new Awl::MidiMeterSlider(this);
+ slider->setId(CTRL_MASTER_VOLUME);
+ slider->setRange(0.0, 1024*16.0);
+ slider->setFixedWidth(40);
+ grid->addWidget(slider, 2, 0, 1, 2, Qt::AlignRight);
+
+ sl = new Awl::MidiVolEntry(this);
+ sl->setId(CTRL_MASTER_VOLUME);
+// sl->setFont(config.fonts[1]);
+ sl->setFixedHeight(entrySize.height());
+
+ connect(slider, SIGNAL(valueChanged(double,int)), SLOT(ctrlChanged(double, int)));
+ connect(slider, SIGNAL(sliderPressed(int)), SLOT(sliderPressed(int)));
+ connect(slider, SIGNAL(sliderReleased(int)), SLOT(sliderReleased(int)));
+ connect(sl, SIGNAL(valueChanged(double,int)), SLOT(ctrlChanged(double, int)));
+ grid->addWidget(sl, 3, 0, 1, 2);
+
+ //---------------------------------------------------
+ // pan, balance
+ //---------------------------------------------------
+
+ if (_align)
+ grid->setRowMinimumHeight(4, STRIP_WIDTH);
+
+ //---------------------------------------------------
+ // sync
+ // mute, solo
+ //---------------------------------------------------
+
+ mute = newMuteButton();
+ mute->setChecked(track->isMute());
+ mute->setFixedHeight(BUTTON_HEIGHT);
+ connect(mute, SIGNAL(clicked(bool)), SLOT(muteToggled(bool)));
+
+ solo = newSoloButton();
+ solo->setFixedHeight(BUTTON_HEIGHT);
+ solo->setChecked(track->solo());
+ connect(solo, SIGNAL(clicked(bool)), SLOT(soloToggled(bool)));
+
+ grid->addWidget(mute, 5, 0);
+ grid->addWidget(solo, 5, 1);
+
+ //---------------------------------------------------
+ // automation mode
+ //---------------------------------------------------
+
+ addAutomationButtons(6);
+
+ //---------------------------------------------------
+ // output routing
+ //---------------------------------------------------
+
+ iR = newInRouteButton();
+ grid->addWidget(iR, 7, 0);
+ connect(iR->menu(), SIGNAL(aboutToShow()), SLOT(iRouteShow()));
+ connect(iR->menu(), SIGNAL(triggered(QAction*)), song, SLOT(routeChanged(QAction*)));
+
+ oR = newOutRouteButton();
+ grid->addWidget(oR, 7, 1);
+ connect(oR->menu(), SIGNAL(aboutToShow()), SLOT(oRouteShow()));
+ connect(oR->menu(), SIGNAL(triggered(QAction*)), song, SLOT(routeChanged(QAction*)));
+
+ connect(song, SIGNAL(songChanged(int)), SLOT(songChanged(int)));
+ connect(track, SIGNAL(muteChanged(bool)), mute, SLOT(setChecked(bool)));
+ connect(track, SIGNAL(soloChanged(bool)), solo, SLOT(setChecked(bool)));
+ connect(track, SIGNAL(autoReadChanged(bool)), SLOT(autoChanged()));
+ connect(track, SIGNAL(autoWriteChanged(bool)), SLOT(autoChanged()));
+ autoChanged();
+ }
+
+//---------------------------------------------------------
+// songChanged
+//---------------------------------------------------------
+
+void MidiSyntiStrip::songChanged(int val)
+ {
+ if (val & SC_TRACK_MODIFIED)
+ updateLabel();
+ }
+
+//---------------------------------------------------------
+// heartBeat
+//---------------------------------------------------------
+
+void MidiSyntiStrip::heartBeat()
+ {
+ double a = track->meter(0); // fast_log10(track->meter(0)) * .2f;
+ slider->setMeterVal(a * 0.008);
+ track->setMeter(0, a * 0.8); // hack
+ }
+
+//---------------------------------------------------------
+// ctrlChanged
+//---------------------------------------------------------
+
+void MidiSyntiStrip::ctrlChanged(double val, int num)
+ {
+ int ival = int(val);
+ CVal cval;
+ cval.i = ival;
+ song->setControllerVal(track, num, cval);
+ }
+
+//---------------------------------------------------------
+// sliderPressed
+//---------------------------------------------------------
+
+void MidiSyntiStrip::sliderPressed(int id)
+ {
+ switch (id) {
+ case CTRL_MASTER_VOLUME: volumeTouched = true; break;
+ }
+ track->startAutoRecord(id);
+ }
+
+//---------------------------------------------------------
+// sliderReleased
+//---------------------------------------------------------
+
+void MidiSyntiStrip::sliderReleased(int id)
+ {
+ switch (id) {
+ case CTRL_MASTER_VOLUME: volumeTouched = false; break;
+ }
+ track->stopAutoRecord(id);
+ }
+
+//---------------------------------------------------------
+// muteToggled
+//---------------------------------------------------------
+
+void MidiSyntiStrip::muteToggled(bool val)
+ {
+ song->setMute(track, val);
+ }
+
+//---------------------------------------------------------
+// soloToggled
+//---------------------------------------------------------
+
+void MidiSyntiStrip::soloToggled(bool val)
+ {
+ song->setSolo(track, val);
+ }
+
+//---------------------------------------------------------
+// autoChanged
+//---------------------------------------------------------
+
+void MidiSyntiStrip::autoChanged()
+ {
+ bool ar = track->autoRead();
+ bool aw = track->autoWrite();
+
+ // controller are enabled if
+ // autoRead is off
+ // autoRead and autoWrite are on (touch mode)
+
+ bool ec = !ar || (ar && aw);
+ slider->setEnabled(ec);
+ sl->setEnabled(ec);
+ }
+
+//---------------------------------------------------------
+// autoReadToggled
+//---------------------------------------------------------
+
+void MidiSyntiStrip::autoReadToggled(bool val)
+ {
+ song->setAutoRead(track, val);
+ }
+
+//---------------------------------------------------------
+// autoWriteToggled
+//---------------------------------------------------------
+
+void MidiSyntiStrip::autoWriteToggled(bool val)
+ {
+ song->setAutoWrite(track, val);
+ }
+
+//---------------------------------------------------------
+// controllerChanged
+//---------------------------------------------------------
+
+void MidiSyntiStrip::controllerChanged(int id)
+ {
+ if (id == CTRL_MASTER_VOLUME) {
+ double val = double(track->ctrlVal(id).i);
+ if (!volumeTouched)
+ slider->setValue(val);
+ sl->setValue(val);
+ }
+ }
+
+//---------------------------------------------------------
+// oRouteShow
+//---------------------------------------------------------
+
+void MidiSyntiStrip::oRouteShow()
+ {
+ QMenu* pup = oR->menu();
+ pup->clear();
+ addMidiOutPorts(pup, track, -1);
+ }
+
+//---------------------------------------------------------
+// iRouteShow
+//---------------------------------------------------------
+
+void MidiSyntiStrip::iRouteShow()
+ {
+ QMenu* pup = oR->menu();
+ pup->clear();
+
+ MidiOutPort* t = (MidiOutPort*)track;
+
+ for (int ch = 0; ch < MIDI_CHANNELS; ++ch) {
+ QMenu* m = pup->addMenu(QString("Channel %1").arg(ch+1));
+ addMidiTracks(m, t, ch, false);
+ addMidiInPorts(m, t, ch);
+ }
+ }
diff --git a/muse_qt4_evolution/muse/mstrip.h b/muse_qt4_evolution/muse/mstrip.h
new file mode 100644
index 00000000..058884db
--- /dev/null
+++ b/muse_qt4_evolution/muse/mstrip.h
@@ -0,0 +1,191 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __MSTRIP_H__
+#define __MSTRIP_H__
+
+#include "strip.h"
+
+namespace Awl {
+ class MidiMeterSlider;
+ class MidiMeter;
+ class FloatEntry;
+ class MidiVolEntry;
+ class Knob;
+ };
+
+class MidiTrack;
+class MidiOutPort;
+class MidiInPort;
+class MidiChannel;
+class MidiSynti;
+
+//---------------------------------------------------------
+// MidiStrip
+//---------------------------------------------------------
+
+class MidiStrip : public Strip {
+ Q_OBJECT
+
+ Awl::MidiMeterSlider* slider;
+ Awl::MidiVolEntry* sl;
+ QToolButton* iR;
+ QToolButton* oR;
+
+ struct KNOB {
+ Awl::Knob* knob;
+ Awl::FloatEntry* dl;
+ QLabel* lb;
+ } controller[4]; // pan variation reverb chorus
+
+ bool volumeTouched;
+ bool panTouched;
+ bool reverbSendTouched;
+ bool variSendTouched;
+ bool chorusSendTouched;
+
+ void addKnob(int ctrl, int idx, const QString&, const QString&, const char*, bool, int row);
+
+ private slots:
+ virtual void controllerChanged(int id);
+ void ctrlChanged(double val, int num);
+ void muteToggled(bool);
+ void soloToggled(bool);
+ void autoChanged();
+ void sliderPressed(int);
+ void sliderReleased(int);
+ void autoReadToggled(bool);
+ void autoWriteToggled(bool);
+ void iRouteShow();
+ void oRouteShow();
+ void recordToggled(bool);
+ void monitorToggled(bool);
+ QMenu* sendMenu() const { return static_cast<QMenu*>(sender()); }
+
+ public slots:
+ virtual void songChanged(int);
+
+ public:
+ MidiStrip(Mixer*, MidiTrack*, bool align = true);
+ virtual void heartBeat();
+ };
+
+//---------------------------------------------------------
+// MidiOutPortStrip
+//---------------------------------------------------------
+
+class MidiOutPortStrip : public Strip {
+ Q_OBJECT
+
+ Awl::MidiMeterSlider* slider;
+ Awl::MidiVolEntry* sl;
+ QToolButton* oR;
+ QToolButton* iR;
+ SimpleButton* sync;
+
+ bool volumeTouched;
+
+ private slots:
+ virtual void controllerChanged(int id);
+ void ctrlChanged(double val, int num);
+ void muteToggled(bool);
+ void soloToggled(bool);
+ void autoChanged();
+ void sliderPressed(int);
+ void sliderReleased(int);
+ void autoReadToggled(bool);
+ void autoWriteToggled(bool);
+ void iRouteShow();
+ void oRouteShow();
+ void syncToggled(bool) const;
+
+ public slots:
+ virtual void songChanged(int);
+
+ public:
+ MidiOutPortStrip(Mixer*, MidiOutPort*, bool align = true);
+ virtual void heartBeat();
+ };
+
+//---------------------------------------------------------
+// MidiSyntiStrip
+//---------------------------------------------------------
+
+class MidiSyntiStrip : public Strip {
+ Q_OBJECT
+
+ Awl::MidiMeterSlider* slider;
+ Awl::MidiVolEntry* sl;
+ QToolButton* iR;
+ QToolButton* oR;
+
+ bool volumeTouched;
+
+ private slots:
+ virtual void controllerChanged(int id);
+ void ctrlChanged(double val, int num);
+ void muteToggled(bool);
+ void soloToggled(bool);
+ void autoChanged();
+ void sliderPressed(int);
+ void sliderReleased(int);
+ void autoReadToggled(bool);
+ void autoWriteToggled(bool);
+ void iRouteShow();
+ void oRouteShow();
+
+ public slots:
+ virtual void songChanged(int);
+
+ public:
+ MidiSyntiStrip(Mixer*, MidiSynti*, bool align = true);
+ virtual void heartBeat();
+ };
+
+//---------------------------------------------------------
+// MidiInPortStrip
+//---------------------------------------------------------
+
+class MidiInPortStrip : public Strip {
+ Q_OBJECT
+
+ bool activity[MIDI_CHANNELS];
+ QPixmap* activityOn;
+ QPixmap* activityOff;
+ QLabel* channelActivity[MIDI_CHANNELS];
+ QToolButton* iR;
+ QToolButton* oR;
+ MidiInPort* inport() const { return (MidiInPort*)track; }
+
+ private slots:
+ void muteToggled(bool);
+ void soloToggled(bool);
+ void iRouteShow();
+ void oRouteShow();
+
+ public slots:
+ virtual void songChanged(int);
+
+ public:
+ MidiInPortStrip(Mixer*, MidiInPort*, bool align = true);
+ virtual void heartBeat();
+ };
+
+#endif
diff --git a/muse_qt4_evolution/muse/mtc.cpp b/muse_qt4_evolution/muse/mtc.cpp
new file mode 100644
index 00000000..54ed5584
--- /dev/null
+++ b/muse_qt4_evolution/muse/mtc.cpp
@@ -0,0 +1,131 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "al/al.h"
+#include "mtc.h"
+
+//---------------------------------------------------------
+// MTC::time
+// converts MTC Time to seconds according to
+// global mtcType
+//---------------------------------------------------------
+
+double MTC::time() const
+ {
+ double time = _h * 3600 + _m * 60 + _s;
+ double ft = 0.0;
+ switch (AL::mtcType) {
+ case 0: // 24 frames sec
+ ft = 1.0/24.0;
+ break;
+ case 1: // 25
+ ft = 0.04;
+ break;
+ case 2: // 30 drop frame TODO
+ case 3: // 30 non drop frame
+ ft = 1.0/30.0;
+ break;
+ }
+ return time + ft *_f + 0.01 * ft * _sf;
+ }
+
+//---------------------------------------------------------
+// MTC
+//---------------------------------------------------------
+
+MTC::MTC(double t)
+ {
+ _h = int(t/3600);
+ t -= _h * 3600;
+ _m = int(t/60);
+ t -= _m * 60;
+ _s = int(t);
+ t -= _s;
+ double ft = 1.0/24.0;
+ switch (AL::mtcType) {
+ case 0: // 24 frames sec
+ ft = 1.0/24.0;
+ break;
+ case 1: // 25
+ ft = 0.04;
+ break;
+ case 2: // 30 drop frame
+ case 3: // 30 non drop frame
+ ft = 1.0/30.0;
+ break;
+ }
+ double frames = t / ft;
+ _f = int(frames);
+ frames -= _f;
+ _sf = int(frames * 100);
+ }
+
+//---------------------------------------------------------
+// incQuarter
+// increment MTC time one quarter frame time
+//---------------------------------------------------------
+
+void MTC::incQuarter()
+ {
+ int frames = 24;
+ switch (AL::mtcType) {
+ case 0:
+ frames = 24;
+ break;
+ case 1:
+ frames = 25;
+ break;
+ case 2:
+ case 3:
+ frames = 30;
+ break;
+ }
+ _sf += 25;
+ if (_sf >= 100) {
+ ++_f;
+ _sf -= 100;
+ }
+ if (_f == frames) {
+ ++_s;
+ _f = 0;
+ }
+ if (_s == 60) {
+ ++_m;
+ _s = 0;
+ }
+ if (_m == 60) {
+ ++_h;
+ _m = 0;
+ }
+ if (_h == 24) {
+ _h = 0;
+ }
+ }
+
+//---------------------------------------------------------
+// print
+//---------------------------------------------------------
+
+void MTC::print() const
+ {
+ printf("%02d:%02d:%02d:%02d:%02d", _h, _m, _s, _f, _sf);
+ }
+
+
diff --git a/muse_qt4_evolution/muse/mtc.h b/muse_qt4_evolution/muse/mtc.h
new file mode 100644
index 00000000..862bc5b1
--- /dev/null
+++ b/muse_qt4_evolution/muse/mtc.h
@@ -0,0 +1,68 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __MTC_H__
+#define __MTC_H__
+
+//---------------------------------------------------------
+// MTC
+//---------------------------------------------------------
+
+class MTC {
+ unsigned char _h, _m, _s, _f, _sf;
+
+ public:
+ MTC(int h, int m, int s, int f, int sf=0) {
+ _h = h;
+ _m = m;
+ _s = s;
+ _f = f;
+ _sf = sf;
+ }
+ MTC() {
+ _h = _m = _s = _f = _sf = 0;
+ }
+ MTC(double);
+ void set(int h, int m, int s, int f, int sf=0) {
+ _h = h;
+ _m = m;
+ _s = s;
+ _f = f;
+ _sf = sf;
+ }
+ void incQuarter();
+ void setH(int val) { _h = val; }
+ void setM(int val) { _m = val; }
+ void setS(int val) { _s = val; }
+ void setF(int val) { _f = val; }
+ void setSf(int val) { _sf = val; }
+
+ int h() const { return _h; }
+ int m() const { return _m; }
+ int s() const { return _s; }
+ int f() const { return _f; }
+ int sf() const { return _sf; }
+ double time() const;
+ void print() const;
+ };
+
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/muse.cpp b/muse_qt4_evolution/muse/muse.cpp
new file mode 100644
index 00000000..01f0d1c4
--- /dev/null
+++ b/muse_qt4_evolution/muse/muse.cpp
@@ -0,0 +1,3029 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "config.h"
+#include <sys/mman.h>
+#include "muse.h"
+#include "transport.h"
+#include "widgets/bigtime.h"
+#include "arranger.h"
+#include "midiedit/pianoroll.h"
+#include "al/al.h"
+#include "al/xml.h"
+#include "al/dsp.h"
+#include "al/tempo.h"
+#include "conf.h"
+#include "liste/listedit.h"
+#include "master/masteredit.h"
+#include "midiedit/drumedit.h"
+#include "mixer.h"
+#include "audiodev.h"
+#include "waveedit/waveedit.h"
+#include "icons.h"
+#include "widgets/mixdowndialog.h"
+#include "midictrl.h"
+#include "widgets/filedialog.h"
+#include "plugin.h"
+#include "marker/markerview.h"
+#include "transpose.h"
+#include "preferences.h"
+#include "audio.h"
+#include "audioprefetch.h"
+#include "audiowriteback.h"
+#include "widgets/shortcutconfig.h"
+#include "gconfig.h"
+#include "ticksynth.h"
+#include "song.h"
+#include "awl/poslabel.h"
+#include "shortcuts.h"
+#include "midiplugin.h"
+#include "midiedit/drummap.h"
+#include "widgets/utils.h"
+#include "instruments/editinstrument.h"
+#include "part.h"
+#include "projectdialog.h"
+#include "templatedialog.h"
+#include "midiedit/miditracker.h"
+#include "projectpropsdialog.h"
+#include "liste/listedit.h"
+#include "strip.h"
+
+extern void initMidiInstruments();
+
+#define PROJECT_LIST_LEN 6
+static QString* projectList[PROJECT_LIST_LEN];
+
+extern void initIcons();
+extern void initMidiSynth();
+extern bool initDummyAudio();
+extern void initVST();
+extern void initDSSI();
+extern bool initJackAudio();
+extern void exitJackAudio();
+
+QStyle* smallStyle;
+
+pthread_t splashThread;
+MusE* muse;
+
+//
+// Arranger Snap values
+//
+
+struct RasterVal {
+ int val;
+ QString label;
+ };
+
+static RasterVal rasterTable[] = {
+ { 1, QT_TR_NOOP("Off") },
+ { 0, QT_TR_NOOP("Bar") },
+ { 2 * config.division, "1/2" },
+ { config.division, "1/4" },
+ { config.division/2, "1/8" },
+ { config.division/4, "1/16" }
+ };
+
+//---------------------------------------------------------
+// seqStart
+//---------------------------------------------------------
+
+bool MusE::seqStart()
+ {
+ if (audioState != AUDIO_STOP) {
+ printf("seqStart(): already running\n");
+ return true;
+ }
+ audioState = AUDIO_START1;
+ if (!audio->start()) {
+ QMessageBox::critical( muse, tr("Failed to start audio!"),
+ tr("Was not able to start audio, check if jack is running.\n"));
+ return false;
+ }
+ //
+ // wait for jack callback
+ //
+ for (int i = 0; i < 60; ++i) {
+ if (audioState == AUDIO_START2)
+ break;
+ sleep(1);
+ }
+ if (audioState != AUDIO_START2) {
+ QMessageBox::critical( muse, tr("Failed to start audio!"),
+ tr("Was not able to start audio, check if jack is running.\n"));
+ }
+ //
+ // now its safe to ask the driver for realtime
+ // priority
+
+ realTimePriority = audioDriver->realtimePriority();
+ audioState = AUDIO_RUNNING;
+ if (realTimePriority) {
+ audioPrefetch->start(realTimePriority - 5);
+ audioWriteback->start(realTimePriority - 5);
+ }
+ else {
+ audioPrefetch->start(0);
+ audioWriteback->start(0);
+ }
+ //
+ // do connections
+ //
+ TrackList* tl = song->tracks();
+ for (iTrack i = tl->begin(); i != tl->end(); ++i)
+ (*i)->activate2();
+ return true;
+ }
+
+//---------------------------------------------------------
+// stop
+//---------------------------------------------------------
+
+void MusE::seqStop()
+ {
+ song->setStop(true);
+ song->setStopPlay(false);
+ audio->stop();
+ audioWriteback->stop(true);
+ audioPrefetch->stop(true);
+ audioState = AUDIO_STOP;
+ }
+
+//---------------------------------------------------------
+// seqRestart
+//---------------------------------------------------------
+
+bool MusE::seqRestart()
+ {
+ bool restartSequencer = audioState == AUDIO_RUNNING;
+ if (restartSequencer) {
+ if (audio->isPlaying()) {
+ audio->msgPlay(false);
+ while (audio->isPlaying())
+ qApp->processEvents();
+ }
+ seqStop();
+ }
+
+ if (!seqStart())
+ return false;
+
+ audioDriver->graphChanged();
+ return true;
+ }
+
+//---------------------------------------------------------
+// addProject
+//---------------------------------------------------------
+
+void addProject(const QString& name)
+ {
+ for (int i = 0; i < PROJECT_LIST_LEN; ++i) {
+ if (projectList[i] == 0)
+ break;
+ if (name == *projectList[i]) {
+ int dst = i;
+ int src = i+1;
+ int n = PROJECT_LIST_LEN - i - 1;
+ delete projectList[i];
+ for (int k = 0; k < n; ++k)
+ projectList[dst++] = projectList[src++];
+ projectList[dst] = 0;
+ break;
+ }
+ }
+ QString** s = &projectList[PROJECT_LIST_LEN - 2];
+ QString** d = &projectList[PROJECT_LIST_LEN - 1];
+ if (*d)
+ delete *d;
+ for (int i = 0; i < PROJECT_LIST_LEN-1; ++i)
+ *d-- = *s--;
+ projectList[0] = new QString(name);
+ }
+
+//---------------------------------------------------------
+// populateAddTrack
+// this is also used in "mixer"
+//---------------------------------------------------------
+
+void populateAddTrack(QMenu* m)
+ {
+ m->setSeparatorsCollapsible(false);
+ m->clear();
+ QAction* a;
+
+ a = m->addSeparator();
+ a->setText(QT_TR_NOOP("Midi"));
+ QFont f(a->font());
+ f.setBold(true);
+ f.setPointSize(8);
+ a->setFont(f);
+
+ a = m->addAction(QIcon(*addtrack_addmiditrackIcon), QT_TR_NOOP("Add Midi Track"));
+ a->setData(Track::MIDI);
+
+ a = m->addAction(QIcon(*addtrack_addmiditrackIcon), QT_TR_NOOP("Add Midi Output"));
+ a->setData(Track::MIDI_OUT);
+
+ a = m->addAction(QIcon(*addtrack_addmiditrackIcon), QT_TR_NOOP("Add Midi Input"));
+ a->setData(Track::MIDI_IN);
+
+ QMenu* ps = m->addMenu(QMenu::tr("Add Midi Generator..."));
+
+ int idx = 5000;
+ for (iMidiPlugin i = midiPlugins.begin(); i != midiPlugins.end(); ++i) {
+ if ((*i)->type() != MEMPI_GENERATOR)
+ continue;
+ a = ps->addAction((*i)->name());
+ a->setData(idx);
+ }
+
+ if (!midiOnly) {
+ a = m->addSeparator();
+ a->setText(QT_TR_NOOP("Audio"));
+ a->setFont(f);
+
+ a = m->addAction(QIcon(*addtrack_wavetrackIcon), QT_TR_NOOP("Add Wave Track"));
+ a->setData(Track::WAVE);
+ a = m->addAction(QIcon(*addtrack_audiooutputIcon), QT_TR_NOOP("Add Audio Output"));
+ a->setData(Track::AUDIO_OUTPUT);
+ a = m->addAction(QIcon(*addtrack_audiogroupIcon), QT_TR_NOOP("Add Audio Group"));
+ a->setData(Track::AUDIO_GROUP);
+ a = m->addAction(QIcon(*addtrack_audioinputIcon), QT_TR_NOOP("Add Audio Input"));
+ a->setData(Track::AUDIO_INPUT);
+
+ ps = m->addMenu(QMenu::tr("Add Soft Synth..."));
+
+ int idx = 1000;
+ for (std::vector<Synth*>::iterator is = synthis.begin(); is != synthis.end(); ++is, ++idx) {
+ a = ps->addAction((*is)->name());
+ a->setData(idx);
+ }
+ }
+ m->connect(m, SIGNAL(triggered(QAction*)), song, SLOT(addTrack(QAction*)));
+ }
+
+//---------------------------------------------------------
+// setupTransportToolbar
+//---------------------------------------------------------
+
+void MusE::setupTransportToolbar(QToolBar* tb) const
+ {
+ tb->addAction(loopAction);
+ tb->addAction(punchinAction);
+ tb->addAction(punchoutAction);
+ tb->addAction(startAction);
+
+ // hack to implement auto repeat:
+ // the action auto repeat does only work for
+ // shortcuts but not for mouse press:
+
+ QToolButton* rewindTb = new QToolButton;
+ rewindTb->setDefaultAction(rewindAction);
+ rewindTb->setAutoRepeat(true);
+ tb->addWidget(rewindTb);
+ connect(rewindTb, SIGNAL(clicked()), song, SLOT(rewind()));
+
+ QToolButton* forwardTb = new QToolButton;
+ forwardTb->setDefaultAction(forwardAction);
+ forwardTb->setAutoRepeat(true);
+ tb->addWidget(forwardTb);
+ connect(forwardTb, SIGNAL(clicked()), song, SLOT(forward()));
+
+ tb->addAction(stopAction);
+ tb->addAction(playAction);
+ tb->addAction(recordAction);
+ }
+
+//---------------------------------------------------------
+// MusE
+//---------------------------------------------------------
+
+MusE::MusE()
+ : QMainWindow()
+ {
+ setWindowIcon(*museIcon);
+ setIconSize(ICON_SIZE);
+ setFocusPolicy(Qt::WheelFocus);
+
+ muse = this; // hack
+ midiSyncConfig = 0;
+ midiRemoteConfig = 0;
+ midiPortConfig = 0;
+ metronomeConfig = 0;
+ audioConfig = 0;
+ midiFileConfig = 0;
+ midiFilterConfig = 0;
+ midiInputTransform = 0;
+ midiRhythmGenerator = 0;
+ preferencesDialog = 0;
+ softSynthesizerConfig = 0;
+ midiTransformerDialog = 0;
+ shortcutConfig = 0;
+ editInstrument = 0;
+ appName = QString("MusE");
+ _raster = 0;
+ audioState = AUDIO_STOP;
+ bigtime = 0;
+ mixer1 = 0;
+ mixer2 = 0;
+ markerView = 0;
+ exportMidiDialog = 0;
+ projectPropsDialog = 0;
+ listEditor = 0;
+
+ //---------------------------------------------------
+ // Transport
+ //---------------------------------------------------
+
+ loopAction = getAction("toggle_loop", this);
+ loopAction->setCheckable(true);
+ connect(loopAction, SIGNAL(triggered(bool)), song, SLOT(setLoop(bool)));
+
+ punchinAction = getAction("punchin", this);
+ punchinAction->setCheckable(true);
+ connect(punchinAction, SIGNAL(toggled(bool)), song, SLOT(setPunchin(bool)));
+
+ punchoutAction = getAction("punchout", this);
+ punchoutAction->setCheckable(true);
+ connect(punchoutAction, SIGNAL(toggled(bool)), song, SLOT(setPunchout(bool)));
+
+ recordAction = getAction("toggle_rec", this);
+ recordAction->setCheckable(true);
+ connect(recordAction, SIGNAL(triggered(bool)), song, SLOT(setRecord(bool)));
+
+ panicAction = getAction("panic", this);
+ connect(panicAction, SIGNAL(triggered()), song, SLOT(panic()));
+
+ startAction = getAction("start", this);
+ connect(startAction, SIGNAL(triggered()), song, SLOT(rewindStart()));
+
+ playAction = getAction("play", this);
+ playAction->setCheckable(true);
+ connect(playAction, SIGNAL(triggered(bool)), song, SLOT(setPlay(bool)));
+
+ QAction* a = getAction("play_toggle", this);
+ connect(a, SIGNAL(triggered()), SLOT(playToggle()));
+ addAction(a);
+
+ a = getAction("toggle_metro", this);
+ connect(a, SIGNAL(triggered()), song, SLOT(toggleClick()));
+ addAction(a);
+
+ a = getAction("goto_left", this);
+ connect(a, SIGNAL(triggered()), song, SLOT(gotoLeftMarker()));
+ addAction(a);
+
+ a = getAction("goto_right", this);
+ connect(a, SIGNAL(triggered()), song, SLOT(gotoRightMarker()));
+ addAction(a);
+
+ rewindAction = getAction("rewind", this);
+ rewindAction->setAutoRepeat(true);
+
+ forwardAction = getAction("forward", this);
+ forwardAction->setAutoRepeat(true);
+
+ stopAction = getAction("stop", this);
+ stopAction->setCheckable(true);
+ connect(stopAction, SIGNAL(triggered(bool)), song, SLOT(setStop(bool)));
+
+ song->blockSignals(true);
+ heartBeatTimer = new QTimer(this);
+ connect(heartBeatTimer, SIGNAL(timeout()), SLOT(beat()));
+
+ //---------------------------------------------------
+ // undo/redo
+ //---------------------------------------------------
+
+ undoAction = getAction("undo", this);
+ undoAction->setEnabled(false);
+ connect(undoAction, SIGNAL(triggered()), song, SLOT(undo()));
+
+ redoAction = getAction("redo", this);
+ redoAction->setEnabled(false);
+ connect(redoAction, SIGNAL(triggered()), song, SLOT(redo()));
+
+ fileOpenAction = getAction("open_project", this);
+ connect(fileOpenAction, SIGNAL(triggered()), SLOT(loadProject()));
+
+ fileSaveAction = getAction("save_project", this);
+ connect(fileSaveAction, SIGNAL(triggered()), SLOT(save()));
+
+ fileSaveAsAction = getAction("save_project_as", this);
+ connect(fileSaveAsAction, SIGNAL(triggered()), SLOT(saveAs()));
+
+ pianoAction = getAction("open_pianoroll", this);
+ connect(pianoAction, SIGNAL(triggered()), SLOT(startPianoroll()));
+
+ waveAction = getAction("open_waveedit", this);
+ connect(waveAction, SIGNAL(triggered()), SLOT(startWaveEditor()));
+
+ trackerAction = getAction("open_miditracker", this);
+ connect(trackerAction, SIGNAL(triggered()), SLOT(startMidiTrackerEditor()));
+
+ //--------------------------------------------------
+ // Toolbar
+ //--------------------------------------------------
+
+ tools = new QToolBar(tr("Project Buttons"));
+ addToolBar(tools);
+
+ tools->addAction(fileOpenAction);
+ tools->addAction(fileSaveAction);
+ tools->addAction(QWhatsThis::createAction(this));
+
+ tools->addSeparator();
+ tools->addAction(undoAction);
+ tools->addAction(redoAction);
+
+ tools1 = new EditToolBar(this, arrangerTools);
+ addToolBar(tools1);
+
+ QToolBar* transportToolbar = addToolBar(tr("Transport"));
+ setupTransportToolbar(transportToolbar);
+
+ QToolBar* panicToolbar = new QToolBar(tr("Panic"), this);
+ addToolBar(panicToolbar);
+ panicToolbar->addAction(panicAction);
+
+ addToolBarBreak();
+
+ audio = new Audio();
+ audioPrefetch = new AudioPrefetch("Prefetch");
+ audioWriteback = new AudioWriteback("Writeback");
+
+ //---------------------------------------------------
+ // MenuBar
+ //---------------------------------------------------
+
+ QMenuBar* mb = menuBar();
+
+ //-------------------------------------------------------------
+ // File
+ //-------------------------------------------------------------
+
+ menu_file = mb->addMenu(tr("&Project"));
+
+ menu_file->addAction(fileOpenAction);
+
+ openRecent = new QMenu(tr("Open &Recent"), this);
+ connect(openRecent, SIGNAL(aboutToShow()), this, SLOT(openRecentMenu()));
+ connect(openRecent, SIGNAL(triggered(QAction*)), this, SLOT(selectProject(QAction*)));
+
+ menu_file->addMenu(openRecent);
+ menu_file->addSeparator();
+ menu_file->addAction(fileSaveAction);
+ menu_file->addAction(fileSaveAsAction);
+ a = getAction("save_as_template", this);
+ connect(a, SIGNAL(triggered()), SLOT(saveAsTemplate()));
+ menu_file->addAction(a);
+
+ menu_file->addSeparator();
+ a = menu_file->addAction(*openIcon, tr("Import Midifile"));
+ connect(a, SIGNAL(triggered()), this, SLOT(importMidi()));
+ a = menu_file->addAction(*saveIcon, tr("Export Midifile"));
+ connect(a, SIGNAL(triggered()), this, SLOT(exportMidi()));
+ menu_file->addSeparator();
+
+ a = menu_file->addAction(*openIcon, tr("Import Wave File"));
+ connect(a, SIGNAL(triggered()), this, SLOT(importWave()));
+ a->setEnabled(!midiOnly);
+
+ menu_file->addSeparator();
+ a = getAction("quit", this);
+ menu_file->addAction(a);
+ connect(a, SIGNAL(triggered()), this, SLOT(quitDoc()));
+ menu_file->addSeparator();
+
+ //-------------------------------------------------------------
+ // Edit
+ //-------------------------------------------------------------
+
+ menuEdit = mb->addMenu(tr("&Edit"));
+
+ menuEdit->addAction(undoAction);
+ menuEdit->addAction(redoAction);
+ menuEdit->addSeparator();
+
+ cutAction = getAction("cut", this);
+ menuEdit->addAction(cutAction);
+ copyAction = getAction("copy", this);
+ menuEdit->addAction(copyAction);
+ pasteAction = getAction("paste", this);
+ menuEdit->addAction(pasteAction);
+
+ menuEdit->addSeparator();
+ a = menuEdit->addAction(QIcon(*edit_track_delIcon), tr("Delete Selected Tracks"));
+ a->setData("delete_track");
+
+ addTrack = menuEdit->addMenu(*edit_track_addIcon, tr("Add Track"));
+ // delay creation of menu (at this moment the list of software
+ // synthesizer is empty):
+ connect(addTrack, SIGNAL(aboutToShow()), SLOT(aboutToShowAddTrack()));
+
+ menuEdit->addSeparator();
+ select = menuEdit->addMenu(QIcon(*selectIcon), tr("Select"));
+ select->addAction(getAction("sel_all", this));
+ select->addAction(getAction("sel_none", this));
+ select->addAction(getAction("sel_inv", this));
+ select->addAction(getAction("sel_ins_loc", this));
+ select->addAction(getAction("sel_out_loc", this));
+ select->addAction(getAction("select_parts_on_track", this));
+
+ menuEdit->addSeparator();
+ menuEdit->addAction(pianoAction);
+ menuEdit->addAction(waveAction);
+ menuEdit->addAction(trackerAction);
+
+ a = getAction("open_drumedit", this);
+ menuEdit->addAction(a);
+ connect(a, SIGNAL(triggered()), SLOT(startDrumEditor()));
+
+ a = getAction("open_master", this);
+ menuEdit->addAction(a);
+ connect(a, SIGNAL(triggered()), SLOT(startMasterEditor()));
+
+ a = menuEdit->addAction(*saveIcon, tr("Project Properties"));
+ connect(a, SIGNAL(triggered()), SLOT(showProjectPropsDialog()));
+
+ menuEdit->addSeparator();
+ connect(menuEdit, SIGNAL(triggered(QAction*)), SLOT(cmd(QAction*)));
+ connect(select, SIGNAL(triggered(QAction*)), SLOT(cmd(QAction*)));
+
+ midiEdit = menuEdit->addMenu(QIcon(*edit_midiIcon), tr("Midi"));
+
+#if 0 // TODO
+ midiEdit->insertItem(tr("Modify Gate Time"), this, SLOT(modifyGateTime()));
+ midiEdit->insertItem(tr("Modify Velocity"), this, SLOT(modifyVelocity()));
+ midiEdit->insertItem(tr("Crescendo"), this, SLOT(crescendo()));
+ midiEdit->insertItem(tr("Transpose"), this, SLOT(transpose()));
+ midiEdit->insertItem(tr("Thin Out"), this, SLOT(thinOut()));
+ midiEdit->insertItem(tr("Erase Event"), this, SLOT(eraseEvent()));
+ midiEdit->insertItem(tr("Note Shift"), this, SLOT(noteShift()));
+ midiEdit->insertItem(tr("Move Clock"), this, SLOT(moveClock()));
+ midiEdit->insertItem(tr("Copy Measure"), this, SLOT(copyMeasure()));
+ midiEdit->insertItem(tr("Erase Measure"), this, SLOT(eraseMeasure()));
+ midiEdit->insertItem(tr("Delete Measure"), this, SLOT(deleteMeasure()));
+ midiEdit->insertItem(tr("Create Measure"), this, SLOT(createMeasure()));
+ midiEdit->insertItem(tr("Mix Track"), this, SLOT(mixTrack()));
+#endif
+ a = midiEdit->addAction(QIcon(*midi_transposeIcon), tr("Transpose"));
+ connect(a, SIGNAL(triggered()), this, SLOT(transpose()));
+
+ //-------------------------------------------------------------
+ // View
+ //-------------------------------------------------------------
+
+ menuView = mb->addMenu(tr("&View"));
+
+ tr_id = getAction("toggle_transport", this);
+ tr_id->setCheckable(true);
+ menuView->addAction(tr_id);
+ connect(tr_id, SIGNAL(triggered(bool)), this, SLOT(showTransport(bool)));
+
+ bt_id = getAction("toggle_bigtime", this);
+ bt_id->setCheckable(true);
+ menuView->addAction(bt_id);
+ connect(bt_id, SIGNAL(triggered(bool)), this, SLOT(showBigtime(bool)));
+
+ aid1a = getAction("toggle_mixer1", this);
+ aid1a->setCheckable(true);
+ menuView->addAction(aid1a);
+ connect(aid1a, SIGNAL(triggered(bool)), this, SLOT(showMixer1(bool)));
+
+ aid1b = getAction("toggle_mixer2", this);
+ aid1b->setCheckable(true);
+ menuView->addAction(aid1b);
+ connect(aid1b, SIGNAL(triggered(bool)), this, SLOT(showMixer2(bool)));
+
+ mk_id = getAction("marker_window", this);
+ mk_id->setCheckable(true);
+ menuView->addAction(mk_id);
+ connect(mk_id , SIGNAL(triggered(bool)), this, SLOT(showMarker(bool)));
+
+ //-------------------------------------------------------------
+ // Structure
+ //-------------------------------------------------------------
+
+ menuStructure = mb->addMenu(tr("&Structure"));
+
+ a = menuStructure->addAction(tr("Global Cut"));
+ connect(a, SIGNAL(triggered()), this, SLOT(globalCut()));
+
+ a = menuStructure->addAction(tr("Global Insert"));
+ connect(a, SIGNAL(triggered()), this, SLOT(globalInsert()));
+
+ a = menuStructure->addAction(tr("Global Split"));
+ connect(a, SIGNAL(triggered()), this, SLOT(globalSplit()));
+
+ a = menuStructure->addAction(tr("Copy Range"));
+ connect(a, SIGNAL(triggered()), this, SLOT(copyRange()));
+ a->setEnabled(false);
+
+ menuStructure->addSeparator();
+
+ a = menuStructure->addAction(tr("Cut Events"));
+ connect(a, SIGNAL(triggered()), this, SLOT(cutEvents()));
+ a->setEnabled(false);
+
+ //-------------------------------------------------------------
+ // Midi
+ //-------------------------------------------------------------
+
+ menu_functions = mb->addMenu(tr("&Midi"));
+
+ a = menu_functions->addAction(QIcon(*midi_edit_instrumentIcon), tr("Edit Instrument"));
+ connect(a, SIGNAL(triggered()), this, SLOT(startEditInstrument()));
+
+ menu_functions->addSeparator();
+ a = menu_functions->addAction(QIcon(*midi_reset_instrIcon), tr("Reset Instr."));
+ connect(a, SIGNAL(triggered()), this, SLOT(resetMidiDevices()));
+ a = menu_functions->addAction(QIcon(*midi_init_instrIcon), tr("Init Instr."));
+ connect(a, SIGNAL(triggered()), this, SLOT(initMidiDevices()));
+ a = menu_functions->addAction(QIcon(*midi_local_offIcon), tr("local off"));
+ connect(a, SIGNAL(triggered()), this, SLOT(localOff()));
+
+ //-------------------------------------------------------------
+ // Audio
+ //-------------------------------------------------------------
+
+ menu_audio = mb->addMenu(tr("&Audio"));
+
+ a = menu_audio->addAction(QIcon(*audio_bounce_to_trackIcon), tr("Bounce to Track"));
+ connect(a, SIGNAL(triggered()), this, SLOT(bounceToTrack()));
+
+ a = menu_audio->addAction(QIcon(*audio_bounce_to_fileIcon), tr("Bounce to File"));
+ connect(a, SIGNAL(triggered()), this, SLOT(bounceToFile()));
+ menu_audio->setEnabled(!midiOnly);
+ a = menu_audio->addAction(QIcon(*audio_restartaudioIcon), tr("Restart Audio"));
+ connect(a, SIGNAL(triggered()), this, SLOT(seqRestart()));
+
+ //-------------------------------------------------------------
+ // Settings
+ //-------------------------------------------------------------
+
+ menuSettings = mb->addMenu(tr("Setti&ngs"));
+ a = menuSettings->addAction(QIcon(*settings_configureshortcutsIcon), tr("Configure shortcuts"));
+ connect(a, SIGNAL(triggered()), this, SLOT(configShortCuts()));
+
+ follow = menuSettings->addMenu(QIcon(*settings_follow_songIcon), tr("follow song"));
+ //follow->menuAction()->setShortcut(Qt::Key_F);
+ fid0 = follow->addAction(tr("dont follow Song"));
+ fid0->setData("follow_no");
+ fid0->setCheckable(true);
+ fid1 = follow->addAction(tr("follow page"));
+ fid1->setData("follow_jump");
+ fid1->setCheckable(true);
+ fid2 = follow->addAction(tr("follow continuous"));
+ fid2->setData("follow_continuous");
+ fid2->setCheckable(true);
+ fid0->setChecked(TimeCanvas::followMode == FOLLOW_NO);
+ fid1->setChecked(TimeCanvas::followMode == FOLLOW_JUMP);
+ fid2->setChecked(TimeCanvas::followMode == FOLLOW_CONTINUOUS);
+ connect(follow, SIGNAL(triggered(QAction*)), SLOT(cmd(QAction*)));
+
+ menuSettings->addSeparator();
+ a = menuSettings->addAction(QIcon(*settings_midisyncIcon), tr("Midi Sync"));
+ connect(a, SIGNAL(triggered()), this, SLOT(configMidiSync()));
+ a = menuSettings->addAction(QIcon(*settings_midifileexportIcon), tr("Midi File Export"));
+ connect(a, SIGNAL(triggered()), this, SLOT(configMidiFile()));
+ menuSettings->addSeparator();
+ QAction* action = menuSettings->addAction(QIcon(*settings_globalsettingsIcon), tr("Preferences"));
+ connect(action, SIGNAL(triggered()), this, SLOT(preferences()));
+
+ //---------------------------------------------------
+ // Help
+ //---------------------------------------------------
+
+ mb->addSeparator();
+ menu_help = mb->addMenu(tr("&Help"));
+
+ a = menu_help->addAction(tr("&Manual"));
+ connect(a, SIGNAL(triggered()), this, SLOT(startHelpBrowser()));
+ a = menu_help->addAction(tr("&MusE homepage"));
+ connect(a, SIGNAL(triggered()), this, SLOT(startHomepageBrowser()));
+ menu_help->addSeparator();
+ a = menu_help->addAction(tr("&Report Bug..."));
+ connect(a, SIGNAL(triggered()), this, SLOT(startBugBrowser()));
+ menu_help->addSeparator();
+ a = menu_help->addAction(tr("&About MusE"));
+ a->setIcon(QIcon(*museIcon));
+ connect(a, SIGNAL(triggered()), this, SLOT(about()));
+ a = menu_help->addAction(tr("About&Qt"));
+ connect(a, SIGNAL(triggered()), this, SLOT(aboutQt()));
+ menu_help->addSeparator();
+ a = QWhatsThis::createAction(this);
+ a->setText(tr("What's &This?"));
+ menu_help->addAction(a);
+
+ //---------------------------------------------------
+ // ToolBar
+ //---------------------------------------------------
+
+ QToolBar* aToolBar = addToolBar(tr("Arranger"));
+
+ QLabel* label = new QLabel(tr("Cursor"));
+ label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
+ label->setIndent(3);
+ aToolBar->addWidget(label);
+
+ Awl::PosLabel* cursorPos = new Awl::PosLabel;
+ aToolBar->addWidget(cursorPos);
+ cursorPos->setFixedHeight(25);
+
+ label = new QLabel(tr("Snap"));
+ label->setIndent(5);
+ aToolBar->addWidget(label);
+
+ rasterCombo = new QComboBox;
+ rasterCombo->setFixedHeight(24);
+ aToolBar->addWidget(rasterCombo);
+ for (unsigned i = 0; i < sizeof(rasterTable)/sizeof(*rasterTable); i++)
+ rasterCombo->addItem(rasterTable[i].label, i);
+ rasterCombo->setCurrentIndex(1);
+ connect(rasterCombo, SIGNAL(activated(int)), SLOT(setRaster(int)));
+
+ // Song len
+ label = new QLabel(tr("Len"));
+ label->setIndent(5);
+ aToolBar->addWidget(label);
+
+ // song length is limited to 10000 bars; the real song len is limited
+ // by overflows in tick computations
+ //
+ QSpinBox* lenEntry = new QSpinBox;
+ lenEntry->setFixedHeight(24);
+ lenEntry->setRange(1, 10000);
+ aToolBar->addWidget(lenEntry);
+ lenEntry->setValue(song->len());
+ connect(lenEntry, SIGNAL(valueChanged(int)), song, SLOT(setMeasureLen(int)));
+ connect(song, SIGNAL(measureLenChanged(int)), lenEntry, SLOT(setValue(int)));
+
+ label = new QLabel(tr("Pitch"));
+ label->setIndent(5);
+ aToolBar->addWidget(label);
+
+ QSpinBox* globalPitchSpinBox = new QSpinBox;
+ globalPitchSpinBox->setFixedHeight(24);
+ globalPitchSpinBox->setRange(-127, 127);
+ aToolBar->addWidget(globalPitchSpinBox);
+ globalPitchSpinBox->setValue(song->globalPitchShift());
+ globalPitchSpinBox->setToolTip(tr("midi pitch"));
+ globalPitchSpinBox->setWhatsThis(tr("global midi pitch shift"));
+ connect(globalPitchSpinBox, SIGNAL(valueChanged(int)), SLOT(globalPitchChanged(int)));
+
+ label = new QLabel(tr("Tempo"));
+ label->setIndent(5);
+ aToolBar->addWidget(label);
+
+ globalTempoSpinBox = new QSpinBox;
+ globalTempoSpinBox->setFixedHeight(24);
+ globalTempoSpinBox->setRange(50, 200);
+ aToolBar->addWidget(globalTempoSpinBox);
+ globalTempoSpinBox->setSuffix(QString("%"));
+ globalTempoSpinBox->setValue(AL::tempomap.globalTempo());
+ globalTempoSpinBox->setToolTip(tr("midi tempo"));
+ globalTempoSpinBox->setWhatsThis(tr("midi tempo"));
+ connect(globalTempoSpinBox, SIGNAL(valueChanged(int)), SLOT(globalTempoChanged(int)));
+
+ QToolButton* tempo50 = new QToolButton;
+ tempo50->setFixedHeight(24);
+ aToolBar->addWidget(tempo50);
+ tempo50->setText(QString("50%"));
+ connect(tempo50, SIGNAL(clicked()), SLOT(setTempo50()));
+
+ QToolButton* tempo100 = new QToolButton;
+ tempo100->setFixedHeight(24);
+ aToolBar->addWidget(tempo100);
+ tempo100->setText(tr("N"));
+ connect(tempo100, SIGNAL(clicked()), SLOT(setTempo100()));
+
+ QToolButton* tempo200 = new QToolButton;
+ tempo200->setFixedHeight(24);
+ aToolBar->addWidget(tempo200);
+ tempo200->setText(QString("200%"));
+ connect(tempo200, SIGNAL(clicked()), SLOT(setTempo200()));
+
+ //---------------------------------------------------
+ // Central Widget
+ //---------------------------------------------------
+
+ arranger = new Arranger(this);
+ setCentralWidget(arranger);
+
+ connect(tools1, SIGNAL(toolChanged(int)), SLOT(setTool(int)));
+ connect(arranger, SIGNAL(toolChanged(int)), SLOT(setTool(int)));
+ connect(arranger, SIGNAL(editPart(Part*)), SLOT(startEditor(Part*)));
+//TODO1 connect(arranger, SIGNAL(dropSongFile(const QString&)), SLOT(loadProject(const QString&)));
+//TODO1 connect(arranger, SIGNAL(dropMidiFile(const QString&)), SLOT(importMidi(const QString&)));
+ connect(arranger, SIGNAL(cursorPos(const AL::Pos&,bool)), cursorPos, SLOT(setValue(const AL::Pos&,bool)));
+
+ //---------------------------------------------------
+ // read list of "Recent Projects"
+ //---------------------------------------------------
+
+ QString prjPath(getenv("HOME"));
+ prjPath += QString("/.musePrj");
+ FILE* f = fopen(prjPath.toLatin1().data(), "r");
+ if (f == 0) {
+ if (debugMsg) {
+ fprintf(stderr, "open projectfile <%s> failed: %s",
+ prjPath.toLatin1().data(), strerror(errno));
+ }
+ for (int i = 0; i < PROJECT_LIST_LEN; ++i)
+ projectList[i] = 0;
+ }
+ else {
+ for (int i = 0; i < PROJECT_LIST_LEN; ++i) {
+ char buffer[256];
+ if (fgets(buffer, 256, f)) {
+ int n = strlen(buffer);
+ if (n && buffer[n-1] == '\n')
+ buffer[n-1] = 0;
+ projectList[i] = *buffer ? new QString(buffer) : 0;
+ }
+ else
+ break;
+ }
+ fclose(f);
+ }
+
+ initMidiSynth();
+
+ transport = new Transport;
+ transport->hide();
+ connect(transport, SIGNAL(closed()), SLOT(transportClosed()));
+
+ QClipboard* cb = QApplication::clipboard();
+ connect(cb, SIGNAL(dataChanged()), SLOT(clipboardChanged()));
+ connect(cb, SIGNAL(selectionChanged()), SLOT(clipboardChanged()));
+ song->blockSignals(false);
+ }
+
+//---------------------------------------------------------
+// aboutToShowAddTrack
+//---------------------------------------------------------
+
+void MusE::aboutToShowAddTrack()
+ {
+ populateAddTrack(addTrack);
+ }
+
+//---------------------------------------------------------
+// setRaster
+//---------------------------------------------------------
+
+void MusE::setRaster(int val)
+ {
+ _raster = rasterTable[val].val;
+ emit rasterChanged(_raster);
+ }
+
+//---------------------------------------------------------
+// initRaster
+//---------------------------------------------------------
+
+void MusE::initRaster(int val)
+ {
+ for (unsigned i = 0; i < sizeof(rasterTable)/sizeof(*rasterTable); ++i) {
+ if (rasterTable[i].val == val) {
+ _raster = val;
+ rasterCombo->setCurrentIndex(i);
+ return;
+ }
+ }
+ _raster = rasterTable[1].val;
+ rasterCombo->setCurrentIndex(1);
+ }
+
+//---------------------------------------------------------
+// setHeartBeat
+//---------------------------------------------------------
+
+void MusE::setHeartBeat()
+ {
+ heartBeatTimer->start(1000/config.guiRefresh);
+ }
+
+//---------------------------------------------------------
+// resetDevices
+//---------------------------------------------------------
+
+void MusE::resetMidiDevices()
+ {
+ audio->msgResetMidiDevices();
+ }
+
+//---------------------------------------------------------
+// initMidiDevices
+//---------------------------------------------------------
+
+void MusE::initMidiDevices()
+ {
+ audio->msgInitMidiDevices();
+ }
+
+//---------------------------------------------------------
+// localOff
+//---------------------------------------------------------
+
+void MusE::localOff()
+ {
+ audio->msgLocalOff();
+ }
+
+//---------------------------------------------------------
+// loadProject
+//---------------------------------------------------------
+
+void MusE::loadProject(const QString& path)
+ {
+ //
+ // stop audio threads if running
+ //
+ bool restartSequencer = audioState == AUDIO_RUNNING;
+ if (restartSequencer) {
+ if (audio->isPlaying()) {
+ audio->msgPlay(false);
+ while (audio->isPlaying())
+ qApp->processEvents();
+ }
+ seqStop();
+ }
+ loadProject1(path);
+ if (restartSequencer)
+ seqStart();
+ audio->msgSeek(song->cPos());
+ }
+
+//---------------------------------------------------------
+// loadProject1
+//---------------------------------------------------------
+
+void MusE::loadProject1(const QString& path)
+ {
+ QFileInfo file(path);
+ QString header = tr("MusE: new project");
+
+ if (leaveProject())
+ return;
+
+ if (mixer1)
+ mixer1->clear();
+ if (mixer2)
+ mixer2->clear();
+
+ QString name(file.fileName());
+ QDir pd(QDir::homePath() + "/" + config.projectPath + "/" + path);
+
+ addProject(path); // add to history
+
+ bool newProject = false;
+ if (!pd.exists()) {
+ newProject = true;
+ if (!pd.mkdir(pd.path())) {
+ QString s(tr("Cannot create project folder <%1>"));
+ QMessageBox::critical(this, header, s.arg(pd.path()));
+ return;
+ }
+ }
+ //
+ // close all toplevel windows
+ //
+ foreach(QWidget* w, QApplication::topLevelWidgets()) {
+ if (!w->isVisible())
+ continue;
+ static const char* const top[] = {
+ "DrumEdit", "PianoRoll", "MasterEdit", "WaveEdit",
+ "ListEdit", "PluginGui"
+ };
+ for (unsigned i = 0; i < sizeof(top)/sizeof(*top); ++i) {
+ if (strcmp(top[i], w->metaObject()->className()) == 0) {
+ w->close();
+ break;
+ }
+ }
+ }
+ emit startLoadSong();
+
+ song->setProjectPath(path);
+ song->clear(false);
+ song->setCreated(newProject);
+
+ QString s = pd.absoluteFilePath(name + ".med");
+
+ QFile f(s);
+
+ song->blockSignals(true);
+
+ bool rv = true;
+ if (f.open(QIODevice::ReadOnly)) {
+ rv = song->read(&f);
+ f.close();
+ }
+ else {
+ TemplateDialog templateDialog;
+ if (templateDialog.exec() == 1) {
+ s = templateDialog.templatePath();
+ if (!s.isEmpty()) {
+ QFile f(s);
+ if (f.open(QIODevice::ReadOnly)) {
+ rv = song->read(&f);
+ f.close();
+ }
+ else {
+ QString msg(tr("Cannot open template file\n%1"));
+ QMessageBox::critical(this, header, msg.arg(s));
+ }
+ }
+ }
+ }
+ if (!rv) {
+ QString msg(tr("File <%1> read error"));
+ QMessageBox::critical(this, header, msg.arg(s));
+ }
+ tr_id->setChecked(config.transportVisible);
+ bt_id->setChecked(config.bigTimeVisible);
+
+ showBigtime(config.bigTimeVisible);
+ showMixer1(config.mixer1Visible);
+ showMixer2(config.mixer2Visible);
+ if (mixer1 && config.mixer1Visible)
+ mixer1->setUpdateMixer();
+ if (mixer2 && config.mixer2Visible)
+ mixer2->setUpdateMixer();
+// resize(config.geometryMain.size());
+// move(config.geometryMain.topLeft());
+ if (config.transportVisible)
+ transport->show();
+ transport->move(config.geometryTransport.topLeft());
+ showTransport(config.transportVisible);
+ song->blockSignals(false);
+ transport->setMasterFlag(song->masterFlag());
+ punchinAction->setChecked(song->punchin());
+ punchoutAction->setChecked(song->punchout());
+ loopAction->setChecked(song->loop());
+ clipboardChanged(); // enable/disable "Paste"
+ song->setLen(song->len()); // emit song->lenChanged() signal
+
+ selectionChanged(); // enable/disable "Copy" & "Paste"
+ arranger->endLoadSong();
+ song->updatePos();
+ song->updateCurrentMarker();
+ //
+ // send "cur" controller values to devices
+ //
+
+ TrackList* tl = song->tracks();
+ for (iTrack i = tl->begin(); i != tl->end(); ++i) {
+ Track* track = *i;
+// track->blockSignals(true);
+ CtrlList* cl = track->controller();
+ for (iCtrl ic = cl->begin(); ic != cl->end(); ++ic) {
+ Ctrl* ctrl = ic->second;
+ if (ctrl->type() & Ctrl::INT) {
+ CVal val;
+ val = ctrl->curVal();
+ if (track->isMidiTrack() && val.i == CTRL_VAL_UNKNOWN)
+ continue;
+ ctrl->setCurVal(CTRL_VAL_UNKNOWN);
+ song->setControllerVal(track, ctrl, val);
+ }
+ }
+// track->blockSignals(false);
+ }
+ setWindowTitle(QString("MusE: Song: ") + name);
+ }
+
+//---------------------------------------------------------
+// MusE::loadProject
+//---------------------------------------------------------
+
+void MusE::loadProject()
+ {
+ ProjectDialog projectDialog;
+ int rv = projectDialog.exec();
+ if (rv == 0)
+ return;
+ QString path = projectDialog.projectPath();
+ if (path.isEmpty())
+ return;
+ loadProject(path);
+ }
+
+//---------------------------------------------------------
+// save
+//---------------------------------------------------------
+
+bool MusE::save()
+ {
+ QString backupCommand;
+
+ QString name(song->projectName() + ".med");
+ QFileInfo fi(song->absoluteProjectPath() + "/" + name);
+
+ QTemporaryFile tmp(fi.path() + "/MusEXXXXXX");
+ tmp.setAutoRemove(false);
+
+ if (!tmp.open()) {
+ QString s("Creating temp file failed: ");
+ s += strerror(errno);
+ QMessageBox::critical(this,
+ tr("MusE: Create tmp file failed"), s);
+ return false;
+ }
+ Xml xml(&tmp);
+ write(xml);
+ if (tmp.error()) {
+ QString s = QString("Write File\n") + tmp.fileName() + QString("\nfailed: ")
+ + tmp.errorString();
+ QMessageBox::critical(this, tr("MusE: Write File failed"), s);
+ return false;
+ }
+ if (!song->backupWritten()) {
+ //
+ // remove old backup file
+ //
+ QDir dir(fi.path());
+ QString backupName = QString(".") + fi.fileName() + QString(",");
+ dir.remove(backupName);
+
+ //
+ // rename old file to backup
+ //
+ QString n(fi.filePath());
+ dir.rename(n, backupName);
+ }
+ //
+ // rename temp name to file name
+ //
+ tmp.rename(fi.filePath());
+
+ song->dirty = false;
+ SndFile::updateRecFiles();
+ return true;
+ }
+
+//---------------------------------------------------------
+// saveAs
+//---------------------------------------------------------
+
+bool MusE::saveAs()
+ {
+ printf("SAVEAS\n");
+ ProjectDialog projectDialog;
+ int rv = projectDialog.exec();
+ if (rv == 0)
+ return false;
+ QString path = projectDialog.projectPath();
+ if (path.isEmpty())
+ return false;
+
+ QDir pd(QDir::homePath() + "/" + config.projectPath + "/" + path);
+ QString header = tr("MusE: new project");
+ if (!pd.exists()) {
+ if (!pd.mkdir(pd.path())) {
+ QString s(tr("Cannot create project folder <%1>"));
+ QMessageBox::critical(this, header, s.arg(pd.path()));
+ return false;
+ }
+ }
+ addProject(path);
+ song->setProjectPath(path);
+ QString name = song->projectName();
+ setWindowTitle(QString("MusE: Song: ") + name);
+ return save();
+ }
+
+
+//---------------------------------------------------------
+// saveAsTemplate
+//---------------------------------------------------------
+
+void MusE::saveAsTemplate()
+ {
+ printf("Not implemented: save as template\n");
+ }
+
+//---------------------------------------------------------
+// quitDoc
+//---------------------------------------------------------
+
+void MusE::quitDoc()
+ {
+ close();
+ }
+
+//---------------------------------------------------------
+// leaveProject
+// return false if user aborts operation
+//---------------------------------------------------------
+
+bool MusE::leaveProject()
+ {
+ if (song->dirty) {
+ int n = 0;
+ n = QMessageBox::warning(this, appName,
+ tr("The current Project contains unsaved data\n"
+ "Save Current Project?"),
+ tr("&Save"), tr("&Nosave"), tr("&Abort"), 0, 2);
+ if (n == 0)
+ return !save();
+ else if (n == 2)
+ return true;
+ //
+ // delete all wave files created in this session and not
+ // referenced any more
+ // delete all if we drop the song
+ //
+ SndFile::cleanupRecFiles(n == 1);
+ }
+ else
+ SndFile::cleanupRecFiles(true);
+ //
+ // if this is a new created project,
+ // delete project directory
+ //
+ if (song->created()) {
+ // delete project directory
+ QDir pp;
+ if (!pp.rmdir(song->absoluteProjectPath()))
+ printf("cannot remove dir <%s>\n", song->absoluteProjectPath().toLatin1().data());
+ }
+ return false;
+ }
+
+//---------------------------------------------------------
+// closeEvent
+//---------------------------------------------------------
+
+void MusE::closeEvent(QCloseEvent* event)
+ {
+ song->setStop(true);
+ //
+ // wait for sequencer
+ //
+ while (audio->isPlaying()) {
+ qApp->processEvents();
+ }
+
+ if (leaveProject()) {
+ event->ignore();
+ return;
+ }
+
+ seqStop();
+
+ // save "Open Recent" list
+ QString prjPath(getenv("HOME"));
+ prjPath += "/.musePrj";
+ FILE* f = fopen(prjPath.toLatin1().data(), "w");
+ if (f) {
+ for (int i = 0; i < PROJECT_LIST_LEN; ++i) {
+ fprintf(f, "%s\n", projectList[i] ? projectList[i]->toLatin1().data() : "");
+ }
+ fclose(f);
+ }
+ exitJackAudio();
+ SynthIList* sl = song->syntis();
+ for (iSynthI i = sl->begin(); i != sl->end(); ++i)
+ delete *i;
+
+ // Cleanup temporary wavefiles + peakfiles used for undo
+ for (std::list<QString>::iterator i = temporaryWavFiles.begin(); i != temporaryWavFiles.end(); i++) {
+ QString filename = *i;
+ QFileInfo f(filename);
+ QDir d = f.dir();
+ d.remove(filename);
+ d.remove(f.baseName() + ".wca");
+ }
+ writeSettings();
+ qApp->quit();
+ }
+
+//---------------------------------------------------------
+// showTransport
+//---------------------------------------------------------
+
+void MusE::showTransport(bool flag)
+ {
+ transport->setShown(flag);
+ tr_id->setChecked(flag);
+ if (flag)
+ transport->setValues();
+ }
+
+//---------------------------------------------------------
+// printVersion
+//---------------------------------------------------------
+
+static void printVersion(const char* prog)
+ {
+ fprintf(stderr, "%s: Linux Music Editor; Version %s\n", prog, VERSION);
+ }
+
+//---------------------------------------------------------
+// startEditor
+//---------------------------------------------------------
+
+void MusE::startEditor(PartList* pl, int type)
+ {
+ switch (type) {
+ case 0: startPianoroll(pl); break;
+ case 1: startListEditor(pl); break;
+ case 2: startMidiTrackerEditor(pl); break;
+ case 3: startDrumEditor(pl); break;
+ case 4: startWaveEditor(pl); break;
+ }
+ }
+
+//---------------------------------------------------------
+// startEditor
+//---------------------------------------------------------
+
+void MusE::startEditor(Part* part, int type)
+ {
+ PartList* pl = new PartList();
+ pl->add(part);
+ startEditor(pl, type);
+ }
+
+//---------------------------------------------------------
+// startEditor
+//---------------------------------------------------------
+
+void MusE::startEditor(Part* part)
+ {
+ PartList* pl = new PartList();
+ pl->add(part);
+ Track* track = part->track();
+ switch (track->type()) {
+ case Track::MIDI:
+ {
+ MidiTrack* t = (MidiTrack*)track;
+ if (t->useDrumMap())
+ startDrumEditor(pl);
+ else
+ startPianoroll(pl);
+ }
+ break;
+ case Track::WAVE:
+ startWaveEditor(pl);
+ break;
+ default:
+ break;
+ }
+ }
+
+//---------------------------------------------------------
+// getMidiPartsToEdit
+//---------------------------------------------------------
+
+PartList* MusE::getMidiPartsToEdit()
+ {
+ PartList* pl = song->getSelectedMidiParts();
+ if (pl->empty()) {
+ QMessageBox::critical(this, QString("MusE"), tr("Nothing to edit"));
+ delete pl;
+ return 0;
+ }
+ return pl;
+ }
+
+//---------------------------------------------------------
+// startPianoroll
+//---------------------------------------------------------
+
+void MusE::startPianoroll()
+ {
+ PartList* pl = getMidiPartsToEdit();
+ if (pl == 0)
+ return;
+ startPianoroll(pl);
+ }
+
+void MusE::startPianoroll(PartList* pl)
+ {
+ PianoRoll* pianoroll = new PianoRoll(pl, false);
+ pianoroll->show();
+// connect(muse, SIGNAL(configChanged()), pianoroll, SLOT(configChanged()));
+ }
+
+//---------------------------------------------------------
+// startListEditor
+//---------------------------------------------------------
+
+void MusE::startListEditor()
+ {
+// PartList* pl = getMidiPartsToEdit();
+// if (pl == 0)
+// return;
+// startListEditor(pl);
+ startListEditor(0);
+ }
+
+void MusE::startListEditor(PartList* pl)
+ {
+ Part* part = 0;
+ if (pl && !pl->empty()) {
+ part = pl->begin()->second;
+ showListEditor(Pos(), part->track(), part, 0);
+ }
+ else
+ showListEditor(Pos(), 0, 0, 0);
+ }
+
+void MusE::showListEditor(const Pos& pos, Track* track, Part* part, Ctrl* ctrl)
+ {
+ if (listEditor == 0)
+ listEditor = new ListEdit(this);
+ listEditor->selectItem(pos, track, part, ctrl);
+ listEditor->show();
+ }
+
+//---------------------------------------------------------
+// startMidiTrackerEditor
+//---------------------------------------------------------
+
+void MusE::startMidiTrackerEditor()
+ {
+ PartList* pl = getMidiPartsToEdit();
+ if (pl == 0)
+ return;
+ startMidiTrackerEditor(pl);
+ }
+
+void MusE::startMidiTrackerEditor(PartList* pl)
+ {
+ MidiTrackerEditor* miditracker = new MidiTrackerEditor(pl, false);
+ miditracker->show();
+ connect(muse, SIGNAL(configChanged()), miditracker, SLOT(configChanged()));
+ }
+
+//---------------------------------------------------------
+// startMasterEditor
+//---------------------------------------------------------
+
+void MusE::startMasterEditor()
+ {
+ MasterEdit* masterEditor = new MasterEdit();
+ masterEditor->show();
+ }
+
+//---------------------------------------------------------
+// showProjectPropsDialog
+//---------------------------------------------------------
+
+void MusE::showProjectPropsDialog()
+ {
+ if (projectPropsDialog == 0)
+ projectPropsDialog = new ProjectPropsDialog(this);
+ projectPropsDialog->show();
+ }
+
+//---------------------------------------------------------
+// startDrumEditor
+//---------------------------------------------------------
+
+void MusE::startDrumEditor()
+ {
+ PartList* pl = getMidiPartsToEdit();
+ if (pl == 0)
+ return;
+ startDrumEditor(pl);
+ }
+
+void MusE::startDrumEditor(PartList* pl)
+ {
+ DrumEdit* drumEditor = new DrumEdit(pl, false);
+ drumEditor->show();
+// connect(muse, SIGNAL(configChanged()), drumEditor, SLOT(configChanged()));
+ }
+
+//---------------------------------------------------------
+// startWaveEditor
+//---------------------------------------------------------
+
+void MusE::startWaveEditor()
+ {
+ PartList* pl = song->getSelectedWaveParts();
+ if (pl->empty()) {
+ QMessageBox::critical(this, QString("MusE"), tr("Nothing to edit"));
+ delete pl;
+ return;
+ }
+ startWaveEditor(pl);
+ }
+
+void MusE::startWaveEditor(PartList* pl)
+ {
+ WaveEdit* waveEditor = new WaveEdit(pl, false);
+ waveEditor->show();
+ connect(muse, SIGNAL(configChanged()), waveEditor, SLOT(configChanged()));
+ }
+
+//---------------------------------------------------------
+// fileMenu
+//---------------------------------------------------------
+
+void MusE::openRecentMenu()
+ {
+ openRecent->clear();
+ for (int i = 0; i < PROJECT_LIST_LEN; ++i) {
+ if (projectList[i] == 0)
+ break;
+ const char* path = projectList[i]->toLatin1().data();
+ const char* p = strrchr(path, '/');
+ if (p == 0)
+ p = path;
+ else
+ ++p;
+ QAction* a = openRecent->addAction(QString(p));
+ a->setData(i);
+ }
+ }
+
+//---------------------------------------------------------
+// selectProject
+//---------------------------------------------------------
+
+void MusE::selectProject(QAction* a)
+ {
+ if (a == 0)
+ return;
+ int id = a->data().toInt();
+ if (id < 0)
+ return;
+ assert(id < PROJECT_LIST_LEN);
+ QString* name = projectList[id];
+ if (name == 0)
+ return;
+ loadProject(*name);
+ }
+
+//---------------------------------------------------------
+// playToggle
+//---------------------------------------------------------
+
+void MusE::playToggle()
+ {
+ if (audio->isPlaying())
+ song->setStop(true);
+ else
+ song->setPlay(true);
+// else if (song->cpos() != song->lpos())
+// song->setPos(0, song->lPos());
+// else {
+// Pos p(0, AL::TICKS);
+// song->setPos(0, p);
+// }
+ }
+
+//---------------------------------------------------------
+// MuseApplication
+//---------------------------------------------------------
+
+MuseApplication::MuseApplication(int& argc, char** argv)
+ : QApplication(argc, argv)
+ {
+ muse = 0;
+ for (unsigned i = 0;; ++i) {
+ if (sc[i].xml == 0)
+ break;
+ shortcuts[sc[i].xml] = &sc[i];
+ }
+ }
+
+//---------------------------------------------------------
+// usage
+//---------------------------------------------------------
+
+static void usage(const char* prog, const char* txt)
+ {
+ fprintf(stderr, "%s: %s\nusage: %s flags midifile\n Flags:",
+ prog, txt, prog);
+ fprintf(stderr, " -v print version\n");
+ fprintf(stderr, " -m MIDI only mode\n");
+ fprintf(stderr, " -d debug mode: no threads, no RT\n");
+ fprintf(stderr, " -D debug mode: enable some debug messages\n");
+ fprintf(stderr, " -i debug mode: trace midi Input\n");
+ fprintf(stderr, " -o debug mode: trace midi Output\n");
+ fprintf(stderr, " -s debug mode: trace sync\n");
+ fprintf(stderr, " -p don't load LADSPA plugins\n");
+#ifdef VST_SUPPORT
+ fprintf(stderr, " -V don't load VST plugins\n");
+#endif
+#ifdef DSSI_SUPPORT
+ fprintf(stderr, " -I don't load DSSI plugins\n");
+#endif
+ }
+
+//---------------------------------------------------------
+// catchSignal
+// only for debugging
+//---------------------------------------------------------
+
+#if 0
+static void catchSignal(int sig)
+ {
+ if (debugMsg)
+ fprintf(stderr, "MusE: signal %d catched\n", sig);
+ if (sig == SIGSEGV) {
+ fprintf(stderr, "MusE: segmentation fault\n");
+ abort();
+ }
+ if (sig == SIGCHLD) {
+ M_DEBUG("caught SIGCHLD - child died\n");
+ int status;
+ int n = waitpid (-1, &status, WNOHANG);
+ if (n > 0) {
+ fprintf(stderr, "SIGCHLD for unknown process %d received\n", n);
+ }
+ }
+ }
+#endif
+
+//---------------------------------------------------------
+// setFollow
+//---------------------------------------------------------
+
+void MusE::setFollow(FollowMode fm)
+ {
+ TimeCanvas::followMode = fm;
+ fid0->setChecked(fm == FOLLOW_NO);
+ fid1->setChecked(fm == FOLLOW_JUMP);
+ fid2->setChecked(fm == FOLLOW_CONTINUOUS);
+ changeConfig(true); // save settings
+ }
+
+//---------------------------------------------------------
+// copyParts
+// copy all selected Parts of type MIDI or WAVE to
+// clipboard whatever first found
+//---------------------------------------------------------
+
+void MusE::copyParts(bool cutFlag)
+ {
+ QBuffer buffer;
+ buffer.open(QIODevice::WriteOnly);
+ AL::Xml xml(&buffer);
+
+ if (cutFlag)
+ song->startUndo();
+ int midiType = -1;
+ TrackList* tl = song->tracks();
+ for (iTrack i = tl->begin(); i != tl->end(); ++i) {
+ Track* track = *i;
+ if (midiType == 1 && !track->isMidiTrack())
+ continue;
+ PartList* pl = track->parts();
+ for (iPart ip = pl->begin(); ip != pl->end(); ++ip) {
+ Part* part = ip->second;
+ if (part->selected()) {
+ if (midiType == -1)
+ midiType = track->isMidiTrack();
+ part->write(xml);
+ if (cutFlag)
+ song->removePart(part);
+ }
+ }
+ }
+ buffer.close();
+ QMimeData* mimeData = new QMimeData;
+ const char* t = midiType ? "application/muse/part/midi" : "application/muse/part/audio";
+ mimeData->setData(t, buffer.buffer());
+ QApplication::clipboard()->setMimeData(mimeData);
+ if (cutFlag)
+ song->endUndo(0);
+ }
+
+//---------------------------------------------------------
+// cmd
+// some cmd's from pulldown menu
+//---------------------------------------------------------
+
+void MusE::cmd(QAction* a)
+ {
+ QString cmd = a->data().toString();
+ TrackList* tracks = song->tracks();
+ int l = song->lpos();
+ int r = song->rpos();
+
+ if (cmd == "cut")
+ copyParts(true);
+ else if (cmd == "copy")
+ copyParts(false);
+ else if (cmd == "paste") {
+ const QMimeData* s = QApplication::clipboard()->mimeData();
+ int isMidi = -1;
+ QByteArray data;
+ if (s->hasFormat("application/muse/part/midi")) {
+ isMidi = 1;
+ data = s->data("application/muse/part/midi");
+ }
+ else if (s->hasFormat("application/muse/part/audio")) {
+ isMidi = 0;
+ data = s->data("application/muse/part/audio");
+ }
+ // exit if unknown format
+ if (isMidi == -1) {
+ printf("paste: unknown format\n");
+ return;
+ }
+
+ // search target track
+ TrackList* tl = song->tracks();
+ Track* track = 0;
+ for (iTrack i = tl->begin(); i != tl->end(); ++i) {
+ Track* t = *i;
+ if ((isMidi == 1 && t->type() == Track::MIDI)
+ || (isMidi == 0 && t->type() == Track::WAVE)) {
+ track = t;
+ break;
+ }
+ }
+ if (track == 0) {
+ printf("no destination track selected\n");
+ return;
+ }
+
+ QDomDocument doc;
+ int line, column;
+ QString err;
+ PartList pl;
+ if (!doc.setContent(data, false, &err, &line, &column)) {
+ QString col, ln, error;
+ col.setNum(column);
+ ln.setNum(line);
+ error = err + "\n at line: " + ln + " col: " + col;
+ printf("error parsing part: %s\n", error.toLatin1().data());
+ return;
+ }
+ int tick = -1;
+ for (QDomNode node = doc.documentElement(); !node.isNull(); node = node.nextSibling()) {
+ QDomElement e = node.toElement();
+ if (e.isNull())
+ continue;
+ if (e.tagName() == "part") {
+ Part* p = new Part(0);
+ p->ref();
+ p->read(node, true);
+ pl.add(p);
+ if (tick == -1 || p->tick() < unsigned(tick))
+ tick = int(p->tick());
+ }
+ else
+ printf("MusE: %s not supported\n", e.tagName().toLatin1().data());
+ }
+
+ unsigned cpos = song->cpos();
+ song->startUndo();
+ for (iPart ip = pl.begin(); ip != pl.end(); ++ip) {
+ Part* part = ip->second;
+ part->setTick(part->tick() - tick + cpos);
+ part->setTrack(track);
+ song->addPart(part);
+ cpos += part->lenTick();
+ }
+ song->endUndo(0);
+ track->partListChanged();
+ }
+
+ else if (cmd == "delete") {
+ TrackList* tl = song->tracks();
+ bool partsMarked = false;
+ for (iTrack it = tl->begin(); it != tl->end(); ++it) {
+ PartList* pl2 = (*it)->parts();
+ for (iPart ip = pl2->begin(); ip != pl2->end(); ++ip) {
+ if (ip->second->selected()) {
+ partsMarked = true;
+ break;
+ }
+ }
+ }
+ if (partsMarked)
+ song->cmdRemoveParts();
+ else
+ audio->msgRemoveTracks();
+ }
+ else if (cmd == "delete_track")
+ audio->msgRemoveTracks();
+ else if (cmd == "sel_all" || cmd == "sel_none" || cmd == "sel_inv"
+ || cmd == "sel_ins_loc" || cmd == "sel_out_loc") {
+ for (iTrack i = tracks->begin(); i != tracks->end(); ++i) {
+ PartList* parts = (*i)->parts();
+ for (iPart p = parts->begin(); p != parts->end(); ++p) {
+ bool f = false;
+ int t1 = p->second->tick();
+ int t2 = t1 + p->second->lenTick();
+ bool inside =
+ ((t1 >= l) && (t1 < r))
+ || ((t2 > l) && (t2 < r))
+ || ((t1 <= l) && (t2 > r));
+ if (cmd == "sel_inv")
+ f = !p->second->selected();
+ else if (cmd == "sel_none")
+ f = false;
+ else if (cmd == "sel_all")
+ f = true;
+ else if (cmd == "sel_ins_loc")
+ f = inside;
+ else if (cmd == "sel_out_loc")
+ f = !inside;
+ p->second->setSelected(f);
+ }
+ (*i)->partListChanged(); // repaints canvaswidget
+ }
+ song->update();
+ }
+ else if (cmd == "select_parts_on_track") {
+ for (iTrack i = tracks->begin(); i != tracks->end(); ++i) {
+ if (!(*i)->selected())
+ continue;
+ PartList* parts = (*i)->parts();
+ for (iPart p = parts->begin(); p != parts->end(); ++p)
+ p->second->setSelected(true);
+ }
+ song->update();
+ }
+
+ else if (cmd == "follow_no")
+ setFollow(FOLLOW_NO);
+ else if (cmd == "follow_jump")
+ setFollow(FOLLOW_JUMP);
+ else if (cmd == "follow_continuous")
+ setFollow(FOLLOW_CONTINUOUS);
+ }
+
+//---------------------------------------------------------
+// clipboardChanged
+//---------------------------------------------------------
+
+void MusE::clipboardChanged()
+ {
+// QString subtype("partlist");
+ const QMimeData* ms = QApplication::clipboard()->mimeData();
+ if (ms == 0)
+ return;
+ bool flag = ms->hasFormat("application/muse/part/midi")
+ || ms->hasFormat("application/muse/part/audio");
+ pasteAction->setEnabled(flag);
+ }
+
+//---------------------------------------------------------
+// selectionChanged
+//---------------------------------------------------------
+
+void MusE::selectionChanged()
+ {
+ int k = 0;
+ TrackList* tl = song->tracks();
+ for (iTrack t = tl->begin(); t != tl->end(); ++t)
+ k += (*t)->selected();
+ cutAction->setEnabled(k == 1);
+ copyAction->setEnabled(k == 1);
+ song->updateSelectedTrack();
+ }
+
+//---------------------------------------------------------
+// transpose
+//---------------------------------------------------------
+
+void MusE::transpose()
+ {
+ Transpose *w = new Transpose();
+ w->show();
+ }
+
+//---------------------------------------------------------
+// modifyGateTime
+//---------------------------------------------------------
+
+void MusE::modifyGateTime()
+ {
+//TODO GateTime* w = new GateTime(this);
+// w->show();
+ }
+
+//---------------------------------------------------------
+// modifyVelocity
+//---------------------------------------------------------
+
+void MusE::modifyVelocity()
+ {
+ printf("not implemented\n");
+ }
+
+//---------------------------------------------------------
+// crescendo
+//---------------------------------------------------------
+
+void MusE::crescendo()
+ {
+ printf("not implemented\n");
+ }
+
+//---------------------------------------------------------
+// thinOut
+//---------------------------------------------------------
+
+void MusE::thinOut()
+ {
+ printf("not implemented\n");
+ }
+
+//---------------------------------------------------------
+// eraseEvent
+//---------------------------------------------------------
+
+void MusE::eraseEvent()
+ {
+ printf("not implemented\n");
+ }
+
+//---------------------------------------------------------
+// noteShift
+//---------------------------------------------------------
+
+void MusE::noteShift()
+ {
+ printf("not implemented\n");
+ }
+
+//---------------------------------------------------------
+// moveClock
+//---------------------------------------------------------
+
+void MusE::moveClock()
+ {
+ printf("not implemented\n");
+ }
+
+//---------------------------------------------------------
+// copyMeasure
+//---------------------------------------------------------
+
+void MusE::copyMeasure()
+ {
+ printf("not implemented\n");
+ }
+
+//---------------------------------------------------------
+// eraseMeasure
+//---------------------------------------------------------
+
+void MusE::eraseMeasure()
+ {
+ printf("not implemented\n");
+ }
+
+//---------------------------------------------------------
+// deleteMeasure
+//---------------------------------------------------------
+
+void MusE::deleteMeasure()
+ {
+ printf("not implemented\n");
+ }
+
+//---------------------------------------------------------
+// createMeasure
+//---------------------------------------------------------
+
+void MusE::createMeasure()
+ {
+ printf("not implemented\n");
+ }
+
+//---------------------------------------------------------
+// mixTrack
+//---------------------------------------------------------
+
+void MusE::mixTrack()
+ {
+ printf("not implemented\n");
+ }
+
+//---------------------------------------------------------
+// configAppearance
+//---------------------------------------------------------
+//
+//void MusE::configAppearance()
+// {
+// if (!appearance)
+// appearance = new Appearance(arranger);
+// appearance->resetValues();
+// appearance->show();
+// }
+
+//---------------------------------------------------------
+// preferences
+//---------------------------------------------------------
+
+void MusE::preferences()
+ {
+ if (!preferencesDialog)
+ preferencesDialog = new PreferencesDialog(arranger);
+ preferencesDialog->resetValues();
+ preferencesDialog->show();
+ }
+
+//---------------------------------------------------------
+// configChanged
+// - called whenever configuration has changed
+// - when configuration has changed by user, call with
+// writeFlag=true to save configuration in ~/.MusE
+//---------------------------------------------------------
+
+void MusE::changeConfig(bool writeFlag)
+ {
+ if (writeFlag)
+ writeGlobalConfiguration();
+ updateConfiguration();
+ emit configChanged();
+ }
+
+//---------------------------------------------------------
+// configShortCuts
+//---------------------------------------------------------
+
+void MusE::configShortCuts()
+ {
+ if (!shortcutConfig)
+ shortcutConfig = new ShortcutConfig(this);
+ shortcutConfig->_config_changed = false;
+ if (shortcutConfig->exec())
+ changeConfig(true);
+ }
+
+//---------------------------------------------------------
+// globalCut
+// - remove area between left and right locator
+// - do not touch muted track
+// - cut master track
+//---------------------------------------------------------
+
+void MusE::globalCut()
+ {
+ int lpos = song->lpos();
+ int rpos = song->rpos();
+ if ((lpos - rpos) >= 0)
+ return;
+
+ song->startUndo();
+ MidiTrackList* tracks = song->midis();
+ for (iMidiTrack it = tracks->begin(); it != tracks->end(); ++it) {
+ MidiTrack* track = *it;
+ if (track->mute())
+ continue;
+ PartList* pl = track->parts();
+ for (iPart p = pl->begin(); p != pl->end(); ++p) {
+ Part* part = p->second;
+ int t = part->tick();
+ int l = part->lenTick();
+ if (t + l <= lpos)
+ continue;
+ if ((t >= lpos) && ((t+l) <= rpos)) {
+ song->removePart(part);
+ }
+ else if ((t < lpos) && ((t+l) > lpos) && ((t+l) <= rpos)) {
+ // remove part tail
+ int len = lpos - t;
+ Part* nPart = new Part(*part);
+ nPart->setLenTick(len);
+ //
+ // cut Events in nPart
+ EventList* el = nPart->events();
+ iEvent ie = el->lower_bound(t + len);
+ for (; ie != el->end();) {
+ iEvent i = ie;
+ ++ie;
+ audio->msgDeleteEvent(i->second, nPart, false);
+ }
+ song->changePart(part, nPart);
+ }
+ else if ((t < lpos) && ((t+l) > lpos) && ((t+l) > rpos)) {
+ //----------------------
+ // remove part middle
+ //----------------------
+
+ Part* nPart = new Part(*part);
+ EventList* el = nPart->events();
+ iEvent is = el->lower_bound(lpos);
+ iEvent ie = el->upper_bound(rpos);
+ for (iEvent i = is; i != ie;) {
+ iEvent ii = i;
+ ++i;
+ audio->msgDeleteEvent(ii->second, nPart, false);
+ }
+
+ ie = el->lower_bound(rpos);
+ for (; ie != el->end();) {
+ iEvent i = ie;
+ ++ie;
+ Event event = i->second;
+ Event nEvent = event.clone();
+ nEvent.setTick(nEvent.tick() - (rpos-lpos));
+ audio->msgChangeEvent(event, nEvent, nPart, false);
+ }
+ nPart->setLenTick(l - (rpos-lpos));
+ song->changePart(part, nPart);
+ }
+ else if ((t >= lpos) && (t < rpos) && (t+l) > rpos) {
+ // TODO: remove part head
+ }
+ else if (t >= rpos) {
+ Part* nPart = new Part(*part);
+ int nt = part->tick();
+ nPart->setTick(nt - (rpos -lpos));
+ song->changePart(part, nPart);
+ }
+ }
+ }
+ // TODO: cut tempo track
+ // TODO: process marker
+ song->endUndo(SC_TRACK_MODIFIED | SC_PART_MODIFIED | SC_PART_REMOVED);
+ }
+
+//---------------------------------------------------------
+// globalInsert
+// - insert empty space at left locator position upto
+// right locator
+// - do not touch muted track
+// - insert in master track
+//---------------------------------------------------------
+
+void MusE::globalInsert()
+ {
+ unsigned lpos = song->lpos();
+ unsigned rpos = song->rpos();
+ if (lpos >= rpos)
+ return;
+
+ song->startUndo();
+ MidiTrackList* tracks = song->midis();
+ for (iMidiTrack it = tracks->begin(); it != tracks->end(); ++it) {
+ MidiTrack* track = *it;
+ //
+ // process only non muted midi tracks
+ //
+ if (track->mute())
+ continue;
+ PartList* pl = track->parts();
+ for (iPart p = pl->begin(); p != pl->end(); ++p) {
+ Part* part = p->second;
+ unsigned t = part->tick();
+ int l = part->lenTick();
+ if (t + l <= lpos)
+ continue;
+ if (lpos >= t && lpos < (t+l)) {
+ Part* nPart = new Part(*part);
+ nPart->setLenTick(l + (rpos-lpos));
+ EventList* el = nPart->events();
+
+ iEvent i = el->end();
+ while (i != el->begin()) {
+ --i;
+ if (i->first < lpos)
+ break;
+ Event event = i->second;
+ Event nEvent = i->second.clone();
+ nEvent.setTick(nEvent.tick() + (rpos-lpos));
+ audio->msgChangeEvent(event, nEvent, nPart, false);
+ }
+ song->changePart(part, nPart);
+ }
+ else if (t > lpos) {
+ Part* nPart = new Part(*part);
+ nPart->setTick(t + (rpos -lpos));
+ song->changePart(part, nPart);
+ }
+ }
+ }
+ // TODO: process tempo track
+ // TODO: process marker
+ song->endUndo(SC_TRACK_MODIFIED | SC_PART_MODIFIED | SC_PART_REMOVED);
+ }
+
+//---------------------------------------------------------
+// globalSplit
+// - split all parts at the song position pointer
+// - do not touch muted track
+//---------------------------------------------------------
+
+void MusE::globalSplit()
+ {
+ int pos = song->cpos();
+ song->startUndo();
+ TrackList* tracks = song->tracks();
+ for (iTrack it = tracks->begin(); it != tracks->end(); ++it) {
+ Track* track = *it;
+ PartList* pl = track->parts();
+ for (iPart p = pl->begin(); p != pl->end(); ++p) {
+ Part* part = p->second;
+ int p1 = part->tick();
+ int l0 = part->lenTick();
+ if (pos > p1 && pos < (p1+l0)) {
+ Part* p1;
+ Part* p2;
+ track->splitPart(part, pos, p1, p2);
+ song->changePart(part, p1);
+ song->addPart(p2);
+ break;
+ }
+ }
+ }
+ song->endUndo(SC_TRACK_MODIFIED | SC_PART_MODIFIED | SC_PART_INSERTED);
+ }
+
+//---------------------------------------------------------
+// copyRange
+// - copy space between left and right locator position
+// to song position pointer
+// - dont process muted tracks
+// - create a new part for every track containing the
+// copied events
+//---------------------------------------------------------
+
+void MusE::copyRange()
+ {
+ QMessageBox::critical(this,
+ tr("MusE: Copy Range"),
+ tr("not implemented")
+ );
+ }
+
+//---------------------------------------------------------
+// cutEvents
+// - make sure that all events in a part end where the
+// part ends
+// - process only marked parts
+//---------------------------------------------------------
+
+void MusE::cutEvents()
+ {
+ QMessageBox::critical(this,
+ tr("MusE: Cut Events"),
+ tr("not implemented")
+ );
+ }
+
+//---------------------------------------------------------
+// checkRegionNotNull
+// return true if (rPos - lPos) <= 0
+//---------------------------------------------------------
+
+bool MusE::checkRegionNotNull()
+ {
+ int start = song->lPos().frame();
+ int end = song->rPos().frame();
+ if (end - start <= 0) {
+ QMessageBox::critical(this,
+ tr("MusE: Bounce"),
+ tr("set left/right marker for bounce range")
+ );
+ return true;
+ }
+ return false;
+ }
+
+//---------------------------------------------------------
+// resetAllRecordFlags
+//---------------------------------------------------------
+
+static void resetAllRecordFlags()
+ {
+ WaveTrackList* wtl = song->waves();
+ for (iWaveTrack i = wtl->begin(); i != wtl->end(); ++i) {
+ if((*i)->recordFlag())
+ song->setRecordFlag(*i, false);
+ }
+ MidiTrackList* mtl = song->midis();
+ for (iMidiTrack i = mtl->begin(); i != mtl->end(); ++i) {
+ if((*i)->recordFlag())
+ song->setRecordFlag(*i, false);
+ }
+ }
+
+//---------------------------------------------------------
+// bounceToTrack
+//---------------------------------------------------------
+
+void MusE::bounceToTrack()
+ {
+ if (checkRegionNotNull())
+ return;
+ // search target track
+ TrackList* tl = song->tracks();
+ WaveTrack* track = 0;
+ for (iTrack it = tl->begin(); it != tl->end(); ++it) {
+ Track* t = *it;
+ if (t->selected()) {
+ if (track) {
+ QMessageBox::critical(this,
+ tr("MusE: Bounce to Track"),
+ tr("more than one target track selected")
+ );
+ return;
+ }
+ if (t->type() != Track::WAVE) {
+ QMessageBox::critical(this,
+ tr("MusE: Bounce to Track"),
+ tr("wrong target track type,\nselect wave track as target")
+ );
+ return;
+ }
+ track = (WaveTrack*)t;
+ }
+ }
+ if (track == 0) {
+ QMessageBox::critical(this,
+ tr("MusE: Bounce to Track"),
+ tr("no target track selected")
+ );
+ return;
+ }
+ song->bounceTrack = track;
+ song->setRecord(true);
+ resetAllRecordFlags();
+ song->setRecordFlag(track, true);
+ audio->msgBounce();
+ }
+
+//---------------------------------------------------------
+// bounceToFile
+//---------------------------------------------------------
+
+void MusE::bounceToFile()
+ {
+ if (checkRegionNotNull())
+ return;
+ SndFile* sf = getSndFile(0, this);
+ if (sf == 0)
+ return;
+ OutputList* ol = song->outputs();
+ AudioOutput* ao = ol->front();
+ if (ao == 0) {
+ QMessageBox::critical(this,
+ tr("MusE: Bounce to File"),
+ tr("no output track found")
+ );
+ return;
+ }
+ ao->setRecFile(sf);
+ song->setRecord(true);
+ resetAllRecordFlags();
+ song->setRecordFlag(ao, true);
+ audio->msgBounce();
+ }
+
+//---------------------------------------------------------
+// startEditInstrument
+//---------------------------------------------------------
+
+void MusE::startEditInstrument()
+ {
+ if (editInstrument == 0)
+ editInstrument = new EditInstrument(this);
+ editInstrument->show();
+ }
+
+//---------------------------------------------------------
+// updateConfiguration
+// called whenever the configuration has changed
+//---------------------------------------------------------
+
+void MusE::updateConfiguration()
+ {
+ }
+
+//---------------------------------------------------------
+// showBigtime
+//---------------------------------------------------------
+
+void MusE::showBigtime(bool on)
+ {
+ if (on && bigtime == 0) {
+ bigtime = new BigTime(0);
+ bigtime->setPos(0, song->cpos(), false);
+ connect(song, SIGNAL(posChanged(int,const AL::Pos&, bool)), bigtime, SLOT(setPos(int,const AL::Pos&, bool)));
+ connect(muse, SIGNAL(configChanged()), bigtime, SLOT(configChanged()));
+ connect(bigtime, SIGNAL(closed()), SLOT(bigtimeClosed()));
+ bigtime->resize(config.geometryBigTime.size());
+ bigtime->move(config.geometryBigTime.topLeft());
+ }
+ if (bigtime)
+ bigtime->setShown(on);
+ bt_id->setChecked(on);
+ }
+
+//---------------------------------------------------------
+// showMarker
+//---------------------------------------------------------
+
+void MusE::showMarker(bool on)
+ {
+ if (on && markerView == 0) {
+ markerView = new MarkerView;
+ connect(markerView, SIGNAL(closed()), SLOT(markerClosed()));
+ }
+ if (markerView)
+ markerView->setShown(on);
+ mk_id->setChecked(on);
+ }
+
+//---------------------------------------------------------
+// markerClosed
+//---------------------------------------------------------
+
+void MusE::markerClosed()
+ {
+ mk_id->setChecked(false);
+ markerView = 0;
+ }
+
+//---------------------------------------------------------
+// bigtimeClosed
+//---------------------------------------------------------
+
+void MusE::bigtimeClosed()
+ {
+ bt_id->setChecked(false);
+ }
+
+//---------------------------------------------------------
+// transportClosed
+//---------------------------------------------------------
+
+void MusE::transportClosed()
+ {
+ tr_id->setChecked(false);
+ }
+
+//---------------------------------------------------------
+// showMixer1
+//---------------------------------------------------------
+
+void MusE::showMixer1(bool on)
+ {
+ if (on && mixer1 == 0) {
+ mixer1 = new Mixer(this, &(config.mixer1));
+ connect(mixer1, SIGNAL(closed()), SLOT(mixer1Closed()));
+ mixer1->resize(config.mixer1.geometry.size());
+ mixer1->move(config.mixer1.geometry.topLeft());
+ }
+ if (mixer1)
+ mixer1->setShown(on);
+ aid1a->setChecked(on);
+ }
+
+//---------------------------------------------------------
+// showMixer2
+//---------------------------------------------------------
+
+void MusE::showMixer2(bool on)
+ {
+ if (on && mixer2 == 0) {
+ mixer2 = new Mixer(this, &(config.mixer2));
+ connect(mixer2, SIGNAL(closed()), SLOT(mixer2Closed()));
+ mixer2->resize(config.mixer2.geometry.size());
+ mixer2->move(config.mixer2.geometry.topLeft());
+ }
+ if (mixer2)
+ mixer2->setShown(on);
+ aid1b->setChecked(on);
+ }
+
+//---------------------------------------------------------
+// mixer1Closed
+//---------------------------------------------------------
+
+void MusE::mixer1Closed()
+ {
+ aid1a->setChecked(false);
+ }
+
+//---------------------------------------------------------
+// mixer2Closed
+//---------------------------------------------------------
+
+void MusE::mixer2Closed()
+ {
+ aid1b->setChecked(false);
+ }
+
+//---------------------------------------------------------
+// transportWindow
+//---------------------------------------------------------
+
+QWidget* MusE::transportWindow()
+ {
+ return transport;
+ }
+
+//---------------------------------------------------------
+// bigtimeWindow
+//---------------------------------------------------------
+
+QWidget* MusE::bigtimeWindow()
+ {
+ return bigtime;
+ }
+
+//---------------------------------------------------------
+// mixer1Window
+//---------------------------------------------------------
+
+QWidget* MusE::mixer1Window()
+ {
+ return mixer1;
+ }
+
+//---------------------------------------------------------
+// mixer2Window
+//---------------------------------------------------------
+
+QWidget* MusE::mixer2Window()
+ {
+ return mixer2;
+ }
+
+//---------------------------------------------------------
+// focusInEvent
+//---------------------------------------------------------
+
+void MusE::focusInEvent(QFocusEvent* ev)
+ {
+ if (mixer1)
+ mixer1->raise();
+ if (mixer2)
+ mixer2->raise();
+ raise();
+ QMainWindow::focusInEvent(ev);
+ }
+
+//---------------------------------------------------------
+// setTool
+//---------------------------------------------------------
+
+void MusE::setTool(int tool)
+ {
+ tools1->set(tool);
+ arranger->setTool(tool);
+ }
+
+void MusE::setTool(const QString& s)
+ {
+ int id = 0;
+ for (int i = 0; i < TOOLS; ++i) {
+ if (toolList[i] == s) {
+ id = i;
+ break;
+ }
+ }
+ id = 1 << id;
+ tools1->set(id);
+ arranger->setTool(id);
+ }
+
+//---------------------------------------------------------
+// globalPitchChanged
+//---------------------------------------------------------
+
+void MusE::globalPitchChanged(int val)
+ {
+ song->setGlobalPitchShift(val);
+ }
+
+//---------------------------------------------------------
+// globalTempoChanged
+//---------------------------------------------------------
+
+void MusE::globalTempoChanged(int val)
+ {
+ audio->msgSetGlobalTempo(val);
+ song->update(SC_TEMPO);
+ }
+
+//---------------------------------------------------------
+// setTempo50
+//---------------------------------------------------------
+
+void MusE::setTempo50()
+ {
+ setGlobalTempo(50);
+ }
+
+//---------------------------------------------------------
+// setTempo100
+//---------------------------------------------------------
+
+void MusE::setTempo100()
+ {
+ setGlobalTempo(100);
+ }
+
+//---------------------------------------------------------
+// setTempo200
+//---------------------------------------------------------
+
+void MusE::setTempo200()
+ {
+ setGlobalTempo(200);
+ }
+
+//---------------------------------------------------------
+// setGlobalTempo
+//---------------------------------------------------------
+
+void MusE::setGlobalTempo(int val)
+ {
+ globalTempoSpinBox->setValue(val);
+ }
+
+//---------------------------------------------------------
+// main
+//---------------------------------------------------------
+
+int main(int argc, char* argv[])
+ {
+ char c;
+ QString opts("mvdDiosP:p");
+
+#ifdef VST_SUPPORT
+ opts += "V";
+#endif
+#ifdef DSSI_SUPPORT
+ opts += "I";
+#endif
+ while ((c = getopt(argc, argv, opts.toLatin1().data())) != EOF) {
+ switch (c) {
+ case 'v': printVersion(argv[0]); return 0;
+ case 'd':
+ debugMode = true;
+ realTimePriority = false;
+ break;
+ case 'm': midiOnly = true; break;
+ case 'D': debugMsg = true; break;
+ case 'i': midiInputTrace = true; break;
+ case 'o': midiOutputTrace = true; break;
+ case 's': debugSync = true; break;
+ case 'p': loadPlugins = false; break;
+ case 'V': loadVST = false; break;
+ case 'I': loadDSSI = false; break;
+ default: usage(argv[0], "bad argument"); return -1;
+ }
+ }
+ AL::debugMsg = debugMsg;
+ if (midiOnly) {
+ loadDSSI = false;
+ loadPlugins = false;
+ loadVST = false;
+ }
+ AL::initDsp();
+
+ museUser = QString(getenv("MUSEHOME"));
+ if (museUser.isEmpty())
+ museUser = QDir::homePath();
+ QString museGlobal;
+ const char* p = getenv("MUSE");
+ museGlobal = p ? p : INSTPREFIX;
+
+ museGlobalLib = museGlobal + "/lib/" INSTALL_NAME;
+ museGlobalShare = museGlobal + "/share/" INSTALL_NAME;
+ configName = museUser + QString("/." INSTALL_NAME);
+ lastMidiPath = museUser + "/" + ::config.importMidiPath;
+ lastWavePath = museUser + "/" + ::config.importWavePath;
+
+ srand(time(0)); // initialize random number generator
+ initMidiController();
+ initMidiInstruments();
+ MuseApplication app(argc, argv);
+ QCoreApplication::setOrganizationName("MusE");
+ QCoreApplication::setOrganizationDomain("muse.org");
+ QCoreApplication::setApplicationName("MusE");
+
+ gmDrumMap.initGm(); // init default drum map
+ readConfiguration();
+
+ // this style is used for scrollbars in mixer plugin racks:
+ smallStyle = new QWindowsStyle();
+
+ // SHOW MUSE SPLASH SCREEN
+ if (config.showSplashScreen) {
+ QPixmap splsh(":/xpm/splash.png");
+
+ if (!splsh.isNull()) {
+ QSplashScreen* muse_splash = new QSplashScreen(splsh,
+ Qt::WindowStaysOnTopHint);
+ muse_splash->show();
+ QTimer* stimer = new QTimer(0);
+ muse_splash->connect(stimer, SIGNAL(timeout()), muse_splash, SLOT(close()));
+ stimer->start(6000);
+ }
+ }
+
+ QFile cf(config.styleSheetFile);
+ if (cf.open(QIODevice::ReadOnly)) {
+ QByteArray ss = cf.readAll();
+ QString sheet(QString::fromUtf8(ss.data()));
+ app.setStyleSheet(sheet);
+ cf.close();
+ }
+ else
+ printf("loading style sheet <%s> failed\n", qPrintable(config.styleSheetFile));
+
+ bool useJACK = !(debugMode || midiOnly);
+ if (useJACK) {
+ if (initJackAudio()) {
+ if (!debugMode)
+ {
+ QMessageBox::critical(NULL, "MusE fatal error",
+ "MusE failed to find a Jack audio server.\n"
+ "Check that Jack was started.\n"
+ "If Jack was started check that it was\n"
+ "started as the same user as MusE.");
+ // fatalError("cannot start JACK");
+ }
+ else
+ {
+ fprintf(stderr, "fatal error: no JACK audio server found\n");
+ fprintf(stderr, "no audio functions available\n");
+ fprintf(stderr, "*** experimental mode -- no play possible ***\n");
+ }
+ useJACK = false;
+ debugMode = true;
+ }
+ }
+ if (!useJACK)
+ initDummyAudio();
+
+ argc -= optind;
+ ++argc;
+
+ if (debugMsg) {
+ printf("global lib: <%s>\n", museGlobalLib.toLatin1().data());
+ printf("global share: <%s>\n", museGlobalShare.toLatin1().data());
+ printf("muse home: <%s>\n", museUser.toLatin1().data());
+ printf("project dir: <%s>\n", config.projectPath.toLatin1().data());
+ printf("config file: <%s>\n", configName.toLatin1().data());
+ }
+
+ static QTranslator translator;
+ QFile f(":/muse.qm");
+ if (f.exists()) {
+ if (debugMsg)
+ printf("locale file found\n");
+ if (translator.load(":/muse.qm")) {
+ if (debugMsg)
+ printf("locale file loaded\n");
+ }
+ qApp->installTranslator(&translator);
+ }
+ else {
+ if (debugMsg) {
+ printf("locale file not found for locale <%s>\n",
+ QLocale::system().name().toLatin1().data());
+ }
+ }
+
+ if (loadPlugins) {
+ initPlugins();
+ initMidiPlugins();
+ }
+ if (loadVST)
+ initVST();
+
+ if (loadDSSI)
+ initDSSI();
+
+ initIcons();
+ if (!midiOnly)
+ initMetronome();
+
+ if (debugMsg) {
+ QStringList list = app.libraryPaths();
+ QStringList::Iterator it = list.begin();
+ printf("QtLibraryPath:\n");
+ while(it != list.end()) {
+ printf(" <%s>\n", (*it).toLatin1().data());
+ ++it;
+ }
+ }
+
+ song = new Song();
+ muse = new MusE();
+ muse->readSettings();
+ app.setMuse(muse);
+
+ //---------------------------------------------------
+ // load project
+ //---------------------------------------------------
+
+ // check for project directory:
+
+ QDir pd(QDir::homePath() + "/" + config.projectPath);
+ if (!pd.exists()) {
+ // ask user to create a new project directory
+ QString title(QT_TR_NOOP("MusE: create project directory"));
+
+ QString s;
+ s = "The MusE project directory\n%1\ndoes not exists";
+ s = s.arg(pd.path());
+
+ int rv = QMessageBox::question(0,
+ title,
+ s,
+ "Create",
+ "Abort",
+ QString(),
+ 0, 1);
+ if (rv == 1)
+ exit(0);
+ if (!pd.mkpath(pd.path())) {
+ // TODO: tell user why this has happened
+ QMessageBox::critical(0,
+ title,
+ "Creating project directory failed");
+ exit(-1);
+ }
+ }
+
+ // check for template directory:
+
+ pd.setPath(QDir::homePath() + "/" + config.templatePath);
+ if (!pd.exists()) {
+ // ask user to create a new template directory
+ QString title(QT_TR_NOOP("MusE: create template directory"));
+
+ QString s;
+ s = "The MusE template directory\n%1\ndoes not exists";
+ s = s.arg(pd.path());
+
+ int rv = QMessageBox::question(0,
+ title,
+ s,
+ "Create",
+ "Abort",
+ QString(),
+ 0, 1);
+ if (rv == 0) {
+ if (!pd.mkpath(pd.path())) {
+ // TODO: tell user why this has happened
+ QMessageBox::critical(0,
+ title,
+ "Creating template directory failed");
+ }
+ }
+ }
+
+ // check for instruments directory:
+
+ pd.setPath(QDir::homePath() + "/" + config.instrumentPath);
+ if (!pd.exists()) {
+ // ask user to create a new instruments directory
+ QString title(QT_TR_NOOP("MusE: create instruments directory"));
+
+ QString s;
+ s = "The MusE instruments directory\n%1\ndoes not exists";
+ s = s.arg(pd.path());
+
+ int rv = QMessageBox::question(0,
+ title,
+ s,
+ "Create",
+ "Abort",
+ QString(),
+ 0, 1);
+ if (rv == 0) {
+ if (!pd.mkpath(pd.path())) {
+ // TODO: tell user why this has happened
+ QMessageBox::critical(0,
+ title,
+ "Creating instruments directory failed");
+ }
+ }
+ }
+
+ QString path; // project path relativ to config.projectPath
+ if (argc >= 2)
+ path = argv[optind]; // start with first name on command line
+ else if (config.startMode == START_LAST_PROJECT) {
+ if (projectList[0])
+ path = *projectList[0];
+ }
+ else if (config.startMode == START_START_PROJECT)
+ path = config.startProject;
+
+ QString name = path.split("/").last();
+ if (!path.isEmpty()) {
+ QFile f(QDir::homePath() +"/"+config.projectPath+"/"+path+"/"+name+".med");
+ if (!f.exists()) {
+ QString s(QT_TR_NOOP("Cannot find project <%1>"));
+ QString header(QT_TR_NOOP("MusE: load Project"));
+ QMessageBox::critical(0, header, s.arg(f.fileName()));
+ path = "";
+ }
+ }
+ if (path.isEmpty()) {
+ //
+ // ask user for a project
+ //
+ for (;;) {
+ ProjectDialog projectDialog;
+ projectDialog.setProjectName(name);
+ int rv = projectDialog.exec();
+ if (rv == 1) {
+ path = projectDialog.projectPath();
+ if (!path.isEmpty())
+ break;
+ }
+ // the user did not select/create a project
+ rv = QMessageBox::question(0,
+ "MusE: create/select project",
+ "before MusE starts, you must select a project\n"
+ "or create a new one",
+ "Go Back",
+ "Abort",
+ QString(),
+ 0, 1);
+ if (rv == 1)
+ exit(0);
+ }
+ }
+
+ muse->loadProject(path);
+ muse->changeConfig(false);
+ if (!debugMode) {
+ if (mlockall(MCL_CURRENT | MCL_FUTURE))
+ perror("WARNING: Cannot lock memory:");
+ }
+ muse->show();
+ muse->seqStart();
+ int n = app.exec();
+ if (n)
+ fprintf(stderr, "app end %d\n", n);
+ return n;
+ }
+
+//---------------------------------------------------------
+// beat
+// heart beat
+//---------------------------------------------------------
+
+void MusE::beat()
+ {
+ song->beat();
+ if (mixer1 && mixer1->isVisible())
+ mixer1->heartBeat();
+ if (mixer2 && mixer2->isVisible())
+ mixer2->heartBeat();
+ if (arranger && arranger->getStrip() && arranger->getStrip()->isVisible())
+ arranger->getStrip()->heartBeat();
+ }
+
+//---------------------------------------------------------
+// writeSettings
+//---------------------------------------------------------
+
+void MusE::writeSettings()
+ {
+ QSettings settings;
+ settings.beginGroup("MainWindow");
+ settings.setValue("size", size());
+ settings.setValue("pos", pos());
+ settings.endGroup();
+ }
+
+//---------------------------------------------------------
+// readSettings
+//---------------------------------------------------------
+
+void MusE::readSettings()
+ {
+ QSettings settings;
+ settings.beginGroup("MainWindow");
+ resize(settings.value("size", QSize(950, 500)).toSize());
+ move(settings.value("pos", QPoint(10, 10)).toPoint());
+ settings.endGroup();
+ }
+
+
diff --git a/muse_qt4_evolution/muse/muse.h b/muse_qt4_evolution/muse/muse.h
new file mode 100644
index 00000000..8a9d4f68
--- /dev/null
+++ b/muse_qt4_evolution/muse/muse.h
@@ -0,0 +1,318 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __APP_H__
+#define __APP_H__
+
+#include "shortcuts.h"
+#include "cobject.h"
+#include "widgets/tools.h"
+
+namespace AL {
+ class Xml;
+ class Pos;
+ };
+using AL::Xml;
+using AL::Pos;
+
+class Part;
+class PartList;
+class Transport;
+class BigTime;
+class Arranger;
+class Track;
+class MidiSyncConfig;
+class MRConfig;
+class MetronomeConfig;
+class AudioConf;
+class MidiFileConfig;
+class MidiFilterConfig;
+class MarkerView;
+class MidiInputTransformDialog;
+class MidiTransformerDialog;
+class RhythmGen;
+class MidiTrack;
+class ShortcutConfig;
+class PreferencesDialog;
+class EditInstrument;
+class Mixer;
+class ExportMidiDialog;
+class ListEdit;
+class Ctrl;
+
+extern void configMidiController();
+
+//---------------------------------------------------------
+// MusE
+//---------------------------------------------------------
+
+class MusE : public QMainWindow // , public Ui::MuseBase
+ {
+ Q_OBJECT
+
+ QAction* fileSaveAction;
+ QAction* fileSaveAsAction;
+ QAction* fileOpenAction;
+ QAction* pianoAction;
+ QAction* waveAction;
+ QAction* trackerAction;
+ QAction* fileNewAction;
+
+ QString appName;
+
+ QToolBar *tools;
+ EditToolBar *tools1;
+ int _raster;
+
+ Transport* transport;
+ QAction* tr_id;
+ BigTime* bigtime;
+ QAction* bt_id;
+ MarkerView* markerView;
+ QAction* mk_id;
+ Mixer* mixer1;
+ QAction* aid1a;
+ Mixer* mixer2;
+ QAction* aid1b;
+ ListEdit* listEditor;
+
+ EditInstrument* editInstrument;
+
+ QMenu *menu_file, *menuView, *menuSettings, *menu_help;
+ QMenu *menuEdit, *menuStructure;
+ QMenu* menu_audio;
+ QMenu* menu_functions;
+ QMenu* select, *master, *midiEdit, *addTrack;
+ QMenu* follow;
+ QMenu* midiInputPlugins;
+
+ QAction* aid2;
+ QAction* aid3;
+ QAction* fid0;
+ QAction* fid1;
+ QAction* fid2;
+ QAction* cutAction;
+ QAction* copyAction;
+ QAction* pasteAction;
+
+ QWidget* midiPortConfig;
+ QWidget* softSynthesizerConfig;
+ MidiSyncConfig* midiSyncConfig;
+ MRConfig* midiRemoteConfig;
+ RhythmGen* midiRhythmGenerator;
+ MetronomeConfig* metronomeConfig;
+ AudioConf* audioConfig;
+ MidiFileConfig* midiFileConfig;
+ MidiFilterConfig* midiFilterConfig;
+ MidiInputTransformDialog* midiInputTransform;
+ ShortcutConfig* shortcutConfig;
+ PreferencesDialog* preferencesDialog;
+ ExportMidiDialog* exportMidiDialog;
+
+ MidiTransformerDialog* midiTransformerDialog;
+ QMenu* openRecent;
+ QSpinBox* globalTempoSpinBox;
+ QComboBox* rasterCombo;
+
+ QDialog* projectPropsDialog;
+
+ //------------------------------------------
+
+ bool readMidi(FILE*);
+ void processTrack(MidiTrack* track);
+
+ void write(Xml& xml) const;
+
+ void setFollow(FollowMode);
+ void readConfigParts(QDomNode);
+ void readCtrl(QDomNode, int port, int channel);
+ PartList* getMidiPartsToEdit();
+ Part* readPart(QDomNode);
+ bool checkRegionNotNull();
+ void loadProject1(const QString&);
+ void writeGlobalConfiguration(Xml&) const;
+ void writeConfiguration(Xml&) const;
+ void updateConfiguration();
+
+ bool leaveProject();
+
+ virtual void focusInEvent(QFocusEvent*);
+ void addMidiFile(const QString name);
+ void copyParts(bool);
+ void writeSettings();
+
+ signals:
+ void configChanged();
+ void rasterChanged(int);
+ void startLoadSong();
+
+ private slots:
+ void beat();
+ void loadProject();
+ void quitDoc();
+ void about();
+ void aboutQt();
+ void startHelpBrowser();
+ void startHomepageBrowser();
+ void startBugBrowser();
+ void importMidi();
+ void importWave();
+ bool importWave(const QString&);
+ void exportMidi();
+
+ void configMidiSync();
+ void configMidiFile();
+ void configShortCuts();
+
+ void startMasterEditor();
+
+ void startDrumEditor();
+ void startDrumEditor(PartList* pl);
+ void startEditor(Part*);
+ void startEditor(PartList*, int);
+ void startPianoroll();
+ void startPianoroll(PartList* pl);
+ void startMidiTrackerEditor();
+ void startMidiTrackerEditor(PartList* pl);
+ void startWaveEditor();
+ void startWaveEditor(PartList*);
+ void writeGlobalConfiguration() const;
+ void startEditInstrument();
+
+ void startListEditor();
+ void startListEditor(PartList*);
+
+ void showProjectPropsDialog();
+
+ void openRecentMenu();
+ void selectProject(QAction*);
+ void cmd(QAction*);
+ void clipboardChanged();
+ void transpose();
+ void modifyGateTime();
+ void modifyVelocity();
+ void crescendo();
+ void thinOut();
+ void eraseEvent();
+ void noteShift();
+ void moveClock();
+ void copyMeasure();
+ void eraseMeasure();
+ void deleteMeasure();
+ void createMeasure();
+ void mixTrack();
+ void globalCut();
+ void globalInsert();
+ void globalSplit();
+ void copyRange();
+ void cutEvents();
+ void bounceToTrack();
+ void resetMidiDevices();
+ void initMidiDevices();
+ void localOff();
+ void bigtimeClosed();
+ void transportClosed();
+ void markerClosed();
+ void mixer1Closed();
+ void mixer2Closed();
+ void syncChanged();
+ void preferences();
+ void aboutToShowAddTrack();
+ void setRaster(int);
+ void playToggle();
+ void saveAsTemplate();
+
+ public slots:
+ void bounceToFile();
+ void closeEvent(QCloseEvent*e);
+ void loadProject(const QString&);
+ bool seqStart();
+ void showTransport(bool flag);
+ void showBigtime(bool);
+ void showMixer1(bool);
+ void showMixer2(bool);
+ void showMarker(bool on);
+ void importMidi(const QString &file);
+ void globalPitchChanged(int val);
+ void globalTempoChanged(int val);
+ bool seqRestart();
+ void setTempo50();
+ void setTempo100();
+ void setTempo200();
+ void setGlobalTempo(int val);
+ void setTool(int);
+ void setTool(const QString&);
+ void startEditor(Part*, int);
+ bool save();
+ bool saveAs();
+
+ public:
+ MusE();
+ Arranger* arranger;
+ QRect configGeometryMain;
+ void kbAccel(int);
+ void changeConfig(bool writeFlag);
+
+ void seqStop();
+ void setHeartBeat();
+ QWidget* transportWindow();
+ QWidget* bigtimeWindow();
+ QWidget* mixer1Window();
+ QWidget* mixer2Window();
+ bool importWaveToTrack(const QString& name, Track* track, const Pos&);
+
+ void selectionChanged();
+
+ int version; // last *.med file version
+ // 0xaabb aa - major version, bb minor version
+ int raster() const { return _raster; }
+ void setupTransportToolbar(QToolBar* tb) const;
+ void readToplevels(QDomNode);
+ void initRaster(int);
+
+ QAction* startAction;
+ QAction* rewindAction;
+ QAction* forwardAction;
+ QAction* stopAction;
+ QAction* playAction;
+
+ void showListEditor(const Pos&, Track*, Part*, Ctrl*);
+ void readSettings();
+ };
+
+//---------------------------------------------------------
+// MuseApplication
+//---------------------------------------------------------
+
+class MuseApplication : public QApplication {
+ MusE* muse;
+
+ public:
+ MuseApplication(int& argc, char** argv);
+ void setMuse(MusE* m) { muse = m; }
+ static Shortcut sc[];
+ };
+
+extern MusE* muse;
+extern QStyle* smallStyle;
+extern void addProject(const QString& name);
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/muse.qrc b/muse_qt4_evolution/muse/muse.qrc
new file mode 100644
index 00000000..b15b64da
--- /dev/null
+++ b/muse_qt4_evolution/muse/muse.qrc
@@ -0,0 +1,85 @@
+<!DOCTYPE RCC>
+<RCC version="1.0">
+ <qresource>
+ <file>style.qss</file>
+ <file>xpm/muse_icon_64x64.png</file>
+ <file>xpm/splash.png</file>
+ <file>xpm/filenew.png</file>
+ <file>xpm/fileopen.png</file>
+ <file>xpm/filesave.png</file>
+ <file>xpm/punchin.xpm</file>
+ <file>xpm/punchout.xpm</file>
+ <file>xpm/loop.xpm</file>
+ <file>xpm/start.xpm</file>
+ <file>xpm/stop.xpm</file>
+ <file>xpm/play.xpm</file>
+ <file>xpm/frewind.xpm</file>
+ <file>xpm/fforward.xpm</file>
+ <file>xpm/folder_new.png</file>
+ <file>xpm/recordOn.svg</file>
+ <file>xpm/recordOff.svg</file>
+ <file>xpm/greendot.svg</file>
+ <file>xpm/darkgreendot.svg</file>
+ <file>xpm/activeon.svg</file>
+ <file>xpm/activeoff.svg</file>
+ <file>xpm/on.svg</file>
+ <file>xpm/off.svg</file>
+ <file>xpm/mono.svg</file>
+ <file>xpm/stereo.svg</file>
+ <file>xpm/loop.xpm</file>
+ <file>xpm/punchin.xpm</file>
+ <file>xpm/punchout.xpm</file>
+ <file>xpm/undo.xpm</file>
+ <file>xpm/redo.xpm</file>
+ <file>xpm/panic.xpm</file>
+ <file>xpm/piano.xpm</file>
+ <file>xpm/view_transport_window.xpm</file>
+ <file>xpm/view_bigtime_window.xpm</file>
+ <file>xpm/view_cliplist.xpm</file>
+ <file>xpm/view_marker.xpm</file>
+ <file>xpm/view_mixer.xpm</file>
+ <file>xpm/pointer.xpm</file>
+ <file>xpm/pencil.xpm</file>
+ <file>xpm/delete.xpm</file>
+ <file>xpm/cut.xpm</file>
+ <file>xpm/glue.xpm</file>
+ <file>xpm/quant.xpm</file>
+ <file>xpm/draw.xpm</file>
+ <file>xpm/editmute.xpm</file>
+
+ <file>xpm/select_all.xpm</file>
+ <file>xpm/select_deselect_all.xpm</file>
+ <file>xpm/select_invert_selection.xpm</file>
+ <file>xpm/select_inside_loop.xpm</file>
+ <file>xpm/select_outside_loop.xpm</file>
+ <file>xpm/editcut.xpm</file>
+ <file>xpm/editcopy.xpm</file>
+ <file>xpm/editpaste.xpm</file>
+ <file>xpm/edit_drumms.xpm</file>
+ <file>xpm/edit_mastertrack.xpm</file>
+ <file>xpm/edit_list.xpm</file>
+ <file>xpm/wave.xpm</file>
+
+ </qresource>
+
+ <qresource lang="de">
+ <file alias="muse.qm">../share/locale/muse_de.qm</file>
+ </qresource>
+
+ <qresource lang="es">
+ <file alias="muse.qm">../share/locale/muse_es.qm</file>
+ </qresource>
+
+ <qresource lang="fr">
+ <file alias="muse.qm">../share/locale/muse_fr.qm</file>
+ </qresource>
+
+ <qresource lang="ru">
+ <file alias="muse.qm">../share/locale/muse_ru.qm</file>
+ </qresource>
+
+ <qresource lang="sv">
+ <file alias="muse.qm">../share/locale/muse_sv_SE.qm</file>
+ </qresource>
+</RCC>
+
diff --git a/muse_qt4_evolution/muse/part.cpp b/muse_qt4_evolution/muse/part.cpp
new file mode 100644
index 00000000..61ba561d
--- /dev/null
+++ b/muse_qt4_evolution/muse/part.cpp
@@ -0,0 +1,361 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "song.h"
+#include "part.h"
+#include "track.h"
+#include "globals.h"
+#include "event.h"
+#include "audio.h"
+#include "al/tempo.h"
+
+const char* partColorNames[] = {
+ QT_TR_NOOP("Default"),
+ QT_TR_NOOP("Refrain"),
+ QT_TR_NOOP("Bridge"),
+ QT_TR_NOOP("Intro"),
+ QT_TR_NOOP("Coda"),
+ QT_TR_NOOP("Chorus"),
+ QT_TR_NOOP("Solo"),
+ QT_TR_NOOP("Brass"),
+ QT_TR_NOOP("Percussion"),
+ QT_TR_NOOP("Drums"),
+ QT_TR_NOOP("Guitar"),
+ QT_TR_NOOP("Bass"),
+ QT_TR_NOOP("Flute"),
+ QT_TR_NOOP("Strings"),
+ QT_TR_NOOP("Keyboard"),
+ QT_TR_NOOP("Piano"),
+ QT_TR_NOOP("Saxophon"),
+ };
+
+CloneList cloneList;
+
+//---------------------------------------------------------
+// Part
+//---------------------------------------------------------
+
+Part::Part(Track* t)
+ {
+ _selected = false;
+ _mute = false;
+ _colorIndex = 0;
+ _raster = -1; // invalid
+ _quant = -1;
+ _xmag = -1.0;
+ _fillLen = 0;
+ _track = t;
+ _events = 0;
+ if (_track && _track->type() == Track::WAVE)
+ setType(AL::FRAMES);
+ }
+
+//---------------------------------------------------------
+// clone
+//---------------------------------------------------------
+
+void Part::clone(EventList* e)
+ {
+ _events = e;
+ ref();
+ }
+
+//---------------------------------------------------------
+// addEvent
+//---------------------------------------------------------
+
+iEvent Part::addEvent(Event& p)
+ {
+ return _events->add(p);
+ }
+
+iEvent Part::addEvent(Event& p, unsigned t)
+ {
+ return _events->add(p, t);
+ }
+
+//---------------------------------------------------------
+// index
+//---------------------------------------------------------
+
+int PartList::index(Part* part)
+ {
+ int index = 0;
+ for (iPart i = begin(); i != end(); ++i, ++index)
+ if (i->second == part) {
+ return index;
+ }
+ printf("PartList::index(): not found!\n");
+ abort();
+// return 0;
+ }
+
+//---------------------------------------------------------
+// find
+//---------------------------------------------------------
+
+Part* PartList::find(int idx)
+ {
+ int index = 0;
+ for (iPart i = begin(); i != end(); ++i, ++index)
+ if (index == idx)
+ return i->second;
+ return 0;
+ }
+
+//---------------------------------------------------------
+// findPart
+// search for part which contains tick
+//---------------------------------------------------------
+
+Part* PartList::findPart(unsigned tick)
+ {
+ iPart i = lower_bound(tick);
+ if (i != begin())
+ --i;
+ for (; i != end(); ++i) {
+ unsigned tick1 = i->second->tick();
+ unsigned tick2 = tick1 + i->second->lenTick();
+
+ if (tick >= tick2)
+ continue;
+ if (tick >= tick1)
+ return i->second;
+ if (tick < tick1)
+ break;
+ }
+ return 0;
+ }
+
+//---------------------------------------------------------
+// add
+//---------------------------------------------------------
+
+iPart PartList::add(Part* part)
+ {
+ return insert(std::pair<const unsigned, Part*> (part->tick(), part));
+ }
+
+//---------------------------------------------------------
+// remove
+//---------------------------------------------------------
+
+void PartList::remove(Part* part)
+ {
+ iPart i;
+ for (i = begin(); i != end(); ++i) {
+ if (i->second == part) {
+ erase(i);
+ return;
+ }
+ }
+printf("remove part: not found\n");
+ assert(i != end());
+ }
+
+//---------------------------------------------------------
+// dump
+//---------------------------------------------------------
+
+void Part::dump(int n) const
+ {
+ for (int i = 0; i < n; ++i)
+ putchar(' ');
+ printf("Part: <%s> ", _name.toLatin1().data());
+ for (int i = 0; i < n; ++i)
+ putchar(' ');
+ PosLen::dump();
+ }
+
+//---------------------------------------------------------
+// Part::write
+//---------------------------------------------------------
+
+void Part::write(Xml& xml)
+ {
+ int id = -1;
+ bool dumpEvents = true;
+
+
+ if (isClone()) {
+ // we have to dump the event list only on first
+ // incarnation of clone
+
+ for (iClone i = cloneList.begin(); i != cloneList.end(); ++i) {
+ if (i->el == _events) {
+ id = i->id;
+ dumpEvents = false;
+ break;
+ }
+ }
+ if (id == -1)
+ cloneList.push_back(ClonePart(_events, cloneList.size()));
+ }
+
+ if (id != -1)
+ xml.stag(QString("part cloneId=\"%1\"").arg(id));
+ else
+ xml.stag("part");
+ if (!_name.isEmpty())
+ xml.tag("name", _name);
+
+ PosLen::write(xml, "poslen");
+ if (_selected)
+ xml.tag("selected", _selected);
+ xml.tag("color", _colorIndex);
+ if (_raster != -1)
+ xml.tag("raster", _raster);
+ if (_quant != -1)
+ xml.tag("quant", _quant);
+ if (_xmag != -1.0)
+ xml.tag("xmag", _xmag);
+ for (ciCtrlCanvas i = ctrlCanvasList.begin(); i != ctrlCanvasList.end(); ++i)
+ xml.tagE(QString("CtrlCanvas h=\"%1\" id=\"%2\"").arg(i->height).arg(i->ctrlId));
+ if (_fillLen)
+ xml.tag("fillLen", _fillLen);
+ if (_mute)
+ xml.tag("mute", _mute);
+ if (dumpEvents) {
+ for (ciEvent e = _events->begin(); e != _events->end(); ++e)
+ e->second.write(xml, *this);
+ }
+ xml.etag("part");
+ }
+
+//---------------------------------------------------------
+// Part::read
+//---------------------------------------------------------
+
+void Part::read(QDomNode node, bool isMidiPart)
+ {
+ QDomElement e = node.toElement();
+ int id = e.attribute("cloneId", "-1").toInt();
+
+ ctrlCanvasList.clear();
+ for (node = node.firstChild(); !node.isNull(); node = node.nextSibling()) {
+ QDomElement e = node.toElement();
+ QString tag(e.tagName());
+ QString s(e.text());
+ int i = s.toInt();
+ if (tag == "name")
+ _name = s;
+ else if (tag == "poslen")
+ PosLen::read(node);
+ else if (tag == "selected")
+ _selected = i;
+ else if (tag == "color")
+ _colorIndex = i;
+ else if (tag == "raster")
+ _raster = i;
+ else if (tag == "quant")
+ _quant = i;
+ else if (tag == "xmag")
+ _xmag = s.toDouble();
+ else if (tag == "CtrlCanvas") {
+ CtrlCanvas c;
+ c.ctrlId = e.attribute("id","0").toInt();
+ c.height = e.attribute("h","50").toInt();
+ ctrlCanvasList.push_back(c);
+ }
+ else if (tag == "mute")
+ _mute = i;
+ else if (tag == "fillLen")
+ _fillLen = i;
+ else if (tag == "event") {
+ EventType type = isMidiPart ? Note : Wave;
+ Event e(type);
+ e.read(node);
+ // tickpos is relative to start of part
+ // TODO: better handling for wave event
+ e.move(-tick());
+ int tick = e.tick();
+ if ((tick < 0) || (tick >= int(lenTick()))) {
+ printf("ReadEvent: warning: event not in part: %d - %d - %d, discarded\n",
+ 0, tick, lenTick());
+ }
+ else {
+#if 0
+ if (e.type() == Controller) {
+ MidiChannel* mc = ((MidiTrack*)_track)->channel();
+ if (mc) {
+ CVal v;
+ v.i = e.dataB();
+ mc->addControllerVal(e.dataA(), tick, v);
+ }
+ else
+ _events.add(e);
+ }
+ else
+#endif
+ _events->add(e);
+ }
+ }
+ else
+ printf("MusE:read: unknown tag %s\n", e.tagName().toLatin1().data());
+ }
+
+ if (id != -1) {
+ bool found = false;
+ for (iClone i = cloneList.begin(); i != cloneList.end(); ++i) {
+ if (i->id == id) {
+ if (_events->size())
+ printf("MusE::internal error: clone part contains events\n");
+ clone(i->el);
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ // add to cloneList:
+ ClonePart cp(_events, id);
+ cloneList.push_back(cp);
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// isClone
+//---------------------------------------------------------
+
+bool Part::isClone() const
+ {
+ return _events->cloneCount > 1;
+ }
+
+//---------------------------------------------------------
+// ref
+//---------------------------------------------------------
+
+void Part::ref()
+ {
+ if (_events == 0)
+ _events = new EventList;
+ ++(_events->cloneCount);
+ }
+
+//---------------------------------------------------------
+// deref
+//---------------------------------------------------------
+
+void Part::deref()
+ {
+ --(_events->cloneCount);
+ }
+
diff --git a/muse_qt4_evolution/muse/part.h b/muse_qt4_evolution/muse/part.h
new file mode 100644
index 00000000..fd5fdd52
--- /dev/null
+++ b/muse_qt4_evolution/muse/part.h
@@ -0,0 +1,151 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __PART_H__
+#define __PART_H__
+
+#include "event.h"
+
+class Track;
+class MidiTrack;
+class WaveTrack;
+
+namespace AL {
+ class Xml;
+ };
+
+using AL::Xml;
+
+//---------------------------------------------------------
+// ClonePart
+//---------------------------------------------------------
+
+struct ClonePart {
+ EventList* el;
+ int id;
+ ClonePart(EventList* e, int i) : el(e), id(i) {}
+ };
+
+typedef std::list<ClonePart> CloneList;
+typedef CloneList::iterator iClone;
+extern CloneList cloneList;
+
+//---------------------------------------------------------
+// CtrlCanvas
+//---------------------------------------------------------
+
+struct CtrlCanvas {
+ int ctrlId;
+ int height;
+ };
+
+typedef std::list<CtrlCanvas> CtrlCanvasList;
+typedef CtrlCanvasList::iterator iCtrlCanvas;
+typedef CtrlCanvasList::const_iterator ciCtrlCanvas;
+
+//---------------------------------------------------------
+// Part
+//---------------------------------------------------------
+
+class Part : public AL::PosLen {
+ QString _name;
+ bool _selected;
+ bool _mute;
+ int _colorIndex;
+
+ // editor presets:
+ int _raster, _quant;
+ double _xmag;
+ CtrlCanvasList ctrlCanvasList;
+
+ // auto fill:
+ int _fillLen; // = 0 if no auto fill
+
+ protected:
+ Track* _track;
+ EventList* _events;
+
+ public:
+ Part(Track*);
+
+ CtrlCanvasList* getCtrlCanvasList() { return &ctrlCanvasList; }
+
+ const QString& name() const { return _name; }
+ void setName(const QString& s) { _name = s; }
+
+ bool selected() const { return _selected; }
+ void setSelected(bool f) { _selected = f; }
+
+ bool mute() const { return _mute; }
+ void setMute(bool b) { _mute = b; }
+
+ Track* track() const { return _track; }
+ void setTrack(Track*t) { _track = t; }
+
+ int colorIndex() const { return _colorIndex; }
+ void setColorIndex(int idx) { _colorIndex = idx; }
+
+ int raster() const { return _raster; }
+ void setRaster(int val) { _raster = val; }
+
+ int quant() const { return _quant; }
+ void setQuant(int val) { _quant = val; }
+
+ double xmag() const { return _xmag; }
+ void setXmag(double val) { _xmag = val; }
+
+ EventList* events() const { return _events; }
+
+ void clone(EventList* e);
+ iEvent addEvent(Event& p);
+ iEvent addEvent(Event& p, unsigned);
+
+ int fillLen() const { return _fillLen; }
+ void setFillLen(int val) { _fillLen = val; }
+
+ void read(QDomNode, bool isMidiPart);
+ void write(Xml&);
+ void dump(int n = 0) const;
+
+ bool isClone() const;
+ void deref();
+ void ref();
+ };
+
+//---------------------------------------------------------
+// PartList
+//---------------------------------------------------------
+
+typedef std::multimap<unsigned, Part*, std::less<unsigned> > PL;
+typedef PL::iterator iPart;
+typedef PL::const_iterator ciPart;
+
+class PartList : public PL {
+ public:
+ Part* findPart(unsigned tick);
+ iPart add(Part*);
+ void remove(Part* part);
+ int index(Part*);
+ Part* find(int idx);
+ };
+
+extern const char* partColorNames[];
+#endif
+
diff --git a/muse_qt4_evolution/muse/partdrag.cpp b/muse_qt4_evolution/muse/partdrag.cpp
new file mode 100644
index 00000000..c47d3c11
--- /dev/null
+++ b/muse_qt4_evolution/muse/partdrag.cpp
@@ -0,0 +1,199 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "partdrag.h"
+#include "al/xml.h"
+#include "part.h"
+
+const char MidiPartDrag::type[] = "application/muse/part/midi";
+const char AudioPartDrag::type[] = "application/muse/part/audio";
+const char WavUriDrag::type[] = "text/uri-list";
+
+//---------------------------------------------------------
+// MidiPartDrag
+//---------------------------------------------------------
+
+MidiPartDrag::MidiPartDrag(Part* part, QWidget* src)
+ : QDrag(src)
+ {
+ QBuffer buffer;
+ buffer.open(QIODevice::WriteOnly);
+ AL::Xml xml(&buffer);
+ part->write(xml);
+ buffer.close();
+ QMimeData* mimeData = new QMimeData;
+ mimeData->setData(type, buffer.buffer());
+ setMimeData(mimeData);
+ }
+
+//---------------------------------------------------------
+// canDecode
+//---------------------------------------------------------
+
+bool MidiPartDrag::canDecode(const QMimeData* s)
+ {
+ return s->hasFormat(type);
+ }
+
+//---------------------------------------------------------
+// decode
+//---------------------------------------------------------
+
+bool MidiPartDrag::decode(const QMimeData* s, Part*& p)
+ {
+ p = 0;
+ QDomDocument doc;
+ int line, column;
+ QString err;
+ if (!doc.setContent(s->data(type), false, &err, &line, &column)) {
+ QString col, ln, error;
+ col.setNum(column);
+ ln.setNum(line);
+ error = err + "\n at line: " + ln + " col: " + col;
+ printf("error parsing part: %s\n", error.toLatin1().data());
+ return false;
+ }
+ for (QDomNode node = doc.documentElement(); !node.isNull(); node = node.nextSibling()) {
+ QDomElement e = node.toElement();
+ if (e.isNull())
+ continue;
+ if (e.tagName() == "part") {
+ p = new Part(0);
+ p->ref();
+ p->read(node, true);
+ }
+ else
+ printf("MusE: %s not supported\n", e.tagName().toLatin1().data());
+ }
+ return (p != 0);
+ }
+
+//---------------------------------------------------------
+// PartDrag
+// does only transfer reference to part, this does
+// not allow for transfers between different apps
+// TODO: transfer content (xml representation)
+//---------------------------------------------------------
+
+AudioPartDrag::AudioPartDrag(Part* part, QWidget* src)
+ : QDrag(src)
+ {
+ QBuffer buffer;
+ buffer.open(QIODevice::WriteOnly);
+ Xml xml(&buffer);
+ part->write(xml);
+ buffer.close();
+
+ QMimeData* mimeData = new QMimeData;
+ mimeData->setData(type, buffer.buffer());
+ setMimeData(mimeData);
+ }
+
+//---------------------------------------------------------
+// canDecode
+//---------------------------------------------------------
+
+bool AudioPartDrag::canDecode(const QMimeData* s)
+ {
+ return s->hasFormat(type);
+ }
+
+//---------------------------------------------------------
+// decode
+//---------------------------------------------------------
+
+bool AudioPartDrag::decode(const QMimeData* s, Part*& p)
+ {
+ p = 0;
+ QDomDocument doc;
+ int line, column;
+ QString err;
+ if (!doc.setContent(s->data(type), false, &err, &line, &column)) {
+ QString col, ln, error;
+ col.setNum(column);
+ ln.setNum(line);
+ error = err + "\n at line: " + ln + " col: " + col;
+ printf("error parsing part: %s\n", error.toLatin1().data());
+ return false;
+ }
+ for (QDomNode node = doc.documentElement(); !node.isNull(); node = node.nextSibling()) {
+ QDomElement e = node.toElement();
+ if (e.isNull())
+ continue;
+ if (e.tagName() == "part") {
+ p = new Part(0);
+ p->ref();
+ p->read(node, false);
+ }
+ else
+ printf("MusE: %s not supported\n", e.tagName().toLatin1().data());
+ }
+ return (p != 0);
+ }
+
+//---------------------------------------------------------
+// WavUriDrag
+//---------------------------------------------------------
+
+WavUriDrag::WavUriDrag(const QString& s, QWidget* src)
+ : QDrag(src)
+ {
+ QByteArray a(s.toAscii());
+ QMimeData* mimeData = new QMimeData;
+ mimeData->setData(type, a);
+ setMimeData(mimeData);
+ }
+
+//---------------------------------------------------------
+// canDecode
+//---------------------------------------------------------
+
+bool WavUriDrag::canDecode(const QMimeData* s)
+ {
+ if (!s->hasFormat(type))
+ return false;
+ QByteArray data = s->data(type);
+ QUrl url(data);
+ if (url.scheme() != "file")
+ return false;
+ QFileInfo fi(url.toLocalFile().trimmed());
+ if (!fi.exists()) {
+ printf("drag file <%s> does not exist\n", fi.filePath().toLatin1().data());
+ return false;
+ }
+ if (fi.suffix() != "wav") {
+ printf("drag file <%s> has no wav suffix\n", fi.filePath().toLatin1().data());
+ return false;
+ }
+ return true;
+ }
+
+//---------------------------------------------------------
+// decode
+//---------------------------------------------------------
+
+bool WavUriDrag::decode(const QMimeData* s, QString* uri)
+ {
+ QByteArray data = s->data(type);
+ QUrl url(data);
+ *uri = url.toLocalFile().trimmed();
+ return true;
+ }
+
diff --git a/muse_qt4_evolution/muse/partdrag.h b/muse_qt4_evolution/muse/partdrag.h
new file mode 100644
index 00000000..d8c2e978
--- /dev/null
+++ b/muse_qt4_evolution/muse/partdrag.h
@@ -0,0 +1,69 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __PARTDRAG_H__
+#define __PARTDRAG_H__
+
+class Part;
+
+//---------------------------------------------------------
+// MidiPartDrag
+//---------------------------------------------------------
+
+class MidiPartDrag : public QDrag {
+ Q_OBJECT
+
+ public:
+ static const char type[];
+ MidiPartDrag(Part*, QWidget* src);
+ static bool canDecode(const QMimeData*);
+ static bool decode(const QMimeData* s, Part*& p);
+ };
+
+//---------------------------------------------------------
+// AudioPartDrag
+//---------------------------------------------------------
+
+class AudioPartDrag : public QDrag {
+ Q_OBJECT
+
+ public:
+ static const char type[];
+ AudioPartDrag(Part*, QWidget* src);
+ static bool canDecode(const QMimeData*);
+ static bool decode(const QMimeData* s, Part*& p);
+ };
+
+//---------------------------------------------------------
+// WavUriDrag
+//---------------------------------------------------------
+
+class WavUriDrag : public QDrag {
+ Q_OBJECT
+
+ public:
+ static const char type[];
+ WavUriDrag(const QString&, QWidget* src);
+ static bool canDecode(const QMimeData*);
+ static bool decode(const QMimeData* s, QString* p);
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/pipeline.cpp b/muse_qt4_evolution/muse/pipeline.cpp
new file mode 100644
index 00000000..ae5b9d25
--- /dev/null
+++ b/muse_qt4_evolution/muse/pipeline.cpp
@@ -0,0 +1,221 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "pipeline.h"
+#include "plugin.h"
+#include "plugingui.h"
+#include "al/dsp.h"
+
+//---------------------------------------------------------
+// Pipeline
+//---------------------------------------------------------
+
+Pipeline::Pipeline()
+ {
+ for (int i = 0; i < MAX_CHANNELS; ++i)
+ posix_memalign((void**)(buffer + i), 16, sizeof(float) * segmentSize);
+ }
+
+Pipeline::Pipeline(const Pipeline& p)
+ : QList<PluginI*>(p)
+ {
+ for (int i = 0; i < MAX_CHANNELS; ++i)
+ posix_memalign((void**)(buffer + i), 16, sizeof(float) * segmentSize);
+ }
+
+//---------------------------------------------------------
+// Pipeline
+//---------------------------------------------------------
+
+Pipeline::~Pipeline()
+ {
+ for (int i = 0; i < MAX_CHANNELS; ++i)
+ ::free(buffer[i]);
+ }
+
+//---------------------------------------------------------
+// setChannels
+//---------------------------------------------------------
+
+void Pipeline::setChannels(int n)
+ {
+ foreach(PluginI* plugin, *this)
+ plugin->setChannels(n);
+ }
+
+//---------------------------------------------------------
+// isOn
+//---------------------------------------------------------
+
+bool Pipeline::isOn(int idx) const
+ {
+ PluginI* p = value(idx);
+ if (p)
+ return p->on();
+ return false;
+ }
+
+//---------------------------------------------------------
+// setOn
+//---------------------------------------------------------
+
+void Pipeline::setOn(int idx, bool flag)
+ {
+ PluginI* p = value(idx);
+ if (p) {
+ p->setOn(flag);
+ if (p->gui())
+ p->gui()->setOn(flag);
+ }
+ }
+
+//---------------------------------------------------------
+// label
+//---------------------------------------------------------
+
+QString Pipeline::label(int idx) const
+ {
+ PluginI* p = value(idx);
+ if (p)
+ return p->label();
+ return QString("");
+ }
+
+//---------------------------------------------------------
+// name
+//---------------------------------------------------------
+
+QString Pipeline::name(int idx) const
+ {
+ PluginI* p = value(idx);
+ if (p)
+ return p->name();
+ return QString("empty");
+ }
+
+//---------------------------------------------------------
+// hasNativeGui
+//---------------------------------------------------------
+
+bool Pipeline::hasNativeGui(int idx) const
+ {
+ PluginI* p = value(idx);
+ if (p)
+ return p->hasNativeGui();
+ return false;
+ }
+
+//---------------------------------------------------------
+// move
+//---------------------------------------------------------
+
+void Pipeline::move(int idx, bool up)
+ {
+ PluginI* p1 = (*this)[idx];
+ if (up) {
+ (*this)[idx] = (*this)[idx-1];
+ (*this)[idx-1] = p1;
+ }
+ else {
+ (*this)[idx] = (*this)[idx+1];
+ (*this)[idx+1] = p1;
+ }
+ }
+
+//---------------------------------------------------------
+// showGui
+//---------------------------------------------------------
+
+void Pipeline::showGui(int idx, bool flag)
+ {
+ PluginI* p = (*this)[idx];
+ if (p)
+ p->showGui(flag);
+ }
+
+//---------------------------------------------------------
+// showNativeGui
+//---------------------------------------------------------
+
+void Pipeline::showNativeGui(int idx, bool flag)
+ {
+ PluginI* p = (*this)[idx];
+ if (p)
+ p->showNativeGui(flag);
+ }
+
+//---------------------------------------------------------
+// guiVisible
+//---------------------------------------------------------
+
+bool Pipeline::guiVisible(int idx)
+ {
+ PluginI* p = (*this)[idx];
+ if (p)
+ return p->guiVisible();
+ return false;
+ }
+
+//---------------------------------------------------------
+// nativeGuiVisible
+//---------------------------------------------------------
+
+bool Pipeline::nativeGuiVisible(int idx)
+ {
+ PluginI* p = (*this)[idx];
+ if (p)
+ return p->nativeGuiVisible();
+ return false;
+ }
+
+//---------------------------------------------------------
+// apply
+//---------------------------------------------------------
+
+void Pipeline::apply(int ports, unsigned long nframes, float** buffer1)
+ {
+ // prepare a second set of buffers in case a plugin is not
+ // capable of inPlace processing
+
+ bool swap = false;
+
+ foreach (PluginI* p, *this) {
+ if (p->on()) {
+ if (p->inPlaceCapable()) {
+ if (swap)
+ p->apply(nframes, ports, buffer, buffer);
+ else
+ p->apply(nframes, ports, buffer1, buffer1);
+ }
+ else {
+ if (swap)
+ p->apply(nframes, ports, buffer, buffer1);
+ else
+ p->apply(nframes, ports, buffer1, buffer);
+ swap = !swap;
+ }
+ }
+ }
+ if (swap) {
+ for (int i = 0; i < ports; ++i)
+ AL::dsp->cpy(buffer1[i], buffer[i], nframes);
+ }
+ }
+
diff --git a/muse_qt4_evolution/muse/pipeline.h b/muse_qt4_evolution/muse/pipeline.h
new file mode 100644
index 00000000..a6e34678
--- /dev/null
+++ b/muse_qt4_evolution/muse/pipeline.h
@@ -0,0 +1,59 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __PIPELINE_H__
+#define __PIPELINE_H__
+
+#include "globaldefs.h"
+
+class PluginI;
+
+//---------------------------------------------------------
+// Pipeline
+// chain of connected efx inserts
+//---------------------------------------------------------
+
+class Pipeline : public QList<PluginI*> {
+ float* buffer[MAX_CHANNELS];
+
+ public:
+ Pipeline();
+ ~Pipeline();
+
+ Pipeline(const Pipeline&);
+ Pipeline& operator=(const Pipeline&); // disable copies
+
+ bool isOn(int idx) const;
+ void setOn(int, bool);
+ QString label(int idx) const;
+ QString name(int idx) const;
+ bool hasNativeGui(int idx) const;
+ void showGui(int, bool);
+ bool guiVisible(int);
+ bool nativeGuiVisible(int);
+ void showNativeGui(int, bool);
+ void apply(int ports, unsigned long nframes, float** buffer);
+ void move(int idx, bool up);
+ void setChannels(int);
+ PluginI* plugin(int idx) { return value(idx); }
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/plugin.cpp b/muse_qt4_evolution/muse/plugin.cpp
new file mode 100644
index 00000000..a661b08e
--- /dev/null
+++ b/muse_qt4_evolution/muse/plugin.cpp
@@ -0,0 +1,466 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include <dlfcn.h>
+
+#include "al/al.h"
+#include "plugin.h"
+#include "ladspaplugin.h"
+#include "auxplugin.h"
+#include "plugingui.h"
+#include "al/xml.h"
+#include "fastlog.h"
+#include "ctrl.h"
+
+PluginList plugins;
+
+//---------------------------------------------------------
+// Plugin
+//---------------------------------------------------------
+
+Plugin::Plugin(const QFileInfo* f)
+ : fi(*f)
+ {
+ _instances = 0;
+ }
+
+//---------------------------------------------------------
+// loadPluginLib
+//---------------------------------------------------------
+
+static void loadPluginLib(QFileInfo* fi)
+ {
+ void* handle = dlopen(fi->filePath().toLatin1().data(), RTLD_NOW);
+ if (handle == 0) {
+ fprintf(stderr, "dlopen(%s) failed: %s\n",
+ fi->filePath().toLatin1().data(), dlerror());
+ return;
+ }
+ LADSPA_Descriptor_Function ladspa = (LADSPA_Descriptor_Function)dlsym(handle, "ladspa_descriptor");
+
+ if (!ladspa) {
+ const char *txt = dlerror();
+ if (txt) {
+ fprintf(stderr,
+ "Unable to find ladspa_descriptor() function in plugin "
+ "library file \"%s\": %s.\n"
+ "Are you sure this is a LADSPA plugin file?\n",
+ fi->filePath().toLatin1().data(),
+ txt);
+ return;
+ }
+ }
+ const LADSPA_Descriptor* descr;
+ for (int i = 0;; ++i) {
+ descr = ladspa(i);
+ if (descr == NULL)
+ break;
+ plugins.push_back(new LadspaPlugin(fi, ladspa, descr));
+ }
+ }
+
+//---------------------------------------------------------
+// loadPluginDir
+//---------------------------------------------------------
+
+static void loadPluginDir(const QString& s)
+ {
+ if (debugMsg)
+ printf("scan ladspa plugin dir <%s>\n", s.toLatin1().data());
+#ifdef __APPLE__
+ QDir pluginDir(s, QString("*.dylib"), 0, QDir::Files);
+#else
+ QDir pluginDir(s, QString("*.so"), 0, QDir::Files);
+#endif
+ if (pluginDir.exists()) {
+ QFileInfoList list = pluginDir.entryInfoList();
+ for (int i = 0; i < list.size(); ++i) {
+ QFileInfo fi = list.at(i);
+ loadPluginLib(&fi);
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// initPlugins
+// search for LADSPA plugins
+//---------------------------------------------------------
+
+void initPlugins()
+ {
+ loadPluginDir(museGlobalLib + QString("/plugins"));
+
+ const char* ladspaPath = getenv("LADSPA_PATH");
+ if (ladspaPath == 0)
+ ladspaPath = "/usr/lib/ladspa:/usr/local/lib/ladspa";
+
+ const char* p = ladspaPath;
+ while (*p != '\0') {
+ const char* pe = p;
+ while (*pe != ':' && *pe != '\0')
+ pe++;
+
+ int n = pe - p;
+ if (n) {
+ char* buffer = new char[n + 1];
+ strncpy(buffer, p, n);
+ buffer[n] = '\0';
+ loadPluginDir(QString(buffer));
+ delete[] buffer;
+ }
+ p = pe;
+ if (*p == ':')
+ p++;
+ }
+ auxPlugin = new AuxPlugin;
+ }
+
+//---------------------------------------------------------
+// find
+//---------------------------------------------------------
+
+Plugin* PluginList::find(const QString& file, const QString& name)
+ {
+ for (iPlugin i = begin(); i != end(); ++i) {
+ if ((file == (*i)->lib()) && (name == (*i)->label()))
+ return *i;
+ }
+ printf("MusE: Plugin <%s> not found\n", name.toAscii().data());
+ return 0;
+ }
+
+//---------------------------------------------------------
+// PluginI
+//---------------------------------------------------------
+
+PluginI::PluginI(AudioTrack* t)
+ {
+ _track = t;
+ _plugin = 0;
+ instances = 0;
+ _gui = 0;
+ _on = true;
+ pif = 0;
+ initControlValues = false;
+ }
+
+//---------------------------------------------------------
+// PluginI
+//---------------------------------------------------------
+
+PluginI::~PluginI()
+ {
+ if (_plugin) {
+ deactivate();
+ _plugin->incInstances(-1);
+ }
+ if (_gui)
+ delete _gui;
+ if (pif) {
+ for (int i = 0; i < instances; ++i) {
+ delete pif[i];
+ }
+ delete[] pif;
+ }
+ }
+
+//---------------------------------------------------------
+// apply
+//---------------------------------------------------------
+
+void PluginI::apply(unsigned nframes, int ports, float** src, float** dst)
+ {
+ int oports = _plugin->outports();
+ int iports = _plugin->inports();
+
+ float* sp[iports * instances];
+ float* dp[oports * instances];
+
+ for (int i = 0; i < iports * instances; ++i)
+ sp[i] = src[i % ports];
+ for (int i = 0; i < oports * instances; ++i)
+ dp[i] = dst[i % ports];
+
+ float** spp = sp;
+ float** dpp = dp;
+ for (int i = 0; i < instances; ++i) {
+ pif[i]->apply(nframes, spp, dpp);
+ spp += iports;
+ dpp += oports;
+ }
+ }
+
+//---------------------------------------------------------
+// setChannel
+//---------------------------------------------------------
+
+void PluginI::setChannels(int c)
+ {
+ if (_channel == c)
+ return;
+ int ni = c / _plugin->outports();
+ if (ni == 0)
+ ni = 1;
+ _channel = c;
+ if (ni == instances)
+ return;
+ _channel = c;
+
+ // remove old instances:
+ deactivate();
+ for (int i = 0; i < instances; ++i)
+ delete pif[i];
+ delete pif;
+
+ instances = ni;
+ pif = new PluginIF*[instances];
+ for (int i = 0; i < instances; ++i) {
+ pif[i] = _plugin->createPIF(this);
+ if (pif[i] == 0)
+ return;
+ }
+ activate();
+ }
+
+//---------------------------------------------------------
+// initPluginInstance
+// return true on error
+//---------------------------------------------------------
+
+bool PluginI::initPluginInstance(Plugin* plug, int c)
+ {
+ if (plug == 0) {
+ printf("initPluginInstance: zero plugin\n");
+ return true;
+ }
+ _channel = c;
+ _plugin = plug;
+ _plugin->incInstances(1);
+ QString inst("-" + QString::number(_plugin->instances()));
+ _name = _plugin->name() + inst;
+ _label = _plugin->label() + inst;
+
+ instances = _channel / plug->outports();
+ if (instances < 1)
+ instances = 1;
+ pif = new PluginIF*[instances];
+ for (int i = 0; i < instances; ++i) {
+ pif[i] = _plugin->createPIF(this);
+ if (pif[i] == 0)
+ return true;
+ }
+ activate();
+ return false;
+ }
+
+//---------------------------------------------------------
+// setParameter
+// set plugin instance controller value by name
+// return true on error
+//---------------------------------------------------------
+
+bool PluginI::setParameter(const QString& s, double val)
+ {
+ if (_plugin == 0)
+ return true;
+ int n = _plugin->parameter();
+ for (int i = 0; i < n; ++i) {
+ if (getParameterName(i) == s) {
+ setParam(i, val);
+ return false;
+ }
+ }
+ printf("PluginI:setControl(%s, %f) controller not found\n",
+ s.toLatin1().data(), val);
+ return true;
+ }
+
+//---------------------------------------------------------
+// saveConfiguration
+//---------------------------------------------------------
+
+void PluginI::writeConfiguration(Xml& xml, bool prefader)
+ {
+ writeConfiguration1(xml, prefader);
+ xml.etag("plugin"); // append endtag
+ }
+
+//---------------------------------------------------------
+// saveConfiguration
+//---------------------------------------------------------
+
+void PluginI::writeConfiguration1(Xml& xml, bool prefader)
+ {
+ xml.stag(QString("plugin pre=\"%1\" file=\"%2\" label=\"%3\" channel=\"%4\"")
+ .arg(prefader)
+ .arg(_plugin->lib())
+ .arg(_plugin->label())
+ .arg(_channel));
+// instances * _plugin->inports());
+ if (_on == false)
+ xml.tag("on", _on);
+ if (guiVisible()) {
+ xml.tag("gui", 1);
+ xml.tag("geometry", _gui);
+ }
+ if (hasNativeGui() && nativeGuiVisible())
+ xml.tag("nativeGui", 1);
+ }
+
+//---------------------------------------------------------
+// readConfiguration
+// return true on error
+//---------------------------------------------------------
+
+bool PluginI::readConfiguration(QDomNode node, bool* prefader)
+ {
+ QDomElement e = node.toElement();
+ QString file = e.attribute("file");
+ QString label = e.attribute("label");
+ _channel = e.attribute("channel").toInt();
+ *prefader = e.attribute("pre", "1").toInt();
+
+ if (_plugin == 0) {
+ // special case: internal plugin Aux
+ if (file.isEmpty() && label == "Aux")
+ _plugin = auxPlugin;
+ else
+ _plugin = plugins.find(file, label);
+ if (_plugin == 0)
+ return true;
+ if (initPluginInstance(_plugin, _channel))
+ return true;
+ }
+ node = node.firstChild();
+ while (!node.isNull()) {
+ e = node.toElement();
+ int i = e.text().toInt();
+ QString tag(e.tagName());
+ if (tag == "on") {
+ bool flag = i;
+ _on = flag;
+ }
+ else if (tag == "gui") {
+ bool flag = i;
+ showGui(flag);
+ }
+ else if (tag == "nativeGui") {
+ bool flag = i;
+ showNativeGui(flag);
+ }
+ else if (tag == "geometry") {
+ QRect r(AL::readGeometry(node));
+ if (_gui) {
+ _gui->resize(r.size());
+ _gui->move(r.topLeft());
+ }
+ }
+ else
+ printf("MusE:PluginI: unknown tag %s\n", e.tagName().toLatin1().data());
+ node = node.nextSibling();
+ }
+ if (_gui)
+ _gui->updateValues();
+ return false;
+ }
+
+//---------------------------------------------------------
+// showGui
+//---------------------------------------------------------
+
+void PluginI::showGui()
+ {
+ if (_plugin) {
+ if (_gui == 0)
+ makeGui();
+ if (_gui->isVisible())
+ _gui->hide();
+ else
+ _gui->show();
+ }
+ }
+
+void PluginI::showGui(bool flag)
+ {
+ if (_plugin) {
+ if (flag) {
+ if (_gui == 0)
+ makeGui();
+ _gui->show();
+ }
+ else {
+ if (_gui)
+ _gui->hide();
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// guiVisible
+//---------------------------------------------------------
+
+bool PluginI::guiVisible() const
+ {
+ return _gui && _gui->isVisible();
+ }
+
+//---------------------------------------------------------
+// makeGui
+//---------------------------------------------------------
+
+void PluginI::makeGui()
+ {
+ _gui = new PluginGui(this);
+ }
+
+//---------------------------------------------------------
+// deactivate
+//---------------------------------------------------------
+
+void PluginI::deactivate()
+ {
+ for (int i = 0; i < instances; ++i) {
+ pif[i]->deactivate();
+ pif[i]->cleanup();
+ }
+ }
+
+//---------------------------------------------------------
+// setParam
+//---------------------------------------------------------
+
+void PluginI::setParam(int idx, double val)
+ {
+ if (_gui)
+ _gui->updateValue(idx, val);
+ for (int i = 0; i < instances; ++i)
+ pif[i]->setParam(idx, val);
+ }
+
+//---------------------------------------------------------
+// activate
+//---------------------------------------------------------
+
+void PluginI::activate()
+ {
+ for (int i = 0; i < instances; ++i)
+ pif[i]->activate();
+ }
+
diff --git a/muse_qt4_evolution/muse/plugin.h b/muse_qt4_evolution/muse/plugin.h
new file mode 100644
index 00000000..c01a1f18
--- /dev/null
+++ b/muse_qt4_evolution/muse/plugin.h
@@ -0,0 +1,218 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __PLUGIN_H__
+#define __PLUGIN_H__
+
+#include "ladspa.h"
+#include "globals.h"
+
+namespace AL {
+ class Xml;
+ };
+using AL::Xml;
+
+class PluginIF;
+class PluginGui;
+class PluginI;
+class LadspaPluginIF;
+class AudioTrack;
+class Ctrl;
+
+#define AUDIO_IN (LADSPA_PORT_AUDIO | LADSPA_PORT_INPUT)
+#define AUDIO_OUT (LADSPA_PORT_AUDIO | LADSPA_PORT_OUTPUT)
+
+//---------------------------------------------------------
+// Plugin
+//---------------------------------------------------------
+
+class Plugin {
+
+ protected:
+ int _instances;
+ QFileInfo fi;
+
+ public:
+ Plugin(const QFileInfo* f);
+ virtual ~Plugin() {}
+
+ int instances() const { return _instances; }
+ virtual void incInstances(int val) { _instances += val; }
+
+ QString lib() const { return fi.baseName(); }
+ QString path() const { return fi.absolutePath(); }
+
+ virtual QString label() const { return QString(); }
+ virtual QString name() const { return QString(); }
+ virtual unsigned long id() const { return 0; }
+ virtual QString maker() const { return QString(); }
+ virtual QString copyright() const { return QString(); }
+
+ virtual PluginIF* createPIF(PluginI*) = 0;
+
+ virtual void range(int, double* min, double* max) const {
+ *min = 0.0f;
+ *max = 1.0f;
+ }
+
+ virtual int parameter() const { return 0; }
+ virtual int inports() const { return 0; }
+ virtual int outports() const { return 0; }
+
+ virtual bool inPlaceCapable() const { return false; }
+
+ virtual bool isLog(int) const { return false; }
+ virtual bool isBool(int) const { return false; }
+ virtual bool isInt(int) const { return false; }
+ virtual double defaultValue(int) const { return 0.0f; }
+ };
+
+//---------------------------------------------------------
+// PluginList
+//---------------------------------------------------------
+
+typedef std::list<Plugin*>::iterator iPlugin;
+
+class PluginList : public std::list<Plugin*> {
+ public:
+ Plugin* find(const QString&, const QString&);
+ PluginList() {}
+ };
+
+//---------------------------------------------------------
+// PluginIF
+// plugin instance interface
+//---------------------------------------------------------
+
+class PluginIF {
+ protected:
+ PluginI* pluginI;
+
+ public:
+ PluginIF(PluginI* pi) { pluginI = pi; }
+ virtual ~PluginIF() {}
+
+ PluginI* pluginInstance() { return pluginI; }
+ const PluginI* pluginInstance() const { return pluginI; }
+
+ virtual void apply(unsigned nframes, float** src, float** dst) = 0;
+ virtual void activate() = 0;
+ virtual void deactivate() = 0;
+ virtual void cleanup() = 0;
+ virtual void setParam(int i, double val) = 0;
+ virtual float param(int i) const = 0;
+ virtual const char* getParameterName(int) const { return ""; }
+ virtual const char* getParameterLabel(int) const { return 0; }
+ virtual const char* getParameterDisplay(int, float) const { return 0; }
+ virtual bool hasGui() const { return false; }
+ virtual bool guiVisible() const { return false; }
+ virtual void showGui(bool) {}
+ };
+
+//---------------------------------------------------------
+// PluginI
+// plugin instance
+//---------------------------------------------------------
+
+class PluginI {
+ Plugin* _plugin;
+ AudioTrack* _track;
+
+ int instances;
+ PluginIF** pif;
+
+ int _channel;
+
+ PluginGui* _gui;
+ bool _on;
+
+ QString _name;
+ QString _label;
+
+ std::vector<Ctrl*> controllerList;
+
+ void makeGui();
+
+ protected:
+ bool initControlValues;
+ friend class LadspaPluginIF;
+
+ public:
+ PluginI(AudioTrack*);
+ ~PluginI();
+
+ Plugin* plugin() const { return _plugin; }
+ bool on() const { return _on; }
+ void setOn(bool val) { _on = val; }
+ PluginGui* gui() const { return _gui; }
+
+ bool initPluginInstance(Plugin*, int channels);
+ void setChannels(int);
+ int channel() const { return _channel; }
+ void apply(unsigned nframes, int ports, float** b1, float** b2);
+
+ void activate();
+ void deactivate();
+ QString label() const { return _label; }
+ QString name() const { return _name; }
+ QString lib() const { return _plugin->lib(); }
+
+ AudioTrack* track() const { return _track; }
+
+ void writeConfiguration(Xml&, bool);
+ void writeConfiguration1(Xml&, bool); // without end tag!
+ bool readConfiguration(QDomNode, bool*);
+
+ void showGui();
+ void showGui(bool);
+ bool guiVisible() const;
+
+ bool hasNativeGui() const { return pif[0]->hasGui(); }
+ void showNativeGui(bool f) { return pif[0]->showGui(f); }
+ bool nativeGuiVisible() const { return pif[0]->guiVisible(); }
+
+ void setControllerList(Ctrl* cl) { controllerList.push_back(cl); }
+ Ctrl* controller(int idx) const { return controllerList[idx]; }
+ bool setParameter(const QString& s, double val);
+ void setParam(int i, double val);
+ double param(int i) const { return pif[0]->param(i); }
+
+ const char* getParameterName(int i) const { return pif[0]->getParameterName(i); }
+ const char* getParameterLabel(int i) const { return pif[0]->getParameterLabel(i); }
+ const char* getParameterDisplay(int i, float v) const { return pif[0]->getParameterDisplay(i, v); }
+
+ void range(int i, double* min, double* max) const {
+ _plugin->range(i, min, max);
+ }
+ double defaultValue(int i) const { return _plugin->defaultValue(i); }
+ bool inPlaceCapable() const { return _plugin->inPlaceCapable(); }
+
+ bool isLog(int k) const { return _plugin->isLog(k); }
+ bool isBool(int k) const { return _plugin->isBool(k); }
+ bool isInt(int k) const { return _plugin->isInt(k); }
+
+ PluginIF* pluginIF(int idx) { return pif[idx]; }
+ };
+
+extern void initPlugins();
+extern PluginList plugins;
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/plugingui.cpp b/muse_qt4_evolution/muse/plugingui.cpp
new file mode 100644
index 00000000..9f0d1d32
--- /dev/null
+++ b/muse_qt4_evolution/muse/plugingui.cpp
@@ -0,0 +1,770 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "song.h"
+#include "fastlog.h"
+#include "widgets/filedialog.h"
+#include "plugin.h"
+#include "plugingui.h"
+#include "icons.h"
+#include "al/xml.h"
+#include "gui.h"
+
+#include "awl/floatentry.h"
+#include "awl/slider.h"
+#include "awl/checkbox.h"
+#include "awl/combobox.h"
+
+using Awl::FloatEntry;
+using Awl::Slider;
+using Awl::CheckBox;
+using Awl::ComboBox;
+
+static const char* preset_file_pattern[] = {
+ QT_TR_NOOP("presets (*.pre *.pre.gz *.pre.bz2)"),
+ QT_TR_NOOP("All Files (*)"),
+ 0
+ };
+
+int PluginDialog::selectedPlugType = SEL_SM;
+QStringList PluginDialog::sortItems = QStringList();
+
+//---------------------------------------------------------
+// PluginDialog
+// select Plugin dialog
+//---------------------------------------------------------
+
+PluginDialog::PluginDialog(QWidget* parent)
+ : QDialog(parent)
+ {
+ setWindowTitle(tr("MusE: select plugin"));
+ QVBoxLayout* layout = new QVBoxLayout(this);
+
+ pList = new QTreeWidget(this);
+ pList->setColumnCount(11);
+ pList->setSortingEnabled(true);
+ QStringList headerLabels;
+ headerLabels << tr("Lib");
+ headerLabels << tr("Label");
+ headerLabels << tr("Name");
+ headerLabels << tr("AI");
+ headerLabels << tr("AO");
+ headerLabels << tr("CI");
+ headerLabels << tr("CO");
+ headerLabels << tr("IP");
+ headerLabels << tr("id");
+ headerLabels << tr("Maker");
+ headerLabels << tr("Copyright");
+
+ int sizes[] = { 110, 110, 0, 30, 30, 30, 30, 30, 40, 110, 110 };
+ for (int i = 0; i < 11; ++i) {
+ if (sizes[i] == 0) {
+ pList->header()->setResizeMode(i, QHeaderView::Stretch);
+ }
+ else {
+ if (sizes[i] <= 40) // hack alert!
+ pList->header()->setResizeMode(i, QHeaderView::Custom);
+ pList->header()->resizeSection(i, sizes[i]);
+ }
+ }
+
+ pList->setHeaderLabels(headerLabels);
+
+ pList->setSelectionBehavior(QAbstractItemView::SelectRows);
+ pList->setSelectionMode(QAbstractItemView::SingleSelection);
+ pList->setAlternatingRowColors(true);
+
+ fillPlugs(selectedPlugType);
+ layout->addWidget(pList);
+
+ //---------------------------------------------------
+ // Ok/Cancel Buttons
+ //---------------------------------------------------
+
+ QBoxLayout* w5 = new QHBoxLayout;
+ layout->addLayout(w5);
+
+ QPushButton* okB = new QPushButton(tr("Ok"), this);
+ okB->setDefault(true);
+ QPushButton* cancelB = new QPushButton(tr("Cancel"), this);
+ okB->setFixedWidth(80);
+ cancelB->setFixedWidth(80);
+ w5->addWidget(okB);
+ w5->addSpacing(12);
+ w5->addWidget(cancelB);
+
+ QGroupBox* plugSelGroup = new QGroupBox;
+ plugSelGroup->setTitle("Show plugs:");
+ QHBoxLayout* psl = new QHBoxLayout;
+ plugSelGroup->setLayout(psl);
+
+ QButtonGroup* plugSel = new QButtonGroup(plugSelGroup);
+ onlySM = new QRadioButton;
+ onlySM->setText(tr("Mono and Stereo"));
+ onlySM->setCheckable(true);
+ plugSel->addButton(onlySM);
+ psl->addWidget(onlySM);
+ onlyS = new QRadioButton;
+ onlyS->setText(tr("Stereo"));
+ onlyS->setCheckable(true);
+ plugSel->addButton(onlyS);
+ psl->addWidget(onlyS);
+ onlyM = new QRadioButton;
+ onlyM->setText(tr("Mono"));
+ onlyM->setCheckable(true);
+ plugSel->addButton(onlyM);
+ psl->addWidget(onlyM);
+ allPlug = new QRadioButton;
+ allPlug->setText(tr("Show All"));
+ allPlug->setCheckable(true);
+ plugSel->addButton(allPlug);
+ psl->addWidget(allPlug);
+ plugSel->setExclusive(true);
+
+ switch(selectedPlugType) {
+ case SEL_SM: onlySM->setChecked(true); break;
+ case SEL_S: onlyS->setChecked(true); break;
+ case SEL_M: onlyM->setChecked(true); break;
+ case SEL_ALL: allPlug->setChecked(true); break;
+ }
+
+ plugSelGroup->setToolTip(tr("Select which types of plugins should be visible in the list.<br>"
+ "Note that using mono plugins on stereo tracks is not a problem, two will be used in parallell.<br>"
+ "Also beware that the 'all' alternative includes plugins that probably not are usable by MusE."));
+
+ w5->addSpacing(12);
+ w5->addWidget(plugSelGroup);
+ w5->addSpacing(12);
+
+ QLabel *sortLabel = new QLabel;
+ sortLabel->setText(tr("Search in 'Label' and 'Name':"));
+ w5->addWidget(sortLabel);
+ w5->addSpacing(2);
+
+ sortBox = new QComboBox(this);
+ sortBox->setEditable(true);
+ if (!sortItems.empty())
+ sortBox->addItems(sortItems);
+
+ sortBox->setMinimumSize(100, 10);
+ w5->addWidget(sortBox);
+ w5->addStretch(-1);
+
+ if (!sortBox->currentText().isEmpty())
+ fillPlugs(sortBox->currentText());
+ else
+ fillPlugs(selectedPlugType);
+
+
+ connect(pList, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), SLOT(accept()));
+ connect(cancelB, SIGNAL(clicked()), SLOT(reject()));
+ connect(okB, SIGNAL(clicked()), SLOT(accept()));
+ connect(plugSel, SIGNAL(buttonClicked(QAbstractButton*)), SLOT(fillPlugs(QAbstractButton*)));
+ connect(sortBox, SIGNAL(editTextChanged(const QString&)),SLOT(fillPlugs(const QString&)));
+ }
+
+//---------------------------------------------------------
+// accept
+//---------------------------------------------------------
+
+void PluginDialog::accept()
+ {
+ if (!sortBox->currentText().isEmpty()) {
+ foreach (QString item, sortItems)
+ if(item == sortBox->currentText()) {
+ QDialog::accept();
+ return;
+ }
+ sortItems.push_front(sortBox->currentText());
+ }
+ QDialog::accept();
+ }
+
+//---------------------------------------------------------
+// value
+//---------------------------------------------------------
+
+Plugin* PluginDialog::value()
+ {
+ QTreeWidgetItem* item = pList->selectedItems().at(0);
+ if (item)
+ return plugins.find(item->text(0), item->text(1));
+printf("plugin not found\n");
+ return 0;
+ }
+
+//---------------------------------------------------------
+// fillPlugs
+//---------------------------------------------------------
+
+void PluginDialog::fillPlugs(QAbstractButton* ab)
+ {
+ if (ab == allPlug)
+ fillPlugs(SEL_ALL);
+ else if (ab == onlyM)
+ fillPlugs(SEL_M);
+ else if (ab == onlyS)
+ fillPlugs(SEL_S);
+ else if (ab == onlySM)
+ fillPlugs(SEL_SM);
+ }
+
+//---------------------------------------------------------
+// fillPlugs int
+//---------------------------------------------------------
+
+void PluginDialog::fillPlugs(int nbr)
+ {
+ pList->clear();
+ for (iPlugin i = plugins.begin(); i != plugins.end(); ++i) {
+ int ai = (*i)->inports();
+ int ao = (*i)->outports();
+ int ci = (*i)->parameter();
+ int co = 0;
+ bool addFlag = false;
+ switch (nbr) {
+ case SEL_SM: // stereo & mono
+ if ((ai == 1 || ai == 2) && (ao == 1 || ao ==2)) {
+ addFlag = true;
+ }
+ break;
+ case SEL_S: // stereo
+ if ((ai == 1 || ai == 2) && ao ==2) {
+ addFlag = true;
+ }
+ break;
+ case SEL_M: // mono
+ if (ai == 1 && ao == 1) {
+ addFlag = true;
+ }
+ break;
+ case SEL_ALL: // all
+ addFlag = true;
+ break;
+ }
+ if (addFlag) {
+ QTreeWidgetItem* item = new QTreeWidgetItem;
+ item->setText(0, (*i)->lib());
+ item->setText(1, (*i)->label());
+ item->setText(2, (*i)->name());
+ item->setText(3, QString().setNum(ai));
+ item->setText(4, QString().setNum(ao));
+ item->setText(5, QString().setNum(ci));
+ item->setText(6, QString().setNum(co));
+ item->setText(7, QString().setNum((*i)->inPlaceCapable()));
+ item->setText(8, QString().setNum((*i)->id()));
+ item->setText(9, (*i)->maker());
+ item->setText(10, (*i)->copyright());
+ pList->addTopLevelItem(item);
+ }
+ }
+ selectedPlugType = nbr;
+ }
+
+//---------------------------------------------------------
+// fillPlugs QString
+//---------------------------------------------------------
+
+void PluginDialog::fillPlugs(const QString &sortValue)
+ {
+ pList->clear();
+ for (iPlugin i = plugins.begin(); i != plugins.end(); ++i) {
+ int ai = (*i)->inports();
+ int ao = (*i)->outports();
+ int ci = (*i)->parameter();
+ int co = 0;
+
+ bool addFlag = false;
+
+ if ((*i)->label().toLower().contains(sortValue.toLower()))
+ addFlag = true;
+ else if ((*i)->name().toLower().contains(sortValue.toLower()))
+ addFlag = true;
+ if (addFlag) {
+ QTreeWidgetItem* item = new QTreeWidgetItem;
+ item->setText(0, (*i)->lib());
+ item->setText(1, (*i)->label());
+ item->setText(2, (*i)->name());
+ item->setText(3, QString().setNum(ai));
+ item->setText(4, QString().setNum(ao));
+ item->setText(5, QString().setNum(ci));
+ item->setText(6, QString().setNum(co));
+ item->setText(7, QString().setNum((*i)->inPlaceCapable()));
+ item->setText(8, QString().setNum((*i)->id()));
+ item->setText(9, (*i)->maker());
+ item->setText(10, (*i)->copyright());
+ pList->addTopLevelItem(item);
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// getPlugin
+//---------------------------------------------------------
+
+Plugin* PluginDialog::getPlugin(QWidget* parent)
+ {
+ PluginDialog* dialog = new PluginDialog(parent);
+ if (dialog->exec())
+ return dialog->value();
+ return 0;
+ }
+
+static const char* presetOpenText = "<img source=\"fileopen\"> "
+ "Click this button to load a saved <em>preset</em>.";
+static const char* presetSaveText = "Click this button to save curent parameter "
+ "settings as a <em>preset</em>. You will be prompted for a file name.";
+static const char* presetBypassText = "Click this button to bypass effect unit";
+
+//---------------------------------------------------------
+// PluginGui
+//---------------------------------------------------------
+
+PluginGui::PluginGui(PluginI* p)
+ : QMainWindow(0)
+ {
+ setIconSize(ICON_SIZE);
+ plugin = p;
+ setWindowTitle(plugin->name());
+
+ QToolBar* tools = addToolBar(tr("File Buttons"));
+
+ QAction* fileOpen = tools->addAction(QIcon(*openIcon), tr("Load Preset"),
+ this, SLOT(load()));
+ fileOpen->setWhatsThis(tr(presetOpenText));
+ QAction* fileSave = tools->addAction(QIcon(*saveIcon), tr("Save Preset"),
+ this, SLOT(save()));
+ fileSave->setWhatsThis(tr(presetSaveText));
+
+ tools->addAction(QWhatsThis::createAction(this));
+
+ onOff = tools->addAction(*onOffIcon, tr("bypass plugin"));
+ onOff->setCheckable(true);
+ onOff->setChecked(plugin->on());
+ onOff->setWhatsThis(tr(presetBypassText));
+ connect(onOff, SIGNAL(triggered(bool)), SLOT(bypassToggled(bool)));
+
+ QString id;
+ id.setNum(plugin->plugin()->id());
+ QString name(museGlobalShare + QString("/plugins/") + id + QString(".ui"));
+
+ QWidget* mw; // main widget
+ QFile uifile(name);
+ if (uifile.exists()) {
+ //
+ // construct GUI from *.ui file
+ //
+ QFormBuilder builder;
+ //
+ // HACK:
+ //
+ QString path(museGlobalLib + "/designer");
+printf("build gui from ui <path><%s>\n", path.toLatin1().data());
+ builder.addPluginPath(path);
+
+ uifile.open(QFile::ReadOnly);
+ mw = builder.load(&uifile, this);
+ uifile.close();
+
+ setCentralWidget(mw);
+ connectPrebuiltGui(mw);
+ }
+ else {
+ mw = new QWidget(this);
+ setCentralWidget(mw);
+ QGridLayout* grid = new QGridLayout;
+ mw->setLayout(grid);
+ grid->setSpacing(2);
+
+ int n = plugin->plugin()->parameter();
+ resize(280, n*20+30);
+
+ QFontMetrics fm = fontMetrics();
+ int h = fm.height() + 4;
+
+ for (int i = 0; i < n; ++i) {
+ double lower;
+ double upper;
+ double dlower;
+ double dupper;
+ double val = plugin->param(i);
+ double dval = val;
+
+ plugin->range(i, &lower, &upper);
+ dlower = lower;
+ dupper = upper;
+
+ if (plugin->isLog(i)) {
+ if (lower == 0.0)
+ lower = 0.001;
+ dlower = fast_log10(lower)*20.0;
+ dupper = fast_log10(upper)*20.0;
+ if (val == 0.0f)
+ dval = dlower;
+ else
+ dval = fast_log10(val) * 20.0;
+ }
+ if (plugin->isBool(i)) {
+ CheckBox* cb = new CheckBox(mw);
+ cb->setId(i);
+ cb->setText(QString(plugin->getParameterName(i)));
+ cb->setChecked(plugin->param(i) > 0.0);
+ cb->setFixedHeight(h);
+ cb->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Maximum));
+
+ GuiWidget w;
+ w.widget = cb;
+ w.parameter = i;
+ w.type = GuiWidget::CHECKBOX;
+ gw.push_back(w);
+ grid->addWidget(cb, i, 0, 1, 3);
+ connect(cb, SIGNAL(valueChanged(double,int)), SLOT(setController(double, int)));
+ }
+ else {
+ QLabel* label = new QLabel(QString(plugin->getParameterName(i)), mw);
+ label->setFixedHeight(20);
+ label->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Maximum));
+ FloatEntry* e = new FloatEntry(mw);
+ e->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Maximum));
+ e->setRange(lower, upper);
+ e->setId(i);
+ e->setFixedHeight(h);
+ e->setFrame(true);
+ GuiWidget w;
+ w.widget = e;
+ w.parameter = i;
+ w.type = GuiWidget::FLOAT_ENTRY;
+ gw.push_back(w);
+
+ Slider* s = new Slider(mw);
+ s->setId(i);
+ s->setLog(plugin->isLog(i));
+ s->setOrientation(Qt::Horizontal);
+ s->setFixedHeight(h);
+ s->setRange(dlower, dupper);
+ s->setLineStep((dupper-dlower)/100.0);
+ s->setPageStep((dupper-dlower)/10.0);
+ s->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Maximum));
+ w.widget = s;
+ w.parameter = i;
+ w.type = GuiWidget::SLIDER;
+ gw.push_back(w);
+ grid->addWidget(label, i, 0);
+ grid->addWidget(e, i, 1);
+ const char* p = plugin->getParameterLabel(i);
+ if (p) {
+ QLabel* l = new QLabel(mw);
+ l->setFixedHeight(h);
+ l->setText(p);
+ grid->addWidget(l, i, 2);
+ }
+ grid->addWidget(s, i, 3);
+ connect(s, SIGNAL(valueChanged(double,int)), SLOT(setController(double,int)));
+ connect(e, SIGNAL(valueChanged(double,int)), SLOT(setController(double,int)));
+ }
+ updateValue(i, val);
+ }
+ grid->setColumnStretch(3, 10);
+ }
+ connect(plugin->track(), SIGNAL(autoReadChanged(bool)), SLOT(autoChanged()));
+ connect(plugin->track(), SIGNAL(autoWriteChanged(bool)), SLOT(autoChanged()));
+ connect(plugin->track(), SIGNAL(controllerChanged(int)), SLOT(controllerChanged(int)));
+ autoChanged();
+ }
+
+
+
+void PluginGui::connectPrebuiltGui(QWidget* wContainer)
+ {
+ QObjectList l = wContainer->children();
+ for (int i = 0; i < l.size(); ++i) {
+
+ QObject* obj = l.at(i);
+
+ const char* name = obj->objectName().toLatin1().data();
+
+ if (strcmp(obj->metaObject()->className(), "QFrame") == 0) {
+ connectPrebuiltGui((QWidget *)obj);
+ }
+ if (*name !='P')
+ continue;
+ GuiWidget w;
+ w.widget = (QWidget*)obj;
+ if (strcmp(obj->metaObject()->className(), "Awl::Slider") == 0) {
+ connect((Slider*)obj, SIGNAL(valueChanged(double,int)), SLOT(setController(double,int)));
+ w.type = GuiWidget::SLIDER;
+ w.parameter = ((Slider*)obj)->id();
+ }
+ else if (strcmp(obj->metaObject()->className(), "Awl::FloatEntry") == 0) {
+ connect((FloatEntry*)obj, SIGNAL(valueChanged(double,int)), SLOT(setController(double,int)));
+ w.type = GuiWidget::FLOAT_ENTRY;
+ w.parameter = ((FloatEntry*)obj)->id();
+ }
+ else if (strcmp(obj->metaObject()->className(), "Awl::CheckBox") == 0) {
+ w.type = GuiWidget::CHECKBOX;
+ w.parameter = ((CheckBox*)obj)->id();
+ connect(obj, SIGNAL(valueChanged(double, int)), SLOT(setController(double, int)));
+ }
+ else if (strcmp(obj->metaObject()->className(), "Awl::ComboBox") == 0) {
+ w.type = GuiWidget::COMBOBOX;
+ w.parameter = ((ComboBox*)obj)->id();
+ connect(obj, SIGNAL(valueChanged(double, int)), SLOT(setController(double,int)));
+ }
+ else {
+ printf("PluginGui::unknown widget class %s\n", obj->metaObject()->className());
+ continue;
+ }
+ gw.push_back(w);
+ }
+}
+
+
+//---------------------------------------------------------
+// PluginGui
+//---------------------------------------------------------
+
+PluginGui::~PluginGui()
+ {
+ }
+
+//---------------------------------------------------------
+// setController
+//---------------------------------------------------------
+
+void PluginGui::setController(double val, int param)
+ {
+ if (plugin->isInt(param))
+ val = rint(val);
+ CVal cval;
+ cval.f = val;
+ song->setControllerVal(plugin->track(), plugin->controller(param), cval);
+ }
+
+//---------------------------------------------------------
+// load
+//---------------------------------------------------------
+
+void PluginGui::load()
+ {
+ QString s("presets/plugins/");
+ s += plugin->plugin()->label();
+ s += "/";
+
+ QStringList pattern;
+ const char** p = preset_file_pattern;
+ while (*p)
+ pattern << *p++;
+ QString fn = getOpenFileName(s, pattern, this, tr("MusE: load preset"));
+ if (fn.isEmpty())
+ return;
+ QFile* qf = fileOpen(this, fn, QString(".pre"), QIODevice::ReadOnly, true);
+ if (qf == 0)
+ return;
+
+ 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 + "\n at line: " + ln + " col: " + col;
+ printf("error reading med file: %s\n", error.toLatin1().data());
+ delete qf;
+ 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"));
+ node = node.firstChild();
+ while (!node.isNull()) {
+ QDomElement e = node.toElement();
+ bool prefader;
+ if (e.tagName() == "plugin")
+ plugin->readConfiguration(node.firstChild(), &prefader);
+ else
+ printf("MusE:PluginGui: unknown tag %s\n", e.tagName().toLatin1().data());
+ node = node.nextSibling();
+ }
+ }
+ else
+ printf("MusE: %s not supported\n", e.tagName().toLatin1().data());
+ node = node.nextSibling();
+ }
+ qf->close();
+ delete qf;
+ }
+
+//---------------------------------------------------------
+// save
+//---------------------------------------------------------
+
+void PluginGui::save()
+ {
+ QString s("presets/plugins/");
+ s += plugin->plugin()->label();
+ s += "/";
+
+ QStringList pattern;
+ const char** p = preset_file_pattern;
+ while (*p)
+ pattern << *p++;
+ QString fn = getSaveFileName(s, pattern, this,
+ tr("MusE: save preset"));
+ if (fn.isEmpty())
+ return;
+ QFile* f = fileOpen(this, fn, QString(".pre"), QIODevice::WriteOnly, true);
+ if (f == 0)
+ return;
+ Xml xml(f);
+ xml.header();
+ xml.stag("muse version=\"1.0\"");
+ plugin->writeConfiguration(xml, true);
+ xml.etag("muse");
+ f->close();
+ delete f;
+ }
+
+//---------------------------------------------------------
+// bypassToggled
+//---------------------------------------------------------
+
+void PluginGui::bypassToggled(bool val)
+ {
+ plugin->setOn(val);
+ song->update(SC_ROUTE);
+ }
+
+//---------------------------------------------------------
+// setOn
+//---------------------------------------------------------
+
+void PluginGui::setOn(bool val)
+ {
+// onOff->blockSignals(true);
+ onOff->setChecked(val);
+// onOff->blockSignals(false);
+ }
+
+//---------------------------------------------------------
+// updateValue
+//---------------------------------------------------------
+
+void PluginGui::updateValue(int parameter, double value)
+ {
+ for (std::vector<GuiWidget>::iterator i = gw.begin(); i != gw.end(); ++i) {
+ int idx = i->parameter;
+ if (idx != parameter)
+ continue;
+ switch (i->type) {
+ case GuiWidget::SLIDER:
+ ((Slider*)(i->widget))->setValue(value);
+ break;
+ case GuiWidget::FLOAT_ENTRY:
+ {
+ const char* p = plugin->getParameterDisplay(idx, value);
+ if (p)
+ ((FloatEntry*)(i->widget))->setText(QString(p));
+ else
+ ((FloatEntry*)(i->widget))->setValue(value);
+ }
+ break;
+ case GuiWidget::CHECKBOX:
+ ((CheckBox*)(i->widget))->setValue(value);
+ break;
+ case GuiWidget::COMBOBOX:
+ ((ComboBox*)(i->widget))->setValue(value);
+ break;
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// updateValues
+//---------------------------------------------------------
+
+void PluginGui::updateValues()
+ {
+ int n = plugin->plugin()->parameter();
+ for (int i = 0; i < n; ++i) {
+ double val = plugin->param(i);
+ updateValue(i, val);
+ }
+ }
+
+//---------------------------------------------------------
+// controllerChanged
+//---------------------------------------------------------
+
+void PluginGui::controllerChanged(int id)
+ {
+ double value = plugin->track()->ctrlVal(id).f;
+ for (std::vector<GuiWidget>::iterator i = gw.begin(); i != gw.end(); ++i) {
+ int idx = i->parameter;
+ if (plugin->controller(idx)->id() != id)
+ continue;
+ switch (i->type) {
+ case GuiWidget::SLIDER:
+ ((Slider*)(i->widget))->setValue(value);
+ break;
+ case GuiWidget::FLOAT_ENTRY:
+ {
+ const char* p = plugin->getParameterDisplay(idx, value);
+ if (p)
+ ((FloatEntry*)(i->widget))->setText(QString(p));
+ else
+ ((FloatEntry*)(i->widget))->setValue(value);
+ }
+ break;
+ case GuiWidget::CHECKBOX:
+ ((CheckBox*)(i->widget))->setValue(value);
+ break;
+ case GuiWidget::COMBOBOX:
+ ((ComboBox*)(i->widget))->setValue(value);
+ break;
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// autoChanged
+//---------------------------------------------------------
+
+void PluginGui::autoChanged()
+ {
+ bool ar = plugin->track()->autoRead();
+ bool aw = plugin->track()->autoWrite();
+
+ // controller are enabled if
+ // autoRead is off
+ // autoRead and autoWrite are on (touch mode)
+
+ bool ec = !ar || (ar && aw);
+
+ for (std::vector<GuiWidget>::iterator i = gw.begin(); i != gw.end(); ++i)
+ i->widget->setEnabled(ec);
+ }
+
+
diff --git a/muse_qt4_evolution/muse/plugingui.h b/muse_qt4_evolution/muse/plugingui.h
new file mode 100644
index 00000000..e54e683a
--- /dev/null
+++ b/muse_qt4_evolution/muse/plugingui.h
@@ -0,0 +1,122 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __PLUGINGUI_H__
+#define __PLUGINGUI_H__
+
+namespace Awl {
+ class FloatEntry;
+ };
+using Awl::FloatEntry;
+
+class Plugin;
+class PluginI;
+
+//---------------------------------------------------------
+// GuiParam
+//---------------------------------------------------------
+
+struct GuiParam {
+ enum {
+ GUI_SLIDER, GUI_SWITCH
+ };
+ int type;
+ FloatEntry* label;
+ QWidget* actuator; // Slider or Toggle Button (SWITCH)
+ };
+
+//---------------------------------------------------------
+// GuiWidget
+//---------------------------------------------------------
+
+struct GuiWidget {
+ enum {
+ SLIDER, FLOAT_ENTRY, CHECKBOX, COMBOBOX
+ } type;
+ QWidget* widget;
+ int parameter;
+ };
+
+//---------------------------------------------------------
+// PluginGui
+//---------------------------------------------------------
+
+class PluginGui : public QMainWindow {
+ Q_OBJECT
+
+ PluginI* plugin; // plugin instance
+ std::vector<GuiWidget> gw;
+
+ QAction* onOff;
+ void connectPrebuiltGui(QWidget* wContainer);
+
+ private slots:
+ void load();
+ void save();
+ void bypassToggled(bool);
+
+ void setController(double, int);
+ void autoChanged();
+
+ public:
+ PluginGui(PluginI*);
+ ~PluginGui();
+ void setOn(bool);
+ void updateValue(int, double);
+ void updateValues();
+
+ public slots:
+ void controllerChanged(int id);
+ };
+
+//---------------------------------------------------------
+// PluginDialog
+//---------------------------------------------------------
+
+enum { SEL_SM, SEL_S, SEL_M, SEL_ALL };
+
+class PluginDialog : public QDialog {
+ QTreeWidget* pList;
+ QRadioButton* allPlug;
+ QRadioButton* onlyM;
+ QRadioButton* onlyS;
+ QRadioButton* onlySM;
+
+ Q_OBJECT
+
+ public:
+ PluginDialog(QWidget* parent=0);
+ static Plugin* getPlugin(QWidget* parent);
+ Plugin* value();
+ void accept();
+
+ public slots:
+ void fillPlugs(QAbstractButton*);
+ void fillPlugs(int i);
+ void fillPlugs(const QString& sortValue);
+
+ private:
+ QComboBox *sortBox;
+ static int selectedPlugType;
+ static QStringList sortItems;
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/port.h b/muse_qt4_evolution/muse/port.h
new file mode 100644
index 00000000..d2f83de9
--- /dev/null
+++ b/muse_qt4_evolution/muse/port.h
@@ -0,0 +1,76 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __PORT_H__
+#define __PORT_H__
+
+#include <jack/jack.h>
+
+//---------------------------------------------------------
+// Port
+//---------------------------------------------------------
+
+class Port {
+ enum { JACK_TYPE, ALSA_TYPE, ZERO_TYPE } type;
+ union {
+ jack_port_t* _jackPort;
+ struct {
+ unsigned char _alsaPort;
+ unsigned char _alsaClient;
+ };
+ };
+ public:
+ Port() {
+ type = ZERO_TYPE;
+ }
+ Port(jack_port_t* p) {
+ _jackPort = p;
+ type = JACK_TYPE;
+ }
+ Port(unsigned char client, unsigned char port) {
+ _alsaPort = port;
+ _alsaClient = client;
+ type = ALSA_TYPE;
+ }
+ void setZero() { type = ZERO_TYPE; }
+ bool isZero() const { return type == ZERO_TYPE; }
+ bool operator==(const Port& p) const {
+ if (type == JACK_TYPE)
+ return _jackPort == p._jackPort;
+ else if (type == ALSA_TYPE)
+ return _alsaPort == p._alsaPort && _alsaClient == p._alsaClient;
+ else
+ return true;
+ }
+ bool operator<(const Port& p) const {
+ if (type == ALSA_TYPE) {
+ if (_alsaPort != p._alsaPort)
+ return _alsaPort < p._alsaPort;
+ return _alsaClient < p._alsaClient;
+ }
+ return false;
+ }
+ unsigned char alsaPort() const { return _alsaPort; }
+ unsigned char alsaClient() const { return _alsaClient; }
+ jack_port_t* jackPort() const { return _jackPort; }
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/preferences.cpp b/muse_qt4_evolution/muse/preferences.cpp
new file mode 100644
index 00000000..022a24da
--- /dev/null
+++ b/muse_qt4_evolution/muse/preferences.cpp
@@ -0,0 +1,932 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "icons.h"
+#include "preferences.h"
+#include "track.h"
+#include "muse.h"
+#include "song.h"
+#include "event.h"
+#include "arranger.h"
+#include "widgets/filedialog.h"
+#include "waveedit/waveedit.h"
+#include "globals.h"
+#include "conf.h"
+#include "gconfig.h"
+
+#include "audio.h"
+#include "mixer.h"
+#include "midirc.h"
+#include "instruments/minstrument.h"
+#include "midiedit/pianoroll.h"
+#include "midiedit/drumedit.h"
+
+static int rtcResolutions[] = {
+ 1024, 2048, 4096, 8192
+ };
+static int divisions[] = {
+ 48, 96, 192, 384, 768, 1536, 3072, 6144, 12288
+ };
+
+//---------------------------------------------------------
+// twi
+//---------------------------------------------------------
+
+static QTreeWidgetItem* twi(QTreeWidget* tw, const char* txt, int data)
+ {
+ QTreeWidgetItem* i = new QTreeWidgetItem(tw);
+ i->setText(0, txt);
+ i->setData(0, 1, data);
+ return i;
+ }
+
+static QTreeWidgetItem* twi(QTreeWidgetItem* tw, const char* txt, int data)
+ {
+ QTreeWidgetItem* i = new QTreeWidgetItem(tw);
+ i->setText(0, txt);
+ i->setData(0, 1, data);
+ return i;
+ }
+
+//---------------------------------------------------------
+// PreferencesDialog
+//---------------------------------------------------------
+
+PreferencesDialog::PreferencesDialog(Arranger* a, QWidget* parent)
+ : QDialog(parent)
+ {
+ setupUi(this);
+ colorframe->setAutoFillBackground(true);
+ palette0->setAutoFillBackground(true);
+ palette1->setAutoFillBackground(true);
+ palette2->setAutoFillBackground(true);
+ palette3->setAutoFillBackground(true);
+ arr = a;
+ color = 0;
+ config = new GlobalConfigValues;
+ resetValues();
+
+ // ARRANGER
+
+ usePixmap->setChecked(config->canvasUseBgPixmap);
+ useColor->setChecked(!config->canvasUseBgPixmap);
+ connect(usePixmap, SIGNAL(toggled(bool)), SLOT(usePixmapToggled(bool)));
+ connect(useColor, SIGNAL(toggled(bool)), SLOT(useColorToggled(bool)));
+
+
+ styleSheetPath->setText(config->styleSheetFile);
+ currentBg = config->canvasBgPixmap;
+ if (currentBg.isEmpty())
+ currentBg = "<none>";
+ else {
+ QBrush b;
+ b.setTexture(QPixmap(currentBg));
+ QPalette p;
+ p.setBrush(QPalette::Window, b);
+ currentBgLabel->setPalette(p);
+ }
+ QPalette p;
+ canvasBackgroundColor->setAutoFillBackground(true);
+ p.setColor(QPalette::Window, config->canvasBgColor);
+ canvasBackgroundColor->setPalette(p);
+
+ currentBgLabel->setAutoFillBackground(true);
+ currentBgLabel->setText(currentBg);
+
+ partShownames->setChecked(config->canvasShowPartType & 1);
+ partShowevents->setChecked(config->canvasShowPartType & 2);
+ partShowCakes->setChecked(!(config->canvasShowPartType & 2));
+
+ eventNoteon->setChecked(config->canvasShowPartEvent & (1 << 0));
+ eventPolypressure->setChecked(config->canvasShowPartEvent & (1 << 1));
+ eventController->setChecked(config->canvasShowPartEvent & (1 << 2));
+ eventProgramchange->setChecked(config->canvasShowPartEvent & (1 << 3));
+ eventAftertouch->setChecked(config->canvasShowPartEvent & (1 << 4));
+ eventPitchbend->setChecked(config->canvasShowPartEvent & (1 << 5));
+ eventSpecial->setChecked(config->canvasShowPartEvent & (1 << 6));
+ eventButtonGroup->setEnabled(config->canvasShowPartType == 2);
+ arrGrid->setChecked(config->canvasShowGrid);
+
+ // COLORS
+ QTreeWidgetItem* id;
+ QTreeWidgetItem* aid;
+ itemList->setSortingEnabled(false);
+ itemList->clear();
+
+ aid = twi(itemList, "Arranger", 0);
+ id = twi(aid, "PartColors", 0);
+ twi(id, "Selected", 0x41d);
+
+ twi(id, "Default", 0x400);
+ twi(id, "Refrain", 0x401);
+ twi(id, "Bridge", 0x402);
+ twi(id, "Intro", 0x403);
+ twi(id, "Coda", 0x404);
+ twi(id, "Chorus", 0x405);
+ twi(id, "Solo", 0x406);
+ twi(id, "Brass", 0x407);
+ twi(id, "Percussion", 0x408);
+ twi(id, "Drums", 0x409);
+ twi(id, "Guitar", 0x40a);
+ twi(id, "Bass", 0x40b);
+ twi(id, "Flute", 0x40c);
+ twi(id, "Strings", 0x40d);
+ twi(id, "Keyboard", 0x40e);
+ twi(id, "Piano", 0x40f);
+ twi(id, "Saxophon", 0x410);
+
+ twi(id, "part canvas background", 0x41c);
+
+ id = twi(aid, "Track List", 0);
+ twi(id, "Audio Output", 0x500 + Track::AUDIO_OUTPUT);
+ twi(id, "Audio Group", 0x500 + Track::AUDIO_GROUP);
+ twi(id, "Wave Track", 0x500 + Track::WAVE);
+ twi(id, "Audio Input", 0x500 + Track::AUDIO_INPUT);
+ twi(id, "Synthesizer", 0x500 + Track::AUDIO_SOFTSYNTH);
+ twi(id, "Midi Track", 0x500 + Track::MIDI);
+ twi(id, "Midi Output", 0x500 + Track::MIDI_OUT);
+ twi(id, "Midi Input", 0x500 + Track::MIDI_IN);
+// twi(id, "Midi Channel", 0x500 + Track::MIDI_CHANNEL);
+ twi(id, "Midi Synti", 0x500 + Track::MIDI_SYNTI);
+
+ id = twi(itemList, "BigTime", 0);
+ twi(id, "background", 0x100);
+ twi(id, "foreground", 0x101);
+
+ id = twi(itemList, "Transport", 0);
+ twi(id, "handle", 0x200);
+
+ id = twi(itemList, "Editor", 0);
+ twi(id, "background", 0x300);
+
+ colorGroup = new QButtonGroup(this);
+ colorGroup->setExclusive(true);
+ colorGroup->addButton(palette0, 0);
+ colorGroup->addButton(palette1, 1);
+ colorGroup->addButton(palette2, 2);
+ colorGroup->addButton(palette3, 3);
+ colorGroup->addButton(palette4, 4);
+ colorGroup->addButton(palette5, 5);
+ colorGroup->addButton(palette6, 6);
+ colorGroup->addButton(palette7, 7);
+ colorGroup->addButton(palette8, 8);
+ colorGroup->addButton(palette9, 9);
+ colorGroup->addButton(palette10, 10);
+ colorGroup->addButton(palette11, 11);
+ colorGroup->addButton(palette12, 12);
+ colorGroup->addButton(palette13, 13);
+ colorGroup->addButton(palette14, 14);
+ colorGroup->addButton(palette15, 15);
+ connect(itemList, SIGNAL(itemSelectionChanged()), SLOT(colorItemSelectionChanged()));
+ connect(colorGroup, SIGNAL(buttonClicked(QAbstractButton*)), SLOT(paletteClicked(QAbstractButton*)));
+ connect(hslider, SIGNAL(valueChanged(int)), SLOT(hsliderChanged(int)));
+ connect(sslider, SIGNAL(valueChanged(int)), SLOT(ssliderChanged(int)));
+ connect(vslider, SIGNAL(valueChanged(int)), SLOT(vsliderChanged(int)));
+
+ connect(addToPalette, SIGNAL(clicked()), SLOT(addToPaletteClicked()));
+
+ connect(applyButton, SIGNAL(clicked()), SLOT(apply()));
+ connect(okButton, SIGNAL(clicked()), SLOT(ok()));
+ connect(cancelButton, SIGNAL(clicked()), SLOT(cancel()));
+ connect(selectCanvasBgPixmap, SIGNAL(clicked()), SLOT(configCanvasBgPixmap()));
+ connect(selectCanvasBgColor, SIGNAL(clicked()), SLOT(configCanvasBgColor()));
+ connect(partShowevents, SIGNAL(toggled(bool)), eventButtonGroup, SLOT(setEnabled(bool)));
+ updateColor();
+
+ for (unsigned i = 0; i < sizeof(rtcResolutions)/sizeof(*rtcResolutions); ++i) {
+ if (rtcResolutions[i] == config->rtcTicks) {
+ rtcResolutionSelect->setCurrentIndex(i);
+ break;
+ }
+ }
+ for (unsigned i = 0; i < sizeof(divisions)/sizeof(*divisions); ++i) {
+ if (divisions[i] == config->division) {
+ midiDivisionSelect->setCurrentIndex(i);
+ break;
+ }
+ }
+ int i = 0;
+ for (iMidiInstrument mi = midiInstruments.begin(); mi != midiInstruments.end(); ++mi, ++i) {
+ preferredInstrument->addItem((*mi)->iname());
+ if ((*mi)->iname() == config->defaultMidiInstrument)
+ preferredInstrument->setCurrentIndex(i);
+ }
+
+ connectToAllDevices->setChecked(config->connectToAllMidiDevices);
+ connectToAllTracks->setChecked(config->connectToAllMidiTracks);
+ createDefaultInput->setChecked(config->createDefaultMidiInput);
+
+ guiRefreshSelect->setValue(config->guiRefresh);
+ minSliderSelect->setValue(int(config->minSlider));
+ maxSliderSelect->setValue(int(config->maxSlider));
+ minMeterSelect->setValue(int(config->minMeter));
+ maxMeterSelect->setValue(int(config->maxMeter));
+ peakHoldTime->setValue(config->peakHoldTime);
+ helpBrowser->setText(config->helpBrowser);
+ startProjectEntry->setText(config->startProject);
+
+ startProjectGroup = new QButtonGroup(this);
+ startProjectGroup->addButton(alwaysAsk);
+ startProjectGroup->addButton(startWithLastProject);
+ startProjectGroup->addButton(startWithProject);
+
+ switch(config->startMode) {
+ case START_ASK_FOR_PROJECT:
+ alwaysAsk->setChecked(true);
+ break;
+ case START_LAST_PROJECT:
+ startWithLastProject->setChecked(true);
+ break;
+ case START_START_PROJECT:
+ startWithProject->setChecked(true);
+ break;
+ }
+
+ showTransport->setChecked(config->transportVisible);
+ showBigtime->setChecked(config->bigTimeVisible);
+ showMixer1->setChecked(config->mixer1Visible);
+ showMixer2->setChecked(config->mixer2Visible);
+
+ transportX->setValue(config->geometryTransport.x());
+ transportY->setValue(config->geometryTransport.y());
+
+ bigtimeX->setValue(config->geometryBigTime.x());
+ bigtimeY->setValue(config->geometryBigTime.y());
+ bigtimeW->setValue(config->geometryBigTime.width());
+ bigtimeH->setValue(config->geometryBigTime.height());
+
+ mixerX1->setValue(config->mixer1.geometry.x());
+ mixerY1->setValue(config->mixer1.geometry.y());
+ mixerW1->setValue(config->mixer1.geometry.width());
+ mixerH1->setValue(config->mixer1.geometry.height());
+
+ mixerX2->setValue(config->mixer2.geometry.x());
+ mixerY2->setValue(config->mixer2.geometry.y());
+ mixerW2->setValue(config->mixer2.geometry.width());
+ mixerH2->setValue(config->mixer2.geometry.height());
+
+ setMixerCurrent1->setEnabled(muse->mixer1Window());
+ setMixerCurrent1->setEnabled(muse->mixer2Window());
+
+ setBigtimeCurrent->setEnabled(muse->bigtimeWindow());
+ setTransportCurrent->setEnabled(muse->transportWindow());
+ freewheelMode->setChecked(config->useJackFreewheelMode);
+ showSplash->setChecked(config->showSplashScreen);
+ projectPath->setText(config->projectPath);
+ templatePath->setText(config->templatePath);
+ instrumentPath->setText(config->instrumentPath);
+ midiImportPath->setText(config->importMidiPath);
+ waveImportPath->setText(config->importWavePath);
+
+ stopActive->setChecked(midiRCList.isActive(RC_STOP));
+ playActive->setChecked(midiRCList.isActive(RC_PLAY));
+ gotoLeftMarkActive->setChecked(midiRCList.isActive(RC_GOTO_LEFT_MARK));
+ recordActive->setChecked(midiRCList.isActive(RC_RECORD));
+
+ connect(applyButton, SIGNAL(clicked()), SLOT(apply()));
+ connect(okButton, SIGNAL(clicked()), SLOT(ok()));
+ connect(cancelButton, SIGNAL(clicked()), SLOT(cancel()));
+ connect(setMixerCurrent1, SIGNAL(clicked()), SLOT(mixerCurrent1()));
+ connect(setMixerCurrent2, SIGNAL(clicked()), SLOT(mixerCurrent2()));
+ connect(setBigtimeCurrent, SIGNAL(clicked()), SLOT(bigtimeCurrent()));
+ connect(setArrangerCurrent, SIGNAL(clicked()), SLOT(arrangerCurrent()));
+ connect(setTransportCurrent, SIGNAL(clicked()), SLOT(transportCurrent()));
+
+ recordStop->setChecked(false);
+ recordRecord->setChecked(false);
+ recordGotoLeftMark->setChecked(false);
+ recordPlay->setChecked(false);
+ rcGroup->setChecked(rcEnable);
+
+ pianorollWidth->setValue(PianoRoll::initWidth);
+ pianorollHeight->setValue(PianoRoll::initHeight);
+ pianorollRaster->setRaster(PianoRoll::initRaster);
+ pianorollQuant->setQuant(PianoRoll::initQuant);
+
+ drumEditorWidth->setValue(DrumEdit::initWidth);
+ drumEditorHeight->setValue(DrumEdit::initHeight);
+
+ waveEditorWidth->setValue(WaveEdit::initWidth);
+ waveEditorHeight->setValue(WaveEdit::initHeight);
+
+ connect(recordStop, SIGNAL(clicked(bool)), SLOT(recordStopToggled(bool)));
+ connect(recordRecord, SIGNAL(clicked(bool)), SLOT(recordRecordToggled(bool)));
+ connect(recordGotoLeftMark, SIGNAL(clicked(bool)), SLOT(recordGotoLeftMarkToggled(bool)));
+ connect(recordPlay, SIGNAL(clicked(bool)), SLOT(recordPlayToggled(bool)));
+
+ }
+
+//---------------------------------------------------------
+// setButtonColor
+//---------------------------------------------------------
+
+static void setButtonColor(QAbstractButton* b, const QRgb c)
+ {
+ QPalette p(b->palette());
+ p.setColor(QPalette::Button, QColor(c));
+ p.setColor(b->backgroundRole(), QColor(c));
+ b->setPalette(p);
+ }
+
+//---------------------------------------------------------
+// resetValues
+//---------------------------------------------------------
+
+void PreferencesDialog::resetValues()
+ {
+ *config = ::config; // init with global config values
+
+ setButtonColor(palette0, QColorDialog::customColor(0));
+ setButtonColor(palette1, QColorDialog::customColor(1));
+ setButtonColor(palette2, QColorDialog::customColor(2));
+ setButtonColor(palette3, QColorDialog::customColor(3));
+ setButtonColor(palette4, QColorDialog::customColor(4));
+ setButtonColor(palette5, QColorDialog::customColor(5));
+ setButtonColor(palette6, QColorDialog::customColor(6));
+ setButtonColor(palette7, QColorDialog::customColor(7));
+ setButtonColor(palette8, QColorDialog::customColor(8));
+ setButtonColor(palette9, QColorDialog::customColor(9));
+ setButtonColor(palette10, QColorDialog::customColor(10));
+ setButtonColor(palette11, QColorDialog::customColor(11));
+ setButtonColor(palette12, QColorDialog::customColor(12));
+ setButtonColor(palette13, QColorDialog::customColor(13));
+ setButtonColor(palette14, QColorDialog::customColor(14));
+ }
+
+//---------------------------------------------------------
+// PreferencesDialog
+//---------------------------------------------------------
+
+PreferencesDialog::~PreferencesDialog()
+ {
+ delete config;
+ }
+
+//---------------------------------------------------------
+// apply
+//---------------------------------------------------------
+
+void PreferencesDialog::apply()
+ {
+ ::config.styleSheetFile = styleSheetPath->text();
+ int showPartEvent = 0;
+ int showPartType = 0;
+
+ if (partShownames->isChecked())
+ showPartType |= 1;
+ if (partShowevents->isChecked())
+ showPartType |= 2;
+ if (partShowCakes->isChecked())
+ showPartType |= 4;
+
+ if (eventNoteon->isChecked())
+ showPartEvent |= (1 << 0);
+ if (eventPolypressure->isChecked())
+ showPartEvent |= (1 << 1);
+ if (eventController->isChecked())
+ showPartEvent |= (1 << 2);
+ if (eventProgramchange->isChecked())
+ showPartEvent |= (1 << 3);
+ if (eventAftertouch->isChecked())
+ showPartEvent |= (1 << 4);
+ if (eventPitchbend->isChecked())
+ showPartEvent |= (1 << 5);
+ if (eventSpecial->isChecked())
+ showPartEvent |= (1 << 6);
+
+ config->canvasUseBgPixmap = usePixmap->isChecked();
+ if (currentBg != "<none>")
+ config->canvasBgPixmap = currentBg;
+
+ config->canvasShowGrid = arrGrid->isChecked();
+ // set colors...
+ ::config = *config;
+
+ rcEnable = rcGroup->isChecked();
+ int rtcticks = rtcResolutionSelect->currentIndex();
+ int div = midiDivisionSelect->currentIndex();
+
+ ::config.connectToAllMidiDevices = connectToAllDevices->isChecked();
+ ::config.connectToAllMidiTracks = connectToAllTracks->isChecked();
+ ::config.createDefaultMidiInput = createDefaultInput->isChecked();
+ ::config.defaultMidiInputDevice = preferredInput->currentText();
+ ::config.defaultMidiOutputDevice = preferredOutput->currentText();
+ ::config.defaultMidiInstrument = preferredInstrument->currentText();
+
+ ::config.guiRefresh = guiRefreshSelect->value();
+ ::config.minSlider = minSliderSelect->value();
+ ::config.maxSlider = maxSliderSelect->value();
+ ::config.minMeter = minMeterSelect->value();
+ ::config.maxMeter = maxMeterSelect->value();
+ ::config.peakHoldTime = peakHoldTime->value();
+ ::config.rtcTicks = rtcResolutions[rtcticks];
+ ::config.guiDivision = divisions[div];
+ ::config.helpBrowser = helpBrowser->text();
+ ::config.startProject = startProjectEntry->text();
+
+ if (alwaysAsk->isChecked())
+ ::config.startMode = START_ASK_FOR_PROJECT;
+ else if (startWithLastProject->isChecked())
+ ::config.startMode = START_LAST_PROJECT;
+ else if (startWithProject->isChecked())
+ ::config.startMode = START_START_PROJECT;
+
+ ::config.transportVisible = showTransport->isChecked();
+ ::config.bigTimeVisible = showBigtime->isChecked();
+ ::config.mixer1Visible = showMixer1->isChecked();
+ ::config.mixer2Visible = showMixer2->isChecked();
+
+ ::config.geometryTransport.setX(transportX->value());
+ ::config.geometryTransport.setY(transportY->value());
+ ::config.geometryTransport.setWidth(0);
+ ::config.geometryTransport.setHeight(0);
+
+ ::config.geometryBigTime.setX(bigtimeX->value());
+ ::config.geometryBigTime.setY(bigtimeY->value());
+ ::config.geometryBigTime.setWidth(bigtimeW->value());
+ ::config.geometryBigTime.setHeight(bigtimeH->value());
+
+ ::config.mixer1.geometry.setX(mixerX1->value());
+ ::config.mixer1.geometry.setY(mixerY1->value());
+ ::config.mixer1.geometry.setWidth(mixerW1->value());
+ ::config.mixer1.geometry.setHeight(mixerH1->value());
+
+ ::config.mixer2.geometry.setX(mixerX2->value());
+ ::config.mixer2.geometry.setY(mixerY2->value());
+ ::config.mixer2.geometry.setWidth(mixerW2->value());
+ ::config.mixer2.geometry.setHeight(mixerH2->value());
+
+ ::config.useJackFreewheelMode = freewheelMode->isChecked();
+ ::config.showSplashScreen = showSplash->isChecked();
+
+ ::config.projectPath = projectPath->text();
+ ::config.templatePath = templatePath->text();
+ ::config.instrumentPath = instrumentPath->text();
+ ::config.importMidiPath = midiImportPath->text();
+ ::config.importWavePath = waveImportPath->text();
+
+ lastMidiPath = museUser + "/" + ::config.importMidiPath;
+ lastWavePath = museUser + "/" + ::config.importWavePath;
+
+ PianoRoll::initWidth = pianorollWidth->value();
+ PianoRoll::initHeight = pianorollHeight->value();
+ PianoRoll::initRaster = pianorollRaster->raster();
+ PianoRoll::initQuant = pianorollQuant->quant();
+
+ DrumEdit::initWidth = drumEditorWidth->value();
+ DrumEdit::initHeight = drumEditorHeight->value();
+
+ muse->showMixer1(::config.mixer1Visible);
+ muse->showMixer2(::config.mixer2Visible);
+ muse->showBigtime(::config.bigTimeVisible);
+ muse->showTransport(::config.transportVisible);
+ QWidget* w = muse->transportWindow();
+ if (w) {
+ w->resize(::config.geometryTransport.size());
+ w->move(::config.geometryTransport.topLeft());
+ }
+ w = muse->mixer1Window();
+ if (w) {
+ w->resize(::config.mixer1.geometry.size());
+ w->move(::config.mixer1.geometry.topLeft());
+ }
+ w = muse->mixer2Window();
+ if (w) {
+ w->resize(::config.mixer2.geometry.size());
+ w->move(::config.mixer2.geometry.topLeft());
+ }
+ w = muse->bigtimeWindow();
+ if (w) {
+ w->resize(::config.geometryBigTime.size());
+ w->move(::config.geometryBigTime.topLeft());
+ }
+
+ muse->setHeartBeat(); // set guiRefresh
+ audio->msgSetRtc(); // set midi tick rate
+ muse->changeConfig(true); // save settings
+ }
+
+//---------------------------------------------------------
+// ok
+//---------------------------------------------------------
+
+void PreferencesDialog::ok()
+ {
+ apply();
+ close();
+ }
+
+//---------------------------------------------------------
+// cancel
+//---------------------------------------------------------
+
+void PreferencesDialog::cancel()
+ {
+ close();
+ }
+
+//---------------------------------------------------------
+// configCanvasBgPixmap
+//---------------------------------------------------------
+
+void PreferencesDialog::configCanvasBgPixmap()
+ {
+ QString cur(currentBg);
+ if (cur == "<none>")
+ cur = museGlobalShare + "/wallpapers";
+
+ QStringList pattern;
+ const char** p = image_file_pattern;
+ while(*p)
+ pattern << *p++;
+ QString s = getImageFileName(cur, pattern, this, tr("MusE: load image"));
+ if (!s.isEmpty()) {
+ QBrush b;
+ currentBg = s;
+ b.setTexture(QPixmap(s));
+ QPalette p;
+ p.setBrush(QPalette::Window, b);
+ currentBgLabel->setPalette(p);
+ currentBgLabel->setText(currentBg);
+ }
+ }
+
+//---------------------------------------------------------
+// configCanvasBgColor
+//---------------------------------------------------------
+
+void PreferencesDialog::configCanvasBgColor()
+ {
+ QColor color = QColorDialog::getColor(config->canvasBgColor, this);
+ if (color.isValid()) {
+ config->canvasBgColor = color;
+ QPalette p;
+ p.setColor(QPalette::Window, color);
+ canvasBackgroundColor->setPalette(p);
+ }
+ }
+
+//---------------------------------------------------------
+// selectionChanged
+//---------------------------------------------------------
+
+void PreferencesDialog::colorItemSelectionChanged()
+ {
+ QTreeWidgetItem* item = (QTreeWidgetItem*)itemList->selectedItems().at(0);
+ QString txt = item->text(0);
+ int id = item->data(0, 1).toInt();
+ if (id == 0) {
+ color = 0;
+ return;
+ }
+ switch(id) {
+ case 0x400 ... 0x410: // "Default"
+ color = &config->partColors[id & 0xff];
+ break;
+ case 0x100:
+ color = &config->bigTimeBackgroundColor;
+ break;
+ case 0x101:
+ color = &config->bigTimeForegroundColor;
+ break;
+ case 0x200:
+ color = &config->transportHandleColor;
+ break;
+ case 0x300:
+ color = &config->waveEditBackgroundColor;
+ break;
+ case 0x500 ... 0x5ff:
+ color = &config->trackBg[id & 0xff];
+ break;
+ case 0x41c:
+ color = &config->selectPartBg;
+ break;
+ default:
+ color = 0;
+ break;
+ }
+ updateColor();
+ }
+
+//---------------------------------------------------------
+// updateColor
+//---------------------------------------------------------
+
+void PreferencesDialog::updateColor()
+ {
+ hslider->setEnabled(color);
+ sslider->setEnabled(color);
+ vslider->setEnabled(color);
+ if (color == 0)
+ return;
+ QPalette p(colorframe->palette());
+ p.setColor(QPalette::Window, *color);
+ colorframe->setPalette(p);
+ int r, g, b, h, s, v;
+ color->getRgb(&r, &g, &b);
+ color->getHsv(&h, &s, &v);
+
+ hslider->blockSignals(true);
+ sslider->blockSignals(true);
+ vslider->blockSignals(true);
+
+ hslider->setValue(h);
+ sslider->setValue(s);
+ vslider->setValue(v);
+
+ hslider->blockSignals(false);
+ sslider->blockSignals(false);
+ vslider->blockSignals(false);
+ }
+
+void PreferencesDialog::hsliderChanged(int val)
+ {
+ int h, s, v;
+ if (color) {
+ color->getHsv(&h, &s, &v);
+ color->setHsv(val, s, v);
+ }
+ updateColor();
+ }
+
+void PreferencesDialog::ssliderChanged(int val)
+ {
+ int h, s, v;
+ if (color) {
+ color->getHsv(&h, &s, &v);
+ color->setHsv(h, val, v);
+ }
+ updateColor();
+ }
+
+void PreferencesDialog::vsliderChanged(int val)
+ {
+ int h, s, v;
+ if (color) {
+ color->getHsv(&h, &s, &v);
+ color->setHsv(h, s, val);
+ }
+ updateColor();
+ }
+
+//---------------------------------------------------------
+// addToPaletteClicked
+//---------------------------------------------------------
+
+void PreferencesDialog::addToPaletteClicked()
+ {
+ if (!color)
+ return;
+ QAbstractButton* button = colorGroup->checkedButton();
+ int r, g, b;
+ QColor c;
+ if (button) {
+ c = button->palette().color(QPalette::Button);
+ c.getRgb(&r, &g, &b);
+ }
+ if (button == 0 || r != 0xff || g != 0xff || b != 0xff) {
+ for (int i = 0; i < 16; ++i) {
+ button = colorGroup->button(i);
+ c = button->palette().color(QPalette::Button);
+ c.getRgb(&r, &g, &b);
+ if (r == 0xff && g == 0xff && b == 0xff) {
+ // found empty slot
+ button->setChecked(true);
+ break;
+ }
+ }
+ }
+ if (button) {
+ int id = colorGroup->checkedId();
+ QColorDialog::setCustomColor(id, color->rgb());
+ setButtonColor(button, color->rgb());
+ }
+ }
+
+//---------------------------------------------------------
+// paletteClicked
+//---------------------------------------------------------
+
+void PreferencesDialog::paletteClicked(QAbstractButton* button)
+ {
+ if (color == 0)
+ return;
+ QColor c = button->palette().color(QPalette::Button);
+ int r, g, b;
+ c.getRgb(&r, &g, &b);
+ if (r == 0xff && g == 0xff && b == 0xff)
+ return; // interpret palette slot as empty
+ *color = c;
+ updateColor();
+ }
+
+//---------------------------------------------------------
+// usePixmapToggled
+//---------------------------------------------------------
+
+void PreferencesDialog::usePixmapToggled(bool val)
+ {
+ useColor->setChecked(!val);
+ }
+
+//---------------------------------------------------------
+// useColorToggled
+//---------------------------------------------------------
+
+void PreferencesDialog::useColorToggled(bool val)
+ {
+ usePixmap->setChecked(!val);
+ }
+
+//---------------------------------------------------------
+// mixerCurrent1
+//---------------------------------------------------------
+
+void PreferencesDialog::mixerCurrent1()
+ {
+ QWidget* w = muse->mixer1Window();
+ if (!w)
+ return;
+ QRect r(w->frameGeometry());
+ mixerX1->setValue(r.x());
+ mixerY1->setValue(r.y());
+ mixerW1->setValue(r.width());
+ mixerH1->setValue(r.height());
+ }
+
+//---------------------------------------------------------
+// mixerCurrent2
+//---------------------------------------------------------
+
+void PreferencesDialog::mixerCurrent2()
+ {
+ QWidget* w = muse->mixer2Window();
+ if (!w)
+ return;
+ QRect r(w->frameGeometry());
+ mixerX2->setValue(r.x());
+ mixerY2->setValue(r.y());
+ mixerW2->setValue(r.width());
+ mixerH2->setValue(r.height());
+ }
+
+//---------------------------------------------------------
+// bigtimeCurrent
+//---------------------------------------------------------
+
+void PreferencesDialog::bigtimeCurrent()
+ {
+ QWidget* w = muse->bigtimeWindow();
+ if (!w)
+ return;
+ QRect r(w->frameGeometry());
+ bigtimeX->setValue(r.x());
+ bigtimeY->setValue(r.y());
+ bigtimeW->setValue(r.width());
+ bigtimeH->setValue(r.height());
+ }
+
+//---------------------------------------------------------
+// arrangerCurrent
+//---------------------------------------------------------
+
+void PreferencesDialog::arrangerCurrent()
+ {
+ QRect r(muse->frameGeometry());
+ arrangerX->setValue(r.x());
+ arrangerY->setValue(r.y());
+ arrangerW->setValue(r.width());
+ arrangerH->setValue(r.height());
+ }
+
+//---------------------------------------------------------
+// transportCurrent
+//---------------------------------------------------------
+
+void PreferencesDialog::transportCurrent()
+ {
+ QWidget* w = muse->transportWindow();
+ if (!w)
+ return;
+ QRect r(w->frameGeometry());
+ transportX->setValue(r.x());
+ transportY->setValue(r.y());
+ }
+
+//---------------------------------------------------------
+// recordStopToggled
+//---------------------------------------------------------
+
+void PreferencesDialog::recordStopToggled(bool f)
+ {
+ recordStop->setChecked(!f);
+ if (!f) {
+ recordRecord->setChecked(false);
+ recordGotoLeftMark->setChecked(false);
+ recordPlay->setChecked(false);
+ connect(song, SIGNAL(midiEvent(MidiEvent)), SLOT(midiEventReceived(MidiEvent)));
+ }
+ else
+ disconnect(song, SIGNAL(midiEvent(MidiEvent)), this, SLOT(midiEventReceived(MidiEvent)));
+ }
+
+//---------------------------------------------------------
+// recordRecordToggled
+//---------------------------------------------------------
+
+void PreferencesDialog::recordRecordToggled(bool f)
+ {
+ recordRecord->setChecked(!f);
+ if (!f) {
+ recordStop->setChecked(false);
+ recordGotoLeftMark->setChecked(false);
+ recordPlay->setChecked(false);
+ connect(song, SIGNAL(midiEvent(MidiEvent)), SLOT(midiEventReceived(MidiEvent)));
+ }
+ else
+ disconnect(song, SIGNAL(midiEvent(MidiEvent)), this, SLOT(midiEventReceived(MidiEvent)));
+ }
+
+//---------------------------------------------------------
+// recordGotoLeftMarkToggled
+//---------------------------------------------------------
+
+void PreferencesDialog::recordGotoLeftMarkToggled(bool f)
+ {
+ recordGotoLeftMark->setChecked(!f);
+ if (!f) {
+ recordStop->setChecked(false);
+ recordRecord->setChecked(false);
+ recordPlay->setChecked(false);
+ connect(song, SIGNAL(midiEvent(MidiEvent)), SLOT(midiEventReceived(MidiEvent)));
+ }
+ else
+ disconnect(song, SIGNAL(midiEvent(MidiEvent)), this, SLOT(midiEventReceived(MidiEvent)));
+ }
+
+//---------------------------------------------------------
+// recordPlayToggled
+//---------------------------------------------------------
+
+void PreferencesDialog::recordPlayToggled(bool f)
+ {
+ recordPlay->setChecked(!f);
+ if (!f) {
+ recordStop->setChecked(false);
+ recordRecord->setChecked(false);
+ recordGotoLeftMark->setChecked(false);
+ connect(song, SIGNAL(midiEvent(MidiEvent)), SLOT(midiEventReceived(MidiEvent)));
+ }
+ else
+ disconnect(song, SIGNAL(midiEvent(MidiEvent)), this, SLOT(midiEventReceived(MidiEvent)));
+ }
+
+//---------------------------------------------------------
+// midiEventReceived
+//---------------------------------------------------------
+
+void PreferencesDialog::midiEventReceived(MidiEvent event)
+ {
+ printf("event received\n");
+ if (recordPlay->isChecked()) {
+ recordPlay->setChecked(false);
+ playActive->setChecked(true);
+ midiRCList.setAction(event, RC_PLAY);
+ }
+ else if (recordStop->isChecked()) {
+ recordStop->setChecked(false);
+ stopActive->setChecked(true);
+ midiRCList.setAction(event, RC_STOP);
+ }
+ else if (recordRecord->isChecked()) {
+ recordRecord->setChecked(false);
+ recordActive->setChecked(true);
+ midiRCList.setAction(event, RC_RECORD);
+ }
+ else if (recordGotoLeftMark->isChecked()) {
+ recordGotoLeftMark->setChecked(false);
+ gotoLeftMarkActive->setChecked(true);
+ midiRCList.setAction(event, RC_GOTO_LEFT_MARK);
+ }
+ // only one shot
+ disconnect(song, SIGNAL(midiEvent(MidiEvent)), this, SLOT(midiEventReceived(MidiEvent)));
+ }
+
+
diff --git a/muse_qt4_evolution/muse/preferences.h b/muse_qt4_evolution/muse/preferences.h
new file mode 100644
index 00000000..75cb5754
--- /dev/null
+++ b/muse_qt4_evolution/muse/preferences.h
@@ -0,0 +1,79 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __PREFERENCES_H__
+#define __PREFERENCES_H__
+
+#include "ui_preferences.h"
+#include "midievent.h"
+
+class MusE;
+class Arranger;
+class GlobalConfigValues;
+
+//---------------------------------------------------------
+// PreferencesDialog
+//---------------------------------------------------------
+
+class PreferencesDialog : public QDialog, public Ui::PreferencesDialogBase {
+ Q_OBJECT
+
+ Arranger* arr;
+ QColor* color;
+ QString currentBg;
+ GlobalConfigValues* config;
+ QButtonGroup* colorGroup;
+ QButtonGroup* startProjectGroup;
+
+ void updateColor();
+
+ private slots:
+ void apply();
+ void ok();
+ void cancel();
+ void configCanvasBgColor();
+ void configCanvasBgPixmap();
+ void colorItemSelectionChanged();
+ void hsliderChanged(int);
+ void ssliderChanged(int);
+ void vsliderChanged(int);
+ void addToPaletteClicked();
+ void paletteClicked(QAbstractButton*);
+ void useColorToggled(bool);
+ void usePixmapToggled(bool);
+
+ void mixerCurrent1();
+ void mixerCurrent2();
+ void bigtimeCurrent();
+ void arrangerCurrent();
+ void transportCurrent();
+ void recordStopToggled(bool);
+ void recordRecordToggled(bool);
+ void recordGotoLeftMarkToggled(bool);
+ void recordPlayToggled(bool);
+ void midiEventReceived(MidiEvent);
+
+ public:
+ PreferencesDialog(Arranger*, QWidget* parent=0);
+ ~PreferencesDialog();
+ void resetValues();
+ };
+
+#endif
diff --git a/muse_qt4_evolution/muse/preferences.ui b/muse_qt4_evolution/muse/preferences.ui
new file mode 100644
index 00000000..5417c33c
--- /dev/null
+++ b/muse_qt4_evolution/muse/preferences.ui
@@ -0,0 +1,2400 @@
+<ui version="4.0" >
+ <class>PreferencesDialogBase</class>
+ <widget class="QDialog" name="PreferencesDialogBase" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>665</width>
+ <height>631</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Dialog</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <property name="leftMargin" >
+ <number>9</number>
+ </property>
+ <property name="topMargin" >
+ <number>9</number>
+ </property>
+ <property name="rightMargin" >
+ <number>9</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>9</number>
+ </property>
+ <item>
+ <widget class="QTabWidget" name="tabWidget" >
+ <property name="currentIndex" >
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="tab" >
+ <attribute name="title" >
+ <string>Application</string>
+ </attribute>
+ <layout class="QVBoxLayout" >
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <property name="leftMargin" >
+ <number>9</number>
+ </property>
+ <property name="topMargin" >
+ <number>9</number>
+ </property>
+ <property name="rightMargin" >
+ <number>9</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>9</number>
+ </property>
+ <item>
+ <widget class="QGroupBox" name="groupBox_8" >
+ <property name="title" >
+ <string>Style</string>
+ </property>
+ <layout class="QHBoxLayout" >
+ <item>
+ <widget class="QLabel" name="label_41" >
+ <property name="text" >
+ <string>Style Sheet:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="styleSheetPath" />
+ </item>
+ <item>
+ <widget class="QToolButton" name="openStyleSheet" >
+ <property name="text" >
+ <string>...</string>
+ </property>
+ <property name="icon" >
+ <iconset resource="muse.qrc" >:/xpm/fileopen.png</iconset>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox" >
+ <property name="title" >
+ <string>Start MusE</string>
+ </property>
+ <property name="flat" >
+ <bool>true</bool>
+ </property>
+ <layout class="QHBoxLayout" >
+ <property name="spacing" >
+ <number>3</number>
+ </property>
+ <property name="leftMargin" >
+ <number>9</number>
+ </property>
+ <property name="topMargin" >
+ <number>9</number>
+ </property>
+ <property name="rightMargin" >
+ <number>9</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>9</number>
+ </property>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="spacing" >
+ <number>3</number>
+ </property>
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QRadioButton" name="alwaysAsk" >
+ <property name="text" >
+ <string>always ask</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="startWithLastProject" >
+ <property name="text" >
+ <string>start with last project</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="startWithProject" >
+ <property name="text" >
+ <string>start with project:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="startProjectEntry" />
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QCheckBox" name="showSplash" >
+ <property name="text" >
+ <string>show splash screen</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox_7" >
+ <property name="title" >
+ <string>Local Paths</string>
+ </property>
+ <property name="flat" >
+ <bool>true</bool>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="leftMargin" >
+ <number>9</number>
+ </property>
+ <property name="topMargin" >
+ <number>9</number>
+ </property>
+ <property name="rightMargin" >
+ <number>9</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>9</number>
+ </property>
+ <property name="horizontalSpacing" >
+ <number>6</number>
+ </property>
+ <property name="verticalSpacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Projects</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QLineEdit" name="projectPath" />
+ </item>
+ <item row="0" column="2" >
+ <widget class="QLabel" name="label_36" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Midi Import</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3" colspan="2" >
+ <widget class="QLineEdit" name="midiImportPath" />
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_35" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Templates</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QLineEdit" name="templatePath" />
+ </item>
+ <item row="1" column="2" >
+ <widget class="QLabel" name="label_37" >
+ <property name="text" >
+ <string>Wave Import</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3" colspan="2" >
+ <widget class="QLineEdit" name="waveImportPath" />
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="label_38" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Instruments</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" >
+ <widget class="QLineEdit" name="instrumentPath" />
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox_2" >
+ <property name="title" >
+ <string>Views</string>
+ </property>
+ <property name="flat" >
+ <bool>true</bool>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="leftMargin" >
+ <number>9</number>
+ </property>
+ <property name="topMargin" >
+ <number>9</number>
+ </property>
+ <property name="rightMargin" >
+ <number>9</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>9</number>
+ </property>
+ <property name="horizontalSpacing" >
+ <number>3</number>
+ </property>
+ <property name="verticalSpacing" >
+ <number>3</number>
+ </property>
+ <item row="3" column="6" >
+ <widget class="QPushButton" name="setMixerCurrent1" >
+ <property name="text" >
+ <string>Cur</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1" >
+ <widget class="QCheckBox" name="showMixer1" >
+ <property name="text" >
+ <string>show</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" >
+ <widget class="QLabel" name="label_5" >
+ <property name="text" >
+ <string>Mixer 1</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="label_4" >
+ <property name="text" >
+ <string>Big Time</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="6" >
+ <widget class="QPushButton" name="setTransportCurrent" >
+ <property name="text" >
+ <string>Cur</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="6" >
+ <widget class="QPushButton" name="setMixerCurrent2" >
+ <property name="text" >
+ <string>Cur</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="6" >
+ <widget class="QPushButton" name="setArrangerCurrent" >
+ <property name="text" >
+ <string>Cur</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="5" >
+ <widget class="QSpinBox" name="mixerH2" >
+ <property name="maximum" >
+ <number>9999</number>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="4" >
+ <widget class="QSpinBox" name="mixerW2" >
+ <property name="maximum" >
+ <number>9999</number>
+ </property>
+ <property name="value" >
+ <number>0</number>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="5" >
+ <widget class="QSpinBox" name="mixerH1" >
+ <property name="maximum" >
+ <number>9999</number>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="4" >
+ <widget class="QSpinBox" name="mixerW1" >
+ <property name="maximum" >
+ <number>9999</number>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="5" >
+ <widget class="QSpinBox" name="bigtimeH" >
+ <property name="maximum" >
+ <number>9999</number>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="4" >
+ <widget class="QSpinBox" name="bigtimeW" >
+ <property name="maximum" >
+ <number>9999</number>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="5" >
+ <widget class="QSpinBox" name="arrangerH" >
+ <property name="maximum" >
+ <number>9999</number>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="4" >
+ <widget class="QSpinBox" name="arrangerW" >
+ <property name="maximum" >
+ <number>9999</number>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="3" >
+ <widget class="QSpinBox" name="mixerY2" >
+ <property name="maximum" >
+ <number>9999</number>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="3" >
+ <widget class="QSpinBox" name="mixerY1" >
+ <property name="maximum" >
+ <number>9999</number>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="3" >
+ <widget class="QSpinBox" name="bigtimeY" >
+ <property name="maximum" >
+ <number>9999</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3" >
+ <widget class="QSpinBox" name="transportY" >
+ <property name="maximum" >
+ <number>9999</number>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3" >
+ <widget class="QSpinBox" name="arrangerY" >
+ <property name="maximum" >
+ <number>9999</number>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="2" >
+ <widget class="QSpinBox" name="mixerX1" >
+ <property name="maximum" >
+ <number>9999</number>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="2" >
+ <widget class="QSpinBox" name="mixerX2" >
+ <property name="maximum" >
+ <number>9999</number>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2" >
+ <widget class="QSpinBox" name="bigtimeX" >
+ <property name="maximum" >
+ <number>9999</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2" >
+ <widget class="QSpinBox" name="transportX" >
+ <property name="maximum" >
+ <number>9999</number>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2" >
+ <widget class="QSpinBox" name="arrangerX" >
+ <property name="maximum" >
+ <number>9999</number>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1" >
+ <widget class="QCheckBox" name="showMixer2" >
+ <property name="text" >
+ <string>show</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QCheckBox" name="showTransport" >
+ <property name="text" >
+ <string>show</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0" >
+ <widget class="QLabel" name="label_6" >
+ <property name="text" >
+ <string>Mixer 2</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_3" >
+ <property name="text" >
+ <string>Transport</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label_2" >
+ <property name="text" >
+ <string>Arranger</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" >
+ <widget class="QCheckBox" name="showBigtime" >
+ <property name="text" >
+ <string>show</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="6" >
+ <widget class="QPushButton" name="setBigtimeCurrent" >
+ <property name="text" >
+ <string>Cur</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab_5" >
+ <attribute name="title" >
+ <string>Editors</string>
+ </attribute>
+ <layout class="QVBoxLayout" >
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <property name="leftMargin" >
+ <number>9</number>
+ </property>
+ <property name="topMargin" >
+ <number>9</number>
+ </property>
+ <property name="rightMargin" >
+ <number>9</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>9</number>
+ </property>
+ <item>
+ <widget class="QTabWidget" name="tabWidget2" >
+ <property name="currentIndex" >
+ <number>4</number>
+ </property>
+ <widget class="QWidget" name="tab_61" >
+ <attribute name="title" >
+ <string>Arranger</string>
+ </attribute>
+ <layout class="QVBoxLayout" >
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <property name="leftMargin" >
+ <number>9</number>
+ </property>
+ <property name="topMargin" >
+ <number>9</number>
+ </property>
+ <property name="rightMargin" >
+ <number>9</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>9</number>
+ </property>
+ <item>
+ <widget class="QGroupBox" name="ButtonGroup3" >
+ <property name="title" >
+ <string>Parts</string>
+ </property>
+ <property name="flat" >
+ <bool>true</bool>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <property name="leftMargin" >
+ <number>11</number>
+ </property>
+ <property name="topMargin" >
+ <number>11</number>
+ </property>
+ <property name="rightMargin" >
+ <number>11</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>11</number>
+ </property>
+ <item>
+ <widget class="QCheckBox" name="partShownames" >
+ <property name="text" >
+ <string>show names</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="partShowevents" >
+ <property name="text" >
+ <string>show events</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="partShowCakes" >
+ <property name="text" >
+ <string>show Cakewalk Style</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="eventButtonGroup" >
+ <property name="title" >
+ <string>Events</string>
+ </property>
+ <property name="flat" >
+ <bool>true</bool>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="leftMargin" >
+ <number>11</number>
+ </property>
+ <property name="topMargin" >
+ <number>11</number>
+ </property>
+ <property name="rightMargin" >
+ <number>11</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>11</number>
+ </property>
+ <property name="horizontalSpacing" >
+ <number>6</number>
+ </property>
+ <property name="verticalSpacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="0" >
+ <widget class="QCheckBox" name="eventNoteon" >
+ <property name="text" >
+ <string>note on</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QCheckBox" name="eventPolypressure" >
+ <property name="text" >
+ <string>poly pressure</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" >
+ <widget class="QCheckBox" name="eventController" >
+ <property name="text" >
+ <string>controller</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QCheckBox" name="eventAftertouch" >
+ <property name="text" >
+ <string>aftertouch</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" >
+ <widget class="QCheckBox" name="eventPitchbend" >
+ <property name="text" >
+ <string>pitch bend</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QCheckBox" name="eventProgramchange" >
+ <property name="text" >
+ <string>program change</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" >
+ <widget class="QCheckBox" name="eventSpecial" >
+ <property name="text" >
+ <string>special</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="useCanvasBgPixmap" >
+ <property name="title" >
+ <string>Background</string>
+ </property>
+ <property name="flat" >
+ <bool>true</bool>
+ </property>
+ <property name="checkable" >
+ <bool>false</bool>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="leftMargin" >
+ <number>9</number>
+ </property>
+ <property name="topMargin" >
+ <number>9</number>
+ </property>
+ <property name="rightMargin" >
+ <number>9</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>9</number>
+ </property>
+ <property name="horizontalSpacing" >
+ <number>6</number>
+ </property>
+ <property name="verticalSpacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="1" >
+ <widget class="QLabel" name="currentBgLabel" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Minimum" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>bg</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignCenter</set>
+ </property>
+ <property name="indent" >
+ <number>-1</number>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" >
+ <widget class="QRadioButton" name="usePixmap" >
+ <property name="text" >
+ <string>Pixmap</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QLabel" name="canvasBackgroundColor" >
+ <property name="text" >
+ <string>Color</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QRadioButton" name="useColor" >
+ <property name="text" >
+ <string>Color</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2" >
+ <widget class="QToolButton" name="selectCanvasBgColor" >
+ <property name="text" >
+ <string>select...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2" >
+ <widget class="QToolButton" name="selectCanvasBgPixmap" >
+ <property name="text" >
+ <string>select...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="arrGrid" >
+ <property name="text" >
+ <string>show snap grid</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab_6" >
+ <attribute name="title" >
+ <string>Pianoroll</string>
+ </attribute>
+ <layout class="QGridLayout" >
+ <property name="leftMargin" >
+ <number>9</number>
+ </property>
+ <property name="topMargin" >
+ <number>9</number>
+ </property>
+ <property name="rightMargin" >
+ <number>9</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>9</number>
+ </property>
+ <property name="horizontalSpacing" >
+ <number>6</number>
+ </property>
+ <property name="verticalSpacing" >
+ <number>6</number>
+ </property>
+ <item row="3" column="0" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>211</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="label_25" >
+ <property name="text" >
+ <string>&lt;html>&lt;head>&lt;meta name="qrichtext" content="1" />&lt;/head>&lt;body style=" white-space: pre-wrap; font-family:Arial; font-size:10pt; font-weight:400; font-style:normal; text-decoration:none;">&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-weight:600;">Quant&lt;/p>&lt;/body>&lt;/html></string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_24" >
+ <property name="text" >
+ <string>&lt;html>&lt;head>&lt;meta name="qrichtext" content="1" />&lt;/head>&lt;body style=" white-space: pre-wrap; font-family:Arial; font-size:10pt; font-weight:400; font-style:normal; text-decoration:none;">&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-weight:600;">Raster&lt;/p>&lt;/body>&lt;/html></string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label_21" >
+ <property name="text" >
+ <string>&lt;html>&lt;head>&lt;meta name="qrichtext" content="1" />&lt;/head>&lt;body style=" white-space: pre-wrap; font-family:Arial; font-size:10pt; font-weight:400; font-style:normal; text-decoration:none;">&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-weight:600;">Geometry&lt;/p>&lt;/body>&lt;/html></string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3" >
+ <widget class="QLabel" name="label_23" >
+ <property name="text" >
+ <string>height:</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QLabel" name="label_22" >
+ <property name="text" >
+ <string>width:</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="4" >
+ <widget class="QSpinBox" name="pianorollHeight" >
+ <property name="minimum" >
+ <number>50</number>
+ </property>
+ <property name="maximum" >
+ <number>9999</number>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2" >
+ <widget class="QSpinBox" name="pianorollWidth" >
+ <property name="minimum" >
+ <number>50</number>
+ </property>
+ <property name="maximum" >
+ <number>9999</number>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" >
+ <widget class="QuantCombo" name="pianorollQuant" />
+ </item>
+ <item row="1" column="1" >
+ <widget class="RasterCombo" name="pianorollRaster" />
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab_7" >
+ <attribute name="title" >
+ <string>DrumEditor</string>
+ </attribute>
+ <layout class="QGridLayout" >
+ <property name="leftMargin" >
+ <number>9</number>
+ </property>
+ <property name="topMargin" >
+ <number>9</number>
+ </property>
+ <property name="rightMargin" >
+ <number>9</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>9</number>
+ </property>
+ <property name="horizontalSpacing" >
+ <number>6</number>
+ </property>
+ <property name="verticalSpacing" >
+ <number>6</number>
+ </property>
+ <item row="1" column="0" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>351</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label_27" >
+ <property name="text" >
+ <string>&lt;html>&lt;head>&lt;meta name="qrichtext" content="1" />&lt;/head>&lt;body style=" white-space: pre-wrap; font-family:Arial; font-size:10pt; font-weight:400; font-style:normal; text-decoration:none;">&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-weight:600;">Geometry&lt;/p>&lt;/body>&lt;/html></string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2" >
+ <widget class="QSpinBox" name="drumEditorWidth" >
+ <property name="minimum" >
+ <number>50</number>
+ </property>
+ <property name="maximum" >
+ <number>9999</number>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QLabel" name="label_28" >
+ <property name="text" >
+ <string>width:</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="4" >
+ <widget class="QSpinBox" name="drumEditorHeight" >
+ <property name="minimum" >
+ <number>50</number>
+ </property>
+ <property name="maximum" >
+ <number>9999</number>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3" >
+ <widget class="QLabel" name="label_26" >
+ <property name="text" >
+ <string>height:</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab_8" >
+ <attribute name="title" >
+ <string>MasterEditor</string>
+ </attribute>
+ <layout class="QGridLayout" >
+ <property name="leftMargin" >
+ <number>9</number>
+ </property>
+ <property name="topMargin" >
+ <number>9</number>
+ </property>
+ <property name="rightMargin" >
+ <number>9</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>9</number>
+ </property>
+ <property name="horizontalSpacing" >
+ <number>6</number>
+ </property>
+ <property name="verticalSpacing" >
+ <number>6</number>
+ </property>
+ <item row="1" column="0" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>331</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="0" column="4" >
+ <widget class="QSpinBox" name="masterEditorHeight" >
+ <property name="minimum" >
+ <number>50</number>
+ </property>
+ <property name="maximum" >
+ <number>9999</number>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3" >
+ <widget class="QLabel" name="label_30" >
+ <property name="text" >
+ <string>height:</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2" >
+ <widget class="QSpinBox" name="masterEditorWidth" >
+ <property name="minimum" >
+ <number>50</number>
+ </property>
+ <property name="maximum" >
+ <number>9999</number>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QLabel" name="label_29" >
+ <property name="text" >
+ <string>width:</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label_31" >
+ <property name="text" >
+ <string>&lt;html>&lt;head>&lt;meta name="qrichtext" content="1" />&lt;/head>&lt;body style=" white-space: pre-wrap; font-family:Arial; font-size:10pt; font-weight:400; font-style:normal; text-decoration:none;">&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-weight:600;">Geometry&lt;/p>&lt;/body>&lt;/html></string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab_9" >
+ <attribute name="title" >
+ <string>WaveEditor</string>
+ </attribute>
+ <layout class="QGridLayout" >
+ <property name="leftMargin" >
+ <number>9</number>
+ </property>
+ <property name="topMargin" >
+ <number>9</number>
+ </property>
+ <property name="rightMargin" >
+ <number>9</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>9</number>
+ </property>
+ <property name="horizontalSpacing" >
+ <number>6</number>
+ </property>
+ <property name="verticalSpacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="4" >
+ <widget class="QSpinBox" name="waveEditorHeight" >
+ <property name="minimum" >
+ <number>50</number>
+ </property>
+ <property name="maximum" >
+ <number>9999</number>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3" >
+ <widget class="QLabel" name="label_34" >
+ <property name="text" >
+ <string>height:</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QLabel" name="label_32" >
+ <property name="text" >
+ <string>width:</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label_33" >
+ <property name="text" >
+ <string>&lt;html>&lt;head>&lt;meta name="qrichtext" content="1" />&lt;/head>&lt;body style=" white-space: pre-wrap; font-family:Arial; font-size:10pt; font-weight:400; font-style:normal; text-decoration:none;">&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-weight:600;">Geometry&lt;/p>&lt;/body>&lt;/html></string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2" >
+ <widget class="QSpinBox" name="waveEditorWidth" >
+ <property name="minimum" >
+ <number>50</number>
+ </property>
+ <property name="maximum" >
+ <number>9999</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>351</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab_1" >
+ <attribute name="title" >
+ <string>Audio</string>
+ </attribute>
+ <layout class="QVBoxLayout" >
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <property name="leftMargin" >
+ <number>9</number>
+ </property>
+ <property name="topMargin" >
+ <number>9</number>
+ </property>
+ <property name="rightMargin" >
+ <number>9</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>9</number>
+ </property>
+ <item>
+ <widget class="QGroupBox" name="groupBox_4" >
+ <property name="title" >
+ <string>Mixer</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="leftMargin" >
+ <number>9</number>
+ </property>
+ <property name="topMargin" >
+ <number>9</number>
+ </property>
+ <property name="rightMargin" >
+ <number>9</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>9</number>
+ </property>
+ <property name="horizontalSpacing" >
+ <number>6</number>
+ </property>
+ <property name="verticalSpacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label_7" >
+ <property name="text" >
+ <string>Slider Val, Min:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QSpinBox" name="minSliderSelect" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="suffix" >
+ <string>dB</string>
+ </property>
+ <property name="minimum" >
+ <number>-100</number>
+ </property>
+ <property name="maximum" >
+ <number>0</number>
+ </property>
+ <property name="value" >
+ <number>-60</number>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2" >
+ <widget class="QLabel" name="label_39" >
+ <property name="text" >
+ <string>Max:</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3" >
+ <widget class="QSpinBox" name="maxSliderSelect" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="suffix" >
+ <string>dB</string>
+ </property>
+ <property name="value" >
+ <number>10</number>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="4" >
+ <widget class="QLabel" name="label_20" >
+ <property name="text" >
+ <string>Peak Hold Time:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="5" >
+ <widget class="QSpinBox" name="peakHoldTime" >
+ <property name="suffix" >
+ <string>ms</string>
+ </property>
+ <property name="minimum" >
+ <number>20</number>
+ </property>
+ <property name="maximum" >
+ <number>5000</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_8" >
+ <property name="text" >
+ <string>Meter Val, Min:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QSpinBox" name="minMeterSelect" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="suffix" >
+ <string>dB</string>
+ </property>
+ <property name="minimum" >
+ <number>-100</number>
+ </property>
+ <property name="maximum" >
+ <number>0</number>
+ </property>
+ <property name="singleStep" >
+ <number>10</number>
+ </property>
+ <property name="value" >
+ <number>-60</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2" >
+ <widget class="QLabel" name="label_40" >
+ <property name="text" >
+ <string>Max:</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3" >
+ <widget class="QSpinBox" name="maxMeterSelect" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="suffix" >
+ <string>dB</string>
+ </property>
+ <property name="maximum" >
+ <number>40</number>
+ </property>
+ <property name="value" >
+ <number>10</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="freewheelMode" >
+ <property name="text" >
+ <string>use JACK freewheel mode if possible</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab_2" >
+ <attribute name="title" >
+ <string>Midi</string>
+ </attribute>
+ <layout class="QVBoxLayout" >
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <property name="leftMargin" >
+ <number>8</number>
+ </property>
+ <property name="topMargin" >
+ <number>8</number>
+ </property>
+ <property name="rightMargin" >
+ <number>8</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>8</number>
+ </property>
+ <item>
+ <widget class="QGroupBox" name="groupBox_5" >
+ <property name="title" >
+ <string>Ticks</string>
+ </property>
+ <property name="flat" >
+ <bool>true</bool>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="leftMargin" >
+ <number>9</number>
+ </property>
+ <property name="topMargin" >
+ <number>9</number>
+ </property>
+ <property name="rightMargin" >
+ <number>9</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>9</number>
+ </property>
+ <property name="horizontalSpacing" >
+ <number>6</number>
+ </property>
+ <property name="verticalSpacing" >
+ <number>6</number>
+ </property>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_10" >
+ <property name="text" >
+ <string>Displayed Resolution
+(Ticks/Quarternote)</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label_9" >
+ <property name="text" >
+ <string>RTC Resolution
+(Ticks/Sec)</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QComboBox" name="rtcResolutionSelect" >
+ <item>
+ <property name="text" >
+ <string>1024</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>2048</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>4096</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>8172</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QComboBox" name="midiDivisionSelect" >
+ <property name="currentIndex" >
+ <number>3</number>
+ </property>
+ <item>
+ <property name="text" >
+ <string>48</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>96</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>192</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>384</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>768</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>1536</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>3072</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>6144</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>12288</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox_3" >
+ <property name="title" >
+ <string>Input Routing</string>
+ </property>
+ <property name="flat" >
+ <bool>true</bool>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="leftMargin" >
+ <number>8</number>
+ </property>
+ <property name="topMargin" >
+ <number>8</number>
+ </property>
+ <property name="rightMargin" >
+ <number>8</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>8</number>
+ </property>
+ <property name="horizontalSpacing" >
+ <number>6</number>
+ </property>
+ <property name="verticalSpacing" >
+ <number>6</number>
+ </property>
+ <item row="1" column="1" >
+ <widget class="QCheckBox" name="connectToAllTracks" >
+ <property name="text" >
+ <string>Connect to all Tracks</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QCheckBox" name="connectToAllDevices" >
+ <property name="text" >
+ <string>Connect to all Input Devices</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_17" >
+ <property name="text" >
+ <string>&lt;html>&lt;head>&lt;meta name="qrichtext" content="1" />&lt;/head>&lt;body style=" white-space: pre-wrap; font-family:Arial; font-weight:400; font-style:normal; text-decoration:none;">&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Preferred Input Device:&lt;/p>&lt;/body>&lt;/html></string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" >
+ <widget class="QComboBox" name="preferredInput" />
+ </item>
+ <item row="0" column="0" >
+ <widget class="QCheckBox" name="createDefaultInput" >
+ <property name="text" >
+ <string>Create Default Input Strip</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox_6" >
+ <property name="title" >
+ <string>Output Routing</string>
+ </property>
+ <property name="flat" >
+ <bool>true</bool>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="leftMargin" >
+ <number>8</number>
+ </property>
+ <property name="topMargin" >
+ <number>8</number>
+ </property>
+ <property name="rightMargin" >
+ <number>8</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>8</number>
+ </property>
+ <property name="horizontalSpacing" >
+ <number>8</number>
+ </property>
+ <property name="verticalSpacing" >
+ <number>8</number>
+ </property>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label_18" >
+ <property name="text" >
+ <string>&lt;html>&lt;head>&lt;meta name="qrichtext" content="1" />&lt;/head>&lt;body style=" white-space: pre-wrap; font-family:Arial; font-weight:400; font-style:normal; text-decoration:none;">&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Preferred Output Device:&lt;/p>&lt;/body>&lt;/html></string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" colspan="2" >
+ <widget class="QComboBox" name="preferredInstrument" />
+ </item>
+ <item row="0" column="1" >
+ <widget class="QLabel" name="label_19" >
+ <property name="text" >
+ <string>&lt;html>&lt;head>&lt;meta name="qrichtext" content="1" />&lt;/head>&lt;body style=" white-space: pre-wrap; font-family:Arial; font-weight:400; font-style:normal; text-decoration:none;">&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Preferred Instrument:&lt;/p>&lt;/body>&lt;/html></string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QComboBox" name="preferredOutput" />
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab_3" >
+ <attribute name="title" >
+ <string>GUI</string>
+ </attribute>
+ <layout class="QGridLayout" >
+ <property name="leftMargin" >
+ <number>9</number>
+ </property>
+ <property name="topMargin" >
+ <number>9</number>
+ </property>
+ <property name="rightMargin" >
+ <number>9</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>9</number>
+ </property>
+ <property name="horizontalSpacing" >
+ <number>6</number>
+ </property>
+ <property name="verticalSpacing" >
+ <number>6</number>
+ </property>
+ <item row="2" column="0" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QLineEdit" name="helpBrowser" />
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_12" >
+ <property name="text" >
+ <string>Help Browser</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QSpinBox" name="guiRefreshSelect" >
+ <property name="suffix" >
+ <string>/sec</string>
+ </property>
+ <property name="minimum" >
+ <number>2</number>
+ </property>
+ <property name="maximum" >
+ <number>100</number>
+ </property>
+ <property name="value" >
+ <number>20</number>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label_11" >
+ <property name="text" >
+ <string>GUI Refresh Rate:</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab_4" >
+ <attribute name="title" >
+ <string>RemoteControl</string>
+ </attribute>
+ <layout class="QVBoxLayout" >
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <property name="leftMargin" >
+ <number>9</number>
+ </property>
+ <property name="topMargin" >
+ <number>9</number>
+ </property>
+ <property name="rightMargin" >
+ <number>9</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>9</number>
+ </property>
+ <item>
+ <widget class="QGroupBox" name="rcGroup" >
+ <property name="toolTip" >
+ <string>enable midi remote control</string>
+ </property>
+ <property name="title" >
+ <string>Midi Remote Control</string>
+ </property>
+ <property name="flat" >
+ <bool>true</bool>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="leftMargin" >
+ <number>9</number>
+ </property>
+ <property name="topMargin" >
+ <number>9</number>
+ </property>
+ <property name="rightMargin" >
+ <number>9</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>9</number>
+ </property>
+ <property name="horizontalSpacing" >
+ <number>6</number>
+ </property>
+ <property name="verticalSpacing" >
+ <number>6</number>
+ </property>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_14" >
+ <property name="text" >
+ <string>Record</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="label_15" >
+ <property name="text" >
+ <string>Goto Left Mark</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label_13" >
+ <property name="text" >
+ <string>Stop</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="3" column="0" >
+ <widget class="QLabel" name="label_16" >
+ <property name="text" >
+ <string>Play</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2" >
+ <widget class="RecordButton" name="recordStop" />
+ </item>
+ <item row="1" column="2" >
+ <widget class="RecordButton" name="recordRecord" />
+ </item>
+ <item row="2" column="2" >
+ <widget class="RecordButton" name="recordGotoLeftMark" />
+ </item>
+ <item row="3" column="2" >
+ <widget class="RecordButton" name="recordPlay" />
+ </item>
+ <item row="0" column="1" >
+ <widget class="GreendotButton" name="stopActive" />
+ </item>
+ <item row="1" column="1" >
+ <widget class="GreendotButton" name="recordActive" />
+ </item>
+ <item row="2" column="1" >
+ <widget class="GreendotButton" name="gotoLeftMarkActive" />
+ </item>
+ <item row="3" column="1" >
+ <widget class="GreendotButton" name="playActive" />
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab_11" >
+ <attribute name="title" >
+ <string>Colors</string>
+ </attribute>
+ <layout class="QGridLayout" >
+ <property name="leftMargin" >
+ <number>9</number>
+ </property>
+ <property name="topMargin" >
+ <number>9</number>
+ </property>
+ <property name="rightMargin" >
+ <number>9</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>9</number>
+ </property>
+ <property name="horizontalSpacing" >
+ <number>6</number>
+ </property>
+ <property name="verticalSpacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="1" >
+ <widget class="QGroupBox" name="colorPalette" >
+ <property name="focusPolicy" >
+ <enum>Qt::NoFocus</enum>
+ </property>
+ <property name="title" >
+ <string>Palette</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="leftMargin" >
+ <number>9</number>
+ </property>
+ <property name="topMargin" >
+ <number>9</number>
+ </property>
+ <property name="rightMargin" >
+ <number>9</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>9</number>
+ </property>
+ <property name="horizontalSpacing" >
+ <number>6</number>
+ </property>
+ <property name="verticalSpacing" >
+ <number>6</number>
+ </property>
+ <item row="4" column="0" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="0" column="0" >
+ <widget class="QToolButton" name="palette0" >
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QToolButton" name="palette1" >
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2" >
+ <widget class="QToolButton" name="palette2" >
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3" >
+ <widget class="QToolButton" name="palette3" >
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QToolButton" name="palette4" >
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" >
+ <widget class="QToolButton" name="palette8" >
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" >
+ <widget class="QToolButton" name="palette12" >
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QToolButton" name="palette5" >
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" >
+ <widget class="QToolButton" name="palette9" >
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1" >
+ <widget class="QToolButton" name="palette13" >
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2" >
+ <widget class="QToolButton" name="palette6" >
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3" >
+ <widget class="QToolButton" name="palette7" >
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2" >
+ <widget class="QToolButton" name="palette10" >
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="3" >
+ <widget class="QToolButton" name="palette11" >
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="2" >
+ <widget class="QToolButton" name="palette14" >
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="3" >
+ <widget class="QToolButton" name="palette15" >
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="4" column="1" colspan="2" >
+ <layout class="QHBoxLayout" >
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="textLabel6_2" >
+ <property name="text" >
+ <string>V</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSlider" name="vslider" >
+ <property name="maximum" >
+ <number>255</number>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item rowspan="5" row="0" column="0" >
+ <widget class="QTreeWidget" name="itemList" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Expanding" hsizetype="Minimum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="rootIsDecorated" >
+ <bool>true</bool>
+ </property>
+ <column>
+ <property name="text" >
+ <string>Items</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QPushButton" name="addToPalette" >
+ <property name="text" >
+ <string>add to palette</string>
+ </property>
+ </widget>
+ </item>
+ <item rowspan="2" row="0" column="2" >
+ <widget class="QFrame" name="colorframe" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape" >
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Sunken</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" colspan="2" >
+ <layout class="QHBoxLayout" >
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="textLabel4_2" >
+ <property name="text" >
+ <string>H</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSlider" name="hslider" >
+ <property name="maximum" >
+ <number>255</number>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="3" column="1" colspan="2" >
+ <layout class="QHBoxLayout" >
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="textLabel5_2" >
+ <property name="text" >
+ <string>S</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSlider" name="sslider" >
+ <property name="maximum" >
+ <number>255</number>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>131</width>
+ <height>31</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="applyButton" >
+ <property name="text" >
+ <string>Apply</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="okButton" >
+ <property name="text" >
+ <string>OK</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="cancelButton" >
+ <property name="text" >
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>RecordButton</class>
+ <extends>QToolButton</extends>
+ <header>recordbutton.h</header>
+ </customwidget>
+ <customwidget>
+ <class>RasterCombo</class>
+ <extends>QComboBox</extends>
+ <header>rastercombo.h</header>
+ </customwidget>
+ <customwidget>
+ <class>QuantCombo</class>
+ <extends>QComboBox</extends>
+ <header>quantcombo.h</header>
+ </customwidget>
+ <customwidget>
+ <class>GreendotButton</class>
+ <extends>QToolButton</extends>
+ <header>greendotbutton.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources>
+ <include location="muse.qrc" />
+ </resources>
+ <connections>
+ <connection>
+ <sender>okButton</sender>
+ <signal>clicked()</signal>
+ <receiver>PreferencesDialogBase</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>278</x>
+ <y>253</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>96</x>
+ <y>254</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>cancelButton</sender>
+ <signal>clicked()</signal>
+ <receiver>PreferencesDialogBase</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>369</x>
+ <y>253</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>179</x>
+ <y>282</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/muse_qt4_evolution/muse/projectdialog.cpp b/muse_qt4_evolution/muse/projectdialog.cpp
new file mode 100644
index 00000000..c85b3446
--- /dev/null
+++ b/muse_qt4_evolution/muse/projectdialog.cpp
@@ -0,0 +1,471 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "projectdialog.h"
+#include "gconfig.h"
+#include "song.h"
+#include "icons.h"
+
+//
+// entry types for projectTree tree widget:
+//
+enum { DIR_TYPE, PROJECT_TYPE };
+
+//---------------------------------------------------------
+// ProjectTree
+//---------------------------------------------------------
+
+ProjectTree::ProjectTree(QWidget* parent)
+ : QTreeWidget(parent)
+ {
+ setAcceptDrops(true);
+ }
+
+//---------------------------------------------------------
+// itemPath
+//---------------------------------------------------------
+
+QString ProjectTree::itemPath(QTreeWidgetItem* item) const
+ {
+ QString path;
+ QTreeWidgetItem* ti = item;
+ QStringList dirComponent;
+ do {
+ dirComponent.prepend(ti->text(0));
+ ti = ti->parent();
+ } while (ti);
+ foreach (QString s, dirComponent) {
+ if (!path.isEmpty())
+ path += "/";
+ path += s;
+ }
+ return path;
+ }
+
+//---------------------------------------------------------
+// mousePressEvent
+//---------------------------------------------------------
+
+void ProjectTree::mousePressEvent(QMouseEvent* event)
+ {
+ dragStartPosition = event->pos();
+ QTreeWidget::mousePressEvent(event);
+ }
+
+//---------------------------------------------------------
+// mouseMoveEvent
+//---------------------------------------------------------
+
+void ProjectTree::mouseMoveEvent(QMouseEvent* ev)
+ {
+ QTreeWidgetItem* item = itemAt(ev->pos());
+ if (item == 0 || item->type() != PROJECT_TYPE) // || ev->button() != Qt::LeftButton)
+ return;
+ if ((ev->pos() - dragStartPosition).manhattanLength()
+ < QApplication::startDragDistance())
+ return;
+ QDrag* drag = new QDrag(this);
+ QMimeData* mimeData = new QMimeData;
+ mimeData->setText(itemPath(item));
+ drag->setMimeData(mimeData);
+ drag->setPixmap(style()->standardPixmap(QStyle::SP_FileIcon));
+ Qt::DropAction dropAction = drag->start(Qt::MoveAction);
+ if (dropAction == Qt::IgnoreAction)
+ return;
+ printf("drop action\n");
+ if (dropAction == Qt::MoveAction) {
+ printf("move action\n");
+ }
+ }
+
+//---------------------------------------------------------
+// dragEnterEvent
+//---------------------------------------------------------
+
+void ProjectTree::dragEnterEvent(QDragEnterEvent* event)
+ {
+ if (event->mimeData()->hasFormat("text/plain")) {
+ event->acceptProposedAction();
+ }
+ }
+
+//---------------------------------------------------------
+// dragMoveEvent
+//---------------------------------------------------------
+
+void ProjectTree::dragMoveEvent(QDragMoveEvent* event)
+ {
+ QTreeWidgetItem* item = itemAt(event->pos());
+ event->setAccepted(item && item->type() == DIR_TYPE);
+ }
+
+//---------------------------------------------------------
+// searchItem
+//---------------------------------------------------------
+
+QTreeWidgetItem* ProjectTree::searchItem(const QString& s, QTreeWidgetItem* p)
+ {
+ int n = p->childCount();
+ for (int i = 0; i < n; ++i) {
+ QTreeWidgetItem* item = p->child(i);
+ if (s == itemPath(item))
+ return p->takeChild(i);
+ item = searchItem(s, item);
+ if (item)
+ return item;
+ }
+ return 0;
+ }
+
+//---------------------------------------------------------
+// dropEvent
+//---------------------------------------------------------
+
+void ProjectTree::dropEvent(QDropEvent* event)
+ {
+ QTreeWidgetItem* dstItem = itemAt(event->pos());
+ if (dstItem && dstItem->type() == DIR_TYPE) {
+ QString src = event->mimeData()->text();
+ QTreeWidgetItem* srcItem = 0;
+ int n = topLevelItemCount();
+ for (int i = 0; i < n; ++i) {
+ QTreeWidgetItem* item = topLevelItem(i);
+ if (src == itemPath(item)) {
+ srcItem = takeTopLevelItem(i);
+ break;
+ }
+ srcItem = searchItem(src, item);
+ if (srcItem)
+ break;
+ }
+ if (srcItem == 0) {
+ printf("src item not found\n");
+ return;
+ }
+ QString dst = itemPath(dstItem);
+ dstItem->addChild(srcItem);
+ //
+ // TODO: - actual move project
+ // - look for name conflicts
+ // - do nothing if src==dst
+ //
+ src = QDir::homePath() + "/" + config.projectPath + "/" + src;
+ dst = QDir::homePath() + "/" + config.projectPath + "/" + dst
+ + "/" + srcItem->text(0);
+ if (src != dst) {
+ QDir dir;
+ if (!dir.rename(src, dst)) {
+printf("Rename <%s> -> <%s> failed\n", src.toLatin1().data(), dst.toLatin1().data());
+ event->acceptProposedAction();
+ }
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// processSubdirectories
+//---------------------------------------------------------
+
+void ProjectDialog::processSubdir(QTreeWidgetItem* item, const QString& p,
+ const QString& subdir, QTreeWidgetItem** current)
+ {
+ QString path(p + "/" + subdir);
+ QFile pf(path + "/" + subdir + ".med");
+ if (pf.exists()) {
+ QTreeWidgetItem* pi = new QTreeWidgetItem(item, PROJECT_TYPE);
+ pi->setText(0, subdir);
+ pi->setIcon(0, style()->standardIcon(QStyle::SP_FileIcon));
+ if (path == song->absoluteProjectPath())
+ *current = pi;
+ }
+ else {
+ QDir sd(path);
+ QStringList dl = sd.entryList(QDir::AllDirs | QDir::NoDotAndDotDot);
+ QTreeWidgetItem* pi = new QTreeWidgetItem(item, DIR_TYPE);
+ pi->setText(0, subdir);
+ itemCollapsed(pi);
+ foreach (QString s, dl)
+ processSubdir(pi, path, s, current);
+ }
+ }
+
+//---------------------------------------------------------
+// ProjectDialog
+//---------------------------------------------------------
+
+ProjectDialog::ProjectDialog(QWidget* parent)
+ : QDialog(parent)
+ {
+ setupUi(this);
+ projectTree->setSelectionBehavior(QAbstractItemView::SelectRows);
+ projectTree->setSelectionMode(QAbstractItemView::SingleSelection);
+ QDir pd(QDir::homePath() + "/" + config.projectPath);
+ QStringList el = pd.entryList(QDir::AllDirs | QDir::NoDotAndDotDot);
+ QTreeWidgetItem* current = 0;
+ foreach (QString s, el) {
+ QString path(QDir::homePath() + "/" + config.projectPath + "/" + s);
+ QFile pf(path + "/" + s + ".med");
+ if (pf.exists()) {
+ QTreeWidgetItem* pi = new QTreeWidgetItem(projectTree, PROJECT_TYPE);
+ pi->setText(0, s);
+ pi->setIcon(0, style()->standardIcon(QStyle::SP_FileIcon));
+ if (path == song->absoluteProjectPath())
+ current = pi;
+ }
+ else {
+ QDir sd(path);
+ QStringList dl = sd.entryList(QDir::AllDirs | QDir::NoDotAndDotDot);
+ if (!dl.isEmpty()) {
+ QTreeWidgetItem* pi = new QTreeWidgetItem(projectTree, DIR_TYPE);
+ pi->setText(0, s);
+ itemCollapsed(pi);
+ foreach (QString s, dl) {
+ processSubdir(pi, path, s, &current);
+ }
+ }
+ }
+ }
+ connect(projectTree,
+ SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)),
+ SLOT(currentChanged(QTreeWidgetItem*, QTreeWidgetItem*)));
+ connect(projectTree,
+ SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)),
+ SLOT(itemDoubleClicked(QTreeWidgetItem*, int)));
+ connect(projectTree,
+ SIGNAL(itemCollapsed(QTreeWidgetItem*)),
+ SLOT(itemCollapsed(QTreeWidgetItem*)));
+ connect(projectTree,
+ SIGNAL(itemExpanded(QTreeWidgetItem*)),
+ SLOT(itemExpanded(QTreeWidgetItem*)));
+ connect(projectNameEntry,
+ SIGNAL(textEdited(const QString&)),
+ SLOT(projectNameEdited(const QString&)));
+ connect(newFolder,
+ SIGNAL(clicked()),
+ SLOT(newFolderClicked()));
+
+ if (current)
+ projectTree->setCurrentItem(current);
+ else
+ currentChanged(0, 0);
+ }
+
+//---------------------------------------------------------
+// itemCollapsed
+//---------------------------------------------------------
+
+void ProjectDialog::itemCollapsed(QTreeWidgetItem* item)
+ {
+ item->setIcon(0, style()->standardIcon(QStyle::SP_DirClosedIcon));
+ }
+
+//---------------------------------------------------------
+// itemExpanded
+//---------------------------------------------------------
+
+void ProjectDialog::itemExpanded(QTreeWidgetItem* item)
+ {
+ item->setIcon(0, style()->standardIcon(QStyle::SP_DirOpenIcon));
+ }
+
+//---------------------------------------------------------
+// currentChanged
+//---------------------------------------------------------
+
+void ProjectDialog::currentChanged(QTreeWidgetItem* item, QTreeWidgetItem*)
+ {
+ bool enable = (item != 0) && (item->type() == PROJECT_TYPE);
+ createdDate->setEnabled(enable);
+ modifiedDate->setEnabled(enable);
+ comment->setEnabled(enable);
+ length->setEnabled(enable);
+
+ // newFolder->setEnabled(item == 0 || item->type() == DIR_TYPE);
+ if (!enable)
+ return;
+
+ projectNameEntry->setText(item->text(0));
+ QString pd(QDir::homePath() + "/" + config.projectPath + "/");
+
+ pd += "/" + projectTree->itemPath(item);
+
+ QFileInfo pf(pd + "/" + item->text(0) + ".med");
+ modifiedDate->setDateTime(pf.lastModified());
+
+ QTime time(0, 0, 0);
+ QDateTime date;
+
+ QFile f(pf.filePath());
+ QDomDocument doc;
+ int line, column;
+ QString err;
+ if (!doc.setContent(&f, false, &err, &line, &column)) {
+ QString col, ln, error;
+ col.setNum(column);
+ ln.setNum(line);
+ error = err + "\n at line: " + ln + " col: " + col;
+ printf("error reading med file: %s\n", error.toLatin1().data());
+ return;
+ }
+ for (QDomNode node = doc.documentElement(); !node.isNull(); node = node.nextSibling()) {
+ QDomElement e = node.toElement();
+ if (e.isNull())
+ continue;
+ if (e.tagName() == "muse") {
+ QString sversion = e.attribute("version", "1.0");
+ int major=0, minor=0;
+ sscanf(sversion.toLatin1().data(), "%d.%d", &major, &minor);
+ int version = major << 8 + minor;
+ if (version >= 0x200) {
+ for (QDomNode n1 = node.firstChild(); !n1.isNull(); n1 = n1.nextSibling()) {
+ QDomElement e = n1.toElement();
+ if (e.tagName() == "song") {
+ for (QDomNode n2 = n1.firstChild(); !n2.isNull(); n2 = n2.nextSibling()) {
+ QDomElement e = n2.toElement();
+ QString tag(e.tagName());
+ QString s(e.text());
+ if (tag == "comment")
+ comment->setPlainText(s);
+ else if (tag == "createDate")
+ date = QDateTime::fromString(e.text(), Qt::ISODate);
+ else if (tag == "LenInSec") {
+ int sec = s.toInt();
+ time = time.addSecs(sec);
+ break;
+ }
+ }
+ }
+ }
+ }
+ break;
+ }
+ }
+ length->setTime(time);
+ createdDate->setDateTime(date);
+ }
+
+//---------------------------------------------------------
+// projectNameEdited
+//---------------------------------------------------------
+
+void ProjectDialog::projectNameEdited(const QString&)
+ {
+ QTreeWidgetItem* item = projectTree->currentItem();
+ if (item && item->type() == PROJECT_TYPE) {
+ projectTree->setItemSelected(item, false);
+ projectTree->setCurrentItem(0);
+ }
+ }
+
+//---------------------------------------------------------
+// projectPath
+//---------------------------------------------------------
+
+QString ProjectDialog::projectPath() const
+ {
+ QTreeWidgetItem* item = projectTree->currentItem();
+ QString s;
+ if (item) {
+ if (item->type() == PROJECT_TYPE)
+ s = projectTree->itemPath(item);
+ else
+ s = projectTree->itemPath(item) + "/" + projectNameEntry->text();
+ }
+ else
+ s = projectNameEntry->text();
+ return s;
+ }
+
+//---------------------------------------------------------
+// projectName
+//---------------------------------------------------------
+
+QString ProjectDialog::projectName() const
+ {
+ return projectNameEntry->text();
+ }
+
+//---------------------------------------------------------
+// setProjectName
+//---------------------------------------------------------
+
+void ProjectDialog::setProjectName(const QString& name)
+ {
+ projectNameEntry->setText(name);
+ }
+
+//---------------------------------------------------------
+// newFolderClicked
+//---------------------------------------------------------
+
+void ProjectDialog::newFolderClicked()
+ {
+ QString title(tr("MusE: create new folder"));
+ QString folder = QInputDialog::getText(this, title, tr("new folder:"));
+ if (folder.isEmpty())
+ return;
+ QString path;
+ QTreeWidgetItem* item = projectTree->currentItem();
+ if (item) {
+ QStringList sl = projectTree->itemPath(item).split("/");
+ int n = sl.size() - 1;
+ for (int i = 0; i < n; ++i) {
+ if (!path.isEmpty())
+ path += "/";
+ path += sl[i];
+ }
+ if (!path.isEmpty())
+ path += "/";
+ }
+ path += folder;
+
+ QDir d;
+ if (!d.mkpath(QDir::homePath() + "/" + config.projectPath + "/" + path)) {
+ QString s("Creating new project folder <%1> failed");
+ QMessageBox::critical(this, title, s.arg(path));
+ }
+ else {
+ if (item)
+ item = item->parent();
+ QStringList pathElements = folder.split("/");
+ foreach(QString s, pathElements) {
+ QTreeWidgetItem* pi;
+ if (item == 0)
+ pi = new QTreeWidgetItem(projectTree, DIR_TYPE);
+ else
+ pi = new QTreeWidgetItem(item, DIR_TYPE);
+ pi->setText(0, s);
+ itemCollapsed(pi);
+ item = pi;
+ }
+ projectTree->setCurrentItem(item);
+ }
+ }
+
+//---------------------------------------------------------
+// itemDoubleClicked
+//---------------------------------------------------------
+
+void ProjectDialog::itemDoubleClicked(QTreeWidgetItem* item, int)
+ {
+ if (item->type() == PROJECT_TYPE)
+ accept();
+ }
+
diff --git a/muse_qt4_evolution/muse/projectdialog.h b/muse_qt4_evolution/muse/projectdialog.h
new file mode 100644
index 00000000..867ae385
--- /dev/null
+++ b/muse_qt4_evolution/muse/projectdialog.h
@@ -0,0 +1,73 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __PROJECT_DIALOG_H__
+#define __PROJECT_DIALOG_H__
+
+//---------------------------------------------------------
+// ProjectTree
+//---------------------------------------------------------
+
+class ProjectTree : public QTreeWidget {
+ Q_OBJECT
+
+ QPoint dragStartPosition;
+ virtual void mousePressEvent(QMouseEvent*);
+ virtual void mouseMoveEvent(QMouseEvent*);
+ virtual void dragEnterEvent(QDragEnterEvent*);
+ virtual void dragMoveEvent(QDragMoveEvent*);
+ virtual void dropEvent(QDropEvent*);
+
+ QTreeWidgetItem* searchItem(const QString&, QTreeWidgetItem*);
+
+ public:
+ ProjectTree(QWidget* parent = 0);
+ QString itemPath(QTreeWidgetItem*) const;
+ };
+
+#include "ui_projectdialog.h"
+
+//---------------------------------------------------------
+// ProjectDialog
+//---------------------------------------------------------
+
+class ProjectDialog : public QDialog, public Ui_ProjectDialogBase {
+ Q_OBJECT
+
+ void processSubdir(QTreeWidgetItem*, const QString&,
+ const QString&, QTreeWidgetItem**);
+
+ private slots:
+ void currentChanged(QTreeWidgetItem*, QTreeWidgetItem*);
+ void projectNameEdited(const QString&);
+ void itemCollapsed(QTreeWidgetItem*);
+ void itemExpanded(QTreeWidgetItem*);
+ void newFolderClicked();
+ void itemDoubleClicked(QTreeWidgetItem*, int);
+
+ public:
+ ProjectDialog(QWidget* parent = 0);
+ QString projectPath() const;
+ QString projectName() const;
+ void setProjectName(const QString&);
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/projectdialog.ui b/muse_qt4_evolution/muse/projectdialog.ui
new file mode 100644
index 00000000..37c08f28
--- /dev/null
+++ b/muse_qt4_evolution/muse/projectdialog.ui
@@ -0,0 +1,269 @@
+<ui version="4.0" >
+ <class>ProjectDialogBase</class>
+ <widget class="QDialog" name="ProjectDialogBase" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>574</width>
+ <height>385</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>MusE: Select Project</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="1" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>221</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="0" column="0" >
+ <widget class="QToolButton" name="newFolder" >
+ <property name="toolTip" >
+ <string>create new project folder</string>
+ </property>
+ <property name="text" >
+ <string>...</string>
+ </property>
+ <property name="icon" >
+ <iconset resource="muse.qrc" >:/xpm/folder_new.png</iconset>
+ </property>
+ </widget>
+ </item>
+ <item rowspan="2" row="0" column="2" >
+ <widget class="QGroupBox" name="groupBox" >
+ <property name="title" >
+ <string>Properties</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>3</number>
+ </property>
+ <item row="0" column="1" >
+ <widget class="QDateEdit" name="createdDate" >
+ <property name="focusPolicy" >
+ <enum>Qt::NoFocus</enum>
+ </property>
+ <property name="readOnly" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QDateEdit" name="modifiedDate" >
+ <property name="focusPolicy" >
+ <enum>Qt::NoFocus</enum>
+ </property>
+ <property name="readOnly" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" >
+ <widget class="QTimeEdit" name="length" >
+ <property name="focusPolicy" >
+ <enum>Qt::NoFocus</enum>
+ </property>
+ <property name="readOnly" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="label_4" >
+ <property name="text" >
+ <string>Length:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" >
+ <widget class="QLabel" name="label_5" >
+ <property name="text" >
+ <string>Comment:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_3" >
+ <property name="text" >
+ <string>Modified:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label_2" >
+ <property name="text" >
+ <string>Created:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0" colspan="2" >
+ <widget class="QTextEdit" name="comment" >
+ <property name="focusPolicy" >
+ <enum>Qt::NoFocus</enum>
+ </property>
+ <property name="readOnly" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="3" column="0" colspan="3" >
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>131</width>
+ <height>31</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="okButton" >
+ <property name="text" >
+ <string>OK</string>
+ </property>
+ <property name="default" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="cancelButton" >
+ <property name="text" >
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="2" column="0" colspan="3" >
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Project:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="projectNameEntry" >
+ <property name="toolTip" >
+ <string>project name</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="0" colspan="2" >
+ <widget class="ProjectTree" name="projectTree" >
+ <property name="dragEnabled" >
+ <bool>false</bool>
+ </property>
+ <property name="alternatingRowColors" >
+ <bool>true</bool>
+ </property>
+ <property name="uniformRowHeights" >
+ <bool>true</bool>
+ </property>
+ <property name="columnCount" >
+ <number>1</number>
+ </property>
+ <column>
+ <property name="text" >
+ <string>Projectlist</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>ProjectTree</class>
+ <extends>QTreeWidget</extends>
+ <header>projectdialog.h</header>
+ </customwidget>
+ </customwidgets>
+ <tabstops>
+ <tabstop>projectNameEntry</tabstop>
+ <tabstop>okButton</tabstop>
+ <tabstop>cancelButton</tabstop>
+ <tabstop>newFolder</tabstop>
+ <tabstop>projectTree</tabstop>
+ </tabstops>
+ <resources>
+ <include location="muse.qrc" />
+ </resources>
+ <connections>
+ <connection>
+ <sender>okButton</sender>
+ <signal>clicked()</signal>
+ <receiver>ProjectDialogBase</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>278</x>
+ <y>253</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>96</x>
+ <y>254</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>cancelButton</sender>
+ <signal>clicked()</signal>
+ <receiver>ProjectDialogBase</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>369</x>
+ <y>253</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>179</x>
+ <y>282</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/muse_qt4_evolution/muse/projectpropsdialog.cpp b/muse_qt4_evolution/muse/projectpropsdialog.cpp
new file mode 100644
index 00000000..eb983801
--- /dev/null
+++ b/muse_qt4_evolution/muse/projectpropsdialog.cpp
@@ -0,0 +1,64 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "projectpropsdialog.h"
+#include "song.h"
+
+#include "al/al.h"
+#include "al/tempo.h"
+
+//---------------------------------------------------------
+// ProjectPropsDialog
+//---------------------------------------------------------
+
+ProjectPropsDialog::ProjectPropsDialog(QWidget* parent)
+ : QDialog(parent)
+ {
+ setupUi(this);
+ comment->setPlainText(song->comment());
+ projectName->setText(song->projectName());
+ createdDate->setDateTime(song->createDate());
+ int n = AL::tempomap.tick2frame(song->len()) / AL::sampleRate;
+ QTime time;
+ time = time.addSecs(n);
+ length->setTime(time);
+ }
+
+//---------------------------------------------------------
+// accept
+//---------------------------------------------------------
+
+void ProjectPropsDialog::accept()
+ {
+ song->setComment(comment->toPlainText());
+ song->dirty = true;
+ QDialog::accept();
+ }
+
+//---------------------------------------------------------
+// reject
+//---------------------------------------------------------
+
+void ProjectPropsDialog::reject()
+ {
+ comment->setPlainText(song->comment());
+ QDialog::reject();
+ }
+
diff --git a/muse_qt4_evolution/muse/projectpropsdialog.h b/muse_qt4_evolution/muse/projectpropsdialog.h
new file mode 100644
index 00000000..83b7a511
--- /dev/null
+++ b/muse_qt4_evolution/muse/projectpropsdialog.h
@@ -0,0 +1,46 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __PROJECTPROPS_DIALOG_H__
+#define __PROJECTPROPS_DIALOG_H__
+
+#include "ui_projectpropsdialog.h"
+
+//---------------------------------------------------------
+// ProjectPropsDialog
+//---------------------------------------------------------
+
+class ProjectPropsDialog : public QDialog, public Ui_ProjectPropsDialogBase {
+ Q_OBJECT
+
+ QString projectComment;
+
+ public slots:
+ virtual void accept();
+ virtual void reject();
+
+ public:
+ ProjectPropsDialog(QWidget* parent = 0);
+ };
+
+#endif
+
+
+
diff --git a/muse_qt4_evolution/muse/projectpropsdialog.ui b/muse_qt4_evolution/muse/projectpropsdialog.ui
new file mode 100644
index 00000000..f431b602
--- /dev/null
+++ b/muse_qt4_evolution/muse/projectpropsdialog.ui
@@ -0,0 +1,188 @@
+<ui version="4.0" >
+ <author></author>
+ <comment></comment>
+ <exportmacro></exportmacro>
+ <class>ProjectPropsDialogBase</class>
+ <widget class="QDialog" name="ProjectPropsDialogBase" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>456</width>
+ <height>382</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>MusE: Project Properties</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="4" column="0" colspan="4" >
+ <widget class="QTextEdit" name="comment" />
+ </item>
+ <item row="3" column="0" colspan="4" >
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Comment:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="3" >
+ <widget class="QSpinBox" name="sampleRate" >
+ <property name="readOnly" >
+ <bool>true</bool>
+ </property>
+ <property name="suffix" >
+ <string>Hz</string>
+ </property>
+ <property name="maximum" >
+ <number>100000</number>
+ </property>
+ <property name="value" >
+ <number>48000</number>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2" >
+ <widget class="QLabel" name="label_5" >
+ <property name="text" >
+ <string>Samplerate:</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="label_4" >
+ <property name="text" >
+ <string>Length:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" >
+ <widget class="QTimeEdit" name="length" >
+ <property name="focusPolicy" >
+ <enum>Qt::NoFocus</enum>
+ </property>
+ <property name="readOnly" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QDateEdit" name="createdDate" >
+ <property name="focusPolicy" >
+ <enum>Qt::NoFocus</enum>
+ </property>
+ <property name="readOnly" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0" colspan="4" >
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>131</width>
+ <height>31</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="okButton" >
+ <property name="text" >
+ <string>OK</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="cancelButton" >
+ <property name="text" >
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_2" >
+ <property name="text" >
+ <string>Created:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label_6" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Project:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" colspan="3" >
+ <widget class="QLineEdit" name="projectName" />
+ </item>
+ </layout>
+ </widget>
+ <pixmapfunction></pixmapfunction>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>okButton</sender>
+ <signal>clicked()</signal>
+ <receiver>ProjectPropsDialogBase</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>278</x>
+ <y>253</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>96</x>
+ <y>254</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>cancelButton</sender>
+ <signal>clicked()</signal>
+ <receiver>ProjectPropsDialogBase</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>369</x>
+ <y>253</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>179</x>
+ <y>282</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/muse_qt4_evolution/muse/rack.cpp b/muse_qt4_evolution/muse/rack.cpp
new file mode 100644
index 00000000..dbd76804
--- /dev/null
+++ b/muse_qt4_evolution/muse/rack.cpp
@@ -0,0 +1,445 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "rack.h"
+#include "song.h"
+#include "audio.h"
+#include "icons.h"
+#include "gconfig.h"
+#include "pipeline.h"
+#include "auxplugin.h"
+#include "plugingui.h"
+#include "widgets/filedialog.h"
+#include "muse.h"
+#include "gui.h"
+
+static const int PipelineDepth = 4;
+
+//---------------------------------------------------------
+// EffectRack
+//---------------------------------------------------------
+
+EffectRack::EffectRack(QWidget* parent, AudioTrack* t, bool flag)
+ : QListWidget(parent)
+ {
+ setUniformItemSizes(true);
+ setAlternatingRowColors(true);
+ prefader = flag;
+ setAttribute(Qt::WA_DeleteOnClose, true);
+ verticalScrollBar()->setStyle(smallStyle);
+
+ track = t;
+// setFont(config.fonts[1]);
+
+ setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+
+ setSelectionMode(QAbstractItemView::SingleSelection);
+ songChanged(SC_RACK); // force update
+ connect(this, SIGNAL(itemDoubleClicked(QListWidgetItem*)),
+ this, SLOT(doubleClicked(QListWidgetItem*)));
+ connect(song, SIGNAL(songChanged(int)), SLOT(songChanged(int)));
+ setToolTip(tr("effect rack"));
+ setAcceptDrops(true);
+ }
+
+//---------------------------------------------------------
+// sizeHint
+//---------------------------------------------------------
+
+QSize EffectRack::sizeHint() const
+ {
+ QFontMetrics fm(font());
+ int h = fm.lineSpacing() * PipelineDepth + 1;
+ return QSize(STRIP_WIDTH, h);
+ }
+
+//---------------------------------------------------------
+// songChanged
+//---------------------------------------------------------
+
+void EffectRack::songChanged(int typ)
+ {
+ if (!(typ & (SC_ROUTE | SC_RACK)))
+ return;
+
+ clear();
+ Pipeline* pipe = prefader ? track->prePipe() : track->postPipe();
+ foreach (PluginI* plugin, *pipe) {
+ QListWidgetItem* item = new QListWidgetItem(this);
+ item->setText(plugin->name());
+ // tooltip should only be set if name does not fit
+ // (is elided)
+ item->setToolTip(plugin->name());
+ item->setBackgroundColor(plugin->on() ? Qt::white : Qt::gray);
+ }
+ }
+
+//---------------------------------------------------------
+// menuRequested
+//---------------------------------------------------------
+
+void EffectRack::contextMenuEvent(QContextMenuEvent* ev)
+ {
+ QPoint pt(ev->pos());
+ QListWidgetItem* item = itemAt(pt);
+
+ int idx = -1;
+ QString name;
+ Pipeline* pipe = prefader ? track->prePipe() : track->postPipe();
+
+ QMenu* menu = new QMenu;
+ QAction* upAction = menu->addAction(QIcon(*upIcon), tr("move up"));
+ QAction* downAction = menu->addAction(QIcon(*downIcon), tr("move down"));
+ QAction* removeAction = menu->addAction(tr("remove"));
+ menu->addSeparator();
+ QAction* bypassAction = menu->addAction(tr("bypass"));
+ QAction* showAction = menu->addAction(tr("show gui"));
+ QAction* showCustomAction = menu->addAction(tr("show native gui"));
+ menu->addSeparator();
+ QAction* newAction = menu->addAction(tr("New Plugin"));
+ QAction* auxAction = menu->addAction(tr("New Aux Send"));
+
+ bypassAction->setCheckable(true);
+ showAction->setCheckable(true);
+ showCustomAction->setCheckable(true);
+
+ if (!item) {
+ upAction->setEnabled(false);
+ downAction->setEnabled(false);
+ removeAction->setEnabled(false);
+ bypassAction->setEnabled(false);
+ showAction->setEnabled(false);
+ showCustomAction->setEnabled(false);
+ }
+ else {
+ idx = row(item);
+ upAction->setEnabled(idx != 0);
+ downAction->setEnabled(idx < pipe->size()-1);
+ idx = item->type();
+ showCustomAction->setEnabled(pipe->hasNativeGui(idx));
+ bypassAction->setEnabled(true);
+ showAction->setEnabled(true);
+
+ bypassAction->setChecked(!pipe->isOn(idx));
+ showAction->setChecked(pipe->guiVisible(idx));
+ showCustomAction->setChecked(pipe->nativeGuiVisible(idx));
+ }
+ if (track->type() != Track::WAVE && track->type() != Track::AUDIO_INPUT)
+ auxAction->setEnabled(false);
+
+ QAction* sel = menu->exec(mapToGlobal(pt), newAction);
+ delete menu;
+ if (sel == 0)
+ return;
+
+ if (sel == newAction) {
+ selectNew();
+ return;
+ }
+ if (sel == removeAction) {
+ audio->msgAddPlugin(track, idx, 0, prefader);
+ }
+ else if (sel == bypassAction) {
+ bool flag = !pipe->isOn(idx);
+ pipe->setOn(idx, flag);
+ }
+ else if (sel == showAction) {
+ bool flag = !pipe->guiVisible(idx);
+ pipe->showGui(idx, flag);
+ }
+ else if (sel == showCustomAction) {
+ bool flag = !pipe->nativeGuiVisible(idx);
+ pipe->showNativeGui(idx, flag);
+ }
+ else if (sel == upAction) {
+ if (idx > 0) {
+ setCurrentRow(idx-1);
+ pipe->move(idx, true);
+ }
+ }
+ else if (sel == downAction) {
+ if (idx < (PipelineDepth-1)) {
+ setCurrentRow(idx+1);
+ pipe->move(idx, false);
+ }
+ }
+ else if (sel == auxAction)
+ addPlugin(auxPlugin);
+ song->update(SC_RACK);
+ }
+
+//---------------------------------------------------------
+// doubleClicked
+// toggle gui and open requester if needed.
+//---------------------------------------------------------
+
+void EffectRack::doubleClicked(QListWidgetItem* it)
+ {
+ if (track == 0)
+ return;
+ int idx = row(it);
+ Pipeline* pipe = prefader ? track->prePipe() : track->postPipe();
+ bool flag = !pipe->guiVisible(idx);
+ pipe->showGui(idx, flag);
+ }
+
+//---------------------------------------------------------
+// startDrag
+//---------------------------------------------------------
+
+void EffectRack::startDrag(int idx)
+ {
+ QString buffer;
+ AL::Xml xml(NULL);
+ xml.setString(&buffer);
+ Pipeline* pipe = prefader ? track->prePipe() : track->postPipe();
+ if (pipe) {
+ if ((*pipe)[idx] != NULL) {
+ PluginI *plug = (*pipe)[idx];
+ xml.header();
+ xml.stag("muse version=\"1.0\"");
+ // header info
+ plug->writeConfiguration1(xml, prefader); // wC1 does not append endtag
+ // parameters
+ int noParams = plug->plugin()->parameter();
+ for (int i=0;i<noParams;i++) {
+ QString fval;
+ QString name(plug->getParameterName(i));
+ fval.setNum(plug->param(i)); // wierd stuff to avoid localization
+ QString str="<control name=\"" + name + "\" val=\""+ fval+"\" />";
+ xml.put(str.toLatin1().data());
+ printf("%s\n",str.toLatin1().data());
+ }
+ xml.etag("plugin");
+
+ xml.etag("muse");
+ }
+ else {
+ //printf("no plugin!\n");
+ return;
+ }
+ }
+ else {
+ //printf("no pipe!\n");
+ return;
+ }
+ //printf("and i wish you were here: %s\n", xml.readAll().toLatin1().data());
+ QByteArray xmldump = xml.readAll().toLatin1();
+ //printf("xmldump=%s\n",xmldump.data());
+ QDrag *drag = new QDrag(this);
+ QMimeData *mime = new QMimeData();
+ mime->setData("text/x-muse-plugin", xmldump);
+ drag->setMimeData(mime);
+/* Qt::DropAction dropAction =*/ drag->start();
+ }
+
+//---------------------------------------------------------
+// startDrag
+//---------------------------------------------------------
+
+void EffectRack::dropEvent(QDropEvent *event)
+ {
+ // printf("drop!\n");
+ QString text;
+ QListWidgetItem* i = itemAt( (event->pos()) );
+ int idx = -1;
+ if (i)
+ idx = row(i);
+
+ Pipeline* pipe = prefader ? track->prePipe() : track->postPipe();
+ if (pipe) {
+ if (i) {
+ if(!QMessageBox::question(this, tr("Replace effect"),tr("Do you really want to replace the effect %1?").arg(pipe->name(idx)),
+ tr("&Yes"), tr("&No"),
+ QString::null, 0, 1 ))
+ {
+ audio->msgAddPlugin(track, idx, 0, prefader);
+ song->update(SC_RACK);
+ }
+ else {
+ printf("nothing here\n");
+ return;
+ }
+ }
+ if(event->mimeData()->hasText())
+ {
+ //printf("has text\n");
+ text = event->mimeData()->text().trimmed();
+ if (QString(text).endsWith(".pre"))
+ {
+ QUrl url(text);
+ QString newPath = url.path();
+
+ QFile xmlfile(newPath);
+ xmlfile.open(QIODevice::ReadOnly);
+ QDomDocument doc;
+ doc.setContent(&xmlfile);
+ QDomNode node = doc.documentElement().firstChild();
+ initPlugin(node, idx);
+ }
+ }
+ else if (event->mimeData()->hasFormat("text/x-muse-plugin"))
+ {
+ QByteArray outxml = event->mimeData()->data("text/x-muse-plugin");
+ //printf("DATA:%s\n",outxml.data());
+ QDomDocument doc;
+ doc.setContent(outxml);
+ QDomNode node = doc.documentElement().firstChild();
+
+ initPlugin(node, idx);
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// dragEnterEvent
+//---------------------------------------------------------
+void EffectRack::dragEnterEvent(QDragEnterEvent *event)
+ {
+ //printf("dragEnterEvent\n");
+ //if (event->mimeData()->hasFormat("text/x-muse-plugin"))
+ event->acceptProposedAction();
+ }
+
+//---------------------------------------------------------
+// dragMoveEvent
+//---------------------------------------------------------
+void EffectRack::dragMoveEvent(QDragMoveEvent *event)
+ {
+ //printf("dragMoveEvent\n");
+ //if (event->mimeData()->hasFormat("text/x-muse-plugin"))
+ event->acceptProposedAction();
+ }
+
+//---------------------------------------------------------
+// contentsMousePressEvent
+//---------------------------------------------------------
+void EffectRack::mousePressEvent(QMouseEvent *event)
+ {
+ //printf("mousePressEvent\n");
+ if(event->button() & Qt::LeftButton) {
+ dragPos = event->pos();
+ }
+ QListWidget::mousePressEvent(event);
+ }
+
+//---------------------------------------------------------
+// contentsMouseMoveEvent
+//---------------------------------------------------------
+void EffectRack::mouseMoveEvent(QMouseEvent *event)
+ {
+ if (event->buttons() & Qt::LeftButton) {
+ int distance = (dragPos-event->pos()).manhattanLength();
+ if (distance > QApplication::startDragDistance()) {
+ QListWidgetItem *i = itemAt( event->pos() );
+ int idx = row(i);
+ startDrag(idx);
+ }
+ }
+ QListWidget::mouseMoveEvent(event);
+ }
+
+
+//---------------------------------------------------------
+// initPlugin
+//---------------------------------------------------------
+
+void EffectRack::initPlugin(QDomNode &node, int idx)
+ {
+ QDomElement e = node.toElement();
+ //QString version = e.attribute("version");
+ QString file = e.attribute("file");
+ QString label = e.attribute("label");
+
+ //printf("version=%s file=%s label=%s channel=%d\n",version.toLatin1().data(),file.toLatin1().data(), label.toLatin1().data(), channel);
+
+ //Plugin* plugin = PluginDialog::getPlugin(this);
+ Plugin* plugin = plugins.find(file, label);
+ if (plugin) {
+ PluginI* plugi = new PluginI(track);
+ if (plugi->initPluginInstance(plugin, track->channels())) {
+ printf("cannot instantiate plugin <%s>\n",
+ plugin->name().toLatin1().data());
+ delete plugi;
+ }
+ else {
+ audio->msgAddPlugin(track, idx, plugi, prefader);
+ song->update(SC_RACK);
+ int i = 0;
+ for (QDomNode n = node.firstChild(); !n.isNull(); n = n.nextSibling()) {
+ QDomElement e = n.toElement();
+ if (e.nodeName() == "control") {
+ //QString name = e.attribute("name"); // currently this value is just thrown.
+ QString value = e.attribute("val");
+ QLocale::setDefault(QLocale::C);
+ double val = value.toFloat();
+ CVal cval;
+ cval.f = val;
+ song->setControllerVal(plugi->track(), plugi->controller(i), cval);
+ i++;
+ }
+ }
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// mouseDoubleClickEvent
+//---------------------------------------------------------
+
+void EffectRack::mouseDoubleClickEvent(QMouseEvent* event)
+ {
+ QListWidgetItem* it = itemAt(event->pos());
+ if (it || (track == 0)) {
+ QListWidget::mouseDoubleClickEvent(event);
+ return;
+ }
+ selectNew();
+ }
+
+//---------------------------------------------------------
+// selectNew
+//---------------------------------------------------------
+
+void EffectRack::selectNew()
+ {
+ Plugin* plugin = PluginDialog::getPlugin(this);
+ addPlugin(plugin);
+ song->update(SC_RACK);
+ }
+
+//---------------------------------------------------------
+// addPlugin
+//---------------------------------------------------------
+
+void EffectRack::addPlugin(Plugin* plugin)
+ {
+ if (plugin == 0)
+ return;
+ PluginI* plugi = new PluginI(track);
+ if (plugi->initPluginInstance(plugin, track->channels())) {
+ printf("cannot instantiate plugin <%s>\n",
+ plugin->name().toLatin1().data());
+ delete plugi;
+ }
+ else
+ audio->msgAddPlugin(track, -1, plugi, prefader);
+ }
+
diff --git a/muse_qt4_evolution/muse/rack.h b/muse_qt4_evolution/muse/rack.h
new file mode 100644
index 00000000..c468d8b9
--- /dev/null
+++ b/muse_qt4_evolution/muse/rack.h
@@ -0,0 +1,66 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __RACK_H__
+#define __RACK_H__
+
+#include <al/xml.h>
+
+class AudioTrack;
+class Plugin;
+
+//---------------------------------------------------------
+// EffectRack
+//---------------------------------------------------------
+
+class EffectRack : public QListWidget {
+ Q_OBJECT
+
+ bool prefader;
+ AudioTrack* track;
+
+ QPoint dragPos;
+
+ virtual void contextMenuEvent(QContextMenuEvent*);
+ virtual void mouseDoubleClickEvent(QMouseEvent*);
+ void selectNew();
+
+ void startDrag(int idx);
+ void initPlugin(QDomNode &node, int idx);
+ void addPlugin(Plugin* plugin);
+
+ private slots:
+ void doubleClicked(QListWidgetItem*);
+ void songChanged(int);
+
+ protected:
+ void dropEvent(QDropEvent *event);
+ void dragEnterEvent(QDragEnterEvent *event);
+ void mousePressEvent(QMouseEvent *event);
+ void mouseMoveEvent(QMouseEvent *event);
+ void dragMoveEvent(QDragMoveEvent *event);
+
+ public:
+ EffectRack(QWidget*, AudioTrack*, bool);
+ QSize sizeHint() const;
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/revision.cpp b/muse_qt4_evolution/muse/revision.cpp
new file mode 100644
index 00000000..a1a32dca
--- /dev/null
+++ b/muse_qt4_evolution/muse/revision.cpp
@@ -0,0 +1,27 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2008 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+
+int revision =
+
+#include "revision.h"
+
+;
+
diff --git a/muse_qt4_evolution/muse/revision.h b/muse_qt4_evolution/muse/revision.h
new file mode 100644
index 00000000..51b40081
--- /dev/null
+++ b/muse_qt4_evolution/muse/revision.h
@@ -0,0 +1 @@
+345
diff --git a/muse_qt4_evolution/muse/route.cpp b/muse_qt4_evolution/muse/route.cpp
new file mode 100644
index 00000000..a529eb9c
--- /dev/null
+++ b/muse_qt4_evolution/muse/route.cpp
@@ -0,0 +1,417 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "song.h"
+#include "route.h"
+#include "audio.h"
+#include "track.h"
+#include "synth.h"
+#include "audiodev.h"
+#include "al/xml.h"
+#include "auxplugin.h"
+
+//---------------------------------------------------------
+// RouteNode
+//---------------------------------------------------------
+
+RouteNode::RouteNode()
+ {
+ track = 0;
+ channel = -1;
+ type = TRACK;
+ }
+
+RouteNode::RouteNode(Port p, int ch, RouteNodeType t)
+ {
+ port = p;
+ channel = ch;
+ type = t;
+ }
+
+RouteNode::RouteNode(Port p, RouteNodeType t)
+ {
+ port = p;
+ channel = -1;
+ type = t;
+ }
+
+RouteNode::RouteNode(Track* tr)
+ {
+ track = tr;
+ channel = -1;
+ type = TRACK;
+ }
+
+RouteNode::RouteNode(AuxPluginIF* p)
+ {
+ plugin = p;
+ channel = -1;
+ type = AUXPLUGIN;
+ }
+
+RouteNode::RouteNode(Track* tr, int ch, RouteNodeType t)
+ {
+ track = tr;
+ channel = ch;
+ type = t;
+ }
+
+//---------------------------------------------------------
+// addRoute
+// return false, if route invalid or cannot be found
+//---------------------------------------------------------
+
+bool addRoute(const Route& r)
+ {
+// printf("addRoute %s.%d:<%s> %s.%d:<%s>\n",
+// r.src.tname(), r.src.channel, r.src.name().toLatin1().data(),
+// r.dst.tname(), r.dst.channel, r.dst.name().toLatin1().data());
+
+ if (r.src.type == RouteNode::AUDIOPORT || r.src.type == RouteNode::JACKMIDIPORT) {
+ if (r.dst.type != RouteNode::TRACK) {
+ fprintf(stderr, "addRoute: bad route 1\n");
+ return false;
+ }
+ if (r.dst.track->type() != Track::AUDIO_INPUT && r.dst.track->type() != Track::MIDI_IN) {
+ fprintf(stderr, "addRoute: bad route 2\n");
+ return false;
+ }
+ RouteList* inRoutes = r.dst.track->inRoutes();
+ if (inRoutes->indexOf(r) != -1) {
+ printf(" route already there 1\n");
+ return true;
+ }
+ inRoutes->push_back(r);
+ }
+ else if (r.dst.type == RouteNode::AUDIOPORT || r.dst.type == RouteNode::JACKMIDIPORT) {
+ if (r.src.type != RouteNode::TRACK) {
+ fprintf(stderr, "addRoute: bad route 3\n");
+ return false;
+ }
+ if (r.src.track->type() != Track::AUDIO_OUTPUT && r.src.track->type() != Track::MIDI_OUT) {
+ fprintf(stderr, "addRoute: bad route 4, tracktype %s\n", r.src.track->cname().toLatin1().data());
+ return false;
+ }
+ RouteList* outRoutes = r.src.track->outRoutes();
+ if (outRoutes->indexOf(r) != -1) {
+ printf(" route already there 2\n");
+ return true;
+ }
+ outRoutes->push_back(r);
+ }
+ else if (r.src.type == RouteNode::AUXPLUGIN) {
+ RouteList* inRoutes = r.dst.track->inRoutes();
+ inRoutes->insert(inRoutes->begin(), r);
+ }
+ else {
+ if (r.src.track->outRoutes()->indexOf(r) != -1) {
+ printf(" route already there 3\n");
+ return true;
+ }
+ r.src.track->outRoutes()->push_back(r);
+ r.dst.track->inRoutes()->push_back(r);
+ }
+ return true;
+ }
+
+//---------------------------------------------------------
+// removeRoute
+//---------------------------------------------------------
+
+void removeRoute(const Route& r)
+ {
+// printf("removeRoute %s.%d:<%s> %s.%d:<%s>\n",
+// r.src.tname(), r.src.channel, r.src.name().toLatin1().data(),
+// r.dst.tname(), r.dst.channel, r.dst.name().toLatin1().data());
+ if (r.src.type == RouteNode::AUDIOPORT || r.src.type == RouteNode::JACKMIDIPORT) {
+ if (r.dst.type != RouteNode::TRACK) {
+ fprintf(stderr, "removeRoute: bad route 1\n");
+ goto error;
+ }
+ if (r.dst.track->type() != Track::AUDIO_INPUT
+ && r.dst.track->type() != Track::AUDIO_SOFTSYNTH
+ && r.dst.track->type() != Track::MIDI_IN) {
+ fprintf(stderr, "removeRoute: bad route 2\n");
+ goto error;
+ }
+ RouteList* inRoutes = r.dst.track->inRoutes();
+ iRoute i;
+ for (i = inRoutes->begin(); i != inRoutes->end(); ++i) {
+ if (*i == r) {
+ inRoutes->erase(i);
+ break;
+ }
+ }
+ }
+ else if (r.dst.type == RouteNode::AUDIOPORT || r.dst.type == RouteNode::JACKMIDIPORT) {
+ if (r.src.type != RouteNode::TRACK) {
+ fprintf(stderr, "removeRoute: bad route 3\n");
+ goto error;
+ }
+ if (r.src.track->type() != Track::AUDIO_OUTPUT && r.src.track->type() != Track::MIDI_OUT) {
+ fprintf(stderr, "removeRoute: bad route 4\n");
+ goto error;
+ }
+ RouteList* outRoutes = r.src.track->outRoutes();
+ iRoute i;
+ for (i = outRoutes->begin(); i != outRoutes->end(); ++i) {
+ if (*i == r) {
+ outRoutes->erase(i);
+ break;
+ }
+ }
+ }
+ else if (r.src.type == RouteNode::AUXPLUGIN) {
+ if (r.dst.type != RouteNode::TRACK) {
+ fprintf(stderr, "removeRoute: bad route 5\n");
+ goto error;
+ }
+ RouteList* inRoutes = r.dst.track->inRoutes();
+ for (iRoute i = inRoutes->begin(); i != inRoutes->end(); ++i) {
+ if (*i == r) {
+ inRoutes->erase(i);
+ break;
+ }
+ }
+ }
+ else {
+ RouteList* outRoutes = r.src.track->outRoutes();
+ for (iRoute i = outRoutes->begin(); i != outRoutes->end(); ++i) {
+ if (*i == r) {
+ outRoutes->erase(i);
+ break;
+ }
+ }
+ RouteList* inRoutes = r.dst.track->inRoutes();
+ for (iRoute i = inRoutes->begin(); i != inRoutes->end(); ++i) {
+ if (*i == r) {
+ inRoutes->erase(i);
+ break;
+ }
+ }
+ }
+ return;
+error:
+ printf("removeRoute %s.%d:<%s> %s.%d:<%s>\n",
+ r.src.tname(), r.src.channel, r.src.name().toLatin1().data(),
+ r.dst.tname(), r.dst.channel, r.dst.name().toLatin1().data());
+ abort();
+ }
+
+//---------------------------------------------------------
+// track2name
+// create string name representation for audio node
+//---------------------------------------------------------
+
+static QString track2name(const Track* n)
+ {
+ return n ? n->name() : "None";
+ }
+
+//---------------------------------------------------------
+// name
+// create string name representation for audio node
+//---------------------------------------------------------
+
+QString RouteNode::name() const
+ {
+ switch (type) {
+ case TRACK:
+ return track2name(track);
+ case AUDIOPORT:
+ case JACKMIDIPORT:
+ if (port.isZero())
+ return QString("0");
+ return audioDriver->portName(port);
+ case AUXPLUGIN:
+ return plugin->pluginInstance()->name();
+ }
+ return QString("?");
+ }
+
+//---------------------------------------------------------
+// read
+//---------------------------------------------------------
+
+void Song::readRoute(QDomNode n)
+ {
+ RouteNode s, d;
+ for (QDomNode node = n.firstChild(); !node.isNull(); node = node.nextSibling()) {
+ QDomElement e = node.toElement();
+ if (e.tagName() == "src")
+ s.read(node);
+ else if (e.tagName() == "dst")
+ d.read(node);
+ else
+ printf("MusE:readRoute: unknown tag %s\n", e.tagName().toLatin1().data());
+ }
+ if (!s.isValid()) { // source port not found?
+ printf("Song::readRoute(): invalid source port: %s.%d:<%s> - %s.%d:<%s>\n",
+ s.tname(), s.channel, s.name().toLatin1().data(),
+ d.tname(), d.channel, d.name().toLatin1().data());
+ return;
+ }
+ if (!d.isValid()) { // destination port not found?
+ printf("Song::readRoute(): invalid destination port: %s.%d:<%s> - %s.%d:<%s>\n",
+ s.tname(), s.channel, s.name().toLatin1().data(),
+ d.tname(), d.channel, d.name().toLatin1().data());
+ return;
+ }
+ Route r(s, d);
+ r.disconnected = true;
+ addRoute(r);
+ }
+
+//---------------------------------------------------------
+// dump
+//---------------------------------------------------------
+
+void RouteNode::dump() const
+ {
+ printf("RouteNode %p dump: <%s> channel %d, type %s\n",
+ track, name().toLatin1().data(), channel, tname());
+ }
+
+//---------------------------------------------------------
+// operator==
+//---------------------------------------------------------
+
+bool RouteNode::operator==(const RouteNode& a) const
+ {
+ if (type != a.type)
+ return false;
+ switch(type) {
+ case TRACK:
+ return (channel == a.channel) && (track == a.track);
+ case JACKMIDIPORT:
+ case AUDIOPORT:
+ return port == a.port;
+ case AUXPLUGIN:
+ return plugin == a.plugin;
+ }
+ return false;
+ }
+
+//---------------------------------------------------------
+// tname
+//---------------------------------------------------------
+
+const char* RouteNode::tname(RouteNodeType t)
+ {
+ static const char* names[] = {
+ "TRACK", "AUDIOPORT", "JACKMIDIPORT", "AUX"
+ };
+ if (t > (int)(sizeof(names)/sizeof(*names)))
+ return "???";
+ return names[t];
+ }
+
+const char* RouteNode::tname() const
+ {
+ return tname(type);
+ }
+
+//---------------------------------------------------------
+// write
+//---------------------------------------------------------
+
+void RouteNode::write(Xml& xml, const char* label) const
+ {
+ if (channel != -1)
+ xml.tagE(QString("%1 type=\"%2\" channel=\"%3\" name=\"%4\"")
+ .arg(label).arg(tname()).arg(channel + 1).arg(name()));
+ else
+ xml.tagE(QString("%1 type=\"%2\" name=\"%3\"")
+ .arg(label).arg(tname()).arg(name()));
+ }
+
+//---------------------------------------------------------
+// read
+//---------------------------------------------------------
+
+void RouteNode::read(QDomNode node)
+ {
+ QDomElement e = node.toElement();
+ channel = e.attribute("channel","0").toInt() - 1;
+ QString s = e.attribute("name");
+ QString st = e.attribute("type", "TRACK");
+
+ if (st == "TRACK") {
+ type = RouteNode::TRACK;
+ track = 0;
+ TrackList* tl = song->tracks();
+ for (iTrack i = tl->begin(); i != tl->end(); ++i) {
+ Track* t = *i;
+ if (t->name() == s) {
+ track = t;
+ break;
+ }
+ }
+ if (track == 0)
+ printf("Route::read(): track <%s> not found\n", s.toLatin1().data());
+ }
+ else if (st == "AUDIOPORT") {
+ type = RouteNode::AUDIOPORT;
+ port = audioDriver->findPort(s);
+ if (port.isZero())
+ printf("Route::read(): audioport <%s> not found\n", s.toLatin1().data());
+ }
+ else if (st == "JACKMIDIPORT") {
+ type = RouteNode::JACKMIDIPORT;
+ port = audioDriver->findPort(s);
+ if (port.isZero())
+ printf("Route::read(): jack midiport <%s> not found\n", s.toLatin1().data());
+ }
+ else if (st == "AUX") {
+ type = RouteNode::AUXPLUGIN;
+ plugin = 0;
+ TrackList* tl = song->tracks();
+ for (iTrack i = tl->begin(); i != tl->end(); ++i) {
+ if ((*i)->type() == Track::WAVE || (*i)->type() == Track::AUDIO_INPUT) {
+ AudioTrack* t = (AudioTrack*)*i;
+ QList<AuxPluginIF*> pl = t->preAux();
+ foreach(AuxPluginIF* p, pl) {
+ if (p->pluginInstance()->name() == s) {
+ plugin = p;
+ break;
+ }
+ }
+ if (plugin)
+ break;
+ pl = t->postAux();
+ foreach(AuxPluginIF* p, pl) {
+ if (p->pluginInstance()->name() == s) {
+ plugin = p;
+ break;
+ }
+ }
+ if (plugin)
+ break;
+ }
+ }
+ if (plugin == 0)
+ printf("Route::read(): plugin <%s> not found\n", s.toLatin1().data());
+ }
+ else {
+ printf("Route::read(): unknown type <%s>\n", st.toLatin1().data());
+ type = RouteNode::TRACK;
+ }
+ }
+
diff --git a/muse_qt4_evolution/muse/route.h b/muse_qt4_evolution/muse/route.h
new file mode 100644
index 00000000..386ea636
--- /dev/null
+++ b/muse_qt4_evolution/muse/route.h
@@ -0,0 +1,108 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __ROUTE_H__
+#define __ROUTE_H__
+
+class Track;
+class AuxPluginIF;
+
+namespace AL {
+ class Xml;
+ };
+using AL::Xml;
+
+#include "driver.h"
+
+//---------------------------------------------------------
+// RouteNode
+// this describes one endpoint of a route
+// Track
+// Track/Channel
+// AuxPlugin
+// Port
+//---------------------------------------------------------
+
+struct RouteNode {
+ enum RouteNodeType {
+ TRACK, AUDIOPORT, JACKMIDIPORT, AUXPLUGIN
+ };
+
+ Port port;
+ union {
+ Track* track;
+ AuxPluginIF* plugin;
+ };
+ int channel;
+ RouteNodeType type;
+
+ RouteNode();
+ RouteNode(Port, int, RouteNodeType);
+ RouteNode(Port, RouteNodeType);
+ RouteNode(Track*);
+ RouteNode(Track*, int, RouteNodeType t = TRACK);
+ RouteNode(AuxPluginIF*);
+
+ bool isPortType() const {
+ return type==AUDIOPORT || type == JACKMIDIPORT;
+ }
+ bool isValid() const {
+ return (isPortType() && !port.isZero())
+ || ((type == TRACK) && track)
+ || ((type == AUXPLUGIN) && plugin);
+ }
+ QString name() const;
+ void read(QDomNode node);
+ void write(Xml&, const char* name) const;
+
+ bool operator==(const RouteNode& a) const;
+ void dump() const;
+ const char* tname() const;
+ static const char* tname(RouteNodeType);
+ };
+
+//---------------------------------------------------------
+// Route
+//---------------------------------------------------------
+
+struct Route {
+ RouteNode src;
+ RouteNode dst;
+ bool disconnected; // if true, do not remove route in graphChanged()
+ // or removeConnection()
+
+ Route() { disconnected = false;}
+ Route(const RouteNode& s, const RouteNode& d) : src(s), dst(d) { disconnected = false;}
+ bool operator==(const Route& a) const {
+ return (src==a.src) && (dst==a.dst);
+ }
+ };
+
+Q_DECLARE_METATYPE(struct Route);
+
+typedef QList<Route> RouteList;
+typedef RouteList::iterator iRoute;
+typedef RouteList::const_iterator ciRoute;
+
+extern bool addRoute(const Route&);
+extern void removeRoute(const Route&);
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/routedialog.cpp b/muse_qt4_evolution/muse/routedialog.cpp
new file mode 100644
index 00000000..a2f3b584
--- /dev/null
+++ b/muse_qt4_evolution/muse/routedialog.cpp
@@ -0,0 +1,196 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "routedialog.h"
+#include "track.h"
+#include "song.h"
+#include "audio.h"
+#include "jackaudio.h"
+
+//---------------------------------------------------------
+// RouteDialog
+//---------------------------------------------------------
+
+RouteDialog::RouteDialog(QWidget* parent)
+ : QDialog(parent)
+ {
+ setupUi(this);
+ connect(routeList, SIGNAL(selectionChanged()), SLOT(routeSelectionChanged()));
+ connect(newSrcList, SIGNAL(selectionChanged()), SLOT(srcSelectionChanged()));
+ connect(newDstList, SIGNAL(selectionChanged()), SLOT(dstSelectionChanged()));
+ connect(removeButton, SIGNAL(clicked()), SLOT(removeRoute()));
+ connect(connectButton, SIGNAL(clicked()), SLOT(addRoute()));
+ connect(song, SIGNAL(songChanged(int)), SLOT(songChanged(int)));
+ routingChanged();
+ }
+
+//---------------------------------------------------------
+// routingChanged
+//---------------------------------------------------------
+
+void RouteDialog::routingChanged()
+ {
+ //---------------------------------------------------
+ // populate lists
+ //---------------------------------------------------
+
+ routeList->clear();
+ newSrcList->clear();
+ newDstList->clear();
+
+#if 0 //TODO3
+ TrackList* tl = song->tracks();
+ for (ciTrack i = tl->begin(); i != tl->end(); ++i) {
+ if ((*i)->isMidiTrack())
+ continue;
+ Track* track = *i;
+ if (track->type() == Track::AUDIO_INPUT) {
+ for (int channel = 0; channel < track->channels(); ++channel)
+ newDstList->insertItem(Route(track, channel).name());
+ const RouteList* rl = track->inRoutes();
+ for (ciRoute r = rl->begin(); r != rl->end(); ++r) {
+ Route dst(track->name(), r->channel, Route::AUDIOPORT);
+ new QListWidgetItem(routeList, r->name(), dst.name());
+ }
+ }
+ else
+ newDstList->insertItem(Route(track, -1).name());
+ if (track->type() == Track::AUDIO_OUTPUT) {
+ for (int channel = 0; channel < track->channels(); ++channel) {
+ Route r(track, channel);
+ newSrcList->insertItem(r.name());
+ }
+ }
+ else
+ newSrcList->insertItem(Route(track, -1).name());
+
+ const RouteList* rl = track->outRoutes();
+ for (ciRoute r = rl->begin(); r != rl->end(); ++r) {
+ QString src(track->name());
+ if (track->type() == Track::AUDIO_OUTPUT) {
+ Route s(src, r->channel, Route::AUDIOPORT);
+ src = s.name();
+ }
+ new QListWidgetItem(routeList, src, r->name());
+ }
+ }
+
+ std::list<QString> sl = audioDriver->outputPorts();
+ for (std::list<QString>::iterator i = sl.begin(); i != sl.end(); ++i)
+ newSrcList->insertItem(*i);
+ sl = audioDriver->inputPorts();
+ for (std::list<QString>::iterator i = sl.begin(); i != sl.end(); ++i)
+ newDstList->insertItem(*i);
+#endif
+ routeSelectionChanged(); // init remove button
+ srcSelectionChanged(); // init select button
+ }
+
+//---------------------------------------------------------
+// songChanged
+//---------------------------------------------------------
+
+void RouteDialog::songChanged(int v)
+ {
+ if (v & (SC_TRACK_INSERTED | SC_TRACK_REMOVED | SC_ROUTE)) {
+ routingChanged();
+ }
+ }
+
+//---------------------------------------------------------
+// routeSelectionChanged
+//---------------------------------------------------------
+
+void RouteDialog::routeSelectionChanged()
+ {
+//TD QListWidgetItem* item = routeList->selectedItem();
+// removeButton->setEnabled(item != 0);
+ }
+
+//---------------------------------------------------------
+// removeRoute
+//---------------------------------------------------------
+
+void RouteDialog::removeRoute()
+ {
+#if 0 //TD
+ QListWidgetItem* item = routeList->selectedItem();
+ if (item == 0)
+ return;
+ audio->msgRemoveRoute(Route(item->text(0), -1, Route::TRACK), Route(item->text(1), -1, Route::AUDIOPORT));
+ delete item;
+#endif
+ }
+
+//---------------------------------------------------------
+// addRoute
+//---------------------------------------------------------
+
+void RouteDialog::addRoute()
+ {
+#if 0 //TD
+ QListWidgetItem* srcItem = newSrcList->selectedItem();
+ QListWidgetItem* dstItem = newDstList->selectedItem();
+ if (srcItem == 0 || dstItem == 0)
+ return;
+ audio->msgAddRoute(Route(srcItem->text(), -1, Route::TRACK), Route(dstItem->text(), -1, Route::AUDIOPORT));
+ new QListWidgetItem(routeList, srcItem->text(), dstItem->text());
+#endif
+ }
+
+//---------------------------------------------------------
+// srcSelectionChanged
+//---------------------------------------------------------
+
+void RouteDialog::srcSelectionChanged()
+ {
+#if 0 //TD
+ QListWidgetItem* srcItem = newSrcList->selectedItem();
+ QListWidgetItem* dstItem = newDstList->selectedItem();
+ connectButton->setEnabled((srcItem != 0)
+ && (dstItem != 0)
+ && checkRoute(srcItem->text(), dstItem->text()));
+#endif
+ }
+
+//---------------------------------------------------------
+// dstSelectionChanged
+//---------------------------------------------------------
+
+void RouteDialog::dstSelectionChanged()
+ {
+#if 0 //TD
+ QListWidgetItem* dstItem = newDstList->selectedItem();
+ QListWidgetItem* srcItem = newSrcList->selectedItem();
+ connectButton->setEnabled((srcItem != 0)
+ && (dstItem != 0)
+ && checkRoute(srcItem->text(), dstItem->text()));
+#endif
+ }
+
+//---------------------------------------------------------
+// closeEvent
+//---------------------------------------------------------
+
+void RouteDialog::closeEvent(QCloseEvent* e)
+ {
+ emit closed();
+ e->accept();
+ }
diff --git a/muse_qt4_evolution/muse/routedialog.h b/muse_qt4_evolution/muse/routedialog.h
new file mode 100644
index 00000000..2bcbf471
--- /dev/null
+++ b/muse_qt4_evolution/muse/routedialog.h
@@ -0,0 +1,53 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __ROUTEDIALOG_H__
+#define __ROUTEDIALOG_H__
+
+#include "ui_routedialog.h"
+
+//---------------------------------------------------------
+// RouteDialog
+//---------------------------------------------------------
+
+class RouteDialog : public QDialog, public Ui::RouteDialogBase {
+ Q_OBJECT
+
+ virtual void closeEvent(QCloseEvent*);
+ void routingChanged();
+
+ private slots:
+ void routeSelectionChanged();
+ void removeRoute();
+ void addRoute();
+ void srcSelectionChanged();
+ void dstSelectionChanged();
+ void songChanged(int);
+
+ signals:
+ void closed();
+
+ public:
+ RouteDialog(QWidget* parent);
+ };
+
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/routedialog.ui b/muse_qt4_evolution/muse/routedialog.ui
new file mode 100644
index 00000000..be34c451
--- /dev/null
+++ b/muse_qt4_evolution/muse/routedialog.ui
@@ -0,0 +1,170 @@
+<ui version="4.0" >
+ <author></author>
+ <comment></comment>
+ <exportmacro></exportmacro>
+ <class>RouteDialogBase</class>
+ <widget class="QDialog" name="RouteDialogBase" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>316</width>
+ <height>383</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle" >
+ <string>MusE: Routing</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>4</number>
+ </property>
+ <property name="spacing" >
+ <number>4</number>
+ </property>
+ <item>
+ <widget class="QGroupBox" name="groupBox4" >
+ <property name="title" >
+ <string>Add Route</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>4</number>
+ </property>
+ <property name="spacing" >
+ <number>4</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QGroupBox" name="groupBox2" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title" >
+ <string>Source:</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>2</number>
+ </property>
+ <property name="spacing" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QListWidget" name="newSrcList" />
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox3" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title" >
+ <string>Destination:</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>2</number>
+ </property>
+ <property name="spacing" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QListWidget" name="newDstList" />
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QToolButton" name="connectButton" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>connect source to destination</string>
+ </property>
+ <property name="text" >
+ <string>Connect</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox1" >
+ <property name="title" >
+ <string>Current Routes</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>4</number>
+ </property>
+ <property name="spacing" >
+ <number>4</number>
+ </property>
+ <item>
+ <widget class="QListWidget" name="routeList" />
+ </item>
+ <item>
+ <widget class="QToolButton" name="removeButton" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>remove selected route</string>
+ </property>
+ <property name="text" >
+ <string>Remove</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11" />
+ <pixmapfunction>qPixmapFromMimeSource</pixmapfunction>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/muse_qt4_evolution/muse/selectfilter.h b/muse_qt4_evolution/muse/selectfilter.h
new file mode 100644
index 00000000..a28e6947
--- /dev/null
+++ b/muse_qt4_evolution/muse/selectfilter.h
@@ -0,0 +1,51 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __SELECTFILTER_H__
+#define __SELECTFILTER_H__
+
+//---------------------------------------------------------
+// SelectFilter
+//---------------------------------------------------------
+
+class SelectFilter :public QObject
+ {
+ QWidget* w;
+ Track* t;
+
+ protected:
+ bool eventFilter(QObject*, QEvent* ev)
+ {
+ if (ev->type() == QEvent::MouseButtonPress) {
+ w->setFocus();
+ song->selectTrack(t);
+ }
+ return false;
+ }
+ public:
+ SelectFilter(QObject* parent, QWidget* widget, Track* track)
+ : QObject(parent) {
+ w = widget;
+ t = track;
+ }
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/seqmsg.cpp b/muse_qt4_evolution/muse/seqmsg.cpp
new file mode 100644
index 00000000..cbd0d0dd
--- /dev/null
+++ b/muse_qt4_evolution/muse/seqmsg.cpp
@@ -0,0 +1,621 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "song.h"
+#include "instruments/minstrument.h"
+#include "muse.h"
+#include "mixer.h"
+#include "al/tempo.h"
+#include "al/sig.h"
+#include "audio.h"
+#include "audiodev.h"
+#include "audio.h"
+#include "arranger.h"
+#include "plugin.h"
+#include "midi.h"
+#include "midictrl.h"
+#include "midiplugin.h"
+#include "part.h"
+#include "midioutport.h"
+#include "midiinport.h"
+
+//---------------------------------------------------------
+// sendMsg
+//---------------------------------------------------------
+
+void Audio::sendMsg(AudioMsg* m)
+ {
+ if (audioState == AUDIO_RUNNING) {
+ msg = m;
+ char c;
+ int rv = read(fromThreadFdr, &c, 1);
+ if (rv != 1)
+ perror("Audio: read pipe failed");
+ }
+ else {
+ // if audio is not running (during initialization)
+ // process commands immediatly
+ msg = m;
+ processMsg();
+ }
+ }
+
+//---------------------------------------------------------
+// sendMessage
+// send request from gui to sequencer
+// wait until request is processed
+//---------------------------------------------------------
+
+bool Audio::sendMessage(AudioMsg* m, bool doUndo)
+ {
+ if (doUndo)
+ song->startUndo();
+ sendMsg(m);
+ if (doUndo)
+ song->endUndo(0); // song->endMsgCmd();
+ return false;
+ }
+
+//---------------------------------------------------------
+// msgRoute
+//---------------------------------------------------------
+
+extern bool mops;
+
+void Audio::msgRoute(bool add, Route r)
+ {
+ if (add)
+ msgAddRoute(r);
+ else
+ msgRemoveRoute(r);
+ song->update(SC_ROUTE);
+ }
+
+//---------------------------------------------------------
+// msgRemoveRoute
+//---------------------------------------------------------
+
+void Audio::msgRemoveRoute(Route r)
+ {
+ if (r.src.type == RouteNode::AUDIOPORT) {
+ AudioInput* ai = (AudioInput*)(r.dst.track);
+ audioDriver->disconnect(r.src.port, ai->jackPort(r.dst.channel));
+ }
+ else if (r.src.type == RouteNode::JACKMIDIPORT) {
+ audioDriver->disconnect(r.src.port, ((MidiInPort*)r.dst.track)->jackPort());
+ }
+ else if (r.dst.type == RouteNode::AUDIOPORT) {
+ AudioOutput* ai = (AudioOutput*)(r.src.track);
+ audioDriver->disconnect(ai->jackPort(r.src.channel), r.dst.port);
+ }
+ else if (r.dst.type == RouteNode::JACKMIDIPORT) {
+ audioDriver->disconnect(((MidiOutPort*)r.src.track)->jackPort(), r.dst.port);
+ }
+ msgRemoveRoute1(r);
+ }
+
+//---------------------------------------------------------
+// msgRemoveRoute1
+//---------------------------------------------------------
+
+void Audio::msgRemoveRoute1(Route r)
+ {
+ AudioMsg msg;
+ msg.id = AUDIO_ROUTEREMOVE;
+ msg.route = r;
+ sendMsg(&msg);
+ }
+
+//---------------------------------------------------------
+// msgAddRoute
+//---------------------------------------------------------
+
+void Audio::msgAddRoute(Route r)
+ {
+ msgAddRoute1(r);
+ if (r.src.type == RouteNode::AUDIOPORT) {
+ AudioInput* ai = (AudioInput*)r.dst.track;
+ audioDriver->connect(r.src.port, ai->jackPort(r.dst.channel));
+ }
+ else if (r.src.type == RouteNode::JACKMIDIPORT) {
+ audioDriver->connect(r.src.port, ((MidiInPort*)r.dst.track)->jackPort());
+ }
+ else if (r.dst.type == RouteNode::AUDIOPORT) {
+ AudioOutput* ao = (AudioOutput*)r.src.track;
+printf("msgAddRoute to AUDIPORT %p\n", ao);
+ audioDriver->connect(ao->jackPort(r.src.channel), r.dst.port);
+ }
+ else if (r.dst.type == RouteNode::JACKMIDIPORT) {
+ audioDriver->connect(((MidiOutPort*)r.src.track)->jackPort(), r.dst.port);
+ }
+ }
+
+//---------------------------------------------------------
+// msgAddRoute1
+//---------------------------------------------------------
+
+void Audio::msgAddRoute1(Route r)
+ {
+ AudioMsg msg;
+ msg.id = AUDIO_ROUTEADD;
+ msg.route = r;
+ sendMsg(&msg);
+ }
+
+//---------------------------------------------------------
+// msgAddMidiPlugin
+//---------------------------------------------------------
+
+void Audio::msgAddMidiPlugin(MidiTrackBase* track, int idx, MidiPluginI* plugin)
+ {
+ AudioMsg msg;
+ msg.id = AUDIO_ADDMIDIPLUGIN;
+ msg.track = track;
+ msg.ival = idx;
+ msg.mplugin = plugin;
+ MidiPluginI* oldPlugin = plugin ? 0 : track->plugin(idx);
+ sendMsg(&msg);
+ if (oldPlugin)
+ delete oldPlugin;
+ }
+
+//---------------------------------------------------------
+// msgAddPlugin
+//---------------------------------------------------------
+
+void Audio::msgAddPlugin(AudioTrack* track, int idx, PluginI* plugin,
+ bool prefader)
+ {
+ AudioMsg msg;
+ msg.id = AUDIO_ADDPLUGIN;
+ msg.track = track;
+ msg.ival = idx;
+ msg.iival = prefader;
+ msg.plugin = plugin;
+ sendMsg(&msg);
+ }
+
+//---------------------------------------------------------
+// msgSetChannels
+//---------------------------------------------------------
+
+void Audio::msgSetChannels(AudioTrack* node, int n)
+ {
+ if (n == node->channels())
+ return;
+ QString name = node->name();
+ int mc = std::max(n, node->channels());
+
+ if (!name.isEmpty()) {
+ if (node->type() == Track::AUDIO_INPUT) {
+ AudioInput* ai = (AudioInput*)node;
+ for (int i = 0; i < mc; ++i) {
+ if (i < n && ai->jackPort(i).isZero()) {
+ char buffer[128];
+ snprintf(buffer, 128, "%s-%d", name.toLatin1().data(), i);
+ ai->setJackPort(audioDriver->registerInPort(QString(buffer), false), i);
+ }
+ else if ((i >= n) && ai->jackPort(i).isZero()) {
+ RouteList* ir = node->inRoutes();
+ for (iRoute ii = ir->begin(); ii != ir->end(); ++ii) {
+ Route r = *ii;
+ if ((r.src.type == RouteNode::AUDIOPORT) && (r.src.channel == i)) {
+ msgRemoveRoute(r);
+ break;
+ }
+ }
+ audioDriver->unregisterPort(ai->jackPort(i));
+ ai->setJackPort(Port(), i);
+ }
+ }
+ }
+ else if (node->type() == Track::AUDIO_OUTPUT) {
+ AudioOutput* ao = (AudioOutput*)node;
+ for (int i = 0; i < mc; ++i) {
+ Port port = ao->jackPort(i);
+ if (i < n && port.isZero()) {
+ char buffer[128];
+ snprintf(buffer, 128, "%s-%d", name.toLatin1().data(), i);
+ ao->setJackPort(audioDriver->registerOutPort(QString(buffer), false), i);
+ }
+ else if (i >= n && !port.isZero()) {
+ RouteList* ir = node->outRoutes();
+ for (iRoute ii = ir->begin(); ii != ir->end(); ++ii) {
+ Route r = *ii;
+ if ((r.src.type == RouteNode::AUDIOPORT) && (r.src.channel == i)) {
+ msgRemoveRoute(r);
+ break;
+ }
+ }
+ audioDriver->unregisterPort(ao->jackPort(i));
+ ao->setJackPort(Port(), i);
+ }
+ }
+ }
+ }
+ AudioMsg msg;
+ msg.id = AUDIO_SET_CHANNELS;
+ msg.track = node;
+ msg.ival = n;
+ sendMsg(&msg);
+ }
+
+//---------------------------------------------------------
+// msgSetSegSize
+//---------------------------------------------------------
+
+void Audio::msgSetSegSize(int bs, int sr)
+ {
+ AudioMsg msg;
+ msg.id = AUDIO_SET_SEG_SIZE;
+ msg.ival = bs;
+ msg.iival = sr;
+ sendMsg(&msg);
+ }
+
+//---------------------------------------------------------
+// msgSeek
+//---------------------------------------------------------
+
+void Audio::msgSeek(const Pos& pos)
+ {
+ audioDriver->seekTransport(pos.frame());
+ }
+
+//---------------------------------------------------------
+// msgUndo
+//---------------------------------------------------------
+
+void Audio::msgUndo()
+ {
+ AudioMsg msg;
+ msg.id = SEQM_UNDO;
+ sendMsg(&msg);
+ }
+
+//---------------------------------------------------------
+// msgRedo
+//---------------------------------------------------------
+
+void Audio::msgRedo()
+ {
+ AudioMsg msg;
+ msg.id = SEQM_REDO;
+ sendMsg(&msg);
+ }
+
+//---------------------------------------------------------
+// msgPlay
+//---------------------------------------------------------
+
+void Audio::msgPlay(bool val)
+ {
+ if (val) {
+ if (audioDriver)
+ audioDriver->startTransport();
+ }
+ else
+ if (audioDriver)
+ audioDriver->stopTransport();
+ }
+
+//---------------------------------------------------------
+// msgRemoveTrack
+//---------------------------------------------------------
+
+void Audio::msgRemoveTrack(Track* track)
+ {
+ AudioMsg msg;
+ msg.id = SEQM_REMOVE_TRACK;
+ msg.track = track;
+ sendMessage(&msg, true);
+ }
+
+//---------------------------------------------------------
+// msgRemoveTracks
+// remove all selected tracks
+//---------------------------------------------------------
+
+void Audio::msgRemoveTracks()
+ {
+ TrackList tl;
+ TrackList* tl2 = song->tracks();
+ for (iTrack t = tl2->begin(); t != tl2->end(); ++t) {
+ if ((*t)->selected())
+ tl.push_back(*t);
+ }
+ for (iTrack t = tl.begin(); t != tl.end(); ++t) {
+ Track* track = *t;
+ int idx = song->tracks()->indexOf(track);
+ song->undoOp(UndoOp::DeleteTrack, idx, track);
+ song->removeTrack1(track);
+ msgRemoveTrack(track);
+ song->removeTrack3(track);
+ }
+ }
+
+//---------------------------------------------------------
+// msgMoveTrack
+//---------------------------------------------------------
+
+void Audio::msgMoveTrack(Track* src, Track* dst)
+ {
+ AudioMsg msg;
+ msg.id = SEQM_MOVE_TRACK;
+ msg.p1 = src;
+ msg.p2 = dst;
+ sendMessage(&msg, false);
+ }
+
+//---------------------------------------------------------
+// msgAddEvent
+//---------------------------------------------------------
+
+void Audio::msgAddEvent(const Event& event, Part* part, bool doUndoFlag)
+ {
+ AudioMsg msg;
+ msg.id = SEQM_ADD_EVENT;
+ msg.ev1 = event;
+ msg.p2 = part;
+ sendMessage(&msg, doUndoFlag);
+ }
+
+//---------------------------------------------------------
+// msgAddEvents
+//---------------------------------------------------------
+
+void Audio::msgAddEvents(QList<Event>* el, Part* part)
+ {
+ AudioMsg msg;
+ msg.id = SEQM_ADD_EVENTS;
+ msg.el = el;
+ msg.p2 = part;
+ sendMessage(&msg, false);
+ }
+
+//---------------------------------------------------------
+// msgDeleteEvent
+//---------------------------------------------------------
+
+void Audio::msgDeleteEvent(const Event& event, Part* part, bool doUndoFlag)
+ {
+ AudioMsg msg;
+ msg.id = SEQM_REMOVE_EVENT;
+ msg.ev1 = event;
+ msg.p2 = part;
+ sendMessage(&msg, doUndoFlag);
+ }
+
+//---------------------------------------------------------
+// msgChangeEvent
+//---------------------------------------------------------
+
+void Audio::msgChangeEvent(const Event& oe, const Event& ne, Part* part, bool doUndoFlag)
+ {
+ AudioMsg msg;
+ msg.id = SEQM_CHANGE_EVENT;
+ msg.ev1 = oe;
+ msg.ev2 = ne;
+ msg.p3 = part;
+ sendMessage(&msg, doUndoFlag);
+ }
+
+//---------------------------------------------------------
+// msgAddTempo
+//---------------------------------------------------------
+
+void Audio::msgAddTempo(int tick, int tempo, bool doUndoFlag)
+ {
+ AudioMsg msg;
+ msg.id = SEQM_ADD_TEMPO;
+ msg.a = tick;
+ msg.b = tempo;
+ sendMessage(&msg, doUndoFlag);
+ }
+
+//---------------------------------------------------------
+// msgSetTempo
+//---------------------------------------------------------
+
+void Audio::msgSetTempo(int tick, int tempo, bool doUndoFlag)
+ {
+ AudioMsg msg;
+ msg.id = SEQM_SET_TEMPO;
+ msg.a = tick;
+ msg.b = tempo;
+ sendMessage(&msg, doUndoFlag);
+ }
+
+//---------------------------------------------------------
+// msgSetGlobalTempo
+//---------------------------------------------------------
+
+void Audio::msgSetGlobalTempo(int val)
+ {
+ AudioMsg msg;
+ msg.id = SEQM_SET_GLOBAL_TEMPO;
+ msg.a = val;
+ sendMessage(&msg, false);
+ }
+
+//---------------------------------------------------------
+// msgDeleteTempo
+//---------------------------------------------------------
+
+void Audio::msgDeleteTempo(int tick, int tempo, bool doUndoFlag)
+ {
+ AudioMsg msg;
+ msg.id = SEQM_REMOVE_TEMPO;
+ msg.a = tick;
+ msg.b = tempo;
+ sendMessage(&msg, doUndoFlag);
+ }
+
+//---------------------------------------------------------
+// msgAddSig
+//---------------------------------------------------------
+
+void Audio::msgAddSig(int tick, const AL::TimeSignature& sig, bool doUndoFlag)
+ {
+ AudioMsg msg;
+ msg.id = SEQM_ADD_SIG;
+ msg.a = tick;
+ msg.b = sig.z;
+ msg.c = sig.n;
+ sendMessage(&msg, doUndoFlag);
+ }
+
+//---------------------------------------------------------
+// msgRemoveSig
+//! sends remove tempo signature message
+//---------------------------------------------------------
+
+void Audio::msgRemoveSig(int tick, int z, int n, bool doUndoFlag)
+ {
+ AudioMsg msg;
+ msg.id = SEQM_REMOVE_SIG;
+ msg.a = tick;
+ msg.b = z;
+ msg.c = n;
+ sendMessage(&msg, doUndoFlag);
+ }
+
+//---------------------------------------------------------
+// msgResetMidiDevices
+//---------------------------------------------------------
+
+void Audio::msgResetMidiDevices()
+ {
+ AudioMsg msg;
+ msg.id = SEQM_RESET_DEVICES;
+ sendMessage(&msg, false);
+ }
+
+//---------------------------------------------------------
+// msgInitMidiDevices
+//---------------------------------------------------------
+
+void Audio::msgInitMidiDevices()
+ {
+ AudioMsg msg;
+ msg.id = SEQM_INIT_DEVICES;
+ sendMessage(&msg, false);
+ }
+
+//---------------------------------------------------------
+// panic
+//---------------------------------------------------------
+
+void Audio::msgPanic()
+ {
+ MidiEvent ev1(0, 0, ME_CONTROLLER, CTRL_ALL_SOUNDS_OFF, 0);
+ MidiEvent ev2(0, 0, ME_CONTROLLER, CTRL_RESET_ALL_CTRL, 0);
+
+ MidiTrackList* cl = song->midis();
+ for (iMidiTrack i = cl->begin(); i != cl->end(); ++i) {
+ (*i)->playMidiEvent(&ev1);
+ (*i)->playMidiEvent(&ev2);
+ }
+ }
+
+//---------------------------------------------------------
+// localOff
+//---------------------------------------------------------
+
+void Audio::msgLocalOff()
+ {
+ MidiEvent ev1(0, 0, ME_CONTROLLER, CTRL_LOCAL_OFF, 0);
+
+ MidiTrackList* cl = song->midis();
+ for (iMidiTrack i = cl->begin(); i != cl->end(); ++i)
+ (*i)->playMidiEvent(&ev1);
+ }
+
+//---------------------------------------------------------
+// msgBounce
+// start bounce operation
+//---------------------------------------------------------
+
+void Audio::msgBounce()
+ {
+ _bounce = true;
+ audioDriver->seekTransport(song->lPos().frame());
+ }
+
+//---------------------------------------------------------
+// msgIdle
+//---------------------------------------------------------
+
+void Audio::msgIdle(bool on)
+ {
+ AudioMsg msg;
+ msg.id = SEQM_IDLE;
+ msg.a = on;
+ sendMessage(&msg, false);
+ }
+
+//---------------------------------------------------------
+// msgAddController
+// add controller value
+//---------------------------------------------------------
+
+void Audio::msgAddController(Track* track, int id, unsigned time, CVal val)
+ {
+ AudioMsg msg;
+ msg.id = SEQM_ADD_CTRL;
+ msg.track = track;
+ msg.a = id;
+ msg.time = time;
+ msg.cval1 = val;
+ song->startUndo();
+ song->undoOp(UndoOp::AddCtrl, track, id, time, val, CVal());
+ sendMessage(&msg, false);
+ song->endUndo(0);
+ }
+
+//---------------------------------------------------------
+// msgRemoveController
+//---------------------------------------------------------
+
+void Audio::msgRemoveController(Track* track, int id, unsigned time)
+ {
+ AudioMsg msg;
+ msg.id = SEQM_REMOVE_CTRL;
+ msg.track = track;
+ msg.a = id;
+ msg.time = time;
+ song->startUndo();
+ CVal a, b;
+ song->undoOp(UndoOp::RemoveCtrl, track, id, time, a, b);
+ sendMessage(&msg, false);
+ song->endUndo(0);
+ }
+
+//---------------------------------------------------------
+// msgSetRtc
+//---------------------------------------------------------
+
+void Audio::msgSetRtc()
+ {
+ AudioMsg msg;
+ msg.id = MS_SET_RTC;
+ sendMsg(&msg);
+ }
+
diff --git a/muse_qt4_evolution/muse/shortcuts.cpp b/muse_qt4_evolution/muse/shortcuts.cpp
new file mode 100644
index 00000000..9a0d6a7f
--- /dev/null
+++ b/muse_qt4_evolution/muse/shortcuts.cpp
@@ -0,0 +1,1169 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Description:
+// Definition of shortcuts used in the application
+//
+// Copyright (C) 2003 Mathias Lundgren <lunar_shuttle@users.sourceforge.net>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "shortcuts.h"
+#include "widgets/shortcutconfig.h"
+#include "al/xml.h"
+#include "muse.h"
+#include "gui.h"
+
+//---------------------------------------------------------
+// shortcut_category
+// These need to be members of ShortcutConfig, otherwise
+// tr() won't play:
+//---------------------------------------------------------
+
+const shortcut_cg ShortcutConfig::shortcut_category[] = {
+ { GLOBAL_SHRT, QT_TR_NOOP("Global") },
+ { ARRANG_SHRT, QT_TR_NOOP("Arranger") },
+ { PROLL_SHRT, QT_TR_NOOP("Pianoroll") },
+ { DEDIT_SHRT, QT_TR_NOOP("Drumeditor") },
+ { LEDIT_SHRT, QT_TR_NOOP("List editor") },
+ { LMEDIT_SHRT, QT_TR_NOOP("List Mastertrack") },
+ { WAVE_SHRT, QT_TR_NOOP("Wave editor") },
+ { ALL_SHRT , QT_TR_NOOP("All categories") }
+ };
+
+QMap<QString, Shortcut*> shortcuts;
+
+Shortcut MuseApplication::sc[] = {
+ Shortcut(
+ "start",
+ QT_TR_NOOP("Transport: Goto Start"),
+ GLOBAL_SHRT,
+ 0,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Goto Start"),
+ QT_TR_NOOP("rewind to start position"),
+ ":/xpm/start.xpm"
+ ),
+ Shortcut(
+ "toggle_loop",
+ QT_TR_NOOP("Transport: Toggle Loop section"),
+ GLOBAL_SHRT,
+ 0, // QKeySequence(Qt::Key_Slash),
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Loop"),
+ QT_TR_NOOP("loop between left mark and right mark"),
+ ":/xpm/loop.xpm"
+ ),
+ Shortcut(
+ "play",
+ QT_TR_NOOP("Transport: Start playback from current location"),
+ GLOBAL_SHRT,
+ QKeySequence(Qt::Key_Enter),
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Play"),
+ QT_TR_NOOP("start sequencer play"),
+ ":/xpm/play.xpm"
+ ),
+ Shortcut(
+ "play_toggle",
+ QT_TR_NOOP("Transport: Play, Stop"),
+ GLOBAL_SHRT,
+ Qt::Key_Space,
+ Qt::ApplicationShortcut
+ ),
+ Shortcut(
+ "stop",
+ QT_TR_NOOP("Transport: Stop Playback"),
+ GLOBAL_SHRT,
+ Qt::Key_Insert,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Stop"),
+ QT_TR_NOOP("stop sequencer"),
+ ":/xpm/stop.xpm"
+ ),
+ Shortcut(
+ "goto_left",
+ QT_TR_NOOP("Transport: Goto left marker"),
+ GLOBAL_SHRT,
+ Qt::Key_End
+ ),
+ Shortcut(
+ "goto_right",
+ QT_TR_NOOP("Transport: Goto right marker"),
+ GLOBAL_SHRT,
+ Qt::Key_PageDown
+ ),
+ Shortcut(
+ "toggle_metro",
+ QT_TR_NOOP("Transport: Toggle metronome"),
+ GLOBAL_SHRT,
+ QKeySequence(Qt::Key_C)
+ ),
+ Shortcut(
+ "toggle_rec",
+ QT_TR_NOOP("Transport: Toggle Record"),
+ GLOBAL_SHRT,
+ Qt::Key_Asterisk,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Record"),
+ QT_TR_NOOP("to record press record and then play"),
+ ":/xpm/recordOn.svg",
+ ":/xpm/recordOff.svg"
+ ),
+ Shortcut(
+ "punchin",
+ QT_TR_NOOP("Transport: Punch In"),
+ GLOBAL_SHRT,
+ 0,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Punchin"),
+ QT_TR_NOOP("record starts at left mark"),
+ ":/xpm/punchin.xpm"
+ ),
+ Shortcut(
+ "punchout",
+ QT_TR_NOOP("Transport: Punch Out"),
+ GLOBAL_SHRT,
+ 0,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Punchout"),
+ QT_TR_NOOP("record stops at right mark"),
+ ":/xpm/punchout.xpm"
+ ),
+ Shortcut(
+ "rewind",
+ QT_TR_NOOP("Transport: Rewind"),
+ GLOBAL_SHRT,
+ 0,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("rewind"),
+ QT_TR_NOOP("rewind current position"),
+ ":/xpm/frewind.xpm"
+ ),
+ Shortcut(
+ "forward",
+ QT_TR_NOOP("Transport: Forward"),
+ GLOBAL_SHRT,
+ 0,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("forward"),
+ QT_TR_NOOP("move current position"),
+ ":/xpm/fforward.xpm"
+ ),
+ Shortcut(
+ "panic",
+ QT_TR_NOOP("Panic"),
+ GLOBAL_SHRT,
+ 0,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Panic"),
+ QT_TR_NOOP("send note off to all midi channels"),
+ ":/xpm/panic.xpm"
+ ),
+ Shortcut(
+ "undo",
+ QT_TR_NOOP("Edit: Undo"),
+ INVIS_SHRT,
+ Qt::CTRL + Qt::Key_Z,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("undo"),
+ QT_TR_NOOP("undo last change to song"),
+ ":/xpm/undo.xpm"
+ ),
+ Shortcut(
+ "redo",
+ QT_TR_NOOP("Edit: Redo"),
+ INVIS_SHRT,
+ Qt::CTRL + Qt::Key_Y,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("redo"),
+ QT_TR_NOOP("redo last undo"),
+ ":/xpm/redo.xpm"
+ ),
+ Shortcut(
+ "cut",
+ QT_TR_NOOP("Edit: Cut" ),
+ INVIS_SHRT,
+ Qt::CTRL + Qt::Key_X,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Cut"),
+ QT_TR_NOOP("Cut"),
+ ":/xpm/editcut.xpm"
+ ),
+ Shortcut(
+ "copy",
+ QT_TR_NOOP("Edit: Copy"),
+ INVIS_SHRT,
+ Qt::CTRL + Qt::Key_C,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Copy"),
+ QT_TR_NOOP("Copy"),
+ ":/xpm/editcopy.xpm"
+ ),
+ Shortcut(
+ "paste",
+ QT_TR_NOOP("Edit: Paste,"),
+ INVIS_SHRT,
+ Qt::CTRL + Qt::Key_V,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Paste"),
+ QT_TR_NOOP("Paste"),
+ ":/xpm/editpaste.xpm"
+ ),
+ Shortcut(
+ "delete",
+ QT_TR_NOOP("Edit: Delete" ),
+ INVIS_SHRT,
+ Qt::Key_Delete,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Delete"),
+ QT_TR_NOOP("Delete"),
+ ":/xpm/delete.png"
+ ),
+ Shortcut(
+ "open_project",
+ QT_TR_NOOP("Open"),
+ ARRANG_SHRT + DEDIT_SHRT,
+ Qt::CTRL + Qt::Key_O,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("open project"),
+ QT_TR_NOOP("Click this button to select a new project\n"
+ "You can also select the <b>Open command</b> from the Project menu."),
+ ":/xpm/fileopen.png"
+ ),
+ Shortcut(
+ "save_project",
+ QT_TR_NOOP("Save"),
+ ARRANG_SHRT + DEDIT_SHRT,
+ Qt::CTRL + Qt::Key_S,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("save project"),
+ QT_TR_NOOP("Click this button to save the project you are editing.\n"
+ "You can also select the Save command from the Project menu."),
+ ":/xpm/filesave.png"
+ ),
+ Shortcut(
+ "save_project_as",
+ QT_TR_NOOP("File: Save as"),
+ ARRANG_SHRT + DEDIT_SHRT,
+ 0,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("save project as..."),
+ QT_TR_NOOP("Click this button to save a new copy of the project.\n"
+ ), ":/xpm/filesave.png"
+ ),
+ Shortcut(
+ "save_as_template",
+ QT_TR_NOOP("File: Save as Template"),
+ ARRANG_SHRT,
+ 0,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("save project as template"),
+ QT_TR_NOOP("Click this button to save the project you are editing\n"
+ "for later use as a template."),
+ ":/xpm/filesave.png"
+ ),
+ Shortcut(
+ "open_recent",
+ QT_TR_NOOP("File: Open recent file"),
+ ARRANG_SHRT,
+ Qt::CTRL + Qt::Key_1
+ ),
+ Shortcut(
+ "import_midi",
+ QT_TR_NOOP("File: Import midi file"),
+ ARRANG_SHRT,
+ 0
+ ),
+ Shortcut(
+ "export_midi",
+ QT_TR_NOOP("File: Export midi file"),
+ ARRANG_SHRT,
+ 0
+ ),
+ Shortcut(
+ "import_audio",
+ QT_TR_NOOP("File: Import audio file"),
+ ARRANG_SHRT,
+ 0
+ ),
+ Shortcut(
+ "quit",
+ QT_TR_NOOP("File: Quit MusE"),
+ ARRANG_SHRT,
+ Qt::CTRL + Qt::Key_Q,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Quit MusE"),
+ QT_TR_NOOP("Quit MusE"),
+ ":/xpm/on.svg",
+ ":/xpm/off.svg"
+ ),
+ Shortcut(
+ "select_parts_on_track",
+ QT_TR_NOOP("Edit: Select parts on track"),
+ ARRANG_SHRT,
+ Qt::CTRL+ Qt::ALT + Qt::Key_P,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("All &Parts on Track"),
+ QT_TR_NOOP("All &Parts on Track"),
+ ":/xpm/select_all_parts_on_track.xpm"
+ ),
+ Shortcut(
+ "open_pianoroll",
+ QT_TR_NOOP("Open Pianoroll"),
+ ARRANG_SHRT,
+ Qt::CTRL + Qt::Key_E,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Pianoroll"),
+ QT_TR_NOOP("Start Pianoroll Editor"),
+ ":/xpm/piano.xpm"
+ ),
+ Shortcut(
+ "open_miditracker",
+ QT_TR_NOOP("Open MidiTracker"),
+ ARRANG_SHRT,
+ Qt::CTRL + Qt::Key_K,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("MidiTracker"),
+ QT_TR_NOOP("Start Midi Tracker"),
+ ":/xpm/piano.xpm"
+ ),
+ Shortcut(
+ "open_drumedit",
+ QT_TR_NOOP("Open drumeditor"),
+ ARRANG_SHRT,
+ Qt::CTRL + Qt::Key_D,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Drum Editor"),
+ QT_TR_NOOP("Start Drum Editor"),
+ ":/xpm/edit_drumms.xpm"
+ ),
+ Shortcut(
+ "open_waveedit",
+ QT_TR_NOOP("Open wave editor"),
+ ARRANG_SHRT,
+ 0,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Wave Editor"),
+ QT_TR_NOOP("Wave Editor"),
+ ":/xpm/wave.xpm"
+ ),
+ Shortcut(
+ "listedit",
+ QT_TR_NOOP("Open listeditor"),
+ ARRANG_SHRT,
+ Qt::CTRL + Qt::Key_L,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Properties"),
+ QT_TR_NOOP("open Properties Editor"),
+ ":/xmp/edit_list.xpm"
+ ),
+ Shortcut(
+ "open_master",
+ QT_TR_NOOP("Open mastertrack editor"),
+ ARRANG_SHRT,
+ Qt::CTRL + Qt::Key_M,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Mastertrack (Tempo) Editor"),
+ QT_TR_NOOP("Start Mastertrack (Tempo) Editor"),
+ ":/xpm/edit_mastertrack.xpm"
+ ),
+ Shortcut(
+ "add_midi_track",
+ QT_TR_NOOP("Add midi track"),
+ ARRANG_SHRT,
+ Qt::CTRL + Qt::Key_J
+ ),
+ Shortcut(
+ "add_drum_track",
+ QT_TR_NOOP("Add drum track"),
+ ARRANG_SHRT,
+ 0
+ ),
+ Shortcut(
+ "add_wave_track",
+ QT_TR_NOOP("Add wave track"),
+ ARRANG_SHRT,
+ 0
+ ),
+ Shortcut(
+ "add_audio_output",
+ QT_TR_NOOP("Add audio output"),
+ ARRANG_SHRT,
+ 0
+ ),
+ Shortcut(
+ "add_audio_group",
+ QT_TR_NOOP("Add audio group"),
+ ARRANG_SHRT,
+ 0
+ ),
+ Shortcut(
+ "add_audio_input",
+ QT_TR_NOOP("Add audio input"),
+ ARRANG_SHRT,
+ 0
+ ),
+ Shortcut(
+ "global_cut",
+ QT_TR_NOOP("Structure: Global cut"),
+ ARRANG_SHRT,
+ 0
+ ),
+ Shortcut(
+ "global_insert",
+ QT_TR_NOOP("Structure: Global insert"),
+ ARRANG_SHRT,
+ 0
+ ),
+ Shortcut(
+ "global_split",
+ QT_TR_NOOP("Structure: Global split"),
+ ARRANG_SHRT,
+ 0
+ ),
+ Shortcut(
+ "copy_range",
+ QT_TR_NOOP("Structure: Copy range"),
+ ARRANG_SHRT,
+ 0
+ ),
+ Shortcut(
+ "cut_events",
+ QT_TR_NOOP("Structure: Cut events"),
+ ARRANG_SHRT,
+ 0
+ ),
+ Shortcut(
+ "toggle_mixer1",
+ QT_TR_NOOP("View: Open mixer 1 window"),
+ ARRANG_SHRT,
+ Qt::Key_F10,
+ Qt::ApplicationShortcut,
+ QT_TR_NOOP("Mixer1"),
+ QT_TR_NOOP("Show Mixer 1"),
+ ":/xpm/view_mixer.xpm"
+ ),
+ Shortcut(
+ "toggle_mixer2",
+ QT_TR_NOOP("View: Open mixer 2 window"),
+ ARRANG_SHRT,
+ 0,
+ Qt::ApplicationShortcut,
+ QT_TR_NOOP("Mixer2"),
+ QT_TR_NOOP("Show Mixer 2"),
+ ":/xpm/view_mixer.xpm"
+ ),
+ Shortcut(
+ "toggle_transport",
+ QT_TR_NOOP("View: Toggle transport window"),
+ ARRANG_SHRT,
+ Qt::Key_F11,
+ Qt::ApplicationShortcut,
+ QT_TR_NOOP("Transport"),
+ QT_TR_NOOP("Show Transport Window"),
+ ":/xpm/view_transport_window.xpm"
+ ),
+ Shortcut(
+ "toggle_bigtime",
+ QT_TR_NOOP("View: Toggle bigtime window"),
+ ARRANG_SHRT,
+ Qt::Key_F12,
+ Qt::ApplicationShortcut,
+ QT_TR_NOOP("BigTime"),
+ QT_TR_NOOP("Show BigTime Window"),
+ ":/xpm/view_bigtime_window.xpm"
+ ),
+ Shortcut(
+ "marker_window",
+ QT_TR_NOOP("View: Open marker window"),
+ ARRANG_SHRT,
+ Qt::Key_F9,
+ Qt::ApplicationShortcut,
+ QT_TR_NOOP("Marker"),
+ QT_TR_NOOP("Show Marker List"),
+ ":/xpm/view_marker.xpm"
+ ),
+ Shortcut(
+ "follow_jump",
+ QT_TR_NOOP("Settings: Follow song by page"),
+ ARRANG_SHRT,
+ 0
+ ),
+ Shortcut(
+ "follow_no",
+ QT_TR_NOOP("Settings: Follow song off"),
+ ARRANG_SHRT,
+ 0
+ ),
+ Shortcut(
+ "follow_continuous",
+ QT_TR_NOOP("Settings: Follow song continuous"),
+ ARRANG_SHRT,
+ 0
+ ),
+ Shortcut(
+ "configure_shortcuts",
+ QT_TR_NOOP("Settings: Configure shortcuts"),
+ ARRANG_SHRT,
+ 0
+ ),
+ Shortcut(
+ "configure_metronome",
+ QT_TR_NOOP("Settings: Configure metronome"),
+ ARRANG_SHRT,
+ 0
+ ),
+ Shortcut(
+ "configure_midi_sync",
+ QT_TR_NOOP("Settings: Midi sync configuration"),
+ ARRANG_SHRT,
+ 0
+ ),
+ Shortcut(
+ "configure_midi_file",
+ QT_TR_NOOP("Settings: Midi file export configuration"),
+ ARRANG_SHRT,
+ 0
+ ),
+ Shortcut(
+ "configure_midi_ports",
+ QT_TR_NOOP("Settings: Midi ports / Soft Synth"),
+ ARRANG_SHRT,
+ 0
+ ),
+ Shortcut(
+ "configure_audio_ports",
+ QT_TR_NOOP("Settings: Audio subsystem configuration"),
+ ARRANG_SHRT,
+ 0
+ ),
+ Shortcut(
+ "midi_edit_instruments",
+ QT_TR_NOOP("Midi: Edit midi instruments"),
+ ARRANG_SHRT,
+ 0
+ ),
+ Shortcut(
+ "midi_remote_control",
+ QT_TR_NOOP("Midi: Midi remote control"),
+ ARRANG_SHRT,
+ 0
+ ),
+ Shortcut(
+ "midi_reset",
+ QT_TR_NOOP("Midi: Reset midi"),
+ ARRANG_SHRT,
+ 0
+ ),
+ Shortcut(
+ "midi_init",
+ QT_TR_NOOP("Midi: Init midi"),
+ ARRANG_SHRT,
+ 0
+ ),
+ Shortcut(
+ "midi_local_off",
+ QT_TR_NOOP("Midi: Midi local off"),
+ ARRANG_SHRT,
+ 0
+ ),
+ Shortcut(
+ "audio_bounce_to_track",
+ QT_TR_NOOP("Audio: Bounce audio to track"),
+ ARRANG_SHRT,
+ 0
+ ),
+ Shortcut(
+ "audio_bounce_to_file",
+ QT_TR_NOOP("Audio: Bounce audio to file"),
+ ARRANG_SHRT,
+ 0
+ ),
+ Shortcut(
+ "audio_restart",
+ QT_TR_NOOP("Audio: Restart audio"),
+ ARRANG_SHRT,
+ 0
+ ),
+ Shortcut(
+ "open_help",
+ QT_TR_NOOP("Help: Open Manual"),
+ ARRANG_SHRT,
+ Qt::Key_F1
+ ),
+ Shortcut(
+ "toggle_whatsthis",
+ QT_TR_NOOP("Help: Toggle whatsthis mode"),
+ ARRANG_SHRT,
+ Qt::SHIFT + Qt::Key_F1
+ ),
+ Shortcut(
+ "edit_selected_part",
+ QT_TR_NOOP("Edit: Edit selected part"),
+ ARRANG_SHRT,
+ Qt::Key_Return
+ ),
+ Shortcut(
+ "sel_part_above",
+ QT_TR_NOOP("Edit: Select nearest part on track above"),
+ ARRANG_SHRT,
+ Qt::Key_Up
+ ),
+ Shortcut(
+ "sel_part_above_add",
+ QT_TR_NOOP("Edit: Add nearest part on track above"),
+ ARRANG_SHRT,
+ Qt::SHIFT + Qt::Key_Up
+ ),
+ Shortcut(
+ "sel_part_below",
+ QT_TR_NOOP("Edit: Select nearest part on track below"),
+ ARRANG_SHRT,
+ Qt::Key_Down
+ ),
+ Shortcut(
+ "sel_part_below_add",
+ QT_TR_NOOP("Edit: Add nearest part on track below"),
+ ARRANG_SHRT,
+ Qt::SHIFT + Qt::Key_Down
+ ),
+ Shortcut(
+ "midi_transpose",
+ QT_TR_NOOP("Midi: Transpose"),
+ ARRANG_SHRT + PROLL_SHRT,
+ 0,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Transpose")
+ ),
+ Shortcut(
+ "sel_all",
+ QT_TR_NOOP("Edit: Select all"),
+ ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT,
+ Qt::CTRL + Qt::Key_A,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Select All"),
+ QT_TR_NOOP("Select All"),
+ ":/xpm/select_all.xpm"
+ ),
+ Shortcut(
+ "sel_none",
+ QT_TR_NOOP("Edit: Select none"),
+ ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT,
+ Qt::CTRL + Qt::SHIFT + Qt::Key_A,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Deselect All"),
+ QT_TR_NOOP("Deselect All"),
+ ":/xpm/select_deselect_all.xpm"
+ ),
+ Shortcut(
+ "sel_inv",
+ QT_TR_NOOP("Edit: Invert selection"),
+ ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT,
+ Qt::CTRL + Qt::Key_I,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Invert Selection"),
+ QT_TR_NOOP("Invert Selection"),
+ ":/xpm/select_invert_selection.xpm"
+ ),
+ Shortcut(
+ "sel_ins_loc",
+ QT_TR_NOOP("Edit: Select events/parts inside locators"),
+ ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT,
+ 0,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Select Inside Loop"),
+ QT_TR_NOOP("Select Inside Loop"),
+ ":/xpm/select_inside_loop.xpm"
+ ),
+ Shortcut(
+ "sel_out_loc",
+ QT_TR_NOOP("Edit: Select events/parts outside locators"),
+ ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT,
+ 0,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Select Outside Loop"),
+ QT_TR_NOOP("Select Outside Loop"),
+ ":/xpm/select_outside_loop.xpm"
+ ),
+ Shortcut(
+ "sel_left",
+ QT_TR_NOOP("Edit: Select nearest part/event to the left"),
+ ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT,
+ Qt::Key_Left
+ ),
+ Shortcut(
+ "sel_left_add",
+ QT_TR_NOOP("Edit: Add nearest part/event to the left to selection"),
+ PROLL_SHRT + DEDIT_SHRT,
+ Qt::Key_Left + Qt::SHIFT
+ ),
+ Shortcut(
+ "sel_right",
+ QT_TR_NOOP("Edit: Select nearest part/event to the left"),
+ ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT,
+ Qt::Key_Right
+ ),
+ Shortcut(
+ "sel_right_add",
+ QT_TR_NOOP("Edit: Add nearest part/event to the right to selection"),
+ PROLL_SHRT + DEDIT_SHRT,
+ Qt::Key_Right + Qt::SHIFT
+ ),
+ Shortcut(
+ "loc_to_sel",
+ QT_TR_NOOP("Edit: Set locators to selection"),
+ ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT,
+ Qt::ALT + Qt::Key_P
+ ),
+ Shortcut(
+ "sel_inc_pitch",
+ QT_TR_NOOP("Edit: Increase pitch"),
+ PROLL_SHRT + DEDIT_SHRT,
+ Qt::CTRL + Qt::Key_Up
+ ),
+ Shortcut(
+ "sel_dec_pitch",
+ QT_TR_NOOP("Edit: Decrease pitch"),
+ PROLL_SHRT + DEDIT_SHRT,
+ Qt::CTRL + Qt::Key_Down
+ ),
+ Shortcut(
+ "midi_fixed_len",
+ QT_TR_NOOP("Edit: Set fixed length on midi events"),
+ DEDIT_SHRT,
+ Qt::ALT + Qt::Key_L,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Set fixed length")
+ ),
+ Shortcut(
+ "midi_over_quant",
+ QT_TR_NOOP("Quantize: Over Quantize"),
+ PROLL_SHRT,
+ 0,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Over Quantize")
+ ),
+ Shortcut(
+ "midi_quant_noteon",
+ QT_TR_NOOP("Quantize: Note On Quantize"),
+ PROLL_SHRT,
+ 0,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Note On Quantize")
+ ),
+ Shortcut(
+ "midi_quant_noteoff",
+ QT_TR_NOOP("Quantize: Note On/Off Quantize"),
+ PROLL_SHRT,
+ 0,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Note On/Off Quantize")
+ ),
+ Shortcut(
+ "midi_quant_iterative",
+ QT_TR_NOOP("Quantize: Iterative Quantize"),
+ PROLL_SHRT,
+ 0,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Iterative Quantize")
+ ),
+ Shortcut(
+ "config_quant",
+ QT_TR_NOOP("Quantize: Configure quant"),
+ PROLL_SHRT,
+ Qt::CTRL + Qt::ALT + Qt::Key_Q
+ ),
+ Shortcut(
+ "midi_mod_gate_time",
+ QT_TR_NOOP("Quantize: Modify Gate Time"),
+ PROLL_SHRT,
+ 0,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Modify Gate Time")
+ ),
+ Shortcut(
+ "midi_mod_velo",
+ QT_TR_NOOP("Quantize: Modify Velocity"),
+ PROLL_SHRT,
+ 0,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Modify Velocity")
+ ),
+ Shortcut(
+ "midi_crescendo",
+ QT_TR_NOOP("Edit: Crescendo"),
+ PROLL_SHRT,
+ 0,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Crescendo")
+ ),
+ Shortcut(
+ "midi_thin_out",
+ QT_TR_NOOP("Edit: Thin Out"),
+ PROLL_SHRT,
+ 0,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Thin Out")
+ ),
+ Shortcut(
+ "midi_erase_event",
+ QT_TR_NOOP("Edit: Erase Event"),
+ PROLL_SHRT,
+ 0,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Erase Event")
+ ),
+ Shortcut(
+ "midi_note_shift",
+ QT_TR_NOOP("Edit: Note Shift"),
+ PROLL_SHRT,
+ 0,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Note Shift")
+ ),
+ Shortcut(
+ "midi_move_clock",
+ QT_TR_NOOP("Edit: Move Clock"),
+ PROLL_SHRT,
+ 0,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Move Clock")
+ ),
+ Shortcut(
+ "midi_copy_measure",
+ QT_TR_NOOP("Edit: Copy Measure"),
+ PROLL_SHRT,
+ 0,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Copy Measure")
+ ),
+ Shortcut(
+ "midi_erase_measure",
+ QT_TR_NOOP("Edit: Erase Measure"),
+ PROLL_SHRT,
+ 0,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Erase Measure")
+ ),
+ Shortcut(
+ "midi_delete_measure",
+ QT_TR_NOOP("Edit: Delete Measure"),
+ PROLL_SHRT,
+ 0,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Delete Measure")
+ ),
+ Shortcut(
+ "midi_create_measure",
+ QT_TR_NOOP("Edit: Create Measure"),
+ PROLL_SHRT,
+ 0,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Create Measure")
+ ),
+ Shortcut(
+ "change_event_color",
+ QT_TR_NOOP("Edit: Change event color"),
+ PROLL_SHRT,
+ Qt::Key_E
+ ),
+ Shortcut(
+ "pointer",
+ QT_TR_NOOP("Tool: Pointer"),
+ ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT,
+ Qt::Key_A,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Pointer"),
+ QT_TR_NOOP("select Pointer Tool:\n"
+ "with the pointer tool you can:\n"
+ " select parts\n"
+ " move parts\n"
+ " copy parts"),
+ ":/xpm/pointer.xpm"
+ ),
+ Shortcut(
+ "pencil",
+ QT_TR_NOOP("Tool: Pencil"),
+ ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT,
+ Qt::Key_D,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Pencil"),
+ QT_TR_NOOP("select Pencil Tool:\n"
+ "with the pencil tool you can:\n"
+ " create new parts\n"
+ " modify length of parts"),
+ ":/xpm/pencil.xpm"
+ ),
+ Shortcut(
+ "eraser",
+ QT_TR_NOOP("Tool: Eraser"),
+ ARRANG_SHRT + PROLL_SHRT + DEDIT_SHRT,
+ Qt::Key_R,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Eraser"),
+ QT_TR_NOOP("select Delete Tool:\n"
+ "with the delete tool you can delete parts"),
+ ":/xpm/delete.xpm"
+ ),
+ Shortcut(
+ "scissor",
+ QT_TR_NOOP("Tool: Scissor"),
+ ARRANG_SHRT,
+ Qt::Key_S,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Scissor"),
+ QT_TR_NOOP("select Cut Tool:\n"
+ "with the cut tool you can split a part"),
+ ":/xpm/cut.xpm"
+ ),
+ Shortcut(
+ "glue",
+ QT_TR_NOOP("Tool: Glue"),
+ ARRANG_SHRT,
+ Qt::Key_G,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Glue"),
+ QT_TR_NOOP("select Glue Tool:\n"
+ "with the glue tool you can glue two parts"),
+ ":/xpm/glue.xpm"
+ ),
+ Shortcut(
+ "declone",
+ QT_TR_NOOP("Declone"),
+ ARRANG_SHRT,
+ 0,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Declone")
+ ),
+ Shortcut(
+ "quantize",
+ QT_TR_NOOP("Tool: Quantize"),
+ ARRANG_SHRT,
+ Qt::Key_G,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Quantize"),
+ QT_TR_NOOP("select Quantize Tool:\n"
+ "insert display quantize event"),
+ ":/xpm/quant.xpm"
+ ),
+ Shortcut(
+ "draw",
+ QT_TR_NOOP("Tool: Line Draw"),
+ PROLL_SHRT + DEDIT_SHRT,
+ 0,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Draw"),
+ QT_TR_NOOP("select Drawing Tool"),
+ ":/xpm/draw.xpm"
+ ),
+ Shortcut(
+ "mute_parts",
+ QT_TR_NOOP("Tool: Mute Parts"),
+ ARRANG_SHRT,
+ 0,
+ Qt::WindowShortcut,
+ QT_TR_NOOP("Mute"),
+ QT_TR_NOOP("select Muting Tool:\n"
+ "click on part to mute/unmute"),
+ ":/xpm/editmute.xpm"
+ ),
+
+ Shortcut(
+ "curpos_increase",
+ QT_TR_NOOP("Transport: Increase current position"),
+ GLOBAL_SHRT,
+ Qt::Key_Plus
+ ),
+ Shortcut(
+ "curpos_decrease",
+ QT_TR_NOOP("Transport: Decrease current position"),
+ GLOBAL_SHRT,
+ Qt::Key_Minus
+ ),
+ Shortcut(
+ "midi_quant_1",
+ QT_TR_NOOP("Quantize: Set quantize to 1/1 note"),
+ PROLL_SHRT,
+ Qt::Key_1
+ ),
+ Shortcut(
+ "midi_quant_2",
+ QT_TR_NOOP("Quantize: Set quantize to 1/2 note"),
+ PROLL_SHRT,
+ Qt::Key_2
+ ),
+ Shortcut(
+ "midi_quant_3",
+ QT_TR_NOOP("Quantize: Set quantize to 1/4 note"),
+ PROLL_SHRT,
+ Qt::Key_3
+ ),
+ Shortcut(
+ "midi_quant_4",
+ QT_TR_NOOP("Quantize: Set quantize to 1/8 note"),
+ PROLL_SHRT,
+ Qt::Key_4
+ ),
+ Shortcut(
+ "midi_quant_5",
+ QT_TR_NOOP("Quantize: Set quantize to 1/16 note"),
+ PROLL_SHRT,
+ Qt::Key_5
+ ),
+ Shortcut(
+ "midi_quant_6",
+ QT_TR_NOOP("Quantize: Set quantize to 1/32 note"),
+ PROLL_SHRT,
+ Qt::Key_6
+ ),
+ Shortcut(
+ "midi_quant_7",
+ QT_TR_NOOP("Quantize: Set quantize to 1/64 note"),
+ PROLL_SHRT,
+ Qt::Key_7
+ ),
+ Shortcut(
+ "midi_quant_triol",
+ QT_TR_NOOP("Quantize: Toggle triol quantization"),
+ PROLL_SHRT,
+ Qt::Key_T
+ ),
+ Shortcut(
+ "midi_quant_punct",
+ QT_TR_NOOP("Quantize: Toggle punctuation quantization"),
+ PROLL_SHRT,
+ Qt::Key_Period
+ ),
+ Shortcut(
+ "midi_quant_punct2",
+ QT_TR_NOOP("Quantize: Toggle punctuation quantization (2)"),
+ PROLL_SHRT,
+ Qt::Key_Comma
+ ),
+ Shortcut(
+ "midi_insert_at_loc",
+ QT_TR_NOOP("Insert"),
+ PROLL_SHRT,
+ Qt::SHIFT + Qt::Key_Right
+ ),
+ Shortcut(
+ "lm_ins_tempo",
+ QT_TR_NOOP("Insert Tempo"),
+ LMEDIT_SHRT,
+ Qt::CTRL + Qt::Key_T
+ ),
+ Shortcut(
+ "lm_ins_sig",
+ QT_TR_NOOP("Insert Signature"),
+ LMEDIT_SHRT,
+ Qt::CTRL + Qt::Key_R
+ ),
+ Shortcut(
+ "lm_edit_beat",
+ QT_TR_NOOP("Change Event Position"),
+ LMEDIT_SHRT,
+ Qt::CTRL + Qt::SHIFT + Qt::Key_E
+ ),
+ Shortcut(
+ "lm_edit_val",
+ QT_TR_NOOP("Edit Event Value"),
+ LMEDIT_SHRT,
+ Qt::CTRL + Qt::Key_E
+ ),
+ Shortcut(0, 0, 0, 0 ),
+ };
+
+KeyboardMovementIndicator shortcutsKbdMovement; //for keeping track of active part selected by kbd
+
+//---------------------------------------------------------
+// writeShortCuts
+//---------------------------------------------------------
+
+void writeShortCuts(Xml& xml)
+ {
+ xml.stag("shortcuts");
+ foreach(Shortcut* s, shortcuts) {
+ //
+ // save only if different from default
+ //
+ for (unsigned i = 0;; ++i) {
+ if (MuseApplication::sc[i].xml == s->xml) {
+ if (MuseApplication::sc[i].key != s->key)
+ xml.tag(s->xml, s->key.toString(QKeySequence::PortableText));
+ break;
+ }
+ }
+ }
+ xml.etag("shortcuts");
+ }
+
+//---------------------------------------------------------
+// readShortCuts
+//---------------------------------------------------------
+
+void readShortCuts(QDomNode node)
+ {
+ for (;!node.isNull(); node = node.nextSibling()) {
+ QDomElement e = node.toElement();
+ Shortcut* s = shortcuts.value(e.tagName());
+ if (s)
+ s->key = QKeySequence::fromString(e.text(), QKeySequence::PortableText);
+ else
+ printf("MusE:readShortCuts: unknown tag <%s>\n", e.tagName().toLatin1().data());
+ }
+ }
+
+//---------------------------------------------------------
+// getAction
+// returns action for shortcut
+//---------------------------------------------------------
+
+QAction* getAction(const char* id, QObject* parent)
+ {
+ Shortcut* s = shortcuts.value(id);
+ if (s == 0) {
+ printf("interanl error: shortcut <%s> not found\n", id);
+ return 0;
+ }
+ if (s->action == 0 || (s->action->parent() != parent)) {
+ s->action = new QAction(s->xml, parent);
+ s->action->setData(s->xml);
+ s->action->setShortcut(s->key);
+ s->action->setShortcutContext(s->context);
+ if (s->help) {
+ s->action->setToolTip(s->help);
+ s->action->setWhatsThis(s->help);
+ }
+ else {
+ s->action->setToolTip(s->descr);
+ s->action->setWhatsThis(s->descr);
+ }
+ if (s->text)
+ s->action->setText(s->text);
+ if (s->iconOn) {
+ QIcon icon;
+ icon.addFile(s->iconOn, ICON_SIZE, QIcon::Normal, QIcon::On);
+ if (s->iconOff)
+ icon.addFile(s->iconOff, ICON_SIZE, QIcon::Normal, QIcon::Off);
+ s->action->setIcon(icon);
+ }
+ }
+// else
+// printf("action <%s> already initialized\n", s->xml);
+ return s->action;
+ }
+
diff --git a/muse_qt4_evolution/muse/shortcuts.h b/muse_qt4_evolution/muse/shortcuts.h
new file mode 100644
index 00000000..d66650e8
--- /dev/null
+++ b/muse_qt4_evolution/muse/shortcuts.h
@@ -0,0 +1,135 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2003 Mathias Lundgren <lunar_shuttle@users.sourceforge.net>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __SHORTCUTS_H__
+#define __SHORTCUTS_H__
+
+class Part;
+class Track;
+namespace AL {
+ class Xml;
+ };
+using AL::Xml;
+
+//
+// Shortcut categories
+//
+#define PROLL_SHRT 1 // Pianoroll shortcut
+#define DEDIT_SHRT 2 // Drumedit shortcut
+#define LEDIT_SHRT 4 // Listedit shortcut
+#define SCORE_SHRT 8 // Score shortcut
+#define ARRANG_SHRT 16 // Arrenger shortcut
+#define TRANSP_SHRT 32 // Transport shortcut
+#define WAVE_SHRT 64 // Waveedit shortcut
+#define GLOBAL_SHRT 128 // Global shortcuts
+#define LMEDIT_SHRT 256 // List masteredit
+#define MEDIT_SHRT 512 // Master editor
+#define ALL_SHRT 1023 // All shortcuts
+#define INVIS_SHRT 1024 // Shortcuts not shown in the config-dialog. Hard-coded. To avoid conflicts
+
+#define SHRT_NUM_OF_CATEGORIES 7 //Number of shortcut categories
+
+//---------------------------------------------------------
+// shortcut
+//! Holds the basic values for a configurable shortcut
+//---------------------------------------------------------
+
+struct Shortcut
+ {
+ const char* xml; /*! xml tag name for configuration file */
+ const char* descr; /*! Description of the shortcut, shown in editor */
+ int type; /*! Bitmask category value mapped against
+ PROLL_SHRT, DEDIT_SHRT etc. One shortcut can
+ be a member of many categories */
+ QKeySequence key; /*! shortcut key */
+ Qt::ShortcutContext context;
+ const char* text; /*! action help */
+ const char* help;
+ const char* iconOn;
+ const char* iconOff;
+ QAction* action; /*! cached action, can be updated if user changes
+ shortcut key sequence */
+
+ Shortcut() {
+ xml = 0;
+ descr = 0;
+ type = 0;
+ key = 0;
+ context = Qt::WindowShortcut;
+ text = 0;
+ help = 0;
+ iconOn = 0;
+ iconOff = 0;
+ action = 0;
+ }
+ Shortcut(const char* name, const char* d, int t, const QKeySequence& k,
+ Qt::ShortcutContext cont = Qt::WindowShortcut,
+ const char* txt=0, const char* h=0, const char* ic1=0, const char* ic2=0)
+ : xml(name), descr(d), type(t), key(k), context(cont), text(txt), help(h),
+ iconOn(ic1), iconOff(ic2) {
+ action = 0;
+ }
+ };
+
+//! Describes a shortcut category
+struct shortcut_cg
+ {
+ int id_flag; /*! The category (one of PROLL_SHRT, DEDIT_SHRT etc) */
+ const char* name; /*! Name (shown in editor) */
+ };
+
+//------------------------------------------------------------------------------------------------
+// KeyboardMovementIndicator
+//! Used by Arranger to keep track of which Part is currently active when navigating with keys
+//------------------------------------------------------------------------------------------------
+
+class KeyboardMovementIndicator {
+ //! Left position of the active part, in ticks
+ unsigned lpos;
+ //! Right position of the active part, in ticks
+ unsigned rpos;
+ //! Last selected part (the active part)
+ Part* lastSelectedPart;
+ //! Track the last selected part belongs to
+ Track* lastSelectedTrack;
+
+ public:
+ KeyboardMovementIndicator()
+ { reset(); }
+
+ void setPos(int l, int r) { lpos = l; rpos = r; }
+ void setPart(Part* p) { lastSelectedPart = p; }
+ void setTrack(Track* t) { lastSelectedTrack = t; }
+ unsigned getLpos() { return lpos; }
+ unsigned getRpos() { return rpos; }
+ Part* part() { return lastSelectedPart; }
+ Track* track() { return lastSelectedTrack; }
+ //! Resets the values (equals to no active part)
+ void reset() { lpos = 0; rpos = 0; lastSelectedPart = 0; lastSelectedTrack = 0; }
+ //! Checks if there is any active part
+ bool isValid() { return (lastSelectedPart && lastSelectedTrack); }
+ };
+
+extern KeyboardMovementIndicator shortcutsKbdMovement;
+extern void writeShortCuts(Xml& xml);
+extern void readShortCuts(QDomNode);
+extern QAction* getAction(const char*, QObject* parent);
+extern QMap<QString, Shortcut*> shortcuts;
+#endif
diff --git a/muse_qt4_evolution/muse/song.cpp b/muse_qt4_evolution/muse/song.cpp
new file mode 100644
index 00000000..a1f3bff0
--- /dev/null
+++ b/muse_qt4_evolution/muse/song.cpp
@@ -0,0 +1,1552 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "muse.h"
+#include "song.h"
+#include "track.h"
+#include "undo.h"
+#include "globals.h"
+#include "event.h"
+#include "midiedit/drummap.h"
+#include "audio.h"
+#include "mixer.h"
+#include "audiodev.h"
+#include "gconfig.h"
+#include "al/marker.h"
+#include "al/sig.h"
+#include "al/tempo.h"
+#include "midi.h"
+#include "plugin.h"
+#include "pipeline.h"
+#include "synth.h"
+#include "midiplugin.h"
+#include "midirc.h"
+#include "part.h"
+#include "conf.h"
+#include "midioutport.h"
+#include "midiinport.h"
+#include "instruments/minstrument.h"
+
+Song* song;
+
+//---------------------------------------------------------
+// Song
+//---------------------------------------------------------
+
+Song::Song()
+ :QObject(0)
+ {
+ undoList = new UndoList;
+ redoList = new UndoList;
+ _markerList = new AL::MarkerList;
+ _globalPitchShift = 0;
+ clear(false);
+ }
+
+//---------------------------------------------------------
+// Song
+//---------------------------------------------------------
+
+Song::~Song()
+ {
+ delete undoList;
+ delete redoList;
+ delete _markerList;
+// delete esettingsList;
+ }
+
+//---------------------------------------------------------
+// putEvent
+//---------------------------------------------------------
+
+void Song::putEvent(const MidiEvent& event)
+ {
+ eventFifo.put(event);
+ }
+
+//---------------------------------------------------------
+// setTempo
+// public slot
+//---------------------------------------------------------
+
+void Song::setTempo(int newTempo)
+ {
+ audio->msgSetTempo(pos[0].tick(), newTempo, true);
+ }
+
+//---------------------------------------------------------
+// setSig
+// called from transport window
+//---------------------------------------------------------
+
+void Song::setSig(const AL::TimeSignature& sig)
+ {
+ if (_masterFlag) {
+ audio->msgAddSig(pos[0].tick(), sig);
+ }
+ }
+
+//---------------------------------------------------------
+// addEvent
+// return true if event was added
+//---------------------------------------------------------
+
+bool Song::addEvent(const Event& event, Part* part)
+ {
+ if (event.type() == Controller) {
+ MidiTrack* track = (MidiTrack*)part->track();
+ int tick = event.tick() + part->tick();
+ int cntrl = event.dataA();
+ CVal val;
+ val.i = event.dataB();
+ if (!track->addControllerVal(cntrl, tick, val)) {
+ track->addMidiController(track->instrument(), cntrl);
+ if (!track->addControllerVal(cntrl, tick, val)) {
+ return false;
+ }
+ }
+ }
+ else {
+ part->events()->add(event);
+ }
+ return true;
+ }
+
+//---------------------------------------------------------
+// changeEvent
+//---------------------------------------------------------
+
+void Song::changeEvent(const Event& oldEvent, const Event& newEvent, Part* part)
+ {
+ iEvent i = part->events()->find(oldEvent);
+ if (i == part->events()->end()) {
+ printf("Song::changeEvent(): EVENT not found !! %ld\n", long(part->events()->size()));
+ // abort();
+ return;
+ }
+ part->events()->erase(i);
+ part->events()->add(newEvent);
+
+ if (newEvent.type() == Controller) {
+ MidiTrack* track = (MidiTrack*)part->track();
+ int tick = newEvent.tick() + part->tick();
+ int cntrl = newEvent.dataA();
+ CVal val;
+ val.i = newEvent.dataB();
+ track->addControllerVal(cntrl, tick, val);
+ }
+ }
+
+//---------------------------------------------------------
+// deleteEvent
+//---------------------------------------------------------
+
+void Song::deleteEvent(const Event& event, Part* part)
+ {
+#if 0 //TODO3
+ if (event.type() == Controller) {
+ MidiTrack* track = (MidiTrack*)part->track();
+ int ch = track->outChannel();
+ int tick = event.tick() + part->tick();
+ int cntrl = event.dataA();
+ midiPorts[track->outPort()].deleteController(ch, tick, cntrl);
+ }
+#endif
+ iEvent ev = part->events()->find(event);
+ if (ev == part->events()->end()) {
+ printf("event not found in part\n");
+ return;
+ }
+ part->events()->erase(ev);
+ }
+
+//---------------------------------------------------------
+// setLoop
+// set transport loop flag
+//---------------------------------------------------------
+
+void Song::setLoop(bool f)
+ {
+ if (loopFlag != f) {
+ loopFlag = f;
+ loopAction->setChecked(loopFlag);
+ emit loopChanged(loopFlag);
+ }
+ }
+
+//---------------------------------------------------------
+// setRecord
+// set record flag
+//---------------------------------------------------------
+
+void Song::setRecord(bool f)
+ {
+ if (recordFlag == f)
+ return;
+ if (muse->playAction->isChecked()) {
+ //
+ // dont allow record state changes when rolling
+ //
+ recordAction->setChecked(!f);
+ return;
+ }
+
+ if (f) {
+ bool alreadyRecEnabled = false;
+ Track *selectedTrack = 0;
+
+ // loop through list and check if any track is rec enabled
+ // if not then rec enable the selected track
+
+ WaveTrackList* wtl = waves();
+ for (iWaveTrack i = wtl->begin(); i != wtl->end(); ++i) {
+ if ((*i)->recordFlag()) {
+ alreadyRecEnabled = true;
+ break;
+ }
+ if ((*i)->selected())
+ selectedTrack = (*i);
+ }
+ if (!alreadyRecEnabled) {
+ MidiTrackList* mtl = midis();
+ for (iMidiTrack it = mtl->begin(); it != mtl->end(); ++it) {
+ if ((*it)->recordFlag()) {
+ alreadyRecEnabled = true;
+ break;
+ }
+ if ((*it)->selected())
+ selectedTrack = (*it);
+ }
+ }
+ if (!alreadyRecEnabled && selectedTrack) {
+ // enable recording on selected track:
+ setRecordFlag(selectedTrack, true);
+ }
+ else {
+ if (!alreadyRecEnabled) {
+ // If there are no tracks, do not enable record.
+ // TODO: This forces the user to first enable record on a track
+ // which probably is a bad thing. Maybe we should warn
+ // only when the user actually starts recording by pressing
+ // play.
+
+ QMessageBox::critical(0, "MusE: Record",
+ "No track(s) enabled for recording");
+ f = false;
+ }
+ }
+ }
+ if (!f)
+ bounceTrack = 0;
+ recordAction->setChecked(f);
+ if (f != recordFlag) {
+ recordFlag = f;
+ emit recordChanged(recordFlag);
+ }
+ }
+
+//---------------------------------------------------------
+// setPunchin
+// set punchin flag
+//---------------------------------------------------------
+
+void Song::setPunchin(bool f)
+ {
+ if (punchinFlag != f) {
+ punchinFlag = f;
+ punchinAction->setChecked(punchinFlag);
+ emit punchinChanged(punchinFlag);
+ }
+ }
+
+//---------------------------------------------------------
+// setPunchout
+// set punchout flag
+//---------------------------------------------------------
+
+void Song::setPunchout(bool f)
+ {
+ if (punchoutFlag != f) {
+ punchoutFlag = f;
+ punchoutAction->setChecked(punchoutFlag);
+ emit punchoutChanged(punchoutFlag);
+ }
+ }
+
+//---------------------------------------------------------
+// setClick
+//---------------------------------------------------------
+
+void Song::setClick(bool val)
+ {
+ if (_click != val) {
+ _click = val;
+ emit clickChanged(_click);
+ }
+ }
+
+//---------------------------------------------------------
+// setQuantize
+//---------------------------------------------------------
+
+void Song::setQuantize(bool val)
+ {
+ if (_quantize != val) {
+ _quantize = val;
+ emit quantizeChanged(_quantize);
+ }
+ }
+
+//---------------------------------------------------------
+// setMasterFlag
+//---------------------------------------------------------
+
+void Song::setMasterFlag(bool val)
+ {
+ _masterFlag = val;
+ if (AL::tempomap.setMasterFlag(cpos(), val)) {
+ emit songChanged(SC_MASTER);
+ emit tempoChanged();
+ }
+ }
+
+//---------------------------------------------------------
+// setPlay
+// set transport play flag
+//---------------------------------------------------------
+
+void Song::setPlay(bool f)
+ {
+ // only allow the user to set the button "on"
+ if (!f) {
+ printf(" setPlay checked\n");
+ muse->playAction->setChecked(true);
+ }
+ else {
+ if (recordAction->isChecked()) {
+ startUndo();
+ MidiTrackList* ml = midis();
+ for (iMidiTrack it = ml->begin(); it != ml->end(); ++it) {
+ if ((*it)->recordFlag())
+ (*it)->startRecording();
+ }
+ WaveTrackList* wl = waves();
+ for (iWaveTrack wt = wl->begin(); wt != wl->end(); ++wt) {
+ if ((*wt)->recordFlag())
+ (*wt)->startRecording();
+ }
+ OutputList* ol = outputs();
+ for (iAudioOutput o = ol->begin(); o != ol->end(); ++o) {
+ if ((*o)->recordFlag())
+ (*o)->startRecording();
+ }
+ }
+ audio->msgPlay(true);
+ }
+ }
+
+//---------------------------------------------------------
+// setStop
+//---------------------------------------------------------
+
+void Song::setStop(bool f)
+ {
+ // only allow the user to set the button "on"
+ if (f)
+ audio->msgPlay(false);
+ else
+ muse->stopAction->setChecked(true);
+ }
+
+//---------------------------------------------------------
+// setStopPlay
+//---------------------------------------------------------
+
+void Song::setStopPlay(bool f)
+ {
+ emit playChanged(f); // signal transport window
+ muse->playAction->setChecked(f);
+ muse->stopAction->setChecked(!f);
+ }
+
+//---------------------------------------------------------
+// swapTracks
+//---------------------------------------------------------
+
+void Song::swapTracks(int i1, int i2)
+ {
+ undoOp(UndoOp::SwapTrack, i1, i2);
+ Track* track = _tracks[i1];
+ _tracks[i1] = _tracks[i2];
+ _tracks[i2] = track;
+ }
+
+//---------------------------------------------------------
+// setTickPos
+//---------------------------------------------------------
+/*
+void Song::setTickPos(int idx, unsigned int tick)
+ {
+ Pos pos(tick);
+ setPos(idx, pos);
+ }
+*/
+//---------------------------------------------------------
+// setPos
+// song->setPos(Song::CPOS, pos, true, true, true);
+//---------------------------------------------------------
+
+void Song::setPos(int idx, const AL::Pos& val)
+ {
+ setPos(idx, val, true, true, false);
+ }
+
+void Song::setPos(int idx, const Pos& val, bool sig, bool isSeek, bool follow)
+ {
+// printf("setPos %d sig=%d,seek=%d,scroll=%d\n",
+// idx, sig, isSeek, follow);
+// val.dump(0);
+// printf("\n");
+
+ if (pos[idx] == val)
+ return;
+ if (idx == CPOS) {
+// _vcpos = val;
+ if (isSeek) {
+ seekInProgress = true;
+ audio->msgSeek(val);
+ return;
+ }
+ }
+ pos[idx] = val;
+ bool swap = pos[LPOS] > pos[RPOS];
+ if (swap) { // swap lpos/rpos if lpos > rpos
+ Pos tmp = pos[LPOS];
+ pos[LPOS] = pos[RPOS];
+ pos[RPOS] = tmp;
+ }
+ if (sig) {
+ if (swap) {
+ emit posChanged(LPOS, pos[LPOS], follow);
+ emit posChanged(RPOS, pos[RPOS], follow);
+ if (idx != LPOS && idx != RPOS)
+ emit posChanged(idx, pos[idx], follow);
+ }
+ else
+ emit posChanged(idx, pos[idx], follow);
+ }
+
+ if (idx == CPOS)
+ updateCurrentMarker();
+ }
+
+//---------------------------------------------------------
+// updateCurrentMarker
+//---------------------------------------------------------
+
+void Song::updateCurrentMarker()
+ {
+ AL::iMarker i1 = _markerList->begin();
+ AL::iMarker i2 = i1;
+ bool currentChanged = false;
+ Pos& val = pos[CPOS];
+ for (; i1 != _markerList->end(); ++i1) {
+ ++i2;
+ if (val.tick() >= i1->first && (i2==_markerList->end() || val.tick() < i2->first)) {
+ if (i1->second.current())
+ return;
+ i1->second.setCurrent(true);
+ if (currentChanged) {
+ emit markerChanged(MARKER_CUR);
+ return;
+ }
+ ++i1;
+ for (; i1 != _markerList->end(); ++i1) {
+ if (i1->second.current())
+ i1->second.setCurrent(false);
+ }
+ emit markerChanged(MARKER_CUR);
+ return;
+ }
+ else {
+ if (i1->second.current()) {
+ currentChanged = true;
+ i1->second.setCurrent(false);
+ }
+ }
+ }
+ if (currentChanged)
+ emit markerChanged(MARKER_CUR);
+ }
+
+//---------------------------------------------------------
+// forward
+// roll forward config.division ticks
+//---------------------------------------------------------
+
+void Song::forward()
+ {
+ unsigned newPos = pos[0].tick() + config.division;
+ audio->msgSeek(Pos(newPos, AL::TICKS));
+ }
+
+//---------------------------------------------------------
+// rewind
+// roll back config.division ticks
+//---------------------------------------------------------
+
+void Song::rewind()
+ {
+ unsigned newPos;
+ if (unsigned(config.division) > pos[0].tick())
+ newPos = 0;
+ else
+ newPos = pos[0].tick() - config.division;
+ audio->msgSeek(Pos(newPos, AL::TICKS));
+ }
+
+//---------------------------------------------------------
+// rewindStart
+//---------------------------------------------------------
+
+void Song::rewindStart()
+ {
+ audio->msgSeek(Pos(0, AL::TICKS));
+ }
+
+//---------------------------------------------------------
+// update
+//---------------------------------------------------------
+
+void Song::update(int flags)
+ {
+ if (flags == 0)
+ return;
+ emit songChanged(flags);
+ if (flags & SC_TEMPO)
+ emit tempoChanged();
+ }
+
+//---------------------------------------------------------
+// updatePos
+//---------------------------------------------------------
+
+void Song::updatePos()
+ {
+ emit posChanged(0, pos[0], false);
+ emit posChanged(1, pos[1], false);
+ emit posChanged(2, pos[2], false);
+ }
+
+//---------------------------------------------------------
+// roundUpBar
+//---------------------------------------------------------
+
+int Song::roundUpBar(int t) const
+ {
+ int bar, beat;
+ unsigned tick;
+ AL::sigmap.tickValues(t, &bar, &beat, &tick);
+ if (beat || tick)
+ return AL::sigmap.bar2tick(bar+1, 0, 0);
+ return t;
+ }
+
+//---------------------------------------------------------
+// roundUpBeat
+//---------------------------------------------------------
+
+int Song::roundUpBeat(int t) const
+ {
+ int bar, beat;
+ unsigned tick;
+ AL::sigmap.tickValues(t, &bar, &beat, &tick);
+ if (tick)
+ return AL::sigmap.bar2tick(bar, beat+1, 0);
+ return t;
+ }
+
+//---------------------------------------------------------
+// roundDownBar
+//---------------------------------------------------------
+
+int Song::roundDownBar(int t) const
+ {
+ int bar, beat;
+ unsigned tick;
+ AL::sigmap.tickValues(t, &bar, &beat, &tick);
+ return AL::sigmap.bar2tick(bar, 0, 0);
+ }
+
+//---------------------------------------------------------
+// dumpMaster
+//---------------------------------------------------------
+
+void Song::dumpMaster()
+ {
+ AL::tempomap.dump();
+ AL::sigmap.dump();
+ }
+
+//---------------------------------------------------------
+// getSelectedParts
+//---------------------------------------------------------
+
+PartList* Song::getSelectedMidiParts() const
+ {
+ PartList* parts = new PartList();
+
+ //------------------------------------------------------
+ // wenn ein Part selektiert ist, diesen editieren
+ // wenn ein Track selektiert ist, den Ersten
+ // Part des Tracks editieren, die restlichen sind
+ // 'ghostparts'
+ // wenn mehrere Parts selektiert sind, dann Ersten
+ // editieren, die restlichen sind 'ghostparts'
+ //
+
+ // collect marked parts
+ for (ciMidiTrack t = _midis.begin(); t != _midis.end(); ++t) {
+ MidiTrack* track = *t;
+ PartList* pl = track->parts();
+ for (iPart p = pl->begin(); p != pl->end(); ++p) {
+ if (p->second->selected()) {
+ parts->add(p->second);
+ }
+ }
+ }
+ // if no part is selected, then search for selected track
+ // and collect all parts of this track
+
+ if (parts->empty()) {
+ for (ciMidiTrack t = _midis.begin(); t != _midis.end(); ++t) {
+ if ((*t)->selected()) {
+ MidiTrack* track = *t;
+ PartList* pl = track->parts();
+ for (iPart p = pl->begin(); p != pl->end(); ++p)
+ parts->add(p->second);
+ break;
+ }
+ }
+ }
+ return parts;
+ }
+
+PartList* Song::getSelectedWaveParts() const
+ {
+ PartList* parts = new PartList();
+
+ //------------------------------------------------------
+ // wenn ein Part selektiert ist, diesen editieren
+ // wenn ein Track selektiert ist, den Ersten
+ // Part des Tracks editieren, die restlichen sind
+ // 'ghostparts'
+ // wenn mehrere Parts selektiert sind, dann Ersten
+ // editieren, die restlichen sind 'ghostparts'
+ //
+
+ // markierte Parts sammeln
+ for (ciWaveTrack t = _waves.begin(); t != _waves.end(); ++t) {
+ WaveTrack* track = *t;
+ PartList* pl = track->parts();
+ for (iPart p = pl->begin(); p != pl->end(); ++p) {
+ if (p->second->selected()) {
+ parts->add(p->second);
+ }
+ }
+ }
+ // wenn keine Parts selektiert, dann markierten Track suchen
+ // und alle Parts dieses Tracks zusammensuchen
+
+ if (parts->empty()) {
+ for (ciWaveTrack t = _waves.begin(); t != _waves.end(); ++t) {
+ if ((*t)->selected()) {
+ WaveTrack* track = *t;
+ PartList* pl = track->parts();
+ for (iPart p = pl->begin(); p != pl->end(); ++p)
+ parts->add(p->second);
+ break;
+ }
+ }
+ }
+ return parts;
+ }
+
+//---------------------------------------------------------
+// beat
+// update gui
+//---------------------------------------------------------
+
+void Song::beat()
+ {
+ updateFlags = 0;
+ if (audio->isPlaying()) {
+ int tick = audio->seqTime()->curTickPos;
+ setPos(0, tick, true, false, true);
+ }
+ if (audio->isRecording()) {
+ MidiTrackList* ml = midis();
+ for (iMidiTrack it = ml->begin(); it != ml->end(); ++it) {
+ MidiTrack* mt = *it;
+ if (mt->recordFlag())
+ mt->recordBeat();
+ }
+ WaveTrackList* wl = waves();
+ for (iWaveTrack wt = wl->begin(); wt != wl->end(); ++wt) {
+ WaveTrack* mt = *wt;
+ if (mt->recordFlag())
+ mt->recordBeat();
+ }
+ }
+ while (!eventFifo.isEmpty()) {
+ MidiEvent event(eventFifo.get());
+ if (rcEnable)
+ midiRCList.doAction(event);
+ emit midiEvent(event);
+ }
+ //
+ // update controller guis
+ //
+ TrackList* tl = tracks();
+ for (iTrack it = tl->begin(); it != tl->end(); ++it) {
+ Track* track = *it;
+ if (!track->autoRead())
+ continue;
+ track->updateController();
+ }
+ update(updateFlags);
+ }
+
+//---------------------------------------------------------
+// setLen
+//---------------------------------------------------------
+
+void Song::setLen(int l)
+ {
+ _len = roundUpBar(l);
+ AL::Pos pos(_len);
+ int bar, beat;
+ unsigned tick;
+ AL::sigmap.tickValues(_len, &bar, &beat, &tick);
+ emit measureLenChanged(bar);
+ emit lenChanged(pos);
+ }
+
+//---------------------------------------------------------
+// setMeasureLen
+//---------------------------------------------------------
+
+void Song::setMeasureLen(int b)
+ {
+ setLen(AL::sigmap.bar2tick(b, 0, 0));
+ }
+
+//---------------------------------------------------------
+// addMarker
+//---------------------------------------------------------
+
+AL::Marker* Song::addMarker(const QString& s, const AL::Pos& pos)
+ {
+ AL::Marker* marker = _markerList->add(s, pos);
+ updateCurrentMarker();
+ emit markerChanged(MARKER_ADD);
+ return marker;
+ }
+
+//---------------------------------------------------------
+// removeMarker
+//---------------------------------------------------------
+
+void Song::removeMarker(AL::Marker* marker)
+ {
+ _markerList->remove(marker);
+ updateCurrentMarker();
+ emit markerChanged(MARKER_REMOVE);
+ }
+
+//---------------------------------------------------------
+// setMarkerName
+//---------------------------------------------------------
+
+AL::Marker* Song::setMarkerName(AL::Marker* m, const QString& s)
+ {
+ m->setName(s);
+ emit markerChanged(MARKER_NAME);
+ return m;
+ }
+
+AL::Marker* Song::setMarkerTick(AL::Marker* m, int t)
+ {
+ AL::Marker mm(*m);
+ _markerList->remove(m);
+ mm.setTick(t);
+ m = _markerList->add(mm);
+ updateCurrentMarker();
+ emit markerChanged(MARKER_TICK);
+ return m;
+ }
+
+AL::Marker* Song::setMarkerLock(AL::Marker* m, bool f)
+ {
+ m->setType(f ? AL::FRAMES : AL::TICKS);
+ updateCurrentMarker();
+ emit markerChanged(MARKER_LOCK);
+ return m;
+ }
+
+//---------------------------------------------------------
+// endMsgCmd
+//---------------------------------------------------------
+
+void Song::endMsgCmd()
+ {
+ redoList->clear(); // TODO: delete elements in list
+ undoAction->setEnabled(true);
+ redoAction->setEnabled(false);
+ update(updateFlags);
+ }
+
+//---------------------------------------------------------
+// undo
+//---------------------------------------------------------
+
+void Song::undo()
+ {
+ updateFlags = 0;
+ if (doUndo1())
+ return;
+ audio->msgUndo();
+ doUndo3();
+ redoAction->setEnabled(true);
+ undoAction->setEnabled(!undoList->empty());
+ if (updateFlags) {
+ emit songChanged(updateFlags);
+ if (updateFlags & SC_TEMPO)
+ emit tempoChanged();
+ }
+ }
+
+//---------------------------------------------------------
+// redo
+//---------------------------------------------------------
+
+void Song::redo()
+ {
+ updateFlags = 0;
+ if (doRedo1())
+ return;
+ audio->msgRedo();
+ doRedo3();
+ undoAction->setEnabled(true);
+ redoAction->setEnabled(!redoList->empty());
+ if (updateFlags) {
+ emit songChanged(updateFlags);
+ if (updateFlags & SC_TEMPO)
+ emit tempoChanged();
+ }
+ }
+
+//---------------------------------------------------------
+// processMsg
+// executed in realtime thread context
+//---------------------------------------------------------
+
+void Song::processMsg(AudioMsg* msg)
+ {
+ switch(msg->id) {
+ case SEQM_UNDO:
+ doUndo2();
+ break;
+ case SEQM_REDO:
+ doRedo2();
+ break;
+
+ case SEQM_ADD_EVENT:
+ updateFlags = SC_EVENT_INSERTED;
+ if (addEvent(msg->ev1, (Part*)(msg->p2))) {
+ undoOp(UndoOp::AddEvent, msg->ev1, (Part*)msg->p2);
+ }
+ else
+ updateFlags = 0;
+ break;
+
+ case SEQM_ADD_EVENTS:
+ updateFlags = SC_EVENT_INSERTED;
+ for (int i = 0; i < msg->el->size(); ++i) {
+ if (addEvent(msg->el->at(i), (Part*)(msg->p2))) {
+ undoOp(UndoOp::AddEvent, msg->el->at(i), (Part*)msg->p2);
+ }
+ }
+ break;
+
+ case SEQM_REMOVE_EVENT:
+ {
+ Event event = msg->ev1;
+ Part* part = (Part*)(msg->p2);
+ Event e;
+ undoOp(UndoOp::DeleteEvent, e, event, part);
+ deleteEvent(event, part);
+ updateFlags = SC_EVENT_REMOVED;
+ }
+ break;
+ case SEQM_CHANGE_EVENT:
+ changeEvent(msg->ev1, msg->ev2, (Part*)(msg->p3));
+ undoOp(UndoOp::ModifyEvent, msg->ev2, msg->ev1, (Part*)msg->p3);
+ updateFlags = SC_EVENT_MODIFIED;
+ break;
+
+ case SEQM_ADD_TEMPO:
+ undoOp(UndoOp::AddTempo, msg->a, msg->b);
+ AL::tempomap.addTempo(msg->a, msg->b);
+ updateFlags = SC_TEMPO;
+ break;
+
+ case SEQM_SET_TEMPO:
+ undoOp(UndoOp::AddTempo, msg->a, msg->b);
+ AL::tempomap.setTempo(msg->a, msg->b);
+ updateFlags = SC_TEMPO;
+ break;
+
+ case SEQM_SET_GLOBAL_TEMPO:
+ AL::tempomap.setGlobalTempo(msg->a);
+ break;
+
+ case SEQM_REMOVE_TEMPO:
+ undoOp(UndoOp::DeleteTempo, msg->a, msg->b);
+ AL::tempomap.delTempo(msg->a);
+ updateFlags = SC_TEMPO;
+ break;
+
+ case SEQM_ADD_SIG:
+ undoOp(UndoOp::AddSig, msg->a, msg->b, msg->c);
+ AL::sigmap.add(msg->a, AL::TimeSignature(msg->b, msg->c));
+ updateFlags = SC_SIG;
+ break;
+
+ case SEQM_REMOVE_SIG:
+ //printf("processMsg (SEQM_REMOVE_SIG) UndoOp::DeleteSig. Deleting AL::sigmap at: %d with z=%d n=%d\n", msg->a, msg->b, msg->c);
+ undoOp(UndoOp::DeleteSig, msg->a, msg->b, msg->c);
+ AL::sigmap.del(msg->a);
+ updateFlags = SC_SIG;
+ break;
+
+ case SEQM_ADD_CTRL:
+ msg->track->addControllerVal(msg->a, msg->time, msg->cval1);
+ break;
+
+ case SEQM_REMOVE_CTRL:
+ msg->track->removeControllerVal(msg->a, msg->time);
+ break;
+
+ case SEQM_ADD_TRACK:
+ insertTrack2(msg->track);
+ break;
+
+ case SEQM_REMOVE_TRACK:
+ removeTrack2(msg->track);
+ break;
+
+ case SEQM_ADD_PART:
+ {
+ Part* part = (Part*)(msg->p1);
+ part->track()->addPart(part);
+ }
+ break;
+
+ case SEQM_REMOVE_PART:
+ {
+ Part* part = (Part*)(msg->p1);
+ Track* track = part->track();
+ track->parts()->remove(part);
+ }
+ break;
+
+ case SEQM_CHANGE_PART:
+ {
+ Part* newPart = (Part*)msg->p2;
+ Part* oldPart = (Part*)msg->p1;
+ Part part = *newPart;
+ *newPart = *oldPart;
+ *oldPart = part;
+ }
+ break;
+
+ case SEQM_MOVE_TRACK:
+ moveTrack((Track*)(msg->p1), (Track*)(msg->p2));
+ break;
+
+ default:
+ printf("unknown seq message %d\n", msg->id);
+ break;
+ }
+ }
+
+//---------------------------------------------------------
+// panic
+//---------------------------------------------------------
+
+void Song::panic()
+ {
+ audio->msgPanic();
+ }
+
+//---------------------------------------------------------
+// clear
+// signal - emit signals for changes if true
+// called from constructor as clear(false) and
+// from MusE::clearSong() as clear(false)
+//---------------------------------------------------------
+
+void Song::clear(bool signal)
+ {
+ _created = false;
+ _backupWritten = false;
+ dirty = false;
+ _comment = "";
+ _createDate = QDateTime::currentDateTime();
+
+ seekInProgress = false;
+ bounceTrack = 0;
+
+// for (iTrack i = _tracks.begin(); i != _tracks.end(); ++i)
+// (*i)->deactivate();
+
+ _selectedTrack = 0;
+ _tracks.clear();
+
+ qDeleteAll(_midis);
+ _midis.clear();
+
+ qDeleteAll(_waves);
+ _waves.clear();
+
+ qDeleteAll(_inputs); // audio input ports
+ _inputs.clear();
+
+ qDeleteAll(_outputs); // audio output ports
+ _outputs.clear();
+
+ qDeleteAll(_groups); // mixer groups
+ _groups.clear();
+
+ qDeleteAll(_synthIs);
+ _synthIs.clear();
+
+ qDeleteAll(_midiSyntis);
+ _midiSyntis.clear();
+
+ qDeleteAll(_midiOutPorts);
+ _midiOutPorts.clear();
+
+ qDeleteAll(_midiInPorts);
+ _midiInPorts.clear();
+
+ AL::tempomap.clear();
+ AL::sigmap.clear();
+ undoList->clear();
+ redoList->clear();
+ _markerList->clear();
+ pos[0].setTick(0);
+ pos[1].setTick(0);
+ pos[2].setTick(0);
+
+ _masterFlag = true;
+ loopFlag = false;
+ loopFlag = false;
+ punchinFlag = false;
+ punchoutFlag = false;
+ recordFlag = false;
+ soloFlag = false;
+ // seq
+ _recMode = REC_OVERDUP;
+ _cycleMode = CYCLE_NORMAL;
+ _click = false;
+ _quantize = false;
+ _len = 1; // song len in ticks
+ // _tempo = 500000; // default tempo 120
+ if (signal) {
+ emit loopChanged(false);
+ recordChanged(false);
+ }
+ }
+
+//---------------------------------------------------------
+// seqSignal
+// sequencer message to GUI
+// execution environment: gui thread
+//---------------------------------------------------------
+
+void Song::seqSignal(int fd)
+ {
+ char buffer[16];
+
+ int n = ::read(fd, buffer, 16);
+ if (n < 0) {
+ printf("Song: seqSignal(): READ PIPE failed: %s\n",
+ strerror(errno));
+ return;
+ }
+ bool graphChangedCalled = false;
+ bool seekDone = false;
+
+// printf("seqSignal %d\n", n);
+ for (int i = 0; i < n; ++i) {
+// printf(" seqSignal to gui:<%c>\n", buffer[i]);
+ switch(buffer[i]) {
+ case MSG_STOP:
+ stopRolling();
+ break;
+ case MSG_PLAY:
+ setStopPlay(true);
+ break;
+ case MSG_RECORD:
+ setRecord(true);
+ break;
+ case MSG_SEEK:
+ if (!seekDone) {
+ seekDone = true;
+ setPos(0, audio->seqTime()->curTickPos, true, false, !seekInProgress);
+ seekInProgress = false;
+ beat(); // update controller guis
+ }
+ break;
+ case MSG_JACK_SHUTDOWN:
+ restartJack();
+ break;
+
+ case MSG_START_BOUNCE:
+ {
+ bool useFreewheel = config.useJackFreewheelMode;
+ if (useFreewheel) {
+ // check:
+ // we cannot use freewheel, if there are active audio input
+ // strips
+
+ for (iAudioInput ii = _inputs.begin(); ii != _inputs.end(); ++i) {
+ AudioInput* ai = *ii;
+ if (!(ai->mute() || ai->off())) {
+ useFreewheel = false;
+ break;
+ }
+ }
+ if (useFreewheel)
+ audioDriver->setFreewheel(true);
+ }
+ }
+ break;
+
+ case MSG_STOP_BOUNCE:
+ if (audio->freewheel())
+ audioDriver->setFreewheel(false);
+ audio->msgPlay(false);
+ break;
+
+ case MSG_GRAPH_CHANGED:
+ if (!graphChangedCalled) {
+ printf(" graph changed\n");
+ graphChangedCalled = true;
+ audioDriver->graphChanged();
+ }
+ break;
+
+ default:
+ printf("unknown Seq Signal <%c>\n", buffer[i]);
+ break;
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// stopRolling
+//---------------------------------------------------------
+
+void Song::stopRolling()
+ {
+ setStopPlay(false);
+ if (record()) {
+ audio->msgIdle(true); // gain access to all data structures
+
+ WaveTrackList* wl = waves();
+ for (iWaveTrack it = wl->begin(); it != wl->end(); ++it) {
+ WaveTrack* track = *it;
+ if (track->recordFlag() || bounceTrack == track) {
+ track->stopRecording(audio->getStartRecordPos(), audio->getEndRecordPos());
+ }
+ }
+ MidiTrackList* ml = midis();
+ for (iMidiTrack it = ml->begin(); it != ml->end(); ++it) {
+ if ((*it)->recordFlag())
+ (*it)->stopRecording();
+ }
+ OutputList* ol = outputs();
+ for (iAudioOutput io = ol->begin(); io != ol->end(); ++io) {
+ AudioOutput* ao = *io;
+ if (ao->recordFlag())
+ ao->stopRecording(audio->getStartRecordPos(), audio->getEndRecordPos());
+ }
+ audio->msgIdle(false);
+ updateFlags |= SC_PART_MODIFIED;
+ endUndo(updateFlags);
+ setRecord(false);
+ }
+ //
+ // process recorded automation events
+ //
+ for (iTrack it = tracks()->begin(); it != tracks()->end(); ++it) {
+ Track* track = *it;
+ if (!track->autoWrite())
+ continue;
+ CtrlRecList* crl = track->recEvents();
+ CtrlList* cl = track->controller();
+ for (iCtrl icl = cl->begin(); icl != cl->end(); ++icl) {
+ Ctrl* cl = icl->second;
+ int id = cl->id();
+ //
+ // remove old events from record region
+ //
+ bool hasEvents = false;
+// int start = audio->getStartRecordPos().frame();
+// int end = audio->getEndRecordPos().frame();
+// iCtrlVal s = cl->lower_bound(start);
+// iCtrlVal e = cl->lower_bound(end);
+// cl->erase(s, e);
+// }
+
+ for (iCtrlRec icr = crl->begin(); icr != crl->end(); ++icr) {
+ if (icr->id == id && icr->type == 1) {
+ int start = icr->time;
+ ++icr;
+ for (; icr != crl->end(); ++icr) {
+ if (icr->id == id && icr->type == 2) {
+ int end = icr->time;
+ if (track->timeType() == AL::TICKS) {
+ start = AL::tempomap.frame2tick(start);
+ end = AL::tempomap.frame2tick(end);
+ }
+ iCtrlVal s = cl->lowerBound(start);
+ iCtrlVal e = cl->lowerBound(end);
+ while (s != e)
+ cl->erase(s++);
+ hasEvents = true;
+ break;
+ }
+ }
+ if (icr == crl->end())
+ break;
+ }
+ }
+ //
+ // extract all recorded events for controller "id"
+ // from CtrlRecList and put into cl
+ //
+ for (iCtrlRec icr = crl->begin(); icr != crl->end(); ++icr) {
+ if (icr->id == id && icr->type == 0)
+ cl->add(icr->time, icr->val);
+ }
+ track->emitControllerChanged(id);
+ }
+ crl->clear();
+ track->setAutoWrite(false);
+ }
+ }
+
+//---------------------------------------------------------
+// addControllerVal
+// GUI context
+//---------------------------------------------------------
+
+void Song::cmdAddControllerVal(Track* t, int id, const Pos& pos, CVal val)
+ {
+ Ctrl* c = t->getController(id);
+ if (c == 0) {
+ printf("Song::addControllerVal:: no controller %d found\n", id);
+ return;
+ }
+ cmdAddControllerVal(t, c, pos, val);
+ }
+
+void Song::cmdAddControllerVal(Track* t, Ctrl* c, const Pos& p, CVal val)
+ {
+ unsigned time = t->timeType() == AL::FRAMES ? p.frame() : p.tick();
+ iCtrlVal e = c->find(time);
+ if (e == c->end()) {
+ // add new controller event
+ audio->msgAddController(t, c->id(), time, val);
+ }
+ else {
+ //
+ // change controller is handled inline:
+ //
+ CVal oval = c->value(time);
+ startUndo();
+ undoOp(UndoOp::ModifyCtrl, t, c->id(), time, val, oval);
+ c->add(time, val);
+ endUndo(0);
+ }
+ if (!audio->isPlaying() && t->autoRead()) {
+ // current value may have changed
+ unsigned ctime = t->timeType() == AL::FRAMES ? pos[0].frame() : pos[0].tick();
+ CVal cval = c->value(ctime);
+ if (c->curVal().i != cval.i) {
+ if (t->type() == Track::MIDI) {
+ MidiEvent ev(0, 0, ME_CONTROLLER, c->id(), cval.i);
+ ((MidiTrack*)t)->playMidiEvent(&ev);
+ }
+ c->setCurVal(cval);
+ }
+ }
+ t->emitControllerChanged(c->id()); //moved this out here, otherwise canvas is not updated
+ }
+
+//---------------------------------------------------------
+// setControllerVal
+// GUI context
+//---------------------------------------------------------
+
+void Song::setControllerVal(Track* t, int id, CVal val)
+ {
+ Ctrl* c = t->getController(id);
+ if (c == 0) {
+ printf("Song::addControllerVal:: no controller %d found\n", id);
+ return;
+ }
+ setControllerVal(t, c, val);
+ }
+
+void Song::setControllerVal(Track* t, Ctrl* c, CVal val)
+ {
+ if (t->isMidiTrack()) {
+ if (t->type() == Track::MIDI) {
+ MidiTrack* mt = (MidiTrack*)t;
+ MidiEvent ev(0, 0, ME_CONTROLLER, c->id(), val.i);
+ mt->playMidiEvent(&ev);
+ }
+ else if (t->type() == Track::MIDI_OUT) {
+ MidiOutPort* mp = (MidiOutPort*)t;
+ MidiEvent ev(0, 0, ME_CONTROLLER, c->id(), val.i);
+ mp->playMidiEvent(&ev);
+ }
+ }
+ else {
+ c->setCurVal(val);
+ if (c->id() & 0x3ffff000) {
+ // plugin controller
+ AudioTrack* track = (AudioTrack*) t;
+ bool prefader;
+ int pluginIndex, ctrlIndex;
+ getCtrlPlugin(c->id(), &prefader, &pluginIndex, &ctrlIndex);
+ Pipeline* pipe = prefader ? track->prePipe() : track->postPipe();
+ pipe->plugin(pluginIndex)->setParam(ctrlIndex, val.f);
+ }
+ }
+ c->setCurVal(val);
+
+ if (t->autoWrite()) {
+ unsigned time = t->timeType() == AL::FRAMES ? pos[0].frame() : pos[0].tick();
+ if (audio->isPlaying())
+ t->recEvents()->push_back(CtrlRecVal(time, c->id(), val));
+ else {
+ iCtrlVal e = c->find(time);
+ if (e == c->end()) {
+ // add new controller event
+ audio->msgAddController(t, c->id(), time, val);
+ }
+ else {
+ CVal oval = c->value(time);
+ startUndo();
+ undoOp(UndoOp::ModifyCtrl, t, c->id(), time, val, oval);
+ c->add(time, val);
+ endUndo(0);
+ }
+ }
+ }
+ t->emitControllerChanged(c->id());
+ }
+
+//---------------------------------------------------------
+// cmdRemoveControllerVal
+//---------------------------------------------------------
+
+void Song::cmdRemoveControllerVal(Track* t, int id, unsigned time)
+ {
+ audio->msgRemoveController(t, id, time);
+ t->emitControllerChanged(id);
+ }
+
+//---------------------------------------------------------
+// absoluteProjectPath
+//---------------------------------------------------------
+
+QString Song::absoluteProjectPath() const
+ {
+ return QDir::homePath() + "/" + config.projectPath + "/" + _projectPath;
+ }
+
+//---------------------------------------------------------
+// projectPath
+//---------------------------------------------------------
+
+QString Song::projectPath() const
+ {
+ return _projectPath;
+ }
+
+//---------------------------------------------------------
+// projectName
+//---------------------------------------------------------
+
+QString Song::projectName() const
+ {
+ QString name = _projectPath.split("/").last();
+ return name;
+ }
+
+//---------------------------------------------------------
+// setProjectPath
+//---------------------------------------------------------
+
+void Song::setProjectPath(const QString& s)
+ {
+ _projectPath = s;
+ }
+
+//---------------------------------------------------------
+// read
+// return false on error
+//---------------------------------------------------------
+
+bool Song::read(QFile* qf)
+ {
+ 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 + "\n at line: " + ln + " col: " + col;
+ printf("error reading med file: %s\n", error.toLatin1().data());
+ return false;
+ }
+ for (QDomNode node = doc.documentElement(); !node.isNull(); node = node.nextSibling()) {
+ QDomElement e = node.toElement();
+ if (e.isNull())
+ continue;
+ if (e.tagName() == "muse") {
+ QString sversion = e.attribute("version", "1.0");
+ int major=0, minor=0;
+ sscanf(sversion.toLatin1().data(), "%d.%d", &major, &minor);
+ int version = major << 8 + minor;
+ if (version >= 0x201)
+ read30(node.firstChild());
+ else if (version >= 0x200)
+ read20(node);
+ else if (version == 0x100)
+ read10(node.firstChild());
+ else
+ printf("unsupported *.med file version %s\n", sversion.toLatin1().data());
+ }
+ else
+ printf("MusE: %s not supported\n", e.tagName().toLatin1().data());
+ }
+ dirty = false;
+ return true;
+ }
+
+//---------------------------------------------------------
+// read10
+//---------------------------------------------------------
+
+void Song::read10(QDomNode)
+ {
+ printf("reading type 1.0 *.med files not implemented\n");
+ }
+
+//---------------------------------------------------------
+// read30
+//---------------------------------------------------------
+
+void Song::read30(QDomNode node)
+ {
+ for (; !node.isNull(); node = node.nextSibling()) {
+ QDomElement e = node.toElement();
+ if (e.isNull())
+ continue;
+ if (e.tagName() == "configuration")
+ readConfiguration(node.firstChild());
+ else if (e.tagName() == "song")
+ read(node.firstChild());
+ else if (e.tagName() == "toplevels")
+ muse->readToplevels(node.firstChild());
+ else
+ printf("MusE:read30(): unknown tag %s\n", e.tagName().toLatin1().data());
+ }
+ }
+
+//---------------------------------------------------------
+// restartJack
+//---------------------------------------------------------
+
+void Song::restartJack()
+ {
+ muse->seqStop();
+ audioState = AUDIO_STOP;
+ for (;;) {
+ // give the user a sensible explanation
+ int btn = QMessageBox::critical( muse, tr("Jack shutdown!"),
+ tr("Jack has detected a performance problem which has lead to\n"
+ "MusE being disconnected.\n"
+ "This could happen due to a number of reasons:\n"
+ "- a performance issue with your particular setup.\n"
+ "- a bug in MusE (or possibly in another connected software).\n"
+ "- a random hiccup which might never occur again.\n"
+ "- jack was voluntary stopped by you or someone else\n"
+ "- jack crashed\n"
+ "If there is a persisting problem you are much welcome to discuss it\n"
+ "on the MusE mailinglist.\n"
+ "(there is information about joining the mailinglist on the MusE\n"
+ " homepage which is available through the help menu)\n"
+ "\n"
+ "To proceed check the status of Jack and try to restart it and then .\n"
+ "click on the Restart button."),
+ "restart", "cancel", "save project"
+ );
+ if (btn == 0) {
+ if (!audioDriver->restart())
+ break;
+ }
+ else if (btn == 2)
+ muse->save();
+ else if (btn == 1)
+ exit(-1);
+ }
+ muse->seqRestart();
+ }
+
+//---------------------------------------------------------
+// routeChanged
+//---------------------------------------------------------
+
+void Song::routeChanged(QAction* a)
+ {
+ audio->msgRoute(a->isChecked(), a->data().value<Route>());
+ }
+
diff --git a/muse_qt4_evolution/muse/song.h b/muse_qt4_evolution/muse/song.h
new file mode 100644
index 00000000..3ad574a0
--- /dev/null
+++ b/muse_qt4_evolution/muse/song.h
@@ -0,0 +1,416 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __SONG_H__
+#define __SONG_H__
+
+#include "undo.h"
+#include "midiinport.h"
+#include "midioutport.h"
+#include "miditrack.h"
+#include "midisynti.h"
+#include "wavetrack.h"
+#include "audioinput.h"
+#include "audiooutput.h"
+#include "audiogroup.h"
+#include "synth.h"
+#include "ctrl.h"
+#include "midififo.h"
+
+namespace AL {
+ class Xml;
+ class Marker;
+ class MarkerList;
+ class Pos;
+ };
+
+struct AudioMsg;
+class Event;
+class Track;
+class Part;
+class PartList;
+class Marker;
+class SettingsList;
+
+#define SC_TRACK_INSERTED 1
+#define SC_TRACK_REMOVED 2
+#define SC_TRACK_MODIFIED 4
+#define SC_PART_INSERTED 8
+#define SC_PART_REMOVED 0x10
+#define SC_PART_MODIFIED 0x20
+#define SC_EVENT_INSERTED 0x40
+#define SC_EVENT_REMOVED 0x80
+#define SC_EVENT_MODIFIED 0x100
+#define SC_SIG 0x200 // timing signature
+#define SC_TEMPO 0x400 // tempo map changed
+#define SC_MASTER 0x800 // master flag changed
+#define SC_SELECTION 0x1000
+#define SC_RECFLAG 0x10000
+#define SC_ROUTE 0x20000
+#define SC_CHANNELS 0x40000
+#define SC_CONFIG 0x80000 // midiPort-midiDevice
+#define SC_DRUMMAP 0x100000 // must update drumeditor
+#define SC_AUTOMATION 0x800000
+#define SC_RACK 0x1000000 // mixer rack changed
+#define SC_CLIP_MODIFIED 0x2000000
+
+//---------------------------------------------------------
+// Song
+//---------------------------------------------------------
+
+class Song : public QObject {
+ Q_OBJECT
+
+ public:
+ enum POS { CPOS = 0, LPOS, RPOS };
+ enum FollowMode { NO, JUMP, CONTINUOUS };
+ enum { REC_OVERDUP, REC_REPLACE };
+ enum { CYCLE_NORMAL, CYCLE_MIX, CYCLE_REPLACE };
+ enum { MARKER_CUR, MARKER_ADD, MARKER_REMOVE, MARKER_NAME,
+ MARKER_TICK, MARKER_LOCK };
+
+ private:
+ QString _projectPath;
+ QString _comment;
+ bool _backupWritten; // set after first "save" operation from
+ // user; used to make sure there will
+ // be only one backup for a session
+ bool _created; // project was created in current session
+ QDateTime _createDate;
+
+ MidiFifo eventFifo;
+
+ int updateFlags;
+
+ TrackList _tracks; // tracklist as seen by arranger
+ MidiTrackList _midis;
+ WaveTrackList _waves;
+ InputList _inputs; // audio input ports
+ OutputList _outputs; // audio output ports
+ GroupList _groups; // mixer groups
+ SynthIList _synthIs;
+ MidiSyntiList _midiSyntis;
+ MidiOutPortList _midiOutPorts;
+ MidiInPortList _midiInPorts;
+ Track* _selectedTrack;
+
+ UndoList* undoList;
+ UndoList* redoList;
+ Pos pos[3];
+ AL::MarkerList* _markerList;
+ bool seekInProgress; // user initiated a seek
+
+ bool _masterFlag;
+ bool loopFlag;
+ bool punchinFlag;
+ bool punchoutFlag;
+ bool recordFlag;
+ bool soloFlag;
+ int _recMode;
+ int _cycleMode;
+ bool _click;
+ bool _quantize;
+ unsigned _len; // song len in ticks
+ int _globalPitchShift;
+ void readMarker(QDomNode);
+ void restartJack();
+ void undoPartModify(Part* oPart, Part* nPart, bool undo);
+
+ public slots:
+
+ void undo();
+ void redo();
+
+ void setTempo(int t);
+ void setSig(const AL::TimeSignature&);
+
+ void setMasterFlag(bool flag);
+ void setLoop(bool f);
+ void setRecord(bool f);
+ void setPlay(bool f);
+ void setStop(bool);
+ void forward();
+ void rewindStart();
+ void rewind();
+ void setPunchin(bool f);
+ void setPunchout(bool f);
+ void setClick(bool val);
+ void toggleClick() { setClick(!click()); }
+ void gotoLeftMarker() { setPos(0, lPos()); }
+ void gotoRightMarker() { setPos(0, rPos()); }
+
+ void setQuantize(bool val);
+ void panic();
+ void seqSignal(int fd);
+ Track* addTrack(QAction*);
+ void setMeasureLen(int l);
+ void cmdChangePart(Part*, unsigned, unsigned);
+ void cmdCreateLRPart(Track* track);
+ void setPos(int, const AL::Pos&);
+ void setPos(int, const AL::Pos&, bool sig, bool isSeek = true,
+ bool adjustScrollbar = false);
+ void routeChanged(QAction*);
+
+ signals:
+ void songChanged(int);
+ void posChanged(int, const AL::Pos&, bool);
+ void loopChanged(bool);
+ void recordChanged(bool);
+ void playChanged(bool);
+ void punchinChanged(bool);
+ void punchoutChanged(bool);
+ void clickChanged(bool);
+ void quantizeChanged(bool);
+ void markerChanged(int);
+ void midiPortsChanged();
+ void midiEvent(const MidiEvent&);
+ void trackAdded(Track*, int idx);
+ void trackRemoved(Track*);
+ void lenChanged(const AL::Pos&);
+ void measureLenChanged(int);
+
+ void recordChanged(Track*,bool);
+ void muteChanged(Track*,bool);
+ void soloChanged(Track*,bool);
+ void offChanged(Track*,bool);
+ void autoReadChanged(Track*,bool);
+ void autoWriteChanged(Track*,bool);
+ void trackSelectionChanged(Track*);
+ void tempoChanged();
+
+ public:
+ Song();
+ ~Song();
+
+ void beat();
+ void putEvent(const MidiEvent&);
+ void endMsgCmd();
+ void processMsg(AudioMsg* msg);
+
+ bool dirty;
+ bool backupWritten() const { return _backupWritten; }
+ void setBackupWritten(bool val) { _backupWritten = val; }
+ WaveTrack* bounceTrack;
+
+ void updatePos();
+
+ void read(QDomNode);
+ void write(Xml&) const;
+
+ void clear(bool signal);
+ void update(int flags = -1);
+
+ int globalPitchShift() const { return _globalPitchShift; }
+ void setGlobalPitchShift(int val) { _globalPitchShift = val; }
+
+ //-----------------------------------------
+ // Marker
+ //-----------------------------------------
+
+ AL::MarkerList* marker() const { return _markerList; }
+ AL::Marker* addMarker(const QString& s, const AL::Pos&);
+ void removeMarker(AL::Marker*);
+ AL::Marker* setMarkerName(AL::Marker*, const QString&);
+ AL::Marker* setMarkerTick(AL::Marker*, int);
+ AL::Marker* setMarkerLock(AL::Marker*, bool);
+ void setMarkerCurrent(AL::Marker* m, bool f);
+
+ //-----------------------------------------
+ // transport
+ //-----------------------------------------
+
+ const Pos& cPos() const { return pos[0]; }
+ const Pos& lPos() const { return pos[1]; }
+ const Pos& rPos() const { return pos[2]; }
+ unsigned cpos() const { return pos[0].tick(); }
+ unsigned lpos() const { return pos[1].tick(); }
+ unsigned rpos() const { return pos[2].tick(); }
+
+ bool loop() const { return loopFlag; }
+ bool record() const { return recordFlag; }
+ bool punchin() const { return punchinFlag; }
+ bool punchout() const { return punchoutFlag; }
+ bool masterFlag() const { return _masterFlag; }
+ void setRecMode(int val) { _recMode = val; }
+ int recMode() const { return _recMode; }
+ void setCycleMode(int val) { _cycleMode = val; }
+ int cycleMode() const { return _cycleMode; }
+ bool click() const { return _click; }
+ bool quantize() const { return _quantize; }
+ void setStopPlay(bool);
+ void stopRolling();
+
+ //-----------------------------------------
+ // access tempomap/sigmap (Mastertrack)
+ //-----------------------------------------
+
+ unsigned len() const { return _len; }
+ int roundUpBar(int tick) const;
+ int roundUpBeat(int tick) const;
+ int roundDownBar(int tick) const;
+
+ //-----------------------------------------
+ // event manipulations
+ //-----------------------------------------
+
+ bool addEvent(const Event&, Part*);
+ void changeEvent(const Event&, const Event&, Part*);
+ void deleteEvent(const Event&, Part*);
+ void cmdChangeWave(QString original, QString tmpfile, unsigned sx, unsigned ex);
+
+ //-----------------------------------------
+ // part manipulations
+ //-----------------------------------------
+
+ void cmdAddPart(Part* part);
+ void addPart(Part* part);
+
+ void cmdRemoveParts();
+ void cmdRemovePart(Part* part);
+ void removePart(Part* part);
+
+ void cmdChangePart(Part* oldPart, Part* newPart);
+ void changePart(Part*, Part*);
+
+ void cmdSplitPart(Part* p, const Pos&);
+ void cmdGluePart(Part* p);
+
+ PartList* getSelectedMidiParts() const;
+ PartList* getSelectedWaveParts() const;
+
+ void cmdMovePart(Part*, unsigned, Track*);
+ void cmdLinkPart(Part*, unsigned, Track*);
+ void cmdCopyPart(Part*, unsigned, Track*);
+ void selectPart(Part*, bool add=false);
+
+ //-----------------------------------------
+ // track manipulations
+ //-----------------------------------------
+
+ TrackList* tracks() { return &_tracks; }
+ MidiTrackList* midis() { return &_midis; }
+ WaveTrackList* waves() { return &_waves; }
+ InputList* inputs() { return &_inputs; }
+ OutputList* outputs() { return &_outputs; }
+ GroupList* groups() { return &_groups; }
+ SynthIList* syntis() { return &_synthIs; }
+ MidiOutPortList* midiOutPorts() { return &_midiOutPorts; }
+ MidiSyntiList* midiSyntis() { return &_midiSyntis; }
+ MidiInPortList* midiInPorts() { return &_midiInPorts; }
+
+ bool trackExists(Track*) const;
+ Track* findTrack(const QString& name) const;
+
+ void removeTrack(Track* track);
+ void removeTrack1(Track* track);
+ void removeTrack2(Track* track);
+ void removeTrack3(Track* track);
+ void changeTrackName(Track* track, const QString&);
+
+ void swapTracks(int i1, int i2);
+ void moveTrack(Track*, Track*);
+ void cmdInsertTrack(Track*, int idx);
+ void insertTrack(Track*, int idx);
+
+ void insertTrack0(Track*, int idx);
+ void insertTrack1(Track*, int idx);
+ void insertTrack2(Track*);
+ void readRoute(QDomNode);
+ std::vector<QString>* synthesizer() const;
+
+ void deselectTracks();
+ void selectTrack(Track*);
+
+ Track* selectedTrack() const { return _selectedTrack; }
+ void updateSelectedTrack();
+
+ //-----------------------------------------
+ // undo, redo
+ //-----------------------------------------
+
+ void startUndo();
+ void endUndo(int);
+ void undoOp(UndoOp::UndoType, int, Track*);
+ void undoOp(UndoOp::UndoType, int, int, int = 0);
+ void undoOp(UndoOp::UndoType, Part*);
+ void undoOp(UndoOp::UndoType, const Event& oevent, const Event& nevent, Part*);
+ void undoOp(UndoOp::UndoType type, const Event& nev, Part* part);
+ void undoOp(UndoOp::UndoType, SigEvent* oevent, SigEvent* nevent);
+ void undoOp(UndoOp::UndoType, Part* oPart, Part* nPart);
+ void undoOp(UndoOp::UndoType, Track*, int, unsigned, CVal, CVal);
+ void undoOp(UndoOp::UndoType, Track*, const QString&, const QString&);
+ void undoOp(UndoOp::UndoType type, const char* changedFile, const char* changeData, int startframe, int endframe);
+ bool doUndo1();
+ void doUndo2();
+ void doUndo3();
+ bool doRedo1();
+ void doRedo2();
+ void doRedo3();
+
+ void addUndo(UndoOp& i);
+
+ //-----------------------------------------
+ // Controller
+ //-----------------------------------------
+
+ void cmdAddControllerVal(Track*, Ctrl*, const Pos&, CVal);
+ void cmdAddControllerVal(Track*, int, const Pos&, CVal);
+ void setControllerVal(Track*, Ctrl*, CVal);
+ void setControllerVal(Track*, int, CVal);
+
+ void cmdRemoveControllerVal(Track*,int,unsigned);
+ void setAutoRead(Track*,bool);
+ void setAutoWrite(Track*,bool);
+
+ //-----------------------------------------
+ // Misc/Debug
+ //-----------------------------------------
+
+ void setLen(int);
+ void dumpMaster();
+ void addUpdateFlags(int f) { updateFlags |= f; }
+ bool solo() const { return soloFlag; }
+ void setRecordFlag(Track*, bool);
+ void setMute(Track*,bool);
+ void setMonitor(Track*,bool);
+ void setSolo(Track*,bool);
+ void setOff(Track*,bool);
+
+ QString projectPath() const;
+ QString absoluteProjectPath() const;
+ QString projectName() const;
+ void setProjectPath(const QString&);
+ QString comment() const { return _comment; }
+ void setComment(const QString& s) { _comment = s; }
+ void setCreated(bool val) { _created = val; }
+ bool created() const { return _created; }
+ QDateTime createDate() const { return _createDate; }
+
+ bool read(QFile* qf);
+ void read30(QDomNode node); // muse >= 1.0
+ void read20(QDomNode node); // muse < 1.0
+ void read10(QDomNode);
+ void updateCurrentMarker();
+ };
+
+extern Song* song;
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/songfile.cpp b/muse_qt4_evolution/muse/songfile.cpp
new file mode 100644
index 00000000..ff89e41e
--- /dev/null
+++ b/muse_qt4_evolution/muse/songfile.cpp
@@ -0,0 +1,489 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "muse.h"
+#include "song.h"
+#include "arranger.h"
+#include "al/al.h"
+#include "al/xml.h"
+#include "midiedit/drummap.h"
+#include "al/marker.h"
+#include "midictrl.h"
+#include "conf.h"
+#include "al/tempo.h"
+#include "al/sig.h"
+#include "synth.h"
+#include "waveedit/waveedit.h"
+#include "master/masteredit.h"
+#include "midiedit/drumedit.h"
+#include "midiedit/pianoroll.h"
+#include "part.h"
+#include "marker/markerview.h"
+#include "liste/listedit.h"
+
+using namespace AL;
+
+//---------------------------------------------------------
+// readPart
+//---------------------------------------------------------
+
+Part* MusE::readPart(QDomNode node)
+ {
+ QDomElement e = node.toElement();
+ Part* part = 0;
+ QString s = e.text();
+ int trackIdx;
+ int partIdx;
+ sscanf(s.toLatin1().data(), "%d:%d", &trackIdx, &partIdx);
+ TrackList* tl = song->tracks();
+ Track* track = song->tracks()->value(trackIdx);
+ if (track) {
+ part = track->parts()->find(partIdx);
+ if (part == 0) {
+ printf("MusE::readPart(): part %d(%d) not found in track <%s>\n",
+ partIdx, track->parts()->size(), track->name().toLatin1().data());
+ }
+ }
+ else {
+ printf("MusE::readPart(): trackIdx >= tl->size %d > %d\n",
+ trackIdx , tl->size());
+ }
+ return part;
+ }
+
+//---------------------------------------------------------
+// readToplevels
+//---------------------------------------------------------
+
+void MusE::readToplevels(QDomNode node)
+ {
+ PartList* pl = new PartList;
+
+ for (;!node.isNull(); node = node.nextSibling()) {
+ QDomElement e = node.toElement();
+ QString tag(e.tagName());
+ if (tag == "part") {
+ Part* part = readPart(node);
+ if (part)
+ pl->add(part);
+ else
+ printf("part not found\n");
+ }
+ else if (tag == "PianoRoll") {
+ PianoRoll* pianoroll = new PianoRoll(pl, true);
+// connect(muse, SIGNAL(configChanged()), pianoroll, SLOT(configChanged()));
+ pianoroll->read(node);
+ pianoroll->show();
+ pl = new PartList;
+ }
+ else if (tag == "DrumEdit") {
+ DrumEdit* drumEditor = new DrumEdit(pl, true);
+// connect(muse, SIGNAL(configChanged()), drumEditor, SLOT(configChanged()));
+ drumEditor->read(node);
+ drumEditor->show();
+ pl = new PartList;
+ }
+ else if (tag == "ListEdit") {
+ listEditor = new ListEdit(0);
+ listEditor->show();
+ listEditor->read(node);
+ }
+ else if (tag == "MasterEdit") {
+ MasterEdit* masterEditor = new MasterEdit();
+ masterEditor->show();
+ masterEditor->read(node);
+ }
+ else if (tag == "MarkerView") {
+ showMarker(true);
+ markerView->read(node);
+ }
+ else if (tag == "WaveEdit") {
+ WaveEdit* waveEditor = new WaveEdit(pl, true);
+ waveEditor->read(node);
+ waveEditor->show();
+ connect(muse, SIGNAL(configChanged()), waveEditor, SLOT(configChanged()));
+ pl = new PartList;
+ }
+ else
+ printf("MusE:readToplevels: unknown tag <%s>\n", e.tagName().toLatin1().data());
+ }
+ delete pl;
+ }
+
+//---------------------------------------------------------
+// readMarker
+//---------------------------------------------------------
+
+void Song::readMarker(QDomNode node)
+ {
+ AL::Marker m;
+ m.read(node);
+ _markerList->add(m);
+ }
+
+//---------------------------------------------------------
+// read
+//---------------------------------------------------------
+
+void Song::read(QDomNode node)
+ {
+ cloneList.clear();
+ for (; !node.isNull(); node = node.nextSibling()) {
+ QDomElement e = node.toElement();
+ QString tag(e.tagName());
+ int i = e.text().toInt();
+ if (tag == "configuration")
+ ; // readConfiguration(node.firstChild());
+ else if (tag == "master")
+ setMasterFlag(i);
+ else if (tag == "loop")
+ setLoop(i);
+ else if (tag == "punchin")
+ setPunchin(i);
+ else if (tag == "punchout")
+ setPunchout(i);
+ else if (tag == "record")
+ ; // setRecord(i);
+ else if (tag == "solo")
+ soloFlag = i;
+ else if (tag == "recmode")
+ _recMode = i;
+ else if (tag == "cycle")
+ _cycleMode = i;
+ else if (tag == "click")
+ setClick(i);
+ else if (tag == "quantize")
+ _quantize = i;
+ else if (tag == "len")
+ _len = i;
+ else if (tag == "tempolist")
+ AL::tempomap.read(node);
+ else if (tag == "siglist")
+ AL::sigmap.read(node.firstChild());
+ else if (tag == "miditrack") {
+ MidiTrack* track = new MidiTrack();
+ track->read(node.firstChild());
+ insertTrack0(track, -1);
+ }
+ else if (tag == "drumtrack") {
+ MidiTrack* track = new MidiTrack();
+ //TODO track->setUseDrumMap(true);
+ track->read(node.firstChild());
+ insertTrack0(track, -1);
+ }
+ else if (tag == "wavetrack") {
+ WaveTrack* track = new WaveTrack();
+ track->read(node.firstChild());
+ insertTrack0(track, -1);
+ }
+ else if (tag == "AudioInput") {
+ AudioInput* track = new AudioInput();
+ track->read(node.firstChild());
+ insertTrack0(track,-1);
+ }
+ else if (tag == "AudioOutput") {
+ AudioOutput* track = new AudioOutput();
+ track->read(node.firstChild());
+ insertTrack0(track,-1);
+ }
+ else if (tag == "AudioGroup") {
+ AudioGroup* track = new AudioGroup();
+ track->read(node.firstChild());
+ insertTrack0(track,-1);
+ }
+ else if (tag == "SynthI") {
+ SynthI* track = new SynthI();
+ track->read(node.firstChild());
+ // insertTrack(track, -1);
+ }
+ else if (tag == "MidiOutPort") {
+ MidiOutPort* track = new MidiOutPort();
+ track->read(node.firstChild());
+ insertTrack0(track, -1);
+ }
+ else if (tag == "MidiInPort") {
+ MidiInPort* track = new MidiInPort();
+ track->read(node.firstChild());
+ insertTrack0(track, -1);
+ }
+ else if (tag == "MidiSynti") {
+ MidiSynti* track = new MidiSynti();
+ track->read(node.firstChild());
+ // insertTrack0(track, -1);
+ }
+ else if (tag == "arranger")
+ muse->arranger->readStatus(node.firstChild());
+ else if (tag == "Route")
+ readRoute(node);
+ else if (tag == "marker")
+ readMarker(node);
+ else if (tag == "globalPitchShift")
+ _globalPitchShift = i;
+ else if (tag == "cpos") {
+ int pos = i;
+ Pos p(pos, AL::TICKS);
+ setPos(Song::CPOS, p, false, false, false);
+ }
+ else if (tag == "lpos") {
+ int pos = i;
+ Pos p(pos, AL::TICKS);
+ setPos(Song::LPOS, p, false, false, false);
+ }
+ else if (tag == "rpos") {
+ int pos = i;
+ Pos p(pos, AL::TICKS);
+ setPos(Song::RPOS, p, false, false, false);
+ }
+ else if (tag == "Pianoroll")
+ PianoRoll::readConfiguration(node);
+ else if (tag == "DrumEdit")
+ DrumEdit::readConfiguration(node);
+ else if (tag == "comment")
+ _comment = e.text();
+ else if (tag == "createDate")
+ _createDate = QDateTime::fromString(e.text(), Qt::ISODate);
+ else if (tag == "LenInSec")
+ ;
+ else
+ printf("MusE:Song: unknown tag %s\n", tag.toLatin1().data());
+ }
+ dirty = false;
+ }
+
+//---------------------------------------------------------
+// write
+//---------------------------------------------------------
+
+void Song::write(Xml& xml) const
+ {
+ xml.stag("song");
+ xml.tag("comment", _comment);
+ xml.tag("createDate", _createDate.toString(Qt::ISODate));
+ int n = AL::tempomap.tick2frame(_len);
+ xml.tag("LenInSec", n / AL::sampleRate);
+
+ xml.tag("cpos", cpos());
+ xml.tag("rpos", rpos());
+ xml.tag("lpos", lpos());
+ xml.tag("master", _masterFlag);
+ if (loopFlag)
+ xml.tag("loop", loopFlag);
+ if (punchinFlag)
+ xml.tag("punchin", punchinFlag);
+ if (punchoutFlag)
+ xml.tag("punchout", punchoutFlag);
+ if (soloFlag)
+ xml.tag("solo", soloFlag);
+ if (_recMode != REC_OVERDUP)
+ xml.tag("recmode", _recMode);
+ if (_cycleMode != CYCLE_NORMAL)
+ xml.tag("cycle", _cycleMode);
+ if (_click)
+ xml.tag("click", _click);
+ if (_quantize)
+ xml.tag("quantize", _quantize);
+ xml.tag("len", _len);
+
+ if (_globalPitchShift)
+ xml.tag("globalPitchShift", _globalPitchShift);
+
+ cloneList.clear();
+
+ // write tracks
+ for (ciTrack i = _tracks.begin(); i != _tracks.end(); ++i)
+ (*i)->write(xml);
+
+ // write routing
+ for (ciTrack i = _tracks.begin(); i != _tracks.end(); ++i)
+ (*i)->writeRouting(xml);
+ muse->arranger->writeStatus(xml);
+
+ AL::tempomap.write(xml);
+ AL::sigmap.write(xml);
+ _markerList->write(xml);
+
+ xml.etag("song");
+ }
+
+//---------------------------------------------------------
+// write
+// write song
+//---------------------------------------------------------
+
+void MusE::write(Xml& xml) const
+ {
+ xml.header();
+
+ xml.stag("muse version=\"3.0\"");
+ writeConfiguration(xml);
+
+ song->write(xml);
+
+ xml.stag("toplevels");
+ foreach(QWidget* w, QApplication::topLevelWidgets()) {
+ if (!w->isVisible())
+ continue;
+ if (strcmp("DrumEdit", w->metaObject()->className()) == 0)
+ ((TopWin*)w)->write(xml);
+ else if (strcmp("PianoRoll", w->metaObject()->className()) == 0)
+ ((TopWin*)w)->write(xml);
+ else if (strcmp("MasterEdit", w->metaObject()->className()) == 0)
+ ((TopWin*)w)->write(xml);
+ else if (strcmp("WaveEdit", w->metaObject()->className()) == 0)
+ ((TopWin*)w)->write(xml);
+ else if (strcmp("ListEdit", w->metaObject()->className()) == 0)
+ ((TopWin*)w)->write(xml);
+ else if (strcmp("MarkerView", w->metaObject()->className()) == 0)
+ ((TopWin*)w)->write(xml);
+ else if (strcmp("Mixer", w->metaObject()->className()) == 0)
+ ;
+ else if (strcmp("Transport", w->metaObject()->className()) == 0)
+ ;
+ else if (strcmp("MusE", w->metaObject()->className()) == 0)
+ ;
+ else if (strcmp("QDesktopWidget", w->metaObject()->className()) == 0)
+ ;
+ else
+ printf("TopLevel <%s>\n", w->metaObject()->className());
+ }
+ xml.etag("toplevels");
+ xml.etag("muse");
+ }
+
+//---------------------------------------------------------
+// read20
+// read old file versions (muse < 1.0)
+//---------------------------------------------------------
+
+void Song::read20(QDomNode node)
+ {
+ printf("Warning: importing old muse file version\n");
+
+ for (QDomNode n = node.firstChild(); !n.isNull(); n = n.nextSibling()) {
+ QDomElement e = n.toElement();
+ if (e.isNull())
+ continue;
+ QString t(e.tagName());
+ if (t == "configuration")
+ readConfiguration(node.firstChild());
+ else if (t == "song") {
+ for (QDomNode n1 = n.firstChild(); !n1.isNull(); n1 = n1.nextSibling()) {
+ QDomElement e = n1.toElement();
+ if (e.isNull())
+ continue;
+ QString t(e.tagName());
+ int i = e.text().toInt();
+ if (t == "automation")
+ ;
+ else if (t == "cpos") {
+ int pos = i;
+ Pos p(pos, AL::TICKS);
+ setPos(Song::CPOS, p, false, false, false);
+ }
+ else if (t == "rpos") {
+ int pos = i;
+ Pos p(pos, AL::TICKS);
+ setPos(Song::RPOS, p, false, false, false);
+ }
+ else if (t == "lpos") {
+ int pos = i;
+ Pos p(pos, AL::TICKS);
+ setPos(Song::LPOS, p, false, false, false);
+ }
+ else if (t == "master")
+ setMasterFlag(i);
+ else if (t == "loop")
+ setLoop(i);
+ else if (t == "punchin")
+ setPunchin(i);
+ else if (t == "punchout")
+ setPunchout(i);
+ else if (t == "record")
+ ;
+ else if (t == "solo")
+ soloFlag = i;
+ else if (t == "type")
+ ;
+ else if (t == "recmode")
+ _recMode = i;
+ else if (t == "cycle")
+ _cycleMode = i;
+ else if (t == "click")
+ setClick(i);
+ else if (t == "quantize")
+ _quantize = i;
+ else if (t == "len")
+ _len = i;
+ else if (t == "follow")
+ ;
+ else if (t == "drummap")
+ ;
+ else if (t == "siglist")
+ AL::sigmap.read(node.firstChild());
+ else if (t == "tempolist")
+ AL::tempomap.read(node);
+ else if (t == "Route")
+ ;
+ else if (t == "AudioAux") {
+ AudioGroup* track = new AudioGroup();
+ track->read(n1.firstChild());
+ insertTrack0(track,-1);
+ }
+ else if (t == "AudioInput") {
+ AudioInput* track = new AudioInput();
+ track->read(n1.firstChild());
+ insertTrack0(track,-1);
+ }
+ else if (t == "AudioGroup") {
+ AudioGroup* track = new AudioGroup();
+ track->read(n1.firstChild());
+ insertTrack0(track,-1);
+ }
+ else if (t == "AudioOutput") {
+ AudioOutput* track = new AudioOutput();
+ track->read(n1.firstChild());
+ insertTrack0(track,-1);
+ }
+ else if (t == "wavetrack") {
+ MidiTrack* track = new MidiTrack();
+ track->read(n1.firstChild());
+ insertTrack0(track, -1);
+ }
+ else if (t == "drumtrack") {
+ MidiTrack* track = new MidiTrack();
+ track->read(n1.firstChild());
+ insertTrack0(track, -1);
+ }
+ else if (t == "miditrack") {
+ MidiTrack* track = new MidiTrack();
+ track->read(n1.firstChild());
+ insertTrack0(track, -1);
+ }
+ else
+ domError(n1);
+ }
+ }
+ else if (t == "toplevels") {
+ }
+ else
+ domError(n);
+ }
+ }
+
diff --git a/muse_qt4_evolution/muse/songpart.cpp b/muse_qt4_evolution/muse/songpart.cpp
new file mode 100644
index 00000000..72faf7f8
--- /dev/null
+++ b/muse_qt4_evolution/muse/songpart.cpp
@@ -0,0 +1,371 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "song.h"
+#include "part.h"
+#include "audio.h"
+
+//---------------------------------------------------------
+// cmdAddPart
+// GUI context + startUndo/endUndo
+//---------------------------------------------------------
+
+void Song::cmdAddPart(Part* part)
+ {
+ Track* track = part->track();
+ //
+ // create default name:
+ //
+ for (int i = 1;;++i) {
+ PartList* pl = track->parts();
+ bool found = false;
+ QString name = QString("Part-%1").arg(i);
+ for (iPart ip = pl->begin(); ip != pl->end(); ++ip) {
+ if (name == ip->second->name()) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ part->setName(name);
+ break;
+ }
+ }
+ startUndo();
+ addPart(part);
+ endUndo(0);
+ track->partListChanged();
+ }
+
+//---------------------------------------------------------
+// addPart
+// GUI context
+//---------------------------------------------------------
+
+void Song::addPart(Part* part)
+ {
+ AudioMsg msg;
+ msg.id = SEQM_ADD_PART;
+ msg.p1 = part;
+ audio->sendMessage(&msg, false);
+ undoOp(UndoOp::AddPart, part);
+ updateFlags |= SC_PART_INSERTED;
+ if (len() < part->endTick())
+ setLen(part->endTick());
+ }
+
+//---------------------------------------------------------
+// cmdRemovePart
+//---------------------------------------------------------
+
+void Song::cmdRemovePart(Part* part)
+ {
+ startUndo();
+ removePart(part);
+ endUndo(0);
+ }
+
+//---------------------------------------------------------
+// cmdRemoveParts
+// remove selected parts
+//---------------------------------------------------------
+
+void Song::cmdRemoveParts()
+ {
+ TrackList* tl = song->tracks();
+ PartList pl;
+
+ for (iTrack it = tl->begin(); it != tl->end(); ++it) {
+ PartList* pl2 = (*it)->parts();
+ for (iPart ip = pl2->begin(); ip != pl2->end(); ++ip) {
+ if (ip->second->selected())
+ pl.add(ip->second);
+ }
+ }
+ startUndo();
+ for (iPart ip = pl.begin(); ip != pl.end(); ++ip)
+ removePart(ip->second);
+ endUndo(0);
+ }
+
+//---------------------------------------------------------
+// removePart
+//---------------------------------------------------------
+
+void Song::removePart(Part* part)
+ {
+ AudioMsg msg;
+ msg.id = SEQM_REMOVE_PART;
+ msg.p1 = part;
+ audio->sendMessage(&msg, false);
+ undoOp(UndoOp::DeletePart, part);
+ updateFlags |= SC_PART_REMOVED;
+ part->deref();
+ part->track()->partListChanged();
+ }
+
+//---------------------------------------------------------
+// cmdChangePart
+// realtime context
+//---------------------------------------------------------
+
+void Song::cmdChangePart(Part* oldPart, Part* newPart)
+ {
+ startUndo();
+ changePart(oldPart, newPart);
+ endUndo(0);
+ newPart->track()->partListChanged();
+ }
+
+//---------------------------------------------------------
+// changePart
+//---------------------------------------------------------
+
+void Song::changePart(Part* oldPart, Part* newPart)
+ {
+ AudioMsg msg;
+ msg.id = SEQM_CHANGE_PART;
+ msg.p1 = oldPart;
+ msg.p2 = newPart;
+ audio->sendMessage(&msg, false);
+ undoOp(UndoOp::ModifyPart, oldPart, newPart);
+ updateFlags = SC_PART_MODIFIED;
+ if (len() < newPart->endTick())
+ setLen(newPart->endTick());
+ }
+
+//---------------------------------------------------------
+// cmdChangePart
+// extend/shrink part in front or at end
+//---------------------------------------------------------
+
+void Song::cmdChangePart(Part* oPart, unsigned pos, unsigned len)
+ {
+ startUndo();
+ //
+ // move events so they stay at same position in song
+ //
+ int delta = oPart->tick() - pos;
+ Part* nPart = new Part(*oPart);
+ nPart->clone(new EventList);
+
+ const EventList* s = oPart->events();
+ for (ciEvent ie = s->begin(); ie != s->end(); ++ie) {
+ int tick = ie->first + delta;
+ if (tick >= 0 && tick < int(len)) {
+ Event ev = ie->second.clone();
+ ev.move(delta);
+ nPart->addEvent(ev, unsigned(tick));
+ }
+ }
+ if (oPart->fillLen() > 0 && len < (unsigned)oPart->fillLen())
+ oPart->setFillLen(len);
+ if (oPart->lenTick() < len && oPart->fillLen() > 0) {
+ unsigned loop = oPart->fillLen();
+ unsigned fillLen = len - oPart->lenTick();
+ for (unsigned i = 0; i < fillLen / loop; ++i) {
+ int start = oPart->lenTick() + loop * i;
+ for (ciEvent ie = s->begin(); ie != s->end(); ++ie) {
+ if (ie->first >= loop)
+ break;
+ Event ev = ie->second.clone();
+ ev.move(start);
+ nPart->addEvent(ev, ie->first + start);
+ }
+ }
+ }
+ nPart->setLenTick(len);
+ nPart->setTick(pos);
+ changePart(oPart, nPart);
+ endUndo(0);
+ oPart->track()->partListChanged();
+ }
+
+//---------------------------------------------------------
+// cmdMovePart
+//---------------------------------------------------------
+
+void Song::cmdMovePart(Part* oPart, unsigned pos, Track* track)
+ {
+ Track* oTrack = oPart->track();
+ Part* nPart = new Part(*oPart);
+ nPart->setTrack(track);
+ nPart->setTick(pos);
+ startUndo();
+ if (oPart->track() != track) {
+ removePart(oPart);
+ addPart(nPart);
+ }
+ else {
+ changePart(oPart, nPart);
+ }
+ endUndo(0);
+ oTrack->partListChanged();
+ }
+
+//---------------------------------------------------------
+// cmdLinkPart
+//---------------------------------------------------------
+
+void Song::cmdLinkPart(Part* sPart, unsigned pos, Track* track)
+ {
+ Part* dPart = track->newPart(sPart, true);
+ dPart->setTick(pos);
+ cmdAddPart(dPart);
+ sPart->track()->partListChanged();
+ dPart->track()->partListChanged();
+ }
+
+//---------------------------------------------------------
+// cmdCopyPart
+//---------------------------------------------------------
+
+void Song::cmdCopyPart(Part* sPart, unsigned pos, Track* track)
+ {
+ bool clone = sPart->isClone();
+ Part* dPart = track->newPart(sPart, clone);
+ dPart->setTick(pos);
+ if (!clone) {
+ //
+ // Copy Events
+ //
+ EventList* se = sPart->events();
+ EventList* de = dPart->events();
+ for (iEvent i = se->begin(); i != se->end(); ++i) {
+ Event oldEvent = i->second;
+ Event ev = oldEvent.clone();
+ de->add(ev);
+ }
+ }
+ cmdAddPart(dPart);
+ sPart->track()->partListChanged();
+ dPart->track()->partListChanged();
+ }
+
+//---------------------------------------------------------
+// cmdCreateLRPart
+//---------------------------------------------------------
+
+void Song::cmdCreateLRPart(Track* track)
+ {
+ Part* part = track->newPart();
+ if (part) {
+ part->setTick(pos[1].tick());
+ part->setLenTick(pos[2].tick()-pos[1].tick());
+ part->setSelected(true);
+ cmdAddPart(part);
+ }
+ }
+
+//---------------------------------------------------------
+// selectPart
+//---------------------------------------------------------
+
+void Song::selectPart(Part* part, bool add)
+ {
+ if (add) {
+ part->setSelected(!part->selected());
+ part->track()->partListChanged();
+ return;
+ }
+ for (iTrack it = _tracks.begin(); it != _tracks.end(); ++it) {
+ PartList* pl = (*it)->parts();
+ bool changed = false;
+ for (iPart ip = pl->begin(); ip != pl->end(); ++ip) {
+ bool f = part == ip->second;
+ if (ip->second->selected() != f) {
+ ip->second->setSelected(f);
+ changed = true;
+ }
+ }
+ if (changed)
+ (*it)->partListChanged();
+ }
+ }
+
+//---------------------------------------------------------
+// cmdSplitPart
+//---------------------------------------------------------
+
+void Song::cmdSplitPart(Part* part, const Pos& pos)
+ {
+ int tick = pos.tick();
+ int l1 = tick - part->tick();
+ int l2 = part->lenTick() - l1;
+ if (l1 <= 0 || l2 <= 0)
+ return;
+ Part* p1;
+ Part* p2;
+ part->track()->splitPart(part, tick, p1, p2);
+
+ startUndo();
+ changePart(part, p1);
+ addPart(p2);
+ endUndo(0);
+ part->track()->partListChanged();
+ }
+
+//---------------------------------------------------------
+// cmdGluePart
+//---------------------------------------------------------
+
+void Song::cmdGluePart(Part* oPart)
+ {
+ Track* track = oPart->track();
+ PartList* pl = track->parts();
+ Part* nextPart = 0;
+
+ for (iPart ip = pl->begin(); ip != pl->end(); ++ip) {
+ if (ip->second == oPart) {
+ ++ip;
+ if (ip == pl->end())
+ return;
+ nextPart = ip->second;
+ break;
+ }
+ }
+
+ Part* nPart = track->newPart(oPart);
+ nPart->setLenTick(nextPart->tick() + nextPart->lenTick() - oPart->tick());
+
+ // populate nPart with Events from oPart and nextPart
+
+ EventList* sl1 = oPart->events();
+ EventList* dl = nPart->events();
+
+ for (iEvent ie = sl1->begin(); ie != sl1->end(); ++ie)
+ dl->add(ie->second);
+
+ EventList* sl2 = nextPart->events();
+ int tickOffset = nextPart->tick() - oPart->tick();
+
+ for (iEvent ie = sl2->begin(); ie != sl2->end(); ++ie) {
+ Event event = ie->second.clone();
+ event.move(tickOffset);
+ dl->add(event);
+ }
+ startUndo();
+ removePart(nextPart);
+ changePart(oPart, nPart);
+ endUndo(0);
+ track->partListChanged();
+ }
+
+
diff --git a/muse_qt4_evolution/muse/songtrack.cpp b/muse_qt4_evolution/muse/songtrack.cpp
new file mode 100644
index 00000000..8a865620
--- /dev/null
+++ b/muse_qt4_evolution/muse/songtrack.cpp
@@ -0,0 +1,715 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "song.h"
+#include "audio.h"
+#include "midiplugin.h"
+#include "audiodev.h"
+#include "muse.h"
+
+//---------------------------------------------------------
+// deselectTracks
+//---------------------------------------------------------
+
+void Song::deselectTracks()
+ {
+ for (iTrack t = _tracks.begin(); t != _tracks.end(); ++t)
+ (*t)->setSelected(false);
+ }
+
+//---------------------------------------------------------
+// selectTrack
+//---------------------------------------------------------
+
+void Song::selectTrack(Track* track)
+ {
+ bool changed = false;
+ for (iTrack t = _tracks.begin(); t != _tracks.end(); ++t) {
+ bool select = *t == track;
+ if ((*t)->selected() != select) {
+ (*t)->setSelected(select);
+ changed = true;
+ }
+ }
+ if (changed) {
+ updateSelectedTrack();
+ trackSelectionChanged(_selectedTrack);
+ }
+ }
+
+//---------------------------------------------------------
+// updateSelectedTrack
+// set _selectedTrack to first selected track
+//---------------------------------------------------------
+
+void Song::updateSelectedTrack()
+ {
+ _selectedTrack = 0;
+ for (iTrack t = _tracks.begin(); t != _tracks.end(); ++t) {
+ bool select = (*t)->selected();
+ if (select) {
+ _selectedTrack = *t;
+ break;
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// addTrack
+// called from GUI context
+//---------------------------------------------------------
+
+Track* Song::addTrack(QAction* action)
+ {
+ int t = action->data().toInt();
+
+ deselectTracks();
+ Track* track = 0;
+
+ Track::TrackType type = (Track::TrackType) t;
+ if (t >= 5000) {
+ int idx = t - 5000;
+ type = Track::MIDI_SYNTI;
+ int k = 0;
+ iMidiPlugin i;
+ for (i = midiPlugins.begin(); i != midiPlugins.end(); ++i) {
+ if ((*i)->type() != MEMPI_GENERATOR)
+ continue;
+ if (k == idx)
+ break;
+ ++k;
+ }
+ if (i == midiPlugins.end()) {
+ fprintf(stderr, "Song::addTrack: midi synti not found\n");
+ return 0;
+ }
+ MidiPlugin* s = *i;
+ MidiSynti* si = new MidiSynti();
+ QString sName(s->name());
+ for (k = s->instances(); k < 1000; ++k) {
+ QString instanceName = (k == 0) ?
+ sName : instanceName.arg(sName).arg(k);
+
+ MidiSyntiList* sl = midiSyntis();
+ iMidiSynti sii;
+ for (sii = sl->begin(); sii != sl->end(); ++sii) {
+ if ((*sii)->name() == instanceName)
+ break;
+ }
+ if (sii == sl->end()) {
+ si->setName(instanceName);
+ break;
+ }
+ }
+ if (si->initInstance(s)) {
+ delete si;
+ return 0;
+ }
+ track = si;
+ }
+ else if (t >= 1000) {
+ type = Track::AUDIO_SOFTSYNTH;
+ QString sclass = synthis[t-1000]->name();
+
+ Synth* s = findSynth(sclass);
+ if (s == 0) {
+ fprintf(stderr, "synthi class <%s> not found\n", sclass.toLatin1().data());
+ return 0;
+ }
+
+ SynthI* si = new SynthI();
+ int i;
+ for (i = s->instances(); i < 1000; ++i) {
+ QString instanceName = (i == 0) ?
+ s->name() : QString("%1-%2").arg(s->name()).arg(i);
+
+ SynthIList* sl = syntis();
+ iSynthI sii;
+ for (sii = sl->begin(); sii != sl->end(); ++sii) {
+ if ((*sii)->name() == instanceName)
+ break;
+ }
+ if (sii == sl->end()) {
+ si->setName(instanceName);
+ break;
+ }
+ }
+ if (si->initInstance(s)) {
+ delete si;
+ return 0;
+ }
+ track = si;
+ }
+ else {
+ switch (type) {
+ case Track::MIDI:
+ track = new MidiTrack();
+ break;
+ case Track::MIDI_OUT:
+ track = new MidiOutPort();
+ break;
+ case Track::MIDI_IN:
+ track = new MidiInPort();
+ break;
+ case Track::WAVE:
+ track = new WaveTrack();
+ break;
+ case Track::AUDIO_OUTPUT:
+ track = new AudioOutput();
+ break;
+ case Track::AUDIO_GROUP:
+ track = new AudioGroup();
+ break;
+ case Track::AUDIO_INPUT:
+ track = new AudioInput();
+ break;
+ case Track::AUDIO_SOFTSYNTH:
+ case Track::TRACK_TYPES:
+ default:
+ printf("Song::addTrack() illegal type %d\n", type);
+ abort();
+ }
+ if (track == 0)
+ return 0;
+ }
+ track->setDefaultName();
+ cmdInsertTrack(track, -1);
+ return track;
+ }
+
+//---------------------------------------------------------
+// cmdInsertTrack
+//---------------------------------------------------------
+
+void Song::cmdInsertTrack(Track* track, int idx)
+ {
+ startUndo();
+ insertTrack(track, idx);
+ endUndo(SC_TRACK_INSERTED | SC_ROUTE);
+ selectTrack(track);
+ }
+
+//---------------------------------------------------------
+// insertTrack
+//---------------------------------------------------------
+
+void Song::insertTrack(Track* track, int idx)
+ {
+ //
+ // add default routes
+ //
+ OutputList* ol = outputs();
+ AudioOutput* ao = 0;
+ if (!ol->empty())
+ ao = ol->front();
+
+ switch (track->type()) {
+ case Track::TRACK_TYPES:
+ case Track::MIDI_OUT:
+ {
+#if 0
+ QList<PortName> op = midiDriver->outputPorts(false);
+ if (!op.isEmpty()) {
+ RouteNode src(track);
+ RouteNode dst(op.back().port, -1, RouteNode::MIDIPORT);
+ Route r = Route(src, dst);
+ track->addOutRoute(r);
+ }
+#endif
+ //TODO: autoconnect to JACK midi ports
+ }
+ break;
+
+ case Track::MIDI_IN:
+ {
+#if 0
+ QList<PortName> op = midiDriver->inputPorts(true);
+ if (!op.isEmpty()) {
+ RouteNode src(op.back().port, -1, RouteNode::MIDIPORT);
+ RouteNode dst(track);
+ Route r = Route(src, dst);
+ track->addInRoute(r);
+ }
+#endif
+ //TODO: autoconnect to JACK midi ports
+ }
+ break;
+
+ case Track::MIDI_SYNTI:
+ break;
+ case Track::MIDI:
+ //
+ // connect to first channel of all all midi input ports,
+ // if there is not already a route
+ //
+ if (track->noInRoute()) {
+ MidiInPortList* mi = midiInPorts();
+ RouteNode dst(track);
+ for (iMidiInPort i = mi->begin(); i != mi->end(); ++i) {
+ RouteNode src(*i, 0, RouteNode::TRACK);
+ track->addInRoute(Route(src, dst));
+ }
+ }
+ //
+ // connect to first free input channel in midi output ports
+ //
+ if (track->noOutRoute()) {
+ MidiOutPortList* mo = midiOutPorts();
+ for (iMidiOutPort i = mo->begin(); i != mo->end(); ++i) {
+ RouteList* rl = (*i)->inRoutes();
+ for (int ch = 0; ch < MIDI_CHANNELS; ++ch) {
+ RouteNode src(track);
+ RouteNode dst(*i, ch, RouteNode::TRACK);
+ Route r(src, dst);
+ bool channelUsed = false;
+ for (iRoute ir = rl->begin(); ir != rl->end(); ++ir) {
+ if (ir->dst.channel == ch) {
+ channelUsed = true;
+ break;
+ }
+ }
+ if (!channelUsed) {
+ track->addOutRoute(r);
+ break;
+ }
+ }
+ if (!track->noOutRoute())
+ break;
+ }
+ }
+ break;
+ case Track::AUDIO_SOFTSYNTH:
+ case Track::WAVE:
+ case Track::AUDIO_GROUP:
+ if (ao)
+ track->addOutRoute(Route(RouteNode(track), RouteNode(ao)));
+ break;
+
+ case Track::AUDIO_INPUT:
+ {
+ // connect first input channel to first available jack output
+ // etc.
+ QList<PortName> op = audioDriver->outputPorts(false);
+ QList<PortName>::iterator is = op.begin();
+ for (int ch = 0; ch < track->channels(); ++ch) {
+ if (is != op.end()) {
+ RouteNode src(is->port, -1, RouteNode::AUDIOPORT);
+ RouteNode dst(track, ch, RouteNode::TRACK);
+ Route r = Route(src, dst);
+ track->addInRoute(r);
+ ++is;
+ }
+ }
+ }
+ break;
+ case Track::AUDIO_OUTPUT:
+ {
+ QList<PortName> op = audioDriver->inputPorts(false);
+ QList<PortName>::iterator is = op.begin();
+ for (int ch = 0; ch < track->channels(); ++ch) {
+ if (is != op.end()) {
+ RouteNode src(track, ch, RouteNode::TRACK);
+ RouteNode dst(is->port, -1, RouteNode::AUDIOPORT);
+ Route r = Route(src, dst);
+ track->addOutRoute(r);
+ ++is;
+ }
+ }
+ }
+ break;
+ }
+ insertTrack1(track, idx);
+
+ undoOp(UndoOp::AddTrack, idx, track);
+ AudioMsg msg;
+ msg.id = SEQM_ADD_TRACK;
+ msg.track = track;
+ msg.ival = idx;
+ audio->sendMsg(&msg);
+ emit trackAdded(track, idx);
+ }
+
+//---------------------------------------------------------
+// insertTrack0
+// can only be called if sequencer is idle
+// (during song load)
+//---------------------------------------------------------
+
+void Song::insertTrack0(Track* track, int idx)
+ {
+ insertTrack1(track, idx);
+ insertTrack2(track);
+ }
+
+//---------------------------------------------------------
+// insertTrack1
+// non realtime part of insertTrack
+//---------------------------------------------------------
+
+void Song::insertTrack1(Track* track, int idx)
+ {
+ if (idx == -1)
+ idx = _tracks.size();
+ _tracks.insert(idx, track);
+ if (track->type() == Track::AUDIO_SOFTSYNTH) {
+ SynthI* s = (SynthI*)track;
+ Synth* sy = s->synth();
+ if (!s->isActivated())
+ s->initInstance(sy);
+ }
+ if (audioState == AUDIO_RUNNING) {
+ track->activate1();
+ track->activate2();
+ }
+ }
+
+//---------------------------------------------------------
+// insertTrack2
+// realtime part
+//---------------------------------------------------------
+
+void Song::insertTrack2(Track* track)
+ {
+ switch(track->type()) {
+ case Track::MIDI_SYNTI:
+ _midiSyntis.push_back((MidiSynti*)track);
+ break;
+ case Track::MIDI:
+ _midis.push_back((MidiTrack*)track);
+ break;
+ case Track::MIDI_OUT:
+ _midiOutPorts.push_back((MidiOutPort*)track);
+ break;
+ case Track::MIDI_IN:
+ _midiInPorts.push_back((MidiInPort*)track);
+ break;
+ case Track::WAVE:
+ _waves.push_back((WaveTrack*)track);
+ break;
+ case Track::AUDIO_OUTPUT:
+ _outputs.push_back((AudioOutput*)track);
+ break;
+ case Track::AUDIO_GROUP:
+ _groups.push_back((AudioGroup*)track);
+ break;
+ case Track::AUDIO_INPUT:
+ _inputs.push_back((AudioInput*)track);
+ break;
+ case Track::AUDIO_SOFTSYNTH:
+ {
+ SynthI* s = (SynthI*)track;
+ midiInstruments.push_back(s->instrument());
+ _synthIs.push_back(s);
+ }
+ break;
+ default:
+ fprintf(stderr, "insertTrack2: unknown track type %d\n", track->type());
+ // abort();
+ return;
+ }
+
+ //
+ // connect routes
+ //
+ if (track->type() == Track::AUDIO_OUTPUT || track->type() == Track::MIDI_OUT) {
+ foreach(Route r, *(track->inRoutes())) {
+ if (r.src.type != RouteNode::AUXPLUGIN) {
+ r.src.track->addOutRoute(r);
+ }
+ }
+ }
+ else if (track->type() == Track::AUDIO_INPUT || track->type() == Track::MIDI_IN) {
+ foreach(Route r, *(track->outRoutes())) {
+ if (r.dst.type != RouteNode::AUXPLUGIN) {
+ r.dst.track->addInRoute(r);
+ }
+ }
+ }
+ else {
+ foreach(Route r, *(track->inRoutes())) {
+ if (r.src.type != RouteNode::AUXPLUGIN) {
+ r.src.track->addOutRoute(r);
+ }
+ }
+ foreach(Route r, *(track->outRoutes())) {
+ if (r.dst.type != RouteNode::AUXPLUGIN) {
+ r.dst.track->addInRoute(r);
+ }
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// removeTrack
+// called from gui context
+//---------------------------------------------------------
+
+void Song::removeTrack(Track* track)
+ {
+ startUndo();
+ int idx = _tracks.indexOf(track);
+ undoOp(UndoOp::DeleteTrack, idx, track);
+ removeTrack1(track);
+ audio->msgRemoveTrack(track);
+ removeTrack3(track);
+ endUndo(SC_TRACK_REMOVED | SC_ROUTE);
+ }
+
+//---------------------------------------------------------
+// removeTrack1
+// non realtime part of removeTrack
+//---------------------------------------------------------
+
+void Song::removeTrack1(Track* track)
+ {
+ track->deactivate();
+ _tracks.removeAt(_tracks.indexOf(track));
+ }
+
+//---------------------------------------------------------
+// removeTrack2
+// called from RT context
+//---------------------------------------------------------
+
+void Song::removeTrack2(Track* track)
+ {
+ switch (track->type()) {
+ case Track::MIDI_SYNTI:
+ _midiSyntis.removeAt(_midiSyntis.indexOf((MidiSynti*)track));
+ break;
+ case Track::MIDI:
+ _midis.removeAt(_midis.indexOf((MidiTrack*)track));
+ break;
+ case Track::MIDI_OUT:
+ _midiOutPorts.removeAt(_midiOutPorts.indexOf((MidiOutPort*)track));
+ break;
+ case Track::MIDI_IN:
+ _midiInPorts.removeAt(_midiInPorts.indexOf((MidiInPort*)track));
+ break;
+ case Track::WAVE:
+ _waves.removeAt(_waves.indexOf((WaveTrack*)track));
+ break;
+ case Track::AUDIO_OUTPUT:
+ _outputs.removeAt(_outputs.indexOf((AudioOutput*)track));
+ break;
+ case Track::AUDIO_INPUT:
+ _inputs.removeAt(_inputs.indexOf((AudioInput*)track));
+ break;
+ case Track::AUDIO_GROUP:
+ _groups.removeAt(_groups.indexOf((AudioGroup*)track));
+ break;
+ case Track::AUDIO_SOFTSYNTH:
+ {
+ SynthI* s = (SynthI*) track;
+ s->deactivate2();
+ _synthIs.removeAt(_synthIs.indexOf(s));
+ }
+ break;
+ case Track::TRACK_TYPES:
+ return;
+ }
+ //
+ // remove routes
+ //
+ foreach (const Route r, *(track->inRoutes())) {
+ if (r.src.type != RouteNode::TRACK)
+ continue;
+ int idx = r.src.track->outRoutes()->indexOf(r);
+ if (idx != -1)
+ r.src.track->outRoutes()->removeAt(idx);
+ else
+ printf("Song::removeTrack2(): input route not found\n");
+ }
+ foreach (const Route r, *(track->outRoutes())) {
+ if (r.dst.type != RouteNode::TRACK)
+ continue;
+ int idx = r.dst.track->inRoutes()->indexOf(r);
+ if (idx != -1)
+ r.dst.track->inRoutes()->removeAt(idx);
+ else {
+ printf("Song::removeTrack2(): output route not found\n");
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// removeTrack3
+// non realtime part of removeTrack
+//---------------------------------------------------------
+
+void Song::removeTrack3(Track* track)
+ {
+ if (track->type() == Track::AUDIO_SOFTSYNTH) {
+ SynthI* s = (SynthI*) track;
+ s->deactivate3();
+ }
+ emit trackRemoved(track);
+ }
+
+//---------------------------------------------------------
+// synthesizer
+//---------------------------------------------------------
+
+std::vector<QString>* Song::synthesizer() const
+ {
+ std::vector<QString>* l = new std::vector<QString>;
+
+ for (std::vector<Synth*>::const_iterator i = synthis.begin();
+ i != synthis.end(); ++i) {
+ l->push_back((*i)->name());
+ }
+ return l;
+ }
+
+//---------------------------------------------------------
+// setRecordFlag
+//---------------------------------------------------------
+
+void Song::setRecordFlag(Track* track, bool val)
+ {
+ if (track->type() == Track::AUDIO_OUTPUT) {
+ if (!val && track->recordFlag() == false) {
+ muse->bounceToFile();
+ }
+ }
+ track->setRecordFlag(val);
+ }
+
+//---------------------------------------------------------
+// setMute
+//---------------------------------------------------------
+
+void Song::setMute(Track* track, bool val)
+ {
+ track->setMute(val);
+ emit muteChanged(track, track->mute());
+ }
+
+//---------------------------------------------------------
+// setMonitor
+//---------------------------------------------------------
+
+void Song::setMonitor(Track* track, bool val)
+ {
+ track->setMonitor(val);
+// emit monitorChanged(track, track->mute());
+ }
+
+//---------------------------------------------------------
+// setOff
+//---------------------------------------------------------
+
+void Song::setOff(Track* track, bool val)
+ {
+ track->setOff(val);
+ emit offChanged(track, track->off());
+ }
+
+//---------------------------------------------------------
+// setAutoRead
+//---------------------------------------------------------
+
+void Song::setAutoRead(Track* track, bool val)
+ {
+ track->setAutoRead(val);
+ emit autoReadChanged(track, track->autoRead());
+ }
+
+//---------------------------------------------------------
+// setAutoWrite
+//---------------------------------------------------------
+
+void Song::setAutoWrite(Track* track, bool val)
+ {
+ track->setAutoWrite(val);
+ emit autoWriteChanged(track, track->autoRead());
+ }
+
+//---------------------------------------------------------
+// setSolo
+//---------------------------------------------------------
+
+void Song::setSolo(Track* track, bool val)
+ {
+ if (!track->setSolo(val))
+ return;
+ emit soloChanged(track, track->solo());
+ soloFlag = false;
+ for (iTrack i = _tracks.begin(); i != _tracks.end(); ++i) {
+ if ((*i)->solo()) {
+ soloFlag = true;
+ break;
+ }
+ }
+ for (iTrack i = _tracks.begin(); i != _tracks.end(); ++i) {
+ (*i)->updateMute();
+ }
+ }
+
+//---------------------------------------------------------
+// moveTrack
+//---------------------------------------------------------
+
+void Song::moveTrack(Track* src, Track* dst)
+ {
+ iTrack si = qFind(_tracks.begin(), _tracks.end(), src);
+ iTrack di = qFind(_tracks.begin(), _tracks.end(), dst);
+ if (si == _tracks.end() || di == _tracks.end()) {
+ printf("Song::moveTrack() track not found\n");
+ return;
+ }
+ _tracks.erase(si);
+ _tracks.insert(di, src);
+ }
+
+//---------------------------------------------------------
+// changeTrackName
+//---------------------------------------------------------
+
+void Song::changeTrackName(Track* t, const QString& s)
+ {
+ startUndo();
+ undoOp(UndoOp::RenameTrack, t, t->name(), s);
+ t->setName(s);
+ endUndo(SC_TRACK_MODIFIED);
+ }
+
+//---------------------------------------------------------
+// trackExists
+//---------------------------------------------------------
+
+bool Song::trackExists(Track* t) const
+ {
+ return findTrack(t->name()) != 0;
+ }
+
+//---------------------------------------------------------
+// findTrack
+//---------------------------------------------------------
+
+Track* Song::findTrack(const QString& name) const
+ {
+ for (int i = 0; i < _tracks.size(); ++i) {
+ if (_tracks[i]->name() == name)
+ return _tracks[i];
+ }
+ return 0;
+ }
+
diff --git a/muse_qt4_evolution/muse/strip.cpp b/muse_qt4_evolution/muse/strip.cpp
new file mode 100644
index 00000000..38519878
--- /dev/null
+++ b/muse_qt4_evolution/muse/strip.cpp
@@ -0,0 +1,123 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "gconfig.h"
+#include "song.h"
+#include "strip.h"
+#include "muse.h"
+#include "widgets/simplebutton.h"
+#include "widgets/utils.h"
+
+//---------------------------------------------------------
+// resetPeaks
+//---------------------------------------------------------
+
+void Strip::resetPeaks()
+ {
+ track->resetPeaks();
+ }
+
+//---------------------------------------------------------
+// updateLabel
+//---------------------------------------------------------
+
+void Strip::updateLabel()
+ {
+ label->setText(track->name());
+ label->setToolTip(track->name());
+ }
+
+//---------------------------------------------------------
+// Strip
+// create mixer strip
+//---------------------------------------------------------
+
+Strip::Strip(Mixer* m, Track* t, bool align)
+ : QFrame()
+ {
+ ar = 0;
+ aw = 0;
+ setAttribute(Qt::WA_DeleteOnClose, true);
+ mixer = m;
+ _align = align;
+ setFrameStyle(QFrame::Panel | QFrame::Raised);
+ setLineWidth(2);
+
+ track = t;
+ grid = new QGridLayout;
+ grid->setMargin(0);
+ grid->setSpacing(0);
+ setLayout(grid);
+
+ //---------------------------------------------
+ // label
+ //---------------------------------------------
+
+ label = new QLabel;
+ label->setObjectName(track->cname());
+ label->setFixedHeight(LABEL_HEIGHT);
+ label->setTextFormat(Qt::PlainText);
+ label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
+ label->setLineWidth(2);
+ label->setFrameStyle(QFrame::Sunken | QFrame::StyledPanel);
+ updateLabel();
+ grid->addWidget(label, 0, 0, 1, 2);
+ connect(muse, SIGNAL(configChanged()), SLOT(configChanged()));
+ connect(track, SIGNAL(controllerChanged(int)), SLOT(controllerChanged(int)));
+ }
+
+//---------------------------------------------------------
+// Strip
+//---------------------------------------------------------
+
+Strip::~Strip()
+ {
+ }
+
+//---------------------------------------------------------
+// configChanged
+//---------------------------------------------------------
+
+void Strip::configChanged()
+ {
+ updateLabel();
+ }
+
+//---------------------------------------------------------
+// addAutomationButtons
+//---------------------------------------------------------
+
+void Strip::addAutomationButtons(int row)
+ {
+ ar = newAutoReadButton();
+ ar->setFixedHeight(BUTTON_HEIGHT);
+ ar->setChecked(track->autoRead());
+ grid->addWidget(ar, row, 0);
+ aw = newAutoWriteButton();
+ aw->setFixedHeight(BUTTON_HEIGHT);
+ aw->setChecked(track->autoWrite());
+ grid->addWidget(aw, row, 1);
+ connect(ar, SIGNAL(clicked(bool)), SLOT(autoReadToggled(bool)));
+ connect(aw, SIGNAL(clicked(bool)), SLOT(autoWriteToggled(bool)));
+ connect(track, SIGNAL(autoReadChanged(bool)), ar, SLOT(setChecked(bool)));
+ connect(track, SIGNAL(autoWriteChanged(bool)), aw, SLOT(setChecked(bool)));
+ }
+
+
diff --git a/muse_qt4_evolution/muse/strip.h b/muse_qt4_evolution/muse/strip.h
new file mode 100644
index 00000000..1e5f7bd4
--- /dev/null
+++ b/muse_qt4_evolution/muse/strip.h
@@ -0,0 +1,75 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __STRIP_H__
+#define __STRIP_H__
+
+#include "globaldefs.h"
+#include "gui.h"
+
+class Track;
+class Meter;
+class SimpleButton;
+class Mixer;
+
+static const QSize entrySize(STRIP_WIDTH/2-2, ENTRY_HEIGHT);
+
+//---------------------------------------------------------
+// Strip
+//---------------------------------------------------------
+
+class Strip : public QFrame {
+ Q_OBJECT
+
+ protected:
+ Mixer* mixer;
+ Track* track;
+ QLabel* label;
+ QGridLayout* grid;
+
+ SimpleButton* solo;
+ SimpleButton* mute;
+ SimpleButton* ar;
+ SimpleButton* aw;
+
+ void updateLabel();
+ bool _align; // align elements for mixer app
+
+ void recordToggled(bool);
+ void addAutomationButtons(int row);
+ void addMidiInPorts(QMenu* menu, Track* dtrack, int channel);
+ void addMidiOutPorts(QMenu* menu, Track* strack, int channel);
+
+ public slots:
+ void resetPeaks();
+ virtual void songChanged(int) = 0;
+ virtual void controllerChanged(int) {}
+ void configChanged();
+
+ public:
+ Strip(Mixer* m, Track* t, bool align);
+ ~Strip();
+ Track* getTrack() const { return track; }
+ virtual void heartBeat() = 0;
+ virtual QSize sizeHint() const { return QSize(STRIP_WIDTH, 80); }
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/style.qss b/muse_qt4_evolution/muse/style.qss
new file mode 100644
index 00000000..b62122c5
--- /dev/null
+++ b/muse_qt4_evolution/muse/style.qss
@@ -0,0 +1,66 @@
+/*
+ * this is the MusE application style sheet
+ */
+
+QLabel#midiChannelLabel { font-size: 6pt }
+MidiRack, EffectRack { font-size: 8pt }
+QLabel#trackLabel { font-size: 6pt }
+SimpleButton { font-size: 8pt }
+QToolButton#routeButton { font-size: 8pt }
+QToolButton#preButton { font-size: 8pt }
+
+TimeCanvas {
+ qproperty-fontSize1: 6;
+ qproperty-fontSize2: 8;
+ qproperty-fontSize3: 8
+ }
+
+QLabel#knobLabel { font-size: 8pt }
+Awl--MidiVolEntry { font-size: 5pt }
+Awl--MidiPanEntry { font-size: 5pt }
+Awl--VolEntry { font-size: 5pt }
+Awl--PanEntry { font-size: 5pt }
+
+QLabel#AudioOut {
+ font-size: 7pt;
+ background-color: white;
+ }
+
+QLabel#Group {
+ font-size: 7pt;
+ background-color: yellow;
+ }
+
+QLabel#Wave {
+ font-size: 7pt;
+ background-color: rgb(0,255,0);
+ }
+
+QLabel#AudioIn {
+ font-size: 7pt;
+ background-color: red;
+ }
+
+QLabel#Synth {
+ font-size: 7pt;
+ background-color: blue;
+ }
+
+QLabel#Midi {
+ font-size: 7pt;
+ background-color: gray;
+ }
+
+QLabel#MidiOut {
+ font-size: 7pt;
+ background-color: gray;
+ }
+
+QLabel#MidiIn {
+ font-size: 7pt;
+ background-color: gray;
+ }
+QLabel#M-Synth {
+ font-size: 7pt;
+ background-color: gray;
+ }
diff --git a/muse_qt4_evolution/muse/sync.cpp b/muse_qt4_evolution/muse/sync.cpp
new file mode 100644
index 00000000..c4cb30fc
--- /dev/null
+++ b/muse_qt4_evolution/muse/sync.cpp
@@ -0,0 +1,499 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "sync.h"
+#include "song.h"
+#include "widgets/utils.h"
+#include "globals.h"
+#include "audio.h"
+#include "audiodev.h"
+#include "gconfig.h"
+#include "al/tempo.h"
+#include "al/al.h"
+
+int rxSyncPort = -1; // receive from all ports
+int txSyncPort = 1;
+
+bool debugSync = false;
+MTC mtcOffset;
+bool extSyncFlag = false;
+bool genMTCSync = false; // output MTC Sync
+bool genMCSync = false; // output MidiClock Sync
+bool genMMC = false; // output Midi Machine Control
+bool acceptMTC = false;
+bool acceptMC = true;
+bool acceptMMC = true;
+
+static MTC mtcCurTime;
+// static int mtcState; // 0-7 next expected quarter message
+// static bool mtcValid;
+// static int mtcLost;
+// static bool mtcSync; // receive complete mtc frame?
+
+//static bool mcStart = false;
+//static int mcStartTick;
+
+enum {
+ MMC_STOP = 1,
+ MMC_PLAY = 2,
+ MMC_DEFERRED_PLAY = 3,
+ MMC_FAST_FORWARD = 4,
+ MMC_REWIND = 5,
+ MMC_RECORD_STROBE = 6, // Punch In
+ MMC_RECORD_EXIT = 7, // Punch Out
+ MMC_PAUSE = 9,
+ MMC_RESET = 13,
+ MMC_GOTO = 0x44
+ };
+
+#if 0
+//---------------------------------------------------------
+// mmcInput
+// Midi Machine Control Input received
+//---------------------------------------------------------
+
+void MidiSeq::mmcInput(int id, int cmd, const Pos& pos)
+ {
+#if 0
+ int rxDeviceId = 127;
+
+ if (!extSyncFlag || !acceptMMC || (id != 127 && id != rxDeviceId))
+ return;
+
+ if (debugMsg)
+ printf("mmcInput: id %d cmd %02x %02x\n", id, cmd, cmd);
+
+ switch (cmd) {
+ case MMC_STOP:
+ if (debugSync)
+ printf(" MMC: STOP\n");
+ if (audio->isPlaying())
+ audioDriver->stopTransport();
+ else
+ // reset REC
+ audio->sendMsgToGui(MSG_STOP);
+ break;
+ case MMC_PLAY:
+ case MMC_DEFERRED_PLAY:
+ audioDriver->startTransport();
+ break;
+ case MMC_FAST_FORWARD:
+ printf("MMC: FF not implemented\n");
+ break;
+ case MMC_REWIND:
+ printf("MMC: REWIND not implemented\n");
+ break;
+ case MMC_RECORD_STROBE:
+ printf("MMC: REC STROBE not implemented\n");
+ break;
+ case MMC_RECORD_EXIT:
+ printf("MMC: REC EXIT not implemented\n");
+ break;
+ case MMC_PAUSE:
+ audio->sendMsgToGui(MSG_RECORD);
+ break;
+ case MMC_RESET:
+ printf("MMC: RESET not implemented\n");
+ break;
+
+ case MMC_GOTO:
+ audioDriver->seekTransport(pos.frame());
+ break;
+
+ default:
+ printf("MMC id %x cmd %x, unknown\n", id, cmd);
+ break;
+ }
+#endif
+ }
+
+//---------------------------------------------------------
+// mtcInputQuarter
+// process Quarter Frame Message
+//---------------------------------------------------------
+
+void MidiSeq::mtcInputQuarter(int, unsigned char c)
+ {
+#if 0
+ static int hour, min, sec, frame;
+
+ if (!extSyncFlag)
+ return;
+
+ int valL = c & 0xf;
+ int valH = valL << 4;
+
+ int _state = (c & 0x70) >> 4;
+ if (mtcState != _state)
+ mtcLost += _state - mtcState;
+ mtcState = _state + 1;
+
+ switch(_state) {
+ case 7:
+ hour = (hour & 0x0f) | valH;
+ break;
+ case 6:
+ hour = (hour & 0xf0) | valL;
+ break;
+ case 5:
+ min = (min & 0x0f) | valH;
+ break;
+ case 4:
+ min = (min & 0xf0) | valL;
+ break;
+ case 3:
+ sec = (sec & 0x0f) | valH;
+ break;
+ case 2:
+ sec = (sec & 0xf0) | valL;
+ break;
+ case 1:
+ frame = (frame & 0x0f) | valH;
+ break;
+ case 0: frame = (frame & 0xf0) | valL;
+ break;
+ }
+ frame &= 0x1f; // 0-29
+ sec &= 0x3f; // 0-59
+ min &= 0x3f; // 0-59
+ hour &= 0x1f;
+
+ if (mtcState == 8) {
+ mtcValid = (mtcLost == 0);
+ mtcState = 0;
+ mtcLost = 0;
+ if (mtcValid) {
+ mtcCurTime.set(hour, min, sec, frame);
+ mtcSyncMsg(mtcCurTime, !mtcSync);
+ mtcSync = true;
+ }
+ }
+ else if (mtcValid && (mtcLost == 0)) {
+ mtcCurTime.incQuarter();
+ mtcSyncMsg(mtcCurTime, false);
+ }
+#endif
+ }
+
+//---------------------------------------------------------
+// mtcInputFull
+// process Frame Message
+//---------------------------------------------------------
+
+void MidiSeq::mtcInputFull(const unsigned char* p, int n)
+ {
+#if 0
+ if (debugSync)
+ printf("mtcInputFull\n");
+ if (!extSyncFlag)
+ return;
+
+ if (p[3] != 1) {
+ if (p[3] != 2) { // silently ignore user bits
+ printf("unknown mtc msg subtype 0x%02x\n", p[3]);
+ dump(p, n);
+ }
+ return;
+ }
+ int hour = p[4];
+ int min = p[5];
+ int sec = p[6];
+ int frame = p[7];
+
+ frame &= 0x1f; // 0-29
+ sec &= 0x3f; // 0-59
+ min &= 0x3f; // 0-59
+// int type = (hour >> 5) & 3;
+ hour &= 0x1f;
+
+ mtcCurTime.set(hour, min, sec, frame);
+ mtcState = 0;
+ mtcValid = true;
+ mtcLost = 0;
+#endif
+ }
+
+//---------------------------------------------------------
+// nonRealtimeSystemSysex
+//---------------------------------------------------------
+
+void MidiSeq::nonRealtimeSystemSysex(const unsigned char* p, int n)
+ {
+#if 0
+// int chan = p[2];
+ switch(p[3]) {
+ case 4:
+ printf("NRT Setup\n");
+ break;
+ default:
+ printf("unknown NRT Msg 0x%02x\n", p[3]);
+ dump(p, n);
+ break;
+ }
+#endif
+ }
+
+//---------------------------------------------------------
+// setSongPosition
+// MidiBeat is a 14 Bit value. Each MidiBeat spans
+// 6 MIDI Clocks. Inother words, each MIDI Beat is a
+// 16th note (since there are 24 MIDI Clocks in a
+// quarter note).
+//---------------------------------------------------------
+
+void MidiSeq::setSongPosition(int port, int midiBeat)
+ {
+#if 0
+ if (midiInputTrace)
+ printf("set song position port:%d %d\n", port, midiBeat);
+ if (!extSyncFlag)
+ return;
+ Pos pos((config.division * midiBeat) / 4, AL::TICKS);
+ audioDriver->seekTransport(pos.frame());
+ if (debugSync)
+ printf("setSongPosition %d\n", pos.tick());
+#endif
+ }
+
+//---------------------------------------------------------
+// realtimeSystemInput
+// real time message received
+//---------------------------------------------------------
+
+void MidiSeq::realtimeSystemInput(int port, int c)
+ {
+#if 0
+ if (midiInputTrace)
+ printf("realtimeSystemInput port:%d 0x%x\n", port+1, c);
+
+ if (midiInputTrace && (rxSyncPort != port) && rxSyncPort != -1) {
+ if (debugSync)
+ printf("rxSyncPort configured as %d; received sync from port %d\n",
+ rxSyncPort, port);
+ return;
+ }
+ if (!extSyncFlag)
+ return;
+ switch(c) {
+ case 0xf8: // midi clock (24 ticks / quarter note)
+ {
+ double mclock0 = curTime();
+ // Difference in time last 2 rounds:
+ double tdiff0 = mclock0 - mclock1;
+ double tdiff1 = mclock1 - mclock2;
+ double averagetimediff = 0.0;
+
+ if (mclock1 != 0.0) {
+ if (storedtimediffs < 24)
+ {
+ timediff[storedtimediffs] = mclock0 - mclock1;
+ storedtimediffs++;
+ }
+ else {
+ for (int i=0; i<23; i++) {
+ timediff[i] = timediff[i+1];
+ }
+ timediff[23] = mclock0 - mclock1;
+ }
+ // Calculate average timediff:
+ for (int i=0; i < storedtimediffs; i++) {
+ averagetimediff += timediff[i]/storedtimediffs;
+ }
+ }
+ processMidiClock();
+
+ // Compare w audio if playing:
+ if (audio->isPlaying() /*state == PLAY*/) {
+ //BEGIN standard setup:
+ recTick += config.division / 24; // The one we're syncing to
+ int tempo = AL::tempomap.tempo(0);
+ unsigned curFrame = audio->pos().frame();
+ double songtick = (double(curFrame)/double(AL::sampleRate)) * config.division * 1000000.0 / double(tempo);
+ double scale = tdiff0/averagetimediff;
+ double tickdiff = songtick - ((double) recTick - 24 + scale*24.0);
+
+ //END standard setup
+ if (debugSync) {
+ //
+ // Create debug values for printing out which beat we're at, etc etc... yaddayadda...
+ //
+ int m, b, t;
+ audio->pos().mbt(&m, &b, &t);
+
+ int song_beat = b + m*4; // if the time-signature is different than 4/4, this will be wrong.
+ int sync_beat = recTick/config.division;
+ printf("pT=%.3f rT=%d diff=%.3f songB=%d syncB=%d scale=%.3f", songtick, recTick, tickdiff, song_beat, sync_beat, scale);
+ }
+ //if ((mclock2 !=0.0) && (tdiff1 > 0.0) && tickdiff != 0.0 && lastTempo != 0) {
+ if ((mclock2 !=0.0) && (tdiff1 > 0.0) && fabs(tickdiff) > 2.0 && lastTempo != 0) {
+ // Interpolate:
+ double tickdiff1 = songtick1 - recTick1;
+ double tickdiff2 = songtick2 - recTick2;
+ //double newtickdiff = tickdiff/3.0 + tickdiff1/5.0 + tickdiff2/7.0; //2 min 15 sec, 120BPM, -p 512 jackd
+ //double newtickdiff = tickdiff/4.0 + tickdiff1/4.0 + tickdiff2/4.0; // Not long... :-P
+ //double newtickdiff = tickdiff/5.0 + tickdiff1/8.0 + tickdiff2/12.0; //3,5 mins on 120BPM, -p 512 jackd
+ //double newtickdiff = tickdiff/7.0 + tickdiff1/8.0 + tickdiff2/9.0; //2 min 15 sec, 120BPM, -p 512 jackd
+ //double newtickdiff = tickdiff/5.0 + tickdiff1/8.0 + tickdiff2/16.0; //3,5 mins on 120BPM, -p 512 jackd
+ double newtickdiff = tickdiff/5.0 + tickdiff1/16.0 + tickdiff2/24.0; //5 mins 30 secs on 116BPM, -p 512 jackd
+ //double newtickdiff = tickdiff/5.0 + tickdiff1/23.0 + tickdiff2/31.0; //5 mins on 116BPM, -p 512 jackd
+ //double newtickdiff = tickdiff + tickdiff1/8.0 + tickdiff2/16.0; // Not long...
+
+ if (newtickdiff != 0.0) {
+ int newTempo = AL::tempomap.tempo(0);
+ //newTempo += int(24.0 * newtickdiff * scale);
+ newTempo += int(24.0 * newtickdiff);
+ if (debugSync)
+ printf(" tdiff=%f ntd=%f lt=%d tmpo=%.3f", tdiff0, newtickdiff, lastTempo, (float)((1000000.0 * 60.0)/newTempo));
+ AL::tempomap.setTempo(0,newTempo);
+ }
+ if (debugSync)
+ printf("\n");
+ }
+ else if (debugSync)
+ printf("\n");
+
+ //BEGIN post calc
+ lastTempo = tempo;
+ recTick2 = recTick1;
+ recTick1 = recTick;
+ mclock2 = mclock1;
+ mclock1 = mclock0;
+ songtick2 = songtick1;
+ songtick1 = songtick;
+ //END post calc
+ break;
+ } // END state play
+ //
+ // Pre-sync (when audio is not running)
+ // Calculate tempo depending on time per pulse
+ //
+ if (mclock1 == 0.0) {
+//TODO3 midiPorts[port].device()->discardInput();
+ if (debugSync)
+ printf("Discarding input from port %d\n", port);
+ }
+ if ((mclock2 != 0.0) && (tdiff0 > 0.0)) {
+ int tempo0 = int(24000000.0 * tdiff0 + .5);
+ int tempo1 = int(24000000.0 * tdiff1 + .5);
+ int tempo = AL::tempomap.tempo(0);
+
+ int diff0 = tempo0 - tempo;
+ int diff1 = tempo1 - tempo0;
+ if (diff0) {
+ int newTempo = tempo + diff0/8 + diff1/16;
+ if (debugSync)
+ printf("setting new tempo %d = %f\n", newTempo, (float)((1000000.0 * 60.0)/newTempo));
+ AL::tempomap.setTempo(0, newTempo);
+ }
+ }
+ mclock2 = mclock1;
+ mclock1 = mclock0;
+ }
+ break;
+ case 0xf9: // midi tick (every 10 msec)
+ if (mcStart) {
+ song->setPos(0, mcStartTick);
+ mcStart = false;
+ return;
+ }
+ break;
+ case 0xfa: // start
+ if (debugSync)
+ printf(" start\n");
+ if (!audio->isPlaying() /*state == IDLE*/) {
+ //seek(0);
+ audioDriver->seekTransport(0);
+ unsigned curFrame = audioDriver->framePos();
+ recTick = recTick1 = recTick2 = 0;
+ mclock1 = 0.0; mclock2 = 0.0;
+ songtick1 = songtick2 = 0;
+ if (debugSync)
+ printf(" curFrame: %d curTick: %d tempo: %d\n", curFrame, recTick, AL::tempomap.tempo(0));
+
+ //startPlay();
+ storedtimediffs = 0;
+ for (int i=0; i<24; i++)
+ timediff[i] = 0.0;
+ audio->msgPlay(true);
+ }
+ break;
+ case 0xfb: // continue
+ if (debugSync)
+ printf(" continue\n");
+ if (!audio->isPlaying() /*state == IDLE */) {
+ unsigned curFrame = audioDriver->framePos();
+ recTick = AL::tempomap.frame2tick(curFrame); // don't think this will work... (ml)
+ audio->msgPlay(true);
+ }
+ break;
+ case 0xfc: // stop
+ if (debugSync)
+ printf(" stop\n");
+ if (audio->isPlaying() /*state == PLAY*/)
+ audio->msgPlay(false);
+ break;
+ case 0xfd: // unknown
+ case 0xfe: // active sensing
+ case 0xff: // system reset
+ break;
+ }
+#endif
+
+ }
+
+//---------------------------------------------------------
+// mtcSyncMsg
+// process received mtc Sync
+// seekFlag - first complete mtc frame received after
+// start
+//---------------------------------------------------------
+
+void MidiSeq::mtcSyncMsg(const MTC& /*mtc*/, bool /*seekFlag*/)
+ {
+#if 0
+ double time = mtc.time();
+ if (debugSync)
+ printf("mtcSyncMsg: time %f\n", time);
+
+ if (seekFlag && state == START_PLAY) {
+// int tick = tempomap.time2tick(time);
+ state = PLAY;
+ sendMsgToGui(MSG_PLAY);
+ return;
+ }
+ // double curT = curTime();
+
+ if (tempoSN != tempomap.tempoSN()) {
+ double cpos = tempomap.tick2time(_midiTick, 0);
+ samplePosStart = samplePos - lrint(cpos * sampleRate);
+ rtcTickStart = rtcTick - lrint(cpos * realRtcTicks);
+ tempoSN = tempomap.tempoSN();
+ }
+
+ //
+ // diff is the time in sec MusE is out of sync
+ //
+ double diff = time - (double(samplePosStart)/double(sampleRate));
+ if (debugSync)
+ printf(" state %d diff %f\n", mtcState, diff);
+#endif
+ }
+#endif
+
diff --git a/muse_qt4_evolution/muse/sync.h b/muse_qt4_evolution/muse/sync.h
new file mode 100644
index 00000000..b8d8920b
--- /dev/null
+++ b/muse_qt4_evolution/muse/sync.h
@@ -0,0 +1,37 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __SYNC_H__
+#define __SYNC_H__
+
+#include "mtc.h"
+
+extern bool debugSync;
+extern MTC mtcOffset;
+extern bool extSyncFlag;
+extern bool genMTCSync; // output MTC Sync
+extern bool genMCSync; // output MidiClock Sync
+extern bool genMMC; // output Midi Machine Control
+extern bool acceptMTC;
+extern bool acceptMC;
+extern bool acceptMMC;
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/synth.cpp b/muse_qt4_evolution/muse/synth.cpp
new file mode 100644
index 00000000..bbec5e34
--- /dev/null
+++ b/muse_qt4_evolution/muse/synth.cpp
@@ -0,0 +1,588 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include <dlfcn.h>
+
+#include "al/al.h"
+#include "al/xml.h"
+#include "al/tempo.h"
+#include "muse.h"
+#include "synth.h"
+#include "midi.h"
+#include "synti/libsynti/mess.h"
+#include "song.h"
+#include "audio.h"
+#include "event.h"
+#include "midievent.h"
+#include "audio.h"
+#include "midictrl.h"
+#include "instruments/minstrument.h"
+#include "audiodev.h"
+
+std::vector<Synth*> synthis; // array of available synthis
+
+extern void connectNodes(AudioTrack*, AudioTrack*);
+
+//---------------------------------------------------------
+// description
+//---------------------------------------------------------
+
+const char* MessSynth::description() const
+ {
+ return descr ? descr->description : "";
+ }
+
+//---------------------------------------------------------
+// version
+//---------------------------------------------------------
+
+const char* MessSynth::version() const
+ {
+ return descr ? descr->version : "";
+ }
+
+bool MessSynthIF::guiVisible() const
+ {
+ return _mess ? _mess->guiVisible() : false;
+ }
+
+void MessSynthIF::showGui(bool v)
+ {
+ if (v == guiVisible())
+ return;
+ if (_mess)
+ _mess->showGui(v);
+ }
+
+bool MessSynthIF::hasGui() const
+ {
+ if (_mess)
+ return _mess->hasGui();
+ return false;
+ }
+
+MidiEvent MessSynthIF::receiveEvent()
+ {
+ if (_mess)
+ return _mess->receiveEvent();
+ return MidiEvent();
+ }
+
+int MessSynthIF::eventsPending() const
+ {
+ if (_mess)
+ return _mess->eventsPending();
+ return 0;
+ }
+
+void MessSynthIF::getGeometry(int* x, int* y, int* w, int* h) const
+ {
+ if (_mess)
+ _mess->getGeometry(x, y, w, h);
+ }
+
+void MessSynthIF::setGeometry(int x, int y, int w, int h)
+ {
+ if (_mess)
+ _mess->setGeometry(x, y, w, h);
+ }
+
+//---------------------------------------------------------
+// findSynth
+// search for synthesizer base class
+//---------------------------------------------------------
+
+Synth* findSynth(const QString& sclass)
+ {
+ for (std::vector<Synth*>::iterator i = synthis.begin();
+ i != synthis.end(); ++i) {
+ if ((*i)->name() == sclass)
+ return *i;
+ }
+ printf("synthi class <%s> not found\n", sclass.toLatin1().data());
+ return 0;
+ }
+
+//---------------------------------------------------------
+// Synth
+//---------------------------------------------------------
+
+Synth::Synth(const QFileInfo* fi, QString s)
+ : info(*fi), _name(s)
+ {
+ _instances = 0;
+ }
+
+//---------------------------------------------------------
+// instantiate
+//---------------------------------------------------------
+
+void* MessSynth::instantiate(const QString& instanceName)
+ {
+ ++_instances;
+ const char* path = strdup(info.filePath().toAscii().data());
+
+ // load Synti dll
+ if (debugMsg)
+ printf(" load synti <%s>\n", path);
+ void* handle = dlopen(path, RTLD_NOW);
+ // void* handle = dlopen(path, RTLD_LAZY);
+ if (handle == 0) {
+ fprintf(stderr, "Synth::instantiate: dlopen(%s) failed: %s\n",
+ path, dlerror());
+ delete path;
+ return 0;
+ }
+ typedef const MESS* (*MESS_Function)();
+ MESS_Function msynth = (MESS_Function)dlsym(handle, "mess_descriptor");
+
+ if (!msynth) {
+ const char *txt = dlerror();
+ if (txt) {
+ fprintf(stderr,
+ "Unable to find msynth_descriptor() function in plugin "
+ "library file \"%s\": %s.\n"
+ "Are you sure this is a MESS plugin file?\n",
+ path, txt);
+ delete path;
+ return 0;
+ }
+ }
+ delete path;
+ descr = msynth();
+ if (descr == 0) {
+ fprintf(stderr, "Synth::instantiate: no MESS descr found\n");
+ return 0;
+ }
+ Mess* mess = descr->instantiate(AL::sampleRate, instanceName.toLatin1().data());
+ return mess;
+ }
+
+//---------------------------------------------------------
+// SynthI
+//---------------------------------------------------------
+
+SynthI::SynthI()
+ : AudioTrack()
+ {
+ track = this;
+ synthesizer = 0;
+ _sif = 0;
+ // setVolume(1.0);
+ // setPan(0.0);
+ setReadonly(true); // midi instrument cannot be edited
+ }
+
+//---------------------------------------------------------
+// ~SynthI
+//---------------------------------------------------------
+
+SynthI::~SynthI()
+ {
+ deactivate2();
+ deactivate3();
+ }
+
+//---------------------------------------------------------
+// setName
+//---------------------------------------------------------
+
+void SynthI::setName(const QString& s)
+ {
+ Track::setName(s);
+ }
+
+//---------------------------------------------------------
+// init
+//---------------------------------------------------------
+
+bool MessSynthIF::init(Synth* s, SynthI* si)
+ {
+ _mess = (Mess*)((MessSynth*)s)->instantiate(si->name());
+ return (_mess == 0);
+ }
+
+//---------------------------------------------------------
+// channels
+//---------------------------------------------------------
+
+int MessSynthIF::channels() const
+ {
+ return _mess->channels();
+ }
+
+//---------------------------------------------------------
+// createSIF
+//---------------------------------------------------------
+
+SynthIF* MessSynth::createSIF(SynthI* si)
+ {
+ MessSynthIF* sif = new MessSynthIF(si);
+ sif->init(this, si);
+ return sif;
+ }
+
+//---------------------------------------------------------
+// initInstance
+// returns false on success
+//---------------------------------------------------------
+
+bool SynthI::initInstance(Synth* s)
+ {
+ synthesizer = s;
+ _sif = s->createSIF(this);
+
+ setIName(name()); // set instrument name
+ int n = _sif->channels();
+ AudioTrack::setChannels(n);
+
+ //---------------------------------------------------
+ // read available controller from synti
+ //---------------------------------------------------
+
+ int id = 0;
+ MidiControllerList* cl = MidiInstrument::controller();
+ for (;;) {
+ const char* name;
+ int ctrl;
+ int min;
+ int max;
+ id = _sif->getControllerInfo(id, &name, &ctrl, &min, &max);
+ if (id == 0)
+ break;
+ MidiController* c = new MidiController(QString(name), ctrl, min, max, 0);
+ cl->push_back(c);
+ }
+
+ EventList* iel = midiState();
+ if (!iel->empty()) {
+ for (iEvent i = iel->begin(); i != iel->end(); ++i) {
+ Event ev = i->second;
+ MidiEvent pev(0, 0, ev);
+ if (_sif->putEvent(pev))
+ putFifo.put(pev); // save for later retry
+ }
+ iel->clear();
+ }
+
+ int idx = 0;
+ for (std::vector<float>::iterator i = initParams.begin(); i != initParams.end(); ++i, ++idx)
+ _sif->setParameter(idx, *i);
+ return false;
+ }
+
+//---------------------------------------------------------
+// getControllerInfo
+//---------------------------------------------------------
+
+int MessSynthIF::getControllerInfo(int id, const char** name, int* ctrl, int* min, int* max)
+ {
+ return _mess->getControllerInfo(id, name, ctrl, min, max);
+ }
+
+//---------------------------------------------------------
+// SynthI::deactivate
+//---------------------------------------------------------
+
+void SynthI::deactivate2()
+ {
+ removeMidiInstrument(this);
+ }
+
+//---------------------------------------------------------
+// deactivate3
+//---------------------------------------------------------
+
+void SynthI::deactivate3()
+ {
+ delete _sif;
+ _sif = 0;
+ synthesizer->incInstances(-1);
+ }
+
+void MessSynthIF::deactivate3()
+ {
+ if (_mess) {
+ delete _mess;
+ _mess = 0;
+ }
+ }
+
+MessSynthIF::~MessSynthIF()
+ {
+ deactivate3();
+ }
+
+//---------------------------------------------------------
+// initMidiSynth
+// search for software synthis and advertise
+//---------------------------------------------------------
+
+void initMidiSynth()
+ {
+ QString s = museGlobalLib + "/synthi";
+
+#ifdef __APPLE__
+ QDir pluginDir(s, QString("*.dylib"), 0, QDir::Files);
+#else
+ QDir pluginDir(s, QString("*.so"), 0, QDir::Files);
+#endif
+ if (debugMsg)
+ printf("searching for software synthesizer in <%s>\n", s.toLatin1().data());
+ if (pluginDir.exists()) {
+ QFileInfoList list = pluginDir.entryInfoList();
+ for (int i = 0; i < list.size(); ++i) {
+ QFileInfo fi = list.at(i);
+ synthis.push_back(new MessSynth(&fi));
+ }
+ if (debugMsg)
+ printf("%zd soft synth found\n", synthis.size());
+ }
+ }
+
+//---------------------------------------------------------
+// write
+//---------------------------------------------------------
+
+void SynthI::write(Xml& xml) const
+ {
+ xml.stag("SynthI");
+ AudioTrack::writeProperties(xml);
+ xml.tag("class", synth()->name());
+
+ //---------------------------------------------
+ // if soft synth is attached to a midi port,
+ // write out port number
+ //---------------------------------------------
+
+ if (hasGui()) {
+ xml.tag("guiVisible", guiVisible());
+ int x, y, w, h;
+ w = 0;
+ h = 0;
+ getGeometry(&x, &y, &w, &h);
+ if (h || w)
+ xml.tag("geometry", QRect(x, y, w, h));
+ }
+ _sif->write(xml);
+ xml.etag("SynthI");
+
+ }
+
+void MessSynthIF::write(Xml& xml) const
+ {
+ //---------------------------------------------
+ // dump current state of synth
+ //---------------------------------------------
+
+ int len = 0;
+ const unsigned char* p;
+ _mess->getInitData(&len, &p);
+ if (len) {
+ xml.stag("midistate");
+ xml.stag(QString("event type=\"%1\" datalen=\"%2\"").arg(Sysex).arg(len));
+ xml.dump(len, p);
+ xml.etag("event");
+ xml.etag("midistate");
+ }
+ }
+
+//---------------------------------------------------------
+// SynthI::read
+//---------------------------------------------------------
+
+void SynthI::read(QDomNode node)
+ {
+ QString sclass;
+ int port = -1;
+ bool startGui = false;
+ QRect r;
+
+ for (; !node.isNull(); node = node.nextSibling()) {
+ QDomElement e = node.toElement();
+ QString tag(e.tagName());
+ if (tag == "class")
+ sclass = e.text();
+ else if (tag == "port")
+ port = e.text().toInt();
+ else if (tag == "guiVisible")
+ startGui = e.text().toInt();
+ else if (tag == "midistate")
+ readMidiState(node.firstChild());
+ else if (tag == "param") {
+ float val = e.text().toFloat();
+ initParams.push_back(val);
+ }
+ else if (tag == "geometry")
+ r = AL::readGeometry(node);
+ else if (AudioTrack::readProperties(node)) {
+ printf("MusE:SynthI: unknown tag %s\n", e.tagName().toLatin1().data());
+ }
+ }
+ Synth* s = findSynth(sclass);
+ if (s == 0)
+ return;
+ if (initInstance(s))
+ return;
+ song->insertTrack0(this, -1);
+ setGeometry(r.x(), r.y(), r.width(), r.height());
+ showGui(startGui);
+ }
+
+//---------------------------------------------------------
+// getPatchName
+//---------------------------------------------------------
+
+QString MessSynthIF::getPatchName(int channel, int prog)
+ {
+ if (_mess)
+ return _mess->getPatchName(channel, prog, 0);
+ return "";
+ }
+
+//---------------------------------------------------------
+// populatePatchPopup
+//---------------------------------------------------------
+
+void MessSynthIF::populatePatchPopup(QMenu* menu, int ch)
+ {
+ menu->clear();
+ const MidiPatch* mp = _mess->getPatchInfo(ch, 0);
+ QMenu *hm = NULL, *lm = NULL;
+ while (mp) {
+ switch(mp->typ) {
+ case MP_TYPE_HBANK :
+ hm = menu->addMenu(QString(mp->name));
+ break;
+ case MP_TYPE_LBANK :
+ if(hm) lm = hm->addMenu(QString(mp->name));
+ else lm = menu->addMenu(QString(mp->name));
+ break;
+ default :
+ int id = ((mp->hbank & 0xff) << 16)
+ + ((mp->lbank & 0xff) << 8) + mp->prog;
+ QAction* a;
+ if(lm) a = lm->addAction(QString(mp->name));
+ else a = menu->addAction(QString(mp->name));
+ a->setData(id);
+ break;
+ }
+ mp = _mess->getPatchInfo(ch, mp);
+ }
+ }
+
+
+
+//---------------------------------------------------------
+// getData
+//---------------------------------------------------------
+
+void MessSynthIF::getData(MidiEventList* el, unsigned pos, int ports, unsigned n, float** buffer)
+ {
+ // Reset buffers first
+ for (int port = 0; port < ports; ++port)
+ memset(buffer[port], 0, n * sizeof(float));
+
+ int curPos = pos;
+ int endPos = pos + n;
+
+ while (!synti->putFifo.isEmpty()) {
+ if (putEvent(synti->putFifo.peek()))
+ break;
+ synti->putFifo.remove();
+ }
+
+ // Echo events from Synti back
+ while (_mess->eventsPending())
+ // _mess->processEvent(_mess->receiveEvent());
+ _mess->receiveEvent(); // throw away event
+
+ if (ports >= channels()) {
+ iMidiEvent i = el->begin();
+ for (; i != el->end(); ++i) {
+ int frame = i->time();
+ if (frame >= endPos)
+ break;
+ if (frame > curPos) {
+ // Several following notes during same segmentsize?
+ _mess->process(buffer, curPos-pos, frame - curPos);
+ curPos = frame; // don't process this piece again
+ }
+ if (putEvent(*i))
+ synti->putFifo.put(*i);
+ }
+ if (endPos - curPos > 0)
+ _mess->process(buffer, curPos-pos, endPos - curPos);
+ el->erase(el->begin(), i);
+ }
+ else {
+ // this happens if the synth has stereo and we switch the
+ // channel to mono
+
+ printf("MessSynthIF::getData - ports %d < channels %d\n",
+ ports, channels());
+ }
+ }
+
+//---------------------------------------------------------
+// putEvent
+// return true on error (busy), event will later be
+// resend
+//---------------------------------------------------------
+
+bool MessSynthIF::putEvent(const MidiEvent& ev)
+ {
+ bool rv = true;
+ if (_mess) {
+ rv = _mess->processEvent(ev);
+ if (midiOutputTrace && !rv) {
+ printf("MidiOut<%s>", synti->name().toLatin1().data());
+ ev.dump();
+ }
+ }
+ return rv;
+ }
+
+//---------------------------------------------------------
+// collectInputData
+//---------------------------------------------------------
+
+void SynthI::collectInputData()
+ {
+ bufferEmpty = false;
+ _sif->getData(&_schedEvents, audioDriver->frameTime(), channels(),
+ segmentSize, buffer);
+ }
+
+//-------------------------------------------------------------------
+// process
+// Collect all midi events for the current process cycle and put
+// into _schedEvents queue. For note on events create the proper
+// note off events. The note off events maybe played after the
+// current process cycle.
+//-------------------------------------------------------------------
+
+void SynthI::processMidi(SeqTime* t)
+ {
+ if (mute())
+ return;
+ MidiOut::processMidi(_schedEvents, t);
+ }
+
diff --git a/muse_qt4_evolution/muse/synth.h b/muse_qt4_evolution/muse/synth.h
new file mode 100644
index 00000000..cae9c417
--- /dev/null
+++ b/muse_qt4_evolution/muse/synth.h
@@ -0,0 +1,227 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __SYNTH_H__
+#define __SYNTH_H__
+
+#include "globals.h"
+#include "instruments/minstrument.h"
+#include "audiotrack.h"
+#include "midiout.h"
+#include "midififo.h"
+
+class Mess;
+struct MESS;
+
+class SynthI;
+class SynthIF;
+
+//---------------------------------------------------------
+// Synth
+// software synthesizer
+//---------------------------------------------------------
+
+class Synth {
+ protected:
+ QFileInfo info;
+ QString _name;
+ int _instances;
+
+ public:
+ Synth(const QFileInfo* fi, QString label);
+ virtual ~Synth() {}
+ virtual const char* description() const { return ""; }
+ virtual const char* version() const { return ""; }
+
+ int instances() const { return _instances; }
+ virtual void incInstances(int val) { _instances += val; }
+
+ QString name() const { return _name; }
+ QString path() const { return info.absolutePath(); }
+ virtual SynthIF* createSIF(SynthI*) = 0;
+ };
+
+//---------------------------------------------------------
+// MessSynth
+//---------------------------------------------------------
+
+class MessSynth : public Synth {
+ const MESS* descr;
+
+ public:
+ MessSynth(const QFileInfo* fi) : Synth(fi, fi->baseName()) { descr = 0; }
+ virtual ~MessSynth() {}
+ virtual const char* description() const;
+ virtual const char* version() const;
+ virtual void* instantiate(const QString&);
+ virtual SynthIF* createSIF(SynthI*);
+ };
+
+class Mess;
+
+//---------------------------------------------------------
+// SynthIF
+// synth instance interface
+//---------------------------------------------------------
+
+class SynthIF {
+
+ protected:
+ SynthI* synti;
+
+ public:
+ SynthIF(SynthI* s) { synti = s; }
+ virtual ~SynthIF() {}
+
+ virtual bool guiVisible() const = 0;
+ virtual void showGui(bool v) = 0;
+ virtual bool hasGui() const = 0;
+ virtual void getGeometry(int*, int*, int*, int*) const = 0;
+ virtual void setGeometry(int, int, int, int) = 0;
+ virtual void getData(MidiEventList*, unsigned pos, int ports, unsigned n, float** buffer) = 0;
+ virtual bool putEvent(const MidiEvent& ev) = 0;
+ virtual MidiEvent receiveEvent() = 0;
+ virtual int eventsPending() const = 0;
+ virtual int channels() const = 0;
+ virtual void deactivate3() = 0;
+ virtual QString getPatchName(int, int) = 0;
+ virtual void populatePatchPopup(QMenu*, int) = 0;
+ virtual void write(Xml& xml) const = 0;
+ virtual void setParameter(int idx, float value) = 0;
+ virtual int getControllerInfo(int id, const char** name, int* ctrl, int* min, int* max) = 0;
+ virtual bool hasAuxSend() const { return true; }
+ };
+
+//---------------------------------------------------------
+// SynthI
+// software synthesizer instance
+// Track
+// MidiInstrument
+//---------------------------------------------------------
+
+class SynthI : public AudioTrack, public MidiOut, public MidiInstrument
+ {
+ Q_OBJECT
+
+ SynthIF* _sif;
+
+ protected:
+ Synth* synthesizer;
+ std::vector<float> initParams;
+ MidiFifo putFifo;
+
+ bool putMidiEvent(const MidiEvent& ev) {
+ return _sif->putEvent(ev);
+ }
+
+ virtual QString open() { return QString("OK");}
+ virtual void close() {}
+ virtual void collectInputData();
+
+ public:
+ friend class SynthIF;
+ friend class MessSynthIF;
+ friend class DssiSynthIF;
+
+ SynthI();
+ virtual ~SynthI();
+ virtual TrackType type() const { return AUDIO_SOFTSYNTH; }
+
+ virtual void setName(const QString& s);
+
+ SynthIF* sif() const { return _sif; }
+ bool initInstance(Synth* s);
+
+ void read(QDomNode);
+ virtual void write(Xml&) const;
+
+ Synth* synth() const { return synthesizer; }
+ virtual bool isSynti() const { return true; }
+
+ virtual QString getPatchName(int ch, int prog) {
+ return _sif ? _sif->getPatchName(ch, prog) : "";
+ }
+ virtual void populatePatchPopup(QMenu* m, int i) {
+ _sif->populatePatchPopup(m, i);
+ }
+
+ void setParameter(const char* name, const char* value) const;
+
+ bool guiVisible() const { return _sif->guiVisible(); }
+ void showGui(bool v) { _sif->showGui(v); }
+ bool hasGui() const { return _sif->hasGui(); }
+ void getGeometry(int* x, int* y, int* w, int* h) const {
+ _sif->getGeometry(x, y, w, h);
+ }
+ void setGeometry(int x, int y, int w, int h) {
+ _sif->setGeometry(x, y, w, h);
+ }
+ MidiEvent receiveEvent() { return _sif->receiveEvent(); }
+ int eventsPending() const { return _sif->eventsPending(); }
+ void deactivate2();
+ void deactivate3();
+ bool isActivated() const { return synthesizer && _sif; }
+ virtual bool hasAuxSend() const { return _sif->hasAuxSend(); }
+ virtual void processMidi(SeqTime*);
+
+ virtual MidiOut* midiOut() { return this; }
+ virtual MidiInstrument* instrument() { return this; }
+ };
+
+//---------------------------------------------------------
+// MessSynthIF
+// mess synthesizer instance
+//---------------------------------------------------------
+
+class MessSynthIF : public SynthIF {
+ Mess* _mess;
+
+ public:
+ MessSynthIF(SynthI* s) : SynthIF(s) { _mess = 0; }
+ virtual ~MessSynthIF();
+
+ virtual bool guiVisible() const;
+ virtual void showGui(bool v);
+ virtual bool hasGui() const;
+ virtual void getGeometry(int*, int*, int*, int*) const;
+ virtual void setGeometry(int, int, int, int);
+ virtual void getData(MidiEventList*, unsigned pos, int ports, unsigned n, float** buffer);
+ virtual bool putEvent(const MidiEvent& ev);
+ virtual MidiEvent receiveEvent();
+ virtual int eventsPending() const;
+ virtual int channels() const;
+ virtual void deactivate3();
+ virtual QString getPatchName(int, int);
+ virtual void populatePatchPopup(QMenu*, int);
+ virtual void write(Xml& xml) const;
+ virtual void setParameter(int, float) {}
+ virtual int getControllerInfo(int id, const char** name, int* ctrl, int* min, int* max);
+ bool init(Synth* s, SynthI* si);
+ };
+
+typedef QList<SynthI*> SynthIList;
+typedef SynthIList::iterator iSynthI;
+typedef SynthIList::const_iterator ciSynthI;
+
+extern std::vector<Synth*> synthis; // array of available synthis
+extern Synth* findSynth(const QString& sclass);
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/templatedialog.cpp b/muse_qt4_evolution/muse/templatedialog.cpp
new file mode 100644
index 00000000..0b655862
--- /dev/null
+++ b/muse_qt4_evolution/muse/templatedialog.cpp
@@ -0,0 +1,259 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "templatedialog.h"
+#include "gconfig.h"
+#include "song.h"
+#include "icons.h"
+
+//
+// entry types for templateTree tree widget:
+//
+enum { DIR_TYPE, LOCAL_TEMPLATE_TYPE, GLOBAL_TEMPLATE_TYPE};
+
+//---------------------------------------------------------
+// processSubdir
+//---------------------------------------------------------
+
+void TemplateDialog::processSubdir(QTreeWidgetItem* item, const QString& p,
+ const QString& subdir, int type)
+ {
+ QDir pd(p + "/" + subdir);
+ pd.setFilter(QDir::Files | QDir::AllDirs | QDir::NoDotAndDotDot);
+ pd.setNameFilters(QStringList("*.med"));
+ QFileInfoList el = pd.entryInfoList();
+ foreach (QFileInfo s, el) {
+ QTreeWidgetItem* pi;
+ if (s.isDir()) {
+ pi = new QTreeWidgetItem(item, DIR_TYPE);
+ itemCollapsed(pi);
+ processSubdir(pi, pd.absolutePath(), s.fileName(), type);
+ }
+ else {
+ pi = new QTreeWidgetItem(item, type);
+ pi->setIcon(0, style()->standardIcon(QStyle::SP_FileIcon));
+ }
+ pi->setText(0, s.fileName());
+ }
+ }
+
+//---------------------------------------------------------
+// TemplateDialog
+//---------------------------------------------------------
+
+TemplateDialog::TemplateDialog(QWidget* parent)
+ : QDialog(parent)
+ {
+ setupUi(this);
+ templateTree->setSelectionBehavior(QAbstractItemView::SelectRows);
+ templateTree->setSelectionMode(QAbstractItemView::SingleSelection);
+
+ //
+ // add global templates to list
+ //
+ QTreeWidgetItem* pi;
+ pi = new QTreeWidgetItem(templateTree, DIR_TYPE);
+ templateTree->setItemExpanded(pi, true);
+ itemExpanded(pi);
+ pi->setText(0, tr("MusE presets"));
+ processSubdir(pi, museGlobalShare, "templates", GLOBAL_TEMPLATE_TYPE);
+
+ //
+ // add local templates to list
+ //
+ pi = new QTreeWidgetItem(templateTree, DIR_TYPE);
+ pi->setIcon(0, style()->standardIcon(QStyle::SP_FileIcon));
+ templateTree->setItemExpanded(pi, true);
+ itemExpanded(pi);
+ pi->setText(0, tr("User presets"));
+ processSubdir(pi, QDir::homePath() + "/" + config.templatePath, ".", LOCAL_TEMPLATE_TYPE);
+
+ connect(templateTree,
+ SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)),
+ SLOT(currentChanged(QTreeWidgetItem*, QTreeWidgetItem*)));
+ connect(templateTree,
+ SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)),
+ SLOT(itemDoubleClicked(QTreeWidgetItem*, int)));
+ connect(templateTree,
+ SIGNAL(itemCollapsed(QTreeWidgetItem*)),
+ SLOT(itemCollapsed(QTreeWidgetItem*)));
+ connect(templateTree,
+ SIGNAL(itemExpanded(QTreeWidgetItem*)),
+ SLOT(itemExpanded(QTreeWidgetItem*)));
+
+ currentChanged(0, 0);
+ }
+
+//---------------------------------------------------------
+// itemCollapsed
+//---------------------------------------------------------
+
+void TemplateDialog::itemCollapsed(QTreeWidgetItem* item)
+ {
+ item->setIcon(0, style()->standardIcon(QStyle::SP_DirClosedIcon));
+ }
+
+//---------------------------------------------------------
+// itemExpanded
+//---------------------------------------------------------
+
+void TemplateDialog::itemExpanded(QTreeWidgetItem* item)
+ {
+ item->setIcon(0, style()->standardIcon(QStyle::SP_DirOpenIcon));
+ }
+
+//---------------------------------------------------------
+// itemPath
+//---------------------------------------------------------
+
+QString TemplateDialog::itemPath(QTreeWidgetItem* item) const
+ {
+ QString path;
+ QTreeWidgetItem* ti = item;
+ QStringList dirComponent;
+ do {
+ dirComponent.prepend(ti->text(0));
+ ti = ti->parent();
+ } while (ti);
+ size_t n = dirComponent.size();
+ for (size_t i = 1; i < n; ++i) {
+ if (!path.isEmpty())
+ path += "/";
+ path += dirComponent[i];
+ }
+ return path;
+ }
+
+//---------------------------------------------------------
+// currentChanged
+//---------------------------------------------------------
+
+void TemplateDialog::currentChanged(QTreeWidgetItem* item, QTreeWidgetItem*)
+ {
+ bool enable = (item != 0) &&
+ (
+ (item->type() == LOCAL_TEMPLATE_TYPE)
+ ||
+ (item->type() == GLOBAL_TEMPLATE_TYPE)
+ );
+ createdDate->setEnabled(enable);
+ modifiedDate->setEnabled(enable);
+ comment->setEnabled(enable);
+
+ // newFolder->setEnabled(item == 0 || item->type() == DIR_TYPE);
+ if (!enable)
+ return;
+
+ QString pd;
+ if (item->type() == LOCAL_TEMPLATE_TYPE)
+ pd = QDir::homePath() + "/" + config.templatePath;
+ else
+ pd = museGlobalShare + "/" + "templates";
+
+ pd += "/" + itemPath(item);
+
+ QFileInfo pf(pd);
+ modifiedDate->setDateTime(pf.lastModified());
+
+ QTime time(0, 0, 0);
+ QDateTime date;
+
+ QFile f(pf.filePath());
+ QDomDocument doc;
+ int line, column;
+ QString err;
+ if (!doc.setContent(&f, false, &err, &line, &column)) {
+ QString col, ln, error;
+ col.setNum(column);
+ ln.setNum(line);
+ error = err + "\n at line: " + ln + " col: " + col;
+ printf("error reading med file: %s\n", error.toLatin1().data());
+ return;
+ }
+ for (QDomNode node = doc.documentElement(); !node.isNull(); node = node.nextSibling()) {
+ QDomElement e = node.toElement();
+ if (e.isNull())
+ continue;
+ if (e.tagName() == "muse") {
+ QString sversion = e.attribute("version", "1.0");
+ int major=0, minor=0;
+ sscanf(sversion.toLatin1().data(), "%d.%d", &major, &minor);
+ int version = major << 8 + minor;
+ if (version >= 0x200) {
+ for (QDomNode n1 = node.firstChild(); !n1.isNull(); n1 = n1.nextSibling()) {
+ QDomElement e = n1.toElement();
+ if (e.tagName() == "song") {
+ for (QDomNode n2 = n1.firstChild(); !n2.isNull(); n2 = n2.nextSibling()) {
+ QDomElement e = n2.toElement();
+ QString tag(e.tagName());
+ QString s(e.text());
+ if (tag == "comment")
+ comment->setPlainText(s);
+ else if (tag == "createDate") {
+ date = QDateTime::fromString(e.text(), Qt::ISODate);
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ createdDate->setDateTime(date);
+ }
+
+//---------------------------------------------------------
+// templatePath
+//---------------------------------------------------------
+
+QString TemplateDialog::templatePath() const
+ {
+ QTreeWidgetItem* item = templateTree->currentItem();
+ QString s;
+ if (item) {
+ if (item->type() == LOCAL_TEMPLATE_TYPE)
+ s = QDir::homePath() + "/" + config.templatePath;
+ else
+ s = museGlobalShare + "/" + "templates";
+ s += "/" + itemPath(item);
+ }
+ return s;
+ }
+
+//---------------------------------------------------------
+// setTemplatePath
+//---------------------------------------------------------
+
+void TemplateDialog::setTemplatePath(const QString&)
+ {
+ // TODO
+ }
+
+//---------------------------------------------------------
+// itemDoubleClicked
+//---------------------------------------------------------
+
+void TemplateDialog::itemDoubleClicked(QTreeWidgetItem* item, int)
+ {
+ if ((item->type() == LOCAL_TEMPLATE_TYPE) ||
+ (item->type() == GLOBAL_TEMPLATE_TYPE))
+ accept();
+ }
+
diff --git a/muse_qt4_evolution/muse/templatedialog.h b/muse_qt4_evolution/muse/templatedialog.h
new file mode 100644
index 00000000..4db03286
--- /dev/null
+++ b/muse_qt4_evolution/muse/templatedialog.h
@@ -0,0 +1,51 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __TEMPLATE_DIALOG_H__
+#define __TEMPLATE_DIALOG_H__
+
+#include "ui_templatedialog.h"
+
+//---------------------------------------------------------
+// TemplateDialog
+//---------------------------------------------------------
+
+class TemplateDialog : public QDialog, public Ui_TemplateDialogBase {
+ Q_OBJECT
+
+ void processSubdir(QTreeWidgetItem*, const QString&,
+ const QString&, int);
+
+ QString itemPath(QTreeWidgetItem*) const;
+
+ private slots:
+ void currentChanged(QTreeWidgetItem*, QTreeWidgetItem*);
+ void itemCollapsed(QTreeWidgetItem*);
+ void itemExpanded(QTreeWidgetItem*);
+ void itemDoubleClicked(QTreeWidgetItem*, int);
+
+ public:
+ TemplateDialog(QWidget* parent = 0);
+ QString templatePath() const;
+ void setTemplatePath(const QString&);
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/templatedialog.ui b/muse_qt4_evolution/muse/templatedialog.ui
new file mode 100644
index 00000000..cbbc295d
--- /dev/null
+++ b/muse_qt4_evolution/muse/templatedialog.ui
@@ -0,0 +1,188 @@
+<ui version="4.0" >
+ <author></author>
+ <comment></comment>
+ <exportmacro></exportmacro>
+ <class>TemplateDialogBase</class>
+ <widget class="QDialog" name="TemplateDialogBase" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>574</width>
+ <height>385</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>MusE: Select Template</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="1" >
+ <widget class="QGroupBox" name="groupBox" >
+ <property name="title" >
+ <string>Properties</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>3</number>
+ </property>
+ <item row="0" column="1" >
+ <widget class="QDateEdit" name="createdDate" >
+ <property name="focusPolicy" >
+ <enum>Qt::NoFocus</enum>
+ </property>
+ <property name="readOnly" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QDateEdit" name="modifiedDate" >
+ <property name="focusPolicy" >
+ <enum>Qt::NoFocus</enum>
+ </property>
+ <property name="readOnly" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" >
+ <widget class="QLabel" name="label_5" >
+ <property name="text" >
+ <string>Comment:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_3" >
+ <property name="text" >
+ <string>Modified:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label_2" >
+ <property name="text" >
+ <string>Created:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0" colspan="2" >
+ <widget class="QTextEdit" name="comment" >
+ <property name="focusPolicy" >
+ <enum>Qt::NoFocus</enum>
+ </property>
+ <property name="readOnly" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="2" >
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>131</width>
+ <height>31</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="okButton" >
+ <property name="text" >
+ <string>OK</string>
+ </property>
+ <property name="default" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="cancelButton" >
+ <property name="text" >
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="0" column="0" >
+ <widget class="QTreeWidget" name="templateTree" >
+ <column>
+ <property name="text" >
+ <string>Templates</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <pixmapfunction></pixmapfunction>
+ <tabstops>
+ <tabstop>okButton</tabstop>
+ <tabstop>cancelButton</tabstop>
+ <tabstop>templateTree</tabstop>
+ <tabstop>modifiedDate</tabstop>
+ <tabstop>createdDate</tabstop>
+ <tabstop>comment</tabstop>
+ </tabstops>
+ <resources>
+ <include location="muse.qrc" />
+ </resources>
+ <connections>
+ <connection>
+ <sender>okButton</sender>
+ <signal>clicked()</signal>
+ <receiver>TemplateDialogBase</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>278</x>
+ <y>253</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>96</x>
+ <y>254</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>cancelButton</sender>
+ <signal>clicked()</signal>
+ <receiver>TemplateDialogBase</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>369</x>
+ <y>253</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>179</x>
+ <y>282</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/muse_qt4_evolution/muse/thread.cpp b/muse_qt4_evolution/muse/thread.cpp
new file mode 100644
index 00000000..8291613b
--- /dev/null
+++ b/muse_qt4_evolution/muse/thread.cpp
@@ -0,0 +1,354 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include <poll.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+
+#include "thread.h"
+#include "globals.h"
+#include "errno.h"
+
+//---------------------------------------------------------
+// Thread
+//---------------------------------------------------------
+
+Thread::~Thread()
+ {
+ }
+
+//---------------------------------------------------------
+// serverloop
+//---------------------------------------------------------
+
+static void* loop(void* mops)
+ {
+ Thread* t = (Thread*) mops;
+ t->loop();
+ return 0;
+ }
+
+//---------------------------------------------------------
+// start
+//---------------------------------------------------------
+
+void Thread::start(int prio, void* ptr)
+ {
+ userPtr = ptr;
+ pthread_attr_t* attributes = 0;
+
+ realTimePriority = prio;
+ if (realTimePriority) {
+ attributes = (pthread_attr_t*) malloc(sizeof(pthread_attr_t));
+ pthread_attr_init(attributes);
+
+ if (pthread_attr_setschedpolicy(attributes, SCHED_FIFO)) {
+ printf("cannot set FIFO scheduling class for RT thread\n");
+ }
+ if (pthread_attr_setscope (attributes, PTHREAD_SCOPE_SYSTEM)) {
+ printf("Cannot set scheduling scope for RT thread\n");
+ }
+ if (pthread_attr_setinheritsched(attributes, PTHREAD_EXPLICIT_SCHED)) {
+ printf("Cannot set setinheritsched for RT thread\n");
+ }
+
+ struct sched_param rt_param;
+ memset(&rt_param, 0, sizeof(rt_param));
+ rt_param.sched_priority = realTimePriority;
+ if (pthread_attr_setschedparam (attributes, &rt_param)) {
+ printf("Cannot set scheduling priority %d for RT thread (%s)\n",
+ realTimePriority, strerror(errno));
+ }
+ }
+
+ int rv;
+ if ((rv = pthread_create(&thread, attributes, ::loop, this))) {
+ fprintf(stderr, "creating thread <%s> failed: %s\n",
+ _name, strerror(rv));
+ thread = 0;
+ }
+ }
+
+//---------------------------------------------------------
+// stop
+//---------------------------------------------------------
+
+void Thread::stop(bool force)
+ {
+ if (thread == 0)
+ return;
+ if (force) {
+ pthread_cancel(thread);
+ threadStop();
+ }
+ _running = false;
+ if (pthread_join(thread, 0)) {
+ // perror("Failed to join sequencer thread");
+ }
+ }
+
+//---------------------------------------------------------
+// Thread
+// prio = 0 no realtime scheduling
+//---------------------------------------------------------
+
+Thread::Thread(const char* s)
+ {
+ userPtr = 0;
+ _name = s;
+ realTimePriority = 0;
+ pfd = 0;
+ npfd = 0;
+ maxpfd = 0;
+ _running = false;
+ _pollWait = -1;
+ thread = 0;
+ sendSerialNo = 0x00a5a500;
+
+ // create message channels
+ int filedes[2]; // 0 - reading 1 - writing
+ if (pipe(filedes) == -1) {
+ perror("thread:creating pipe4");
+ exit(-1);
+ }
+ toThreadFdr = filedes[0];
+ toThreadFdw = filedes[1];
+ if (fcntl(toThreadFdw, F_SETFL, O_NONBLOCK) == -1)
+ perror("set pipe nonblocking\n");
+
+ if (pipe(filedes) == -1) {
+ perror("thread: creating pipe5");
+ exit(-1);
+ }
+ fromThreadFdr = filedes[0];
+ fromThreadFdw = filedes[1];
+ if (fcntl(fromThreadFdw, F_SETFL, O_NONBLOCK) == -1)
+ perror("set pipe nonblocking\n");
+ }
+
+//---------------------------------------------------------
+// addPollFd
+//---------------------------------------------------------
+
+void Thread::addPollFd(int fd, int action, void (*handler)(void*,void*), void* p, void* q)
+ {
+ if (fd == -1)
+ return;
+ for (iPoll i = plist.begin(); i != plist.end(); ++i) {
+ if ((i->fd == fd) && (i->action == action))
+ return;
+ }
+
+ plist.push_back(Poll(fd, action, handler, p, q));
+
+ if (npfd == maxpfd) {
+ int n = (maxpfd == 0) ? 4 : maxpfd * 2;
+ //TODO: delete old pfd
+ pfd = new struct pollfd[n];
+ maxpfd = n;
+ }
+ ++npfd;
+ int idx = 0;
+ for (iPoll i = plist.begin(); i != plist.end(); ++i, ++idx) {
+ pfd[idx].fd = i->fd;
+ pfd[idx].events = i->action;
+ }
+ }
+
+//---------------------------------------------------------
+// removePollFd
+//---------------------------------------------------------
+
+void Thread::removePollFd(int fd, int action)
+ {
+ for (iPoll i = plist.begin(); i != plist.end(); ++i) {
+ if (i->fd == fd && i->action == action) {
+ plist.erase(i);
+ --npfd;
+ break;
+ }
+ }
+ int idx = 0;
+ for (iPoll i = plist.begin(); i != plist.end(); ++i, ++idx) {
+ pfd[idx].fd = i->fd;
+ pfd[idx].events = i->action;
+ }
+ }
+
+//---------------------------------------------------------
+// loop
+//---------------------------------------------------------
+
+void Thread::loop()
+ {
+ if (!debugMode) {
+ if (mlockall(MCL_CURRENT | MCL_FUTURE))
+ perror("WARNING: Cannot lock memory:");
+ }
+#ifdef __APPLE__
+#define BIG_ENOUGH_STACK (1024*256*1)
+#else
+#define BIG_ENOUGH_STACK (1024*1024*1)
+#endif
+ char buf[BIG_ENOUGH_STACK];
+ for (int i = 0; i < BIG_ENOUGH_STACK; i++)
+ buf[i] = i;
+#undef BIG_ENOUGH_STACK
+
+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, 0);
+ pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);
+
+ int policy;
+ /*if ((policy = sched_getscheduler (0)) < 0) {
+ printf("Thread: Cannot get current client scheduler: %s\n", strerror(errno));
+ }
+*/
+ if (debugMsg)
+ printf("Thread <%s, id %p> has %s priority %d\n",
+ _name, (void *)pthread_self(), policy == SCHED_FIFO ? "SCHED_FIFO" : "SCHED_OTHER",
+ realTimePriority);
+
+ _running = true;
+
+ threadStart(userPtr);
+ while (_running) {
+ if (debugMode) // DEBUG
+ _pollWait = 10; // ms
+ else
+ _pollWait = -1;
+
+ int n = poll(pfd, npfd, _pollWait);
+ if (n < 0) {
+ if (errno == EINTR)
+ continue;
+ fprintf(stderr, "poll failed: %s\n", strerror(errno));
+ exit(-1);
+ }
+ if (n == 0) { // timeout
+ defaultTick();
+ continue;
+ }
+ struct pollfd* p = &pfd[0];
+ int i = 0;
+ for (iPoll ip = plist.begin(); ip != plist.end(); ++ip, ++p, ++i) {
+ if (ip->action & p->revents) {
+ (ip->handler)(ip->param1, ip->param2);
+ break;
+ }
+ }
+ }
+ threadStop();
+ }
+
+//---------------------------------------------------------
+// sendMsg
+// send request from gui to thread
+// wait until request is processed
+//---------------------------------------------------------
+
+extern const char* seqMsgList[];
+
+bool Thread::sendMsg(const ThreadMsg* m)
+ {
+// fprintf(stderr, "<%s> self: %p sendMsg %d id %s running %d\n",
+// _name,
+// pthread_self(), sendSerialNo, seqMsgList[m->id], _running);
+
+ m->serialNo = sendSerialNo;
+ if (_running) {
+ int rv = write(toThreadFdw, &m, sizeof(ThreadMsg*));
+ if (rv != sizeof(ThreadMsg*)) {
+ perror("Thread::sendMessage(): write pipe failed");
+ return true;
+ }
+
+ // wait for thread to finish operation
+ int c;
+ rv = read(fromThreadFdr, &c, sizeof(c));
+ if (rv != sizeof(c)) {
+ perror("Thread::sendMessage(): read pipe failed");
+ return true;
+ }
+ if (c != sendSerialNo)
+ fprintf(stderr, "%p Thread:sendMsg() serial No mismatch %d - %d\n",
+ this, c, sendSerialNo);
+ }
+ else {
+ // if thread is not running (during initialization)
+ // process commands directly:
+ processMsg(m);
+ }
+ ++sendSerialNo;
+ return false;
+ }
+
+//---------------------------------------------------------
+// sendMsg1
+// send request from gui to thread
+// do __not__ wait until request is processed
+//---------------------------------------------------------
+
+bool Thread::sendMsg1(const void* m, int n)
+ {
+ int rv = write(toThreadFdw, m, n);
+ if (rv != n) {
+ perror("Thread::sendMessage1(): write pipe failed");
+ return true;
+ }
+ return false;
+ }
+
+//---------------------------------------------------------
+// readMsg
+//---------------------------------------------------------
+
+void Thread::readMsg()
+ {
+ ThreadMsg* p;
+ if (read(toThreadFdr, &p, sizeof(p)) != sizeof(p)) {
+ perror("Thread::readMsg(): read pipe failed");
+ exit(-1);
+ }
+// fprintf(stderr, "%p read msg %d %s\n", this, p->serialNo, seqMsgList[p->id]);
+
+ processMsg(p);
+ int c = p->serialNo;
+ int rv = write(fromThreadFdw, &c, sizeof(c));
+ if (rv != sizeof(c))
+ perror("Thread::readMsg(): write pipe failed");
+ }
+
+//---------------------------------------------------------
+// readMsg
+// sequencer reads one gui message
+//---------------------------------------------------------
+
+void Thread::readMsg1(int size)
+ {
+ char buffer[size];
+ int n = read(toThreadFdr, buffer, size);
+ if (n != size) {
+ fprintf(stderr, "Thread::readMessage1(): read pipe failed, get %d, expected %d: %s\n",
+ n, size, strerror(errno));
+ exit(-1);
+ }
+ processMsg1(buffer);
+ }
+
diff --git a/muse_qt4_evolution/muse/thread.h b/muse_qt4_evolution/muse/thread.h
new file mode 100644
index 00000000..cf7fc40b
--- /dev/null
+++ b/muse_qt4_evolution/muse/thread.h
@@ -0,0 +1,109 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __THREAD_H__
+#define __THREAD_H__
+
+#include <pthread.h>
+
+//---------------------------------------------------------
+// Poll
+//---------------------------------------------------------
+
+struct Poll {
+ int fd;
+ int action;
+ void (*handler)(void*,void*);
+ void* param1;
+ void* param2;
+
+ Poll(int _fd, int _action, void(*_handler)(void*,void*), void* p, void* q) {
+ fd = _fd;
+ action = _action;
+ handler = _handler;
+ param1 = p;
+ param2 = q;
+ }
+ };
+
+typedef std::list<Poll> PollList;
+typedef std::list<Poll>::iterator iPoll;
+
+
+//---------------------------------------------------------
+// ThreadMsg
+//---------------------------------------------------------
+
+struct ThreadMsg {
+ int id;
+ mutable int serialNo; // debug
+ };
+
+//---------------------------------------------------------
+// Thread
+//---------------------------------------------------------
+
+class Thread {
+ const char* _name;
+ volatile bool _running;
+ int _pollWait; // poll timeout in msec (-1 = infinite)
+ int sendSerialNo; // debug
+
+ pthread_t thread;
+
+ int toThreadFdw; // message to thread (app write)
+
+ PollList plist;
+ void* userPtr;
+
+ protected:
+ int realTimePriority;
+ int fromThreadFdr; // message from thread (seq read)
+ int fromThreadFdw; // message from thread (app write)
+ int toThreadFdr; // message to thread (seq read)
+ struct pollfd* pfd; // poll file descriptors
+ int npfd;
+ int maxpfd;
+ virtual void processMsg(const ThreadMsg*) {}
+ virtual void processMsg1(const void *) {}
+ virtual void defaultTick() {}
+
+ public:
+ Thread(const char* name);
+ virtual ~Thread();
+ const char* name() const { return _name; }
+ virtual void start(int priority, void* ptr=0);
+ void stop(bool);
+ void clearPollFd() { plist.clear(); npfd = 0; }
+ void addPollFd(int fd, int action, void (*handler)(void*,void*), void*, void*);
+ void removePollFd(int fd, int action);
+ void loop();
+ void readMsg();
+ void readMsg1(int size);
+ bool sendMsg1(const void* m, int n);
+ bool sendMsg(const ThreadMsg* m);
+ bool isRunning() const { return _running; }
+ void setPollWait(int val) { _pollWait = val; }
+ virtual void threadStart(void*){ } // called from loop
+ virtual void threadStop() { } // called from loop before leaving
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/ticksynth.cpp b/muse_qt4_evolution/muse/ticksynth.cpp
new file mode 100644
index 00000000..861861de
--- /dev/null
+++ b/muse_qt4_evolution/muse/ticksynth.cpp
@@ -0,0 +1,181 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "audio.h"
+#include "ticksynth.h"
+#include "default_click.h"
+
+SynthI* metronome = 0;
+
+class MetronomeSynth;
+static MetronomeSynth* metronomeSynth;
+
+//---------------------------------------------------------
+// MetronomeSynth
+//---------------------------------------------------------
+
+class MetronomeSynth : public Synth {
+ public:
+ MetronomeSynth(const QFileInfo* fi) : Synth(fi, QString("Metronome")) {}
+ virtual ~MetronomeSynth() {}
+ virtual void incInstances(int) {}
+ virtual void* instantiate();
+ virtual SynthIF* createSIF(SynthI*);
+ };
+
+//---------------------------------------------------------
+// instantiate
+//---------------------------------------------------------
+
+void* MetronomeSynth::instantiate()
+ {
+ return 0;
+ }
+
+//---------------------------------------------------------
+// MetronomeSynthIF
+//---------------------------------------------------------
+
+class MetronomeSynthIF : public SynthIF
+ {
+ const float* data;
+ int pos;
+ int len;
+ void process(float** buffer, int offset, int n);
+
+ public:
+ MetronomeSynthIF(SynthI* s) : SynthIF(s) {
+ data = 0;
+ }
+ virtual bool guiVisible() const { return false; }
+ virtual void showGui(bool) {}
+ virtual bool hasGui() const { return false; }
+ virtual void getGeometry(int*, int*, int*, int*) const {}
+ virtual void setGeometry(int, int, int, int) {}
+ virtual void getData(MidiEventList*, unsigned pos, int ports, unsigned n, float** buffer);
+ virtual bool putEvent(const MidiEvent& ev);
+ virtual MidiEvent receiveEvent() { return MidiEvent(); }
+ virtual int eventsPending() const { return 0; }
+ virtual int channels() const { return 1; }
+ virtual void deactivate2() {}
+ virtual void deactivate3() {}
+ virtual QString getPatchName(int, int, int) const { return ""; }
+ virtual QString getPatchName(int, int) { return ""; }
+ virtual void populatePatchPopup(QMenu*, int) {};
+ virtual void write(Xml&) const {}
+ virtual void setParameter(int, float) {}
+ virtual int getControllerInfo(int, const char**, int*, int*, int*) { return 0; }
+ virtual bool hasAuxSend() const { return false; }
+ };
+
+//---------------------------------------------------------
+// getData
+//---------------------------------------------------------
+
+void MetronomeSynthIF::getData(MidiEventList* el, unsigned pos, int/*ports*/, unsigned n, float** buffer)
+ {
+ unsigned curPos = pos;
+ unsigned endPos = pos + n;
+ unsigned off = pos;
+
+ iMidiEvent i = el->begin();
+ for (; i != el->end(); ++i) {
+ unsigned frame = i->time();
+ if (frame >= endPos)
+ break;
+ if (frame > curPos) {
+ if (frame < pos)
+ printf("should not happen: missed event %d\n", pos -frame);
+ else
+ process(buffer, curPos-pos, frame - curPos);
+ curPos = frame;
+ }
+ putEvent(*i);
+ }
+ if (endPos - curPos)
+ process(buffer, curPos - off, endPos - curPos);
+ el->erase(el->begin(), i);
+ }
+
+//---------------------------------------------------------
+// putEvent
+//---------------------------------------------------------
+
+bool MetronomeSynthIF::putEvent(const MidiEvent& ev)
+ {
+ if (ev.dataA() == 0) {
+ data = defaultClickEmphasis;
+ len = defaultClickEmphasisLength;
+ }
+ else {
+ data = defaultClick;
+ len = defaultClickLength;
+ }
+ pos = 0;
+ return false;
+ }
+
+//---------------------------------------------------------
+// createSIF
+//---------------------------------------------------------
+
+SynthIF* MetronomeSynth::createSIF(SynthI* s)
+ {
+ return new MetronomeSynthIF(s);
+ }
+
+//---------------------------------------------------------
+// process
+// synthesize n samples into buffer+offset
+//---------------------------------------------------------
+
+void MetronomeSynthIF::process(float** buffer, int offset, int n)
+ {
+ if (data == 0) {
+ memset(buffer[0], 0, n * sizeof(float));
+ return;
+ }
+ const float* s = data + pos;
+ float* d = *buffer + offset;
+ int l = std::min(n, len);
+ int i;
+ for (i = 0; i < l; ++i)
+ *d++ = *s++;
+ for (; i < n; ++i)
+ *d++ = 0.0f;
+ pos += l;
+ len -= l;
+ if (len <= 0)
+ data = 0;
+ }
+
+//---------------------------------------------------------
+// initMetronome
+//---------------------------------------------------------
+
+void initMetronome()
+ {
+ QFileInfo fi; // dummy
+ metronomeSynth = new MetronomeSynth(&fi);
+ metronome = new SynthI();
+ metronome->setName("metronome");
+ metronome->initInstance(metronomeSynth);
+ }
+
diff --git a/muse_qt4_evolution/muse/ticksynth.h b/muse_qt4_evolution/muse/ticksynth.h
new file mode 100644
index 00000000..d18a483d
--- /dev/null
+++ b/muse_qt4_evolution/muse/ticksynth.h
@@ -0,0 +1,29 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __TICKSYNTH_H__
+#define __TICKSYNTH_H__
+
+#include "synth.h"
+extern void initMetronome();
+extern SynthI* metronome;
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/tllineedit.cpp b/muse_qt4_evolution/muse/tllineedit.cpp
new file mode 100644
index 00000000..0581b858
--- /dev/null
+++ b/muse_qt4_evolution/muse/tllineedit.cpp
@@ -0,0 +1,70 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "tllineedit.h"
+
+//---------------------------------------------------------
+// TLLineEdit
+//---------------------------------------------------------
+
+TLLineEdit::TLLineEdit(const QString& contents, QWidget* parent)
+ : QLineEdit(contents, parent)
+ {
+ setReadOnly(true);
+ setFrame(false);
+ setAlignment(Qt::AlignLeft);
+ setCursorPosition(0);
+ connect(this, SIGNAL(editingFinished()), SLOT(contentHasChanged()));
+ }
+
+//---------------------------------------------------------
+// contentHasChanged
+//---------------------------------------------------------
+
+void TLLineEdit::contentHasChanged()
+ {
+ setReadOnly(true);
+ setFrame(false);
+ if (isModified())
+ emit contentChanged(text());
+ setModified(false);
+ }
+
+//---------------------------------------------------------
+// mouseDoubleClickEvent
+//---------------------------------------------------------
+
+void TLLineEdit::mouseDoubleClickEvent(QMouseEvent*)
+ {
+ setReadOnly(false);
+ setFocus();
+ setFrame(true);
+ }
+
+//---------------------------------------------------------
+// mousePressEvent
+//---------------------------------------------------------
+
+void TLLineEdit::mousePressEvent(QMouseEvent* ev)
+ {
+ QLineEdit::mousePressEvent(ev);
+ emit mousePress();
+ }
+
diff --git a/muse_qt4_evolution/muse/tllineedit.h b/muse_qt4_evolution/muse/tllineedit.h
new file mode 100644
index 00000000..56bfdd55
--- /dev/null
+++ b/muse_qt4_evolution/muse/tllineedit.h
@@ -0,0 +1,48 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __TLLINEEDIT_H__
+#define __TLLINEEDIT_H__
+
+//---------------------------------------------------------
+// TLLineEdit
+//---------------------------------------------------------
+
+class TLLineEdit : public QLineEdit {
+ Q_OBJECT
+
+ virtual void mouseDoubleClickEvent(QMouseEvent*);
+ virtual void mousePressEvent(QMouseEvent*);
+
+ private slots:
+ void contentHasChanged();
+
+ signals:
+ void contentChanged(QString s);
+ void mousePress();
+
+ public:
+ TLLineEdit(const QString& contents, QWidget* parent = 0);
+ };
+
+#endif
+
+
+
diff --git a/muse_qt4_evolution/muse/tlswidget.cpp b/muse_qt4_evolution/muse/tlswidget.cpp
new file mode 100644
index 00000000..23b7fbc1
--- /dev/null
+++ b/muse_qt4_evolution/muse/tlswidget.cpp
@@ -0,0 +1,355 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "song.h"
+#include "track.h"
+#include "tlswidget.h"
+#include "tlwlayout.h"
+#include "icons.h"
+#include "arranger.h"
+#include "widgets/simplebutton.h"
+#include "muse.h"
+#include "ctrl/configmidictrl.h"
+#include "ctrl/ctrldialog.h"
+#include "midictrl.h"
+#include "widgets/utils.h"
+
+//---------------------------------------------------------
+// TLSLayout
+//---------------------------------------------------------
+
+class TLSLayout : public QLayout {
+ QList<QLayoutItem*> itemList;
+
+ public:
+ TLSLayout() {}
+ ~TLSLayout();
+
+ void addItem(QLayoutItem* item);
+ void insertWidget(int index, QWidget* item);
+ Qt::Orientations expandingDirections() const { return 0; }
+ bool hasHeightForWidth() const { return false; }
+ int count() const { return itemList.size(); }
+ void setGeometry(const QRect &rect);
+ QSize sizeHint() const { return ((QWidget*)parent())->size(); }
+ QLayoutItem *itemAt(int index) const { return itemList.value(index); }
+ QLayoutItem *takeAt(int idx) {
+ return idx >= 0 && idx < itemList.size() ? itemList.takeAt(idx) : 0;
+ }
+ };
+
+//---------------------------------------------------------
+// TLSLayout
+//---------------------------------------------------------
+
+TLSLayout::~TLSLayout()
+ {
+ QLayoutItem* child;
+ while ((child = takeAt(0)) != 0)
+ delete child;
+ }
+
+//---------------------------------------------------------
+// insertWidget
+//---------------------------------------------------------
+
+void TLSLayout::insertWidget(int index, QWidget* item)
+ {
+ if (item->parent() == 0)
+ item->setParent((QWidget*)parent());
+ itemList.insert(index, new QWidgetItem(item));
+ update();
+ }
+
+//---------------------------------------------------------
+// addItem
+//---------------------------------------------------------
+
+void TLSLayout::addItem(QLayoutItem* item)
+ {
+ itemList.append(item);
+ update();
+ }
+
+//---------------------------------------------------------
+// setGeometry
+//---------------------------------------------------------
+
+void TLSLayout::setGeometry(const QRect& rect)
+ {
+ static const int labelWidth = 50;
+ int x1 = rect.x() + labelWidth;
+ int y = rect.y();
+ int y2 = y + rect.height();
+
+ QLayoutItem *item = itemList.at(0);
+ QSize size(item->sizeHint());
+ item->widget()->setGeometry(QRect(x1 - 18, y2 - 18-splitWidth, 18, 18));
+
+ item = itemList.at(1);
+ size = item->sizeHint();
+ item->setGeometry(QRect(x1, rect.y(),
+ rect.width() - x1 - 2, trackRowHeight));
+ }
+
+//---------------------------------------------------------
+// TLSWidget
+//---------------------------------------------------------
+
+TLSWidget::TLSWidget(Track* t, ArrangerTrack* atrack, TimeCanvas* timeC)
+ {
+ setAttribute(Qt::WA_NoBackground);
+ setAttribute(Qt::WA_StaticContents);
+ setAutoFillBackground(true);
+
+ setMouseTracking(true);
+ _tc = timeC;
+ state = S_NORMAL;
+
+ at = atrack;
+ _track = t;
+ _ctrlTrack = t;
+
+ TLSLayout* l = new TLSLayout;
+ setLayout(l);
+ //
+ // track type
+ //
+ SimpleButton* minus = newMinusButton();
+ minus->setToolTip(tr("Remove Subtrack"));
+ l->addWidget(minus);
+
+ ctrlList = new QToolButton;
+ ctrlList->setText(tr("Ctrl"));
+
+ connect(ctrlList, SIGNAL(clicked()), SLOT(showControllerList()));
+
+ l->addWidget(ctrlList);
+ ctrlList->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+
+ connect(_track, SIGNAL(selectionChanged(bool)), SLOT(selectionChanged()));
+ connect(_track, SIGNAL(controllerChanged(int)), SLOT(controllerListChanged(int)));
+ connect(_track, SIGNAL(autoReadChanged(bool)), SLOT(autoReadChanged()));
+ connect(muse, SIGNAL(configChanged()), SLOT(configChanged()));
+ connect(minus, SIGNAL(clicked()), SLOT(labelMinusClicked()));
+ configChanged();
+ }
+
+//---------------------------------------------------------
+// ctrl
+//---------------------------------------------------------
+
+Ctrl* TLSWidget::ctrl() const
+ {
+ return at->controller;
+ }
+
+//---------------------------------------------------------
+// height
+//---------------------------------------------------------
+
+int TLSWidget::cheight() const
+ {
+ return at->tw->height() - splitWidth;
+ }
+
+//---------------------------------------------------------
+// selectionChanged
+//---------------------------------------------------------
+
+void TLSWidget::selectionChanged()
+ {
+// setFrameShadow(_track->selected() ? QFrame::Sunken : QFrame::Raised);
+ }
+
+//---------------------------------------------------------
+// configChanged
+//---------------------------------------------------------
+
+void TLSWidget::configChanged()
+ {
+ QColor c(_track->ccolor());
+ QPalette p(palette());
+ p.setColor(QPalette::Background, c.light(100));
+ setPalette(p);
+ }
+
+//---------------------------------------------------------
+// showControllerList
+//---------------------------------------------------------
+
+bool TLSWidget::showControllerList()
+ {
+ Ctrl* c = ctrl();
+ int id;
+ if (c)
+ id = c->id();
+ else
+ id = CTRL_NO_CTRL;
+ for (;;) {
+ CtrlDialog cd(_ctrlTrack, id);
+ int rv = cd.exec();
+ if (rv != 1)
+ return false;
+ id = cd.curId();
+ if (id == CTRL_NO_CTRL)
+ return false;
+ if (id != CTRL_OTHER)
+ break;
+ ConfigMidiCtrl* mce = new ConfigMidiCtrl((MidiTrack*)_track);
+ mce->exec();
+ delete mce;
+ }
+ setCtrl(id);
+ return true;
+ }
+
+//---------------------------------------------------------
+// setCtrl
+//---------------------------------------------------------
+
+bool TLSWidget::setCtrl(int ctrl)
+ {
+ if (ctrl == CTRL_NO_CTRL || ctrl == CTRL_OTHER) {
+ // this controller subtrack is new, ask user for
+ // controller:
+ return showControllerList();
+ }
+
+ if (_ctrlTrack && _ctrlTrack != _track) {
+ disconnect(_ctrlTrack, SIGNAL(controllerChanged(int)), this, SLOT(controllerListChanged(int)));
+ }
+ if (ctrl == CTRL_VELOCITY) {
+ at->controller = &veloList;
+ at->ctrl = CTRL_VELOCITY;
+ ctrlList->setText(tr("Velocity"));
+ _ctrlTrack = _track;
+ emit controllerChanged(at->ctrl);
+ }
+ else {
+ at->ctrl = ctrl;
+ at->controller = _track->getController(ctrl);
+ if (at->controller) {
+ _ctrlTrack = _track;
+ ctrlList->setText(at->controller->name());
+ emit controllerChanged(ctrl);
+ }
+ }
+ return true;
+ }
+
+//---------------------------------------------------------
+// labelMinusClicked
+//---------------------------------------------------------
+
+void TLSWidget::labelMinusClicked()
+ {
+ emit minusClicked(this);
+ }
+
+//---------------------------------------------------------
+// mousePressEvent
+//---------------------------------------------------------
+
+void TLSWidget::mousePressEvent(QMouseEvent* ev)
+ {
+ if (ev->button() == Qt::RightButton) {
+ QMenu* menu = new QMenu(this);
+ QAction* a = menu->addAction(tr("Delete Controller"));
+ a->setData(0);
+ QAction* rv = menu->exec(ev->globalPos());
+ if (rv == 0)
+ return;
+ emit minusClicked(this);
+ return;
+ }
+ song->selectTrack(_track);
+
+ int y = ev->pos().y();
+ int wh = height();
+ starty = ev->globalPos().y();
+ if (y > (wh - splitWidth)) {
+ state = S_DRAGBOTTOM;
+ emit startDrag(trackIdx);
+ }
+ }
+
+//---------------------------------------------------------
+// mouseReleaseEvent
+//---------------------------------------------------------
+
+void TLSWidget::mouseReleaseEvent(QMouseEvent*)
+ {
+ state = S_NORMAL;
+ }
+
+//---------------------------------------------------------
+// mouseMoveEvent
+//---------------------------------------------------------
+
+void TLSWidget::mouseMoveEvent(QMouseEvent* ev)
+ {
+ QPoint pos(ev->pos());
+
+ if (state == S_DRAGTOP)
+ emit drag(trackIdx-1, ev->globalPos().y() - starty);
+ else if (state == S_DRAGBOTTOM)
+ emit drag(trackIdx, ev->globalPos().y() - starty);
+ else {
+ int y = pos.y();
+ int wh = height();
+ if (y > (wh - splitWidth))
+ setCursor(Qt::SizeVerCursor);
+ else
+ setCursor(Qt::ArrowCursor);
+ }
+ }
+
+//---------------------------------------------------------
+// controllerListChanged
+// controller list for controller id changed
+//---------------------------------------------------------
+
+void TLSWidget::controllerListChanged(int id)
+ {
+ if (ctrl()->id() == id)
+ tc()->widget()->update();
+ }
+
+//---------------------------------------------------------
+// autoReadChanged
+//---------------------------------------------------------
+
+void TLSWidget::autoReadChanged()
+ {
+ tc()->widget()->update();
+ }
+
+//---------------------------------------------------------
+// paintEvent
+//---------------------------------------------------------
+
+void TLSWidget::paintEvent(QPaintEvent* ev)
+ {
+ QPainter p(this);
+ QRect r(ev->rect());
+ p.fillRect(r, _track->ccolor());
+ paintHLine(p, r.x(), r.x() + r.width(), height() - splitWidth);
+ }
diff --git a/muse_qt4_evolution/muse/tlswidget.h b/muse_qt4_evolution/muse/tlswidget.h
new file mode 100644
index 00000000..ccdfa3b8
--- /dev/null
+++ b/muse_qt4_evolution/muse/tlswidget.h
@@ -0,0 +1,83 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __TLSWIDGET_H__
+#define __TLSWIDGET_H__
+
+class Track;
+class ArrangerTrack;
+class CtrlDialog;
+class TimeCanvas;
+
+#include "ctrl/ctrleditor.h"
+
+//---------------------------------------------------------
+// TLSWidget
+//---------------------------------------------------------
+
+class TLSWidget : public QWidget, public CtrlEditor {
+ Q_OBJECT
+
+ enum { S_NORMAL, S_DRAGTOP, S_DRAGBOTTOM, S_DRAG };
+ int state;
+
+ int trackIdx;
+ int starty;
+ Track* _track; // editor canvas is associated to this track
+ Track* _ctrlTrack; // track were ctrl belongs to
+ TimeCanvas* _tc;
+ QToolButton* ctrlList;
+ QLineEdit* nameEdit;
+ ArrangerTrack* at;
+
+ TimeCanvas* tc() const { return _tc; }
+ Ctrl* ctrl() const;
+ int cheight() const;
+
+ virtual void paintEvent(QPaintEvent*);
+ virtual void mousePressEvent(QMouseEvent*);
+ virtual void mouseReleaseEvent(QMouseEvent*);
+ virtual void mouseMoveEvent(QMouseEvent*);
+
+ private slots:
+ void labelMinusClicked();
+ bool showControllerList();
+ void selectionChanged();
+ void configChanged();
+ void controllerListChanged(int);
+ void autoReadChanged();
+
+ signals:
+ void minusClicked(TLSWidget*);
+ void controllerChanged(int);
+ void startDrag(int idx);
+ void drag(int idx, int);
+
+ public:
+ TLSWidget(Track*, ArrangerTrack*, TimeCanvas* tc);
+ Track* track() const { return _track; }
+ Track* ctrlTrack() const { return _ctrlTrack; }
+ bool setCtrl(int ctrl);
+ void setIdx(int n) { trackIdx = n; }
+ };
+
+#endif
+
+
diff --git a/muse_qt4_evolution/muse/tlwidget.cpp b/muse_qt4_evolution/muse/tlwidget.cpp
new file mode 100644
index 00000000..fdf08d0b
--- /dev/null
+++ b/muse_qt4_evolution/muse/tlwidget.cpp
@@ -0,0 +1,641 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "song.h"
+#include "track.h"
+#include "tlwidget.h"
+#include "tlwlayout.h"
+#include "tllineedit.h"
+#include "icons.h"
+#include "arranger.h"
+#include "widgets/simplebutton.h"
+#include "muse.h"
+#include "trelement.h"
+#include "gconfig.h"
+#include "widgets/utils.h"
+#include "trackdrag.h"
+#include "synth.h"
+#include "widgets/outportcombo.h"
+#include "audio.h"
+#include "midioutport.h"
+#include "instruments/minstrument.h"
+
+//---------------------------------------------------------
+// TLWidget
+//---------------------------------------------------------
+
+TLWidget::TLWidget(Track* t, TrGroupList* tgl)
+ {
+ setAttribute(Qt::WA_OpaquePaintEvent);
+ setAutoFillBackground(true);
+
+ setMouseTracking(true);
+
+ state = S_NORMAL;
+ off = 0;
+ tel = tgl;
+ _track = t;
+ outPort = 0;
+
+ bgColor = _track->ccolor();
+ selectBgColor = bgColor.light();
+
+ QPalette p(palette());
+ p.setColor(QPalette::Window, bgColor);
+ p.setColor(QPalette::Base, bgColor);
+ setPalette(p);
+
+ l = new TLWidgetLayout(this);
+ configChanged();
+
+ connect(_track, SIGNAL(selectionChanged(bool)), SLOT(selectionChanged()));
+ setAcceptDrops(true);
+ connect(muse, SIGNAL(configChanged()), SLOT(configChanged()));
+ }
+
+//---------------------------------------------------------
+// selectionChanged
+//---------------------------------------------------------
+
+void TLWidget::selectionChanged()
+ {
+ update();
+ }
+
+//---------------------------------------------------------
+// nameChanged
+//---------------------------------------------------------
+
+void TLWidget::nameChanged(QString s)
+ {
+ song->changeTrackName(_track, s);
+ nameEdit->setCursorPosition(0);
+ }
+
+//---------------------------------------------------------
+// selectTL
+//---------------------------------------------------------
+
+void TLWidget::select()
+ {
+ setFocus();
+ song->selectTrack(_track);
+ }
+
+//---------------------------------------------------------
+// labelPlusClicked
+//---------------------------------------------------------
+
+void TLWidget::labelPlusClicked()
+ {
+ emit plusClicked(this);
+ }
+
+//---------------------------------------------------------
+// mousePressEvent
+//---------------------------------------------------------
+
+void TLWidget::mousePressEvent(QMouseEvent* ev)
+ {
+ enum {
+ CMD_REMOVE_TRACK, CMD_COPY_TRACK, CMD_SHOW_AUDIO_GUI,
+ CMD_SHOW_MIDI_GUI
+ };
+ int button = ev->button();
+ if (button == Qt::RightButton) {
+ QMenu* menu = new QMenu(this);
+ QAction* a = getAction("delete", this);
+ menu->addAction(a);
+ a->setData(CMD_REMOVE_TRACK);
+ if (_track->type() == Track::MIDI || _track->type() == Track::WAVE) {
+ a = menu->addAction(tr("Copy Track"));
+ a->setData(CMD_COPY_TRACK);
+ }
+ if (_track->type() == Track::AUDIO_SOFTSYNTH) {
+ SynthI* s = (SynthI*) _track;
+ if (s->hasGui()) {
+ menu->addSeparator();
+ a = menu->addAction(tr("Show Gui"));
+ a->setData(CMD_SHOW_AUDIO_GUI);
+ a->setCheckable(true);
+ a->setChecked(s->guiVisible());
+ }
+ }
+ else if (_track->type() == Track::MIDI_SYNTI) {
+ MidiSynti* s = (MidiSynti*) _track;
+ if (s->hasGui()) {
+ menu->addSeparator();
+ a = menu->addAction(tr("Show Gui"));
+ a->setData(CMD_SHOW_MIDI_GUI);
+ a->setCheckable(true);
+ a->setChecked(s->guiVisible());
+ }
+ }
+
+ a = menu->exec(ev->globalPos());
+ if (!a)
+ return;
+ int rv = a->data().toInt();
+ switch (rv) {
+ default:
+ break;
+ case CMD_REMOVE_TRACK:
+ song->removeTrack(_track);
+ break;
+ case CMD_COPY_TRACK:
+ {
+ int idx = song->tracks()->indexOf(_track);
+ if (_track->type() == Track::MIDI) {
+ MidiTrack* t = new MidiTrack();
+ t->clone((MidiTrack*)_track);
+ song->cmdInsertTrack(t, idx);
+ }
+ else {
+ WaveTrack* t = new WaveTrack();
+ t->clone((WaveTrack*)_track);
+ song->cmdInsertTrack(t, idx);
+ }
+ }
+ break;
+ case CMD_SHOW_AUDIO_GUI:
+ {
+ SynthI* s = (SynthI*) _track;
+ s->showGui(!s->guiVisible());
+ }
+ break;
+ case CMD_SHOW_MIDI_GUI:
+ {
+ MidiSynti* s = (MidiSynti*) _track;
+ s->showGui(!s->guiVisible());
+ }
+ break;
+ }
+ return;
+ }
+ int y = ev->pos().y();
+ int wh = height();
+ starty = ev->globalPos().y();
+ if (y > (wh - splitWidth)) {
+ state = S_DRAGBOTTOM;
+ emit startDrag(trackIdx);
+ }
+ else {
+ state = S_DRAG;
+ startDragPos = ev->pos();
+ startDragTime = QTime::currentTime();
+ select();
+ }
+ }
+
+//---------------------------------------------------------
+// mouseReleaseEvent
+//---------------------------------------------------------
+
+void TLWidget::mouseReleaseEvent(QMouseEvent*)
+ {
+ state = S_NORMAL;
+ }
+
+//---------------------------------------------------------
+// mouseMoveEvent
+//---------------------------------------------------------
+
+void TLWidget::mouseMoveEvent(QMouseEvent* ev)
+ {
+ QPoint pos(ev->pos());
+
+ if (state == S_DRAGBOTTOM)
+ emit drag(trackIdx, ev->globalPos().y() - starty);
+ else if (state == S_DRAG) {
+ int t = startDragTime.msecsTo(QTime::currentTime());
+ bool dragActive = (startDragPos - pos).manhattanLength() >
+ QApplication::startDragDistance()
+ || t > QApplication::startDragTime();
+ if (dragActive) {
+ QDrag* d = new TrackDrag(_track, this);
+ d->start(Qt::MoveAction);
+ state = S_NORMAL;
+ }
+ }
+ else {
+ int y = pos.y();
+ int wh = height();
+ if (y > (wh - splitWidth))
+ setCursor(Qt::SizeVerCursor);
+ else
+ setCursor(Qt::ArrowCursor);
+ }
+ }
+
+//---------------------------------------------------------
+// configChanged
+//---------------------------------------------------------
+
+void TLWidget::configChanged()
+ {
+ l->clear();
+ wlist.clear();
+ nameEdit = 0;
+ record = 0;
+ off = 0;
+ outChannel = 0;
+ outPort = 0;
+
+ label = new QLabel;
+ label->setObjectName("trackLabel");
+ l->addWidget(label);
+ label->setIndent(3);
+
+ label->setText(_track->cname());
+ label->setFixedHeight(11);
+
+ plus = newPlusButton();
+ l->addWidget(plus);
+ plus->setToolTip(tr("Add Subtrack"));
+ connect(plus, SIGNAL(clicked()), SLOT(labelPlusClicked()));
+
+ for (iTrGroup i = tel->begin(); i != tel->end(); ++i) {
+ TrElementList& el = *i;
+ iTrElement k;
+ for (k = el.begin(); k != el.end(); ++k) {
+ int id = (*k)->id;
+ switch(id) {
+ case TR_NAME:
+ nameEdit = new TLLineEdit(_track->name(), this);
+ nameEdit->setFixedHeight(trackRowHeight);
+ connect(nameEdit, SIGNAL(contentChanged(QString)), SLOT(nameChanged(QString)));
+ connect(nameEdit, SIGNAL(mousePress()), SLOT(select()));
+ connect(_track, SIGNAL(nameChanged(const QString&)), nameEdit, SLOT(setText(const QString&)));
+ nameEdit->setToolTip(_track->clname() + " Name");
+ l->addWidget(nameEdit);
+ wlist.push_back(nameEdit);
+ break;
+
+ case TR_INSTRUMENT:
+ {
+ instrument = new QComboBox(this);
+ instrument->setFixedHeight(trackRowHeight);
+ MidiOutPort* op = (MidiOutPort*)_track;
+ MidiInstrument* mi = op->instrument();
+ int idx = 0;
+ int curIdx = 0;
+ for (iMidiInstrument i = midiInstruments.begin(); i != midiInstruments.end(); ++i, ++idx) {
+ instrument->addItem((*i)->iname());
+ if ((*i)->iname() == mi->iname())
+ curIdx = idx;
+ }
+ instrument->setCurrentIndex(curIdx);
+ connect(instrument, SIGNAL(activated(int)), SLOT(instrumentSelected(int)));
+ connect(op, SIGNAL(instrumentChanged()), SLOT(instrumentChanged()));
+ l->addWidget(instrument);
+ wlist.push_back(instrument);
+ }
+ break;
+
+ case TR_PATCH:
+ {
+ // Ctrl* ctrl = _track->getController(CTRL_PROGRAM);
+ }
+ break;
+
+ case TR_OFF:
+ {
+ off = newOffButton();
+ off->setFixedSize(trackRowHeight, trackRowHeight);
+ off->setChecked(_track->off());
+ connect(off, SIGNAL(clicked(bool)), SLOT(offToggled(bool)));
+ connect(_track, SIGNAL(offChanged(bool)), this, SLOT(updateOffState()));
+ l->addWidget(off);
+ wlist.push_back(off);
+ }
+ break;
+
+ case TR_DRUMMAP:
+ {
+ SimpleButton* dm = newDrumMapButton();
+ dm->setFixedSize(trackRowHeight, trackRowHeight);
+ dm->setChecked(((MidiTrack*)_track)->useDrumMap());
+ connect(dm, SIGNAL(clicked(bool)), SLOT(drumMapToggled(bool)));
+ connect(_track, SIGNAL(useDrumMapChanged(bool)), dm, SLOT(setChecked(bool)));
+ l->addWidget(dm);
+ wlist.push_back(dm);
+ }
+ break;
+
+ case TR_MUTE:
+ {
+ SimpleButton* mute = newMuteButton();
+ mute->setFixedSize(trackRowHeight, trackRowHeight);
+ mute->setChecked(_track->isMute());
+ connect(mute, SIGNAL(clicked(bool)), SLOT(muteToggled(bool)));
+ connect(_track, SIGNAL(muteChanged(bool)), mute, SLOT(setChecked(bool)));
+ l->addWidget(mute);
+ wlist.push_back(mute);
+ }
+ break;
+
+ case TR_SOLO:
+ {
+ SimpleButton* solo = newSoloButton();
+ solo->setFixedSize(trackRowHeight, trackRowHeight);
+ solo->setChecked(_track->solo());
+ connect(solo, SIGNAL(clicked(bool)), SLOT(soloToggled(bool)));
+ connect(_track, SIGNAL(soloChanged(bool)), solo, SLOT(setChecked(bool)));
+ l->addWidget(solo);
+ wlist.push_back(solo);
+ }
+ break;
+
+ case TR_MONITOR:
+ {
+ SimpleButton* monitor = newMonitorButton();
+ monitor->setFixedSize(trackRowHeight+4, trackRowHeight);
+ monitor->setChecked(_track->monitor());
+ connect(monitor, SIGNAL(clicked(bool)), SLOT(monitorToggled(bool)));
+ connect(_track, SIGNAL(monitorChanged(bool)), monitor, SLOT(setChecked(bool)));
+ l->addWidget(monitor);
+ wlist.push_back(monitor);
+ }
+ break;
+
+ case TR_RECORD:
+ {
+ record = newRecordButton();
+ record->setFixedSize(trackRowHeight, trackRowHeight);
+ record->setChecked(_track->recordFlag());
+ connect(record, SIGNAL(clicked(bool)), SLOT(recordToggled(bool)));
+ connect(_track, SIGNAL(recordChanged(bool)), record, SLOT(setChecked(bool)));
+ l->addWidget(record);
+ wlist.push_back(record);
+ }
+ break;
+
+ case TR_AREAD:
+ {
+ SimpleButton* b = newAutoReadButton();
+ b->setFixedSize(trackRowHeight, trackRowHeight);
+ b->setChecked(_track->autoRead());
+ connect(b, SIGNAL(clicked(bool)), SLOT(autoReadToggled(bool)));
+ connect(_track, SIGNAL(autoReadChanged(bool)), b, SLOT(setChecked(bool)));
+ l->addWidget(b);
+ wlist.push_back(b);
+ }
+ break;
+
+ case TR_AWRITE:
+ {
+ SimpleButton* b = newAutoWriteButton();
+ b->setFixedSize(trackRowHeight, trackRowHeight);
+ b->setChecked(_track->autoWrite());
+ connect(b, SIGNAL(clicked(bool)), SLOT(autoWriteToggled(bool)));
+ connect(_track, SIGNAL(autoWriteChanged(bool)), b, SLOT(setChecked(bool)));
+ l->addWidget(b);
+ wlist.push_back(b);
+ }
+ break;
+
+ case TR_OCHANNEL:
+ {
+ outChannel = new QSpinBox(this);
+ outChannel->setFixedSize(45, trackRowHeight);
+ outChannel->setRange(1, 16);
+ outChannel->setValue(((MidiTrack*)_track)->channelNo() + 1);
+ outChannel->setToolTip(tr("Midi Output Channel"));
+ l->addWidget(outChannel);
+ wlist.push_back(outChannel);
+ connect(outChannel, SIGNAL(valueChanged(int)), SLOT(setChannel(int)));
+ connect((MidiTrack*)_track, SIGNAL(channelChanged(int)), SLOT(channelChanged(int)));
+ }
+ break;
+
+ default:
+ printf("TLWidget:: unknown element %d\n", id);
+ break;
+ }
+ }
+ }
+ updateOffState();
+ selectionChanged(); // update selection state
+ l->update();
+ }
+
+//---------------------------------------------------------
+// recordToggled
+//---------------------------------------------------------
+
+void TLWidget::recordToggled(bool val)
+ {
+ song->setRecordFlag(_track, !val);
+ }
+
+//---------------------------------------------------------
+// muteToggled
+//---------------------------------------------------------
+
+void TLWidget::muteToggled(bool val)
+ {
+ song->setMute(_track, val);
+ }
+
+//---------------------------------------------------------
+// monitorToggled
+//---------------------------------------------------------
+
+void TLWidget::monitorToggled(bool val)
+ {
+ _track->setMonitor(val);
+ }
+
+//---------------------------------------------------------
+// drumMapToggled
+//---------------------------------------------------------
+
+void TLWidget::drumMapToggled(bool val)
+ {
+ ((MidiTrack*)_track)->setUseDrumMap(val);
+ }
+
+//---------------------------------------------------------
+// offToggled
+//---------------------------------------------------------
+
+void TLWidget::offToggled(bool val)
+ {
+ song->setOff(_track, !val);
+ }
+
+//---------------------------------------------------------
+// soloToggled
+//---------------------------------------------------------
+
+void TLWidget::soloToggled(bool val)
+ {
+ song->setSolo(_track, val);
+ }
+
+//---------------------------------------------------------
+// autoReadToggled
+//---------------------------------------------------------
+
+void TLWidget::autoReadToggled(bool val)
+ {
+ song->setAutoRead(_track, val);
+ }
+
+//---------------------------------------------------------
+// autoWriteToggled
+//---------------------------------------------------------
+
+void TLWidget::autoWriteToggled(bool val)
+ {
+ song->setAutoWrite(_track, val);
+ }
+
+//---------------------------------------------------------
+// setOutPort
+//---------------------------------------------------------
+
+void TLWidget::setOutPort(int n)
+ {
+ outPort->setCurrentIndex(n);
+ }
+
+//---------------------------------------------------------
+// dragEnterEvent
+//---------------------------------------------------------
+
+void TLWidget::dragEnterEvent(QDragEnterEvent* event)
+ {
+ if (TrackDrag::canDecode(event))
+ event->acceptProposedAction();
+ }
+
+//---------------------------------------------------------
+// dropEvent
+//---------------------------------------------------------
+
+void TLWidget::dropEvent(QDropEvent* event)
+ {
+ Track* t;
+ TrackDrag::decode(event, t);
+ if (_track != t)
+ emit moveTrack(t, _track);
+ event->acceptProposedAction();
+ }
+
+//---------------------------------------------------------
+// updateOffState
+//---------------------------------------------------------
+
+void TLWidget::updateOffState()
+ {
+ bool val = !_track->off();
+ std::vector<QWidget*>::iterator i = wlist.begin();
+ for (; i != wlist.end(); ++i) {
+ if ((*i) != off)
+ (*i)->setEnabled(val);
+ }
+ if (off)
+ off->setChecked(!val);
+ }
+
+//---------------------------------------------------------
+// instrumentSelected
+//---------------------------------------------------------
+
+void TLWidget::instrumentSelected(int n)
+ {
+ MidiOutPort* op = (MidiOutPort*)_track;
+ int idx = 0;
+ for (iMidiInstrument i = midiInstruments.begin(); i != midiInstruments.end(); ++i, ++idx) {
+ if (idx == n) {
+ op->setInstrument(*i);
+ break;
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// instrumentChanged
+//---------------------------------------------------------
+
+void TLWidget::instrumentChanged()
+ {
+ MidiOutPort* op = (MidiOutPort*)_track;
+ MidiInstrument* mi = op->instrument();
+ int idx = 0;
+ for (iMidiInstrument i = midiInstruments.begin(); i != midiInstruments.end(); ++i, ++idx) {
+ if (*i == mi) {
+ instrument->setCurrentIndex(idx);
+ break;
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// paintEvent
+//---------------------------------------------------------
+
+void TLWidget::paintEvent(QPaintEvent* ev)
+ {
+ QPainter p(this);
+ QRect r(ev->rect());
+ QColor color(_track->selected() ? selectBgColor : bgColor);
+ p.fillRect(r, color);
+
+ paintHLine(p, r.x(), r.x() + r.width(), height() - splitWidth);
+ QPalette pl = nameEdit->palette();
+ pl.setColor(QPalette::Window, color);
+ pl.setColor(QPalette::Base, color);
+ nameEdit->setPalette(pl);
+
+ // The selected track will get a 4 pixel red bar to the left
+ if ( _track->selected()) {
+ QColor color(200,10,10);
+ QRect qr(0, 0, 4, r.height()-splitWidth);
+ p.fillRect(qr, color);
+ }
+ }
+
+//---------------------------------------------------------
+// channelChanged
+// SLOT: callend when channel routing of track has
+// changed
+// - channel starts counting at 0
+//---------------------------------------------------------
+
+void TLWidget::channelChanged(int channel)
+ {
+ if (outChannel->value() == channel + 1)
+ return;
+ outChannel->setValue(channel + 1);
+ }
+
+//---------------------------------------------------------
+// setChannel
+// - called when channel spinbox value changed
+// - channel starts counting at 1
+//---------------------------------------------------------
+
+void TLWidget::setChannel(int channel)
+ {
+ ((MidiTrack*)_track)->setChannel(channel - 1);
+ }
+
diff --git a/muse_qt4_evolution/muse/tlwidget.h b/muse_qt4_evolution/muse/tlwidget.h
new file mode 100644
index 00000000..fbe428e2
--- /dev/null
+++ b/muse_qt4_evolution/muse/tlwidget.h
@@ -0,0 +1,105 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __TLWIDGET_H__
+#define __TLWIDGET_H__
+
+class Track;
+class TrGroupList;
+class TLWidgetLayout;
+class SimpleButton;
+
+//---------------------------------------------------------
+// TLWidget
+//---------------------------------------------------------
+
+class TLWidget : public QWidget {
+ Q_OBJECT
+
+ enum { S_NORMAL, S_DRAGBOTTOM, S_DRAG };
+ int state;
+
+ int trackIdx;
+ int starty;
+ Track* _track;
+ QColor bgColor;
+ QColor selectBgColor;
+
+ QLineEdit* nameEdit;
+ TLWidgetLayout* l;
+ TrGroupList* tel;
+ QSpinBox* outChannel;
+ QComboBox* outPort;
+ SimpleButton* off;
+ SimpleButton* plus;
+ SimpleButton* record;
+ std::vector<QWidget*> wlist;
+ QComboBox* instrument;
+ QLabel* label;
+
+ QTime startDragTime;
+ QPoint startDragPos;
+
+ virtual void paintEvent(QPaintEvent*);
+ virtual void mousePressEvent(QMouseEvent*);
+ virtual void mouseReleaseEvent(QMouseEvent*);
+ virtual void mouseMoveEvent(QMouseEvent*);
+ virtual void dragEnterEvent(QDragEnterEvent*);
+ virtual void dropEvent(QDropEvent*);
+
+ signals:
+ void startDrag(int idx);
+ void drag(int idx, int);
+
+ private slots:
+ void nameChanged(QString);
+ void labelPlusClicked();
+ void configChanged();
+ void recordToggled(bool);
+ void muteToggled(bool);
+ void offToggled(bool);
+ void soloToggled(bool);
+ void monitorToggled(bool);
+ void drumMapToggled(bool);
+ void selectionChanged();
+ void setOutPort(int);
+ void autoReadToggled(bool val);
+ void autoWriteToggled(bool val);
+ void instrumentSelected(int);
+ void instrumentChanged();
+ void updateOffState();
+ void channelChanged(int);
+ void setChannel(int);
+
+ public slots:
+ void select();
+
+ signals:
+ void plusClicked(TLWidget*);
+ void moveTrack(Track* src, Track* dst);
+
+ public:
+ TLWidget(Track* t, TrGroupList*);
+ Track* track() const { return _track; }
+ void setIdx(int n) { trackIdx = n; }
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/tlwlayout.cpp b/muse_qt4_evolution/muse/tlwlayout.cpp
new file mode 100644
index 00000000..076f07cf
--- /dev/null
+++ b/muse_qt4_evolution/muse/tlwlayout.cpp
@@ -0,0 +1,144 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "tlwlayout.h"
+#include "arranger.h"
+#include "gui.h"
+
+//---------------------------------------------------------
+// TLWidgetLayout
+//---------------------------------------------------------
+
+TLWidgetLayout::TLWidgetLayout(QWidget *parent)
+ : QLayout(parent)
+ {
+ setMargin(0);
+ setSpacing(0);
+ }
+
+TLWidgetLayout::TLWidgetLayout()
+ {
+ setMargin(0);
+ setSpacing(0);
+ }
+
+//---------------------------------------------------------
+// takeAt
+//---------------------------------------------------------
+
+QLayoutItem *TLWidgetLayout::takeAt(int index)
+ {
+ if (index >= 0 && index < itemList.size())
+ return itemList.takeAt(index);
+ else
+ return 0;
+ }
+
+//---------------------------------------------------------
+// setGeometry
+//---------------------------------------------------------
+
+void TLWidgetLayout::setGeometry(const QRect &rect)
+ {
+ int n = itemList.size();
+ if (n < 2)
+ return;
+
+ static const int labelWidth = 50;
+ int x1 = rect.x() + labelWidth;
+ int x2 = rect.x() + rect.width();
+ int y = rect.y() + 1;
+ int y2 = y + rect.height() - splitWidth;
+ int dh = trackRowHeight;
+
+ QLayoutItem* item = itemList.at(0);
+ QSize size(item->sizeHint());
+ item->setGeometry(QRect(rect.x(), rect.y(), size.width(), size.height()));
+
+ item = itemList.at(1);
+ item->setGeometry(QRect(x1 - 18, y2 - 19, 18, 18));
+
+ itemList.at(2)->setGeometry(QRect(x1, y, x2-x1, dh));
+ if (n <= 3)
+ return;
+
+ y += dh;
+ if ((y + itemList.at(3)->sizeHint().height()) > y2) {
+ for (int i = 3; i < n; ++i)
+ itemList.at(i)->setGeometry(QRect(-1000, -1000, 0, 0));
+ return;
+ }
+ int x = x1;
+
+ for (int i = 3; i < n; ++i) {
+ QLayoutItem *item = itemList.at(i);
+ QSize size(item->sizeHint());
+
+ if ((x > x1) && ((x + size.width()) > x2)) {
+ x = x1;
+ y += dh;
+ if ((y + size.height()) > y2) {
+ for (; i < n; ++i)
+ itemList.at(i)->setGeometry(QRect(-1000, -1000, 0, 0));
+ return;
+ }
+ }
+ item->setGeometry(QRect(x, y, size.width(), dh));
+ x += size.width();
+ }
+ }
+
+//---------------------------------------------------------
+// sizeHint
+//---------------------------------------------------------
+
+QSize TLWidgetLayout::sizeHint() const
+ {
+ return minimumSize();
+ }
+
+//---------------------------------------------------------
+// minimumSize
+//---------------------------------------------------------
+
+QSize TLWidgetLayout::minimumSize() const
+ {
+ QSize size;
+ QLayoutItem *item;
+ foreach (item, itemList)
+ size = size.expandedTo(item->minimumSize());
+
+ size += QSize(2*margin(), 2*margin());
+ return size;
+ }
+
+//---------------------------------------------------------
+// clear
+//---------------------------------------------------------
+
+void TLWidgetLayout::clear()
+ {
+ QLayoutItem* child;
+ while ((child = takeAt(0)) != 0) {
+ delete child->widget();
+ delete child;
+ }
+ }
+
diff --git a/muse_qt4_evolution/muse/tlwlayout.h b/muse_qt4_evolution/muse/tlwlayout.h
new file mode 100644
index 00000000..1a9cc914
--- /dev/null
+++ b/muse_qt4_evolution/muse/tlwlayout.h
@@ -0,0 +1,51 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __TLWLAYOUT_H__
+#define __TLWLAYOUT_H__
+
+//---------------------------------------------------------
+// TLWidgetLayout
+//---------------------------------------------------------
+
+class TLWidgetLayout : public QLayout {
+ QList<QLayoutItem*> itemList;
+
+ int doLayout(const QRect& rect, bool testOnly) const;
+
+ public:
+ TLWidgetLayout(QWidget* parent);
+ TLWidgetLayout();
+ ~TLWidgetLayout() { clear(); }
+
+ void addItem(QLayoutItem* item) { itemList.append(item); }
+ Qt::Orientations expandingDirections() const { return 0; }
+ bool hasHeightForWidth() const { return false; }
+ int count() const { return itemList.size(); }
+ QSize minimumSize() const;
+ void setGeometry(const QRect &rect);
+ QSize sizeHint() const;
+ QLayoutItem *itemAt(int index) const { return itemList.value(index); }
+ QLayoutItem *takeAt(int index);
+ void clear();
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/track.cpp b/muse_qt4_evolution/muse/track.cpp
new file mode 100644
index 00000000..93d92ac1
--- /dev/null
+++ b/muse_qt4_evolution/muse/track.cpp
@@ -0,0 +1,1062 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "track.h"
+#include "song.h"
+#include "al/tempo.h"
+#include "al/xml.h"
+#include "icons.h"
+#include "audio.h"
+#include "gconfig.h"
+#include "midictrl.h"
+#include "part.h"
+#include "gui.h"
+#include "audiodev.h"
+
+// synchronize with TrackType!:
+
+const char* Track::_cname[] = {
+ "AudioOut", "Group", "Wave", "AudioIn",
+ "Synth", "Midi", "MidiOut", "MidiIn", "M-Synth"
+ };
+
+const char* Track::_clname[] = {
+ "Audio Output", "Audio Group", "Wave Track", "Audio Input",
+ "Synti", "Midi Track", "Midi Output", "Midi Input",
+ "Midi Synth"
+ };
+
+//---------------------------------------------------------
+// ArrangerTrack
+//---------------------------------------------------------
+
+ArrangerTrack::ArrangerTrack()
+ {
+ tw = 0;
+ ctrl = -1; // first ctrl in list
+ controller = 0;
+ h = defaultTrackHeight;
+ }
+
+//---------------------------------------------------------
+// ccolor
+// return track specific track background color
+//---------------------------------------------------------
+
+QColor Track::ccolor() const
+ {
+ return config.trackBg[type()];
+ }
+
+//---------------------------------------------------------
+// pixmap
+//---------------------------------------------------------
+
+QPixmap* Track::pixmap(TrackType t)
+ {
+ switch(t) {
+ case AUDIO_OUTPUT: return addtrack_audiooutputIcon;
+ case AUDIO_GROUP: return addtrack_audiogroupIcon;
+ case WAVE: return addtrack_wavetrackIcon;
+ case AUDIO_INPUT: return addtrack_audioinputIcon;
+ case AUDIO_SOFTSYNTH: return addtrack_audioinputIcon; // DEBUG
+ default:
+ case MIDI: return addtrack_addmiditrackIcon;
+ case MIDI_OUT: return addtrack_addmiditrackIcon;
+ case MIDI_IN: return addtrack_addmiditrackIcon;
+ }
+ }
+
+//---------------------------------------------------------
+// Track
+//---------------------------------------------------------
+
+Track::Track()
+ {
+ _tt = AL::TICKS;
+ _recordFlag = false;
+ _monitor = false;
+ _mute = false;
+ _solo = false;
+ _off = false;
+ _channels = 0; // 1 - mono, 2 - stereo
+ _selected = false;
+ _locked = false;
+ _autoRead = autoReadDefault();
+ _autoWrite = autoWriteDefault();
+
+ for (int i = 0; i < MAX_CHANNELS; ++i) {
+ _meter[i] = 0.0f;
+ _peak[i] = 0.0f;
+ _peakTimer[i] = 0;
+ }
+ _sendSync = false;
+ _deviceId = 127;
+ _parts = new PartList;
+ }
+
+//---------------------------------------------------------
+// ~Track
+//---------------------------------------------------------
+
+Track::~Track()
+ {
+ delete _parts;
+
+ for (int i = 0; i < MAX_CHANNELS; ++i) {
+// if (!_alsaPort[i].isZero())
+// midiDriver->unregisterPort(_alsaPort[i]);
+ if (!_jackPort[i].isZero())
+ audioDriver->unregisterPort(_jackPort[i]);
+ }
+
+ }
+
+//---------------------------------------------------------
+// setDefaultName
+// generate unique name for track
+//---------------------------------------------------------
+
+void Track::setDefaultName()
+ {
+ QString base;
+ switch(type()) {
+ case MIDI:
+ case WAVE:
+ base = QString("Track");
+ break;
+ case AUDIO_GROUP:
+ base = QString("Group");
+ break;
+ case AUDIO_SOFTSYNTH:
+ // base = QString("Synth");
+ return;
+ case AUDIO_OUTPUT:
+ case AUDIO_INPUT:
+ case MIDI_OUT:
+ case MIDI_IN:
+ case MIDI_SYNTI:
+ case TRACK_TYPES:
+ base = cname();
+ break;
+ };
+ //
+ // create unique name
+ //
+ for (int i = 1;; ++i) {
+ QString s;
+ if (i == 1)
+ s = base;
+ else
+ s = QString("%1 %2").arg(base).arg(i);
+ bool found = false;
+ TrackList* tl = song->tracks();
+ for (iTrack it = tl->begin(); it != tl->end(); ++it) {
+ Track* track = *it;
+ if (track->name() == s) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ setName(s);
+ break;
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// dump
+//---------------------------------------------------------
+
+void Track::dump() const
+ {
+ printf("Track <%s>: typ %d, parts %zd sel %d\n",
+ _name.toLatin1().data(), type(), _parts->size(), _selected);
+ }
+
+//---------------------------------------------------------
+// addPart
+//---------------------------------------------------------
+
+void Track::addPart(Part* p)
+ {
+ p->setTrack(this);
+ _parts->add(p);
+ }
+
+//---------------------------------------------------------
+// findPart
+//---------------------------------------------------------
+
+Part* Track::findPart(unsigned tick)
+ {
+ for (iPart i = _parts->begin(); i != _parts->end(); ++i) {
+ Part* part = i->second;
+ if (tick >= part->tick() && tick < (part->tick()+part->lenTick()))
+ return part;
+ }
+ return 0;
+ }
+
+//---------------------------------------------------------
+// Track::writeProperties
+//---------------------------------------------------------
+
+void Track::writeProperties(Xml& xml) const
+ {
+ xml.tag("name", _name);
+ if (!_comment.isEmpty())
+ xml.tag("comment", _comment);
+ if (_recordFlag)
+ xml.tag("record", _recordFlag);
+ if (mute() != muteDefault())
+ xml.tag("mute", mute());
+ if (solo())
+ xml.tag("solo", solo());
+ if (off())
+ xml.tag("off", off());
+ if (_channels)
+ xml.tag("channels", _channels);
+ if (_locked)
+ xml.tag("locked", _locked);
+ if (_monitor)
+ xml.tag("monitor", _monitor);
+ if (_autoRead != autoReadDefault())
+ xml.tag("autoRead", _autoRead);
+ if (_autoWrite != autoWriteDefault())
+ xml.tag("autoWrite", _autoWrite);
+ if (_selected)
+ xml.tag("selected", _selected);
+ for (ciCtrl icl = controller()->begin(); icl != controller()->end(); ++icl)
+ icl->second->write(xml);
+ if (arrangerTrack.tw)
+ xml.tag("height", arrangerTrack.tw->height());
+ for (ciArrangerTrack i = subtracks.begin(); i != subtracks.end(); ++i) {
+ xml.stag("subtrack");
+ xml.tag("height", (*i)->tw->height());
+ xml.tag("ctrl", (*i)->ctrl);
+ xml.etag("subtrack");
+ }
+ }
+
+//---------------------------------------------------------
+// Track::readProperties
+//---------------------------------------------------------
+
+bool Track::readProperties(QDomNode node)
+ {
+ QDomElement e = node.toElement();
+ QString tag(e.tagName());
+ QString s(e.text());
+ int i = s.toInt();
+
+ if (tag == "name")
+ setName(s);
+ else if (tag == "comment")
+ _comment = s;
+ else if (tag == "record") {
+ bool recordFlag = i;
+ setRecordFlag(recordFlag);
+ }
+ else if (tag == "mute")
+ _mute = i;
+ else if (tag == "solo")
+ _solo = i;
+ else if (tag == "off")
+ _off = i;
+ else if (tag == "channels")
+ _channels = i;
+ else if (tag == "locked")
+ _locked = i;
+ else if (tag == "monitor")
+ _monitor = i;
+ else if (tag == "selected")
+ _selected = i;
+ else if (tag == "autoRead")
+ _autoRead = i;
+ else if (tag == "autoWrite")
+ _autoWrite = i;
+ else if (tag == "controller") {
+ Ctrl* l = new Ctrl();
+ l->read(node, false);
+
+ iCtrl icl = controller()->find(l->id());
+ if (icl == controller()->end())
+ controller()->add(l);
+ else { //???
+ Ctrl* d = icl->second;
+ for (iCtrlVal i = l->begin(); i != l->end(); ++i)
+ d->insert(i.key(), i.value());
+ d->setCurVal(l->curVal());
+ d->setDefault(l->getDefault());
+ delete l;
+ }
+ }
+ else if (tag == "height")
+ arrangerTrack.h = i < minTrackHeight ? minTrackHeight : i;
+ else if (tag == "subtrack") {
+ ArrangerTrack* st = new ArrangerTrack;
+ for (QDomNode n = node.firstChild(); !n.isNull(); n = n.nextSibling()) {
+ QDomElement e = n.toElement();
+ QString tag = e.tagName();
+ QString s = e.text();
+ int i = s.toInt();
+ if (tag == "height")
+ st->h = i;
+ else if (tag == "ctrl") {
+ st->ctrl = i;
+ }
+ else
+ printf("Track::subtrack: unknown tag <%s>\n", tag.toLatin1().data());
+ }
+ subtracks.push_back(st);
+ }
+ else
+ return true;
+ return false;
+ }
+
+//---------------------------------------------------------
+// addController
+//---------------------------------------------------------
+
+void Track::addController(Ctrl* list)
+ {
+ iCtrl i = controller()->find(list->id());
+ if (i != controller()->end()) {
+ // printf("%s(%s)::addController(%s): already there 0x%x\n",
+ // cname().toLatin1().data(), name().toLatin1().data(), list->name().toLatin1().data(), list->id());
+ // abort();
+ return;
+ }
+ controller()->add(list);
+ emit clChanged();
+ }
+
+//---------------------------------------------------------
+// addMidiController
+//---------------------------------------------------------
+
+void Track::addMidiController(MidiInstrument* mi, int ctrl)
+ {
+ iCtrl cl = _controller.find(ctrl);
+ if (cl != _controller.end())
+ return;
+
+ MidiController* mc = mi->midiController(ctrl);
+ Ctrl* pvl;
+ if (mc) {
+ pvl = new Ctrl(mc);
+ }
+ else {
+ printf("unknown midi controller %x\n", ctrl);
+ pvl = new Ctrl(ctrl, QString("unknown"));
+ pvl->setCurVal(CTRL_VAL_UNKNOWN);
+ pvl->setType(Ctrl::DISCRETE | Ctrl::INT);
+ }
+ addController(pvl);
+ }
+
+//---------------------------------------------------------
+// removeController
+//---------------------------------------------------------
+
+void Track::removeController(int id)
+ {
+ iCtrl i = controller()->find(id);
+ if (i == controller()->end()) {
+ printf("Track::removeController id 0x%x not found, listsize %zd\n",
+ id, controller()->size());
+ return;
+ }
+ controller()->erase(i);
+ emit clChanged();
+ }
+
+//---------------------------------------------------------
+// changeCtrlName
+//---------------------------------------------------------
+
+void Track::changeCtrlName(Ctrl* c, const QString& s)
+ {
+ c->setName(s);
+ emit clChanged();
+ }
+
+//---------------------------------------------------------
+// addControllerVal
+// return true if new controller value added
+//---------------------------------------------------------
+
+bool Track::addControllerVal(int id, unsigned time, CVal val)
+ {
+ iCtrl i = controller()->find(id);
+ if (i == controller()->end()) {
+ if ((id & 0xf0000) == CTRL_NRPN_OFFSET) {
+ int msb = id & 0xff00;
+ // int lsb = id & 0xff;
+ int nid = CTRL_NRPN_OFFSET + msb + 0xff;
+ i = controller()->find(nid);
+ if (i != controller()->end()) {
+ Ctrl* c = new Ctrl(*(i->second));
+ c->setId(id);
+ addController(c);
+// printf("add pitch ctrl %x\n", id);
+ return c->add(time, val);
+ }
+ }
+ printf("Track::addControllerVal(): id 0x%x not found, listsize %zd\n",
+ id, controller()->size());
+ return false;
+ }
+ return i->second->add(time, val);
+ }
+
+//---------------------------------------------------------
+// removeControllerVal
+//---------------------------------------------------------
+
+void Track::removeControllerVal(int id, unsigned time)
+ {
+ iCtrl i = controller()->find(id);
+ if (i == controller()->end()) {
+ printf("Track::removeControllerVal(): id 0x%x not found, listsize %zd\n",
+ id, controller()->size());
+ return;
+ }
+ i->second->del(time);
+ }
+
+//---------------------------------------------------------
+// getController
+//---------------------------------------------------------
+
+Ctrl* Track::getController(int id) const
+ {
+ ciCtrl i = controller()->find(id);
+ if (i == controller()->end()) {
+// printf("%s(%s)::getController(%d) size %d: not found\n",
+// cname().toLatin1().data(), name().toLatin1().data(), id, controller()->size());
+// const CtrlList* cl = controller();
+// for (ciCtrl i = cl->begin(); i != cl->end(); ++i)
+// printf(" Ctrl %d\n", i->first);
+ return 0;
+ }
+ return i->second;
+ }
+
+//---------------------------------------------------------
+// controllerNames
+//---------------------------------------------------------
+
+ControllerNameList* Track::controllerNames() const
+ {
+ ControllerNameList* l = new ControllerNameList;
+ for (ciCtrl i = controller()->begin(); i != controller()->end(); ++i)
+ l->push_back(ControllerName(i->second->name(), i->second->id()));
+ return l;
+ }
+
+//---------------------------------------------------------
+// setRecordFlag
+//---------------------------------------------------------
+
+void Track::setRecordFlag(bool f)
+ {
+ if (_recordFlag != f) {
+ _recordFlag = f;
+ emit recordChanged(_recordFlag);
+ }
+ }
+
+//---------------------------------------------------------
+// setMonitor
+//---------------------------------------------------------
+
+void Track::setMonitor(bool f)
+ {
+ if (_monitor != f) {
+ _monitor = f;
+ emit monitorChanged(_monitor);
+ }
+ }
+
+//---------------------------------------------------------
+// setSelected
+//---------------------------------------------------------
+
+void Track::setSelected(bool f)
+ {
+ if (f != _selected) {
+ _selected = f;
+ emit selectionChanged(_selected);
+// muse->selectionChanged();
+ }
+ }
+
+//---------------------------------------------------------
+// setController
+// called from GUI
+//---------------------------------------------------------
+
+#if 0
+void Track::setController(Pos pos, int id, int v)
+ {
+ CVal val;
+ val.i = v;
+ setController(pos, id, val);
+ }
+
+void Track::setController(Pos pos, int id, double v)
+ {
+ CVal val;
+ val.f = v;
+ setController(pos, id, val);
+ }
+
+void Track::setController(Pos pos, int id, CVal val)
+ {
+ Ctrl* c = getController(id);
+ if (c == 0) {
+ printf("no controller 0x%x %s\n", id, name().toLatin1().data());
+ return;
+ }
+ if (isMidiTrack()) {
+ int port = ((MidiTrack*)this)->outPort();
+ int channel = ((MidiTrack*)this)->outChannel();
+ MidiEvent ev(0, port, channel, ME_CONTROLLER, id, val.i);
+ audio->msgPlayMidiEvent(&ev);
+ }
+ else {
+ // non midi controller are current once set
+ c->setCurVal(val);
+ }
+ c->setSchedVal(val);
+ if (autoWrite()) {
+ unsigned time = _tt == AL::FRAMES ? pos.frame() : pos.tick();
+ if (audio->isPlaying())
+ _recEvents.push_back(CtrlRecVal(time, id, val));
+ else
+ song->addControllerVal(this, c, id, time, val);
+ }
+ emit controllerChanged(id);
+ }
+#endif
+
+//---------------------------------------------------------
+// startAutoRecord
+// slider/knob touched
+//---------------------------------------------------------
+
+void Track::startAutoRecord(int n)
+ {
+ Ctrl* ctrl = getController(n);
+ if (ctrl) {
+ ctrl->setTouched(true);
+ if (audio->isPlaying() && autoWrite())
+ _recEvents.push_back(CtrlRecVal(song->cPos().frame(), n, 1));
+ }
+ else
+ printf("no ctrl 0x%x\n", n);
+ }
+
+//---------------------------------------------------------
+// stopAutoRecord
+// slider/knob released
+//---------------------------------------------------------
+
+void Track::stopAutoRecord(int n)
+ {
+ Ctrl* ctrl = getController(n);
+ if (ctrl) {
+ ctrl->setTouched(false);
+ if (audio->isPlaying() && autoWrite())
+ _recEvents.push_back(CtrlRecVal(song->cPos().frame(), n, 2));
+ }
+ else
+ printf("no ctrl 0x%x\n", n);
+ }
+
+//---------------------------------------------------------
+// setName
+//---------------------------------------------------------
+
+void Track::setName(const QString& s)
+ {
+ _name = s;
+ emit nameChanged(_name);
+ }
+
+//---------------------------------------------------------
+// setAutoRead
+//---------------------------------------------------------
+
+void Track::setAutoRead(bool val)
+ {
+ if (_autoRead != val) {
+ _autoRead = val;
+ emit autoReadChanged(_autoRead);
+ }
+ }
+
+//---------------------------------------------------------
+// setAutoWrite
+//---------------------------------------------------------
+
+void Track::setAutoWrite(bool val)
+ {
+ if (_autoWrite != val) {
+ _autoWrite = val;
+ emit autoWriteChanged(_autoWrite);
+ }
+ }
+
+//---------------------------------------------------------
+// cpos
+//---------------------------------------------------------
+
+unsigned Track::cpos() const
+ {
+ return timeType() == AL::TICKS ? song->cPos().tick() : song->cPos().frame();
+ }
+
+//---------------------------------------------------------
+// updateController
+//---------------------------------------------------------
+
+void Track::updateController()
+ {
+ CtrlList* cl = controller();
+ for (iCtrl i = cl->begin(); i != cl->end(); ++i) {
+ Ctrl* c = i->second;
+ if (c->changed()) {
+ c->setChanged(false);
+ emit controllerChanged(c->id());
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// writeRouting
+//---------------------------------------------------------
+
+void Track::writeRouting(Xml& xml) const
+ {
+ if (type() == AUDIO_INPUT || type() == MIDI_IN) {
+ foreach(Route r, _inRoutes) {
+ xml.stag("Route");
+ r.src.write(xml, "src");
+ r.dst.write(xml, "dst");
+ xml.etag("Route");
+ }
+ }
+ foreach(Route r, _outRoutes) {
+ xml.stag("Route");
+ r.src.write(xml, "src");
+ r.dst.write(xml, "dst");
+ xml.etag("Route");
+ }
+ }
+
+//---------------------------------------------------------
+// hwCtrlState
+//---------------------------------------------------------
+
+int Track::hwCtrlState(int ctrl) const
+ {
+ ciCtrl cl = _controller.find(ctrl);
+ if (cl == _controller.end()) {
+ if (debugMsg)
+ printf("hwCtrlState: ctrl 0x%x not found\n", ctrl);
+ return CTRL_VAL_UNKNOWN;
+ }
+ Ctrl* vl = cl->second;
+ return vl->curVal().i;
+ }
+
+//---------------------------------------------------------
+// setHwCtrlState
+//---------------------------------------------------------
+
+void Track::setHwCtrlState(int ctrl, int val)
+ {
+ iCtrl cl = _controller.find(ctrl);
+ if (cl == _controller.end()) {
+ // try to add new controller
+ if (debugMsg)
+ printf("setHwCtrlState(0x%x,0x%x): not found\n", ctrl, val);
+ return;
+ }
+ Ctrl* vl = cl->second;
+// printf("setHwCtrlState ctrl %x val %x\n", ctrl, val);
+ vl->setChanged(true);
+ return vl->setCurVal(val);
+ }
+
+//---------------------------------------------------------
+// getCtrl
+//---------------------------------------------------------
+
+int Track::getCtrl(int tick, int ctrl) const
+ {
+ ciCtrl cl = _controller.find(ctrl);
+ if (cl == _controller.end()) {
+ if (debugMsg)
+ printf("getCtrl: controller %d(0x%x) not found %zd\n",
+ ctrl, ctrl, _controller.size());
+ return CTRL_VAL_UNKNOWN;
+ }
+ return cl->second->value(tick).i;
+ }
+
+//---------------------------------------------------------
+// setSolo
+//---------------------------------------------------------
+
+bool Track::setSolo(bool val)
+ {
+ if (_solo != val) {
+ _solo = val;
+ emit soloChanged(_solo);
+ return true;
+ }
+ return false;
+ }
+
+//---------------------------------------------------------
+// setMute
+// return true if mute changed
+//---------------------------------------------------------
+
+bool Track::setMute(bool val)
+ {
+ if (_mute != val) {
+ _mute = val;
+ emit muteChanged(_mute);
+ return true;
+ }
+ return false;
+ }
+
+//---------------------------------------------------------
+// setOff
+// return true if state changed
+//---------------------------------------------------------
+
+bool Track::setOff(bool val)
+ {
+ if (_off != val) {
+ _off = val;
+ emit offChanged(_off);
+ return true;
+ }
+ return false;
+ }
+
+//---------------------------------------------------------
+// setChannels
+//---------------------------------------------------------
+
+void Track::setChannels(int n)
+ {
+ _channels = n;
+ for (int i = 0; i < _channels; ++i) {
+ _meter[i] = 0.0f;
+ _peak[i] = 0.0f;
+ }
+ }
+
+//---------------------------------------------------------
+// resetMeter
+//---------------------------------------------------------
+
+void Track::resetMeter()
+ {
+ for (int i = 0; i < _channels; ++i)
+ _meter[i] = 0.0f;
+ }
+
+//---------------------------------------------------------
+// resetPeaks
+//---------------------------------------------------------
+
+void Track::resetPeaks()
+ {
+ for (int i = 0; i < _channels; ++i)
+ _peak[i] = 0;
+ }
+
+//---------------------------------------------------------
+// resetAllMeter
+//---------------------------------------------------------
+
+void Track::resetAllMeter()
+ {
+ TrackList* tl = song->tracks();
+ for (iTrack i = tl->begin(); i != tl->end(); ++i)
+ (*i)->resetMeter();
+ }
+
+//---------------------------------------------------------
+// activate1
+// register JACK and ALSA ports
+//---------------------------------------------------------
+
+void Track::activate1()
+ {
+ if (isMidiTrack()) {
+ if (!jackPort(0).isZero())
+ printf("Track::activate1() midi: jack port already active!\n");
+ if (type() == MIDI_OUT) {
+ _jackPort[0] = audioDriver->registerOutPort(_name, true);
+ }
+ else if (type() == MIDI_IN) {
+ _jackPort[0] = audioDriver->registerInPort(_name, true);
+ }
+ return;
+ }
+
+ for (int i = 0; i < channels(); ++i) {
+ if (!jackPort(i).isZero())
+ printf("Track<%s>::activate1(): channel %d already active!\n",
+ name().toLatin1().data(), i);
+ else {
+ QString s(QString("%1-%2").arg(_name).arg(i));
+ if (type() == AUDIO_OUTPUT)
+ _jackPort[i] = audioDriver->registerOutPort(s, false);
+ else if (type() == AUDIO_INPUT)
+ _jackPort[i] = audioDriver->registerInPort(s, false);
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// activate2
+// connect all JACK/ALSA in/out routes
+// connect to JACK only works if JACK is running
+//---------------------------------------------------------
+
+void Track::activate2()
+ {
+ if (audioState != AUDIO_RUNNING) {
+ printf("Track::activate2(): no audio running !\n");
+ abort();
+ }
+ foreach(Route r, _outRoutes) {
+ if (r.dst.type == RouteNode::JACKMIDIPORT) {
+ audioDriver->connect(_jackPort[0], r.dst.port);
+ r.disconnected = false;
+ }
+ else if (r.dst.type == RouteNode::AUDIOPORT) {
+ audioDriver->connect(_jackPort[r.src.channel], r.dst.port);
+ r.disconnected = false;
+ }
+ }
+ foreach(Route r, _inRoutes) {
+ if (r.src.type == RouteNode::JACKMIDIPORT) {
+ audioDriver->connect(r.src.port, _jackPort[0]);
+ r.disconnected = false;
+ }
+ else if (r.src.type == RouteNode::AUDIOPORT) {
+ audioDriver->connect(r.src.port, _jackPort[r.dst.channel]);
+ r.disconnected = false;
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// deactivate
+// disconnect and unregister JACK and ALSA ports
+//---------------------------------------------------------
+
+void Track::deactivate()
+ {
+// printf("deactivate<%s>\n", name().toLatin1().data());
+ foreach(Route r, _outRoutes) {
+ if (r.dst.type == RouteNode::JACKMIDIPORT) {
+ r.disconnected = true;
+ audioDriver->disconnect(_jackPort[0], r.dst.port);
+ }
+ else if (r.dst.type == RouteNode::AUDIOPORT) {
+ audioDriver->disconnect(_jackPort[r.src.channel], r.dst.port);
+ r.disconnected = true;
+ }
+ }
+ foreach(Route r, _inRoutes) {
+ if (r.src.type == RouteNode::JACKMIDIPORT) {
+ r.disconnected = true;
+ audioDriver->disconnect(r.src.port, _jackPort[0]);
+ }
+ else if (r.src.type == RouteNode::AUDIOPORT) {
+ r.disconnected = true;
+ audioDriver->disconnect(r.src.port, _jackPort[r.dst.channel]);
+ }
+ }
+ for (int i = 0; i < channels(); ++i) {
+ if (!_jackPort[i].isZero()) {
+ audioDriver->unregisterPort(_jackPort[i]);
+ _jackPort[i].setZero();
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// setSendSync
+//---------------------------------------------------------
+
+void Track::setSendSync(bool val)
+ {
+ _sendSync = val;
+ emit sendSyncChanged(val);
+ }
+
+//---------------------------------------------------------
+// splitPart
+// split part "part" at "tick" position
+// create two new parts p1 and p2
+//---------------------------------------------------------
+
+void Track::splitPart(Part* part, int tickpos, Part*& p1, Part*& p2)
+ {
+ int l1 = 0; // len of first new part (ticks or samples)
+ int l2 = 0; // len of second new part
+
+ int samplepos = AL::tempomap.tick2frame(tickpos);
+
+ switch (type()) {
+ case WAVE:
+ l1 = samplepos - part->frame();
+ l2 = part->lenFrame() - l1;
+ break;
+ case MIDI:
+ l1 = tickpos - part->tick();
+ l2 = part->lenTick() - l1;
+ break;
+ default:
+ return;
+ }
+
+ if (l1 <= 0 || l2 <= 0)
+ return;
+
+ p1 = newPart(part); // new left part
+ p2 = newPart(part); // new right part
+
+ switch (type()) {
+ case WAVE:
+ p1->setLenFrame(l1);
+ p2->setFrame(samplepos);
+ p2->setLenFrame(l2);
+ break;
+ case MIDI:
+ p1->setLenTick(l1);
+ p2->setTick(tickpos);
+ p2->setLenTick(l2);
+ break;
+ default:
+ break;
+ }
+
+ EventList* se = part->events();
+ EventList* de1 = p1->events();
+ EventList* de2 = p2->events();
+
+ if (type() == WAVE) {
+ int ps = part->frame();
+ int d1p1 = p1->frame();
+ int d2p1 = p1->endFrame();
+ int d1p2 = p2->frame();
+ int d2p2 = p2->endFrame();
+ for (iEvent ie = se->begin(); ie != se->end(); ++ie) {
+ Event event = ie->second;
+ int s1 = event.frame() + ps;
+ int s2 = event.endFrame() + ps;
+
+ if ((s2 > d1p1) && (s1 < d2p1)) {
+ Event si = event.mid(d1p1 - ps, d2p1 - ps);
+ de1->add(si);
+ }
+ if ((s2 > d1p2) && (s1 < d2p2)) {
+ Event si = event.mid(d1p2 - ps, d2p2 - ps);
+ si.setFrame(si.frame() - l1); //??
+ si.setFrame(0); //??
+ de2->add(si);
+ }
+ }
+ }
+ else {
+ for (iEvent ie = se->begin(); ie != se->end(); ++ie) {
+ Event event = ie->second.clone();
+ int t = event.tick();
+ if (t >= l1) {
+ event.move(-l1);
+ de2->add(event);
+ }
+ else
+ de1->add(event);
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// addInRoute
+//---------------------------------------------------------
+
+void Track::addInRoute(const Route& r)
+ {
+ if (_inRoutes.indexOf(r) != -1) {
+ printf("Track::addInRoute: route already there\n");
+ return;
+ }
+ _inRoutes.push_back(r);
+ }
+
+//---------------------------------------------------------
+// addOutRoute
+//---------------------------------------------------------
+
+void Track::addOutRoute(const Route& r)
+ {
+ if (_outRoutes.indexOf(r) != -1) {
+ printf("Track::addOutRoute: route already there\n");
+ return;
+ }
+ _outRoutes.push_back(r);
+ }
+
+//---------------------------------------------------------
+// inRouteExists
+//---------------------------------------------------------
+
+bool Track::inRouteExists(const Route& r) const
+ {
+ return _inRoutes.indexOf(r) != -1;
+ }
+
+//---------------------------------------------------------
+// outRouteExists
+//---------------------------------------------------------
+
+bool Track::outRouteExists(const Route& r) const
+ {
+ return _outRoutes.indexOf(r) != -1;
+ }
+
diff --git a/muse_qt4_evolution/muse/track.h b/muse_qt4_evolution/muse/track.h
new file mode 100644
index 00000000..1afa3cc2
--- /dev/null
+++ b/muse_qt4_evolution/muse/track.h
@@ -0,0 +1,345 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __TRACK_H__
+#define __TRACK_H__
+
+#include "port.h"
+#include "al/pos.h"
+#include "route.h"
+#include "ctrl.h"
+#include "globaldefs.h"
+
+namespace AL {
+ class Xml;
+ enum TType;
+ };
+using AL::Xml;
+using AL::TType;
+
+class DrumMap;
+class MidiPipeline;
+class MidiEvent;
+class MidiEventList;
+class SynthI;
+class MidiPlugin;
+class MidiPluginI;
+class MidiInstrument;
+class PartList;
+class Part;
+class MidiOutPort;
+class MidiInPort;
+class MidiOut;
+
+//---------------------------------------------------------
+// ArrangerTrack
+//---------------------------------------------------------
+
+struct ArrangerTrack {
+ QWidget* tw; // tracklist widget
+ int ctrl;
+ int h; // tmp val used by readProperties()
+ Ctrl* controller;
+
+ ArrangerTrack();
+ };
+
+typedef std::list<ArrangerTrack*> ArrangerTrackList;
+typedef ArrangerTrackList::iterator iArrangerTrack;
+typedef ArrangerTrackList::const_iterator ciArrangerTrack;
+
+//---------------------------------------------------------
+// Track
+//---------------------------------------------------------
+
+class Track : public QObject {
+ Q_OBJECT
+
+ public:
+ enum TrackType {
+ AUDIO_OUTPUT,
+ AUDIO_GROUP,
+ WAVE,
+ AUDIO_INPUT,
+ AUDIO_SOFTSYNTH,
+ MIDI,
+ MIDI_OUT,
+ MIDI_IN,
+ MIDI_SYNTI,
+ TRACK_TYPES
+ };
+ enum {
+ M_AUDIO_OUTPUT = 1 << AUDIO_OUTPUT,
+ M_AUDIO_GROUP = 1 << AUDIO_GROUP,
+ M_WAVE = 1 << WAVE,
+ M_AUDIO_INPUT = 1 << AUDIO_INPUT,
+ M_AUDIO_SOFTSYNTH = 1 << AUDIO_SOFTSYNTH,
+ M_MIDI = 1 << MIDI,
+ M_MIDI_OUT = 1 << MIDI_OUT,
+ M_MIDI_IN = 1 << MIDI_IN,
+ M_MIDI_SYNTI = 1 << MIDI_SYNTI
+ };
+
+ private:
+ QString _comment;
+ PartList* _parts;
+ Port _jackPort[MAX_CHANNELS];
+ bool _sendSync; // this port sends mtc/mmc events
+ int _deviceId; // midi device id: 0-126; 127 == all
+
+ protected:
+ TType _tt; // time type
+ QString _name;
+ bool _recordFlag;
+ bool _mute;
+ bool _solo;
+ bool _off;
+ bool _monitor;
+ int _channels; // 1 - mono, 2 - stereo
+ // Note: midi out/in tracks have
+ // 1 channel
+ CtrlRecList _recEvents; // recorded automation events
+ double _meter[MAX_CHANNELS];
+ double _peak[MAX_CHANNELS];
+ int _peakTimer[MAX_CHANNELS];
+ bool _locked; // true if parts are locked to frames
+ bool _selected;
+
+ RouteList _inRoutes, _outRoutes;
+ CtrlList _controller;
+
+ bool _autoRead, _autoWrite;
+
+ bool readProperties(QDomNode);
+ void writeProperties(Xml& xml) const;
+
+ virtual bool setMute(bool val);
+ virtual bool setOff(bool val);
+ virtual bool setSolo(bool val);
+
+ signals:
+ void recordChanged(bool);
+ void autoReadChanged(bool);
+ void autoWriteChanged(bool);
+ void clChanged();
+ void controllerChanged(int id);
+ void selectionChanged(bool);
+ void muteChanged(bool);
+ void soloChanged(bool);
+ void monitorChanged(bool);
+ void offChanged(bool);
+ void partsChanged();
+ void nameChanged(const QString&);
+ void routeChanged();
+ void sendSyncChanged(bool);
+
+ private slots:
+ void setAutoRead(bool);
+ void setAutoWrite(bool);
+
+ public:
+ Track();
+ virtual ~Track();
+
+ static const char* _cname[];
+ static const char* _clname[];
+
+ QString comment() const { return _comment; }
+ void setComment(const QString& s) { _comment = s; }
+ TType timeType() const { return _tt; }
+ void setTimeType(TType t) { _tt = t; }
+
+ QString cname() const {
+ int t = type();
+ return QString(_cname[t]);
+ }
+ QString clname() const { return QString(_clname[type()]); }
+
+ //
+ // called before and after use
+ // (undo/redo)
+ // connects/reconnects to the outside world
+ //
+ void activate1();
+ void activate2();
+ void deactivate();
+
+ //----------------------------------------------------------
+ // controller handling
+ //----------------------------------------------------------
+
+ CtrlList* controller() { return &_controller; }
+ const CtrlList* controller() const { return &_controller; }
+
+ ControllerNameList* controllerNames() const;
+ void addController(Ctrl*);
+ void addMidiController(MidiInstrument*, int ctrl);
+ void removeController(int id);
+ Ctrl* getController(int id) const;
+
+ int hwCtrlState(int ctrl) const;
+ void setHwCtrlState(int ctrl, int val);
+
+ // current value:
+ CVal ctrlVal(int id) { return getController(id)->curVal(); }
+
+ // editor interface:
+ bool addControllerVal(int id, unsigned pos, CVal);
+ void removeControllerVal(int id, unsigned pos);
+ int getCtrl(int tick, int ctrl) const;
+
+ // signal interface:
+ virtual void emitControllerChanged(int id) { emit controllerChanged(id); }
+ void updateController();
+ void changeCtrlName(Ctrl* c, const QString& s);
+
+ // automation
+ void startAutoRecord(int);
+ void stopAutoRecord(int);
+ CtrlRecList* recEvents() { return &_recEvents; }
+ //----------------------------------------------------------
+
+ QColor ccolor() const;
+ QPixmap* pixmap() const { return pixmap(type()); }
+ static QPixmap* pixmap(TrackType);
+
+ bool selected() const { return _selected; }
+ void setSelected(bool f);
+
+ bool locked() const { return _locked; }
+ void setLocked(bool b) { _locked = b; }
+
+ QString name() const { return _name; }
+ virtual void setName(const QString& s);
+
+ virtual TrackType type() const = 0;
+
+ PartList* parts() const { return _parts; }
+
+ Part* findPart(unsigned tick);
+ void addPart(Part* p);
+
+ virtual void write(Xml&) const = 0;
+
+ void setRecordFlag(bool);
+ virtual Part* newPart(Part*p=0, bool clone = false) = 0;
+ void dump() const;
+ virtual void splitPart(Part*, int, Part*&, Part*&);
+
+ void setMonitor(bool val);
+ virtual bool isMute() const = 0;
+
+ bool monitor() const { return _monitor; }
+ bool solo() const { return _solo; }
+ bool mute() const { return _mute; }
+ bool off() const { return _off; }
+ bool recordFlag() const { return _recordFlag; }
+
+ void resetMeter();
+ void resetPeaks();
+ static void resetAllMeter();
+ double meter(int ch) const { return _meter[ch]; }
+ void addMidiMeter(int velo) {
+ _meter[0] += velo/5;
+ if (_meter[0] > 127.0f)
+ _meter[0] = 127.0f;
+ }
+ double peak(int ch) const { return _peak[ch]; }
+ void setPeak(int ch, double v) { _peak[ch] = v; }
+ void resetPeak(int ch) {
+ _peak[ch] = 0;
+ _peakTimer[ch] = 0;
+ }
+ int peakTimer(int ch) const { return _peakTimer[ch]; }
+ void setPeakTimer(int ch, int v) { _peakTimer[ch] = v; }
+ void setMeter(int ch, double v) {
+ _meter[ch] = v;
+ if (v > _peak[ch]) {
+ _peak[ch] = v;
+ _peakTimer[ch] = 0;
+ }
+ }
+
+ void setDefaultName();
+ int channels() const { return _channels; }
+ virtual void setChannels(int n);
+ bool isMidiTrack() const {
+ return type() == MIDI
+ || type() == MIDI_IN
+ || type() == MIDI_OUT
+ || type() == MIDI_SYNTI;
+ }
+ virtual bool canRecord() const { return false; }
+
+ bool autoRead() const { return _autoRead; }
+ bool autoWrite() const { return _autoWrite; }
+
+ void partListChanged() { emit partsChanged(); }
+ void updateMute() { emit muteChanged(isMute()); }
+ unsigned cpos() const;
+
+ //----------------------------------------------------------
+ // routing
+ //----------------------------------------------------------
+
+ RouteList* inRoutes() { return &_inRoutes; }
+ RouteList* outRoutes() { return &_outRoutes; }
+ bool noInRoute() const { return _inRoutes.empty(); }
+ bool noOutRoute() const { return _outRoutes.empty(); }
+ void addInRoute(const Route& r);
+ void addOutRoute(const Route& r);
+ void writeRouting(Xml&) const;
+ bool inRouteExists(const Route& r) const;
+ bool outRouteExists(const Route& r) const;
+
+ Port jackPort(int channel = 0) const { return _jackPort[channel]; }
+
+ void setJackPort(const Port& port, int channel = 0) {
+ _jackPort[channel] = port;
+ }
+
+ struct ArrangerTrack arrangerTrack;
+ ArrangerTrackList subtracks;
+
+ friend class Song;
+
+ virtual void routeEvent(const MidiEvent&) {}
+ bool sendSync() const { return _sendSync; }
+ void setSendSync(bool val);
+ int deviceId() const { return _deviceId; }
+ void setDeviceId(int val) { _deviceId = val; }
+
+ virtual bool muteDefault() const { return false; }
+ virtual bool autoReadDefault() const { return false; }
+ virtual bool autoWriteDefault() const { return false; }
+
+ virtual MidiOut* midiOut() { return 0; }
+ virtual MidiInstrument* instrument() { return 0; }
+ };
+
+Q_DECLARE_METATYPE(class Track*);
+
+typedef QList<Track*> TrackList;
+typedef TrackList::iterator iTrack;
+typedef TrackList::const_iterator ciTrack;
+
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/trackdrag.cpp b/muse_qt4_evolution/muse/trackdrag.cpp
new file mode 100644
index 00000000..beab87dd
--- /dev/null
+++ b/muse_qt4_evolution/muse/trackdrag.cpp
@@ -0,0 +1,61 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "trackdrag.h"
+
+class Track;
+const char TrackDrag::type[] = "application/muse/track";
+
+//---------------------------------------------------------
+// TrackDrag
+//---------------------------------------------------------
+
+TrackDrag::TrackDrag(Track* track, QWidget* src)
+ : QDrag(src)
+ {
+ QByteArray a((char*)&track, sizeof(track));
+ QMimeData* mimeData = new QMimeData;
+ mimeData->setData(type, a);
+ setMimeData(mimeData);
+ }
+
+//---------------------------------------------------------
+// canDecode
+//---------------------------------------------------------
+
+bool TrackDrag::canDecode(const QMimeSource* s)
+ {
+ return !strcmp(s->format(0), type);
+ }
+
+//---------------------------------------------------------
+// decode
+//---------------------------------------------------------
+
+bool TrackDrag::decode(const QMimeSource* s, Track*& p)
+ {
+ QByteArray a = s->encodedData(type);
+ p = (Track*)((a[0] & 0xff)
+ | (a[1] & 0xff) << 8
+ | (a[2] & 0xff) << 16
+ | (a[3] & 0xff) << 24);
+ return true;
+ }
+
diff --git a/muse_qt4_evolution/muse/trackdrag.h b/muse_qt4_evolution/muse/trackdrag.h
new file mode 100644
index 00000000..083a94b3
--- /dev/null
+++ b/muse_qt4_evolution/muse/trackdrag.h
@@ -0,0 +1,42 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __TRACKDRAG_H__
+#define __TRACKDRAG_H__
+
+class Track;
+
+//---------------------------------------------------------
+// TrackDrag
+//---------------------------------------------------------
+
+class TrackDrag : public QDrag {
+ static const char type[];
+ Q_OBJECT
+
+ public:
+ TrackDrag(Track*, QWidget* src);
+ static bool canDecode(const QMimeSource*);
+ static bool decode(const QMimeSource* s, Track*& p);
+ };
+
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/trackinfo.cpp b/muse_qt4_evolution/muse/trackinfo.cpp
new file mode 100644
index 00000000..1a62b1c0
--- /dev/null
+++ b/muse_qt4_evolution/muse/trackinfo.cpp
@@ -0,0 +1,553 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "arranger.h"
+#include "widgets/outportcombo.h"
+#include "instruments/minstrument.h"
+#include "midiedit/drummap.h"
+#include "midictrl.h"
+#include "song.h"
+#include "trackinfo.h"
+#include "synth.h"
+#include "tllineedit.h"
+#include "audio.h"
+#include "gui.h"
+#include "midioutport.h"
+#include "midiinport.h"
+
+static QColor labelColor(140, 140, 255);
+
+//---------------------------------------------------------
+// createTrackInfo
+//---------------------------------------------------------
+
+TrackInfo* Arranger::createTrackInfo()
+ {
+ Track::TrackType t = _curTrack->type();
+ switch (t) {
+ case Track::MIDI: return new MidiTrackInfo();
+ case Track::AUDIO_OUTPUT: return new AudioOutputInfo();
+ case Track::AUDIO_GROUP: return new AudioGroupInfo();
+ case Track::WAVE: return new WaveTrackInfo();
+ case Track::AUDIO_INPUT: return new AudioInputInfo();
+ case Track::AUDIO_SOFTSYNTH: return new SynthIInfo();
+ case Track::MIDI_OUT: return new MidiOutPortInfo();
+ case Track::MIDI_IN: return new MidiInPortInfo();
+ case Track::MIDI_SYNTI: return new MidiSynthIInfo();
+ default:
+ printf("Arranger::createTrackInfo: type %d\n", t);
+ abort();
+ }
+ }
+
+//---------------------------------------------------------
+// TrackInfo
+//---------------------------------------------------------
+
+TrackInfo::TrackInfo()
+ : QWidget()
+ {
+ track = 0;
+ label = new QLabel;
+ label->setToolTip(tr("Track Type"));
+ label->setLineWidth(2);
+ label->setFrameStyle(QFrame::Panel | QFrame::Raised);
+ label->setAutoFillBackground(true);
+ QPalette p = label->palette();
+ p.setColor(QPalette::Background, labelColor);
+ label->setPalette(p);
+
+ name = new TLLineEdit("");
+ name->setToolTip(tr("Track Name"));
+ name->setMaximumHeight(24);
+
+ grid = new QGridLayout;
+ grid->setMargin(0);
+ grid->setSpacing(0);
+ setLayout(grid);
+
+ grid->addWidget(label, 0, 0, 1, 2);
+ grid->addWidget(name, 1, 0, 1, 2);
+ connect(name, SIGNAL(contentChanged(QString)), SLOT(nameChanged(QString)));
+ connect(song, SIGNAL(songChanged(int)), SLOT(songChanged(int)));
+// resize(QSize(infoWidth, height()));
+ }
+
+//---------------------------------------------------------
+// nameChanged
+//---------------------------------------------------------
+
+void TrackInfo::nameChanged(QString s)
+ {
+ song->changeTrackName(track, s);
+ name->setCursorPosition(0);
+ }
+
+//---------------------------------------------------------
+// init
+//---------------------------------------------------------
+
+void TrackInfo::init(Track* t)
+ {
+ track = t;
+ if (t == 0)
+ return;
+ label->setText(track->clname());
+ name->setText(track->name());
+ connect(track, SIGNAL(nameChanged(const QString&)), name, SLOT(setText(const QString&)));
+ }
+
+//---------------------------------------------------------
+// songChanged
+//---------------------------------------------------------
+
+void TrackInfo::songChanged(int val)
+ {
+ if ((val & SC_ROUTE) && track)
+ init(track);
+ }
+
+//---------------------------------------------------------
+// MidiTrackInfo
+//---------------------------------------------------------
+
+MidiTrackInfo::MidiTrackInfo()
+ : TrackInfo()
+ {
+ QWidget* midiTrackInfo = new QWidget;
+ mt.setupUi(midiTrackInfo);
+
+ QWidget* midiPortInfo = new QWidget;
+ mp.setupUi(midiPortInfo);
+
+ grid->addWidget(midiTrackInfo, 2, 0, 1, 2);
+
+ channel = new QComboBox;
+ channel->setMaximumHeight(24);
+ for (int ch = 0; ch < MIDI_CHANNELS; ++ch)
+ channel->addItem(tr("Channel %1").arg(ch+1), ch);
+ grid->addWidget(channel, 3, 0, 1, 2);
+
+ QLabel* label = new QLabel;
+ label->setText(tr("Midi Port"));
+ label->setLineWidth(2);
+ label->setFrameStyle(QFrame::Panel | QFrame::Raised);
+ label->setAutoFillBackground(true);
+ QPalette p = label->palette();
+ p.setColor(QPalette::Background, labelColor);
+ label->setPalette(p);
+ grid->addWidget(label, 4, 0, 1, 2);
+
+ port = new QComboBox;
+ port->setMaximumHeight(24);
+ grid->addWidget(port, 5, 0, 1, 2);
+ grid->addWidget(midiPortInfo, 6, 0, 1, 2);
+ grid->setRowStretch(grid->rowCount(), 100);
+
+ pop = new QMenu(mt.patch);
+
+ connect(mt.transposition, SIGNAL(valueChanged(int)), SLOT(transpositionChanged(int)));
+ connect(mt.velocity, SIGNAL(valueChanged(int)), SLOT(velocityChanged(int)));
+ connect(mt.delay, SIGNAL(valueChanged(int)), SLOT(delayChanged(int)));
+ connect(mt.length, SIGNAL(valueChanged(int)), SLOT(lenChanged(int)));
+ connect(mt.compression, SIGNAL(valueChanged(int)), SLOT(iKomprChanged(int)));
+ connect(mt.patch, SIGNAL(clicked()), SLOT(patchClicked()));
+ connect(port, SIGNAL(activated(int)), SLOT(portSelected(int)));
+ connect(mp.instrument, SIGNAL(activated(int)), SLOT(instrumentSelected(int)));
+ connect(mp.deviceId, SIGNAL(valueChanged(int)), SLOT(deviceIdChanged(int)));
+ connect(song, SIGNAL(autoReadChanged(Track*,bool)), SLOT(autoChanged(Track*,bool)));
+ connect(song, SIGNAL(autoWriteChanged(Track*,bool)), SLOT(autoChanged(Track*,bool)));
+ }
+
+//---------------------------------------------------------
+// init
+//---------------------------------------------------------
+
+void MidiTrackInfo::init(Track* t)
+ {
+ MidiTrack* midiTrack = (MidiTrack*)&*t;
+ if (t != track) {
+ if (track) {
+ disconnect(channel, 0, track, 0);
+ disconnect(track, 0, channel, 0);
+ }
+ connect(channel, SIGNAL(activated(int)), midiTrack, SLOT(setChannel(int)));
+ connect(midiTrack,SIGNAL(channelChanged(int)), channel, SLOT(setCurrentIndex(int)));
+ }
+
+ TrackInfo::init(t);
+ mt.transposition->setValue(midiTrack->transposition());
+ mt.delay->setValue(midiTrack->delay());
+ mt.length->setValue(midiTrack->len());
+ mt.velocity->setValue(midiTrack->velocity());
+ mt.compression->setValue(midiTrack->compression());
+
+ mp.instrument->clear();
+ foreach(MidiInstrument* mi, midiInstruments)
+ mp.instrument->addItem(mi->iname());
+
+ RouteList* rl = track->outRoutes();
+ Track* outputTrack = 0;
+ if (!rl->isEmpty())
+ outputTrack = (*rl)[0].dst.track;
+
+ port->clear();
+ port->addItem("---", QVariant::fromValue<void*>(0));
+ foreach(MidiOutPort* mp, *(song->midiOutPorts()))
+ port->addItem(mp->name(), QVariant::fromValue<void*>(mp));
+ foreach(SynthI* s, *(song->syntis()))
+ port->addItem(s->name(), QVariant::fromValue<void*>(s));
+ if (outputTrack) {
+ int idx = port->findText(outputTrack->name());
+ port->setCurrentIndex(idx == -1 ? 0 : idx);
+ }
+
+ channel->setCurrentIndex(midiTrack->channelNo());
+
+ connect(track, SIGNAL(controllerChanged(int)), SLOT(controllerChanged(int)));
+ if (outputTrack && outputTrack->type() == Track::MIDI_OUT)
+ connect(outputTrack, SIGNAL(instrumentChanged()), SLOT(instrumentChanged()));
+
+ instrumentChanged(); // setup instrument
+
+ // enable instrument selection only for tracks routed to a
+ // midi out port:
+ mp.instrument->setEnabled(outputTrack && (outputTrack->type() == Track::MIDI_OUT));
+
+ if (!rl->isEmpty()) {
+ mp.deviceId->setValue(midiTrack->deviceId());
+ autoChanged(track, false); // update enable
+ int val = midiTrack->ctrlVal(CTRL_PROGRAM).i;
+ int channelno = midiTrack->channelNo();
+ mt.patch->setText(midiTrack->instrument()->getPatchName(channelno, val));
+ }
+ else {
+ channel->setCurrentIndex(0);
+ port->setCurrentIndex(0);
+ mp.instrument->addItem("--");
+ mp.instrument->setCurrentIndex(0);
+ mt.patch->setText("--");
+ }
+ }
+
+//---------------------------------------------------------
+// portSelected
+//---------------------------------------------------------
+
+void MidiTrackInfo::portSelected(int idx)
+ {
+ QVariant v(port->itemData(idx));
+ Track* outputTrack = (Track*)v.value<void*>();
+ if (outputTrack == 0)
+ return;
+ RouteList* rl = track->outRoutes();
+ if (rl->isEmpty())
+ return;
+ Route r = (*rl)[0];
+ audio->msgRemoveRoute(r);
+ r.dst.track = outputTrack;
+ audio->msgAddRoute(r);
+ song->update(SC_ROUTE);
+ }
+
+//---------------------------------------------------------
+// controllerChanged
+//---------------------------------------------------------
+
+void MidiTrackInfo::controllerChanged(int id)
+ {
+ if (id == CTRL_PROGRAM) {
+ MidiInstrument* mi = track->instrument();
+ int val = track->ctrlVal(id).i;
+ mt.patch->setText(mi->getPatchName(((MidiTrack*)&*track)->channelNo(), val));
+ }
+ }
+
+//---------------------------------------------------------
+// instrumentChanged
+//---------------------------------------------------------
+
+void MidiTrackInfo::instrumentChanged()
+ {
+ MidiInstrument* mi = track->instrument();
+ mp.instrument->setCurrentIndex(midiInstruments.indexOf(mi));
+ }
+
+//---------------------------------------------------------
+// autoChanged
+//---------------------------------------------------------
+
+void MidiTrackInfo::autoChanged(Track* t, bool)
+ {
+ if (t != track)
+ return;
+ bool ar = t->autoRead();
+ bool aw = t->autoWrite();
+ bool en = !ar || (ar && aw);
+ mt.patch->setEnabled(en);
+ }
+
+//---------------------------------------------------------
+// transpositionChanged
+//---------------------------------------------------------
+
+void MidiTrackInfo::transpositionChanged(int val)
+ {
+ ((MidiTrack*)&*track)->setTransposition(val);
+ }
+
+//---------------------------------------------------------
+// patchClicked
+//---------------------------------------------------------
+
+void MidiTrackInfo::patchClicked()
+ {
+ MidiInstrument* mi = track->instrument();
+ mi->populatePatchPopup(pop, 0);
+
+ QAction* rv = pop->exec(mt.patch->mapToGlobal(QPoint(10,5)));
+ if (rv != 0) {
+ CVal cval;
+ cval.i = rv->data().toInt();
+ song->setControllerVal(track, CTRL_PROGRAM, cval);
+ }
+ }
+
+//---------------------------------------------------------
+// instrumentSelected
+//---------------------------------------------------------
+
+void MidiTrackInfo::instrumentSelected(int n)
+ {
+ RouteList* rl = track->outRoutes();
+ if (rl->isEmpty())
+ return;
+ Track* outTrack = (*rl)[0].dst.track;
+ if (outTrack->type() == Track::MIDI_OUT)
+ ((MidiOutPort*)outTrack)->setInstrument(midiInstruments[n]);
+ }
+
+//---------------------------------------------------------
+// velocityChanged
+//---------------------------------------------------------
+
+void MidiTrackInfo::velocityChanged(int val)
+ {
+ ((MidiTrack*)&*track)->setVelocity(val);
+ }
+
+//---------------------------------------------------------
+// delayChanged
+//---------------------------------------------------------
+
+void MidiTrackInfo::delayChanged(int val)
+ {
+ ((MidiTrack*)&*track)->setDelay(val);
+ }
+
+//---------------------------------------------------------
+// lenChanged
+//---------------------------------------------------------
+
+void MidiTrackInfo::lenChanged(int val)
+ {
+ ((MidiTrack*)&*track)->setLen(val);
+ }
+
+//---------------------------------------------------------
+// iKomprChanged
+//---------------------------------------------------------
+
+void MidiTrackInfo::iKomprChanged(int val)
+ {
+ ((MidiTrack*)&*track)->setCompression(val);
+ }
+
+//---------------------------------------------------------
+// deviceIdChanged
+//---------------------------------------------------------
+
+void MidiTrackInfo::deviceIdChanged(int val)
+ {
+ ((MidiTrack*)&*track)->setDeviceId(val);
+ }
+
+//---------------------------------------------------------
+// AudioOutputInfo
+//---------------------------------------------------------
+
+AudioOutputInfo::AudioOutputInfo()
+ : TrackInfo()
+ {
+ grid->setRowStretch(grid->rowCount(), 100);
+ }
+
+//---------------------------------------------------------
+// AudioInputInfo
+//---------------------------------------------------------
+
+AudioInputInfo::AudioInputInfo()
+ : TrackInfo()
+ {
+ grid->setRowStretch(grid->rowCount(), 100);
+ }
+
+//---------------------------------------------------------
+// AudioGroupInfo
+//---------------------------------------------------------
+
+AudioGroupInfo::AudioGroupInfo()
+ : TrackInfo()
+ {
+ grid->setRowStretch(grid->rowCount(), 100);
+ }
+
+//---------------------------------------------------------
+// AudioAuxInfo
+//---------------------------------------------------------
+
+AudioAuxInfo::AudioAuxInfo()
+ : TrackInfo()
+ {
+ grid->setRowStretch(grid->rowCount(), 100);
+ }
+
+//---------------------------------------------------------
+// WaveTrackInfo
+//---------------------------------------------------------
+
+WaveTrackInfo::WaveTrackInfo()
+ : TrackInfo()
+ {
+ grid->setRowStretch(grid->rowCount(), 100);
+ }
+
+//---------------------------------------------------------
+// SynthIInfo
+//---------------------------------------------------------
+
+SynthIInfo::SynthIInfo()
+ : TrackInfo()
+ {
+ grid->setRowStretch(grid->rowCount(), 100);
+ }
+
+//---------------------------------------------------------
+// MidiSynthIInfo
+//---------------------------------------------------------
+
+MidiSynthIInfo::MidiSynthIInfo()
+ : TrackInfo()
+ {
+ grid->setRowStretch(grid->rowCount(), 100);
+ }
+
+//---------------------------------------------------------
+// MidiOutPortInfo
+//---------------------------------------------------------
+
+MidiOutPortInfo::MidiOutPortInfo()
+ : TrackInfo()
+ {
+ QWidget* midiPortInfo = new QWidget;
+ mp.setupUi(midiPortInfo);
+ grid->addWidget(midiPortInfo, 2, 0, 1, 2);
+
+ grid->setRowStretch(grid->rowCount(), 100);
+
+ connect(mp.instrument, SIGNAL(activated(int)), SLOT(instrumentSelected(int)));
+ connect(mp.deviceId, SIGNAL(valueChanged(int)), SLOT(deviceIdChanged(int)));
+ }
+
+//---------------------------------------------------------
+// init
+//---------------------------------------------------------
+
+void MidiOutPortInfo::init(Track* t)
+ {
+ TrackInfo::init(t);
+
+ MidiOutPort* op = (MidiOutPort*)&*track;
+ MidiInstrument* mi = op->instrument();
+ int idx = 0;
+ int curIdx = 0;
+ mp.instrument->clear();
+ for (iMidiInstrument i = midiInstruments.begin(); i != midiInstruments.end(); ++i, ++idx) {
+ mp.instrument->addItem((*i)->iname());
+ if ((*i)->iname() == mi->iname())
+ curIdx = idx;
+ }
+ mp.instrument->setCurrentIndex(curIdx);
+ mp.deviceId->setValue(op->deviceId());
+ connect(t, SIGNAL(instrumentChanged()), SLOT(instrumentChanged()));
+ }
+
+//---------------------------------------------------------
+// deviceIdChanged
+//---------------------------------------------------------
+
+void MidiOutPortInfo::deviceIdChanged(int val)
+ {
+ ((MidiOutPort*)&*track)->setDeviceId(val);
+ }
+
+//---------------------------------------------------------
+// instrumentChanged
+//---------------------------------------------------------
+
+void MidiOutPortInfo::instrumentChanged()
+ {
+ MidiOutPort* op = (MidiOutPort*)&*track;
+ MidiInstrument* mi = op->instrument();
+ int idx = 0;
+ for (iMidiInstrument i = midiInstruments.begin(); i != midiInstruments.end(); ++i, ++idx) {
+ if (*i == mi) {
+ mp.instrument->setCurrentIndex(idx);
+ break;
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// instrumentSelected
+//---------------------------------------------------------
+
+void MidiOutPortInfo::instrumentSelected(int n)
+ {
+ MidiOutPort* op = (MidiOutPort*)&*track;
+ int idx = 0;
+ for (iMidiInstrument i = midiInstruments.begin(); i != midiInstruments.end(); ++i, ++idx) {
+ if (idx == n) {
+ op->setInstrument(*i);
+ break;
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// MidiInPortInfo
+//---------------------------------------------------------
+
+MidiInPortInfo::MidiInPortInfo()
+ : TrackInfo()
+ {
+ grid->setRowStretch(grid->rowCount(), 100);
+ }
+
diff --git a/muse_qt4_evolution/muse/trackinfo.h b/muse_qt4_evolution/muse/trackinfo.h
new file mode 100644
index 00000000..bea98d70
--- /dev/null
+++ b/muse_qt4_evolution/muse/trackinfo.h
@@ -0,0 +1,203 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __TRACKINFO_H__
+#define __TRACKINFO_H__
+
+#include "ui_miditrackinfo.h"
+#include "ui_midiportinfo.h"
+
+class Track;
+class MidiTrack;
+class AudioOutput;
+class AudioInput;
+class AudioGroup;
+class AudioAux;
+class SynthI;
+class MidiInPort;
+class MidiOutPort;
+class MidiChannel;
+class WaveTrack;
+class TLLineEdit;
+
+//---------------------------------------------------------
+// TrackInfo
+//---------------------------------------------------------
+
+class TrackInfo : public QWidget {
+ Q_OBJECT
+
+ QLabel* label;
+ TLLineEdit* name;
+
+ protected:
+ QGridLayout* grid;
+ QPointer<Track> track;
+
+ private slots:
+ void nameChanged(QString s);
+ void songChanged(int);
+
+ public:
+ TrackInfo();
+ virtual void init(Track*);
+ };
+
+//---------------------------------------------------------
+// MidiTrackInfo
+//---------------------------------------------------------
+
+class MidiTrackInfo : public TrackInfo {
+ Q_OBJECT
+
+ Ui::MidiTrackInfoBase mt;
+ Ui::MidiPortInfoBase mp;
+ QComboBox* port;
+ QComboBox* channel;
+ QMenu* pop;
+
+ private slots:
+ void transpositionChanged(int val);
+ void velocityChanged(int val);
+ void delayChanged(int val);
+ void lenChanged(int val);
+ void iKomprChanged(int val);
+ void patchClicked();
+ void instrumentSelected(int);
+ void instrumentChanged();
+ void autoChanged(Track*,bool);
+ void controllerChanged(int);
+ void portSelected(int);
+ void deviceIdChanged(int);
+
+ public:
+ MidiTrackInfo();
+ virtual void init(Track*);
+ };
+
+//---------------------------------------------------------
+// AudioOutputInfo
+//---------------------------------------------------------
+
+class AudioOutputInfo : public TrackInfo {
+ Q_OBJECT
+
+ public:
+ AudioOutputInfo();
+ };
+
+//---------------------------------------------------------
+// AudioInputInfo
+//---------------------------------------------------------
+
+class AudioInputInfo : public TrackInfo {
+ Q_OBJECT
+
+ public:
+ AudioInputInfo();
+ };
+
+//---------------------------------------------------------
+// AudioGroupInfo
+//---------------------------------------------------------
+
+class AudioGroupInfo : public TrackInfo {
+ Q_OBJECT
+
+ public:
+ AudioGroupInfo();
+ };
+
+//---------------------------------------------------------
+// AudioAuxInfo
+//---------------------------------------------------------
+
+class AudioAuxInfo : public TrackInfo {
+ Q_OBJECT
+
+ public:
+ AudioAuxInfo();
+ };
+
+//---------------------------------------------------------
+// WaveTrackInfo
+//---------------------------------------------------------
+
+class WaveTrackInfo : public TrackInfo {
+ Q_OBJECT
+
+ public:
+ WaveTrackInfo();
+ };
+
+//---------------------------------------------------------
+// SynthIInfo
+//---------------------------------------------------------
+
+class SynthIInfo : public TrackInfo {
+ Q_OBJECT
+
+ public:
+ SynthIInfo();
+ };
+
+//---------------------------------------------------------
+// MidiSynthIInfo
+//---------------------------------------------------------
+
+class MidiSynthIInfo : public TrackInfo {
+ Q_OBJECT
+
+ public:
+ MidiSynthIInfo();
+ };
+
+//---------------------------------------------------------
+// MidiOutPortInfo
+//---------------------------------------------------------
+
+class MidiOutPortInfo : public TrackInfo {
+ Q_OBJECT
+
+ Ui::MidiPortInfoBase mp;
+
+ private slots:
+ void instrumentSelected(int);
+ void instrumentChanged();
+ void deviceIdChanged(int);
+
+ public:
+ MidiOutPortInfo();
+ virtual void init(Track*);
+ };
+
+//---------------------------------------------------------
+// MidiInPortInfo
+//---------------------------------------------------------
+
+class MidiInPortInfo : public TrackInfo {
+ Q_OBJECT
+
+ public:
+ MidiInPortInfo();
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/transport.cpp b/muse_qt4_evolution/muse/transport.cpp
new file mode 100644
index 00000000..aa8fcc7c
--- /dev/null
+++ b/muse_qt4_evolution/muse/transport.cpp
@@ -0,0 +1,411 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "song.h"
+#include "transport.h"
+#include "widgets/doublelabel.h"
+#include "widgets/siglabel.h"
+#include "globals.h"
+#include "icons.h"
+#include "awl/posedit.h"
+#include "sync.h"
+#include "shortcuts.h"
+#include "gconfig.h"
+#include "muse.h"
+#include "al/sig.h"
+#include "al/tempo.h"
+
+static const char* recordTransportText = QT_TR_NOOP("Click this button to enable recording");
+static const char* stopTransportText = QT_TR_NOOP("Click this button to stop playback");
+static const char* playTransportText = QT_TR_NOOP("Click this button to start playback");
+static const char* startTransportText = QT_TR_NOOP("Click this button to rewind to start position");
+static const char* frewindTransportText = QT_TR_NOOP("Click this button to rewind");
+static const char* fforwardTransportText = QT_TR_NOOP("Click this button to forward current play position");
+
+//---------------------------------------------------------
+// Transport
+//---------------------------------------------------------
+
+Transport::Transport()
+ {
+ setupUi(this);
+
+ connect(recMode, SIGNAL(activated(int)), SLOT(setRecMode(int)));
+ connect(cycleMode, SIGNAL(activated(int)), SLOT(setCycleMode(int)));
+
+ //-----------------------------------------------------
+ // loop flags
+ //-----------------------------------------------------
+
+ connect(punchinButton, SIGNAL(toggled(bool)), song, SLOT(setPunchin(bool)));
+ connect(punchoutButton, SIGNAL(toggled(bool)), song, SLOT(setPunchout(bool)));
+ connect(loopButton, SIGNAL(toggled(bool)), song, SLOT(setLoop(bool)));
+
+ connect(song, SIGNAL(punchinChanged(bool)), punchinButton, SLOT(setChecked(bool)));
+ connect(song, SIGNAL(punchoutChanged(bool)), punchoutButton, SLOT(setChecked(bool)));
+ connect(song, SIGNAL(loopChanged(bool)), loopButton, SLOT(setChecked(bool)));
+
+ //-----------------------------------------------------
+ // Transport Buttons
+ //-----------------------------------------------------
+
+ time2->setSmpte(true);
+
+ buttons[0] = tb1;
+ tb1->setWhatsThis(tr(startTransportText));
+
+ buttons[1] = tb2;
+ tb2->setAutoRepeat(true);
+ tb2->setWhatsThis(tr(frewindTransportText));
+
+ buttons[2] = tb3;
+ tb3->setAutoRepeat(true);
+ tb3->setWhatsThis(tr(fforwardTransportText));
+
+ buttons[3] = tb4;
+ tb4->setChecked(true); // set STOP
+ tb4->setWhatsThis(tr(stopTransportText));
+
+ buttons[4] = tb5;
+ tb5->setWhatsThis(tr(playTransportText));
+
+ buttons[5] = tb6;
+ tb6->setIcon(*recordIcon);
+ tb6->setWhatsThis(tr(recordTransportText));
+
+ connect(buttons[0], SIGNAL(clicked()), song, SLOT(rewindStart()));
+ connect(buttons[1], SIGNAL(clicked()), song, SLOT(rewind()));
+ connect(buttons[2], SIGNAL(clicked()), song, SLOT(forward()));
+ connect(buttons[3], SIGNAL(clicked(bool)), SLOT(stopToggled(bool)));
+ connect(buttons[4], SIGNAL(clicked(bool)), SLOT(playToggled(bool)));
+ connect(buttons[5], SIGNAL(clicked(bool)), song, SLOT(setRecord(bool)));
+
+ connect(song, SIGNAL(recordChanged(bool)), SLOT(setRecord(bool)));
+
+ //-----------------------------------------------------
+ // AQ - Click - Sync
+ //-----------------------------------------------------
+
+//TODOB clickButton->setShortcut(shortcuts[SHRT_TOGGLE_METRO].key);
+
+ connect(quantizeButton, SIGNAL(clicked(bool)), song, SLOT(setQuantize(bool)));
+ connect(clickButton, SIGNAL(clicked(bool)), song, SLOT(setClick(bool)));
+ connect(syncButton, SIGNAL(clicked(bool)), SLOT(syncButtonClicked(bool)));
+//TD connect(&extSyncFlag, SIGNAL(valueChanged(bool)), SLOT(syncChanged(bool)));
+
+ connect(song, SIGNAL(quantizeChanged(bool)), this, SLOT(setQuantizeFlag(bool)));
+ connect(song, SIGNAL(clickChanged(bool)), clickButton, SLOT(setChecked(bool)));
+
+ //-----------------------------------------------------
+ // Tempo/Sig
+ //-----------------------------------------------------
+
+ connect(masterButton, SIGNAL(clicked(bool)), song, SLOT(setMasterFlag(bool)));
+
+ //-----------------------------------------------------
+
+ connect(tl1, SIGNAL(valueChanged(const Pos&)), SLOT(lposChanged(const Pos&)));
+ connect(tl2, SIGNAL(valueChanged(const Pos&)), SLOT(rposChanged(const Pos&)));
+ connect(time1, SIGNAL(valueChanged(const Pos&)), SLOT(cposChanged(const Pos&)));
+ connect(time2, SIGNAL(valueChanged(const Pos&)), SLOT(cposChanged(const Pos&)));
+
+ slider->setRange(0, song->len());
+ connect(song, SIGNAL(lenChanged(const AL::Pos&)), SLOT(setLen(const AL::Pos&)));
+ connect(slider,SIGNAL(sliderMoved(int)), SLOT(cposChanged(int)));
+ connect(song, SIGNAL(posChanged(int,const AL::Pos&, bool)), SLOT(setPos(int,const AL::Pos&)));
+ connect(tempo, SIGNAL(tempoChanged(int)), song, SLOT(setTempo(int)));
+ connect(song, SIGNAL(playChanged(bool)), SLOT(setPlay(bool)));
+ connect(song, SIGNAL(songChanged(int)), this, SLOT(songChanged(int)));
+ setValues();
+ }
+
+//---------------------------------------------------------
+// setValues
+//---------------------------------------------------------
+
+void Transport::setValues()
+ {
+ punchinButton->setChecked(song->punchin());
+ loopButton->setChecked(song->loop());
+ punchoutButton->setChecked(song->punchout());
+ quantizeButton->setChecked(song->quantize());
+ clickButton->setChecked(song->click());
+ syncButton->setChecked(extSyncFlag);
+ setPos(0, song->cpos());
+ setPos(1, song->lpos());
+ setPos(2, song->rpos());
+ }
+
+//---------------------------------------------------------
+// setLen
+// song len changed
+//---------------------------------------------------------
+
+void Transport::setLen(const AL::Pos& len)
+ {
+ slider->setRange(0, len.tick());
+ }
+
+//---------------------------------------------------------
+// setTimesig
+//---------------------------------------------------------
+
+void Transport::setTimesig(int /*z*/, int /*n*/)
+ {
+//TD tempo->setTimesig(z, n);
+ }
+
+//---------------------------------------------------------
+// setPos
+//---------------------------------------------------------
+
+void Transport::setPos(int idx, const AL::Pos& pos)
+ {
+ switch (idx) {
+ case 0:
+ time1->setValue(pos);
+ time2->setValue(pos);
+ slider->setValue(pos.tick());
+ {
+ int tp = AL::tempomap.tempo(pos.tick());
+ AL::TimeSignature sig = AL::sigmap.timesig(pos.tick());
+ int z = sig.z;
+ int n = sig.n;
+ setTimesig(z, n);
+ tempo->setTempo(tp);
+ }
+ break;
+ case 1:
+ tl1->setValue(pos);
+ break;
+ case 2:
+ tl2->setValue(pos);
+ break;
+ }
+ }
+
+//---------------------------------------------------------
+// cposChanged
+//---------------------------------------------------------
+
+void Transport::cposChanged(int tick)
+ {
+ song->setPos(0, tick);
+ }
+
+//---------------------------------------------------------
+// cposChanged
+//---------------------------------------------------------
+
+void Transport::cposChanged(const Pos& pos)
+ {
+ song->setPos(0, pos.tick());
+ }
+
+//---------------------------------------------------------
+// lposChanged
+//---------------------------------------------------------
+
+void Transport::lposChanged(const Pos& pos)
+ {
+ song->setPos(1, pos.tick());
+ }
+
+//---------------------------------------------------------
+// rposChanged
+//---------------------------------------------------------
+
+void Transport::rposChanged(const Pos& pos)
+ {
+ song->setPos(2, pos.tick());
+ }
+
+//---------------------------------------------------------
+// setPlay
+//---------------------------------------------------------
+
+void Transport::setPlay(bool f)
+ {
+ buttons[3]->setChecked(!f);
+ buttons[4]->setChecked(f);
+ }
+
+//---------------------------------------------------------
+// setMasterFlag
+//---------------------------------------------------------
+
+void Transport::setMasterFlag(bool f)
+ {
+ masterButton->setChecked(f);
+ }
+
+//---------------------------------------------------------
+// setQuantizeFlag
+//---------------------------------------------------------
+
+void Transport::setQuantizeFlag(bool f)
+ {
+ quantizeButton->setChecked(f);
+ }
+
+//---------------------------------------------------------
+// setSyncFlag
+//---------------------------------------------------------
+
+void Transport::setSyncFlag(bool f)
+ {
+ syncButton->setChecked(f);
+ }
+
+//---------------------------------------------------------
+// toggleRecMode
+//---------------------------------------------------------
+
+void Transport::setRecMode(int id)
+ {
+ song->setRecMode(id);
+ }
+
+//---------------------------------------------------------
+// toggleCycleMode
+//---------------------------------------------------------
+
+void Transport::setCycleMode(int id)
+ {
+ song->setCycleMode(id);
+ }
+
+//---------------------------------------------------------
+// songChanged
+//---------------------------------------------------------
+
+void Transport::songChanged(int flags)
+ {
+ int cpos = song->cpos();
+ if (flags & (SC_MASTER | SC_TEMPO)) {
+ if (extSyncFlag) {
+ tempo->setTempo(0);
+ }
+ else {
+ int t = AL::tempomap.tempo(cpos);
+ tempo->setTempo(t);
+ }
+ }
+ if (flags & SC_SIG) {
+ AL::TimeSignature sig = AL::sigmap.timesig(cpos);
+ int z = sig.z;
+ int n = sig.n;
+ setTimesig(z, n);
+ }
+ if (flags & SC_MASTER)
+ masterButton->setChecked(song->masterFlag());
+ }
+
+//---------------------------------------------------------
+// syncChanged
+//---------------------------------------------------------
+
+void Transport::syncChanged(bool flag)
+ {
+ syncButton->setChecked(flag);
+ buttons[0]->setEnabled(!flag); // goto start
+ buttons[1]->setEnabled(!flag); // rewind
+ buttons[2]->setEnabled(!flag); // forward
+ buttons[3]->setEnabled(!flag); // stop
+ buttons[4]->setEnabled(!flag); // play
+ slider->setEnabled(!flag);
+ masterButton->setEnabled(!flag);
+ if (flag) {
+ masterButton->setChecked(false);
+ song->setMasterFlag(false);
+ tempo->setValue(0); // slave mode: show "extern"
+ }
+ else
+ tempo->setValue(AL::tempomap.tempo(song->cpos()));
+ muse->playAction->setEnabled(!flag);
+ muse->startAction->setEnabled(!flag);
+ muse->stopAction->setEnabled(!flag);
+ muse->rewindAction->setEnabled(!flag);
+ muse->forwardAction->setEnabled(!flag);
+ }
+
+//---------------------------------------------------------
+// stopToggled
+//---------------------------------------------------------
+
+void Transport::stopToggled(bool val)
+ {
+ if (val)
+ song->setStop(true);
+ else {
+ buttons[3]->setChecked(true);
+ }
+ }
+
+//---------------------------------------------------------
+// playToggled
+//---------------------------------------------------------
+
+void Transport::playToggled(bool val)
+ {
+ if (val)
+ song->setPlay(true);
+ else {
+ buttons[4]->setChecked(true);
+ }
+ }
+
+//---------------------------------------------------------
+// setRecord
+//---------------------------------------------------------
+
+void Transport::setRecord(bool flag)
+ {
+ buttons[5]->setChecked(flag);
+ }
+
+//---------------------------------------------------------
+// syncButtonClicked
+//---------------------------------------------------------
+
+void Transport::syncButtonClicked(bool flag)
+ {
+ extSyncFlag = flag;
+ }
+
+//---------------------------------------------------------
+// syncChanged
+//---------------------------------------------------------
+
+void Transport::syncChanged()
+ {
+ syncButton->setChecked(extSyncFlag);
+ }
+
+//---------------------------------------------------------
+// closeEvent
+//---------------------------------------------------------
+
+void Transport::closeEvent(QCloseEvent *ev)
+ {
+ emit closed();
+ QWidget::closeEvent(ev);
+ }
+
diff --git a/muse_qt4_evolution/muse/transport.h b/muse_qt4_evolution/muse/transport.h
new file mode 100644
index 00000000..43acef24
--- /dev/null
+++ b/muse_qt4_evolution/muse/transport.h
@@ -0,0 +1,74 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __TRANSPORT_H__
+#define __TRANSPORT_H__
+
+#include "ui_transport.h"
+
+namespace AL {
+ class Pos;
+ };
+using AL::Pos;
+
+//---------------------------------------------------------
+// Transport
+//---------------------------------------------------------
+
+class Transport : public QWidget, public Ui::TransportBase
+ {
+ QToolButton* buttons[6]; // transport buttons
+ Q_OBJECT
+
+ virtual void closeEvent(QCloseEvent*);
+
+ private slots:
+ void cposChanged(const Pos&);
+ void cposChanged(int);
+ void lposChanged(const Pos&);
+ void rposChanged(const Pos&);
+ void setRecMode(int);
+ void setCycleMode(int);
+ void songChanged(int);
+ void syncChanged(bool);
+ void setRecord(bool flag);
+ void stopToggled(bool);
+ void playToggled(bool);
+ void setLen(const AL::Pos& len);
+
+ public slots:
+ void setTimesig(int a, int b);
+ void setPos(int idx, const AL::Pos& pos);
+ void setMasterFlag(bool);
+ void setQuantizeFlag(bool);
+ void setSyncFlag(bool);
+ void setPlay(bool f);
+ void syncButtonClicked(bool);
+ void syncChanged();
+
+ signals:
+ void closed();
+
+ public:
+ Transport();
+ void setValues();
+ };
+#endif
+
diff --git a/muse_qt4_evolution/muse/transport.ui b/muse_qt4_evolution/muse/transport.ui
new file mode 100644
index 00000000..a70992e9
--- /dev/null
+++ b/muse_qt4_evolution/muse/transport.ui
@@ -0,0 +1,856 @@
+<ui version="4.0" >
+ <author></author>
+ <comment></comment>
+ <exportmacro></exportmacro>
+ <class>TransportBase</class>
+ <widget class="QWidget" name="TransportBase" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>636</width>
+ <height>99</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle" >
+ <string>MusE: Transport Panel</string>
+ </property>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>1</number>
+ </property>
+ <property name="spacing" >
+ <number>1</number>
+ </property>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>3</number>
+ </property>
+ <property name="spacing" >
+ <number>2</number>
+ </property>
+ <item>
+ <widget class="QComboBox" name="recMode" >
+ <item>
+ <property name="text" >
+ <string>Overdub</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Replace</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label" >
+ <property name="font" >
+ <font>
+ <family>Sans Serif</family>
+ <pointsize>6</pointsize>
+ <weight>50</weight>
+ <italic>false</italic>
+ <bold>false</bold>
+ <underline>false</underline>
+ <strikeout>false</strikeout>
+ </font>
+ </property>
+ <property name="text" >
+ <string>Rec Mode</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="cycleMode" >
+ <item>
+ <property name="text" >
+ <string>Normal</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Mix</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Replace</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_2" >
+ <property name="font" >
+ <font>
+ <family>Sans Serif</family>
+ <pointsize>6</pointsize>
+ <weight>50</weight>
+ <italic>false</italic>
+ <bold>false</bold>
+ <underline>false</underline>
+ <strikeout>false</strikeout>
+ </font>
+ </property>
+ <property name="text" >
+ <string>Cycle Rec</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>2</number>
+ </property>
+ <property name="spacing" >
+ <number>2</number>
+ </property>
+ <item>
+ <widget class="QToolButton" name="punchinButton" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="icon" >
+ <iconset resource="muse.qrc" >:/xpm/punchin.xpm</iconset>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="loopButton" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>...</string>
+ </property>
+ <property name="icon" >
+ <iconset resource="muse.qrc" >:/xpm/loop.xpm</iconset>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="punchoutButton" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="icon" >
+ <iconset resource="muse.qrc" >:/xpm/punchout.xpm</iconset>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ <property name="toolButtonStyle" >
+ <enum>Qt::ToolButtonTextOnly</enum>
+ </property>
+ <property name="arrowType" >
+ <enum>Qt::NoArrow</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>2</number>
+ </property>
+ <property name="spacing" >
+ <number>2</number>
+ </property>
+ <item>
+ <widget class="Awl::PosEdit" name="tl1" />
+ </item>
+ <item>
+ <widget class="QLabel" name="label_3" >
+ <property name="font" >
+ <font>
+ <family>Sans Serif</family>
+ <pointsize>6</pointsize>
+ <weight>50</weight>
+ <italic>false</italic>
+ <bold>false</bold>
+ <underline>false</underline>
+ <strikeout>false</strikeout>
+ </font>
+ </property>
+ <property name="text" >
+ <string>Left Loc</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Awl::PosEdit" name="tl2" />
+ </item>
+ <item>
+ <widget class="QLabel" name="label_4" >
+ <property name="font" >
+ <font>
+ <family>Sans Serif</family>
+ <pointsize>6</pointsize>
+ <weight>50</weight>
+ <italic>false</italic>
+ <bold>false</bold>
+ <underline>false</underline>
+ <strikeout>false</strikeout>
+ </font>
+ </property>
+ <property name="text" >
+ <string>Right Loc</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>3</number>
+ </property>
+ <property name="spacing" >
+ <number>2</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="Awl::PosEdit" name="time1" />
+ </item>
+ <item>
+ <widget class="Awl::PosEdit" name="time2" />
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QSlider" name="slider" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>3</number>
+ </property>
+ <property name="spacing" >
+ <number>1</number>
+ </property>
+ <item>
+ <widget class="QToolButton" name="tb1" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>rewind to start</string>
+ </property>
+ <property name="text" >
+ <string>...</string>
+ </property>
+ <property name="icon" >
+ <iconset resource="muse.qrc" >:/xpm/start.xpm</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="tb2" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>rewind</string>
+ </property>
+ <property name="text" >
+ <string>...</string>
+ </property>
+ <property name="icon" >
+ <iconset resource="muse.qrc" >:/xpm/frewind.xpm</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="tb3" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>forward</string>
+ </property>
+ <property name="text" >
+ <string>...</string>
+ </property>
+ <property name="icon" >
+ <iconset resource="muse.qrc" >:/xpm/fforward.xpm</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="tb4" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>stop</string>
+ </property>
+ <property name="text" >
+ <string>...</string>
+ </property>
+ <property name="icon" >
+ <iconset resource="muse.qrc" >:/xpm/stop.xpm</iconset>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="tb5" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>play</string>
+ </property>
+ <property name="text" >
+ <string>...</string>
+ </property>
+ <property name="icon" >
+ <iconset resource="muse.qrc" >:/xpm/play.xpm</iconset>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="tb6" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>record</string>
+ </property>
+ <property name="text" >
+ <string>...</string>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>2</number>
+ </property>
+ <property name="spacing" >
+ <number>2</number>
+ </property>
+ <item>
+ <widget class="QToolButton" name="quantizeButton" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>AC</string>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="clickButton" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Click</string>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="syncButton" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Sync</string>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>5</number>
+ </property>
+ <property name="spacing" >
+ <number>1</number>
+ </property>
+ <item>
+ <widget class="QFrame" name="frame" >
+ <property name="frameShape" >
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>1</number>
+ </property>
+ <property name="spacing" >
+ <number>1</number>
+ </property>
+ <item>
+ <widget class="Awl::TempoEdit" name="tempo" />
+ </item>
+ <item>
+ <widget class="SigLabel" name="sig" >
+ <property name="palette" >
+ <palette>
+ <active>
+ <color>
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ <color>
+ <red>221</red>
+ <green>223</green>
+ <blue>228</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>85</red>
+ <green>85</green>
+ <blue>85</blue>
+ </color>
+ <color>
+ <red>199</red>
+ <green>199</green>
+ <blue>199</blue>
+ </color>
+ <color>
+ <red>199</red>
+ <green>199</green>
+ <blue>199</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>86</red>
+ <green>117</green>
+ <blue>148</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>238</blue>
+ </color>
+ <color>
+ <red>82</red>
+ <green>24</green>
+ <blue>139</blue>
+ </color>
+ <color>
+ <red>232</red>
+ <green>232</green>
+ <blue>232</blue>
+ </color>
+ </active>
+ <inactive>
+ <color>
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ <color>
+ <red>221</red>
+ <green>223</green>
+ <blue>228</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>85</red>
+ <green>85</green>
+ <blue>85</blue>
+ </color>
+ <color>
+ <red>199</red>
+ <green>199</green>
+ <blue>199</blue>
+ </color>
+ <color>
+ <red>199</red>
+ <green>199</green>
+ <blue>199</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>86</red>
+ <green>117</green>
+ <blue>148</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>238</blue>
+ </color>
+ <color>
+ <red>82</red>
+ <green>24</green>
+ <blue>139</blue>
+ </color>
+ <color>
+ <red>232</red>
+ <green>232</green>
+ <blue>232</blue>
+ </color>
+ </inactive>
+ <disabled>
+ <color>
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ <color>
+ <red>221</red>
+ <green>223</green>
+ <blue>228</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>85</red>
+ <green>85</green>
+ <blue>85</blue>
+ </color>
+ <color>
+ <red>199</red>
+ <green>199</green>
+ <blue>199</blue>
+ </color>
+ <color>
+ <red>199</red>
+ <green>199</green>
+ <blue>199</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>86</red>
+ <green>117</green>
+ <blue>148</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>238</blue>
+ </color>
+ <color>
+ <red>82</red>
+ <green>24</green>
+ <blue>139</blue>
+ </color>
+ <color>
+ <red>232</red>
+ <green>232</green>
+ <blue>232</blue>
+ </color>
+ </disabled>
+ </palette>
+ </property>
+ <property name="text" >
+ <string>4/4</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="masterButton" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>use tempo map</string>
+ </property>
+ <property name="text" >
+ <string>Tempomap</string>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ <property name="checked" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <pixmapfunction></pixmapfunction>
+ <customwidgets>
+ <customwidget>
+ <class>Awl::PosEdit</class>
+ <extends>QWidget</extends>
+ <header>awl/posedit.h</header>
+ <container>0</container>
+ <pixmap></pixmap>
+ </customwidget>
+ <customwidget>
+ <class>SigLabel</class>
+ <extends>QLabel</extends>
+ <header>widgets/siglabel.h</header>
+ <container>0</container>
+ <pixmap></pixmap>
+ </customwidget>
+ <customwidget>
+ <class>Awl::TempoEdit</class>
+ <extends>QWidget</extends>
+ <header>awl/tempoedit.h</header>
+ <container>0</container>
+ <pixmap></pixmap>
+ </customwidget>
+ </customwidgets>
+ <resources>
+ <include location="muse.qrc" />
+ </resources>
+ <connections/>
+</ui>
diff --git a/muse_qt4_evolution/muse/transpose.cpp b/muse_qt4_evolution/muse/transpose.cpp
new file mode 100644
index 00000000..73edb05a
--- /dev/null
+++ b/muse_qt4_evolution/muse/transpose.cpp
@@ -0,0 +1,92 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "transpose.h"
+#include "track.h"
+#include "song.h"
+#include "event.h"
+#include "audio.h"
+#include "part.h"
+
+//---------------------------------------------------------
+// Transpose
+//---------------------------------------------------------
+
+Transpose::Transpose(QWidget* parent)
+ : QDialog(parent)
+ {
+ setupUi(this);
+ if (song->lpos() != song->rpos()) {
+ time_selected->setChecked(true);
+ }
+ else {
+// time_all->setChecked(true);
+ ButtonGroup1->setEnabled(false);
+ }
+// parts_all->setSelected(true);
+ }
+
+//---------------------------------------------------------
+// accept
+//---------------------------------------------------------
+
+void Transpose::accept()
+ {
+ int left = 0, right = 0;
+ int dv = delta->value();
+
+ TrackList *tracks = song->tracks();
+
+ if (time_selected->isChecked()) {
+ left = song->lpos();
+ right = song->rpos();
+ }
+ else {
+ left = 0;
+ right = song->len();
+ }
+
+ song->startUndo();
+ for (iTrack t = tracks->begin(); t != tracks->end(); ++t) {
+ if (((*t)->type() != Track::MIDI)
+ || !(parts_all->isChecked() || (*t)->selected()))
+ continue;
+
+ PartList *pl = (*t)->parts();
+ for (iPart p = pl->begin(); p != pl->end(); ++p) {
+ Part *mp = p->second;
+ EventList* el = mp->events();
+ for (iEvent i = el->begin(); i != el->end(); ++i) {
+ Event oe = i->second;
+ int tick = oe.tick();
+ if (tick > right)
+ break;
+ if (tick < left)
+ continue;
+ Event ne = oe.clone();
+ ne.setA(oe.dataA() + dv );
+ audio->msgChangeEvent(oe, ne, mp, false);
+ }
+ }
+ }
+ song->endUndo(SC_EVENT_MODIFIED);
+ close();
+ }
+
diff --git a/muse_qt4_evolution/muse/transpose.h b/muse_qt4_evolution/muse/transpose.h
new file mode 100644
index 00000000..31b73865
--- /dev/null
+++ b/muse_qt4_evolution/muse/transpose.h
@@ -0,0 +1,40 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __TRANSPOSE_H__
+#define __TRANSPOSE_H__
+
+#include "ui_transpose.h"
+
+//---------------------------------------------------------
+// transpose widget
+//---------------------------------------------------------
+
+class Transpose : public QDialog, public Ui::TransposeDialogBase {
+ Q_OBJECT
+
+ private slots:
+ virtual void accept();
+
+ public:
+ Transpose(QWidget* parent=0);
+ };
+
+#endif
diff --git a/muse_qt4_evolution/muse/transpose.ui b/muse_qt4_evolution/muse/transpose.ui
new file mode 100644
index 00000000..de0bfe2e
--- /dev/null
+++ b/muse_qt4_evolution/muse/transpose.ui
@@ -0,0 +1,193 @@
+<ui version="4.0" >
+ <author></author>
+ <comment></comment>
+ <exportmacro></exportmacro>
+ <class>TransposeDialogBase</class>
+ <widget class="QDialog" name="TransposeDialogBase" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>289</width>
+ <height>317</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>MusE: Midi Transpose</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>11</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QGroupBox" name="GroupBox1" >
+ <property name="title" >
+ <string>Value</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>11</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QSpinBox" name="delta" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimum" >
+ <number>-99</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="TextLabel1" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>halftones</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="ButtonGroup1" >
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>11</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QRadioButton" name="time_all" >
+ <property name="text" >
+ <string>all</string>
+ </property>
+ <property name="checked" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="time_selected" >
+ <property name="text" >
+ <string>between markers</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="ButtonGroup2" >
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>11</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QRadioButton" name="parts_all" >
+ <property name="text" >
+ <string>all</string>
+ </property>
+ <property name="checked" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="parts_selected" >
+ <property name="windowTitle" >
+ <string/>
+ </property>
+ <property name="text" >
+ <string>all in selected tracks</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="okButton" >
+ <property name="text" >
+ <string>OK</string>
+ </property>
+ <property name="autoDefault" >
+ <bool>false</bool>
+ </property>
+ <property name="default" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="cancelButton" >
+ <property name="text" >
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11" />
+ <pixmapfunction>qPixmapFromMimeSource</pixmapfunction>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/muse_qt4_evolution/muse/trelement.h b/muse_qt4_evolution/muse/trelement.h
new file mode 100644
index 00000000..4c702ae2
--- /dev/null
+++ b/muse_qt4_evolution/muse/trelement.h
@@ -0,0 +1,63 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __TR_ELEMENT_H__
+#define __TR_ELEMENT_H__
+
+#include "track.h"
+
+//---------------------------------------------------------
+// TrElement
+// describes a configurable gui element of the
+// track list
+//---------------------------------------------------------
+
+enum {
+ TR_NAME, TR_MUTE, TR_OFF, TR_SOLO, TR_RECORD, TR_AREAD, TR_AWRITE,
+ TR_OCHANNEL, TR_MONITOR, TR_DRUMMAP, TR_INSTRUMENT, TR_PATCH
+ };
+
+struct TrElement {
+ int id;
+ int grp; // default group
+ const char* name;
+ int trackMask;
+
+ TrElement(int i, int g, const char* s, int m)
+ : id(i), grp(g), name(s), trackMask(m) {}
+ };
+
+//---------------------------------------------------------
+// TrGroup
+// TrElements are grouped
+//---------------------------------------------------------
+
+typedef std::list<const TrElement*> TrElementList;
+typedef TrElementList::iterator iTrElement;
+
+class TrGroupList : public std::list<TrElementList> {
+ };
+typedef TrGroupList::iterator iTrGroup;
+
+extern const TrElement trElements[];
+extern const int nTrElements;
+extern TrGroupList glist[Track::TRACK_TYPES];
+
+#endif
diff --git a/muse_qt4_evolution/muse/undo.cpp b/muse_qt4_evolution/muse/undo.cpp
new file mode 100644
index 00000000..383f7d33
--- /dev/null
+++ b/muse_qt4_evolution/muse/undo.cpp
@@ -0,0 +1,614 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "undo.h"
+#include "song.h"
+#include "globals.h"
+#include "al/tempo.h"
+#include "al/sig.h"
+#include "al/sig.h"
+#include "part.h"
+
+// iundo points to last Undo() in Undo-list
+
+static bool undoMode = false; // for debugging
+std::list<QString> temporaryWavFiles;
+
+//---------------------------------------------------------
+// typeName
+//---------------------------------------------------------
+
+const char* UndoOp::typeName()
+ {
+ static const char* name[] = {
+ "AddTrack", "DeleteTrack", "RenameTrack",
+ "AddPart", "DeletePart", "ModifyPart",
+ "AddEvent", "DeleteEvent", "ModifyEvent",
+ "AddTempo", "DeleteTempo",
+ "AddSig", "DeleteSig",
+ "SwapTrack",
+ "ModifyClip",
+ "AddCtrl", "RemoveCtrl", "ModifyCtrl"
+ };
+ return name[type];
+ }
+
+//---------------------------------------------------------
+// dump
+//---------------------------------------------------------
+
+void UndoOp::dump()
+ {
+ printf("UndoOp: %s\n ", typeName());
+ switch(type) {
+ case AddTrack:
+ case DeleteTrack:
+ printf("%d %s\n", id, track->name().toLatin1().data());
+ break;
+ case AddPart:
+ case DeletePart:
+ case ModifyPart:
+ break;
+ case AddEvent:
+ case DeleteEvent:
+ printf("old event:\n");
+ oEvent.dump(5);
+ printf(" new event:\n");
+ nEvent.dump(5);
+ printf(" Part:\n");
+ if (part)
+ part->dump(5);
+ break;
+ case ModifyEvent:
+ case AddTempo:
+ case DeleteTempo:
+ case AddSig:
+ case DeleteSig:
+ case SwapTrack:
+ case AddCtrl:
+ case RemoveCtrl:
+ case ModifyCtrl:
+ case RenameTrack:
+ case ModifyClip:
+ break;
+ }
+ }
+
+//---------------------------------------------------------
+// startUndo
+//---------------------------------------------------------
+
+void Song::startUndo()
+ {
+ undoList->push_back(Undo());
+ updateFlags = 0;
+ undoMode = true;
+ }
+
+//---------------------------------------------------------
+// endUndo
+//---------------------------------------------------------
+
+void Song::endUndo(int flags)
+ {
+ updateFlags |= flags;
+ endMsgCmd();
+ undoMode = false;
+ }
+
+//---------------------------------------------------------
+// doUndo2
+// real time part
+//---------------------------------------------------------
+
+void Song::doUndo2()
+ {
+ Undo& u = undoList->back();
+
+// printf("doUndo2\n");
+ for (riUndoOp i = u.rbegin(); i != u.rend(); ++i) {
+// printf(" doUndo2 %s\n", i->typeName());
+ switch(i->type) {
+ case UndoOp::AddTrack:
+ removeTrack2(i->track);
+ updateFlags |= SC_TRACK_REMOVED;
+ break;
+ case UndoOp::DeleteTrack:
+ insertTrack2(i->track);
+ updateFlags |= SC_TRACK_INSERTED;
+ break;
+ case UndoOp::SwapTrack:
+ {
+ updateFlags |= SC_TRACK_MODIFIED;
+ Track* track = _tracks[i->a];
+ _tracks[i->a] = _tracks[i->b];
+ _tracks[i->b] = track;
+ updateFlags |= SC_TRACK_MODIFIED;
+ }
+ break;
+ case UndoOp::RenameTrack:
+ i->track->setName(*(i->os));
+ break;
+ case UndoOp::AddPart:
+ {
+ Part* part = i->oPart;
+ part->track()->parts()->remove(part);
+ updateFlags |= SC_PART_REMOVED;
+ part->deref();
+ }
+ break;
+ case UndoOp::DeletePart:
+ i->oPart->track()->addPart(i->oPart);
+ updateFlags |= SC_PART_INSERTED;
+ i->oPart->ref();
+ break;
+ case UndoOp::ModifyPart:
+ {
+ Part* oldPart = i->oPart;
+ Part* newPart = i->nPart;
+ Part part = *newPart;
+ *newPart = *oldPart;
+ *oldPart = part;
+// oldPart->deref();
+// newPart->ref();
+ updateFlags |= SC_PART_MODIFIED;
+ }
+ break;
+ case UndoOp::AddEvent:
+ deleteEvent(i->nEvent, i->part);
+ updateFlags |= SC_EVENT_REMOVED;
+ break;
+ case UndoOp::DeleteEvent:
+ addEvent(i->nEvent, i->part);
+ updateFlags |= SC_EVENT_INSERTED;
+ break;
+ case UndoOp::ModifyEvent:
+ updateFlags |= SC_EVENT_MODIFIED;
+ changeEvent(i->oEvent, i->nEvent, i->part);
+ break;
+ case UndoOp::AddTempo:
+ AL::tempomap.delTempo(i->a);
+ updateFlags |= SC_TEMPO;
+ break;
+ case UndoOp::DeleteTempo:
+ AL::tempomap.addTempo(i->a, i->b);
+ updateFlags |= SC_TEMPO;
+ break;
+ case UndoOp::AddSig:
+ AL::sigmap.del(i->a);
+ updateFlags |= SC_SIG;
+ break;
+ case UndoOp::DeleteSig:
+ AL::sigmap.add(i->a, AL::TimeSignature(i->b, i->c));
+ updateFlags |= SC_SIG;
+ break;
+ case UndoOp::AddCtrl:
+ i->track->removeControllerVal(i->id, i->time);
+ break;
+ case UndoOp::RemoveCtrl:
+ i->track->addControllerVal(i->id, i->time, i->cval1);
+ break;
+ case UndoOp::ModifyCtrl:
+ i->track->addControllerVal(i->id, i->time, i->cval2);
+ break;
+ case UndoOp::ModifyClip:
+ break;
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// Song::doRedo2
+//---------------------------------------------------------
+
+void Song::doRedo2()
+ {
+ Undo& u = redoList->back();
+// printf("doRedo2\n");
+ for (iUndoOp i = u.begin(); i != u.end(); ++i) {
+// printf(" doRedo2 %s\n", i->typeName());
+ switch(i->type) {
+ case UndoOp::AddTrack:
+ insertTrack2(i->track);
+ updateFlags |= SC_TRACK_INSERTED;
+ break;
+ case UndoOp::DeleteTrack:
+ removeTrack2(i->track);
+ updateFlags |= SC_TRACK_REMOVED;
+ break;
+ case UndoOp::SwapTrack:
+ {
+ Track* track = _tracks[i->a];
+ _tracks[i->a] = _tracks[i->b];
+ _tracks[i->b] = track;
+ updateFlags |= SC_TRACK_MODIFIED;
+ }
+ break;
+ case UndoOp::RenameTrack:
+ i->track->setName(*(i->ns));
+ break;
+ case UndoOp::AddPart:
+ i->oPart->track()->addPart(i->oPart);
+ updateFlags |= SC_PART_INSERTED;
+ i->oPart->ref();
+ break;
+ case UndoOp::DeletePart:
+ {
+ Part* part = i->oPart;
+ part->track()->parts()->remove(part);
+ updateFlags |= SC_PART_REMOVED;
+ part->deref();
+ }
+ break;
+ case UndoOp::ModifyPart:
+ {
+ Part* oldPart = i->oPart;
+ Part* newPart = i->nPart;
+ Part part = *newPart;
+ *newPart = *oldPart;
+ *oldPart = part;
+ updateFlags |= SC_PART_MODIFIED;
+// oldPart->ref();
+// newPart->deref();
+ }
+ break;
+ case UndoOp::AddEvent:
+ addEvent(i->nEvent, i->part);
+ updateFlags |= SC_EVENT_INSERTED;
+ break;
+ case UndoOp::DeleteEvent:
+ deleteEvent(i->nEvent, i->part);
+ updateFlags |= SC_EVENT_REMOVED;
+ break;
+ case UndoOp::ModifyEvent:
+ changeEvent(i->nEvent, i->oEvent, i->part);
+ updateFlags |= SC_EVENT_MODIFIED;
+ break;
+ case UndoOp::AddTempo:
+ AL::tempomap.addTempo(i->a, i->b);
+ updateFlags |= SC_TEMPO;
+ break;
+ case UndoOp::DeleteTempo:
+ AL::tempomap.delTempo(i->a);
+ updateFlags |= SC_TEMPO;
+ break;
+ case UndoOp::AddSig:
+ AL::sigmap.add(i->a, AL::TimeSignature(i->b, i->c));
+ updateFlags |= SC_SIG;
+ break;
+ case UndoOp::DeleteSig:
+ //printf("doRedo: UndoOp::DeleteSig. Deleting sigmap at: %d, z=%d n=%d\n", i->a, i->b, i->c);
+ AL::sigmap.del(i->a);
+ updateFlags |= SC_SIG;
+ break;
+ case UndoOp::AddCtrl:
+ i->track->addControllerVal(i->id, i->time, i->cval1);
+ break;
+ case UndoOp::RemoveCtrl:
+ i->track->removeControllerVal(i->id, i->time);
+ break;
+ case UndoOp::ModifyCtrl:
+ i->track->addControllerVal(i->id, i->time, i->cval1);
+ break;
+ case UndoOp::ModifyClip:
+ break;
+ }
+ }
+ }
+
+void Song::undoOp(UndoOp::UndoType type, int a, int b, int c)
+ {
+ UndoOp i;
+ i.type = type;
+ i.a = a;
+ i.b = b;
+ i.c = c;
+ addUndo(i);
+ }
+
+void Song::undoOp(UndoOp::UndoType type, int n, Track* track)
+ {
+ UndoOp i;
+ i.type = type;
+ i.id = n;
+ i.track = track;
+ if (type == UndoOp::AddTrack)
+ updateFlags |= SC_TRACK_INSERTED;
+ addUndo(i);
+ }
+
+void Song::undoOp(UndoOp::UndoType type, Part* part)
+ {
+ UndoOp i;
+ i.type = type;
+ i.oPart = part;
+ addUndo(i);
+ }
+
+void Song::undoOp(UndoOp::UndoType type, const Event& oev, const Event& nev, Part* part)
+ {
+ UndoOp i;
+ i.type = type;
+ i.nEvent = nev;
+ i.oEvent = oev;
+ i.part = part;
+ addUndo(i);
+ }
+
+void Song::undoOp(UndoOp::UndoType type, const Event& nev, Part* part)
+ {
+ UndoOp i;
+ i.type = type;
+ i.nEvent = nev;
+ i.part = part;
+ addUndo(i);
+ }
+
+void Song::undoOp(UndoOp::UndoType type, Part* oPart, Part* nPart)
+ {
+ UndoOp i;
+ i.type = type;
+ i.oPart = nPart;
+ i.nPart = oPart;
+ addUndo(i);
+ }
+
+void Song::undoOp(UndoOp::UndoType type, SigEvent* oevent, SigEvent* nevent)
+ {
+ UndoOp i;
+ i.type = type;
+ i.oSignature = oevent;
+ i.nSignature = nevent;
+ addUndo(i);
+ }
+
+void Song::undoOp(UndoOp::UndoType type, Track* t, int id, unsigned time, CVal nval, CVal oval)
+ {
+ UndoOp i;
+ i.type = type;
+ i.track = t;
+ i.id = id;
+ i.time = time;
+ i.cval1 = nval;
+ i.cval2 = oval;
+ addUndo(i);
+ }
+
+void Song::undoOp(UndoOp::UndoType type, Track* t, const QString& s1, const QString& s2)
+ {
+ UndoOp i;
+ i.type = type;
+ i.track = t;
+ i.os = new QString(s1);
+ i.ns = new QString(s2);
+ addUndo(i);
+ }
+
+void Song::undoOp(UndoOp::UndoType type, const char* changedFile, const char* changeData, int startframe, int endframe)
+ {
+ UndoOp i;
+ i.type = type;
+ i.filename = changedFile;
+ i.tmpwavfile = changeData;
+ i.startframe = startframe;
+ i.endframe = endframe;
+ addUndo(i);
+ temporaryWavFiles.push_back(QString(changeData));
+
+ printf("Adding ModifyClip undo-operation: origfile=%s tmpfile=%s sf=%d ef=%d\n", changedFile, changeData, startframe, endframe);
+ }
+
+//---------------------------------------------------------
+// addUndo
+//---------------------------------------------------------
+
+void Song::addUndo(UndoOp& i)
+ {
+ if (!undoMode) {
+ printf("internal error: undoOp without startUndo()\n");
+abort();
+ return;
+ }
+ undoList->back().push_back(i);
+ dirty = true;
+ }
+
+//---------------------------------------------------------
+// doUndo1
+// non realtime context
+// return true if nothing to do
+//---------------------------------------------------------
+
+bool Song::doUndo1()
+ {
+ if (undoList->empty())
+ return true;
+// printf("doUndo1\n");
+ Undo& u = undoList->back();
+ for (riUndoOp i = u.rbegin(); i != u.rend(); ++i) {
+// printf(" doUndo1 %s\n", i->typeName());
+ switch(i->type) {
+ case UndoOp::AddTrack:
+ removeTrack1(i->track);
+ break;
+ case UndoOp::DeleteTrack:
+ insertTrack1(i->track, i->id);
+ break;
+ case UndoOp::ModifyClip:
+ SndFile::applyUndoFile(i->filename, i->tmpwavfile, i->startframe, i->endframe);
+ break;
+ default:
+ break;
+ }
+ }
+ return false;
+ }
+
+//---------------------------------------------------------
+// doUndo3
+// non realtime context after realtime operation
+//---------------------------------------------------------
+
+void Song::doUndo3()
+ {
+// printf("doUndo3\n");
+ Undo& u = undoList->back();
+ for (riUndoOp i = u.rbegin(); i != u.rend(); ++i) {
+// printf(" doUndo3 %s\n", i->typeName());
+ switch(i->type) {
+ case UndoOp::AddTrack:
+ removeTrack3(i->track);
+ break;
+ case UndoOp::DeleteTrack:
+ emit trackAdded(i->track, i->id);
+ if (i->track->selected()) {
+ i->track->setSelected(false);
+ selectTrack(i->track);
+ }
+ break;
+ case UndoOp::ModifyPart:
+ undoPartModify(i->oPart, i->nPart, true);
+
+ case UndoOp::AddPart:
+ case UndoOp::DeletePart:
+ i->oPart->track()->partListChanged();
+ break;
+ case UndoOp::AddCtrl:
+ case UndoOp::RemoveCtrl:
+ case UndoOp::ModifyCtrl:
+ i->track->emitControllerChanged(i->id);
+ break;
+ default:
+ break;
+ }
+ }
+ redoList->push_back(u); // put item on redo list
+ undoList->pop_back();
+ dirty = true;
+ }
+
+//---------------------------------------------------------
+// doRedo1
+// non realtime context
+// return true if nothing to do
+//---------------------------------------------------------
+
+bool Song::doRedo1()
+ {
+ if (redoList->empty())
+ return true;
+// printf("doRedo1\n");
+ Undo& u = redoList->back();
+ for (iUndoOp i = u.begin(); i != u.end(); ++i) {
+// printf(" doRedo1 %s\n", i->typeName());
+ switch(i->type) {
+ case UndoOp::AddTrack:
+ insertTrack1(i->track, i->id);
+ break;
+ case UndoOp::DeleteTrack:
+ removeTrack1(i->track);
+ break;
+ case UndoOp::ModifyClip:
+ SndFile::applyUndoFile(i->filename, i->tmpwavfile, i->startframe, i->endframe);
+ break;
+ case UndoOp::AddCtrl:
+ case UndoOp::RemoveCtrl:
+ default:
+ break;
+ }
+ }
+ return false;
+ }
+
+//---------------------------------------------------------
+// doRedo3
+// non realtime context
+//---------------------------------------------------------
+
+void Song::doRedo3()
+ {
+// printf("doRedo3\n");
+ Undo& u = redoList->back();
+ for (iUndoOp i = u.begin(); i != u.end(); ++i) {
+// printf(" doRedo3 %s\n", i->typeName());
+ switch(i->type) {
+ case UndoOp::AddTrack:
+ emit trackAdded(i->track, i->id);
+ break;
+ case UndoOp::DeleteTrack:
+ removeTrack3(i->track);
+ break;
+ case UndoOp::ModifyPart:
+ undoPartModify(i->oPart, i->nPart, false);
+
+ case UndoOp::AddPart:
+ case UndoOp::DeletePart:
+ i->oPart->track()->partListChanged();
+ break;
+ case UndoOp::AddCtrl:
+ case UndoOp::RemoveCtrl:
+ case UndoOp::ModifyCtrl:
+ i->track->emitControllerChanged(i->id);
+ break;
+ default:
+ break;
+ }
+ }
+ undoList->push_back(u); // put item on undo list
+ redoList->pop_back();
+ dirty = true;
+ }
+
+//---------------------------------------------------------
+// undoPartModify
+//---------------------------------------------------------
+
+void Song::undoPartModify(Part* oPart, Part* nPart, bool undo)
+ {
+ if (oPart->track() != nPart->track())
+ nPart->track()->partListChanged();
+ //
+ // look for cloned part
+ //
+ for (iMidiTrack i = _midis.begin(); i != _midis.end(); ++i) {
+ PartList* pl = (*i)->parts();
+ for (iPart ip = pl->begin(); ip != pl->end(); ++ip) {
+ Part* p = ip->second;
+ if (undo) {
+ if (p == nPart)
+ continue;
+ if (p->events() == nPart->events()) {
+ // this is a cloned Part
+ p->ref();
+ return;
+ }
+ }
+ else {
+ if (p == oPart)
+ continue;
+ if (p->events() == oPart->events()) {
+ p->deref();
+ return;
+ }
+ }
+ }
+ }
+ }
+
diff --git a/muse_qt4_evolution/muse/undo.h b/muse_qt4_evolution/muse/undo.h
new file mode 100644
index 00000000..620199bb
--- /dev/null
+++ b/muse_qt4_evolution/muse/undo.h
@@ -0,0 +1,103 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __UNDO_H__
+#define __UNDO_H__
+
+#include "event.h"
+#include "ctrl.h"
+
+class Track;
+class TEvent;
+class SigEvent;
+class Part;
+
+extern std::list<QString> temporaryWavFiles; //!< Used for storing all tmp-files, for cleanup on shutdown
+
+//---------------------------------------------------------
+// UndoOp
+//---------------------------------------------------------
+
+struct UndoOp {
+ enum UndoType {
+ AddTrack, DeleteTrack, RenameTrack,
+ AddPart, DeletePart, ModifyPart,
+ AddEvent, DeleteEvent, ModifyEvent,
+ AddTempo, DeleteTempo,
+ AddSig, DeleteSig,
+ SwapTrack,
+ ModifyClip,
+ AddCtrl, RemoveCtrl, ModifyCtrl
+ };
+ UndoType type;
+
+ union {
+ struct {
+ int a;
+ int b;
+ int c;
+ };
+ struct {
+ Part* oPart;
+ Part* nPart;
+ };
+ struct {
+ Part* part;
+ };
+ struct {
+ SigEvent* nSignature;
+ SigEvent* oSignature;
+ };
+ struct {
+ int startframe; //!< Start frame of changed data
+ int endframe; //!< End frame of changed data
+ const char* filename; //!< The file that is changed
+ const char* tmpwavfile; //!< The file with the changed data
+ };
+ struct {
+ Track* track;
+ int id;
+ unsigned time;
+ CVal cval1, cval2;
+ QString* os;
+ QString* ns;
+ };
+ };
+ Event oEvent;
+ Event nEvent;
+ const char* typeName();
+ void dump();
+ };
+
+class Undo : public std::list<UndoOp> {
+ void undoOp(UndoOp::UndoType, int data);
+ };
+
+typedef Undo::iterator iUndoOp;
+typedef Undo::reverse_iterator riUndoOp;
+
+class UndoList : public std::list<Undo> {
+ public:
+ };
+
+typedef UndoList::iterator iUndo;
+
+
+#endif // __UNDO_H__
diff --git a/muse_qt4_evolution/muse/value.cpp b/muse_qt4_evolution/muse/value.cpp
new file mode 100644
index 00000000..9434d192
--- /dev/null
+++ b/muse_qt4_evolution/muse/value.cpp
@@ -0,0 +1,73 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "value.h"
+#include "al/xml.h"
+
+IValue::IValue(QObject* parent, const char* name)
+ : QObject(parent)
+ {
+ setObjectName(name);
+ }
+BValue::BValue(QObject* parent, const char* name)
+ : QObject(parent)
+ {
+ setObjectName(name);
+ }
+
+//---------------------------------------------------------
+// save
+//---------------------------------------------------------
+
+void BValue::save(Xml& xml)
+ {
+ xml.intTag(objectName().toLatin1().data(), val);
+ }
+
+//---------------------------------------------------------
+// save
+//---------------------------------------------------------
+
+void IValue::save(Xml& xml)
+ {
+ xml.intTag(objectName().toLatin1().data(), val);
+ }
+
+//---------------------------------------------------------
+// setValue
+//---------------------------------------------------------
+
+void BValue::setValue(bool v)
+ {
+ if (val != v) {
+ val = v;
+ emit valueChanged(val);
+ emit valueChanged(int(val));
+ }
+ }
+
+void IValue::setValue(int v)
+ {
+ if (val != v) {
+ val = v;
+ emit valueChanged(val);
+ }
+ }
+
diff --git a/muse_qt4_evolution/muse/vst.cpp b/muse_qt4_evolution/muse/vst.cpp
new file mode 100644
index 00000000..f91d1322
--- /dev/null
+++ b/muse_qt4_evolution/muse/vst.cpp
@@ -0,0 +1,1063 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+// This code is based on jack_fst:
+// Copyright (C) 2004 Paul Davis <paul@linuxaudiosystems.com>
+// Torben Hohn <torbenh@informatik.uni-bremen.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "config.h"
+
+#ifdef VST_SUPPORT
+
+#include "al/al.h"
+#include <fst.h>
+#include <vst/aeffectx.h>
+#include <jack/jack.h>
+
+#include "vst.h"
+#include "globals.h"
+#include "synth.h"
+#include "jackaudio.h"
+#include "midi.h"
+#include "al/xml.h"
+#include "song.h"
+#include "audio.h"
+#include "widgets/utils.h"
+
+extern "C" void fst_error(const char *fmt, ...);
+extern JackAudio* jackAudio;
+
+//---------------------------------------------------------
+// jfstReserveMem
+//---------------------------------------------------------
+
+static void jfstReserveMem(int size)
+ {
+ char buf[size];
+
+ for (int i = 0; i < size; ++i)
+ buf[i] = (char)(i % 256);
+ }
+
+//---------------------------------------------------------
+// vstHostCallback
+//---------------------------------------------------------
+
+static long vstHostCallback(AEffect* effect,
+ long opcode, long index, long value, void* ptr, float opt)
+ {
+ static VstTimeInfo _timeInfo;
+
+ VstPluginIF* pluginIF = effect ? (VstPluginIF*) effect->user : 0;
+
+ jack_position_t jack_pos;
+ jack_transport_state_t tstate;
+
+ switch (opcode) {
+ case audioMasterAutomate:
+ // index, value, returns 0
+ if (pluginIF) {
+ PluginI* pi = pluginIF->pluginInstance();
+ // pi->setParam(index, opt);
+ CVal cval;
+ cval.f = opt;
+ song->setControllerVal(pi->track(), pi->controller(index), cval);
+ }
+ return 0;
+
+ case audioMasterVersion:
+ // vst version, currently 2 (0 for older)
+ return 2200;
+
+ case audioMasterCurrentId:
+ // returns the unique id of a plug that's currently
+ // loading
+ return 0;
+
+ case audioMasterIdle:
+ // call application idle routine (this will
+ // call effEditIdle for all open editors too)
+ effect->dispatcher(effect, effEditIdle, 0, 0, NULL, 0.0f);
+ return 0;
+
+ case audioMasterPinConnected:
+ // inquire if an input or output is beeing connected;
+ // index enumerates input or output counting from zero:
+ // value is 0 for input and != 0 otherwise. note: the
+ // return value is 0 for <true> such that older versions
+ // will always return true.
+ return 1;
+
+ case audioMasterWantMidi:
+ // <value> is a filter which is currently ignored
+ return 0;
+
+ case audioMasterGetTime:
+ // returns const VstTimeInfo* (or 0 if not supported)
+ // <value> should contain a mask indicating which fields are required
+ // (see valid masks above), as some items may require extensive
+ // conversions
+
+ memset(&_timeInfo, 0, sizeof(_timeInfo));
+
+ if (effect) {
+ tstate = jackAudio->transportQuery(&jack_pos);
+
+ _timeInfo.samplePos = jack_pos.frame;
+ _timeInfo.sampleRate = jack_pos.frame_rate;
+ _timeInfo.flags = 0;
+
+ if ((value & (kVstBarsValid|kVstTempoValid)) && (jack_pos.valid & JackPositionBBT)) {
+ _timeInfo.tempo = jack_pos.beats_per_minute;
+ _timeInfo.timeSigNumerator = (long) floor (jack_pos.beats_per_bar);
+ _timeInfo.timeSigDenominator = (long) floor (jack_pos.beat_type);
+ _timeInfo.flags |= (kVstBarsValid|kVstTempoValid);
+ }
+ if (tstate == JackTransportRolling) {
+ _timeInfo.flags |= kVstTransportPlaying;
+ }
+ }
+ else {
+ _timeInfo.samplePos = 0;
+ _timeInfo.sampleRate = AL::sampleRate;
+ }
+ return (long)&_timeInfo;
+
+ case audioMasterProcessEvents:
+ // VstEvents* in <ptr>
+ return 0;
+
+ case audioMasterSetTime:
+ // VstTimenfo* in <ptr>, filter in <value>, not supported
+
+ case audioMasterTempoAt:
+ // returns tempo (in bpm * 10000) at sample frame location passed in <value>
+ return 0;
+
+ case audioMasterGetNumAutomatableParameters:
+ return 0;
+
+ case audioMasterGetParameterQuantization:
+ // returns the integer value for +1.0 representation,
+ // or 1 if full single float precision is maintained
+ // in automation. parameter index in <value> (-1: all, any)
+ return 0;
+
+ case audioMasterIOChanged:
+ // numInputs and/or numOutputs has changed
+ return 0;
+
+ case audioMasterNeedIdle:
+ // plug needs idle calls (outside its editor window)
+ return 0;
+
+ case audioMasterSizeWindow:
+ // index: width, value: height
+ return 0;
+
+ case audioMasterGetSampleRate:
+ return 0;
+
+ case audioMasterGetBlockSize:
+ return 0;
+
+ case audioMasterGetInputLatency:
+ return 0;
+
+ case audioMasterGetOutputLatency:
+ return 0;
+
+ case audioMasterGetPreviousPlug:
+ // input pin in <value> (-1: first to come), returns cEffect*
+ return 0;
+
+ case audioMasterGetNextPlug:
+ // output pin in <value> (-1: first to come), returns cEffect*
+
+ case audioMasterWillReplaceOrAccumulate:
+ // returns: 0: not supported, 1: replace, 2: accumulate
+ return 0;
+
+ case audioMasterGetCurrentProcessLevel:
+ // returns: 0: not supported,
+ // 1: currently in user thread (gui)
+ // 2: currently in audio thread (where process is called)
+ // 3: currently in 'sequencer' thread (midi, timer etc)
+ // 4: currently offline processing and thus in user thread
+ // other: not defined, but probably pre-empting user thread.
+ return 0;
+
+ case audioMasterGetAutomationState:
+ // returns 0: not supported, 1: off, 2:read, 3:write, 4:read/write
+ // offline
+ return 0;
+
+ case audioMasterOfflineStart:
+ case audioMasterOfflineRead:
+ // ptr points to offline structure, see below. return 0: error, 1 ok
+ return 0;
+
+ case audioMasterOfflineWrite:
+ // same as read
+ return 0;
+
+ case audioMasterOfflineGetCurrentPass:
+ case audioMasterOfflineGetCurrentMetaPass:
+ return 0;
+
+ case audioMasterSetOutputSampleRate:
+ // for variable i/o, sample rate in <opt>
+ return 0;
+
+ case audioMasterGetSpeakerArrangement:
+ // (long)input in <value>, output in <ptr>
+ return 0;
+
+ case audioMasterGetVendorString:
+ // fills <ptr> with a string identifying the vendor (max 64 char)
+ strcpy ((char*) ptr, "LAD");
+ return 0;
+
+ case audioMasterGetProductString:
+ // fills <ptr> with a string with product name (max 64 char)
+ strcpy ((char*) ptr, "FreeST");
+
+ case audioMasterGetVendorVersion:
+ // returns vendor-specific version
+ return 1000;
+
+ case audioMasterVendorSpecific:
+ // no definition, vendor specific handling
+ return 0;
+
+ case audioMasterSetIcon:
+ // void* in <ptr>, format not defined yet
+ return 0;
+
+ case audioMasterCanDo:
+ // string in ptr, see below
+ return 0;
+
+ case audioMasterGetLanguage:
+ // see enum
+ return 0;
+
+ case audioMasterOpenWindow:
+ // returns platform specific ptr
+ return 0;
+
+ case audioMasterCloseWindow:
+ // close window, platform specific handle in <ptr>
+ return 0;
+
+ case audioMasterGetDirectory:
+ // get plug directory, FSSpec on MAC, else char*
+ return 0;
+
+ case audioMasterUpdateDisplay:
+ // something has changed, update 'multi-fx' display
+ effect->dispatcher(effect, effEditIdle, 0, 0, NULL, 0.0f);
+ return 0;
+
+ case audioMasterBeginEdit:
+ // begin of automation session (when mouse down), parameter index in <index>
+ return 0;
+
+ case audioMasterEndEdit:
+ // end of automation session (when mouse up), parameter index in <index>
+ return 0;
+
+ case audioMasterOpenFileSelector:
+ // open a fileselector window with VstFileSelect* in <ptr>
+ return 0;
+
+ default:
+ break;
+ }
+ return 0;
+ }
+
+
+//---------------------------------------------------------
+// FstPlugin
+//---------------------------------------------------------
+
+FstPlugin::FstPlugin()
+ {
+ _fst = 0;
+ }
+
+//---------------------------------------------------------
+// ~FstPlugin
+//---------------------------------------------------------
+
+FstPlugin::~FstPlugin()
+ {
+ if (_fst) {
+ destroyEditor();
+ fst_close(_fst);
+ _fst = 0;
+ }
+ }
+
+//---------------------------------------------------------
+// instantiate
+//---------------------------------------------------------
+
+void FstPlugin::instantiate(FSTHandle* fstHandle, void* p)
+ {
+ _fst = fst_instantiate(fstHandle, vstHostCallback, p);
+ if (_fst == 0) {
+ printf("FstPlugin::instantiate:: cannot instantiate plugin\n");
+ return;
+ }
+ AEffect* plugin = _fst->plugin;
+ version = plugin->dispatcher (plugin, effGetVstVersion, 0, 0, 0, 0.0f);
+ }
+
+//---------------------------------------------------------
+// numInputs
+//---------------------------------------------------------
+
+int FstPlugin::numInputs() const
+ {
+ return _fst->plugin->numInputs;
+ }
+
+//---------------------------------------------------------
+// numOutputs
+//---------------------------------------------------------
+
+int FstPlugin::numOutputs() const
+ {
+ return _fst->plugin->numOutputs;
+ }
+
+//---------------------------------------------------------
+// numParameter
+//---------------------------------------------------------
+
+int FstPlugin::numParameter() const
+ {
+ return _fst->plugin->numParams;
+ }
+
+//---------------------------------------------------------
+// setSampleRate
+//---------------------------------------------------------
+
+void FstPlugin::setSampleRate(float sr)
+ {
+ AEffect* plugin = _fst->plugin;
+ plugin->dispatcher(plugin, effSetSampleRate, 0, 0, 0, sr);
+ }
+
+//---------------------------------------------------------
+// setBlockSize
+//---------------------------------------------------------
+
+void FstPlugin::setBlockSize(int bs)
+ {
+ AEffect* plugin = _fst->plugin;
+ plugin->dispatcher(plugin, effSetBlockSize, 0, bs, 0, 0.0f);
+ }
+
+//---------------------------------------------------------
+// mainsChanged
+//---------------------------------------------------------
+
+void FstPlugin::mainsChanged(bool on)
+ {
+ AEffect* plugin = _fst->plugin;
+ plugin->dispatcher(plugin, effMainsChanged, 0, on, 0, 0.0f);
+ }
+
+//---------------------------------------------------------
+// setProgram
+//---------------------------------------------------------
+
+void FstPlugin::setProgram(int p)
+ {
+ AEffect* plugin = _fst->plugin;
+ plugin->dispatcher(plugin, effSetProgram, 0, p, 0, 0.0f);
+ }
+
+//---------------------------------------------------------
+// hasGui
+//---------------------------------------------------------
+
+bool FstPlugin::hasGui() const
+ {
+ return _fst->plugin->flags & effFlagsHasEditor;
+ }
+
+//---------------------------------------------------------
+// canReplacing
+//---------------------------------------------------------
+
+bool FstPlugin::canReplacing()
+ {
+ return _fst->plugin->flags & effFlagsCanReplacing;
+ }
+
+//---------------------------------------------------------
+// runEditor
+//---------------------------------------------------------
+
+bool FstPlugin::runEditor()
+ {
+ return fst_run_editor(_fst);
+ }
+
+//---------------------------------------------------------
+// destroyEditor
+//---------------------------------------------------------
+
+void FstPlugin::destroyEditor()
+ {
+ fst_destroy_editor(_fst);
+ }
+
+//---------------------------------------------------------
+// getVstVersion
+//---------------------------------------------------------
+
+int FstPlugin::getVstVersion()
+ {
+ return version;
+ }
+
+//---------------------------------------------------------
+// setParameter
+//---------------------------------------------------------
+
+void FstPlugin::setParameter(int idx, float value)
+ {
+ AEffect* plugin = _fst->plugin;
+ plugin->setParameter(plugin, idx, value);
+ }
+
+//---------------------------------------------------------
+// getParameter
+//---------------------------------------------------------
+
+float FstPlugin::getParameter(int idx)
+ {
+ AEffect* plugin = _fst->plugin;
+ return plugin->getParameter(plugin, idx);
+ }
+
+//---------------------------------------------------------
+// processReplacing
+//---------------------------------------------------------
+
+void FstPlugin::processReplacing(float** ins, float** outs, int n)
+ {
+ AEffect* plugin = _fst->plugin;
+ plugin->processReplacing(plugin, ins, outs, n);
+ }
+
+//---------------------------------------------------------
+// process
+//---------------------------------------------------------
+
+void FstPlugin::process(float** ins, float** outs, int n)
+ {
+ AEffect* plugin = _fst->plugin;
+ plugin->process(plugin, ins, outs, n);
+ }
+
+//---------------------------------------------------------
+// putEvent
+//---------------------------------------------------------
+
+void FstPlugin::putEvent(const MidiEvent& ev)
+ {
+ AEffect* plugin = _fst->plugin;
+ static struct VstEvents events;
+ static struct VstMidiEvent event;
+ events.numEvents = 1;
+ events.reserved = 0;
+ events.events[0] = (VstEvent*)(&event);
+
+ event.type = kVstMidiType;
+ event.byteSize = 24;
+ event.deltaFrames = 0;
+ event.flags = 0;
+ event.detune = 0;
+ event.noteLength = 0;
+ event.noteOffset = 0;
+ event.reserved1 = 0;
+ event.reserved2 = 0;
+ event.noteOffVelocity = 0;
+ switch (ev.type()) {
+ case ME_PITCHBEND:
+ {
+ int a = ev.dataA() + 8192;
+ int b = a >> 7;
+ event.midiData[0] = (ev.type() | ev.channel()) & 0xff;
+ event.midiData[1] = a & 0x7f;
+ event.midiData[2] = b & 0x7f;
+ event.midiData[3] = 0;
+ }
+ break;
+
+ case ME_CONTROLLER:
+ case ME_NOTEON:
+ default:
+ event.midiData[0] = (ev.type() | ev.channel()) & 0xff;
+ event.midiData[1] = ev.dataA() & 0xff;
+ event.midiData[2] = ev.dataB() & 0xff;
+ event.midiData[3] = 0;
+ break;
+ }
+ plugin->dispatcher(plugin, effProcessEvents, 0, 0, &events, 0.0f);
+ }
+
+//---------------------------------------------------------
+// getParameterName
+//---------------------------------------------------------
+
+const char* FstPlugin::getParameterName(int idx) const
+ {
+ static char dsp[8];
+ dsp[0] = 0;
+ AEffect* effect = _fst->plugin;
+ effect->dispatcher(effect, effGetParamName, idx, 0, &dsp, 0.0f);
+ return dsp;
+ }
+
+//---------------------------------------------------------
+// getParameterLabel
+//---------------------------------------------------------
+
+const char* FstPlugin::getParameterLabel(int idx) const
+ {
+ static char dsp[8];
+ dsp[0] = 0;
+ AEffect* effect = _fst->plugin;
+ effect->dispatcher(effect, effGetParamLabel, idx, 0, &dsp, 0.0f);
+ return dsp;
+ }
+
+//---------------------------------------------------------
+// getParameterDisplay
+//---------------------------------------------------------
+
+const char* FstPlugin::getParameterDisplay(int idx, float val) const
+ {
+ static char dsp[8];
+ dsp[0] = 0;
+ AEffect* effect = _fst->plugin;
+ effect->dispatcher(effect, effGetParamDisplay, idx, 0, &dsp, val);
+ return dsp;
+ }
+
+//---------------------------------------------------------
+// scanVstDir
+//---------------------------------------------------------
+
+static void scanVstDir(const QString& s)
+ {
+ if (debugMsg)
+ printf("scan vst plugin dir <%s>\n", s.toLatin1().data());
+ QDir pluginDir(s, QString("*.dll"), QDir::Unsorted, QDir::Files);
+ if (pluginDir.exists()) {
+ const QFileInfoList list = pluginDir.entryInfoList();
+ for (int i = 0; i < list.size(); ++i) {
+ QFileInfo fi = list.at(i);
+ char* path = strdup(fi.filePath().toLatin1().data());
+ FSTInfo* info = fst_get_info(path);
+ if (info) {
+ //
+ // simple hack:
+ // plugins with no inputs are treated
+ // as software synthesizer
+ //
+ // if (info->wantEvents && info->numOutputs) {
+ if (info->numInputs == 0 && info->numOutputs) {
+ if (debugMsg)
+ printf(" add vsti synti <%s>\n", fi.fileName().toLatin1().data());
+ synthis.push_back(new VstSynth(&fi));
+ fst_free_info(info);
+ }
+ else if (info->numInputs && info->numOutputs) {
+ if (debugMsg)
+ printf(" add vst plugin <%s>\n", fi.fileName().toLatin1().data());
+ plugins.push_back(new VstPlugin(&fi, info));
+ }
+ }
+ free(path);
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// fstSignalHandler
+//---------------------------------------------------------
+
+static void fstSignalHandler(int sig, siginfo_t* /*info*/, void* /*context*/)
+ {
+ fst_error("fst signal handler %d, thread = 0x%x", sig, pthread_self ());
+ //if (sig == SIGSEGV || sig == SIGABRT) {
+ char*p = 0;
+ *p = 0;
+// }
+ fatalError("fst signal");
+ }
+
+//---------------------------------------------------------
+// initVST
+//---------------------------------------------------------
+
+void initVST()
+ {
+ jfstReserveMem(1000000);
+
+ if (fst_init(fstSignalHandler)) {
+ printf("initVST failed\n");
+ return;
+ }
+ char* vstPath = getenv("VST_PATH");
+ if (vstPath == 0)
+ vstPath = "/usr/lib/vst:/usr/local/lib/vst";
+
+ char* p = vstPath;
+ while (*p != '\0') {
+ char* pe = p;
+ while (*pe != ':' && *pe != '\0')
+ pe++;
+
+ int n = pe - p;
+ if (n) {
+ char* buffer = new char[n + 1];
+ strncpy(buffer, p, n);
+ buffer[n] = '\0';
+ scanVstDir(QString(buffer));
+ delete[] buffer;
+ }
+ p = pe;
+ if (*p == ':')
+ p++;
+ }
+ }
+
+//---------------------------------------------------------
+// guiVisible
+//---------------------------------------------------------
+
+bool VstSynthIF::guiVisible() const
+ {
+ return _guiVisible;
+ }
+
+//---------------------------------------------------------
+// showGui
+//---------------------------------------------------------
+
+void VstSynthIF::showGui(bool v)
+ {
+ if (v == guiVisible())
+ return;
+ if (v)
+ _fst->runEditor();
+ else
+ _fst->destroyEditor();
+ _guiVisible = v;
+ }
+
+//---------------------------------------------------------
+// receiveEvent
+//---------------------------------------------------------
+
+MidiEvent VstSynthIF::receiveEvent()
+ {
+ return MidiEvent();
+ }
+
+//---------------------------------------------------------
+// hasGui
+//---------------------------------------------------------
+
+bool VstSynthIF::hasGui() const
+ {
+ return _fst->hasGui();
+ }
+
+//---------------------------------------------------------
+// incInstances
+//---------------------------------------------------------
+
+void VstSynth::incInstances(int val)
+ {
+ _instances += val;
+ if (_instances == 0 && fstHandle) {
+ fst_unload(fstHandle);
+ fstHandle = 0;
+ }
+ }
+
+//---------------------------------------------------------
+// init
+//---------------------------------------------------------
+
+bool VstSynthIF::init(FSTHandle* h)
+ {
+ _fst = new FstPlugin();
+ _fst->instantiate(h, 0);
+ _fst->setSampleRate(AL::sampleRate);
+ _fst->setBlockSize(segmentSize);
+ _fst->mainsChanged(true);
+ _fst->setProgram(0);
+ return true;
+ }
+
+//---------------------------------------------------------
+// channels
+//---------------------------------------------------------
+
+int VstSynthIF::channels() const
+ {
+ return _fst->numOutputs();
+ }
+
+//---------------------------------------------------------
+// createSIF
+//---------------------------------------------------------
+
+SynthIF* VstSynth::createSIF(SynthI* s)
+ {
+ VstSynthIF* sif = new VstSynthIF(s);
+ ++_instances;
+ const char* path = info.filePath().toLatin1().data();
+
+ if (fstHandle == 0) {
+ fstHandle = fst_load(path);
+ if (fstHandle == 0) {
+ printf("SynthIF:: cannot load vst plugin %s\n", path);
+ return 0;
+ }
+ }
+ sif->init(fstHandle);
+ return sif;
+ }
+
+//---------------------------------------------------------
+// deactivate3
+//---------------------------------------------------------
+
+void VstSynthIF::deactivate3()
+ {
+ if (_fst) {
+ delete _fst;
+ _fst = 0;
+ }
+ }
+
+//---------------------------------------------------------
+// ~VstSynthIF
+//---------------------------------------------------------
+
+VstSynthIF::~VstSynthIF()
+ {
+ deactivate3();
+ }
+
+//---------------------------------------------------------
+// setParameter
+//---------------------------------------------------------
+
+void VstSynthIF::setParameter(int idx, float value)
+ {
+ _fst->setParameter(idx, value);
+ }
+
+//---------------------------------------------------------
+// write
+//---------------------------------------------------------
+
+void VstSynthIF::write(Xml& xml) const
+ {
+ //---------------------------------------------
+ // dump current state of synth
+ //---------------------------------------------
+
+ int params = _fst->numParameter();
+ for (int i = 0; i < params; ++i) {
+ float f = _fst->getParameter(i);
+ xml.tag("param", f);
+ }
+ }
+
+//---------------------------------------------------------
+// getData
+//---------------------------------------------------------
+
+void VstSynthIF::getData(MidiEventList* el, unsigned pos, int ports, unsigned n, float** buffer)
+ {
+ unsigned int endPos = pos + n;
+ iMidiEvent i = el->begin();
+ for (; i != el->end(); ++i) {
+ if (i->time() >= endPos)
+ break;
+ putEvent(*i);
+ }
+ el->erase(el->begin(), i);
+
+ int outputs = _fst->numOutputs();
+ if (ports < outputs) {
+ float* ob[outputs];
+ float fp[n * (outputs-ports)]; // dummy output buffer
+ for (int i = 0; i < outputs; ++i) {
+ if (i < ports)
+ ob[i] = buffer[i];
+ else
+ ob[i] = fp + n * (i-ports);
+ }
+ if (_fst->canReplacing())
+ _fst->processReplacing(0, ob, n);
+ else {
+ for (int i = 0; i < outputs; ++i)
+ memset(ob[i], 0, n * sizeof(float));
+ _fst->process(0, ob, n);
+ }
+ }
+ else {
+ if (_fst->canReplacing())
+ _fst->processReplacing(0, buffer, n);
+ else {
+ for (int i = 0; i < outputs; ++i)
+ memset(buffer[i], 0, n * sizeof(float));
+ _fst->process(0, buffer, n);
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// putEvent
+//---------------------------------------------------------
+
+bool VstSynthIF::putEvent(const MidiEvent& ev)
+ {
+ if (midiOutputTrace)
+ ev.dump();
+ _fst->putEvent(ev);
+ return false;
+ }
+
+//---------------------------------------------------------
+// VstPlugin
+//---------------------------------------------------------
+
+VstPlugin::VstPlugin(const QFileInfo* fi, FSTInfo* i)
+ : Plugin(fi)
+ {
+ info = i;
+ fstHandle = 0;
+ }
+
+//---------------------------------------------------------
+// VstPlugin
+//---------------------------------------------------------
+
+VstPlugin::~VstPlugin()
+ {
+ fst_free_info(info);
+ }
+
+//---------------------------------------------------------
+// createPIF
+//---------------------------------------------------------
+
+PluginIF* VstPlugin::createPIF(PluginI* pi)
+ {
+ VstPluginIF* pif = new VstPluginIF(pi);
+ ++_instances;
+ const char* path = fi.filePath().toLatin1().data();
+
+ if (fstHandle == 0) {
+ fstHandle = fst_load(path);
+ if (fstHandle == 0) {
+ printf("SynthIF:: cannot load vst plugin %s\n", path);
+ return 0;
+ }
+ }
+ pif->init(fstHandle);
+ return pif;
+ }
+
+//---------------------------------------------------------
+// parameter
+//---------------------------------------------------------
+
+int VstPlugin::parameter() const
+ {
+ return info->numParams;
+ }
+
+//---------------------------------------------------------
+// inports
+//---------------------------------------------------------
+
+int VstPlugin::inports() const
+ {
+ return info->numInputs;
+ }
+
+//---------------------------------------------------------
+// outports
+//---------------------------------------------------------
+
+int VstPlugin::outports() const
+ {
+ return info->numOutputs;
+ }
+
+//---------------------------------------------------------
+// id
+//---------------------------------------------------------
+
+unsigned long VstPlugin::id() const
+ {
+ return info->UniqueID;
+ }
+
+//---------------------------------------------------------
+// VstPluginIF
+//---------------------------------------------------------
+
+VstPluginIF::VstPluginIF(PluginI* pi)
+ : PluginIF(pi)
+ {
+ _fst = 0;
+ _guiVisible = false;
+ }
+
+VstPluginIF::~VstPluginIF()
+ {
+ if (_fst == 0)
+ return;
+ delete _fst;
+ }
+
+//---------------------------------------------------------
+// init
+//---------------------------------------------------------
+
+bool VstPluginIF::init(FSTHandle* h)
+ {
+ _fst = new FstPlugin();
+ _fst->instantiate(h, this);
+ _fst->setSampleRate(AL::sampleRate);
+ _fst->setBlockSize(segmentSize);
+ _fst->mainsChanged(true);
+ _fst->setProgram(0);
+ return true;
+ }
+
+//---------------------------------------------------------
+// hasGui
+//---------------------------------------------------------
+
+bool VstPluginIF::hasGui() const
+ {
+ return _fst->hasGui();
+ }
+
+//---------------------------------------------------------
+// showGui
+//---------------------------------------------------------
+
+void VstPluginIF::showGui(bool v)
+ {
+ if (v == guiVisible())
+ return;
+ if (v)
+ _fst->runEditor();
+ else
+ _fst->destroyEditor();
+ _guiVisible = v;
+ }
+
+//---------------------------------------------------------
+// getParameterName
+//---------------------------------------------------------
+
+const char* VstPluginIF::getParameterName(int idx) const
+ {
+ return _fst->getParameterName(idx);
+ }
+
+//---------------------------------------------------------
+// getParameterLabel
+//---------------------------------------------------------
+
+const char* VstPluginIF::getParameterLabel(int idx) const
+ {
+ return _fst->getParameterLabel(idx);
+ }
+
+//---------------------------------------------------------
+// getParameterDisplay
+//---------------------------------------------------------
+
+const char* VstPluginIF::getParameterDisplay(int idx, float val) const
+ {
+ return _fst->getParameterDisplay(idx, val);
+ }
+
+//---------------------------------------------------------
+// apply
+//---------------------------------------------------------
+
+void VstPluginIF::apply(unsigned nframes, float** src, float** dst)
+ {
+ if (_fst->canReplacing())
+ _fst->processReplacing(src, dst, nframes);
+ else {
+ int n = _fst->numOutputs();
+
+ for (int i = 0; i < n; ++i)
+ memset(dst[i], 0, sizeof(float) * nframes);
+ _fst->process(src, dst, nframes);
+ }
+ }
+
+//---------------------------------------------------------
+// setParam
+//---------------------------------------------------------
+
+void VstPluginIF::setParam(int i, double val)
+ {
+ _fst->setParameter(i, val);
+ }
+
+//---------------------------------------------------------
+// param
+//---------------------------------------------------------
+
+float VstPluginIF::param(int i) const
+ {
+ return _fst->getParameter(i);
+ }
+
+#else
+void initVST() {}
+#endif
+
diff --git a/muse_qt4_evolution/muse/vst.h b/muse_qt4_evolution/muse/vst.h
new file mode 100644
index 00000000..0ecea974
--- /dev/null
+++ b/muse_qt4_evolution/muse/vst.h
@@ -0,0 +1,172 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __VST_H__
+#define __VST_H__
+
+#include "synth.h"
+#include "plugin.h"
+
+struct _FSTHandle;
+struct _FST;
+class VstPluginIF;
+
+//---------------------------------------------------------
+// FstPlugin
+//---------------------------------------------------------
+
+class FstPlugin {
+ _FST* _fst;
+ int version;
+
+ public:
+ FstPlugin();
+ ~FstPlugin();
+ void instantiate(FSTHandle* s, void*);
+ int numInputs() const;
+ int numOutputs() const;
+ int numParameter() const;
+ void setProgram(int p);
+ void mainsChanged(bool on);
+ void setBlockSize(int bs);
+ void setSampleRate(float sr);
+ bool runEditor();
+ void destroyEditor();
+ int getVstVersion();
+ bool hasGui() const;
+ bool canReplacing();
+ void setParameter(int idx, float value);
+ float getParameter(int idx);
+ void processReplacing(float**, float**, int);
+ void process(float**, float**, int);
+ void putEvent(const MidiEvent& ev);
+ const char* getParameterName(int idx) const;
+ const char* getParameterLabel(int idx) const;
+ const char* getParameterDisplay(int idx, float val) const;
+ };
+
+//---------------------------------------------------------
+// VstSynth
+//---------------------------------------------------------
+
+class VstSynth : public Synth {
+ _FSTHandle* fstHandle;
+ int vstVersion;
+
+ public:
+ VstSynth(const QFileInfo* fi) : Synth(fi, fi->baseName()) {
+ fstHandle = 0;
+ }
+ virtual ~VstSynth() {}
+ virtual void incInstances(int val);
+ virtual SynthIF* createSIF(SynthI*);
+ };
+
+//---------------------------------------------------------
+// VstSynthIF
+// VSTi synthesizer instance
+//---------------------------------------------------------
+
+class VstSynthIF : public SynthIF
+ {
+ FstPlugin* _fst;
+ bool _guiVisible;
+
+ public:
+ VstSynthIF(SynthI* s) : SynthIF(s) {
+ _fst = 0;
+ _guiVisible = false;
+ }
+ virtual ~VstSynthIF();
+
+ virtual bool guiVisible() const;
+ virtual void showGui(bool v);
+ virtual bool hasGui() const;
+ virtual void getGeometry(int*, int*, int*, int*) const {}
+ virtual void setGeometry(int, int, int, int) {}
+ virtual void getData(MidiEventList*, unsigned pos, int ports, unsigned n, float** buffer) ;
+ virtual bool putEvent(const MidiEvent& ev);
+ virtual MidiEvent receiveEvent();
+ virtual int eventsPending() const { return 0; }
+ virtual int channels() const;
+ virtual void deactivate3();
+ virtual QString getPatchName(int, int) { return QString(""); }
+ virtual void populatePatchPopup(QMenu*, int) {};
+ virtual void write(Xml& xml) const;
+ virtual void setParameter(int idx, float value);
+ virtual int getControllerInfo(int, const char**, int*, int*, int*) { return 0; }
+ bool init(FSTHandle*);
+ };
+
+//---------------------------------------------------------
+// VstPlugin
+//---------------------------------------------------------
+
+class VstPlugin : public Plugin {
+ _FSTHandle* fstHandle;
+ FSTInfo* info;
+
+ protected:
+ int vstVersion;
+ friend class VstPluginIF;
+
+ public:
+ VstPlugin(const QFileInfo* fi, FSTInfo* i);
+ virtual ~VstPlugin();
+ virtual PluginIF* createPIF(PluginI*);
+ virtual QString name() const { return QString(info->name); }
+ virtual QString label() const { return QString(info->name); }
+
+ virtual int parameter() const;
+ virtual int inports() const;
+ virtual int outports() const;
+ virtual unsigned long id() const;
+ };
+
+//---------------------------------------------------------
+// VstPluginIF
+// Vst plugin instance interface
+//---------------------------------------------------------
+
+class VstPluginIF : public PluginIF {
+ FstPlugin* _fst;
+ bool _guiVisible;
+
+ public:
+ VstPluginIF(PluginI*);
+ virtual ~VstPluginIF();
+
+ virtual void apply(unsigned nframes, float** src, float** dst);
+ virtual void activate() {}
+ virtual void deactivate() {}
+ virtual void cleanup() {}
+ virtual void setParam(int i, double val);
+ virtual float param(int i) const;
+ virtual const char* getParameterName(int k) const;
+ virtual const char* getParameterLabel(int) const;
+ virtual const char* getParameterDisplay(int, float) const;
+ virtual bool hasGui() const;
+ virtual bool guiVisible() const { return _guiVisible; }
+ virtual void showGui(bool f);
+ bool init(FSTHandle*);
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/wave.cpp b/muse_qt4_evolution/muse/wave.cpp
new file mode 100644
index 00000000..dca9843b
--- /dev/null
+++ b/muse_qt4_evolution/muse/wave.cpp
@@ -0,0 +1,1087 @@
+ //=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include <samplerate.h>
+
+#include "al/xml.h"
+#include "al/al.h"
+#include "song.h"
+#include "wave.h"
+#include "muse.h"
+#include "widgets/filedialog.h"
+#include "arranger.h"
+#include "globals.h"
+#include "event.h"
+#include "audio.h"
+#include "part.h"
+
+const char* audioFilePattern[] = {
+ "Wave/Binary (*.wav *.bin)",
+ "Wave (*.wav)",
+ "Binary (*.bin)",
+ "All Files (*)",
+ 0
+ };
+const int cacheMag = 128;
+
+QHash<QString, SndFile*> SndFile::sndFiles;
+QList<SndFile*> SndFile::createdFiles;
+int SndFile::recFileNumber;
+
+//---------------------------------------------------------
+// copyWaveFileToProject
+// - copy wave file to project directory
+// - do sample rate conversion
+//
+// return false on error
+//---------------------------------------------------------
+
+static bool copyWaveFileToProject(const QString& path)
+ {
+ QFile srcFile(path);
+ QFileInfo srcInfo(srcFile);
+
+ QString dst(song->absoluteProjectPath());
+ QFile dstFile(dst + "/" + srcInfo.fileName());
+ if (dstFile.exists()) {
+ // TODO: rename file or check for identity
+ // we cannot easily check for identity if destination
+ // file is sample rate converted
+ //
+ // for now we assume that the file has already
+ // be imported:
+ //
+ printf("File already exists\n");
+ return true;
+ }
+
+ SF_INFO sfinfoSrc;
+ memset(&sfinfoSrc, 0, sizeof(SF_INFO));
+ SNDFILE* sfSrc = sf_open(path.toLatin1().data(), SFM_READ, &sfinfoSrc);
+ if (sfSrc == 0) {
+ printf("Cannot open source file: %s\n", strerror(errno));
+ return false;
+ }
+ int channels = sfinfoSrc.channels;
+ sf_count_t size = sfinfoSrc.frames;
+
+ SF_INFO sfinfoDst;
+ memset(&sfinfoDst, 0, sizeof(SF_INFO));
+ sfinfoDst.samplerate = AL::sampleRate;
+ sfinfoDst.channels = channels;
+ sfinfoDst.format = SF_FORMAT_WAV | SF_FORMAT_FLOAT;
+ SNDFILE* sfDst = sf_open(dstFile.fileName().toLatin1().data(),
+ SFM_WRITE, &sfinfoDst);
+ if (sfDst == 0) {
+ printf("Cannot open destination file<%s>: %s\n",
+ dstFile.fileName().toLatin1().data(), strerror(errno));
+ return false;
+ }
+
+ bool showProgress = size > (1024LL * 1024LL * 8LL);
+ QProgressDialog* progress = 0;
+ if (showProgress) {
+ QString label(QWidget::tr("copy \n %1\nto\n %2"));
+ label = label.arg(path).arg(dst);
+ if (sfinfoSrc.samplerate != AL::sampleRate) {
+ QString cs(QWidget::tr("\nconverting sample rate\n"
+ "from %1 to %2"));
+ label += cs.arg(sfinfoSrc.samplerate).arg(AL::sampleRate);
+ }
+ int csize = size / 1024;
+ progress = new QProgressDialog(label, QWidget::tr("Abort"), 0, csize);
+ progress->setValue(0);
+ progress->setWindowTitle("MusE");
+ progress->raise();
+ progress->show();
+ qApp->processEvents();
+ }
+ sf_count_t inSize = 1024LL * 64LL;
+ sf_count_t samplesWritten = 0LL;
+
+ bool returnValue = true;
+ if (sfinfoSrc.samplerate != AL::sampleRate) {
+ // TODO: convertsample rate
+ printf("wave file has samplerate of %d, our project has %d\n",
+ sfinfoSrc.samplerate,AL::sampleRate);
+
+ int srcType = SRC_SINC_MEDIUM_QUALITY;
+ int error;
+ SRC_STATE* src = src_new(srcType, channels, &error);
+ if (src == 0) {
+ printf("creating sample rate converter failed: error %d\n",
+ error);
+ return false;
+ }
+ double ratio = double(AL::sampleRate) / double(sfinfoSrc.samplerate);
+ src_set_ratio(src, ratio);
+ sf_count_t outSize = int(inSize * ratio) + 1;
+ float inBuffer[inSize * channels];
+ float* inPtr = inBuffer;
+ while (size) {
+ float outBuffer[outSize * channels];
+
+ // read buffer
+ sf_count_t framesToRead = (inBuffer + inSize) - inPtr;
+ if (framesToRead > size)
+ framesToRead = size;
+ sf_count_t nr = sf_readf_float(sfSrc, inPtr, framesToRead);
+ if (nr != framesToRead) {
+ printf("sound file read failed\n");
+ src_delete(src);
+ returnValue = false;
+ break;
+ }
+
+ // convert
+ SRC_DATA data;
+ data.data_in = inBuffer;
+ data.data_out = outBuffer;
+ data.input_frames = inSize;
+ data.output_frames = outSize;
+ data.end_of_input = framesToRead == size;
+ data.src_ratio = ratio;
+
+ int rv = src_process(src, &data);
+ if (rv > 0) {
+ printf("error sampe rate conversion: %s\n",
+ src_strerror(rv));
+ src_delete(src);
+ returnValue = false;
+ break;
+ }
+
+ // write buffer
+ sf_count_t n = sf_writef_float(sfDst, outBuffer, data.output_frames_gen);
+ if (n != data.output_frames_gen) {
+ printf("sound write failed: returns %lld, should return %ld\n",
+ n, data.output_frames_gen);
+ returnValue = false;
+ break;
+ }
+
+ int rest = (inPtr + nr - inBuffer) - data.input_frames_used;
+ rest *= (sizeof(float) * channels);
+ if (rest > 0)
+ memcpy(inBuffer, inBuffer + data.input_frames_used, rest);
+
+ inPtr += framesToRead;
+ inPtr -= data.input_frames_used;
+ if (data.input_frames_used > size)
+ size = 0;
+ else
+ size -= data.input_frames_used;
+ framesToRead = data.input_frames_used;
+ samplesWritten += data.input_frames_used;
+
+ if (framesToRead > size)
+ framesToRead = size;
+ if (showProgress) {
+ progress->setValue(samplesWritten / 1024LL);
+ progress->raise();
+ qApp->processEvents();
+ if (progress->wasCanceled()) {
+ returnValue = false;
+ break;
+ }
+ }
+ }
+ src_delete(src);
+ }
+ else {
+ while (size) {
+ float buffer[inSize * channels];
+
+ sf_count_t n = inSize > size ? size : inSize;
+ sf_count_t nn = sf_readf_float(sfSrc, buffer, n);
+
+ if (nn != n) {
+ printf("sound file read failed\n");
+ returnValue = false;
+ break;
+ }
+ // write buffer
+ nn = sf_writef_float(sfDst, buffer, n);
+ if (n != nn) {
+ printf("sound write failed: returns %lld, should return %lld\n",
+ nn, n);
+ returnValue = false;
+ break;
+ }
+ size -= n;
+ samplesWritten += n;
+ if (showProgress) {
+ progress->setValue(samplesWritten / 1024LL);
+ progress->raise();
+ qApp->processEvents();
+ if (progress->wasCanceled()) {
+ returnValue = false;
+ break;
+ }
+ }
+ }
+ }
+ if (progress)
+ delete progress;
+ sf_close(sfSrc);
+ sf_close(sfDst);
+ return returnValue;
+ }
+
+//---------------------------------------------------------
+// SndFile
+//---------------------------------------------------------
+
+SndFile::SndFile(const QString& name)
+ {
+ refCount = 0;
+ _finfo.setFile(name);
+ sfRT = 0;
+ sfUI = 0;
+ csize = 0;
+ cache = 0;
+ openFlag = false;
+ sndFiles[_finfo.absoluteFilePath()] = this;
+ }
+
+SndFile::~SndFile()
+ {
+ if (openFlag)
+ close();
+ sndFiles.remove(_finfo.absoluteFilePath());
+ if (cache) {
+ for (unsigned i = 0; i < channels(); ++i)
+ delete cache[i];
+ delete[] cache;
+ cache = 0;
+ }
+ }
+
+//---------------------------------------------------------
+// openRead
+//---------------------------------------------------------
+
+bool SndFile::openRead()
+ {
+ if (openFlag) {
+ printf("SndFile:: alread open\n");
+ return false;
+ }
+ QString p = _finfo.absoluteFilePath();
+ sfinfo.format = 0;
+ sfUI = sf_open(p.toAscii().data(), SFM_READ, &sfinfo);
+ sfinfo.format = 0;
+ sfRT = sf_open(p.toAscii().data(), SFM_READ, &sfinfo);
+ if (sfUI == 0 || sfRT == 0) {
+ printf("SndFile::openRead(): failed\n");
+ return true;
+ }
+ writeFlag = false;
+ openFlag = true;
+ QString cacheName = _finfo.absolutePath() + QString("/") + _finfo.baseName() + QString(".wca");
+ readCache(cacheName, true);
+ return false;
+ }
+
+//---------------------------------------------------------
+// update
+// called after recording to file
+//---------------------------------------------------------
+
+void SndFile::update()
+ {
+ close();
+
+ // force recreation of wca data
+ QString cacheName = _finfo.absolutePath() +
+ QString("/") + _finfo.baseName() + QString(".wca");
+ ::remove(cacheName.toLatin1().data());
+ if (openRead()) {
+ printf("SndFile::openRead(%s) failed: %s\n", _finfo.filePath().toLatin1().data(), strerror().toLatin1().data());
+ }
+ }
+
+//---------------------------------------------------------
+// readCache
+//---------------------------------------------------------
+
+void SndFile::readCache(const QString& path, bool showProgress)
+ {
+// printf("readCache %s for %d samples channel %d\n",
+// path.toLatin1().data(), samples(), channels());
+
+ if (cache) {
+ for (unsigned i = 0; i < channels(); ++i)
+ delete cache[i];
+ delete[] cache;
+ }
+ if (samples() == 0) {
+// printf("SndFile::readCache: file empty\n");
+ return;
+ }
+ csize = (samples() + cacheMag - 1)/cacheMag;
+ cache = new SampleV*[channels()];
+ for (unsigned ch = 0; ch < channels(); ++ch)
+ cache[ch] = new SampleV[csize];
+
+ FILE* cfile = fopen(path.toAscii().data(), "r");
+ if (cfile) {
+ for (unsigned ch = 0; ch < channels(); ++ch)
+ fread(cache[ch], csize * sizeof(SampleV), 1, cfile);
+ fclose(cfile);
+ return;
+ }
+
+ //---------------------------------------------------
+ // create cache
+ //---------------------------------------------------
+
+ QProgressDialog* progress = 0;
+ if (showProgress) {
+ QString label(QWidget::tr("create peakfile for "));
+ label += _finfo.baseName();
+ progress = new QProgressDialog(label, "Abort", 0, csize, 0);
+ qApp->processEvents();
+ }
+ float data[channels()][cacheMag];
+ float* fp[channels()];
+ for (unsigned k = 0; k < channels(); ++k)
+ fp[k] = &data[k][0];
+ int interval = csize / 10;
+ for (int i = 0; i < csize; i++) {
+ if (showProgress && ((i % interval) == 0)) {
+ progress->setValue(i);
+ progress->raise();
+ qApp->processEvents();
+ if (progress->wasCanceled()) {
+ // TODO
+ }
+ }
+ seek(i * cacheMag);
+ read(channels(), fp, cacheMag);
+ for (unsigned ch = 0; ch < channels(); ++ch) {
+ float rms = 0.0;
+ cache[ch][i].peak = 0;
+ for (int n = 0; n < cacheMag; n++) {
+ float fd = data[ch][n];
+ rms += fd * fd;
+ int idata = lrint(fd * 255.0);
+ if (idata < 0)
+ idata = -idata;
+ if (idata > 255)
+ idata = 255;
+ if (cache[ch][i].peak < idata)
+ cache[ch][i].peak = idata;
+ }
+ // amplify rms value +12dB
+ int rmsValue = lrint((sqrt(rms/cacheMag) * 255.0));
+ if (rmsValue > 255)
+ rmsValue = 255;
+ cache[ch][i].rms = rmsValue;
+ }
+ }
+ if (showProgress) {
+ progress->setValue(csize);
+ qApp->processEvents();
+ }
+ writeCache(path);
+ if (showProgress)
+ delete progress;
+ }
+
+//---------------------------------------------------------
+// writeCache
+//---------------------------------------------------------
+
+void SndFile::writeCache(const QString& path)
+ {
+ FILE* cfile = fopen(path.toLatin1().data(), "w");
+ if (cfile == 0)
+ return;
+ for (unsigned ch = 0; ch < channels(); ++ch)
+ fwrite(cache[ch], csize * sizeof(SampleV), 1, cfile);
+ fclose(cfile);
+ }
+
+//---------------------------------------------------------
+// read
+// integrate "mag" samples, starting at position "pos"
+// into "s"
+//---------------------------------------------------------
+
+void SndFile::read(SampleV* s, int mag, unsigned pos)
+ {
+ for (unsigned ch = 0; ch < channels(); ++ch) {
+ s[ch].peak = 0;
+ s[ch].rms = 0;
+ }
+ if (pos > samples())
+ return;
+
+ if (mag < cacheMag) {
+ float data[channels()][mag];
+ float* fp[channels()];
+ for (unsigned i = 0; i < channels(); ++i)
+ fp[i] = &data[i][0];
+ sf_seek(sfUI, pos, SEEK_SET);
+ {
+ int srcChannels = channels();
+ int dstChannels = sfinfo.channels;
+ float** dst = fp;
+ float buffer[mag * dstChannels];
+ size_t rn = sf_readf_float(sfUI, buffer, mag);
+ float* src = buffer;
+
+ if (srcChannels == dstChannels) {
+ for (size_t i = 0; i < rn; ++i) {
+ for (int ch = 0; ch < srcChannels; ++ch)
+ *(dst[ch]+i) = *src++;
+ }
+ }
+ else if ((srcChannels == 1) && (dstChannels == 2)) {
+ // stereo to mono
+ for (size_t i = 0; i < rn; ++i)
+ *(dst[0] + i) = src[i + i] + src[i + i + 1];
+ }
+ else if ((srcChannels == 2) && (dstChannels == 1)) {
+ // mono to stereo
+ for (size_t i = 0; i < rn; ++i) {
+ float data = *src++;
+ *(dst[0]+i) = data;
+ *(dst[1]+i) = data;
+ }
+ }
+ }
+
+ for (unsigned ch = 0; ch < channels(); ++ch) {
+ s[ch].peak = 0;
+ float rms = 0.0;
+ for (int i = 0; i < mag; i++) {
+ float fd = data[ch][i];
+ rms += fd;
+ int idata = int(fd * 255.0);
+ if (idata < 0)
+ idata = -idata;
+ if (s[ch].peak < idata)
+ s[ch].peak = idata;
+ }
+ s[ch].rms = 0; // TODO rms / mag;
+ }
+ }
+ else {
+ mag /= cacheMag;
+ int rest = csize - (pos/cacheMag);
+ int end = mag;
+ if (rest < mag)
+ end = rest;
+
+ for (unsigned ch = 0; ch < channels(); ++ch) {
+ int rms = 0;
+ int off = pos/cacheMag;
+ for (int offset = off; offset < off+end; offset++) {
+ rms += cache[ch][offset].rms;
+ if (s[ch].peak < cache[ch][offset].peak)
+ s[ch].peak = cache[ch][offset].peak;
+ }
+ s[ch].rms = rms / mag;
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// openWrite
+//---------------------------------------------------------
+
+bool SndFile::openWrite()
+ {
+ if (openFlag) {
+ printf("SndFile:: alread open\n");
+ return false;
+ }
+ QString p = _finfo.filePath();
+ sfRT = sf_open(p.toLatin1().data(), SFM_RDWR, &sfinfo);
+ sfUI = 0;
+ if (sfRT) {
+ openFlag = true;
+ writeFlag = true;
+ QString cacheName = _finfo.absolutePath() +
+ QString("/") + _finfo.baseName() + QString(".wca");
+ readCache(cacheName, true);
+ }
+ return sfRT == 0;
+ }
+
+//---------------------------------------------------------
+// close
+//---------------------------------------------------------
+
+void SndFile::close()
+ {
+ if (!openFlag) {
+ printf("SndFile:: alread closed\n");
+ return;
+ }
+ sf_close(sfRT);
+ if (sfUI)
+ sf_close(sfUI);
+ openFlag = false;
+ }
+
+//---------------------------------------------------------
+// remove
+//---------------------------------------------------------
+
+void SndFile::remove()
+ {
+ if (openFlag)
+ close();
+ QString cacheName = _finfo.absolutePath() + QString("/") + _finfo.baseName() + QString(".wca");
+ // QFile::remove(_finfo.filePath());
+ // QFile::remove(cacheName);
+ // DEBUG:
+ QFile::rename(_finfo.filePath(), _finfo.filePath() + ".del");
+ QFile::rename(cacheName, cacheName + ".del");
+ }
+
+//---------------------------------------------------------
+// samples
+//---------------------------------------------------------
+
+unsigned SndFile::samples() const
+ {
+ return sfinfo.frames;
+ }
+
+//---------------------------------------------------------
+// channels
+//---------------------------------------------------------
+
+unsigned SndFile::channels() const
+ {
+ return sfinfo.channels;
+ }
+
+//---------------------------------------------------------
+// samplerate
+//---------------------------------------------------------
+
+unsigned SndFile::samplerate() const
+ {
+ return sfinfo.samplerate;
+ }
+
+//---------------------------------------------------------
+// format
+//---------------------------------------------------------
+
+unsigned SndFile::format() const
+ {
+ return sfinfo.format;
+ }
+
+//---------------------------------------------------------
+// setFormat
+//---------------------------------------------------------
+
+void SndFile::setFormat(int fmt, int ch, int rate)
+ {
+ sfinfo.samplerate = rate;
+ sfinfo.channels = ch;
+ sfinfo.format = fmt;
+ sfinfo.seekable = true;
+ sfinfo.frames = 0;
+ }
+
+//---------------------------------------------------------
+// read
+//---------------------------------------------------------
+
+size_t SndFile::read(int srcChannels, float** dst, size_t n)
+ {
+ float buffer[n * sfinfo.channels];
+ size_t rn = sf_readf_float(sfRT, buffer, n);
+
+ float* src = buffer;
+ int dstChannels = sfinfo.channels;
+
+ if (srcChannels == dstChannels) {
+ for (size_t i = 0; i < rn; ++i) {
+ for (int ch = 0; ch < srcChannels; ++ch)
+ *(dst[ch]+i) = *src++;
+ }
+ }
+ else if ((srcChannels == 1) && (dstChannels == 2)) {
+ // stereo to mono
+ for (size_t i = 0; i < rn; ++i)
+ *(dst[0] + i) = src[i + i] + src[i + i + 1];
+ }
+ else if ((srcChannels == 2) && (dstChannels == 1)) {
+ // mono to stereo
+ for (size_t i = 0; i < rn; ++i) {
+ float data = *src++;
+ *(dst[0]+i) = data;
+ *(dst[1]+i) = data;
+ }
+ }
+ else {
+ printf("SndFile:read channel mismatch %d -> %d\n",
+ srcChannels, dstChannels);
+ }
+ return rn;
+ }
+
+//---------------------------------------------------------
+// write
+//---------------------------------------------------------
+
+size_t SndFile::write(int srcChannels, float** src, size_t n)
+ {
+ int dstChannels = sfinfo.channels;
+ float buffer[n * dstChannels];
+ float* dst = buffer;
+
+ if (srcChannels == dstChannels) {
+ for (size_t i = 0; i < n; ++i) {
+ for (int ch = 0; ch < dstChannels; ++ch)
+ *dst++ = *(src[ch]+i);
+ }
+ }
+ else if ((srcChannels == 1) && (dstChannels == 2)) {
+ // mono to stereo
+ for (size_t i = 0; i < n; ++i) {
+ float data = *(src[0]+i);
+ *dst++ = data;
+ *dst++ = data;
+ }
+ }
+ else if ((srcChannels == 2) && (dstChannels == 1)) {
+ // stereo to mono
+ for (size_t i = 0; i < n; ++i)
+ *dst++ = *(src[0]+i) + *(src[1]+i);
+ }
+ else {
+ printf("SndFile:write channel mismatch %d -> %d\n",
+ srcChannels, dstChannels);
+ return 0;
+ }
+ return sf_writef_float(sfRT, buffer, n) ;
+ }
+
+//---------------------------------------------------------
+// seek
+//---------------------------------------------------------
+
+off_t SndFile::seek(off_t frames)
+ {
+ return sf_seek(sfRT, frames, SEEK_SET);
+ }
+
+//---------------------------------------------------------
+// strerror
+//---------------------------------------------------------
+
+QString SndFile::strerror() const
+ {
+ char buffer[128];
+ buffer[0] = 0;
+ sf_error_str(sfRT, buffer, 128);
+ return QString(buffer);
+ }
+
+//---------------------------------------------------------
+// getWave
+//---------------------------------------------------------
+
+SndFile* SndFile::getWave(const QString& inName, bool writeFlag)
+ {
+ QString name = song->absoluteProjectPath() + "/" + inName;
+
+ SndFile* f = sndFiles.value(name);
+// printf("SndFile::getWave: %p writeFlag %d %s %s\n", f, writeFlag, inName.toLatin1().data(), name.toLatin1().data());
+ if (f == 0) {
+ if (!QFile::exists(name)) {
+ fprintf(stderr, "wave file <%s> not found\n",
+ name.toLatin1().data());
+ return 0;
+ }
+ f = new SndFile(name);
+ bool error;
+ if (writeFlag)
+ error = f->openWrite();
+ else
+ error = f->openRead();
+ if (error) {
+ fprintf(stderr, "open wave file(%s) for %s failed: %s\n",
+ name.toLatin1().data(),
+ writeFlag ? "writing" : "reading",
+ f->strerror().toLatin1().data());
+ delete f;
+ f = 0;
+ }
+ }
+ else {
+ if (writeFlag && ! f->isWritable()) {
+ if (f->isOpen())
+ f->close();
+ f->openWrite();
+ }
+ }
+ return f;
+ }
+
+//---------------------------------------------------------
+// applyUndoFile
+//---------------------------------------------------------
+
+void SndFile::applyUndoFile(const QString& original, const QString& tmpfile, unsigned startframe, unsigned endframe)
+ {
+ // This one is called on both undo and redo of a wavfile
+ // For redo to be called, undo must have been called first, and we don't store both the original data and the modified data in separate
+ // files. Thus, each time this function is called the data in the "original"-file will be written to the tmpfile, after the data
+ // from the tmpfile has been applied.
+ //
+ // F.ex. if mute has been made on part of a wavfile, the unmuted data is stored in the tmpfile when
+ // the undo operation occurs. The unmuted data is then written back to the original file, and the mute data will be
+ // put in the tmpfile, and when redo is eventually called the data is switched again (causing the muted data to be written to the "original"
+ // file. The data is merely switched.
+
+ //printf("Applying undofile: orig=%s tmpfile=%s startframe=%d endframe=%d\n", original.toLatin1().data(), tmpfile.toLatin1().data(), startframe, endframe);
+ SndFile* orig = sndFiles.value(original);
+ SndFile tmp = SndFile(tmpfile);
+ if (!orig) {
+ printf("Internal error: could not find original file: %s in filelist - Aborting\n", original.toLatin1().data());
+ return;
+ }
+
+ if (!orig->isOpen()) {
+ if (orig->openRead()) {
+ printf("Cannot open original file %s for reading - cannot undo! Aborting\n", original.toLatin1().data());
+ return;
+ }
+ }
+
+ if (!tmp.isOpen()) {
+ if (tmp.openRead()) {
+ printf("Could not open temporary file %s for writing - cannot undo! Aborting\n", tmpfile.toLatin1().data());
+ return;
+ }
+ }
+
+ audio->msgIdle(true);
+ tmp.setFormat(orig->format(), orig->channels(), orig->samplerate());
+
+ // Read data in original file to memory before applying tmpfile to original
+ unsigned file_channels = orig->channels();
+ unsigned tmpdatalen = endframe - startframe;
+ float* data2beoverwritten[file_channels];
+
+ for (unsigned i=0; i<file_channels; i++) {
+ data2beoverwritten[i] = new float[tmpdatalen];
+ }
+ orig->seek(startframe);
+ orig->read(file_channels, data2beoverwritten, tmpdatalen);
+
+ orig->close();
+
+ // Read data from temporary file to memory
+ float* tmpfiledata[file_channels];
+ for (unsigned i=0; i<file_channels; i++) {
+ tmpfiledata[i] = new float[tmpdatalen];
+ }
+ tmp.seek(0);
+ tmp.read(file_channels, tmpfiledata, tmpdatalen);
+ tmp.close();
+
+ // Write temporary data to original file:
+ if (orig->openWrite()) {
+ printf("Cannot open orig for write - aborting.\n");
+ return;
+ }
+
+ orig->seek(startframe);
+ orig->write(file_channels, tmpfiledata, tmpdatalen);
+
+ // Delete dataholder for temporary file
+ for (unsigned i=0; i<file_channels; i++) {
+ delete[] tmpfiledata[i];
+ }
+
+ // Write the overwritten data to the tmpfile
+ if (tmp.openWrite()) {
+ printf("Cannot open tmpfile for writing - redo operation of this file won't be possible. Aborting.\n");
+ audio->msgIdle(false);
+ return;
+ }
+ tmp.seek(0);
+ tmp.write(file_channels, data2beoverwritten, tmpdatalen);
+ tmp.close();
+
+ // Delete dataholder for replaced original file
+ for (unsigned i=0; i<file_channels; i++) {
+ delete[] data2beoverwritten[i];
+ }
+
+ orig->close();
+ orig->openRead();
+ orig->update();
+ audio->msgIdle(false);
+ }
+
+//---------------------------------------------------------
+// importAudio
+//---------------------------------------------------------
+
+void MusE::importWave()
+ {
+ Track* track = arranger->curTrack();
+ if (track == 0 || track->type() != Track::WAVE) {
+ QMessageBox::critical(this, QString("MusE"),
+ tr("to import a audio file you have first to select"
+ "a wave track"));
+ return;
+ }
+ QStringList pattern;
+ const char** p = audioFilePattern;
+ while (*p)
+ pattern << *p++;
+ QString fn = getOpenFileName(lastWavePath, pattern, this,
+ tr("Import Wave File"));
+ if (!fn.isEmpty()) {
+ QFileInfo qf(fn);
+ lastWavePath = qf.path();
+ importWave(fn);
+ }
+ }
+
+//---------------------------------------------------------
+// importWave
+//---------------------------------------------------------
+
+bool MusE::importWave(const QString& name)
+ {
+ return importWaveToTrack(name, (WaveTrack*)(arranger->curTrack()),
+ song->cPos());
+ }
+
+//---------------------------------------------------------
+// importWaveToTrack
+//---------------------------------------------------------
+
+bool MusE::importWaveToTrack(const QString& wave, Track* track, const Pos& pos)
+ {
+ if (!copyWaveFileToProject(wave))
+ return true;
+ QFileInfo srcInfo(wave);
+ SndFile* f = SndFile::getWave(srcInfo.fileName(), false);
+
+ if (f == 0) {
+ printf("import audio file failed\n");
+ return true;
+ }
+ int samples = f->samples();
+ track->setChannels(f->channels());
+
+ Part* part = new Part((WaveTrack *)track);
+ part->ref();
+ part->setType(AL::FRAMES);
+ part->setTick(pos.tick());
+ part->setLenFrame(samples);
+
+ Event event(Wave);
+ SndFileR sf(f);
+ event.setSndFile(sf);
+ event.setSpos(0);
+ event.setLenFrame(samples);
+ part->addEvent(event);
+
+ part->setName(srcInfo.baseName());
+ song->cmdAddPart(part);
+ unsigned endTick = part->tick() + part->lenTick();
+ if (song->len() < endTick)
+ song->setLen(endTick);
+ return false;
+ }
+
+//---------------------------------------------------------
+// cmdChangeWave
+// called from GUI context
+//---------------------------------------------------------
+
+void Song::cmdChangeWave(QString original, QString tmpfile, unsigned sx, unsigned ex)
+ {
+ char* original_charstr = new char[original.length() + 1];
+ char* tmpfile_charstr = new char[tmpfile.length() + 1];
+ strcpy(original_charstr, original.toLatin1().data());
+ strcpy(tmpfile_charstr, tmpfile.toLatin1().data());
+ song->undoOp(UndoOp::ModifyClip, original_charstr, tmpfile_charstr, sx, ex);
+ }
+
+//---------------------------------------------------------
+// SndFileR
+//---------------------------------------------------------
+
+SndFileR::SndFileR(SndFile* _sf)
+ {
+ sf = _sf;
+ if (sf)
+ (sf->refCount)++;
+ }
+
+SndFileR::SndFileR(const SndFileR& ed)
+ {
+ sf = ed.sf;
+ if (sf)
+ (sf->refCount)++;
+ }
+
+//---------------------------------------------------------
+// operator=
+//---------------------------------------------------------
+
+SndFileR& SndFileR::operator=(const SndFileR& ed)
+ {
+ if (sf == ed.sf)
+ return *this;
+ if (sf && --(sf->refCount) == 0)
+ delete sf;
+ sf = ed.sf;
+ if (sf)
+ (sf->refCount)++;
+ return *this;
+ }
+
+//---------------------------------------------------------
+// ~SndFileR
+//---------------------------------------------------------
+
+SndFileR::~SndFileR()
+ {
+ if (sf && --(sf->refCount) <= 0)
+ delete sf;
+ }
+
+//---------------------------------------------------------
+// createRecFile
+// create soundfile for recording
+//---------------------------------------------------------
+
+SndFile* SndFile::createRecFile(int channels)
+ {
+ QString fileName("%1/rec%2.wav");
+ QFileInfo fi;
+ do {
+ fi.setFile(fileName.arg(song->absoluteProjectPath()).arg(recFileNumber));
+ ++recFileNumber;
+ } while (fi.exists());
+ SndFile* recFile = new SndFile(fi.absoluteFilePath());
+ recFile->setFormat(SF_FORMAT_WAV | SF_FORMAT_FLOAT, channels,
+ AL::sampleRate);
+ createdFiles.append(recFile);
+ return recFile;
+ }
+
+//---------------------------------------------------------
+// cleanupRecFiles
+// remove all record files which are not referenced
+// any more
+// this is called on exit
+//---------------------------------------------------------
+
+void SndFile::cleanupRecFiles(bool removeAll)
+ {
+ QList<SndFile*>* fl;
+ QList<SndFile*> removeFiles;
+
+ if (removeAll)
+ fl = &createdFiles;
+ else {
+ foreach (SndFile* s, createdFiles) {
+ bool remove = true;
+ WaveTrackList* wt = song->waves();
+ for (iWaveTrack iwt = wt->begin(); iwt != wt->end(); ++iwt) {
+ WaveTrack* t = *iwt;
+ PartList* parts = t->parts();
+ for (iPart ip = parts->begin(); ip != parts->end(); ++ip) {
+ Part* part = ip->second;
+ EventList* events = part->events();
+ for (iEvent ie = events->begin(); ie != events->end(); ++ie) {
+ if (ie->second.sndFile() == s) {
+ remove = false;
+ break;
+ }
+ }
+ }
+ if (t->recFile() && t->recFile()->samples() == 0) {
+ t->recFile()->remove();
+ }
+ }
+ if (remove)
+ removeFiles.append(s);
+ }
+ fl = &removeFiles;
+ }
+ foreach (SndFile* sf, *fl) {
+ printf("cleanup rec file <%s>\n", sf->finfo()->absoluteFilePath().toLatin1().data());
+ sf->remove();
+ }
+ createdFiles.clear();
+ }
+
+//---------------------------------------------------------
+// updateRecFiles
+// this is called on "save"
+// remove all saved wave files from list of potentially
+// to delete files
+//---------------------------------------------------------
+
+void SndFile::updateRecFiles()
+ {
+ QList<SndFile*> removeFiles;
+
+ foreach (SndFile* s, createdFiles) {
+ bool remove = true;
+ WaveTrackList* wt = song->waves();
+ for (iWaveTrack iwt = wt->begin(); iwt != wt->end(); ++iwt) {
+ WaveTrack* t = *iwt;
+ PartList* parts = t->parts();
+ for (iPart ip = parts->begin(); ip != parts->end(); ++ip) {
+ Part* part = ip->second;
+ EventList* events = part->events();
+ for (iEvent ie = events->begin(); ie != events->end(); ++ie) {
+ if (ie->second.sndFile() == s) {
+ remove = false;
+ break;
+ }
+ }
+ if (!remove)
+ break;
+ }
+ if (t->recFile() && t->recFile()->samples() == 0) {
+ t->recFile()->remove();
+ }
+ if (!remove)
+ break;
+ }
+ if (remove)
+ removeFiles.append(s);
+ }
+ createdFiles = removeFiles;
+ }
+
diff --git a/muse_qt4_evolution/muse/wave.h b/muse_qt4_evolution/muse/wave.h
new file mode 100644
index 00000000..42054f87
--- /dev/null
+++ b/muse_qt4_evolution/muse/wave.h
@@ -0,0 +1,162 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __WAVE_H__
+#define __WAVE_H__
+
+#include <sndfile.h>
+
+//---------------------------------------------------------
+// SampleV
+// peak file value
+//---------------------------------------------------------
+
+struct SampleV {
+ unsigned char peak;
+ unsigned char rms;
+ };
+
+class SndFile;
+
+class SndFileList : public QHash<QString, SndFile*> {
+ public:
+ SndFile* search(const QString& name) { return (*this)[name]; }
+ };
+
+//---------------------------------------------------------
+// SndFile
+//---------------------------------------------------------
+
+class SndFile {
+ static QHash<QString, SndFile*> sndFiles;
+ static QList<SndFile*> createdFiles;
+ static int recFileNumber;
+
+ QFileInfo _finfo;
+ SNDFILE* sfRT; // used by rt process (prefetch)
+ SNDFILE* sfUI; // used by ui process
+ SF_INFO sfinfo;
+ SampleV** cache;
+ int csize; // frames in cache
+
+ void readCache(const QString& path, bool progress);
+ void writeCache(const QString& path);
+
+ bool openFlag;
+ bool writeFlag;
+
+ protected:
+ int refCount;
+
+ public:
+ SndFile(const QString& name);
+ ~SndFile();
+
+ static void applyUndoFile(const QString& original, const QString& tmpfile, unsigned sx, unsigned ex);
+
+ bool openRead(); // return true on error
+ bool openWrite(); // return true on error
+ void close();
+ void remove();
+
+ bool isOpen() const { return openFlag; }
+ bool isWritable() const { return writeFlag; }
+ void update();
+
+ QFileInfo* finfo() { return &_finfo; }
+
+ unsigned samples() const;
+ unsigned channels() const;
+ unsigned samplerate() const;
+ unsigned format() const;
+ int sampleBits() const;
+ void setFormat(int fmt, int ch, int rate);
+
+ size_t read(int channel, float**, size_t);
+ size_t write(int channel, float**, size_t);
+
+ off_t seek(off_t frames);
+ void read(SampleV* s, int mag, unsigned pos);
+ QString strerror() const;
+
+ static SndFile* createRecFile(int);
+ static void cleanupRecFiles(bool);
+ static void updateRecFiles();
+ static SndFile* search(const QString& name);
+ static SndFile* getWave(const QString& inName, bool writeFlag);
+
+ friend class SndFileR;
+ };
+
+//---------------------------------------------------------
+// SndFileR
+// SndFile with reference count
+//---------------------------------------------------------
+
+class SndFileR {
+ SndFile* sf;
+
+ public:
+ SndFileR() { sf = 0; }
+ SndFileR(SndFile* _sf);
+ SndFileR(const SndFileR& ed);
+ SndFileR& operator=(const SndFileR& ed);
+ bool operator==(const SndFileR& c) const { return sf == c.sf; }
+ bool operator==(SndFile* c) const { return sf == c; }
+ ~SndFileR();
+ int getRefCount() const { return sf->refCount; }
+ bool isNull() const { return sf == 0; }
+
+ bool openRead() { return sf->openRead(); }
+ bool openWrite() { return sf->openWrite(); }
+ void close() { sf->close(); }
+ void remove() { sf->remove(); }
+
+ bool isOpen() const { return sf->isOpen(); }
+ bool isWritable() const { return sf->isWritable(); }
+ void update() { sf->update(); }
+ QFileInfo* finfo() { return sf->finfo(); }
+ const QFileInfo* finfo() const { return sf->finfo(); }
+
+ unsigned samples() const { return sf->samples(); }
+ unsigned channels() const { return sf->channels(); }
+ unsigned samplerate() const { return sf->samplerate(); }
+ unsigned format() const { return sf->format(); }
+ int sampleBits() const { return sf->sampleBits(); }
+ void setFormat(int fmt, int ch, int rate) {
+ sf->setFormat(fmt, ch, rate);
+ }
+ size_t read(int channel, float** f, size_t n) {
+ return sf->read(channel, f, n);
+ }
+ size_t write(int channel, float** f, size_t n) {
+ return sf->write(channel, f, n);
+ }
+ off_t seek(off_t frames) {
+ return sf->seek(frames);
+ }
+ void read(SampleV* s, int mag, unsigned pos) {
+ sf->read(s, mag, pos);
+ }
+ QString strerror() const { return sf->strerror(); }
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/waveedit/CMakeLists.txt b/muse_qt4_evolution/muse/waveedit/CMakeLists.txt
new file mode 100644
index 00000000..69ff19e3
--- /dev/null
+++ b/muse_qt4_evolution/muse/waveedit/CMakeLists.txt
@@ -0,0 +1,34 @@
+#=============================================================================
+# MusE
+# Linux Music Editor
+# $Id:$
+#
+# Copyright (C) 2002-2006 by Werner Schweer and others
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#=============================================================================
+
+QT4_WRAP_CPP ( waveedit_mocs
+ waveedit.h
+ waveview.h
+ )
+
+add_library ( waveedit STATIC
+ ${waveedit_mocs}
+ waveedit.cpp
+ waveview.cpp
+ )
+
+set_target_properties( waveedit
+ PROPERTIES COMPILE_FLAGS "-include ${PROJECT_BINARY_DIR}/all.h"
+ )
diff --git a/muse_qt4_evolution/muse/waveedit/waveedit.cpp b/muse_qt4_evolution/muse/waveedit/waveedit.cpp
new file mode 100644
index 00000000..3bfbbe40
--- /dev/null
+++ b/muse_qt4_evolution/muse/waveedit/waveedit.cpp
@@ -0,0 +1,289 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2000-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "waveedit.h"
+#include "waveview.h"
+#include "song.h"
+#include "awl/poslabel.h"
+#include "esettings.h"
+#include "al/tempo.h"
+#include "icons.h"
+#include "shortcuts.h"
+#include "wave.h"
+#include "part.h"
+#include "muse.h"
+
+int WaveEdit::initWidth = WaveEdit::INIT_WIDTH;
+int WaveEdit::initHeight = WaveEdit::INIT_HEIGHT;
+
+//---------------------------------------------------------
+// WaveEdit
+//---------------------------------------------------------
+
+WaveEdit::WaveEdit(PartList* pl, bool init)
+ : Editor()
+ {
+ _parts = pl;
+ selPart = 0;
+
+ //---------Pulldown Menu----------------------------
+ QMenuBar* mb = menuBar();
+ QAction* a;
+
+ QMenu* menuFile = mb->addMenu(tr("&File"));
+ QMenu* menuEdit = mb->addMenu(tr("&Edit"));
+ menuFunctions = mb->addMenu(tr("Func&tions"));
+
+ menuGain = menuFunctions->addMenu(tr("&Gain"));
+ a = menuGain->addAction(tr("200%"));
+ a->setData("gain200");
+ a = menuGain->addAction(tr("150%"));
+ a->setData("gain150");
+ a = menuGain->addAction(tr("75%"));
+ a->setData("gain75");
+ a = menuGain->addAction(tr("50%"));
+ a->setData("gain50");
+ a = menuGain->addAction(tr("25%"));
+ a->setData("gain25");
+ a = menuGain->addAction(tr("Other"));
+ a->setData("gain_free");
+ a = menuFunctions->addSeparator();
+
+ a = menuEdit->addAction(tr("Edit in E&xternal Editor"));
+ a->setData("exit_external");
+ a = menuFunctions->addAction(tr("Mute Selection"));
+ a->setData("mute");
+ a = menuFunctions->addAction(tr("Normalize Selection"));
+ a->setData("normalize");
+ a = menuFunctions->addAction(tr("Fade In Selection"));
+ a->setData("fade_in");
+ a = menuFunctions->addAction(tr("Fade Out Selection"));
+ a->setData("fade_out");
+ a = menuFunctions->addAction(tr("Reverse Selection"));
+ a->setData("reverse");
+
+ select = menuEdit->addMenu(QIcon(*selectIcon), tr("Select"));
+ select->addAction(getAction("sel_all", this));
+ select->addAction(getAction("sel_none", this));
+
+ connect(menuFunctions, SIGNAL(triggered(QAction*)), SLOT(cmd(QAction*)));
+ connect(menuFile, SIGNAL(triggered(QAction*)), SLOT(cmd(QAction*)));
+ connect(select, SIGNAL(triggered(QAction*)), SLOT(cmd(QAction*)));
+ connect(menuGain, SIGNAL(triggered(QAction*)), SLOT(cmd(QAction*)));
+ connect(menuEdit, SIGNAL(triggered(QAction*)), SLOT(cmd(QAction*)));
+
+ //---------ToolBar----------------------------------
+ tools = addToolBar(tr("waveedit-tools"));
+ tools->addAction(undoAction);
+ tools->addAction(redoAction);
+
+ const int waveeditTools = PointerTool | PencilTool
+ | RubberTool | DrawTool;
+ EditToolBar* tools2 = new EditToolBar(this, waveeditTools);
+ addToolBar(tools2);
+
+ //--------------------------------------------------
+ // Transport Bar
+ QToolBar* transport = addToolBar(tr("Transport"));
+ muse->setupTransportToolbar(transport);
+
+ //--------------------------------------------------
+ // ToolBar: Solo Cursor1 Cursor2
+
+ addToolBarBreak();
+ tb1 = addToolBar(tr("pianoroll-tools"));
+ solo = tb1->addAction(tr("Solo"));
+ solo->setCheckable(true);
+ connect(solo, SIGNAL(toggled(bool)), SLOT(soloChanged(bool)));
+
+ tb1->addWidget(new QLabel(tr("Cursor")));
+ pos1 = new PosLabel;
+ pos2 = new PosLabel;
+ pos2->setSmpte(true);
+ tb1->addWidget(pos1);
+ tb1->addWidget(pos2);
+
+ //---------------------------------------------------
+ // Rest
+ //---------------------------------------------------
+
+// if (!parts()->empty()) { // Roughly match total size of part
+// Part* firstPart = parts()->begin()->second;
+// xscale = 0 - firstPart->lenFrame()/_widthInit;
+// }
+
+ view = new WaveView(this);
+ view->setRaster(0);
+ view->setFollow(INIT_FOLLOW);
+
+ connect(muse, SIGNAL(configChanged()), SLOT(configChanged()));
+ connect(song, SIGNAL(posChanged(int,const AL::Pos&,bool)), view, SLOT(setLocatorPos(int,const AL::Pos&,bool)));
+ view->setLocatorPos(0, song->cpos(), true);
+ view->setLocatorPos(1, song->lpos(), false);
+ view->setLocatorPos(2, song->rpos(), false);
+// connect(view, SIGNAL(cursorPos(unsigned)), SIGNAL(setTime(unsigned)));
+ connect(view, SIGNAL(posChanged(int,const AL::Pos&)), song, SLOT(setPos(int,const AL::Pos&)));
+
+ setCentralWidget(view);
+ view->setCornerWidget(new QSizeGrip(view));
+ setWindowTitle(view->getCaption());
+
+ Pos p1(0, AL::FRAMES), p2(0, AL::FRAMES);
+ view->range(p1, p2);
+ p2 += AL::sigmap.ticksMeasure(p2.tick()); // show one more measure
+ view->setTimeRange(p1, p2);
+
+ connect(view, SIGNAL(toolChanged(int)), tools2, SLOT(set(int)));
+ connect(tools2, SIGNAL(toolChanged(int)), view, SLOT(setTool(int)));
+
+// view->selectFirst();
+ configChanged();
+ if (init)
+ ; // initFromPart();
+ else {
+ resize(initWidth, initHeight);
+ }
+ }
+
+//---------------------------------------------------------
+// configChanged
+//---------------------------------------------------------
+
+void WaveEdit::configChanged()
+ {
+// view->setBg(config.waveEditBackgroundColor);
+ }
+
+//---------------------------------------------------------
+// setTime
+//---------------------------------------------------------
+
+void WaveEdit::setTime(unsigned samplepos)
+ {
+// printf("setTime %d %x\n", samplepos, samplepos);
+ unsigned tick = AL::tempomap.frame2tick(samplepos);
+ pos1->setValue(tick, true);
+ pos2->setValue(tick, true);
+// time->setPos(3, tick, false);
+ }
+
+//---------------------------------------------------------
+// ~WaveEdit
+//---------------------------------------------------------
+
+WaveEdit::~WaveEdit()
+ {
+// undoRedo->removeFrom(tools);
+ }
+
+//---------------------------------------------------------
+// cmd
+//---------------------------------------------------------
+
+void WaveEdit::cmd(QAction* a)
+ {
+ view->cmd(a->data().toString());
+ }
+
+//---------------------------------------------------------
+// soloChanged
+// signal from "song"
+//---------------------------------------------------------
+
+void WaveEdit::soloChanged(SNode*/* s*/)
+ {
+ Part* part = parts()->begin()->second;
+ solo->setChecked(part->track()->solo());
+ }
+
+//---------------------------------------------------------
+// soloChanged
+// signal from solo button
+//---------------------------------------------------------
+
+void WaveEdit::soloChanged(bool flag)
+ {
+ Part* part = parts()->begin()->second;
+ song->setSolo(part->track(), flag);
+ }
+
+//---------------------------------------------------------
+// viewKeyPressEvent
+//---------------------------------------------------------
+
+void WaveEdit::keyPressEvent(QKeyEvent* event)
+ {
+ int key = event->key();
+ if (key == Qt::Key_Escape) {
+ close();
+ return;
+ }
+ else {
+ event->ignore();
+ }
+ }
+
+//---------------------------------------------------------
+// read
+//---------------------------------------------------------
+
+void WaveEdit::read(QDomNode node)
+ {
+ for (node = node.firstChild(); !node.isNull(); node = node.nextSibling()) {
+ QDomElement e = node.toElement();
+ QString tag(e.tagName());
+ if (tag == "CtrlEdit") {
+ int id = e.attribute("id","0").toInt();
+ int h = e.attribute("h","50").toInt();
+ view->addController(id, h);
+ }
+ else
+ AL::readProperties(this, node);
+ }
+ view->layout1();
+ }
+
+
+//---------------------------------------------------------
+// write
+//---------------------------------------------------------
+
+void WaveEdit::write(Xml& xml) const
+ {
+ for (ciPart p = _parts->begin(); p != _parts->end(); ++p) {
+ Part* part = p->second;
+ Track* track = part->track();
+ int trkIdx = song->tracks()->indexOf(track);
+ int partIdx = track->parts()->index(part);
+ xml.stag("part");
+ xml.put(QString("%1:%2").arg(trkIdx).arg(partIdx));
+ xml.etag("part");
+ }
+ xml.stag(metaObject()->className());
+ xml.writeProperties(this);
+ const CtrlEditList* el = view->getCtrlEditors();
+ for (ciCtrlEdit i = el->begin(); i != el->end(); ++i) {
+ xml.tagE(QString("CtrlEdit h=\"%1\" id=\"%2\"")
+ .arg((*i)->height()).arg((*i)->ctrl()->id()));
+ }
+ xml.etag(metaObject()->className());
+ }
+
+
diff --git a/muse_qt4_evolution/muse/waveedit/waveedit.h b/muse_qt4_evolution/muse/waveedit/waveedit.h
new file mode 100644
index 00000000..f861587d
--- /dev/null
+++ b/muse_qt4_evolution/muse/waveedit/waveedit.h
@@ -0,0 +1,88 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __WAVE_EDIT_H__
+#define __WAVE_EDIT_H__
+
+#include "midiedit/midieditor.h"
+
+class PartList;
+class WaveView;
+class ScrollScale;
+class SNode;
+
+namespace Awl {
+ class PosLabel;
+ };
+using Awl::PosLabel;
+
+
+//---------------------------------------------------------
+// WaveEdit
+//---------------------------------------------------------
+
+class WaveEdit : public Editor {
+ Q_OBJECT
+
+ PartList* _parts;
+ Part* selPart;
+
+ WaveView* view;
+ QToolBar* tools;
+ QToolBar* tb1;
+ QAction* solo;
+ PosLabel* pos1;
+ PosLabel* pos2;
+
+ static int _widthInit, _heightInit;
+
+ virtual void keyPressEvent(QKeyEvent*);
+
+ QMenu* menuFunctions, *select, *menuGain;
+
+ private slots:
+ void cmd(QAction*);
+ void setTime(unsigned t);
+ void soloChanged(SNode* s);
+ void soloChanged(bool flag);
+
+ public slots:
+ void configChanged();
+
+ public:
+ WaveEdit(PartList*, bool);
+ ~WaveEdit();
+ PartList* parts() const { return _parts; }
+ void read(QDomNode node);
+ void write(Xml& xml) const;
+
+ enum { CMD_MUTE=0, CMD_NORMALIZE, CMD_FADE_IN, CMD_FADE_OUT, CMD_REVERSE,
+ CMD_GAIN_FREE, CMD_GAIN_200, CMD_GAIN_150, CMD_GAIN_75, CMD_GAIN_50, CMD_GAIN_25,
+ CMD_EDIT_EXTERNAL,
+ CMD_SELECT_ALL, CMD_SELECT_NONE };
+ static int initWidth, initHeight;
+ static const int INIT_WIDTH = 650;
+ static const int INIT_HEIGHT = 450;
+ };
+
+static const bool INIT_FOLLOW = false;
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/waveedit/waveview.cpp b/muse_qt4_evolution/muse/waveedit/waveview.cpp
new file mode 100644
index 00000000..eb5a744d
--- /dev/null
+++ b/muse_qt4_evolution/muse/waveedit/waveview.cpp
@@ -0,0 +1,1124 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include <sys/wait.h>
+
+#include "waveview.h"
+#include "song.h"
+#include "midiedit/midieditor.h"
+#include "al/tempo.h"
+#include "event.h"
+#include "globals.h"
+#include "waveedit.h"
+#include "audio.h"
+#include "gconfig.h"
+#include "part.h"
+#include "widgets/simplebutton.h"
+#include "utils.h"
+
+static const int partLabelHeight = 13;
+
+//---------------------------------------------------------
+// WaveView
+//---------------------------------------------------------
+
+WaveView::WaveView(WaveEdit* pr)
+ : TimeCanvas(TIME_CANVAS_WAVEEDIT)
+ {
+ setMarkerList(song->marker());
+ curSplitter = -1;
+ dragSplitter = false;
+ selectionStart = 0;
+ selectionStop = 0;
+ lastGainvalue = 100;
+ editor = pr;
+
+ curPart = editor->parts()->begin()->second;
+ setMouseTracking(true);
+
+ songChanged(SC_TRACK_INSERTED);
+ }
+
+//---------------------------------------------------------
+// drawWavePart
+// y0 - start of track
+// th - track height
+// from - x pixel coordinate start drawing
+// to - x end drawing
+//
+// redraw area is QRect(from, y0, to-from, th)
+//---------------------------------------------------------
+
+void WaveView::drawWavePart(QPainter& p, Part* wp, int y0, int th, int from, int to)
+ {
+ int h = th/2;
+ int y = y0 + 1 + h;
+ int cc = th % 2 ? 0 : 1;
+
+ const Pos pos(pix2pos(from));
+ EventList* el = wp->events();
+ for (iEvent e = el->begin(); e != el->end(); ++e) {
+ Event event = e->second;
+ SndFileR f = event.sndFile();
+ if (f.isNull())
+ continue;
+ unsigned channels = f.channels();
+ if (channels == 0) {
+ printf("drawWavePart: channels==0! %s\n", f.finfo()->fileName().toLatin1().data());
+ continue;
+ }
+
+ int x1 = pos2pix(event.pos() + *wp);
+ int x2 = pos2pix(event.end() + *wp);
+ int w = x2 - x1;
+ if (w == 0)
+ continue;
+
+ int samples = event.lenFrame();
+ int xScale = (samples + w/2)/w;
+ int frame = pos.frame() - wp->frame()
+ - event.pos().frame() + event.spos();
+
+ if (h < 20) {
+ //
+ // combine multi channels into one waveform
+ //
+ for (int i = from; i < to; i++) {
+ SampleV sa[channels];
+ f.read(sa, xScale, frame);
+ frame += xScale;
+ int peak = 0;
+ int rms = 0;
+ for (unsigned k = 0; k < channels; ++k) {
+ if (sa[k].peak > peak)
+ peak = sa[k].peak;
+ rms += sa[k].rms;
+ }
+ rms /= channels;
+ peak = (peak * (th-2)) >> 9;
+ rms = (rms * (th-2)) >> 9;
+ p.setPen(QColor(Qt::darkGray));
+ p.drawLine(i, y - peak - cc, i, y + peak);
+ p.setPen(QColor(Qt::black));
+ p.drawLine(i, y - rms - cc, i, y + rms);
+ }
+ }
+ else {
+ //
+ // multi channel display
+ //
+ h = th / (channels * 2);
+ int cc = th % (channels * 2) ? 0 : 1;
+ for (int i = from; i < to; i++) {
+ y = y0 + 1 + h;
+ SampleV sa[channels];
+ f.read(sa, xScale, frame);
+ frame += xScale;
+ for (unsigned k = 0; k < channels; ++k) {
+ int peak = (sa[k].peak * (h - 1)) >> 8;
+ int rms = (sa[k].rms * (h - 1)) >> 8;
+ p.setPen(QColor(Qt::darkGray));
+ p.drawLine(i, y - peak - cc, i, y + peak);
+ p.setPen(QColor(Qt::black));
+ p.drawLine(i, y - rms - cc, i, y + rms);
+ y += 2 * h;
+ }
+ }
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// draw
+//---------------------------------------------------------
+
+void WaveView::paint(QPainter& p, QRect r)
+ {
+ QFont f = font();
+ f.setPointSize(8);
+ p.setFont(f);
+
+ int from = r.x();
+ int to = from + r.width();
+
+ PartList* pl = editor->parts();
+ for (iPart ip = pl->begin(); ip != pl->end(); ++ip) {
+ Part* part = ip->second;
+ int x1 = pos2pix(*part);
+ int x2 = pos2pix(part->end());
+ int len = x2 - x1;
+
+ if (x2 <= from)
+ continue;
+ if (x1 > to)
+ break;
+
+ int h = rCanvasA.height();
+ int xx1 = x1;
+ if (xx1 < from)
+ xx1 = from;
+ int xx2 = x2;
+ if (xx2 > to)
+ xx2 = to;
+ drawWavePart(p, part, 0, h, xx1, xx2);
+ int yy = h - partLabelHeight;
+ p.drawText(x1 + 3, yy, len - 6,
+ partLabelHeight-1, Qt::AlignVCenter | Qt::AlignLeft,
+ part->name());
+ }
+ }
+
+//---------------------------------------------------------
+// getCaption
+//---------------------------------------------------------
+
+QString WaveView::getCaption() const
+ {
+ QString caption("MusE: WaveEditor");
+ if (curPart)
+ return caption + QString(": ") + curPart->name();
+ return caption;
+ }
+
+//---------------------------------------------------------
+// songChanged
+//---------------------------------------------------------
+
+void WaveView::songChanged(int flags)
+ {
+ if (flags & ~SC_SELECTION) {
+ startFrame = MAXINT;
+ endFrame = 0;
+ for (iPart p = editor->parts()->begin(); p != editor->parts()->end(); ++p) {
+ Part* part = p->second;
+ int sframe = part->frame();
+ int eframe = sframe + part->lenFrame();
+ if (sframe < startFrame)
+ startFrame = sframe;
+ if (eframe > endFrame)
+ endFrame = eframe;
+ }
+ }
+// if (flags & SC_CLIP_MODIFIED) {
+// update(); // Boring, but the only thing possible to do
+// }
+ setPart(*curPart, curPart->end());
+ widget()->update();
+ }
+
+//---------------------------------------------------------
+// mousePress
+//---------------------------------------------------------
+
+void WaveView::mousePress(QMouseEvent* me)
+ {
+ QPoint pos(me->pos());
+
+ if (rCanvasA.contains(pos)) {
+// mousePressCanvasA(me);
+ return;
+ }
+ if (curSplitter != -1) {
+ dragSplitter = true;
+ splitterY = pos.y();
+ return;
+ }
+
+ if (rCanvasB.contains(pos)) {
+ for (iCtrlEdit i = ctrlEditList.begin(); i != ctrlEditList.end(); ++i) {
+ CtrlEdit* c = *i;
+ QRect r(rCanvasB.x(), rCanvasB.y() + c->y + splitWidth,
+ rCanvasB.width(), c->cheight());
+ if (r.contains(pos)) {
+ c->mousePress(pos - r.topLeft(), me);
+ break;
+ }
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// mouseRelease
+//---------------------------------------------------------
+
+void WaveView::mouseRelease(QMouseEvent* me)
+ {
+ if (dragSplitter) {
+ dragSplitter = false;
+ return;
+ }
+ QPoint pos(me->pos());
+ if (rCanvasA.contains(pos)) {
+ // mouseReleaseCanvasA(me);
+ return;
+ }
+ if (rCanvasB.contains(pos)) {
+ for (iCtrlEdit i = ctrlEditList.begin(); i != ctrlEditList.end(); ++i) {
+ CtrlEdit* c = *i;
+ QRect r(rCanvasB.x(), rCanvasB.y() + c->y + splitWidth,
+ rCanvasB.width(), c->cheight());
+ if (r.contains(pos)) {
+ c->mouseRelease();
+ break;
+ }
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// mouseMove
+//---------------------------------------------------------
+
+void WaveView::mouseMove(QPoint pos)
+ {
+ if (dragSplitter) {
+ int deltaY = pos.y() - splitterY;
+
+ iCtrlEdit i = ctrlEditList.begin();
+ int y = 0;
+ if (curSplitter > 0) {
+ int k = 0;
+ CtrlEdit* c = 0;
+ for (; i != ctrlEditList.end(); ++i, ++k) {
+ c = *i;
+ y += c->height();
+ if ((k+1) == curSplitter)
+ break;
+ }
+ if (i == ctrlEditList.end()) {
+ printf("unexpected edit list end, curSplitter %d\n", curSplitter);
+ return;
+ }
+ if (c->height() + deltaY < splitWidth)
+ deltaY = splitWidth - c->height();
+ ++i;
+ int rest = 0;
+ for (iCtrlEdit ii = i; ii != ctrlEditList.end(); ++ii)
+ rest += (*ii)->cheight();
+ if (rest < deltaY)
+ deltaY = rest;
+ c->setHeight(c->height() + deltaY);
+ layoutPanelB(c);
+ y += deltaY;
+ }
+ //
+ // layout rest, add deltaY vertical
+ //
+ int rest = 0;
+ for (iCtrlEdit ii = i; ii != ctrlEditList.end(); ++ii) {
+ CtrlEdit* c = *ii;
+ rest += c->cheight();
+ }
+ if (rest < deltaY)
+ deltaY = rest;
+ rest = deltaY;
+ for (; i != ctrlEditList.end(); ++i) {
+ CtrlEdit* c = *i;
+ int d = c->cheight();
+ if (d > deltaY)
+ d = deltaY;
+ c->setHeight(c->height() - d);
+ c->y = y;
+ layoutPanelB(c);
+ y += c->height();
+ deltaY -= d;
+ if (deltaY == 0)
+ break;
+ }
+ if (i != ctrlEditList.end())
+ ++i;
+ for (; i != ctrlEditList.end(); ++i) {
+ CtrlEdit* c = *i;
+ c->y = y;
+ y += c->height();
+ }
+ if (curSplitter == 0)
+ resizeController(ctrlHeight - rest);
+ else
+ widget()->update(rPanelB | rCanvasB);
+ splitterY = pos.y();
+ updatePartControllerList();
+ return;
+ }
+ if (rCanvasA.contains(pos)) {
+ // mouseMoveCanvasA(pos - rCanvasA.topLeft());
+ return;
+ }
+ if (button == 0) {
+ if (rPanelB.contains(pos) || rCanvasB.contains(pos)) {
+ int y = pos.y() - rPanelB.y();
+ int k = 0;
+ for (iCtrlEdit i = ctrlEditList.begin(); i != ctrlEditList.end(); ++i, ++k) {
+ CtrlEdit* c = *i;
+ if (y >= c->y && y < (c->y + splitWidth)) {
+ curSplitter = k;
+ setCursor();
+ return;
+ }
+ int ypos = y - c->y - splitWidth;
+ if (ypos >= 0)
+ emit yChanged(c->pixel2val(ypos));
+ }
+ }
+ if (curSplitter != -1) {
+ curSplitter = -1;
+ setCursor();
+ }
+ return;
+ }
+ if (rCanvasB.contains(pos)) {
+ for (iCtrlEdit i = ctrlEditList.begin(); i != ctrlEditList.end(); ++i) {
+ CtrlEdit* c = *i;
+ QRect r(rCanvasB.x(), rCanvasB.y() + c->y + splitWidth,
+ rCanvasB.width(), c->cheight());
+ if (r.contains(pos)) {
+ c->mouseMove(pos - r.topLeft());
+ break;
+ }
+ }
+ }
+
+ }
+
+//---------------------------------------------------------
+// cmd
+//---------------------------------------------------------
+
+void WaveView::cmd(const QString&)
+ {
+#if 0
+ int modifyoperation = -1;
+ double paramA = 0.0;
+
+ switch(n) {
+ case WaveEdit::CMD_SELECT_ALL:
+ if (!editor->parts()->empty()) {
+ iPart iBeg = editor->parts()->begin();
+ iPart iEnd = editor->parts()->end();
+ iEnd--;
+ Part* beg = iBeg->second;
+ Part* end = iEnd->second;
+ selectionStart = beg->frame();
+ selectionStop = end->frame() + end->lenFrame();
+ update();
+ }
+ break;
+
+ case WaveEdit::CMD_EDIT_EXTERNAL:
+ modifyoperation = EDIT_EXTERNAL;
+ break;
+
+ case WaveEdit::CMD_SELECT_NONE:
+ selectionStart = selectionStop = 0;
+ update();
+ break;
+
+ case WaveEdit::CMD_MUTE:
+ modifyoperation = MUTE;
+ break;
+
+ case WaveEdit::CMD_NORMALIZE:
+ modifyoperation = NORMALIZE;
+ break;
+
+ case WaveEdit::CMD_FADE_IN:
+ modifyoperation = FADE_IN;
+ break;
+
+ case WaveEdit::CMD_FADE_OUT:
+ modifyoperation = FADE_OUT;
+ break;
+
+ case WaveEdit::CMD_REVERSE:
+ modifyoperation = REVERSE;
+ break;
+
+ case WaveEdit::CMD_GAIN_FREE: {
+ /*
+ EditGain* editGain = new EditGain(this, lastGainvalue);
+ if (editGain->exec() == QDialog::Accepted) {
+ lastGainvalue = editGain->getGain();
+ modifyoperation = GAIN;
+ paramA = (double)lastGainvalue / 100.0;
+ }
+ delete editGain;
+ */
+ printf("Free gain - todo!\n");
+ }
+ break;
+
+ case WaveEdit::CMD_GAIN_200:
+ modifyoperation = GAIN;
+ paramA = 2.0;
+ break;
+
+ case WaveEdit::CMD_GAIN_150:
+ modifyoperation = GAIN;
+ paramA = 1.5;
+ break;
+
+ case WaveEdit::CMD_GAIN_75:
+ modifyoperation = GAIN;
+ paramA = 0.75;
+ break;
+
+ case WaveEdit::CMD_GAIN_50:
+ modifyoperation = GAIN;
+ paramA = 0.5;
+ break;
+
+ case WaveEdit::CMD_GAIN_25:
+ modifyoperation = GAIN;
+ paramA = 0.25;
+ break;
+
+ default:
+ break;
+ }
+
+ if (modifyoperation != -1) {
+ if (selectionStart == selectionStop) {
+ printf("No selection. Ignoring\n"); //@!TODO: Disable menu options when no selection
+ return;
+ }
+ modifySelection(modifyoperation, selectionStart, selectionStop, paramA);
+ }
+#endif
+ }
+
+//---------------------------------------------------------
+// getSelection
+//---------------------------------------------------------
+
+WaveSelectionList WaveView::getSelection(unsigned /*startpos*/, unsigned /*stoppos*/)
+ {
+ WaveSelectionList selection;
+#if 0
+ for (iPart ip = editor->parts()->begin(); ip != editor->parts()->end(); ++ip) {
+ Part* wp = ip->second;
+ unsigned part_offset = wp->frame();
+ EventList* el = wp->events();
+
+ for (iEvent e = el->begin(); e != el->end(); ++e) {
+ Event event = e->second;
+ if (event.empty())
+ continue;
+ SndFileR file = event.sndFile();
+ if (file.isNull())
+ continue;
+
+ unsigned event_offset = event.frame() + part_offset;
+ unsigned event_startpos = event.spos();
+ unsigned event_length = event.lenFrame() + event.spos();
+ unsigned event_end = event_offset + event_length;
+ //printf("startpos=%d stoppos=%d part_offset=%d event_offset=%d event_startpos=%d event_length=%d event_end=%d\n", startpos, stoppos, part_offset, event_offset, event_startpos, event_length, event_end);
+
+ if (!(event_end <= startpos || event_offset >= stoppos)) {
+ int tmp_sx = startpos - event_offset + event_startpos;
+ int tmp_ex = stoppos - event_offset + event_startpos;
+ unsigned sx;
+ unsigned ex;
+
+ tmp_sx < (int)event_startpos ? sx = event_startpos : sx = tmp_sx;
+ tmp_ex > (int)event_length ? ex = event_length : ex = tmp_ex;
+
+ //printf("Event data affected: %d->%d filename:%s\n", sx, ex, file.name().toLatin1().data());
+ WaveEventSelection s;
+ s.file = file;
+ s.startframe = sx;
+ s.endframe = ex;
+ selection.push_back(s);
+ }
+ }
+ }
+#endif
+ return selection;
+ }
+
+//---------------------------------------------------------
+// modifySelection
+//---------------------------------------------------------
+
+void WaveView::modifySelection(int /*operation*/, unsigned /*startpos*/, unsigned /*stoppos*/, double /*paramA*/)
+ {
+#if 0
+ song->startUndo();
+
+ WaveSelectionList selection = getSelection(startpos, stoppos);
+ for (iWaveSelection i = selection.begin(); i != selection.end(); i++) {
+ WaveEventSelection w = *i;
+ SndFileR& file = w.file;
+ unsigned sx = w.startframe;
+ unsigned ex = w.endframe;
+ unsigned file_channels = file.channels();
+
+ QString tmpWavFile = QString::null;
+ if (!getUniqueTmpfileName(tmpWavFile)) {
+ break;
+ }
+
+ audio->msgIdle(true); // Not good with playback during operations
+ SndFile tmpFile(tmpWavFile);
+ tmpFile.setFormat(file.format(), file_channels, file.samplerate());
+ if (tmpFile.openWrite()) {
+ audio->msgIdle(false);
+ printf("Could not open temporary file...\n");
+ break;
+ }
+
+ //
+ // Write out data that will be changed to temp file
+ //
+ unsigned tmpdatalen = ex - sx;
+ off_t tmpdataoffset = sx;
+ float* tmpdata[file_channels];
+
+ for (unsigned i=0; i<file_channels; i++) {
+ tmpdata[i] = new float[tmpdatalen];
+ }
+
+ file.seek(tmpdataoffset, 0);
+ file.read(file_channels, tmpdata, tmpdatalen);
+ file.close();
+ tmpFile.write(file_channels, tmpdata, tmpdatalen);
+ tmpFile.close();
+
+ switch(operation)
+ {
+ case MUTE:
+ muteSelection(file_channels, tmpdata, tmpdatalen);
+ break;
+
+ case NORMALIZE:
+ normalizeSelection(file_channels, tmpdata, tmpdatalen);
+ break;
+
+ case FADE_IN:
+ fadeInSelection(file_channels, tmpdata, tmpdatalen);
+ break;
+
+ case FADE_OUT:
+ fadeOutSelection(file_channels, tmpdata, tmpdatalen);
+ break;
+
+ case REVERSE:
+ reverseSelection(file_channels, tmpdata, tmpdatalen);
+ break;
+
+ case GAIN:
+ applyGain(file_channels, tmpdata, tmpdatalen, paramA);
+ break;
+
+ case EDIT_EXTERNAL:
+ editExternal(file.format(), file.samplerate(), file_channels, tmpdata, tmpdatalen);
+ break;
+
+ default:
+ printf("Error: Default state reached in modifySelection\n");
+ break;
+
+ }
+
+ file.openWrite();
+ file.seek(tmpdataoffset, 0);
+ file.write(file_channels, tmpdata, tmpdatalen);
+ file.update();
+ file.close();
+ file.openRead();
+
+ for (unsigned i=0; i<file_channels; i++) {
+ delete[] tmpdata[i];
+ }
+
+ // Undo handling
+ song->cmdChangeWave(file.dirPath() + "/" + file.name(), tmpWavFile, sx, ex);
+ audio->msgIdle(false); // Not good with playback during operations
+ }
+ song->endUndo(SC_CLIP_MODIFIED);
+ update();
+#endif
+ }
+
+//---------------------------------------------------------
+// muteSelection
+//---------------------------------------------------------
+
+void WaveView::muteSelection(unsigned /*channels*/, float** /*data*/, unsigned /*length*/)
+ {
+#if 0
+ // Set everything to 0!
+ for (unsigned i=0; i<channels; i++) {
+ for (unsigned j=0; j<length; j++) {
+ data[i][j] = 0;
+ }
+ }
+#endif
+ }
+
+//---------------------------------------------------------
+// normalizeSelection
+//---------------------------------------------------------
+
+void WaveView::normalizeSelection(unsigned /*channels*/, float** /*data*/, unsigned /*length*/)
+ {
+#if 0
+ float loudest = 0.0;
+
+ for (unsigned i=0; i<channels; i++) {
+ for (unsigned j=0; j<length; j++) {
+ if (data[i][j] > loudest)
+ loudest = data[i][j];
+ }
+ }
+
+ double scale = 0.99 / (double)loudest;
+
+ for (unsigned i=0; i<channels; i++) {
+ for (unsigned j=0; j<length; j++) {
+ data[i][j] = (float) ((double)data[i][j] * scale);
+ }
+ }
+#endif
+ }
+
+//---------------------------------------------------------
+// fadeInSelection
+//---------------------------------------------------------
+
+void WaveView::fadeInSelection(unsigned /*channels*/, float** /*data*/, unsigned /*length*/)
+ {
+#if 0
+ for (unsigned i=0; i<channels; i++) {
+ for (unsigned j=0; j<length; j++) {
+ double scale = (double) j / (double)length ;
+ data[i][j] = (float) ((double)data[i][j] * scale);
+ }
+ }
+#endif
+ }
+
+//---------------------------------------------------------
+// fadeOutSelection
+//---------------------------------------------------------
+
+void WaveView::fadeOutSelection(unsigned /*channels*/, float** /*data*/, unsigned /*length*/)
+ {
+#if 0
+ for (unsigned i=0; i<channels; i++) {
+ for (unsigned j=0; j<length; j++) {
+ double scale = (double) (length - j) / (double)length ;
+ data[i][j] = (float) ((double)data[i][j] * scale);
+ }
+ }
+#endif
+ }
+
+//---------------------------------------------------------
+// reverseSelection
+//---------------------------------------------------------
+
+void WaveView::reverseSelection(unsigned channels, float** data, unsigned length)
+ {
+ for (unsigned i=0; i<channels; i++) {
+ for (unsigned j=0; j<length/2; j++) {
+ float tmpl = data[i][j];
+ float tmpr = data[i][length - j];
+ data[i][j] = tmpr;
+ data[i][length - j] = tmpl;
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// applyGain
+//---------------------------------------------------------
+
+void WaveView::applyGain(unsigned channels, float** data, unsigned length, double gain)
+ {
+ for (unsigned i=0; i<channels; i++) {
+ for (unsigned j=0; j<length; j++) {
+ data[i][j] = (float) ((double)data[i][j] * gain);
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// editExternal
+//---------------------------------------------------------
+
+void WaveView::editExternal(unsigned file_format, unsigned file_samplerate, unsigned file_channels, float** tmpdata, unsigned tmpdatalen)
+ {
+ // Create yet another tmp-file
+ QString exttmpFileName;
+ if (!getUniqueTmpfileName(exttmpFileName)) {
+ printf("Could not create temp file - aborting...\n");
+ return;
+ }
+
+ SndFile exttmpFile(exttmpFileName);
+ exttmpFile.setFormat(file_format, file_channels, file_samplerate);
+ if (exttmpFile.openWrite()) {
+ printf("Could not open temporary file...\n");
+ return;
+ }
+ // Write out change-data to this file:
+ exttmpFile.write(file_channels, tmpdata, tmpdatalen);
+ exttmpFile.close();
+
+ // Forkaborkabork
+ int pid = vfork();
+ if (pid == 0) {
+ if (execlp(config.externalWavEditor.toLatin1().data(), "", exttmpFileName.toLatin1().data(), NULL) == -1) {
+ perror("Failed to launch external editor");
+ // Get out of here
+ exit(-1);
+ }
+ //@!TODO: Handle unsuccessful attempts
+ }
+ else if (pid == -1) {
+ perror("fork failed");
+ }
+ else {
+ waitpid(pid, 0, 0);
+ if (exttmpFile.openRead()) {
+ printf("Could not reopen temporary file again!\n");
+ }
+ else {
+ // Re-read file again
+ exttmpFile.seek(0);
+ size_t sz = exttmpFile.read(file_channels, tmpdata, tmpdatalen);
+ if (sz != tmpdatalen) {
+ // File must have been shrunken - not good. Alert user.
+ QMessageBox::critical(this, tr("MusE - file size changed"),
+ tr("When editing in external editor - you should not change the filesize\nsince it must fit the selected region.\n\nMissing data is muted"));
+ for (unsigned i=0; i<file_channels; i++) {
+ for (unsigned j=sz; j<tmpdatalen; j++) {
+ tmpdata[i][j] = 0;
+ }
+ }
+ }
+ }
+ QDir dir = exttmpFile.finfo()->absolutePath();
+ dir.remove(exttmpFileName);
+ dir.remove(exttmpFile.finfo()->baseName() + ".wca");
+ }
+ }
+
+//---------------------------------------------------------
+// getUniqueTmpfileName
+//---------------------------------------------------------
+
+bool WaveView::getUniqueTmpfileName(QString& newFilename)
+ {
+ // Check if tmp-directory exists under project path
+ QString tmpWavDir = song->absoluteProjectPath() + "/tmp_musewav"; //!@TODO: Don't hardcode like this
+ QFileInfo tmpdirfi(tmpWavDir);
+ if (!tmpdirfi.isDir()) {
+ // Try to create a tmpdir
+ QDir projdir(song->absoluteProjectPath());
+ if (!projdir.mkdir("tmp_musewav")) {
+ printf("Could not create undo dir!\n");
+ return false;
+ }
+ }
+
+
+ tmpdirfi.setFile(tmpWavDir);
+
+ if (!tmpdirfi.isWritable()) {
+ printf("Temp directory is not writable - aborting\n");
+ return false;
+ }
+
+ QDir tmpdir = tmpdirfi.dir();
+
+ // Find a new filename
+ for (int i=0; i<10000; i++) {
+ QString filename = "muse_tmp";
+ filename.append(QString::number(i));
+ filename.append(".wav");
+
+ if (!tmpdir.exists(tmpWavDir +"/" + filename)) {
+ newFilename = tmpWavDir + "/" + filename;
+ return true;
+ }
+ }
+
+ printf("Could not find a suitable tmpfilename (more than 10000 tmpfiles in tmpdir - clean up!\n");
+ return false;
+ }
+
+//---------------------------------------------------------
+// range
+//---------------------------------------------------------
+
+void WaveView::range(AL::Pos& s, AL::Pos& e) const
+ {
+ s.setFrame(startFrame);
+ e.setFrame(endFrame);
+ }
+
+//---------------------------------------------------------
+// layout
+//---------------------------------------------------------
+
+void WaveView::layout()
+ {
+ int n = ctrlEditList.size();
+ if (n == 0)
+ return;
+ if (ctrlHeight == 0) {
+ int wh = widget()->height();
+ resizeController(wh < 120 ? wh / 2 : 100);
+ }
+ // check, if layout is ok already; this happens after
+ // song load
+ int h = 0;
+ for (iCtrlEdit i = ctrlEditList.begin(); i != ctrlEditList.end(); ++i) {
+ CtrlEdit* c = *i;
+ h += c->height();
+ }
+ if (h == ctrlHeight) {
+ for (iCtrlEdit i = ctrlEditList.begin(); i != ctrlEditList.end(); ++i)
+ layoutPanelB(*i);
+ return;
+ }
+ int y = 0;
+ int sch = ctrlHeight / n;
+ for (iCtrlEdit i = ctrlEditList.begin(); i != ctrlEditList.end(); ++i) {
+ CtrlEdit* c = *i;
+ c->y = y;
+ c->setHeight(sch);
+ layoutPanelB(c);
+ y += sch;
+ }
+ }
+
+//---------------------------------------------------------
+// layout1
+//---------------------------------------------------------
+
+void WaveView::layout1()
+ {
+ int n = ctrlEditList.size();
+ if (n == 0)
+ return;
+ int y = 0;
+ for (iCtrlEdit i = ctrlEditList.begin(); i != ctrlEditList.end(); ++i) {
+ CtrlEdit* c = *i;
+ c->y = y;
+ y += c->height();
+ }
+ resizeController(y);
+ }
+
+//---------------------------------------------------------
+// layoutPanelB
+//---------------------------------------------------------
+
+void WaveView::layoutPanelB(CtrlEdit* c)
+ {
+ int y = c->y;
+ int h = c->height();
+ int bx = rPanelB.x() + rPanelB.width() - 23;
+ int by = rPanelB.y() + y + h - 19;
+ c->minus->setGeometry(bx, by, 18, 18);
+ bx = rPanelB.x() + 1;
+ by = rPanelB.y() + y + 5;
+ c->sel->setGeometry(bx, by, rPanelB.width() - 5, 18);
+ }
+
+//---------------------------------------------------------
+// addController
+//---------------------------------------------------------
+
+void WaveView::addController()
+ {
+ int n = ctrlEditList.size();
+ CtrlEdit* ce = new CtrlEdit(widget(), this, curPart->track());
+ ce->setHeight(50);
+ ctrlEditList.push_back(ce);
+
+ ce->minus->defaultAction()->setData(n);
+ connect(ce->minus, SIGNAL(triggered(QAction*)), SLOT(removeController(QAction*)));
+ ce->minus->show();
+ ce->sel->show();
+
+ layout();
+ widget()->update();
+ updatePartControllerList();
+ }
+
+void WaveView::addController(int id, int h)
+ {
+ ctrlHeight += h;
+ int n = ctrlEditList.size();
+
+ CtrlEdit* ce = new CtrlEdit(widget(), this, curPart->track());
+ ce->setHeight(h);
+ ce->setCtrl(id);
+ ctrlEditList.push_back(ce);
+
+ ce->minus->defaultAction()->setData(n);
+ connect(ce->minus, SIGNAL(triggered(QAction*)), SLOT(removeController(QAction*)));
+ }
+
+//---------------------------------------------------------
+// removeController
+//---------------------------------------------------------
+
+void WaveView::removeController(QAction* a)
+ {
+ int id = a->data().toInt();
+
+ int k = 0;
+ for (iCtrlEdit i = ctrlEditList.begin(); i != ctrlEditList.end(); ++i, ++k) {
+ if (k == id) {
+ CtrlEdit* c = *i;
+ delete c;
+ ctrlEditList.erase(i);
+ break;
+ }
+ }
+ k = 0;
+ for (iCtrlEdit i = ctrlEditList.begin(); i != ctrlEditList.end(); ++i, ++k) {
+ CtrlEdit* c = *i;
+ c->minus->defaultAction()->setData(k);
+ }
+
+ if (ctrlEditList.empty())
+ resizeController(0);
+ else
+ layout();
+ widget()->update();
+ updatePartControllerList();
+ }
+
+//---------------------------------------------------------
+// updatePartControllerList
+//---------------------------------------------------------
+
+void WaveView::updatePartControllerList()
+ {
+ if (curPart == 0)
+ return;
+ CtrlCanvasList* cl = curPart->getCtrlCanvasList();
+ cl->clear();
+ for (iCtrlEdit i = ctrlEditList.begin(); i != ctrlEditList.end(); ++i) {
+ CtrlCanvas cc;
+ cc.ctrlId = (*i)->ctrlId;
+ cc.height = (*i)->height();
+ cl->push_back(cc);
+ }
+ }
+
+//---------------------------------------------------------
+// paintControllerCanvas
+// r(0, 0) is PanelB topLeft()
+//---------------------------------------------------------
+
+void WaveView::paintControllerCanvas(QPainter& p, QRect r)
+ {
+ int x1 = r.x();
+ int x2 = x1 + r.width();
+
+ int xx2 = rCanvasB.width();
+ if (xx2 >= x2)
+ x2 = xx2 - 2;
+ for (iCtrlEdit i = ctrlEditList.begin(); i != ctrlEditList.end(); ++i) {
+ CtrlEdit* c = *i;
+ int y = c->y;
+ paintHLine(p, x1, x2, y);
+ p.setPen(lineColor[0]);
+ p.drawLine(xx2-1, 1, xx2-1, splitWidth-2);
+
+ QRect rc(0, y + splitWidth, rCanvasB.width(), c->cheight());
+ QPoint pt(rc.topLeft());
+ rc &= r;
+ if (!rc.isEmpty()) {
+ p.translate(pt);
+ c->paint(p, rc.translated(-pt));
+ p.translate(-pt);
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// paintControllerPanel
+// panelB
+//---------------------------------------------------------
+
+void WaveView::paintControllerPanel(QPainter& p, QRect r)
+ {
+ p.fillRect(r, QColor(0xe0, 0xe0, 0xe0));
+ int x1 = r.x();
+ int x2 = x1 + r.width();
+
+ paintVLine(p, r.y() + splitWidth, r.y() + r.height(),
+ rPanelB.x() + rPanelB.width());
+
+ if (x1 == 0)
+ x1 = 1;
+ for (iCtrlEdit i = ctrlEditList.begin(); i != ctrlEditList.end(); ++i) {
+ CtrlEdit* c = *i;
+ paintHLine(p, x1, x2, c->y);
+ p.setPen(lineColor[0]);
+ p.drawLine(0, 1, 0, splitWidth-2);
+ }
+ }
+
+//---------------------------------------------------------
+// setCursor
+//---------------------------------------------------------
+
+void WaveView::setCursor()
+ {
+ if (curSplitter != -1) {
+ widget()->setCursor(Qt::SplitVCursor);
+ return;
+ }
+ TimeCanvas::setCursor();
+ }
+
+//---------------------------------------------------------
+// enterB
+//---------------------------------------------------------
+
+void WaveView::enterB()
+ {
+ if ((button == 0) && curSplitter != -1) {
+ curSplitter = -1;
+ setCursor();
+ }
+ }
+
+//---------------------------------------------------------
+// leaveB
+//---------------------------------------------------------
+
+void WaveView::leaveB()
+ {
+ if ((button == 0) && (curSplitter != -1)) {
+ curSplitter = -1;
+ setCursor();
+ }
+ }
+
+
diff --git a/muse_qt4_evolution/muse/waveedit/waveview.h b/muse_qt4_evolution/muse/waveedit/waveview.h
new file mode 100644
index 00000000..462ce26d
--- /dev/null
+++ b/muse_qt4_evolution/muse/waveedit/waveview.h
@@ -0,0 +1,127 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef WAVE_VIEW_H
+#define WAVE_VIEW_H
+
+#include "al/pos.h"
+#include "wave.h"
+#include "awl/tcanvas.h"
+#include "ctrl/ctrledit.h"
+
+class PartList;
+class QPainter;
+class QRect;
+class Part;
+class WaveEdit;
+class GraphMidiEditor;
+
+//---------------------------------------------------------
+// WaveEventSelection
+//---------------------------------------------------------
+
+struct WaveEventSelection {
+ SndFileR file;
+ unsigned startframe;
+ unsigned endframe;
+ };
+
+typedef std::list<WaveEventSelection> WaveSelectionList;
+typedef std::list<WaveEventSelection>::iterator iWaveSelection;
+
+//---------------------------------------------------------
+// WaveView
+//---------------------------------------------------------
+
+class WaveView : public TimeCanvas {
+ Q_OBJECT
+
+ WaveEdit* editor;
+ CtrlEditList ctrlEditList;
+
+ int startFrame;
+ int endFrame;
+
+ Part* curPart;
+
+ enum { NORMAL, DRAG } mode;
+ enum { MUTE = 0, NORMALIZE, FADE_IN, FADE_OUT, REVERSE, GAIN, EDIT_EXTERNAL }; //!< Modify operations
+
+ unsigned selectionStart, selectionStop, dragstartx;
+ int curSplitter; // -1 mouse not in splitter
+ bool dragSplitter;
+ int splitterY;
+
+ virtual void paint(QPainter&, QRect);
+ virtual void mousePress(QMouseEvent*);
+ virtual void mouseMove(QPoint);
+ virtual void enterB();
+ virtual void leaveB();
+ virtual void mouseRelease(QMouseEvent*);
+
+ bool getUniqueTmpfileName(QString& newFilename); //!< Generates unique filename for temporary SndFile
+ WaveSelectionList getSelection(unsigned startpos, unsigned stoppos);
+
+ int lastGainvalue; //!< Stores the last used gainvalue when specifiying gain value in the editgain dialog
+ void modifySelection(int operation, unsigned startpos, unsigned stoppos, double paramA); //!< Modifies selection
+
+ void muteSelection(unsigned channels, float** data, unsigned length); //!< Mutes selection
+ void normalizeSelection(unsigned channels, float** data, unsigned length); //!< Normalizes selection
+ void fadeInSelection(unsigned channels, float** data, unsigned length); //!< Linear fade in of selection
+ void fadeOutSelection(unsigned channels, float** data, unsigned length); //!< Linear fade out of selection
+ void reverseSelection(unsigned channels, float** data, unsigned length); //!< Reverse selection
+ void applyGain(unsigned channels, float** data, unsigned length, double gain); //!< Apply gain to selection
+
+ void editExternal(unsigned file_format, unsigned file_samplerate, unsigned channels, float** data, unsigned length);
+
+ //void applyLadspa(unsigned channels, float** data, unsigned length); //!< Apply LADSPA plugin on selection
+
+ void drawWavePart(QPainter& p, Part* wp, int y0, int th, int from, int to);
+ virtual void addController();
+ virtual void layout();
+ void layoutPanelB(CtrlEdit*);
+ void updatePartControllerList();
+
+ virtual void paintControllerCanvas(QPainter&, QRect);
+ virtual void paintControllerPanel(QPainter&, QRect);
+
+ void setCursor();
+
+ private slots:
+ void removeController(QAction*);
+
+ public slots:
+ void songChanged(int type);
+
+ signals:
+ void yChanged(int); // emitted from mouseMove in controller canvas
+
+ public:
+ WaveView(WaveEdit*);
+ QString getCaption() const;
+ void cmd(const QString&);
+ void range(AL::Pos&, AL::Pos&) const;
+ void addController(int id, int h);
+ void layout1();
+ const CtrlEditList* getCtrlEditors() const { return &ctrlEditList; }
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/waveevent.cpp b/muse_qt4_evolution/muse/waveevent.cpp
new file mode 100644
index 00000000..4aff6a47
--- /dev/null
+++ b/muse_qt4_evolution/muse/waveevent.cpp
@@ -0,0 +1,137 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "globals.h"
+#include "event.h"
+#include "waveevent.h"
+#include "al/xml.h"
+#include "wave.h"
+
+//---------------------------------------------------------
+// WaveEvent
+//---------------------------------------------------------
+
+WaveEventBase::WaveEventBase(EventType t)
+ : EventBase(t)
+ {
+ deleted = false;
+ }
+
+//---------------------------------------------------------
+// WaveEvent::mid
+//---------------------------------------------------------
+
+EventBase* WaveEventBase::mid(unsigned b, unsigned e)
+ {
+ WaveEventBase* ev = new WaveEventBase(*this);
+
+ int offset = b - frame();
+ unsigned end = endFrame();
+ if (e < end)
+ end = e;
+
+ int len = end - b;
+ ev->setFrame(b);
+ ev->setLenFrame(len);
+ ev->setSpos(spos() + offset);
+ return ev;
+ }
+
+//---------------------------------------------------------
+// dump
+//---------------------------------------------------------
+
+void WaveEventBase::dump(int n) const
+ {
+ EventBase::dump(n);
+ }
+
+//---------------------------------------------------------
+// WaveEventBase::read
+//---------------------------------------------------------
+
+void WaveEventBase::read(QDomNode node)
+ {
+ node = node.firstChild();
+ while (!node.isNull()) {
+ QDomElement e = node.toElement();
+ if (e.tagName() == "poslen")
+ PosLen::read(node);
+ else if (e.tagName() == "frame")
+ _spos = e.text().toInt();
+ else if (e.tagName() == "file") {
+ SndFile* wf = SndFile::getWave(e.text(), false);
+ if (wf)
+ f = SndFileR(wf);
+ }
+ else
+ printf("MusE:WaveEventBase: unknown tag %s\n", e.tagName().toLatin1().data());
+ node = node.nextSibling();
+ }
+ Pos::setType(AL::FRAMES);
+ }
+
+//---------------------------------------------------------
+// write
+//---------------------------------------------------------
+
+void WaveEventBase::write(Xml& xml, const Pos& offset) const
+ {
+ if (f.isNull())
+ return;
+ xml.stag("event");
+ PosLen wpos(*this);
+ wpos += offset;
+// if (offset)
+// wpos.setTick(wpos.tick() + offset);
+ wpos.write(xml, "poslen");
+ xml.tag("frame", _spos); // offset in wave file
+ xml.tag("file", f.finfo()->fileName());
+ xml.etag("event");
+ }
+
+//---------------------------------------------------------
+// read
+//---------------------------------------------------------
+
+void WaveEventBase::read(unsigned offset, float** buffer, int channel, int n)
+ {
+ if (f.isNull())
+ return;
+ f.seek(offset + _spos);
+ f.read(channel, buffer, n);
+ }
+
+//---------------------------------------------------------
+// WaveEventBase::operator==
+//---------------------------------------------------------
+
+bool WaveEventBase::operator==(const EventBase& ev) const {
+
+ const WaveEventBase* pev = dynamic_cast<const WaveEventBase*>(&ev);
+
+ if(pev) return operator==(*pev);
+ else return false;
+}
+
+bool WaveEventBase::operator==(const WaveEventBase& /*ev*/) const {
+ //TODO
+ return false;
+}
diff --git a/muse_qt4_evolution/muse/waveevent.h b/muse_qt4_evolution/muse/waveevent.h
new file mode 100644
index 00000000..476b3a03
--- /dev/null
+++ b/muse_qt4_evolution/muse/waveevent.h
@@ -0,0 +1,61 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __WAVE_EVENT_H__
+#define __WAVE_EVENT_H__
+
+#include "eventbase.h"
+
+//---------------------------------------------------------
+// WaveEvent
+//---------------------------------------------------------
+
+class WaveEventBase : public EventBase {
+ QString _name;
+ SndFileR f;
+ int _spos; // start sample position in WaveFile
+ bool deleted;
+
+ virtual EventBase* clone() const { return new WaveEventBase(*this); }
+
+ public:
+ WaveEventBase(EventType t);
+ virtual ~WaveEventBase() {}
+
+ virtual void read(QDomNode);
+ virtual void write(Xml&, const Pos& offset) const;
+ virtual EventBase* mid(unsigned, unsigned);
+ virtual void dump(int n = 0) const;
+
+
+ virtual const QString name() const { return _name; }
+ virtual void setName(const QString& s) { _name = s; }
+ virtual int spos() const { return _spos; }
+ virtual void setSpos(int s) { _spos = s; }
+ virtual SndFileR sndFile() const { return f; }
+ virtual void setSndFile(SndFileR& sf) { f = sf; }
+ virtual void read(unsigned offset, float** bpp, int channels, int nn);
+
+ virtual bool operator==(const EventBase&) const;
+ virtual bool operator==(const WaveEventBase&) const;
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/wavetrack.cpp b/muse_qt4_evolution/muse/wavetrack.cpp
new file mode 100644
index 00000000..e796c3f3
--- /dev/null
+++ b/muse_qt4_evolution/muse/wavetrack.cpp
@@ -0,0 +1,427 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "wavetrack.h"
+#include "event.h"
+#include "audio.h"
+#include "wave.h"
+#include "al/xml.h"
+#include "al/dsp.h"
+#include "song.h"
+#include "globals.h"
+#include "part.h"
+#include "audiowriteback.h"
+#include "muse.h"
+#include "audioprefetch.h"
+
+bool WaveTrack::firstWaveTrack = true;
+
+//---------------------------------------------------------
+// WaveTrack
+//---------------------------------------------------------
+
+WaveTrack::WaveTrack()
+ : AudioTrack()
+ {
+ //
+ // allocate prefetch buffer
+ //
+ float* p = new float[FIFO_BUFFER * segmentSize * MAX_CHANNELS];
+ float** pp = new float*[FIFO_BUFFER * MAX_CHANNELS];
+
+ for (int i = 0; i < FIFO_BUFFER; ++i) {
+ readBuffer[i] = pp;
+ for (int k = 0; k < MAX_CHANNELS; ++k) {
+ *pp = p;
+ p += segmentSize;
+ ++pp;
+ }
+ }
+
+ recordPart = 0; // part we are recording into
+ }
+
+//---------------------------------------------------------
+// WaveTrack
+//---------------------------------------------------------
+
+WaveTrack::~WaveTrack()
+ {
+ delete[] *readBuffer[0];
+ delete[] readBuffer[0];
+ }
+
+//---------------------------------------------------------
+// fetchData
+// called from prefetch thread
+//---------------------------------------------------------
+
+void WaveTrack::fetchData(unsigned pos, unsigned samples, int widx)
+ {
+ float** bp = readBuffer[widx];
+ for (int i = 0; i < channels(); ++i)
+ memset(bp[i], 0, samples * sizeof(float));
+
+ PartList* pl = parts();
+ for (iPart ip = pl->begin(); ip != pl->end(); ++ip) {
+ Part* part = ip->second;
+
+ if (part->mute())
+ continue;
+ unsigned p_spos = part->frame();
+ if (pos + samples <= p_spos)
+ break;
+ unsigned p_epos = p_spos + part->lenFrame();
+ if (pos >= p_epos)
+ continue;
+
+ EventList* events = part->events();
+ for (iEvent ie = events->begin(); ie != events->end(); ++ie) {
+ Event& event = ie->second;
+
+ unsigned e_spos = event.frame() + p_spos;
+ if (pos + samples <= e_spos)
+ break;
+ unsigned nn = event.lenFrame();
+ unsigned e_epos = e_spos + nn;
+ if (pos >= e_epos)
+ continue;
+
+ int offset = e_spos - pos;
+
+ unsigned srcOffset, dstOffset;
+ if (offset > 0) {
+ nn = samples - offset;
+ srcOffset = 0;
+ dstOffset = offset;
+ }
+ else {
+ srcOffset = -offset;
+ dstOffset = 0;
+ nn -= offset;
+ if (nn > samples)
+ nn = samples;
+ }
+ if (dstOffset) {
+ float* bpp[channels()];
+ for (int i = 0; i < channels(); ++i)
+ bpp[i] = bp[i] + dstOffset;
+ event.read(srcOffset, bpp, channels(), nn);
+ }
+ else
+ event.read(srcOffset, bp, channels(), nn);
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// write
+//---------------------------------------------------------
+
+void WaveTrack::write(Xml& xml) const
+ {
+ xml.stag("wavetrack");
+ AudioTrack::writeProperties(xml);
+ const PartList* pl = parts();
+ for (ciPart p = pl->begin(); p != pl->end(); ++p)
+ p->second->write(xml);
+ xml.etag("wavetrack");
+ }
+
+//---------------------------------------------------------
+// read
+//---------------------------------------------------------
+
+void WaveTrack::read(QDomNode node)
+ {
+ for (; !node.isNull(); node = node.nextSibling()) {
+ QDomElement e = node.toElement();
+ if (e.tagName() == "part") {
+ Part* p = newPart();
+ p->read(node, false);
+ parts()->add(p);
+ }
+ else if (AudioTrack::readProperties(node))
+ printf("MusE:WaveTrack: unknown tag %s\n", e.tagName().toLatin1().data());
+ }
+ }
+
+//---------------------------------------------------------
+// newPart
+//---------------------------------------------------------
+
+Part* WaveTrack::newPart(Part*p, bool clone)
+ {
+ Part* part = new Part(this);
+ if (p) {
+ if (clone)
+ part->clone(p->events());
+ else
+ part->ref();
+ part->setName(p->name());
+ part->setColorIndex(p->colorIndex());
+
+ *(AL::PosLen*)part = *(AL::PosLen*)p;
+ part->setMute(p->mute());
+ }
+ else
+ part->ref();
+ return part;
+ }
+
+//---------------------------------------------------------
+// setChannels
+//---------------------------------------------------------
+
+void WaveTrack::setChannels(int n)
+ {
+ AudioTrack::setChannels(n);
+ SndFile* sf = recFile();
+ if (sf) {
+ if (sf->samples() == 0) {
+ sf->remove();
+ sf->setFormat(sf->format(), _channels,
+ sf->samplerate());
+ sf->openWrite();
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// startRecording
+// gui context
+//---------------------------------------------------------
+
+void WaveTrack::startRecording()
+ {
+ AudioTrack::startRecording(); // create file
+ partCreated = false;
+ AL::Pos start = song->punchin() ? song->lPos() : song->cPos();
+
+ // search for recordPart
+ recordPart = 0;
+ for (iPart ip = parts()->begin(); ip != parts()->end(); ++ip) {
+ Part* part = ip->second;
+ unsigned partStart = part->tick();
+ unsigned partEnd = partStart + part->lenTick();
+ if (start.tick() >= partStart && start.tick() < partEnd) {
+ recordPart = part;
+ break;
+ }
+ }
+ if (recordPart == 0) {
+ //
+ // create new part for recording
+ //
+ recordPart = new Part(this);
+ recordPart->ref();
+ recordPart->setType(AL::FRAMES);
+ Pos spos(start.downSnaped(muse->raster()));
+ Pos epos(start.upSnaped(muse->raster()));
+ recordPart->setPos(spos);
+ recordPart->setLenTick(epos.tick() - spos.tick());
+ recordPart->setName(name());
+ song->addPart(recordPart);
+ partCreated = true;
+ emit partsChanged();
+ }
+ }
+
+//---------------------------------------------------------
+// recordBeat
+// gui context
+// update current recording
+//---------------------------------------------------------
+
+void WaveTrack::recordBeat()
+ {
+ if (partCreated) {
+ int cpos = song->cpos();
+ int ptick = recordPart->tick();
+ recordPart->setLenTick(cpos - ptick);
+ song->addUpdateFlags(SC_PART_MODIFIED);
+ }
+ }
+
+//---------------------------------------------------------
+// stopRecording
+// gui context
+//---------------------------------------------------------
+
+void WaveTrack::stopRecording(const Pos& s, const Pos& e)
+ {
+ int updateFlags = 0;
+
+ while(audioWriteback->active())
+ sleep(1);
+ _recFile->update();
+
+ // create Event
+ Event event(Wave);
+ SndFileR sf(_recFile);
+ event.setSndFile(sf);
+ event.setPos(s - *recordPart);
+ event.setSpos(0);
+ event.setLenFrame(e.frame() - s.frame());
+ // recordPart->addEvent(event);
+ audio->msgAddEvent(event, recordPart, false);
+
+ _recFile = 0;
+
+ //
+ // adjust part len && song len
+ //
+ unsigned etick = e.upSnaped(muse->raster()).tick();
+ unsigned len = etick - recordPart->tick();
+
+ if (recordPart->lenTick() < len) {
+ recordPart->setLenTick(len);
+ updateFlags |= SC_PART_MODIFIED;
+ }
+
+ if (song->len() < etick)
+ song->setLen(etick);
+ song->update(updateFlags);
+ }
+
+//---------------------------------------------------------
+// canEnableRecord
+//---------------------------------------------------------
+
+bool WaveTrack::canEnableRecord() const
+ {
+ return (!noInRoute() || (this == song->bounceTrack));
+ }
+
+//---------------------------------------------------------
+// collectInputData
+//---------------------------------------------------------
+
+void WaveTrack::collectInputData()
+ {
+ bufferEmpty = false;
+ if (recordFlag() && (audio->isRecording() || !audio->isPlaying())) {
+ if (song->bounceTrack == this && audio->isPlaying()) {
+ OutputList* ol = song->outputs();
+ if (!ol->empty()) {
+//TODO AudioOutput* out = ol->front();
+ }
+ }
+ else
+ AudioTrack::collectInputData();
+ return;
+ }
+ if (!audio->isPlaying()) {
+ for (int i = 0; i < channels(); ++i)
+ memset(buffer[i], 0, sizeof(float) * segmentSize);
+ return;
+ }
+
+ if (audio->freewheel()) {
+ // when freewheeling, read data direct from file:
+ // TODO: fetchData(framePos, segmentSize, buffer);
+ }
+ else {
+ int idx = audio->curReadIndex();
+ if (idx == -1) {
+ for (int i = 0; i < channels(); ++i)
+ memset(buffer[i], 0, sizeof(float) * segmentSize);
+ }
+ else {
+ float** bpp = readBuffer[idx];
+ for (int i = 0; i < channels(); ++i)
+ AL::dsp->cpy(buffer[i], bpp[i], segmentSize);
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// process
+//---------------------------------------------------------
+
+void WaveTrack::process()
+ {
+ AudioTrack::process();
+
+ //
+ // record collected data for track
+ //
+ if (recordFlag() && audio->isRecording() && recFile()) {
+ unsigned framePos = audio->seqTime()->pos.frame();
+ if (audio->freewheel()) {
+ // write data directly to file
+ _recFile->write(channels(), buffer, framePos);
+ }
+ else {
+ if (fifo.put(channels(), segmentSize, buffer, framePos)) {
+ printf("WaveTrack(%s)::getData: fifo overrun\n",
+ name().toLatin1().data());
+ }
+ }
+ if (!_monitor) {
+ //
+ // end data processing here if monitor is not on
+ //
+ bufferEmpty = true;
+ }
+ return;
+ }
+ if (!audio->isPlaying() && !_monitor)
+ bufferEmpty = true;
+ }
+
+//---------------------------------------------------------
+// clone
+//---------------------------------------------------------
+
+void WaveTrack::clone(WaveTrack* t)
+ {
+ QString name;
+ for (int i = 1; ; ++i) {
+ name.sprintf("%s-%d", t->name().toLatin1().data(), i);
+ TrackList* tl = song->tracks();
+ bool found = false;
+ for (iTrack it = tl->begin(); it != tl->end(); ++it) {
+ if ((*it)->name() == name) {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ break;
+ }
+ setName(name);
+
+ _recordFlag = t->_recordFlag;
+ _mute = t->_mute;
+ _solo = t->_solo;
+ _off = t->_off;
+ _monitor = t->_monitor;
+ _channels = t->_channels;
+ _locked = t->_locked;
+ _inRoutes = t->_inRoutes;
+ _outRoutes = t->_outRoutes;
+ _controller = t->_controller;
+ _autoRead = t->_autoRead;
+ _autoWrite = t->_autoWrite;
+ setPrefader(t->prefader());
+ }
+
+
diff --git a/muse_qt4_evolution/muse/wavetrack.h b/muse_qt4_evolution/muse/wavetrack.h
new file mode 100644
index 00000000..0e195ddb
--- /dev/null
+++ b/muse_qt4_evolution/muse/wavetrack.h
@@ -0,0 +1,84 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __WAVETRACK_H__
+#define __WAVETRACK_H__
+
+#include "audiotrack.h"
+
+namespace AL {
+ class Pos;
+ };
+
+class Part;
+
+//---------------------------------------------------------
+// WaveTrack
+//---------------------------------------------------------
+
+class WaveTrack : public AudioTrack {
+ Q_OBJECT
+
+ float** readBuffer[FIFO_BUFFER];
+
+ Part* recordPart; // part we are recording into
+ bool partCreated;
+
+ void getDummyInput(int, unsigned);
+
+ protected:
+ virtual void collectInputData();
+
+ public:
+ static bool firstWaveTrack;
+
+ WaveTrack();
+ ~WaveTrack();
+ virtual TrackType type() const { return WAVE; }
+
+ void clone(WaveTrack*);
+
+ virtual Part* newPart(Part*p=0, bool clone=false);
+
+ virtual void read(QDomNode);
+ virtual void write(Xml&) const;
+
+ virtual void fetchData(unsigned pos, unsigned frames, int);
+
+ virtual void setChannels(int n);
+ virtual bool hasAuxSend() const { return true; }
+ bool canEnableRecord() const;
+ virtual bool canRecord() const { return true; }
+
+ virtual void startRecording();
+ void recordBeat();
+ virtual void stopRecording(const AL::Pos&, const AL::Pos&);
+ virtual void process();
+ };
+
+
+typedef QList<WaveTrack*> WaveTrackList;
+typedef WaveTrackList::iterator iWaveTrack;
+typedef WaveTrackList::const_iterator ciWaveTrack;
+
+#endif
+
+
+
diff --git a/muse_qt4_evolution/muse/widgets/CMakeLists.txt b/muse_qt4_evolution/muse/widgets/CMakeLists.txt
new file mode 100644
index 00000000..03866a0c
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/CMakeLists.txt
@@ -0,0 +1,88 @@
+#=============================================================================
+# MusE
+# Linux Music Editor
+# $Id:$
+#
+# Copyright (C) 2002-2006 by Werner Schweer and others
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#=============================================================================
+
+QT4_WRAP_CPP (widget_mocs
+ doublelabel.h
+ noteinfo.h
+ dentry.h
+ siglabel.h
+ simplebutton.h
+ tb1.h
+ tools.h
+ fontsel.h
+ ctrlcombo.h
+ filedialog.h
+ outportcombo.h splitter.h
+ quantcombo.h rastercombo.h
+ comboQuant.h bigtime.h
+ midisync.h
+ mixdowndialog.h
+ comment.h
+ shortcutconfig.h
+ shortcutcapturedialog.h
+ greendotbutton.h recordbutton.h
+ )
+
+QT4_WRAP_UI (widget_ui_headers
+ comment.ui
+ midisync.ui
+ mixdowndialog.ui
+ shortcutcapturedialog.ui
+ shortcutconfig.ui
+ )
+
+# add_custom_command(OUTPUT ui_midisync.h
+# COMMAND ${QT_UIC_EXECUTABLE}
+# ARGS -o ${CMAKE_CURRENT_BINARY_DIR}/ui_midisync.h ${CMAKE_CURRENT_SOURCE_DIR}/midisync.ui
+# DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/midisync.ui
+# )
+
+# ADD_FILE_DEPENDENCIES(moc_midisync.cxx ${CMAKE_CURRENT_BINARY_DIR}/ui_midisync.h)
+
+add_library ( widgets STATIC
+ ${widget_ui_headers}
+ ${widget_mocs}
+
+ utils.cpp
+ shortcutconfig.cpp
+ shortcutconfig.h
+ shortcutcapturedialog.cpp
+ midisync.cpp
+ comment.cpp
+ mixdowndialog.cpp
+ tools.cpp
+ doublelabel.cpp
+ noteinfo.cpp
+ dentry.cpp
+ siglabel.cpp
+ simplebutton.cpp
+ tb1.cpp
+ fontsel.cpp
+ ctrlcombo.cpp
+ filedialog.cpp
+ outportcombo.cpp splitter.cpp
+ quantcombo.cpp rastercombo.cpp
+ comboQuant.cpp bigtime.cpp
+ )
+
+set_target_properties( widgets
+ PROPERTIES COMPILE_FLAGS "-include ${PROJECT_BINARY_DIR}/all.h"
+ )
+
diff --git a/muse_qt4_evolution/muse/widgets/action.h b/muse_qt4_evolution/muse/widgets/action.h
new file mode 100644
index 00000000..c71ac1bb
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/action.h
@@ -0,0 +1,42 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __ACTION_H__
+#define __ACTION_H__
+
+//---------------------------------------------------------
+// Action
+//---------------------------------------------------------
+
+class Action : public QAction {
+ int _id;
+
+ public:
+ Action(QObject* parent, int i, const char* name = 0, bool toggle = false)
+ : QAction(parent, name, toggle) {
+ _id = i;
+ }
+ void setId(int i) { _id = i; }
+ int id() const { return _id; }
+ };
+
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/widgets/bigtime.cpp b/muse_qt4_evolution/muse/widgets/bigtime.cpp
new file mode 100644
index 00000000..3d1c7b21
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/bigtime.cpp
@@ -0,0 +1,267 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "globals.h"
+#include "bigtime.h"
+#include "song.h"
+#include "gconfig.h"
+
+#include "al/al.h"
+#include "al/sig.h"
+#include "al/tempo.h"
+
+//
+// the bigtime widget
+// display is split into several parts to avoid flickering.
+//
+
+//---------------------------------------------------------
+// BigTime
+//---------------------------------------------------------
+
+BigTime::BigTime(QWidget* parent)
+ : QWidget(parent)
+ {
+ setWindowFlags(Qt::WindowStaysOnTopHint);
+
+ barLabel = new QLabel(this);
+ beatLabel = new QLabel(this);
+ tickLabel = new QLabel(this);
+ hourLabel = new QLabel(this);
+ minLabel = new QLabel(this);
+ secLabel = new QLabel(this);
+ frameLabel = new QLabel(this);
+ sep1 = new QLabel(QString("."), this);
+ sep2 = new QLabel(QString("."), this);
+ sep3 = new QLabel(QString(":"), this);
+ sep4 = new QLabel(QString(":"), this);
+ sep5 = new QLabel(QString(":"), this);
+
+ oldbar = oldbeat = oldtick = oldhour = oldmin = oldsec = oldframe = -1;
+
+ setString(song->cPos());
+
+ configChanged();
+
+ QFont f(QString("Courier"));
+ f.setPixelSize(10);
+ setFont(f);
+ setWindowTitle(tr("MusE: Bigtime"));
+ }
+
+//---------------------------------------------------------
+// configChanged
+//---------------------------------------------------------
+
+void BigTime::configChanged()
+ {
+ setBgColor(config.bigTimeBackgroundColor);
+ setFgColor(config.bigTimeForegroundColor);
+ }
+
+//---------------------------------------------------------
+// closeEvent
+//---------------------------------------------------------
+
+void BigTime::closeEvent(QCloseEvent *ev)
+ {
+ emit closed();
+ QWidget::closeEvent(ev);
+ }
+
+//---------------------------------------------------------
+// setString
+//---------------------------------------------------------
+
+bool BigTime::setString(AL::Pos pos)
+ {
+ int bar, beat, tick;
+ pos.mbt(&bar, &beat, &tick);
+ int min, sec, hour, frame, subframe;
+ pos.msf(&min, &sec, &frame, &subframe);
+
+ hour = min / 60;
+ min %= 60;
+
+ QString s;
+
+ if(oldbar != bar) {
+ s.sprintf("%04d", bar+1);
+ barLabel->setText(s);
+ oldbar = bar;
+ }
+
+ if(oldbeat != beat) {
+ s.sprintf("%02d", beat+1);
+ beatLabel->setText(s);
+ oldbeat = beat;
+ }
+
+ if(oldtick != tick) {
+ s.sprintf("%03d", tick);
+ tickLabel->setText(s);
+ oldtick = tick;
+ }
+
+ if(oldhour != hour) {
+ s.sprintf("%02d", hour);
+ hourLabel->setText(s);
+ oldhour = hour;
+ }
+
+ if(oldmin != min) {
+ s.sprintf("%02d", min);
+ minLabel->setText(s);
+ oldmin = min;
+ }
+
+ if(oldsec != sec) {
+ s.sprintf("%02d", sec);
+ secLabel->setText(s);
+ oldsec = sec;
+ }
+
+ if(oldframe != frame) {
+ s.sprintf("%02d", frame);
+ frameLabel->setText(s);
+ oldframe = frame;
+ }
+
+ return false;
+ }
+
+//---------------------------------------------------------
+// setPos
+//---------------------------------------------------------
+
+void BigTime::setPos(int idx, AL::Pos pos, bool)
+ {
+ if (idx == 0)
+ setString(pos);
+ }
+
+//---------------------------------------------------------
+// resizeEvent
+//---------------------------------------------------------
+
+void BigTime::resizeEvent(QResizeEvent *ev)
+ {
+ QFont f = font();
+ QFontMetrics fm(f);
+ int fs = f.pixelSize();
+ int hspace = 20;
+ int tw = fm.width(QString("00:00:00:00"));
+ fs = ((ev->size().width() - hspace*2)*fs) / tw;
+
+// printf("resize BigTime %d -> %d, w %d\n", fs, nfs, ev->size().width());
+
+ // set min/max
+ if (fs < 10)
+ fs = 10;
+ else if (fs > 256)
+ fs = 256;
+ f.setPixelSize(fs);
+ setFont(f);
+
+ int digitWidth = fontMetrics().width(QString("0"));
+
+ int vspace = (ev->size().height() - (fs*2)) / 3;
+ int tickY = vspace;
+ int timeY = vspace*2 + fs;
+
+ barLabel->resize(digitWidth*4, fs);
+ beatLabel->resize(digitWidth*2, fs);
+ tickLabel->resize(digitWidth*3, fs);
+ hourLabel->resize(digitWidth*2, fs);
+ minLabel->resize(digitWidth*2, fs);
+ secLabel->resize(digitWidth*2, fs);
+ frameLabel->resize(digitWidth*2, fs);
+
+ sep1->resize(digitWidth, fs);
+ sep2->resize(digitWidth, fs);
+ sep3->resize(digitWidth, fs);
+ sep4->resize(digitWidth, fs);
+ sep5->resize(digitWidth, fs);
+
+ barLabel->move( hspace + (digitWidth*0), tickY);
+ sep1->move( hspace + (digitWidth*4), tickY);
+ beatLabel->move( hspace + (digitWidth*5), tickY);
+ sep2->move( hspace + (digitWidth*7), tickY);
+ tickLabel->move( hspace + (digitWidth*8), tickY);
+
+ hourLabel->move( hspace + (digitWidth*0), timeY);
+ sep3->move( hspace + (digitWidth*2), timeY);
+ minLabel->move( hspace + (digitWidth*3), timeY);
+ sep4->move( hspace + (digitWidth*5), timeY);
+ secLabel->move( hspace + (digitWidth*6), timeY);
+ sep5->move( hspace + (digitWidth*8), timeY);
+ frameLabel->move( hspace + (digitWidth*9), timeY);
+ }
+
+//---------------------------------------------------------
+// setForegroundColor
+//---------------------------------------------------------
+
+void BigTime::setFgColor(QColor c)
+ {
+ QPalette cg = palette();
+ cg.setColor(QPalette::Foreground, c);
+ setPalette(cg);
+
+ barLabel->setPalette(cg);
+ beatLabel->setPalette(cg);
+ tickLabel->setPalette(cg);
+ hourLabel->setPalette(cg);
+ minLabel->setPalette(cg);
+ secLabel->setPalette(cg);
+ frameLabel->setPalette(cg);
+
+ sep1->setPalette(cg);
+ sep2->setPalette(cg);
+ sep3->setPalette(cg);
+ sep4->setPalette(cg);
+ sep5->setPalette(cg);
+ }
+
+//---------------------------------------------------------
+// setBackgroundColor
+//---------------------------------------------------------
+
+void BigTime::setBgColor(QColor c)
+ {
+ QPalette cg = palette();
+ cg.setColor(QPalette::Background, c);
+ setPalette(cg);
+
+ barLabel->setPalette(cg);
+ beatLabel->setPalette(cg);
+ tickLabel->setPalette(cg);
+ hourLabel->setPalette(cg);
+ minLabel->setPalette(cg);
+ secLabel->setPalette(cg);
+ frameLabel->setPalette(cg);
+
+ sep1->setPalette(cg);
+ sep2->setPalette(cg);
+ sep3->setPalette(cg);
+ sep4->setPalette(cg);
+ sep5->setPalette(cg);
+ }
+
diff --git a/muse_qt4_evolution/muse/widgets/bigtime.h b/muse_qt4_evolution/muse/widgets/bigtime.h
new file mode 100644
index 00000000..82b054bf
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/bigtime.h
@@ -0,0 +1,64 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __BIGTIME_H__
+#define __BIGTIME_H__
+
+#include "al/pos.h"
+
+class MusE;
+class AL::Pos;
+
+//---------------------------------------------------------
+// BigTime
+//---------------------------------------------------------
+
+class BigTime : public QWidget {
+ bool tickmode;
+ MusE* seq;
+ Q_OBJECT
+
+ bool setString(AL::Pos);
+
+ QLabel *barLabel, *beatLabel, *tickLabel,
+ *hourLabel, *minLabel, *secLabel, *frameLabel,
+ *sep1, *sep2, *sep3, *sep4, *sep5;
+ int oldbar, oldbeat, oldhour, oldmin, oldsec, oldframe;
+ int oldtick;
+
+ void setFgColor(QColor c);
+ void setBgColor(QColor c);
+
+ protected:
+ virtual void resizeEvent(QResizeEvent*);
+ virtual void closeEvent(QCloseEvent*);
+
+ public slots:
+ void setPos(int, AL::Pos, bool);
+ void configChanged();
+
+ signals:
+ void closed();
+
+ public:
+ BigTime(QWidget* parent);
+ };
+
+#endif
diff --git a/muse_qt4_evolution/muse/widgets/cliplisteditorbase.h b/muse_qt4_evolution/muse/widgets/cliplisteditorbase.h
new file mode 100644
index 00000000..789edac6
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/cliplisteditorbase.h
@@ -0,0 +1,138 @@
+#ifndef CLIPLISTEDITORBASE_H
+#define CLIPLISTEDITORBASE_H
+
+#include <qvariant.h>
+
+
+#include <Qt3Support/Q3GroupBox>
+#include <Qt3Support/Q3Header>
+#include <Qt3Support/Q3ListView>
+#include <QtCore/QVariant>
+#include <QtGui/QAction>
+#include <QtGui/QApplication>
+#include <QtGui/QButtonGroup>
+#include <QtGui/QHBoxLayout>
+#include <QtGui/QLabel>
+#include <QtGui/QSpacerItem>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QWidget>
+#include "awl/posedit.h"
+#include <awl::posedit.h>
+#include <Qt3Support/Q3MimeSourceFactory>
+
+class Ui_ClipListEditorBase
+{
+public:
+ QVBoxLayout *vboxLayout;
+ Q3ListView *view;
+ Q3GroupBox *GroupBox1;
+ QHBoxLayout *hboxLayout;
+ QLabel *TextLabel1;
+ Awl::PosEdit *start;
+ QLabel *TextLabel2;
+ Awl::PosEdit *len;
+ QSpacerItem *spacerItem;
+
+ void setupUi(QWidget *ClipListEditorBase)
+ {
+ ClipListEditorBase->setObjectName(QString::fromUtf8("ClipListEditorBase"));
+ ClipListEditorBase->resize(QSize(600, 480).expandedTo(ClipListEditorBase->minimumSizeHint()));
+ vboxLayout = new QVBoxLayout(ClipListEditorBase);
+ vboxLayout->setSpacing(6);
+ vboxLayout->setMargin(11);
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
+ view = new Q3ListView(ClipListEditorBase);
+ view->addColumn(QApplication::translate("ClipListEditorBase", "Name", 0, QApplication::UnicodeUTF8));
+ view->header()->setClickEnabled(true, view->header()->count() - 1);
+ view->addColumn(QApplication::translate("ClipListEditorBase", "Refs", 0, QApplication::UnicodeUTF8));
+ view->header()->setClickEnabled(true, view->header()->count() - 1);
+ view->addColumn(QApplication::translate("ClipListEditorBase", "Start", 0, QApplication::UnicodeUTF8));
+ view->header()->setClickEnabled(true, view->header()->count() - 1);
+ view->addColumn(QApplication::translate("ClipListEditorBase", "Len", 0, QApplication::UnicodeUTF8));
+ view->header()->setClickEnabled(true, view->header()->count() - 1);
+ view->addColumn(QApplication::translate("ClipListEditorBase", "Data", 0, QApplication::UnicodeUTF8));
+ view->header()->setClickEnabled(true, view->header()->count() - 1);
+ view->setObjectName(QString::fromUtf8("view"));
+ view->setAllColumnsShowFocus(true);
+ view->setRootIsDecorated(true);
+
+ vboxLayout->addWidget(view);
+
+ GroupBox1 = new Q3GroupBox(ClipListEditorBase);
+ GroupBox1->setObjectName(QString::fromUtf8("GroupBox1"));
+ GroupBox1->setColumnLayout(0, Qt::Vertical);
+ GroupBox1->layout()->setSpacing(6);
+ GroupBox1->layout()->setMargin(11);
+ hboxLayout = new QHBoxLayout(GroupBox1->layout());
+ hboxLayout->setAlignment(Qt::AlignTop);
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
+ hboxLayout->setMargin(11);
+ hboxLayout->setSpacing(6);
+ TextLabel1 = new QLabel(GroupBox1);
+ TextLabel1->setObjectName(QString::fromUtf8("TextLabel1"));
+
+ hboxLayout->addWidget(TextLabel1);
+
+ start = new Awl::PosEdit(GroupBox1);
+ start->setObjectName(QString::fromUtf8("start"));
+ start->setSmpte(true);
+
+ hboxLayout->addWidget(start);
+
+ TextLabel2 = new QLabel(GroupBox1);
+ TextLabel2->setObjectName(QString::fromUtf8("TextLabel2"));
+
+ hboxLayout->addWidget(TextLabel2);
+
+ len = new Awl::PosEdit(GroupBox1);
+ len->setObjectName(QString::fromUtf8("len"));
+ len->setSmpte(true);
+
+ hboxLayout->addWidget(len);
+
+ spacerItem = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+
+ hboxLayout->addItem(spacerItem);
+
+
+ vboxLayout->addWidget(GroupBox1);
+
+ retranslateUi(ClipListEditorBase);
+
+ QMetaObject::connectSlotsByName(ClipListEditorBase);
+ } // setupUi
+
+ void retranslateUi(QWidget *ClipListEditorBase)
+ {
+ ClipListEditorBase->setWindowTitle(QApplication::translate("ClipListEditorBase", "MusE: ClipList", 0, QApplication::UnicodeUTF8));
+ view->header()->setLabel(0, QApplication::translate("ClipListEditorBase", "Name", 0, QApplication::UnicodeUTF8));
+ view->header()->setLabel(1, QApplication::translate("ClipListEditorBase", "Refs", 0, QApplication::UnicodeUTF8));
+ view->header()->setLabel(2, QApplication::translate("ClipListEditorBase", "Start", 0, QApplication::UnicodeUTF8));
+ view->header()->setLabel(3, QApplication::translate("ClipListEditorBase", "Len", 0, QApplication::UnicodeUTF8));
+ view->header()->setLabel(4, QApplication::translate("ClipListEditorBase", "Data", 0, QApplication::UnicodeUTF8));
+ GroupBox1->setTitle(QApplication::translate("ClipListEditorBase", "Clip Properties", 0, QApplication::UnicodeUTF8));
+ TextLabel1->setText(QApplication::translate("ClipListEditorBase", "Pos:", 0, QApplication::UnicodeUTF8));
+ TextLabel2->setText(QApplication::translate("ClipListEditorBase", "Len:", 0, QApplication::UnicodeUTF8));
+ Q_UNUSED(ClipListEditorBase);
+ } // retranslateUi
+
+};
+
+namespace Ui {
+ class ClipListEditorBase: public Ui_ClipListEditorBase {};
+} // namespace Ui
+
+class ClipListEditorBase : public QWidget, public Ui::ClipListEditorBase
+{
+ Q_OBJECT
+
+public:
+ ClipListEditorBase(QWidget* parent = 0, const char* name = 0, Qt::WFlags fl = 0);
+ ~ClipListEditorBase();
+
+protected slots:
+ virtual void languageChange();
+
+};
+
+#endif // CLIPLISTEDITORBASE_H
diff --git a/muse_qt4_evolution/muse/widgets/cliplisteditorbase.ui b/muse_qt4_evolution/muse/widgets/cliplisteditorbase.ui
new file mode 100644
index 00000000..0dab43be
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/cliplisteditorbase.ui
@@ -0,0 +1,146 @@
+<ui version="4.0" >
+ <author></author>
+ <comment></comment>
+ <exportmacro></exportmacro>
+ <class>ClipListEditorBase</class>
+ <widget class="QWidget" name="ClipListEditorBase" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>600</width>
+ <height>480</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>MusE: ClipList</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>11</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="Q3ListView" name="view" >
+ <property name="allColumnsShowFocus" >
+ <bool>true</bool>
+ </property>
+ <property name="rootIsDecorated" >
+ <bool>true</bool>
+ </property>
+ <column>
+ <property name="text" >
+ <string>Name</string>
+ </property>
+ </column>
+ <column>
+ <property name="text" >
+ <string>Refs</string>
+ </property>
+ </column>
+ <column>
+ <property name="text" >
+ <string>Start</string>
+ </property>
+ </column>
+ <column>
+ <property name="text" >
+ <string>Len</string>
+ </property>
+ </column>
+ <column>
+ <property name="text" >
+ <string>Data</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ <item>
+ <widget class="Q3GroupBox" name="GroupBox1" >
+ <property name="title" >
+ <string>Clip Properties</string>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>11</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="TextLabel1" >
+ <property name="text" >
+ <string>Pos:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Awl::PosEdit" name="start" />
+ </item>
+ <item>
+ <widget class="QLabel" name="TextLabel2" >
+ <property name="text" >
+ <string>Len:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Awl::PosEdit" name="len" />
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11" />
+ <pixmapfunction>qPixmapFromMimeSource</pixmapfunction>
+ <customwidgets>
+ <customwidget>
+ <class>Q3ListView</class>
+ <extends></extends>
+ <header>q3listview.h</header>
+ <container>0</container>
+ <pixmap></pixmap>
+ </customwidget>
+ <customwidget>
+ <class>Q3GroupBox</class>
+ <extends></extends>
+ <header>Qt3Support/Q3GroupBox</header>
+ <container>1</container>
+ <pixmap></pixmap>
+ </customwidget>
+ <customwidget>
+ <class>Awl::PosEdit</class>
+ <extends>QWidget</extends>
+ <header>awl::posedit.h</header>
+ <container>1</container>
+ <pixmap></pixmap>
+ </customwidget>
+ </customwidgets>
+ <includes>
+ <include location="local" >awl/posedit.h</include>
+ </includes>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/muse_qt4_evolution/muse/widgets/comboQuant.cpp b/muse_qt4_evolution/muse/widgets/comboQuant.cpp
new file mode 100644
index 00000000..1a95e3b6
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/comboQuant.cpp
@@ -0,0 +1,69 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "comboQuant.h"
+
+static int quantTable[] = {
+ 1, 16, 32, 64, 128, 256, 512, 1024,
+ 1, 24, 48, 96, 192, 384, 768, 1536,
+ 1, 36, 72, 144, 288, 576, 1152, 2304
+ };
+
+static const char* quantStrings[] = {
+ QT_TR_NOOP("Off"), "64T", "32T", "16T", "8T", "4T", "2T", "1T",
+ QT_TR_NOOP("Off"), "64", "32", "16", "8", "4", "2", "1",
+ QT_TR_NOOP("Off"), "64.", "32.", "16.", "8.", "4.", "2.", "1."
+ };
+
+//---------------------------------------------------------
+// ComboQuant
+//---------------------------------------------------------
+
+ComboQuant::ComboQuant(QWidget* parent)
+ : QComboBox(parent)
+ {
+ for (int i = 0; i < 24; i++)
+ addItem(tr(quantStrings[i]), i);
+ connect(this, SIGNAL(activated(int)), SLOT(activated(int)));
+ }
+
+//---------------------------------------------------------
+// activated
+//---------------------------------------------------------
+
+void ComboQuant::activated(int index)
+ {
+ emit valueChanged(quantTable[index]);
+ }
+
+//---------------------------------------------------------
+// setQuant
+//---------------------------------------------------------
+
+void ComboQuant::setValue(int val)
+ {
+ for (int i = 0; i < 24; i++) {
+ if (val == quantTable[i]) {
+ setCurrentIndex(i);
+ return;
+ }
+ }
+ }
+
diff --git a/muse_qt4_evolution/muse/widgets/comboQuant.h b/muse_qt4_evolution/muse/widgets/comboQuant.h
new file mode 100644
index 00000000..de2a8d82
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/comboQuant.h
@@ -0,0 +1,43 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __COMBOQUANT_H__
+#define __COMBOQUANT_H__
+
+//---------------------------------------------------------
+// ComboQuant
+//---------------------------------------------------------
+
+class ComboQuant : public QComboBox {
+ Q_OBJECT
+
+ private slots:
+ void activated(int);
+
+ signals:
+ void valueChanged(int);
+
+ public:
+ ComboQuant(QWidget* parent = 0);
+ void setValue(int val);
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/widgets/combobox.cpp b/muse_qt4_evolution/muse/widgets/combobox.cpp
new file mode 100644
index 00000000..8b6a5ea2
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/combobox.cpp
@@ -0,0 +1,81 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "combobox.h"
+
+//---------------------------------------------------------
+// ComboBox
+//---------------------------------------------------------
+
+ComboBox::ComboBox(QWidget* parent, const char* name)
+ : QLabel(parent, name)
+ {
+ _currentItem = 0;
+ _id = -1;
+ list = new Q3PopupMenu(0, "comboPopup");
+ connect(list, SIGNAL(activated(int)), SLOT(activatedIntern(int)));
+ setFrameStyle(Q3Frame::Panel | Q3Frame::Raised);
+ setLineWidth(2);
+ }
+
+ComboBox::~ComboBox()
+ {
+ delete list;
+ }
+
+//---------------------------------------------------------
+// mousePressEvent
+//---------------------------------------------------------
+
+void ComboBox::mousePressEvent(QMouseEvent*)
+ {
+ list->exec(QCursor::pos());
+ }
+
+//---------------------------------------------------------
+// activated
+//---------------------------------------------------------
+
+void ComboBox::activatedIntern(int n)
+ {
+ _currentItem = n;
+ emit activated(n, _id);
+ setText(list->text(_currentItem));
+ }
+
+//---------------------------------------------------------
+// setCurrentItem
+//---------------------------------------------------------
+
+void ComboBox::setCurrentItem(int i)
+ {
+ _currentItem = i;
+ setText(list->text(list->idAt(_currentItem)));
+ }
+
+//---------------------------------------------------------
+// insertItem
+//---------------------------------------------------------
+
+void ComboBox::insertItem(const QString& s, int id, int idx)
+ {
+ list->insertItem(s, id, idx);
+ }
+
diff --git a/muse_qt4_evolution/muse/widgets/combobox.h b/muse_qt4_evolution/muse/widgets/combobox.h
new file mode 100644
index 00000000..70d71030
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/combobox.h
@@ -0,0 +1,57 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __COMBOBOX_H__
+#define __COMBOBOX_H__
+
+class Q3PopupMenu;
+
+//---------------------------------------------------------
+// ComboBox
+//---------------------------------------------------------
+
+class ComboBox : public QLabel {
+ Q_OBJECT
+ Q_PROPERTY(int id READ id WRITE setId)
+
+ int _id;
+ int _currentItem;
+ Q3PopupMenu* list;
+ virtual void mousePressEvent(QMouseEvent*);
+
+ private slots:
+ void activatedIntern(int);
+
+ signals:
+ void activated(int val, int id);
+
+ public:
+ ComboBox(QWidget* parent, const char* name = 0);
+ ~ComboBox();
+ void setCurrentItem(int);
+ void insertItem(const QString& s, int id = -1, int idx=-1);
+ int id() const { return _id; }
+ void setId(int i) { _id = i; }
+ };
+
+#endif
+
+
+
diff --git a/muse_qt4_evolution/muse/widgets/comment.cpp b/muse_qt4_evolution/muse/widgets/comment.cpp
new file mode 100644
index 00000000..2bb981eb
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/comment.cpp
@@ -0,0 +1,91 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "comment.h"
+#include "song.h"
+#include "track.h"
+
+//---------------------------------------------------------
+// Comment
+//---------------------------------------------------------
+
+Comment::Comment(QWidget* parent)
+ : QWidget(parent)
+ {
+ setupUi(this);
+ }
+
+//---------------------------------------------------------
+// textChanged
+//---------------------------------------------------------
+
+void Comment::textChanged()
+ {
+ setText(textentry->document()->toPlainText());
+ }
+
+//---------------------------------------------------------
+// TrackComment
+//---------------------------------------------------------
+
+TrackComment::TrackComment(Track* t, QWidget* parent)
+ : Comment(parent)
+ {
+ setWindowTitle(tr("MusE: Track Comment"));
+ track = t;
+ connect(song, SIGNAL(songChanged(int)), SLOT(songChanged(int)));
+ textentry->setPlainText(track->comment());
+ connect(textentry, SIGNAL(textChanged()), SLOT(textChanged()));
+ label1->setText(tr("Track Comment:"));
+ label2->setText(track->name());
+ }
+
+//---------------------------------------------------------
+// songChanged
+//---------------------------------------------------------
+
+void TrackComment::songChanged(int flags)
+ {
+ if ((flags & (SC_TRACK_INSERTED|SC_TRACK_REMOVED|SC_TRACK_MODIFIED)) == 0)
+ return;
+ if (!song->trackExists(track)) {
+ close();
+ return;
+ }
+ label2->setText(track->name());
+ QString txt(textentry->document()->toPlainText());
+ if (track->comment() != txt) {
+ disconnect(textentry, SIGNAL(textChanged()), this, SLOT(textChanged()));
+ textentry->setPlainText(track->comment());
+// textentry->setCursorPosition(1000, 1000);
+ connect(textentry, SIGNAL(textChanged()), this, SLOT(textChanged()));
+ }
+ }
+
+//---------------------------------------------------------
+// setText
+//---------------------------------------------------------
+
+void TrackComment::setText(const QString& s)
+ {
+ track->setComment(s);
+ song->update(SC_TRACK_MODIFIED);
+ }
+
diff --git a/muse_qt4_evolution/muse/widgets/comment.h b/muse_qt4_evolution/muse/widgets/comment.h
new file mode 100644
index 00000000..9d356d7a
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/comment.h
@@ -0,0 +1,69 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __COMMENT_H__
+#define __COMMENT_H__
+
+#include "ui_comment.h"
+
+namespace AL {
+ class Xml;
+ };
+using AL::Xml;
+
+class Track;
+
+//---------------------------------------------------------
+// Comment
+//---------------------------------------------------------
+
+class Comment : public QWidget, public Ui::CommentBase {
+ Q_OBJECT
+
+ private:
+ virtual void setText(const QString& s) = 0;
+
+ private slots:
+ void textChanged();
+
+ public:
+ Comment(QWidget* parent);
+ };
+
+//---------------------------------------------------------
+// TrackComment
+//---------------------------------------------------------
+
+class TrackComment : public Comment {
+ Track* track;
+ Q_OBJECT
+
+ private:
+ virtual void setText(const QString& s);
+
+ private slots:
+ void songChanged(int);
+
+ public:
+ TrackComment(Track*, QWidget*);
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/widgets/comment.ui b/muse_qt4_evolution/muse/widgets/comment.ui
new file mode 100644
index 00000000..fc1b8d64
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/comment.ui
@@ -0,0 +1,97 @@
+<ui version="4.0" >
+ <author></author>
+ <comment></comment>
+ <exportmacro></exportmacro>
+ <class>CommentBase</class>
+ <widget class="QWidget" name="CommentBase" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>387</width>
+ <height>205</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Form1</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>11</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label1" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Track Comment</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label2" >
+ <property name="font" >
+ <font>
+ <family>Arial</family>
+ <pointsize>12</pointsize>
+ <weight>75</weight>
+ <italic>false</italic>
+ <bold>true</bold>
+ <underline>false</underline>
+ <strikeout>false</strikeout>
+ </font>
+ </property>
+ <property name="frameShape" >
+ <enum>QFrame::Box</enum>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Sunken</enum>
+ </property>
+ <property name="midLineWidth" >
+ <number>1</number>
+ </property>
+ <property name="text" >
+ <string>Track 1</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QTextEdit" name="textentry" >
+ <property name="font" >
+ <font>
+ <family>Arial</family>
+ <pointsize>12</pointsize>
+ <weight>75</weight>
+ <italic>false</italic>
+ <bold>true</bold>
+ <underline>false</underline>
+ <strikeout>false</strikeout>
+ </font>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <pixmapfunction>qPixmapFromMimeSource</pixmapfunction>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/muse_qt4_evolution/muse/widgets/ctrlcombo.cpp b/muse_qt4_evolution/muse/widgets/ctrlcombo.cpp
new file mode 100644
index 00000000..3139265a
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/ctrlcombo.cpp
@@ -0,0 +1,68 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "ctrlcombo.h"
+
+//---------------------------------------------------------
+// CtrlComboBox
+//---------------------------------------------------------
+
+CtrlComboBox::CtrlComboBox(QWidget* parent)
+ : QComboBox(parent)
+ {
+ const char* ctxt[] = {
+ "No Ctrl", "BankSelMSB", "Modulation", "BreathCtrl",
+ "Control 3", "Foot Ctrl", "Porta Time", "DataEntMSB",
+ "MainVolume", "Balance", "Control 9", "Pan",
+ "Expression", "Control 12", "Control 13", "Control 14",
+ "Control 15", "Gen.Purp.1", "Gen.Purp.2", "Gen.Purp.3",
+ "Gen.Purp.4", "Control 20", "Control 21", "Control 22",
+ "Control 23", "Control 24", "Control 25", "Control 26",
+ "Control 27", "Control 28", "Control 29", "Control 30",
+ "Control 31", "BankSelLSB", "Modul. LSB", "BrthCt.LSB",
+ "Control 35", "FootCt.LSB", "Port.T LSB", "DataEntLSB",
+ "MainVolLSB", "BalanceLSB", "Control 41", "Pan LSB",
+ "Expr. LSB", "Control 44", "Control 45", "Control 46",
+ "Control 47", "Gen.P.1LSB", "Gen.P.2LSB", "Gen.P.3LSB",
+ "Gen.P.4LSB", "Control 52", "Control 53", "Control 54",
+ "Control 55", "Control 56", "Control 57", "Control 58",
+ "Control 59", "Control 60", "Control 61", "Control 62",
+ "Control 63", "Sustain", "Porta Ped", "Sostenuto",
+ "Soft Pedal", "Control 68", "Hold 2", "Control 70",
+ "HarmonicCo", "ReleaseTime", "Attack Time", "Brightness",
+ "Control 75", "Control 76", "Control 77", "Control 78",
+ "Control 79", "Gen.Purp.5", "Gen.Purp.6", "Gen.Purp.7",
+ "Gen.Purp.8", "Porta Ctrl", "Control 85", "Control 86",
+ "Control 87", "Control 88", "Control 89", "Control 90",
+ "Effect1Dep", "Effect2Dep", "Effect3Dep", "Effect4Dep",
+ "Phaser Dep", "Data Incr", "Data Decr", "NRPN LSB",
+ "NRPN MSB", "RPN LSB", "RPN MSB", "Control102",
+ "Control103", "Control104", "Control105", "Control106",
+ "Control107", "Control108", "Control109", "Control110",
+ "Control111", "Control112", "Control113", "Control114",
+ "Control115", "Control116", "Control117", "Control118",
+ "Control119", "AllSndOff", "Reset Ctrl", "Local Ctrl",
+ "AllNoteOff", "OmniModOff", "OmniModeOn", "MonoModeOn",
+ "PolyModeOn"
+ };
+ for (unsigned int i = 0; i < sizeof(ctxt)/sizeof(*ctxt); ++i)
+ addItem(QString(ctxt[i]));
+ }
+
diff --git a/muse_qt4_evolution/muse/widgets/ctrlcombo.h b/muse_qt4_evolution/muse/widgets/ctrlcombo.h
new file mode 100644
index 00000000..1eb59ab0
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/ctrlcombo.h
@@ -0,0 +1,32 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __CTRLGRP_H__
+#define __CTRLGRP_H__
+
+class CtrlComboBox : public QComboBox {
+ Q_OBJECT
+ public:
+ CtrlComboBox(QWidget* parent);
+ };
+
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/widgets/dentry.cpp b/muse_qt4_evolution/muse/widgets/dentry.cpp
new file mode 100644
index 00000000..b52d4363
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/dentry.cpp
@@ -0,0 +1,208 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "dentry.h"
+#include "globals.h"
+
+#define TIMER1 400
+#define TIMER2 200
+#define TIMEC 7
+#define TIMER3 100
+#define TIMEC2 20
+#define TIMER4 50
+
+//---------------------------------------------------------
+// Dentry
+// lineedit double values
+//---------------------------------------------------------
+
+Dentry::Dentry(QWidget* parent)
+ : QLineEdit(parent)
+ {
+ _id = -1;
+ drawFrame = false;
+ QLineEdit::setFrame(drawFrame);
+ timer = new QTimer(this);
+ connect(timer, SIGNAL(timeout()), SLOT(repeat()));
+ val = 0.01;
+ connect(this, SIGNAL(returnPressed()), SLOT(endEdit()));
+ setCursor(QCursor(Qt::ArrowCursor));
+ evx = 1.0;
+ }
+
+//---------------------------------------------------------
+// setFrame
+//---------------------------------------------------------
+
+void Dentry::setFrame(bool flag)
+ {
+ drawFrame = flag;
+ QLineEdit::setFrame(drawFrame);
+ update();
+ }
+
+//---------------------------------------------------------
+// endEdit
+//---------------------------------------------------------
+
+void Dentry::endEdit()
+ {
+ if (isModified()) {
+ if (setSValue(text())) {
+ setString(val);
+ return;
+ }
+ }
+ setString(val);
+ clearFocus();
+ if (!drawFrame)
+ QLineEdit::setFrame(false);
+ }
+
+//---------------------------------------------------------
+// mousePressEvent
+//---------------------------------------------------------
+
+void Dentry::mousePressEvent(QMouseEvent* event)
+ {
+ button = event->button();
+ starty = event->y();
+ evx = double(event->x());
+ timecount = 0;
+ repeat();
+ timer->start(TIMER1);
+ }
+
+//---------------------------------------------------------
+// wheelEvent
+//---------------------------------------------------------
+
+void Dentry::wheelEvent(QWheelEvent* event)
+ {
+ int delta = event->delta();
+
+ if (delta < 0)
+ decValue(-1.0);
+ else if (delta > 0)
+ incValue(1.0);
+ }
+
+//---------------------------------------------------------
+// repeat
+//---------------------------------------------------------
+
+void Dentry::repeat()
+ {
+ if (timecount == 1) {
+ ++timecount;
+ timer->stop();
+ timer->start(TIMER2);
+ return;
+ }
+ ++timecount;
+ if (timecount == TIMEC) {
+ timer->stop();
+ timer->start(TIMER3);
+ }
+ if (timecount == TIMEC2) {
+ timer->stop();
+ timer->start(TIMER4);
+ }
+
+ switch (button) {
+ case Qt::LeftButton:
+ return;
+ case Qt::MidButton:
+ decValue(evx);
+ break;
+ case Qt::RightButton:
+ incValue(evx);
+ break;
+ default:
+ break;
+ }
+ }
+
+//---------------------------------------------------------
+// mouseReleaseEvent
+//---------------------------------------------------------
+
+void Dentry::mouseReleaseEvent(QMouseEvent*)
+ {
+ button = Qt::NoButton;
+ timer->stop();
+ }
+
+//---------------------------------------------------------
+// mouseMoveEvent
+//---------------------------------------------------------
+
+void Dentry::mouseMoveEvent(QMouseEvent*)
+ {
+ switch (button) {
+ case Qt::LeftButton:
+ break;
+ case Qt::MidButton:
+ break;
+ case Qt::RightButton:
+ break;
+ default:
+ break;
+ }
+ }
+
+//---------------------------------------------------------
+// mouseDoubleClickEvent
+//---------------------------------------------------------
+
+void Dentry::mouseDoubleClickEvent(QMouseEvent* event)
+ {
+ if (event->button() != Qt::LeftButton) {
+ mousePressEvent(event);
+ return;
+ }
+ setFocus();
+ QLineEdit::setFrame(true);
+ update();
+ }
+
+//---------------------------------------------------------
+// setValue
+//---------------------------------------------------------
+
+void Dentry::setValue(double v)
+ {
+ if (v == val)
+ return;
+ setString(v);
+#if 0
+ if (setString(v)) {
+ clearFocus();
+ if (!drawFrame)
+ QLineEdit::setFrame(false);
+ setEnabled(false);
+ }
+ else {
+ setEnabled(true);
+ }
+#endif
+ val = v;
+ }
+
diff --git a/muse_qt4_evolution/muse/widgets/dentry.h b/muse_qt4_evolution/muse/widgets/dentry.h
new file mode 100644
index 00000000..5e2ba724
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/dentry.h
@@ -0,0 +1,79 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __DENTRY_H__
+#define __DENTRY_H__
+
+class QTimer;
+
+//---------------------------------------------------------
+// Dentry
+//---------------------------------------------------------
+
+class Dentry : public QLineEdit {
+ Q_OBJECT
+
+ Q_PROPERTY( int id READ id WRITE setId )
+ Q_PROPERTY( double value READ value WRITE setValue )
+ Q_PROPERTY( bool frame READ frame WRITE setFrame )
+
+ int button;
+ int starty;
+ bool drawFrame;
+ QTimer* timer;
+ double evx;
+ int timecount;
+
+ virtual void wheelEvent(QWheelEvent*);
+ virtual void mousePressEvent(QMouseEvent*);
+ virtual void mouseMoveEvent(QMouseEvent*);
+ virtual void mouseDoubleClickEvent(QMouseEvent*);
+ virtual void mouseReleaseEvent(QMouseEvent*);
+
+ protected:
+ int _id;
+ double val;
+
+ virtual void incValue(double x) = 0;
+ virtual void decValue(double x) = 0;
+ virtual bool setString(double) = 0;
+ virtual bool setSValue(const QString&) = 0;
+
+ private slots:
+ void repeat();
+
+ protected slots:
+ void endEdit();
+
+ signals:
+ void valueChanged(double, int);
+
+ public slots:
+ virtual void setValue(double);
+
+ public:
+ Dentry(QWidget* parent = 0);
+ double value() const { return val; }
+ bool frame() const { return drawFrame; }
+ void setFrame(bool);
+ int id() const { return _id; }
+ void setId(int i) { _id = i; }
+ };
+#endif
diff --git a/muse_qt4_evolution/muse/widgets/doublelabel.cpp b/muse_qt4_evolution/muse/widgets/doublelabel.cpp
new file mode 100644
index 00000000..4026800b
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/doublelabel.cpp
@@ -0,0 +1,144 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "doublelabel.h"
+#include "utils.h"
+
+//---------------------------------------------------------
+// DoubleLabel
+//---------------------------------------------------------
+
+DoubleLabel::DoubleLabel(QWidget* parent)
+ : Dentry(parent), _specialText("---")
+ {
+ min = 0.0;
+ max = 1.0;
+ _precision = 3;
+ setValue(0.0);
+ }
+
+DoubleLabel::DoubleLabel(double _val, double m, double mx, QWidget* parent)
+ : Dentry(parent), _specialText("---")
+ {
+ min = m;
+ max = mx;
+ _precision = 3;
+ setValue(_val);
+ }
+
+//---------------------------------------------------------
+// setString
+//---------------------------------------------------------
+
+bool DoubleLabel::setString(double v)
+ {
+ QString s;
+ if (v < min || v > max) {
+ setText(_specialText);
+ return true;
+ }
+ s.setNum(v, 'f', _precision);
+ if (!_suffix.isEmpty()) {
+ s += " ";
+ s += _suffix;
+ }
+
+ setText(s);
+ return false;
+ }
+
+//---------------------------------------------------------
+// setSValue
+//---------------------------------------------------------
+
+bool DoubleLabel::setSValue(const QString& s)
+ {
+ bool ok;
+ double v = s.toDouble(&ok);
+ if (ok && (v != val)) {
+ if (v < min)
+ v = min;
+ if (v > max)
+ v = max;
+ setValue(v);
+ emit valueChanged(val, _id);
+ }
+ return false;
+ }
+
+//---------------------------------------------------------
+// incValue
+//---------------------------------------------------------
+
+void DoubleLabel::incValue(double)
+ {
+ if (val + 1.0 < max) {
+ setValue(val + 1.0);
+ emit valueChanged(val, _id);
+ }
+ }
+
+//---------------------------------------------------------
+// decValue
+//---------------------------------------------------------
+
+void DoubleLabel::decValue(double)
+ {
+ if (val - 1.0 > min) {
+ setValue(val - 1.0);
+ emit valueChanged(val, _id);
+ }
+ }
+
+//---------------------------------------------------------
+// setPrecision
+//---------------------------------------------------------
+
+void DoubleLabel::setPrecision(int v)
+ {
+ _precision = v;
+ setString(val);
+ }
+
+//---------------------------------------------------------
+// sizeHint
+//---------------------------------------------------------
+
+QSize DoubleLabel::sizeHint() const
+ {
+ QFontMetrics fm = fontMetrics();
+ int h = fm.height() + 4;
+ int n = _precision + 3;
+#if 0
+ double aval = fabs(val);
+ if (aval >= 10.0)
+ ++n;
+ if (aval >= 100.0)
+ ++n;
+ if (aval >= 1000.0)
+ ++n;
+ if (aval >= 10000.0)
+ ++n;
+ if (aval >= 100000.0)
+ ++n;
+#endif
+ int w = fm.width(QString("-0.")) + fm.width('0') * n + 6;
+ return QSize(w, h);
+ }
diff --git a/muse_qt4_evolution/muse/widgets/doublelabel.h b/muse_qt4_evolution/muse/widgets/doublelabel.h
new file mode 100644
index 00000000..0ed72514
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/doublelabel.h
@@ -0,0 +1,68 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __DOUBLELABEL_H__
+#define __DOUBLELABEL_H__
+
+#include "dentry.h"
+
+//---------------------------------------------------------
+// DoubleLabel
+//---------------------------------------------------------
+
+class DoubleLabel : public Dentry {
+ Q_PROPERTY( double minValue READ minValue WRITE setMinValue )
+ Q_PROPERTY( double maxValue READ maxValue WRITE setMaxValue )
+ Q_PROPERTY( QString specialText READ specialText WRITE setSpecialText )
+ Q_PROPERTY( QString suffix READ suffix WRITE setSuffix )
+ Q_PROPERTY( int precision READ precision WRITE setPrecision )
+
+ double min, max;
+ QString _specialText; // text to show if value outside min,max
+ QString _suffix;
+ int _precision;
+ Q_OBJECT
+
+ virtual bool setSValue(const QString&);
+ virtual bool setString(double val);
+ virtual void incValue(double);
+ virtual void decValue(double);
+
+ public:
+ DoubleLabel(QWidget* parent = 0);
+ DoubleLabel(double val, double min, double max, QWidget*);
+ virtual QSize sizeHint() const;
+ double minValue() const { return min; }
+ double maxValue() const { return max; }
+ void setMinValue(double v) { min = v; }
+ void setMaxValue(double v) { max = v; }
+ void setRange(double a, double b) { min = a; max = b; }
+ int precision() const { return _precision; }
+ void setPrecision(int val);
+ QString specialText() const { return _specialText; }
+ void setSpecialText(const QString& s) {
+ _specialText = s;
+ update();
+ }
+ QString suffix() const { return _suffix; }
+ void setSuffix(const QString& s) { _suffix = s; }
+ };
+
+#endif
diff --git a/muse_qt4_evolution/muse/widgets/editmetadialogbase.cpp b/muse_qt4_evolution/muse/widgets/editmetadialogbase.cpp
new file mode 100644
index 00000000..0bbe8dd1
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/editmetadialogbase.cpp
@@ -0,0 +1,110 @@
+#include "editmetadialogbase.h"
+
+#include <qvariant.h>
+#include <awl/posedit.h>
+/*
+ * Constructs a EditMetaDialogBase as a child of 'parent', with the
+ * name 'name' and widget flags set to 'f'.
+ *
+ * The dialog will by default be modeless, unless you set 'modal' to
+ * true to construct a modal dialog.
+ */
+EditMetaDialogBase::EditMetaDialogBase(QWidget* parent, const char* name, bool modal, Qt::WFlags fl)
+ : QDialog(parent, name, modal, fl)
+{
+ setupUi(this);
+
+
+ // signals and slots connections
+ connect(buttonOk, SIGNAL(clicked()), this, SLOT(accept()));
+ connect(buttonCancel, SIGNAL(clicked()), this, SLOT(reject()));
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+EditMetaDialogBase::~EditMetaDialogBase()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+
+/*
+ * Sets the strings of the subwidgets using the current
+ * language.
+ */
+void EditMetaDialogBase::languageChange()
+{
+ retranslateUi(this);
+}
+
+/****************************************************************************
+** Meta object code from reading C++ file 'editmetadialogbase.h'
+**
+** Created: Fri Sep 23 12:43:18 2005
+** by: The Qt Meta Object Compiler version 58 (Qt 4.0.1)
+**
+** WARNING! All changes made in this file will be lost!
+*****************************************************************************/
+
+#include "editmetadialogbase.h"
+#if !defined(Q_MOC_OUTPUT_REVISION)
+#error "The header file 'editmetadialogbase.h' doesn't include <QObject>."
+#elif Q_MOC_OUTPUT_REVISION != 58
+#error "This file was generated using the moc from 4.0.1. It"
+#error "cannot be used with the include files from this version of Qt."
+#error "(The moc has changed too much.)"
+#endif
+
+static const uint qt_meta_data_EditMetaDialogBase[] = {
+
+ // content:
+ 1, // revision
+ 0, // classname
+ 0, 0, // classinfo
+ 1, 10, // methods
+ 0, 0, // properties
+ 0, 0, // enums/sets
+
+ // slots: signature, parameters, type, tag, flags
+ 20, 19, 19, 19, 0x09,
+
+ 0 // eod
+};
+
+static const char qt_meta_stringdata_EditMetaDialogBase[] = {
+ "EditMetaDialogBase\0\0languageChange()\0"
+};
+
+const QMetaObject EditMetaDialogBase::staticMetaObject = {
+ { &QDialog::staticMetaObject, qt_meta_stringdata_EditMetaDialogBase,
+ qt_meta_data_EditMetaDialogBase, 0 }
+};
+
+const QMetaObject *EditMetaDialogBase::metaObject() const
+{
+ return &staticMetaObject;
+}
+
+void *EditMetaDialogBase::qt_metacast(const char *_clname)
+{
+ if (!_clname) return 0;
+ if (!strcmp(_clname, qt_meta_stringdata_EditMetaDialogBase))
+ return static_cast<void*>(const_cast<EditMetaDialogBase*>(this));
+ if (!strcmp(_clname, "Ui::EditMetaDialogBase"))
+ return static_cast<Ui::EditMetaDialogBase*>(const_cast<EditMetaDialogBase*>(this));
+ return QDialog::qt_metacast(_clname);
+}
+
+int EditMetaDialogBase::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
+{
+ _id = QDialog::qt_metacall(_c, _id, _a);
+ if (_id < 0)
+ return _id;
+ if (_c == QMetaObject::InvokeMetaMethod) {
+ switch (_id) {
+ case 0: languageChange(); break;
+ }
+ _id -= 1;
+ }
+ return _id;
+}
diff --git a/muse_qt4_evolution/muse/widgets/editmetadialogbase.ui b/muse_qt4_evolution/muse/widgets/editmetadialogbase.ui
new file mode 100644
index 00000000..3f5730de
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/editmetadialogbase.ui
@@ -0,0 +1,137 @@
+<ui version="4.0" >
+ <author></author>
+ <comment></comment>
+ <exportmacro></exportmacro>
+ <class>EditMetaDialogBase</class>
+ <widget class="QDialog" name="EditMetaDialogBase" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Dialog</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>8</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="3" column="0" colspan="3" >
+ <widget class="QTextEdit" name="textEdit" />
+ </item>
+ <item row="4" column="0" colspan="3" >
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>131</width>
+ <height>31</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="okButton" >
+ <property name="text" >
+ <string>OK</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="cancelButton" >
+ <property name="text" >
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QSpinBox" name="spinBox" />
+ </item>
+ <item row="1" column="1" >
+ <widget class="QSpinBox" name="spinBox_2" />
+ </item>
+ <item row="2" column="0" colspan="2" >
+ <widget class="QCheckBox" name="checkBox" >
+ <property name="text" >
+ <string>Enter Hex</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_2" >
+ <property name="text" >
+ <string>Meta Type:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Time Position:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2" >
+ <widget class="QLabel" name="label_3" >
+ <property name="text" >
+ <string>TextLabel</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <pixmapfunction></pixmapfunction>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>okButton</sender>
+ <signal>clicked()</signal>
+ <receiver>EditMetaDialogBase</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>278</x>
+ <y>253</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>96</x>
+ <y>254</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>cancelButton</sender>
+ <signal>clicked()</signal>
+ <receiver>EditMetaDialogBase</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>369</x>
+ <y>253</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>179</x>
+ <y>282</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/muse_qt4_evolution/muse/widgets/fdialogbuttons.ui b/muse_qt4_evolution/muse/widgets/fdialogbuttons.ui
new file mode 100644
index 00000000..9d46cb59
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/fdialogbuttons.ui
@@ -0,0 +1,167 @@
+<ui version="4.0" >
+ <author></author>
+ <comment></comment>
+ <exportmacro></exportmacro>
+ <class>FileDialogButtons</class>
+ <widget class="QWidget" name="FileDialogButtons" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>175</width>
+ <height>438</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle" >
+ <string>Form1</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>11</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="Q3ButtonGroup" name="pathGroup" >
+ <property name="title" >
+ <string/>
+ </property>
+ <property name="flat" >
+ <bool>true</bool>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="exclusive" >
+ <bool>true</bool>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>11</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QToolButton" name="globalButton" >
+ <property name="text" >
+ <string>Global</string>
+ </property>
+ <property name="icon" >
+ <iconset>image0</iconset>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="userButton" >
+ <property name="text" >
+ <string>User</string>
+ </property>
+ <property name="icon" >
+ <iconset>image1</iconset>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="projectButton" >
+ <property name="text" >
+ <string>Project</string>
+ </property>
+ <property name="icon" >
+ <iconset>image2</iconset>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>60</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="Q3ButtonGroup" name="loadAllGroup" >
+ <property name="title" >
+ <string>Load:</string>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="exclusive" >
+ <bool>true</bool>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>11</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QRadioButton" name="loadAllButton" >
+ <property name="text" >
+ <string>Songdata +
+Cofiguration</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="loadSongButton" >
+ <property name="text" >
+ <string>only
+Songdata</string>
+ </property>
+ <property name="checked" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11" />
+ <pixmapfunction></pixmapfunction>
+ <customwidgets>
+ <customwidget>
+ <class>Q3ButtonGroup</class>
+ <extends></extends>
+ <header>Qt3Support/Q3ButtonGroup</header>
+ <container>1</container>
+ <pixmap></pixmap>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/muse_qt4_evolution/muse/widgets/filedialog.cpp b/muse_qt4_evolution/muse/widgets/filedialog.cpp
new file mode 100644
index 00000000..eec678f5
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/filedialog.cpp
@@ -0,0 +1,193 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "filedialog.h"
+#include "../globals.h"
+
+//---------------------------------------------------------
+// MFileDialog
+//---------------------------------------------------------
+
+MFileDialog::MFileDialog(const QString& dir,
+ const QString& filter, QWidget* parent, bool /*writeFlag*/)
+ : QFileDialog(parent, QString(), dir, filter)
+ {
+ }
+
+//---------------------------------------------------------
+// getOpenFileName
+//---------------------------------------------------------
+
+QString getOpenFileName(const QString &startWith,
+ const QStringList& filters, QWidget* parent, const QString& name)
+ {
+ MFileDialog *dlg = new MFileDialog(startWith, QString::null, parent);
+ dlg->setFilters(filters);
+ dlg->setWindowTitle(name);
+ dlg->setFileMode(QFileDialog::ExistingFile);
+ QString result;
+ if (dlg->exec() == QDialog::Accepted) {
+ QStringList sl = dlg->selectedFiles();
+ result = sl.at(0);
+ }
+ delete dlg;
+ return result;
+ }
+
+//---------------------------------------------------------
+// getSaveFileName
+//---------------------------------------------------------
+
+QString getSaveFileName(const QString &startWith,
+ const QStringList& filters, QWidget* parent, const QString& name)
+ {
+ MFileDialog *dlg = new MFileDialog(startWith, QString::null, parent, true);
+ dlg->setFilters(filters);
+ dlg->setWindowTitle(name);
+ dlg->setFileMode(QFileDialog::AnyFile);
+ QString result;
+ if (dlg->exec() == QDialog::Accepted) {
+ QStringList sl = dlg->selectedFiles();
+ result = sl.at(0);
+ }
+ delete dlg;
+ return result;
+ }
+
+//---------------------------------------------------------
+// getImageFileName
+//---------------------------------------------------------
+
+QString getImageFileName(const QString& startWith,
+ const QStringList& filters, QWidget* parent, const QString& name)
+ {
+ QString initialSelection;
+ QString* workingDirectory = new QString(QDir::current().absolutePath());
+ if (!startWith.isEmpty() ) {
+ QFileInfo fi(startWith);
+ if (fi.exists() && fi.isDir()) {
+ *workingDirectory = startWith;
+ }
+ else if (fi.exists() && fi.isFile()) {
+ *workingDirectory = fi.absolutePath();
+ initialSelection = fi.absolutePath();
+ }
+ }
+ MFileDialog *dlg = new MFileDialog(*workingDirectory, QString::null,
+ parent);
+
+//TD dlg->setContentsPreviewEnabled(true);
+// ContentsPreview* preview = new ContentsPreview(dlg);
+// dlg->setContentsPreview(preview, preview);
+// dlg->setPreviewMode(QFileDialog::Contents);
+
+ dlg->setWindowTitle(name);
+ dlg->setFilters(filters);
+ dlg->setFileMode(QFileDialog::ExistingFile);
+ QString result;
+ if (!initialSelection.isEmpty())
+ dlg->selectFile(initialSelection);
+ if (dlg->exec() == QDialog::Accepted) {
+ QStringList sl = dlg->selectedFiles();
+ result = sl.at(0);
+ }
+ delete dlg;
+ return result;
+ }
+
+//---------------------------------------------------------
+// fileOpen
+// opens file "name" with extension "ext" in mode "mode"
+//
+// mode = "r" or "w"
+// noError show no error if file was not found in "r"
+// mode. Has no effect in "w" mode
+// overwriteWarning
+// warn in "w" mode, if file exists
+//---------------------------------------------------------
+
+QFile* fileOpen(QWidget* parent, QString name, const QString& ext,
+ QIODevice::OpenMode mode, bool overwriteWarning)
+ {
+ QFileInfo info(name);
+
+ if (info.completeSuffix() == "") {
+ name += ext;
+ info.setFile(name);
+ }
+ if (mode == QIODevice::WriteOnly && overwriteWarning && info.exists()) {
+ QString s(QWidget::tr("File\n") + name + QWidget::tr("\nexists"));
+ int rv = QMessageBox::warning(parent,
+ QWidget::tr("MusE: write"),
+ s,
+ QWidget::tr("Overwrite"),
+ QWidget::tr("Quit"), QString::null, 0, 1);
+ switch(rv) {
+ case 0: // overwrite
+ break;
+ case 1: // quit
+ return 0;
+ }
+ }
+ QFile* file = new QFile(name);
+ if (!file->open(mode)) {
+ QString s(QWidget::tr("Open File\n") + name + QWidget::tr("\nfailed: ")
+ + QString(strerror(errno)));
+ QMessageBox::critical(parent, QWidget::tr("MusE: Open File"), s);
+ }
+ return file;
+ }
+
+//---------------------------------------------------------
+// MFile
+//---------------------------------------------------------
+
+MFile::MFile(const QString& _path, const QString& _ext)
+ : path(_path), ext(_ext)
+ {
+ f = 0;
+ }
+
+MFile::~MFile()
+ {
+ if (f) {
+ f->close();
+ delete f;
+ }
+ }
+
+//---------------------------------------------------------
+// open
+//---------------------------------------------------------
+
+QFile* MFile::open(QIODevice::OpenMode mode, const QStringList& pattern,
+ QWidget* parent, bool warnIfOverwrite, const QString& caption)
+ {
+ QString name;
+ if (mode == QIODevice::ReadOnly)
+ name = getOpenFileName(path, pattern, parent, caption);
+ else
+ name = getSaveFileName(path, pattern, parent, caption);
+ if (name.isEmpty())
+ return 0;
+ f = fileOpen(parent, name, ext, mode, warnIfOverwrite);
+ return f;
+ }
+
diff --git a/muse_qt4_evolution/muse/widgets/filedialog.h b/muse_qt4_evolution/muse/widgets/filedialog.h
new file mode 100644
index 00000000..cb906e00
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/filedialog.h
@@ -0,0 +1,65 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+class FileDialogButtons;
+
+//---------------------------------------------------------
+// MFileDialog
+//---------------------------------------------------------
+
+class MFileDialog : public QFileDialog {
+ bool showButtons;
+ QString baseDir;
+ Q_OBJECT
+
+ public:
+ MFileDialog(const QString& dir, const QString& filter = QString::null,
+ QWidget* parent = 0, bool writeFlag = false);
+ };
+
+QString getSaveFileName(const QString& startWidth, const QStringList& filter,
+ QWidget* parent, const QString& name);
+QString getOpenFileName(const QString& startWidth, const QStringList& filter,
+ QWidget* parent, const QString& name);
+QString getImageFileName(const QString& startWith, const QStringList& filter,
+ QWidget* parent, const QString& name);
+
+QFile* fileOpen(QWidget*, QString, const QString&,
+ QIODevice::OpenMode, bool = false);
+
+
+//---------------------------------------------------------
+// MFile
+// "Muse" File
+//---------------------------------------------------------
+
+class MFile {
+ QFile* f;
+ QString path;
+ QString ext;
+
+ public:
+ MFile(const QString& path, const QString& ext);
+ ~MFile();
+ QFile* open(QIODevice::OpenMode, const QStringList& pattern,
+ QWidget* parent,
+ bool warnIfOverwrite, const QString& caption);
+ };
+
diff --git a/muse_qt4_evolution/muse/widgets/floatlabel.cpp b/muse_qt4_evolution/muse/widgets/floatlabel.cpp
new file mode 100644
index 00000000..75e81419
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/floatlabel.cpp
@@ -0,0 +1,144 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "doublelabel.h"
+#include "utils.h"
+
+//---------------------------------------------------------
+// DoubleLabel
+//---------------------------------------------------------
+
+DoubleLabel::DoubleLabel(QWidget* parent, const char* name)
+ : Dentry(parent, name), _specialText("---")
+ {
+ min = 0.0;
+ max = 1.0;
+ _precision = 3;
+ setValue(0.0);
+ }
+
+DoubleLabel::DoubleLabel(double _val, double m, double mx, QWidget* parent)
+ : Dentry(parent), _specialText("---")
+ {
+ min = m;
+ max = mx;
+ _precision = 3;
+ setValue(_val);
+ }
+
+//---------------------------------------------------------
+// setString
+//---------------------------------------------------------
+
+bool DoubleLabel::setString(double v)
+ {
+ QString s;
+ if (v < min || v > max) {
+ setText(_specialText);
+ return true;
+ }
+ s.setNum(v, 'f', _precision);
+ if (!_suffix.isEmpty()) {
+ s += " ";
+ s += _suffix;
+ }
+
+ setText(s);
+ return false;
+ }
+
+//---------------------------------------------------------
+// setSValue
+//---------------------------------------------------------
+
+bool DoubleLabel::setSValue(const QString& s)
+ {
+ bool ok;
+ double v = s.toDouble(&ok);
+ if (ok && (v != val)) {
+ if (v < min)
+ v = min;
+ if (v > max)
+ v = max;
+ setValue(v);
+ emit valueChanged(val, _id);
+ }
+ return false;
+ }
+
+//---------------------------------------------------------
+// incValue
+//---------------------------------------------------------
+
+void DoubleLabel::incValue(double)
+ {
+ if (val + 1.0 < max) {
+ setValue(val + 1.0);
+ emit valueChanged(val, _id);
+ }
+ }
+
+//---------------------------------------------------------
+// decValue
+//---------------------------------------------------------
+
+void DoubleLabel::decValue(double)
+ {
+ if (val - 1.0 > min) {
+ setValue(val - 1.0);
+ emit valueChanged(val, _id);
+ }
+ }
+
+//---------------------------------------------------------
+// setPrecision
+//---------------------------------------------------------
+
+void DoubleLabel::setPrecision(int v)
+ {
+ _precision = v;
+ setString(val);
+ }
+
+//---------------------------------------------------------
+// sizeHint
+//---------------------------------------------------------
+
+QSize DoubleLabel::sizeHint() const
+ {
+ QFontMetrics fm = fontMetrics();
+ int h = fm.height() + 4;
+ int n = _precision + 3;
+#if 0
+ double aval = fabs(val);
+ if (aval >= 10.0)
+ ++n;
+ if (aval >= 100.0)
+ ++n;
+ if (aval >= 1000.0)
+ ++n;
+ if (aval >= 10000.0)
+ ++n;
+ if (aval >= 100000.0)
+ ++n;
+#endif
+ int w = fm.width(QString("-0.")) + fm.width('0') * n + 6;
+ return QSize(w, h);
+ }
diff --git a/muse_qt4_evolution/muse/widgets/floatlabel.h b/muse_qt4_evolution/muse/widgets/floatlabel.h
new file mode 100644
index 00000000..9f51d7d4
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/floatlabel.h
@@ -0,0 +1,68 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __FLOATLABEL_H__
+#define __FLOATLABEL_H__
+
+#include "dentry.h"
+
+//---------------------------------------------------------
+// FloatLabel
+//---------------------------------------------------------
+
+class FloatLabel : public Dentry {
+ Q_PROPERTY(float minValue READ minValue WRITE setMinValue )
+ Q_PROPERTY(float maxValue READ maxValue WRITE setMaxValue )
+ Q_PROPERTY(QString specialText READ specialText WRITE setSpecialText )
+ Q_PROPERTY(QString suffix READ suffix WRITE setSuffix )
+ Q_PROPERTY(int precision READ precision WRITE setPrecision )
+
+ float min, max;
+ QString _specialText; // text to show if value outside min,max
+ QString _suffix;
+ int _precision;
+ Q_OBJECT
+
+ virtual bool setSValue(const QString&);
+ virtual bool setString(double val);
+ virtual void incValue(double);
+ virtual void decValue(double);
+
+ public:
+ DoubleLabel(QWidget*, const char* name = 0);
+ DoubleLabel(double val, double min, double max, QWidget*);
+ virtual QSize sizeHint() const;
+ double minValue() const { return min; }
+ double maxValue() const { return max; }
+ void setMinValue(double v) { min = v; }
+ void setMaxValue(double v) { max = v; }
+ void setRange(double a, double b) { min = a; max = b; }
+ int precision() const { return _precision; }
+ void setPrecision(int val);
+ QString specialText() const { return _specialText; }
+ void setSpecialText(const QString& s) {
+ _specialText = s;
+ update();
+ }
+ QString suffix() const { return _suffix; }
+ void setSuffix(const QString& s) { _suffix = s; }
+ };
+
+#endif
diff --git a/muse_qt4_evolution/muse/widgets/fontsel.cpp b/muse_qt4_evolution/muse/widgets/fontsel.cpp
new file mode 100644
index 00000000..b0d6c95b
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/fontsel.cpp
@@ -0,0 +1,138 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "icons.h"
+#include "fontsel.h"
+
+//---------------------------------------------------------
+// FontSel
+//---------------------------------------------------------
+
+FontSel::FontSel(QWidget* parent, const QFont& f, const QString& name)
+ : QWidget(parent)
+ {
+ _font = f;
+ QHBoxLayout* box = new QHBoxLayout(this);
+
+ cb = new QComboBox(this);
+ cb->setFixedWidth(80);
+ cb->addItem(QString("arial"));
+ cb->addItem(QString("avantgarde"));
+ cb->addItem(QString("charter"));
+ cb->addItem(QString("garamond"));
+ cb->addItem(QString("gillsans"));
+ cb->addItem(QString("helvetica"));
+ cb->addItem(QString("times"));
+ cb->addItem(QString("terminal"));
+ cb->addItem(QString("utopia"));
+ cb->addItem(QString("new century schoolbook"));
+
+ QLabel* l1 = new QLabel(tr("Size:"), this);
+ s1 = new QSpinBox(this);
+ s1->setRange(8, 48);
+
+ fcb1 = new QToolButton(this);
+ fcb1->setCheckable(true);
+ fcb1->setIcon(*boldIcon);
+
+ fcb2 = new QToolButton(this);
+ fcb2->setCheckable(true);
+ fcb2->setIcon(*italicIcon);
+
+ fcb3 = new QToolButton(this);
+ fcb3->setCheckable(true);
+ fcb3->setIcon(*underlinedIcon);
+
+ QToolButton* pb = new QToolButton(this);
+ connect(pb, SIGNAL(pressed()), SLOT(fontSelect()));
+ pb->setText(QString("??"));
+
+ QLabel* l2 = new QLabel(name, this);
+
+ box->addWidget(cb);
+ box->addSpacing(8);
+ box->addWidget(l1);
+ box->addSpacing(5);
+ box->addWidget(s1);
+ box->addSpacing(5);
+ box->addWidget(fcb1);
+ box->addWidget(fcb2);
+ box->addWidget(fcb3);
+ box->addSpacing(2);
+ box->addWidget(pb);
+ box->addSpacing(5);
+ box->addWidget(l2);
+ box->addStretch(100);
+ setFixedHeight(18);
+ setFont();
+ }
+
+//---------------------------------------------------------
+// fontSelect
+//---------------------------------------------------------
+
+void FontSel::fontSelect()
+ {
+ bool ok;
+ QFont f = QFontDialog::getFont(&ok, _font, this);
+ if (ok) {
+ _font = f;
+ setFont();
+ }
+ }
+
+//---------------------------------------------------------
+// setFont
+//---------------------------------------------------------
+
+void FontSel::setFont()
+ {
+ s1->setValue(_font.pointSize());
+ fcb1->setChecked(_font.weight() == QFont::Bold);
+ fcb2->setChecked(_font.italic());
+ fcb3->setChecked(_font.underline());
+ int i;
+ for (i = 0; i < cb->count(); ++i) {
+ QString s = cb->itemText(i);
+ if (s == _font.family()) {
+ cb->setCurrentIndex(i);
+ break;
+ }
+ }
+ if (i == cb->count()) {
+ cb->addItem(_font.family());
+ cb->setCurrentIndex(i);
+ }
+ }
+
+//---------------------------------------------------------
+// font
+//---------------------------------------------------------
+
+const QFont& FontSel::font()
+ {
+ _font.setPointSize(s1->value());
+ _font.setWeight(fcb1->isChecked() ? QFont::Bold : QFont::Normal);
+ _font.setItalic(fcb2->isChecked());
+ _font.setUnderline(fcb3->isChecked());
+ _font.setFamily(cb->currentText());
+ return _font;
+ }
+
diff --git a/muse_qt4_evolution/muse/widgets/fontsel.h b/muse_qt4_evolution/muse/widgets/fontsel.h
new file mode 100644
index 00000000..92d076b6
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/fontsel.h
@@ -0,0 +1,57 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __FONTSEL_H__
+#define __FONTSEL_H__
+
+#include "song.h"
+
+class QFont;
+class QSpinBox;
+class QToolButton;
+class QComboBox;
+
+//---------------------------------------------------------
+// FontSel
+//---------------------------------------------------------
+
+class FontSel : public QWidget {
+ QFont _font;
+ QSpinBox* s1;
+ QToolButton* fcb1;
+ QToolButton* fcb2;
+ QToolButton* fcb3;
+ QComboBox* cb;
+
+ Q_OBJECT
+
+ void setFont();
+
+ private slots:
+ void fontSelect();
+
+ public:
+ FontSel(QWidget* parent, const QFont&, const QString&);
+ const QFont& font();
+ };
+
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/widgets/greendotbutton.h b/muse_qt4_evolution/muse/widgets/greendotbutton.h
new file mode 100644
index 00000000..84bfab96
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/greendotbutton.h
@@ -0,0 +1,38 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __GREENDOTBUTTON_H__
+#define __GREENDOTBUTTON_H__
+
+#include "simplebutton.h"
+
+//---------------------------------------------------------
+// GreendotButton
+//---------------------------------------------------------
+
+class GreendotButton : public SimpleButton {
+ Q_OBJECT
+
+ public:
+ GreendotButton(QWidget* parent = 0);
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/widgets/intlabel.h b/muse_qt4_evolution/muse/widgets/intlabel.h
new file mode 100644
index 00000000..c8919735
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/intlabel.h
@@ -0,0 +1,56 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __INTLABEL_H__
+#define __INTLABEL_H__
+
+#include "nentry.h"
+
+class QString;
+
+//---------------------------------------------------------
+// IntLabel
+//---------------------------------------------------------
+
+class IntLabel : public Nentry {
+ int min, max, off;
+ QString suffix;
+ QString specialValue;
+ Q_OBJECT
+
+ void init();
+
+ virtual bool setSValue(const QString&);
+ virtual bool setString(int val, bool editable = false);
+ virtual void incValue(int);
+ virtual void decValue(int);
+
+ signals:
+ void valueChanged(int);
+
+ public:
+ IntLabel(int, int, int, QWidget*, int _off = MAXINT,
+ const QString& = QString(""), int lpos = 0);
+ void setOff(int v);
+ void setSuffix(const QString& s) { suffix = s; }
+ void setSpecialValueText(const QString& s);
+ };
+
+#endif
diff --git a/muse_qt4_evolution/muse/widgets/menutitle.cpp b/muse_qt4_evolution/muse/widgets/menutitle.cpp
new file mode 100644
index 00000000..0dd7ddab
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/menutitle.cpp
@@ -0,0 +1,50 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "menutitle.h"
+
+//---------------------------------------------------------
+// MenuTitleItem
+//---------------------------------------------------------
+
+MenuTitleItem::MenuTitleItem(QString ss)
+ : s(ss)
+ {
+ }
+
+//---------------------------------------------------------
+// sizeHint
+//---------------------------------------------------------
+
+QSize MenuTitleItem::sizeHint()
+ {
+ return QSize(60, 20);
+ }
+
+//---------------------------------------------------------
+// drawItem
+//---------------------------------------------------------
+
+void MenuTitleItem::paint(QPainter* p, const QColorGroup&, bool,
+ bool, int x, int y, int w, int h)
+ {
+ p->fillRect(x, y, w, h, QBrush(lightGray));
+ p->drawText(x, y, w, h, AlignCenter, s);
+ }
diff --git a/muse_qt4_evolution/muse/widgets/menutitle.h b/muse_qt4_evolution/muse/widgets/menutitle.h
new file mode 100644
index 00000000..f3e85849
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/menutitle.h
@@ -0,0 +1,41 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __MENUTITLE_H__
+#define __MENUTITLE_H__
+
+//---------------------------------------------------------
+// MenuTitleItem
+//---------------------------------------------------------
+
+class MenuTitleItem : public QCustomMenuItem {
+ QString s;
+ virtual bool fullSpan() const { return true; }
+ virtual bool isSeparator() const { return true; }
+ virtual void paint(QPainter* p, const QColorGroup& cg, bool act,
+ bool, int, int, int, int);
+ virtual QSize sizeHint();
+
+ public:
+ MenuTitleItem(QString s);
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/widgets/midisync.cpp b/muse_qt4_evolution/muse/widgets/midisync.cpp
new file mode 100644
index 00000000..7b6f69df
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/midisync.cpp
@@ -0,0 +1,128 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "al/al.h"
+#include "midisync.h"
+#include "sync.h"
+
+//---------------------------------------------------------
+// MidiSyncConfig
+// Midi Sync Config
+//---------------------------------------------------------
+
+MidiSyncConfig::MidiSyncConfig(QWidget* parent)
+ : QDialog(parent)
+ {
+ setupUi(this);
+ connect(okButton, SIGNAL(clicked()), SLOT(ok()));
+ connect(applyButton, SIGNAL(clicked()), SLOT(apply()));
+ connect(cancelButton, SIGNAL(clicked()), SLOT(cancel()));
+
+ connect(syncMaster, SIGNAL(toggled(bool)), SLOT(syncMasterChanged(bool)));
+ connect(syncSlave, SIGNAL(toggled(bool)), SLOT(syncSlaveChanged(bool)));
+
+// dstDevId->setValue(txDeviceId);
+// srcDevId->setValue(rxDeviceId);
+
+ mtcSync->setChecked(genMTCSync);
+ mcSync->setChecked(genMCSync);
+ midiMachineControl->setChecked(genMMC);
+
+ acceptMTCCheckbox->setChecked(acceptMTC);
+ acceptMCCheckbox->setChecked(acceptMC);
+ acceptMMCCheckbox->setChecked(acceptMMC);
+
+ mtcSyncType->setCurrentIndex(AL::mtcType);
+
+ mtcOffH->setValue(mtcOffset.h());
+ mtcOffM->setValue(mtcOffset.m());
+ mtcOffS->setValue(mtcOffset.s());
+ mtcOffF->setValue(mtcOffset.f());
+ mtcOffSf->setValue(mtcOffset.sf());
+
+ syncSlaveChanged(extSyncFlag);
+ }
+
+//---------------------------------------------------------
+// ok Pressed
+//---------------------------------------------------------
+
+void MidiSyncConfig::ok()
+ {
+ apply();
+ cancel();
+ }
+
+//---------------------------------------------------------
+// cancel Pressed
+//---------------------------------------------------------
+
+void MidiSyncConfig::cancel()
+ {
+ close();
+ }
+
+//---------------------------------------------------------
+// apply Pressed
+//---------------------------------------------------------
+
+void MidiSyncConfig::apply()
+ {
+// txDeviceId = dstDevId->value();
+// rxDeviceId = srcDevId->value();
+
+ genMTCSync = mtcSync->isChecked();
+ genMCSync = mcSync->isChecked();
+ genMMC = midiMachineControl->isChecked();
+
+ AL::mtcType = mtcSyncType->currentIndex();
+ extSyncFlag = syncSlave->isChecked();
+
+ mtcOffset.setH(mtcOffH->value());
+ mtcOffset.setM(mtcOffM->value());
+ mtcOffset.setS(mtcOffS->value());
+ mtcOffset.setF(mtcOffF->value());
+ mtcOffset.setSf(mtcOffSf->value());
+
+ acceptMC = acceptMCCheckbox->isChecked();
+ acceptMMC = acceptMMCCheckbox->isChecked();
+ acceptMTC = acceptMTCCheckbox->isChecked();
+ emit syncChanged();
+ }
+
+//---------------------------------------------------------
+// syncMasterChanged
+//---------------------------------------------------------
+
+void MidiSyncConfig::syncMasterChanged(bool val)
+ {
+ syncSlave->setChecked(!val);
+ }
+
+//---------------------------------------------------------
+// syncSlaveChanged
+//---------------------------------------------------------
+
+void MidiSyncConfig::syncSlaveChanged(bool val)
+ {
+ syncMaster->setChecked(!val);
+ }
+
+
diff --git a/muse_qt4_evolution/muse/widgets/midisync.h b/muse_qt4_evolution/muse/widgets/midisync.h
new file mode 100644
index 00000000..c1db5fdd
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/midisync.h
@@ -0,0 +1,49 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __MIDISYNC_H__
+#define __MIDISYNC_H__
+
+#include "ui_midisync.h"
+
+//---------------------------------------------------------
+// MidiSyncConfig
+//---------------------------------------------------------
+
+class MidiSyncConfig : public QDialog, private Ui::MidiSyncConfigBase {
+ Q_OBJECT
+
+ private slots:
+ void syncMasterChanged(bool);
+ void syncSlaveChanged(bool);
+ void ok();
+ void cancel();
+ void apply();
+
+ signals:
+ void syncChanged();
+
+ public:
+ MidiSyncConfig(QWidget* parent=0);
+ MidiSyncConfig();
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/widgets/midisync.ui b/muse_qt4_evolution/muse/widgets/midisync.ui
new file mode 100644
index 00000000..6ea9ef1a
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/midisync.ui
@@ -0,0 +1,711 @@
+<ui version="4.0" >
+ <author>werner schweer</author>
+ <comment>midi sync
+configuration dialog</comment>
+ <exportmacro></exportmacro>
+ <class>MidiSyncConfigBase</class>
+ <widget class="QDialog" name="MidiSyncConfigBase" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>530</width>
+ <height>359</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>4</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle" >
+ <string>MusE: Midi Sync</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="0" >
+ <widget class="QGroupBox" name="syncMaster" >
+ <property name="title" >
+ <string>Master</string>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ <property name="checked" >
+ <bool>true</bool>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>11</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QCheckBox" name="mtcSync" >
+ <property name="enabled" >
+ <bool>true</bool>
+ </property>
+ <property name="text" >
+ <string>Midi Time Code (MTC)</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="mcSync" >
+ <property name="enabled" >
+ <bool>true</bool>
+ </property>
+ <property name="text" >
+ <string>Midi Clock</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="midiMachineControl" >
+ <property name="enabled" >
+ <bool>true</bool>
+ </property>
+ <property name="text" >
+ <string>Midi Machine Control (MMC)</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="TextLabel7" >
+ <property name="enabled" >
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Id:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="dstDevId" >
+ <property name="enabled" >
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>device id</string>
+ </property>
+ <property name="maximum" >
+ <number>127</number>
+ </property>
+ <property name="minimum" >
+ <number>0</number>
+ </property>
+ <property name="value" >
+ <number>127</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Preferred</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>30</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QGroupBox" name="syncSlave" >
+ <property name="title" >
+ <string>Slave</string>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ <property name="checked" >
+ <bool>false</bool>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>11</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QCheckBox" name="acceptMTCCheckbox" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="text" >
+ <string>accept MTC</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="acceptMCCheckbox" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="text" >
+ <string>accept Midi Clock</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="acceptMMCCheckbox" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="text" >
+ <string>accept MMC</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="TextLabel7_2" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Id:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="srcDevId" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>device id</string>
+ </property>
+ <property name="maximum" >
+ <number>127</number>
+ </property>
+ <property name="minimum" >
+ <number>0</number>
+ </property>
+ <property name="value" >
+ <number>127</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="2" column="0" colspan="2" >
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="applyButton" >
+ <property name="text" >
+ <string>Apply</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="okButton" >
+ <property name="text" >
+ <string>Ok</string>
+ </property>
+ <property name="default" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="cancelButton" >
+ <property name="text" >
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="0" colspan="2" >
+ <widget class="QGroupBox" name="GroupBox13" >
+ <property name="enabled" >
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title" >
+ <string>MTC</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="textLabel2" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Type:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="mtcSyncType" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <item>
+ <property name="text" >
+ <string>24</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>25</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>30D</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>30N</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>407</width>
+ <height>69</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="textLabel1" >
+ <property name="text" >
+ <string>Offset:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="mtcOffH" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="toolTip" >
+ <string>hour</string>
+ </property>
+ <property name="maximum" >
+ <number>23</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="TextLabel2" >
+ <property name="text" >
+ <string>h</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="mtcOffM" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="toolTip" >
+ <string>minute</string>
+ </property>
+ <property name="maximum" >
+ <number>59</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="TextLabel3" >
+ <property name="text" >
+ <string>m</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="mtcOffS" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="toolTip" >
+ <string>second</string>
+ </property>
+ <property name="maximum" >
+ <number>59</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="TextLabel4" >
+ <property name="text" >
+ <string>s</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="mtcOffF" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="toolTip" >
+ <string>frame</string>
+ </property>
+ <property name="maximum" >
+ <number>30</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="TextLabel5" >
+ <property name="text" >
+ <string>f</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="mtcOffSf" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="toolTip" >
+ <string>subframe</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11" />
+ <pixmapfunction>qPixmapFromMimeSource</pixmapfunction>
+ <tabstops>
+ <tabstop>acceptMTCCheckbox</tabstop>
+ <tabstop>acceptMCCheckbox</tabstop>
+ <tabstop>mtcSync</tabstop>
+ <tabstop>mcSync</tabstop>
+ <tabstop>midiMachineControl</tabstop>
+ <tabstop>dstDevId</tabstop>
+ <tabstop>mtcOffH</tabstop>
+ <tabstop>mtcOffM</tabstop>
+ <tabstop>mtcOffS</tabstop>
+ <tabstop>mtcOffF</tabstop>
+ <tabstop>mtcOffSf</tabstop>
+ <tabstop>applyButton</tabstop>
+ <tabstop>okButton</tabstop>
+ <tabstop>cancelButton</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>syncSlave</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>acceptMTCCheckbox</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>377</x>
+ <y>79</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>341</x>
+ <y>67</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>syncSlave</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>acceptMCCheckbox</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>365</x>
+ <y>102</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>361</x>
+ <y>94</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>syncSlave</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>acceptMMCCheckbox</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>392</x>
+ <y>132</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>328</x>
+ <y>121</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>syncSlave</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>srcDevId</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>366</x>
+ <y>103</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>375</x>
+ <y>147</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>mcSync</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>mcSync</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>255</x>
+ <y>94</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>255</x>
+ <y>94</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>mtcSync</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>mtcSync</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>255</x>
+ <y>67</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>255</x>
+ <y>67</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>syncMaster</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>midiMachineControl</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>268</x>
+ <y>131</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>255</x>
+ <y>121</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>syncMaster</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>dstDevId</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>268</x>
+ <y>129</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>175</x>
+ <y>147</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>syncMaster</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>mtcSync</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>268</x>
+ <y>40</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>255</x>
+ <y>67</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>syncMaster</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>GroupBox13</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>53</x>
+ <y>17</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>41</x>
+ <y>256</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/muse_qt4_evolution/muse/widgets/mittransposebase.h b/muse_qt4_evolution/muse/widgets/mittransposebase.h
new file mode 100644
index 00000000..531cb200
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/mittransposebase.h
@@ -0,0 +1,111 @@
+#ifndef MITTRANSPOSEBASE_H
+#define MITTRANSPOSEBASE_H
+
+#include <qvariant.h>
+
+
+#include <QtCore/QVariant>
+#include <QtGui/QAction>
+#include <QtGui/QApplication>
+#include <QtGui/QButtonGroup>
+#include <QtGui/QCheckBox>
+#include <QtGui/QHBoxLayout>
+#include <QtGui/QLabel>
+#include <QtGui/QWidget>
+#include "awl/pitchedit.h"
+#include <awl::pitchedit.h>
+#include <Qt3Support/Q3MimeSourceFactory>
+
+class Ui_MITTransposeBase
+{
+public:
+ QHBoxLayout *hboxLayout;
+ QCheckBox *onCheckBox;
+ QLabel *TextLabel1;
+ Awl::PitchEdit *triggerKeySpinBox;
+ QLabel *TextLabel2;
+ QLabel *transposeLabel;
+
+ void setupUi(QWidget *MITTransposeBase)
+ {
+ MITTransposeBase->setObjectName(QString::fromUtf8("MITTransposeBase"));
+ MITTransposeBase->resize(QSize(423, 50).expandedTo(MITTransposeBase->minimumSizeHint()));
+ hboxLayout = new QHBoxLayout(MITTransposeBase);
+ hboxLayout->setSpacing(6);
+ hboxLayout->setMargin(11);
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
+ onCheckBox = new QCheckBox(MITTransposeBase);
+ onCheckBox->setObjectName(QString::fromUtf8("onCheckBox"));
+
+ hboxLayout->addWidget(onCheckBox);
+
+ TextLabel1 = new QLabel(MITTransposeBase);
+ TextLabel1->setObjectName(QString::fromUtf8("TextLabel1"));
+ TextLabel1->setAlignment(Qt::AlignVCenter|Qt::AlignRight);
+ TextLabel1->setIndent(5);
+
+ hboxLayout->addWidget(TextLabel1);
+
+ triggerKeySpinBox = new Awl::PitchEdit(MITTransposeBase);
+ triggerKeySpinBox->setObjectName(QString::fromUtf8("triggerKeySpinBox"));
+
+ hboxLayout->addWidget(triggerKeySpinBox);
+
+ TextLabel2 = new QLabel(MITTransposeBase);
+ TextLabel2->setObjectName(QString::fromUtf8("TextLabel2"));
+ TextLabel2->setAlignment(Qt::AlignVCenter|Qt::AlignRight);
+ TextLabel2->setIndent(5);
+
+ hboxLayout->addWidget(TextLabel2);
+
+ transposeLabel = new QLabel(MITTransposeBase);
+ transposeLabel->setObjectName(QString::fromUtf8("transposeLabel"));
+ QSizePolicy sizePolicy((QSizePolicy::Policy)5, (QSizePolicy::Policy)0);
+ sizePolicy.setHorizontalStretch(0);
+ sizePolicy.setVerticalStretch(0);
+ sizePolicy.setHeightForWidth(transposeLabel->sizePolicy().hasHeightForWidth());
+ transposeLabel->setSizePolicy(sizePolicy);
+ transposeLabel->setFrameShape(QFrame::Panel);
+ transposeLabel->setLineWidth(2);
+ transposeLabel->setMargin(2);
+ transposeLabel->setMidLineWidth(2);
+ transposeLabel->setAlignment(Qt::AlignVCenter|Qt::AlignRight);
+ transposeLabel->setIndent(5);
+
+ hboxLayout->addWidget(transposeLabel);
+
+ retranslateUi(MITTransposeBase);
+
+ QMetaObject::connectSlotsByName(MITTransposeBase);
+ } // setupUi
+
+ void retranslateUi(QWidget *MITTransposeBase)
+ {
+ MITTransposeBase->setWindowTitle(QApplication::translate("MITTransposeBase", "MusE: Midi Input Plugin: Transpose", 0, QApplication::UnicodeUTF8));
+ onCheckBox->setText(QApplication::translate("MITTransposeBase", "On", 0, QApplication::UnicodeUTF8));
+ TextLabel1->setText(QApplication::translate("MITTransposeBase", "TriggerKey", 0, QApplication::UnicodeUTF8));
+ TextLabel2->setText(QApplication::translate("MITTransposeBase", "Transpose:", 0, QApplication::UnicodeUTF8));
+ transposeLabel->setText(QApplication::translate("MITTransposeBase", "+0", 0, QApplication::UnicodeUTF8));
+ Q_UNUSED(MITTransposeBase);
+ } // retranslateUi
+
+};
+
+namespace Ui {
+ class MITTransposeBase: public Ui_MITTransposeBase {};
+} // namespace Ui
+
+class MITTransposeBase : public QWidget, public Ui::MITTransposeBase
+{
+ Q_OBJECT
+
+public:
+ MITTransposeBase(QWidget* parent = 0, const char* name = 0, Qt::WFlags fl = 0);
+ ~MITTransposeBase();
+
+protected slots:
+ virtual void languageChange();
+
+};
+
+#endif // MITTRANSPOSEBASE_H
diff --git a/muse_qt4_evolution/muse/widgets/mittransposebase.ui b/muse_qt4_evolution/muse/widgets/mittransposebase.ui
new file mode 100644
index 00000000..c1aad75a
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/mittransposebase.ui
@@ -0,0 +1,112 @@
+<ui version="4.0" >
+ <author></author>
+ <comment></comment>
+ <exportmacro></exportmacro>
+ <class>MITTransposeBase</class>
+ <widget class="QWidget" name="MITTransposeBase" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>423</width>
+ <height>50</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>MusE: Midi Input Plugin: Transpose</string>
+ </property>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>11</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QCheckBox" name="onCheckBox" >
+ <property name="text" >
+ <string>On</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="TextLabel1" >
+ <property name="text" >
+ <string>TriggerKey</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ <property name="indent" >
+ <number>5</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Awl::PitchEdit" name="triggerKeySpinBox" />
+ </item>
+ <item>
+ <widget class="QLabel" name="TextLabel2" >
+ <property name="text" >
+ <string>Transpose:</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ <property name="indent" >
+ <number>5</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="transposeLabel" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape" >
+ <enum>QFrame::Panel</enum>
+ </property>
+ <property name="lineWidth" >
+ <number>2</number>
+ </property>
+ <property name="midLineWidth" >
+ <number>2</number>
+ </property>
+ <property name="text" >
+ <string>+0</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ <property name="margin" >
+ <number>2</number>
+ </property>
+ <property name="indent" >
+ <number>5</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11" />
+ <pixmapfunction>qPixmapFromMimeSource</pixmapfunction>
+ <customwidgets>
+ <customwidget>
+ <class>Awl::PitchEdit</class>
+ <extends>QWidget</extends>
+ <header>awl::pitchedit.h</header>
+ <container>1</container>
+ <pixmap></pixmap>
+ </customwidget>
+ </customwidgets>
+ <includes>
+ <include location="local" >awl/pitchedit.h</include>
+ </includes>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/muse_qt4_evolution/muse/widgets/mixdowndialog.cpp b/muse_qt4_evolution/muse/widgets/mixdowndialog.cpp
new file mode 100644
index 00000000..ac517d30
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/mixdowndialog.cpp
@@ -0,0 +1,133 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "al/al.h"
+#include "mixdowndialog.h"
+#include "globals.h"
+#include "wave.h"
+#include "song.h"
+#include "gconfig.h"
+
+//---------------------------------------------------------
+// sndFileOpen
+// sf - old soundfile, used to preset file parameters
+//---------------------------------------------------------
+
+SndFile* getSndFile(SndFile* sf, QWidget* parent)
+ {
+ MixdownFileDialog* dialog = new MixdownFileDialog(sf, parent);
+ dialog->exec();
+ SndFile* sndFile = dialog->sndFile();
+ delete dialog;
+ return sndFile;
+ }
+
+//---------------------------------------------------------
+// MixdownFileDialog
+//---------------------------------------------------------
+
+MixdownFileDialog::MixdownFileDialog(SndFile* _sf, QWidget* parent)
+ : QDialog(parent)
+ {
+ setupUi(this);
+ sf = 0;
+ connect(buttonPath, SIGNAL(clicked()), SLOT(fdialog()));
+ if (_sf) {
+ int channels = _sf->channels();
+ int format = _sf->format();
+ switch(channels) {
+ case 1: channels = 1; break;
+ case 2: channels = 0; break;
+ case 6: channels = 2; break;
+ }
+ editPath->setText(_sf->finfo()->filePath());
+ comboChannel->setCurrentIndex(channels);
+ comboFormat->setCurrentIndex(format);
+ }
+ else {
+ // create unique mixdown file path
+ QString path = QDir::homePath() + "/" + config.projectPath + "/" + song->projectPath();
+
+ QDir dir(path);
+ for (int i = 1; i < 1000; ++i) {
+ QString fp = QString("md%2.wav").arg(i);
+ if (!dir.exists(fp)) {
+ path = dir.filePath(fp);
+ break;
+ }
+ }
+ editPath->setText(path);
+ }
+ }
+
+//---------------------------------------------------------
+// accept
+//---------------------------------------------------------
+
+void MixdownFileDialog::accept()
+ {
+ QString oldpath;
+ unsigned channel = comboChannel->currentIndex();
+ unsigned format = comboFormat->currentIndex();
+ switch (channel) {
+ case 0: channel = 2; break;
+ case 1: channel = 1; break;
+ case 2: channel = 6; break; // not implemented!
+ }
+ switch (format) {
+ case 0: // 16 bit wave
+ format = SF_FORMAT_WAV | SF_FORMAT_PCM_16;
+ break;
+ case 1: // 24 bit wave
+ format = SF_FORMAT_WAV | SF_FORMAT_PCM_24;
+ break;
+ case 2: // 32 bit float wave
+ format = SF_FORMAT_WAV | SF_FORMAT_FLOAT;
+ break;
+ }
+ QString path = editPath->text();
+ if (path.isEmpty()) {
+ sf = 0;
+ reject();
+ return;
+ }
+ if (path.right(4) != ".wav")
+ path += ".wav";
+ sf = new SndFile(path);
+ sf->setFormat(format, channel, AL::sampleRate);
+ done(1);
+ }
+
+//---------------------------------------------------------
+// fdialog
+//---------------------------------------------------------
+
+void MixdownFileDialog::fdialog()
+ {
+ QString path = QFileDialog::getSaveFileName(
+ this,
+ tr("MusE: set mixdown file name"),
+ editPath->text(),
+ tr("Wave Files (*.wav);;All Files (*)")
+ );
+ if (!path.isEmpty())
+ editPath->setText(path);
+ }
+
diff --git a/muse_qt4_evolution/muse/widgets/mixdowndialog.h b/muse_qt4_evolution/muse/widgets/mixdowndialog.h
new file mode 100644
index 00000000..58d1b970
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/mixdowndialog.h
@@ -0,0 +1,48 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __MIXDOWNDIALOG_H__
+#define __MIXDOWNDIALOG_H__
+
+#include "ui_mixdowndialog.h"
+
+class SndFile;
+
+extern SndFile* getSndFile(SndFile* sf, QWidget* parent);
+
+//---------------------------------------------------------
+// MixdownFileDialog
+//---------------------------------------------------------
+
+class MixdownFileDialog : public QDialog, private Ui::MixdownFileDialogBase {
+ Q_OBJECT
+ SndFile* sf;
+
+ private slots:
+ void fdialog();
+ virtual void accept();
+
+ public:
+ MixdownFileDialog(SndFile* f, QWidget* parent = 0);
+ SndFile* sndFile() { return sf; }
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/widgets/mixdowndialog.ui b/muse_qt4_evolution/muse/widgets/mixdowndialog.ui
new file mode 100644
index 00000000..c1c3d4fa
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/mixdowndialog.ui
@@ -0,0 +1,212 @@
+<ui version="4.0" >
+ <class>MixdownFileDialogBase</class>
+ <widget class="QDialog" name="MixdownFileDialogBase" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>381</width>
+ <height>116</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>MusE: Set Mixdown Wavefile</string>
+ </property>
+ <property name="sizeGripEnabled" >
+ <bool>true</bool>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>11</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="2" column="0" colspan="5" >
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonOk" >
+ <property name="text" >
+ <string>&amp;OK</string>
+ </property>
+ <property name="autoDefault" >
+ <bool>true</bool>
+ </property>
+ <property name="default" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonCancel" >
+ <property name="text" >
+ <string>&amp;Cancel</string>
+ </property>
+ <property name="autoDefault" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="TextLabel1" >
+ <property name="text" >
+ <string>File Path</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="TextLabel2" >
+ <property name="text" >
+ <string>Channel</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" colspan="4" >
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLineEdit" name="editPath" />
+ </item>
+ <item>
+ <widget class="QToolButton" name="buttonPath" >
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="icon" >
+ <iconset resource="../muse.qrc" >:/xpm/fileopen.png</iconset>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QComboBox" name="comboChannel" >
+ <item>
+ <property name="text" >
+ <string>Stereo</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Mono</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>5.1</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="1" column="4" >
+ <widget class="QComboBox" name="comboFormat" >
+ <item>
+ <property name="text" >
+ <string>wav,16 Bit</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>wav, 24 Bit</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>wav, 32 Bit (float)</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="1" column="3" >
+ <widget class="QLabel" name="TextLabel3" >
+ <property name="text" >
+ <string>Format</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11" />
+ <resources>
+ <include location="../muse.qrc" />
+ </resources>
+ <connections>
+ <connection>
+ <sender>buttonOk</sender>
+ <signal>clicked()</signal>
+ <receiver>MixdownFileDialogBase</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>248</x>
+ <y>93</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>99</x>
+ <y>89</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonCancel</sender>
+ <signal>clicked()</signal>
+ <receiver>MixdownFileDialogBase</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>318</x>
+ <y>94</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>170</x>
+ <y>105</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/muse_qt4_evolution/muse/widgets/noteinfo.cpp b/muse_qt4_evolution/muse/widgets/noteinfo.cpp
new file mode 100644
index 00000000..9ae02ab0
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/noteinfo.cpp
@@ -0,0 +1,207 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "noteinfo.h"
+#include "song.h"
+#include "globals.h"
+#include "awl/posedit.h"
+#include "awl/pitchedit.h"
+
+//---------------------------------------------------
+// NoteInfo
+// ToolBar
+// Start, Len, Note, Velo on, Velo off, Channel
+//---------------------------------------------------
+
+NoteInfo::NoteInfo(QMainWindow* parent)
+ : QToolBar(tr("Note Info"), parent)
+ {
+ deltaMode = false;
+
+ QLabel* label = new QLabel(tr("Start"));
+ label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
+ label->setIndent(3);
+ addWidget(label);
+
+ selTime = new Awl::PosEdit;
+ selTime->setFixedHeight(24);
+ addWidget(selTime);
+
+ label = new QLabel(tr("Len"), this);
+ label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
+ label->setIndent(3);
+ addWidget(label);
+
+ selLen = new QSpinBox(this);
+ selLen->setRange(0, 100000);
+ selLen->setFixedHeight(24);
+ addWidget(selLen);
+
+ label = new QLabel(tr("Pitch"), this);
+ label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
+ label->setIndent(3);
+ addWidget(label);
+ selPitch = new Awl::PitchEdit(this);
+ selPitch->setFixedHeight(24);
+ addWidget(selPitch);
+
+ label = new QLabel(tr("Velo On"), this);
+ label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
+ label->setIndent(3);
+ addWidget(label);
+ selVelOn = new QSpinBox(this);
+ selVelOn->setRange(0, 127);
+ selVelOn->setFixedHeight(24);
+ addWidget(selVelOn);
+
+ label = new QLabel(tr("Velo Off"), this);
+ label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
+ label->setIndent(3);
+ addWidget(label);
+ selVelOff = new QSpinBox(this);
+ selVelOff->setRange(0, 127);
+ selVelOff->setFixedHeight(24);
+ addWidget(selVelOff);
+
+ connect(selLen, SIGNAL(valueChanged(int)), SLOT(lenChanged(int)));
+ connect(selPitch, SIGNAL(valueChanged(int)), SLOT(pitchChanged(int)));
+ connect(selVelOn, SIGNAL(valueChanged(int)), SLOT(velOnChanged(int)));
+ connect(selVelOff, SIGNAL(valueChanged(int)), SLOT(velOffChanged(int)));
+ connect(selTime, SIGNAL(valueChanged(const Pos&)), SLOT(timeChanged(const Pos&)));
+ }
+
+//---------------------------------------------------------
+// setDeltaMode
+//---------------------------------------------------------
+
+void NoteInfo::setDeltaMode(bool val)
+ {
+ deltaMode = val;
+ selPitch->setDeltaMode(val);
+ if (val) {
+ selLen->setRange(-100000, 100000);
+ selVelOn->setRange(-127, 127);
+ selVelOff->setRange(-127, 127);
+ }
+ else {
+ selLen->setRange(0, 100000);
+ selVelOn->setRange(0, 127);
+ selVelOff->setRange(0, 127);
+ }
+ }
+
+//---------------------------------------------------------
+// lenChanged
+//---------------------------------------------------------
+
+void NoteInfo::lenChanged(int val)
+ {
+ if (!signalsBlocked())
+ emit valueChanged(VAL_LEN, val);
+ }
+
+//---------------------------------------------------------
+// velOnChanged
+//---------------------------------------------------------
+
+void NoteInfo::velOnChanged(int val)
+ {
+ if (!signalsBlocked())
+ emit valueChanged(VAL_VELON, val);
+ }
+
+//---------------------------------------------------------
+// velOffChanged
+//---------------------------------------------------------
+
+void NoteInfo::velOffChanged(int val)
+ {
+ if (!signalsBlocked())
+ emit valueChanged(VAL_VELOFF, val);
+ }
+
+//---------------------------------------------------------
+// pitchChanged
+//---------------------------------------------------------
+
+void NoteInfo::pitchChanged(int val)
+ {
+ if (!signalsBlocked())
+ emit valueChanged(VAL_PITCH, val);
+ }
+
+//---------------------------------------------------------
+// setValue
+//---------------------------------------------------------
+
+void NoteInfo::setValue(ValType type, int val)
+ {
+ blockSignals(true);
+ switch(type) {
+ case VAL_TIME:
+ selTime->setValue(val);
+ break;
+ case VAL_LEN:
+ selLen->setValue(val);
+ break;
+ case VAL_VELON:
+ selVelOn->setValue(val);
+ break;
+ case VAL_VELOFF:
+ selVelOff->setValue(val);
+ break;
+ case VAL_PITCH:
+ selPitch->setValue(val);
+ break;
+ }
+ blockSignals(false);
+ }
+
+//---------------------------------------------------------
+// setValue
+//---------------------------------------------------------
+
+void NoteInfo::setValues(unsigned tick, int val2, int val3, int val4,
+ int val5)
+ {
+ blockSignals(true);
+ if (selTime->pos().tick() != tick)
+ selTime->setValue(tick);
+ if (selLen->value() != val2)
+ selLen->setValue(val2);
+ if (selPitch->value() != val3)
+ selPitch->setValue(val3);
+ if (selVelOn->value() != val4)
+ selVelOn->setValue(val4);
+ if (selVelOff->value() != val5)
+ selVelOff->setValue(val5);
+ blockSignals(false);
+ }
+
+//---------------------------------------------------------
+// timeChanged
+//---------------------------------------------------------
+
+void NoteInfo::timeChanged(const Pos& pos)
+ {
+ if (!signalsBlocked())
+ emit valueChanged(VAL_TIME, pos.tick());
+ }
+
diff --git a/muse_qt4_evolution/muse/widgets/noteinfo.h b/muse_qt4_evolution/muse/widgets/noteinfo.h
new file mode 100644
index 00000000..afcb6d1f
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/noteinfo.h
@@ -0,0 +1,68 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __NOTE_INFO_H__
+#define __NOTE_INFO_H__
+
+namespace Awl {
+ class PosEdit;
+ class PitchEdit;
+ };
+namespace AL {
+ class Pos;
+ }
+
+using AL::Pos;
+
+//---------------------------------------------------------
+// NoteInfo
+//---------------------------------------------------------
+
+class NoteInfo : public QToolBar {
+ Awl::PosEdit* selTime;
+ QSpinBox* selLen;
+ Awl::PitchEdit* selPitch;
+ QSpinBox* selVelOn;
+ QSpinBox* selVelOff;
+ bool deltaMode;
+
+ Q_OBJECT
+
+ public:
+ enum ValType {VAL_TIME, VAL_LEN, VAL_VELON, VAL_VELOFF, VAL_PITCH };
+ NoteInfo(QMainWindow* parent);
+ void setValues(unsigned, int, int, int, int);
+ void setDeltaMode(bool);
+
+ private slots:
+ void lenChanged(int);
+ void velOnChanged(int);
+ void velOffChanged(int);
+ void pitchChanged(int);
+ void timeChanged(const Pos&);
+
+ public slots:
+ void setValue(ValType, int);
+
+ signals:
+ void valueChanged(NoteInfo::ValType, int);
+ };
+#endif
+
diff --git a/muse_qt4_evolution/muse/widgets/outportcombo.cpp b/muse_qt4_evolution/muse/widgets/outportcombo.cpp
new file mode 100644
index 00000000..a3e55adc
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/outportcombo.cpp
@@ -0,0 +1,52 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "outportcombo.h"
+#include "song.h"
+#include "midioutport.h"
+
+//---------------------------------------------------------
+// OutportCombo
+//---------------------------------------------------------
+
+OutportCombo::OutportCombo(QWidget* parent)
+ : QComboBox(parent)
+ {
+ setToolTip(tr("Midi Output Port"));
+ populate();
+ // midiPort names may change, when inserting/deleting syntis
+ connect(song, SIGNAL(trackAdded(Track*,int)), SLOT(populate()));
+ connect(song, SIGNAL(trackRemoved(Track*)), SLOT(populate()));
+ }
+
+//---------------------------------------------------------
+// populate
+//---------------------------------------------------------
+
+void OutportCombo::populate()
+ {
+ int cur = currentIndex();
+ clear();
+ MidiOutPortList* mpl = song->midiOutPorts();
+ for (iMidiOutPort i = mpl->begin(); i != mpl->end(); ++i)
+ addItem((*i)->name());
+ setCurrentIndex(cur);
+ }
+
diff --git a/muse_qt4_evolution/muse/widgets/outportcombo.h b/muse_qt4_evolution/muse/widgets/outportcombo.h
new file mode 100644
index 00000000..8a49fc53
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/outportcombo.h
@@ -0,0 +1,39 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __OUTPORTCOMBO_H__
+#define __OUTPORTCOMBO_H__
+
+//---------------------------------------------------------
+// OutportCombo
+//---------------------------------------------------------
+
+class OutportCombo : public QComboBox {
+ Q_OBJECT
+
+ private slots:
+ void populate();
+
+ public:
+ OutportCombo(QWidget* parent = 0);
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/widgets/quantcombo.cpp b/muse_qt4_evolution/muse/widgets/quantcombo.cpp
new file mode 100644
index 00000000..89cd27fc
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/quantcombo.cpp
@@ -0,0 +1,80 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "quantcombo.h"
+
+static int quantTable[] = {
+ 1, 24, 48, 96, 192, 384, 768, 1536,
+ 16, 32, 64, 128, 256, 512, 1024,
+ 36, 72, 144, 288, 576, 1152, 2304
+ };
+
+static const char* quantStrings[] = {
+ QT_TR_NOOP("Off"), "64", "32", "16", "8", "4", "2", "1",
+ "64T", "32T", "16T", "8T", "4T", "2T", "1T",
+ "64.", "32.", "16.", "8.", "4.", "2.", "1."
+ };
+
+//---------------------------------------------------------
+// QuantCombo
+//---------------------------------------------------------
+
+QuantCombo::QuantCombo(QWidget* parent)
+ : QComboBox(parent)
+ {
+ for (unsigned i = 0; i < sizeof(quantStrings)/sizeof(*quantStrings); i++)
+ addItem(tr(quantStrings[i]), i);
+ connect(this, SIGNAL(activated(int)), SLOT(_quantChanged(int)));
+ }
+
+//---------------------------------------------------------
+// _quantChanged
+//---------------------------------------------------------
+
+void QuantCombo::_quantChanged(int idx)
+ {
+ emit quantChanged(quantTable[idx]);
+ }
+
+//---------------------------------------------------------
+// quant
+//---------------------------------------------------------
+
+int QuantCombo::quant() const
+ {
+ return quantTable[currentIndex()];
+ }
+
+//---------------------------------------------------------
+// setQuant
+//---------------------------------------------------------
+
+void QuantCombo::setQuant(int val)
+ {
+ for (unsigned i = 0; i < sizeof(quantTable)/sizeof(*quantTable); i++) {
+ if (val == quantTable[i]) {
+ setCurrentIndex(i);
+ return;
+ }
+ }
+ printf("setQuant(%d) not defined\n", val);
+abort();
+ setCurrentIndex(0);
+ }
diff --git a/muse_qt4_evolution/muse/widgets/quantcombo.h b/muse_qt4_evolution/muse/widgets/quantcombo.h
new file mode 100644
index 00000000..6cdfb69d
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/quantcombo.h
@@ -0,0 +1,46 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __QUANTCOMBO_H__
+#define __QUANTCOMBO_H__
+
+//---------------------------------------------------------
+// QuantCombo
+//---------------------------------------------------------
+
+class QuantCombo : public QComboBox {
+ Q_OBJECT
+
+ private slots:
+ void _quantChanged(int);
+
+ public slots:
+ void setQuant(int);
+
+ signals:
+ void quantChanged(int);
+
+ public:
+ QuantCombo(QWidget* parent = 0);
+ int quant() const;
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/widgets/rastercombo.cpp b/muse_qt4_evolution/muse/widgets/rastercombo.cpp
new file mode 100644
index 00000000..f5b3c7e6
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/rastercombo.cpp
@@ -0,0 +1,82 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "rastercombo.h"
+
+static int rasterTable[] = {
+ //------ 8 4 2
+ 1, 6, 12, 24, 48, 96, 192, 384, 768, 1536,
+ 4, 8, 16, 32, 64, 128, 256, 512, 1024,
+ 9, 18, 36, 72, 144, 288, 576, 1152, 2304
+ };
+
+static const char* rasterStrings[] = {
+ QT_TR_NOOP("Off"), "3pp", "6pp", "64", "32", "16", "8", "4", "2", "1",
+ "2pp", "5pp", "64T", "32T", "16T", "8T", "4T", "2T", "1T",
+ "4pp", "7pp", "64.", "32.", "16.", "8.", "4.", "2.", "1."
+ };
+
+//---------------------------------------------------------
+// RasterCombo
+//---------------------------------------------------------
+
+RasterCombo::RasterCombo(QWidget* parent)
+ : QComboBox(parent)
+ {
+ for (unsigned i = 0; i < sizeof(rasterStrings)/sizeof(*rasterStrings); i++)
+ addItem(tr(rasterStrings[i]), i);
+ connect(this, SIGNAL(activated(int)), SLOT(_rasterChanged(int)));
+ }
+
+//---------------------------------------------------------
+// _rasterChanged
+//---------------------------------------------------------
+
+void RasterCombo::_rasterChanged(int idx)
+ {
+ emit rasterChanged(rasterTable[idx]);
+ }
+
+//---------------------------------------------------------
+// raster
+//---------------------------------------------------------
+
+int RasterCombo::raster() const
+ {
+ return rasterTable[currentIndex()];
+ }
+
+//---------------------------------------------------------
+// setRaster
+//---------------------------------------------------------
+
+void RasterCombo::setRaster(int val)
+ {
+ for (unsigned i = 0; i < sizeof(rasterTable)/sizeof(*rasterTable); i++) {
+ if (val == rasterTable[i]) {
+ setCurrentIndex(i);
+ return;
+ }
+ }
+ printf("setRaster(%d) not defined\n", val);
+ setCurrentIndex(0);
+ }
+
+
diff --git a/muse_qt4_evolution/muse/widgets/rastercombo.h b/muse_qt4_evolution/muse/widgets/rastercombo.h
new file mode 100644
index 00000000..9ae48ba6
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/rastercombo.h
@@ -0,0 +1,46 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __RASTERCOMBO_H__
+#define __RASTERCOMBO_H__
+
+//---------------------------------------------------------
+// RasterCombo
+//---------------------------------------------------------
+
+class RasterCombo : public QComboBox {
+ Q_OBJECT
+
+ private slots:
+ void _rasterChanged(int);
+
+ public slots:
+ void setRaster(int);
+
+ signals:
+ void rasterChanged(int);
+
+ public:
+ RasterCombo(QWidget* parent = 0);
+ int raster() const;
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/widgets/recordbutton.h b/muse_qt4_evolution/muse/widgets/recordbutton.h
new file mode 100644
index 00000000..9b30de01
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/recordbutton.h
@@ -0,0 +1,38 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __RECORDBUTTON_H__
+#define __RCORDBUTTON_H__
+
+#include "simplebutton.h"
+
+//---------------------------------------------------------
+// RecordButton
+//---------------------------------------------------------
+
+class RecordButton : public SimpleButton {
+ Q_OBJECT
+
+ public:
+ RecordButton(QWidget* parent = 0);
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/widgets/shortcutcapturedialog.cpp b/muse_qt4_evolution/muse/widgets/shortcutcapturedialog.cpp
new file mode 100644
index 00000000..dab3330f
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/shortcutcapturedialog.cpp
@@ -0,0 +1,97 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2003 Mathias Lundgren (lunar_shuttle@users.sourceforge.net)
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "shortcutcapturedialog.h"
+#include "shortcuts.h"
+
+//---------------------------------------------------------
+// ShortcutCaptureDialog
+//---------------------------------------------------------
+
+ShortcutCaptureDialog::ShortcutCaptureDialog(Shortcut* _s, QWidget* parent)
+ : QDialog(parent)
+ {
+ setupUi(this);
+ s = _s;
+
+ oshrtLabel->setText(s->key.toString(QKeySequence::NativeText));
+ connect(clearButton, SIGNAL(clicked()), SLOT(clearClicked()));
+ clearClicked();
+ grabKeyboard();
+ }
+
+//---------------------------------------------------------
+// ShortcutCaptureDialog
+//---------------------------------------------------------
+
+ShortcutCaptureDialog::~ShortcutCaptureDialog()
+ {
+ releaseKeyboard();
+ }
+
+//---------------------------------------------------------
+// keyPressEvent
+//---------------------------------------------------------
+
+void ShortcutCaptureDialog::keyPressEvent(QKeyEvent* e)
+ {
+ if (key.count() >= 4)
+ return;
+ int k = e->key();
+ if (k == 0 || k == Qt::Key_Shift || k == Qt::Key_Control ||
+ k == Qt::Key_Meta || k == Qt::Key_Alt || k == Qt::Key_AltGr
+ || k == Qt::Key_CapsLock || k == Qt::Key_NumLock
+ || k == Qt::Key_ScrollLock)
+ return;
+
+ k += e->modifiers();
+ switch(key.count()) {
+ case 0: key = QKeySequence(k); break;
+ case 1: key = QKeySequence(key[0], k); break;
+ case 2: key = QKeySequence(key[0], key[1], k); break;
+ case 3: key = QKeySequence(key[0], key[1], key[2], k); break;
+ }
+
+ // Check against conflicting shortcuts
+ bool conflict = false;
+ QString msgString;
+ foreach (Shortcut* ss, shortcuts) {
+ if ((s != ss) && (ss->key == key)
+ && (ss->type & (s->type | GLOBAL_SHRT | INVIS_SHRT))) {
+ msgString = tr("Shortcut conflicts with ") + ss->descr;
+ conflict = true;
+ break;
+ }
+ }
+ messageLabel->setText(msgString);
+ okButton->setEnabled(conflict == false);
+ nshrtLabel->setText(key.toString(QKeySequence::NativeText));
+ }
+
+//---------------------------------------------------------
+// clearClicked
+//---------------------------------------------------------
+
+void ShortcutCaptureDialog::clearClicked()
+ {
+ nshrtLabel->setText(tr("Undefined"));
+ key = 0;
+ }
+
diff --git a/muse_qt4_evolution/muse/widgets/shortcutcapturedialog.h b/muse_qt4_evolution/muse/widgets/shortcutcapturedialog.h
new file mode 100644
index 00000000..4c2b5b6c
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/shortcutcapturedialog.h
@@ -0,0 +1,52 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2003 Mathias Lundgren <lunar_shuttle@users.sourceforge.net>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+//
+// C++ Interface: shortcutcapturedialog
+//
+// Description:
+// Dialog window for capturing keyboard shortcuts
+//
+
+#include "shortcuts.h"
+#include "filedialog.h"
+#include "ui_shortcutcapturedialog.h"
+
+//---------------------------------------------------------
+// ShortcutCaptureDialog
+//---------------------------------------------------------
+
+class ShortcutCaptureDialog : public QDialog, public Ui::ShortcutCaptureDialogBase
+ {
+ Q_OBJECT
+ private:
+ Shortcut* s;
+ void keyPressEvent(QKeyEvent* e);
+ QKeySequence key;
+
+ private slots:
+ void clearClicked();
+
+ public:
+ ShortcutCaptureDialog(Shortcut* s = 0, QWidget* parent = 0);
+ ~ShortcutCaptureDialog();
+ QKeySequence getKey() const { return key; }
+ };
+
diff --git a/muse_qt4_evolution/muse/widgets/shortcutcapturedialog.ui b/muse_qt4_evolution/muse/widgets/shortcutcapturedialog.ui
new file mode 100644
index 00000000..0df2338f
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/shortcutcapturedialog.ui
@@ -0,0 +1,162 @@
+<ui version="4.0" >
+ <class>ShortcutCaptureDialogBase</class>
+ <widget class="QDialog" name="ShortcutCaptureDialogBase" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>461</width>
+ <height>214</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Enter shortcut sequence</string>
+ </property>
+ <property name="modal" >
+ <bool>true</bool>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="0" colspan="2" >
+ <widget class="QLabel" name="descrLabel" >
+ <property name="text" >
+ <string>Press up to 4 keys to enter shortcut sequence!</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="2" >
+ <widget class="QLabel" name="messageLabel" >
+ <property name="text" >
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="oshrtTextLabel" >
+ <property name="text" >
+ <string>Old shortcut:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" >
+ <widget class="QLineEdit" name="oshrtLabel" >
+ <property name="readOnly" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" >
+ <widget class="QLabel" name="nshrtTextLabel" >
+ <property name="text" >
+ <string>New shortcut:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1" >
+ <widget class="QLineEdit" name="nshrtLabel" >
+ <property name="readOnly" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0" colspan="2" >
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QToolButton" name="clearButton" >
+ <property name="text" >
+ <string>Clear</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="okButton" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="text" >
+ <string>OK</string>
+ </property>
+ <property name="shortcut" >
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="cancelButton" >
+ <property name="text" >
+ <string>Cancel</string>
+ </property>
+ <property name="shortcut" >
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11" />
+ <pixmapfunction>qPixmapFromMimeSource</pixmapfunction>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>okButton</sender>
+ <signal>clicked()</signal>
+ <receiver>ShortcutCaptureDialogBase</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>337</x>
+ <y>189</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>242</x>
+ <y>194</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>cancelButton</sender>
+ <signal>clicked()</signal>
+ <receiver>ShortcutCaptureDialogBase</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>425</x>
+ <y>194</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>350</x>
+ <y>153</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/muse_qt4_evolution/muse/widgets/shortcutconfig.cpp b/muse_qt4_evolution/muse/widgets/shortcutconfig.cpp
new file mode 100644
index 00000000..025f1494
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/shortcutconfig.cpp
@@ -0,0 +1,167 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2003 Mathias Lundgren (lunar_shuttle@users.sourceforge.net)
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "shortcutconfig.h"
+#include "shortcutcapturedialog.h"
+#include "shortcuts.h"
+
+//---------------------------------------------------------
+// ShortcutConfig
+//---------------------------------------------------------
+
+ShortcutConfig::ShortcutConfig(QWidget* parent)
+ : QDialog(parent)
+ {
+ setupUi(this);
+ connect(cgListView, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)),
+ this, SLOT(categorySelChanged(QTreeWidgetItem*)));
+ connect(scListView, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)),
+ this, SLOT(shortcutSelChanged(QTreeWidgetItem*)));
+ connect(defineButton, SIGNAL(pressed()), this, SLOT(assignShortcut()));
+ connect(clearButton, SIGNAL(pressed()), this, SLOT(clearShortcut()));
+ connect(applyButton, SIGNAL(pressed()), this, SLOT(assignAll()));
+ connect(scListView, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), this, SLOT(assignShortcut()));
+
+ current_category = ALL_SHRT;
+//TD cgListView->setSorting(SHRT_CATEGORY_COL, -1);
+ _config_changed = false;
+
+ //Fill up category listview:
+ for (int i=0; i < SHRT_NUM_OF_CATEGORIES; i++) {
+ QTreeWidgetItem* newItem = new QTreeWidgetItem;
+ newItem->setText(SHRT_CATEGORY_COL, tr(shortcut_category[i].name));
+ newItem->setData(0, Qt::UserRole, i);
+ cgListView->addTopLevelItem(newItem);
+ }
+ updateSCListView();
+ }
+
+//---------------------------------------------------------
+// updateSCListView
+//---------------------------------------------------------
+
+void ShortcutConfig::updateSCListView(int category)
+ {
+ scListView->clear();
+ foreach (Shortcut* s, shortcuts) {
+ if (s && (s->type & category)) {
+ QTreeWidgetItem* newItem;
+ newItem = new QTreeWidgetItem;
+ newItem->setText(SHRT_DESCR_COL, tr(s->descr));
+ QKeySequence seq = s->key;
+ newItem->setText(SHRT_SHRTCUT_COL, s->key.toString(QKeySequence::NativeText));
+ newItem->setData(0, Qt::UserRole, s->xml);
+ scListView->addTopLevelItem(newItem);
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// assignShortcut
+//---------------------------------------------------------
+
+void ShortcutConfig::assignShortcut()
+ {
+ QTreeWidgetItem* active = scListView->currentItem();
+ Shortcut* s = shortcuts[active->data(0, Qt::UserRole).toString()];
+ ShortcutCaptureDialog sc(s, this);
+ if (sc.exec()) {
+ s->key = sc.getKey();
+ active->setText(SHRT_SHRTCUT_COL, s->key.toString(QKeySequence::NativeText));
+ _config_changed = true;
+ }
+ clearButton->setEnabled(true);
+ }
+
+//---------------------------------------------------------
+// clearShortcut
+//---------------------------------------------------------
+
+void ShortcutConfig::clearShortcut()
+ {
+ QTreeWidgetItem* active = scListView->currentItem();
+ Shortcut* s = shortcuts[active->data(0, Qt::UserRole).toString()];
+ s->key = 0;
+ active->setText(SHRT_SHRTCUT_COL, "");
+ clearButton->setEnabled(false);
+ _config_changed = true;
+ }
+
+//---------------------------------------------------------
+// categorySelChanged
+//---------------------------------------------------------
+
+void ShortcutConfig::categorySelChanged(QTreeWidgetItem* i)
+ {
+ int idx = i->data(0, Qt::UserRole).toInt();
+ current_category = shortcut_category[idx].id_flag;
+ updateSCListView(current_category);
+ }
+
+//---------------------------------------------------------
+// shortcutSelChanged
+//---------------------------------------------------------
+
+void ShortcutConfig::shortcutSelChanged(QTreeWidgetItem* active)
+ {
+ defineButton->setEnabled(active != 0);
+ if (active == 0) {
+ clearButton->setEnabled(false);
+ return;
+ }
+ Shortcut* s = shortcuts[active->data(0, Qt::UserRole).toString()];
+ clearButton->setEnabled(s && !s->key.isEmpty());
+ }
+
+//---------------------------------------------------------
+// closeEvent
+//---------------------------------------------------------
+
+void ShortcutConfig::closeEvent(QCloseEvent*)
+ {
+ done(_config_changed);
+ }
+
+//---------------------------------------------------------
+// assignAll
+//---------------------------------------------------------
+
+void ShortcutConfig::assignAll()
+ {
+ foreach(QWidget* w, QApplication::allWidgets()) {
+ foreach(QAction* a, w->actions()) {
+ QVariant v(a->data());
+ if (v.type() == QVariant::String) {
+ QString name = v.toString();
+ foreach (Shortcut* s, shortcuts) {
+ if (s->xml == name) {
+ if (a->shortcut() != s->key) {
+ printf("shortcut <%s> changed\n", s->xml);
+ a->setShortcuts(QList<QKeySequence>());
+ a->setShortcut(s->key);
+ }
+ }
+ }
+ }
+ }
+ }
+ done(_config_changed);
+ }
+
diff --git a/muse_qt4_evolution/muse/widgets/shortcutconfig.h b/muse_qt4_evolution/muse/widgets/shortcutconfig.h
new file mode 100644
index 00000000..0e9e24b2
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/shortcutconfig.h
@@ -0,0 +1,50 @@
+//
+// C++ Interface: shortcutconfig
+//
+// Description:
+// Dialog for configuring keyboard shortcuts
+//
+// Author: Mathias Lundgren <lunar_shuttle@users.sourceforge.net>, (C) 2003
+//
+// Copyright: Mathias Lundgren (lunar_shuttle@users.sourceforge.net) (C) 2003
+//
+//
+#ifndef __SHORTCUTCONFIG_H
+#define __SHORTCUTCONFIG_H
+
+#include "ui_shortcutconfig.h"
+#include "shortcuts.h"
+
+#define SHRT_CATEGORY_COL 0
+enum {
+ SHRT_DESCR_COL = 0,
+ SHRT_SHRTCUT_COL
+ };
+
+//---------------------------------------------------------
+// ShortcutConfig
+//---------------------------------------------------------
+
+class ShortcutConfig : public QDialog, public Ui::ShortcutConfigBase {
+ Q_OBJECT
+ private:
+ int current_category;
+ void updateSCListView(int category);
+ void updateSCListView() { updateSCListView(current_category); }
+ void closeEvent(QCloseEvent *e);
+
+ private slots:
+ void categorySelChanged(QTreeWidgetItem*);
+ void shortcutSelChanged(QTreeWidgetItem*);
+ void assignShortcut();
+ void clearShortcut();
+ void assignAll();
+
+ public:
+ ShortcutConfig(QWidget* parent = 0);
+ bool _config_changed;
+ static const shortcut_cg shortcut_category[];
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/widgets/shortcutconfig.ui b/muse_qt4_evolution/muse/widgets/shortcutconfig.ui
new file mode 100644
index 00000000..901e2cac
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/shortcutconfig.ui
@@ -0,0 +1,180 @@
+<ui version="4.0" >
+ <class>ShortcutConfigBase</class>
+ <widget class="QDialog" name="ShortcutConfigBase" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>661</width>
+ <height>403</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Configure Keyboard Shortcuts</string>
+ </property>
+ <property name="sizeGripEnabled" >
+ <bool>true</bool>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QSplitter" name="splitter" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <widget class="QTreeWidget" name="cgListView" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>1</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize" >
+ <size>
+ <width>105</width>
+ <height>200</height>
+ </size>
+ </property>
+ <property name="indentation" >
+ <number>0</number>
+ </property>
+ <property name="rootIsDecorated" >
+ <bool>false</bool>
+ </property>
+ <property name="sortingEnabled" >
+ <bool>true</bool>
+ </property>
+ <property name="columnCount" >
+ <number>1</number>
+ </property>
+ <column>
+ <property name="text" >
+ <string>Category</string>
+ </property>
+ </column>
+ </widget>
+ <widget class="QTreeWidget" name="scListView" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>2</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize" >
+ <size>
+ <width>170</width>
+ <height>230</height>
+ </size>
+ </property>
+ <property name="alternatingRowColors" >
+ <bool>true</bool>
+ </property>
+ <property name="indentation" >
+ <number>0</number>
+ </property>
+ <property name="rootIsDecorated" >
+ <bool>false</bool>
+ </property>
+ <property name="uniformRowHeights" >
+ <bool>true</bool>
+ </property>
+ <property name="sortingEnabled" >
+ <bool>true</bool>
+ </property>
+ <property name="allColumnsShowFocus" >
+ <bool>true</bool>
+ </property>
+ <property name="columnCount" >
+ <number>2</number>
+ </property>
+ <column>
+ <property name="text" >
+ <string>Description</string>
+ </property>
+ </column>
+ <column>
+ <property name="text" >
+ <string>Shortcut</string>
+ </property>
+ </column>
+ </widget>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="clearButton" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="text" >
+ <string>&amp;Clear</string>
+ </property>
+ <property name="shortcut" >
+ <string>Alt+C</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="defineButton" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="text" >
+ <string>&amp;Define</string>
+ </property>
+ <property name="shortcut" >
+ <string>Alt+D</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>30</width>
+ <height>21</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="applyButton" >
+ <property name="text" >
+ <string>Ok</string>
+ </property>
+ <property name="shortcut" >
+ <string>Alt+A</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11" />
+ <pixmapfunction>qPixmapFromMimeSource</pixmapfunction>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/muse_qt4_evolution/muse/widgets/siglabel.cpp b/muse_qt4_evolution/muse/widgets/siglabel.cpp
new file mode 100644
index 00000000..2f8d3e84
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/siglabel.cpp
@@ -0,0 +1,165 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "siglabel.h"
+
+#define TIMER1 400
+#define TIMER2 200
+#define TIMEC 7
+#define TIMER3 100
+#define TIMEC2 20
+#define TIMER4 50
+
+#include "globals.h"
+
+//---------------------------------------------------------
+// SigLabel
+// edit Signature Values (4/4)
+//---------------------------------------------------------
+
+SigLabel::SigLabel(QWidget* parent)
+ : QLabel(parent)
+ {
+ z = n = 0;
+ setFocusPolicy(Qt::NoFocus);
+ setAlignment(Qt::AlignCenter);
+ }
+
+//---------------------------------------------------------
+// mousePressEvent
+//---------------------------------------------------------
+
+void SigLabel::mousePressEvent(QMouseEvent* event)
+ {
+ int button = event->button();
+ bool zaehler = event->x() < width() /2;
+
+ int zz = z, nn = n;
+ switch (button) {
+ case Qt::LeftButton:
+ return;
+ case Qt::MidButton:
+ incValue(zaehler, false, zz, nn);
+ break;
+ case Qt::RightButton:
+ incValue(zaehler, true, zz, nn);
+ break;
+ default:
+ break;
+ }
+ if ((zz != z) || (nn != n)) {
+ setValue(zz, nn);
+ emit valueChanged(zz, nn);
+ }
+ }
+
+//---------------------------------------------------------
+// incValue
+//---------------------------------------------------------
+
+void SigLabel::incValue(bool zaehler, bool up, int& zz, int& nn)
+ {
+ if (!up) {
+ if (zaehler) {
+ --zz;
+ if (zz < 1)
+ zz = 1;
+ }
+ else {
+ switch (nn) {
+ case 1: break;
+ case 2: nn = 1; break;
+ case 4: nn = 2; break;
+ case 8: nn = 4; break;
+ case 16: nn = 8; break;
+ case 32: nn = 16; break;
+ case 64: nn = 32; break;
+ case 128: nn = 64; break;
+ }
+ }
+ }
+ else {
+ if (zaehler) {
+ ++zz;
+ if (zz > 16)
+ zz = 16;
+ }
+ else {
+ switch (nn) {
+ case 1: nn = 2; break;
+ case 2: nn = 4; break;
+ case 4: nn = 8; break;
+ case 8: nn = 16; break;
+ case 16: nn = 32; break;
+ case 32: nn = 64; break;
+ case 64: nn = 128; break;
+ case 128: break;
+ }
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// wheelEvent
+//---------------------------------------------------------
+
+void SigLabel::wheelEvent(QWheelEvent* event)
+ {
+ bool zaehler = event->x() < width() /2;
+ int delta = event->delta();
+ int zz = z, nn = n;
+
+ bool inc = delta >= 0;
+ incValue(zaehler, inc, zz, nn);
+ if ((zz != z) || (nn != n)) {
+ setValue(zz, nn);
+ emit valueChanged(zz, nn);
+ }
+ }
+
+//---------------------------------------------------------
+// setValue
+//---------------------------------------------------------
+
+void SigLabel::setValue(int a, int b)
+ {
+ if (a == z && b == n)
+ return;
+ z = a;
+ n = b;
+ QString sa;
+ sa.setNum(a);
+
+ QString sb;
+ sb.setNum(b);
+
+ QString s = sa + QString("/") + sb;
+ setText(s);
+ }
+
+//---------------------------------------------------------
+// setFrame
+//---------------------------------------------------------
+
+void SigLabel::setFrame(bool flag)
+ {
+ setFrameStyle(flag ? Panel | Sunken : NoFrame);
+ setLineWidth(2);
+ }
diff --git a/muse_qt4_evolution/muse/widgets/siglabel.h b/muse_qt4_evolution/muse/widgets/siglabel.h
new file mode 100644
index 00000000..8ffa317e
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/siglabel.h
@@ -0,0 +1,50 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __SIGLABEL_H__
+#define __SIGLABEL_H__
+
+//---------------------------------------------------------
+// SigLabel
+// show/edit time signature
+//---------------------------------------------------------
+
+class SigLabel : public QLabel {
+ Q_OBJECT
+ virtual void mousePressEvent(QMouseEvent*);
+ virtual void wheelEvent(QWheelEvent*);
+ void incValue(bool zaehler, bool inc, int&, int&);
+
+ protected:
+ int z, n;
+
+ signals:
+ void valueChanged(int, int);
+
+ public slots:
+ virtual void setValue(int, int);
+
+ public:
+ SigLabel(QWidget* parent = 0);
+ void value(int& a, int& b) const { a = z; b = n; }
+ void setFrame(bool);
+ };
+#endif
+
diff --git a/muse_qt4_evolution/muse/widgets/simplebutton.cpp b/muse_qt4_evolution/muse/widgets/simplebutton.cpp
new file mode 100644
index 00000000..36ab7097
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/simplebutton.cpp
@@ -0,0 +1,65 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "simplebutton.h"
+#include "gui.h"
+
+//---------------------------------------------------------
+// SimpleButton
+//---------------------------------------------------------
+
+SimpleButton::SimpleButton(const QString& on, const QString& off, QWidget* parent)
+ : QToolButton(parent)
+ {
+ setAutoRaise(true);
+ QIcon icon;
+ icon.addFile(on, ICON_SIZE, QIcon::Normal, QIcon::On);
+ icon.addFile(off, ICON_SIZE, QIcon::Normal, QIcon::Off);
+ QAction* a = new QAction(this);
+ a->setIcon(icon);
+ setDefaultAction(a);
+ }
+
+//---------------------------------------------------------
+// SimpleButton
+//---------------------------------------------------------
+
+SimpleButton::SimpleButton(QPixmap* on, QPixmap* off, QWidget* parent)
+ : QToolButton(parent)
+ {
+ setAutoRaise(true);
+ QIcon icon(*off);
+ icon.addPixmap(*on, QIcon::Normal, QIcon::On);
+ QAction* a = new QAction(this);
+ a->setIcon(icon);
+ setDefaultAction(a);
+ }
+
+//---------------------------------------------------------
+// SimpleButton
+//---------------------------------------------------------
+
+SimpleButton::SimpleButton(const QString& s, QWidget* parent)
+ : QToolButton(parent)
+ {
+ setAutoRaise(false);
+ setText(s);
+ }
+
diff --git a/muse_qt4_evolution/muse/widgets/simplebutton.h b/muse_qt4_evolution/muse/widgets/simplebutton.h
new file mode 100644
index 00000000..469767ac
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/simplebutton.h
@@ -0,0 +1,41 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __SIMPLE_BUTTON_H__
+#define __SIMPLE_BUTTON_H__
+
+//---------------------------------------------------------
+// SimpleButton
+//---------------------------------------------------------
+
+class SimpleButton : public QToolButton {
+ Q_OBJECT
+
+ int _id;
+ virtual QSize minimumSizeHint() const { return QSize(0, 0); }
+
+ public:
+ SimpleButton(QPixmap* on, QPixmap* off, QWidget* parent = 0);
+ SimpleButton(const QString& on, const QString& off, QWidget* parent = 0);
+ SimpleButton(const QString& s, QWidget* parent = 0);
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/widgets/splitter.cpp b/muse_qt4_evolution/muse/widgets/splitter.cpp
new file mode 100644
index 00000000..b95750ab
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/splitter.cpp
@@ -0,0 +1,107 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "splitter.h"
+#include "utils.h"
+#include "al/xml.h"
+
+//---------------------------------------------------------
+// SplitterHandle
+//---------------------------------------------------------
+
+void SplitterHandle::paintEvent(QPaintEvent* ev)
+ {
+ QPainter p(this);
+ QRect r(ev->rect());
+ if (orientation() == Qt::Horizontal) {
+ int x = 0;
+ int y1 = r.y();
+ int y2 = y1 + r.height();
+ if (y1 == 0)
+ y1 = 1;
+ if (y2 == height())
+ y2 = height() - 2;
+ for (int i = 0; i < splitWidth; ++i) {
+ p.setPen(lineColor[i]);
+ p.drawLine(x, y1, x, y2);
+ ++x;
+ }
+ p.setPen(lineColor[0]);
+ p.drawLine(1, 0, splitWidth - 2, 0);
+ p.drawLine(1, height()-1, splitWidth - 2, height()-1);
+ }
+ else {
+ int y = 0;
+ int x1 = r.x();
+ int x2 = x1 + r.width();
+ for (int i = 0; i < splitWidth; ++i) {
+ p.setPen(lineColor[i]);
+ p.drawLine(x1, y, x2, y);
+ ++y;
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// Splitter
+//---------------------------------------------------------
+
+Splitter::Splitter(Qt::Orientation o)
+ : QSplitter(o)
+ {
+ setHandleWidth(splitWidth);
+ }
+
+//---------------------------------------------------------
+// writeStatus
+//---------------------------------------------------------
+
+void Splitter::writeStatus(const char* name, Xml& xml)
+ {
+ QList<int> sl = sizes();
+ xml.stag(name);
+ int n = sl.size();
+ for (int i = 0; i < n; ++i) {
+ int n = sl.at(i);
+ xml.tag("size", n);
+ }
+ xml.etag(name);
+ }
+
+//---------------------------------------------------------
+// readStatus
+//---------------------------------------------------------
+
+void Splitter::readStatus(QDomNode node)
+ {
+ QList<int> sl;
+ for (QDomNode n = node.firstChild(); !n.isNull(); n = n.nextSibling()) {
+ QDomElement e = n.toElement();
+ QString tag(e.tagName());
+ int i = e.text().toInt();
+ if (tag == "size") {
+ sl.push_back(i);
+ }
+ else
+ printf("Splitter::unknown tag <%s>\n", tag.toLatin1().data());
+ }
+ setSizes(sl);
+ }
+
diff --git a/muse_qt4_evolution/muse/widgets/splitter.h b/muse_qt4_evolution/muse/widgets/splitter.h
new file mode 100644
index 00000000..238031c3
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/splitter.h
@@ -0,0 +1,62 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __SPLITTER_H__
+#define __SPLITTER_H__
+
+namespace AL {
+ class Xml;
+ };
+
+using AL::Xml;
+
+//---------------------------------------------------------
+// SplitterHandle
+//---------------------------------------------------------
+
+class SplitterHandle : public QSplitterHandle {
+ Q_OBJECT
+ virtual void paintEvent(QPaintEvent*);
+
+ public:
+ SplitterHandle(Qt::Orientation o, QSplitter* parent)
+ : QSplitterHandle(o, parent) {
+ }
+ };
+
+//---------------------------------------------------------
+// Splitter
+//---------------------------------------------------------
+
+class Splitter : public QSplitter {
+ Q_OBJECT
+
+ protected:
+ virtual QSplitterHandle* createHandle() {
+ return new SplitterHandle(orientation(), this);
+ }
+ public:
+ Splitter(Qt::Orientation);
+ void writeStatus(const char* name, Xml&);
+ void readStatus(QDomNode node);
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/widgets/synthwizardbase.h b/muse_qt4_evolution/muse/widgets/synthwizardbase.h
new file mode 100644
index 00000000..590ff789
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/synthwizardbase.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+** Form interface generated from reading ui file 'synthwizardbase.ui'
+**
+** Created: Wed Nov 12 10:38:24 2003
+** by: The User Interface Compiler ($Id: synthwizardbase.h,v 1.6 2005/09/22 20:13:39 wschweer Exp $)
+**
+** WARNING! All changes made in this file will be lost!
+****************************************************************************/
+
+#ifndef SYNTHCONFIGBASE_H
+#define SYNTHCONFIGBASE_H
+
+#include <qvariant.h>
+#include <q3wizard.h>
+//Added by qt3to4:
+#include <QVBoxLayout>
+#include <QHBoxLayout>
+#include <QGridLayout>
+
+class QVBoxLayout;
+class QHBoxLayout;
+class QGridLayout;
+class QWidget;
+class Q3GroupBox;
+class Q3ListView;
+class Q3ListViewItem;
+class QPushButton;
+
+class SynthConfigBase : public Q3Wizard
+{
+ Q_OBJECT
+
+public:
+ SynthConfigBase( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, Qt::WFlags fl = 0 );
+ ~SynthConfigBase();
+
+ QWidget* WizardPage;
+ Q3GroupBox* GroupBox2;
+ Q3ListView* synthList;
+ QPushButton* addInstance;
+ Q3GroupBox* GroupBox3;
+ Q3ListView* instanceList;
+ QPushButton* removeInstance;
+ QWidget* WizardPage_2;
+
+protected:
+ QVBoxLayout* WizardPageLayout;
+ QVBoxLayout* GroupBox2Layout;
+ QHBoxLayout* Layout1;
+ QVBoxLayout* GroupBox3Layout;
+ QHBoxLayout* Layout3;
+
+protected slots:
+ virtual void languageChange();
+
+};
+
+#endif // SYNTHCONFIGBASE_H
diff --git a/muse_qt4_evolution/muse/widgets/tb1.cpp b/muse_qt4_evolution/muse/widgets/tb1.cpp
new file mode 100644
index 00000000..33400420
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/tb1.cpp
@@ -0,0 +1,180 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "tb1.h"
+#include "globals.h"
+#include "awl/poslabel.h"
+#include "awl/pitchlabel.h"
+#include "rastercombo.h"
+#include "quantcombo.h"
+
+//---------------------------------------------------------
+// genToolbar
+// solo time pitch raster quant
+//---------------------------------------------------------
+
+Toolbar1::Toolbar1(int r, int q, bool showPitch)
+ {
+ solo = new QToolButton;
+ solo->setText(tr("Solo"));
+ solo->setCheckable(true);
+ addWidget(solo);
+
+ //---------------------------------------------------
+ // Cursor Position
+ //---------------------------------------------------
+
+ QLabel* label = new QLabel;
+ label->setText(tr("Cursor"));
+ label->setIndent(3);
+ addWidget(label);
+ pos = new Awl::PosLabel;
+ pos->setFixedHeight(24);
+ addWidget(pos);
+ if (showPitch) {
+ pitch = new Awl::PitchLabel;
+ pitch->setEnabled(false);
+ pitch->setFixedHeight(24);
+ addWidget(pitch);
+ }
+ else
+ pitch = 0;
+
+ //---------------------------------------------------
+ // Raster, Quant.
+ //---------------------------------------------------
+
+ QLabel* l = new QLabel(tr("Snap"));
+ l->setIndent(5);
+ addWidget(l);
+ raster = new RasterCombo;
+ addWidget(raster);
+
+ l = new QLabel(tr("Quantize"));
+ l->setIndent(5);
+ addWidget(l);
+ quant = new QuantCombo;
+ addWidget(quant);
+
+ raster->setFixedHeight(24);
+ quant->setFixedHeight(24);
+
+ setRaster(r);
+ setQuant(q);
+
+ //---------------------------------------------------
+ // To Menu
+ //---------------------------------------------------
+
+ addWidget(new QLabel(tr("To")));
+ toList = new QComboBox;
+ toList->setFixedHeight(24);
+ addWidget(toList);
+ toList->addItem(tr("All Events"), RANGE_ALL);
+ toList->addItem(tr("Looped Ev."), RANGE_LOOPED);
+ toList->addItem(tr("Selected Ev."), RANGE_SELECTED);
+ toList->addItem(tr("Looped+Sel."), RANGE_LOOPED | RANGE_SELECTED);
+
+ connect(raster, SIGNAL(rasterChanged(int)), SIGNAL(rasterChanged(int)));
+ connect(quant, SIGNAL(quantChanged(int)), SIGNAL(quantChanged(int)));
+ connect(toList, SIGNAL(activated(int)), SIGNAL(toChanged(int)));
+ connect(solo, SIGNAL(toggled(bool)), SIGNAL(soloChanged(bool)));
+ pos->setEnabled(false);
+ }
+
+//---------------------------------------------------------
+// setApplyTo
+//---------------------------------------------------------
+
+void Toolbar1::setApplyTo(int val)
+ {
+ toList->setCurrentIndex(toList->findData(val));
+ }
+
+//---------------------------------------------------------
+// setPitch
+//---------------------------------------------------------
+
+void Toolbar1::setPitch(int val)
+ {
+ if (pitch) {
+ pitch->setEnabled(val != -1);
+ pitch->setPitch(val);
+ }
+ }
+
+//---------------------------------------------------------
+// setInt
+//---------------------------------------------------------
+
+void Toolbar1::setInt(int val)
+ {
+ if (pitch) {
+ pitch->setEnabled(val != -1);
+ pitch->setInt(val);
+ }
+ }
+
+//---------------------------------------------------------
+// setTime
+//---------------------------------------------------------
+
+void Toolbar1::setTime(const AL::Pos& val, bool enable)
+ {
+ pos->setValue(val, enable);
+ }
+
+//---------------------------------------------------------
+// setRaster
+//---------------------------------------------------------
+
+void Toolbar1::setRaster(int val)
+ {
+ raster->setRaster(val);
+ }
+
+//---------------------------------------------------------
+// setQuant
+//---------------------------------------------------------
+
+void Toolbar1::setQuant(int val)
+ {
+ quant->setQuant(val);
+ }
+
+//---------------------------------------------------------
+// setSolo
+//---------------------------------------------------------
+
+void Toolbar1::setSolo(bool flag)
+ {
+ solo->setChecked(flag);
+ }
+
+//---------------------------------------------------------
+// setPitchMode
+//---------------------------------------------------------
+
+void Toolbar1::setPitchMode(bool flag)
+ {
+ if (pitch)
+ pitch->setPitchMode(flag);
+ }
+
diff --git a/muse_qt4_evolution/muse/widgets/tb1.h b/muse_qt4_evolution/muse/widgets/tb1.h
new file mode 100644
index 00000000..e10884d2
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/tb1.h
@@ -0,0 +1,71 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __TB1_H__
+#define __TB1_H__
+
+namespace Awl {
+ class PosLabel;
+ class PitchLabel;
+ };
+namespace AL {
+ class Pos;
+ };
+
+class RasterCombo;
+class QuantCombo;
+
+enum { RANGE_ALL, RANGE_SELECTED, RANGE_LOOPED };
+
+//---------------------------------------------------------
+// Toolbar1
+//---------------------------------------------------------
+
+class Toolbar1 : public QToolBar {
+ QToolButton* solo;
+ Awl::PosLabel* pos;
+ Awl::PitchLabel* pitch;
+ QuantCombo* quant;
+ QComboBox* toList;
+ RasterCombo* raster;
+ Q_OBJECT
+
+ public slots:
+ void setTime(const AL::Pos&, bool);
+ void setPitch(int);
+ void setInt(int);
+ void setRaster(int);
+ void setQuant(int);
+
+ signals:
+ void rasterChanged(int);
+ void quantChanged(int);
+ void soloChanged(bool);
+ void toChanged(int);
+
+ public:
+ Toolbar1(int r=96, int q=96, bool showPitch=true);
+ void setSolo(bool val);
+ void setPitchMode(bool flag);
+ void setApplyTo(int);
+ };
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/widgets/tools.cpp b/muse_qt4_evolution/muse/widgets/tools.cpp
new file mode 100644
index 00000000..39d7aa4d
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/tools.cpp
@@ -0,0 +1,100 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "tools.h"
+#include "icons.h"
+#include "shortcuts.h"
+
+const char* toolList[TOOLS] = {
+ "pointer", "pencil", "eraser", "scissor", "glue",
+ "quantize", "draw", "mute_parts"
+ };
+
+//---------------------------------------------------------
+// EditToolBar
+//---------------------------------------------------------
+
+EditToolBar::EditToolBar(QMainWindow* parent, int tools)
+ : QToolBar(tr("Edit Tools"))
+ {
+ actionGroup = new QActionGroup(parent);
+ actionGroup->setExclusive(true);
+
+ bool first = true;
+ for (unsigned i = 0; i < sizeof(toolList)/sizeof(*toolList); ++i) {
+ if ((tools & (1 << i))==0)
+ continue;
+ QAction* a = getAction(toolList[i], this);
+ a->setData(1 << i);
+ a->setCheckable(true);
+ actionGroup->addAction(a);
+ addAction(a);
+ if (first) {
+ a->setChecked(true);
+ first = false;
+ }
+ }
+ connect(actionGroup, SIGNAL(triggered(QAction*)), SLOT(toolChanged(QAction*)));
+ }
+
+//---------------------------------------------------------
+// toolChanged
+//---------------------------------------------------------
+
+void EditToolBar::toolChanged(QAction* action)
+ {
+ emit toolChanged(action->data().toInt());
+ }
+
+//---------------------------------------------------------
+// set
+//---------------------------------------------------------
+
+void EditToolBar::set(int id)
+ {
+ QList<QAction*> actions = actionGroup->actions();
+ int n = actions.size();
+
+ for (int i = 0; i < n; ++i) {
+ QAction* action = actions.at(i);
+ if (action->data().toInt() == id) {
+ action->setChecked(true);
+ return;
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// curTool
+//---------------------------------------------------------
+
+int EditToolBar::curTool()
+ {
+ QList<QAction*> actions = actionGroup->actions();
+ int n = actions.size();
+
+ for (int i = 0; i < n; ++i) {
+ QAction* a = actions.at(i);
+ if (a->isChecked())
+ return a->data().toInt();
+ }
+ return -1;
+ }
+
diff --git a/muse_qt4_evolution/muse/widgets/tools.h b/muse_qt4_evolution/muse/widgets/tools.h
new file mode 100644
index 00000000..f05e1095
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/tools.h
@@ -0,0 +1,58 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __TOOLS_H__
+#define __TOOLS_H__
+
+class Action;
+
+#include "awl/tcanvas.h"
+
+const int arrangerTools = PointerTool | PencilTool | RubberTool | DrawTool
+ | CutTool | GlueTool | MuteTool;
+
+const int TOOLS = 8;
+
+//---------------------------------------------------------
+// EditToolBar
+//---------------------------------------------------------
+
+class EditToolBar : public QToolBar {
+ Q_OBJECT
+ QActionGroup* actionGroup;
+
+ private slots:
+ void toolChanged(QAction* action);
+
+ signals:
+ void toolChanged(int);
+
+ public slots:
+ void set(int id);
+
+ public:
+ EditToolBar(QMainWindow*, int);
+ int curTool();
+ };
+
+extern const char* toolList[];
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/widgets/transformbase.ui b/muse_qt4_evolution/muse/widgets/transformbase.ui
new file mode 100644
index 00000000..1365a0c9
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/transformbase.ui
@@ -0,0 +1,993 @@
+<ui version="4.0" >
+ <author></author>
+ <comment></comment>
+ <exportmacro></exportmacro>
+ <class>MidiTransformDialogBase</class>
+ <widget class="QDialog" name="MidiTransformDialogBase" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>843</width>
+ <height>659</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>MusE: Midi Transformator</string>
+ </property>
+ <property name="sizeGripEnabled" >
+ <bool>true</bool>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>11</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="3" column="0" colspan="2" >
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="buttonNew" >
+ <property name="text" >
+ <string>&amp;New</string>
+ </property>
+ <property name="autoDefault" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonDelete" >
+ <property name="text" >
+ <string>&amp;Delete</string>
+ </property>
+ <property name="autoDefault" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonApply" >
+ <property name="text" >
+ <string>&amp;Apply</string>
+ </property>
+ <property name="autoDefault" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonOk" >
+ <property name="text" >
+ <string>&amp;OK</string>
+ </property>
+ <property name="autoDefault" >
+ <bool>true</bool>
+ </property>
+ <property name="default" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonCancel" >
+ <property name="text" >
+ <string>&amp;Cancel</string>
+ </property>
+ <property name="autoDefault" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item rowspan="3" row="0" column="0" >
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="TextLabel1_2" >
+ <property name="text" >
+ <string>PresetList</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Q3ListBox" name="presetList" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>3</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="1" >
+ <widget class="Q3GroupBox" name="GroupBox5" >
+ <property name="title" >
+ <string>Processing</string>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>11</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="TextLabel5" >
+ <property name="text" >
+ <string>Event Type</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QComboBox" name="procEventOp" >
+ <item>
+ <property name="text" >
+ <string>Keep</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Fix</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="2" column="0" >
+ <widget class="QComboBox" name="procType" >
+ <item>
+ <property name="text" >
+ <string>Note</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Poly Pressure</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Control Change</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Aftertouch</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Pitch Bend</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>NRPN</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>RPN</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QComboBox" name="procVal1Op" >
+ <item>
+ <property name="text" >
+ <string>Keep</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Plus</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Minus</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Multiply</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Divide</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Fix</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Value 2</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Invert</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>ScaleMap</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Flip</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Dyn</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Random</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QLabel" name="TextLabel6" >
+ <property name="text" >
+ <string>Value 1</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2" >
+ <widget class="QLabel" name="TextLabel7" >
+ <property name="text" >
+ <string>Value 2</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3" >
+ <widget class="QLabel" name="TextLabel10_2" >
+ <property name="text" >
+ <string>Length</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="4" >
+ <widget class="QLabel" name="TextLabel12" >
+ <property name="text" >
+ <string>Position</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2" >
+ <widget class="QComboBox" name="procVal2Op" >
+ <item>
+ <property name="text" >
+ <string>Keep</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Plus</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Minus</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Multiply</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Divide</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Fix</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Value 1</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Invert</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Dyn</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Random</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="1" column="3" >
+ <widget class="QComboBox" name="procLenOp" >
+ <item>
+ <property name="text" >
+ <string>Keep</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Plus</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Minus</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Multiply</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Divide</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Fix</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="3" column="1" >
+ <widget class="QSpinBox" name="procVal1b" >
+ <property name="maximum" >
+ <number>9999</number>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="2" >
+ <widget class="QSpinBox" name="procVal2b" >
+ <property name="maximum" >
+ <number>9999</number>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" >
+ <widget class="QDoubleSpinBox" name="procVal1a" />
+ </item>
+ <item row="1" column="4" >
+ <widget class="QComboBox" name="procPosOp" >
+ <item>
+ <property name="text" >
+ <string>Keep</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Plus</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Minus</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Multiply</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Divide</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="2" column="2" >
+ <widget class="QDoubleSpinBox" name="procVal2a" />
+ </item>
+ <item row="2" column="3" >
+ <widget class="QDoubleSpinBox" name="procLenA" />
+ </item>
+ <item row="2" column="4" >
+ <widget class="QDoubleSpinBox" name="procPosA" />
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="Q3GroupBox" name="GroupBox3" >
+ <property name="title" >
+ <string>Filter</string>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>11</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="1" column="0" >
+ <widget class="QComboBox" name="selEventOp" >
+ <item>
+ <property name="text" >
+ <string>All</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Equal</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Unequal</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="2" column="0" >
+ <widget class="QComboBox" name="selType" >
+ <item>
+ <property name="text" >
+ <string>Note</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Control Change</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Sysex</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Poly Pressure</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Aftertouch</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Meta</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="0" column="2" >
+ <widget class="QLabel" name="TextLabel3" >
+ <property name="text" >
+ <string>Value 2</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QLabel" name="TextLabel2" >
+ <property name="text" >
+ <string>Value 1</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="TextLabel1" >
+ <property name="text" >
+ <string>Event Type</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QComboBox" name="selVal1Op" >
+ <item>
+ <property name="text" >
+ <string>Ignore</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Equal</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Unequal</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Higher</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Lower</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Inside</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Outside</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="0" column="3" >
+ <widget class="QLabel" name="TextLabel10" >
+ <property name="text" >
+ <string>Length</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="4" >
+ <widget class="QLabel" name="TextLabel11" >
+ <property name="text" >
+ <string>Bar Range</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2" >
+ <widget class="QComboBox" name="selVal2Op" >
+ <item>
+ <property name="text" >
+ <string>Ignore</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Equal</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Unequal</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Higher</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Lower</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Inside</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Outside</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="1" column="3" >
+ <widget class="QComboBox" name="selLenOp" >
+ <item>
+ <property name="text" >
+ <string>Ignore</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Equal</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Unequal</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Higher</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Lower</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Inside</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Outside</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="1" column="4" >
+ <widget class="QComboBox" name="selRangeOp" >
+ <item>
+ <property name="text" >
+ <string>Ignore</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Equal</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Unequal</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Higher</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Lower</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Inside</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Outside</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="3" column="1" >
+ <widget class="QSpinBox" name="selVal1b" >
+ <property name="maximum" >
+ <number>127</number>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="3" >
+ <widget class="QSpinBox" name="selLenA" >
+ <property name="maximum" >
+ <number>127</number>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="3" >
+ <widget class="QSpinBox" name="selLenB" >
+ <property name="maximum" >
+ <number>127</number>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2" >
+ <widget class="QSpinBox" name="selVal2a" >
+ <property name="maximum" >
+ <number>127</number>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="2" >
+ <widget class="QSpinBox" name="selVal2b" >
+ <property name="maximum" >
+ <number>127</number>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" >
+ <widget class="QSpinBox" name="selVal1a" >
+ <property name="maximum" >
+ <number>127</number>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="4" >
+ <widget class="QDoubleSpinBox" name="selBarB" />
+ </item>
+ <item row="2" column="4" >
+ <widget class="QDoubleSpinBox" name="selBarA" />
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="2" column="1" >
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="Q3GroupBox" name="GroupBox6_2" >
+ <property name="title" >
+ <string>Preset</string>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>11</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="TextLabel13_2" >
+ <property name="text" >
+ <string>Name:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="nameEntry" />
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QLabel" name="TextLabel14_2" >
+ <property name="text" >
+ <string>Comment:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Q3MultiLineEdit" name="commentEntry" />
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="Q3GroupBox" name="GroupBox5_2" >
+ <property name="title" >
+ <string>Range</string>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>11</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QCheckBox" name="processAll" >
+ <property name="text" >
+ <string>process all events</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="selectedTracks" >
+ <property name="text" >
+ <string>selected tracks</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="insideLoop" >
+ <property name="text" >
+ <string>inside loop</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="Q3GroupBox" name="GroupBox7_2" >
+ <property name="title" >
+ <string>Function</string>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>11</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QComboBox" name="funcOp" >
+ <item>
+ <property name="text" >
+ <string>Select</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Quantize</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Delete</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Transform</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Insert</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Copy</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Extract</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="TextLabel9_2" >
+ <property name="text" >
+ <string>Quantize Value</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="ComboQuant" name="funcQuantVal" />
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11" />
+ <pixmapfunction></pixmapfunction>
+ <customwidgets>
+ <customwidget>
+ <class>Q3GroupBox</class>
+ <extends></extends>
+ <header>Qt3Support/Q3GroupBox</header>
+ <container>1</container>
+ <pixmap></pixmap>
+ </customwidget>
+ <customwidget>
+ <class>Q3MultiLineEdit</class>
+ <extends>QWidget</extends>
+ <header>q3multilineedit.h</header>
+ <container>1</container>
+ <pixmap></pixmap>
+ </customwidget>
+ <customwidget>
+ <class>ComboQuant</class>
+ <extends></extends>
+ <header>comboQuant.h</header>
+ <container>0</container>
+ <pixmap></pixmap>
+ </customwidget>
+ <customwidget>
+ <class>Q3ListBox</class>
+ <extends></extends>
+ <header>q3listbox.h</header>
+ <container>0</container>
+ <pixmap></pixmap>
+ </customwidget>
+ </customwidgets>
+ <tabstops>
+ <tabstop>selEventOp</tabstop>
+ <tabstop>selType</tabstop>
+ <tabstop>selVal1Op</tabstop>
+ <tabstop>selVal1a</tabstop>
+ <tabstop>selVal1b</tabstop>
+ <tabstop>selVal2Op</tabstop>
+ <tabstop>selVal2a</tabstop>
+ <tabstop>selVal2b</tabstop>
+ <tabstop>selLenOp</tabstop>
+ <tabstop>selLenA</tabstop>
+ <tabstop>selLenB</tabstop>
+ <tabstop>selRangeOp</tabstop>
+ <tabstop>procEventOp</tabstop>
+ <tabstop>procType</tabstop>
+ <tabstop>procVal1Op</tabstop>
+ <tabstop>procVal1b</tabstop>
+ <tabstop>procVal2Op</tabstop>
+ <tabstop>procVal2b</tabstop>
+ <tabstop>procLenOp</tabstop>
+ <tabstop>procPosOp</tabstop>
+ <tabstop>nameEntry</tabstop>
+ <tabstop>commentEntry</tabstop>
+ <tabstop>processAll</tabstop>
+ <tabstop>selectedTracks</tabstop>
+ <tabstop>insideLoop</tabstop>
+ <tabstop>funcOp</tabstop>
+ <tabstop>presetList</tabstop>
+ <tabstop>buttonNew</tabstop>
+ <tabstop>buttonDelete</tabstop>
+ <tabstop>buttonApply</tabstop>
+ <tabstop>buttonOk</tabstop>
+ <tabstop>buttonCancel</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/muse_qt4_evolution/muse/widgets/utils.cpp b/muse_qt4_evolution/muse/widgets/utils.cpp
new file mode 100644
index 00000000..b7fd9cee
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/utils.cpp
@@ -0,0 +1,451 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include <sys/time.h>
+#include "utils.h"
+#include "icons.h"
+#include "gconfig.h"
+#include "greendotbutton.h"
+#include "recordbutton.h"
+
+static const int BFONT = 4; // simple button font
+
+//---------------------------------------------------------
+// RecordButton
+//---------------------------------------------------------
+
+RecordButton::RecordButton(QWidget* parent)
+ : SimpleButton(":/xpm/recordOn.svg", ":/xpm/recordOff.svg", parent)
+ {
+ setCheckable(true);
+ setToolTip(tr("record"));
+ }
+
+//---------------------------------------------------------
+// GreendotButton
+//---------------------------------------------------------
+
+GreendotButton::GreendotButton(QWidget* parent)
+ : SimpleButton(":/xpm/greendot.svg", ":/xpm/darkgreendot.svg", parent)
+ {
+ setCheckable(true);
+ setToolTip(tr("record"));
+ }
+
+//---------------------------------------------------------
+// curTime
+//---------------------------------------------------------
+
+double curTime()
+ {
+ struct timeval t;
+ gettimeofday(&t, 0);
+ return (double)((double)t.tv_sec + (t.tv_usec / 1000000.0));
+ }
+
+//---------------------------------------------------------
+// dump
+// simple debug output
+//---------------------------------------------------------
+
+void dump(const unsigned char* p, int n)
+ {
+ printf("dump %d\n", n);
+ for (int i = 0; i < n; ++i) {
+ printf("%02x ", *p++);
+ if ((i > 0) && (i % 16 == 0) && (i+1 < n))
+ printf("\n");
+ }
+ printf("\n");
+ }
+
+//---------------------------------------------------------
+// num2cols
+//---------------------------------------------------------
+
+int num2cols(int min, int max)
+ {
+ int amin = abs(min);
+ int amax = abs(max);
+ int l = amin > amax ? amin : amax;
+ return int(log10(l)) + 1;
+ }
+
+//---------------------------------------------------------
+// hLine
+//---------------------------------------------------------
+
+QFrame* hLine(QWidget* w)
+ {
+ QFrame* delim = new QFrame(w);
+ delim->setFrameStyle(QFrame::HLine | QFrame::Sunken);
+ return delim;
+ }
+
+//---------------------------------------------------------
+// vLine
+//---------------------------------------------------------
+
+QFrame* vLine(QWidget* w)
+ {
+ QFrame* delim = new QFrame(w);
+ delim->setFrameStyle(QFrame::VLine | QFrame::Sunken);
+ return delim;
+ }
+
+//---------------------------------------------------------
+// bitmap2String
+// 5c -> 1-4 1-6
+//
+// 01011100
+//
+//---------------------------------------------------------
+
+QString bitmap2String(int bm)
+ {
+ QString s;
+//printf("bitmap2string: bm %04x", bm);
+ if (bm == 0xffff)
+ s = "all";
+ else if (bm == 0)
+ s = "none";
+ else {
+ bool range = false;
+ int first = 0;
+ bool needSpace = false;
+ bm &= 0xffff;
+ for (int i = 0; i < 17; ++i) {
+ if ((1 << i) & bm) {
+ if (!range) {
+ range = true;
+ first = i;
+ }
+ }
+ else {
+ if (range) {
+ if (needSpace)
+ s += " ";
+ QString ns;
+ if (first == i-1)
+ ns.sprintf("%d", first+1);
+ else
+ ns.sprintf("%d-%d", first+1, i);
+ s += ns;
+ needSpace = true;
+ }
+ range = false;
+ }
+ }
+ }
+//printf(" -> <%s>\n", s.toLatin1().data());
+ return s;
+ }
+
+//---------------------------------------------------------
+// string2bitmap
+//---------------------------------------------------------
+
+int string2bitmap(const QString& str)
+ {
+ int val = 0;
+ QString ss(str.simplified());
+ const char* s = ss.toLatin1().data();
+//printf("string2bitmap <%s>\n", s);
+
+ if (s == 0)
+ return 0;
+ if (strcmp(s, "all") == 0)
+ return 0xffff;
+ if (strcmp(s, "none") == 0)
+ return 0;
+// printf("str2bitmap: <%s> ", str.toLatin1().data());
+ int tval = 0;
+ bool range = false;
+ int sval = 0;
+ while (*s == ' ')
+ ++s;
+ while (*s) {
+ if (*s >= '0' && *s <= '9') {
+ tval *= 10;
+ tval += *s - '0';
+ }
+ else if (*s == ' ' || *s == ',') {
+ if (range) {
+ for (int i = sval-1; i < tval; ++i)
+ val |= (1 << i);
+ range = false;
+ }
+ else {
+ val |= (1 << (tval-1));
+ }
+ tval = 0;
+ }
+ else if (*s == '-') {
+ range = true;
+ sval = tval;
+ tval = 0;
+ }
+ ++s;
+ }
+ if (range && tval) {
+ for (int i = sval-1; i < tval; ++i)
+ val |= (1 << i);
+ }
+ else if (tval) {
+ val |= (1 << (tval-1));
+ }
+ return val & 0xffff;
+ }
+
+//---------------------------------------------------------
+// muteButton
+//---------------------------------------------------------
+
+SimpleButton* newMuteButton()
+ {
+ // SimpleButton* mute = new SimpleButton(parent, muteIconOff, muteIconOn);
+ SimpleButton* mute = new SimpleButton(QT_TR_NOOP("m"));
+ mute->setCheckable(true);
+ mute->setToolTip(QT_TR_NOOP("mute"));
+ mute->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
+ return mute;
+ }
+
+//---------------------------------------------------------
+// soloButton
+//---------------------------------------------------------
+
+SimpleButton* newSoloButton()
+ {
+// SimpleButton* solo = new SimpleButton(parent, soloIconOn, soloIconOff);
+ SimpleButton* solo = new SimpleButton(QT_TR_NOOP("s"));
+ solo->setCheckable(true);
+ solo->setToolTip(QT_TR_NOOP("solo"));
+ solo->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
+ return solo;
+ }
+
+//---------------------------------------------------------
+// monitorButton
+//---------------------------------------------------------
+
+SimpleButton* newMonitorButton()
+ {
+ SimpleButton* monitor = new SimpleButton(QT_TR_NOOP("Mo"));
+ monitor->setCheckable(true);
+ monitor->setToolTip(QT_TR_NOOP("monitor"));
+ monitor->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
+ return monitor;
+ }
+
+//---------------------------------------------------------
+// drumMapButton
+//---------------------------------------------------------
+
+SimpleButton* newDrumMapButton()
+ {
+ SimpleButton* dm = new SimpleButton(QT_TR_NOOP("Dr"));
+ dm->setCheckable(true);
+ dm->setToolTip(QT_TR_NOOP("use drum map"));
+ return dm;
+ }
+
+//---------------------------------------------------------
+// newOffButton
+//---------------------------------------------------------
+
+SimpleButton* newOffButton()
+ {
+ SimpleButton* off = new SimpleButton(":/xpm/off.svg", ":/xpm/on.svg");
+ off->setCheckable(true);
+ off->setToolTip(QT_TR_NOOP("off"));
+ return off;
+ }
+
+//---------------------------------------------------------
+// newRecordButton
+//---------------------------------------------------------
+
+SimpleButton* newRecordButton()
+ {
+ SimpleButton* record = new RecordButton();
+ record->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
+ return record;
+ }
+
+//---------------------------------------------------------
+// newAutoReadButton
+//---------------------------------------------------------
+
+SimpleButton* newAutoReadButton()
+ {
+ SimpleButton* ar = new SimpleButton(QT_TR_NOOP("aR"));
+ ar->setCheckable(true);
+ ar->setToolTip(QT_TR_NOOP("automation read"));
+ return ar;
+ }
+
+//---------------------------------------------------------
+// newAutoWriteButton
+//---------------------------------------------------------
+
+SimpleButton* newAutoWriteButton()
+ {
+ SimpleButton* aw = new SimpleButton(QT_TR_NOOP("aW"));
+ aw->setCheckable(true);
+ aw->setToolTip(QT_TR_NOOP("automation write"));
+ return aw;
+ }
+
+//---------------------------------------------------------
+// syncButton
+//---------------------------------------------------------
+
+SimpleButton* newSyncButton()
+ {
+ SimpleButton* sync = new SimpleButton(QT_TR_NOOP("sync"));
+ sync->setCheckable(true);
+ sync->setToolTip(QT_TR_NOOP("send sync events"));
+ return sync;
+ }
+
+//---------------------------------------------------------
+// newMinusButton
+//---------------------------------------------------------
+
+SimpleButton* newMinusButton()
+ {
+ return new SimpleButton(minusIcon, minusIcon);
+ }
+
+//---------------------------------------------------------
+// newPlusButton
+//---------------------------------------------------------
+
+SimpleButton* newPlusButton()
+ {
+ SimpleButton* sync = new SimpleButton(plusIcon, plusIcon);
+ return sync;
+ }
+
+//---------------------------------------------------------
+// newStereoButton
+//---------------------------------------------------------
+
+SimpleButton* newStereoButton()
+ {
+ SimpleButton* stereo = new SimpleButton(":/xpm/stereo.svg", ":/xpm/mono.svg");
+ stereo->setCheckable(true);
+ stereo->setToolTip(QT_TR_NOOP("1/2 channel"));
+ return stereo;
+ }
+
+//---------------------------------------------------------
+// newOutRouteButton
+//---------------------------------------------------------
+
+QToolButton* newOutRouteButton()
+ {
+ QToolButton* oR = new QToolButton;
+ oR->setObjectName("routeButton");
+ oR->setFixedHeight(BUTTON_HEIGHT);
+ oR->setText(QT_TR_NOOP("oR"));
+ oR->setCheckable(false);
+ oR->setToolTip(QT_TR_NOOP("output routing"));
+ oR->setMenu(new QMenu);
+ oR->setPopupMode(QToolButton::InstantPopup);
+ oR->menu()->setSeparatorsCollapsible(false);
+ oR->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+ return oR;
+ }
+
+//---------------------------------------------------------
+// newInRouteButton
+//---------------------------------------------------------
+
+QToolButton* newInRouteButton()
+ {
+ QToolButton* iR = new QToolButton;
+ iR->setObjectName("routeButton");
+ iR->setFixedHeight(BUTTON_HEIGHT);
+ iR->setText(QT_TR_NOOP("iR"));
+ iR->setCheckable(false);
+ iR->setToolTip(QT_TR_NOOP("input routing"));
+ iR->setMenu(new QMenu);
+ iR->setPopupMode(QToolButton::InstantPopup);
+ iR->menu()->setSeparatorsCollapsible(false);
+ iR->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+ return iR;
+ }
+
+//---------------------------------------------------------
+// fatalError
+//---------------------------------------------------------
+
+void fatalError(const char* s)
+ {
+ fprintf(stderr, "%s\n", s);
+ exit(-1);
+ }
+
+//---------------------------------------------------------
+// lineColor
+//---------------------------------------------------------
+
+QColor lineColor[splitWidth] = {
+ QColor(0x55, 0x55, 0x52),
+ QColor(0xc6, 0xc6, 0xbf),
+ QColor(0xee, 0xee, 0xe6),
+ QColor(0xff, 0xff, 0xfc),
+ QColor(0xff, 0xff, 0xff),
+ QColor(0x55, 0x55, 0x52),
+ };
+
+//---------------------------------------------------------
+// paintHLine
+//---------------------------------------------------------
+
+void paintHLine(QPainter& p, int x1, int x2, int y)
+ {
+ for (int i = 0; i < splitWidth; ++i) {
+ p.setPen(lineColor[i]);
+ p.drawLine(x1, y, x2, y);
+ ++y;
+ }
+ }
+
+//---------------------------------------------------------
+// paintVLine
+//---------------------------------------------------------
+
+void paintVLine(QPainter& p, int y1, int y2, int x)
+ {
+ static QColor color[splitWidth] = {
+ QColor(0x55, 0x55, 0x52),
+ QColor(0xff, 0xff, 0xff),
+ };
+ x -= 2;
+ for (int i = 0; i < 2; ++i) {
+ p.setPen(color[i]);
+ p.drawLine(x, y1, x, y2);
+ ++x;
+ }
+ }
+
diff --git a/muse_qt4_evolution/muse/widgets/utils.h b/muse_qt4_evolution/muse/widgets/utils.h
new file mode 100644
index 00000000..360dd28e
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/utils.h
@@ -0,0 +1,58 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#ifndef __UTILS_H__
+#define __UTILS_H__
+
+#include "gui.h"
+
+class SimpleButton;
+
+extern QString bitmap2String(int bm);
+extern int string2bitmap(const QString& str);
+
+extern int num2cols(int min, int max);
+extern QFrame* hLine(QWidget* parent);
+extern QFrame* vLine(QWidget* parent);
+extern void dump(const unsigned char* p, int n);
+extern double curTime();
+extern SimpleButton* newMuteButton();
+extern SimpleButton* newSoloButton();
+extern SimpleButton* newMonitorButton();
+extern SimpleButton* newDrumMapButton();
+extern SimpleButton* newOffButton();
+extern SimpleButton* newRecordButton();
+extern SimpleButton* newAutoWriteButton();
+extern SimpleButton* newAutoReadButton();
+extern SimpleButton* newSyncButton();
+extern SimpleButton* newPlusButton();
+extern SimpleButton* newMinusButton();
+extern SimpleButton* newStereoButton();
+QToolButton* newOutRouteButton();
+QToolButton* newInRouteButton();
+
+extern void fatalError(const char*);
+
+extern QColor lineColor[splitWidth];
+extern void paintHLine(QPainter& p, int x1, int x2, int y);
+extern void paintVLine(QPainter& p, int y1, int y2, int x);
+
+#endif
+
diff --git a/muse_qt4_evolution/muse/widgets/wtrackinfobase.ui b/muse_qt4_evolution/muse/widgets/wtrackinfobase.ui
new file mode 100644
index 00000000..da341c74
--- /dev/null
+++ b/muse_qt4_evolution/muse/widgets/wtrackinfobase.ui
@@ -0,0 +1,166 @@
+<ui version="4.0" >
+ <author></author>
+ <comment></comment>
+ <exportmacro></exportmacro>
+ <class>WaveTrackInfoBase</class>
+ <widget class="QWidget" name="WaveTrackInfoBase" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>129</width>
+ <height>548</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>3</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>32767</width>
+ <height>32767</height>
+ </size>
+ </property>
+ <property name="windowTitle" >
+ <string>MusE: TrackInfo</string>
+ </property>
+ <property name="toolTip" >
+ <string/>
+ </property>
+ <property name="whatsThis" >
+ <string/>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>1</number>
+ </property>
+ <property name="spacing" >
+ <number>1</number>
+ </property>
+ <item row="0" column="0" colspan="2" >
+ <widget class="QLabel" name="TextLabel1" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape" >
+ <enum>QFrame::WinPanel</enum>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Raised</enum>
+ </property>
+ <property name="lineWidth" >
+ <number>1</number>
+ </property>
+ <property name="midLineWidth" >
+ <number>0</number>
+ </property>
+ <property name="text" >
+ <string>Track Info</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="2" >
+ <widget class="QLineEdit" name="iName" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Track Name</string>
+ </property>
+ <property name="whatsThis" >
+ <string>Track Name</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>30</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="2" column="0" >
+ <widget class="QSpinBox" name="delay" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Track Delay (ticks)</string>
+ </property>
+ <property name="specialValueText" >
+ <string>off</string>
+ </property>
+ <property name="maximum" >
+ <number>1000</number>
+ </property>
+ <property name="minimum" >
+ <number>-1000</number>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" >
+ <widget class="QLabel" name="TextLabel10" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Delay (Frames)</string>
+ </property>
+ <property name="text" >
+ <string>Delay</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11" />
+ <pixmapfunction>qPixmapFromMimeSource</pixmapfunction>
+ <tabstops>
+ <tabstop>iName</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/muse_qt4_evolution/muse/xpm/activeoff.svg b/muse_qt4_evolution/muse/xpm/activeoff.svg
new file mode 100644
index 00000000..8449f988
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/activeoff.svg
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="20"
+ height="10"
+ id="svg1307"
+ sodipodi:version="0.32"
+ inkscape:version="0.44"
+ sodipodi:docbase="/home/ws/projects/muse/muse/trunk/muse/muse/xpm"
+ sodipodi:docname="activeoff.svg"
+ version="1.0">
+ <defs
+ id="defs1309">
+ <linearGradient
+ id="linearGradient1319">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop1321" />
+ <stop
+ style="stop-color:#1a561c;stop-opacity:1;"
+ offset="1"
+ id="stop1323" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1370">
+ <stop
+ style="stop-color:#ff271f;stop-opacity:1;"
+ offset="0"
+ id="stop1372" />
+ <stop
+ style="stop-color:#ff0000;stop-opacity:0;"
+ offset="1"
+ id="stop1374" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1370"
+ id="linearGradient1376"
+ x1="-5.6423869"
+ y1="-5.6206923"
+ x2="8.5200005"
+ y2="8.4349537"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1370"
+ id="linearGradient1315"
+ gradientUnits="userSpaceOnUse"
+ x1="-1.8582375"
+ y1="-0.071628742"
+ x2="3.8178029"
+ y2="2.5516095" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1319"
+ id="radialGradient1325"
+ cx="18.5282"
+ cy="0.093760476"
+ fx="18.5282"
+ fy="0.093760476"
+ r="7.8356543"
+ gradientTransform="matrix(-0.515305,-0.68232,0.563264,-0.418808,19.85983,21.47543)"
+ gradientUnits="userSpaceOnUse" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="39.396621"
+ inkscape:cx="11.149585"
+ inkscape:cy="3.4613455"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ inkscape:grid-bbox="true"
+ inkscape:document-units="px"
+ inkscape:window-width="1680"
+ inkscape:window-height="996"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ width="20px"
+ height="10px" />
+ <metadata
+ id="metadata1312">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer">
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#radialGradient1325);fill-opacity:1;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ id="path1317"
+ sodipodi:cx="7.3610373"
+ sodipodi:cy="7.3317437"
+ sodipodi:rx="7.3356543"
+ sodipodi:ry="7.2721972"
+ d="M 14.696692 7.3317437 A 7.3356543 7.2721972 0 1 1 0.025382996,7.3317437 A 7.3356543 7.2721972 0 1 1 14.696692 7.3317437 z"
+ transform="matrix(1.301701,0,0,0.625509,0.41813,0.413925)" />
+ </g>
+</svg>
diff --git a/muse_qt4_evolution/muse/xpm/activeon.svg b/muse_qt4_evolution/muse/xpm/activeon.svg
new file mode 100644
index 00000000..c6426e54
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/activeon.svg
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="20"
+ height="11"
+ id="svg1307"
+ sodipodi:version="0.32"
+ inkscape:version="0.44"
+ sodipodi:docbase="/home/ws/projects/muse/muse/trunk/muse/muse/xpm"
+ sodipodi:docname="activeon.svg"
+ version="1.0">
+ <defs
+ id="defs1309">
+ <linearGradient
+ id="linearGradient1319">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop1321" />
+ <stop
+ style="stop-color:#11ff00;stop-opacity:1;"
+ offset="1"
+ id="stop1323" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1370">
+ <stop
+ style="stop-color:#ff271f;stop-opacity:1;"
+ offset="0"
+ id="stop1372" />
+ <stop
+ style="stop-color:#ff0000;stop-opacity:0;"
+ offset="1"
+ id="stop1374" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1370"
+ id="linearGradient1376"
+ x1="-5.6423869"
+ y1="-5.6206923"
+ x2="8.5200005"
+ y2="8.4349537"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1370"
+ id="linearGradient1315"
+ gradientUnits="userSpaceOnUse"
+ x1="-1.8582375"
+ y1="-0.071628742"
+ x2="3.8178029"
+ y2="2.5516095" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1319"
+ id="radialGradient1325"
+ cx="18.5282"
+ cy="0.093760476"
+ fx="18.5282"
+ fy="0.093760476"
+ r="7.8356543"
+ gradientTransform="matrix(-0.515305,-0.68232,0.563264,-0.418808,19.85983,21.47543)"
+ gradientUnits="userSpaceOnUse" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="39.396621"
+ inkscape:cx="14.970261"
+ inkscape:cy="4.476661"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ inkscape:grid-bbox="true"
+ inkscape:document-units="px"
+ inkscape:window-width="1680"
+ inkscape:window-height="996"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ width="20px"
+ height="11px" />
+ <metadata
+ id="metadata1312">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer">
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#radialGradient1325);fill-opacity:1;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ id="path1317"
+ sodipodi:cx="7.3610373"
+ sodipodi:cy="7.3317437"
+ sodipodi:rx="7.3356543"
+ sodipodi:ry="7.2721972"
+ d="M 14.696692 7.3317437 A 7.3356543 7.2721972 0 1 1 0.025382996,7.3317437 A 7.3356543 7.2721972 0 1 1 14.696692 7.3317437 z"
+ transform="matrix(1.29863,0,0,0.691167,0.440736,0.432544)" />
+ </g>
+</svg>
diff --git a/muse_qt4_evolution/muse/xpm/addtrack_addmiditrack.xpm b/muse_qt4_evolution/muse/xpm/addtrack_addmiditrack.xpm
new file mode 100644
index 00000000..cfeb255b
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/addtrack_addmiditrack.xpm
@@ -0,0 +1,26 @@
+/* XPM */
+static const char *addtrack_addmiditrack_xpm[]={
+"16 16 7 1",
+"a c #000000",
+"e c #404000",
+". c #800000",
+"c c #808080",
+"b c #c00000",
+"d c #dcdcdc",
+"# c #ffffff",
+".......##aa###..",
+".bbbbb###aaa#bb.",
+".b#######aaaa#b.",
+".b#######a#aa#b.",
+".bc#c#c#dad#a#b.",
+".eeeeeeedadeeee.",
+".bc#c#c#dad#c#b.",
+".bc#c#c#dad#c#b.",
+".bc#c#d#dad#c#b.",
+".bc#c#aaaad#c#b.",
+".eeedaaaaadeeee.",
+".bc#caaaaa##c#b.",
+".b####aaa#####b.",
+".b############b.",
+".bbbbbbbbbbbbbb.",
+"................"};
diff --git a/muse_qt4_evolution/muse/xpm/addtrack_audiogroup.xpm b/muse_qt4_evolution/muse/xpm/addtrack_audiogroup.xpm
new file mode 100644
index 00000000..52a0b082
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/addtrack_audiogroup.xpm
@@ -0,0 +1,35 @@
+/* XPM */
+static const char * addtrack_audiogroup_xpm[] = {
+"16 16 16 1",
+" c None",
+". c #800000",
+"+ c #C20000",
+"@ c #FFFFFF",
+"# c #363736",
+"$ c #000100",
+"% c #616161",
+"& c #DBDDDA",
+"* c #828282",
+"= c #313231",
+"- c #222322",
+"; c #545454",
+"> c #4E4F4E",
+", c #323332",
+"' c #454645",
+") c #2E2F2E",
+"................",
+".++@@##$$$#@@++.",
+".+@@#%@@@@#$&@+.",
+".@@##@@@@@@##@@.",
+"&&@$@@&@&@@@$@&&",
+"@@***@@&@&@***@@",
+"@*%$%@&&&@@%$$*@",
+"*=-$*@@&&@@;$$$%",
+">$#$#@&@&@@,$#$#",
+"'$#$#@@&@@@#$#$#",
+"*)$$%@@@&@@%$$$*",
+"@*%$%@&&&@@*$$*@",
+".@***@&&@&@***@.",
+".+@@@@@@&&@@@@+.",
+".++++++++++++++.",
+"................"};
diff --git a/muse_qt4_evolution/muse/xpm/addtrack_audioinput.xpm b/muse_qt4_evolution/muse/xpm/addtrack_audioinput.xpm
new file mode 100644
index 00000000..1f5cfd9a
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/addtrack_audioinput.xpm
@@ -0,0 +1,33 @@
+/* XPM */
+static const char * addtrack_audioinput_xpm[] = {
+"16 16 14 1",
+" c None",
+". c #800000",
+"+ c #DBDDDA",
+"@ c #555652",
+"# c #FEFFFC",
+"$ c #8D8E88",
+"% c #9FA19E",
+"& c #FCFCF5",
+"* c #C2C4C0",
+"= c #C20000",
+"- c #313230",
+"; c #BEBFBA",
+"> c #000100",
+", c #565856",
+".+@##....###@+#.",
+".#$%+#####+%$##.",
+".+#@%@&##*%@+#=.",
+".####++##+####=.",
+".######-######=.",
+"###+$$+-#+$%+##.",
+"#+#$;##-##%$%##.",
+"##$;+##-###+$%#.",
+".#@###>>>######.",
+".#####>>>#+####.",
+".=####>>>##+##+#",
+".=##+#>>>#######",
+".=#+###,###+#,,,",
+".=###+#,####,,##",
+".==####,,##,,#=.",
+"......##,,,,#..."};
diff --git a/muse_qt4_evolution/muse/xpm/addtrack_audiooutput.xpm b/muse_qt4_evolution/muse/xpm/addtrack_audiooutput.xpm
new file mode 100644
index 00000000..9b3780c6
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/addtrack_audiooutput.xpm
@@ -0,0 +1,44 @@
+/* XPM */
+static const char * addtrack_audiooutput_xpm[] = {
+"16 16 25 1",
+" c None",
+". c #800000",
+"+ c #FEFFFC",
+"@ c #C20000",
+"# c #DBDDDA",
+"$ c #656664",
+"% c #FDF7F6",
+"& c #545654",
+"* c #626361",
+"= c #767775",
+"- c #000100",
+"; c #7B7C7A",
+"> c #7C7D7A",
+", c #838481",
+"' c #D8D9D7",
+") c #CFD0CE",
+"! c #D6D8D5",
+"~ c #FBFCF9",
+"{ c #C0C1BE",
+"] c #E7E8E5",
+"^ c #F3F4F1",
+"/ c #B7B8B6",
+"( c #F8FEFF",
+"_ c #B4B5B3",
+": c #B3B0AF",
+"................",
+".+@@@@@@@@@@@@@.",
+"##+$$$$$$$$$$#@.",
+"$$$$++#++++#$$+.",
+"$++++++++++%#$#.",
+"++++++&*&++%=$+.",
+"##+&*&---;>,=++.",
+".++'''---)!=~+#.",
+".@++##{{'##=#++.",
+".@#+%+#+]-;=+++.",
+".@++++%^---+++@.",
+".@++++^---/++(@.",
+".@++++*--_%++%@.",
+".@+++&-:_++++(@.",
+".@@@#-#%++@@@@@.",
+"....+#+........."};
diff --git a/muse_qt4_evolution/muse/xpm/addtrack_auxsend.xpm b/muse_qt4_evolution/muse/xpm/addtrack_auxsend.xpm
new file mode 100644
index 00000000..d3528418
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/addtrack_auxsend.xpm
@@ -0,0 +1,28 @@
+/* XPM */
+static const char * addtrack_auxsend_xpm[] = {
+"16 16 9 1",
+" c None",
+". c #FFFFFF",
+"+ c #F4F4F4",
+"@ c #9FA19E",
+"# c #797D7C",
+"$ c #DEDFDE",
+"% c #000000",
+"& c #C9CAC8",
+"* c #F1F1F1",
+".+@..........@+.",
+"+#$.+@....@..$#+",
+"#%$+#$....$#.$%#",
+"%&.#%$....$%#.&%",
+"%$+%........%.$%",
+"%$#%.$@..@$.%#$%",
+"%$%$.#$..$#.$%$%",
+"%$%$.#.%%.#.$%$%",
+"%$%$.#$%%$#.$%$%",
+"%$%$.#$.%$#.$%$%",
+"%$#%.$@.%@$.%#$%",
+"%$+%....%...%.$%",
+"%&.#%$..%.$%#.&%",
+"#%$+#$..%.$#.$##",
+"+#$.*@..%.@..$%+",
+"..@.....%....@+."};
diff --git a/muse_qt4_evolution/muse/xpm/addtrack_drumtrack.xpm b/muse_qt4_evolution/muse/xpm/addtrack_drumtrack.xpm
new file mode 100644
index 00000000..a2841740
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/addtrack_drumtrack.xpm
@@ -0,0 +1,41 @@
+/* XPM */
+static const char * addtrack_drumtrack_xpm[] = {
+"16 16 22 1",
+" c None",
+". c #800000",
+"+ c #000100",
+"@ c #C20000",
+"# c #9FA19E",
+"$ c #F8FEFF",
+"% c #A29FA3",
+"& c #FDF7F6",
+"* c #FEFFFC",
+"= c #2F312E",
+"- c #797D7C",
+"; c #FBF5F4",
+"> c #C2C4C0",
+", c #DBDDDA",
+"' c #ACA5B1",
+") c #DDE2E5",
+"! c #D3D8DA",
+"~ c #7F817E",
+"{ c #E0CEC3",
+"] c #F0F5F8",
+"^ c #DEE0DD",
+"/ c #CED7DF",
+"...........+....",
+".@@@@@@@@@++#@@.",
+".@$$$$$$$++%%$+.",
+".@&&&&&&++##*++.",
+".@*****++%%$++#.",
+".$*==+++==*++#%.",
+"&*+-&++;;+++%#@.",
+"*=>&,*--+++##$@.",
+"&==->>>-++=%&$@.",
+"&='=====++=%**$*",
+"&=%))&)),%+++++*",
+".=%-;);!%++>#>~+",
+".&=){]^,~=+->>++",
+".@/======%++++++",
+".@@&'%%%%%+%~~+*",
+"........**&+++**"};
diff --git a/muse_qt4_evolution/muse/xpm/addtrack_wavetrack.xpm b/muse_qt4_evolution/muse/xpm/addtrack_wavetrack.xpm
new file mode 100644
index 00000000..c67befb9
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/addtrack_wavetrack.xpm
@@ -0,0 +1,36 @@
+/* XPM */
+static const char * addtrack_wavetrack_xpm[] = {
+"16 16 17 1",
+" c None",
+". c #800000",
+"+ c #FEFFFC",
+"@ c #FDF7F6",
+"# c #A29FA3",
+"$ c #9FA19E",
+"% c #C20000",
+"& c #F9FBF8",
+"* c #C2C4C0",
+"= c #BAC5C6",
+"- c #7F817E",
+"; c #FFFFFF",
+"> c #F8FEFF",
+", c #000100",
+"' c #797D7C",
+") c #DBDDDA",
+"! c #DDE2E5",
+".........+++@#$#",
+".%%%%%%%+++@+++#",
+".%++&&&&++*=#-++",
+".;>>>++,>@@@@$@+",
+">>+@@+,,+=**@$++",
+"+,,+,,,,++@#@-@+",
+"+,,+,,+,**+#+'-@",
+"+,,+,++,+#@-+@'@",
+"+,,+,++,+$+'@+'@",
+"+,,+,,+,**@$@--@",
+"+,,+,,,,@@+#+#@+",
+"++++)),,+***+*++",
+".+)+@!),+@@@+*@+",
+".%+@+@)!;+**#'@$",
+".%%%%%%%;+@@+@+#",
+".........@@+++$$"};
diff --git a/muse_qt4_evolution/muse/xpm/audio_bounce_to_file.xpm b/muse_qt4_evolution/muse/xpm/audio_bounce_to_file.xpm
new file mode 100644
index 00000000..ee645fdc
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/audio_bounce_to_file.xpm
@@ -0,0 +1,24 @@
+/* XPM */
+static const char * audio_bounce_to_file_xpm[] = {
+"16 16 5 1",
+" c None",
+". c #000000",
+"+ c #C3C3C3",
+"@ c #DCDCDC",
+"# c #A0A0A0",
+" ... ",
+" ..+.. ",
+" ..+@@.. ",
+" ..+@#@@.. ",
+" ..+@###@@.. ",
+" ..+@####+@+.. ",
+"..@@###+@+@.... ",
+".+@###+@++.##...",
+"..+##@@++.####..",
+" ..++@++.###### ",
+" ..+++..##### ",
+" ..+.##.### ",
+" ....##.# ",
+" ....## ",
+" ... ",
+" . "};
diff --git a/muse_qt4_evolution/muse/xpm/audio_bounce_to_track.xpm b/muse_qt4_evolution/muse/xpm/audio_bounce_to_track.xpm
new file mode 100644
index 00000000..3708b6bf
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/audio_bounce_to_track.xpm
@@ -0,0 +1,27 @@
+/* XPM */
+static const char * audio_bounce_to_track_xpm[] = {
+"16 16 8 1",
+" c None",
+". c #CECECE",
+"+ c #FB0000",
+"@ c #8A5C04",
+"# c #9E772E",
+"$ c #000000",
+"% c #AE8E51",
+"& c #2B2B2B",
+" .++ ",
+" .++ ",
+" ...++ ",
+" .++++++ ",
+" ..++++ . ",
+" ..++ . ",
+" .... ",
+" ",
+" ",
+" @# @# @# @# ",
+"$$$$$$$$$$$$$$$$",
+"@#. @%..@#..@#. ",
+"#. @%..@#..@#. @",
+". ##. @#. @#. @#",
+"$$$$$$$&$$$$$$$$",
+" @#. @#. @#. @# "};
diff --git a/muse_qt4_evolution/muse/xpm/audio_restartaudio.xpm b/muse_qt4_evolution/muse/xpm/audio_restartaudio.xpm
new file mode 100644
index 00000000..f74a3050
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/audio_restartaudio.xpm
@@ -0,0 +1,69 @@
+/* XPM */
+static const char * audio_restartaudio_xpm[] = {
+"16 16 50 1",
+" c None",
+". c #F5A630",
+"+ c #F8B657",
+"@ c #A98F5C",
+"# c #F2B64F",
+"$ c #BBBBBB",
+"% c #323232",
+"& c #0A0A0A",
+"* c #D2D2D2",
+"= c #292929",
+"- c #101010",
+"; c #191916",
+"> c #B6B1AF",
+", c #5C5C5C",
+"' c #1C1C1D",
+") c #C4C4C5",
+"! c #B0B0B0",
+"~ c #DADADA",
+"{ c #C9C9C9",
+"] c #808080",
+"^ c #5A5A5A",
+"/ c #3A3A3B",
+"( c #929292",
+"_ c #A4A4A4",
+": c #949494",
+"< c #39393B",
+"[ c #1F1E22",
+"} c #5A5A59",
+"| c #3E3E3D",
+"1 c #353537",
+"2 c #18171B",
+"3 c #060606",
+"4 c #363636",
+"5 c #393939",
+"6 c #272727",
+"7 c #29292B",
+"8 c #141417",
+"9 c #0B0B0B",
+"0 c #1C1C1C",
+"a c #252527",
+"b c #2E2D2F",
+"c c #262628",
+"d c #1D1D1E",
+"e c #19191B",
+"f c #0A0A0B",
+"g c #111114",
+"h c #0F0F13",
+"i c #0F0E11",
+"j c #0E0E10",
+"k c #0D0D0F",
+" .. + ",
+" ++...+++ ",
+" ++.++ ",
+" ++++@+#++ ",
+" $%&&+ ++ ",
+" * = -;>++ ",
+" * ,'' ) + ",
+" * ! ''&!+ ",
+"* ~ {]^/'& ",
+" (_: <[&& ",
+"= }|123& ",
+"=45 6789( ",
+"!&0abcdef9! ",
+" !&ghijk&! ",
+" !&&&&&! ",
+" !&& ! "};
diff --git a/muse_qt4_evolution/muse/xpm/back.xpm b/muse_qt4_evolution/muse/xpm/back.xpm
new file mode 100644
index 00000000..917213c0
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/back.xpm
@@ -0,0 +1,27 @@
+/* XPM */
+/* Drawn by Mark Donohoe for the K Desktop Environment */
+/* See http://www.kde.org */
+static const char*back_xpm[]={
+"16 16 5 1",
+"# c #000000",
+"a c #ffffff",
+"c c #808080",
+"b c #c0c0c0",
+". c None",
+"................",
+".......#........",
+"......##........",
+".....#a#........",
+"....#aa########.",
+"...#aabaaaaaaa#.",
+"..#aabbbbbbbbb#.",
+"...#abbbbbbbbb#.",
+"...c#ab########.",
+"....c#a#ccccccc.",
+".....c##c.......",
+"......c#c.......",
+".......cc.......",
+"........c.......",
+"................",
+"......................"};
+
diff --git a/muse_qt4_evolution/muse/xpm/bold.xpm b/muse_qt4_evolution/muse/xpm/bold.xpm
new file mode 100644
index 00000000..b5d786ac
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/bold.xpm
@@ -0,0 +1,16 @@
+/* XPM */
+static const char * bold_xpm[] = {
+"11 11 2 1",
+" g None",
+". g #000000",
+" ",
+" ....... ",
+" .. ... ",
+" .. .. ",
+" .. .. ",
+" ..... ",
+" .. ... ",
+" .. .. ",
+" .. ... ",
+" ....... ",
+" "};
diff --git a/muse_qt4_evolution/muse/xpm/buttondown.xpm b/muse_qt4_evolution/muse/xpm/buttondown.xpm
new file mode 100644
index 00000000..a8cff668
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/buttondown.xpm
@@ -0,0 +1,27 @@
+/* XPM */
+static const char * buttondown_xpm[] = {
+"16 18 6 1",
+" c None",
+". c #F0F0F0",
+"+ c #000000",
+"@ c #F8FCF8",
+"# c #484C48",
+"$ c #D8DCD8",
+"...............+",
+".@@@@@@@@@@@@@#+",
+".@$$$$$$$$$$$$#+",
+".@$$$$$$$$$$$$#+",
+".@$$$$$$$$$$$$#+",
+".@$$$$$$$$$$$$#+",
+".@$$$$$$$$$$$$#+",
+".@$$+++++++$$$#+",
+".@$$$+++++$$$$#+",
+".@$$$$+++$$$$$#+",
+".@$$$$$+$$$$$$#+",
+".@$$$$$$$$$$$$#+",
+".@$$$$$$$$$$$$#+",
+".@$$$$$$$$$$$$#+",
+".@$$$$$$$$$$$$#+",
+".@$$$$$$$$$$$$#+",
+".##############+",
+"++++++++++++++++"};
diff --git a/muse_qt4_evolution/muse/xpm/cafter.xpm b/muse_qt4_evolution/muse/xpm/cafter.xpm
new file mode 100644
index 00000000..3ab12692
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/cafter.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static const char *cafter_xpm[] = {
+"22 22 2 1",
+". c None",
+"# c #000000",
+"######################",
+"##...................#",
+"#.#..................#",
+"#..#.................#",
+"#...#................#",
+"#....#...............#",
+"#.....#..............#",
+"#......#.............#",
+"#.......#............#",
+"#........#...........#",
+"#.........#..........#",
+"#..........#.........#",
+"#...........#........#",
+"#............#.......#",
+"#.............#......#",
+"#..............#.....#",
+"#...............#....#",
+"#................#...#",
+"#.................#..#",
+"#..................#.#",
+"#...................##",
+"######################"
+};
+
diff --git a/muse_qt4_evolution/muse/xpm/cliplistS.xpm b/muse_qt4_evolution/muse/xpm/cliplistS.xpm
new file mode 100644
index 00000000..6ba516fc
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/cliplistS.xpm
@@ -0,0 +1,28 @@
+/* XPM */
+static const char *cliplistS_xpm[]={
+"16 16 9 1",
+"# c #000000",
+"f c #585858",
+"e c #808080",
+"d c #a0a0a0",
+"c c #c000c0",
+"g c #c3c3c3",
+"a c #dcdcdc",
+". c #ff00ff",
+"b c #ffffff",
+"................",
+"..############..",
+"..#aaaaaaaaaa#..",
+"..#abbbbbbbba#c.",
+"..#bbdeeeedbb#c.",
+"..#bdbbbbbbdb#c.",
+"..#bbbdffdbbb#c.",
+"..#bbbbbbbbbb#c.",
+"..#b#gggggg#b#c.",
+"..#bb######gb#c.",
+"..#bbb####gbb#c.",
+"..#bbbb##gbbb#c.",
+"..#bbbbggbbbb#c.",
+"..############c.",
+"....ccccccccccc.",
+"................"};
diff --git a/muse_qt4_evolution/muse/xpm/cmark.xpm b/muse_qt4_evolution/muse/xpm/cmark.xpm
new file mode 100644
index 00000000..5c8cf1fc
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/cmark.xpm
@@ -0,0 +1,23 @@
+/* XPM */
+static const char* cmark_xpm[]={
+"18 18 2 1",
+"# c #ff0000",
+". c None",
+"..................",
+"..................",
+"..................",
+"..................",
+"..................",
+"..................",
+"..................",
+"##################",
+".################.",
+"..##############..",
+"...############...",
+"....##########....",
+".....########.....",
+"......######......",
+".......####.......",
+"........##........",
+"........##........",
+"........##........"};
diff --git a/muse_qt4_evolution/muse/xpm/config.xpm b/muse_qt4_evolution/muse/xpm/config.xpm
new file mode 100644
index 00000000..727c4095
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/config.xpm
@@ -0,0 +1,36 @@
+/* XPM */
+static const char * config_xpm[] = {
+"16 16 17 1",
+" c None",
+". c #000000",
+"+ c #808080",
+"@ c #646464",
+"# c #DCDCDC",
+"$ c #C3C3C3",
+"% c #A0A0A0",
+"& c #B8B8B8",
+"* c #787878",
+"= c #FFFFFF",
+"- c #EDEDED",
+"; c #585858",
+"> c #C2C2C2",
+", c #B7B7B7",
+"' c #E7E7E7",
+") c #303030",
+"! c #CFCFCF",
+" ...... ",
+" .+@#$%.. ",
+" .&*@#$%. ",
+"... ..&@#$. ",
+".=$.. .@##%. ",
+".=-#$.;@>##,. ",
+".@=-######'$%.. ",
+")=@*=--##'$!$%%.",
+".$#=@@@*%$-#!$,%",
+" ..$#$$$*@*=-#!$",
+" ...%#$$%@*=-#",
+" ....-#%@*=",
+" ..-#%@",
+" ..-#",
+" ..",
+" "};
diff --git a/muse_qt4_evolution/muse/xpm/configure.xpm b/muse_qt4_evolution/muse/xpm/configure.xpm
new file mode 100644
index 00000000..5bcb079f
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/configure.xpm
@@ -0,0 +1,36 @@
+/* XPM */
+static const char * configure_xpm[] = {
+"16 16 17 1",
+" c None",
+". c #000000",
+"+ c #808080",
+"@ c #646464",
+"# c #DCDCDC",
+"$ c #C3C3C3",
+"% c #A0A0A0",
+"& c #B8B8B8",
+"* c #787878",
+"= c #FFFFFF",
+"- c #EDEDED",
+"; c #585858",
+"> c #C2C2C2",
+", c #B7B7B7",
+"' c #E7E7E7",
+") c #303030",
+"! c #CFCFCF",
+" ...... ",
+" .+@#$%.. ",
+" .&*@#$%. ",
+"... ..&@#$. ",
+".=$.. .@##%. ",
+".=-#$.;@>##,. ",
+".@=-######'$%.. ",
+")=@*=--##'$!$%%.",
+".$#=@@@*%$-#!$,%",
+" ..$#$$$*@*=-#!$",
+" ...%#$$%@*=-#",
+" ....-#%@*=",
+" ..-#%@",
+" ..-#",
+" ..",
+" "};
diff --git a/muse_qt4_evolution/muse/xpm/ctrl.xpm b/muse_qt4_evolution/muse/xpm/ctrl.xpm
new file mode 100644
index 00000000..01124b02
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/ctrl.xpm
@@ -0,0 +1,27 @@
+/* XPM */
+static const char * ctrl_xpm[] = {
+"22 22 2 1",
+" c #FFFFFFFFFFFF",
+". c #000000000000",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ... . .. ",
+" .. .. . ",
+" . . . . ",
+" . ..... .. . ",
+" . . .. . ",
+" . . . . ",
+" . . . . . ",
+" .. .. . . . ",
+" .... ..... ... ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" "};
diff --git a/muse_qt4_evolution/muse/xpm/cut.xpm b/muse_qt4_evolution/muse/xpm/cut.xpm
new file mode 100644
index 00000000..b104bd1c
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/cut.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static const char*cut_xpm[]={
+"18 18 7 1",
+"# c #a0a0a4",
+"a c #585858",
+"b c #303030",
+"d c #dcdcdc",
+"e c #ffffff",
+"c c #c0c0c0",
+". c None",
+"..................",
+"..................",
+"..#aba#...........",
+"..bccca#.....ab#..",
+"..accccb...#abaa#.",
+"..#aacaa..#aba#...",
+"...#bab#.#ab#.....",
+".....#aaaba#......",
+"aaaaaaaada#aaaaaa.",
+".....#baaaaeeeeed.",
+"...#aaa#.#dd#.....",
+"..#abcba..daba#...",
+"..accccb..e#abab#.",
+"..bccca#.....aa#..",
+"..#aba#...........",
+"..................",
+"..................",
+".................."};
+
diff --git a/muse_qt4_evolution/muse/xpm/darkgreendot.svg b/muse_qt4_evolution/muse/xpm/darkgreendot.svg
new file mode 100644
index 00000000..b673f1ae
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/darkgreendot.svg
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16px"
+ height="16px"
+ id="svg1307"
+ sodipodi:version="0.32"
+ inkscape:version="0.43"
+ sodipodi:docbase="/home/ws/projects/muse/muse/trunk/muse/muse/xpm"
+ sodipodi:docname="darkgreendot.svg">
+ <defs
+ id="defs1309">
+ <linearGradient
+ id="linearGradient1319">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop1321" />
+ <stop
+ style="stop-color:#1a561c;stop-opacity:1;"
+ offset="1"
+ id="stop1323" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1370">
+ <stop
+ style="stop-color:#ff271f;stop-opacity:1;"
+ offset="0"
+ id="stop1372" />
+ <stop
+ style="stop-color:#ff0000;stop-opacity:0;"
+ offset="1"
+ id="stop1374" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1370"
+ id="linearGradient1376"
+ x1="-5.6423869"
+ y1="-5.6206923"
+ x2="8.5200005"
+ y2="8.4349537"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1370"
+ id="linearGradient1315"
+ gradientUnits="userSpaceOnUse"
+ x1="-1.8582375"
+ y1="-0.071628742"
+ x2="3.8178029"
+ y2="2.5516095" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1319"
+ id="radialGradient1325"
+ cx="18.5282"
+ cy="0.093760476"
+ fx="18.5282"
+ fy="0.093760476"
+ r="7.8356543"
+ gradientTransform="matrix(-0.515305,-0.68232,0.563264,-0.418808,19.85983,21.47543)"
+ gradientUnits="userSpaceOnUse" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="39.396621"
+ inkscape:cx="8"
+ inkscape:cy="9.5532385"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ inkscape:grid-bbox="true"
+ inkscape:document-units="px"
+ inkscape:window-width="1913"
+ inkscape:window-height="1135"
+ inkscape:window-x="0"
+ inkscape:window-y="0" />
+ <metadata
+ id="metadata1312">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer">
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#radialGradient1325);fill-opacity:1.0;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ id="path1317"
+ sodipodi:cx="7.3610373"
+ sodipodi:cy="7.3317437"
+ sodipodi:rx="7.3356543"
+ sodipodi:ry="7.2721972"
+ d="M 14.696692 7.3317437 A 7.3356543 7.2721972 0 1 1 0.025382996,7.3317437 A 7.3356543 7.2721972 0 1 1 14.696692 7.3317437 z"
+ transform="matrix(1.020974,0,0,1.028955,0.484572,0.453358)" />
+ </g>
+</svg>
diff --git a/muse_qt4_evolution/muse/xpm/delete.xpm b/muse_qt4_evolution/muse/xpm/delete.xpm
new file mode 100644
index 00000000..7c337199
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/delete.xpm
@@ -0,0 +1,27 @@
+/* XPM */
+static const char* delete_xpm[]={
+"18 18 5 1",
+"# c #000000",
+"a c #ffffff",
+"b c #a0a0a4",
+"c c #dcdcdc",
+". c None",
+"..................",
+"..................",
+"..................",
+"..................",
+"........########..",
+".......#aaaaaa##b.",
+"......#aaaaaa#c#b.",
+".....#aaaaaa#cc#b.",
+"....#aaaaaa#cc#bb.",
+"...#aaaaaa#cc#bb..",
+"..#aaaaaa#cc#bb...",
+".########cc#bb....",
+".#cccccc#c#bb.....",
+".#cccccc##bb......",
+".########bb.......",
+"..bbbbbbbb........",
+"..................",
+".................."};
+
diff --git a/muse_qt4_evolution/muse/xpm/down.xpm b/muse_qt4_evolution/muse/xpm/down.xpm
new file mode 100644
index 00000000..9ac9f1f9
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/down.xpm
@@ -0,0 +1,15 @@
+/* XPM */
+static const char* down_xpm[]={
+"14 10 2 1",
+"# c #000000",
+". c None",
+"..............",
+"......##......",
+"......##......",
+"......##......",
+"......##......",
+"...##.##.##...",
+"....######....",
+".....####.....",
+"......##......",
+".............."};
diff --git a/muse_qt4_evolution/muse/xpm/draw.xpm b/muse_qt4_evolution/muse/xpm/draw.xpm
new file mode 100644
index 00000000..5bb771a3
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/draw.xpm
@@ -0,0 +1,25 @@
+/* XPM */
+static const char *draw_xpm[]={
+"18 18 4 1",
+". c None",
+"# c #000040",
+"b c #c3c3c3",
+"a c #ffffff",
+"..................",
+"..........###.....",
+"..........#a#.....",
+".........####.....",
+"........#b..#.....",
+".......#b....#....",
+"......#b.....#....",
+".....#bb......#...",
+"....#bb.......###.",
+".###bb........#a#.",
+".#a#b.........###.",
+".###b.............",
+"..................",
+"..................",
+"..................",
+"..................",
+"..................",
+".................."};
diff --git a/muse_qt4_evolution/muse/xpm/edit_drumms.xpm b/muse_qt4_evolution/muse/xpm/edit_drumms.xpm
new file mode 100644
index 00000000..8738f267
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/edit_drumms.xpm
@@ -0,0 +1,45 @@
+/* XPM */
+static const char * edit_drumms_xpm[] = {
+"16 16 26 1",
+" c None",
+". c #13A913",
+"+ c #000100",
+"@ c #0AD700",
+"# c #496447",
+"$ c #FEFFFC",
+"% c #F8FEFF",
+"& c #A29FA3",
+"* c #9FA19E",
+"= c #FDF7F6",
+"- c #2F312E",
+"; c #797D7C",
+"> c #FBF5F4",
+", c #C2C4C0",
+"' c #DBDDDA",
+") c #F9FBF8",
+"! c #ACA5B1",
+"~ c #DDE2E5",
+"{ c #D3D8DA",
+"] c #7F817E",
+"^ c #E0CEC3",
+"/ c #F0F5F8",
+"( c #DEE0DD",
+"_ c #CED7DF",
+": c #078002",
+"< c #00C100",
+"...........+....",
+".@@@@@@@@@++#@@.",
+".@$$$$$$%++&*%+.",
+".@======++**%++.",
+".@%$%$%++&&$++*.",
+".@$--+++--$++**.",
+".@+;=++>>+++&&@.",
+".-,='$;;+++**)@.",
+".--;,,,;++-&%$@.",
+".-!-----++-&%=@.",
+".-&~~=~~'&+++++.",
+".-&;>~>{&++,&,]+",
+".@-~^/(']-+],,++",
+".@_------&++++++",
+".@@@::::::+*]]+.",
+"...........+++<."};
diff --git a/muse_qt4_evolution/muse/xpm/edit_list.xpm b/muse_qt4_evolution/muse/xpm/edit_list.xpm
new file mode 100644
index 00000000..19b62b41
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/edit_list.xpm
@@ -0,0 +1,31 @@
+/* XPM */
+static const char * edit_list_xpm[] = {
+"16 16 12 1",
+" c None",
+". c #13A913",
+"+ c #0AD700",
+"@ c #000100",
+"# c #DBDDDA",
+"$ c #FDF7F6",
+"% c #D3D8DA",
+"& c #078002",
+"* c #F9FBF8",
+"= c #F8FEFF",
+"- c #DDE2E5",
+"; c #DEE0DD",
+"................",
+".+@@@@@@@@@@@@+.",
+".+@##########@+.",
+".+@$@$@$@$@$%@&.",
+".+@*=@=@=@=@#@&.",
+".+@$$*$*$*$$%@&.",
+".+@=@-@-@-@;#@&.",
+".+@**@#@-@#@%@&.",
+".+@$*$*$*$$$#@&.",
+".+@=@-@#@-@#-@&.",
+".+@**@#@#@-@#@&.",
+".+@$$*$*$$$$%@&.",
+".+@=$=$==*=$#@&.",
+".+@@@@@@@@@@@@&.",
+".+++&&&&&&&&&&&.",
+"................"};
diff --git a/muse_qt4_evolution/muse/xpm/edit_mastertrack.xpm b/muse_qt4_evolution/muse/xpm/edit_mastertrack.xpm
new file mode 100644
index 00000000..e4f1a948
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/edit_mastertrack.xpm
@@ -0,0 +1,38 @@
+/* XPM */
+static const char * edit_mastertrack_xpm[] = {
+"16 16 19 1",
+" c None",
+". c #13A913",
+"+ c #000100",
+"@ c #0AD700",
+"# c #F9FBF8",
+"$ c #F8FEFF",
+"% c #FEFFFC",
+"& c #FDF7F6",
+"* c #ED9E9D",
+"= c #EA8B8B",
+"- c #5B6062",
+"; c #D78080",
+"> c #EC9594",
+", c #DA8A8A",
+"' c #797D7C",
+") c #747573",
+"! c #FF9797",
+"~ c #1C1D1C",
+"{ c #C2C4C0",
+"................",
+"++@@@@@@@@@@@@@.",
+".++##$%#%$%%&%@.",
+".@++&&&&&&&&$&@.",
+".@&++$**%$$%$%@.",
+".@%%++%=*%%%$&@.",
+".@%%%+-;;==++++.",
+".@%%%%>,;;;+'++.",
+".@%&&%%*=;;++++.",
+".@%$%$%)*=!++++.",
+".@%%&%$%%~$++++.",
+".@%%%%%%%%%{{{{.",
+".@%%%%%%%%&&&&@.",
+".@%%%%%%%%%%%%@.",
+".@@@@@@@@@@@@@@.",
+"................"};
diff --git a/muse_qt4_evolution/muse/xpm/edit_midi.xpm b/muse_qt4_evolution/muse/xpm/edit_midi.xpm
new file mode 100644
index 00000000..3c7071c0
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/edit_midi.xpm
@@ -0,0 +1,26 @@
+/* XPM */
+static const char * edit_midi_xpm[] = {
+"16 16 7 1",
+" c None",
+". c #57A8FE",
+"+ c #A6DDFD",
+"@ c #000100",
+"# c #FDF7F6",
+"$ c #2F312E",
+"% c #FEFFFC",
+"................",
+".++++@@@@@@++++.",
+".+##@$$$$$$@##+.",
+".+%@$######$@#+.",
+".+@$#%%$$%#%$@+.",
+".@$#%%#$$%%%#$@.",
+".@$%$$###%$$#$@.",
+".@$#$$%%%#$$#$@.",
+".@$###%%%####$@.",
+".@$%$$%%%%$$#$@.",
+".@$#$$#%%#$$#$@.",
+".+@$##%%%###$@+.",
+".+#@$%%%%%%$@#+.",
+".+%%@$$$$$$@%#+.",
+".++++@@@@@@++++.",
+"................"};
diff --git a/muse_qt4_evolution/muse/xpm/edit_pianoroll.xpm b/muse_qt4_evolution/muse/xpm/edit_pianoroll.xpm
new file mode 100644
index 00000000..c2672271
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/edit_pianoroll.xpm
@@ -0,0 +1,28 @@
+/* XPM */
+static const char * edit_pianoroll_xpm[] = {
+"16 16 9 1",
+" c None",
+". c #13A913",
+"+ c #0AD700",
+"@ c #000100",
+"# c #F8FEFF",
+"$ c #FDF7F6",
+"% c #FEFFFC",
+"& c #DBDDDA",
+"* c #006B00",
+"................",
+".++++++++++++++.",
+".+@@@@@@@@@###+.",
+".+@@@@@@@@@$$$+.",
+".+%&&&&&&&&&%#+.",
+".+@@@@@@@@@$%$+.",
+".+@@@@@@@@@%%%+.",
+".+%&&&&&&&&&#$+.",
+".+@@@@@@@@@%##+.",
+".+@@@@@@@@@%%$+.",
+".+%&&&&&&&&&%%+.",
+".+%$$$$$$$$$#$+.",
+".+@@@@@@@@@%#%+.",
+".+@@@@@@@@@%#$+.",
+".++*********+++.",
+"................"};
diff --git a/muse_qt4_evolution/muse/xpm/edit_track_add.xpm b/muse_qt4_evolution/muse/xpm/edit_track_add.xpm
new file mode 100644
index 00000000..6f659f7f
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/edit_track_add.xpm
@@ -0,0 +1,24 @@
+/* XPM */
+static const char *edit_track_add_xpm[]={
+"16 16 5 1",
+"c c #404000",
+". c #800000",
+"b c #808080",
+"# c #c00000",
+"a c #ffffff",
+"................",
+".##############.",
+".#aaaaaaaaaaaa#.",
+".#aaaaaaaaaaaa#.",
+".#babababababa#.",
+".cccccccccccccc.",
+".#babababababa#.",
+".#babababababa#.",
+".#babababababa#.",
+".#babababababa#.",
+".cccccccccccccc.",
+".#babababababa#.",
+".#aaaaaaaaaaaa#.",
+".#aaaaaaaaaaaa#.",
+".##############.",
+"................"};
diff --git a/muse_qt4_evolution/muse/xpm/edit_track_del.xpm b/muse_qt4_evolution/muse/xpm/edit_track_del.xpm
new file mode 100644
index 00000000..4ead97ff
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/edit_track_del.xpm
@@ -0,0 +1,25 @@
+/* XPM */
+static const char * edit_track_del_xpm[] = {
+"16 16 6 1",
+" c None",
+". c #800000",
+"+ c #C00000",
+"@ c #FFFFFF",
+"# c #808080",
+"$ c #404000",
+"................",
+".++++++++++++++.",
+".+++@@@@@@@@@@+.",
+".++++@@@@@@@@@+.",
+".+#+++#@#@#@#@+.",
+".$$$+++$$$$$$$$.",
+".+#@#+++#@#@#@+.",
+".+#@#@+++@#@#@+.",
+".+#@#@#+++#@#@+.",
+".+#@#@#@+++@#@+.",
+".$$$$$$$$+++$$$.",
+".+#@#@#@#@+++@+.",
+".+@@@@@@@@@++++.",
+".+@@@@@@@@@@+++.",
+".++++++++++++++.",
+"................"};
diff --git a/muse_qt4_evolution/muse/xpm/editcopy.xpm b/muse_qt4_evolution/muse/xpm/editcopy.xpm
new file mode 100644
index 00000000..7823c06b
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/editcopy.xpm
@@ -0,0 +1,102 @@
+/* XPM */
+static const char * editcopy_xpm[] = {
+"22 22 77 1",
+" c None",
+". c #121212",
+"+ c #FFFFFF",
+"@ c #313131",
+"# c #898989",
+"$ c #3C3B3C",
+"% c #C9C9C9",
+"& c #828282",
+"* c #C6C6C6",
+"= c #474646",
+"- c #5C5B5B",
+"; c #FEFCFB",
+"> c #A4A4A4",
+", c #747474",
+"' c #FDFBF9",
+") c #FCF7F3",
+"! c #FAF4EE",
+"~ c #F0EAE6",
+"{ c #C1BAB3",
+"] c #C3C3C3",
+"^ c #5A5552",
+"/ c #7E7873",
+"( c #9F958D",
+"_ c #7D746E",
+": c #D8D0C8",
+"< c #FCF8F5",
+"[ c #FBF5F0",
+"} c #F9F1EA",
+"| c #F8EEE5",
+"1 c #F7EADF",
+"2 c #F5E7DA",
+"3 c #D6CABF",
+"4 c #5B5959",
+"5 c #C4C0BD",
+"6 c #807C79",
+"7 c #5A5653",
+"8 c #C0B5AC",
+"9 c #998778",
+"0 c #7B6F65",
+"a c #7A6D62",
+"b c #D3C3B4",
+"c c #FBF6F2",
+"d c #FAF2EC",
+"e c #F9EFE7",
+"f c #F7EBE1",
+"g c #F6E8DC",
+"h c #F4E4D6",
+"i c #F3E0D0",
+"j c #F2DDCB",
+"k c #D1BCAA",
+"l c #4D4D4D",
+"m c #7F7A76",
+"n c #595551",
+"o c #7B6F64",
+"p c #564C45",
+"q c #786A5C",
+"r c #CEB6A0",
+"s c #F8EDE3",
+"t c #F6E9DD",
+"u c #F5E5D8",
+"v c #F3E2D2",
+"w c #F2DECD",
+"x c #F1DAC7",
+"y c #EFD7C2",
+"z c #EED3BC",
+"A c #CCAF97",
+"B c #DEDEDE",
+"C c #D7CCC1",
+"D c #D5C7BA",
+"E c #D3C2B3",
+"F c #D1BEAC",
+"G c #CFB9A5",
+"H c #CEB49F",
+"I c #CCB097",
+"J c #CAAB90",
+"K c #C9A88C",
+"L c #000000",
+" ",
+" ......... ",
+" .++++++@#. ",
+" .++++++$+%. ",
+" .+&%&*+=%+#. ",
+" .++++++==$@. ",
+" .+&-%&%;*>,...... ",
+" .+++++')!~{.]++@#. ",
+" .+-&*&^/(_:.]++$+%. ",
+" .++;<[}|123.&*+=%+#. ",
+" .+4567890ab.]++==$@. ",
+" .+cdefghijk.l&%+*>&. ",
+" .+mn89op9qr.]+++++*. ",
+" .+stuvwxyzA.>&-&>&B. ",
+" .:CDEFGHIJK.]+++++B. ",
+" ..........LL&-*>&&B. ",
+" .]]]]+++++B. ",
+" .+&-*>&->&B. ",
+" .+++++++++B. ",
+" .BBBBBBBBBB. ",
+" ............ ",
+" "};
diff --git a/muse_qt4_evolution/muse/xpm/editcut.xpm b/muse_qt4_evolution/muse/xpm/editcut.xpm
new file mode 100644
index 00000000..4efcb43c
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/editcut.xpm
@@ -0,0 +1,33 @@
+/* XPM */
+static const char * editcut_xpm[] = {
+"22 22 8 1",
+" c None",
+". c #000000",
+"+ c #080203",
+"@ c #FFFFFF",
+"# c #C3C3C3",
+"$ c #010101",
+"% c #A0A0A0",
+"& c #303030",
+" ",
+" ",
+" ..+. ",
+" ... .. ... ",
+" .. .. .@@#. ",
+" .. .. .@@#. ",
+" .. . .@@#. ",
+" ... .. .@@#. ",
+" ....$ .@@#. ",
+" .....@@#. ",
+" %.@@#. ",
+" .@&#. ",
+" ....@.#. ",
+" ....$..@@#. ",
+" ... .. .@@#. ",
+" .. . .@@#. ",
+" .. .. .@@#. ",
+" .. .. .@@#. ",
+" .. .. .@@#. ",
+" ..+. ... ",
+" ",
+" "};
diff --git a/muse_qt4_evolution/muse/xpm/editcutS.xpm b/muse_qt4_evolution/muse/xpm/editcutS.xpm
new file mode 100644
index 00000000..06031f4a
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/editcutS.xpm
@@ -0,0 +1,24 @@
+/* XPM */
+static const char * editcutS_xpm[] = {
+"16 16 5 1",
+" g None",
+". g #000000",
+"+ g #FFFFFF",
+"@ g #DCDCDC",
+"# g #808080",
+" ",
+" .... .. ",
+".. .. .+@.",
+".. .. .+@. ",
+" .. . .+@. ",
+" ...... .+@. ",
+" .....+@. ",
+" ..+@. ",
+" .+@.. ",
+" .....#@. ",
+" ...... .+@. ",
+" .. . .+@. ",
+".. .. .+@. ",
+".. .. .+@.",
+" .... .. ",
+" "};
diff --git a/muse_qt4_evolution/muse/xpm/editmute.xpm b/muse_qt4_evolution/muse/xpm/editmute.xpm
new file mode 100644
index 00000000..ff0e22ac
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/editmute.xpm
@@ -0,0 +1,33 @@
+/* XPM */
+static const char * editmute_xpm[] = {
+"22 22 8 1",
+" c None",
+". c #000000",
+"+ c #080203",
+"@ c #FFFFFF",
+"# c #C3C3C3",
+"$ c #010101",
+"% c #A0A0A0",
+"& c #303030",
+" ",
+" ",
+" ",
+" ... ... ",
+" .@@#. .@@#. ",
+" .@@#. .@@#. ",
+" .@@#. .@@#. ",
+" .@@#. .@@#. ",
+" .@@#. .@@#. ",
+" .@@#..@@#. ",
+" .@@@@@#. ",
+" .#&&#. ",
+" .@@@@@#. ",
+" .@@#..@@#. ",
+" .@@#. .@@#. ",
+" .@@#. .@@#. ",
+" .@@#. .@@#. ",
+" .@@#. .@@#. ",
+" .@@#. .@@#. ",
+" ... ... ",
+" ",
+" "};
diff --git a/muse_qt4_evolution/muse/xpm/editpaste.xpm b/muse_qt4_evolution/muse/xpm/editpaste.xpm
new file mode 100644
index 00000000..8793a955
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/editpaste.xpm
@@ -0,0 +1,210 @@
+/* XPM */
+static const char * editpaste_xpm[] = {
+"22 22 185 2",
+" c None",
+". c #161616",
+"+ c #3A3616",
+"@ c #6F681E",
+"# c #625607",
+"$ c #575006",
+"% c #020202",
+"& c #060A06",
+"* c #262206",
+"= c #807529",
+"- c #FEFEFD",
+"; c #CAC682",
+"> c #A69E62",
+", c #362E16",
+"' c #EAEAEA",
+") c #EEEEEE",
+"! c #574D0A",
+"~ c #FFFFFF",
+"{ c #F6F6DE",
+"] c #EEEECA",
+"^ c #CECA96",
+"/ c #9E964A",
+"( c #4A462E",
+"_ c #C5C5C5",
+": c #C9C9C9",
+"< c #CCCCCC",
+"[ c #D4D4D4",
+"} c #DBDBDB",
+"| c #3A3636",
+"1 c #D6D6D6",
+"2 c #A6A6A6",
+"3 c #989898",
+"4 c #D6D29E",
+"5 c #CAC686",
+"6 c #B6B26A",
+"7 c #AAA65A",
+"8 c #7E721E",
+"9 c #818181",
+"0 c #888885",
+"a c #8C8C8C",
+"b c #262626",
+"c c #DADADA",
+"d c #A2A2A2",
+"e c #A9A9A9",
+"f c #B2B6B6",
+"g c #3E3A32",
+"h c #2E2E26",
+"i c #26261A",
+"j c #22221A",
+"k c #222216",
+"l c #161612",
+"m c #626266",
+"n c #727272",
+"o c #6E6E6E",
+"p c #7A7A7A",
+"q c #222222",
+"r c #D5D5D5",
+"s c #999999",
+"t c #9E9E9E",
+"u c #AAAAAA",
+"v c #BEBEBE",
+"w c #9A9A9A",
+"x c #828282",
+"y c #6C6C6C",
+"z c #5E5E5E",
+"A c #656565",
+"B c #5B5B5B",
+"C c #2E2E2E",
+"D c #B5B5B1",
+"E c #AFAFAF",
+"F c #9A9E9E",
+"G c #969696",
+"H c #7E7E7E",
+"I c #432E1A",
+"J c #372617",
+"K c #2C1F14",
+"L c #201711",
+"M c #15110D",
+"N c #1B1B1B",
+"O c #1E1E1E",
+"P c #939393",
+"Q c #9F9F9F",
+"R c #A4A4A4",
+"S c #A2A29E",
+"T c #313131",
+"U c #898989",
+"V c #121212",
+"W c #B6B6B6",
+"X c #9F9FA3",
+"Y c #979797",
+"Z c #8A8A8A",
+"` c #797979",
+" . c #676767",
+".. c #3C3B3C",
+"+. c #AEAEAE",
+"@. c #949494",
+"#. c #C6C6C6",
+"$. c #474646",
+"%. c #8E8E8E",
+"&. c #D2D2D2",
+"*. c #A2A2A6",
+"=. c #868686",
+"-. c #717171",
+";. c #5C5B5B",
+">. c #FEFCFB",
+",. c #747474",
+"'. c #868682",
+"). c #FDFBF9",
+"!. c #FCF7F3",
+"~. c #FAF4EE",
+"{. c #F0EAE6",
+"]. c #C1BAB3",
+"^. c #CACACA",
+"/. c #6A6A6A",
+"(. c #3A2818",
+"_. c #5A5552",
+":. c #7E7873",
+"<. c #9F958D",
+"[. c #7D746E",
+"}. c #D8D0C8",
+"|. c #CECECE",
+"1. c #767676",
+"2. c #636363",
+"3. c #322316",
+"4. c #FCF8F5",
+"5. c #FBF5F0",
+"6. c #F9F1EA",
+"7. c #F8EEE5",
+"8. c #F7EADF",
+"9. c #F5E7DA",
+"0. c #D6CABF",
+"a. c #2A1E14",
+"b. c #5B5959",
+"c. c #C4C0BD",
+"d. c #807C79",
+"e. c #5A5653",
+"f. c #C0B5AC",
+"g. c #998778",
+"h. c #7B6F65",
+"i. c #7A6D62",
+"j. c #D3C3B4",
+"k. c #707070",
+"l. c #595959",
+"m. c #221811",
+"n. c #FBF6F2",
+"o. c #FAF2EC",
+"p. c #F9EFE7",
+"q. c #F7EBE1",
+"r. c #F6E8DC",
+"s. c #F4E4D6",
+"t. c #F3E0D0",
+"u. c #F2DDCB",
+"v. c #D1BCAA",
+"w. c #808080",
+"x. c #4F4F4F",
+"y. c #19140F",
+"z. c #7F7A76",
+"A. c #595551",
+"B. c #7B6F64",
+"C. c #564C45",
+"D. c #786A5C",
+"E. c #CEB6A0",
+"F. c #6A6666",
+"G. c #565656",
+"H. c #494949",
+"I. c #120F0C",
+"J. c #F8EDE3",
+"K. c #F6E9DD",
+"L. c #F5E5D8",
+"M. c #F3E2D2",
+"N. c #F2DECD",
+"O. c #F1DAC7",
+"P. c #EFD7C2",
+"Q. c #EED3BC",
+"R. c #CCAF97",
+"S. c #D7CCC1",
+"T. c #D5C7BA",
+"U. c #D3C2B3",
+"V. c #D1BEAC",
+"W. c #CFB9A5",
+"X. c #CEB49F",
+"Y. c #CCB097",
+"Z. c #CAAB90",
+"`. c #C9A88C",
+" + c #000000",
+" . + @ # $ ",
+" % % % % % & * = - ; > , % % % % % % ",
+"% ' ) ) ) ) ) ! ~ { ] ^ / ( _ : < [ } | ",
+"% 1 2 2 2 3 = ~ 4 5 6 7 / 8 ( 9 0 9 a b ",
+"% c d e f 2 g h i i j i j k l m n o p q ",
+"% r s t u v u w x y z A B A z B A y w C ",
+"% 1 D E u F t G H I I I J K L M N N y O ",
+"% r P Q R S w G H I ~ ~ ~ ~ ~ ~ T U V O ",
+"% 1 W u X Y Z ` .I ~ ~ ~ ~ ~ ~ ..~ : V ",
+"% 1 G t t u +.@.x I ~ x : x #.~ $.: ~ U V ",
+"% 1 w 2 t %.x x o I ~ ~ ~ ~ ~ ~ $.$...T V ",
+"% &.%.G w 2 *.=.-.I ~ x ;.: x : >.#.R ,.V ",
+"% &.2 u 2 '.=.=.-.I ~ ~ ~ ~ ~ ).!.~.{.].V ",
+"% ^.H =.Z w G H /.(.~ ;.x #.x _.:.<.[.}.V ",
+"% |.w G =.H p 1.2.3.~ ~ >.4.5.6.7.8.9.0.V ",
+"% ^.=.%.%.=.x p .a.~ b.c.d.e.f.g.h.i.j.V ",
+"% ^.H x H p k./.l.m.~ n.o.p.q.r.s.t.u.v.V ",
+"% #.x =.=.w.w.z x.y.~ z.A.f.g.B.C.g.D.E.V ",
+"% u o o o o F.G.H.I.~ J.K.L.M.N.O.P.Q.R.V ",
+" % % % % % % % V N }.S.T.U.V.W.X.Y.Z.`.V ",
+" V V V V V V V V V V + + ",
+" "};
diff --git a/muse_qt4_evolution/muse/xpm/fforward.xpm b/muse_qt4_evolution/muse/xpm/fforward.xpm
new file mode 100644
index 00000000..11bf7523
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/fforward.xpm
@@ -0,0 +1,17 @@
+/* XPM */
+static const char * fforward_xpm[] = {
+"17 12 2 1",
+" c None",
+". c #000000",
+" . . ",
+" ... ... ",
+" ... ... ",
+" .... .... ",
+" .... .... ",
+" ..... ..... ",
+" ..... ..... ",
+" .... .... ",
+" .... .... ",
+" ... ... ",
+" ... ... ",
+" . . "};
diff --git a/muse_qt4_evolution/muse/xpm/filenew.png b/muse_qt4_evolution/muse/xpm/filenew.png
new file mode 100644
index 00000000..1214837b
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/filenew.png
Binary files differ
diff --git a/muse_qt4_evolution/muse/xpm/filenewS.xpm b/muse_qt4_evolution/muse/xpm/filenewS.xpm
new file mode 100644
index 00000000..1980070a
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/filenewS.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static const char * filenewS_xpm[] = {
+"16 16 10 1",
+" c None",
+". c #000000",
+"+ c #303030",
+"@ c #DCDCDC",
+"# c #C3C3C3",
+"$ c #FFFFFF",
+"% c #585858",
+"& c #A0A0A0",
+"* c #FFFFC0",
+"= c #400000",
+" ..+...+.. ",
+" +@@@@@#+#. ",
+" .@$$$$$%$@. ",
+" .@$$$$$%@$#. ",
+" .@$$$$$%%%+. ",
+" .@$$$$$$@#&. ",
+" .@$$$$$$*$@. ",
+" .@$$$$$$$$$. ",
+" .@$$$$*$*$*. ",
+" .@$$$$$$$*$. ",
+" .@$$*$*$*$*. ",
+" .@$$$$$*$*$. ",
+" +@*$*$*$*$*. ",
+" .@$$$*$*$**. ",
+" .@*$*$*$***. ",
+" ......=..+.. "};
diff --git a/muse_qt4_evolution/muse/xpm/fileopen.png b/muse_qt4_evolution/muse/xpm/fileopen.png
new file mode 100644
index 00000000..bb35ee03
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/fileopen.png
Binary files differ
diff --git a/muse_qt4_evolution/muse/xpm/filesave.png b/muse_qt4_evolution/muse/xpm/filesave.png
new file mode 100644
index 00000000..d69158ee
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/filesave.png
Binary files differ
diff --git a/muse_qt4_evolution/muse/xpm/flag.xpm b/muse_qt4_evolution/muse/xpm/flag.xpm
new file mode 100644
index 00000000..f8bcf244
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/flag.xpm
@@ -0,0 +1,28 @@
+/* XPM */
+static const char* flag_xpm[] = {
+"22 22 3 1",
+". c None",
+"+ c #000000",
+"@ c #00FF00",
+"......................",
+"......................",
+"......................",
+"......................",
+"........++............",
+"........+@++..........",
+"........+@@@+.........",
+"........+@@@@+........",
+"........+@@@@@+.......",
+"........+@@@@+........",
+"........+@@@+.........",
+"........+@++..........",
+"........++............",
+"........+.............",
+"........+.............",
+"........+.............",
+"........+.............",
+"........+.............",
+"........+.............",
+"......................",
+"......................",
+"......................"};
diff --git a/muse_qt4_evolution/muse/xpm/flagS.xpm b/muse_qt4_evolution/muse/xpm/flagS.xpm
new file mode 100644
index 00000000..741528e1
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/flagS.xpm
@@ -0,0 +1,19 @@
+/* XPM */
+static const char* flagS_xpm[] = {
+"8 12 3 1",
+". c None",
+"+ c #000000",
+"@ c #00FF00",
+"+.......",
+"+@+.....",
+"+@@@+...",
+"+@@@@@+.",
+"+@@@@+..",
+"+@@@+...",
+"+@+.....",
+"+.......",
+"+.......",
+"+.......",
+"+.......",
+"+......."};
+
diff --git a/muse_qt4_evolution/muse/xpm/folder_new.png b/muse_qt4_evolution/muse/xpm/folder_new.png
new file mode 100644
index 00000000..1277281f
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/folder_new.png
Binary files differ
diff --git a/muse_qt4_evolution/muse/xpm/forward.xpm b/muse_qt4_evolution/muse/xpm/forward.xpm
new file mode 100644
index 00000000..c2104314
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/forward.xpm
@@ -0,0 +1,28 @@
+/* XPM */
+/* Drawn by Mark Donohoe for the K Desktop Environment */
+/* See http://www.kde.org */
+static const char*forward_xpm[]={
+"16 16 5 1",
+"# c #000000",
+"a c #ffffff",
+"c c #808080",
+"b c #c0c0c0",
+". c None",
+"................",
+"................",
+".........#......",
+".........##.....",
+".........#a#....",
+"..########aa#...",
+"..#aaaaaaabaa#..",
+"..#bbbbbbbbbaa#.",
+"..#bbbbbbbbba#..",
+"..########ba#c..",
+"..ccccccc#a#c...",
+"........c##c....",
+"........c#c.....",
+"........cc......",
+"........c.......",
+"................",
+"................"};
+
diff --git a/muse_qt4_evolution/muse/xpm/frewind.xpm b/muse_qt4_evolution/muse/xpm/frewind.xpm
new file mode 100644
index 00000000..8c11fc3a
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/frewind.xpm
@@ -0,0 +1,17 @@
+/* XPM */
+static const char * frewind_xpm[] = {
+"17 12 2 1",
+" c None",
+". c #000000",
+" . . ",
+" ... ... ",
+" ... ... ",
+" .... .... ",
+" .... .... ",
+" ..... ..... ",
+" ..... ..... ",
+" .... .... ",
+" .... .... ",
+" ... ... ",
+" ... ... ",
+" . . "};
diff --git a/muse_qt4_evolution/muse/xpm/glue.xpm b/muse_qt4_evolution/muse/xpm/glue.xpm
new file mode 100644
index 00000000..caff2484
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/glue.xpm
@@ -0,0 +1,49 @@
+/* XPM */
+static const char * glue_xpm[] = {
+"22 22 24 1",
+" c None",
+". c #A0A0A4",
+"+ c #8C9BBA",
+"@ c #BBC4D6",
+"# c #7C8BAA",
+"$ c #A3ACBE",
+"% c #7D8EAE",
+"& c #98A6C0",
+"* c #8895B0",
+"= c #4F6693",
+"- c #0D1628",
+"; c #7586A6",
+"> c #4A566E",
+", c #000000",
+"' c #6D7FA2",
+") c #63779D",
+"! c #9B9B9F",
+"~ c #6A7A99",
+"{ c #687B9F",
+"] c #374664",
+"^ c #424F6A",
+"/ c #5C7199",
+"( c #3B4967",
+"_ c #3E4C68",
+" ",
+" ",
+" . ",
+" . ",
+" .+. ",
+" .+.. ",
+" .@+#. ",
+" .@+#.. ",
+" .@@@$#. ",
+" .@@@@@##. ",
+" .@@@@@$%.. ",
+" .&@@@@$*#=- ",
+" .&@@@@$;#>,. ",
+" .'*@@@*;'),. ",
+" !~;$$*{')],. ",
+" ,^;{*//(,.. ",
+" ,_#))_,.. ",
+" ,,,,,.. ",
+" ..... ",
+" ",
+" ",
+" "};
diff --git a/muse_qt4_evolution/muse/xpm/greendot.svg b/muse_qt4_evolution/muse/xpm/greendot.svg
new file mode 100644
index 00000000..823240de
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/greendot.svg
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16px"
+ height="16px"
+ id="svg1307"
+ sodipodi:version="0.32"
+ inkscape:version="0.43"
+ sodipodi:docbase="/home/ws/projects/muse/muse/trunk/muse/muse/xpm"
+ sodipodi:docname="greendot.svg">
+ <defs
+ id="defs1309">
+ <linearGradient
+ id="linearGradient1319">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop1321" />
+ <stop
+ style="stop-color:#11ff00;stop-opacity:1;"
+ offset="1"
+ id="stop1323" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1370">
+ <stop
+ style="stop-color:#ff271f;stop-opacity:1;"
+ offset="0"
+ id="stop1372" />
+ <stop
+ style="stop-color:#ff0000;stop-opacity:0;"
+ offset="1"
+ id="stop1374" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1370"
+ id="linearGradient1376"
+ x1="-5.6423869"
+ y1="-5.6206923"
+ x2="8.5200005"
+ y2="8.4349537"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1370"
+ id="linearGradient1315"
+ gradientUnits="userSpaceOnUse"
+ x1="-1.8582375"
+ y1="-0.071628742"
+ x2="3.8178029"
+ y2="2.5516095" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1319"
+ id="radialGradient1325"
+ cx="18.5282"
+ cy="0.093760476"
+ fx="18.5282"
+ fy="0.093760476"
+ r="7.8356543"
+ gradientTransform="matrix(-0.515305,-0.68232,0.563264,-0.418808,19.85983,21.47543)"
+ gradientUnits="userSpaceOnUse" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="39.396621"
+ inkscape:cx="8"
+ inkscape:cy="9.5532385"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ inkscape:grid-bbox="true"
+ inkscape:document-units="px"
+ inkscape:window-width="1913"
+ inkscape:window-height="1135"
+ inkscape:window-x="0"
+ inkscape:window-y="0" />
+ <metadata
+ id="metadata1312">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer">
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#radialGradient1325);fill-opacity:1.0;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ id="path1317"
+ sodipodi:cx="7.3610373"
+ sodipodi:cy="7.3317437"
+ sodipodi:rx="7.3356543"
+ sodipodi:ry="7.2721972"
+ d="M 14.696692 7.3317437 A 7.3356543 7.2721972 0 1 1 0.025382996,7.3317437 A 7.3356543 7.2721972 0 1 1 14.696692 7.3317437 z"
+ transform="matrix(1.020974,0,0,1.028955,0.484572,0.453358)" />
+ </g>
+</svg>
diff --git a/muse_qt4_evolution/muse/xpm/gv.xpm b/muse_qt4_evolution/muse/xpm/gv.xpm
new file mode 100644
index 00000000..cf4a2ed1
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/gv.xpm
@@ -0,0 +1,23 @@
+/* XPM */
+static const char * gv_xpm[] = {
+"16 16 4 1",
+" g None",
+". g #000000",
+"+ g #FFFFFF",
+"@ g #C0C0C0",
+" ........... ",
+".+++++++++++. ",
+".+@@@@+@@@++. ",
+".+++++++++++. ",
+".+@++@...@++. ",
+".+++@.+++.@+. ",
+".+@+.++@++.+. ",
+".+++.++@@+.+. ",
+".+++.+++++.+. ",
+".+++@.+++..+. ",
+".@@+@@....+.. ",
+".@+@@@++++.+. ",
+".@@++@+++++.+. ",
+".@+@@+++++++.+. ",
+" ........... .+.",
+" . "};
diff --git a/muse_qt4_evolution/muse/xpm/home.xpm b/muse_qt4_evolution/muse/xpm/home.xpm
new file mode 100644
index 00000000..de96eea3
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/home.xpm
@@ -0,0 +1,27 @@
+/* XPM */
+/* Drawn by Mark Donohoe for the K Desktop Environment */
+/* See http://www.kde.org */
+static const char *home_xpm[]={
+"16 16 4 1",
+"# c #000000",
+"a c #ffffff",
+"b c #c0c0c0",
+". c None",
+"........... ....",
+" ....##.......",
+"..#...####......",
+"..#..#aabb#.....",
+"..#.#aaaabb#....",
+"..##aaaaaabb#...",
+"..#aaaaaaaabb#..",
+".#aaaaaaaaabbb#.",
+"###aaaaaaaabb###",
+"..#aaaaaaaabb#..",
+"..#aaa###aabb#..",
+"..#aaa#.#aabb#..",
+"..#aaa#.#aabb#..",
+"..#aaa#.#aabb#..",
+"..#aaa#.#aabb#..",
+"..#####.######..",
+"................"};
+
diff --git a/muse_qt4_evolution/muse/xpm/initS.xpm b/muse_qt4_evolution/muse/xpm/initS.xpm
new file mode 100644
index 00000000..998b02fe
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/initS.xpm
@@ -0,0 +1,23 @@
+/* XPM */
+static const char * initS_xpm[] = {
+"16 16 4 1",
+" c None",
+". c #C00000",
+"+ c #FFFFFF",
+"@ c #000000",
+"................",
+"................",
+"..++++++++++++..",
+"..+@@++++++@@+..",
+"..+@@@++++@@@+..",
+"..++@@@++@@@++..",
+"..+++@@@@@@+++..",
+"..++++@@@@++++..",
+"..++++@@@@++++..",
+"..+++@@@@@@+++..",
+"..++@@@++@@@++..",
+"..+@@@++++@@@+..",
+"..+@@++++++@@+..",
+"..++++++++++++..",
+"................",
+"................"};
diff --git a/muse_qt4_evolution/muse/xpm/inputpluginS.xpm b/muse_qt4_evolution/muse/xpm/inputpluginS.xpm
new file mode 100644
index 00000000..33e8e578
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/inputpluginS.xpm
@@ -0,0 +1,22 @@
+/* XPM */
+static const char *inputpluginS_xpm[]={
+"16 16 3 1",
+"a c #000000",
+". c #00ff00",
+"# c #ffffff",
+"................",
+"................",
+"..############..",
+"..#aaaaa######a.",
+".aaaaaaaaaa##a.a",
+"a.#aaaaa######a.",
+"..############..",
+"..#aaaaa######a.",
+"aaaaaaaaaaa##a.a",
+"..#aaaaa######a.",
+"..############..",
+"a.#aaaaa######a.",
+".aaaaaaaaaa##a.a",
+"..#aaaaa######a.",
+"................",
+"................"};
diff --git a/muse_qt4_evolution/muse/xpm/italic.xpm b/muse_qt4_evolution/muse/xpm/italic.xpm
new file mode 100644
index 00000000..e21ebbff
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/italic.xpm
@@ -0,0 +1,16 @@
+/* XPM */
+static const char * italic_xpm[] = {
+"11 11 2 1",
+" g None",
+". g #000000",
+" ",
+" .... ",
+" .. ",
+" .. ",
+" .. ",
+" .. ",
+" .. ",
+" .. ",
+" .. ",
+" .... ",
+" "};
diff --git a/muse_qt4_evolution/muse/xpm/listS.xpm b/muse_qt4_evolution/muse/xpm/listS.xpm
new file mode 100644
index 00000000..cc561f06
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/listS.xpm
@@ -0,0 +1,26 @@
+/* XPM */
+static const char *listS_xpm[]={
+"16 16 7 1",
+"# c #000000",
+"e c #008000",
+". c #00ff00",
+"b c #dbdbdb",
+"a c #dcdcdc",
+"d c #fafafa",
+"c c #fbfbfb",
+"................",
+"..############..",
+"..#aaaaaaaabb#..",
+"..#c#c#c#c#db#e.",
+"..#cc#c#c#c#b#e.",
+"..#cccccccccb#e.",
+"..#c#a#a#a#ab#e.",
+"..#cc#a#a#a#b#e.",
+"..#cccccccccb#e.",
+"..#c#a#a#a#ab#e.",
+"..#cc#a#a#a#b#e.",
+"..#cccccccccb#e.",
+"..#cccccccccb#e.",
+"..############e.",
+"....eeeeeeeeeee.",
+"................"};
diff --git a/muse_qt4_evolution/muse/xpm/lmark.xpm b/muse_qt4_evolution/muse/xpm/lmark.xpm
new file mode 100644
index 00000000..2da119b9
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/lmark.xpm
@@ -0,0 +1,23 @@
+/* XPM */
+static const char* lmark_xpm[]={
+"18 18 2 1",
+"# c #0000ff",
+". c None",
+"..................",
+"..................",
+"..................",
+"..................",
+"..................",
+"..................",
+"..................",
+"##########........",
+".#########........",
+"..########........",
+"...#######........",
+"....######........",
+".....#####........",
+"......####........",
+".......###........",
+"........##........",
+"........##........",
+"........##........"};
diff --git a/muse_qt4_evolution/muse/xpm/localoffS.xpm b/muse_qt4_evolution/muse/xpm/localoffS.xpm
new file mode 100644
index 00000000..312793a5
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/localoffS.xpm
@@ -0,0 +1,22 @@
+/* XPM */
+static const char *localoffS_xpm[]={
+"16 16 3 1",
+"a c #000000",
+". c #c00000",
+"# c #ffffff",
+"................",
+"................",
+"..############..",
+"..############..",
+"..####aaaa####..",
+"..##aaaaaaaa##..",
+"..##aaaaaaaa##..",
+"..############..",
+"..############..",
+"..##aaaaaaaa##..",
+"..##aaaaaaaa##..",
+"..####aaaa####..",
+"..############..",
+"..############..",
+"................",
+"................"};
diff --git a/muse_qt4_evolution/muse/xpm/lock.xpm b/muse_qt4_evolution/muse/xpm/lock.xpm
new file mode 100644
index 00000000..9c38103b
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/lock.xpm
@@ -0,0 +1,86 @@
+/* XPM */
+static const char * lock_xpm[] = {
+"15 15 68 1",
+" c None",
+". c #747474",
+"+ c #838383",
+"@ c #727272",
+"# c #808080",
+"$ c #929292",
+"% c #7F7F7F",
+"& c #7A7A7A",
+"* c #6A6A6A",
+"= c #8C8C8C",
+"- c #F3F3F3",
+"; c #DEDEDE",
+"> c #2F2F2F",
+", c #2C2C2C",
+"' c #191919",
+") c #242424",
+"! c #3A3A3A",
+"~ c #6D6D6D",
+"{ c #CBCBCB",
+"] c #212121",
+"^ c #B6B6B6",
+"/ c #D1D1D1",
+"( c #C6C6C6",
+"_ c #1D1D1D",
+": c #787878",
+"< c #C1C1C1",
+"[ c #757575",
+"} c #1F1F1F",
+"| c #404040",
+"1 c #BDBDBD",
+"2 c #878787",
+"3 c #CFCFCF",
+"4 c #282828",
+"5 c #1C1C1C",
+"6 c #DCDCDC",
+"7 c #7C7C7C",
+"8 c #B5B5B5",
+"9 c #262626",
+"0 c #202020",
+"a c #232323",
+"b c #A3A3A3",
+"c c #2D2D2D",
+"d c #C4C4C4",
+"e c #1E1E1E",
+"f c #D8D8D8",
+"g c #272727",
+"h c #292929",
+"i c #E3E3E3",
+"j c #D4D4D4",
+"k c #B8B8B8",
+"l c #EBEBEB",
+"m c #444444",
+"n c #323232",
+"o c #3B3B3B",
+"p c #414141",
+"q c #383838",
+"r c #434343",
+"s c #EFEFEF",
+"t c #ABABAB",
+"u c #E7E7E7",
+"v c #A0A0A0",
+"w c #353535",
+"x c #363636",
+"y c #373737",
+"z c #C3C3C3",
+"A c #969696",
+"B c #1B1B1B",
+"C c #8F8F8F",
+".+@#$.@%&+%%@+*",
+"=--;;>,')!;;--$",
+"~{;;]!^;/(_;{/:",
+"=<;)[^}_)/+|1<2",
+"&3/41);;;56}(/%",
+"73;)89;;;06_(/+",
+"2(5abc;;;]d)e/%",
+"7f5)90g]g0ahe3+",
+"+;ai<(j(<<k6]l@",
+"@;9bmncopqr1)-%",
+"+i4stui({(b;}l:",
+"2;}v|w>x|yp(g-+",
+".jn6z6uk<u<8]u#",
+"Aie9B4]a455>eiC",
+"@%@%=22@@%&+#=~"};
diff --git a/muse_qt4_evolution/muse/xpm/loop.xpm b/muse_qt4_evolution/muse/xpm/loop.xpm
new file mode 100644
index 00000000..acd999c8
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/loop.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char *loop[]={
+"22 22 4 1",
+". c None",
+"a c #000000",
+"b c #7f7f7f",
+"# c #ffffff",
+"......................",
+"......................",
+".......########.......",
+"......#aaaaaaaab......",
+".....#abbbbbbbbab.....",
+"....#ab........#ab....",
+"....#ab........#ab....",
+"....#ab........#ab....",
+"....#ab.......#aaa....",
+"....#ab.......#aaab...",
+"....#ab......#aaaaa...",
+"....#ab......#aaaaa...",
+"....#ab......#ababa...",
+"....#ab........bab....",
+"....#ab........#ab....",
+"....#ab........#ab....",
+"....#ab........#ab....",
+".....ba......##ab.....",
+"......baaaaaaaab......",
+"........bbbbbbb.......",
+"......................",
+"......................"};
diff --git a/muse_qt4_evolution/muse/xpm/master.xpm b/muse_qt4_evolution/muse/xpm/master.xpm
new file mode 100644
index 00000000..8d241c9f
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/master.xpm
@@ -0,0 +1,15 @@
+/* XPM */
+static const char*master_xpm[]={
+"10 10 2 1",
+"# c #000000",
+". c None",
+"..........",
+".#.,....#.",
+".##....##.",
+".###..###.",
+".########.",
+".##.##.##.",
+".##....##.",
+".##....##.",
+".##....##.",
+".........."};
diff --git a/muse_qt4_evolution/muse/xpm/mastertrackS.xpm b/muse_qt4_evolution/muse/xpm/mastertrackS.xpm
new file mode 100644
index 00000000..3f1dfcb9
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/mastertrackS.xpm
@@ -0,0 +1,25 @@
+/* XPM */
+static const char *mastertrackS_xpm[]={
+"16 16 6 1",
+"# c #000000",
+". c #00ff00",
+"c c #808080",
+"d c #c3c3c3",
+"b c #ffc0c0",
+"a c #ffffff",
+"................",
+"................",
+"..#aaaaaaaaaaa..",
+"..##aaaaaaaaaa..",
+"..a##abbaaaaaa..",
+"..aa##abbaaaaa..",
+"..aaa#cbbbb####.",
+"..aaaabcbbb#c##.",
+"..aaaaabbbb####.",
+"..aaaaacbbb####.",
+"..aaaaaaa#a####.",
+"..aaaaaaaaadddd.",
+"..aaaaaaaaaaaa..",
+"..aaaaaaaaaaaa..",
+"................",
+"................"};
diff --git a/muse_qt4_evolution/muse/xpm/mastertrack_graphic.xpm b/muse_qt4_evolution/muse/xpm/mastertrack_graphic.xpm
new file mode 100644
index 00000000..0651619c
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/mastertrack_graphic.xpm
@@ -0,0 +1,28 @@
+/* XPM */
+static const char * mastertrack_graphic_xpm[] = {
+"16 16 9 1",
+" c None",
+". c #13A913",
+"+ c #0AD700",
+"@ c #800000",
+"# c #FEFFFC",
+"$ c #C2C4C0",
+"% c #C20000",
+"& c #FF0000",
+"* c #078002",
+"................",
+".++@@++++++++++.",
+".+#@@$########+.",
+".+#%%$########+.",
+".+#%%$########+.",
+".+#&&$#@@#####+.",
+".+#&&$#@@####@@.",
+".@@&&$#%%####@@*",
+".@@&&@@%%$###%%*",
+".%%&&@@&&@@##%%*",
+".%%&&%%&&@@@@&&*",
+".&&&&%%&&%%@@&&*",
+".&&&&&&&&%%%%&&*",
+".&&&&&&&&&&%%&&*",
+".+**************",
+"................"};
diff --git a/muse_qt4_evolution/muse/xpm/mastertrack_list.xpm b/muse_qt4_evolution/muse/xpm/mastertrack_list.xpm
new file mode 100644
index 00000000..e8ed00db
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/mastertrack_list.xpm
@@ -0,0 +1,27 @@
+/* XPM */
+static const char * mastertrack_list_xpm[] = {
+"16 16 8 1",
+" c None",
+". c #13A913",
+"+ c #0AD700",
+"@ c #000100",
+"# c #FEFFFC",
+"$ c #DBDDDA",
+"% c #078002",
+"& c #C2C4C0",
+"................",
+".+@@@@@@@@@@@@+.",
+".+@#$$$####$$@%.",
+".+@$@&@&@&@&#@%.",
+".+@##@&@&@&@#@%.",
+".+@#$##$#####@%.",
+".+@$@@#@#@#@#@%.",
+".+@$@@#$@#@##@%.",
+".+@$$##$#####@%.",
+".+@#@@#@$@#@#@%.",
+".+@#@@##@$@##@%.",
+".+@$#@@#@#@##@%.",
+".+@#@##@@#@@#@%.",
+".+@$#####$$#$@%.",
+".+@@@@@@@@@@@@%.",
+"...%%%%%%%%%%%%."};
diff --git a/muse_qt4_evolution/muse/xpm/meta.xpm b/muse_qt4_evolution/muse/xpm/meta.xpm
new file mode 100644
index 00000000..c424c23c
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/meta.xpm
@@ -0,0 +1,27 @@
+/* XPM */
+static const char * meta_xpm[] = {
+"22 22 2 1",
+" c #FFFFFFFFFFFF",
+". c #000000000000",
+" ",
+" ",
+" ",
+" ",
+" ........ .... ",
+" .. .. .. .. .. ",
+" .. .. .. ...... ",
+" .. .. .. .. ",
+" .. .. .. .. . ",
+" ... .. ... .... ",
+" ",
+" ",
+" .. ",
+" .. ",
+" .... .... ",
+" .. .. ",
+" .. ..... ",
+" .. .. .. ",
+" .. .. .. ",
+" ... ....... ",
+" ",
+" "};
diff --git a/muse_qt4_evolution/muse/xpm/midi_edit_instrument.xpm b/muse_qt4_evolution/muse/xpm/midi_edit_instrument.xpm
new file mode 100644
index 00000000..90e3df49
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/midi_edit_instrument.xpm
@@ -0,0 +1,27 @@
+/* XPM */
+static const char * midi_edit_instrument_xpm[] = {
+"16 16 8 1",
+" c None",
+". c #000000",
+"+ c #FFFFFF",
+"@ c #FF0000",
+"# c #A0A0A0",
+"$ c #808000",
+"% c #404000",
+"& c #585858",
+" ",
+" ........... ",
+" .+++++++++. @@",
+" .+########.@@@",
+" .+++++++++$%@ ",
+" .+#######$%$ ",
+" .+++++++$%$ ",
+" .+####+$%$. ",
+" .+++++$%$+. ",
+" .+#++$%$++. ",
+" .+++&$$+++. ",
+" .+++&&++++. ",
+" .+++++++++. ",
+" .+#######+. ",
+" .+++++++++. ",
+" ........... "};
diff --git a/muse_qt4_evolution/muse/xpm/midi_init_instr.xpm b/muse_qt4_evolution/muse/xpm/midi_init_instr.xpm
new file mode 100644
index 00000000..a64dc56f
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/midi_init_instr.xpm
@@ -0,0 +1,28 @@
+/* XPM */
+static const char * midi_init_instr_xpm[] = {
+"16 16 9 1",
+" c None",
+". c #800000",
+"+ c #C00000",
+"@ c #E1DDDA",
+"# c #C7C0BB",
+"$ c #FFFFFF",
+"% c #0E0702",
+"& c #080401",
+"* c #000000",
+"................",
+".++++++++++++++.",
+".+@###$$$$@##$+.",
+".+@%&#@$$##&&#+.",
+".+@%*&#@@@&*&#+.",
+".+@#&*&#@&**##+.",
+".+@$#&*&*&%@@@+.",
+".+@$$#&***#@@@+.",
+".+@$$#****#@$@+.",
+".+@@#%*%&&%#@@+.",
+".+@#&*%#@&*&#@+.",
+".+#&*%##$@**%#+.",
+".+#%%#@$$@#%%#+.",
+".+@@@@$$$$$##$+.",
+".++++++++++++++.",
+"................"};
diff --git a/muse_qt4_evolution/muse/xpm/midi_local_off.xpm b/muse_qt4_evolution/muse/xpm/midi_local_off.xpm
new file mode 100644
index 00000000..80dd1268
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/midi_local_off.xpm
@@ -0,0 +1,105 @@
+/* XPM */
+static const char * midi_local_off_xpm[] = {
+"16 16 86 1",
+" c None",
+". c #800000",
+"+ c #C00000",
+"@ c #FFFFFF",
+"# c #F2F2F2",
+"$ c #3D3D3D",
+"% c #414141",
+"& c #FEFEFE",
+"* c #F1F1F1",
+"= c #BFBFBF",
+"- c #E7E7E7",
+"; c #EEEEEE",
+"> c #363636",
+", c #353535",
+"' c #D1D1D1",
+") c #B5B5B5",
+"! c #FAFAFA",
+"~ c #878787",
+"{ c #040404",
+"] c #636363",
+"^ c #E9E9E9",
+"/ c #6B6B6B",
+"( c #0E0E0E",
+"_ c #999999",
+": c #C4C4C4",
+"< c #1E1E1E",
+"[ c #1C1C1C",
+"} c #B7B7B7",
+"| c #ECECEC",
+"1 c #F7F7F7",
+"2 c #9E9E9E",
+"3 c #121212",
+"4 c #2E2E2E",
+"5 c #DFDFDF",
+"6 c #535353",
+"7 c #070707",
+"8 c #EFEFEF",
+"9 c #E5E5E5",
+"0 c #4C4C4C",
+"a c #0A0A0A",
+"b c #949494",
+"c c #212121",
+"d c #B8B8B8",
+"e c #979797",
+"f c #454545",
+"g c #171717",
+"h c #3C3C3C",
+"i c #DADADA",
+"j c #494949",
+"k c #BEBEBE",
+"l c #292929",
+"m c #242424",
+"n c #101010",
+"o c #A8A8A8",
+"p c #4B4B4B",
+"q c #FDFDFD",
+"r c #868686",
+"s c #373737",
+"t c #828282",
+"u c #090909",
+"v c #5C5C5C",
+"w c #F0F0F0",
+"x c #F4F4F4",
+"y c #FBFBFB",
+"z c #404040",
+"A c #0F0F0F",
+"B c #A5A5A5",
+"C c #111111",
+"D c #4E4E4E",
+"E c #B4B4B4",
+"F c #EBEBEB",
+"G c #ACACAC",
+"H c #464646",
+"I c #E8E8E8",
+"J c #131313",
+"K c #484848",
+"L c #2D2D2D",
+"M c #0D0D0D",
+"N c #5A5A5A",
+"O c #CECECE",
+"P c #FCFCFC",
+"Q c #CCCCCC",
+"R c #7F7F7F",
+"S c #262626",
+"T c #A7A7A7",
+"U c #E2E2E2",
+"................",
+".++++++++++++++.",
+".+@@@@#$%&@@@@+.",
+".+@*=-;>,&')!@+.",
+".+!~{]^>,^/(_@+.",
+".+:<[}|>,12345+.",
+".+67/8;>,&90ab+.",
+".+<cd@;>,&@eaf+.",
+".+ghi@;>j&@k<l+.",
+".+mno&8pj&qr{s+.",
+".+tuv9qwxyizAB+.",
+".+'%CDEF-GHA6I+.",
+".+qkf7JKLM7NO@+.",
+".+@PQRSCC/TU@@+.",
+".++++++++++++++.",
+"................"};
diff --git a/muse_qt4_evolution/muse/xpm/midi_plugS.xpm b/muse_qt4_evolution/muse/xpm/midi_plugS.xpm
new file mode 100644
index 00000000..330a4b35
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/midi_plugS.xpm
@@ -0,0 +1,22 @@
+/* XPM */
+static const char *midi_plugS_xpm[]={
+"16 16 3 1",
+". c #00ff00",
+"a c #303030",
+"# c #ffffff",
+"................",
+"................",
+"..###aaaaaa###..",
+"..##a######a##..",
+"..#a###aa###a#..",
+"..a####aa####a..",
+"..a#aa####aa#a..",
+"..a#aa####aa#a..",
+"..a##########a..",
+"..a#aa####aa#a..",
+"..a#aa####aa#a..",
+"..#a########a#..",
+"..##a######a##..",
+"..###aaaaaa###..",
+"................",
+"................"};
diff --git a/muse_qt4_evolution/muse/xpm/midi_reset_instr.xpm b/muse_qt4_evolution/muse/xpm/midi_reset_instr.xpm
new file mode 100644
index 00000000..9460fd41
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/midi_reset_instr.xpm
@@ -0,0 +1,55 @@
+/* XPM */
+static const char * midi_reset_instr_xpm[] = {
+"16 16 36 1",
+" c None",
+". c #800000",
+"+ c #C00000",
+"@ c #FFFFFF",
+"# c #D4D4D4",
+"$ c #606060",
+"% c #000000",
+"& c #F8F8F8",
+"* c #DDDDDD",
+"= c #272727",
+"- c #E0E0E0",
+"; c #757575",
+"> c #E1E1E1",
+", c #AE0000",
+"' c #A3A3A3",
+") c #909090",
+"! c #474747",
+"~ c #D1D1D1",
+"{ c #E6E6E6",
+"] c #B3B3B3",
+"^ c #B0B0B0",
+"/ c #C0C0C0",
+"( c #CBCBCB",
+"_ c #B5B5B5",
+": c #DCDCDC",
+"< c #DBDBDB",
+"[ c #E4E4E4",
+"} c #2A2A2A",
+"| c #1E1E1E",
+"1 c #C2C2C2",
+"2 c #D3D3D3",
+"3 c #4E4E4E",
+"4 c #252525",
+"5 c #EAEAEA",
+"6 c #D7D7D7",
+"7 c #CCCCCC",
+"................",
+".++++++++++++++.",
+".+@@@@#$#@@@@@+.",
+".+@@@#%%#@@@@@+.",
+".+&@#%%%#####@+.",
+".+&*%%%%%%=$#@+.",
+".+&-%%%%%%%%;>,.",
+".+@@#%%%');%!~,.",
+".+@@{]%%']^%%]+.",
+".+@@@@]$/(_=%/+.",
+".+@@@:<]##;%=@+.",
+".+@@[}|%%%%=!1+.",
+".+@@234%%!$$]@+.",
+".+@@@5677777@{+.",
+".++++++++++++++.",
+"................"};
diff --git a/muse_qt4_evolution/muse/xpm/midi_transform.xpm b/muse_qt4_evolution/muse/xpm/midi_transform.xpm
new file mode 100644
index 00000000..d354191f
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/midi_transform.xpm
@@ -0,0 +1,30 @@
+/* XPM */
+static const char * midi_transform_xpm[] = {
+"16 16 11 1",
+" c None",
+". c #58A8FF",
+"+ c #A8DCFF",
+"@ c #363636",
+"# c #FFFFFF",
+"$ c #CACACA",
+"% c #626262",
+"& c #000000",
+"* c #85AECA",
+"= c #010101",
+"- c #4685CA",
+"................",
+".+++++++++@@+++.",
+".+##@#####@@##+.",
+".+##@$####@@##+.",
+".+##@$####@@##+.",
+".+#%&%##%@&&@%+.",
+".+#%&%$#%@&&@%*.",
+".+#%&%$#%@&&@%*.",
+".+#%&%$#%@&&@%*.",
+".+##&$$#%@&&@%*.",
+".+#&=$##%@&&@%*.",
+".+&&$$###$=&$$*.",
+".&&$$####&&&$#+.",
+"&&$$####&&&$$#+.",
+"&**++++&&&**+++.",
+"--....&&&--....."};
diff --git a/muse_qt4_evolution/muse/xpm/midi_transpose.xpm b/muse_qt4_evolution/muse/xpm/midi_transpose.xpm
new file mode 100644
index 00000000..0fdf5ac0
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/midi_transpose.xpm
@@ -0,0 +1,31 @@
+/* XPM */
+static const char * midi_transpose_xpm[] = {
+"16 16 12 1",
+" c None",
+". c #58A8FF",
+"+ c #000000",
+"@ c #A8DCFF",
+"# c #FFFFFF",
+"$ c #CACACA",
+"% c #797C7E",
+"& c #808080",
+"* c #545454",
+"= c #7E7F7F",
+"- c #6F91A8",
+"; c #3A6FA8",
+"......+.........",
+".@@@@++@@@@@@@@.",
+".@##+++#######@.",
+".@#++$+$######@.",
+".@#+$$+$##++##@.",
+".@##$#+$#++++#@.",
+".%&&&&+*&++++*=.",
+".@####+$#+++$$@.",
+".@##+++$#+$$$#@.",
+".@#++++$#+$###@.",
+".&&++++*&+*&&&&.",
+".@##++$$#+$#+#@.",
+".@###$$##+$++$@.",
+".@#######+++$$@.",
+".@@@@@@@@++--@@.",
+".........+;;...."};
diff --git a/muse_qt4_evolution/muse/xpm/midiin.xpm b/muse_qt4_evolution/muse/xpm/midiin.xpm
new file mode 100644
index 00000000..15b906ac
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/midiin.xpm
@@ -0,0 +1,23 @@
+/* XPM */
+static const char* midiin_xpm[] ={
+"18 18 2 1",
+". c None",
+"# c #000000",
+"......#####.......",
+"....##.....##.....",
+"...#...##....#....",
+"..#....##.....#...",
+".#..##.....##..#..",
+".#..##.....##..#..",
+"#...............#.",
+"#...............#.",
+"#..##.......##..#.",
+"#..##.......##..#.",
+"#...............#.",
+".#....#####....#..",
+".#....#####....#..",
+"..#...##.##...#...",
+"...#.........#....",
+"....##.....##.....",
+"......#####.......",
+".................."};
diff --git a/muse_qt4_evolution/muse/xpm/miditransformS.xpm b/muse_qt4_evolution/muse/xpm/miditransformS.xpm
new file mode 100644
index 00000000..3e43e097
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/miditransformS.xpm
@@ -0,0 +1,22 @@
+/* XPM */
+static const char *miditransformS_xpm[]={
+"16 16 3 1",
+"a c #303030",
+". c #58a8ff",
+"# c #ffffff",
+"................",
+"................",
+"..###aaaaaa###..",
+"..##a######a##..",
+"..#a###aa###a#..",
+"..a####aa####a..",
+"..a#aa####aa#a..",
+"..a#aa####aa#a..",
+"..a##########a..",
+"..a#aa####aa#a..",
+"..a#aa####aa#a..",
+"..#a########a#..",
+"..##a######a##..",
+"..###aaaaaa###..",
+"................",
+"................"};
diff --git a/muse_qt4_evolution/muse/xpm/miditransposeS.xpm b/muse_qt4_evolution/muse/xpm/miditransposeS.xpm
new file mode 100644
index 00000000..fa4593f4
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/miditransposeS.xpm
@@ -0,0 +1,25 @@
+/* XPM */
+static const char *miditransposeS_xpm[]={
+"16 16 6 1",
+"a c #303030",
+". c #58a8ff",
+"c c #800000",
+"b c #ff0000",
+"d c #ffc0c0",
+"# c #ffffff",
+"................",
+"................",
+"..###aaaaab###..",
+"..##a#####bb##..",
+"..#a###aa#bbb#..",
+"..a####aa#bbbb..",
+"..a#aabbbbccbbb.",
+"..a#aabbbbccbbb.",
+"..a###bb##bbbbd.",
+"..a#aabb##ccbd..",
+"..a#aabb##ccda..",
+"..#a##bb##bda#..",
+"..##a#bb##da##..",
+"..###abbaaa###..",
+"......bb........",
+"................"};
diff --git a/muse_qt4_evolution/muse/xpm/minus.xpm b/muse_qt4_evolution/muse/xpm/minus.xpm
new file mode 100644
index 00000000..7533722a
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/minus.xpm
@@ -0,0 +1,24 @@
+/* XPM */
+static const char * minus_xpm[] = {
+"16 16 5 1",
+" c None",
+". c #000000",
+"+ c #FFFFFF",
+"@ c #DCDCDC",
+"# c #A0A0A4",
+" ",
+" ..... ",
+" ..+++++.. ",
+" .++@@@@@@@. ",
+" .+@@@@@@@@. ",
+" .+@@@@@@@@@#. ",
+" .+@@@@@@@@@#. ",
+" .+@.......@#. ",
+" .+@@@@@@@@@#. ",
+" .+@@@@@@@@@#. ",
+" .@@@@@@@@#. ",
+" .@@@@@@@##. ",
+" ..#####.. ",
+" ..... ",
+" ",
+" "};
diff --git a/muse_qt4_evolution/muse/xpm/mixerS.xpm b/muse_qt4_evolution/muse/xpm/mixerS.xpm
new file mode 100644
index 00000000..b7b19735
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/mixerS.xpm
@@ -0,0 +1,21 @@
+/* XPM */
+static const char * mixerS_xpm[] = {
+"16 16 2 1",
+" c None",
+". c #000000",
+" ",
+" ",
+" ",
+" . . . . ",
+" ... . ... . ",
+" ... . ... . ",
+" . . . . ",
+" . . . ... ",
+" . . . ... ",
+" . . . . ",
+" . . . . ",
+" . ... . . ",
+" . ... . . ",
+" ",
+" ",
+" "};
diff --git a/muse_qt4_evolution/muse/xpm/mixeraudioS.xpm b/muse_qt4_evolution/muse/xpm/mixeraudioS.xpm
new file mode 100644
index 00000000..bc02fc72
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/mixeraudioS.xpm
@@ -0,0 +1,22 @@
+/* XPM */
+static const char *mixerAudioS_xpm[]={
+"16 16 3 1",
+"a c #000000",
+". c #ff00ff",
+"# c #ffffff",
+"................",
+"................",
+"..############..",
+"..#a##a##a##a#..",
+"..aaa#a#aaa#a#..",
+"..aaa#a#aaa#a#..",
+"..#a##a##a##a#..",
+"..#a##a##a#aaa..",
+"..#a##a##a#aaa..",
+"..#a##a##a##a#..",
+"..#a#aaa#a##a#..",
+"..#a#aaa#a##a#..",
+"..############..",
+"..############..",
+"................",
+"................"};
diff --git a/muse_qt4_evolution/muse/xpm/mono.svg b/muse_qt4_evolution/muse/xpm/mono.svg
new file mode 100644
index 00000000..ac764181
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/mono.svg
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16"
+ height="16"
+ id="svg1307"
+ sodipodi:version="0.32"
+ inkscape:version="0.45"
+ version="1.0"
+ sodipodi:docbase="/home/ws/projects/muse/muse/trunk/muse/muse/xpm"
+ sodipodi:docname="mono.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ sodipodi:modified="true">
+ <defs
+ id="defs1309" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="18.7"
+ inkscape:cx="16.5"
+ inkscape:cy="10"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ inkscape:grid-bbox="true"
+ inkscape:document-units="px"
+ inkscape:window-width="907"
+ inkscape:window-height="591"
+ inkscape:window-x="608"
+ inkscape:window-y="401"
+ width="16px"
+ height="16px" />
+ <metadata
+ id="metadata1312">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ transform="translate(-7.6895154,-1)">
+ <path
+ sodipodi:type="arc"
+ style="fill:#ff0000;fill-opacity:0;stroke:#3e3e3e;stroke-width:2.26799989;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="path2192"
+ sodipodi:cx="12.245989"
+ sodipodi:cy="10.374331"
+ sodipodi:rx="7.4331551"
+ sodipodi:ry="6.3547478"
+ d="M 19.679144 10.374331 A 7.4331551 6.3547478 0 1 1 4.8128338,10.374331 A 7.4331551 6.3547478 0 1 1 19.679144 10.374331 z"
+ transform="matrix(0.7216721,0,0,0.8227871,6.6137967,0.5665679)" />
+ </g>
+</svg>
diff --git a/muse_qt4_evolution/muse/xpm/muse_icon.xpm b/muse_qt4_evolution/muse/xpm/muse_icon.xpm
new file mode 100644
index 00000000..a7621e34
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/muse_icon.xpm
@@ -0,0 +1,411 @@
+/* XPM */
+static const char * muse_icon_xpm[] = {
+"32 32 376 2",
+" c None",
+". c #616161",
+"+ c #626262",
+"@ c #8E4B33",
+"# c #7C7B65",
+"$ c #C6C4A3",
+"% c #9F984E",
+"& c #B46C17",
+"* c #E6A34D",
+"= c #EBB268",
+"- c #E59F3C",
+"; c #BC7A1B",
+"> c #AB741E",
+", c #B6AB8B",
+"' c #E5E3B8",
+") c #C4C07B",
+"! c #BAAC17",
+"~ c #778E33",
+"{ c #87877C",
+"] c #DA9235",
+"^ c #E9B168",
+"/ c #E9B97A",
+"( c #E9AD5E",
+"_ c #E8A855",
+": c #E08B1D",
+"< c #75584E",
+"[ c #636363",
+"} c #BF8E48",
+"| c #EBDEB6",
+"1 c #ECE9BB",
+"2 c #C4BC75",
+"3 c #D2981B",
+"4 c #B57614",
+"5 c #6C6C6C",
+"6 c #6B6B6B",
+"7 c #979560",
+"8 c #FAFADD",
+"9 c #F7F6E4",
+"0 c #E3DAC2",
+"a c #CEBC9F",
+"b c #D59E56",
+"c c #E69E41",
+"d c #E0A045",
+"e c #9D794A",
+"f c #6A6A6A",
+"g c #696969",
+"h c #666666",
+"i c #646464",
+"j c #BE791F",
+"k c #D2BF9B",
+"l c #FDF9CE",
+"m c #E2E0B1",
+"n c #C2BC5D",
+"o c #C6941B",
+"p c #D1821C",
+"q c #B76F1A",
+"r c #6D6D6D",
+"s c #A7A164",
+"t c #C7C38F",
+"u c #C5C074",
+"v c #C5C06E",
+"w c #C5C380",
+"x c #CDCAA2",
+"y c #C9C09E",
+"z c #C5A772",
+"A c #E29A3D",
+"B c #E1AA5C",
+"C c #C89347",
+"D c #6F6A68",
+"E c #957548",
+"F c #C4A471",
+"G c #F6EBC1",
+"H c #F3F1C2",
+"I c #CDCB9C",
+"J c #C6BE3B",
+"K c #B8C300",
+"L c #CA8119",
+"M c #D4831B",
+"N c #BC7315",
+"O c #6E6E6E",
+"P c #6F6F6F",
+"Q c #717171",
+"R c #B7B342",
+"S c #E5DD18",
+"T c #EBE30C",
+"U c #E2DA11",
+"V c #E3DB0E",
+"W c #E0D521",
+"X c #CBC650",
+"Y c #C6C38D",
+"Z c #C7C19F",
+"` c #C29B63",
+" . c #E0A44F",
+".. c #DEAA5F",
+"+. c #D8953F",
+"@. c #CEA25D",
+"#. c #E7D7AC",
+"$. c #F7F4C8",
+"%. c #DDDAAA",
+"&. c #B5AE36",
+"*. c #6A6D62",
+"=. c #8C643D",
+"-. c #DA8B1B",
+";. c #727272",
+">. c #737373",
+",. c #A69F55",
+"'. c #BDB53E",
+"). c #EAE30F",
+"!. c #C1BB16",
+"~. c #7C784F",
+"{. c #ABA13C",
+"]. c #CEC533",
+"^. c #DDDBB0",
+"/. c #E0DBBD",
+"(. c #E6DBBB",
+"_. c #F2E9C5",
+":. c #FAFACF",
+"<. c #E3E0B0",
+"[. c #C5C180",
+"}. c #CCC333",
+"|. c #8F8B4E",
+"1. c #686868",
+"2. c #A8702D",
+"3. c #D7861E",
+"4. c #CC7F1B",
+"5. c #B77813",
+"6. c #747474",
+"7. c #AEAA3F",
+"8. c #B7AA10",
+"9. c #9F9C48",
+"0. c #C3BC4C",
+"a. c #D0CD9D",
+"b. c #CDCA9A",
+"c. c #CFC634",
+"d. c #A8A23D",
+"e. c #B17126",
+"f. c #CE7C1B",
+"g. c #C07719",
+"h. c #AF5A16",
+"i. c #BFB730",
+"j. c #D5CF28",
+"k. c #A6411D",
+"l. c #777664",
+"m. c #7C7C7C",
+"n. c #7B7B7B",
+"o. c #797979",
+"p. c #777777",
+"q. c #8A8761",
+"r. c #A39E4A",
+"s. c #A5A148",
+"t. c #91915A",
+"u. c #73746F",
+"v. c #9F692A",
+"w. c #B77210",
+"x. c #C13200",
+"y. c #C9C430",
+"z. c #C4BB31",
+"A. c #A7621E",
+"B. c #8D8A5C",
+"C. c #7A7A7A",
+"D. c #787878",
+"E. c #757575",
+"F. c #C6801D",
+"G. c #CCC337",
+"H. c #BDAF34",
+"I. c #B2771B",
+"J. c #928E63",
+"K. c #767676",
+"L. c #707070",
+"M. c #8D734E",
+"N. c #C2B669",
+"O. c #BDB048",
+"P. c #A29B45",
+"Q. c #968E3B",
+"R. c #7F7248",
+"S. c #CCC43B",
+"T. c #C2B635",
+"U. c #BF971E",
+"V. c #81826D",
+"W. c #BC9E4D",
+"X. c #C8C25D",
+"Y. c #CFC746",
+"Z. c #DFD424",
+"`. c #D6CB1F",
+" + c #6B754E",
+".+ c #CDC538",
+"++ c #C9BA36",
+"@+ c #BF9D28",
+"#+ c #997448",
+"$+ c #C0B65F",
+"%+ c #CEC949",
+"&+ c #D9CF30",
+"*+ c #EADD0B",
+"=+ c #A49D2B",
+"-+ c #CFC632",
+";+ c #CDC13C",
+">+ c #BF9B2C",
+",+ c #B29743",
+"'+ c #CAC355",
+")+ c #D4CE3B",
+"!+ c #E7E016",
+"~+ c #EEE609",
+"{+ c #C2BC19",
+"]+ c #CDC42E",
+"^+ c #CEC343",
+"/+ c #C09B2B",
+"(+ c #95764A",
+"_+ c #C6B44F",
+":+ c #D1C840",
+"<+ c #DDD328",
+"[+ c #D9D110",
+"}+ c #656565",
+"|+ c #C5BC2E",
+"1+ c #D3CA3C",
+"2+ c #C6A32B",
+"3+ c #7C7B5F",
+"4+ c #BA9337",
+"5+ c #CDC54A",
+"6+ c #D8CE31",
+"7+ c #E7DF0A",
+"8+ c #867C47",
+"9+ c #B7AC34",
+"0+ c #D8D231",
+"a+ c #C8AA2F",
+"b+ c #8B8754",
+"c+ c #676767",
+"d+ c #9D7940",
+"e+ c #C6B949",
+"f+ c #D6CC35",
+"g+ c #E5D918",
+"h+ c #ABA32C",
+"i+ c #9E9945",
+"j+ c #CFBB34",
+"k+ c #977F46",
+"l+ c #837056",
+"m+ c #B99A3C",
+"n+ c #D2C93F",
+"o+ c #DFD824",
+"p+ c #CCC617",
+"q+ c #7C7C5B",
+"r+ c #E4D819",
+"s+ c #D4CB37",
+"t+ c #B27A2B",
+"u+ c #A47A39",
+"v+ c #CCC441",
+"w+ c #DAD02D",
+"x+ c #DED20F",
+"y+ c #756E58",
+"z+ c #D8CD17",
+"A+ c #DCD629",
+"B+ c #C99F2C",
+"C+ c #80744D",
+"D+ c #976E3E",
+"E+ c #C0AF3B",
+"F+ c #E8DB15",
+"G+ c #EAE20B",
+"H+ c #989B34",
+"I+ c #BFB622",
+"J+ c #E5D91A",
+"K+ c #D4BE2D",
+"L+ c #BC7C21",
+"M+ c #73625C",
+"N+ c #AF8E36",
+"O+ c #D3CA3A",
+"P+ c #BFBA1E",
+"Q+ c #847C4B",
+"R+ c #E7DB10",
+"S+ c #DCD129",
+"T+ c #C89025",
+"U+ c #AB742C",
+"V+ c #A1793A",
+"W+ c #E0D523",
+"X+ c #EADD0F",
+"Y+ c #D3CD16",
+"Z+ c #D3C812",
+"`+ c #E8DB13",
+" @ c #CD7F1A",
+".@ c #A78034",
+"+@ c #6A6D60",
+"@@ c #8A7451",
+"#@ c #C4B941",
+"$@ c #E8E013",
+"%@ c #77755E",
+"&@ c #89864A",
+"*@ c #E9DC0E",
+"=@ c #C4AC57",
+"-@ c #DD8E28",
+";@ c #C3A358",
+">@ c #ADA86E",
+",@ c #8F8E78",
+"'@ c #8C7E69",
+")@ c #BEB591",
+"!@ c #DBD8A8",
+"~@ c #DCD127",
+"{@ c #95944A",
+"]@ c #B7AF30",
+"^@ c #DDD728",
+"/@ c #C6C06B",
+"(@ c #C7B17C",
+"_@ c #DC963B",
+":@ c #D99A38",
+"<@ c #B6AC75",
+"[@ c #BDB592",
+"}@ c #E8E6B5",
+"|@ c #D8D6A7",
+"1@ c #C6C367",
+"2@ c #AFA946",
+"3@ c #6F716A",
+"4@ c #CCC625",
+"5@ c #D5CF38",
+"6@ c #C5C384",
+"7@ c #DBD0A4",
+"8@ c #D3A966",
+"9@ c #C3AF7A",
+"0@ c #DCD9AB",
+"a@ c #C3BB3E",
+"b@ c #757671",
+"c@ c #7E7E7E",
+"d@ c #7F7F7F",
+"e@ c #7D7D7D",
+"f@ c #717467",
+"g@ c #D4C521",
+"h@ c #C5C288",
+"i@ c #EFECC6",
+"j@ c #EFEED0",
+"k@ c #C2C0A1",
+"l@ c #B4AE6F",
+"m@ c #C4A92F",
+"n@ c #A77D3A",
+"o@ c #837766",
+"p@ c #818181",
+"q@ c #838383",
+"r@ c #707366",
+"s@ c #D0C621",
+"t@ c #C5C078",
+"u@ c #E1DEB2",
+"v@ c #C6BBA1",
+"w@ c #DA9945",
+"x@ c #DE9639",
+"y@ c #E19426",
+"z@ c #D4881B",
+"A@ c #937C5E",
+"B@ c #808080",
+"C@ c #858585",
+"D@ c #888888",
+"E@ c #696D5C",
+"F@ c #D0C50B",
+"G@ c #D8D21F",
+"H@ c #B2A945",
+"I@ c #AB7622",
+"J@ c #A57536",
+"K@ c #746863",
+"L@ c #848484",
+"M@ c #828282",
+"N@ c #8B8B8B",
+"O@ c #8E8E8E",
+"P@ c #919191",
+"Q@ c #959595",
+"R@ c #979797",
+"S@ c #898989",
+"T@ c #878787",
+"U@ c #868686",
+"V@ c #8C8C8C",
+"W@ c #9A9A9A",
+"X@ c #9E9E9E",
+"Y@ c #A3A3A3",
+"Z@ c #A8A8A8",
+"`@ c #ABABAB",
+" # c #A0A0A0",
+".# c #989898",
+"+# c #9C9C9C",
+"@# c #969696",
+"## c #949494",
+"$# c #939393",
+"%# c #9B9B9B",
+"&# c #8F8F8F",
+". . . . . . . . . . . . . . . . . . . . . . . . . . + + . . . . ",
+". . . . . . . . @ . . . . . . . . . . . . . . . . # $ % . . . . ",
+". . . . . . & * = - ; . . . . . . . . . . . . > , ' ) ! . . . . ",
+". . . . ~ { ] ^ / ( _ : < [ [ + . . . . . . } | 1 2 3 4 . . . . ",
+"5 5 5 6 7 8 9 0 a b c * d e 5 6 f g h i j k l m n o p q . . . . ",
+"r r r 5 s t u v w x y z A B C D 5 f E F G H I J K L M N . . . . ",
+"O O P Q R S T U V W X Y Z ` ...+.@.#.$.%.v &.*.=.-.p q . . . . ",
+"P ;.;.>.,.'.).!.. ~.{.].u ^./.(._.:.<.[.}.|.1.5 2.3.4.5.. . . . ",
+"Q ;.;.>.6.7.S 8.i ;.Q Q 9.0.[.a.b.u c.d.*.r r 5 e.f.g.h.. . . . ",
+"Q ;.;.>.6.i.j.k.l.m.n.n.o.p.q.r.s.t.u.P r O 5 6 v.N w.x.+ + . . ",
+"Q ;.;.>.6.y.z.A.B.m.m.C.n.o.D.p.E.6.;.;.Q P r 6 F.A.. + + + + + ",
+"Q Q ;.;.>.G.H.I.J.C.o.n.o.D.p.K.E.6.;.Q L.P r M.N.O.P.Q.R.+ + + ",
+"Q Q Q ;.;.S.T.U.V.D.o.p.o.p.K.E.6.>.;.Q P 5 5 W.X.Y.Z.S `. ++ + ",
+"L.L.Q Q Q .+++@+>.>.;.>.>.K.K.6.>.;.Q P O 5 #+$+%+&+T *+=+[ + + ",
+"P P L.Q Q -+;+>+Q 5 Q Q ;.Q ;.>.;.Q L.P O r ,+'+)+!+~+{+i i [ + ",
+"P P P P L.]+^+/+O g 5 L.P Q L.L.Q L.P O r (+_+:+<+~+[+}+i i [ [ ",
+"P O O P P |+1+2+3+1.g O P P P O O P O r D 4+5+6+).7+8+}+i i i [ ",
+"O r O O O 9+0+a+b+c+1.f 5 O O r 5 5 r 5 d+e+f+g+~+h+}+}+i i [ [ ",
+"O 5 r r r i+<+j+k+c+c+g f f 5 5 5 6 6 l+m+n+o+~+p+h }+}+i i [ [ ",
+"r 5 5 5 5 q+r+s+t+c+c+c+g g g g f f f u+v+w+).x+y+}+}+i i [ [ [ ",
+"r 6 6 6 5 g z+A+B+C+h h 1.1.g 1.c+c+D+E+6+F+G+H+i i i [ i i i i ",
+"5 f f f 6 1.I+J+K+L+}+}+h 1.c+c+c+M+N+O+W ~+P+h c+c+c+c+c+h h }+",
+"5 g f f f 1.Q+R+S+T+U+}+}+c+c+h c+V+;+W+X+Y+g f f f f g g 1.c+c+",
+"5 g g g f c+c+Z+`+K+ @.@+@g f 5 @@#@S+$@V %@f f g f 6 6 f g g 1.",
+"6 1.1.g g c+h &@*@6+=@-@;@>@,@'@)@!@[.~@{@r 5 r 5 5 O O 6 6 f f ",
+"6 f 5 P Q O 5 5 ]@^@/@(@_@:@<@[@}@|@1@2@>.;.;.Q ;.O O f f f f f ",
+"K.D.p.p.D.K.5 O 3@4@5@6@7@8@9@m 0@[.a@b@K.6.6.;.;.L.O 5 6 f f g ",
+"D.n.c@d@c@e@K.O 5 f@g@:+h@i@j@k@l@m@n@o@>.6.6.6.6.;.Q L.P P 6 f ",
+"p.o.n.c@p@q@p@n.E.P r@s@5@t@u@v@w@x@y@z@A@B@d@n.D.K.6.;.Q L.O r ",
+"C.m.c@B@q@C@D@D@q@o.Q E@F@G@H@I@L J@K@;.6.o.L@d@d@m.m.n.o.o.p.K.",
+"e@d@M@L@D@N@O@P@Q@R@P@S@m.5 + g [ h ;.m.p@T@N@S@D@U@L@p@d@m.n.o.",
+"B@q@U@S@V@P@Q@W@X@Y@Z@`@Z@ #.#+#.#@###$#W@%#.#$#&#N@D@L@M@d@e@n."};
diff --git a/muse_qt4_evolution/muse/xpm/muse_icon_64x64.png b/muse_qt4_evolution/muse/xpm/muse_icon_64x64.png
new file mode 100644
index 00000000..5a1acb96
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/muse_icon_64x64.png
Binary files differ
diff --git a/muse_qt4_evolution/muse/xpm/mutebutton_off.xpm b/muse_qt4_evolution/muse/xpm/mutebutton_off.xpm
new file mode 100644
index 00000000..37c50f1c
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/mutebutton_off.xpm
@@ -0,0 +1,165 @@
+/* XPM */
+static const char * mutebutton_off_xpm[] = {
+"22 22 140 2",
+" c #000000",
+". c #720000",
+"+ c #7B0000",
+"@ c #810000",
+"# c #840000",
+"$ c #870000",
+"% c #8D0000",
+"& c #930000",
+"* c #980000",
+"= c #9C0000",
+"- c #9B0000",
+"; c #970000",
+"> c #900000",
+", c #8C0000",
+"' c #850000",
+") c #800000",
+"! c #760000",
+"~ c #730000",
+"{ c #710000",
+"] c #770000",
+"^ c #A10000",
+"/ c #A90000",
+"( c #AE0000",
+"_ c #B10000",
+": c #B60000",
+"< c #B50000",
+"[ c #B30000",
+"} c #AC0000",
+"| c #A70000",
+"1 c #9E0000",
+"2 c #8F0000",
+"3 c #890000",
+"4 c #7F0000",
+"5 c #7A0000",
+"6 c #7C0000",
+"7 c #8E0000",
+"8 c #A00000",
+"9 c #AD0000",
+"0 c #B80000",
+"a c #C00000",
+"b c #C60000",
+"c c #C80000",
+"d c #CB0000",
+"e c #C70000",
+"f c #BB0000",
+"g c #B20000",
+"h c #A30000",
+"i c #960000",
+"j c #860000",
+"k c #920000",
+"l c #BA0000",
+"m c #C50000",
+"n c #CE0000",
+"o c #D40000",
+"p c #D80000",
+"q c #D70000",
+"r c #DA0000",
+"s c #D10000",
+"t c #C90000",
+"u c #C30000",
+"v c #B40000",
+"w c #A40000",
+"x c #910000",
+"y c #7D0000",
+"z c #950000",
+"A c #AB0000",
+"B c #BD0000",
+"C c #CC0000",
+"D c #D60000",
+"E c #DF0000",
+"F c #E30000",
+"G c #E10000",
+"H c #DC0000",
+"I c #D00000",
+"J c #C20000",
+"K c #BC0000",
+"L c #A50000",
+"M c #AF0000",
+"N c #E40000",
+"O c #E70000",
+"P c #E60000",
+"Q c #3F3F3F",
+"R c #DD0200",
+"S c #D90300",
+"T c #D40200",
+"U c #CD0000",
+"V c #B90000",
+"W c #AA0000",
+"X c #9A0000",
+"Y c #D20000",
+"Z c #D90000",
+"` c #DE0000",
+" . c #E20000",
+".. c #3B3B3B",
+"+. c #313131",
+"@. c #E00300",
+"#. c #DD0300",
+"$. c #D10100",
+"%. c #A80000",
+"&. c #880000",
+"*. c #C40000",
+"=. c #454545",
+"-. c #E40200",
+";. c #E10300",
+">. c #DC0100",
+",. c #D50100",
+"'. c #D50000",
+"). c #121212",
+"!. c #E90000",
+"~. c #CA0000",
+"{. c #4C4C4C",
+"]. c #525252",
+"^. c #1E0700",
+"/. c #E80000",
+"(. c #BE0000",
+"_. c #030A1D",
+":. c #000F00",
+"<. c #7E0000",
+"[. c #CF0000",
+"}. c #DB0000",
+"|. c #0B0017",
+"1. c #000700",
+"2. c #BF0000",
+"3. c #DD0000",
+"4. c #D30000",
+"5. c #990000",
+"6. c #B00000",
+"7. c #C10000",
+"8. c #E00000",
+"9. c #940000",
+"0. c #7A0100",
+"a. c #A60000",
+"b. c #9D0000",
+"c. c #9D0101",
+"d. c #7B0200",
+"e. c #8C0100",
+"f. c #9E0101",
+"g. c #8F0101",
+"h. c #7F0101",
+"i. c #720101",
+" ",
+" . + @ # $ % & & * = - ; > , ' ) + ! ~ { ",
+" ] $ & - ^ / ( _ : < [ } | 1 * 2 3 # 4 5 ",
+" 6 7 8 9 0 a b b c d e a f g / h - i 7 j ",
+" 6 k | l m n o p q r q s t u f v 9 w - x ",
+" y z A B C D r E F F G H q I d J K g L z ",
+" ) * M J n D H E N O P Q R S T U m V W i ",
+" # X _ u C Y Z ` .P ..+.@.#.S $.t f %.& ",
+" &.8 : *.n Y p r E Q =. -.;.>.,.C f L % ",
+" % L l c n '.Z r Q Q ). !.P F q d 0 ^ 3 ",
+" > / K ~.s p Q {.].).^. /./.F p ~.< - @ ",
+" > / (.U q H Q +. _.:. P /. .Z t g X <. ",
+" x %.(.[.q }.+. |.1. E F ` p t [ i 6 ",
+" 2 %.2.U '.}. 3.3.}.q c _ i y ",
+" % w f d 4.p }.D r H 3.q t g i <. ",
+" &.8 : c I 4.D 4.s H E ` D e g ; <. ",
+" # 5.6.7.~.U n n U n H 8.3.o e 6.; <. ",
+" 4 & / l a J m e t c n r }.Z n J 9 9.y ",
+" 0.x h g l f 2.(.a m t U 4.4.I c f a.> + ",
+" 0.% b.W M [ [ v 0 f 2.u e b u l 6.c.$ ! ",
+" d.e.5.8 a.L L a.W A 6.[ < v M %.f.g.h.i. ",
+" "};
diff --git a/muse_qt4_evolution/muse/xpm/mutebutton_on.xpm b/muse_qt4_evolution/muse/xpm/mutebutton_on.xpm
new file mode 100644
index 00000000..d66647d5
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/mutebutton_on.xpm
@@ -0,0 +1,352 @@
+/* XPM */
+static const char * mutebutton_on_xpm[] = {
+"22 22 327 2",
+" c #000000",
+". c #066714",
+"+ c #056613",
+"@ c #076915",
+"# c #076A15",
+"$ c #076A16",
+"% c #086B17",
+"& c #096C18",
+"* c #066B15",
+"= c #066B14",
+"- c #076F17",
+"; c #0C751C",
+"> c #107B20",
+", c #0F7C1F",
+"' c #0D791D",
+") c #097318",
+"! c #066E15",
+"~ c #066C14",
+"{ c #066814",
+"] c #086B16",
+"^ c #0A6F19",
+"/ c #0B711A",
+"( c #0B721B",
+"_ c #0C731C",
+": c #0C731B",
+"< c #0A731A",
+"[ c #097219",
+"} c #077318",
+"| c #0A781B",
+"1 c #0E7E1F",
+"2 c #118522",
+"3 c #128722",
+"4 c #0F8321",
+"5 c #0B7D1B",
+"6 c #077517",
+"7 c #067016",
+"8 c #056713",
+"9 c #066914",
+"0 c #086D17",
+"a c #0A721A",
+"b c #0F771E",
+"c c #107A20",
+"d c #117D21",
+"e c #127E21",
+"f c #117F21",
+"g c #0E7D1F",
+"h c #0D801E",
+"i c #0F8620",
+"j c #128F25",
+"k c #159627",
+"l c #169828",
+"m c #159427",
+"n c #0F8B21",
+"o c #0B821C",
+"p c #087718",
+"q c #086E17",
+"r c #0B731A",
+"s c #0F791F",
+"t c #138223",
+"u c #168727",
+"v c #188A29",
+"w c #178D28",
+"x c #168D27",
+"y c #158C26",
+"z c #128D25",
+"A c #129125",
+"B c #313131",
+"C c #17A22B",
+"D c #19AA2D",
+"E c #1AAC2E",
+"F c #19A82C",
+"G c #159E29",
+"H c #119122",
+"I c #0C831D",
+"J c #066D15",
+"K c #0A7119",
+"L c #0C7A1D",
+"M c #118323",
+"N c #178D29",
+"O c #1B952E",
+"P c #1B9C2E",
+"Q c #1A9E2E",
+"R c #199C2B",
+"S c #3F3F3F",
+"T c #189E2B",
+"U c #17A32C",
+"V c #18AC2E",
+"W c #222222",
+"X c #1CC033",
+"Y c #1DC334",
+"Z c #1BBE32",
+"` c #18B22F",
+" . c #16A22A",
+".. c #129025",
+"+. c #097519",
+"@. c #0F801F",
+"#. c #158E27",
+"$. c #1A992E",
+"%. c #1DA633",
+"&. c #1EAD35",
+"*. c #1CAE32",
+"=. c #3B3B3B",
+"-. c #19AF2F",
+";. c #1ABE32",
+">. c #1CC835",
+",. c #1DD537",
+"'. c #1DCF37",
+"). c #1CC335",
+"!. c #19B130",
+"~. c #179C2A",
+"{. c #067015",
+"]. c #097A1A",
+"^. c #108922",
+"/. c #17982A",
+"(. c #1CA831",
+"_. c #1DB636",
+":. c #1DBB35",
+"<. c #454545",
+"[. c #1ABD31",
+"}. c #1AC332",
+"|. c #1BD435",
+"1. c #1BDE37",
+"2. c #1CDA38",
+"3. c #1DD038",
+"4. c #1BB832",
+"5. c #19A22D",
+"6. c #067215",
+"7. c #0A7F1B",
+"8. c #119124",
+"9. c #18A22D",
+"0. c #1BB635",
+"a. c #1BC336",
+"b. c #121212",
+"c. c #18C833",
+"d. c #18CC33",
+"e. c #19D934",
+"f. c #1AE236",
+"g. c #1BDF37",
+"h. c #1CD136",
+"i. c #1CBD35",
+"j. c #19A42E",
+"k. c #087618",
+"l. c #0B821D",
+"m. c #129725",
+"n. c #4C4C4C",
+"o. c #525252",
+"p. c #1E0700",
+"q. c #19CE33",
+"r. c #17D232",
+"s. c #18DA34",
+"t. c #19E036",
+"u. c #070707",
+"v. c #19DB36",
+"w. c #1ACF36",
+"x. c #1BBB33",
+"y. c #1AA22E",
+"z. c #087818",
+"A. c #0C861E",
+"B. c #129B26",
+"C. c #18B12F",
+"D. c #030A1D",
+"E. c #000F00",
+"F. c #17D231",
+"G. c #17D733",
+"H. c #18DB35",
+"I. c #19D534",
+"J. c #1ACB34",
+"K. c #1AB832",
+"L. c #199F2D",
+"M. c #087918",
+"N. c #0D891F",
+"O. c #129C26",
+"P. c #17B22F",
+"Q. c #0B0017",
+"R. c #000700",
+"S. c #16D230",
+"T. c #16D531",
+"U. c #16D731",
+"V. c #010101",
+"W. c #19D034",
+"X. c #18C432",
+"Y. c #19B230",
+"Z. c #169A2A",
+"`. c #087A19",
+" + c #0D881F",
+".+ c #139C27",
+"++ c #17AF2D",
+"@+ c #17CF30",
+"#+ c #14CF2F",
+"$+ c #14D130",
+"%+ c #15D330",
+"&+ c #16CC31",
+"*+ c #18C132",
+"=+ c #18B02E",
+"-+ c #159828",
+";+ c #0A7A1A",
+">+ c #149C27",
+",+ c #17AE2D",
+"'+ c #18BB31",
+")+ c #18C232",
+"!+ c #16CD31",
+"~+ c #14CC2F",
+"{+ c #14CE30",
+"]+ c #14CD2F",
+"^+ c #17CA31",
+"/+ c #15BF2F",
+"(+ c #15AE2B",
+"_+ c #129624",
+":+ c #0E8821",
+"<+ c #17AD2E",
+"[+ c #18BA31",
+"}+ c #19C331",
+"|+ c #17C730",
+"1+ c #15CC30",
+"2+ c #15CA30",
+"3+ c #14CB2E",
+"4+ c #15CD2F",
+"5+ c #14C72E",
+"6+ c #14BD2C",
+"7+ c #11AD29",
+"8+ c #0F9423",
+"9+ c #0B7B1A",
+"0+ c #0F8720",
+"a+ c #139B26",
+"b+ c #16AA2B",
+"c+ c #17B82D",
+"d+ c #17C130",
+"e+ c #17C72F",
+"f+ c #15CB30",
+"g+ c #16C730",
+"h+ c #15C82F",
+"i+ c #12C82B",
+"j+ c #11C52C",
+"k+ c #10BA29",
+"l+ c #0FA825",
+"m+ c #0C9020",
+"n+ c #0B791C",
+"o+ c #0D871F",
+"p+ c #119625",
+"q+ c #15A82A",
+"r+ c #16B52C",
+"s+ c #17C12E",
+"t+ c #16C82E",
+"u+ c #14CA30",
+"v+ c #15C92F",
+"w+ c #15C52F",
+"x+ c #14C42F",
+"y+ c #10C32A",
+"z+ c #10C02A",
+"A+ c #0EB526",
+"B+ c #0DA322",
+"C+ c #0A8D1D",
+"D+ c #097419",
+"E+ c #0E9121",
+"F+ c #11A126",
+"G+ c #14AF29",
+"H+ c #14BC2C",
+"I+ c #14C12D",
+"J+ c #14C32D",
+"K+ c #13C32E",
+"L+ c #14C22D",
+"M+ c #13C12D",
+"N+ c #13BA2B",
+"O+ c #10B928",
+"P+ c #10B828",
+"Q+ c #0EB426",
+"R+ c #0DAA23",
+"S+ c #0B9A20",
+"T+ c #08871B",
+"U+ c #077217",
+"V+ c #0A871D",
+"W+ c #0D9521",
+"X+ c #10A425",
+"Y+ c #11AE27",
+"Z+ c #11B228",
+"`+ c #12B529",
+" @ c #11B628",
+".@ c #10B429",
+"+@ c #10B227",
+"@@ c #10AF27",
+"#@ c #10AC27",
+"$@ c #0FAB26",
+"%@ c #0EA824",
+"&@ c #0DA624",
+"*@ c #0CA221",
+"=@ c #0B9C20",
+"-@ c #088F1C",
+";@ c #068018",
+">@ c #056D13",
+",@ c #057214",
+"'@ c #067A17",
+")@ c #09841B",
+"!@ c #0C911E",
+"~@ c #0D9921",
+"{@ c #0E9F22",
+"]@ c #0EA123",
+"^@ c #0DA222",
+"/@ c #0DA123",
+"(@ c #0C9C21",
+"_@ c #0B981F",
+":@ c #0C971F",
+"<@ c #0C951F",
+"[@ c #0B931F",
+"}@ c #0A911E",
+"|@ c #088E1C",
+"1@ c #07891A",
+"2@ c #058218",
+"3@ c #047715",
+"4@ c #036812",
+"5@ c #046C12",
+"6@ c #047014",
+"7@ c #057615",
+"8@ c #077D19",
+"9@ c #09831B",
+"0@ c #09871C",
+"a@ c #08891C",
+"b@ c #088A1B",
+"c@ c #078619",
+"d@ c #078419",
+"e@ c #078018",
+"f@ c #067D18",
+"g@ c #067C18",
+"h@ c #067D17",
+"i@ c #057B16",
+"j@ c #047815",
+"k@ c #037313",
+"l@ c #036D12",
+" ",
+" . + + . @ # $ % & % * = - ; > , ' ) ! ~ ",
+" . + { ] ^ / ( _ : < [ } | 1 2 3 4 5 6 7 ",
+" 8 9 0 a b c d e f g 1 h i j k l m n o p ",
+" { q r s t u v w x y z A B C D E F G H I ",
+" J K L M N O P Q R S T U V W X Y Z ` ... ",
+" J +.@.#.$.%.&.*.=.B -.B ;.>.B ,.'.).!.~. ",
+" {.].^./.(._.:.S <. [.}.S |.1.B 2.3.4.5. ",
+" 6.7.8.9.0.a.S S b. c.d.W e.f. g.h.i.j. ",
+" k.l.m.V S n.o.b.p. q.r. s.t.u.v.w.x.y. ",
+" z.A.B.C.S B D.E. r.F. G.H. I.J.K.L. ",
+" M.N.O.P.B Q.R. F.S. T.U.V.W.X.Y.Z. ",
+" `. +.+++ @+#+ $+%+ &+*+=+-+ ",
+" ;+N.>+,+'+)+ !+~+ {+]+ ^+/+(+_+ ",
+" ;+:+>+<+[+}+|+ 1+2+ 3+4+ 5+6+7+8+ ",
+" 9+0+a+b+c+d+e+f+ 2+ g+h+ i+j+k+l+m+ ",
+" n+o+p+q+r+s+t+u+v+ v+w+x+ j+y+z+A+B+C+ ",
+" D+l.E+F+G+H+I+J+K+L+M+6+ N+O+P+Q+R+S+T+ ",
+" U+`.V+W+X+Y+Z+`+ @.@+@@@#@$@%@&@*@=@-@;@ ",
+" >@,@'@)@!@~@{@]@^@/@(@_@:@<@[@}@|@1@2@3@ ",
+" 4@5@6@7@8@9@0@a@b@1@c@d@e@f@g@h@i@j@k@l@ ",
+" "};
diff --git a/muse_qt4_evolution/muse/xpm/newmutebutton.xpm b/muse_qt4_evolution/muse/xpm/newmutebutton.xpm
new file mode 100644
index 00000000..994e3321
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/newmutebutton.xpm
@@ -0,0 +1,69 @@
+/* XPM */
+static const char * newmutebutton_xpm[] = {
+"22 22 44 1",
+" c None",
+". c #000000",
+"+ c #313131",
+"@ c #E5141A",
+"# c #E1180D",
+"$ c #3F3F3F",
+"% c #222222",
+"& c #9E000D",
+"* c #FB1300",
+"= c #E91900",
+"- c #3B3B3B",
+"; c #EB1420",
+"> c #A9010C",
+", c #454545",
+"' c #E10E08",
+") c #DD1F0F",
+"! c #121212",
+"~ c #ED0014",
+"{ c #FF0603",
+"] c #F7001C",
+"^ c #4C4C4C",
+"/ c #525252",
+"( c #1E0700",
+"_ c #ED021A",
+": c #F00018",
+"< c #E21C19",
+"[ c #070707",
+"} c #030A1D",
+"| c #000F00",
+"1 c #E90412",
+"2 c #0B0017",
+"3 c #000700",
+"4 c #010101",
+"5 c #EC141D",
+"6 c #EA0900",
+"7 c #DE0B09",
+"8 c #E01000",
+"9 c #E81400",
+"0 c #F10E1C",
+"a c #EE0E16",
+"b c #E50300",
+"c c #FF0316",
+"d c #E70816",
+"e c #FF1901",
+"......................",
+". .",
+". .",
+". .",
+". + @# .",
+". $ %&*= .",
+". -+ + ;+> .",
+". $,. $')+ .",
+". $$!. ~%{]. .",
+". $^/!(._:.< [ .",
+". $+.}|.'1. . .",
+". +..23.{]. 4 .",
+". ......< . . .",
+". .... . . .",
+". 56... . . .",
+". 7890.. . . .",
+". abcd . . .",
+". 6e~ . .",
+". .",
+". .",
+". .",
+"......................"};
diff --git a/muse_qt4_evolution/muse/xpm/off.svg b/muse_qt4_evolution/muse/xpm/off.svg
new file mode 100644
index 00000000..7b24c60c
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/off.svg
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16px"
+ height="16px"
+ id="svg1307"
+ sodipodi:version="0.32"
+ inkscape:version="0.43"
+ sodipodi:docbase="/home/ws/projects/muse/muse/trunk/muse/muse/xpm"
+ sodipodi:docname="off.svg">
+ <defs
+ id="defs1309">
+ <linearGradient
+ id="linearGradient1319">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop1321" />
+ <stop
+ style="stop-color:#11ff00;stop-opacity:1;"
+ offset="1"
+ id="stop1323" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1370">
+ <stop
+ style="stop-color:#ff271f;stop-opacity:1;"
+ offset="0"
+ id="stop1372" />
+ <stop
+ style="stop-color:#ff0000;stop-opacity:0;"
+ offset="1"
+ id="stop1374" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1370"
+ id="linearGradient1376"
+ x1="-5.6423869"
+ y1="-5.6206923"
+ x2="8.5200005"
+ y2="8.4349537"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1370"
+ id="linearGradient1315"
+ gradientUnits="userSpaceOnUse"
+ x1="-1.8582375"
+ y1="-0.071628742"
+ x2="3.8178029"
+ y2="2.5516095" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="14.928528"
+ inkscape:cx="8"
+ inkscape:cy="7.5226075"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ inkscape:grid-bbox="true"
+ inkscape:document-units="px"
+ inkscape:window-width="1294"
+ inkscape:window-height="1027"
+ inkscape:window-x="619"
+ inkscape:window-y="66" />
+ <metadata
+ id="metadata1312">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer">
+ <path
+ sodipodi:type="arc"
+ style="fill:#ff0000;fill-opacity:0;fill-rule:evenodd;stroke:#646464;stroke-width:2.72968221;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="path1314"
+ sodipodi:cx="8.7697878"
+ sodipodi:cy="7.8774762"
+ sodipodi:rx="6.3837962"
+ sodipodi:ry="6.1680417"
+ d="M 15.153584,7.8774762 A 6.3837962,6.1680417 0 1 1 8.7708891,1.7094346"
+ transform="matrix(-0.727929,-0.732179,0.762556,-0.743756,8.334611,20.30045)"
+ sodipodi:start="0"
+ sodipodi:end="4.7125615"
+ sodipodi:open="true" />
+ <path
+ style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#5a5a5a;stroke-width:2.26799989;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 0.13399994,7.8236671 C 2.7476675,7.8489703 5.8595881,7.8713382 10.154827,7.8648734"
+ id="path1316"
+ sodipodi:nodetypes="cc" />
+ </g>
+</svg>
diff --git a/muse_qt4_evolution/muse/xpm/off.xpm b/muse_qt4_evolution/muse/xpm/off.xpm
new file mode 100644
index 00000000..64ddd452
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/off.xpm
@@ -0,0 +1,25 @@
+/* XPM */
+static const char * off_xpm[] = {
+"16 16 6 1",
+" c None",
+". c #000000",
+"+ c #FFFFFF",
+"@ c #DCDCDC",
+"# c #A0A0A4",
+"$ c #808080",
+" ",
+" ..... ",
+" ..+++++.. ",
+" .++@@@@@@@. ",
+" .+@@@.@@@@. ",
+" .+@@@@.@@@@#. ",
+" .+@@@@.@@@@#. ",
+" .+@@@@.@@@@#. ",
+" .+@@@@.@@@@#. ",
+" .+@@@@.@@@@#. ",
+" .@@@@.@@@#.$ ",
+" .@@@@@@@##. ",
+" ..#####.. ",
+" ..... ",
+" ",
+" "};
diff --git a/muse_qt4_evolution/muse/xpm/on.svg b/muse_qt4_evolution/muse/xpm/on.svg
new file mode 100644
index 00000000..5bb8ef4e
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/on.svg
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16px"
+ height="16px"
+ id="svg1307"
+ sodipodi:version="0.32"
+ inkscape:version="0.43"
+ sodipodi:docbase="/home/ws/projects/muse/muse/trunk/muse/muse/xpm"
+ sodipodi:docname="on.svg">
+ <defs
+ id="defs1309">
+ <linearGradient
+ id="linearGradient1319">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop1321" />
+ <stop
+ style="stop-color:#11ff00;stop-opacity:1;"
+ offset="1"
+ id="stop1323" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1370">
+ <stop
+ style="stop-color:#ff271f;stop-opacity:1;"
+ offset="0"
+ id="stop1372" />
+ <stop
+ style="stop-color:#ff0000;stop-opacity:0;"
+ offset="1"
+ id="stop1374" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1370"
+ id="linearGradient1376"
+ x1="-5.6423869"
+ y1="-5.6206923"
+ x2="8.5200005"
+ y2="8.4349537"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1370"
+ id="linearGradient1315"
+ gradientUnits="userSpaceOnUse"
+ x1="-1.8582375"
+ y1="-0.071628742"
+ x2="3.8178029"
+ y2="2.5516095" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="14.928528"
+ inkscape:cx="8"
+ inkscape:cy="7.5226075"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ inkscape:grid-bbox="true"
+ inkscape:document-units="px"
+ inkscape:window-width="1294"
+ inkscape:window-height="1027"
+ inkscape:window-x="619"
+ inkscape:window-y="66" />
+ <metadata
+ id="metadata1312">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer">
+ <path
+ sodipodi:type="arc"
+ style="fill:#ff0000;fill-opacity:0;fill-rule:evenodd;stroke:#646464;stroke-width:2.72968221;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="path1314"
+ sodipodi:cx="8.7697878"
+ sodipodi:cy="7.8774762"
+ sodipodi:rx="6.3837962"
+ sodipodi:ry="6.1680417"
+ d="M 15.153584,7.8774762 A 6.3837962,6.1680417 0 1 1 8.7708891,1.7094346"
+ transform="matrix(0.732179,-0.727929,0.743756,0.762556,-4.280292,8.334699)"
+ sodipodi:start="0"
+ sodipodi:end="4.7125615"
+ sodipodi:open="true" />
+ <path
+ style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#5a5a5a;stroke-width:2.268;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 8.0255001,-0.012957598 C 8.0001969,2.60071 7.977829,5.7126306 7.9842938,10.007869"
+ id="path1316"
+ sodipodi:nodetypes="cc" />
+ </g>
+</svg>
diff --git a/muse_qt4_evolution/muse/xpm/pafter.xpm b/muse_qt4_evolution/muse/xpm/pafter.xpm
new file mode 100644
index 00000000..a39ed901
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/pafter.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static const char *pafter_xpm[] = {
+"22 22 2 1",
+". c None",
+"# c #000000",
+"######################",
+"##...................#",
+"#.#..................#",
+"#..#.................#",
+"#...#................#",
+"#....#...............#",
+"#.....#..............#",
+"#......#.............#",
+"#.......#............#",
+"#........#...........#",
+"#.........#..........#",
+"#..........#.........#",
+"#...........#........#",
+"#............#.......#",
+"#.............#......#",
+"#..............#.....#",
+"#...............#....#",
+"#................#...#",
+"#.................#..#",
+"#..................#.#",
+"#...................##",
+"######################"
+};
+
diff --git a/muse_qt4_evolution/muse/xpm/panic.xpm b/muse_qt4_evolution/muse/xpm/panic.xpm
new file mode 100644
index 00000000..9b8f937c
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/panic.xpm
@@ -0,0 +1,50 @@
+/* XPM */
+static const char * panic_xpm[] = {
+"18 18 29 1",
+" c None",
+". c #F7001C",
+"+ c #EB1420",
+"@ c #FB1300",
+"# c #E10E08",
+"$ c #E21C19",
+"% c #DD1F0F",
+"& c #313131",
+"* c #ED0014",
+"= c #FF0603",
+"- c #F00018",
+"; c #3F3F3F",
+"> c #222222",
+", c #ED021A",
+"' c #3B3B3B",
+") c #E90412",
+"! c #454545",
+"~ c #000000",
+"{ c #525252",
+"] c #121212",
+"^ c #4C4C4C",
+"/ c #1E0700",
+"( c #070707",
+"_ c #030A1D",
+": c #0B0017",
+"< c #000700",
+"[ c #010101",
+"} c #E1180D",
+"| c #E50300",
+".. +@",
+"#.$ +#%",
+"$... & *#=.",
+" .-$ ; >#-=$ ",
+" #,. '& & .&) ",
+" # ;!~ ;#=& ",
+" {;]~ > ~ ",
+" ;^{~/~ ~ ( ",
+" ;&~_~~ ~ ~ ",
+" &~~:<~ ~ [ ",
+" ~~~~~~ ~ ~ ",
+" ~~~~ ~ ~ ",
+" }~~~ ~##~ ",
+" #% ~~ ~ #~# ",
+" *|$ ~ ~#$. ",
+" ,-% ~ $... ",
+"*$). $$$.",
+"-$. .$$"};
diff --git a/muse_qt4_evolution/muse/xpm/pencil.xpm b/muse_qt4_evolution/muse/xpm/pencil.xpm
new file mode 100644
index 00000000..16c06603
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/pencil.xpm
@@ -0,0 +1,27 @@
+/* XPM */
+static const char*pencil_xpm[]={
+"18 18 5 1",
+"# c #000000",
+"c c #ffffff",
+"b c #a0a0a4",
+"a c #dcdcdc",
+". c None",
+"..................",
+"........####......",
+"........#aaa#.....",
+".......#aaaa#b....",
+".......##aa#bb....",
+"......#cc###b.....",
+"......#caa#bb.....",
+".....#ccaa#b......",
+".....#caa#bb......",
+"....#ccaa#b.......",
+"....#caa#bb.......",
+"....##aa#b........",
+"....####bb........",
+"....###bb.........",
+"....##bb..........",
+"....#bb...........",
+".....b............",
+".................."};
+
diff --git a/muse_qt4_evolution/muse/xpm/piano.xpm b/muse_qt4_evolution/muse/xpm/piano.xpm
new file mode 100644
index 00000000..3649919e
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/piano.xpm
@@ -0,0 +1,24 @@
+/* XPM */
+static const char *pianoS_xpm[]={
+"16 16 5 1",
+"# c #000000",
+"c c #00c000",
+". c #00ff00",
+"b c #dcdcdc",
+"a c #ffffff",
+"................",
+"................",
+"..#########aaa..",
+"..#########aaa..",
+"..abbbbbbbbaaa..",
+"..#########aaa..",
+"..#########aaa..",
+"..abbbbbbbbaaa..",
+"..#########aaa..",
+"..#########aaa..",
+"..abbbbbbbbaaa..",
+"..aaaaaaaaaaaa..",
+"..#########aaa..",
+"..#########aaa..",
+"...ccccccccc....",
+"................"};
diff --git a/muse_qt4_evolution/muse/xpm/pitch.xpm b/muse_qt4_evolution/muse/xpm/pitch.xpm
new file mode 100644
index 00000000..e8f67efb
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/pitch.xpm
@@ -0,0 +1,28 @@
+/* XPM */
+static const char *pitch_xpm[]={
+"22 22 3 1",
+"a c #303030",
+"# c #808080",
+". c None",
+"..............#..#....",
+"...............#..#...",
+"................#.#...",
+".......a......a.#.#...",
+".......a......a.#.#...",
+".......a......a.#.#...",
+".......a......a.#.#...",
+".......a......a.#.#...",
+".......a......a#..#...",
+".......a......a..#....",
+"........a....a..#.....",
+".........aaaa.........",
+"..........aa..........",
+"..........aa..........",
+"..........aa..........",
+".........aaaa.........",
+"........aaaaaa........",
+"........aaaaaa........",
+".........aaaa.........",
+"..........aa..........",
+"......................",
+"......................"};
diff --git a/muse_qt4_evolution/muse/xpm/play.xpm b/muse_qt4_evolution/muse/xpm/play.xpm
new file mode 100644
index 00000000..b38afc78
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/play.xpm
@@ -0,0 +1,17 @@
+/* XPM */
+static const char * play_xpm[] = {
+"12 12 2 1",
+" c None",
+". c #000000",
+" . ",
+" ... ",
+" ... ",
+" .... ",
+" .... ",
+" ..... ",
+" ..... ",
+" .... ",
+" .... ",
+" ... ",
+" ... ",
+" . "};
diff --git a/muse_qt4_evolution/muse/xpm/plus.xpm b/muse_qt4_evolution/muse/xpm/plus.xpm
new file mode 100644
index 00000000..e68e8db2
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/plus.xpm
@@ -0,0 +1,21 @@
+/* XPM */
+static const char * plus_xpm[] = {
+"13 13 5 1",
+" c None",
+". c #000000",
+"+ c #FFFFFF",
+"@ c #DCDCDC",
+"# c #A0A0A4",
+" ..... ",
+" ..+++++.. ",
+" .++@@@@@@@. ",
+" .+@@@.@@@@. ",
+".+@@@@.@@@@#.",
+".+@@@@.@@@@#.",
+".+@.......@#.",
+".+@@@@.@@@@#.",
+".+@@@@.@@@@#.",
+" .@@@@.@@@#. ",
+" .@@@@@@@##. ",
+" ..#####.. ",
+" ..... " };
diff --git a/muse_qt4_evolution/muse/xpm/pointer.xpm b/muse_qt4_evolution/muse/xpm/pointer.xpm
new file mode 100644
index 00000000..87801aa7
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/pointer.xpm
@@ -0,0 +1,28 @@
+/* XPM */
+/* Drawn by Mark Donohoe for the K Desktop Environment */
+/* See http://www.kde.org */
+static const char*pointer_xpm[]={
+"18 18 4 1",
+"# c #000000",
+"a c #000080",
+"b c #808080",
+". c None",
+"..................",
+"..................",
+".....#............",
+".....##...........",
+".....###..........",
+".....####.........",
+".....#####........",
+".....######.......",
+".....#######......",
+".....########.....",
+".....#####........",
+".....##.##........",
+".....#...##.......",
+".........##.......",
+"..........##......",
+"..........##......",
+"..................",
+".................."};
+
diff --git a/muse_qt4_evolution/muse/xpm/punchin.xpm b/muse_qt4_evolution/muse/xpm/punchin.xpm
new file mode 100644
index 00000000..2bd3ce7f
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/punchin.xpm
@@ -0,0 +1,17 @@
+/* XPM */
+static char *punchin[]={
+"12 12 2 1",
+". c None",
+"# c #000000",
+"............",
+"####........",
+"######......",
+"....##......",
+"....##......",
+"....##......",
+"....##......",
+"....##......",
+"....########",
+"......######",
+"............",
+"............"};
diff --git a/muse_qt4_evolution/muse/xpm/punchout.xpm b/muse_qt4_evolution/muse/xpm/punchout.xpm
new file mode 100644
index 00000000..d176ed5d
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/punchout.xpm
@@ -0,0 +1,18 @@
+/* XPM */
+static const char* punchout_xpm[]={
+"12 12 3 1",
+"a c #c0c0c0",
+"# c #000000",
+". c None",
+"............",
+"............",
+"......######",
+"....########",
+"....##......",
+"....##......",
+"....##......",
+"....##......",
+"######......",
+"####........",
+"............",
+"............"};
diff --git a/muse_qt4_evolution/muse/xpm/quant.xpm b/muse_qt4_evolution/muse/xpm/quant.xpm
new file mode 100644
index 00000000..70d763dd
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/quant.xpm
@@ -0,0 +1,28 @@
+/* XPM */
+static const char* quant_xpm[]={
+"22 22 2 1",
+"x c #000000",
+". c None",
+"......................",
+"......................",
+"......................",
+".........xxxx.........",
+".......xx....xx.......",
+".....xx........xx.....",
+"....x............x....",
+"...x..............x...",
+"...x..............x...",
+"..x................x..",
+"..x................x..",
+"..x................x..",
+"..x................x..",
+"...x..............x...",
+"...x.......x......x...",
+"....x.......x....x....",
+".....xx......x.xx.....",
+".......xx....xx.......",
+".........xxxx..x......",
+"................x.....",
+"......................",
+"......................"};
+
diff --git a/muse_qt4_evolution/muse/xpm/recordOff.svg b/muse_qt4_evolution/muse/xpm/recordOff.svg
new file mode 100644
index 00000000..05c88a04
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/recordOff.svg
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16px"
+ height="16px"
+ id="svg1307"
+ sodipodi:version="0.32"
+ inkscape:version="0.43"
+ sodipodi:docbase="/home/ws/projects/muse/muse/trunk/muse/muse/xpm"
+ sodipodi:docname="recordOff.svg">
+ <defs
+ id="defs1309">
+ <linearGradient
+ id="linearGradient1319">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop1321" />
+ <stop
+ style="stop-color:#561a1a;stop-opacity:1;"
+ offset="1"
+ id="stop1323" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1370">
+ <stop
+ style="stop-color:#ff271f;stop-opacity:1;"
+ offset="0"
+ id="stop1372" />
+ <stop
+ style="stop-color:#ff0000;stop-opacity:0;"
+ offset="1"
+ id="stop1374" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1370"
+ id="linearGradient1376"
+ x1="-5.6423869"
+ y1="-5.6206923"
+ x2="8.5200005"
+ y2="8.4349537"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1370"
+ id="linearGradient1315"
+ gradientUnits="userSpaceOnUse"
+ x1="-1.8582375"
+ y1="-0.071628742"
+ x2="3.8178029"
+ y2="2.5516095" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1319"
+ id="radialGradient1325"
+ cx="18.5282"
+ cy="0.093760476"
+ fx="18.5282"
+ fy="0.093760476"
+ r="7.8356543"
+ gradientTransform="matrix(-0.515305,-0.68232,0.563264,-0.418808,19.85983,21.47543)"
+ gradientUnits="userSpaceOnUse" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="39.396621"
+ inkscape:cx="8"
+ inkscape:cy="9.5532385"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ inkscape:grid-bbox="true"
+ inkscape:document-units="px"
+ inkscape:window-width="1913"
+ inkscape:window-height="1135"
+ inkscape:window-x="0"
+ inkscape:window-y="0" />
+ <metadata
+ id="metadata1312">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer">
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#radialGradient1325);fill-opacity:1.0;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ id="path1317"
+ sodipodi:cx="7.3610373"
+ sodipodi:cy="7.3317437"
+ sodipodi:rx="7.3356543"
+ sodipodi:ry="7.2721972"
+ d="M 14.696692 7.3317437 A 7.3356543 7.2721972 0 1 1 0.025382996,7.3317437 A 7.3356543 7.2721972 0 1 1 14.696692 7.3317437 z"
+ transform="matrix(1.020974,0,0,1.028955,0.484572,0.453358)" />
+ </g>
+</svg>
diff --git a/muse_qt4_evolution/muse/xpm/recordOn.svg b/muse_qt4_evolution/muse/xpm/recordOn.svg
new file mode 100644
index 00000000..d97f8249
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/recordOn.svg
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16px"
+ height="16px"
+ id="svg1307"
+ sodipodi:version="0.32"
+ inkscape:version="0.43"
+ sodipodi:docbase="/home/ws/projects/muse/muse/trunk/muse/muse/xpm"
+ sodipodi:docname="recordOn.svg">
+ <defs
+ id="defs1309">
+ <linearGradient
+ id="linearGradient1319">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop1321" />
+ <stop
+ style="stop-color:#ff0000;stop-opacity:1;"
+ offset="1"
+ id="stop1323" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1370">
+ <stop
+ style="stop-color:#ff271f;stop-opacity:1;"
+ offset="0"
+ id="stop1372" />
+ <stop
+ style="stop-color:#ff0000;stop-opacity:0;"
+ offset="1"
+ id="stop1374" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1370"
+ id="linearGradient1376"
+ x1="-5.6423869"
+ y1="-5.6206923"
+ x2="8.5200005"
+ y2="8.4349537"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1370"
+ id="linearGradient1315"
+ gradientUnits="userSpaceOnUse"
+ x1="-1.8582375"
+ y1="-0.071628742"
+ x2="3.8178029"
+ y2="2.5516095" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1319"
+ id="radialGradient1325"
+ cx="18.5282"
+ cy="0.093760476"
+ fx="18.5282"
+ fy="0.093760476"
+ r="7.8356543"
+ gradientTransform="matrix(-0.515305,-0.68232,0.563264,-0.418808,19.85983,21.47543)"
+ gradientUnits="userSpaceOnUse" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="39.396621"
+ inkscape:cx="8"
+ inkscape:cy="9.5532385"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ inkscape:grid-bbox="true"
+ inkscape:document-units="px"
+ inkscape:window-width="1913"
+ inkscape:window-height="1135"
+ inkscape:window-x="0"
+ inkscape:window-y="0" />
+ <metadata
+ id="metadata1312">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer">
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#radialGradient1325);fill-opacity:1.0;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ id="path1317"
+ sodipodi:cx="7.3610373"
+ sodipodi:cy="7.3317437"
+ sodipodi:rx="7.3356543"
+ sodipodi:ry="7.2721972"
+ d="M 14.696692 7.3317437 A 7.3356543 7.2721972 0 1 1 0.025382996,7.3317437 A 7.3356543 7.2721972 0 1 1 14.696692 7.3317437 z"
+ transform="matrix(1.020974,0,0,1.028955,0.484572,0.453358)" />
+ </g>
+</svg>
diff --git a/muse_qt4_evolution/muse/xpm/redo.xpm b/muse_qt4_evolution/muse/xpm/redo.xpm
new file mode 100644
index 00000000..24771785
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/redo.xpm
@@ -0,0 +1,92 @@
+/* XPM */
+static const char * redo_xpm[] = {
+"22 22 67 1",
+" c None",
+". c #275F0B",
+"+ c #9AC589",
+"@ c #CDE2C1",
+"# c #E5EEDF",
+"$ c #FFFFFF",
+"% c #91D56B",
+"& c #79BE53",
+"* c #C7E0BA",
+"= c #F5F9F4",
+"- c #1C4408",
+"; c #47AB29",
+"> c #3FA21C",
+", c #4AA721",
+"' c #87C86A",
+") c #C8E1BE",
+"! c #000000",
+"~ c #020202",
+"{ c #53B529",
+"] c #5BC930",
+"^ c #6FD63D",
+"/ c #8AC963",
+"( c #35691B",
+"_ c #2B6A0E",
+": c #E4ECDF",
+"< c #79B658",
+"[ c #41821F",
+"} c #0E2005",
+"| c #060D03",
+"1 c #102806",
+"2 c #42A01E",
+"3 c #A7C49A",
+"4 c #7FAA67",
+"5 c #3A8816",
+"6 c #1C4508",
+"7 c #0B1B05",
+"8 c #72C24F",
+"9 c #7FCC67",
+"0 c #67A050",
+"a c #40A513",
+"b c #275E0D",
+"c c #122B06",
+"d c #469D24",
+"e c #51B929",
+"f c #38AA18",
+"g c #3F9524",
+"h c #173807",
+"i c #081204",
+"j c #63C53E",
+"k c #41AE20",
+"l c #48B227",
+"m c #53A82F",
+"n c #071003",
+"o c #5B973A",
+"p c #50932F",
+"q c #4A8D2D",
+"r c #428727",
+"s c #428525",
+"t c #15260E",
+"u c #070D04",
+"v c #0F1C09",
+"w c #102009",
+"x c #12230A",
+"y c #13250A",
+"z c #234413",
+"A c #15270C",
+"B c #13200C",
+" ",
+" ",
+" ..... ",
+" ..+@#@+.. ",
+" .+$%&&&&*=-- ",
+" .#%;>>>>,,')=! ~ ",
+" .+%>{]^^^^]>,/=! -! ",
+" .$>{(_!!!!{^]>/=!-:! ",
+"-+<[_}| 1!{^2/3:4! ",
+"-$567 !{^2890! ",
+"-abc !de2fg! ",
+" -hi -:jklm! ",
+" !-n -:opqrs! ",
+" -t ~!!!!!!!! ",
+" u-v ",
+" w-x ",
+" yzA ",
+" !-B ",
+" !!! ",
+" ",
+" ",
+" "};
diff --git a/muse_qt4_evolution/muse/xpm/resetS.xpm b/muse_qt4_evolution/muse/xpm/resetS.xpm
new file mode 100644
index 00000000..261af17e
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/resetS.xpm
@@ -0,0 +1,22 @@
+/* XPM */
+static const char *resetS_xpm[]={
+"16 16 3 1",
+"a c #000000",
+". c #c00000",
+"# c #ffffff",
+"................",
+"................",
+"..############..",
+"..####aa######..",
+"..###aaa######..",
+"..##aaaaaaaa##..",
+"..##aaaaaaaaa#..",
+"..###aaa##aaa#..",
+"..####aa###aa#..",
+"..#########aa#..",
+"..########aaa#..",
+"..##aaaaaaaaa#..",
+"..##aaaaaaaa##..",
+"..############..",
+"................",
+"................"};
diff --git a/muse_qt4_evolution/muse/xpm/rmark.xpm b/muse_qt4_evolution/muse/xpm/rmark.xpm
new file mode 100644
index 00000000..c0dbd780
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/rmark.xpm
@@ -0,0 +1,23 @@
+/* XPM */
+static const char* rmark_xpm[]={
+"18 18 2 1",
+"# c #0000ff",
+". c None",
+"..................",
+"..................",
+"..................",
+"..................",
+"..................",
+"..................",
+"..................",
+"........##########",
+"........#########.",
+"........########..",
+"........#######...",
+"........######....",
+"........#####.....",
+"........####......",
+"........###.......",
+"........##........",
+"........##........",
+"........##........"};
diff --git a/muse_qt4_evolution/muse/xpm/select.xpm b/muse_qt4_evolution/muse/xpm/select.xpm
new file mode 100644
index 00000000..a29f3370
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/select.xpm
@@ -0,0 +1,21 @@
+/* XPM */
+static const char *select_xpm[]={
+"16 16 2 1",
+". c #000000",
+"# c #ffffff",
+"..#..#..#..#..#.",
+"###############.",
+".###############",
+".##############.",
+"###############.",
+".###############",
+".##############.",
+"###############.",
+".###############",
+".##############.",
+"###############.",
+".###############",
+".##############.",
+"###############.",
+".###############",
+".#..#..#..#..#.."};
diff --git a/muse_qt4_evolution/muse/xpm/select_all.xpm b/muse_qt4_evolution/muse/xpm/select_all.xpm
new file mode 100644
index 00000000..b0133636
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/select_all.xpm
@@ -0,0 +1,21 @@
+/* XPM */
+static const char *select_all_xpm[]={
+"16 16 2 1",
+". c #000000",
+"# c #ffffff",
+"..#..#..#..#..#.",
+"###############.",
+".###############",
+".##############.",
+"###############.",
+".###############",
+".##############.",
+"###############.",
+".###############",
+".##############.",
+"###############.",
+".###############",
+".##############.",
+"###############.",
+".###############",
+".#..#..#..#..#.."};
diff --git a/muse_qt4_evolution/muse/xpm/select_all_parts_on_track.xpm b/muse_qt4_evolution/muse/xpm/select_all_parts_on_track.xpm
new file mode 100644
index 00000000..4761a256
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/select_all_parts_on_track.xpm
@@ -0,0 +1,39 @@
+/* XPM */
+static const char * select_all_parts_on_track_xpm[] = {
+"16 16 20 1",
+" c None",
+". c #000100",
+"+ c #FEFFFC",
+"@ c #FDF7F6",
+"# c #FFFFFF",
+"$ c #F8FEFF",
+"% c #F4F1E9",
+"& c #AA8747",
+"* c #9E772E",
+"= c #8A5C04",
+"- c #0F0F0F",
+"; c #000000",
+"> c #95702B",
+", c #CECECE",
+"' c #F3F3F3",
+") c #AE8E51",
+"! c #FDFDFD",
+"~ c #FCFCFC",
+"{ c #926716",
+"] c #2B2B2B",
+"..+..+..+..+..+.",
+"+++++++++++++++.",
+".@#############+",
+".+#############.",
+"$%#############.",
+".&*##=*##=*##=*#",
+"-;;;;;;;;;;;;;;;",
+">*,'=),,=*,,=*,#",
+"*,!=),,=*,,=*,#=",
+",~{*,#=*,#=*##=;",
+";;;;;;;];;;;;;;;",
+"#=*,#=*,#=*##=*#",
+".##############;",
+"###############;",
+".###############",
+".+..+..+..+..+.."};
diff --git a/muse_qt4_evolution/muse/xpm/select_deselect_all.xpm b/muse_qt4_evolution/muse/xpm/select_deselect_all.xpm
new file mode 100644
index 00000000..d3a9bce9
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/select_deselect_all.xpm
@@ -0,0 +1,22 @@
+/* XPM */
+static const char *select_deselect_all[]={
+"16 16 3 1",
+". c #000000",
+"a c #ff0000",
+"# c #ffffff",
+"..#..#..#..#..#.",
+"###############.",
+".#aa########aa##",
+".#aaa######aaa#.",
+"###aaa####aaa##.",
+".###aaa##aaa####",
+".####aaaaaa####.",
+"######aaaa#####.",
+".#####aaaa######",
+".####aaaaaa####.",
+"####aaa##aaa###.",
+".##aaa####aaa###",
+".#aaa######aaa#.",
+"##aa########aa#.",
+".###############",
+".#..#..#..#..#.."};
diff --git a/muse_qt4_evolution/muse/xpm/select_inside_loop.xpm b/muse_qt4_evolution/muse/xpm/select_inside_loop.xpm
new file mode 100644
index 00000000..46d57b28
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/select_inside_loop.xpm
@@ -0,0 +1,21 @@
+/* XPM */
+static const char *select_inside_loop_xpm[]={
+"16 16 2 1",
+". c #000000",
+"# c #ffffff",
+"................",
+"................",
+"....########....",
+"....#......#....",
+"....#......#....",
+".#######...#....",
+"..#####....#....",
+"...###.....#....",
+"....#.....###...",
+"....#....#####..",
+"....#...#######.",
+"....#......#....",
+"....#......#....",
+"....########....",
+"................",
+"................"};
diff --git a/muse_qt4_evolution/muse/xpm/select_invert_selection.xpm b/muse_qt4_evolution/muse/xpm/select_invert_selection.xpm
new file mode 100644
index 00000000..c2f11b55
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/select_invert_selection.xpm
@@ -0,0 +1,21 @@
+/* XPM */
+static const char *select_invert_selection[]={
+"16 16 2 1",
+". c #000000",
+"# c #ffffff",
+"................",
+"...............#",
+"..............##",
+"......#####..###",
+".....#######.###",
+"....#######..###",
+"...#######....##",
+"...######.....##",
+"...#####......##",
+"...####.......##",
+"...###........##",
+"....#........###",
+"............####",
+"...###.....#####",
+"..##############",
+".###############"};
diff --git a/muse_qt4_evolution/muse/xpm/select_outside_loop.xpm b/muse_qt4_evolution/muse/xpm/select_outside_loop.xpm
new file mode 100644
index 00000000..555b6157
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/select_outside_loop.xpm
@@ -0,0 +1,21 @@
+/* XPM */
+static const char *select_outside_loop_xpm[]={
+"16 16 2 1",
+"# c #000000",
+". c #ffffff",
+"................",
+"................",
+"....########....",
+"....#......#....",
+"....#......#....",
+".#######...#....",
+"..#####....#....",
+"...###.....#....",
+"....#.....###...",
+"....#....#####..",
+"....#...#######.",
+"....#......#....",
+"....#......#....",
+"....########....",
+"................",
+"................"};
diff --git a/muse_qt4_evolution/muse/xpm/settings_appearance_settings.xpm b/muse_qt4_evolution/muse/xpm/settings_appearance_settings.xpm
new file mode 100644
index 00000000..46dcc335
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/settings_appearance_settings.xpm
@@ -0,0 +1,66 @@
+/* XPM */
+static const char * settings_appearance_settings_xpm[] = {
+"16 16 47 1",
+" c None",
+". c #000000",
+"+ c #A80000",
+"@ c #B60000",
+"# c #D40000",
+"$ c #93440B",
+"% c #A44C0C",
+"& c #B7550D",
+"* c #E56A10",
+"= c #CD5F0E",
+"- c #C9CC00",
+"; c #FCFF00",
+"> c #B4B600",
+", c #A1A300",
+"' c #CC0000",
+") c #E40000",
+"! c #E1E400",
+"~ c #909200",
+"{ c #4E8F00",
+"] c #61B300",
+"^ c #57A000",
+"/ c #B000B6",
+"( c #6CC800",
+"_ c #79E000",
+": c #DC00E4",
+"< c #C500CC",
+"[ c #9D00A3",
+"} c #009836",
+"| c #468000",
+"1 c #7D0083",
+"2 c #1B687D",
+"3 c #008830",
+"4 c #22829D",
+"5 c #00D44B",
+"6 c #00AA3C",
+"7 c #250492",
+"8 c #3304CB",
+"9 c #2E04B6",
+"0 c #3905E3",
+"a c #2904A3",
+"b c #2691B0",
+"c c #2AA2C5",
+"d c #00ED54",
+"e c #00BE43",
+"f c #2FB5DC",
+"g c #185D70",
+"h c #1E748C",
+"................",
+".+@#.$%&*=.-;>,.",
+".'').==*=.--!->.",
+".')).===.~!-!;-.",
+".))).=&.........",
+"..)'.&....{]^]{.",
+"./.).......((_].",
+".:<.........(((.",
+".:::.........]^.",
+"./[::.......}.|.",
+".1<:<[....2.}3..",
+".........44.556.",
+".78908a.bbc.d5e.",
+".88888.4fbc.6de.",
+".aa09.ghcc4.3e6.",
+"................"};
diff --git a/muse_qt4_evolution/muse/xpm/settings_configureshortcuts.xpm b/muse_qt4_evolution/muse/xpm/settings_configureshortcuts.xpm
new file mode 100644
index 00000000..bd858629
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/settings_configureshortcuts.xpm
@@ -0,0 +1,36 @@
+/* XPM */
+static const char *settings_configureshortcuts_xpm[] = {
+"16 16 17 1",
+" c None",
+". c #000000",
+"+ c #808080",
+"@ c #646464",
+"# c #DCDCDC",
+"$ c #C3C3C3",
+"% c #A0A0A0",
+"& c #B8B8B8",
+"* c #787878",
+"= c #FFFFFF",
+"- c #EDEDED",
+"; c #585858",
+"> c #C2C2C2",
+", c #B7B7B7",
+"' c #E7E7E7",
+") c #303030",
+"! c #CFCFCF",
+" ...... ",
+" .+@#$%.. ",
+" .&*@#$%. ",
+"... ..&@#$. ",
+".=$.. .@##%. ",
+".=-#$.;@>##,. ",
+".@=-######'$%.. ",
+")=@*=--##'$!$%%.",
+".$#=@@@*%$-#!$,%",
+" ..$#$$$*@*=-#!$",
+" ...%#$$%@*=-#",
+" ....-#%@*=",
+" ..-#%@",
+" ..-#",
+" ..",
+" "};
diff --git a/muse_qt4_evolution/muse/xpm/settings_follow_song.xpm b/muse_qt4_evolution/muse/xpm/settings_follow_song.xpm
new file mode 100644
index 00000000..9a066715
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/settings_follow_song.xpm
@@ -0,0 +1,30 @@
+/* XPM */
+static const char * settings_follow_song_xpm[] = {
+"16 16 11 1",
+" c None",
+". c #545454",
+"+ c #202020",
+"@ c #696969",
+"# c #7C7C7C",
+"$ c #000000",
+"% c #3C3C3C",
+"& c #C3C3C3",
+"* c #CBCBCB",
+"= c #8C8C8C",
+"- c #DCDCDC",
+" ",
+" .+@ ",
+" #$+%& ",
+" .$$+&#%% ",
+" .$$+&@$.. ",
+" .$$$&%$+@& ",
+" +$$$&%$+%& ",
+" $$$$&$$+%& ",
+" $$$+&+$$$& ",
+" $+@&++$$& ",
+" **&+$$$& ",
+" .$@&=.+&& ",
+" +$$& &&& ",
+" &&&.$@ ",
+" -- $++ ",
+" --- -- "};
diff --git a/muse_qt4_evolution/muse/xpm/settings_globalsettings.xpm b/muse_qt4_evolution/muse/xpm/settings_globalsettings.xpm
new file mode 100644
index 00000000..2593ee83
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/settings_globalsettings.xpm
@@ -0,0 +1,89 @@
+/* XPM */
+static const char * settings_globalsettings_xpm[] = {
+"16 16 70 1",
+" c None",
+". c #BDBDBD",
+"+ c #000000",
+"@ c #B0B0B0",
+"# c #ABABAB",
+"$ c #CAC8C1",
+"% c #B5B5B5",
+"& c #EBEBE8",
+"* c #D7D7D7",
+"= c #D8D8D8",
+"- c #C4C4C4",
+"; c #F9F8F8",
+"> c #BBBBBB",
+", c #828282",
+"' c #D2D0CC",
+") c #F7F7F7",
+"! c #DEDBD6",
+"~ c #9C9C9C",
+"{ c #7B7B7B",
+"] c #7D7D7D",
+"^ c #D2D2D2",
+"/ c #D3D2CF",
+"( c #E3E2E1",
+"_ c #DFDEDC",
+": c #DBDAD7",
+"< c #A4A19C",
+"[ c #5F5F5F",
+"} c #292929",
+"| c #D3D3D3",
+"1 c #1C1C1C",
+"2 c #D2D1D0",
+"3 c #50504F",
+"4 c #101010",
+"5 c #3A3A3A",
+"6 c #494746",
+"7 c #D1D1D1",
+"8 c #DADADA",
+"9 c #363636",
+"0 c #C8C7C6",
+"a c #6C6967",
+"b c #CCCCCC",
+"c c #708295",
+"d c #CFD6DD",
+"e c #7C91A7",
+"f c #D6D5D5",
+"g c #8A8784",
+"h c #C9C9C9",
+"i c #7D8C9C",
+"j c #788DA4",
+"k c #7F99B3",
+"l c #1F272F",
+"m c #ECEBEA",
+"n c #72706D",
+"o c #CBCBCB",
+"p c #8D99A5",
+"q c #748AA2",
+"r c #849EB9",
+"s c #4D5F73",
+"t c #D5D4D3",
+"u c #6B6A69",
+"v c #7D91A7",
+"w c #849EBA",
+"x c #D6D6D6",
+"y c #525252",
+"z c #717171",
+"A c #484848",
+"B c #66798F",
+"C c #CACACA",
+"D c #6F6F6F",
+"E c #8D8D8D",
+" ",
+" .+@ #+#",
+" +$+# #+%+",
+" +&+* +=+#",
+" -+ +;+> ,++# ",
+" +'++)!+~ {+] ",
+" ^+/(_:<+[}{ ",
+" |+1++23+[ ",
+" 456+78 ",
+" +++9+0a+b ",
+" +cde+ +fg+h8 ",
+" +idjkl -+mn+o ",
+" +pdqrs+ +tu+b",
+" +dvws+^ x+2yz",
+" AvBs+C ++D",
+" EA++> "};
diff --git a/muse_qt4_evolution/muse/xpm/settings_metronome.xpm b/muse_qt4_evolution/muse/xpm/settings_metronome.xpm
new file mode 100644
index 00000000..985b1910
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/settings_metronome.xpm
@@ -0,0 +1,99 @@
+/* XPM */
+static const char * settings_metronome_xpm[] = {
+"16 16 80 1",
+" c None",
+". c #C4B71A",
+"+ c #BAAE17",
+"@ c #B4AA40",
+"# c #D1C440",
+"$ c #E0D123",
+"% c #87824B",
+"& c #E9D926",
+"* c #F8E407",
+"= c #F9E60D",
+"- c #752D08",
+"; c #9D3D0B",
+"> c #82330A",
+", c #6D2B08",
+"' c #FCEE4E",
+") c #612607",
+"! c #813308",
+"~ c #DCD05F",
+"{ c #EADC49",
+"] c #933A09",
+"^ c #712D07",
+"/ c #6F5E58",
+"( c #2A1006",
+"_ c #C04B0C",
+": c #FCEB2D",
+"< c #6D2B07",
+"[ c #4E3826",
+"} c #FCEF5D",
+"| c #F7EA49",
+"1 c #470A31",
+"2 c #7A3108",
+"3 c #752F07",
+"4 c #704517",
+"5 c #F1E132",
+"6 c #FBED4A",
+"7 c #F1E141",
+"8 c #7C3B3A",
+"9 c #BC6130",
+"0 c #7F3F0A",
+"a c #482B0E",
+"b c #F5E537",
+"c c #ECDB33",
+"d c #51142E",
+"e c #8E5C41",
+"f c #A8420A",
+"g c #612D07",
+"h c #43260A",
+"i c #50350F",
+"j c #673013",
+"k c #A95A2E",
+"l c #693208",
+"m c #281003",
+"n c #341403",
+"o c #C1500D",
+"p c #B9541A",
+"q c #B85C29",
+"r c #706914",
+"s c #120803",
+"t c #331608",
+"u c #774A33",
+"v c #62290A",
+"w c #B6AA20",
+"x c #131307",
+"y c #2C1103",
+"z c #662F12",
+"A c #743008",
+"B c #7D3E1B",
+"C c #251309",
+"D c #331809",
+"E c #BA6334",
+"F c #B75D2C",
+"G c #73300B",
+"H c #793A17",
+"I c #7F3208",
+"J c #903909",
+"K c #883609",
+"L c #622809",
+"M c #371908",
+"N c #4D2108",
+"O c #722E07",
+" .+ ",
+" @#$% ",
+" &*=& ",
+" -;;> ",
+" ,'') ",
+" !,~{]^ /( ",
+" ^_:~_< [}|1",
+" 2^_{~_345678",
+" ^]9{{_0abcd ",
+" e;_f'{_ghid ",
+" jf_k{:lmno ",
+" j_pq_{rstq_u ",
+" vf_f_wxy]f_z ",
+" AApqpBCDEFpqGA ",
+" HHIJKLMNOOO^HH ",
+" aaaaaaaaaaaaaa"};
diff --git a/muse_qt4_evolution/muse/xpm/settings_midifileexport.xpm b/muse_qt4_evolution/muse/xpm/settings_midifileexport.xpm
new file mode 100644
index 00000000..ec65b59d
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/settings_midifileexport.xpm
@@ -0,0 +1,30 @@
+/* XPM */
+static const char * settings_midifileexport_xpm[] = {
+"16 16 11 1",
+" c None",
+". c #292929",
+"+ c #000000",
+"@ c #676767",
+"# c #C9C9C9",
+"$ c #793C11",
+"% c #994C15",
+"& c #C2611B",
+"* c #4F270B",
+"= c #371B07",
+"- c #5F2F0D",
+" ",
+" . ",
+" ++ ",
+" +@+ ",
+" +#+# ",
+" +### ",
+" +# ++++++++",
+" +# +$%&&%$++",
+" +# +$%&&%$+$+",
+" +++#++++++++$$+",
+"++++#+$$%&%$+%&+",
+"++++#+*$$$$%+&$+",
+" ####+&$$=$%+$+#",
+" +$$%&%-++##",
+" ++++++++## ",
+" ######## "};
diff --git a/muse_qt4_evolution/muse/xpm/settings_midiport_softsynths.xpm b/muse_qt4_evolution/muse/xpm/settings_midiport_softsynths.xpm
new file mode 100644
index 00000000..b637e5c1
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/settings_midiport_softsynths.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static const char * settings_midiport_softsynths_xpm[] = {
+"16 16 10 1",
+" c None",
+". c #000000",
+"+ c #CECECE",
+"@ c #313131",
+"# c #939393",
+"$ c #797979",
+"% c #595959",
+"& c #282828",
+"* c #A6A6A6",
+"= c #484848",
+" .... ",
+" . . ",
+" .. ..+ ",
+" @..@+ ",
+" #..$+ ",
+" ...... ",
+" ..+++ ",
+" ..+ ",
+" $$ ..+$$ ",
+" ... ..+ ... ",
+" ..$ ..+ $.. ",
+" $.%.. ..+..$.$ ",
+" $ +&......@++$ ",
+" *=....%++ ",
+" =..=++ ",
+" ++++ "};
diff --git a/muse_qt4_evolution/muse/xpm/settings_midisync.xpm b/muse_qt4_evolution/muse/xpm/settings_midisync.xpm
new file mode 100644
index 00000000..3bfdb180
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/settings_midisync.xpm
@@ -0,0 +1,53 @@
+/* XPM */
+static const char * settings_midisync_xpm[] = {
+"16 16 34 1",
+" c None",
+". c #7C7C7C",
+"+ c #787878",
+"@ c #818181",
+"# c #747474",
+"$ c #757575",
+"% c #000000",
+"& c #636363",
+"* c #8C8C8C",
+"= c #909090",
+"- c #939393",
+"; c #8A8A8A",
+"> c #7F7F7F",
+", c #9A9A9A",
+"' c #777777",
+") c #949494",
+"! c #828282",
+"~ c #9E9E9E",
+"{ c #999999",
+"] c #888888",
+"^ c #979797",
+"/ c #929292",
+"( c #969696",
+"_ c #9B9B9B",
+": c #858585",
+"< c #848484",
+"[ c #898989",
+"} c #7A7A7A",
+"| c #7E7E7E",
+"1 c #808080",
+"2 c #838383",
+"3 c #737373",
+"4 c #6A6A6A",
+"5 c #676767",
+" ",
+" ",
+" .+@#$% ",
+" & **% ",
+" =% ",
+" +% #% ",
+" -;>% >% ",
+" +;,'.% )!-~{)]%",
+"^/(_{-]% :,<[!% ",
+" }@% .|>% ",
+" 12% <% ",
+" }<%% ",
+" 34% 4% ",
+" }55}% ",
+" ",
+" "};
diff --git a/muse_qt4_evolution/muse/xpm/solobutton.xpm b/muse_qt4_evolution/muse/xpm/solobutton.xpm
new file mode 100644
index 00000000..e0c1002a
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/solobutton.xpm
@@ -0,0 +1,39 @@
+/* XPM */
+static const char * solobutton_xpm[] = {
+"22 22 14 1",
+" c None",
+". c #000000",
+"+ c #F10606",
+"@ c #414141",
+"# c #852A2A",
+"$ c #473E3E",
+"% c #723030",
+"& c #CB1212",
+"* c #4E3C3C",
+"= c #E20A0A",
+"- c #A51F1F",
+"; c #9E2121",
+"> c #832A2A",
+", c #9C2222",
+"......................",
+". .",
+". .",
+". .",
+". + .",
+". ++ .",
+". +++ .",
+". @@@@@@@@@#+++ .",
+". $@@@@@@@%++& .",
+". *$ ++=@ .",
+". +- +++;@ .",
+". >++ ++++@@ .",
+". @+++ +++ @@ .",
+". @@+++++++ @@ .",
+". @@ +++++ @@ .",
+". @@ ++++ @@ .",
+". @@ ++ @@ .",
+". @@@@@,+@@@@@ .",
+". @@@@@@@@@@@@ .",
+". .",
+". .",
+"......................"};
diff --git a/muse_qt4_evolution/muse/xpm/solobutton_off.xpm b/muse_qt4_evolution/muse/xpm/solobutton_off.xpm
new file mode 100644
index 00000000..31cc8e5a
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/solobutton_off.xpm
@@ -0,0 +1,146 @@
+/* XPM */
+static const char * solobutton_off_xpm[] = {
+"22 22 121 2",
+" c #000000",
+". c #720000",
+"+ c #7B0000",
+"@ c #810000",
+"# c #840000",
+"$ c #870000",
+"% c #8D0000",
+"& c #930000",
+"* c #980000",
+"= c #9C0000",
+"- c #9B0000",
+"; c #970000",
+"> c #900000",
+", c #8C0000",
+"' c #850000",
+") c #800000",
+"! c #760000",
+"~ c #730000",
+"{ c #710000",
+"] c #770000",
+"^ c #A10000",
+"/ c #A90000",
+"( c #AE0000",
+"_ c #B10000",
+": c #B60000",
+"< c #B50000",
+"[ c #B30000",
+"} c #AC0000",
+"| c #A70000",
+"1 c #9E0000",
+"2 c #8F0000",
+"3 c #890000",
+"4 c #7F0000",
+"5 c #7A0000",
+"6 c #7C0000",
+"7 c #8E0000",
+"8 c #A00000",
+"9 c #AD0000",
+"0 c #B80000",
+"a c #C00000",
+"b c #C60000",
+"c c #C80000",
+"d c #CB0000",
+"e c #C70000",
+"f c #BB0000",
+"g c #B20000",
+"h c #A30000",
+"i c #960000",
+"j c #860000",
+"k c #920000",
+"l c #BA0000",
+"m c #C50000",
+"n c #CE0000",
+"o c #D40000",
+"p c #D80000",
+"q c #D70000",
+"r c #DA0000",
+"s c #D10000",
+"t c #C90000",
+"u c #C30000",
+"v c #B40000",
+"w c #A40000",
+"x c #910000",
+"y c #7D0000",
+"z c #950000",
+"A c #AB0000",
+"B c #BD0000",
+"C c #CC0000",
+"D c #D60000",
+"E c #DF0000",
+"F c #E30000",
+"G c #E10000",
+"H c #DC0000",
+"I c #D00000",
+"J c #C20000",
+"K c #BC0000",
+"L c #A50000",
+"M c #AF0000",
+"N c #414141",
+"O c #CD0000",
+"P c #B90000",
+"Q c #AA0000",
+"R c #9A0000",
+"S c #473E3E",
+"T c #D10100",
+"U c #A80000",
+"V c #880000",
+"W c #D20000",
+"X c #E50000",
+"Y c #E80000",
+"Z c #E40200",
+"` c #D50100",
+" . c #D50000",
+".. c #D90000",
+"+. c #DE0000",
+"@. c #E20000",
+"#. c #E40000",
+"$. c #E70000",
+"%. c #E90000",
+"&. c #DB0000",
+"*. c #CA0000",
+"=. c #BE0000",
+"-. c #E00000",
+";. c #E60000",
+">. c #7E0000",
+",. c #DD0000",
+"'. c #BF0000",
+"). c #D30000",
+"!. c #990000",
+"~. c #B00000",
+"{. c #940000",
+"]. c #7A0100",
+"^. c #A60000",
+"/. c #9D0000",
+"(. c #9D0101",
+"_. c #7B0200",
+":. c #8C0100",
+"<. c #9E0101",
+"[. c #8F0101",
+"}. c #7F0101",
+"|. c #720101",
+" ",
+" . + @ # $ % & & * = - ; > , ' ) + ! ~ { ",
+" ] $ & - ^ / ( _ : < [ } | 1 * 2 3 # 4 5 ",
+" 6 7 8 9 0 a b b c d e a f g / h - i 7 j ",
+" 6 k | l m n o p q r q s t u f v 9 w - x ",
+" y z A B C D r E F F G H q I d J K g L z ",
+" ) * M N N N N N N N N N N N N O m P Q i ",
+" # R _ S N N N N N N N N N N N T t f U & ",
+" V 8 : N N W p r E X Y X Z N N ` C f L % ",
+" % L l N N ...r +.@.#.$.%.N N q d 0 ^ 3 ",
+" > / K N N p p r &.+.@.#.Y N N p *.< - @ ",
+" > / =.N N H &.&.&.&.E -.;.N N ..t g R >. ",
+" x U =.N N &.,.&.p ..r H E N N p t [ i 6 ",
+" 2 U '.N N &.+...D . ...,.N N q c _ i y ",
+" % w f N N p &.D ).).). .r N N q t g i >. ",
+" V 8 : N N ).D ).s I ).D H N N D e g ; >. ",
+" # !.~.N N N N N N N N N N N N o e ~.; >. ",
+" 4 & / N N N N N N N N N N N N n J 9 {.y ",
+" ].x h g l f '.=.a m t O ).).I c f ^.> + ",
+" ].% /.Q M [ [ v 0 f '.u e b u l ~.(.$ ! ",
+" _.:.!.8 ^.L L ^.Q A ~.[ < v M U <.[.}.|. ",
+" "};
diff --git a/muse_qt4_evolution/muse/xpm/solobutton_on.xpm b/muse_qt4_evolution/muse/xpm/solobutton_on.xpm
new file mode 100644
index 00000000..c53e5884
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/solobutton_on.xpm
@@ -0,0 +1,300 @@
+/* XPM */
+static const char * solobutton_on_xpm[] = {
+"22 22 275 2",
+" c #000000",
+". c #066714",
+"+ c #056613",
+"@ c #076915",
+"# c #076A15",
+"$ c #076A16",
+"% c #086B17",
+"& c #096C18",
+"* c #066B15",
+"= c #066B14",
+"- c #076F17",
+"; c #0C751C",
+"> c #107B20",
+", c #0F7C1F",
+"' c #0D791D",
+") c #097318",
+"! c #066E15",
+"~ c #066C14",
+"{ c #066814",
+"] c #086B16",
+"^ c #0A6F19",
+"/ c #0B711A",
+"( c #0B721B",
+"_ c #0C731C",
+": c #0C731B",
+"< c #0A731A",
+"[ c #097219",
+"} c #077318",
+"| c #0A781B",
+"1 c #0E7E1F",
+"2 c #118522",
+"3 c #128722",
+"4 c #0F8321",
+"5 c #0B7D1B",
+"6 c #077517",
+"7 c #067016",
+"8 c #056713",
+"9 c #066914",
+"0 c #086D17",
+"a c #0A721A",
+"b c #0F771E",
+"c c #107A20",
+"d c #117D21",
+"e c #127E21",
+"f c #117F21",
+"g c #0E7D1F",
+"h c #0D801E",
+"i c #0F8620",
+"j c #128F25",
+"k c #159627",
+"l c #169828",
+"m c #159427",
+"n c #F10606",
+"o c #0B821C",
+"p c #087718",
+"q c #086E17",
+"r c #0B731A",
+"s c #0F791F",
+"t c #138223",
+"u c #168727",
+"v c #188A29",
+"w c #178D28",
+"x c #168D27",
+"y c #158C26",
+"z c #128D25",
+"A c #129125",
+"B c #149926",
+"C c #17A22B",
+"D c #19AA2D",
+"E c #1AAC2E",
+"F c #119122",
+"G c #0C831D",
+"H c #066D15",
+"I c #0A7119",
+"J c #0C7A1D",
+"K c #118323",
+"L c #178D29",
+"M c #1B952E",
+"N c #1B9C2E",
+"O c #1A9E2E",
+"P c #199C2B",
+"Q c #189D2B",
+"R c #189E2B",
+"S c #17A32C",
+"T c #18AC2E",
+"U c #19B630",
+"V c #1CC033",
+"W c #16A22A",
+"X c #129025",
+"Y c #097519",
+"Z c #0F801F",
+"` c #158E27",
+" . c #414141",
+".. c #852A2A",
+"+. c #1CC335",
+"@. c #19B130",
+"#. c #179C2A",
+"$. c #067015",
+"%. c #097A1A",
+"&. c #108922",
+"*. c #17982A",
+"=. c #473E3E",
+"-. c #723030",
+";. c #CB1212",
+">. c #1CDA38",
+",. c #1DD038",
+"'. c #1BB832",
+"). c #19A22D",
+"!. c #067215",
+"~. c #0A7F1B",
+"{. c #119124",
+"]. c #18A22D",
+"^. c #4E3C3C",
+"/. c #1BCB35",
+"(. c #1ACD35",
+"_. c #19CB34",
+":. c #1AC932",
+"<. c #18C833",
+"[. c #18CC33",
+"}. c #E20A0A",
+"|. c #1BDF37",
+"1. c #1CD136",
+"2. c #1CBD35",
+"3. c #19A42E",
+"4. c #087618",
+"5. c #0B821D",
+"6. c #129725",
+"7. c #A51F1F",
+"8. c #18D435",
+"9. c #18D433",
+"0. c #18D333",
+"a. c #18D033",
+"b. c #19CE33",
+"c. c #9E2121",
+"d. c #19DB36",
+"e. c #1ACF36",
+"f. c #1BBB33",
+"g. c #1AA22E",
+"h. c #087818",
+"i. c #0C861E",
+"j. c #129B26",
+"k. c #18B12F",
+"l. c #832A2A",
+"m. c #19D833",
+"n. c #17D433",
+"o. c #19D534",
+"p. c #1ACB34",
+"q. c #1AB832",
+"r. c #199F2D",
+"s. c #087918",
+"t. c #0D891F",
+"u. c #129C26",
+"v. c #17B22F",
+"w. c #17D232",
+"x. c #16D531",
+"y. c #19D034",
+"z. c #18C432",
+"A. c #19B230",
+"B. c #169A2A",
+"C. c #087A19",
+"D. c #0D881F",
+"E. c #139C27",
+"F. c #17AF2D",
+"G. c #14D130",
+"H. c #16CC31",
+"I. c #18C132",
+"J. c #18B02E",
+"K. c #159828",
+"L. c #0A7A1A",
+"M. c #149C27",
+"N. c #17AE2D",
+"O. c #16C830",
+"P. c #14CD2E",
+"Q. c #14CE30",
+"R. c #17CA31",
+"S. c #15BF2F",
+"T. c #15AE2B",
+"U. c #129624",
+"V. c #0E8821",
+"W. c #17AD2E",
+"X. c #17C730",
+"Y. c #16CA31",
+"Z. c #15C92E",
+"`. c #14CB2E",
+" + c #14C72E",
+".+ c #14BD2C",
+"++ c #11AD29",
+"@+ c #0F9423",
+"#+ c #0B7B1A",
+"$+ c #0F8720",
+"%+ c #139B26",
+"&+ c #16AA2B",
+"*+ c #17C72F",
+"=+ c #15CB30",
+"-+ c #15CC31",
+";+ c #15C82F",
+">+ c #16C730",
+",+ c #11C52C",
+"'+ c #10BA29",
+")+ c #0FA825",
+"!+ c #0C9020",
+"~+ c #0B791C",
+"{+ c #0D871F",
+"]+ c #119625",
+"^+ c #15A82A",
+"/+ c #9C2222",
+"(+ c #10C02A",
+"_+ c #0EB526",
+":+ c #0DA322",
+"<+ c #0A8D1D",
+"[+ c #097419",
+"}+ c #0E9121",
+"|+ c #11A126",
+"1+ c #0EB426",
+"2+ c #0DAA23",
+"3+ c #0B9A20",
+"4+ c #08871B",
+"5+ c #077217",
+"6+ c #0A871D",
+"7+ c #0D9521",
+"8+ c #10A425",
+"9+ c #11AE27",
+"0+ c #11B228",
+"a+ c #12B529",
+"b+ c #11B628",
+"c+ c #10B429",
+"d+ c #10B227",
+"e+ c #10AF27",
+"f+ c #10AC27",
+"g+ c #0FAB26",
+"h+ c #0EA824",
+"i+ c #0DA624",
+"j+ c #0CA221",
+"k+ c #0B9C20",
+"l+ c #088F1C",
+"m+ c #068018",
+"n+ c #056D13",
+"o+ c #057214",
+"p+ c #067A17",
+"q+ c #09841B",
+"r+ c #0C911E",
+"s+ c #0D9921",
+"t+ c #0E9F22",
+"u+ c #0EA123",
+"v+ c #0DA222",
+"w+ c #0DA123",
+"x+ c #0C9C21",
+"y+ c #0B981F",
+"z+ c #0C971F",
+"A+ c #0C951F",
+"B+ c #0B931F",
+"C+ c #0A911E",
+"D+ c #088E1C",
+"E+ c #07891A",
+"F+ c #058218",
+"G+ c #047715",
+"H+ c #036812",
+"I+ c #046C12",
+"J+ c #047014",
+"K+ c #057615",
+"L+ c #077D19",
+"M+ c #09831B",
+"N+ c #09871C",
+"O+ c #08891C",
+"P+ c #088A1B",
+"Q+ c #078619",
+"R+ c #078419",
+"S+ c #078018",
+"T+ c #067D18",
+"U+ c #067C18",
+"V+ c #067D17",
+"W+ c #057B16",
+"X+ c #047815",
+"Y+ c #037313",
+"Z+ c #036D12",
+" ",
+" . + + . @ # $ % & % * = - ; > , ' ) ! ~ ",
+" . + { ] ^ / ( _ : < [ } | 1 2 3 4 5 6 7 ",
+" 8 9 0 a b c d e f g 1 h i j k l m n o p ",
+" { q r s t u v w x y z A B C D E n n F G ",
+" H I J K L M N O P Q R S T U V n n n W X ",
+" H Y Z ` . . . . . . . . ...n n n +.@.#. ",
+" $.%.&.*.=. . . . . . . .-.n n ;.>.,.'.). ",
+" !.~.{.].^.=./.(._.:.<.[.n n }. .|.1.2.3. ",
+" 4.5.6.T n 7.8.9.0.a.b.n n n c. .d.e.f.g. ",
+" h.i.j.k.l.n n m.n.0.n n n n . .o.p.q.r. ",
+" s.t.u.v. .n n n w.w.n n n x. . .y.z.A.B. ",
+" C.D.E.F. . .n n n n n n n G. . .H.I.J.K. ",
+" L.t.M.N. . .O.n n n n n P.Q. . .R.S.T.U. ",
+" L.V.M.W. . .X.Y.n n n n Z.`. . . +.+++@+ ",
+" #+$+%+&+ . .*+=+-+n n ;+>+;+ . .,+'+)+!+ ",
+" ~+{+]+^+ . . . . ./+n . . . . .(+_+:+<+ ",
+" [+5.}+|+ . . . . . . . . . . . .1+2+3+4+ ",
+" 5+C.6+7+8+9+0+a+b+c+d+e+f+g+h+i+j+k+l+m+ ",
+" n+o+p+q+r+s+t+u+v+w+x+y+z+A+B+C+D+E+F+G+ ",
+" H+I+J+K+L+M+N+O+P+E+Q+R+S+T+U+V+W+X+Y+Z+ ",
+" "};
diff --git a/muse_qt4_evolution/muse/xpm/speaker.xpm b/muse_qt4_evolution/muse/xpm/speaker.xpm
new file mode 100644
index 00000000..1595e298
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/speaker.xpm
@@ -0,0 +1,23 @@
+/* XPM */
+static const char * speaker_xpm[] = {
+"18 18 2 1",
+" c None",
+". c #000000",
+" ",
+" .. ",
+" . . ",
+" . . ",
+" . . ",
+" ..... . ",
+" . . ",
+" . . ",
+" . . ",
+" . . ",
+" . . ",
+" . . ",
+" ..... . ",
+" . . ",
+" . . ",
+" . . ",
+" .. ",
+" "};
diff --git a/muse_qt4_evolution/muse/xpm/splash.png b/muse_qt4_evolution/muse/xpm/splash.png
new file mode 100644
index 00000000..077e305e
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/splash.png
Binary files differ
diff --git a/muse_qt4_evolution/muse/xpm/start.xpm b/muse_qt4_evolution/muse/xpm/start.xpm
new file mode 100644
index 00000000..cc5b8f9c
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/start.xpm
@@ -0,0 +1,17 @@
+/* XPM */
+static const char * start_xpm[] = {
+"17 12 2 1",
+" c None",
+". c #000000",
+" .... . ",
+" .... ... ",
+" .... ... ",
+" .... .... ",
+" .... .... ",
+" .... ..... ",
+" .... ..... ",
+" .... .... ",
+" .... .... ",
+" .... ... ",
+" .... ... ",
+" .... . "};
diff --git a/muse_qt4_evolution/muse/xpm/steprec.xpm b/muse_qt4_evolution/muse/xpm/steprec.xpm
new file mode 100644
index 00000000..4c606c15
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/steprec.xpm
@@ -0,0 +1,24 @@
+/* XPM */
+static const char* steprec_xpm[]={
+"18 18 3 1",
+". c None",
+"a c #ffffff",
+"# c #ff0000",
+"......#####.......",
+"....##aaaaa##.....",
+"...#aaa####aa#....",
+"..#aa########a#...",
+".#aaa##aaaa##aa#..",
+".#aaa##aaaaaaaa#..",
+"#aaaa##aaaaaaaaa#.",
+"#aaaaa#####aaaaa#.",
+"#aaaaaa#####aaaa#.",
+"#aaaaaaaaaa##aaa#.",
+"#aaaa#aaaaa##aaa#.",
+".#aaa##aaaa##aa#..",
+".#aaaa#######aa#..",
+"..#aaaa#####aa#...",
+"...#aaaaaaaaa#....",
+"....##aaaaa##.....",
+"......#####.......",
+".................."};
diff --git a/muse_qt4_evolution/muse/xpm/stereo.svg b/muse_qt4_evolution/muse/xpm/stereo.svg
new file mode 100644
index 00000000..2d222f61
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/stereo.svg
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.0"
+ width="16"
+ height="16"
+ id="svg1307"
+ sodipodi:version="0.32"
+ inkscape:version="0.45"
+ sodipodi:docname="stereo.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ sodipodi:docbase="/home/ws/projects/muse/muse/trunk/muse/muse/xpm"
+ sodipodi:modified="true">
+ <metadata
+ id="metadata8">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <sodipodi:namedview
+ inkscape:window-height="591"
+ inkscape:window-width="907"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ guidetolerance="10.0"
+ gridtolerance="10.0"
+ objecttolerance="10.0"
+ borderopacity="1.0"
+ bordercolor="#666666"
+ pagecolor="#ffffff"
+ id="base"
+ width="16px"
+ height="16px"
+ inkscape:zoom="18.9"
+ inkscape:cx="16.5"
+ inkscape:cy="10"
+ inkscape:window-x="20"
+ inkscape:window-y="266"
+ inkscape:current-layer="svg1307" />
+ <defs
+ id="defs1309" />
+ <g
+ id="layer1"
+ transform="matrix(0.6319982,0,0,0.6402952,-2.3836027,1.951611)">
+ <path
+ d="M 16.797341,15.398537 C 13.77507,17.399581 9.4702685,17.114643 6.8442934,14.739737 C 4.2183184,12.364831 4.1274584,8.6743768 6.6342179,6.2071094 C 9.1409773,3.739842 13.427942,3.3002982 16.546025,5.1908488"
+ transform="matrix(1,0,0,1.161391,9.876871e-2,-2.446221)"
+ style="fill:#ff0000;fill-opacity:0;stroke:#3e3e3e;stroke-width:2.26799989;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="path1317" />
+ <path
+ d="M 19.679144,10.374331 C 19.679144,13.883961 16.351207,16.729079 12.245989,16.729079 C 8.1407707,16.729079 4.8128338,13.883961 4.8128338,10.374331 C 4.8128338,6.8647007 8.1407707,4.0195832 12.245989,4.0195832 C 16.351207,4.0195832 19.679144,6.8647007 19.679144,10.374331 z "
+ transform="matrix(1,0,0,1.161391,8.098769,-2.446221)"
+ style="fill:#ff0000;fill-opacity:0;stroke:#3e3e3e;stroke-width:2.26799989;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="path2192" />
+ </g>
+</svg>
diff --git a/muse_qt4_evolution/muse/xpm/stick.xpm b/muse_qt4_evolution/muse/xpm/stick.xpm
new file mode 100644
index 00000000..b5817f1f
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/stick.xpm
@@ -0,0 +1,33 @@
+/* XPM */
+static const char * stick_xpm[] = {
+"16 16 14 1",
+" c None",
+". c #000100",
+"+ c #9FA19E",
+"@ c #A29FA3",
+"# c #2F312E",
+"$ c #878A8A",
+"% c #ABAFB0",
+"& c #DDE2E5",
+"* c #6D706F",
+"= c #6D6F6C",
+"- c #D3D8DA",
+"; c #C2C4C0",
+"> c #7F817E",
+", c #868885",
+" . ",
+" ..+ ",
+" ..@+ . ",
+" ..++ ..+",
+" ..@@ ..++",
+" ##...## ..++ ",
+" .$%..$$...@@ ",
+" #$%&&&%...++ ",
+" ##$%&%$..#@ ",
+" #*#####..#@ ",
+" #*$&&%$=#..... ",
+" #*%&&&-*..;@;>.",
+" #$&&%,##.>;;..",
+" ###### ......",
+" .+>>. ",
+" ... "};
diff --git a/muse_qt4_evolution/muse/xpm/stop.xpm b/muse_qt4_evolution/muse/xpm/stop.xpm
new file mode 100644
index 00000000..c4c5dbe2
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/stop.xpm
@@ -0,0 +1,17 @@
+/* XPM */
+static const char * stop_xpm[] = {
+"12 12 2 1",
+" c None",
+". c #000000",
+" ",
+" .......... ",
+" .......... ",
+" .......... ",
+" .......... ",
+" .......... ",
+" .......... ",
+" .......... ",
+" .......... ",
+" .......... ",
+" .......... ",
+" "};
diff --git a/muse_qt4_evolution/muse/xpm/sysex.xpm b/muse_qt4_evolution/muse/xpm/sysex.xpm
new file mode 100644
index 00000000..3cc5734e
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/sysex.xpm
@@ -0,0 +1,27 @@
+/* XPM */
+static const char * sysex_xpm[] = {
+"22 22 2 1",
+" c None",
+". c #000000000000",
+" ... . ",
+" . .. ",
+" . . ",
+" .. .. .. ... ",
+" ... . . . . ",
+" .. . .. .. ",
+" . . . . .. ",
+" .. .. .. . . ",
+" . ... . ... ",
+" . ",
+" . ",
+" .. ",
+" ....... ",
+" . . ",
+" . ",
+" . . .. .. ",
+" ..... . . ",
+" . . . ",
+" . . ",
+" . . . . ",
+" ....... .. .. ",
+" "};
diff --git a/muse_qt4_evolution/muse/xpm/toc.xpm b/muse_qt4_evolution/muse/xpm/toc.xpm
new file mode 100644
index 00000000..e8791dbc
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/toc.xpm
@@ -0,0 +1,27 @@
+/* XPM */
+static const char*toc_xpm[]={
+"18 18 6 1",
+"d c #a0a0a0",
+"# c #c0c0c0",
+"a c #000000",
+". c None",
+"c c #00c000",
+"b c #ffffff",
+"..................",
+"..................",
+".#aaaaaaaaaaa.....",
+".#a...abbba#a#....",
+".#a#c#abbba#.aa#..",
+".#a.c.abbba###a#..",
+".#a.c.abbbaaaaa#..",
+".#a#c#abbbbbbba#..",
+".#a.c.abdddbbba#..",
+".#a.c.abbbbbbba#..",
+".#a#c.abbddddba##.",
+".#a#c.abbbbbbba##.",
+".#a#c.abbbbbbba##.",
+".#a#c.abddddbba##.",
+".#a...abbbbbbba#..",
+".#aaaaaaaaaaaaa#..",
+"..............###.",
+".................."};
diff --git a/muse_qt4_evolution/muse/xpm/track_add.xpm b/muse_qt4_evolution/muse/xpm/track_add.xpm
new file mode 100644
index 00000000..0d78d13b
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/track_add.xpm
@@ -0,0 +1,23 @@
+/* XPM */
+static const char *track_add_xpm[]={
+"16 16 4 1",
+"b c #404000",
+"a c #808080",
+". c #c00000",
+"# c #ffffff",
+"................",
+"................",
+"..############..",
+"..############..",
+"..a#a#a#a#a#a#..",
+".bbbbbbbbbbbbbb.",
+"..a#a#a#a#a#a#..",
+"..a#a#a#a#a#a#..",
+"..a#a#a#a#a#a#..",
+"..a#a#a#a#a#a#..",
+".bbbbbbbbbbbbbb.",
+"..a#a#a#a#a#a#..",
+"..############..",
+"..############..",
+"................",
+"................"};
diff --git a/muse_qt4_evolution/muse/xpm/track_delete.xpm b/muse_qt4_evolution/muse/xpm/track_delete.xpm
new file mode 100644
index 00000000..e8a60338
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/track_delete.xpm
@@ -0,0 +1,23 @@
+/* XPM */
+static const char *track_delete_xpm[]={
+"16 16 4 1",
+"b c #404000",
+"a c #808080",
+". c #c00000",
+"# c #ffffff",
+"................",
+"................",
+"....##########..",
+".....#########..",
+"..a...a#a#a#a#..",
+".bbb...bbbbbbbb.",
+"..a#a...a#a#a#..",
+"..a#a#...#a#a#..",
+"..a#a#a...a#a#..",
+"..a#a#a#...#a#..",
+".bbbbbbbb...bbb.",
+"..a#a#a#a#...#..",
+"..#########.....",
+"..##########....",
+"................",
+"................"};
diff --git a/muse_qt4_evolution/muse/xpm/underlined.xpm b/muse_qt4_evolution/muse/xpm/underlined.xpm
new file mode 100644
index 00000000..a84a1e7d
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/underlined.xpm
@@ -0,0 +1,16 @@
+/* XPM */
+static const char * underlined_xpm[] = {
+"11 11 2 1",
+" g None",
+". g #000000",
+" .... ... ",
+" .. . ",
+" .. . ",
+" .. . ",
+" .. . ",
+" .. . ",
+" .. . ",
+" ... .. ",
+" ..... ",
+" ",
+" ......... "};
diff --git a/muse_qt4_evolution/muse/xpm/undo.xpm b/muse_qt4_evolution/muse/xpm/undo.xpm
new file mode 100644
index 00000000..4ba2b07b
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/undo.xpm
@@ -0,0 +1,93 @@
+/* XPM */
+static const char * undo_xpm[] = {
+"22 22 68 1",
+" c None",
+". c #275F0B",
+"+ c #9AC589",
+"@ c #CDE2C1",
+"# c #E5EEDF",
+"$ c #F5F9F4",
+"% c #C7E0BA",
+"& c #79BE53",
+"* c #91D56B",
+"= c #C8E1BE",
+"- c #87C86A",
+"; c #4AA721",
+"> c #3FA21C",
+", c #47AB29",
+"' c #000000",
+") c #8AC963",
+"! c #5BC930",
+"~ c #6FD63D",
+"{ c #53B529",
+"] c #D4E4CB",
+"^ c #2B6A0E",
+"/ c #35691B",
+"( c #FFFFFF",
+"_ c #E4ECDF",
+": c #A7C49A",
+"< c #42A01E",
+"[ c #102806",
+"} c #060D03",
+"| c #0E2005",
+"1 c #41821F",
+"2 c #79B658",
+"3 c #1C4408",
+"4 c #ECF3E8",
+"5 c #7FCC67",
+"6 c #72C24F",
+"7 c #0B1B05",
+"8 c #1C4508",
+"9 c #3A8816",
+"0 c #38AA18",
+"a c #34A814",
+"b c #51B929",
+"c c #469D24",
+"d c #122B06",
+"e c #275E0D",
+"f c #40A513",
+"g c #CCE5C2",
+"h c #48B227",
+"i c #4BB626",
+"j c #79D54B",
+"k c #081204",
+"l c #173807",
+"m c #88BE71",
+"n c #3F8222",
+"o c #478824",
+"p c #5B923C",
+"q c #3E8320",
+"r c #529033",
+"s c #071003",
+"t c #020202",
+"u c #15260E",
+"v c #0F1C09",
+"w c #070D04",
+"x c #12230A",
+"y c #102009",
+"z c #15270C",
+"A c #234413",
+"B c #13250A",
+"C c #13200C",
+" ",
+" ",
+" ..... ",
+" ..+@#@+.. ",
+" ..$%&&&&*#+. ",
+" . .$=-;;>>>>,*#' ",
+" .. .$);>!~~~~!{>*+' ",
+" .]..$)>!~{''''^/{>(' ",
+" .]_:)<~{'[ }|^12+3",
+" .456<~{' 789(3",
+" .40abc' def3",
+" .ghaij3 kl3 ",
+" .mnopqr3 s3' ",
+" .'''''''t u3 ",
+" v3w ",
+" x3y ",
+" zAB ",
+" C3' ",
+" ''' ",
+" ",
+" ",
+" "};
diff --git a/muse_qt4_evolution/muse/xpm/up.xpm b/muse_qt4_evolution/muse/xpm/up.xpm
new file mode 100644
index 00000000..94ad7cd5
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/up.xpm
@@ -0,0 +1,15 @@
+/* XPM */
+static const char* up_xpm[]={
+"14 10 2 1",
+"# c #000000",
+". c None",
+"..............",
+"......##......",
+".....####.....",
+"....######....",
+"...##.##.##...",
+"......##......",
+"......##......",
+"......##......",
+"......##......",
+".............."};
diff --git a/muse_qt4_evolution/muse/xpm/view_bigtime_window.xpm b/muse_qt4_evolution/muse/xpm/view_bigtime_window.xpm
new file mode 100644
index 00000000..9ff59a5a
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/view_bigtime_window.xpm
@@ -0,0 +1,22 @@
+/* XPM */
+static const char * view_bigtime_window_xpm[] = {
+"16 16 3 1",
+" c None",
+". c #D4D4D4",
+"+ c #000000",
+" .++. ",
+" .++..++. ",
+" +. ++ .+ ",
+" +. ++ .+ ",
+" .. ++. .. ",
+" + ++. + ",
+".+ ++. +.",
+"+. ++. .+",
+"+. + .. .+",
+".+ + . +.",
+" + + . + ",
+" ..+ . .. ",
+" +.. .+ ",
+" +. .+ ",
+" .++..++. ",
+" .++. "};
diff --git a/muse_qt4_evolution/muse/xpm/view_cliplist.xpm b/muse_qt4_evolution/muse/xpm/view_cliplist.xpm
new file mode 100644
index 00000000..6217b397
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/view_cliplist.xpm
@@ -0,0 +1,32 @@
+/* XPM */
+static const char * view_cliplist_xpm[] = {
+"16 16 13 1",
+" c None",
+". c #5E2ABF",
+"+ c #945BFD",
+"@ c #000000",
+"# c #DCDCDC",
+"$ c #CACACA",
+"% c #E6E6E6",
+"& c #EAEAEA",
+"* c #FFFFFF",
+"= c #FCFCFC",
+"- c #461F8E",
+"; c #FBFBFB",
+"> c #F9F9F9",
+"................",
+".+@@@@@@@@@@+++.",
+".+@####$###@@++.",
+".+@%&@***@*@@@+.",
+".+@%@@#&@@#*=@-.",
+".+@%@@#*@@#@=@-.",
+".+@;&@#**@#*@@-.",
+".+@;&&#&&*#@=@-.",
+".+@;&@***@*=@@-.",
+".+@%@@#&@@#@>@-.",
+".+@%@@#*@@#=@@-.",
+".+@%%@#;;@#@=@-.",
+".+@;%%#;%;#;#@-.",
+".+@@@@@@@@@@@@-.",
+".++------------.",
+"................"};
diff --git a/muse_qt4_evolution/muse/xpm/view_marker.xpm b/muse_qt4_evolution/muse/xpm/view_marker.xpm
new file mode 100644
index 00000000..26dba09a
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/view_marker.xpm
@@ -0,0 +1,37 @@
+/* XPM */
+static const char * view_marker_xpm[] = {
+"16 16 18 1",
+" c None",
+". c #DCDCDC",
+"+ c #0C0C0C",
+"@ c #253B52",
+"# c #395B7F",
+"$ c #588DC4",
+"% c #531228",
+"& c #C3B2E5",
+"* c #240E16",
+"= c #5F132A",
+"- c #828282",
+"; c #542838",
+"> c #232323",
+", c #020202",
+"' c #BDBDBD",
+") c #4C4C4C",
+"! c #A6A6A6",
+"~ c #331B5F",
+" ... ",
+" ... . ",
+". ++++ . ",
+".+@#$#++. ... ",
+".+#$$$$#+. . ..",
+" ++$$$$#++++++++",
+"..+$$$$#+#$$#++.",
+" .+$$##@%$$++ &",
+" +**+=$$+. . ",
+" +- . *; . ",
+" -> ",
+" ,' ",
+" +) ",
+" !+ ",
+" ++ ",
+" ~ "};
diff --git a/muse_qt4_evolution/muse/xpm/view_mixer.xpm b/muse_qt4_evolution/muse/xpm/view_mixer.xpm
new file mode 100644
index 00000000..ec64f3c8
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/view_mixer.xpm
@@ -0,0 +1,26 @@
+/* XPM */
+static const char * view_mixer_xpm[] = {
+"16 16 7 1",
+" c None",
+". c #5E2ABF",
+"+ c #945BFD",
+"@ c #FFFFFF",
+"# c #000000",
+"$ c #CACACA",
+"% c #5727B0",
+"................",
+".++++++++++++++.",
+".+@@@@@@@@@@@@+.",
+".+@#@@#@@#@@#@+.",
+".+###@#$###@#$+.",
+".+###$#$###$#$+.",
+".+@#$$#$@#$$#$+.",
+".+@#$@#$@#$###+.",
+".+@#$@#$@#$###%.",
+".+@#$@#$@#$@#$%.",
+".+@#$###@#$@#$+.",
+".+@#$###$#$@#$+.",
+".+@@$@@@$@$@@$+.",
+".+@@@@@@@@@@@@+.",
+".++++++++++++++.",
+"................"};
diff --git a/muse_qt4_evolution/muse/xpm/view_transport_window.xpm b/muse_qt4_evolution/muse/xpm/view_transport_window.xpm
new file mode 100644
index 00000000..fba8696f
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/view_transport_window.xpm
@@ -0,0 +1,24 @@
+/* XPM */
+static const char * view_transport_window_xpm[] = {
+"16 16 5 1",
+" c None",
+". c #575757",
+"+ c #000000",
+"@ c #D4D4D4",
+"# c #D1CFD5",
+" .+. ",
+" .+++. ",
+" .+++.@ ",
+" .+.@@ ",
+" ",
+" ",
+" .+++.@ ",
+" .+++++@ ",
+" .@++++@ ",
+" @++.@@ ",
+" ++ ",
+" .++@@ ",
+" +++@++ ",
+" .+++++.@ ",
+" .++++.@# ",
+" @@@@@@ "};
diff --git a/muse_qt4_evolution/muse/xpm/wave.xpm b/muse_qt4_evolution/muse/xpm/wave.xpm
new file mode 100644
index 00000000..f2a93c66
--- /dev/null
+++ b/muse_qt4_evolution/muse/xpm/wave.xpm
@@ -0,0 +1,33 @@
+/* XPM */
+static const char * wave_xpm[] = {
+"16 16 14 1",
+" c None",
+". c #828282",
+"+ c #000000",
+"@ c #7F7F7F",
+"# c #8A8A8A",
+"$ c #4B4B4B",
+"% c #444444",
+"& c #E50000",
+"* c #290000",
+"= c #FF0000",
+"- c #1E0000",
+"; c #F20000",
+"> c #1B0000",
+", c #D50000",
+" ",
+" . ",
+" .+. ",
+" @@ #+@+# ",
+" $++$ +@ @+ ",
+" +@@+ + + @",
+" + + + + %",
+" + + + + +",
+" + + + + +",
+" + + + + +",
+"&*==-&;&>,==+;=+",
+"%+ + + + +",
+"+@ +@ @+ + +",
+"% #+@+# +@@+",
+"@ .+. $++$",
+" . @@ "};