~timo-jyrinki/ubuntu/trusty/lmms/1.0.0_packaging

« back to all changes in this revision

Viewing changes to debian/patches/upstream-fixes

  • Committer: Israel Dahl (God Loves You)
  • Date: 2014-04-09 21:49:52 UTC
  • Revision ID: israeldahl@gmail.com-20140409214952-2ja8v2gcvqg8h6t7
* upstream git patches
  - Automatable model: When using value from linked model, make sure to fit it into own range
  as otherwise this can cause out-of-boundary accesses e.g. in ComboBoxModel. 
  - Fix broken command line rendering. Should always check that editor windows exist before using them
* fix-crash-on-close: (Filipe Coelho)
* debian/rules: tiny version (Rodney Dawes)
* debian/compat: 9
* debian/menu: name * LMMS
* debian/control: removed obsolete builddeps, added fltk libs... suggest
  fluid-soundfont-gm
* Completely redesigned default theme and UI style
* New splash screen and logo
* New plugins:
  - DynamicsProcessor
  - sfxr
  - OpulenZ, an FM synth for LMMS
  - Waveshaper
  - Dual Filter
  - vocoder LADSPA plugin
* AudioFileProcessor: added stutter playback mode
* Added time display widget
* Added support for vector-based automations with various interpolation methods
* Added config option to enable waveform display by default
* Added more controls to Peak Controller
* Added standard paths to file open/save dialog
* LFO controller: added support for custom waveforms
* New file dialogs allowing for project versioning
* Added pitch range support for instruments
* Vestige: Path to VST plugins stored as relative, if opened from
  default VST plugin path
* Song, SongEditor, BB-Editor, Piano-Roll: correction of play button problems
* Display key presses in Piano Roll
* Save solo states for tracks
* Fixed envelope sustain response
* Add support for upgrading presets
* Added optional drawing of note names in Piano Roll
* Improved overall performance by switching of FX processing if input
  is silent - you might need to tweak the FX decay knobs
* Use Kicker as default instrument in B+B-Editor
* Added option for unlinking all controls to context menu of controls
* Fixed various build issues related to ZynAddSubFX, VST support etc.
* Atomically write project files via overwrite-by-rename to prevent
  data loss upon disk failures
* Timeline: allow right click + shift to move left loop point
* Fixed various MIDI-related issues
* Default MIDI velocity to 63 for volume=100%
* CLANG compatibility
* Hide contents of envelope/LFO tab and display info about
  single-streamed instruments instead
* Knob code improvement: make the acceleration curve smoother
  and less "sudden" (exponential response curve for smoothing operation)
* File dialog: Common places added to left pane
* New mime-type icons
* Native Amplifier plugin
* Added support for loading 32-bit samples
* Fixed oversampling and other problems in export

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
Index: lmms/src/tracks/pattern.cpp
 
2
===================================================================
 
3
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
4
+++ lmms/src/tracks/pattern.cpp 2014-04-09 16:45:36.513043688 -0500
 
5
@@ -0,0 +1,1163 @@
 
6
+/*
 
7
+ * pattern.cpp - implementation of class pattern which holds notes
 
8
+ *
 
9
+ * Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
 
10
+ * Copyright (c) 2005-2007 Danny McRae <khjklujn/at/yahoo.com>
 
11
+ *
 
12
+ * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
 
13
+ *
 
14
+ * This program is free software; you can redistribute it and/or
 
15
+ * modify it under the terms of the GNU General Public
 
16
+ * License as published by the Free Software Foundation; either
 
17
+ * version 2 of the License, or (at your option) any later version.
 
18
+ *
 
19
+ * This program is distributed in the hope that it will be useful,
 
20
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
21
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
22
+ * General Public License for more details.
 
23
+ *
 
24
+ * You should have received a copy of the GNU General Public
 
25
+ * License along with this program (see COPYING); if not, write to the
 
26
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 
27
+ * Boston, MA 02110-1301 USA.
 
28
+ *
 
29
+ */
 
30
+
 
31
+#include <QtXml/QDomElement>
 
32
+#include <QtCore/QTimer>
 
33
+#include <QtGui/QMenu>
 
34
+#include <QtGui/QMessageBox>
 
35
+#include <QtGui/QMouseEvent>
 
36
+#include <QtGui/QPainter>
 
37
+#include <QtGui/QProgressBar>
 
38
+#include <QtGui/QPushButton>
 
39
+#include <QtAlgorithms>
 
40
+
 
41
+#include "pattern.h"
 
42
+#include "InstrumentTrack.h"
 
43
+#include "templates.h"
 
44
+#include "gui_templates.h"
 
45
+#include "embed.h"
 
46
+#include "engine.h"
 
47
+#include "PianoRoll.h"
 
48
+#include "TrackContainer.h"
 
49
+#include "rename_dialog.h"
 
50
+#include "SampleBuffer.h"
 
51
+#include "AudioSampleRecorder.h"
 
52
+#include "song.h"
 
53
+#include "tooltip.h"
 
54
+#include "bb_track_container.h"
 
55
+#include "string_pair_drag.h"
 
56
+#include "MainWindow.h"
 
57
+
 
58
+
 
59
+QPixmap * patternView::s_stepBtnOn = NULL;
 
60
+QPixmap * patternView::s_stepBtnOverlay = NULL;
 
61
+QPixmap * patternView::s_stepBtnOff = NULL;
 
62
+QPixmap * patternView::s_stepBtnOffLight = NULL;
 
63
+
 
64
+
 
65
+
 
66
+pattern::pattern( InstrumentTrack * _instrument_track ) :
 
67
+       trackContentObject( _instrument_track ),
 
68
+       m_instrumentTrack( _instrument_track ),
 
69
+       m_patternType( BeatPattern ),
 
70
+       m_steps( MidiTime::stepsPerTact() )
 
71
+{
 
72
+       setName( _instrument_track->name() );
 
73
+       init();
 
74
+}
 
75
+
 
76
+
 
77
+
 
78
+
 
79
+pattern::pattern( const pattern & _pat_to_copy ) :
 
80
+       trackContentObject( _pat_to_copy.m_instrumentTrack ),
 
81
+       m_instrumentTrack( _pat_to_copy.m_instrumentTrack ),
 
82
+       m_patternType( _pat_to_copy.m_patternType ),
 
83
+       m_steps( _pat_to_copy.m_steps )
 
84
+{
 
85
+       for( NoteVector::ConstIterator it = _pat_to_copy.m_notes.begin();
 
86
+                                       it != _pat_to_copy.m_notes.end(); ++it )
 
87
+       {
 
88
+               m_notes.push_back( new note( **it ) );
 
89
+       }
 
90
+
 
91
+       init();
 
92
+}
 
93
+
 
94
+
 
95
+pattern::~pattern()
 
96
+{
 
97
+       for( NoteVector::Iterator it = m_notes.begin();
 
98
+                                               it != m_notes.end(); ++it )
 
99
+       {
 
100
+               delete *it;
 
101
+       }
 
102
+
 
103
+       m_notes.clear();
 
104
+}
 
105
+
 
106
+
 
107
+
 
108
+
 
109
+void pattern::init()
 
110
+{
 
111
+       connect( engine::getSong(), SIGNAL( timeSignatureChanged( int, int ) ),
 
112
+                               this, SLOT( changeTimeSignature() ) );
 
113
+       saveJournallingState( false );
 
114
+
 
115
+       ensureBeatNotes();
 
116
+
 
117
+       changeLength( length() );
 
118
+       restoreJournallingState();
 
119
+}
 
120
+
 
121
+
 
122
+
 
123
+
 
124
+MidiTime pattern::length() const
 
125
+{
 
126
+       if( m_patternType == BeatPattern )
 
127
+       {
 
128
+               return beatPatternLength();
 
129
+       }
 
130
+
 
131
+       tick_t max_length = MidiTime::ticksPerTact();
 
132
+
 
133
+       for( NoteVector::ConstIterator it = m_notes.begin();
 
134
+                                               it != m_notes.end(); ++it )
 
135
+       {
 
136
+               if( ( *it )->length() > 0 )
 
137
+               {
 
138
+                       max_length = qMax<tick_t>( max_length,
 
139
+                                                       ( *it )->endPos() );
 
140
+               }
 
141
+       }
 
142
+       return MidiTime( max_length ).nextFullTact() *
 
143
+                                               MidiTime::ticksPerTact();
 
144
+}
 
145
+
 
146
+
 
147
+
 
148
+
 
149
+MidiTime pattern::beatPatternLength() const
 
150
+{
 
151
+       tick_t max_length = MidiTime::ticksPerTact();
 
152
+
 
153
+       for( NoteVector::ConstIterator it = m_notes.begin();
 
154
+                                               it != m_notes.end(); ++it )
 
155
+       {
 
156
+               if( ( *it )->length() < 0 )
 
157
+               {
 
158
+                       max_length = qMax<tick_t>( max_length,
 
159
+                               ( *it )->pos() +
 
160
+                                       MidiTime::ticksPerTact() /
 
161
+                                               MidiTime::stepsPerTact() );
 
162
+               }
 
163
+       }
 
164
+
 
165
+       if( m_steps != MidiTime::stepsPerTact() )
 
166
+       {
 
167
+               max_length = m_steps * MidiTime::ticksPerTact() /
 
168
+                                               MidiTime::stepsPerTact() ;
 
169
+       }
 
170
+
 
171
+       return MidiTime( max_length ).nextFullTact() * MidiTime::ticksPerTact();
 
172
+}
 
173
+
 
174
+note * pattern::addNote( const note & _new_note, const bool _quant_pos )
 
175
+{
 
176
+       note * new_note = new note( _new_note );
 
177
+       if( _quant_pos && engine::pianoRoll() )
 
178
+       {
 
179
+               new_note->quantizePos( engine::pianoRoll()->quantization() );
 
180
+       }
 
181
+
 
182
+       engine::mixer()->lock();
 
183
+       if( m_notes.size() == 0 || m_notes.back()->pos() <= new_note->pos() )
 
184
+       {
 
185
+               m_notes.push_back( new_note );
 
186
+       }
 
187
+       else
 
188
+       {
 
189
+               // simple algorithm for inserting the note between two
 
190
+               // notes with smaller and greater position
 
191
+               // maybe it could be optimized by starting in the middle and
 
192
+               // going forward or backward but note-inserting isn't that
 
193
+               // time-critical since it is usually not done while playing...
 
194
+               long new_note_abs_time = new_note->pos();
 
195
+               NoteVector::Iterator it = m_notes.begin();
 
196
+
 
197
+               while( it != m_notes.end() &&
 
198
+                                       ( *it )->pos() < new_note_abs_time )
 
199
+               {
 
200
+                       ++it;
 
201
+               }
 
202
+
 
203
+               m_notes.insert( it, new_note );
 
204
+       }
 
205
+       engine::mixer()->unlock();
 
206
+
 
207
+       checkType();
 
208
+       changeLength( length() );
 
209
+
 
210
+       emit dataChanged();
 
211
+
 
212
+       updateBBTrack();
 
213
+
 
214
+       return new_note;
 
215
+}
 
216
+
 
217
+
 
218
+
 
219
+
 
220
+void pattern::removeNote( const note * _note_to_del )
 
221
+{
 
222
+       engine::mixer()->lock();
 
223
+       NoteVector::Iterator it = m_notes.begin();
 
224
+       while( it != m_notes.end() )
 
225
+       {
 
226
+               if( *it == _note_to_del )
 
227
+               {
 
228
+                       delete *it;
 
229
+                       m_notes.erase( it );
 
230
+                       break;
 
231
+               }
 
232
+               ++it;
 
233
+       }
 
234
+       engine::mixer()->unlock();
 
235
+
 
236
+       checkType();
 
237
+       changeLength( length() );
 
238
+
 
239
+       emit dataChanged();
 
240
+
 
241
+       updateBBTrack();
 
242
+}
 
243
+
 
244
+
 
245
+// returns a pointer to the note at specified step, or NULL if note doesn't exist
 
246
+
 
247
+note * pattern::noteAtStep( int _step )
 
248
+{
 
249
+       for( NoteVector::Iterator it = m_notes.begin(); it != m_notes.end();
 
250
+                                                                       ++it )
 
251
+       {
 
252
+               if( ( *it )->pos() == ( _step *  MidiTime::ticksPerTact() ) / MidiTime::stepsPerTact() )
 
253
+               {
 
254
+                       return *it;
 
255
+               }
 
256
+       }
 
257
+       return NULL;
 
258
+}
 
259
+
 
260
+
 
261
+note * pattern::rearrangeNote( const note * _note_to_proc,
 
262
+                                                       const bool _quant_pos )
 
263
+{
 
264
+       // just rearrange the position of the note by removing it and adding
 
265
+       // a copy of it -> addNote inserts it at the correct position
 
266
+       note copy_of_note( *_note_to_proc );
 
267
+       removeNote( _note_to_proc );
 
268
+
 
269
+       return addNote( copy_of_note, _quant_pos );
 
270
+}
 
271
+
 
272
+
 
273
+
 
274
+void pattern::rearrangeAllNotes()
 
275
+{
 
276
+       // sort notes by start time
 
277
+       qSort(m_notes.begin(), m_notes.end(), note::lessThan );
 
278
+}
 
279
+
 
280
+
 
281
+
 
282
+void pattern::clearNotes()
 
283
+{
 
284
+       engine::mixer()->lock();
 
285
+       for( NoteVector::Iterator it = m_notes.begin(); it != m_notes.end();
 
286
+                                                                       ++it )
 
287
+       {
 
288
+               delete *it;
 
289
+       }
 
290
+       m_notes.clear();
 
291
+       engine::mixer()->unlock();
 
292
+
 
293
+       checkType();
 
294
+       emit dataChanged();
 
295
+}
 
296
+
 
297
+
 
298
+
 
299
+
 
300
+void pattern::setStep( int _step, bool _enabled )
 
301
+{
 
302
+       for( NoteVector::Iterator it = m_notes.begin(); it != m_notes.end();
 
303
+                                                                       ++it )
 
304
+       {
 
305
+               if( ( *it )->pos() == ( _step * MidiTime::ticksPerTact() ) / MidiTime::stepsPerTact() &&
 
306
+                                               ( *it )->length() <= 0 )
 
307
+               {
 
308
+                       ( *it )->setLength( _enabled ?
 
309
+                                               -DefaultTicksPerTact : 0 );
 
310
+               }
 
311
+       }
 
312
+}
 
313
+
 
314
+
 
315
+
 
316
+
 
317
+void pattern::setType( PatternTypes _new_pattern_type )
 
318
+{
 
319
+       if( _new_pattern_type == BeatPattern ||
 
320
+                               _new_pattern_type == MelodyPattern )
 
321
+       {
 
322
+               m_patternType = _new_pattern_type;
 
323
+       }
 
324
+}
 
325
+
 
326
+
 
327
+
 
328
+
 
329
+void pattern::checkType()
 
330
+{
 
331
+       NoteVector::Iterator it = m_notes.begin();
 
332
+       while( it != m_notes.end() )
 
333
+       {
 
334
+               if( ( *it )->length() > 0 )
 
335
+               {
 
336
+                       setType( pattern::MelodyPattern );
 
337
+                       return;
 
338
+               }
 
339
+               ++it;
 
340
+       }
 
341
+       setType( pattern::BeatPattern );
 
342
+}
 
343
+
 
344
+
 
345
+
 
346
+
 
347
+void pattern::saveSettings( QDomDocument & _doc, QDomElement & _this )
 
348
+{
 
349
+       _this.setAttribute( "type", m_patternType );
 
350
+       _this.setAttribute( "name", name() );
 
351
+       // as the target of copied/dragged pattern is always an existing
 
352
+       // pattern, we must not store actual position, instead we store -1
 
353
+       // which tells loadSettings() not to mess around with position
 
354
+       if( _this.parentNode().nodeName() == "clipboard" ||
 
355
+                       _this.parentNode().nodeName() == "dnddata" )
 
356
+       {
 
357
+               _this.setAttribute( "pos", -1 );
 
358
+       }
 
359
+       else
 
360
+       {
 
361
+               _this.setAttribute( "pos", startPosition() );
 
362
+       }
 
363
+       _this.setAttribute( "len", length() );
 
364
+       _this.setAttribute( "muted", isMuted() );
 
365
+       _this.setAttribute( "steps", m_steps );
 
366
+
 
367
+       // now save settings of all notes
 
368
+       for( NoteVector::Iterator it = m_notes.begin();
 
369
+                                               it != m_notes.end(); ++it )
 
370
+       {
 
371
+               if( ( *it )->length() )
 
372
+               {
 
373
+                       ( *it )->saveState( _doc, _this );
 
374
+               }
 
375
+       }
 
376
+}
 
377
+
 
378
+
 
379
+
 
380
+
 
381
+void pattern::loadSettings( const QDomElement & _this )
 
382
+{
 
383
+       m_patternType = static_cast<PatternTypes>( _this.attribute( "type"
 
384
+                                                               ).toInt() );
 
385
+       setName( _this.attribute( "name" ) );
 
386
+       if( _this.attribute( "pos" ).toInt() >= 0 )
 
387
+       {
 
388
+               movePosition( _this.attribute( "pos" ).toInt() );
 
389
+       }
 
390
+       changeLength( MidiTime( _this.attribute( "len" ).toInt() ) );
 
391
+       if( _this.attribute( "muted" ).toInt() != isMuted() )
 
392
+       {
 
393
+               toggleMute();
 
394
+       }
 
395
+
 
396
+       clearNotes();
 
397
+
 
398
+       QDomNode node = _this.firstChild();
 
399
+       while( !node.isNull() )
 
400
+       {
 
401
+               if( node.isElement() &&
 
402
+                       !node.toElement().attribute( "metadata" ).toInt() )
 
403
+               {
 
404
+                       note * n = new note;
 
405
+                       n->restoreState( node.toElement() );
 
406
+                       m_notes.push_back( n );
 
407
+               }
 
408
+               node = node.nextSibling();
 
409
+        }
 
410
+
 
411
+       m_steps = _this.attribute( "steps" ).toInt();
 
412
+       if( m_steps == 0 )
 
413
+       {
 
414
+               m_steps = MidiTime::stepsPerTact();
 
415
+       }
 
416
+
 
417
+       ensureBeatNotes();
 
418
+       checkType();
 
419
+
 
420
+       emit dataChanged();
 
421
+
 
422
+       updateBBTrack();
 
423
+}
 
424
+
 
425
+
 
426
+
 
427
+
 
428
+void pattern::clear()
 
429
+{
 
430
+       clearNotes();
 
431
+       ensureBeatNotes();
 
432
+}
 
433
+
 
434
+
 
435
+
 
436
+
 
437
+void pattern::addSteps()
 
438
+{
 
439
+       m_steps += MidiTime::stepsPerTact();
 
440
+       ensureBeatNotes();
 
441
+       emit dataChanged();
 
442
+       updateBBTrack();
 
443
+}
 
444
+
 
445
+
 
446
+
 
447
+
 
448
+void pattern::removeSteps()
 
449
+{
 
450
+       int _n = MidiTime::stepsPerTact();
 
451
+       if( _n < m_steps )
 
452
+       {
 
453
+               for( int i = m_steps - _n; i < m_steps; ++i )
 
454
+               {
 
455
+                       for( NoteVector::Iterator it = m_notes.begin();
 
456
+                                               it != m_notes.end(); ++it )
 
457
+                       {
 
458
+                               if( ( *it )->pos() ==
 
459
+                                       ( i * MidiTime::ticksPerTact() ) /
 
460
+                                               MidiTime::stepsPerTact() &&
 
461
+                                                       ( *it )->length() <= 0 )
 
462
+                               {
 
463
+                                       removeNote( *it );
 
464
+                                       break;
 
465
+                               }
 
466
+                       }
 
467
+               }
 
468
+               m_steps -= _n;
 
469
+               emit dataChanged();
 
470
+       }
 
471
+       updateBBTrack();
 
472
+}
 
473
+
 
474
+
 
475
+
 
476
+
 
477
+trackContentObjectView * pattern::createView( trackView * _tv )
 
478
+{
 
479
+       return new patternView( this, _tv );
 
480
+}
 
481
+
 
482
+
 
483
+
 
484
+
 
485
+
 
486
+void pattern::ensureBeatNotes()
 
487
+{
 
488
+       // make sure, that all step-note exist
 
489
+       for( int i = 0; i < m_steps; ++i )
 
490
+       {
 
491
+               bool found = false;
 
492
+               for( NoteVector::Iterator it = m_notes.begin(); it != m_notes.end(); ++it )
 
493
+               {
 
494
+                       // if a note in this position is the one we want
 
495
+                       if( ( *it )->pos() ==
 
496
+                               ( i * MidiTime::ticksPerTact() ) / MidiTime::stepsPerTact()
 
497
+                               && ( *it )->length() <= 0 )
 
498
+                       {
 
499
+                               found = true;
 
500
+                               break;
 
501
+                       }
 
502
+               }
 
503
+               if( found == false )
 
504
+               {
 
505
+                       addNote( note( MidiTime( 0 ), MidiTime( ( i *
 
506
+                               MidiTime::ticksPerTact() ) /
 
507
+                                       MidiTime::stepsPerTact() ) ), false );
 
508
+               }
 
509
+       }
 
510
+
 
511
+       // remove notes we no longer need:
 
512
+       // that is, disabled notes that no longer fall to the steps of the new time sig
 
513
+
 
514
+       for( NoteVector::Iterator it = m_notes.begin(); it != m_notes.end(); )
 
515
+       {
 
516
+               bool needed = false;
 
517
+               for( int i = 0; i < m_steps; ++i )
 
518
+               {
 
519
+                       if( ( *it )->pos() == ( i * MidiTime::ticksPerTact() ) / MidiTime::stepsPerTact()
 
520
+                               || ( *it )->length() != 0 )
 
521
+                       {
 
522
+                               needed = true;
 
523
+                               break;
 
524
+                       }
 
525
+               }
 
526
+               if( needed == false )
 
527
+               {
 
528
+                       delete *it;
 
529
+                       it = m_notes.erase( it );
 
530
+               }
 
531
+               else ++it;
 
532
+       }
 
533
+}
 
534
+
 
535
+
 
536
+
 
537
+
 
538
+void pattern::updateBBTrack()
 
539
+{
 
540
+       if( getTrack()->trackContainer() == engine::getBBTrackContainer() )
 
541
+       {
 
542
+               engine::getBBTrackContainer()->updateBBTrack( this );
 
543
+       }
 
544
+
 
545
+       if( engine::pianoRoll() && engine::pianoRoll()->currentPattern() == this )
 
546
+       {
 
547
+               engine::pianoRoll()->update();
 
548
+       }
 
549
+}
 
550
+
 
551
+
 
552
+
 
553
+
 
554
+bool pattern::empty()
 
555
+{
 
556
+       for( NoteVector::ConstIterator it = m_notes.begin();
 
557
+                                               it != m_notes.end(); ++it )
 
558
+       {
 
559
+               if( ( *it )->length() != 0 )
 
560
+               {
 
561
+                       return false;
 
562
+               }
 
563
+       }
 
564
+       return true;
 
565
+}
 
566
+
 
567
+
 
568
+
 
569
+
 
570
+void pattern::changeTimeSignature()
 
571
+{
 
572
+       MidiTime last_pos = MidiTime::ticksPerTact();
 
573
+       for( NoteVector::ConstIterator cit = m_notes.begin();
 
574
+                                               cit != m_notes.end(); ++cit )
 
575
+       {
 
576
+               if( ( *cit )->length() < 0 && ( *cit )->pos() > last_pos )
 
577
+               {
 
578
+                       last_pos = ( *cit )->pos()+MidiTime::ticksPerTact() /
 
579
+                                               MidiTime::stepsPerTact();
 
580
+               }
 
581
+       }
 
582
+       last_pos = last_pos.nextFullTact() * MidiTime::ticksPerTact();
 
583
+       for( NoteVector::Iterator it = m_notes.begin(); it != m_notes.end(); )
 
584
+       {
 
585
+               if( ( *it )->length() == 0 && ( *it )->pos() >= last_pos )
 
586
+               {
 
587
+                       delete *it;
 
588
+                       it = m_notes.erase( it );
 
589
+                       --m_steps;
 
590
+               }
 
591
+               else
 
592
+               {
 
593
+                       ++it;
 
594
+               }
 
595
+       }
 
596
+       m_steps = qMax<tick_t>(
 
597
+               qMax<tick_t>( m_steps, MidiTime::stepsPerTact() ),
 
598
+                               last_pos.getTact() * MidiTime::stepsPerTact() );
 
599
+       ensureBeatNotes();
 
600
+       updateBBTrack();
 
601
+}
 
602
+
 
603
+
 
604
+
 
605
+
 
606
+
 
607
+patternView::patternView( pattern * _pattern, trackView * _parent ) :
 
608
+       trackContentObjectView( _pattern, _parent ),
 
609
+       m_pat( _pattern ),
 
610
+       m_paintPixmap(),
 
611
+       m_needsUpdate( true )
 
612
+{
 
613
+       connect( engine::pianoRoll(), SIGNAL( currentPatternChanged() ),
 
614
+                       this, SLOT( update() ) );
 
615
+
 
616
+       if( s_stepBtnOn == NULL )
 
617
+       {
 
618
+               s_stepBtnOn = new QPixmap( embed::getIconPixmap(
 
619
+                                                       "step_btn_on_100" ) );
 
620
+       }
 
621
+
 
622
+       if( s_stepBtnOverlay == NULL )
 
623
+       {
 
624
+               s_stepBtnOverlay = new QPixmap( embed::getIconPixmap(
 
625
+                                               "step_btn_on_yellow" ) );
 
626
+       }
 
627
+
 
628
+       if( s_stepBtnOff == NULL )
 
629
+       {
 
630
+               s_stepBtnOff = new QPixmap( embed::getIconPixmap(
 
631
+                                                       "step_btn_off" ) );
 
632
+       }
 
633
+
 
634
+       if( s_stepBtnOffLight == NULL )
 
635
+       {
 
636
+               s_stepBtnOffLight = new QPixmap( embed::getIconPixmap(
 
637
+                                               "step_btn_off_light" ) );
 
638
+       }
 
639
+
 
640
+       setFixedHeight( parentWidget()->height() - 2 );
 
641
+       setAutoResizeEnabled( false );
 
642
+
 
643
+       toolTip::add( this,
 
644
+               tr( "double-click to open this pattern in piano-roll\n"
 
645
+                       "use mouse wheel to set volume of a step" ) );
 
646
+       setStyle( QApplication::style() );
 
647
+}
 
648
+
 
649
+
 
650
+
 
651
+
 
652
+
 
653
+
 
654
+patternView::~patternView()
 
655
+{
 
656
+       if( engine::pianoRoll()->currentPattern() == m_pat )
 
657
+       {
 
658
+               engine::pianoRoll()->setCurrentPattern( NULL );
 
659
+               // we have to have the song-editor to stop playing if it played
 
660
+               // us before
 
661
+               if( engine::getSong()->isPlaying() &&
 
662
+                       engine::getSong()->playMode() ==
 
663
+                                                       song::Mode_PlayPattern )
 
664
+               {
 
665
+                       engine::getSong()->playPattern( NULL );
 
666
+               }
 
667
+       }
 
668
+}
 
669
+
 
670
+
 
671
+
 
672
+
 
673
+
 
674
+void patternView::update()
 
675
+{
 
676
+       m_needsUpdate = true;
 
677
+       m_pat->changeLength( m_pat->length() );
 
678
+       trackContentObjectView::update();
 
679
+}
 
680
+
 
681
+
 
682
+
 
683
+
 
684
+void patternView::openInPianoRoll()
 
685
+{
 
686
+       engine::pianoRoll()->setCurrentPattern( m_pat );
 
687
+       engine::pianoRoll()->parentWidget()->show();
 
688
+       engine::pianoRoll()->setFocus();
 
689
+}
 
690
+
 
691
+
 
692
+
 
693
+
 
694
+void patternView::resetName()
 
695
+{
 
696
+       m_pat->setName( m_pat->m_instrumentTrack->name() );
 
697
+}
 
698
+
 
699
+
 
700
+
 
701
+
 
702
+void patternView::changeName()
 
703
+{
 
704
+       QString s = m_pat->name();
 
705
+       renameDialog rename_dlg( s );
 
706
+       rename_dlg.exec();
 
707
+       m_pat->setName( s );
 
708
+}
 
709
+
 
710
+
 
711
+
 
712
+
 
713
+void patternView::constructContextMenu( QMenu * _cm )
 
714
+{
 
715
+       QAction * a = new QAction( embed::getIconPixmap( "piano" ),
 
716
+                                       tr( "Open in piano-roll" ), _cm );
 
717
+       _cm->insertAction( _cm->actions()[0], a );
 
718
+       connect( a, SIGNAL( triggered( bool ) ),
 
719
+                                       this, SLOT( openInPianoRoll() ) );
 
720
+       _cm->insertSeparator( _cm->actions()[1] );
 
721
+
 
722
+       _cm->addSeparator();
 
723
+
 
724
+       _cm->addAction( embed::getIconPixmap( "edit_erase" ),
 
725
+                       tr( "Clear all notes" ), m_pat, SLOT( clear() ) );
 
726
+       _cm->addSeparator();
 
727
+
 
728
+       _cm->addAction( embed::getIconPixmap( "reload" ), tr( "Reset name" ),
 
729
+                                               this, SLOT( resetName() ) );
 
730
+       _cm->addAction( embed::getIconPixmap( "edit_rename" ),
 
731
+                                               tr( "Change name" ),
 
732
+                                               this, SLOT( changeName() ) );
 
733
+       _cm->addSeparator();
 
734
+
 
735
+       _cm->addAction( embed::getIconPixmap( "step_btn_add" ),
 
736
+               tr( "Add steps" ), m_pat, SLOT( addSteps() ) );
 
737
+       _cm->addAction( embed::getIconPixmap( "step_btn_remove" ),
 
738
+               tr( "Remove steps" ), m_pat, SLOT( removeSteps() ) );
 
739
+}
 
740
+
 
741
+
 
742
+
 
743
+
 
744
+void patternView::mouseDoubleClickEvent( QMouseEvent * _me )
 
745
+{
 
746
+       if( _me->button() != Qt::LeftButton )
 
747
+       {
 
748
+               _me->ignore();
 
749
+               return;
 
750
+       }
 
751
+       if( m_pat->type() == pattern::MelodyPattern ||
 
752
+               !( m_pat->type() == pattern::BeatPattern &&
 
753
+               ( pixelsPerTact() >= 192 ||
 
754
+                               m_pat->m_steps != MidiTime::stepsPerTact() ) &&
 
755
+               _me->y() > height() - s_stepBtnOff->height() ) )
 
756
+       {
 
757
+               openInPianoRoll();
 
758
+       }
 
759
+}
 
760
+
 
761
+
 
762
+
 
763
+
 
764
+void patternView::mousePressEvent( QMouseEvent * _me )
 
765
+{
 
766
+       if( _me->button() == Qt::LeftButton &&
 
767
+                               m_pat->m_patternType == pattern::BeatPattern &&
 
768
+                               ( fixedTCOs() || pixelsPerTact() >= 96 ||
 
769
+                               m_pat->m_steps != MidiTime::stepsPerTact() ) &&
 
770
+                               _me->y() > height() - s_stepBtnOff->height() )
 
771
+
 
772
+       // when mouse button is pressed in beat/bassline -mode
 
773
+
 
774
+       {
 
775
+//     get the step number that was clicked on and
 
776
+//     do calculations in floats to prevent rounding errors...
 
777
+               float tmp = ( ( float(_me->x()) - TCO_BORDER_WIDTH ) *
 
778
+                               float( m_pat -> m_steps ) ) / float(width() - TCO_BORDER_WIDTH*2);
 
779
+
 
780
+               int step = int( tmp );
 
781
+
 
782
+//     debugging to ensure we get the correct step...
 
783
+//             qDebug( "Step (%f) %d", tmp, step );
 
784
+
 
785
+               if( step >= m_pat->m_steps )
 
786
+               {
 
787
+                       qDebug( "Something went wrong in pattern.cpp: step %d doesn't exist in pattern!", step );
 
788
+                       return;
 
789
+               }
 
790
+
 
791
+               note * n = m_pat->noteAtStep( step );
 
792
+
 
793
+               // if note at step not found, ensureBeatNotes and try again
 
794
+               if( n == NULL )
 
795
+               {
 
796
+                       m_pat -> ensureBeatNotes();
 
797
+                       n = m_pat->noteAtStep( step );
 
798
+                       if( n == NULL ) // still can't find a note? bail!
 
799
+                       {
 
800
+                               qDebug( "Something went wrong in pattern.cpp: couldn't add note at step %d!", step );
 
801
+                               return;
 
802
+                       }
 
803
+               }
 
804
+               else // note at step found
 
805
+               {
 
806
+                       if( n->length() < 0 )
 
807
+                       {
 
808
+                               n->setLength( 0 );      // set note as enabled beat note
 
809
+                       }
 
810
+                       else
 
811
+                       {
 
812
+                               n->setLength( -DefaultTicksPerTact );   // set note as disabled beat note
 
813
+                       }
 
814
+               }
 
815
+
 
816
+               engine::getSong()->setModified();
 
817
+               update();
 
818
+
 
819
+               if( engine::pianoRoll()->currentPattern() == m_pat )
 
820
+               {
 
821
+                       engine::pianoRoll()->update();
 
822
+               }
 
823
+       }
 
824
+       else
 
825
+
 
826
+       // if not in beat/bassline -mode, let parent class handle the event
 
827
+
 
828
+       {
 
829
+               trackContentObjectView::mousePressEvent( _me );
 
830
+       }
 
831
+}
 
832
+
 
833
+
 
834
+
 
835
+
 
836
+void patternView::wheelEvent( QWheelEvent * _we )
 
837
+{
 
838
+       if( m_pat->m_patternType == pattern::BeatPattern &&
 
839
+                               ( fixedTCOs() || pixelsPerTact() >= 96 ||
 
840
+                               m_pat->m_steps != MidiTime::stepsPerTact() ) &&
 
841
+                               _we->y() > height() - s_stepBtnOff->height() )
 
842
+       {
 
843
+//     get the step number that was wheeled on and
 
844
+//     do calculations in floats to prevent rounding errors...
 
845
+               float tmp = ( ( float(_we->x()) - TCO_BORDER_WIDTH ) *
 
846
+                               float( m_pat -> m_steps ) ) / float(width() - TCO_BORDER_WIDTH*2);
 
847
+
 
848
+               int step = int( tmp );
 
849
+
 
850
+               if( step >= m_pat->m_steps )
 
851
+               {
 
852
+                       return;
 
853
+               }
 
854
+
 
855
+               int vol = 0;
 
856
+               int len = 0;
 
857
+
 
858
+               note * n = m_pat->noteAtStep( step );
 
859
+               if( n != NULL )
 
860
+               {
 
861
+                       vol = n->getVolume();
 
862
+                       len = n->length();
 
863
+               }
 
864
+
 
865
+               if( len == 0 && _we->delta() > 0 )
 
866
+               {
 
867
+                       n->setLength( -DefaultTicksPerTact );
 
868
+                       n->setVolume( 5 );
 
869
+               }
 
870
+               else if( _we->delta() > 0 )
 
871
+               {
 
872
+                       n->setVolume( qMin( 100, vol + 5 ) );
 
873
+               }
 
874
+               else
 
875
+               {
 
876
+                       n->setVolume( qMax( 0, vol - 5 ) );
 
877
+               }
 
878
+
 
879
+               engine::getSong()->setModified();
 
880
+               update();
 
881
+               if( engine::pianoRoll()->currentPattern() == m_pat )
 
882
+               {
 
883
+                       engine::pianoRoll()->update();
 
884
+               }
 
885
+               _we->accept();
 
886
+       }
 
887
+       else
 
888
+       {
 
889
+               trackContentObjectView::wheelEvent( _we );
 
890
+       }
 
891
+}
 
892
+
 
893
+
 
894
+
 
895
+
 
896
+void patternView::paintEvent( QPaintEvent * )
 
897
+{
 
898
+       if( m_needsUpdate == false )
 
899
+       {
 
900
+               QPainter p( this );
 
901
+               p.drawPixmap( 0, 0, m_paintPixmap );
 
902
+               return;
 
903
+       }
 
904
+
 
905
+       QPainter _p( this );
 
906
+       const QColor styleColor = _p.pen().brush().color();
 
907
+
 
908
+       m_pat->changeLength( m_pat->length() );
 
909
+
 
910
+       m_needsUpdate = false;
 
911
+
 
912
+       if( m_paintPixmap.isNull() == true || m_paintPixmap.size() != size() )
 
913
+       {
 
914
+               m_paintPixmap = QPixmap( size() );
 
915
+       }
 
916
+
 
917
+       QPainter p( &m_paintPixmap );
 
918
+
 
919
+       QLinearGradient lingrad( 0, 0, 0, height() );
 
920
+
 
921
+       QColor c;
 
922
+
 
923
+       if(( m_pat->m_patternType != pattern::BeatPattern ) &&
 
924
+                               !( m_pat->getTrack()->isMuted() || m_pat->isMuted() ))
 
925
+               c = isSelected() ? QColor( 0, 0, 224 )
 
926
+                                          : styleColor;
 
927
+       else
 
928
+               c = QColor( 80, 80, 80 );
 
929
+
 
930
+       if( m_pat->m_patternType != pattern::BeatPattern )
 
931
+       {
 
932
+               lingrad.setColorAt( 1, c.darker( 300 ) );
 
933
+               lingrad.setColorAt( 0, c );
 
934
+       }
 
935
+       else
 
936
+       {
 
937
+               lingrad.setColorAt( 0, c.darker( 300 ) );
 
938
+               lingrad.setColorAt( 1, c );
 
939
+       }
 
940
+
 
941
+       p.setBrush( lingrad );
 
942
+       if( engine::pianoRoll()->currentPattern() == m_pat && m_pat->m_patternType != pattern::BeatPattern )
 
943
+               p.setPen( c.lighter( 130 ) );
 
944
+       else
 
945
+               p.setPen( c.darker( 300 ) );
 
946
+       p.drawRect( QRect( 0, 0, width() - 1, height() - 1 ) );
 
947
+
 
948
+       p.setBrush( QBrush() );
 
949
+       if( m_pat->m_patternType != pattern::BeatPattern )
 
950
+       {
 
951
+               if( engine::pianoRoll()->currentPattern() == m_pat )
 
952
+                       p.setPen( c.lighter( 160 ) );
 
953
+               else
 
954
+                       p.setPen( c.lighter( 130 ) );
 
955
+               p.drawRect( QRect( 1, 1, width() - 3, height() - 3 ) );
 
956
+       }
 
957
+
 
958
+       const float ppt = fixedTCOs() ?
 
959
+                       ( parentWidget()->width() - 2 * TCO_BORDER_WIDTH )
 
960
+                                       / (float) m_pat->length().getTact() :
 
961
+                                                               pixelsPerTact();
 
962
+
 
963
+       const int x_base = TCO_BORDER_WIDTH;
 
964
+       p.setPen( c.darker( 300 ) );
 
965
+
 
966
+       for( tact_t t = 1; t < m_pat->length().getTact(); ++t )
 
967
+       {
 
968
+               p.drawLine( x_base + static_cast<int>( ppt * t ) - 1,
 
969
+                               TCO_BORDER_WIDTH, x_base + static_cast<int>(
 
970
+                                               ppt * t ) - 1, 5 );
 
971
+               p.drawLine( x_base + static_cast<int>( ppt * t ) - 1,
 
972
+                               height() - ( 4 + 2 * TCO_BORDER_WIDTH ),
 
973
+                               x_base + static_cast<int>( ppt * t ) - 1,
 
974
+                               height() - 2 * TCO_BORDER_WIDTH );
 
975
+       }
 
976
+
 
977
+// melody pattern paint event
 
978
+
 
979
+       if( m_pat->m_patternType == pattern::MelodyPattern )
 
980
+       {
 
981
+               if( m_pat->m_notes.size() > 0 )
 
982
+               {
 
983
+                       // first determine the central tone so that we can
 
984
+                       // display the area where most of the m_notes are
 
985
+                       // also calculate min/max tones so the tonal range can be
 
986
+                       // properly stretched accross the pattern vertically
 
987
+
 
988
+                       int central_key = 0;
 
989
+                       int max_key = 0;
 
990
+                       int min_key = 9999999;
 
991
+                       int total_notes = 0;
 
992
+
 
993
+                       for( NoteVector::Iterator it = m_pat->m_notes.begin();
 
994
+                                       it != m_pat->m_notes.end(); ++it )
 
995
+                       {
 
996
+                               if( ( *it )->length() > 0 )
 
997
+                               {
 
998
+                                       max_key = qMax( max_key, ( *it )->key() );
 
999
+                                       min_key = qMin( min_key, ( *it )->key() );
 
1000
+                                       central_key += ( *it )->key();
 
1001
+                                       ++total_notes;
 
1002
+                               }
 
1003
+                       }
 
1004
+
 
1005
+                       if( total_notes > 0 )
 
1006
+                       {
 
1007
+                               central_key = central_key / total_notes;
 
1008
+                               const int keyrange = qMax( qMax( max_key - central_key, central_key - min_key ), 1 );
 
1009
+
 
1010
+                               // debug code
 
1011
+                               // qDebug( "keyrange: %d", keyrange );
 
1012
+
 
1013
+                               // determine height of the pattern view, sans borders
 
1014
+                               const int ht = height() - 1 - TCO_BORDER_WIDTH * 2;
 
1015
+
 
1016
+                               // determine maximum height value for drawing bounds checking
 
1017
+                               const int max_ht = height() - 1 - TCO_BORDER_WIDTH;
 
1018
+
 
1019
+                               // set colour based on mute status
 
1020
+                               if( m_pat->getTrack()->isMuted() ||
 
1021
+                                                       m_pat->isMuted() )
 
1022
+                               {
 
1023
+                                       p.setPen( QColor( 160, 160, 160 ) );
 
1024
+                               }
 
1025
+                               else
 
1026
+                               {
 
1027
+                                       p.setPen( QColor( 255, 255, 255 ) );    /// \todo make this a qproperty
 
1028
+                               }
 
1029
+
 
1030
+                               // scan through all the notes and draw them on the pattern
 
1031
+                               for( NoteVector::Iterator it =
 
1032
+                                                       m_pat->m_notes.begin();
 
1033
+                                       it != m_pat->m_notes.end(); ++it )
 
1034
+                               {
 
1035
+                                       // calculate relative y-position
 
1036
+                                       const float y_key =
 
1037
+                                               ( float( central_key - ( *it )->key() ) / keyrange + 1.0f ) / 2;
 
1038
+                                       // multiply that by pattern height
 
1039
+                                       const int y_pos = static_cast<int>( TCO_BORDER_WIDTH + y_key * ht );
 
1040
+
 
1041
+                                       // debug code
 
1042
+                                       // if( ( *it )->length() > 0 ) qDebug( "key %d, central_key %d, y_key %f, y_pos %d", ( *it )->key(), central_key, y_key, y_pos );
 
1043
+
 
1044
+                                       // check that note isn't out of bounds, and has a length
 
1045
+                                       if( ( *it )->length() > 0 &&
 
1046
+                                                       y_pos >= TCO_BORDER_WIDTH &&
 
1047
+                                                       y_pos <= max_ht )
 
1048
+                                       {
 
1049
+                                               // calculate start and end x-coords of the line to be drawn
 
1050
+                                               const int x1 = x_base +
 
1051
+                                                       static_cast<int>
 
1052
+                                                       ( ( *it )->pos() * ( ppt  / MidiTime::ticksPerTact() ) );
 
1053
+                                               const int x2 = x_base +
 
1054
+                                                       static_cast<int>
 
1055
+                                                       ( ( ( *it )->pos() + ( *it )->length() ) * ( ppt  / MidiTime::ticksPerTact() ) );
 
1056
+
 
1057
+                                               // check bounds, draw line
 
1058
+                                               if( x1 < width() - TCO_BORDER_WIDTH )
 
1059
+                                                       p.drawLine( x1, y_pos,
 
1060
+                                                                               qMin( x2, width() - TCO_BORDER_WIDTH ), y_pos );
 
1061
+                                       }
 
1062
+                               }
 
1063
+                       }
 
1064
+               }
 
1065
+       }
 
1066
+
 
1067
+// beat pattern paint event
 
1068
+
 
1069
+       else if( m_pat->m_patternType == pattern::BeatPattern &&
 
1070
+               ( fixedTCOs() || ppt >= 96
 
1071
+                       || m_pat->m_steps != MidiTime::stepsPerTact() ) )
 
1072
+       {
 
1073
+               QPixmap stepon;
 
1074
+               QPixmap stepoverlay;
 
1075
+               QPixmap stepoff;
 
1076
+               QPixmap stepoffl;
 
1077
+               const int steps = qMax( 1,
 
1078
+                                       m_pat->m_steps );
 
1079
+               const int w = width() - 2 * TCO_BORDER_WIDTH;
 
1080
+
 
1081
+               // scale step graphics to fit the beat pattern length
 
1082
+               stepon = s_stepBtnOn->scaled( w / steps,
 
1083
+                                             s_stepBtnOn->height(),
 
1084
+                                             Qt::IgnoreAspectRatio,
 
1085
+                                             Qt::SmoothTransformation );
 
1086
+               stepoverlay = s_stepBtnOverlay->scaled( w / steps,
 
1087
+                                             s_stepBtnOn->height(),
 
1088
+                                             Qt::IgnoreAspectRatio,
 
1089
+                                             Qt::SmoothTransformation );
 
1090
+               stepoff = s_stepBtnOff->scaled( w / steps,
 
1091
+                                               s_stepBtnOff->height(),
 
1092
+                                               Qt::IgnoreAspectRatio,
 
1093
+                                               Qt::SmoothTransformation );
 
1094
+               stepoffl = s_stepBtnOffLight->scaled( w / steps,
 
1095
+                                               s_stepBtnOffLight->height(),
 
1096
+                                               Qt::IgnoreAspectRatio,
 
1097
+                                               Qt::SmoothTransformation );
 
1098
+
 
1099
+               for( int it = 0; it < steps; it++ )     // go through all the steps in the beat pattern
 
1100
+               {
 
1101
+                       note * n = m_pat->noteAtStep( it );
 
1102
+
 
1103
+                       // figure out x and y coordinates for step graphic
 
1104
+                       const int x = TCO_BORDER_WIDTH + static_cast<int>( it * w / steps );
 
1105
+                       const int y = height() - s_stepBtnOff->height() - 1;
 
1106
+
 
1107
+                       // get volume and length of note, if noteAtStep returned null
 
1108
+                       // (meaning, note at step doesn't exist for some reason)
 
1109
+                       // then set both at zero, ie. treat as an off step
 
1110
+                       const int vol = ( n != NULL ? n->getVolume() : 0 );
 
1111
+                       const int len = ( n != NULL ? int( n->length() ) : 0 );
 
1112
+
 
1113
+                       if( len < 0 )
 
1114
+                       {
 
1115
+                               p.drawPixmap( x, y, stepoff );
 
1116
+                               for( int i = 0; i < vol / 5 + 1; ++i )
 
1117
+                               {
 
1118
+                                       p.drawPixmap( x, y, stepon );
 
1119
+                               }
 
1120
+                               for( int i = 0; i < ( 25 + ( vol - 75 ) ) / 5;
 
1121
+                                                                       ++i )
 
1122
+                               {
 
1123
+                                       p.drawPixmap( x, y, stepoverlay );
 
1124
+                               }
 
1125
+                       }
 
1126
+                       else if( ( it / 4 ) % 2 )
 
1127
+                       {
 
1128
+                               p.drawPixmap( x, y, stepoffl );
 
1129
+                       }
 
1130
+                       else
 
1131
+                       {
 
1132
+                               p.drawPixmap( x, y, stepoff );
 
1133
+                       }
 
1134
+               } // end for loop
 
1135
+       }
 
1136
+
 
1137
+       p.setFont( pointSize<8>( p.font() ) );
 
1138
+
 
1139
+       QColor text_color = ( m_pat->isMuted() || m_pat->getTrack()->isMuted() )
 
1140
+               ? QColor( 30, 30, 30 )
 
1141
+               : QColor( 255, 255, 255 );
 
1142
+
 
1143
+       if( m_pat->name() != m_pat->instrumentTrack()->name() )
 
1144
+       {
 
1145
+               p.setPen( QColor( 0, 0, 0 ) );
 
1146
+               p.drawText( 4, p.fontMetrics().height()+1, m_pat->name() );
 
1147
+               p.setPen( text_color );
 
1148
+               p.drawText( 3, p.fontMetrics().height(), m_pat->name() );
 
1149
+       }
 
1150
+
 
1151
+       if( m_pat->isMuted() )
 
1152
+       {
 
1153
+               p.drawPixmap( 3, p.fontMetrics().height() + 1,
 
1154
+                               embed::getIconPixmap( "muted", 16, 16 ) );
 
1155
+       }
 
1156
+
 
1157
+       p.end();
 
1158
+
 
1159
+       _p.drawPixmap( 0, 0, m_paintPixmap );
 
1160
+
 
1161
+}
 
1162
+
 
1163
+
 
1164
+
 
1165
+
 
1166
+#include "moc_pattern.cxx"
 
1167
+
 
1168
+