~ubuntu-branches/ubuntu/hardy/lmms/hardy

« back to all changes in this revision

Viewing changes to src/core/automation_pattern.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Tobias Doerffel
  • Date: 2007-09-17 15:00:24 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20070917150024-mo0zk4ks81jawqii
Tags: 0.3.0-1ubuntu1
* Resynchronized with Debian (LP: #139759, LP: #90806, LP: #102639,
  LP: #113447, LP: #121172, LP: #124890)
* reverted changes from 0.2.1-1.1ubuntu1 as upstream merged/included them

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#ifndef SINGLE_SOURCE_COMPILE
 
2
 
 
3
/*
 
4
 * automation_pattern.cpp - implementation of class automationPattern which
 
5
 *                          holds dynamic values
 
6
 *
 
7
 * Copyright (c) 2006-2007 Javier Serrano Polo <jasp00/at/users.sourceforge.net>
 
8
 * 
 
9
 * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
 
10
 *
 
11
 * This program is free software; you can redistribute it and/or
 
12
 * modify it under the terms of the GNU General Public
 
13
 * License as published by the Free Software Foundation; either
 
14
 * version 2 of the License, or (at your option) any later version.
 
15
 *
 
16
 * This program is distributed in the hope that it will be useful,
 
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
19
 * General Public License for more details.
 
20
 *
 
21
 * You should have received a copy of the GNU General Public
 
22
 * License along with this program (see COPYING); if not, write to the
 
23
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 
24
 * Boston, MA 02110-1301 USA.
 
25
 *
 
26
 */
 
27
 
 
28
 
 
29
#include "qt3support.h"
 
30
 
 
31
#ifdef QT4
 
32
 
 
33
#include <Qt/QtXml>
 
34
 
 
35
#else
 
36
 
 
37
#include <qdom.h>
 
38
#define value data
 
39
 
 
40
#endif
 
41
 
 
42
 
 
43
#include "automation_pattern.h"
 
44
#include "automation_editor.h"
 
45
#include "engine.h"
 
46
#include "level_object.h"
 
47
#include "note.h"
 
48
#include "templates.h"
 
49
#include "track.h"
 
50
 
 
51
 
 
52
 
 
53
 
 
54
automationPattern::automationPattern( track * _track, levelObject * _object ) :
 
55
        m_track( _track ),
 
56
        m_object( _object ),
 
57
        m_update_first( TRUE ),
 
58
        m_dynamic( FALSE )
 
59
{
 
60
}
 
61
 
 
62
 
 
63
 
 
64
 
 
65
automationPattern::automationPattern( const automationPattern & _pat_to_copy ) :
 
66
        QObject(),
 
67
        journallingObject(),
 
68
        m_track( _pat_to_copy.m_track ),
 
69
        m_object( _pat_to_copy.m_object ),
 
70
        m_update_first( _pat_to_copy.m_update_first ),
 
71
        m_dynamic( _pat_to_copy.m_dynamic )
 
72
{
 
73
        for( timeMap::const_iterator it = _pat_to_copy.m_time_map.begin();
 
74
                                it != _pat_to_copy.m_time_map.end(); ++it )
 
75
        {
 
76
                m_time_map[it.key()] = it.value();
 
77
        }
 
78
 
 
79
        if( m_dynamic && m_track )
 
80
        {
 
81
                m_track->addAutomationPattern( this );
 
82
        }
 
83
}
 
84
 
 
85
 
 
86
 
 
87
 
 
88
automationPattern::automationPattern( const automationPattern & _pat_to_copy,
 
89
                                                levelObject * _object ) :
 
90
        m_track( _pat_to_copy.m_track ),
 
91
        m_object( _object ),
 
92
        m_update_first( _pat_to_copy.m_update_first ),
 
93
        m_dynamic( _pat_to_copy.m_dynamic )
 
94
{
 
95
        for( timeMap::const_iterator it = _pat_to_copy.m_time_map.begin();
 
96
                                it != _pat_to_copy.m_time_map.end(); ++it )
 
97
        {
 
98
                m_time_map[it.key()] = it.value();
 
99
        }
 
100
 
 
101
        if( m_dynamic && m_track )
 
102
        {
 
103
                m_track->addAutomationPattern( this );
 
104
        }
 
105
}
 
106
 
 
107
 
 
108
 
 
109
 
 
110
automationPattern::~automationPattern()
 
111
{
 
112
        if( m_dynamic && m_track )
 
113
        {
 
114
                m_track->removeAutomationPattern( this );
 
115
        }
 
116
 
 
117
        if( engine::getAutomationEditor()
 
118
                && engine::getAutomationEditor()->currentPattern() == this )
 
119
        {
 
120
                engine::getAutomationEditor()->setCurrentPattern( NULL );
 
121
        }
 
122
}
 
123
 
 
124
 
 
125
 
 
126
 
 
127
//TODO: Improve this
 
128
midiTime automationPattern::length( void ) const
 
129
{
 
130
        Sint32 max_length = 0;
 
131
 
 
132
        for( timeMap::const_iterator it = m_time_map.begin();
 
133
                                                        it != m_time_map.end();
 
134
                                                                        ++it )
 
135
        {
 
136
                max_length = tMax<Sint32>( max_length, -it.key() );
 
137
        }
 
138
        if( max_length % 64 == 0 )
 
139
        {
 
140
                return( midiTime( tMax<Sint32>( max_length, 64 ) ) );
 
141
        }
 
142
        return( midiTime( tMax( midiTime( max_length ).getTact() + 1, 1 ),
 
143
                                                                        0 ) );
 
144
}
 
145
 
 
146
 
 
147
 
 
148
 
 
149
midiTime automationPattern::putValue( const midiTime & _time, const int _value,
 
150
                                                        const bool _quant_pos )
 
151
{
 
152
        midiTime new_time = _quant_pos ?
 
153
                note::quantized( _time,
 
154
                        engine::getAutomationEditor()->quantization() ) :
 
155
                _time;
 
156
 
 
157
        m_time_map[-new_time] = _value;
 
158
 
 
159
        if( !m_dynamic && new_time != 0 )
 
160
        {
 
161
                m_dynamic = TRUE;
 
162
                if( m_track )
 
163
                {
 
164
                        m_track->addAutomationPattern( this );
 
165
                }
 
166
        }
 
167
 
 
168
        return( new_time );
 
169
}
 
170
 
 
171
 
 
172
 
 
173
 
 
174
void automationPattern::removeValue( const midiTime & _time )
 
175
{
 
176
        if( _time != 0 )
 
177
        {
 
178
                m_time_map.remove( -_time );
 
179
 
 
180
                if( m_time_map.size() == 1 )
 
181
                {
 
182
                        m_dynamic = FALSE;
 
183
                        m_object->setLevel( m_time_map[0] );
 
184
                        if( m_track )
 
185
                        {
 
186
                                m_track->removeAutomationPattern( this );
 
187
                        }
 
188
                }
 
189
        }
 
190
}
 
191
 
 
192
 
 
193
 
 
194
 
 
195
void automationPattern::clear( void )
 
196
{
 
197
        m_time_map.clear();
 
198
        if( engine::getAutomationEditor()->currentPattern() == this )
 
199
        {
 
200
                engine::getAutomationEditor()->update();
 
201
        }
 
202
}
 
203
 
 
204
 
 
205
 
 
206
 
 
207
int automationPattern::valueAt( const midiTime & _time )
 
208
{
 
209
        return( m_time_map.lowerBound( -_time ).value() );
 
210
}
 
211
 
 
212
 
 
213
 
 
214
 
 
215
void automationPattern::saveSettings( QDomDocument & _doc, QDomElement & _this )
 
216
{
 
217
        for( timeMap::iterator it = m_time_map.begin(); it != m_time_map.end();
 
218
                                                                        ++it )
 
219
        {
 
220
                QDomElement element = _doc.createElement( "time" );
 
221
                element.setAttribute( "pos", -it.key() );
 
222
                element.setAttribute( "value", m_object->levelToLabel(
 
223
                                                                it.value() ) );
 
224
                _this.appendChild( element );
 
225
        }
 
226
}
 
227
 
 
228
 
 
229
 
 
230
 
 
231
void automationPattern::loadSettings( const QDomElement & _this )
 
232
{
 
233
        clear();
 
234
 
 
235
        for( QDomNode node = _this.firstChild(); !node.isNull();
 
236
                                                node = node.nextSibling() )
 
237
        {
 
238
                QDomElement element = node.toElement();
 
239
                if( element.isNull() || element.tagName() != "time" )
 
240
                {
 
241
                        continue;
 
242
                }
 
243
                m_time_map[-element.attribute( "pos" ).toInt()]
 
244
                                = m_object->labelToLevel(
 
245
                                                element.attribute( "value" ) );
 
246
        }
 
247
 
 
248
        if( !m_dynamic )
 
249
        {
 
250
                m_dynamic = TRUE;
 
251
                if( m_track )
 
252
                {
 
253
                        m_track->addAutomationPattern( this );
 
254
                }
 
255
        }
 
256
}
 
257
 
 
258
 
 
259
 
 
260
 
 
261
void automationPattern::openInAutomationEditor( void )
 
262
{
 
263
        engine::getAutomationEditor()->setCurrentPattern( this );
 
264
        engine::getAutomationEditor()->show();
 
265
        engine::getAutomationEditor()->setFocus();
 
266
}
 
267
 
 
268
 
 
269
 
 
270
 
 
271
const QString automationPattern::name( void )
 
272
{
 
273
        if( m_track )
 
274
        {
 
275
                QString widget_name = dynamic_cast<QWidget *>( m_object )
 
276
                                                        ->accessibleName();
 
277
                return( m_track->name() + " - " + widget_name );
 
278
        }
 
279
        else
 
280
        {
 
281
                return( m_object->displayName() );
 
282
        }
 
283
}
 
284
 
 
285
 
 
286
 
 
287
 
 
288
void automationPattern::processMidiTime( const midiTime & _time )
 
289
{
 
290
        if( _time >= 0 )
 
291
        {
 
292
                m_object->setLevel( m_time_map.lowerBound( -_time ).value() );
 
293
        }
 
294
}
 
295
 
 
296
 
 
297
#undef value
 
298
 
 
299
#include "automation_pattern.moc"
 
300
 
 
301
 
 
302
#endif