~ubuntu-branches/ubuntu/quantal/muse/quantal

« back to all changes in this revision

Viewing changes to muse/arranger/pcanvas.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Fabrice Coutadeur
  • Date: 2010-11-17 21:43:38 UTC
  • mfrom: (1.1.8 upstream)
  • Revision ID: james.westby@ubuntu.com-20101117214338-1hvfl7oo2dsqnvrb
Tags: 1.1-0ubuntu1
* New upstream release (LP: #668631)
* Switch to dpkg-source 3.0 (quilt) format
* Switch to dh7 short form
* debian/rules:
  - added --enable-dssi and --enable-osc to conf flags for dssi support
  - added -ljackserver to LDFLAGS to fix a FTBFS because of --as-needed
* debian/control:
  - added build build dependency on liblo-dev and dssi-dev for dssi support
  - bump Standards-version to 3.9.1. No changes required.
* debian/muse.desktop, debian/muse.xpm: dropped as desktop file and icon is
  now shipped upstream.
* fix-desktop-categories.patch: fix Categories tag in upstream desktop file
* 10_es_locale_fix.dpatch: refreshed and converted to quilt as
  fix_es_locale.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
#include <errno.h>
12
12
#include <values.h>
13
13
#include <uuid/uuid.h>
 
14
#include <math.h>
14
15
 
15
16
#include <qapplication.h>
16
17
#include <qclipboard.h>
36
37
#include "gconfig.h"
37
38
#include "app.h"
38
39
#include "filedialog.h"
 
40
#include "marker/marker.h"
39
41
 
40
42
const char* partColorNames[] = {
41
43
      "Default",
560
562
      for (iCItem i = items.begin(); i != items.end(); ++i) {
561
563
            NPart* part = (NPart*)(i->second);
562
564
            part->part()->setSelected(i->second->isSelected());
563
 
            }
 
565
      }
564
566
      emit selectionChanged();
565
567
      redraw();
566
568
      }
861
863
                  {
862
864
                  const Part* part = item->part();
863
865
                  bool popenFlag = false;
864
 
                  QString fn = getSaveFileName(QString(""), part_file_pattern, this, tr("MusE: save part"));
 
866
                  //QString fn = getSaveFileName(QString(""), part_file_pattern, this, tr("MusE: save part"));
 
867
                  QString fn = getSaveFileName(QString(""), part_file_save_pattern, this, tr("MusE: save part"));
865
868
                  if (!fn.isEmpty()) {
866
869
                        FILE* fp = fileOpen(this, fn, ".mpt", "w", popenFlag, false, false);
867
870
                        if (fp) {
1084
1087
            emit setUsedTool(MuteTool);
1085
1088
            return;
1086
1089
            }
 
1090
      else if (key == shortcuts[SHRT_SEL_TRACK_ABOVE].key) {
 
1091
            emit selectTrackAbove();
 
1092
            return;
 
1093
            }
 
1094
      else if (key == shortcuts[SHRT_SEL_TRACK_BELOW].key) {
 
1095
            emit selectTrackBelow();
 
1096
            return;
 
1097
            }
1087
1098
 
1088
1099
      //
1089
1100
      // Shortcuts that require selected parts from here
1090
1101
      //
1091
 
      if (!curItem) { //TODO: Fix a curItem from selected parts if song is loaded and has selected parts.
1092
 
            event->ignore();
1093
 
            return;
1094
 
            }
 
1102
      if (!curItem) {
 
1103
          if (items.size()==0) {
 
1104
              return;
 
1105
          }
 
1106
          for (iCItem i = items.begin(); i != items.end(); ++i) {
 
1107
              NPart* part = (NPart*)(i->second);
 
1108
              if (part->isSelected()) {
 
1109
                curItem=part;
 
1110
                break;
 
1111
              }
 
1112
          }
 
1113
          if (!curItem)
 
1114
            curItem = (NPart*)items.begin()->second; // just grab the first part
 
1115
      }
1095
1116
 
1096
1117
      CItem* newItem = 0;
1097
1118
      bool singleSelection = isSingleSelection();
1176
1197
                  newItem = i->second;
1177
1198
                  }
1178
1199
            }
 
1200
 
1179
1201
      // Select nearest part on track above
1180
1202
      else if (key == shortcuts[SHRT_SEL_ABOVE].key || key == shortcuts[SHRT_SEL_ABOVE_ADD].key) {
1181
1203
            if (key == shortcuts[SHRT_SEL_ABOVE_ADD].key)
1186
1208
            track = y2Track(track->y() - 1);
1187
1209
 
1188
1210
            //If we're at topmost, leave
1189
 
            if (!track)
 
1211
            if (!track) {
 
1212
              printf("no track above!\n");
1190
1213
                  return;
1191
 
 
 
1214
                }
1192
1215
            int middle = curItem->x() + curItem->part()->lenTick()/2;
1193
1216
            CItem *aboveL = 0, *aboveR = 0;
1194
1217
            //Upper limit: song end, lower limit: song start
1345
1368
      int from   = rect.x();
1346
1369
      int to     = from + rect.width();
1347
1370
 
 
1371
      //printf("from %d to %d\n", from,to);
1348
1372
      Part* part = ((NPart*)item)->part();
1349
1373
      int pTick  = part->tick();
1350
1374
      from      -= pTick;
1358
1382
      //QRect r    = item->bbox().intersect(rect);
1359
1383
      int i      = part->colorIndex();
1360
1384
 
 
1385
      //printf("part start tick %d part start pixel %d\n", part->tick(), r.x());
 
1386
 
1361
1387
      // Added by Tim. p3.3.6
1362
1388
      //printf("PartCanvas::drawItem %s evRefs:%d pTick:%d pLen:%d bb.x:%d bb.w:%d rect.x:%d rect.w:%d r.x:%d r.w:%d\n", part->name().latin1(), part->events()->arefCount(), pTick, part->lenTick(), item->bbox().x(), item->bbox().width(), rect.x(), rect.width(), r.x(), r.width());
1363
1389
  
1444
1470
                  p.setPen(darkGray);
1445
1471
                  EventList* events = mp->events();
1446
1472
                  iEvent ito(events->lower_bound(to));
1447
 
                  // Added by Tim. P3.3.6
1448
1473
                  //printf("PartCanvas::drawItem pTick:%d from:%d to:%d part len:%d\n", pTick, from, to, part->lenTick());
1449
1474
                  
1450
1475
                  for (iEvent i = events->begin(); i != ito; ++i) {
1453
1478
 
1454
1479
                        if (t > (to + pTick))
1455
1480
                        {
1456
 
                          // Added by Tim. P3.3.6
1457
1481
                          printf("PartCanvas::drawItem t:%d > to:%d + pTick:%d i->first:%d\n", t, to, pTick, i->first);
1458
1482
                          
1459
1483
                          break;
1677
1701
            case CMD_PASTE_CLONE_PART_TO_TRACK:
1678
1702
                  paste(true);
1679
1703
                  break;
 
1704
            case CMD_INSERT_PART:
 
1705
                  paste(false, false, true);
 
1706
                  break;
 
1707
            case CMD_INSERT_EMPTYMEAS:
 
1708
                  song->startUndo();
 
1709
                  int startPos=song->vcpos();
 
1710
                  int oneMeas=sigmap.ticksMeasure(startPos);
 
1711
                  movePartsTotheRight(startPos,oneMeas);
 
1712
                  song->endUndo(SC_PART_INSERTED);
 
1713
                  break;
1680
1714
            }
1681
1715
      }
1682
1716
 
1787
1821
      int  done = 0;
1788
1822
      bool end = false;
1789
1823
 
1790
 
      song->startUndo();
 
1824
      //song->startUndo();
1791
1825
      for (;;) {
1792
1826
            Xml::Token token = xml.parse();
1793
1827
            const QString& tag = xml.s1();
1836
1870
                                    posOffset=pos-p->tick();
1837
1871
                                    }
1838
1872
                              p->setTick(p->tick()+posOffset);
1839
 
                              finalPos=p->tick()+p->lenTick();
 
1873
                              if (p->tick()+p->lenTick()>finalPos) {
 
1874
                                finalPos=p->tick()+p->lenTick();
 
1875
                              }
1840
1876
                              //pos += p->lenTick();
1841
1877
                              audio->msgAddPart(p,false);
1842
1878
                              }
1853
1889
                  break;
1854
1890
            }
1855
1891
      
1856
 
      song->endUndo(SC_PART_INSERTED);
 
1892
      //song->endUndo(SC_PART_INSERTED);
1857
1893
      //return pos;
1858
1894
      
1859
1895
      if(notDone)
2265
2301
//---------------------------------------------------------
2266
2302
 
2267
2303
//void PartCanvas::paste()
2268
 
void PartCanvas::paste(bool clone, bool toTrack)
 
2304
void PartCanvas::paste(bool clone, bool toTrack, bool doInsert)
2269
2305
{
2270
2306
      Track* track = 0;
 
2307
 
 
2308
      if (doInsert) // logic depends on keeping track of newly selected tracks
 
2309
          deselectAll();
 
2310
 
 
2311
 
2271
2312
      // If we want to paste to a selected track...
2272
2313
      if(toTrack)
2273
2314
      {  
2338
2379
            
2339
2380
      QCString subtype = 0;
2340
2381
      QString txt = cb->text(subtype);
2341
 
      if (!txt.isEmpty()) 
 
2382
      int endPos=0;
 
2383
      int startPos=song->vcpos();
 
2384
      if (!txt.isEmpty())
2342
2385
      {
2343
 
        Pos p(pasteAt(txt, track, song->vcpos(), clone, toTrack), true);
 
2386
        song->startUndo();
 
2387
        endPos=pasteAt(txt, track, startPos, clone, toTrack);
 
2388
        Pos p(endPos, true);
2344
2389
        song->setPos(0, p);
 
2390
        if (!doInsert)
 
2391
          song->endUndo(SC_PART_INSERTED);
 
2392
 
 
2393
      }
 
2394
 
 
2395
      if (doInsert) {
 
2396
        int offset = endPos-startPos;
 
2397
        movePartsTotheRight(startPos, offset);
 
2398
        song->endUndo(SC_PART_INSERTED);
2345
2399
      }
2346
2400
    }
2347
2401
 
2348
2402
//---------------------------------------------------------
 
2403
//   movePartsToTheRight
 
2404
//---------------------------------------------------------
 
2405
void PartCanvas::movePartsTotheRight(int startTicks, int length)
 
2406
{
 
2407
        // all parts that start after the pasted parts will be moved the entire length of the pasted parts
 
2408
        for (iCItem i = items.begin(); i != items.end(); ++i) {
 
2409
          if (!i->second->isSelected()) {
 
2410
              Part* part = i->second->part();
 
2411
              if (part->tick() >= startTicks) {
 
2412
                //void Audio::msgChangePart(Part* oldPart, Part* newPart, bool doUndoFlag, bool doCtrls, bool doClones)
 
2413
                Part *newPart = part->clone();
 
2414
                newPart->setTick(newPart->tick()+length);
 
2415
                if (part->track()->type() == Track::WAVE) {
 
2416
                  audio->msgChangePart((WavePart*)part,(WavePart*)newPart,false,false,false);
 
2417
                } else {
 
2418
                  audio->msgChangePart(part,newPart,false,false,false);
 
2419
                }
 
2420
 
 
2421
              }
 
2422
          }
 
2423
        }
 
2424
        // perhaps ask if markers should be moved?
 
2425
        MarkerList *markerlist = song->marker();
 
2426
        for(iMarker i = markerlist->begin(); i != markerlist->end(); ++i)
 
2427
        {
 
2428
            Marker* m = &i->second;
 
2429
            if (m->tick() >= startTicks) {
 
2430
              Marker *oldMarker = new Marker();
 
2431
              *oldMarker = *m;
 
2432
              m->setTick(m->tick()+length);
 
2433
              song->undoOp(UndoOp::ModifyMarker,oldMarker, m);
 
2434
            }
 
2435
        }
 
2436
}
 
2437
//---------------------------------------------------------
2349
2438
//   startDrag
2350
2439
//---------------------------------------------------------
2351
2440
 
2471
2560
                  Track* track = 0;
2472
2561
                  if (trackNo < tracks->size())
2473
2562
                        track = tracks->index(trackNo);
2474
 
                  if (track)
 
2563
                  if (track) {
 
2564
                        song->startUndo();
2475
2565
                        pasteAt(text, track, x);
 
2566
                        song->endUndo(SC_PART_INSERTED);
 
2567
                      }
2476
2568
                  }
2477
2569
            else if (type == 2) {
2478
2570
                  text = text.stripWhiteSpace();
2530
2622
//---------------------------------------------------------
2531
2623
 
2532
2624
void PartCanvas::drawCanvas(QPainter& p, const QRect& rect)
2533
 
      {
 
2625
{
2534
2626
      int x = rect.x();
2535
2627
      int y = rect.y();
2536
2628
      int w = rect.width();
2539
2631
      //////////
2540
2632
      // GRID //
2541
2633
      //////////
2542
 
 
2543
 
      p.setPen(lightGray);
2544
 
 
 
2634
      QColor baseColor(config.partCanvasBg.light(104));
 
2635
      p.setPen(baseColor);
 
2636
 
 
2637
      //--------------------------------
 
2638
      // vertical lines
 
2639
      //-------------------------------
 
2640
      //printf("raster=%d\n", *_raster);
 
2641
      if (config.canvasShowGrid) {
 
2642
          int bar, beat;
 
2643
          unsigned tick;
 
2644
 
 
2645
          sigmap.tickValues(x, &bar, &beat, &tick);
 
2646
          for (;;) {
 
2647
            int xt = sigmap.bar2tick(bar++, 0, 0);
 
2648
            if (xt >= x + w)
 
2649
                  break;
 
2650
            if (!((bar-1) % 4))
 
2651
                p.setPen(baseColor.dark(115));
 
2652
            else
 
2653
                p.setPen(baseColor);
 
2654
            p.drawLine(xt, y, xt, y+h);
 
2655
 
 
2656
            // append
 
2657
            int noDivisors=0;
 
2658
            if (*_raster == config.division *2)         // 1/2
 
2659
                noDivisors=2;
 
2660
            else if (*_raster== config.division)        // 1/4
 
2661
                noDivisors=4;
 
2662
            else if (*_raster==config.division/2)         // 1/8
 
2663
                noDivisors=8;
 
2664
            else if (*_raster==config.division/4)          // 1/16
 
2665
                noDivisors=16;
 
2666
            else if (*_raster==config.division/8)          // 1/16
 
2667
                noDivisors=32;
 
2668
            else if (*_raster==config.division/16)          // 1/16
 
2669
                noDivisors=64;
 
2670
 
 
2671
            int r = *_raster;
 
2672
            int rr = rmapx(r);
 
2673
            if (*_raster > 1) {
 
2674
              while (rr < 4) {
 
2675
                r *= 2;
 
2676
                rr = rmapx(r);
 
2677
                noDivisors=noDivisors/2;
 
2678
              }
 
2679
              p.setPen(baseColor);
 
2680
              for (int t=1;t< noDivisors;t++)
 
2681
                p.drawLine(xt+r*t, y, xt+r*t, y+h);
 
2682
            }
 
2683
          }
 
2684
      }
2545
2685
      //--------------------------------
2546
2686
      // horizontal lines
2547
2687
      //--------------------------------
2552
2692
            if (yy > y + h)
2553
2693
                  break;
2554
2694
            Track* track = *it;
2555
 
            if (config.canvasShowGrid || !track->isMidiTrack())
 
2695
            if (/*config.canvasShowGrid ||*/ !track->isMidiTrack()) {
 
2696
              p.setPen(baseColor.dark(130));
2556
2697
              p.drawLine(x, yy, x + w, yy);
 
2698
              p.setPen(baseColor);
 
2699
            }
2557
2700
            if (!track->isMidiTrack() && (track->type() != Track::WAVE)) {
2558
2701
                  QRect r = rect & QRect(x, yy, w, track->height());
2559
2702
                  drawAudioTrack(p, r, (AudioTrack*)track);
2560
 
                  }
 
2703
                  p.setPen(baseColor);
 
2704
            }
 
2705
            if (!track->isMidiTrack()) { // draw automation
 
2706
                  QRect r = rect & QRect(x, yy, w, track->height());
 
2707
                  drawAutomation(p, r, (AudioTrack*)track);
 
2708
                  p.setPen(baseColor);
 
2709
 
 
2710
            }
2561
2711
            yy += track->height();
2562
2712
            }
2563
 
 
2564
 
      if (!config.canvasShowGrid)
2565
 
            return;
2566
 
 
2567
 
      //--------------------------------
2568
 
      // vertical lines
2569
 
      //--------------------------------
2570
 
 
2571
 
      int bar, beat;
2572
 
      unsigned tick;
2573
 
      switch (*_raster) {
2574
 
            case 0:     // measure
2575
 
                  sigmap.tickValues(x, &bar, &beat, &tick);
2576
 
                  for (;;) {
2577
 
                        int xt = sigmap.bar2tick(bar++, 0, 0);
2578
 
                        if (xt >= x + w)
2579
 
                              break;
2580
 
                        p.drawLine(xt, y, xt, y+h);
2581
 
                        }
2582
 
                  break;
2583
 
            case 1:           // no raster
2584
 
                  break;
2585
 
            case 768:         // 1/2
2586
 
            case 384:         // 1/4
2587
 
            case 192:         // 1/8
2588
 
            case 96:          // 1/16
2589
 
                  {
2590
 
                  int r = *_raster;
2591
 
                  int rr = rmapx(r);
2592
 
                  while (rr < 4) {
2593
 
                        r *= 2;
2594
 
                        rr = rmapx(r);
2595
 
                        }
2596
 
 
2597
 
                  for (int xt = x; xt < (x + w); xt += r)
2598
 
                        p.drawLine(xt, y, xt+1, y+h);
2599
 
                  }
2600
 
                  break;
2601
 
            }
2602
 
      }
 
2713
}
2603
2714
 
2604
2715
//---------------------------------------------------------
2605
2716
//   drawAudioTrack
2606
2717
//---------------------------------------------------------
2607
2718
 
2608
 
void PartCanvas::drawAudioTrack(QPainter& p, const QRect& r, AudioTrack*)
2609
 
      {
 
2719
void PartCanvas::drawAudioTrack(QPainter& p, const QRect& r, AudioTrack *t)
 
2720
{
2610
2721
      p.setPen(QPen(black, 2, SolidLine));
2611
2722
      p.setBrush(gray);
2612
2723
      p.drawRect(r);
2613
 
      }
2614
 
 
 
2724
}
 
2725
 
 
2726
//---------------------------------------------------------
 
2727
//   drawAutomation
 
2728
//---------------------------------------------------------
 
2729
 
 
2730
void PartCanvas::drawAutomation(QPainter& p, const QRect& r, AudioTrack *t)
 
2731
{
 
2732
//     printf("drawAudioTrack %d x %d y %d w %d h %d\n",t, r.x(), r.y(), r.width(), r.height());
 
2733
     //int v2=r.x()+r.width();
 
2734
     //printf("v2=%d mapx=%d rmapx=%d mapxdev=%d rmapxdev=%d\n",v2, mapx(v2),rmapx(v2),mapxDev(v2),rmapxDev(v2));
 
2735
     return;
 
2736
 
 
2737
     p.setPen(QPen(black, 2, SolidLine));
 
2738
     int height=r.bottom()-r.top()-4; // limit height
 
2739
 
 
2740
     CtrlListList* cll = t->controller();
 
2741
     QColor cols[10];
 
2742
     cols[0]=white;
 
2743
     cols[1]=red;
 
2744
     cols[2]=yellow;
 
2745
     cols[3]=black;
 
2746
     cols[4]=blue;
 
2747
     int colIndex=0;
 
2748
     bool firstRun=true;
 
2749
     for(CtrlListList::iterator icll =cll->begin();icll!=cll->end();++icll)
 
2750
     {
 
2751
       //iCtrlList *icl = icll->second;
 
2752
       CtrlList *cl = icll->second;
 
2753
       double prevVal;
 
2754
       iCtrl ic=cl->begin();
 
2755
       p.setPen(QPen(cols[colIndex++],1,SolidLine));
 
2756
 
 
2757
       if (ic!=cl->end()) { // if there are no automation values we don't draw at all
 
2758
         CtrlVal cvFirst = ic->second;
 
2759
         ic++;
 
2760
         int prevPos=cvFirst.frame;
 
2761
         prevVal = cvFirst.val;
 
2762
         if (cl->id() == AC_VOLUME ) { // use db scale for volume
 
2763
           prevVal = (20.0*log10(cvFirst.val)+60) / 70.0; // represent volume between 0 and 1
 
2764
           if (prevVal < 0) prevVal = 0.0;
 
2765
         }
 
2766
         else {
 
2767
           // we need to set curVal between 0 and 1
 
2768
           double min, max;
 
2769
           cl->range(&min,&max);
 
2770
           prevVal = (prevVal- min)/(max-min);
 
2771
         }
 
2772
         for (; ic !=cl->end(); ++ic)
 
2773
         {
 
2774
            CtrlVal cv = ic->second;
 
2775
            double nextVal = cv.val; // was curVal
 
2776
            if (cl->id() == AC_VOLUME ) { // use db scale for volume
 
2777
              nextVal = (20.0*log10(cv.val)+60) / 70.0; // represent volume between 0 and 1
 
2778
              if (nextVal < 0) nextVal = 0.0;
 
2779
            }
 
2780
            else {
 
2781
              // we need to set curVal between 0 and 1
 
2782
              double min, max;
 
2783
              cl->range(&min,&max);
 
2784
              nextVal = (nextVal- min)/(max-min);
 
2785
            }
 
2786
            //printf("volume automation event %d %f %f %d\n",cv.frame,cv.val, tempomap.frame2tick(cv.frame));
 
2787
            //p.drawLine(r.x(),(r.bottom()-2)-lastVal*height,r.x()+r.width(),(r.bottom()-2)-curVal*height); // debuggingtest
 
2788
            int leftX=tempomap.frame2tick(prevPos);
 
2789
            if (firstRun && leftX>r.x()) {
 
2790
              printf("first run\n");
 
2791
              leftX=r.x();
 
2792
            }
 
2793
 
 
2794
            printf("inner draw\n");
 
2795
            p.drawLine(leftX,(r.bottom()-2)-prevVal*height,tempomap.frame2tick(cv.frame),(r.bottom()-2)-prevVal*height);
 
2796
            firstRun=false;
 
2797
            //printf("draw line: %d %f %d %f\n",tempomap.frame2tick(lastPos),r.bottom()-lastVal*height,tempomap.frame2tick(cv.frame),r.bottom()-curVal*height);
 
2798
            prevPos=cv.frame;
 
2799
            prevVal=nextVal;
 
2800
         }
 
2801
         printf("outer draw %f\n", cvFirst.val);
 
2802
         p.drawLine(tempomap.frame2tick(prevPos),(r.bottom()-2)-prevVal*height,tempomap.frame2tick(prevPos)+r.width(),(r.bottom()-2)-prevVal*height);
 
2803
         //printf("draw last line: %d %f %d %f\n",tempomap.frame2tick(lastPos),r.bottom()-lastVal*height,150000,r.bottom()-lastVal*height);
 
2804
       }
 
2805
//       if (height >100) {
 
2806
//          p.drawText(tempomap.frame2tick(0)+1000,40,"FOOO");
 
2807
//          printf("drawText %s\n", cl->name().latin1());
 
2808
//        }
 
2809
     }
 
2810
}
 
2811
 
 
2812
 
 
2813
void PartCanvas::controllerChanged(Track *t)
 
2814
{
 
2815
  redraw();
 
2816
}