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

« back to all changes in this revision

Viewing changes to widgets/posedit.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Kobras
  • Date: 2002-04-23 17:28:23 UTC
  • Revision ID: james.westby@ubuntu.com-20020423172823-w8yplzr81a759xa3
Tags: upstream-0.5.2
ImportĀ upstreamĀ versionĀ 0.5.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//=========================================================
 
2
//  MusE
 
3
//  Linux Music Editor
 
4
//    $Id: posedit.cpp,v 1.1 2002/01/30 14:54:03 muse Exp $
 
5
//  (C) Copyright 2001 Werner Schweer (ws@seh.de)
 
6
//=========================================================
 
7
 
 
8
#include "posedit.h"
 
9
 
 
10
#include <qrangecontrol.h>
 
11
#include <qapplication.h>
 
12
#include <qpixmap.h>
 
13
#include <qapplication.h>
 
14
#include <qvaluelist.h>
 
15
#include <qstring.h>
 
16
#include <qstyle.h>
 
17
#include <values.h>
 
18
#include <qpainter.h>
 
19
#include <qtimer.h>
 
20
#include "sig.h"
 
21
 
 
22
extern int mtcType;
 
23
 
 
24
//---------------------------------------------------------
 
25
//   QNumberSection
 
26
//---------------------------------------------------------
 
27
 
 
28
class QNumberSection
 
29
      {
 
30
      int selstart;
 
31
      int selend;
 
32
 
 
33
   public:
 
34
      QNumberSection(int selStart = 0, int selEnd = 0)
 
35
         : selstart(selStart), selend(selEnd )  {}
 
36
      int selectionStart() const    { return selstart; }
 
37
      void setSelectionStart(int s) { selstart = s; }
 
38
      int selectionEnd() const      { return selend; }
 
39
      void setSelectionEnd( int s ) { selend = s; }
 
40
      int width() const             { return selend - selstart; }
 
41
      };
 
42
 
 
43
//---------------------------------------------------------
 
44
//   PosEditor
 
45
//---------------------------------------------------------
 
46
 
 
47
class PosEditor : public QWidget
 
48
      {
 
49
      PosEdit* cw;
 
50
      bool frm;
 
51
      QPixmap *pm;
 
52
      int focusSec;
 
53
      QValueList<QNumberSection> sections;
 
54
      QString sep;
 
55
      int offset;
 
56
 
 
57
      int section(const QPoint&);
 
58
 
 
59
   protected:
 
60
      void init();
 
61
      bool event(QEvent *e);
 
62
      void resizeEvent(QResizeEvent*);
 
63
      void paintEvent(QPaintEvent*);
 
64
      void mousePressEvent(QMouseEvent *e);
 
65
 
 
66
      void applyFocusSelection() {}
 
67
 
 
68
   public:
 
69
      PosEditor(PosEdit* Q_PARENT, const char * Q_NAME );
 
70
      ~PosEditor();
 
71
 
 
72
      void setControlWidget(PosEdit * widget);
 
73
      PosEdit* controlWidget() const;
 
74
 
 
75
      void setSeparator(const QString& s) { sep = s; }
 
76
      QString separator() const           { return sep; }
 
77
      int focusSection()  const           { return focusSec; }
 
78
 
 
79
      bool setFocusSection(int s);
 
80
      void appendSection(const QNumberSection& sec);
 
81
      void clearSections();
 
82
      void setSectionSelection(int sec, int selstart, int selend);
 
83
      bool eventFilter(QObject *o, QEvent *e);
 
84
      };
 
85
 
 
86
//---------------------------------------------------------
 
87
//   section
 
88
//---------------------------------------------------------
 
89
 
 
90
int PosEditor::section(const QPoint& pt)
 
91
      {
 
92
      if (pm->isNull())
 
93
            return -1;
 
94
      QPainter p(pm);
 
95
      int fw = frm ? style().pixelMetric(QStyle::PM_DefaultFrameWidth) : 0;
 
96
      int x = 2 + fw;
 
97
      int y = 0;
 
98
      int w = width();
 
99
      int h = height();
 
100
      for (unsigned int i = 0; i < sections.count(); ++i) {
 
101
            QString s = cw->sectionFormattedText(i);
 
102
            QRect bb = p.boundingRect(x, y, w, h, AlignVCenter|AlignLeft, s);
 
103
            int nx = bb.x() + bb.width();
 
104
            if (pt.x() >= x && pt.x() < nx)
 
105
                  return i;
 
106
            x = nx;
 
107
            if (i < sections.count()-1) {
 
108
                  QString s = sep;
 
109
                  p.drawText(x, y, w, h, AlignVCenter|AlignLeft, s, -1, &bb);
 
110
                  x = bb.x() + bb.width();
 
111
                  }
 
112
            }
 
113
      return -1;
 
114
      }
 
115
 
 
116
//---------------------------------------------------------
 
117
//   PosEditor
 
118
//---------------------------------------------------------
 
119
 
 
120
PosEditor::PosEditor(PosEdit* parent, const char* name)
 
121
   : QWidget(parent, name), sep(".")
 
122
      {
 
123
      cw       = parent;
 
124
      frm      = true;
 
125
      focusSec = 0;
 
126
      pm       = new QPixmap;
 
127
      offset   = 0;
 
128
      init();
 
129
      }
 
130
 
 
131
//---------------------------------------------------------
 
132
//   ~PosEditor
 
133
//---------------------------------------------------------
 
134
 
 
135
PosEditor::~PosEditor()
 
136
      {
 
137
      delete pm;
 
138
      }
 
139
 
 
140
//---------------------------------------------------------
 
141
//   init
 
142
//---------------------------------------------------------
 
143
 
 
144
void PosEditor::init()
 
145
      {
 
146
      setBackgroundMode(PaletteBase);
 
147
      setFocusSection(-1);
 
148
      setKeyCompression(true);
 
149
      installEventFilter(this);
 
150
      setFocusPolicy(WheelFocus);
 
151
      }
 
152
 
 
153
//---------------------------------------------------------
 
154
//   event
 
155
//---------------------------------------------------------
 
156
 
 
157
bool PosEditor::event(QEvent *e)
 
158
      {
 
159
      if (e->type() == QEvent::FocusIn || e->type() == QEvent::FocusOut) {
 
160
            repaint( rect(), false);
 
161
            }
 
162
      else if (e->type() == QEvent::AccelOverride) {
 
163
            QKeyEvent* ke = (QKeyEvent*) e;
 
164
            switch (ke->key()) {
 
165
                  case Key_Delete:
 
166
                  case Key_Backspace:
 
167
                  case Key_Up:
 
168
                  case Key_Down:
 
169
                  case Key_Left:
 
170
                  case Key_Right:
 
171
                        ke->accept();
 
172
                  default:
 
173
                        break;
 
174
                  }
 
175
            }
 
176
      return QWidget::event(e);
 
177
      }
 
178
 
 
179
void PosEditor::resizeEvent(QResizeEvent *e)
 
180
      {
 
181
      pm->resize(e->size());
 
182
      QWidget::resizeEvent(e);
 
183
      }
 
184
 
 
185
//---------------------------------------------------------
 
186
//   paintEvent
 
187
//---------------------------------------------------------
 
188
 
 
189
void PosEditor::paintEvent(QPaintEvent *)
 
190
      {
 
191
      if (pm->isNull())
 
192
            return;
 
193
 
 
194
      const QColorGroup & cg = colorGroup();
 
195
      QPainter p(pm);
 
196
      p.setPen(colorGroup().text());
 
197
      QBrush bg = cg.brush(QColorGroup::Base);
 
198
 
 
199
      int fw = frm ? style().pixelMetric(QStyle::PM_DefaultFrameWidth) : 0;
 
200
      int x = 2 + fw;
 
201
      int y = 0;
 
202
      int w = width();
 
203
      int h = height();
 
204
      p.fillRect(0, 0, w, h, bg);
 
205
 
 
206
      for (unsigned int i = 0; i < sections.count(); ++i) {
 
207
            QRect bb;
 
208
            QString s = cw->sectionFormattedText(i);
 
209
 
 
210
            if (hasFocus() && (int(i) == focusSec)) {
 
211
                  QBrush bg = cg.brush(QColorGroup::Highlight);
 
212
                  QRect r = p.boundingRect(x, y, w, h, AlignVCenter|AlignLeft, s, -1);
 
213
                  p.setPen(colorGroup().highlightedText());
 
214
                  p.fillRect(r, bg);
 
215
                  }
 
216
            else
 
217
                  p.setPen(colorGroup().text());
 
218
            p.drawText(x, y, w, h, AlignVCenter|AlignLeft, s, -1, &bb);
 
219
            x = bb.x() + bb.width();
 
220
            if (i < sections.count()-1) {
 
221
                  QString s = sep;
 
222
                  p.drawText(x, y, w, h, AlignVCenter|AlignLeft, s, -1, &bb);
 
223
                  x = bb.x() + bb.width();
 
224
                  }
 
225
            }
 
226
      p.end();
 
227
      bitBlt(this, 0, 0, pm);
 
228
      }
 
229
 
 
230
//---------------------------------------------------------
 
231
//   mousePressEvent
 
232
//---------------------------------------------------------
 
233
 
 
234
void PosEditor::mousePressEvent(QMouseEvent *e)
 
235
      {
 
236
      QPoint p(e->pos().x(), 0);
 
237
      int sec = section(p);
 
238
      if (sec != -1) {
 
239
            cw->setFocusSection(sec);
 
240
            repaint(rect(), false);
 
241
            }
 
242
      }
 
243
 
 
244
//---------------------------------------------------------
 
245
//   eventFilter
 
246
//---------------------------------------------------------
 
247
 
 
248
bool PosEditor::eventFilter(QObject *o, QEvent *e)
 
249
      {
 
250
      if (o != this)
 
251
            return false;
 
252
      if (e->type() != QEvent::KeyPress )
 
253
            return false;
 
254
 
 
255
      QKeyEvent *ke = (QKeyEvent*)e;
 
256
      switch (ke->key()) {
 
257
            case Key_Right:
 
258
                  if (unsigned(focusSec) <= sections.count()) {
 
259
                        if (cw->setFocusSection(focusSec+1))
 
260
                              repaint(rect(), false);
 
261
                        }
 
262
                  return true;
 
263
            case Key_Left:
 
264
                  if (focusSec > 0 ) {
 
265
                        if (cw->setFocusSection(focusSec-1))
 
266
                              repaint(rect(), false);
 
267
                        }
 
268
                  return true;
 
269
            case Key_Up:
 
270
                  cw->stepUp();
 
271
                  return true;
 
272
            case Key_Down:
 
273
                  cw->stepDown();
 
274
                  return true;
 
275
            case Key_Backspace:
 
276
            case Key_Delete:
 
277
                  cw->removeLastNumber(focusSec);
 
278
                  return true;
 
279
            default:
 
280
                  QString txt = ke->text();
 
281
                  if (!txt.isEmpty() && !sep.isEmpty() && txt[0] == sep[0]) {
 
282
                        // do the same thing as KEY_RIGHT when the user presses the separator key
 
283
                        if (focusSec < sections.count()) {
 
284
                              if (cw->setFocusSection(focusSec+1))
 
285
                                    repaint(rect(), false);
 
286
                              }
 
287
                        return true;
 
288
                        }
 
289
                  int num = txt[0].digitValue();
 
290
                  if (num != -1) {
 
291
                        cw->addNumber(focusSec, num);
 
292
                        return true;
 
293
                        }
 
294
            }
 
295
      return false;
 
296
      }
 
297
 
 
298
void PosEditor::appendSection(const QNumberSection& sec)
 
299
      {
 
300
      sections.append(sec);
 
301
      }
 
302
void PosEditor::clearSections()
 
303
      {
 
304
      sections.clear();
 
305
      }
 
306
 
 
307
//---------------------------------------------------------
 
308
//   setSectionSelection
 
309
//---------------------------------------------------------
 
310
 
 
311
void PosEditor::setSectionSelection(int secNo, int selstart, int selend)
 
312
      {
 
313
      if (secNo < 0 || secNo > (int)sections.count())
 
314
            return;
 
315
      sections[secNo].setSelectionStart(selstart);
 
316
      sections[secNo].setSelectionEnd(selend);
 
317
      }
 
318
 
 
319
//---------------------------------------------------------
 
320
//   setFocusSection
 
321
//---------------------------------------------------------
 
322
 
 
323
bool PosEditor::setFocusSection(int idx)
 
324
      {
 
325
      if (idx > (int)sections.count()-1 || idx < 0)
 
326
            return false;
 
327
      if (idx != focusSec) {
 
328
            focusSec = idx;
 
329
            applyFocusSelection();
 
330
            return true;
 
331
            }
 
332
      return false;
 
333
      }
 
334
 
 
335
//---------------------------------------------------------
 
336
//   PosEdit
 
337
//---------------------------------------------------------
 
338
 
 
339
PosEdit::PosEdit(QWidget* parent, const char* name = 0)
 
340
   : QWidget(parent, name)
 
341
      {
 
342
      init();
 
343
      updateButtons();
 
344
      }
 
345
 
 
346
PosEdit::PosEdit(const Pos& time, QWidget* parent, const char* name = 0)
 
347
    : QWidget(parent, name)
 
348
      {
 
349
      init();
 
350
      setValue(time);
 
351
      updateButtons();
 
352
      }
 
353
 
 
354
PosEdit::~PosEdit()
 
355
      {
 
356
      }
 
357
 
 
358
//---------------------------------------------------------
 
359
//   init
 
360
//---------------------------------------------------------
 
361
 
 
362
void PosEdit::init()
 
363
      {
 
364
      ed       = new PosEditor(this, "pos editor");
 
365
      controls = new QSpinWidget(this, "pos edit controls");
 
366
      controls->setEditWidget(ed);
 
367
      setFocusProxy(ed);
 
368
      connect(controls, SIGNAL(stepUpPressed()), SLOT(stepUp()));
 
369
      connect(controls, SIGNAL(stepDownPressed()), SLOT(stepDown()));
 
370
      connect(this, SIGNAL(valueChanged(const Pos&)),SLOT(updateButtons()));
 
371
 
 
372
      overwrite = false;
 
373
      timerId   = 0;
 
374
      typing    = false;
 
375
      min       = Pos(0);
 
376
      max       = Pos(MAXINT);
 
377
      changed   = false;
 
378
      adv       = false;
 
379
 
 
380
 
 
381
      static Section s_midiSections[3] = {  // measure, beat, tick
 
382
            { 0, 4, 1, 0 },
 
383
            { 5, 2, 1, 0 },
 
384
            { 8, 3, 0, 0 }
 
385
            };
 
386
      static Section s_smpteSections[4] = {  // minute second frame subframe
 
387
            {  0, 3, 0, 0 },
 
388
            {  4, 2, 0, 0 },
 
389
            {  7, 2, 0, 0 },
 
390
            { 10, 2, 0, 0 }
 
391
            };
 
392
      memcpy(midiSections, s_midiSections, sizeof(s_midiSections));
 
393
      memcpy(smpteSections, s_smpteSections, sizeof(s_smpteSections));
 
394
 
 
395
      _smpte     = false;  // show position in smpte format
 
396
      sec       = midiSections;
 
397
      setSections();
 
398
      setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed));
 
399
      }
 
400
 
 
401
//---------------------------------------------------------
 
402
//   setSetions
 
403
//---------------------------------------------------------
 
404
 
 
405
void PosEdit::setSections()
 
406
      {
 
407
      ed->clearSections();
 
408
      ed->appendSection(QNumberSection(0,0));
 
409
      ed->appendSection(QNumberSection(0,0));
 
410
      ed->appendSection(QNumberSection(0,0));
 
411
      if (_smpte) {
 
412
            ed->appendSection(QNumberSection(0,0));
 
413
            ed->setSeparator(":");
 
414
            }
 
415
      else {
 
416
            ed->setSeparator(".");
 
417
            }
 
418
      }
 
419
 
 
420
//---------------------------------------------------------
 
421
//   smpte
 
422
//---------------------------------------------------------
 
423
 
 
424
bool PosEdit::smpte() const
 
425
      {
 
426
      return _smpte;
 
427
      }
 
428
 
 
429
//---------------------------------------------------------
 
430
//   setSmpte
 
431
//---------------------------------------------------------
 
432
 
 
433
void PosEdit::setSmpte(bool f)
 
434
      {
 
435
      _smpte = f;
 
436
      sec   = f ? smpteSections : midiSections;
 
437
      setSections();
 
438
      ed->repaint(ed->rect(), false);
 
439
      }
 
440
 
 
441
//---------------------------------------------------------
 
442
//   minValue
 
443
//---------------------------------------------------------
 
444
 
 
445
Pos PosEdit::minValue() const
 
446
      {
 
447
      return min;
 
448
      }
 
449
 
 
450
//---------------------------------------------------------
 
451
//   maxValue
 
452
//---------------------------------------------------------
 
453
 
 
454
Pos PosEdit::maxValue() const
 
455
      {
 
456
      return max;
 
457
      }
 
458
 
 
459
//---------------------------------------------------------
 
460
//   setRange
 
461
//---------------------------------------------------------
 
462
 
 
463
void PosEdit::setRange(const Pos& _min, const Pos& _max)
 
464
      {
 
465
      if (min.isValid())
 
466
            min = _min;
 
467
      if (max.isValid())
 
468
            max = _max;
 
469
      }
 
470
 
 
471
//---------------------------------------------------------
 
472
//   setValue
 
473
//---------------------------------------------------------
 
474
 
 
475
void PosEdit::setValue(const Pos& time)
 
476
      {
 
477
/*      if (!time.isValid()) {
 
478
            m = 0;
 
479
            b = 0;
 
480
            t = 0;
 
481
            return;
 
482
            }
 
483
*/
 
484
      if (time > maxValue() || time < minValue())
 
485
            return;
 
486
      if (_smpte)
 
487
            time.msf(&(sec[0].val), &(sec[1].val), &(sec[2].val),
 
488
               &(sec[3].val));
 
489
      else
 
490
            time.mbt(&(sec[0].val), &(sec[1].val), &(sec[2].val));
 
491
//      emit valueChanged(time);
 
492
      changed = false;
 
493
      ed->repaint(ed->rect(), false);
 
494
      }
 
495
 
 
496
void PosEdit::setValue(const QString& s)
 
497
      {
 
498
      Pos time(s);
 
499
      setValue(time);
 
500
      }
 
501
 
 
502
void PosEdit::setValue(int t)
 
503
      {
 
504
      Pos time(t);
 
505
      setValue(time);
 
506
      }
 
507
 
 
508
Pos PosEdit::pos() const
 
509
      {
 
510
      if (_smpte) {
 
511
            if (Pos::isValid(sec[0].val, sec[1].val, sec[2].val, sec[3].val))
 
512
                  return Pos(sec[0].val, sec[1].val, sec[2].val, sec[3].val);
 
513
            }
 
514
      else {
 
515
            if (Pos::isValid(sec[0].val, sec[1].val, sec[2].val))
 
516
                  return Pos(sec[0].val, sec[1].val, sec[2].val);
 
517
            }
 
518
      return Pos();
 
519
      }
 
520
 
 
521
void PosEdit::setSeparator(const QString& s)
 
522
      {
 
523
      ed->setSeparator(s);
 
524
      }
 
525
 
 
526
QString PosEdit::separator() const
 
527
      {
 
528
      return ed->separator();
 
529
      }
 
530
 
 
531
bool PosEdit::event(QEvent *e)
 
532
      {
 
533
      if (e->type() == QEvent::FocusOut) {
 
534
            typing = false;
 
535
            if (changed) {
 
536
                  emit valueChanged(pos() );
 
537
                  changed = false;
 
538
                  }
 
539
            }
 
540
      return QWidget::event(e);
 
541
      }
 
542
 
 
543
void PosEdit::timerEvent(QTimerEvent *)
 
544
      {
 
545
      overwrite = true;
 
546
      }
 
547
 
 
548
//---------------------------------------------------------
 
549
//   stepUp
 
550
//---------------------------------------------------------
 
551
 
 
552
void PosEdit::stepUp()
 
553
      {
 
554
      int secNo = ed->focusSection();
 
555
      bool accepted = false;
 
556
 
 
557
      if (!outOfRange(secNo, sec[secNo].val+1)) {
 
558
            accepted = true;
 
559
            setSec(secNo, sec[secNo].val+1);
 
560
            }
 
561
      if (accepted) {
 
562
            changed = true;
 
563
            emit valueChanged(pos());
 
564
            }
 
565
      ed->repaint(ed->rect(), false);
 
566
      }
 
567
 
 
568
 
 
569
//---------------------------------------------------------
 
570
//   stepDown
 
571
//---------------------------------------------------------
 
572
 
 
573
void PosEdit::stepDown()
 
574
      {
 
575
      int secNo = ed->focusSection();
 
576
      bool accepted = false;
 
577
      if (!outOfRange(secNo, sec[secNo].val-1)) {
 
578
            accepted = true;
 
579
            setSec(secNo, sec[secNo].val-1);
 
580
            }
 
581
      if (accepted) {
 
582
            changed = true;
 
583
            emit valueChanged(pos());
 
584
            }
 
585
      ed->repaint(ed->rect(), false);
 
586
      }
 
587
 
 
588
//---------------------------------------------------------
 
589
//   sectionFormattedText
 
590
//    Returns the formatted number for section sec.
 
591
//---------------------------------------------------------
 
592
 
 
593
QString PosEdit::sectionFormattedText(int secNo)
 
594
      {
 
595
      QString txt = sectionText(secNo);
 
596
      int so      = sec[secNo].offset;
 
597
      int len     = sec[secNo].len;
 
598
      int eo      = so + len;
 
599
 
 
600
      if (typing && secNo == ed->focusSection())
 
601
            ed->setSectionSelection(secNo, eo - txt.length(), eo);
 
602
      else
 
603
            ed->setSectionSelection(secNo, so, eo);
 
604
      txt = txt.rightJustify(len, '0');
 
605
      return txt;
 
606
      }
 
607
 
 
608
//---------------------------------------------------------
 
609
//   setFocusSection
 
610
//---------------------------------------------------------
 
611
 
 
612
bool PosEdit::setFocusSection(int s)
 
613
      {
 
614
      if (s != ed->focusSection()) {
 
615
            killTimer(timerId);
 
616
            overwrite = true;
 
617
            typing    = false;
 
618
            int so = sec[s].offset;
 
619
            int eo = so + sec[s].len;
 
620
            ed->setSectionSelection(s, so, eo);
 
621
            if (changed) {
 
622
                  emit valueChanged(pos());
 
623
                  changed = false;
 
624
                  }
 
625
            }
 
626
      return ed->setFocusSection(s);
 
627
      }
 
628
 
 
629
//---------------------------------------------------------
 
630
//   setSec
 
631
//---------------------------------------------------------
 
632
 
 
633
void PosEdit::setSec(int secNo, int val)
 
634
      {
 
635
      if (val < 0)
 
636
            val = 0;
 
637
      if (_smpte) {
 
638
            switch(secNo) {
 
639
                  case 0:
 
640
                        break;
 
641
                  case 1:
 
642
                        if (val > 59)
 
643
                              val = 59;
 
644
                        break;
 
645
                  case 2:
 
646
                        switch(mtcType) {
 
647
                              case 0:     // 24 frames sec
 
648
                                    if (val > 23)
 
649
                                          val = 23;
 
650
                                    break;
 
651
                              case 1:
 
652
                                    if (val > 24)
 
653
                                          val = 24;
 
654
                                    break;
 
655
                              case 2:     // 30 drop frame
 
656
                              case 3:     // 30 non drop frame
 
657
                                    if (val > 29)
 
658
                                          val = 29;
 
659
                                    break;
 
660
                              }
 
661
                        break;
 
662
                  case 3:
 
663
                        if (val > 99)
 
664
                              val = 99;
 
665
                  }
 
666
            }
 
667
      else {
 
668
            switch(secNo) {
 
669
                  case 0:
 
670
                        break;
 
671
                  case 1:
 
672
                        {
 
673
                        int z, n;
 
674
                        int tick = sigmap.bar2tick(sec[0].val, val, sec[2].val);
 
675
                        sigmap.timesig(tick, z, n);
 
676
                        if (val >= n)
 
677
                              val = n-1;
 
678
                        }
 
679
                        break;
 
680
                  case 2:
 
681
                        {
 
682
                        int tick = sigmap.bar2tick(sec[0].val, sec[1].val, val);
 
683
                        int tb = sigmap.ticksBeat(tick);
 
684
                        if (val >= tb)
 
685
                              val = tb-1;
 
686
                        }
 
687
                        break;
 
688
                  }
 
689
            }
 
690
      sec[secNo].val = val;
 
691
      }
 
692
 
 
693
//---------------------------------------------------------
 
694
//   sectionText
 
695
//    Returns the text of section \a sec.
 
696
//---------------------------------------------------------
 
697
 
 
698
QString PosEdit::sectionText(int secNo)
 
699
      {
 
700
      return QString::number(sec[secNo].val + sec[secNo].voff);
 
701
      }
 
702
 
 
703
//---------------------------------------------------------
 
704
//   outOfRange
 
705
//    return true if out of range
 
706
//---------------------------------------------------------
 
707
 
 
708
bool PosEdit::outOfRange(int secNo, int val) const
 
709
      {
 
710
      if (val < 0)
 
711
            return true;
 
712
      int limit = MAXINT;
 
713
      if (_smpte) {
 
714
            switch(secNo) {
 
715
                  case 0:
 
716
                        break;
 
717
                  case 1:
 
718
                        limit = 59;
 
719
                        break;
 
720
                  case 2:
 
721
                        switch(mtcType) {
 
722
                              case 0:     // 24 frames sec
 
723
                                    limit = 23;
 
724
                                    break;
 
725
                              case 1:
 
726
                                    limit = 24;
 
727
                                    break;
 
728
                              case 2:     // 30 drop frame
 
729
                              case 3:     // 30 non drop frame
 
730
                                    limit = 29;
 
731
                                    break;
 
732
                              }
 
733
                        break;
 
734
                  case 3:
 
735
                        limit = 99;
 
736
                        break;
 
737
                  }
 
738
            }
 
739
      else {
 
740
            switch(secNo) {
 
741
                  case 0:
 
742
                        break;
 
743
                  case 1:
 
744
                        {
 
745
                        int z;
 
746
                        int tick = sigmap.bar2tick(sec[0].val, val, sec[2].val);
 
747
                        sigmap.timesig(tick, z, limit);
 
748
                        limit -= 1;
 
749
                        }
 
750
                        break;
 
751
                  case 2:
 
752
                        int tick = sigmap.bar2tick(sec[0].val, sec[1].val, val);
 
753
                        limit = sigmap.ticksBeat(tick) - 1;
 
754
                        break;
 
755
                  }
 
756
            }
 
757
      return val > limit;
 
758
      }
 
759
 
 
760
//---------------------------------------------------------
 
761
//   addNumber
 
762
//---------------------------------------------------------
 
763
 
 
764
void PosEdit::addNumber(int secNo, int num)
 
765
      {
 
766
      if (secNo == -1)
 
767
            return;
 
768
      killTimer(timerId);
 
769
      bool accepted  = false;
 
770
      typing         = true;
 
771
      int voff       = sec[secNo].voff;
 
772
 
 
773
      QString txt = sectionText(secNo);
 
774
 
 
775
      if (txt.length() == sec[secNo].len) {
 
776
            if (!outOfRange(secNo, num - voff)) {
 
777
                  accepted = true;
 
778
                  sec[secNo].val = num - voff;
 
779
                  }
 
780
            }
 
781
      else {
 
782
            txt += QString::number(num);
 
783
            int temp = txt.toInt() - voff;
 
784
            if (outOfRange(secNo, temp))
 
785
                  txt = sectionText(secNo);
 
786
            else {
 
787
                  accepted = true;
 
788
                  sec[secNo].val = temp;
 
789
                  }
 
790
            if (adv && (txt.length() == sec[secNo].len)) {
 
791
                  setFocusSection(ed->focusSection() + 1);
 
792
                  }
 
793
            }
 
794
      changed = accepted;
 
795
      if (accepted)
 
796
            emit valueChanged(pos());
 
797
      timerId = startTimer(qApp->doubleClickInterval()*4);
 
798
      ed->repaint(ed->rect(), false);
 
799
      }
 
800
 
 
801
//---------------------------------------------------------
 
802
//   removeLastNumber
 
803
//---------------------------------------------------------
 
804
 
 
805
void PosEdit::removeLastNumber(int secNo)
 
806
      {
 
807
      if (secNo == -1)
 
808
              return;
 
809
      QString txt = QString::number(sec[secNo].val);
 
810
      txt = txt.mid(0, txt.length() - 1);
 
811
      sec[secNo].val = txt.toInt() - sec[secNo].voff;
 
812
      ed->repaint(ed->rect(), false);
 
813
      }
 
814
 
 
815
//---------------------------------------------------------
 
816
//   resizeEvent
 
817
//---------------------------------------------------------
 
818
 
 
819
void PosEdit::resizeEvent(QResizeEvent *)
 
820
      {
 
821
      controls->resize(width(), height());
 
822
      }
 
823
 
 
824
//---------------------------------------------------------
 
825
//   sizeHint
 
826
//---------------------------------------------------------
 
827
 
 
828
QSize PosEdit::sizeHint() const
 
829
      {
 
830
      QFontMetrics fm(font());
 
831
      int fw = style().pixelMetric(QStyle::PM_DefaultFrameWidth, this);
 
832
      int h  = fm.height() + fw * 2;
 
833
      int w  = 2 + controls->upRect().width() + fw * 4;
 
834
      if (_smpte)
 
835
            w += fm.width('9') * 9 + fm.width(ed->separator()) * 3;
 
836
      else
 
837
            w += fm.width('9') * 9 + fm.width(ed->separator()) * 2;
 
838
      return QSize(w, h).expandedTo(QApplication::globalStrut());
 
839
      }
 
840
 
 
841
//---------------------------------------------------------
 
842
//   updateButtons
 
843
//---------------------------------------------------------
 
844
 
 
845
void PosEdit::updateButtons()
 
846
      {
 
847
      bool upEnabled   = isEnabled() && pos() < maxValue();
 
848
      bool downEnabled = isEnabled() && pos() > minValue();
 
849
 
 
850
      controls->setUpEnabled(upEnabled);
 
851
      controls->setDownEnabled(downEnabled);
 
852
      }
 
853