~ubuntu-branches/ubuntu/wily/muse/wily-proposed

« back to all changes in this revision

Viewing changes to muse/midiedit/dcanvas.cpp

  • Committer: Package Import Robot
  • Author(s): Alessio Treglia
  • Date: 2011-12-03 17:12:54 UTC
  • mfrom: (1.1.8)
  • Revision ID: package-import@ubuntu.com-20111203171254-28b1j4lpb46r5jtl
Tags: 2.0~rc1-1
* New upstream RC release.
* Refresh patches, remove those patches not needed anymore.

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
//  Linux Music Editor
4
4
//    $Id: dcanvas.cpp,v 1.16.2.10 2009/10/15 22:45:50 terminator356 Exp $
5
5
//  (C) Copyright 1999 Werner Schweer (ws@seh.de)
 
6
//
 
7
//  This program is free software; you can redistribute it and/or
 
8
//  modify it under the terms of the GNU General Public License
 
9
//  as published by the Free Software Foundation; version 2 of
 
10
//  the License, or (at your option) any later version.
 
11
//
 
12
//  This program is distributed in the hope that it will be useful,
 
13
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
//  GNU General Public License for more details.
 
16
//
 
17
//  You should have received a copy of the GNU General Public License
 
18
//  along with this program; if not, write to the Free Software
 
19
//  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
20
//
6
21
//=========================================================
7
22
 
8
23
#include <QPainter>
19
34
#include <stdio.h>
20
35
#include <values.h>
21
36
#include <errno.h>
 
37
#include <set>
22
38
//#include <sys/stat.h>
23
39
//#include <sys/mman.h>
24
40
 
31
47
#include "globals.h"
32
48
#include "midiport.h"
33
49
#include "audio.h"
34
 
#include "velocity.h"
35
50
#include "shortcuts.h"
36
51
#include "icons.h"
 
52
#include "functions.h"
37
53
 
38
54
#define CARET   10
39
55
#define CARET2   5
40
56
 
 
57
namespace MusEGui {
 
58
 
41
59
//---------------------------------------------------------
42
60
//   DEvent
43
61
//---------------------------------------------------------
44
62
 
45
 
DEvent::DEvent(Event e, Part* p)
 
63
DEvent::DEvent(MusECore::Event e, MusECore::Part* p)
46
64
  : CItem(e, p)
47
65
      {
48
66
      int instr = e.pitch();
56
74
//   addItem
57
75
//---------------------------------------------------------
58
76
 
59
 
void DrumCanvas::addItem(Part* part, Event& event)
 
77
CItem* DrumCanvas::addItem(MusECore::Part* part, MusECore::Event& event)
60
78
      {
61
79
      if (signed(event.tick())<0) {
62
80
            printf("ERROR: trying to add event before current part!\n");
63
 
            return;
 
81
            return NULL;
64
82
      }
65
83
      
66
84
      DEvent* ev = new DEvent(event, part);
69
87
      int diff = event.endTick()-part->lenTick();
70
88
      if (diff > 0)  {// too short part? extend it
71
89
            //printf("addItem - this code should not be run!\n");
72
 
            //Part* newPart = part->clone();
 
90
            //MusECore::Part* newPart = part->clone();
73
91
            //newPart->setLenTick(newPart->lenTick()+diff);
74
 
            //audio->msgChangePart(part, newPart,false);
 
92
            //MusEGlobal::audio->msgChangePart(part, newPart,false);
75
93
            //part = newPart;
76
94
            part->setLenTick(part->lenTick()+diff);
77
95
            }
 
96
      
 
97
      return ev;
78
98
      }
79
99
 
80
100
//---------------------------------------------------------
88
108
      setVirt(false);
89
109
      cursorPos= QPoint(0,0);
90
110
      _stepSize=1;
 
111
      
 
112
      steprec=new MusECore::StepRec(NULL);
 
113
      
91
114
      songChanged(SC_TRACK_INSERTED);
 
115
      connect(MusEGlobal::song, SIGNAL(midiNote(int, int)), SLOT(midiNote(int,int)));
92
116
      }
93
117
 
 
118
DrumCanvas::~DrumCanvas()
 
119
{
 
120
  //items.clearDelete();
 
121
}
 
122
 
94
123
//---------------------------------------------------------
95
124
//   moveCanvasItems
96
125
//---------------------------------------------------------
97
126
 
98
 
void DrumCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtype, int* pflags)
 
127
MusECore::Undo DrumCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtype)
99
128
{      
100
129
  if(editor->parts()->empty())
101
 
    return;
102
 
    
103
 
  PartsToChangeMap parts2change;
104
 
  
105
 
  int modified = 0;
106
 
  for(iPart ip = editor->parts()->begin(); ip != editor->parts()->end(); ++ip)
 
130
    return MusECore::Undo(); //return empty list
 
131
  
 
132
  MusECore::PartsToChangeMap parts2change;
 
133
  MusECore::Undo operations;  
 
134
  
 
135
  for(MusECore::iPart ip = editor->parts()->begin(); ip != editor->parts()->end(); ++ip)
107
136
  {
108
 
    Part* part = ip->second;
 
137
    MusECore::Part* part = ip->second;
109
138
    if(!part)
110
139
      continue;
111
140
    
122
151
      
123
152
      // Test moving the item...
124
153
      DEvent* nevent = (DEvent*) ci;
125
 
      Event event    = nevent->event();
 
154
      MusECore::Event event    = nevent->event();
126
155
      x              = newpos.x();
127
156
      if(x < 0)
128
157
        x = 0;
138
167
        
139
168
    if(npartoffset > 0)
140
169
    {    
141
 
      // Create new part...
142
 
      // if there are several events that are moved outside the part, it will be recreated for each
143
 
      // so the part _in_ the event will not be valid, ask the authority.
144
 
//      Part* newPart = part->clone();
145
 
      //Part* newPart = Canvas::part()->clone();
146
 
 
147
 
//      newPart->setLenTick(newPart->lenTick() + npartoffset);
148
 
      //audio->msgChangePart(part, newPart,false);
149
 
 
150
 
//      modified = SC_PART_MODIFIED;
151
 
 
152
 
      // BUG FIX: #1650953
153
 
      // Added by T356.
154
 
      // Fixes posted "select and drag past end of part - crashing" bug
155
 
//      for(iPart ip = editor->parts()->begin(); ip != editor->parts()->end(); ++ip)
156
 
//      {
157
 
//        if(ip->second == part)
158
 
//        {
159
 
//          editor->parts()->erase(ip);
160
 
//          break;
161
 
//        }
162
 
//      }
163
 
      
164
 
//      editor->parts()->add(newPart);
165
 
//      audio->msgChangePart(part, newPart,false);
166
 
      
167
 
//      if(parts2change.find(part) == parts2change.end())
168
 
//       parts2change.insert(std::pair<Part*, Part*> (part, newPart));
169
 
      iPartToChange ip2c = parts2change.find(part);
 
170
      MusECore::iPartToChange ip2c = parts2change.find(part);
170
171
      if(ip2c == parts2change.end())
171
172
      {
172
 
        PartToChange p2c = {0, npartoffset};
173
 
        parts2change.insert(std::pair<Part*, PartToChange> (part, p2c));
 
173
        MusECore::PartToChange p2c = {0, npartoffset};
 
174
        parts2change.insert(std::pair<MusECore::Part*, MusECore::PartToChange> (part, p2c));
174
175
      }
175
176
      else
176
177
        ip2c->second.xdiff = npartoffset;
177
 
      
178
 
      
179
 
      //part = newPart; // reassign
180
 
      //item->setPart(part);
181
 
      //item->setEvent(newEvent);
182
 
      //curPart = part;
183
 
      //curPartId = curPart->sn();
184
 
 
185
 
    }
186
 
  }
187
 
    
188
 
  for(iPartToChange ip2c = parts2change.begin(); ip2c != parts2change.end(); ++ip2c)
189
 
  {
190
 
    Part* opart = ip2c->first;
191
 
    int diff = ip2c->second.xdiff;
192
 
    
193
 
    Part* newPart = opart->clone();
194
 
    
195
 
    newPart->setLenTick(newPart->lenTick() + diff);
196
 
    
197
 
    modified = SC_PART_MODIFIED;
198
 
    
199
 
    // BUG FIX: #1650953
200
 
    // Added by T356.
201
 
    // Fixes posted "select and drag past end of part - crashing" bug
202
 
    for(iPart ip = editor->parts()->begin(); ip != editor->parts()->end(); ++ip)
203
 
    {
204
 
      if(ip->second == opart)
205
 
      {
206
 
        editor->parts()->erase(ip);
207
 
        break;
208
 
      }
209
 
    }
210
 
      
211
 
    editor->parts()->add(newPart);
212
 
    // Indicate no undo, and do port controller values but not clone parts. 
213
 
    //audio->msgChangePart(opart, newPart, false);
214
 
    audio->msgChangePart(opart, newPart, false, true, false);
215
 
    
216
 
    ip2c->second.npart = newPart;
217
 
    
218
 
  }
219
 
    
220
 
  iPartToChange icp = parts2change.find(curPart);
221
 
  if(icp != parts2change.end())
222
 
  {
223
 
    curPart = icp->second.npart;
224
 
    curPartId = curPart->sn();
225
 
  }  
226
 
    
227
 
  std::vector< CItem* > doneList;
228
 
  typedef std::vector< CItem* >::iterator iDoneList;
 
178
    }
 
179
  }
229
180
  
230
 
  for(iCItem ici = items.begin(); ici != items.end(); ++ici) 
 
181
  bool forbidden=false;
 
182
  for(MusECore::iPartToChange ip2c = parts2change.begin(); ip2c != parts2change.end(); ++ip2c)
231
183
  {
232
 
    CItem* ci = ici->second;
233
 
    
234
 
    // If this item's part is in the parts2change list, change the item's part to the new part.
235
 
    Part* pt = ci->part();
236
 
    iPartToChange ip2c = parts2change.find(pt);
237
 
    if(ip2c != parts2change.end())
238
 
      ci->setPart(ip2c->second.npart);
239
 
    
240
 
    int x = ci->pos().x();
241
 
    int y = ci->pos().y();
242
 
    int nx = x + dx;
243
 
    int ny = pitch2y(y2pitch(y) + dp);
244
 
    QPoint newpos = raster(QPoint(nx, ny));
245
 
    selectItem(ci, true);
246
 
    
247
 
    iDoneList idl;
248
 
    for(idl = doneList.begin(); idl != doneList.end(); ++idl)
249
 
      // This compares EventBase pointers to see if they're the same...
250
 
      if((*idl)->event() == ci->event())
251
 
        break;
252
 
      
253
 
    // Do not process if the event has already been processed (meaning it's an event in a clone part)...
254
 
    //if(moveItem(ci, newpos, dtype))
255
 
    if(idl != doneList.end())
256
 
      // Just move the canvas item.
257
 
      ci->move(newpos);
258
 
    else
 
184
    MusECore::Part* opart = ip2c->first;
 
185
    if (opart->hasHiddenEvents())
259
186
    {
260
 
      // Currently moveItem always returns true.
261
 
      if(moveItem(ci, newpos, dtype))
262
 
      {
263
 
        // Add the canvas item to the list of done items.
264
 
        doneList.push_back(ci);
265
 
        // Move the canvas item.
266
 
        ci->move(newpos);
267
 
      }  
268
 
    }
269
 
          
270
 
    if(moving.size() == 1) {
271
 
          itemReleased(curItem, newpos);
272
 
          }
273
 
    if(dtype == MOVE_COPY || dtype == MOVE_CLONE)
274
 
          selectItem(ci, false);
275
 
  }  
276
 
      
277
 
  if(pflags)
278
 
    *pflags = modified;
 
187
                        forbidden=true;
 
188
                        break;
 
189
                }
 
190
  }    
 
191
 
 
192
        
 
193
        if (!forbidden)
 
194
        {
 
195
                std::vector< CItem* > doneList;
 
196
                typedef std::vector< CItem* >::iterator iDoneList;
 
197
                
 
198
                for(iCItem ici = items.begin(); ici != items.end(); ++ici) 
 
199
                {
 
200
                        CItem* ci = ici->second;
 
201
                        
 
202
                        int x = ci->pos().x();
 
203
                        int y = ci->pos().y();
 
204
                        int nx = x + dx;
 
205
                        int ny = pitch2y(y2pitch(y) + dp);
 
206
                        QPoint newpos = raster(QPoint(nx, ny));
 
207
                        selectItem(ci, true);
 
208
                        
 
209
                        iDoneList idl;
 
210
                        for(idl = doneList.begin(); idl != doneList.end(); ++idl)
 
211
                                // This compares EventBase pointers to see if they're the same...
 
212
                                if((*idl)->event() == ci->event())
 
213
                                        break;
 
214
                                
 
215
                        // Do not process if the event has already been processed (meaning it's an event in a clone part)...
 
216
                        if (idl == doneList.end())
 
217
                        {
 
218
                                operations.push_back(moveItem(ci, newpos, dtype));
 
219
                                doneList.push_back(ci);
 
220
                        }
 
221
                        ci->move(newpos);
 
222
                                                
 
223
                        if(moving.size() == 1) 
 
224
                                                itemReleased(curItem, newpos);
 
225
 
 
226
                        if(dtype == MOVE_COPY || dtype == MOVE_CLONE)
 
227
                                                selectItem(ci, false);
 
228
                }  
 
229
 
 
230
                for(MusECore::iPartToChange ip2c = parts2change.begin(); ip2c != parts2change.end(); ++ip2c)
 
231
                {
 
232
                        MusECore::Part* opart = ip2c->first;
 
233
                        int diff = ip2c->second.xdiff;
 
234
                        
 
235
                        schedule_resize_all_same_len_clone_parts(opart, opart->lenTick() + diff, operations); 
 
236
                }    
 
237
                                        
 
238
        return operations;
 
239
  }
 
240
  else
 
241
  {
 
242
                return MusECore::Undo(); //return empty list
 
243
        }
279
244
}
280
245
      
281
246
//---------------------------------------------------------
282
247
//   moveItem
283
248
//---------------------------------------------------------
284
249
 
285
 
// Changed by T356.
286
 
//bool DrumCanvas::moveItem(CItem* item, const QPoint& pos, DragType dtype, int* pflags)
287
 
bool DrumCanvas::moveItem(CItem* item, const QPoint& pos, DragType dtype)
 
250
MusECore::UndoOp DrumCanvas::moveItem(CItem* item, const QPoint& pos, DragType dtype)
288
251
      {
289
252
      DEvent* nevent   = (DEvent*) item;
290
253
      
291
 
      // Changed by T356.
292
 
      //MidiPart* part   = (MidiPart*)Canvas::part(); // part can be dynamically recreated, ask the authority
293
 
      MidiPart* part   = (MidiPart*)nevent->part();   
 
254
      MusECore::MidiPart* part   = (MusECore::MidiPart*)nevent->part();   
294
255
      
295
 
      Event event      = nevent->event();
 
256
      MusECore::Event event      = nevent->event();
296
257
      int x            = pos.x();
297
258
      if (x < 0)
298
259
            x = 0;
300
261
      if (ntick < 0)
301
262
            ntick = 0;
302
263
      int npitch       = y2pitch(pos.y());
303
 
      Event newEvent   = event.clone();
 
264
      MusECore::Event newEvent   = event.clone();
304
265
 
305
266
      newEvent.setPitch(npitch);
306
267
      newEvent.setTick(ntick);
307
268
 
308
 
      // Removed by T356.
309
 
      /*
310
 
      // Added by T356.
311
 
      int modified = 0;
312
 
      //song->startUndo();
313
 
      int diff = newEvent.endTick()-part->lenTick();
314
 
      if (diff > 0)  // too short part? extend it
315
 
      {
316
 
        // if there are several events that are moved outside the part, it will be recreated for each
317
 
        // so the part _in_ the event will not be valid, ask the authority.
318
 
        //Part* newPart = part->clone();
319
 
        MidiPart* newPart = (MidiPart*)Canvas::part()->clone();
320
 
        newPart->setLenTick(newPart->lenTick()+diff);
321
 
        audio->msgChangePart(Canvas::part(), newPart,false);
322
 
        
323
 
        modified = SC_PART_MODIFIED;
324
 
        part = newPart; // reassign
325
 
        for(iPart i = editor->parts()->begin(); i != editor->parts()->end(); ++i)
326
 
        {  
327
 
          if(i->second == Canvas::part())
328
 
          {
329
 
            editor->parts()->erase(i); 
330
 
            break;
331
 
          }    
332
 
        }
333
 
        editor->parts()->add(part);
334
 
        item->setPart(part);
335
 
        item->setEvent(newEvent);
336
 
        curPart = part;
337
 
        curPartId = curPart->sn();
338
 
      }
339
 
      */
340
 
      
341
 
      // Added by T356. 
342
 
      // msgAddEvent and msgChangeEvent (below) will set these, but set them here first?
343
 
      //item->setPart(part);
344
 
      item->setEvent(newEvent);
345
 
      
346
 
      // Added by T356. 
347
 
      if(((int)newEvent.endTick() - (int)part->lenTick()) > 0)  
348
 
        printf("DrumCanvas::moveItem Error! New event end:%d exceeds length:%d of part:%s\n", newEvent.endTick(), part->lenTick(), part->name().toLatin1().constData());
349
 
      
350
 
      if (dtype == MOVE_COPY || dtype == MOVE_CLONE) {
351
 
            // Indicate no undo, and do not do port controller values and clone parts. 
352
 
            //audio->msgAddEvent(newEvent, part, false);
353
 
            audio->msgAddEvent(newEvent, part, false, false, false);
354
 
            }
355
 
      else {
356
 
            // Indicate no undo, and do not do port controller values and clone parts. 
357
 
            //audio->msgChangeEvent(event, newEvent, part, false);
358
 
            audio->msgChangeEvent(event, newEvent, part, false, false, false);
359
 
            }
360
 
        
361
 
      // Removed by T356.
362
 
      //if(pflags)
363
 
      //  *pflags = modified;
364
 
      
365
 
      return true;
 
269
      // Added by T356, removed by flo93: with operation groups, it happens that the
 
270
      // part is too short right now, even if it's queued for being extended
 
271
      //if(((int)newEvent.endTick() - (int)part->lenTick()) > 0)  
 
272
      //  printf("DrumCanvas::moveItem Error! New event end:%d exceeds length:%d of part:%s\n", newEvent.endTick(), part->lenTick(), part->name().toLatin1().constData());
 
273
      
 
274
      if (dtype == MOVE_COPY || dtype == MOVE_CLONE)
 
275
            return MusECore::UndoOp(MusECore::UndoOp::AddEvent, newEvent, part, false, false);
 
276
      else
 
277
            return MusECore::UndoOp(MusECore::UndoOp::ModifyEvent, newEvent, event, part, false, false);
366
278
      }
367
279
 
368
280
//---------------------------------------------------------
371
283
 
372
284
CItem* DrumCanvas::newItem(const QPoint& p, int state)
373
285
      {
374
 
      int instr = y2pitch(p.y());         //drumInmap[y2pitch(p.y())];
375
 
      int velo  = drumMap[instr].lv4;
 
286
      int instr = y2pitch(p.y());         //MusEGlobal::drumInmap[y2pitch(p.y())];
 
287
      int velo  = MusEGlobal::drumMap[instr].lv4;
376
288
      if (state == Qt::ShiftModifier)
377
 
            velo = drumMap[instr].lv3;
 
289
            velo = MusEGlobal::drumMap[instr].lv3;
378
290
      else if (state == Qt::ControlModifier)
379
 
            velo = drumMap[instr].lv2;
 
291
            velo = MusEGlobal::drumMap[instr].lv2;
380
292
      else if (state == (Qt::ControlModifier | Qt::ShiftModifier))
381
 
            velo = drumMap[instr].lv1;
 
293
            velo = MusEGlobal::drumMap[instr].lv1;
382
294
      int tick = editor->rasterVal(p.x());
383
295
      return newItem(tick, instr, velo);
384
296
      }
390
302
CItem* DrumCanvas::newItem(int tick, int instrument, int velocity)
391
303
{
392
304
  tick    -= curPart->tick();
393
 
  Event e(Note);
 
305
  MusECore::Event e(MusECore::Note);
394
306
  e.setTick(tick);
395
307
  e.setPitch(instrument);
396
308
  e.setVelo(velocity);
397
 
  e.setLenTick(drumMap[instrument].len);
 
309
  e.setLenTick(MusEGlobal::drumMap[instrument].len);
398
310
  return new DEvent(e, curPart);
399
311
}
400
312
 
402
314
//   resizeItem
403
315
//---------------------------------------------------------
404
316
 
405
 
void DrumCanvas::resizeItem(CItem* item, bool)
 
317
void DrumCanvas::resizeItem(CItem* item, bool, bool)
406
318
      {
407
319
      DEvent* nevent = (DEvent*) item;
408
 
      Event ev = nevent->event();
 
320
      MusECore::Event ev = nevent->event();
409
321
      // Indicate do undo, and do not do port controller values and clone parts. 
410
 
      //audio->msgDeleteEvent(ev, nevent->part());
411
 
      audio->msgDeleteEvent(ev, nevent->part(), true, false, false);
 
322
      MusEGlobal::audio->msgDeleteEvent(ev, nevent->part(), true, false, false);
412
323
      }
413
324
 
414
325
//---------------------------------------------------------
421
332
void DrumCanvas::newItem(CItem* item, bool noSnap, bool replace)
422
333
      {
423
334
      DEvent* nevent = (DEvent*) item;
424
 
      Event event    = nevent->event();
 
335
      MusECore::Event event    = nevent->event();
425
336
      int x = item->x();
426
337
      if (!noSnap)
427
338
            x = editor->rasterVal(x);
428
339
      event.setTick(x - nevent->part()->tick());
429
 
      //int npitch = drumMap[y2pitch(item->y())].enote;
430
340
      int npitch = event.pitch();
431
341
      event.setPitch(npitch);
432
342
 
434
344
      // check for existing event
435
345
      //    if found change command semantic from insert to delete
436
346
      //
437
 
      EventList* el = nevent->part()->events();
438
 
      iEvent lower  = el->lower_bound(event.tick());
439
 
      iEvent upper  = el->upper_bound(event.tick());
 
347
      MusECore::EventList* el = nevent->part()->events();
 
348
      MusECore::iEvent lower  = el->lower_bound(event.tick());
 
349
      MusECore::iEvent upper  = el->upper_bound(event.tick());
440
350
 
441
 
      for (iEvent i = lower; i != upper; ++i) {
442
 
            Event ev = i->second;
 
351
      for (MusECore::iEvent i = lower; i != upper; ++i) {
 
352
            MusECore::Event ev = i->second;
443
353
            // Added by T356. Only do notes.
444
354
            if(!ev.isNote())
445
355
              continue;
446
356
              
447
357
            if (ev.pitch() == npitch) {
448
358
                  // Indicate do undo, and do not do port controller values and clone parts. 
449
 
                  //audio->msgDeleteEvent(ev, nevent->part());
450
 
                  audio->msgDeleteEvent(ev, nevent->part(), true, false, false);
 
359
                  MusEGlobal::audio->msgDeleteEvent(ev, nevent->part(), true, false, false);
451
360
                  if (replace)
452
361
                    break;
453
362
                  else
457
366
            }
458
367
 
459
368
      // Added by T356.
460
 
      Part* part = nevent->part();
461
 
      song->startUndo();
462
 
      int modified=SC_EVENT_MODIFIED;
 
369
      MusECore::Part* part = nevent->part();
 
370
      MusECore::Undo operations;
463
371
      int diff = event.endTick()-part->lenTick();
464
 
      if (diff > 0)  {// too short part? extend it
465
 
            Part* newPart = part->clone();
466
 
            newPart->setLenTick(newPart->lenTick()+diff);
467
 
            // Indicate no undo, and do port controller values but not clone parts. 
468
 
            //audio->msgChangePart(part, newPart,false);
469
 
            audio->msgChangePart(part, newPart, false, true, false);
470
 
            modified=modified|SC_PART_MODIFIED;
471
 
            part = newPart; // reassign
472
 
            }
473
 
      // Indicate no undo, and do not do port controller values and clone parts. 
474
 
      //audio->msgAddEvent(event, part,false); 
475
 
      audio->msgAddEvent(event, part, false, false, false); 
476
 
      song->endUndo(modified);
477
372
      
 
373
      if (! ((diff > 0) && part->hasHiddenEvents()) ) //operation is allowed
 
374
      {
 
375
        operations.push_back(MusECore::UndoOp(MusECore::UndoOp::AddEvent,event, part, false, false));
 
376
        
 
377
        if (diff > 0)// part must be extended?
 
378
        {
 
379
              schedule_resize_all_same_len_clone_parts(part, event.endTick(), operations);
 
380
              printf("newItem: extending\n");
 
381
        }
 
382
      }
 
383
      //else forbid action by not applying it
 
384
      MusEGlobal::song->applyOperationGroup(operations);
 
385
      songChanged(SC_EVENT_INSERTED); //this forces an update of the itemlist, which is neccessary
 
386
                                      //to remove "forbidden" events from the list again
478
387
      }
479
388
 
480
389
//---------------------------------------------------------
483
392
 
484
393
bool DrumCanvas::deleteItem(CItem* item)
485
394
      {
486
 
      Event ev = ((DEvent*)item)->event();
 
395
      MusECore::Event ev = ((DEvent*)item)->event();
487
396
      // Indicate do undo, and do not do port controller values and clone parts. 
488
 
      //audio->msgDeleteEvent(ev, ((DEvent*)item)->part());
489
 
      audio->msgDeleteEvent(ev, ((DEvent*)item)->part(), true, false, false);
 
397
      MusEGlobal::audio->msgDeleteEvent(ev, ((DEvent*)item)->part(), true, false, false);
490
398
      return false;
491
399
      }
492
400
 
531
439
      else
532
440
      {
533
441
            int velo    = e->event().velo();
534
 
            DrumMap* dm = &drumMap[y2pitch(y)]; //Get the drum item
 
442
            MusECore::DrumMap* dm = &MusEGlobal::drumMap[y2pitch(y)]; //Get the drum item
535
443
            QColor color;
536
444
            if (velo < dm->lv1)
537
445
                  color.setRgb(240, 240, 255);
554
462
 
555
463
void DrumCanvas::drawMoving(QPainter& p, const CItem* item, const QRect& rect)
556
464
    {
557
 
      //if(((DEvent*)item)->part() != curPart)
558
 
      //  return;
559
 
      //if(!item->isMoving()) 
560
 
      //  return;
561
465
      QPolygon pa(4);
562
466
      QPoint pt = map(item->mp());
563
467
      int x = pt.x();
579
483
//   drawCanvas
580
484
//---------------------------------------------------------
581
485
 
582
 
extern void drawTickRaster(QPainter& p, int, int, int, int, int);
583
 
 
584
486
void DrumCanvas::drawCanvas(QPainter& p, const QRect& rect)
585
487
      {
586
488
      int x = rect.x();
608
510
//---------------------------------------------------------
609
511
//   drawTopItem
610
512
//---------------------------------------------------------
611
 
void DrumCanvas::drawTopItem(QPainter &p, const QRect &r)
 
513
void DrumCanvas::drawTopItem(QPainter& p, const QRect&)
612
514
{
613
515
  // draw cursor
614
516
  if (_tool == CursorTool) {
648
550
 
649
551
void DrumCanvas::cmd(int cmd)
650
552
      {
651
 
      switch(cmd) {
652
 
            case CMD_CUT:
653
 
                  copy();
654
 
                  song->startUndo();
655
 
                  for (iCItem i = items.begin(); i != items.end(); ++i) {
656
 
                        if (!i->second->isSelected())
657
 
                              continue;
658
 
                        DEvent* e = (DEvent*)(i->second);
659
 
                        Event event = e->event();
660
 
                        // Indicate no undo, and do not do port controller values and clone parts. 
661
 
                        //audio->msgDeleteEvent(event, e->part(), false);
662
 
                        audio->msgDeleteEvent(event, e->part(), false, false, false);
663
 
                        }
664
 
                  song->endUndo(SC_EVENT_REMOVED);
665
 
                  break;
666
 
            case CMD_COPY:
667
 
                  copy();
668
 
                  break;
669
 
            case CMD_PASTE:
670
 
                  paste();
671
 
                  break;
 
553
      switch (cmd) {
672
554
            case CMD_SELECT_ALL:     // select all
673
555
                  for (iCItem k = items.begin(); k != items.end(); ++k) {
674
556
                        if (!k->second->isSelected())
686
568
            case CMD_SELECT_ILOOP:     // select inside loop
687
569
                  for (iCItem k = items.begin(); k != items.end(); ++k) {
688
570
                        DEvent* nevent =(DEvent*)(k->second);
689
 
                        Part* part = nevent->part();
690
 
                        Event event = nevent->event();
 
571
                        MusECore::Part* part = nevent->part();
 
572
                        MusECore::Event event = nevent->event();
691
573
                        unsigned tick  = event.tick() + part->tick();
692
 
                        if (tick < song->lpos() || tick >= song->rpos())
 
574
                        if (tick < MusEGlobal::song->lpos() || tick >= MusEGlobal::song->rpos())
693
575
                              selectItem(k->second, false);
694
576
                        else
695
577
                              selectItem(k->second, true);
698
580
            case CMD_SELECT_OLOOP:     // select outside loop
699
581
                  for (iCItem k = items.begin(); k != items.end(); ++k) {
700
582
                        DEvent* nevent = (DEvent*)(k->second);
701
 
                        Part* part     = nevent->part();
702
 
                        Event event    = nevent->event();
 
583
                        MusECore::Part* part     = nevent->part();
 
584
                        MusECore::Event event    = nevent->event();
703
585
                        unsigned tick  = event.tick() + part->tick();
704
 
                        if (tick < song->lpos() || tick >= song->rpos())
 
586
                        if (tick < MusEGlobal::song->lpos() || tick >= MusEGlobal::song->rpos())
705
587
                              selectItem(k->second, true);
706
588
                        else
707
589
                              selectItem(k->second, false);
709
591
                  break;
710
592
            case CMD_SELECT_PREV_PART:     // select previous part
711
593
                  {
712
 
                      Part* pt = editor->curCanvasPart();
713
 
                      Part* newpt = pt;
714
 
                      PartList* pl = editor->parts();
715
 
                      for(iPart ip = pl->begin(); ip != pl->end(); ++ip)
 
594
                      MusECore::Part* pt = editor->curCanvasPart();
 
595
                      MusECore::Part* newpt = pt;
 
596
                      MusECore::PartList* pl = editor->parts();
 
597
                      for(MusECore::iPart ip = pl->begin(); ip != pl->end(); ++ip)
716
598
                        if(ip->second == pt)
717
599
                        {
718
600
                          if(ip == pl->begin())
727
609
                  break;
728
610
            case CMD_SELECT_NEXT_PART:     // select next part
729
611
                  {
730
 
                      Part* pt = editor->curCanvasPart();
731
 
                      Part* newpt = pt;
732
 
                      PartList* pl = editor->parts();
733
 
                      for(iPart ip = pl->begin(); ip != pl->end(); ++ip)
 
612
                      MusECore::Part* pt = editor->curCanvasPart();
 
613
                      MusECore::Part* newpt = pt;
 
614
                      MusECore::PartList* pl = editor->parts();
 
615
                      for(MusECore::iPart ip = pl->begin(); ip != pl->end(); ++ip)
734
616
                        if(ip->second == pt)
735
617
                        {
736
618
                          ++ip;
743
625
                        editor->setCurCanvasPart(newpt);
744
626
                  }
745
627
                  break;
746
 
            case CMD_DEL:
747
 
                  if (selectionSize()) {
748
 
                        song->startUndo();
749
 
                        for (iCItem i = items.begin(); i != items.end(); ++i) {
750
 
                              if (!i->second->isSelected())
751
 
                                    continue;
752
 
                              Event ev = i->second->event();
753
 
                              // Indicate no undo, and do not do port controller values and clone parts. 
754
 
                              //audio->msgDeleteEvent(ev, i->second->part(), false);
755
 
                              audio->msgDeleteEvent(ev, i->second->part(), false, false, false);
756
 
                              }
757
 
                        song->endUndo(SC_EVENT_REMOVED);
758
 
                        }
759
 
                  return;
760
628
 
761
629
            case CMD_SAVE:
762
630
            case CMD_LOAD:
766
634
            case CMD_FIXED_LEN: //Set notes to the length specified in the drummap
767
635
                  if (!selectionSize())
768
636
                        break;
769
 
                  song->startUndo();
 
637
                  MusEGlobal::song->startUndo();
770
638
                  for (iCItem k = items.begin(); k != items.end(); ++k) {
771
639
                        if (k->second->isSelected()) {
772
640
                              DEvent* devent = (DEvent*)(k->second);
773
 
                              Event event    = devent->event();
774
 
                              Event newEvent = event.clone();
775
 
                              newEvent.setLenTick(drumMap[event.pitch()].len);
 
641
                              MusECore::Event event    = devent->event();
 
642
                              MusECore::Event newEvent = event.clone();
 
643
                              newEvent.setLenTick(MusEGlobal::drumMap[event.pitch()].len);
776
644
                              // Indicate no undo, and do not do port controller values and clone parts. 
777
 
                              //audio->msgChangeEvent(event, newEvent, devent->part() , false);
778
 
                              audio->msgChangeEvent(event, newEvent, devent->part(), false, false, false);
 
645
                              MusEGlobal::audio->msgChangeEvent(event, newEvent, devent->part(), false, false, false);
779
646
                              }
780
647
                        }
781
 
                  song->endUndo(SC_EVENT_MODIFIED);
 
648
                  MusEGlobal::song->endUndo(SC_EVENT_MODIFIED);
782
649
                  break;
783
650
            case CMD_LEFT:
784
651
                  {
790
657
                      }
791
658
                      if(spos < 0)
792
659
                        spos = 0;
793
 
                      Pos p(spos,true);
794
 
                      song->setPos(0, p, true, true, true);
 
660
                      MusECore::Pos p(spos,true);
 
661
                      MusEGlobal::song->setPos(0, p, true, true, true);
795
662
                  }
796
663
                  break;
797
664
            case CMD_RIGHT:
798
665
                  {
799
666
                      int spos = AL::sigmap.raster2(pos[0] + 1, editor->rasterStep(pos[0]));    // Nudge by +1, then snap up with raster2.
800
 
                      Pos p(spos,true);
801
 
                      song->setPos(0, p, true, true, true);
 
667
                      MusECore::Pos p(spos,true);
 
668
                      MusEGlobal::song->setPos(0, p, true, true, true);
802
669
                  }
803
670
                  break;
804
671
            case CMD_LEFT_NOSNAP:
807
674
                  int spos = pos[0] - editor->rasterStep(pos[0]);
808
675
                  if (spos < 0)
809
676
                        spos = 0;
810
 
                  Pos p(spos,true);
811
 
                  song->setPos(0, p, true, true, true); //CDW
 
677
                  MusECore::Pos p(spos,true);
 
678
                  MusEGlobal::song->setPos(0, p, true, true, true); //CDW
812
679
                  }
813
680
                  break;
814
681
            case CMD_RIGHT_NOSNAP:
815
682
                  {
816
 
                  Pos p(pos[0] + editor->rasterStep(pos[0]), true);
817
 
                  //if (p > part->tick())
818
 
                  //      p = part->tick();
819
 
                  song->setPos(0, p, true, true, true); //CDW
820
 
                  }
821
 
                  break;
822
 
            case CMD_MODIFY_VELOCITY:
823
 
                  {
824
 
                  Velocity w;
825
 
                  w.setRange(0); //TODO: Make this work! Probably put _to & _toInit in ecanvas instead
826
 
                  if (!w.exec())
827
 
                        break;
828
 
                  int range  = w.range();        // all, selected, looped, sel+loop
829
 
                  int rate   = w.rateVal();
830
 
                  int offset = w.offsetVal();
831
 
 
832
 
                  song->startUndo();
833
 
                  for (iCItem k = items.begin(); k != items.end(); ++k) {
834
 
                        DEvent* devent = (DEvent*)(k->second);
835
 
                        Event event    = devent->event();
836
 
                        if (event.type() != Note)
837
 
                              continue;
838
 
                        unsigned tick      = event.tick();
839
 
                        bool selected = k->second->isSelected();
840
 
                        bool inLoop   = (tick >= song->lpos()) && (tick < song->rpos());
841
 
 
842
 
                        if ((range == 0)
843
 
                           || (range == 1 && selected)
844
 
                           || (range == 2 && inLoop)
845
 
                           || (range == 3 && selected && inLoop)) {
846
 
                              int velo = event.velo();
847
 
 
848
 
                              //velo = rate ? (velo * 100) / rate : 64;
849
 
                              velo = (velo * rate) / 100;
850
 
                              velo += offset;
851
 
 
852
 
                              if (velo <= 0)
853
 
                                    velo = 1;
854
 
                              if (velo > 127)
855
 
                                    velo = 127;
856
 
                              if (event.velo() != velo) {
857
 
                                    Event newEvent = event.clone();
858
 
                                    newEvent.setVelo(velo);
859
 
                                    // Indicate no undo, and do not do port controller values and clone parts. 
860
 
                                    //audio->msgChangeEvent(event, newEvent, devent->part(), false);
861
 
                                    audio->msgChangeEvent(event, newEvent, devent->part(), false, false, false);
862
 
                                    }
863
 
                              }
864
 
                        }
865
 
                  song->endUndo(SC_EVENT_MODIFIED);
 
683
                  MusECore::Pos p(pos[0] + editor->rasterStep(pos[0]), true);
 
684
                  MusEGlobal::song->setPos(0, p, true, true, true); //CDW
866
685
                  }
867
686
                  break;
868
687
            }
870
689
      redraw();
871
690
      }
872
691
 
873
 
/*
874
 
//---------------------------------------------------------
875
 
//   getTextDrag
876
 
//---------------------------------------------------------
877
 
 
878
 
Q3TextDrag* DrumCanvas::getTextDrag(QWidget* parent)
879
 
      {
880
 
      //---------------------------------------------------
881
 
      //   generate event list from selected events
882
 
      //---------------------------------------------------
883
 
 
884
 
      EventList el;
885
 
      unsigned startTick = MAXINT;
886
 
      for (iCItem i = items.begin(); i != items.end(); ++i) {
887
 
            if (!i->second->isSelected())
888
 
                  continue;
889
 
            DEvent* ne = (DEvent*)(i->second);
890
 
            Event    e = ne->event();
891
 
            if (startTick == MAXINT)
892
 
                  startTick = e.tick();
893
 
            el.add(e);
894
 
            }
895
 
 
896
 
      //---------------------------------------------------
897
 
      //    write events as XML into tmp file
898
 
      //---------------------------------------------------
899
 
 
900
 
      FILE* tmp = tmpfile();
901
 
      if (tmp == 0) {
902
 
            fprintf(stderr, "EventCanvas::copy() fopen failed: %s\n",
903
 
               strerror(errno));
904
 
            return 0;
905
 
            }
906
 
      Xml xml(tmp);
907
 
 
908
 
      int level = 0;
909
 
      for (ciEvent e = el.begin(); e != el.end(); ++e)
910
 
            e->second.write(level, xml, -startTick);
911
 
 
912
 
      //---------------------------------------------------
913
 
      //    read tmp file into QTextDrag Object
914
 
      //---------------------------------------------------
915
 
 
916
 
      fflush(tmp);
917
 
      struct stat f_stat;
918
 
      if (fstat(fileno(tmp), &f_stat) == -1) {
919
 
            fprintf(stderr, "EventCanvas::copy() fstat failes:<%s>\n",
920
 
               strerror(errno));
921
 
            fclose(tmp);
922
 
            return 0;
923
 
            }
924
 
      int n = f_stat.st_size;
925
 
      char* fbuf  = (char*)mmap(0, n+1, PROT_READ|PROT_WRITE,
926
 
         MAP_PRIVATE, fileno(tmp), 0);
927
 
      fbuf[n] = 0;
928
 
      Q3TextDrag* drag = new Q3TextDrag(QString(fbuf), parent);
929
 
      drag->setSubtype("eventlist");
930
 
      munmap(fbuf, n);
931
 
      fclose(tmp);
932
 
      return drag;
933
 
      }
934
 
*/
935
 
 
936
 
//---------------------------------------------------------
937
 
//   copy
938
 
//    cut copy paste
939
 
//---------------------------------------------------------
940
 
 
941
 
void DrumCanvas::copy()
942
 
      {
943
 
      QMimeData* md = getTextDrag();
944
 
      
945
 
      if (md)
946
 
            QApplication::clipboard()->setMimeData(md, QClipboard::Clipboard);
947
 
      }
948
 
 
949
 
/*
950
 
//---------------------------------------------------------
951
 
//   paste
952
 
//---------------------------------------------------------
953
 
 
954
 
int DrumCanvas::pasteAt(const QString& pt, int pos)
955
 
      {
956
 
      QByteArray ba = pt.toLatin1();
957
 
      const char* p = ba.constData();
958
 
      Xml xml(p);
959
 
 
960
 
      // Added by T356. 
961
 
      int modified = SC_EVENT_INSERTED;
962
 
      
963
 
      song->startUndo();
964
 
      for (;;) {
965
 
            Xml::Token token = xml.parse();
966
 
            QString tag = xml.s1();
967
 
            switch (token) {
968
 
                  case Xml::Error:
969
 
                  case Xml::End:
970
 
                        song->endUndo(modified);
971
 
                        return pos;
972
 
                  case Xml::TagStart:
973
 
                        if (tag == "event") {
974
 
                              Event e(Note);
975
 
                              e.read(xml);
976
 
                              
977
 
                              // Added by T356. 
978
 
                              int tick = e.tick() + pos - curPart->tick();
979
 
                              if (tick<0) { 
980
 
                                      printf("DrumCanvas::pasteAt ERROR: trying to add event before current part!\n");
981
 
                                      song->endUndo(SC_EVENT_INSERTED);
982
 
                                      //delete el;
983
 
                                      return pos;
984
 
                                      }
985
 
                              e.setTick(tick);
986
 
                              int diff = e.endTick() - curPart->lenTick();
987
 
                              if (diff > 0)  {// too short part? extend it
988
 
                                      Part* newPart = curPart->clone();
989
 
                                      newPart->setLenTick(newPart->lenTick()+diff);
990
 
                                      // Indicate no undo, and do port controller values but not clone parts. 
991
 
                                      audio->msgChangePart(curPart, newPart, false, true, false);
992
 
                                      
993
 
                                      modified=modified|SC_PART_MODIFIED;
994
 
                                      curPart = newPart; // reassign
995
 
                                      }
996
 
                              
997
 
                              // Indicate no undo, and do not do port controller values and clone parts. 
998
 
                              audio->msgAddEvent(e, curPart, false, false, false);
999
 
                              }
1000
 
                        else
1001
 
                              xml.unknown("DCanvas::pasteAt");
1002
 
                        break;
1003
 
                  case Xml::TagEnd:
1004
 
                  default:
1005
 
                        break;
1006
 
                  }
1007
 
            }
1008
 
      }
1009
 
*/
1010
 
 
1011
 
//---------------------------------------------------------
1012
 
//   paste
1013
 
//    paste events
1014
 
//---------------------------------------------------------
1015
 
 
1016
 
void DrumCanvas::paste()
1017
 
      {
1018
 
      QString stype("x-muse-eventlist");
1019
 
      
1020
 
      //QString s = QApplication::clipboard()->text(stype, QClipboard::Selection);  
1021
 
      QString s = QApplication::clipboard()->text(stype, QClipboard::Clipboard);  // TODO CHECK Tim.
1022
 
      
1023
 
      pasteAt(s, song->cpos());
1024
 
      }
1025
692
 
1026
693
//---------------------------------------------------------
1027
694
//   startDrag
1029
696
 
1030
697
void DrumCanvas::startDrag(CItem* /* item*/, bool copymode)
1031
698
      {
1032
 
      QMimeData* md = getTextDrag();
 
699
      QMimeData* md = selected_events_to_mime(partlist_to_set(editor->parts()), 1);
1033
700
      
1034
701
      if (md) {
1035
 
//            QApplication::clipboard()->setData(drag, QClipboard::Clipboard);   // This line NOT enabled in muse-1 
1036
 
            //QApplication::clipboard()->setMimeData(md);                // TODO CHECK Tim.
1037
 
            //QApplication::clipboard()->setMimeData(drag->mimeData());  // 
1038
 
 
1039
702
            // "Note that setMimeData() assigns ownership of the QMimeData object to the QDrag object. 
1040
703
            //  The QDrag must be constructed on the heap with a parent QWidget to ensure that Qt can 
1041
704
            //  clean up after the drag and drop operation has been completed. "
1074
737
      {
1075
738
      }
1076
739
 
1077
 
/*
1078
 
//---------------------------------------------------------
1079
 
//   dropEvent
1080
 
//---------------------------------------------------------
1081
 
 
1082
 
void DrumCanvas::viewDropEvent(QDropEvent* event)
1083
 
      {
1084
 
      QString text;
1085
 
      if (event->source() == this) {
1086
 
            printf("local DROP\n");      
1087
 
            //event->acceptProposedAction();     
1088
 
            //event->ignore();                     // TODO CHECK Tim.
1089
 
            return;
1090
 
            }
1091
 
      //if (event->mimeData()->hasText()) {
1092
 
      if (event->mimeData()->hasFormat("text/x-muse-eventlist")) {
1093
 
            
1094
 
            //text = event->mimeData()->text();
1095
 
            text = QString(event->mimeData()->data("text/x-muse-eventlist"));
1096
 
      
1097
 
//            printf("drop <%s>\n", text.ascii());
1098
 
            int x = editor->rasterVal(event->pos().x());
1099
 
            if (x < 0)
1100
 
                  x = 0;
1101
 
            pasteAt(text, x);
1102
 
            //event->accept();  // TODO
1103
 
            }
1104
 
      else {
1105
 
            printf("cannot decode drop\n");
1106
 
            //event->acceptProposedAction();     
1107
 
            //event->ignore();                     // TODO CHECK Tim.
1108
 
            }
1109
 
      }
1110
 
*/
1111
740
 
1112
741
//---------------------------------------------------------
1113
742
//   keyPressed - called from DList
1116
745
void DrumCanvas::keyPressed(int index, int velocity)
1117
746
      {
1118
747
      // called from DList - play event
1119
 
      int port = drumMap[index].port;
1120
 
      int channel = drumMap[index].channel;
1121
 
      int pitch = drumMap[index].anote;
 
748
      int port = MusEGlobal::drumMap[index].port;
 
749
      int channel = MusEGlobal::drumMap[index].channel;
 
750
      int pitch = MusEGlobal::drumMap[index].anote;
1122
751
 
1123
752
      // play note:
1124
 
      MidiPlayEvent e(0, port, channel, 0x90, pitch, velocity);
1125
 
      audio->msgPlayMidiEvent(&e);
 
753
      MusECore::MidiPlayEvent e(0, port, channel, 0x90, pitch, velocity);
 
754
      MusEGlobal::audio->msgPlayMidiEvent(&e);
 
755
 
 
756
      if (_steprec && pos[0] >= start_tick /* && pos[0] < end_tick [removed by flo93: this is handled in steprec->record] */ && curPart)
 
757
            steprec->record(curPart,index,MusEGlobal::drumMap[index].len,editor->raster(),velocity,MusEGlobal::globalKeyState&Qt::ControlModifier,MusEGlobal::globalKeyState&Qt::ShiftModifier);
 
758
            
1126
759
      }
1127
760
 
1128
761
//---------------------------------------------------------
1132
765
void DrumCanvas::keyReleased(int index, bool)
1133
766
      {
1134
767
      // called from DList - silence playing event
1135
 
      int port = drumMap[index].port;
1136
 
      int channel = drumMap[index].channel;
1137
 
      int pitch = drumMap[index].anote;
 
768
      int port = MusEGlobal::drumMap[index].port;
 
769
      int channel = MusEGlobal::drumMap[index].channel;
 
770
      int pitch = MusEGlobal::drumMap[index].anote;
1138
771
 
1139
772
      // release note:
1140
 
      MidiPlayEvent e(0, port, channel, 0x90, pitch, 0);
1141
 
      audio->msgPlayMidiEvent(&e);
 
773
      MusECore::MidiPlayEvent e(0, port, channel, 0x90, pitch, 0);
 
774
      MusEGlobal::audio->msgPlayMidiEvent(&e);
1142
775
      }
1143
776
 
1144
777
//---------------------------------------------------------
1147
780
 
1148
781
void DrumCanvas::mapChanged(int spitch, int dpitch)
1149
782
      {
1150
 
      //TODO: Circumvent undo behaviour, since this isn't really a true change of the events,
1151
 
      // but merely a change in pitch because the pitch relates to the order of the dlist.
1152
 
      // Right now the sequencer spits out internalError: undoOp without startUndo() if start/stopundo is there, which is misleading
1153
 
      // If start/stopundo is there, undo misbehaves since it doesn't undo but messes things up
1154
 
      // Other solution: implement a specific undo-event for this (SC_DRUMMAP_MODIFIED or something) which undoes movement of
1155
 
      // dlist-items (ml)
1156
 
 
1157
 
      std::vector< std::pair<Part*, Event*> > delete_events;
1158
 
      std::vector< std::pair<Part*, Event> > add_events;
1159
 
      
1160
 
      typedef std::vector< std::pair<Part*, Event*> >::iterator idel_ev;
1161
 
      typedef std::vector< std::pair<Part*, Event> >::iterator iadd_ev;
1162
 
      
1163
 
      /*
1164
 
      class delete_events : public std::vector< Part*, Event* > 
1165
 
      {
1166
 
        public:
1167
 
          idel_ev find(Part* p, Event* e)
1168
 
          {
1169
 
          
1170
 
          };
1171
 
      };
1172
 
      class add_events : public std::vector< Part*, Event > 
1173
 
      {
1174
 
        public:
1175
 
          iadd_ev find(Part* p, Event& e)
1176
 
          {
1177
 
          
1178
 
          };
1179
 
      };
1180
 
      */
1181
 
      
1182
 
      MidiTrackList* tracks = song->midis();
1183
 
      for (ciMidiTrack t = tracks->begin(); t != tracks->end(); t++) {
1184
 
            MidiTrack* curTrack = *t;
1185
 
            if (curTrack->type() != Track::DRUM)
 
783
      MusECore::Undo operations;
 
784
      std::vector< std::pair<MusECore::Part*, MusECore::Event*> > delete_events;
 
785
      std::vector< std::pair<MusECore::Part*, MusECore::Event> > add_events;
 
786
      
 
787
      typedef std::vector< std::pair<MusECore::Part*, MusECore::Event*> >::iterator idel_ev;
 
788
      typedef std::vector< std::pair<MusECore::Part*, MusECore::Event> >::iterator iadd_ev;
 
789
      
 
790
      MusECore::MidiTrackList* tracks = MusEGlobal::song->midis();
 
791
      for (MusECore::ciMidiTrack t = tracks->begin(); t != tracks->end(); t++) {
 
792
            MusECore::MidiTrack* curTrack = *t;
 
793
            if (curTrack->type() != MusECore::Track::DRUM)
1186
794
                  continue;
1187
795
 
1188
 
            MidiPort* mp = &midiPorts[curTrack->outPort()];
1189
 
            PartList* parts= curTrack->parts();
1190
 
            for (iPart part = parts->begin(); part != parts->end(); ++part) {
1191
 
                  EventList* events = part->second->events();
1192
 
                  Part* thePart = part->second;
1193
 
                  for (iEvent i = events->begin(); i != events->end(); ++i) {
1194
 
                        Event event = i->second;
1195
 
                        if(event.type() != Controller && event.type() != Note)
 
796
            MusECore::MidiPort* mp = &MusEGlobal::midiPorts[curTrack->outPort()];
 
797
            MusECore::PartList* parts= curTrack->parts();
 
798
            for (MusECore::iPart part = parts->begin(); part != parts->end(); ++part) {
 
799
                  MusECore::EventList* events = part->second->events();
 
800
                  MusECore::Part* thePart = part->second;
 
801
                  for (MusECore::iEvent i = events->begin(); i != events->end(); ++i) {
 
802
                        MusECore::Event event = i->second;
 
803
                        if(event.type() != MusECore::Controller && event.type() != MusECore::Note)
1196
804
                          continue;
1197
805
                        int pitch = event.pitch();
1198
806
                        bool drc = false;
1199
807
                        // Is it a drum controller event, according to the track port's instrument?
1200
 
                        if(event.type() == Controller && mp->drumController(event.dataA()))
 
808
                        if(event.type() == MusECore::Controller && mp->drumController(event.dataA()))
1201
809
                        {
1202
810
                          drc = true;
1203
811
                          pitch = event.dataA() & 0x7f;
1204
812
                        }
1205
813
                        
1206
814
                        if (pitch == spitch) {
1207
 
                              Event* spitch_event = &(i->second);
1208
 
                              delete_events.push_back(std::pair<Part*, Event*>(thePart, spitch_event));
1209
 
                              Event newEvent = spitch_event->clone();
 
815
                              MusECore::Event* spitch_event = &(i->second);
 
816
                              delete_events.push_back(std::pair<MusECore::Part*, MusECore::Event*>(thePart, spitch_event));
 
817
                              MusECore::Event newEvent = spitch_event->clone();
1210
818
                              if(drc)
1211
819
                                newEvent.setA((newEvent.dataA() & ~0xff) | dpitch);
1212
820
                              else
1213
821
                                newEvent.setPitch(dpitch);
1214
 
                              add_events.push_back(std::pair<Part*, Event>(thePart, newEvent));
 
822
                              add_events.push_back(std::pair<MusECore::Part*, MusECore::Event>(thePart, newEvent));
1215
823
                              }
1216
824
                        else if (pitch == dpitch) {
1217
 
                              Event* dpitch_event = &(i->second);
1218
 
                              delete_events.push_back(std::pair<Part*, Event*>(thePart, dpitch_event));
1219
 
                              Event newEvent = dpitch_event->clone();
 
825
                              MusECore::Event* dpitch_event = &(i->second);
 
826
                              delete_events.push_back(std::pair<MusECore::Part*, MusECore::Event*>(thePart, dpitch_event));
 
827
                              MusECore::Event newEvent = dpitch_event->clone();
1220
828
                              if(drc)
1221
829
                                newEvent.setA((newEvent.dataA() & ~0xff) | spitch);
1222
830
                              else
1223
831
                                newEvent.setPitch(spitch);
1224
 
                              add_events.push_back(std::pair<Part*, Event>(thePart, newEvent));
 
832
                              add_events.push_back(std::pair<MusECore::Part*, MusECore::Event>(thePart, newEvent));
1225
833
                              }
1226
834
                        }
1227
835
                  }
1228
836
            }
1229
837
 
1230
 
      song->startUndo();
1231
838
      for (idel_ev i = delete_events.begin(); i != delete_events.end(); i++) {
1232
 
            //std::pair<Part*, Event*> pair = *i;
1233
 
            //Part*  thePart = pair.first;
1234
 
            //Event* theEvent = pair.second;
1235
 
            Part*  thePart = (*i).first;
1236
 
            Event* theEvent = (*i).second;
1237
 
            // Indicate no undo, and do port controller values but not clone parts. 
1238
 
            //audio->msgDeleteEvent(*theEvent, thePart, false);
1239
 
            audio->msgDeleteEvent(*theEvent, thePart, false, true, false);
 
839
            MusECore::Part*  thePart = (*i).first;
 
840
            MusECore::Event* theEvent = (*i).second;
 
841
            operations.push_back(MusECore::UndoOp(MusECore::UndoOp::DeleteEvent, *theEvent, thePart, true, false));
1240
842
            }
1241
843
 
1242
 
      DrumMap dm = drumMap[spitch];
1243
 
      drumMap[spitch] = drumMap[dpitch];
1244
 
      drumMap[dpitch] = dm;
1245
 
      drumInmap[int(drumMap[spitch].enote)]  = spitch;
1246
 
      drumOutmap[int(drumMap[int(spitch)].anote)] = spitch;
1247
 
      drumInmap[int(drumMap[int(dpitch)].enote)]  = dpitch;
1248
 
      drumOutmap[int(drumMap[int(dpitch)].anote)] = dpitch;
 
844
      MusECore::DrumMap dm = MusEGlobal::drumMap[spitch];
 
845
      MusEGlobal::drumMap[spitch] = MusEGlobal::drumMap[dpitch];
 
846
      MusEGlobal::drumMap[dpitch] = dm;
 
847
      MusEGlobal::drumInmap[int(MusEGlobal::drumMap[spitch].enote)]  = spitch;
 
848
      MusEGlobal::drumOutmap[int(MusEGlobal::drumMap[int(spitch)].anote)] = spitch;
 
849
      MusEGlobal::drumInmap[int(MusEGlobal::drumMap[int(dpitch)].enote)]  = dpitch;
 
850
      MusEGlobal::drumOutmap[int(MusEGlobal::drumMap[int(dpitch)].anote)] = dpitch;
1249
851
            
1250
852
      for (iadd_ev i = add_events.begin(); i != add_events.end(); i++) {
1251
 
            //std::pair<Part*, Event> pair = *i;
1252
 
            //Part*  thePart = pair.first;
1253
 
            //Event& theEvent = pair.second;
1254
 
            Part*  thePart = (*i).first;
1255
 
            Event& theEvent = (*i).second;
1256
 
            // Indicate no undo, and do port controller values but not clone parts. 
1257
 
            //audio->msgAddEvent(theEvent, thePart, false);
1258
 
            audio->msgAddEvent(theEvent, thePart, false, true, false);
 
853
            MusECore::Part*  thePart = (*i).first;
 
854
            MusECore::Event& theEvent = (*i).second;
 
855
            operations.push_back(MusECore::UndoOp(MusECore::UndoOp::AddEvent, theEvent, thePart, true, false));
1259
856
            }
1260
857
      
1261
 
      song->endUndo(SC_EVENT_MODIFIED);
1262
 
      song->update(SC_DRUMMAP);
 
858
      MusEGlobal::song->applyOperationGroup(operations, false); // do not indicate undo
 
859
      MusEGlobal::song->update(SC_DRUMMAP); //this update is neccessary, as it's not handled by applyOperationGroup()
1263
860
      }
1264
861
 
1265
862
//---------------------------------------------------------
1280
877
 
1281
878
void DrumCanvas::modifySelected(NoteInfo::ValType type, int delta)
1282
879
      {
1283
 
      audio->msgIdle(true);
1284
 
      song->startUndo();
 
880
      MusEGlobal::audio->msgIdle(true);
 
881
      MusEGlobal::song->startUndo();
1285
882
      for (iCItem i = items.begin(); i != items.end(); ++i) {
1286
883
            if (!(i->second->isSelected()))
1287
884
                  continue;
1288
885
            DEvent* e   = (DEvent*)(i->second);
1289
 
            Event event = e->event();
1290
 
            if (event.type() != Note)
 
886
            MusECore::Event event = e->event();
 
887
            if (event.type() != MusECore::Note)
1291
888
                  continue;
1292
889
 
1293
 
            MidiPart* part = (MidiPart*)(e->part());
1294
 
            Event newEvent = event.clone();
 
890
            MusECore::MidiPart* part = (MusECore::MidiPart*)(e->part());
 
891
            MusECore::Event newEvent = event.clone();
1295
892
 
1296
893
            switch (type) {
1297
894
                  case NoteInfo::VAL_TIME:
1303
900
                        }
1304
901
                        break;
1305
902
                  case NoteInfo::VAL_LEN:
1306
 
                        /*
1307
 
                        {
1308
 
                        int len = event.lenTick() + delta;
1309
 
                        if (len < 1)
1310
 
                              len = 1;
1311
 
                        newEvent.setLenTick(len);
1312
 
                        }
1313
 
                        */
1314
903
                        printf("DrumCanvas::modifySelected - NoteInfo::VAL_LEN not implemented\n");
1315
904
                        break;
1316
905
                  case NoteInfo::VAL_VELON:
1317
 
                        /*
1318
 
                        {
1319
 
                        int velo = event->velo() + delta;
1320
 
                        if (velo > 127)
1321
 
                              velo = 127;
1322
 
                        else if (velo < 0)
1323
 
                              velo = 0;
1324
 
                        newEvent.setVelo(velo);
1325
 
                        }
1326
 
                        */
1327
906
                        printf("DrumCanvas::modifySelected - NoteInfo::VAL_VELON not implemented\n");
1328
907
                        break;
1329
908
                  case NoteInfo::VAL_VELOFF:
1330
 
                        /*
1331
 
                        {
1332
 
                        int velo = event.veloOff() + delta;
1333
 
                        if (velo > 127)
1334
 
                              velo = 127;
1335
 
                        else if (velo < 0)
1336
 
                              velo = 0;
1337
 
                        newEvent.setVeloOff(velo);
1338
 
                        }
1339
 
                        */
1340
909
                        printf("DrumCanvas::modifySelected - NoteInfo::VAL_VELOFF not implemented\n");
1341
910
                        break;
1342
911
                  case NoteInfo::VAL_PITCH:
1350
919
                        }
1351
920
                        break;
1352
921
                  }
1353
 
            song->changeEvent(event, newEvent, part);
 
922
            MusEGlobal::song->changeEvent(event, newEvent, part);
1354
923
            // Indicate do not do port controller values and clone parts. 
1355
 
            //song->undoOp(UndoOp::ModifyEvent, newEvent, event, part);
1356
 
            song->undoOp(UndoOp::ModifyEvent, newEvent, event, part, false, false);
 
924
            MusEGlobal::song->addUndo(MusECore::UndoOp(MusECore::UndoOp::ModifyEvent, newEvent, event, part, false, false));
1357
925
            }
1358
 
      song->endUndo(SC_EVENT_MODIFIED);
1359
 
      audio->msgIdle(false);
 
926
      MusEGlobal::song->endUndo(SC_EVENT_MODIFIED);
 
927
      MusEGlobal::audio->msgIdle(false);
1360
928
      }
1361
929
 
1362
930
//---------------------------------------------------------
1399
967
  if (_tool == CursorTool) {
1400
968
 
1401
969
    int key = event->key();
1402
 
    ///if (event->state() & Qt::ShiftButton)
1403
970
    if (((QInputEvent*)event)->modifiers() & Qt::ShiftModifier)
1404
971
          key += Qt::SHIFT;
1405
 
    ///if (event->state() & Qt::AltButton)
1406
972
    if (((QInputEvent*)event)->modifiers() & Qt::AltModifier)
1407
973
          key += Qt::ALT;
1408
 
    ///if (event->state() & Qt::ControlButton)
1409
974
    if (((QInputEvent*)event)->modifiers() & Qt::ControlModifier)
1410
975
          key+= Qt::CTRL;
1411
976
 
1429
994
      return;
1430
995
    }
1431
996
    else if (key == shortcuts[SHRT_ADDNOTE_1].key) {
1432
 
          newItem(newItem(cursorPos.x(), cursorPos.y(), drumMap[cursorPos.y()].lv1),false,true);
1433
 
          keyPressed(cursorPos.y(), drumMap[cursorPos.y()].lv1);
 
997
          newItem(newItem(cursorPos.x(), cursorPos.y(), MusEGlobal::drumMap[cursorPos.y()].lv1),false,true);
 
998
          keyPressed(cursorPos.y(), MusEGlobal::drumMap[cursorPos.y()].lv1);
1434
999
          keyReleased(cursorPos.y(), false);
1435
1000
          cursorPos.setX(getNextStep(cursorPos.x(),1, _stepSize));
1436
1001
          selectCursorEvent(getEventAtCursorPos());
1439
1004
          return;
1440
1005
    }
1441
1006
    else if (key == shortcuts[SHRT_ADDNOTE_2].key) {
1442
 
          newItem(newItem(cursorPos.x(), cursorPos.y(), drumMap[cursorPos.y()].lv2),false,true);
1443
 
          keyPressed(cursorPos.y(), drumMap[cursorPos.y()].lv2);
 
1007
          newItem(newItem(cursorPos.x(), cursorPos.y(), MusEGlobal::drumMap[cursorPos.y()].lv2),false,true);
 
1008
          keyPressed(cursorPos.y(), MusEGlobal::drumMap[cursorPos.y()].lv2);
1444
1009
          keyReleased(cursorPos.y(), false);
1445
1010
          cursorPos.setX(getNextStep(cursorPos.x(),1, _stepSize));
1446
1011
          selectCursorEvent(getEventAtCursorPos());
1449
1014
          return;
1450
1015
    }
1451
1016
    else if (key == shortcuts[SHRT_ADDNOTE_3].key) {
1452
 
          newItem(newItem(cursorPos.x(), cursorPos.y(), drumMap[cursorPos.y()].lv3),false,true);
1453
 
          keyPressed(cursorPos.y(), drumMap[cursorPos.y()].lv3);
 
1017
          newItem(newItem(cursorPos.x(), cursorPos.y(), MusEGlobal::drumMap[cursorPos.y()].lv3),false,true);
 
1018
          keyPressed(cursorPos.y(), MusEGlobal::drumMap[cursorPos.y()].lv3);
1454
1019
          keyReleased(cursorPos.y(), false);
1455
1020
          cursorPos.setX(getNextStep(cursorPos.x(),1, _stepSize));
1456
1021
          selectCursorEvent(getEventAtCursorPos());
1459
1024
          return;
1460
1025
    }
1461
1026
    else if (key == shortcuts[SHRT_ADDNOTE_4].key) {
1462
 
          newItem(newItem(cursorPos.x(), cursorPos.y(), drumMap[cursorPos.y()].lv4),false,true);
1463
 
          keyPressed(cursorPos.y(), drumMap[cursorPos.y()].lv4);
 
1027
          newItem(newItem(cursorPos.x(), cursorPos.y(), MusEGlobal::drumMap[cursorPos.y()].lv4),false,true);
 
1028
          keyPressed(cursorPos.y(), MusEGlobal::drumMap[cursorPos.y()].lv4);
1464
1029
          keyReleased(cursorPos.y(), false);
1465
1030
          cursorPos.setX(getNextStep(cursorPos.x(),1, _stepSize));
1466
1031
          selectCursorEvent(getEventAtCursorPos());
1504
1069
//---------------------------------------------------------
1505
1070
//   getEventAtCursorPos
1506
1071
//---------------------------------------------------------
1507
 
Event *DrumCanvas::getEventAtCursorPos()
 
1072
MusECore::Event *DrumCanvas::getEventAtCursorPos()
1508
1073
{
1509
1074
    if (_tool != CursorTool)
1510
1075
      return 0;
1511
 
    EventList* el = curPart->events();
1512
 
    iEvent lower  = el->lower_bound(cursorPos.x()-curPart->tick());
1513
 
    iEvent upper  = el->upper_bound(cursorPos.x()-curPart->tick());
1514
 
    for (iEvent i = lower; i != upper; ++i) {
1515
 
      Event &ev = i->second;
 
1076
    MusECore::EventList* el = curPart->events();
 
1077
    MusECore::iEvent lower  = el->lower_bound(cursorPos.x()-curPart->tick());
 
1078
    MusECore::iEvent upper  = el->upper_bound(cursorPos.x()-curPart->tick());
 
1079
    for (MusECore::iEvent i = lower; i != upper; ++i) {
 
1080
      MusECore::Event &ev = i->second;
1516
1081
      if(!ev.isNote())
1517
1082
        continue;
1518
1083
      if (ev.pitch() == cursorPos.y()) {
1524
1089
//---------------------------------------------------------
1525
1090
//   selectCursorEvent
1526
1091
//---------------------------------------------------------
1527
 
void DrumCanvas::selectCursorEvent(Event *ev)
 
1092
void DrumCanvas::selectCursorEvent(MusECore::Event *ev)
1528
1093
{
1529
1094
  for (iCItem i = items.begin(); i != items.end(); ++i)
1530
1095
  {
1531
 
        Event e = i->second->event();
 
1096
        MusECore::Event e = i->second->event();
1532
1097
 
1533
1098
        if (ev && ev->tick() == e.tick() && ev->pitch() == e.pitch() && e.isNote())
1534
1099
          i->second->setSelected(true);
1538
1103
  }
1539
1104
  updateSelection();
1540
1105
}
 
1106
 
 
1107
 
 
1108
void DrumCanvas::moveAwayUnused()
 
1109
{
 
1110
        using std::set;
 
1111
        
 
1112
        set<int> used;
 
1113
        for (iCItem it=items.begin(); it!=items.end(); it++)
 
1114
        {
 
1115
                const MusECore::Event& ev=it->second->event();
 
1116
                
 
1117
                if (ev.type()==MusECore::Note)
 
1118
                        used.insert(ev.pitch());
 
1119
        }
 
1120
        
 
1121
        int count=0;
 
1122
        for (set<int>::iterator it=used.begin(); it!=used.end();)
 
1123
        {
 
1124
                while ((*it != count) && (used.find(count)!=used.end())) count++;
 
1125
                
 
1126
                if (*it != count)
 
1127
                        mapChanged(*it, count);
 
1128
 
 
1129
                count++;
 
1130
                
 
1131
                used.erase(it++);
 
1132
        }
 
1133
}
 
1134
 
 
1135
 
 
1136
//---------------------------------------------------------
 
1137
//   midiNote
 
1138
//---------------------------------------------------------
 
1139
void DrumCanvas::midiNote(int pitch, int velo)
 
1140
      {
 
1141
      if (MusEGlobal::debugMsg) printf("DrumCanvas::midiNote: pitch=%i, velo=%i\n", pitch, velo);
 
1142
 
 
1143
      if (_midiin && _steprec && curPart
 
1144
         && !MusEGlobal::audio->isPlaying() && velo && pos[0] >= start_tick
 
1145
         /* && pos[0] < end_tick [removed by flo93: this is handled in steprec->record] */
 
1146
         && !(MusEGlobal::globalKeyState & Qt::AltModifier)) {
 
1147
                                               steprec->record(curPart,MusEGlobal::drumInmap[pitch],MusEGlobal::drumMap[(int)MusEGlobal::drumInmap[pitch]].len,editor->raster(),velo,MusEGlobal::globalKeyState&Qt::ControlModifier,MusEGlobal::globalKeyState&Qt::ShiftModifier);
 
1148
         }
 
1149
      }
 
1150
 
 
1151
} // namespace MusEGui