1 /*
2  * Hydrogen
3  * Copyright(c) 2002-2008 by Alex >Comix< Cominu [comix@users.sourceforge.net]
4  *
5  * http://www.hydrogen-music.org
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY, without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  *
21  */
22 
23 #include <hydrogen/basics/pattern_list.h>
24 
25 //#include <hydrogen/helpers/xml.h>
26 #include <hydrogen/basics/pattern.h>
27 
28 namespace H2Core
29 {
30 
31 const char* PatternList::__class_name = "PatternList";
32 
PatternList()33 PatternList::PatternList() : Object( __class_name )
34 {
35 }
36 
PatternList(PatternList * other)37 PatternList::PatternList( PatternList* other ) : Object( __class_name )
38 {
39 	assert( __patterns.size() == 0 );
40 	for ( int i=0; i<other->size(); i++ ) {
41 		( *this ) << ( new Pattern( ( *other )[i] ) );
42 	}
43 }
44 
~PatternList()45 PatternList::~PatternList()
46 {
47 	for ( int i = 0; i < __patterns.size(); ++i ) {
48 		assert ( __patterns[i] );
49 		delete __patterns[i];
50 	}
51 }
52 
operator <<(Pattern * pattern)53 void PatternList::operator<<( Pattern* pattern )
54 {
55 	// do nothing if already in __patterns
56 	for( int i=0; i<__patterns.size(); i++ ) {
57 		if( __patterns[i]==pattern ) return;
58 	}
59 	__patterns.push_back( pattern );
60 }
61 
add(Pattern * pattern)62 void PatternList::add( Pattern* pattern )
63 {
64 	// do nothing if already in __patterns
65 	for( int i=0; i<__patterns.size(); i++ ) {
66 		if( __patterns[i]==pattern ) return;
67 	}
68 	__patterns.push_back( pattern );
69 }
70 
insert(int idx,Pattern * pattern)71 void PatternList::insert( int idx, Pattern* pattern )
72 {
73 	// do nothing if already in __patterns
74 	for( int i=0; i<__patterns.size(); i++ ) {
75 		if( __patterns[i]==pattern ) return;
76 	}
77 	__patterns.insert( __patterns.begin() + idx, pattern );
78 }
79 
operator [](int idx)80 Pattern* PatternList::operator[]( int idx )
81 {
82 	if ( idx < 0 || idx >= __patterns.size() ) {
83 		ERRORLOG( QString( "idx %1 out of [0;%2]" ).arg( idx ).arg( size() ) );
84 		return nullptr;
85 	}
86 	assert( idx >= 0 && idx < __patterns.size() );
87 	return __patterns[idx];
88 }
89 
get(int idx)90 Pattern* PatternList::get( int idx )
91 {
92 	if ( idx < 0 || idx >= __patterns.size() ) {
93 		ERRORLOG( QString( "idx %1 out of [0;%2]" ).arg( idx ).arg( size() ) );
94 		return nullptr;
95 	}
96 	assert( idx >= 0 && idx < __patterns.size() );
97 	return __patterns[idx];
98 }
99 
get(int idx) const100 const Pattern* PatternList::get( int idx ) const
101 {
102 	if ( idx < 0 || idx >= __patterns.size() ) {
103 		ERRORLOG( QString( "idx %1 out of [0;%2]" ).arg( idx ).arg( size() ) );
104 		return nullptr;
105 	}
106 	assert( idx >= 0 && idx < __patterns.size() );
107 	return __patterns[idx];
108 }
109 
index(Pattern * pattern)110 int PatternList::index( Pattern* pattern )
111 {
112 	for( int i=0; i<__patterns.size(); i++ ) {
113 		if ( __patterns[i]==pattern ) return i;
114 	}
115 	return -1;
116 }
117 
del(int idx)118 Pattern* PatternList::del( int idx )
119 {
120 	assert( idx >= 0 && idx < __patterns.size() );
121 	Pattern* pattern = __patterns[idx];
122 	__patterns.erase( __patterns.begin() + idx );
123 	return pattern;
124 }
125 
del(Pattern * pattern)126 Pattern* PatternList::del( Pattern* pattern )
127 {
128 	for( int i=0; i<__patterns.size(); i++ ) {
129 		if( __patterns[i]==pattern ) {
130 			__patterns.erase( __patterns.begin() + i );
131 			return pattern;
132 		}
133 	}
134 	return nullptr;
135 }
136 
replace(int idx,Pattern * pattern)137 Pattern* PatternList::replace( int idx, Pattern* pattern )
138 {
139 	/*
140 	 * if we insert a new pattern (copy, add new pattern, undo delete pattern and so on will do this)
141 	 * idx is > __pattern.size(). that's why i add +1 to assert expression
142 	 */
143 
144 	assert( idx >= 0 && idx <= __patterns.size() +1 );
145 	if( idx < 0 || idx >= __patterns.size() ) {
146 		ERRORLOG( QString( "index out of bounds %1 (size:%2)" ).arg( idx ).arg( __patterns.size() ) );
147 		return nullptr;
148 	}
149 
150 	__patterns.insert( __patterns.begin() + idx, pattern );
151 	__patterns.erase( __patterns.begin() + idx + 1 );
152 
153 	//create return pattern after patternlist tätatä to return the right one
154 	Pattern* ret = __patterns[idx];
155 	return ret;
156 }
157 
set_to_old()158 void PatternList::set_to_old()
159 {
160 	for( int i=0; i<__patterns.size(); i++ ) {
161 		__patterns[i]->set_to_old();
162 	}
163 }
164 
find(const QString & name)165 Pattern*  PatternList::find( const QString& name )
166 {
167 	for( int i=0; i<__patterns.size(); i++ ) {
168 		if ( __patterns[i]->get_name()==name ) return __patterns[i];
169 	}
170 	return nullptr;
171 }
172 
swap(int idx_a,int idx_b)173 void PatternList::swap( int idx_a, int idx_b )
174 {
175 	assert( idx_a >= 0 && idx_a < __patterns.size() );
176 	assert( idx_b >= 0 && idx_b < __patterns.size() );
177 	if( idx_a == idx_b ) return;
178 	//DEBUGLOG(QString("===>> SWAP  %1 %2").arg(idx_a).arg(idx_b) );
179 	Pattern* tmp = __patterns[idx_a];
180 	__patterns[idx_a] = __patterns[idx_b];
181 	__patterns[idx_b] = tmp;
182 }
183 
move(int idx_a,int idx_b)184 void PatternList::move( int idx_a, int idx_b )
185 {
186 	assert( idx_a >= 0 && idx_a < __patterns.size() );
187 	assert( idx_b >= 0 && idx_b < __patterns.size() );
188 	if( idx_a == idx_b ) return;
189 	//DEBUGLOG(QString("===>> MOVE  %1 %2").arg(idx_a).arg(idx_b) );
190 	Pattern* tmp = __patterns[idx_a];
191 	__patterns.erase( __patterns.begin() + idx_a );
192 	__patterns.insert( __patterns.begin() + idx_b, tmp );
193 }
194 
flattened_virtual_patterns_compute()195 void PatternList::flattened_virtual_patterns_compute()
196 {
197 	for ( int i=0 ; i<__patterns.size() ; i++ ) __patterns[i]->flattened_virtual_patterns_clear();
198 	for ( int i=0 ; i<__patterns.size() ; i++ ) __patterns[i]->flattened_virtual_patterns_compute();
199 }
200 
virtual_pattern_del(Pattern * pattern)201 void PatternList::virtual_pattern_del( Pattern* pattern )
202 {
203 	for( int i=0; i<__patterns.size(); i++ ) __patterns[i]->virtual_patterns_del( pattern );
204 }
205 
check_name(QString patternName)206 bool PatternList::check_name( QString patternName )
207 {
208 	if (patternName == "") {
209 		return false;
210 	}
211 
212 	for (uint i = 0; i < __patterns.size(); i++) {
213 		if ( __patterns[i]->get_name() == patternName) {
214 			return false;
215 		}
216 	}
217 	return true;
218 }
219 
find_unused_pattern_name(QString sourceName)220 QString PatternList::find_unused_pattern_name( QString sourceName )
221 {
222 	QString unusedPatternNameCandidate;
223 
224 	if( sourceName.isEmpty() ) {
225 		sourceName = "Pattern 11";
226 	}
227 
228 	int i = 1;
229 	QString suffix = "";
230 	unusedPatternNameCandidate = sourceName;
231 
232 	while( !check_name( unusedPatternNameCandidate + suffix ) ) {
233 		suffix = " #" + QString::number(i);
234 		i++;
235 	}
236 
237 	unusedPatternNameCandidate += suffix;
238 
239 	return unusedPatternNameCandidate;
240 }
241 
242 }
243 
244 
245 
246 /* vim: set softtabstop=4 noexpandtab: */
247